You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Decide the concurrency model: live Runs per Workspace and per Secant instance #102
Which Runs may be live at the same time, and who owns them? The recorded rule is one live Run per Workspace path across all Secant processes (#4, 2026-08-23: "two Runs editing one repository would have each one's Git steps observing the other's half-finished work"; enforced by the Workspace claim and owner fencing of #16 and ADR 0023; ADR 0019 says blocked holds the claim). #21 (2026-09-01) added: one ephemeral process per invocation, two processes on one home are legal, a Run live in another process refuses to open.
The M2 audit (#94, rows A5, A6, S2, S3) found the code releases the claim on blocked, offers actions another Run will refuse, and reconciles a live Run in another process as dead. The human's position in the grilling: enable, do not restrict. N live Runs per Workspace are fine, with the same or different Bundles; each Run is owned by exactly one instance and a second instance is refused for that Run only; Workspace collisions are the user's problem, and the Materialization conflict already halts the later writer.
Sub-questions to settle in one grilling: may one instance run two Runs at once (with async execution the natural answer is yes, in the background; how does the Workbench present that and how does Previous Runs mark live Runs)? Does the Workspace claim disappear or become advisory? What replaces "claim present = dead process" at startup reconciliation once a Run can be live elsewhere (#98 adds an owner PID probe)? Which ADR 0019 and ADR 0023 sentences and which M2 spec story (#76 US26) change, with the reason recorded?
Output: the decision comment, the ADR amendments, and the implementation tickets cut as sub-issues of #75 blocking it (they are blocked by the audit's #98).
Cut from the M2 audit (#94) as a hand-over that the human chose to have decided and implemented inside M2; it blocks #75 with a native edge. Its implementation tickets are cut by this grilling as sub-issues of #75, blocked by #98 (which adds the owner-PID liveness probe and defers Run settlement, the shape any model builds on) and blocking #101 (the drizzle conversion waits for the final coordination schema).
Reading rule. Read the recorded decisions first (#4, #16, #21) so the grilling starts from what was decided and why, then the audit rows that show where the code diverged, then the ADR sentences that would change. OpenCode is the comparison for "many live sessions in one process".
Input
Why it matters
Authority
#4 decision comment (2026-08-23) "One live Run per Workspace… two Runs editing one repository would have each one's Git steps observing the other's half-finished work"
The rule being re-decided and its recorded reason.
The Workspace claim and owner fencing that enforce it; what fencing protects independent of the rule (stale writers after a crash).
Canonical
#21 runtime decision (2026-09-01) "one ephemeral process per invocation… coordination.db fencing arbitrates concurrent invocations… a Run live in another process refuses to open"
Multi-process is already legal; only two live Runs on one Workspace path are forbidden today.
Where the code releases the claim on blocked, offers actions another Run refuses, and reconciles a live Run in another process as dead; the human's stated position ("we are enablers not restrictors").
How several live Runs would present in the Workbench and Previous Runs.
Advisory
Local OpenCode checkout, packages/opencode/src/session/run-state.ts and effect/runner.ts
Many sessions live per process, one runner each, per-session state machine, no global lock.
Reference
Sub-questions the grilling settles: N live Runs per Workspace or one; ownership per Run per instance; one instance running several Runs (Workbench and Previous Runs presentation); whether the Workspace claim disappears or becomes advisory; what replaces the claim at startup reconciliation; which ADR 0019/0023 sentences and spec stories change, with the reason recorded.
Decision. Any number of Runs may be live in one Workspace, from the same or different Bundles. Each live Run has exactly one Run owner; a second Secant instance is refused for that Run only. The Workspace claim is deleted, not made advisory. Recorded in ADR 0031.
Reason recorded.#4's only justification for one live Run per Workspace was "two Runs editing one repository would have each one's Git steps observing the other's half-finished work"; #14 removed Git Steps, so the premise names nothing in the product. #21 had already scoped cross-process refusal to the single Run. #94's rule applies: "Secant enables rather than restricts" (that is the verbatim wording; the Starting context's "we are enablers not restrictors" is a paraphrase). OpenCode, the practice baseline, runs many live sessions per process with no per-directory lock.
Sub-questions settled.
Question
Answer
Live Runs per Workspace
Unbounded. Workspace collisions are the user's; the Materialization conflict stays the only detection and covers only home: workspace Artifacts.
Ownership record
Per Run in coordination.db: nullable owning process id plus fencing epoch. NULL is unowned. The state column and the one_live_run partial unique index are deleted.
Does blocked hold ownership
Yes, while the owning instance is alive. A Review checkpoint is answered in the instance that reached it. Ownership is released only when the Run rests, is deleted, or is taken over.
Startup reconciliation
Whoever opens a Workspace group probes each owned Run's process. Alive: left live, listed as live elsewhere, refused to open with the owner named (#21 unchanged). Dead: a running Run rests halted with the indeterminate marker as today; a derived-blocked Run stays blocked with ownership released, because nothing was cut off. This replaces "claim present = dead process" and closes the A5 micro-window.
Takeover
Resume of a Run whose owner appears alive is offered behind one confirmation naming the owner. Fencing makes it safe by construction (the epoch bump refuses the stale owner's next write); the probe is only a courtesy against accidents and process-id reuse.
One instance, several Runs
Yes. Leaving the Workbench leaves the Run running; launching while others are live is not prompted; Previous Runs rows gain a live marker and follow durable updates; the Run header says live here or live in another instance. No tabs or split panes.
Quitting with live Runs
q asks one confirmation naming the count, then halts every live Run through the SIGINT path and quits.
Cross-instance observation
Stays deferred per #21; observe and own remain one fencing operation.
Recording
New ADR 0031; ADR 0019 and ADR 0023 gain amendment sections pointing at it (superseding decision, the allowed reason).
Rejected. An advisory launch warning (a gate under another name); releasing ownership on blocked (ownership split by state the Workbench would have to explain); read-only observation now; keeping state beside the owner id.
Text changed. ADR 0031 added; ADR 0019 and ADR 0023 amended; glossary crucible-run-lifecycle.md (Run owner definition, the ownership rule, related decisions). Spec #76 lines on grouping, US26, the Run Store section, the narrower-Interface seam, and the Windows risk row now state the per-Run model. #98's owner-liveness bullet and acceptance criterion now leave the Run live and refuse only opening that Run. #101's dependency line and the unique-index acceptance criterion now reference #103 and #104 and the per-Run schema. src/run/store/AGENTS.md is rewritten by #103 when the code changes, not before.
Implementation tickets (sub-issues of #75, blocked by #98, blocking #101):
Activity
Sandstorm831 commentedon Sep 14, 2026
Starting context
Cut from the M2 audit (#94) as a hand-over that the human chose to have decided and implemented inside M2; it blocks #75 with a native edge. Its implementation tickets are cut by this grilling as sub-issues of #75, blocked by #98 (which adds the owner-PID liveness probe and defers Run settlement, the shape any model builds on) and blocking #101 (the drizzle conversion waits for the final coordination schema).
Reading rule. Read the recorded decisions first (#4, #16, #21) so the grilling starts from what was decided and why, then the audit rows that show where the code diverged, then the ADR sentences that would change. OpenCode is the comparison for "many live sessions in one process".
:11-12,35-36coordination.dbfencing arbitrates concurrent invocations… a Run live in another process refuses to open":24-26runningandblocked": the sentence that changes or stays.blocked, offers actions another Run refuses, and reconciles a live Run in another process as dead; the human's stated position ("we are enablers not restrictors").:800-842, src/run/store/AGENTS.mdpackages/opencode/src/session/run-state.tsandeffect/runner.tsSub-questions the grilling settles: N live Runs per Workspace or one; ownership per Run per instance; one instance running several Runs (Workbench and Previous Runs presentation); whether the Workspace claim disappears or becomes advisory; what replaces the claim at startup reconciliation; which ADR 0019/0023 sentences and spec stories change, with the reason recorded.
Sandstorm831 commentedon Sep 14, 2026
Resolution (2026-09-14)
Decision. Any number of Runs may be live in one Workspace, from the same or different Bundles. Each live Run has exactly one Run owner; a second Secant instance is refused for that Run only. The Workspace claim is deleted, not made advisory. Recorded in ADR 0031.
Reason recorded. #4's only justification for one live Run per Workspace was "two Runs editing one repository would have each one's Git steps observing the other's half-finished work"; #14 removed Git Steps, so the premise names nothing in the product. #21 had already scoped cross-process refusal to the single Run. #94's rule applies: "Secant enables rather than restricts" (that is the verbatim wording; the Starting context's "we are enablers not restrictors" is a paraphrase). OpenCode, the practice baseline, runs many live sessions per process with no per-directory lock.
Sub-questions settled.
home: workspaceArtifacts.coordination.db: nullable owning process id plus fencing epoch.NULLis unowned. Thestatecolumn and theone_live_runpartial unique index are deleted.blockedhold ownershiprunningRun restshaltedwith theindeterminatemarker as today; a derived-blockedRun staysblockedwith ownership released, because nothing was cut off. This replaces "claim present = dead process" and closes the A5 micro-window.qasks one confirmation naming the count, then halts every live Run through the SIGINT path and quits.Rejected. An advisory launch warning (a gate under another name); releasing ownership on
blocked(ownership split by state the Workbench would have to explain); read-only observation now; keepingstatebeside the owner id.Text changed. ADR 0031 added; ADR 0019 and ADR 0023 amended; glossary
crucible-run-lifecycle.md(Run owner definition, the ownership rule, related decisions). Spec #76 lines on grouping, US26, the Run Store section, the narrower-Interface seam, and the Windows risk row now state the per-Run model. #98's owner-liveness bullet and acceptance criterion now leave the Run live and refuse only opening that Run. #101's dependency line and the unique-index acceptance criterion now reference #103 and #104 and the per-Run schema.src/run/store/AGENTS.mdis rewritten by #103 when the code changes, not before.Implementation tickets (sub-issues of #75, blocked by #98, blocking #101):
blocked, dead-owner reconciliation, takeover.Sandstorm831 commentedon Sep 14, 2026
Resolved above; ADR 0031 and the amendments land in the docs commit, implementation in #103 and #104.
docs(#102): own Runs per Run, not per Workspace (ADR 0031)
feat(#103): own Runs per Run in the Run Store — no Workspace claim, o…