9fadf50375
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
bbd2556861
|
feat(tool): google_workspace operation-level allowlist (#4010)
* feat(config): add google workspace operation allowlists * docs(superpowers): link google workspace operation inventory sources * docs(superpowers): verify starter operation examples * fix(google_workspace): remove duplicate credential/audit blocks, fix trim in allowlist check, add duplicate-methods test - Remove the duplicated credentials_path, default_account, and audit_log blocks that were copy-pasted into execute() — they were idempotent but misleading and would double-append --account args on every call. - Trim stored service/resource/method values in is_operation_allowed() to match the trim applied during Config::validate(), preventing a mismatch where a config entry with surrounding whitespace would pass validation but never match at runtime. - Add google_workspace_allowed_operations_reject_duplicate_methods_within_entry test to cover the duplicate-method validation path that was implemented but untested. * fix(google_workspace): close sub_resource bypass, trim allowed_services at runtime, mark spec implemented - HIGH: extract and validate sub_resource before the allowlist check; is_operation_allowed() now accepts Option<&str> for sub_resource and returns false (fail-closed) when allowed_operations is non-empty and a sub_resource is present — prevents nested gws calls such as `drive/files/permissions/list` from slipping past a 3-segment policy - MEDIUM: runtime allowed_services check now uses s.trim() == service, matching the trim() applied during config validation - LOW: spec status updated to Implemented; stale "does not currently support method-level allowlists" line removed - Added test: operation_allowlist_rejects_sub_resource_when_operations_configured * docs(google_workspace): document sub_resource limitation and add config-reference entries Spec updates (superpowers/specs): - Semantics section: note that sub_resource calls are denied fail-closed when allowed_operations is configured - Mental model: show both 3-segment and 4-segment gws command shapes; explain that 4-segment commands are unsupported with allowed_operations in this version - Runtime enforcement: correct the validation order to match the implementation (sub_resource extracted before allowlist check, budget charged last) - New section: Sub-Resource Limitation — documents impact, operator workaround, and confirms the deny is intentional for this slice - Follow-On Work: add sub_resource config model extension as item 1 Config reference updates (all three locales): - Add [google_workspace] section with top-level keys, [[allowed_operations]] sub-table, sub-resource limitation note, and TOML example * fix(docs): add classroom and events to allowed_services list in all config-reference locales * feat(google_workspace): extend allowed_operations to support sub_resource for 4-segment gws commands All Gmail operations use gws gmail users <sub_resource> <method>, not the flat 3-segment shape. Without sub_resource support in allowed_operations, Gmail could not be scoped at all, making the email-assistant use case impossible. Config model: - Add optional sub_resource field to GoogleWorkspaceAllowedOperation - An entry without sub_resource matches 3-segment calls (Drive, Calendar, etc.) - An entry with sub_resource matches only calls with that exact sub_resource value - Duplicate detection updated to (service, resource, sub_resource) key Runtime: - Remove blanket sub_resource deny; is_operation_allowed now matches on all four dimensions including the optional sub_resource Tests: - Add operation_allowlist_matches_gmail_sub_resource_shape - Add operation_allowlist_matches_drive_3_segment_shape - Add rejects_operation_with_unlisted_sub_resource - Add google_workspace_allowed_operations_allow_same_resource_different_sub_resource - Add google_workspace_allowed_operations_reject_invalid_sub_resource_characters - Add google_workspace_allowed_operations_deserialize_without_sub_resource - Update all existing tests to use correct gws command shapes Docs: - Spec: correct Gmail examples throughout; remove Sub-Resource Limitation section; update data model, validation rules, example use case, and follow-on work - Config-reference (en, vi, zh-CN): add sub_resource field to allowed_operations table; update Gmail examples to correct 4-segment shapes Platform: - email-assistant SKILL.md: update allowed_operations paths to gmail/users/* shape * fix(google_workspace): add classroom and events to service parameter schema description * fix(google_workspace): cross-validate allowed_operations service against allowed_services When allowed_services is explicitly configured, each allowed_operations entry's service must appear in that list. An entry that can never match at runtime is a misconfigured policy: it looks valid but silently produces a narrower scope than the operator intended. Validation now rejects it with a clear error message. Scope: only applies when allowed_services is non-empty. When it is empty, the tool uses a built-in default list defined in the tool layer; the validator cannot enumerate that list without duplicating the constant, so the cross-check is skipped. Also: - Update allowed_operations field doc-comment from 3-part (service, resource, method) to 4-part (service, resource, sub_resource, method) model - Soften Gmail sub_resource "required" language in config-reference (en, vi, zh-CN) from a validation requirement to a runtime matching requirement — the validator does not and should not hardcode API shape knowledge for individual services - Add tests: rejects operation service not in allowed_services; skips cross-check when allowed_services is empty * fix(google_workspace): cross-validate allowed_operations.service against effective service set When allowed_services is empty the validator was silently skipping the service cross-check, allowing impossible configs like an unlisted service in allowed_operations to pass validation and only fail at runtime. Move DEFAULT_GWS_SERVICES from the tool layer (google_workspace.rs) into schema.rs so the validator can use it unconditionally. When allowed_services is explicitly set, validate against that set; when empty, fall back to DEFAULT_GWS_SERVICES. Remove the now-incorrect "skips cross-check when empty" test and add two replacement tests: one confirming a valid default service passes, one confirming an unknown service is rejected even with empty allowed_services. * fix(google_workspace): update test assertion for new error message wording * docs(google_workspace): fix stale 3-segment gmail example in TDD plan * fix(google_workspace): address adversarial review round 4 findings - Error message for denied operations now includes sub_resource when present, so gmail/users/messages/send and gmail/users/drafts/send produce distinct, debuggable errors. - Audit log now records sub_resource, completing the trail for 4-segment Gmail operations. - Normalize (trim) allowed_services and allowed_operations fields at construction time in new(). Runtime comparisons now use plain equality instead of .trim() on every call, removing the latent defect where a future code path could forget to trim and silently fail to match. - Unify runtime character validation with schema validation: sub_resource and service/resource/method checks now both require lowercase alphanumeric plus underscore and hyphen, matching the validator's character set. - Add positional_cmd_args() test helper and tests verifying 3-segment (Drive) and 4-segment (Gmail) argument ordering. - Add test confirming page_limit without page_all passes validation. - Add test confirming whitespace in config values is normalized at construction, not deferred to comparison time. - Fix spec Runtime Enforcement section to reflect actual code order. * fix(google_workspace): wire production helpers to close test coverage gaps - Remove #[cfg(test)] from positional_cmd_args; execute() now calls the same function the arg-ordering tests exercise, so a drift in the real command-building path is caught by the existing tests. - Extract build_pagination_args(page_all, page_limit) as a production method used by execute(). Replace the brittle page_limit_without_page_all test (which relied on environment-specific execution failure wording) with four direct assertions on build_pagination_args covering all page_all/page_limit combinations. --------- Co-authored-by: argenis de la rosa <theonlyhennygod@gmail.com> |
||
|
|
95bf229225
|
fix(config): enable compact_context by default (#3995)
* fix: change compact_context default to true Local LLMs with limited context windows immediately run out of context when compact_context defaults to false. The system prompt alone can consume 25K+ tokens, exceeding even 55K context windows with history. Setting compact_context=true by default limits system prompt injection to 6000 chars and RAG results to 2 chunks, making the agent usable with smaller models out of the box. Fixes #3987 * docs: update compact_context default to true in config reference Update all locale variants (en, zh-CN, vi) to reflect the new default. * test: update tests to expect compact_context default of true Update assertions in schema.rs unit tests and config_persistence.rs component tests to match the new default value. |
||
|
|
e2f6f20bfb |
feat(agent): add tool_call_dedup_exempt config to bypass within-turn dedup (#2978)
Add `agent.tool_call_dedup_exempt` config key (list of tool names) to allow specific tools to bypass the within-turn identical-signature deduplication check in run_tool_call_loop. This fixes the browser snapshot polling use case where repeated calls with identical arguments are legitimate and should not be suppressed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
77a3b39ff7
|
feat(tools): Use system default browser instead of hard-coded Brave Browser (#1453)
* ci(homebrew): prefer HOMEBREW_UPSTREAM_PR_TOKEN with fallback * ci(homebrew): handle existing upstream remote and main base * feat(tools): Use system default browser instead of hard-coded Brave Browser --------- Co-authored-by: Will Sarg <12886992+willsarg@users.noreply.github.com> |
||
|
|
58ca515f9c |
style(docs/vi): polish Vietnamese translations for natural readability
- Convert all Title Case Vietnamese headings to sentence case (Vietnamese doesn't use Title Case) - Replace calque translations with natural Vietnamese phrasing: "Bảo Mật Agnostic" → "Bảo mật không phụ thuộc nền tảng", "Bảo Mật Không Ma Sát" → "Bảo mật không gây cản trở", "tư thế bảo mật" → "tình trạng bảo mật", "kiềm chế ở cấp độ OS" → "cách ly cấp hệ điều hành" - Standardize terminology: "rõ ràng" → "tường minh" for "explicit" - Shorten verbose phrasing across navigation docs and references - Make prose more direct and developer-friendly throughout 21 files touched, 168 lines changed (wording only, no structural changes) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
79cc1bd30b |
docs(vi): add comprehensive Vietnamese localization under docs/vi/
Full Vietnamese translation of all documentation using directory-per-locale structure (docs/vi/) instead of flat suffixes. Covers 41 docs across all categories: getting-started, reference, operations, security, hardware, datasheets, contributing, and project. Also includes python/README.vi.md. Translation conventions: natural idiomatic Vietnamese for prose; technical terms, CLI commands, config keys, and code blocks kept in English. Supersedes flat-suffix approach from #1092. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |