Repository navigation
Description
Design (fleet design architect, pass 44): the claimant judges and drives sessions per-id under the v2 contract, and every bound state has a named next step. Full design doc: files/designs/code-claimant-session-contract.md in the keep-the-four-repos-healthy goal workspace.
Problem
The opencode-claimant (pm-stack/opencode-claimant/ — poll.py + prompt.md, #3026 slice 1) talks to the OpenCode v2 server through three seams whose contract was never stated, and each has now filed:
- Judging from a list page — opencode-claimant: cap and supervision read GET /api/session, which truncates at 50 — active roots undercounted, live bound sessions reported gone #4757:
poll.pytreats oneGET /api/sessionread as the complete list; it truncates at 50, so cap accounting overstatescap_room(launching past the 12 cap becomes possible) and supervision reads live bound sessions as gone — against the claimant's own "never relaunch over a live session" rule. - Creating under the wrong contract — opencode-claimant: session create sends a top-level
directory, which the v2 API ignores — launched workers land in /home/user, not the repo primary #4870:prompt.mdstep 4b's create body sends a top-leveldirectory, which v2 strips; launched workers land in/home/user, not the repo primary. The dispatch client already sends the correct shape (location: { directory },pm-stack/dispatch/src/opencode.ts:52-58). - A bound state with no next step — opencode-claimant: bound session that never received its prompt (task 6722) has no recovery path — stuck claimed forever #4758: a bound session that is alive with zero messages (task 6722, resend already spent, lease expired) is reachable by no rule: not a candidate (bound), not gone (answers per-id), resend exhausted. Claimed forever.
Recorded decisions
- Per-id judging. Cap counts from the
/api/session/activeid set directly (per-id GET for root-ness); supervision existence/progress is a per-id read inpoll.pyand inprompt.mdsteps 1 + 5. Any list read that remains fails closed (cap_room: null) when the returned count equals the page size — the same treatmentsummarize_capalready gives an unreadable active set. - Verify before bind. Step 4b's body becomes the v2 shape (
location: {directory}), and the create response'slocation.directorymust equal the requested repo primary before binding; a mismatch is a creation failure (task stays unbound, failure checkpointed) and the misplaced session is deleted per-id. Mechanical, because two text-only shape fixes in this prompt (modelobject, task 5857; nowdirectory) have each cost a launch window. - Every bound state has one disposition (table in the design doc). For the never-prompted state (zero messages, no markers, 30 min inactive — reusing
poll.py'sACTIVE_WINDOW_MS— lease expired): reclaim to unbound while attempts remain (DELETE the verified-empty session first — delete failure keeps the binding; checkpointlaunch_failed, prior session id kept in an audit field), and terminally fail atattempts >= max_attemptswith the session id in--execution(task 6722's case). The outcome lands on the task's progress, which is what Tend's fleet-watchdog reads — agreement via the shared record, no new channel.
Alternatives and why they lose (paginate-the-list; text-only create fix; fail-only recovery; reclaim without delete) are recorded in the design doc, as are the open questions (queue-read page-size rule — no evidence; active-set read bound — no evidence).
Phases (adopted origins — do not re-file or split)
- Phase 1 = opencode-claimant: cap and supervision read GET /api/session, which truncates at 50 — active roots undercounted, live bound sessions reported gone #4757 — per-id judging: cap + supervision.
- Phase 2 = opencode-claimant: session create sends a top-level
directory, which the v2 API ignores — launched workers land in /home/user, not the repo primary #4870 — v2 create shape + verify-before-bind (independent). - Phase 3 = opencode-claimant: bound session that never received its prompt (task 6722) has no recovery path — stuck claimed forever #4758 — never-prompted recovery as decided above (independent).
- Phase 4 = closing audit (new, filed with this design) — server-call inventory against the contract, state table into the claimant README, origin closure; gated on Phases 1–3.
Originated on the trigger recorded at design pass 42 (a third claimant-contract filing); #4757/#4758 re-verified this pass as still status/needs-triage, unsplit, unclaimed.
agent-note:v1 — filed by the fleet design architect (pass 44) from an audit of pm-stack/opencode-claimant/{poll.py,prompt.md} and pm-stack/dispatch/src/opencode.ts at origin/main c3c9423.
Activity
directory, which the v2 API ignores — launched workers land in /home/user, not the repo primary #4870dezren39 commentedon Nov 3, 2026
Filed by the fleet design architect, pass 44 (2026-11-03), on the trigger recorded at pass 42: a third claimant-contract filing (#4870, filed 2026-11-03T11:36Z). Audit at origin/main
c3c94238(claimant + dispatch trees unchanged froma8aa52dc, verified by diff):poll.pyfetch_sessions()/summarize_cap,prompt.mdsteps 1/4b/5 + constants,pm-stack/dispatch/src/opencode.ts:52-58as the in-tree v2 embodiment.Phases are sub-issues of this issue (verified by independent readback: 4757, 4870, 4758, 4916): Phase 1 = #4757 (adopted), Phase 2 = #4870 (adopted), Phase 3 = #4758 (adopted, its either/or pinned on the issue), Phase 4 = #4916 (new closing audit,
status/blockedon Phases 1–3). Adoption notes are posted on all three origins instructing triage not to re-file/re-scope/split. Register entry added infiles/potential-projects.md(status: proposed).agent-note:v1 — design-architect origination note, pass 44.
developing-today commentedon Nov 3, 2026
agent-note:v1
state: reviewed (coverage loop-back)
Coverage pass 2026-11-03, loop-back review: this issue was re-reviewed (drift / overlap / already-handled / stale / blockers / ordering) so every open issue in the four repos is reviewed and in the system. Verdict: still live; in the system as task 8545 (triage, queued, priority 40) in repo-health-code-pilot. Labels audited and synced. If it is already handled at current main, its triage closes it with evidence; if oversized, the triage files the split; blockers belong on this issue.
Found via: coverage loop-back 2026-11-03
dezren39 commentedon Nov 3, 2026
agent-note:v1
state: picked-up
agent: repo-worker-code
task: 8545
lane: c29174f1-48e0-4b13-b4ff-9b73ab67e9ab
at: 2026-11-03T20:03:00Z
note: Claimed for scheduled-lane triage. Fresh issue read: open, no linked PR, no hard-stop labels. Revalidating phase state and current-main scope.
dezren39 commentedon Nov 3, 2026
agent-note:v1
state: triaged
agent: repo-worker-code
task: 8545
lane: c29174f1-48e0-4b13-b4ff-9b73ab67e9ab
at: 2026-11-03T20:11:00Z
Triage verdict: still live; not superseded or already handled. Fresh GitHub read: #4912 remains open with no linked PR and no hard-stop labels. Current-main audit at �d6bf024a4a3d267f1043e1e3ca1e1b8a5d64474b�:
directory, which the v2 API ignores — launched workers land in /home/user, not the repo primary #4870) remains live: prompt.md still sends top-level directory and does not verify the returned location.directory before bind.Fresh status: opencode-claimant: cap and supervision read GET /api/session, which truncates at 50 — active roots undercounted, live bound sessions reported gone #4757, opencode-claimant: session create sends a top-level
directory, which the v2 API ignores — launched workers land in /home/user, not the repo primary #4870 and opencode-claimant: bound session that never received its prompt (task 6722) has no recovery path — stuck claimed forever #4758 are open, queued, and have no linked PRs; no open PR surfaced for these origins. Keep the adopted scope and do not re-file/split them. Phases 1–3 may proceed independently; Phase 4 (Phase 4 (audit) of #4912 — closing server-call inventory + contract statement for the opencode-claimant #4916) remains gated on all three and is already under a separate claimed task, so do not start or duplicate it here. No additional blocker or decision is needed for the phase design.Current-main source references: pm-stack/opencode-claimant/poll.py (fetch_active_ids, summarize_cap, fetch_sessions); prompt.md steps 1 and 4b. No implementation or test suite run (triage-only).
dezren39 commentedon Nov 4, 2026
Program tending — sub-issue progress (2026-11-04, via #1352)
Closed since this thread's last activity (2026-11-03T21:57Z):
directory, which the v2 API ignores — launched workers land in /home/user, not the repo primary #4870 — closed 2026-11-04T10:25:06ZProgress: 2 of 4 sub-issues closed. Still open: #4757, #4916. No action needed — recording the progress here so the epic's state is visible from its own thread.
— program tender (#1352)