{"type":"meta","slug":"harness-v2-phase3","base_branch":"origin/main","gate0_mode":"strict","preset":"codex","land_mode":"merge-to-main"}
{"type":"goal","text":"Add a durable linear harness v2 plan queue with restart-safe local-time run windows and honest queue visibility in CLI, TUI, and Overdeck."}
{"type":"methodology","text":"Implement contract-first in dependency waves; keep queue state in one atomic JSONL file; use one-shot systemd workers only; derive advancement from durable run journal and supervision receipts; use TDD; fail closed on corruption or ambiguous ownership; commit only each task's declared files."}
{"type":"intent","text":"Let the owner enqueue dependent plans, constrain launches to configured hours, and leave the chain unattended without a daemon, lost work, duplicate launches, or hidden queue state."}
{"type":"direction","verbatim":"no monolithic daemon, systemd units/timers + short idempotent scripts, state on disk"}
{"type":"direction","verbatim":"v1 code bodies are NEVER ported, only behavior re-specced"}
{"type":"direction","verbatim":"fail-closed"}
{"type":"direction","verbatim":"v2's own land step pushes main directly and the repo guard rejects it — the run's work stays on plan/harness-v2-phase3--integration and is landed via ship.sh afterwards; tasks must NOT try to push main."}
{"type":"anchor","path":"docs/specs/2026-07-29-harness-v2-parity-design.md","what":"spec"}
{"type":"anchor","path":"docs/plans/2026-07-30-harness-v2-phase3.md","what":"plan"}
{"type":"task","id":"t1","wave":1,"seat":"coder","tier":"medium","desc":"Read docs/plans/2026-07-30-harness-v2-phase3.md Task 1 (Durable Queue Store and Run-Window Projection) for the full contract. Persist ordered queue state atomically, enforce legal transitions and failure stops, recover only provably stale locks, and evaluate named or explicit IANA-time-zone windows under a fake clock. Acceptance: node --test modules/harness/v2/test/queue.test.js. Commit only: modules/harness/v2/queue.js, modules/harness/v2/test/queue.test.js.","requires_decision":null,"verify":["node --test modules/harness/v2/test/queue.test.js"],"acceptance":["node --test modules/harness/v2/test/queue.test.js"]}
{"type":"task","id":"t2","wave":1,"seat":"coder","tier":"medium","desc":"Read docs/plans/2026-07-30-harness-v2-phase3.md Task 2 (Stateless Queue systemd Service and Timer) for the full contract. Define a persistent timer and one-shot service where each invocation performs at most one queue transition and exits with no daemon or unit-owned mutable state. Acceptance: node --test modules/harness/v2/test/systemd-phase3.test.js. Commit only: modules/harness/systemd/harness-queue.service, modules/harness/systemd/harness-queue.timer, modules/harness/v2/test/systemd-phase3.test.js.","requires_decision":null,"verify":["node --test modules/harness/v2/test/systemd-phase3.test.js"],"acceptance":["node --test modules/harness/v2/test/systemd-phase3.test.js"]}
{"type":"task","id":"t3","wave":2,"seat":"coder","tier":"medium","desc":"Read docs/plans/2026-07-30-harness-v2-phase3.md Task 3 (Queue CLI and Idempotent Worker) for the full contract. Add queue add/list/start/skip/rm, launch one eligible entry through existing supervision, stop durably on failure, retry only after explicit start, journal window bypasses, and close every crash gap without duplicate live runs. Acceptance: node --test modules/harness/v2/test/queue-worker.test.js. Commit only: modules/harness/v2/bin/runplan.js, modules/harness/v2/bin/queue-worker.js, modules/harness/spec/events.schema.json, modules/harness/v2/test/queue-worker.test.js.","requires_decision":null,"verify":["node --test modules/harness/v2/test/queue-worker.test.js"],"acceptance":["node --test modules/harness/v2/test/queue-worker.test.js"]}
{"type":"task","id":"t4","wave":2,"seat":"coder","tier":"medium","desc":"Read docs/plans/2026-07-30-harness-v2-phase3.md Task 4 (Queue Read API) for the full contract. Add authenticated read-only GET /queue with ordered camelCase projection, explicit null optionals, no internal identities, and non-200 failure on corrupt state. Acceptance: node --test --test-name-pattern='queue' modules/harness/v2/test/control-api.test.js. Commit only: modules/harness/v2/control-api.js, modules/harness/v2/test/control-api.test.js.","requires_decision":null,"verify":["node --test --test-name-pattern='queue' modules/harness/v2/test/control-api.test.js"],"acceptance":["node --test --test-name-pattern='queue' modules/harness/v2/test/control-api.test.js"]}
{"type":"task","id":"t5","wave":3,"seat":"coder","tier":"medium","desc":"Read docs/plans/2026-07-30-harness-v2-phase3.md Task 5 (Collector Queue Projection) for the full contract. Poll and validate GET /queue as mandatory plans state, retain prior state on failure, and project ordered queue entries losslessly without fabricated run fields. Acceptance: bun test collector/src/adapters/harness.test.ts. Commit only: collector/src/adapters/harness.ts, collector/src/adapters/harness.test.ts.","requires_decision":null,"verify":["bun test collector/src/adapters/harness.test.ts"],"acceptance":["bun test collector/src/adapters/harness.test.ts"]}
{"type":"task","id":"t6","wave":3,"seat":"coder","tier":"medium","desc":"Read docs/plans/2026-07-30-harness-v2-phase3.md Task 6 (TUI Queue Visibility) for the full contract. Fetch strict queue state, retain the last valid snapshot on transport failure, render honest read-only queue rows above runs, and prevent every run action from targeting a queue row. Acceptance: cargo test --manifest-path modules/harness/tui/Cargo.toml queue. Commit only: modules/harness/tui/src/control.rs, modules/harness/tui/src/state.rs, modules/harness/tui/src/plans.rs, modules/harness/tui/src/lib.rs, modules/harness/tui/src/main.rs, modules/harness/tui/tests/plans.rs, modules/harness/tui/tests/state.rs, modules/harness/tui/tests/model.rs, modules/harness/tui/tests/interaction.rs.","requires_decision":null,"verify":["cargo test --manifest-path modules/harness/tui/Cargo.toml queue"],"acceptance":["cargo test --manifest-path modules/harness/tui/Cargo.toml queue"]}
{"type":"task","id":"t7","wave":4,"seat":"coder","tier":"medium","desc":"Read docs/plans/2026-07-30-harness-v2-phase3.md Task 7 (Overdeck Plans Queue Visibility) for the full contract. Render a read-only queue section using existing deck-ui exports, preserve source order/status and honest nulls, link only explicit run IDs, and keep queue-only panels visible with no new primitive. Acceptance: pnpm --filter web test -- src/components/plans/PlansContent.test.tsx. Commit only: apps/web/src/lib/panel-data.ts, apps/web/src/components/plans/PlansContent.tsx, apps/web/src/components/plans/PlansContent.test.tsx.","requires_decision":null,"verify":["pnpm --filter web test -- src/components/plans/PlansContent.test.tsx"],"acceptance":["pnpm --filter web test -- src/components/plans/PlansContent.test.tsx"]}
{"type":"task","id":"t8","wave":5,"seat":"coder","tier":"medium","desc":"Read docs/plans/2026-07-30-harness-v2-phase3.md Task 8 (Register and Run Full Phase 3 Regression Suite) for the full contract. Register every Phase 3 Node suite exactly once and run syntax, focused queue, full v2, preset, collector, TUI, deck-ui, and web gates without warnings, resident workers, wall-clock eligibility sleeps, or suppressed coverage. Acceptance: node --check modules/harness/v2/queue.js && node --check modules/harness/v2/bin/queue-worker.js && node --check modules/harness/v2/bin/runplan.js && node --test modules/harness/v2/test/queue.test.js modules/harness/v2/test/queue-worker.test.js modules/harness/v2/test/systemd-phase3.test.js modules/harness/v2/test/control-api.test.js && node modules/harness/v2/test/index.js && node modules/harness/presets/_validate.mjs && bun test collector/src/adapters/harness.test.ts && cargo test --manifest-path modules/harness/tui/Cargo.toml && pnpm --filter @overdeck/deck-ui test && pnpm --filter @overdeck/deck-ui typecheck && pnpm --filter web test -- src/components/plans/PlansContent.test.tsx && pnpm --filter web build && pnpm --filter web typecheck. Commit only: modules/harness/v2/test/index.js.","requires_decision":null,"verify":["node --check modules/harness/v2/queue.js && node --check modules/harness/v2/bin/queue-worker.js && node --check modules/harness/v2/bin/runplan.js && node --test modules/harness/v2/test/queue.test.js modules/harness/v2/test/queue-worker.test.js modules/harness/v2/test/systemd-phase3.test.js modules/harness/v2/test/control-api.test.js && node modules/harness/v2/test/index.js && node modules/harness/presets/_validate.mjs && bun test collector/src/adapters/harness.test.ts && cargo test --manifest-path modules/harness/tui/Cargo.toml && pnpm --filter @overdeck/deck-ui test && pnpm --filter @overdeck/deck-ui typecheck && pnpm --filter web test -- src/components/plans/PlansContent.test.tsx && pnpm --filter web build && pnpm --filter web typecheck"],"acceptance":["node --check modules/harness/v2/queue.js && node --check modules/harness/v2/bin/queue-worker.js && node --check modules/harness/v2/bin/runplan.js && node --test modules/harness/v2/test/queue.test.js modules/harness/v2/test/queue-worker.test.js modules/harness/v2/test/systemd-phase3.test.js modules/harness/v2/test/control-api.test.js && node modules/harness/v2/test/index.js && node modules/harness/presets/_validate.mjs && bun test collector/src/adapters/harness.test.ts && cargo test --manifest-path modules/harness/tui/Cargo.toml && pnpm --filter @overdeck/deck-ui test && pnpm --filter @overdeck/deck-ui typecheck && pnpm --filter web test -- src/components/plans/PlansContent.test.tsx && pnpm --filter web build && pnpm --filter web typecheck"]}
