feat(enforcement): v2 Phase 1 — WS-A enforcement plane - #107
Merged
Conversation
Adopt all 12 features synthesized from full-source reviews of oh-my-claudecode (yeachan-heo), ruflo (ruvnet), and ralph (snarktank), organized into five layer-based workstreams across six gated phases. - plans/zo-v2-rearchitecture.md: 20-check tiered oracle, anti-scope, reference repo links (+ .gitignore exception) - docs/reference/v2-rearchitecture.mdx: full feature table w/ provenance - docs/roadmap.mdx: v2 section (4 pillars + repo credits) - website: new §11 'What's next' crediting the three source repos - memory: STATE session 040, DECISION_LOG v2 decision, research corpus at memory/zo-platform/research/2026-08-12-repo-reviews/ Website change verified via HTML balance check + static-server DOM inspection; Astro build deferred to CI (no Node.js on this machine). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ift guard, memory hooks, sealed paths, nonce gates) Implements all five WS-A features from plans/zo-v2-rearchitecture.md: - contracts.json emitted at decompose (src/zo/contracts.py) with concrete deliverable paths; SubagentStop hook blocks agents stopping with unmet deliverables (missing/undersized/pattern/empty-dir checks) - workflow-drift-guard Stop hook: completion claim in last message + added TODO/FIXME/NotImplementedError diff lines -> block (ZO_DRIFT_GUARD=0 opt-out) - PreCompact/SessionEnd/PostToolUseFailure hooks mechanize the memory protocol (STATE flush, summary backfill, structured failure JSONL feed) - sealed-paths PreToolUse guard: memory-root control files + user prefixes denied; per-agent off-limits write scopes enforced from contracts.json - nonce-verified gates end to end: minted at GATED, required by apply_human_decision (PermissionError otherwise, single-use), new 'zo gates approve/reject --nonce' CLI, /approve+/reject slash commands rewritten to route through it (forgeable hand-edit path closed) One shim (.claude/hooks/zo-hookkit.sh -> python3 -m zo.hookkit) routes all six hook events; every handler fail-open. Plan check 6 amended to path-scoped verifier enforcement (no disallowedTools frontmatter exists; rationale in DECISION_LOG). Tests: 854 -> 904 passed / 7 skipped (+50, incl. the repo's first hook-script tests: subprocess + stdin JSON). ruff src/ clean. validate-docs green. Seeded-failure tests cover plan oracle checks 1-5, 7. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Deploying zero-operators with
|
| Latest commit: |
3305661
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://c08a91d1.zero-operators.pages.dev |
| Branch Preview URL: | https://claude-v2-phase1-enforcement.zero-operators.pages.dev |
…on evidence
- zo.hookkit: one JSONL trace line per hook invocation (event, stdin keys,
agent identity, emitted-output flag) to logs/hook-trace-{date}.jsonl;
ZO_HOOK_TRACE=0 disables. This is how the enforcement plane's firing is
observable in live sessions (handlers are silent unless they block).
- drift-guard: prefer the live Stop payload's last_assistant_message
(verified present in the 2026-08-12 live trace); transcript parse kept
as fallback.
- Live verification evidence (DECISION_LOG 15:30 entry): sealed-paths
DENIED a real Write to gate_mode in a live session; drift-guard fired
correctly-silent on a real Stop; subagent-stop fired with agent_type +
agent_id in the live payload — resolves the Phase-1 agent-identity
question (per-agent contract enforcement keys correctly).
- PR-046 prior: this Desktop-managed Mac has no claude CLI/uv/npm; hook
shims must run on bare python3 (venv fallback is load-bearing).
Tests: 904 -> 908 passed / 7 skipped. ruff src/ clean. validate-docs green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
|
Live pre-merge verification added (latest commit): the enforcement plane was verified firing in a real Claude Code session, not just under pytest. From
Caveats recorded in DECISION_LOG: PostToolUseFailure fires on tool-infrastructure errors only (not nonzero-exit commands); PreCompact/SessionEnd not yet observed live; a full 🤖 Generated with Claude Code |
…de kept for all stacked-file conflicts Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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
First build phase of the v2 rearchitecture (stacked on #106). Implements the full WS-A enforcement plane — the deterministic hook layer beneath the prompt plane — per
plans/zo-v2-rearchitecture.mdPhase 1:contracts.jsonemitted at decompose with concrete paths (ownership ∩ required_artifacts); SubagentStop hook blocks agents stopping with unmet deliverablesZO_DRIFT_GUARD=0opt-out)apply_human_decision(single-use); newzo gates approve/reject --nonce;/approve+/rejectrewritten to route through the CLI — the forgeable hand-edit path is closedAll six hook events route through one fail-open shim (
.claude/hooks/zo-hookkit.sh→python3 -m zo.hookkit), so file mutation reuses MemoryManager's atomic/flock paths.Plan amendment
Check 6 amended from "disallowedTools" to path-scoped verifier enforcement: Claude Code has no disallowedTools frontmatter for subagents, and verifiers need scoped writes (oracle-qa owns
oracle/reports/). Enforcement keys on agent identity in the hook payload, fail-open without it — flagged for live confirmation in Phase 6 e2e. Full rationale in DECISION_LOG.Verification
src/clean · validate-docs green🤖 Generated with Claude Code