feat(permissions): add Goose tool-permissions adapter (permission.yaml)#1957
Open
dyoshikawa wants to merge 2 commits into
Open
feat(permissions): add Goose tool-permissions adapter (permission.yaml)#1957dyoshikawa wants to merge 2 commits into
dyoshikawa wants to merge 2 commits into
Conversation
Block Goose persists per-tool permission overrides in the global
~/.config/goose/permission.yaml, a YAML map of mode key -> PermissionConfig
{ always_allow, ask_before, never_allow } where each field is a list of tool
names. rulesync writes user-set decisions under the `user` key.
- Add GoosePermissions adapter (global-scope only; mirrors the Rovodev adapter)
mapping canonical allow/ask/deny onto always_allow/ask_before/never_allow.
Tool-name mapping: bash -> developer__shell, edit/write ->
developer__text_editor; other categories pass through verbatim. Goose lists
hold whole tool names, so only a category's catch-all `*` is representable;
non-catch-all patterns are warned and skipped. The smart_approve LLM cache
and other top-level keys are preserved; the file is never deleted.
- Register `goose` in permissions-processor (tool target tuple + factory map,
supportsProject: false, supportsGlobal: true, supportsImport: true).
- Add GOOSE_PERMISSIONS_FILE_NAME constant.
- Update README and docs Tool x Feature matrix, file-formats.md, and the
rulesync-feature-research goose.md reference; keep docs/<->skills/ in sync.
- Add unit tests (round-trip allow/ask/deny, global-only enforcement, merge)
and a global-mode e2e permissions case.
Closes #1922
Review nit: the file-formats note said the conflicting edit/write catch-all
resolves with 'the later value wins', implying source-order dependence, but the
implementation is deterministic — edit always takes precedence. Match the
adjacent Rovo Dev wording ('edit takes precedence').
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
permissionstarget for Block Goose (codename goose), closing the parity gap tracked in #1922. rulesync now generates Goose's per-tool permission overrides under the global~/.config/goose/permission.yaml.Closes #1922 — #1922
Confirmed
permission.yamlschema (primary source)Verified from the Goose source
crates/goose/src/config/permission.rs:So
permission.yamlis a YAML map of mode key →PermissionConfig, where eachPermissionConfighas threeVec<String>(lists of tool names):always_allow/ask_before/never_allow. User-set decisions live under the top-leveluserkey (other keys such assmart_approvehold the LLM-decision cache).What changed
src/features/permissions/goose-permissions.ts(GoosePermissions), global-scope only (mirrors the Rovodev adapter). Mapping:allow→always_allow,ask→ask_before,deny→never_allow.bash→developer__shell,edit/write→developer__text_editor; any other category passes through verbatim.writecollapses ontodeveloper__text_editor, so a conflictingedit/writecatch-all is reported andeditwins.*is representable; non-catch-all patterns are warned and skipped.userblock is owned by rulesync; thesmart_approvecache and every other top-level key are preserved; the file is never deleted.gooseinpermissions-processor.ts(tool-target tuple + factory map,supportsProject: false,supportsGlobal: true,supportsImport: true).GOOSE_PERMISSIONS_FILE_NAMEtosrc/constants/goose-paths.ts.gitignore-entries.ts: noted that Goose permissions are global-only (no project-level entry);pnpm dev gitignoreconfirms no.gitignorechange.docs/reference/supported-tools.mdmatrix (Goose permissions → 🌏), a Goose paragraph indocs/reference/file-formats.md, and refreshed the stale permissions row in.rulesync/skills/rulesync-feature-research/references/goose.md.docs/↔skills/rulesync/kept in sync.goose-permissions.test.ts) covering round-trip allow/ask/deny ↔ always_allow/ask_before/never_allow, global path, global-only enforcement, non-catch-all skip, edit/write conflict, and non-destructive merge; updatedpermissions-processor.test.tsglobal-targets expectation; added a global-mode e2e case ine2e-permissions.spec.ts.Verification
pnpm cicheckpasses (code + content): fmt, oxlint, typecheck, 6813 unit tests, sync-skill-docs, cspell, secretlint. The fulle2e-permissions.spec.ts(42 tests) passes including the new Goose global case.🤖 Generated with Claude Code