feat(issue-tracer): wire v3 receipts plugin-side and prove ingestion reaches a durable plan (#2564) - #2783
feat(issue-tracer): wire v3 receipts plugin-side and prove ingestion reaches a durable plan (#2564)#2783zaxbysauce wants to merge 6 commits into
Conversation
…reaches a durable plan (#2564) Adds the four issue-tracer v3 receipt surfaces to the plugin runtime with producer, reader, reducer-consumer, registration, docs, and tests wired in one change: - record_branch_freshness (Phase 0): .swarm/branch-freshness.json; reader mirrors trace-check.sh phase0 (behind/bare fetch-failed fail closed, override rescues fetch failures only); FRESHNESS_GATE one-shot row before PLAN. - record_trace_validation (per-phase validator receipts): upsert-per-phase .swarm/trace-validation.json with 40-hex reviewedCommit+treeId; any fail entry fails closed; TRACE_VALIDATION_GATE row before the commit-pr handoff. - record_recurrence_sweep widened: relatedProblems (Phase 1 related-problems sweep results) required and non-vacuously reader-enforced on both paths. - record_merge_approval (Phase 5.1): PR-head-bound (prHeadSha === finalCriticReviewedCommit) with the approval captured verbatim; new terminal TraceStatus merge_approval_recorded after published — recorded, never certified: nextMode stays null and the directive names the human as the merge authority. Journey proof: new e2e tests drive /swarm issue <N> --trace through handleIssueCommand, every real receipt executor, the ledger-authoritative savePlan/loadPlan (acceptance, files_touched, fr_refs), approve_plan_critic via ensureAgentSession, interruption/resume via cache resets, and the full gates ladder to published and merge_approval_recorded — no _internals behavioral overrides. Also resolves a pre-existing committed merge-conflict marker in docs/observability-retention-registry.md at the record-receipt-artifacts row (both pr-feedback-loop-state and speckit-checkoff-ledger rows retained).
…lands (#2564 final-critic round 1) The i-pre3 fire condition over-excluded REVIEW_GATE and RECURRENCE_GATE, so in the canonical reducer-driven ladder (RECURRENCE_GATE fires, the sweep receipt lands) the very next cycle parked silently instead of emitting the validation directive — the gate stayed fail-closed but the engine went idle at its own new gate. The exclusion set now excludes only this row's own sentinel plus EXECUTE_TO_COMMIT, mirroring how i-pre2 does not exclude REVIEW_GATE. Adds the reducer test firing from both prior sentinels and makes the journey completion test assert the validation-gate cycle actually emits the directive.
…2564 review round 3) Row i-pre3 now requires both residual-B gates to be verified before its directive can claim they are satisfied: with the sentinel present but the underlying review/sweep receipt no longer verified (vanished, stale, foreign), the row declines to the shared exhausted-one-shot noop instead of emitting a lying directive. Adds the inconsistent-state reducer tests.
Drift check reportFound 2 drift finding(s): 0 error, 0 warning, 2 notice. required-check-contract (2)
|
#2564) CI round 2 surfaced two ratchet classes the local tests/-scoped sweep could not see (src/ tests and the unit-job ratchets were skipped behind the first quality failure): - atomic-write WRITER_CLASSIFICATION: register the three new receipt tools' per-invocation temp constructions under target-suffix-tmp-num-alnum (record-branch-freshness:90, record-trace-validation:134, record-merge-approval:87) and re-pin the two citations drifted by this change (issue-trace-state.ts 315->442, record-recurrence-sweep.ts 125->140). - src/adversarial-tests.test.ts: the architect tool-map sanity bound rises 100 -> 110; the three #2564 receipt tools put the architect count at exactly 100.
There was a problem hiding this comment.
🔵 Needs a closer look
It restructures a core workflow reducer state machine, adds a behavior-changing gate for in-flight traces plus a breaking record_recurrence_sweep schema requirement and a new terminal status, warranting final human review despite thorough tests.
Pull request overview
This PR wires the issue-tracer v3 protocol gates into the plugin runtime. Previously these gates were enforced only by scripts/trace-check.sh and skill text; the plugin-side reducer/state-adapter/receipt tools only knew v2-era artifacts. The change adds full producer→reader→reducer→registration→docs→tests coverage for four v3 receipt surfaces, plus an end-to-end ingestion-journey proof driving the real command, receipt executors, and ledger to a durable plan. It closes #2564 and deliberately coordinates (without absorbing) #2566 and #2600.
Changes:
- Adds three new architect tools (
record_branch_freshness,record_trace_validation,record_merge_approval) and widensrecord_recurrence_sweepto require non-vacuousrelatedProblems. - Extends the reducer with a pre-PLAN
FRESHNESS_GATE, a pre-handoffTRACE_VALIDATION_GATE, and a new terminalpublished → merge_approval_recordedtransition (recorded, never certified), with matching fail-closed readers inissue-trace-state.ts. - Registers the tools, updates the retention registry + skill mirrors + release fragment, and resolves a committed merge-conflict marker in the observability doc.
File summaries
| File | Description |
|---|---|
| src/tools/record-branch-freshness.ts | New Phase 0 freshness receipt writer (synced/behind/fetch-failed + override) |
| src/tools/record-trace-validation.ts | New per-phase validator receipt writer, upserts one entry per phase |
| src/tools/record-merge-approval.ts | New PR-head-bound merge-approval writer; rejects SHA mismatch at write time |
| src/tools/record-recurrence-sweep.ts | Widened to require non-vacuous relatedProblems on both paths |
| src/hooks/issue-trace-state.ts | Adds three fail-closed readers + merge_approval_recorded status; widens sweep reader |
| src/hooks/issue-trace-reducer.ts | New gate rows + terminal transition; === false guards keep v2 literals transparent |
| src/hooks/issue-trace.ts | Wires the three new readers into WorkflowArtifacts |
| src/tools/{tool-metadata,manifest,index}.ts | Registration surfaces for the three new tools |
| scripts/retention-registry.data.ts | Adds new writers/citations to the record-receipt-artifacts row |
| docs/observability-retention-registry.md | Removes committed merge-conflict markers (both rows retained) |
| docs/releases/pending/issue-2564-*.md | Release fragment |
| .opencode/.claude issue-ingest SKILL.md | Documents the new gates (byte-identical mirrors) |
| tests/unit/{hooks,tools}/* | New receipt/reader/reducer/journey suites + fixture updates to existing hook tests |
I verified the wiring is complete (metadata/manifest/barrel/readers/reducer/tests), the reducer gate ladder and one-shot semantics are internally consistent, the readers mirror the writers, the retention-registry citations point to accurate lines (issue-trace-state.ts:435 = writeTraceState, :396/:414 = readers), the skill mirrors are identical, and existing hook-driving tests were updated to satisfy the new gates. I found no objective defect within the changed regions.
Review details
- Files reviewed: 26/26 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
🤖 Multi-Stage PR ReviewPipeline: MiniMax-M2.7-highspeed (orientation) (context pack) → MiniMax-M2.7-highspeed (explorer) + MiniMax-M2.7-highspeed (explorer B) (parallel explore, distinct lenses) → GLM-5-turbo (critique) ↔ GLM-5-turbo (critique) (cross-critique) → MiniMax-M2.7-highspeed (fallback arbiter) (arbiter: blind-spot + synthesize) Challenge ResultsFindings Kept After ChallengeAfter reviewing each confirmed finding against the diff and full-file content, I found the following: FINDING 1 — record-branch-freshness.ts:81 (
FINDING 2 — tempCounter race condition (
Findings Dropped as False Positives
Blind-Spot FindingsNone identified. After reviewing the full diff:
🔁 Validation Provenance
Final Review🚨 Confirmed Findings[MEDIUM]
|
| Check | Result |
|---|---|
| No CRITICAL findings | ✅ |
| No unresolved STEALTH_CHANGE | ✅ |
| No UNSUPPORTED obligations | ✅ |
| Test coverage adequate | ✅ |
| No hardcoded secrets | ✅ |
| All async errors handled | |
| Input validation present | ✅ |
| No broken agent role boundaries | ✅ |
| Prompt format contracts intact | ✅ |
| Lockfile consistent | ✅ |
🔒 Reviewed by a 3-model cross-family adversarial debate (architect → dual-lens parallel explorers → cross-critique → arbiter) for high recall with low false-positive noise. Findings are advisory — verify before acting.
feat(issue-tracer): wire v3 receipts plugin-side and prove ingestion reaches a durable plan
Closes #2564
Summary
The issue-tracer v3 protocol's gates were enforced only by the skill text and
scripts/trace-check.sh— the plugin-side reducer, state adapter, and receipt tools knew onlythe v2-era artifacts. This change wires all four v3 receipt surfaces into the plugin runtime
with producer, reader, reducer-consumer, registration, docs, and tests in one change:
record_branch_freshnesstool writes.swarm/branch-freshness.json(synced/behind:<n>/fetch-failed:<reason>+ optionalverbatim user override). The reader mirrors
trace-check.sh phase0exactly (behind and barefetch-failed fail closed; only a recorded override rescues a failed fetch) and the reducer's
new
FRESHNESS_GATEone-shot parks the trace before PLAN until the receipt permits.record_trace_validationtool records eachtrace-check.sh phase <N>outcome (v3 phase enum, pass/fail, 40-hex reviewedCommit + treeId)into
.swarm/trace-validation.json, upserting per phase; any fail entry fails closed untilre-recorded as a pass. The reducer's
TRACE_VALIDATION_GATEblocks the commit-pr handoffand chains after the recurrence gate in the canonical ladder.
record_recurrence_sweepnow requiresrelatedProblems(the Phase 1 related-problems sweep results, ≥1 entry) on both the real-defect-class and
"no defect class" paths; the reader enforces the widened shape non-vacuously.
record_merge_approvalrecords the humanmerge approval bound to the exact PR head (
prHeadSha === finalCriticReviewedCommit, both40-hex; mismatch rejected at write time) with the approval captured verbatim. The trace gains
a true terminal
merge_approval_recordedstatus afterpublished— recorded, nevercertified:
nextModestays null and the directive names the human as the merge authority,inheriting trace-check.sh's "human-enforced gate; presence and binding only" posture.
/swarm issue <N> --tracethroughhandleIssueCommand, every real receipt executor, the ledger-authoritativesavePlan/loadPlan(tasks carry acceptance criteria,files_touched,fr_refs), the realapprove_plan_criticpath, an interruption/resume step (module cache resets), and the fullgates ladder to
publishedandmerge_approval_recorded— with the actionable next stepasserted at every gate, and no
_internalsbehavioral overrides.Also resolves a pre-existing committed merge-conflict marker in
docs/observability-retention-registry.mdat therecord-receipt-artifactsrow (bothpr-feedback-loop-stateandspeckit-checkoff-ledgerrows retained) — a disclosed adjacentcleanup, verified present at the base commit.
Acceptance Criteria -> Evidence
exercised) + record-v3-receipts / state-v3-receipts suites.
status, PR-head binding across receipts, and no mode driven.
TOOL_MANIFEST handlers, barrel, reducer consumption, state readers, hook calls, BOTH
issue-ingest SKILL.md mirrors, test references) + check-tool-registration (137 tools).
interruption/resume → critic → EXECUTE → gates → handoff → published → merge recorded) +
the two journey bun:test files.
[Workstream F] PR 14 of 21: Complete deferred issue-tracer v3 validator, portability and migration follow-ups #2566 owns load-time migrations (documented in the release fragment).
version/CHANGELOG/.release-please-manifest edits in the diff.
Invariant audit
tools are lazily loaded thunks. Evidence: no
src/index.tschange in the diff; init surfaceunchanged.
bun run buildexit 0,node --input-type=module -e "await import('./dist/index.js')"exit 0,bundle-portability + bundle-plugin-shape tests 12 pass / 0 fail.
.swarm/viavalidateSwarmPath;bun run check:retentionpasses with the three new writers registered in therecord-receipt-artifacts row (122 rows, every writer registered or exempt).
savePlan/loadPlan);plan-ledger.jsonlasserted authoritative; no projection reads added.check:test-file-cap0 violations),_internalsseams extended not bypassed, no newmock.module targets (
check:mock-cleanupclean),realpathSync(mkdtempSync)everywhere,check-test-tmpdir.shclean,check:invariants8/8.foreign issue numbers); no session-global growth.
user-role guidance carriers (appendGuidanceCarrier); journey tests assert carrier delivery.
check-tool-registration.tspasses (137 tools coherent);bun run drift:check --enforceshows no new findings (the sole blocking pr-standards finding reproduces identically at the
pre-fix base — pre-existing upstream drift).
Test plan
Per-file isolation (
bun test <file> --timeout 120000), all green:record-v3-receipts 7, issue-trace-state-v3-receipts 6, issue-trace-reducer-v3 14,
issue-trace-journey-v3 6, issue-trace-journey-v3-completion 2, issue-trace 21,
issue-trace-e2e 10, record-residual-b-receipts 12, issue-trace-state-receipts 23,
issue-trace-state 19, issue-trace-reducer 17, issue-trace-reducer-publication 15,
record-issue-receipts 10, agent-tool-map 13, loader.metadata.parity 9, loader.metadata 16,
host-guidance-trace-controls-2526 3, host-rendered-guidance-2526 2, issue-trace-registration 5,
issue-trace-approval-cache 3, issue-trace-state-plan 10, system-guidance-carrier 22,
issue-ingest-skill 10, issue-command 18, cleanup-drift 2,
nested-project-boundary-command-sinks 2, bundle-portability + bundle-plugin-shape 12.
Quality gates: typecheck exit 0; biome ci (4765 files) exit 0; check-tool-registration,
check:retention, check:registry-citations (90/90 baseline, no new drift), check-invariants,
check:test-file-cap, check-test-tmpdir, check:mock-cleanup all clean. The nine frozen
arm's-length acceptance checks (C1-C9, red-checkpointed at base b865ba2) all pass with
verify-checkpoint 9/9 OK.
Waivers (or none)
None.
Merge status: AWAITING_USER_APPROVAL — the merge decision is human-enforced; this plugin
records approvals, it never certifies or drives merges.
PR head: e80139a