Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ zo gates set MODE --project NAME

`MODE` is one of: `supervised` (human approves every gate), `auto` (orchestrator approves unless ambiguous), `full-auto` (all gates auto-approved).

### zo status (control plane)

When a project has a `plan-ledger.json` (v2 WS-B — generated automatically at
plan decompose), `zo status` renders progress from it first: per-phase status,
oracle-owned pass counts, attempts, and last failure. The ledger is the
machine-readable truth; STATE.md remains the human-readable projection and
the fallback for legacy projects.

### zo gates approve / reject

Record a nonce-verified human decision on the pending blocking gate (v2
Expand Down
12 changes: 12 additions & 0 deletions memory/zo-platform/DECISION_LOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1265,3 +1265,15 @@ The `--no-headlines` flag is preserved (not removed) for backwards compatibility
**Honest caveats:** PostToolUseFailure did not fire for nonzero-exit Bash commands in this session — its semantics appear limited to tool-infrastructure errors, so the failure feed will capture fewer events than designed; if nonzero-exit capture matters, add PostToolUse-with-error-inspection in WS-D. PreCompact/SessionEnd not yet observed live (no compaction occurred; SessionEnd fires at session close) — same wiring pattern as the three proven events. A full `zo build` demo run remains desirable on a machine with the claude CLI (this Desktop-managed Mac has none — see PR-046).

**Outcome:** 904 → 908 tests (3 trace + 1 live-payload drift-guard), ruff clean. Fail-open verified end to end in production conditions. Evidence committed to PR #107.

## Decision: 2026-08-12T17:00:00Z
**Type:** FEATURE + ARCHITECTURE
**Title:** v2 Phase 2 (WS-B control plane) — plan ledger with oracle-owned pass flags, story sizing lint, ledger-first status

**Decision:** Implemented WS-B per plans/zo-v2-rearchitecture.md Phase 2. (1) `src/zo/ledger.py`: `plan-ledger.json` in the project memory root — one entry per (phase, subtask) with synthesized acceptance criteria (artifact existence for all phases; oracle threshold for phase_4), verification descriptor, `passes`, attempts, last_failure, plus a phase_status map. Regeneration is merge-preserving (progress survives re-decompose); every write atomic. (2) Oracle-owned flips: `mark_phase_passed` is called ONLY from the two verified-completion paths (automated gate after artifact/experiment checks, nonce-verified human PROCEED); ITERATE/loop-CONTINUE reset entries with the reason; `mark_subtask_complete` counts attempts but cannot set passes; the ledger file joined `_SEALED_DEFAULTS`, so builder Write/Edit is denied by the existing WS-A4 hook. (3) Sizing lint: optional `## Stories` plan section (StorySpec parser) + `validate_plan` rule — every declared story needs ≥1 machine-verifiable criterion (threshold/path/`command`); surfaces through preflight and `zo validate` for free; legacy plans without Stories are untouched. (4) `zo status` renders a control-plane table from the ledger (per-phase status, pass counts, attempts, last failure) with STATE.md as fallback/projection.

**Also fixed (recon findings on Phase 1):** `contracts.set_active_phase` was non-atomic (torn read = enforcement silently off) — now temp+rename; the wrapper never exported hook env for delivery sessions — `zo build` now passes ZO_MEMORY_ROOT/ZO_DELIVERY_ROOT/ZO_CONTRACTS_PATH via extra_env, closing the per-project sealing gap.

**Scope deferrals (deliberate, to Phase 3):** `evaluate_loop_state` keeps its ExperimentRegistry input (already oracle-derived; signature change touches ~20 test call sites and belongs to the fresh-context loop rework); session-state restore still reads STATE.md (cutover rides the fresh-context substrate to avoid regressing the PR-036 GATED-precedence resume fix).

**Outcome:** 908 → 929 passed / 7 skipped (+21: 13 ledger, 5 stories/lint, 2 nonce-flip, 1 status), ruff clean, validate-docs green. Oracle checks 8-10 have passing seeded tests: status renders from the ledger; builder ledger-write denied while the oracle flip lands; vague story rejected. Cascade: specs/plan.md (§10 Stories + lint), specs/workflow.md (state-tracking line), docs/COMMANDS.md (status control plane). Branch `claude/v2-phase2-control-plane`.
2 changes: 1 addition & 1 deletion memory/zo-platform/STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ status: complete

## Current Position

**Session 040 (current) — pick up here.** Research + decision session: deep-dive review of three agent-orchestration repos (oh-my-claudecode, ruflo, ralph — cloned to `~/Documents/code/`) to inform the ZO v2 rearchitecture. 9-agent workflow (7 source-reading lenses + ZO baseline + adversarial synthesis, ~1.06M tokens) catalogued **63 features**, distilled to **12 ranked adoptions** + 6 rearchitecture themes + 11 anti-patterns; all findings persisted to `memory/zo-platform/research/2026-08-12-repo-reviews/` (per-repo markdown + `raw-findings.json`). **Sam decided: adopt all 12.** Work organized into **five layer-based workstreams** (A enforcement plane, B control plane, C execution substrate, D self-learning/platform oracle, E operator experience) — NOT source-repo categories, because features from different repos interlock into single mechanisms. Shipped this session: `plans/zo-v2-rearchitecture.md` (full plan: 6 gated phases, 20-check oracle, anti-scope; + `.gitignore` exception), `docs/reference/v2-rearchitecture.mdx` (all 12 features w/ provenance + repo links; added to mint.json Reference nav), `docs/roadmap.mdx` v2 section (4 pillars + repo credits), website §11 "What's next" (new section w/ 3 repo credit cards; quick start renumbered §12; drawer nav updated). **Verification caveat: no Node.js on this machine** — Astro build NOT run; website change verified via HTML-parser balance check + static-server DOM inspection (section text, all 4 links, drawer entry, renumbering all confirmed rendered). CI/deploy build must confirm. **Same session, part 2 — v2 Phase 1 (WS-A enforcement plane) SHIPPED** on branch `claude/v2-phase1-enforcement` (stacked on the plan branch, PR #106): (A1) `src/zo/contracts.py` — contracts.json emitted at decompose into memory_root (gate_mode precedent), `contract_produced` upgraded from prose placeholders to concrete paths (ownership ∩ required_artifacts, ownership-dir fallback), SubagentStop hook validates deliverables (missing/undersized/pattern/empty-dir) and blocks with a violation list; (A2) drift-guard Stop hook — completion-claim regex over the last assistant transcript message + added TODO/FIXME/NotImplementedError lines in `git diff HEAD` → block (env kill-switch `ZO_DRIFT_GUARD=0`); (A3) PreCompact (STATE flush + checkpoint decision), SessionEnd (summary backfill), PostToolUseFailure (`logs/comms/failures-{date}.jsonl` feed) — specs/memory.md recovery section updated to match (replaces the never-built periodic postToolUse checkpoint design); (A4) sealed-paths PreToolUse guard — memory-root control files (gate_mode/gate_nonce/gate_decision/contracts.json/sealed_paths) + user `sealed_paths` prefixes denied, off-limits write-scope enforced per contracts.json when agent identity present in hook input (plan check 6 AMENDED: no disallowedTools frontmatter exists for subagents and verifiers need scoped writes — path-scoped enforcement instead, fail-open without identity); (A5) nonce gates — minted at GATED (`secrets.token_hex(8)` → `gate_nonce` file), surfaced in `prepare_gate_review`, `apply_human_decision` raises PermissionError without it (single-use, cleared on terminal decisions), new `zo gates approve/reject --nonce` CLI writes DECISION_LOG + comms + `gate_decision` file consumed on next decompose, `/approve`+`/reject` slash commands rewritten to route through the CLI (forgeable hand-edit path CLOSED). All via one shim (`.claude/hooks/zo-hookkit.sh` → `python3 -m zo.hookkit`, venv-preferring, fail-open) + 6 new settings.json wirings. **First-ever hook-script tests** (subprocess + stdin JSON pattern). **854 → 904 passed / 7 skipped, ruff `src/` clean, validate-docs green.** 4 pre-existing integration tests updated to pass the nonce (designed behaviour change). Plan oracle checks 1-5 + 7 have passing seeded-failure tests; check 6 as amended. **Part 3 — live pre-PR verification (Sam-directed):** added always-on hook-trace observability (`logs/hook-trace-{date}.jsonl`, `ZO_HOOK_TRACE=0` off-switch) and verified in the live session itself: sealed-paths DENIED a real Write to gate_mode; drift-guard fired correctly-silent on a real Stop; subagent-stop fired with `agent_type`+`agent_id` in the live payload — **agent-identity open question RESOLVED** (per-agent enforcement keys correctly). Drift-guard now prefers the live payload's `last_assistant_message` (transcript parse = fallback). Caveats logged: PostToolUseFailure doesn't fire on nonzero-exit Bash (infrastructure errors only); PreCompact/SessionEnd not yet observed live; full `zo build` demo needs a machine with the claude CLI (this Mac has none — PR-046). **908 passed / 7 skipped, ruff clean.** **Next:** Phase 1 gate review → then WS-B control plane (plan-ledger.json) per `plans/zo-v2-rearchitecture.md`; prior Batch D/E + Tier-1 items queue behind v2.
**Session 040 (current) — pick up here.** Research + decision session: deep-dive review of three agent-orchestration repos (oh-my-claudecode, ruflo, ralph — cloned to `~/Documents/code/`) to inform the ZO v2 rearchitecture. 9-agent workflow (7 source-reading lenses + ZO baseline + adversarial synthesis, ~1.06M tokens) catalogued **63 features**, distilled to **12 ranked adoptions** + 6 rearchitecture themes + 11 anti-patterns; all findings persisted to `memory/zo-platform/research/2026-08-12-repo-reviews/` (per-repo markdown + `raw-findings.json`). **Sam decided: adopt all 12.** Work organized into **five layer-based workstreams** (A enforcement plane, B control plane, C execution substrate, D self-learning/platform oracle, E operator experience) — NOT source-repo categories, because features from different repos interlock into single mechanisms. Shipped this session: `plans/zo-v2-rearchitecture.md` (full plan: 6 gated phases, 20-check oracle, anti-scope; + `.gitignore` exception), `docs/reference/v2-rearchitecture.mdx` (all 12 features w/ provenance + repo links; added to mint.json Reference nav), `docs/roadmap.mdx` v2 section (4 pillars + repo credits), website §11 "What's next" (new section w/ 3 repo credit cards; quick start renumbered §12; drawer nav updated). **Verification caveat: no Node.js on this machine** — Astro build NOT run; website change verified via HTML-parser balance check + static-server DOM inspection (section text, all 4 links, drawer entry, renumbering all confirmed rendered). CI/deploy build must confirm. **Same session, part 2 — v2 Phase 1 (WS-A enforcement plane) SHIPPED** on branch `claude/v2-phase1-enforcement` (stacked on the plan branch, PR #106): (A1) `src/zo/contracts.py` — contracts.json emitted at decompose into memory_root (gate_mode precedent), `contract_produced` upgraded from prose placeholders to concrete paths (ownership ∩ required_artifacts, ownership-dir fallback), SubagentStop hook validates deliverables (missing/undersized/pattern/empty-dir) and blocks with a violation list; (A2) drift-guard Stop hook — completion-claim regex over the last assistant transcript message + added TODO/FIXME/NotImplementedError lines in `git diff HEAD` → block (env kill-switch `ZO_DRIFT_GUARD=0`); (A3) PreCompact (STATE flush + checkpoint decision), SessionEnd (summary backfill), PostToolUseFailure (`logs/comms/failures-{date}.jsonl` feed) — specs/memory.md recovery section updated to match (replaces the never-built periodic postToolUse checkpoint design); (A4) sealed-paths PreToolUse guard — memory-root control files (gate_mode/gate_nonce/gate_decision/contracts.json/sealed_paths) + user `sealed_paths` prefixes denied, off-limits write-scope enforced per contracts.json when agent identity present in hook input (plan check 6 AMENDED: no disallowedTools frontmatter exists for subagents and verifiers need scoped writes — path-scoped enforcement instead, fail-open without identity); (A5) nonce gates — minted at GATED (`secrets.token_hex(8)` → `gate_nonce` file), surfaced in `prepare_gate_review`, `apply_human_decision` raises PermissionError without it (single-use, cleared on terminal decisions), new `zo gates approve/reject --nonce` CLI writes DECISION_LOG + comms + `gate_decision` file consumed on next decompose, `/approve`+`/reject` slash commands rewritten to route through the CLI (forgeable hand-edit path CLOSED). All via one shim (`.claude/hooks/zo-hookkit.sh` → `python3 -m zo.hookkit`, venv-preferring, fail-open) + 6 new settings.json wirings. **First-ever hook-script tests** (subprocess + stdin JSON pattern). **854 → 904 passed / 7 skipped, ruff `src/` clean, validate-docs green.** 4 pre-existing integration tests updated to pass the nonce (designed behaviour change). Plan oracle checks 1-5 + 7 have passing seeded-failure tests; check 6 as amended. **Part 3 — live pre-PR verification (Sam-directed):** added always-on hook-trace observability (`logs/hook-trace-{date}.jsonl`, `ZO_HOOK_TRACE=0` off-switch) and verified in the live session itself: sealed-paths DENIED a real Write to gate_mode; drift-guard fired correctly-silent on a real Stop; subagent-stop fired with `agent_type`+`agent_id` in the live payload — **agent-identity open question RESOLVED** (per-agent enforcement keys correctly). Drift-guard now prefers the live payload's `last_assistant_message` (transcript parse = fallback). Caveats logged: PostToolUseFailure doesn't fire on nonzero-exit Bash (infrastructure errors only); PreCompact/SessionEnd not yet observed live; full `zo build` demo needs a machine with the claude CLI (this Mac has none — PR-046). **908 passed / 7 skipped, ruff clean.** **Part 4 — Phases merged + Phase 2 (WS-B control plane) SHIPPED:** #106 + #107 merged to main (stack conflict resolved by merging main into the branch, branch side kept — main had nothing unique). Then WS-B on `claude/v2-phase2-control-plane`: `src/zo/ledger.py` (plan-ledger.json: per-subtask entries w/ synthesized criteria, merge-preserving regeneration, atomic writes, phase_status map); oracle-owned flips wired at the two verified-completion sites (automated gate + nonce-verified human PROCEED), resets on ITERATE/loop-CONTINUE, attempts on mark_subtask_complete, ledger sealed via `_SEALED_DEFAULTS`; `## Stories` plan section + sizing lint in validate_plan (fires only when stories declared — legacy plans untouched); `zo status` renders the control-plane table from the ledger (STATE.md = fallback/projection). Phase-1 hardenings from recon: `contracts.set_active_phase` now atomic; `zo build` exports ZO_MEMORY_ROOT/ZO_DELIVERY_ROOT/ZO_CONTRACTS_PATH so per-project sealing works in delivery sessions. Deferred to Phase 3 (documented): evaluate_loop_state ledger input, session-restore cutover (PR-036 precedence). **929 passed / 7 skipped, ruff clean, validate-docs green. Oracle checks 8-10 seeded tests pass.** **Next:** Phase 2 PR review/merge → Phase 3 (WS-C: watchdog, then fresh-context loop — demo validation needs the Linux box w/ claude CLI, PR-046).

**Session 039 (prior).** Test-only change making the CLI command-set test plugin-tolerant: `tests/unit/test_cli.py::TestCliGroup::test_cli_group_has_all_commands` asserted strict equality on `cli.commands`, which contradicts the extension points ZO itself shipped in PR #99 — any downstream build installing a `zo.commands` entry-point plugin (the documented mechanism in `zo.extensions.load_cli_plugins`) adds commands and turned the core suite red in that environment, despite zero core changes. Changed `assert expected == actual` → `assert expected <= actual` with an explanatory comment. Trade-off accepted: equality also caught *core* commands added without updating the test; subset still catches removals, and additions have always required updating this test's `expected` set anyway. Surfaced by the first real downstream plugin registering a new command group. No code, version, agents, or docs touched — single-assertion diff (+ memory). **854 passed / 7 skipped on Python 3.11 AND 3.12, ruff `src/` clean, validate-docs 0 failures.** **Next:** unchanged — Batch **D** / **E**, standing Tier-1 (caveman, onboarding).

Expand Down
39 changes: 32 additions & 7 deletions memory/zo-platform/sessions/session-040-2026-08-12.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,35 @@ Sam said go — WS-A shipped on `claude/v2-phase1-enforcement` (stacked):
- 854 → 904 tests passed / 7 skipped; ruff clean; validate-docs green;
first-ever hook-script tests (subprocess + stdin JSON)

## Next session

Phase 1 gate review with Sam, then WS-B control plane (plan-ledger.json,
oracle-owned pass flags, sizing lint) per plans/zo-v2-rearchitecture.md
Phase 2. Watchdog (WS-C) after that. Note for Phase 6 e2e: confirm Claude
Code's SubagentStop/PreToolUse hook payloads carry agent identity in live
team sessions (enforcement is fail-open without it).
## Live verification + merges + Phase 2 (same session, parts 3-4)

- Live pre-PR verification (Sam-directed): hook-trace observability
added; sealed-paths DENIED a real Write, drift-guard fired silent on a
real Stop, subagent-stop payload carries agent_type+agent_id (identity
question RESOLVED). PR-046: this Mac has no claude CLI/uv/npm.
- #106 (plan+docs+website) MERGED. #107 (Phase 1) MERGED after resolving
a stack conflict (merged main in, kept branch side).
- Phase 2 / WS-B SHIPPED as PR #108 (targets main, full CI GREEN):
src/zo/ledger.py, oracle-owned flips at the two verified-completion
sites, ledger sealed, `## Stories` + sizing lint, ledger-first
`zo status`; Phase-1 hardenings (atomic set_active_phase, hook env
exported by zo build). 929 passed / 7 skipped.

## Next session — pick up here

1. Confirm #108 merged (Phase 2 gate). If not, merge it (CI is green).
2. Start Phase 3 = WS-C on a fresh branch off main:
`claude/v2-phase3-substrate`. Watchdog FIRST (heartbeat JSON per
agent, external checker in LifecycleWrapper poll loop, never-block
taxonomy: context-limit/rate-limit/auth/user-abort, bounded nudges,
rate-limit wait-and-resume, PID+start-time identity) — oracle checks
11-12, buildable/testable on this Mac. THEN the fresh-context loop
for ML Phase 4 (experiment_loop.py spawns fresh builder per iteration
from ledger+lineage+priors digest) — its go/no-go check 13 needs the
Linux box with the claude CLI (PR-046).
3. Deferred-into-Phase-3 items: evaluate_loop_state ledger input;
session-restore cutover from STATE.md to ledger (keep PR-036 GATED
precedence). PostToolUseFailure only catches infra errors → WS-D.
4. Playbook that worked: recon swarm (4-7 read-only mappers w/ exact
file:line integration points) → build → seeded-failure test per
mechanism + wiring test → memory protocol → commit → PR.
27 changes: 27 additions & 0 deletions specs/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,33 @@ These sections are included based on project needs.

Milestones are informational. Agents do not skip work to meet deadlines. If a milestone is missed, the orchestrator logs the delay and notifies the human.

### 10. Stories (optional, v2 WS-B)

An optional `## Stories` section declares explicit user stories with per-story
acceptance criteria. Each `### <title>` sub-heading is one story; bullets under
an `**Acceptance criteria:**` label become its criteria:

```markdown
## Stories

### Load and validate the dataset

**Acceptance criteria:**
- `pytest tests/test_ingest.py` passes with exit code 0
- data/processed/clean.csv exists
```

**Sizing lint (ralph's "Number One Rule"):** when stories are declared, every
story must carry at least one *machine-verifiable* acceptance criterion — a
threshold comparison (`RMSE <= 0.05`), an artifact path, or a backticked
runnable command. `validate_plan` rejects vague criteria ("works well") as an
error, which also fails `zo preflight` and `zo validate`. Plans without a
Stories section are unaffected. Story sizing guidance: each story should be
completable in a single agent context window.

Parsed stories feed `plan-ledger.json` (the machine-readable progress ledger
whose `passes` flags only the oracle-verified gate paths may flip).

### 10. Delivery Specification

```markdown
Expand Down
Loading
Loading