plan-overlap and lease-check disagree on directory-lease semantics #132

Closed
opened 2026-08-15 14:33:35 +00:00 by john · 1 comment
Owner

Source: deep dive F2
Verdict: AGREE - high

Claim as reviewed

plan-overlap compares declarations using exact string equality while the execution lease checker interprets a declaration ending in / as a directory prefix, so overlapping plans can pass the parallel-safety gate.

At HEAD f354864 (v3.3.0)

cadence-core/bin/planning.mjs:1772-1777 - declared[i].files.filter((x) => declared[j].files.includes(x)) - exact string intersection.

cadence-core/bin/planning.mjs:2201-2207 - const prefixes = declared.filter((f) => f.endsWith('/')); ... !prefixes.some((d) => p.startsWith(d)) - trailing slash is a directory lease.

cadence-core/workflows/execute.md:103-121 requires an empty overlaps array as the arithmetic half of the parallel decision.

Plan 1 declaring src/ and Plan 2 declaring src/auth.js produce an empty intersection, so the phase is eligible for parallel worktree execution, while lease-check authorizes both plans to stage src/auth.js. Nested directory declarations (src/ and src/auth/) have the same defect.

Note

Bounding fact: cadence-core/references/plan-frontmatter.md never documents the trailing-slash directory form as a files: value, so a planner is unlikely to emit one today. That limits likelihood, not validity - lease-check honors the form, so it is live.

Fix shape: one shared lease-normalization/intersection module consumed by both cmdPlanOverlap and cmdLeaseCheck. Two leases collide when equal, or when either is a directory lease whose prefix contains the other path.

**Source:** deep dive F2 **Verdict:** AGREE - high ### Claim as reviewed `plan-overlap` compares declarations using exact string equality while the execution lease checker interprets a declaration ending in `/` as a directory prefix, so overlapping plans can pass the parallel-safety gate. ### At HEAD f354864 (v3.3.0) `cadence-core/bin/planning.mjs:1772-1777` - `declared[i].files.filter((x) => declared[j].files.includes(x))` - exact string intersection. `cadence-core/bin/planning.mjs:2201-2207` - `const prefixes = declared.filter((f) => f.endsWith('/')); ... !prefixes.some((d) => p.startsWith(d))` - trailing slash is a directory lease. `cadence-core/workflows/execute.md:103-121` requires an empty `overlaps` array as the arithmetic half of the parallel decision. Plan 1 declaring `src/` and Plan 2 declaring `src/auth.js` produce an empty intersection, so the phase is eligible for parallel worktree execution, while `lease-check` authorizes both plans to stage `src/auth.js`. Nested directory declarations (`src/` and `src/auth/`) have the same defect. ### Note Bounding fact: `cadence-core/references/plan-frontmatter.md` never documents the trailing-slash directory form as a `files:` value, so a planner is unlikely to emit one today. That limits likelihood, not validity - `lease-check` honors the form, so it is live. Fix shape: one shared lease-normalization/intersection module consumed by both `cmdPlanOverlap` and `cmdLeaseCheck`. Two leases collide when equal, or when either is a directory lease whose prefix contains the other path.
john added this to the v3.5.2 milestone 2026-08-15 15:06:08 +00:00
Author
Owner

Hazard: this is the parallel-safety gate, being fixed under parallel execution

v3.5.2 pairs this with #133. The two share no files - #132 is planning.mjs (cmdPlanOverlap, cmdLeaseCheck), #133 is ~16 workflow/reference prose files plus the flags they call - so plan-overlap will report empty and the phase is eligible for parallel worktree execution.

That is exactly the mechanism under repair here. If these run as parallel plans, the gate authorizing that parallelism is the code one of them is rewriting.

Run this milestone sequentially, or put #132 in its own phase. Not because a collision is likely, but because a green parallel run of the phase that fixes the parallel gate proves nothing about the gate.

Scope

One shared lease-normalization/intersection helper, consumed by both cmdPlanOverlap (planning.mjs:1772-1777, currently exact .includes) and cmdLeaseCheck (:2201-2207, currently trailing-/ prefix). Two leases collide when equal, when either is a directory lease whose prefix contains the other, or when they normalize to the same repo-relative path.

Also decide the grammar question

cadence-core/references/plan-frontmatter.md documents the files: grammar and never mentions the trailing-slash directory form, while cmdLeaseCheck honours it. That gap is why this defect is unlikely to have fired yet.

So there are two coherent fixes and the plan should pick one deliberately:

  1. Support directory leases properly - shared helper, and document the form in plan-frontmatter.md.
  2. Drop directory leases - cmdLeaseCheck stops treating trailing / as a prefix, and both sides are exact. Smaller, and consistent with a grammar that never advertised the form.

Option 2 is the smaller change and closes the divergence outright. Option 1 keeps a capability nothing currently documents. Do not land a shared helper without answering which of these the grammar is supposed to say.

## Hazard: this is the parallel-safety gate, being fixed under parallel execution v3.5.2 pairs this with #133. The two share no files - #132 is `planning.mjs` (`cmdPlanOverlap`, `cmdLeaseCheck`), #133 is ~16 workflow/reference prose files plus the flags they call - so `plan-overlap` will report empty and the phase is eligible for parallel worktree execution. That is exactly the mechanism under repair here. If these run as parallel plans, the gate authorizing that parallelism is the code one of them is rewriting. **Run this milestone sequentially, or put #132 in its own phase.** Not because a collision is likely, but because a green parallel run of the phase that fixes the parallel gate proves nothing about the gate. ## Scope One shared lease-normalization/intersection helper, consumed by both `cmdPlanOverlap` (`planning.mjs:1772-1777`, currently exact `.includes`) and `cmdLeaseCheck` (`:2201-2207`, currently trailing-`/` prefix). Two leases collide when equal, when either is a directory lease whose prefix contains the other, or when they normalize to the same repo-relative path. ## Also decide the grammar question `cadence-core/references/plan-frontmatter.md` documents the `files:` grammar and never mentions the trailing-slash directory form, while `cmdLeaseCheck` honours it. That gap is why this defect is unlikely to have fired yet. So there are two coherent fixes and the plan should pick one deliberately: 1. **Support directory leases properly** - shared helper, and document the form in `plan-frontmatter.md`. 2. **Drop directory leases** - `cmdLeaseCheck` stops treating trailing `/` as a prefix, and both sides are exact. Smaller, and consistent with a grammar that never advertised the form. Option 2 is the smaller change and closes the divergence outright. Option 1 keeps a capability nothing currently documents. Do not land a shared helper without answering which of these the grammar is supposed to say.
john closed this issue 2026-08-16 16:39:37 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: crenshawdev/cadence-archived#132
No description provided.