Activate parallel intra-tenant drains via per-task git worktrees, or stay serialize-only? (one-way-door topology call)

task-activate-intra-tenant-worktree-parallelism

task confidence asserted status blocked 2026-06-20 owner principal-architect
source principal-architect — disposed this one-way-door topology call 2026-06-20 after grounding in the actual code + records (worktree.ts mechanism built/proven; drainBoardSerialized + board-drain.mjs prove maxTasksPerRun=1 / single-drain / no concurrent scheduler; one early tenant RBA). Recorded as DEC-0062: defer, keep dormant, pin the design + a measured trigger. Supersedes the log-auditor-filed open question (confidence: inferred, 2026-06-20).

Activate parallel intra-tenant drains via per-task git worktrees, or stay serialize-only?

DISPOSED 2026-06-20 — DEFER (stay serialize-only). The Principal Platform Architect made the one-way-door call and recorded it as DEC-0062. This task is status: blockedblocked on a measured trigger, not on work. It is a clean stopping point, not a punt: the question is answered (do not activate now), the three sub-questions are resolved (in DEC-0062), and the only thing outstanding is the trigger that would re-open it for an FDE to build the pinned design.

The disposition

DEC-0053 §4 resolved intra-tenant concurrency by serializing drains per tenant now (Inv 4, shipped + live — drain-lock.ts) and "designing toward per-task git worktrees." That "design toward" obligation is fully discharged: the worktree isolation mechanism is built and offline-proven (packages/runtime/src/worktree.ts, packages/runtime/test/worktree.test.ts). The remaining call was whether to activate it, and the answer is not now:

  • Zero intra-tenant throughput pressure exists. drainBoardSerialized serializes per tenant; scripts/board-drain.mjs runs a single drainBoard with maxTasksPerRun: 1; there is no scheduler or Actions matrix dispatching concurrent drains; one early client tenant. Activation would take the actual one-way door (relaxing Inv 4 from a per-tenant to a per-task lock) to buy throughput nobody is requesting — premature complexity, YAGNI.
  • The mechanism stays built-but-dormant behind the proven withTaskWorktree seam, so activation is a flag, not a rewrite, the day it is warranted.

The trigger to re-open (see blocked_on_trigger + DEC-0062)

Re-open and route the build to the Principal Forward Deployed Engineer when all hold: (1) a real tenant has ≥3 sustained, simultaneously-claimable, independent tasks the single serial drain can't clear within its wake cadence; (2) that serial bottleneck misses an explicit written latency expectation; (3) per-tenant drain latency / queue depth is observable so the benefit is measurable. A bursty board or a dependency-chained backlog (which serializes anyway) does not trip it.

The three sub-questions — RESOLVED in DEC-0062 (no longer open)

  1. Merge topology → per-task branches open PRs the human gate (Inv 3) disposes via dispose.ts approveTask/rejectTask; not fast-forward to main (that would bypass the human-only done).
  2. Budget accrual → the per-team split (budget.ts decideTeamBudget) is the apportionment key; concurrent drains' spend sums into one tenant-level total before the post-drain enforceBudget; the board-pause kill switch stays tenant-level.
  3. The drain lock (THE one-way door) → a per-task sub-lock (worktree path = isolation unit) nested under a retained per-tenant coordination lease that caps concurrency and owns the summed accrual; the merge-to-main ref update stays serialized through the human gate. Inv 1/2/3/5/6/7 untouched by construction.