v0.7.0
This release hardens the enforcement layer and closes a consistency gap in how the review gate was documented. It's backward-compatible — no command contract or .forge/ layout changed.
Robustness
- State is now persisted atomically.
lib/state.savewrites a temp file andos.replaces it into place. A torn write was previously read back as corrupt JSON and silently reset to the empty skeleton — dropping recorded passes and the overrides audit trail — and two concurrent tool calls could lose each other's writes. The audit trail is the whole point of the override mechanism, so it must never vanish silently. - Gates check freshness before consuming an override.
require_check,require_review,require_audit, andrequire_plannow confirm the gate is actually unsatisfied before taking a one-shot override — so a green/satisfied action never burns (or falsely logs) a bypass that wasn't needed. require_planonly treats a plan with unchecked items as active. A completed plan (every item ticked) or an empty file no longer holds the gate open, so finishing a plan correctly re-demands a new one before more source is written.auto_formatis scoped to forge-enabled projects, like every other hook — no more silentruffruns on.pyedits in unrelated repos.require_reviewdecodes git's C-quoted paths (octal-escaped non-ASCII / special filenames) before matching them against reference globs, so the reference half of the gate no longer misses a governed file with such a name.
Added
bin/plan.py active <path>(backed bylib/state.set_active_plan) —/forge:planrecords the active plan through a helper instead of hand-editingstate.json, where a malformed write would corrupt workflow state. This was the last state mutation without a dedicated entrypoint.
Documentation
- Propagated the review gate into every place it had drifted from:
/forge:status, the scaffoldedCLAUDE.mdtemplate,/forge:init's loop string, and the README loop diagram — and qualified the README's auto-format claim to match its new forge-scoped behaviour. doc-gap-scannerno longer assumes the plugin's own layout;src/**is the universal case and plugin-only kinds are optional.
Quality
Coverage of lib/ rises to 94% (gate runner 90% → 99%): added unit tests for the subprocess timeout and full/fast gate aggregation, atomic-write failure cleanup, the override-not-consumed-when-satisfied path across all four gates, git C-path unquoting, and the completed-plan case. 258 tests, green across Python 3.10–3.13.
Full changelog: v0.6.0...v0.7.0