Skip to content

structure: delete dead coordinator code in workflow-runner (Step 1.3, A1 PR-1) - #3410

Open
Serhan-Asad wants to merge 60 commits into
refactor/clean-kitchenfrom
refactor/d2-dead-runner
Open

Serhan-Asad wants to merge 60 commits into
refactor/clean-kitchenfrom
refactor/d2-dead-runner

Conversation

@Serhan-Asad

@Serhan-Asad Serhan-Asad commented Nov 14, 2026 •

Copy link
Copy Markdown
Collaborator

Class C: dead-surface deletion. This is Step 1.3 of the refactor plan (A1 PR-1). It deletes coordinator code in src/workflow-runner.mjs that nothing calls, together with its prompt text. It removes no test, because no test calls this code. Behavior does not change.

Merge after #3411. This branch already contains origin/refactor/d2-sync-main (60be32b), merged with no rebase. Until #3411 merges, GitHub also shows main's commits. Against 60be32b the change is:

Lines: +30 / -249 (5 files). Code +6 / -169, prompts +24 / -80.

Deleted symbols and the proof that each is dead

The proof has three parts for each symbol.

  1. On the merged tree (60be32b plus this PR), grep -rn over src/ (with src/runtime/), bin/, scripts/, skills/, .github/, test/, tests/, prompts/ and docs/ finds 0 users of every deleted name. The same is true for automatic-pr1.lock, #automatic-attention-projection, progressRecorded and extraChanges.
  2. There is no string dispatch. pdd-cli.mjs RUNNER_ROUTES names none of them, and every await import('./workflow-runner.mjs') user in src/ destructures other names.
  3. V8 coverage (NODE_V8_COVERAGE) ran on the pre-sync base 659a351, one process for each of 11 focused test files: workflow-runner (172 tests), cli, autopilot-alerts, autopilot-parking, autopilot-launcher, autopilot-core, autopilot-idle-agents, workflow-claim-open, workflow-stopped-panes, workflow-worker-completion and workflow-completion-delivery. No test reaches any of these functions (0 calls).
Symbol Lines Kind
WORKFLOW_CAPABILITIES 1 export, no reader
automaticAttention 12 export, no caller
advanceAutomaticPr1 61 export, no caller
automaticPr1ParkingEligible, automaticPr1Eligible, recordedStoryDecision, deriveStoryCoverage 62 private helpers used only by advanceAutomaticPr1
hasParkedReply 3 export, no caller
releaseParkedRun 22 export, no caller
PROMPT_TESTS 1 private const, already unused

Only advanceAutomaticPr1 passed two parameters. This PR removes them, and behavior stays the same:

  • changedStoryGate(..., approval, extraChanges): approval is now read as storyCoverage(run) inside the function, which was the default. The 6 live calls pass at most 6 arguments.
  • automaticPr1(..., progressRecorded = () => {}): this was a no-op for the one live call.

An intra-file closure check finds no other newly dead helper. The set of unused imports is identical on base and head.

Kept on purpose

  • src/workflow-worker-completion.mjs is kept, because it is not dead in production.
    • workflow-runner.mjs imports armSavedWorkerCompletion statically. armCurrentAutomaticChat calls it from 4 live sites (startNextChat and the open/replace paths).
    • In base coverage, armCurrentAutomaticChat runs 327 times in workflow-runner tests.
    • Its result selects which line the person sees ("Automatic completion observer unavailable..." or "If automatic completion observation becomes unavailable..."). So deleting it changes visible output.
    • This is A1 decision D3, not class C.
  • The 4 status readers of a saved gate.automaticHold stay, because old saved runs can still carry the field. The prompt keeps their rule (review must-fix 1).

Prompt changes (need person approval)

Needs person approval: prompts/cli/workflow-runner.prompt.md, prompts/cli/autopilot-parking.prompt.md and prompts/cli/autopilot-alerts.prompt.md. No approval was recorded.

  • workflow-runner.prompt.md:
    • delete the "Automatic attention projection" section;
    • in "Automatic PR 1 full-pass gate", keep only the rules that the live automaticPr1 path still applies to automatic-origin runs, plus the display rule for a saved hold reason ("Keep a gate hold reason that status detail, next-step guidance and list/JSON words show."). Delete the advanceAutomaticPr1 command, its lock, eligibility, Story-coverage derivation and hold writing;
    • delete the WORKFLOW_CAPABILITIES, hasParkedReply and releaseParkedRun sentences in "Resource-free parking". The releasing readers stay, so their sentence stays.
  • autopilot-parking.prompt.md:11: "unless hasParkedReply confirms" becomes "unless the caller's clearing evidence confirms" (review must-fix 2). The other dead wake rules there stay for A1 PR-5.
  • autopilot-alerts.prompt.md: delete the ## Dependencies link to the deleted #automatic-attention-projection anchor. No other prompt links to that anchor.
  • Interfaces:
    • pdd interface draft --refresh refuses both blocks. The runner's is partial ("Supply a full executable contract"), and the parking one has empty entries.
    • So I followed the route that pdd test --fill-hash prints for a changed approved prompt: "set status to draft, run pdd test --fill-hash, ask the person". Only "status" changed by hand, from approved to draft. The tool filled prose_sha256. The declarations are unchanged.
    • --fill-hash also fills 3 unrelated drafts that are already stale on base (autopilot-regressions, runtime-lint-receipt, setup-interaction). I reverted those files, so they are not in this PR.
  • Generated headers:
    • src/workflow-runner.mjs and src/autopilot-alerts.mjs are current, and pdd owner says certain.
    • src/autopilot-parking.mjs keeps its hashless header (state none, the same as base).
    • src/workflow-eligibility.mjs has a workflow-runner header. It was already stale on base, and this PR does not touch it.

Golden CLI diff (in-tree test/golden/run.mjs)

  • clean 60be32b vs this head: 34 cases, 34 identical, 0 differ.
  • Before the sync (7ce1dbf vs the earlier head): also 34/34 identical.

The cases include workflow-run-admission-busy. No CLI case reaches the deleted code, so no difference was expected.

Focused tests (laptop, this head)

At 88e8267, all pass:

  • workflow-runner: 172/172
  • runtime-seam: 24/24 (the SEAM5 record does not change)
  • autopilot-parking: 13/13
  • metrics-runner-interface.integration: 2/2 (draft shape accepted, prose hash current)

At c95141c, which has the same code and differs only by the 2 prompt sentences, all pass:

  • workflow-prompt-reentry: 46/46
  • cli: 8/8
  • autopilot-alerts: 34/34
  • workflow-worker-completion: 4/4
  • workflow-completion-delivery: 1/1

autopilot-launcher is flaky on this laptop, on base 60be32b too. Each run fails 1 or 2 different tests (#4 timer cleanup, #7 --share, #8 --agent). Base and head failed the same way, and that file does not load the deleted code.

I did not run the full suite. The VM suite is left to the lead.

Ratchet (in-tree test/tools/ratchet.mjs, base 60be32b)

Measure Base Head Change Result
Biggest host file (lines) 6,284 workflow-runner.mjs 6,121 workflow-runner.mjs -163 better
Host files over 1,500 lines 3 3 0 same
Largest import loop (modules) 36 36 0 same
Modules in import loops 36 36 0 same
Upward imports (module pairs) 14 14 0 same
Exact clone lines (50-token window) 352 346 -6 better
Comment lines not on the keep-list 2,352 2,346 -6 better
History references in host prompts 163 162 -1 better
Test-only exports 32 27 -5 better
Lines of host code 38,798 38,635 -163 better
Lines of host tests 115,292 115,292 0 same
Lines of host prompts 25,005 24,949 -56 better

Net host lines (code, tests, prompts): -219. Lower is better on every row. This report never blocks.
Host only: src/**/*.mjs and bin/ without the Runtime package and src/vendor/; test/ without test/runtime-package/; prompts/ without the Runtime prompts. Loops and upward imports count static, import() and createRequire edges. Clones: 50-token windows seen earlier in host code, runs of 5+ lines.
Modules with no box (add them to BOXES in test/tools/ratchet.mjs): autopilot-telemetry.mjs, autopilot-update.mjs, login-pool.mjs, release-notice.mjs, story-lint.mjs.

Follow-ups (not in this PR)

  • autopilot-alerts.prompt.md:292-293 still says that digest attention rows come from the runner's projection. The digest action has no production caller.
  • src/workflow-runner.mjs comment in changedStoryGate ("so the progress guard can save its new hold") names the deleted hold writer. Step 2 handles comments.
  • Nothing calls the parking wake rules in autopilot-parking.prompt.md:9-12 any more. The same is true of skills/pdd-prompting/runbook/autopilot-and-checklists.md:50 (capability waits). This belongs to A1 PR-5, after Ishaan is told.

Prompt diffs (against 60be32b)

workflow-runner, autopilot-parking and autopilot-alerts prompts (interface JSON shortened after prose_sha256)
diff --git a/prompts/cli/autopilot-alerts.prompt.md b/prompts/cli/autopilot-alerts.prompt.md
index 8c0da5020..c6d1770c7 100644
--- a/prompts/cli/autopilot-alerts.prompt.md
+++ b/prompts/cli/autopilot-alerts.prompt.md
@@ -347,4 +347,2 @@ An open `unconfirmed` incident still counts without resending.
   `alertStatusLine` with its saved repository and state root.
-- [Workflow runner attention](workflow-runner.prompt.md#automatic-attention-projection): required native context for
-  `automaticAttention` rows.
 - [Workflow runner lock](workflow-runner.prompt.md#native-admission-lock): required native context for
diff --git a/prompts/cli/autopilot-parking.prompt.md b/prompts/cli/autopilot-parking.prompt.md
index b14e28ac4..801ad10bc 100644
--- a/prompts/cli/autopilot-parking.prompt.md
+++ b/prompts/cli/autopilot-parking.prompt.md
@@ -10,3 +10,3 @@ Recognize a saved wait for #2897, or a saved question/stop about the missing sup
 
-On each auto tick, close blocked workers via park and retain all disk custody. A parking phase closing remains occupied until close confirms absence; a missing session or unknown chat custody also retains native admission occupancy even when the stopped workflow is not reported as working; parked consumes no working slot only while check custody is positively idle. A check admitted after parking, including queued or unavailable custody, reserves working capacity without reopening chats; retain this observation as parking.checkHeld until a fresh idle observation clears it. Such runs cannot wake or release, including at timeout or surplus limits. Never infer stopped custody from labels or age. Retry incomplete cleanup. A closing reservation does not override new progress: retain its occupied custody while a new recovery-ceiling grace runs or the worker has returned to running without a saved blocker. An accepted replacement blocker supersedes the previous clearing condition without resetting park age or saved-session custody. Retain a parked blocker when no replacement cause is saved. Once parked, do not restore chats until the current blocker clears and normal capacity permits. Attempt ready wakes before fresh work, by parking.at then issue number. A failed wake remains in wakePending and retains its working reservation; it does not reserve every still-free slot. person clears on a durably queued reply bound to the current parked wait, or recorded reply/approval (the bound old gate/question no longer present); an unbound person blocker remains parked; dependency only on merged issue evidence; pdd only on installed capability or commit evidence (never a package version comparison): #2897 requires capability prompt-reentry, capability:NAME requires that installed capability, commit:HEX requires that ancestor in the installed package; an older VERSION-only wait stays blocked until it has fix evidence; account/github only on saved reset timestamp; CI/review only on a new result/lease evidence; interpreter only on the existing runtime-ready rule; environment only on its existing due/healthy wake. Unknown evidence remains parked unless hasParkedReply confirms a durably queued explicit reply or retry for this same unknown park. Treat that request as clearing evidence and deliver it once through the existing journal after capacity admission; never send an additional continue notice or grant approval. Keep each wake reservation occupied across failures. Return the summary with ready wakePending in oldest-first order. A PDD wake sends one notice that names the installed fix and tells the saved session to continue. For #2897 it explains that the PR 1 re-entry/current-main integration route now exists. Preserve independent questions and approvals; a recovery notice is never a person answer. A successful wake consumes its rule once. Same files impose no admission hold.
+On each auto tick, close blocked workers via park and retain all disk custody. A parking phase closing remains occupied until close confirms absence; a missing session or unknown chat custody also retains native admission occupancy even when the stopped workflow is not reported as working; parked consumes no working slot only while check custody is positively idle. A check admitted after parking, including queued or unavailable custody, reserves working capacity without reopening chats; retain this observation as parking.checkHeld until a fresh idle observation clears it. Such runs cannot wake or release, including at timeout or surplus limits. Never infer stopped custody from labels or age. Retry incomplete cleanup. A closing reservation does not override new progress: retain its occupied custody while a new recovery-ceiling grace runs or the worker has returned to running without a saved blocker. An accepted replacement blocker supersedes the previous clearing condition without resetting park age or saved-session custody. Retain a parked blocker when no replacement cause is saved. Once parked, do not restore chats until the current blocker clears and normal capacity permits. Attempt ready wakes before fresh work, by parking.at then issue number. A failed wake remains in wakePending and retains its working reservation; it does not reserve every still-free slot. person clears on a durably queued reply bound to the current parked wait, or recorded reply/approval (the bound old gate/question no longer present); an unbound person blocker remains parked; dependency only on merged issue evidence; pdd only on installed capability or commit evidence (never a package version comparison): #2897 requires capability prompt-reentry, capability:NAME requires that installed capability, commit:HEX requires that ancestor in the installed package; an older VERSION-only wait stays blocked until it has fix evidence; account/github only on saved reset timestamp; CI/review only on a new result/lease evidence; interpreter only on the existing runtime-ready rule; environment only on its existing due/healthy wake. Unknown evidence remains parked unless the caller's clearing evidence confirms a durably queued explicit reply or retry for this same unknown park. Treat that request as clearing evidence and deliver it once through the existing journal after capacity admission; never send an additional continue notice or grant approval. Keep each wake reservation occupied across failures. Return the summary with ready wakePending in oldest-first order. A PDD wake sends one notice that names the installed fix and tells the saved session to continue. For #2897 it explains that the PR 1 re-entry/current-main integration route now exists. Preserve independent questions and approvals; a recovery notice is never a person answer. A successful wake consumes its rule once. Same files impose no admission hold.
 
@@ -69,3 +69,3 @@ never wake it through interpreter health alone. Display binding in summaries.
 ```json
-{"status":"approved","prose_sha256":"7198672b8e0fbf95d3a6cbc4fa9b617b1ba14df876e39e57d8475d6d934c64c1", ...rest of the interface JSON unchanged
+{"status":"draft","prose_sha256":"eea158d3e5633e83e817ae9dd1c8afcf5f521ba0534043873c6f510e442969e8", ...rest of the interface JSON unchanged

diff --git a/prompts/cli/workflow-runner.prompt.md b/prompts/cli/workflow-runner.prompt.md
index b7b82bfcc..def27e326 100644
--- a/prompts/cli/workflow-runner.prompt.md
+++ b/prompts/cli/workflow-runner.prompt.md
@@ -266,17 +266,2 @@ skill's 2-repair rule applies.

-## Automatic attention projection

-Export automaticAttention({repo, machine}, ports = {}), a synchronous, read-only
-projection of all saved runs on this machine from workflow-runs allRuns, or
-injected ports.readRuns(). Pass ports.env/stateDir to the native reader.
-Include only runs whose automaticOrigin.machine matches machine and whose repo
-matches ignoring case. Exclude ended runs except completed runs still at an
-ask-code gate. Emit {number, category, cause} rows: stuck with the existing
-stuck reason for stuck runs; otherwise parked with runtimeWait.reason or
-parkReason for paused runs; otherwise decision with the current open question
-or gate kind for a question or gate. One row per run, sorted by issue number.
-Ignore manual runs, other machines and repositories. Do not probe chats, wake,
-approve, mutate, or infer a stop. This supplies the launcher's repository digest
-across parallel runs, without changing run state or ownership.

Record an automatic stopped run

@@ -659,22 +644,11 @@ Standalone prompt journal evidence and gate decisions use [run records](workflow

-Export advanceAutomaticPr1({ref,cwd,packageRoot,coordinatorId,machine},ports).
-This native boundary serializes publication attempts with a per-run
-automatic-pr1.lock, using the existing exclusive-lock ownership and recovery
-rules. It leaves chat-replacement.lock available for cancellation and claim
-cleanup; the progress guards below stop publication after cancellation.
-It considers only a waiting,
-unpublished approve-pr gate in a bug or feature prompt PR area whose required
-steps are done, with no open question or pending chat replacement. A parking
-record is eligible only in phase parked for a person blocker bound to this same
-approve-pr gate, with no bound question, explicit independent blocker, runtime
-wait or held check custody; the current parking policy must still classify the
-wait as person. Preserve its closed chats, session identities and reservation
-age. Publication binds that reservation to the new code gate without resuming a
-worker, so a reply to the old approval wait cannot clear the new gate.
-Other parking causes and incomplete cleanup or wake reservations stay protected.
-Require a valid saved automatic origin matching this source checkout, coordinator
-and machine, the current enabled matching operator start scope in auto mode,
-the selected workflow Autopilot overlay, and non-strict policy from sourceRoot.
+For a run with a saved automatic origin, require the current enabled matching
+operator start scope in auto mode, the selected workflow Autopilot overlay, and
+non-strict policy from sourceRoot.
Current winning claim custody must pass the ordinary continuation check. Missing,
-unavailable or changed authority never supplies approval.
+unavailable or changed authority never supplies approval. When a parked person
+wait is bound to the published approve-pr gate, preserve its closed chats, session
+identities and reservation age. Publication binds that reservation to the new code
+gate without resuming a worker, so a reply to the old approval wait cannot clear
+the new gate.

@@ -683,31 +657,7 @@ paths, saved-batch freshness/completeness and pinned publication evidence rules.
Automatic Story coverage is the latest saved decision's storyCoverage, falling
-back to storyApproval. If coverage is absent, derive it once from the latest
-recorded approval of the workflow's Story area. Require its identified evidence
-to match the approval journal, including the approved prompt paths and hashes.
-Require a saved Story contract and paths bound to that approval. An earlier
-Story-step source hash, even when matched by a local ancestor and unchanged
-prompt prose, cannot establish which Story the later approval covered. Missing
-approval-bound evidence keeps the person gate with a coverage hold reason.
-Capture the current Story contract and fingerprint from the same immutable file
-snapshot so an edit between contract validation and fingerprint capture cannot
-become approved coverage. Read source inventory through the program port; do
-not change the source worktree while recovering its fingerprint.
-Compare the snapshot contract with the approval's saved contract, and its Story,
-plan, expected values and prompt paths with the current selection before saving.
-Every fingerprinted Story and scenario must belong to that contract's file
-inventory. An unbound file keeps the person gate. A difference or intervening
-edit reopens the Story card and saves no derived coverage. Otherwise save
-storyApproval with gateId, evidenceId, original approval at, fingerprint,
-prompts, and source: "derived from the recorded approval". Its derivedFrom
-records storyContract for the approval-bound snapshot. Preserve the original
-decision and journal; this is coverage recovery, not a new approval. Guard the save against changed run,
-decision, gate, scope and custody, and recheck current source before publication.
-Retries reuse saved coverage. Normal runs never derive coverage and retain their
-person gate when it is missing. A changed Story,
+back to storyApproval. A changed Story,
plan, expected value or prompt list reopens the Story gate; an already reopened
-Story gate requires explicit approval and is never crossed by this boundary.
-When this command reopens a Story gate that owns an eligible parked person wait,
-bind that reservation to the revised gate in the same saved transition. Replace
-any earlier check-failure hold with the Story approval reason; status next-step
-guidance and later ticks must retain that reason. The JSON/list summary words
+Story gate requires explicit approval and is never crossed by this route.
+When this route reopens a Story gate that owns an eligible parked person wait,
+bind that reservation to the revised gate in the same saved transition. The JSON/list summary words
for a parked run must also include its current automaticHold, beside the parking
@@ -719,5 +669,4 @@ A prompt-only repair can use a fresh full pass under the same Story coverage.
Failed, partial, missing, stale or no-verdict checks keep the gate and publish
-nothing. Keep a gate hold reason that status detail and list/JSON words show,
-including strict policy, missing scope, missing Story coverage, Story changes,
-check problems or unavailable custody. A hold reason never authorizes a gate.
+nothing. Keep a gate hold reason that status detail, next-step guidance and list/JSON
+words show. A hold reason never authorizes a gate.

@@ -728,7 +677,5 @@ before preparation and authorization, and winning custody before authorization.
Guard progress against the latest saved run before approval writes, Git mutations
-and PR publication effects. Require the same run, area, gate, automatic origin
-and Story approval coverage, with the waiting state and all eligibility guards
-above still satisfied. Cancellation, a new person question or another eligibility
-change during preparation or publication stops further effects and preserves the
-saved blocker. The run lock alone does not exclude cancellation or questions.
+and PR publication effects. Cancellation during preparation or publication stops
+further effects and preserves the saved blocker. The run lock alone does not
+exclude cancellation or questions.
Supply the current-run progress guard to the approval journal's guarded commit
@@ -753,4 +700,3 @@ replace that coverage before continuation. Missing prior code authority, changed
Story coverage or strict policy never gains code authority from PR 1 publication.
-Do not merge, answer a question or create another run. Repeating the coordinator
-call after PR 1 opens makes no duplicate approval, push or PR.
+Do not merge, answer a question or create another run.

@@ -1607,3 +1553,3 @@ Export sweepIdleRuns({graceMs=60000,need,timeBudgetMs}={},ports={}) returning

-The owning parking policy supplies blocker shapes, clearing rules and tick order as required generation/testing context. The park command still records existing interpreter/environment/work causes before any cleanup. It additionally accepts blocker and until: --blocker dependency --until N, --blocker pdd --until FIX, --blocker account|github --until ISO, or --blocker person|ci|review. Invalid kinds or clearing values refuse without mutation. A person blocker requires an existing open question or person gate; otherwise refuse without mutation. Absence of a wait is not evidence of a reply. Store explicit waits as blockedOn: {kind,until} (until null for person/CI/review); they set state paused and keep the reason. PDD FIX accepts #N, capability:NAME or commit:HEX; retain legacy VERSION records without treating the number as installed-fix evidence. Export frozen WORKFLOW_CAPABILITIES containing prompt-reentry for the supported PR 1 re-entry route and route-interface-drafting for the installed interface draft command. Also export route-code-only-checker for the independent code-only bug checker route in RUNBOOK §14. The default installed capability list must clear saved waits for both routes without an injected capability override, through the #3112 capability wake. Preserve route history, independent questions and approval gates; a wake notice supplies no verdict or approval. An installed PDD capability or ancestor commit clears pdd, never a merged fix alone.
+The owning parking policy supplies blocker shapes, clearing rules and tick order as required generation/testing context. The park command still records existing interpreter/environment/work causes before any cleanup. It additionally accepts blocker and until: --blocker dependency --until N, --blocker pdd --until FIX, --blocker account|github --until ISO, or --blocker person|ci|review. Invalid kinds or clearing values refuse without mutation. A person blocker requires an existing open question or person gate; otherwise refuse without mutation. Absence of a wait is not evidence of a reply. Store explicit waits as blockedOn: {kind,until} (until null for person/CI/review); they set state paused and keep the reason. PDD FIX accepts #N, capability:NAME or commit:HEX; retain legacy VERSION records without treating the number as installed-fix evidence. Preserve route history, independent questions and approval gates; a wake notice supplies no verdict or approval. An installed PDD capability or ancestor commit clears pdd, never a merged fix alone.

@@ -1611,5 +1557,5 @@ Export `parkBlockedRun({ref,cwd,blocker,coordinatorId,machine,expected?,interpre

-Waking uses the existing open/rebuild/resume path and the existing continuation journal (#3068/#3072), in background, preserving the same native session. Extend that route to a deliberately parked closed chat; do not add a native launch implementation. Keep a waking reservation occupied after dispatch failure or restart. An accepted park command updates the saved parking blocker and its bound person wait when the wait changes, preserving park age and capacity reservations. On entry or replacement of an interpreter wait, save the current interpreterWait and bind the current gate as interpreterGate, using the parking owner's evidence rules even when the blocker kind stays interpreter. For a finished-check inference, interpreterCheck is {step,result}: step is the current done.check or null; result is {batch,at,states}, with absent fields null, or null when absent or unreadable. Save it as parking.interpreterCheck. Compare it and the gate with the previous binding before accepting a cached wait. Changed evidence creates a wait at the current observation time with the current batch, advancing at by at least one millisecond from the previous wait when the clock has not advanced; unchanged evidence keeps the previous wait. Remove interpreterCheck for explicit interpreter causes. Remove interpreterWait/interpreterGate/interpreterCheck when another blocker supersedes it. Preserve an unchanged interpreter wait's identity across ticks; never carry its batch into a later wait. These evidence updates preserve the saved session, workflow gates and questions. Recheck origin, park timestamp and the current blocker before effects. Automatic wakes supply expectedBlocker and the injected parkingBlockerCleared(run) port; revalidate current clearing evidence under run custody before first reserving a wake, and refuse a changed blocker or active/uncertain check. A waking reservation retries its already accepted clearance. On the first accepted wake reservation, clear runtimeWait/blockedOn for that wake and retire its consumed parkReason/stuckCause before resume or delivery can save a new stop. Keep environment causes until their existing retry delivery applies its effects. A waking retry must not clear a newly saved cause; completing delivery removes only the matching parking reservation. Later stops use their new evidence, never the consumed cause. Preserve person gates/questions, and deliver the provided interpreter read-first text once as a notice (environment retry text keeps its change effects), or the existing continue notice when no special text is supplied. A failed resume leaves the reservation for retry. A confirmed native rejection before dispatch (agent_not_found or pane_not_found) clears only that attempt's unconfirmed-start flag and keeps the saved session as ended for the existing open path to retry. Unknown dispatch stays unconfirmed and occupied. No approval is granted. Normal stopped-chat recovery and idle nudging must skip parking records. The existing request journal accepts an internal stable requestKey for one park continuation across restarts. queueOnly saves a group join as pending through that journal without launching a chat or submitting text. Reopening carries pending group requests through the ordinary resume message. Only acknowledged native resume dispatch marks those exact pending group journal entries delivered; a failed or unknown dispatch retains their custody. Do not send those group entries again as a separate prompt. Environment wakes retain their existing change-request effects and retry accounting. An explicit manual open can use the same resume route. A queued personRetry identity survives the wake transition to running: revalidate its current repair limit, enabled coordinator and claim before reserving a wake, again at delivery and immediately before submission, and retain the retry-only failed-step and unknown-outcome instructions. A refusal leaves the request pending and grants no approval. An ordinary parked reply saves its answer or change in the existing delivery journal, bound to the park timestamp and current question/gate, under run custody; it never opens a pane or bypasses normal capacity. Export hasParkedReply(run,ports) to read this durable ready evidence without writes. Pending, definitely unsent replies for the bound current wait make a person park ready for the coordinator's oldest-first admission; uncertain or in-flight requests do not. After admitted resume, deliver those replies by their existing journal identities once, preserving FIFO, answer effects and unknown-delivery custody; do not also send a continue notice for the same reply. A retry before admission reuses its pending journal entry. Never send an answer into an absent closed pane.
+Waking uses the existing open/rebuild/resume path and the existing continuation journal (#3068/#3072), in background, preserving the same native session. Extend that route to a deliberately parked closed chat; do not add a native launch implementation. Keep a waking reservation occupied after dispatch failure or restart. An accepted park command updates the saved parking blocker and its bound person wait when the wait changes, preserving park age and capacity reservations. On entry or replacement of an interpreter wait, save the current interpreterWait and bind the current gate as interpreterGate, using the parking owner's evidence rules even when the blocker kind stays interpreter. For a finished-check inference, interpreterCheck is {step,result}: step is the current done.check or null; result is {batch,at,states}, with absent fields null, or null when absent or unreadable. Save it as parking.interpreterCheck. Compare it and the gate with the previous binding before accepting a cached wait. Changed evidence creates a wait at the current observation time with the current batch, advancing at by at least one millisecond from the previous wait when the clock has not advanced; unchanged evidence keeps the previous wait. Remove interpreterCheck for explicit interpreter causes. Remove interpreterWait/interpreterGate/interpreterCheck when another blocker supersedes it. Preserve an unchanged interpreter wait's identity across ticks; never carry its batch into a later wait. These evidence updates preserve the saved session, workflow gates and questions. Recheck origin, park timestamp and the current blocker before effects. Automatic wakes supply expectedBlocker and the injected parkingBlockerCleared(run) port; revalidate current clearing evidence under run custody before first reserving a wake, and refuse a changed blocker or active/uncertain check. A waking reservation retries its already accepted clearance. On the first accepted wake reservation, clear runtimeWait/blockedOn for that wake and retire its consumed parkReason/stuckCause before resume or delivery can save a new stop. Keep environment causes until their existing retry delivery applies its effects. A waking retry must not clear a newly saved cause; completing delivery removes only the matching parking reservation. Later stops use their new evidence, never the consumed cause. Preserve person gates/questions, and deliver the provided interpreter read-first text once as a notice (environment retry text keeps its change effects), or the existing continue notice when no special text is supplied. A failed resume leaves the reservation for retry. A confirmed native rejection before dispatch (agent_not_found or pane_not_found) clears only that attempt's unconfirmed-start flag and keeps the saved session as ended for the existing open path to retry. Unknown dispatch stays unconfirmed and occupied. No approval is granted. Normal stopped-chat recovery and idle nudging must skip parking records. The existing request journal accepts an internal stable requestKey for one park continuation across restarts. queueOnly saves a group join as pending through that journal without launching a chat or submitting text. Reopening carries pending group requests through the ordinary resume message. Only acknowledged native resume dispatch marks those exact pending group journal entries delivered; a failed or unknown dispatch retains their custody. Do not send those group entries again as a separate prompt. Environment wakes retain their existing change-request effects and retry accounting. An explicit manual open can use the same resume route. A queued personRetry identity survives the wake transition to running: revalidate its current repair limit, enabled coordinator and claim before reserving a wake, again at delivery and immediately before submission, and retain the retry-only failed-step and unknown-outcome instructions. A refusal leaves the request pending and grants no approval. An ordinary parked reply saves its answer or change in the existing delivery journal, bound to the park timestamp and current question/gate, under run custody; it never opens a pane or bypasses normal capacity. Pending, definitely unsent replies for the bound current wait make a person park ready for the coordinator's oldest-first admission; uncertain or in-flight requests do not. After admitted resume, deliver those replies by their existing journal identities once, preserving FIFO, answer effects and unknown-delivery custody; do not also send a continue notice for the same reply. A retry before admission reuses its pending journal entry. Never send an answer into an absent closed pane.

-Export releaseParkedRun({ref,cwd,runId,at,coordinatorId,machine},ports) with ordinary {exitCode,message} and recovery released or skipped. Hold the existing run lock through revalidation, the injected releaseParkedClaim(run) effect, matching local allocation release and cancellation. Require matching runId, park timestamp, origin/source and parked/releasing phase. Under the run lock, revalidate live check custody before each claim effect and cancellation; queued, running or unavailable check custody refuses release. Save phase releasing before the first claim effect. Refused, failed or unknown effects retain that reservation for retry. Revalidate before each effect and cancellation; never cancel a replaced or resumed run. Open, changes and workflow progress commands refuse a releasing reservation, including after restart; cancel remains available. Park cleanup and wakes leave it alone.
+Open, changes and workflow progress commands refuse a releasing reservation, including after restart; cancel remains available. Park cleanup and wakes leave it alone.

@@ -1711,3 +1657,3 @@ Export recoverAutomaticRunOwner({ref,cwd,coordinatorId,machine},ports), with the

-{"kind":"partial","status":"approved","prose_sha256":"e40373c2b33a8034fde05a3a2bfc6dee787994cf1a88fb0a892f58353f885dc2", ...rest of the interface JSON unchanged
+{"kind":"partial","status":"draft","prose_sha256":"921e0a9bd7d1f1d9c964bd1e66166bc855cd63157c8e6fcdbdd17d116fc4b4b5", ...rest of the interface JSON unchanged
</details>

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Serhan-Asad and others added 30 commits November 13, 2026 13:05
Add deterministic local Story quality lint (src/story-lint.mjs) and test-prompt ownership checks (isTestPromptPath, findTestPromptViolations) across pdd owner, pdd approve, and workflow pre-gate and pre-PR transitions (+709 / -15 lines).

Closes #3362
…area grouping

Support --intake active alongside off and shadow so Autopilot can run 24/7
without manual opt-in label hand-feeding while gating work strictly on
ready intake cards for the current issue version:
- Parse areas (with area_hint alias), group_with, and size on intake cards.
- Claim 2-3 small ready grouped issues into one grouped job/PR (Closes #A,
  Closes #B) and serialize overlapping module/file areas across slots.
- Rank unblockers, active group continuations, high-clarity small/bug wins,
  and priority ahead of oldest issue age.
- Run one bounded read-only repo-inspection auto-improve pass per issue
  version on improve cards before asking a human with pdd:needs-decision.

Closes #3190
Closes #3189
Refs #3233
…mpanion ownership

- Parse GitHub issue URLs via new URL host validation (github.com only)
  and strip scheme URLs in area path extraction (fixes CodeQL URL alert).
- Pass trusted Autopilot spec-refinement comments and label-only approval
  notes into active card evaluation, detect body/title edits in
  auto-improve loop guards, and restrict prevImproved reconciliation to
  ready cards.
- Align autopilot-core prompt S2 collision rule for off and shadow modes.
- Detach expired or rival-claimed companions during heartbeats and verify
  companion ownership before closing or updating labels on merge/observe.

Refs #3190
Refs #3189
Refs #3233
…-user-metrics-3250-3262' into release/0.1.32
Serhan-Asad and others added 30 commits November 13, 2026 17:43
…252' into release/0.1.32

# Conflicts:
#	docs/cli.md
#	prompts/cli/command-catalog.prompt.md
#	src/autopilot-core.mjs
#	src/autopilot-launcher.mjs
#	src/command-catalog.mjs
#	test/runtime-seam.test.mjs
…710-3324' into release/0.1.32

# Conflicts:
#	docs/cli.md
#	prompts/cli/autopilot-launcher.prompt.md
#	prompts/cli/command-catalog.prompt.md
#	prompts/cli/pdd-cli.prompt.md
#	src/autopilot-launcher.mjs
#	src/command-catalog.mjs
#	src/pdd-cli.mjs
…l-tiering-3154' into release/0.1.32

# Conflicts:
#	prompts/cli/autopilot-core.prompt.md
#	src/autopilot-core.mjs
#	test/runtime-seam.test.mjs
Remove WORKFLOW_CAPABILITIES, automaticAttention, advanceAutomaticPr1 and its
helpers, hasParkedReply, releaseParkedRun and the unused PROMPT_TESTS
constant. No production or test code calls them. Drop the two parameters
that only advanceAutomaticPr1 passed. Remove the matching prompt text, set
the runner interface to draft and refresh the generated headers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…to release/0.1.32

# Conflicts:
#	prompts/cli/workflow-runner.prompt.md
#	src/workflow-runner.mjs
…to release/0.1.32

# Conflicts:
#	prompts/cli/workflow-runner.prompt.md
#	src/workflow-runner.mjs
…-rules

docs(skills,runbook): add ordered subagent handoffs, compact grid checks, and parallel Story rules (+12 / -12)
…dd-3376

fix(small-change): scope pdd-small-change strictly to files outside PDD (+58 / -59)
…ng-3377

fix(owner): match prompt owners by mirrored path and unique file name (+308 / -20)
Brings #3385 and the 0.1.32 release work into the integration branch.
Conflicts: the two job-rules docs take main's #3376 text; the seam test
keeps the fixture-based SEAM5 and its record gains 8 load lines for
main's new modules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep the runner interface as draft and refill its hash. Refresh the runner header.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of #3410: status still reads a saved gate.automaticHold, so the
runner prompt keeps the rule for its display. The parking prompt no
longer names the deleted hasParkedReply. Its interface is now draft, as
pdd test --fill-hash asks for a changed approved prompt. No approval
recorded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant