Skip to content

Remove static writePaths lock; detect concurrent lane overlap at spawn - #591

Merged
TheGreatAxios merged 2 commits into
mainfrom
cl-6952-remove-the-static-per-package-writepaths-lock-detect-concurrent-lane
Aug 24, 2026
Merged

Remove static writePaths lock; detect concurrent lane overlap at spawn#591
TheGreatAxios merged 2 commits into
mainfrom
cl-6952-remove-the-static-per-package-writepaths-lock-detect-concurrent-lane

Conversation

@TheGreatAxios

@TheGreatAxios TheGreatAxios commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Closes CL-6952. Removes the static per-package writePaths authz lock (DirectorPackage.writePaths, AgentProfile.writePaths, and the gate.ts enforcement block at the old lines 394-413, plus write-path-policy.ts and its test) and replaces it with detection of concurrent lane overlap at spawn.

No shipped director ever set a non-empty writePaths (registry.test.ts explicitly asserted this) — this removes dead enforcement that only ever read as a live guarantee, not a working one.

What was deleted:

  • DirectorPackage.writePaths / AgentProfile.writePaths and all propagation through registry.ts, task-tool.ts, RunSubAgentParams, SubAgentIdentity.
  • The permission-gate enforcement block in gate.ts and the now-dead write-path-policy.ts (matchesWritePathAllowlist / writePathDeniedReason) plus its test file.

What replaced it:
A non-blocking conflict detector inside the existing task() dispatch in task-tool.ts. Each running dispatch is tracked (by call id) with the cwd it resolved to; a new dispatch checks currently-running lanes for one already working in the same cwd and records a concurrent-lane-overlap entry (new conflict class in intervention-log.ts) if so. A lane is removed from tracking the moment its dispatch finishes, so sequential work against the same cwd is never flagged.

Judgement calls:

  • Intended scope: task() has no field for a caller to declare which paths a dispatch will touch, so nothing more precise than cwd is honestly knowable at spawn. Worktree-isolated lanes get a fresh, disjoint directory by construction and can never collide on this check; it only fires in the shared-cwd fallback, which is exactly the one mode where two lanes can really overwrite each other's writes.
  • Block vs warn vs record: record only, never block. Two lanes sharing a cwd doesn't prove they touch the same files, only that they could — refusing the spawn on that alone would invent precision the signal doesn't have, which is worse than no check at all.
  • Where to log it: intervention-log.ts, since it already tracks parent-side dispatch signal (refusals, outcomes) for this task tool instance. Added conflict as a new InterventionClass rather than overloading block/nudge, which mean something more specific (actually refusing/injecting).

Docs updated to match: docs/IMPLEMENTATION.md (5 spots — module table entries for task-tool.ts/identity-context.ts/gate.ts, the packageToProfile mapping note, and the primary-role/leaf-writePaths notes), docs/ARCHITECTURE.md (director-package field list, docs/design director tool-envelope note, primary-role note), and docs/PRODUCT.md (primary-role paragraph) — all previously described writePaths as an existing, enforced feature.

Gate: bun run check green — lint 0 errors, tsc clean, build succeeds, 5363 tests pass.

Deletes DirectorPackage.writePaths / AgentProfile.writePaths and the
gate.ts enforcement that read them (write-path-policy.ts and its test
are now dead and removed). No shipped director ever set a non-empty
writePaths, so this was already unenforced-in-practice authz machinery
that read as active.

Replaces it with a non-blocking conflict detector in the task tool:
each running dispatch is tracked by call id and resolved cwd; a new
dispatch that shares a still-running lane's cwd is recorded (not
blocked) as a concurrent-lane-overlap intervention. A completed lane
is removed before the next dispatch starts, so sequential work against
the same cwd never triggers it.

Judgement calls:
- task() has no field for a caller to declare which paths a dispatch
  will touch, so cwd is the only intended-scope signal honestly
  available at spawn. Worktree-isolated lanes get distinct cwds by
  construction and can never collide here; this only fires in the
  shared-cwd fallback, which is the one case where two lanes can
  really overwrite each other.
- Warn/record, not block: cwd equality does not prove two lanes touch
  the same files, only that they could, so refusing the spawn would
  invent precision the signal does not have.
- Recorded in intervention-log.ts (new "conflict" class) rather than a
  separate mechanism, alongside the existing parent-side refusal/outcome
  records it already keeps for this task tool instance.
@linear-code

linear-code Bot commented Aug 24, 2026

Copy link
Copy Markdown

CL-6952

docs/IMPLEMENTATION.md, docs/ARCHITECTURE.md, and docs/PRODUCT.md still
described DirectorPackage/AgentProfile writePaths as an existing,
enforced feature. Update all references to describe what actually
happens now: no static write-path declaration, and a shared-cwd lane
overlap is recorded as a conflict intervention rather than gated.
@TheGreatAxios
TheGreatAxios merged commit 63ec5c1 into main Aug 24, 2026
5 checks passed
TheGreatAxios added a commit that referenced this pull request Aug 24, 2026
Resolved against the writePaths removal (#591) and requiredSections
removal (#588): kept this branch's directorId gate key, dropped every
writePaths reference including the registry guard test, since the field
no longer exists.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant