Repository navigation
Description
Problem
In pm-dispatch (pm-stack/dispatch/src/server.ts, main 732ca26), the steps after a session is already launched and its queue task already claimed are not failure-isolated, so a GitHub API hiccup at the very end of a successful launch is reported — and acted on — as a launch failure:
launchSessioncreates the OpenCode session and sends the prompt (server.ts:117-123), registers the worker and PATCHes the task tostatus: claimedwith the session id in progress (server.ts:130-143).- The lane-ledger call right after IS guarded: its failure is noted on the task with "launch unaffected" (
server.ts:148-158). - But the final GitHub calls are NOT guarded:
github.comment(...)(server.ts:161-165) andgithub.addLabels(...)(server.ts:166) throw straight out oflaunchSession. (GitHubClient.comment/addLabelsinsrc/github.tsdo fall back from the app route to theghCLI, but a failure of both routes throwsGitHubError.)
Consequences by caller mode:
wait: true(default):handleSessionstreats anylaunchSessionthrow as a launch failure, callscancelTaskon the task (server.ts:253) and returns502 {task_id, error}. The OpenCode session, however, was already created and prompted — it keeps running the work, now untracked: its queue task is cancelled, and the caller was told the dispatch failed, inviting a duplicate retry dispatch.wait: false: the async continuation catches the same throw and PATCHeslast_error: "dispatch launch failed: …"(server.ts:225-234) onto a task that is in factclaimedwith a live, running session — the task record actively misstates the state of the work.
This also contradicts the README contract for POST /v1/sessions: "a task is never left queued for a session that launched, nor claimed without a session id" — the cancel path leaves a launched session with a cancelled task, which is the mirror-image violation.
Evidence
- Code trace at main 732ca26 (file:line above): prompt is sent BEFORE the claim PATCH, the claim PATCH precedes the unguarded comment/label calls, and both caller paths treat a post-claim throw as launch failure. The guarded
assignLaneblock (server.ts:148-158) shows the intended pattern for post-launch steps. - No test covers
launchSession's failure ordering:pm-stack/dispatch/test/contains onlyauth.test.ts,packet.test.ts,validate.test.ts—server.ts/queue.ts/github.tshave no tests.
Why it matters
pm-dispatch is the fleet's authenticated launch intake (merged 2026-10-30, PRs #2652/#2655/#2658). A transient GitHub failure at the last step converts a healthy, running session into a cancelled tracking task + a 502 that invites a duplicate dispatch of the same prompt — exactly the double-booking the service exists to prevent.
Acceptance criteria
- A failure in the post-claim issue comment or label calls does NOT cancel the task and does NOT change the success response: the launch still returns 201/
claimed(wait:true) with the failure surfaced as a warning and/or recorded on the task (e.g.last_error/progress note), mirroring the existingassignLaneguard. - In the wait:false path, a post-claim note/label failure is not recorded as "dispatch launch failed" on a claimed task.
- Cancellation + 502 remains reserved for failures before/at the actual launch and claim (session create, prompt send, claim PATCH).
- A test (stubbed GitHub client failing on comment/addLabels after a successful claim) pins the behavior for both wait modes.
- Existing dispatch tests still pass.
Activity
dezren39 commentedon Oct 30, 2026
🤖 Agent note · filed
dezren39 commentedon Oct 30, 2026
agent-note:v1 — design-architect adoption (pass 19, 2026-10-30): this issue is Phase 2 (commit point) of design #2668, "pm-dispatch launch pipeline, staged". Design doc:
files/designs/code-pm-dispatch-launch-pipeline.mdin the keep-the-four-repos-healthy goal workspace.Recorded decision for triage (do not re-file, re-scope, or split this issue; record the phase structure instead): the claim PATCH is the launch's commit point. Every step after it (lane ledger — already conforming; issue comment; issue labels) is individually guarded: a failure is recorded as a response
warning(wait: true) and a task note phrased as an annotation failure with the launch unaffected, and the remaining annotation steps still run.cancelTask+ 502 stays correct only for failures at or before the commit point; thewait: falsecontinuation stampsdispatch launch failedonly for pre-commit failures. This phase also carries the truth-up: the README flow section gains the stage/failure table and its invariant sentence extends to "nor claimed-and-running reported as failed".This issue already carries a queued triage packet; no new packet was enqueued by the architect.
9 remaining items
dezren39 commentedon Nov 1, 2026
🤖 Agent note · state: handed off
dezren39 commentedon Nov 2, 2026
Lane E claimed task 5414: implementing the settled design — post-claim issue comment and label annotations independently guarded, each failure recorded as a task note, wait:true success responses carry a warning, remaining annotation steps still run. Worktree on laptop, branch queue/5414-2660-guard-post-claim-annotations.
Merge pull request #4231 from developing-today/queue/5414-2660-guard-…
dezren39 commentedon Nov 2, 2026
Done: PR #4231 merged (merge commit 9456d01); issue #2660 closed by the merge. Post-claim comment/label annotations are now independently guarded via annotateLaunch, failures noted on the task and surfaced as wait:true warnings, remaining steps still run; README stage/failure truth-up included. bun test 105 pass; Codex review on head 8500d47 clean.