Guard mode → enabled/disabled + guard.* → failsafe.* (backward-compatible)#6
Open
Tombar wants to merge 30 commits into
Open
Guard mode → enabled/disabled + guard.* → failsafe.* (backward-compatible)#6Tombar wants to merge 30 commits into
Tombar wants to merge 30 commits into
Conversation
This was referenced Jun 10, 2026
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s assert) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ut never used) Found by the doc-validation harness (test/docs/iterm.bats pyflakes check). The iTerm2 toggle registers its RPC off `connection`; `app` was dead code.
… distros
- tmux list-keys: accept C-M-t or M-C-t (older tmux reorders modifiers);
assert the stable toggle-path + #{pane_id} first.
- luacheck: --no-color so ANSI escapes don't split the '0 errors' substring.
- bats --print-output-on-failure for diagnosability.
…ngs REPORT REPORT.md records per-claim PASS/STATIC/LIVE-MANUAL results and the one doc bug the harness caught and fixed (iterm.md unused async_get_app).
…dation demo.sh: guided, narrated walkthrough (failsafe ENABLED/DISABLED framing) to run in a WezTerm window while screen-recording. manual-test-plan.md: 19-check live GUI checklist (WezTerm/iTerm/tmux/statusline) with recording + KeyCastr + troubleshooting notes. Local only — held back from PR #2 pending the read→enable/disable rename.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lves Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fe.* namespace (dual-namespace) - Rewrites 7 mode-gating sites in kubectl/helm/aws/terraform.rego from input.mode == "read" to not input.failsafe_enabled == false, so a missing or undefined field BLOCKS (fail-safe) rather than failing open. - Renames all bundled package declarations guard.bundled.* → failsafe.bundled.* (git, failsafe, kubectl, helm, aws, terraform). - Updates validator to accept both guard.* and failsafe.* namespaces via layerSuffix() helper; .failsafe.rego accepts guard.repo OR failsafe.repo. - Adds TDD security tests in internal/embed/policies_failsafe_test.go proving missing failsafe_enabled → BLOCK (fail-safe property). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fo failsafe Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… legacy guard.user back-compat case - Add failsafe_enabled:true to 27 fact.json files (mode=read) and failsafe_enabled:false to 3 (mode="read & write": 03, 23, 26) so bundled policies' `not input.failsafe_enabled == false` gate correctly allows mutations in read & write mode. - Update corpus 30 expected.json reason_contains from "blocked in read mode" to "blocked while failsafe is enabled" to match the renamed reason string in kubectl.rego. - Rename 5 corpus dirs: lairguard-* -> failsafe-* (25-29). - Add TestLegacyGuardUserPolicy_BlocksWithInputMode to internal/embed/policies_failsafe_test.go: compiles a hand-written package guard.user module with input.mode == "read" gate and proves it fires alongside the bundled failsafe.bundled.* namespace, guaranteeing legacy user policies keep working (dual-namespace back-compat proof). All 30 corpus cases pass; go test ./... green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bled fact (mode legacy) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…an, legacy mode back-compat Update all doc-validation bats assertions from the old read/read-&-write vocabulary to the renamed enabled/disabled canonical values: - helpers.bats: mode-file round-trip uses "disabled" - crosscutting.bats: chain-order writes disabled/enabled; missing-file default is "enabled"; rego meta-test replaced with two assertions — (a) all deny rules use `not input.failsafe_enabled == false` and (b) no rule compares `input.mode ==`; back-compat test asserts `mode get | cut -f1` returns `enabled`/`disabled`; alias round-trip updated to new on/off/rw/ro/sudo/lock vocabulary - statusline.bats: glyph/label assertions → `🔒 enabled` / `🔓 disabled` - wezterm.bats: toggle expects `disabled` (from default enabled); badge grep updated to `(mode == "disabled") and " off " or " on "`; sudo-timeout checks `echo enabled` - tmux.bats: toggle flip expects disabled/enabled; status-script test checks `🔒 on`; no-script toggle expects "disabled" - iterm.bats: read_mode default assertion → "enabled"; toggle flips to "disabled" - extract.bats: status-indicator block check → `🔒 on` - live-gui/demo.sh: status() compares "disabled" (drops the legacy bridge comment) - live-gui/manual-test-plan.md: all expect strings → enabled/disabled, on/off badges - REPORT.md: per-claim table and doc-bugs section updated Also fixes a doc bug in docs/toggle/tmux.md: sudo-timeout prose said `echo read` (stale); corrected to `echo enabled`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
c9caa7a to
4c001ae
Compare
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
Renames the guard-mode vocabulary to describe the guard's state instead of the agent's capability, introduces a boolean policy interface, and modernizes the Rego namespace — all backward-compatible (no existing user policy or script breaks).
read/read & write→enabled/disabled(mode files,FAILSAFE_MODE,mode get, statusline, badges). Default isenabled.input.failsafe_enabled(bool) is the primary interface; bundled policies gate on the fail-safe formnot input.failsafe_enabled == false(a missing/garbled field stays protected, never fail-open).input.modeis retained with legacyread/read & writevalues, so existinginput.mode == "read"policies keep working.guard.*→failsafe.*with dual-namespace back-compat: the engine already evaluates each module at its own declared package, so legacypackage guard.user/guard.repofiles still evaluate; only the advisory validator changed to accept both.mode setaliases:enabled/enable/on/closed/close/lock/ro/r/read/safeanddisabled/disable/off/open/unlock/rw/w/write/sudo.Canonicalizechoke point migrates legacy mode files and maps any unknown/empty value toenabled.serverInfo.name(guard→failsafe), CLI/toggle, audit log, all docs, and the doc-validation harness updated;CHANGELOG.mdadded.Supersedes #2 — this branch contains the doc-validation harness and the rename; close #2 when this merges.
Security invariants (all verified by tests)
not input.failsafe_enabled == falseat all 7 bundled sites; the unsafe!= falseform appears nowhere.failsafe_enabledblocks a mutation (TestFailsafeGate_MissingField_Blocks).Default: "enabled"+Canonicalizeunknown →enabled(no fail-open default).package guard.user+input.mode == "read"still blocks (TestLegacyGuardUserPolicy_BlocksWithInputMode).failsafe_enabled:falsecorpus fixtures (03/23/26) keep correct, non-inverted expectations.normalizeModealias-polarity matrix test.Test Plan
go test ./...— 12/12 packages passfailsafe test ./test/corpus— 30/30 passmake validate-docs— 34/34 (2 known local skips) against the freshly-built binary🤖 Generated with Claude Code