feat(permissions): setup autonomy: detect + warn + offer-to-remove overlay attributes that override the intended posture#401
Merged
Conversation
…rlay attributes setup autonomy now detects per-machine settings.local.json attributes that override the intended autonomy posture (platform-aware: macOS intended = sandbox-OFF per #336, else ON), warns loudly naming each override and how it defeats the posture, and offers consent-gated removal via --remove-overrides (whole-file when purely overriding, else attributes-only preserving other keys). Detection reads only the gitignored per-machine overlay; the committed baseline is never opened for write. Removal flows through a consent gate and is deliberately not wired to any blanket --yes (the trust-gesture exemption). Composes with #313's seal: detect runs pre-confinement, removal re-detects post-seal and reports already-reconciled required-attrs rather than double-handling. Distinguishes genuine overrides (remove-to-restore-autonomy) from inert cruft (remove-to-tidy). Surface change (new flag + new principle) -> backbone 1.130.2 -> 1.131.0. Closes #399 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Owner
Author
|
Reviewer agent (local, reviewer): APPROVED
|
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.
What
pkit permissions setup autonomynow detects per-machinesettings.local.jsonattributes that override the intended autonomy posture, warns loudly, and offers consent-gated removal. Generalizes #313 (theautoAllowBashIfSandboxedsplit-brain) from one override to the whole class._intended_sandbox_onreturnsFalseon macOS (intended posture is sandbox-OFF per [Feature] setup autonomy must not enable a macOS-incompatible sandbox (detect platform; warn or skip) #336),Trueelsewhere. Judgesenabledagainst the platform-correct intent (on macOSenabled:falseagrees with intent and is not flagged;enabled:trueis) andallowUnsandboxedCommands:true(un-seals ADR-028) on any platform. Reads only the gitignored overlay — the committed floor is the intended posture, never a finding.✗+ a "how it defeats" line, labelled remove-to-restore-autonomy; inert cruft (e.g. deadexcludedCommandswith the box off) renders with·, labelled remove-to-tidy.--remove-overrides(auto-confirm) or interactiveclick.confirm; deliberately not wired to any blanket--yes(the trust-gesture exemption). Declined / non-interactive → warn-only, file untouched.settings.local.jsononly when nothing of value remains after stripping findings (decided on a deep copy); else strip only the finding keys, leaving every other key byte-faithful.settings.local.json; a dedicated test asserts the committedsettings.jsonis byte-identical before/after.Composition with #313's seal (architect-confirmed)
Order is detect → confinement step (
sandbox_enable(strict)re-asserts #313's seal) → report/remove. Removal re-detects post-seal and removes only what is still a finding — so a required-attr override the seal already reconciled is reported "already reconciled" rather than double-handled. The seal stays the single writer ofallowUnsandboxedCommands(ADR-028 dp-2); #399 defers to it and removes only the slice no primitive owns (cruft everywhere + the macOSenabledinversion). Warn is wide (honesty, all platforms); removal is narrow (only where this feature owns the key). Architect review: no escalation, no reorder needed.Verification
pkit schemas validate(13 pass);migrations check-diff --include-working-tree --base mainclean (pure addition)..claude/settings.local.jsonuntouched (tests usetmp_pathtrees).Version / migration
Backbone (
src/project_kit/permissions.py) —.pkit/VERSION1.130.2 → 1.131.0 (new flag + new principle = surface change per PRJ-002);package.yamlrequires_backboneauto-broadened. No migration (additive).Doc impact
.pkit/cli/README.md— detection/removal behavior +--remove-overrideson thesetup autonomyrow.Follow-up (non-blocking, architect-flagged)
On macOS a
settings.local.jsoncontaining onlysandbox.enabled:trueis whole-file-unlinked rather than routed throughsandbox_disable(the key's owning primitive). Consent-gated, macOS-only, reversible — correct today, but routing the macOSenabledoverride throughsandbox_disablewould keep the "remove via the owning primitive" discipline the seal path follows. Worth a later tidy, not a blocker.Closes #399
🤖 Generated with Claude Code