Skip to content

Decide the concurrency model: live Runs per Workspace and per Secant instance #102

Closed

Description

@Sandstorm831

Part of #2

Question

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).

Activity

  1. Sandstorm831 commented on Sep 14, 2026

    @Sandstorm831
    CollaboratorAuthor

    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".

    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. Canonical decision
    #16 Run Store decision and ADR 0023 :11-12,35-36 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. Canonical decision
    ADR 0019 :24-26 "the one-live-Run-per-Workspace rule covers only running and blocked": the sentence that changes or stays. Canonical
    Audit report rows A5, A6 and the decision rows S2, S3 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"). Canonical
    store.ts :800-842, src/run/store/AGENTS.md Startup reconciliation and the "claim, not state, tells a killed Run from a paused one" invariant that any new model must replace. Canonical
    M2 spec #76 US26 and "Run Store and the Artifact Module" The spec sentences that restate the rule. Canonical
    #23 Workbench IA 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.

  2. self-assigned this
    on Sep 14, 2026
  3. Sandstorm831 commented on Sep 14, 2026

    @Sandstorm831
    CollaboratorAuthor

    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.

    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):

  4. Sandstorm831 commented on Sep 14, 2026

    @Sandstorm831
    CollaboratorAuthor

    Resolved above; ADR 0031 and the amendments land in the docs commit, implementation in #103 and #104.

  5. added 2 commits that reference this issue on Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

wayfinder:context-readyWayfinding ticket has curated starting context and may be claimedwayfinder:grillingHITL grilling decision ticket

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions