Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
6089f54
chore(TP-198): step 0 preflight complete
HenryLach Sep 7, 2026
911e267
hydrate: TP-198 Step 1 design notes
HenryLach Sep 7, 2026
282f181
hydrate: TP-198 revise Step 1 plan per R001 review
HenryLach Sep 7, 2026
b25180d
feat(TP-198): complete Step 1 — ratification.ts pure module + tests
HenryLach Sep 7, 2026
4a97fb7
hydrate: TP-198 Step 2 design
HenryLach Sep 8, 2026
9d3ebca
feat(TP-198): complete Step 2 — ratify_gate tool + /orch-ratify comma…
HenryLach Sep 8, 2026
2491d69
feat(TP-198): complete Step 3 — finalize-gate ratification binding + …
HenryLach Sep 8, 2026
dfd5057
hydrate: TP-198 add R003 REVISE items to Step 3
HenryLach Sep 8, 2026
131d8a7
fix(TP-198): address R003 review — gate binding, proof==HEAD, unique …
HenryLach Sep 8, 2026
5199194
fix(TP-198): address R004 review — canonical proof oid, clean-tree bi…
HenryLach Sep 8, 2026
5940a09
fix(TP-198): address R005 review — shared selectPacketPaths, hold-lan…
HenryLach Sep 8, 2026
f00f155
fix(TP-198): address R006 — extract testable ratifyGate, packet-home …
HenryLach Sep 8, 2026
f73d188
fix(TP-198): address R007 — immutable-oid proof binding (reject symbo…
HenryLach Sep 8, 2026
e4faae5
docs(TP-198): record R007 resolution in STATUS
HenryLach Sep 8, 2026
9bbf4ad
fix(TP-198): address R008 — scope working-tree allowlist to task runt…
HenryLach Sep 8, 2026
bf4d97a
chore(TP-198): Step 3 complete (code review APPROVE @ R009)
HenryLach Sep 8, 2026
e5e25c1
test(TP-198): Step 4 — full suite green (baseline-matched), fix 2 wir…
HenryLach Sep 8, 2026
c719a24
docs(TP-198): Step 5 — primer ratify recipe, /orch-ratify command, sp…
HenryLach Sep 8, 2026
fc40f5e
checkpoint: TP-198 task artifacts (.DONE, STATUS.md)
HenryLach Sep 8, 2026
421af0a
merge: wave 1 lane 1 — TP-198
HenryLach Sep 8, 2026
b5fe368
hydrate: TP-199 Step 0 complete + expand Step 1 design
HenryLach Sep 8, 2026
d349fd5
feat(TP-199): step 1 — authorizeCompletion single predicate + finaliz…
HenryLach Sep 8, 2026
4b18429
feat(TP-199): step 2 — resume .DONE acceptance uses authorizeCompletion
HenryLach Sep 8, 2026
9b2b8d7
feat(TP-199): step 3 — Taskplane-Ruling trailer parse/validate + lane…
HenryLach Sep 8, 2026
07f1566
fix(TP-199): R002 — remove stale import, format changed files, self-c…
HenryLach Sep 8, 2026
d8374f8
fix(TP-199): R003 — resume binds ratification authority to clean sour…
HenryLach Sep 8, 2026
910a7b8
chore(TP-199): steps 1-3 complete (code review APPROVE @ R004)
HenryLach Sep 8, 2026
aba1baa
test(TP-199): step 4 — full suite green (baseline-matched), update 2 …
HenryLach Sep 8, 2026
d7ef613
docs(TP-199): step 5 — primer citation-flag alert, spec Stage 2b, CHA…
HenryLach Sep 8, 2026
9b7c3ab
checkpoint: TP-199 task artifacts (.DONE, STATUS.md)
HenryLach Sep 8, 2026
ec8e37a
merge: wave 2 lane 1 — TP-199
HenryLach Sep 8, 2026
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
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### New

- **Unified `.DONE` completion authority + ruling commit-trailer validation
(#627, Stage 2b).** Closes the two remaining gaps in the held-state completion
model. (1) A single predicate, `authorizeCompletion()`
(`completion-authority.ts`), now decides completion for BOTH the lane-runner's
live finalize gate AND resume's `.DONE` acceptance
(`collectDoneTaskIdsForResume`): it composes hold authority, blocking review
gates (latest REVISE/RETHINK) and linked-APPROVE ratification validity,
reporting all blockers. A worker-written `.DONE` left over a blocking gate — or
a valid ratification whose worktree carries uncommitted **source** drift — is
now refused on resume exactly as it is live (runtime-owned task artifacts
remain exempt). (2) Workers may cite a ruling that released a hold ONLY through
the structured commit trailer `Taskplane-Ruling: <id>`. After each iteration
the runtime enumerates the commits the worker created and validates every
citation against the durable hold table: an unknown id, an id whose hold binds
another unit, or a prose claim of a ruling with no trailer is **flagged** —
logged to STATUS.md (`Ruling citation flagged`), written to the supervisor
audit trail (`ruling_citation_flagged`, classification `diagnostic`) and
surfaced as one supervisor alert per iteration. A citation flag is a diagnostic
only: it never changes task status, releases a hold, counts toward
progress/stall, or serves as approval.
- **Gate ratification record + finalize binding (#627, Stage 2a).** Gives the
"delegated closure" pattern a first-class, verifiable artifact. When a review
gate hits its revision cap, the supervisor closes it with the new trusted
operation — the `ratify_gate` tool (stamps role `supervisor`) or the
`/orch-ratify <taskId> <gate> <rulingId> <proofRevision> -- <summary>`
operator command (stamps role `operator`) — instead of hand-writing an APPROVE
review file. The operation builds a validated `GateRatification` record
(`R{NNN}-{gate}.ratification.json`), canonicalizes the proof to an immutable
commit id equal to the current worktree HEAD, requires a clean source working
tree, writes the next R-numbered APPROVE review with a `Ratification: <id>`
link, and audits `gate_ratified`. The finalize gate in the lane-runner now
treats an APPROVE that claims a ratification as **blocking** unless the linked
record validates (reference, unit/gate scope, authority, proof == HEAD,
superseded-review hash) and is not stale — refusing `.DONE` with the new
`review_gate_refusal` / `reviewInterventionKind: "invalid-ratification"`
alert. An APPROVE with no `Ratification:` link keeps today's behaviour.
- **First-class `held` state for escalations (#627, Stage 1).** When a worker
calls `escalate_to_supervisor`, the runtime now holds the unit itself: a
durable hold record is persisted (strictly — a persist failure blocks, never
Expand Down
30 changes: 30 additions & 0 deletions docs/reference/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,36 @@ does not approve the result; review gates still apply. If the batch is parked

---

### `/orch-ratify <taskId> <gate> <rulingId> <proofRevision> -- <summary>`

Close a review **gate** that hit its revision cap by writing a validated
**ratification** as the **operator** (#627 Stage 2a). A ruling releases a held
lane; a *ratification* is what makes the APPROVE that closes the gate
trustworthy. This is the only operator path (mirroring `/orch-rule`) that stamps
role `operator` on a ratification; the supervisor equivalent is the `ratify_gate`
tool (role `supervisor`). Use it ONLY after ruling on the findings, verifying the
worker's fold, and confirming the proof commit — never hand-write an APPROVE
review file, which the runtime cannot trust.

**Syntax**

```text
/orch-ratify TP-198 code-step3 1788817706765-cd7b6 a1b2c3d -- Findings 1-2 fixed at HEAD; finding 3 ruled out of authority.
```

- `gate` is the gate key `{type}-step{N}` (e.g. `code-step3`).
- `rulingId` is the ruling message id that released the lane (from the hold).
- `proofRevision` MUST be the current worktree HEAD (an immutable sha) with a
clean working tree — a symbolic ref, an older commit, or uncommitted source
changes are refused.

On success it writes `R{NNN}-{gate}.ratification.json` AND the next R-numbered
APPROVE review file carrying a `Ratification: <id>` link, and audits
`gate_ratified`. The finalize gate then trusts that APPROVE only while the record
validates and is not stale. The worker never writes the APPROVE file itself.

---

### `/orch-confirm-engine-shutdown [--batch <batchId>] <note>`

Record that the operator verified **no engine process is running** for a batch
Expand Down
52 changes: 43 additions & 9 deletions docs/specifications/taskplane/held-state-spec.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Held state and typed rulings — design spec (#627, companion to #626/#628/#630/#631)

Status: **Stage 1 implemented** on `feat/held-state` (design Sage-reviewed 2026-09-07). Stages 2–4 below.
Status: **Stage 1 implemented**; **Stage 2a (ratification record + finalize binding) implemented** (#627, TP-198); **Stage 2b (`authorizeCompletion()` unification + `Taskplane-Ruling:` trailer validation) implemented** (#627, TP-199). Design Sage-reviewed 2026-09-07. Stages 3–4 below.

## Problem

Expand Down Expand Up @@ -117,12 +117,39 @@ interface GateRatification {

A trusted operation validates and persists the record, then writes the next R-numbered APPROVE file
referencing it; the finalize gate validates reference, scope, authority and proof binding. Later
blocking reviews or relevant code changes invalidate a stale ratification. One centralized
`authorizeCompletion()` is called from: pre-spawn completion shortcuts, step-status heuristic, segment
success and final `.DONE`, monitor and resume completion recognition, merge/recovery eligibility. An
unauthorized worker-written `.DONE` is quarantined; failure to remove it never makes it authoritative.
Commits reference rulings via a structured trailer `Taskplane-Ruling: <id>`; unknown/wrong-scope ids
are logged via `logRecoveryAction()` and are never evidence of approval.
blocking reviews or relevant code changes invalidate a stale ratification.

**Stage 2a implemented (TP-198).** The record is written to
`R{NNN}-{gate}.ratification.json` (same `{NNN}` as the APPROVE markdown it
authorizes, allocated from the global `**Review Counter:**`), and the authorizing
APPROVE review file carries the exact link line `Ratification: <id>`. The trusted
operation is the `ratify_gate` supervisor tool (stamps role `supervisor`) and the
`/orch-ratify` operator command (stamps role `operator`); it canonicalizes the
proof to an immutable object id equal to the current worktree HEAD, requires a
clean (source) working tree, and audits `gate_ratified`. The finalize gate
(`findBlockingReviewGates` in `lane-runner.ts`) treats a linked APPROVE as
blocking unless the record validates (via `validateRatification`) and is not
`isRatificationStale`, emitting `review_gate_refusal` with
`reviewInterventionKind: "invalid-ratification"`. An APPROVE with NO
`Ratification:` link keeps today's behaviour (not blocking — the full coverage
gate is #626).

**Stage 2b implemented (TP-199).** `authorizeCompletion()` (`completion-authority.ts`)
is now the single completion predicate: it composes hold authority
(`evaluateCompletionAuthority`) → blocking review gates (latest REVISE/RETHINK) →
linked-APPROVE ratification validity, reporting ALL blockers. The lane-runner's
finalize path and resume's `.DONE` acceptance (`collectDoneTaskIdsForResume`)
both call it, so a worker-written `.DONE` over a blocking gate is refused on
resume exactly as it is live (including the clean-source-tree drift binding when
the lane worktree exists). An unauthorized worker-written `.DONE` is quarantined;
failure to remove it never makes it authoritative. Commits reference rulings via
a structured trailer `Taskplane-Ruling: <id>` (`ruling-trailer.ts`); after each
iteration the runtime validates every citation against the durable hold table and
FLAGS unknown ids, wrong-unit ids, and prose ruling claims — logged to STATUS,
written to the audit trail (`ruling_citation_flagged`, classification
`diagnostic`) and surfaced to the supervisor as one alert per iteration. A flag
never changes task status, releases a hold, or counts toward progress/stall, and
is never evidence of approval.

## Staging

Expand All @@ -132,8 +159,15 @@ are logged via `logRecoveryAction()` and are never evidence of approval.
replacing `pendingEscalation`/`MAX_HOLD_RELAUNCHES`, execution/engine (persistence callback, held
monitoring, wave accounting, `hold-timeout` pause), resume hold-first + lane-parallel restart,
extension/supervisor/merge/cleanup/worktree safeguards, dashboard `held`, primer/docs.
- **Stage 2 — ratification** (#627 remainder, feeds #626): `GateRatification`, trusted ratify
operation, finalize-gate binding, `authorizeCompletion()` unification, commit trailer validation.
- **Stage 2 — ratification** (#627 remainder, feeds #626):
- **Stage 2a (DONE, TP-198):** `GateRatification` record + validation + staleness (`ratification.ts`),
trusted ratify operation (`ratifyGate` in `ratification-op.ts`; `ratify_gate` tool + `/orch-ratify`
command), finalize-gate binding (`invalid-ratification` refusal), record filename
`R{NNN}-{gate}.ratification.json` + `Ratification: <id>` link line.
- **Stage 2b (DONE, TP-199):** `authorizeCompletion()` unification (`completion-authority.ts`)
across the live finalize gate and resume `.DONE` acceptance, commit trailer
(`Taskplane-Ruling: <id>`) parsing + validation (`ruling-trailer.ts`) with per-iteration
citation flagging (`ruling_citation_flagged` audit + supervisor alert; diagnostic-only).
- **Stage 3 — #631 lease/generation** (fencing for split-brain; prerequisite for trusting single-writer).
- **Stage 4 — #628 takeover state machine**, **#626 full coverage gate**.

Expand Down
Loading