Skip to content

feat(run): auto-arm the write guard; scope preflight warnings#149

Merged
slowdini merged 1 commit into
devfrom
feat/guard-auto-arm
Jul 17, 2026
Merged

feat(run): auto-arm the write guard; scope preflight warnings#149
slowdini merged 1 commit into
devfrom
feat/guard-auto-arm

Conversation

@slowdini

Copy link
Copy Markdown
Owner

Closes #126.

What changed

Issue #126 asked that every harness enhancement be detected and provided automatically, with warnings naming the limitation wherever a harness lacks one. The preflight already implemented the warn-and-degrade model; this PR closes the remaining gaps:

  • The write guard now arms automatically on guard-capable built-in harnesses whenever staging is active. A new --no-guard flag opts out; --guard remains as the explicit form (it warns where auto-arm quietly stays off — guardless harness, --no-stage — and is still rejected on user-descriptor-only harnesses, since the guard fails open). This replaces the README's "arm --guard unless the user opts out" agent-etiquette with actual default behavior. RunOptions.guard is tri-state (None = auto) and the preflight resolves it; the run plan prints guard: armed … (--no-guard to opt out).
  • The transcript warning is scoped to configs that use it: the transcript_check-unverifiable clause only appears when the loaded evals.json actually declares a transcript_check assertion (resolve now runs before preflight — it is read-only, so nothing is built before preflight can still reject).
  • Missing dispatch recipes now warn: a harness without a [dispatch] exec_template (OpenCode, exec-less BYOH descriptors) gets a preflight warning naming the generic-handoff fallback, via a new has_dispatch_recipes() trait probe.
  • Fixed a latent inconsistency: --guard --no-stage previously kept guard=true through artifact rendering (manifest/runbook carried guard args for an unguarded run); the guard is now resolved before rendering.

Before/after (bare eval-magic run, claude-code)

Before: run is unguarded unless the operator remembered --guard.

After:

Preparing my-skill iteration-1 (new-skill)
  ...
  guard: armed — the write guard blocks out-of-env writes during dispatch (--no-guard to opt out)

🛡 Write guard armed: a PreToolUse hook is staged in .claude/settings.local.json

Bare eval-magic run --harness opencode now messages every limitation:

⚠ --harness opencode declares no write guard — … Pass --no-guard to acknowledge and silence this.
⚠ --harness opencode declares no transcript parser — tokens/duration go unrecorded and …
⚠ --harness opencode declares no dispatch exec recipe — RUNBOOK.md and dispatch-manifest.md carry handoff guidance …

Docs

run --help (--guard/--no-guard/--no-stage/--harness), top-level --help examples, README (quick-start examples, Cost & confirmation, Harnesses fallback paragraph), docs/progressive-enhancements.md, docs/byoh.md, per-harness notes, harnesses/template.toml.

Verification

  • cargo test — 637 tests green (9 new unit tests incl. the full guard decision table; 9 new/renamed integration tests across lifecycle/codex/opencode/byoh/basics)
  • cargo fmt --check, cargo clippy --all-targets -- -D warnings
  • End-to-end drives: bare run auto-arms (plan line + banner + marker/hook in each env); --no-guard installs nothing and silences the warning; --guard --no-guard is a parse error; opencode/BYOH degrade with the warnings above

🤖 Generated with Claude Code

Closes the #126 gaps: supported enhancements are now provided
automatically, and the remaining silent degradations warn.

- The write guard arms automatically on guard-capable built-in
  harnesses whenever staging is active; new --no-guard opts out.
  --guard stays as the explicit form (warns where auto-arm quietly
  stays off; still rejected on user-descriptor-only harnesses).
  RunOptions.guard is now tri-state (None = auto), resolved by the
  preflight, and the run plan prints the armed guard status.
- The no-transcript-parser warning is scoped to eval configs that
  actually use transcript_check (resolve now runs before preflight).
- A harness without a dispatch exec recipe now warns naming the
  generic-handoff fallback (new has_dispatch_recipes probe).
- Docs updated across --help, README, progressive-enhancements, byoh,
  per-harness notes, and the descriptor template.

Verification: cargo test (637 green), cargo fmt --check,
cargo clippy --all-targets -- -D warnings, plus end-to-end drives
(bare run auto-arms; opencode warns guard/transcript/dispatch;
--guard --no-guard conflicts at parse).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@slowdini
slowdini merged commit 892d0ad into dev Jul 17, 2026
6 checks passed
@slowdini
slowdini deleted the feat/guard-auto-arm branch July 17, 2026 03:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Full progressive enhancement for runs

1 participant