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
Copy file name to clipboardExpand all lines: docs/SESSION-DRIFT-CONTROLS.md
+18-1Lines changed: 18 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -307,6 +307,23 @@ and `prune-merged.ps1` are sibling-only, so the nested population — where ever
307
307
— has creation but no scripted teardown, and `prune-merged.ps1` run from a worktree prints a green
308
308
"No sibling worktrees to consider" and exits 0. A wrong-cwd run reports a clean bill of health.
309
309
310
+
> **Half fixed, 2026-07-30.** `prune-merged.ps1` now **refuses** from anywhere but the primary (exit 2,
311
+
> naming both paths) instead of reporting a green no-op, and it refuses to remove any sibling that
312
+
> *contains* a nested worktree — a nested checkout is gitignored inside its parent, so the parent reads
313
+
> perfectly clean and `--force` used to delete both, leaving the nested one registered with no
314
+
> directory. A session in a nested tree now vetoes its ancestor too. Still true: the candidate set is
315
+
> sibling-only, so the nested population has no scripted teardown.
316
+
>
317
+
> **Correction, same day.** "The candidate set is sibling-only" was *stated* but not *true*. The set was
318
+
> a bare `<primary>-` **prefix match**, and `<primary>-pins/.claude/worktrees/x` starts with
319
+
> `<primary>-` — so a Claude-managed nested worktree under a **sibling** was a candidate in its own
320
+
> right and was removed, with its branch, while the containment veto above protected only its parent.
321
+
> Nested trees under the **primary** were excluded by the accident that `<primary>/` is not
322
+
> `<primary>-`, which is the only case anyone had tested. Fixed: anything nested inside another
323
+
> registered worktree, or carrying a `.claude/worktrees/` path segment, is excluded from the candidate
324
+
> set and unreachable by `-Name`. The teardown gap itself is unchanged — nested worktrees still have no
325
+
> scripted removal, they are now merely safe from this script.
326
+
310
327
### G12 — The gate has never produced a receipt — **FIXED**
311
328
312
329
`Write-Deny` writes JSON to stdout and exits 0. There is no log, no counter, no audit file. Nothing can
@@ -449,7 +466,7 @@ analysis must be redone.
449
466
| B7 | **Half done** | Rule 4 is opt-in, not retired — preserving the owner's decision while removing the trap where re-installing would activate it. |
450
467
| B10 | **Done** | One allowlist, shared by the gate and the backstop, with the legacy path kept as a fallback so a version-skewed installed copy cannot silently disarm the backstop. `install-selfheal.ps1` gained the `CLAUDECODE` refusal its sibling always had — the *higher*-privilege installer was the unprotected one. |
451
468
| B6 | **Started** | `.worktreeinclude` added, so the leak gate's gitignored token list reaches every worktree Claude Code creates itself (`--worktree`, desktop sessions, `isolation: worktree` subagents) — previously only `new.ps1`'s own worktrees got it, and a fresh first-party worktree could not commit at all. **Not** done: worktree-first as the documented default entry point, and `new.ps1` calling `git worktree lock` while a session is live. |
452
-
| B11 | **Started** | Rule 3d closes the worst of G9: `git worktree remove` / `move` on another session's checkout. **Not** done: the rest of the absent verbs (`rm`, `mv`, `sparse-checkout`, `checkout-index`, `bisect`, `branch -f`, `update-ref`, `read-tree`), `gh pr checkout`, and G11's teardown half — `prune-merged.ps1` is still sibling-onlyand still prints a green "nothing to consider" when run from the wrong cwd. |
469
+
| B11 | **Started** | Rule 3d closes the worst of G9: `git worktree remove` / `move` on another session's checkout. **Not** done: the rest of the absent verbs (`rm`, `mv`, `sparse-checkout`, `checkout-index`, `bisect`, `branch -f`, `update-ref`, `read-tree`), `gh pr checkout`, and G11's teardown half — `prune-merged.ps1` is still sibling-only. Its wrong-cwd green no-op is **fixed** (2026-07-30): it refuses with exit 2 and names both paths, and it will not `--force`-remove a sibling containing a nested worktree. |
453
470
454
471
Remaining order: the rest of B6, the rest of B11, then the B1/B3/B4 remainders.
Copy file name to clipboardExpand all lines: docs/releases/BACKLOG-MULTISESSION-PLAN.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -138,7 +138,7 @@ The three lanes are **file-disjoint by construction**. `ledger` owns `docs/BACKL
138
138
139
139
**Build steps**
140
140
141
-
1.**Write every banner fresh from the code you verify yourself. Never paste vault prose.**Measured: `vault/main:docs/BACKLOG.md` fails `scripts/security/scan_forbidden.py` with **102 hits** (customer/vendor tokens ×98, an estate token, a site-code pattern, two worktree slugs). Hits are concentrated in the vault's `#232-#307` range **but are not confined to it** — lines 594, 595, 5815, 5824, 6698 are inside the `#1-#231` range, and 5815/5824 sit inside `## 231.` itself, the very item this lane must correct. `docs/BACKLOG.md` is **not** in the leak gate's `docs/security/*` allowlist.
141
+
1.**Write every banner fresh from the code you verify yourself. Never paste vault prose.**The vault's copy of `docs/BACKLOG.md` fails `scripts/security/scan_forbidden.py`, and the hitsare **not** confined to the high-numbered range you would expect — several sit inside the `#1-#231` range, including inside `## 231.` itself, the very item this lane must correct. Assume any vault line may carry a token; the gate, not a memorised range, is the authority. `docs/BACKLOG.md` is **not** in the leak gate's `docs/security/*` allowlist.
142
142
2.**Edit only the leading `> <glyph>` banner block** of each `## N.` section. Leave the prose below it untouched.
143
143
3.**Banner invariant (`scripts/docs/backlog_status_check.py`).** The banner block runs from the heading through every blank-or-`>` line and terminates at the first non-blockquote line. Exactly one such block per item; a CLOSED glyph (`✅ ⛔ 🪦`) must **never** coexist with an OPEN one (`🔢 🚧`); two OPENs are legal. Several items carry two banner lines (#117 has `🛠`+`🔢`, #48 has `🔢`+`🔶`) — remove the stale OPEN one; `🛠`/`🔶` are not status glyphs and may stay. Re-run the checker after **every** commit.
144
144
4.**Every banner cites `path:line` or an ADR id.** The checker is structural — its own docstring says *"it cannot know whether a banner is truthful, only that a claim exists and does not contradict itself."*`origin/main` passes it **today**, with all 30 stale banners in place. A fabricated citation also passes. See the DoD.
0 commit comments