Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 0 additions & 72 deletions docs/BACKLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6528,78 +6528,6 @@ the blanking here without measuring `#1086`'s false-deny rows in the same table.

**Source:** found 2026-08-06 by the must-keep-allowing inventory built for #1066, which enumerated what rule 3c allows today and found this in the gap between the shipped tests.

## 1069. Rule 3c matched the disarm key on the quote-blanked scan string, so a QUOTED key was invisible
> **THE QUOTED-KEY FAIL-OPEN IS FIXED 2026-08-27; the banner stays open for the archive pass, and the
> multi-word spelling below REMAINS OPEN BY DESIGN.** `Remove-QuotedSpans` now UNMASKS a quoted span
> holding a single BARE WORD -- no whitespace, quote, `$`, bracket, brace, semicolon, ampersand, pipe
> or backtick. Prose keeps its spaces and stays masked; a config key has none and becomes visible.
>
> **Measured before and after, with the UNQUOTED spelling as a known-answer control** (it denied in
> both arms, so an ALLOW below is a reading and not a dead probe): all five quoted spellings this row
> lists ALLOWED before and DENY after; three prose commit messages quoting `core.hooksPath` ALLOW in
> both arms, so the false-deny this item warns about was not admitted.
>
> **THE LENGTH-PRESERVING MASK THIS ROW PRESCRIBES WAS DELIBERATELY NOT BUILT, and the reason is a
> measurement rather than a preference.** Its stated rationale is that *"length preservation is what
> lets the same offsets read paths back out of the raw text afterwards"* -- and NO RULE DOES THAT.
> Every path site re-runs `[regex]::Match($seg.Raw, ...)` and computes its offsets inside `Raw` from
> scratch. Length-preserving masking would change what every OTHER rule sees, for zero benefit to the
> defect being closed. **Widening scope beyond the defect is precisely how the earlier attempt at this
> item acquired five new fail-opens**, which is the outcome this row's own DO-NOT-SHIP order records.
>
> The banked patch remains unshipped and untouched.
>
> **THE PIN EXISTS AND PASSES, so the re-score's "absent from tests/" clause below is SUPERSEDED, not
> wrong when written.** That reading was taken 2026-08-20 and the fix landed 2026-08-27, after it.
> Re-checked 2026-09-03: `test_a_QUOTED_MULTI_WORD_alias_value_is_still_invisible` lives in
> [`tests/test_worktree_gate_quoted_key.py`](../tests/test_worktree_gate_quoted_key.py) and the file
> is 10 passed. It asserts ALLOW deliberately, and its docstring says so: a DENY there is a BEHAVIOUR
> CHANGE to review, and the response is to invert the test and this banner together, never to delete
> either.
>
> **Re-verified 2026-09-03 on the REPOSITORY copy** of `scripts/hooks/worktree_gate.ps1`, blob
> `b194d0a0`, by driving the hook with constructed payloads against a throwaway governed repo -- no
> disarmed git command was ever run. The unquoted spelling is the KNOWN-ANSWER CONTROL and it DENIED,
> so the ALLOW rows are readings rather than a dead probe: `git config core.hooksPath /dev/null` DENY
> (control); `git config "core.hooksPath" /dev/null` DENY; `git -c "core.hooksPath=/dev/null" commit
> -m x` DENY; `git commit -m "do not set core.hooksPath in a worktree"` ALLOW, so the false deny this
> fix must not admit was not admitted; `git -c 'alias.ci=commit --no-verify' ci -m x` ALLOW, the class
> that is open by design.
>
> **A repo-copy reading is a statement about the SOURCE, not about the live gate on this machine.**
> The installed user-scope copy at `%USERPROFILE%\.claude\hooks\worktree_gate.ps1` is a DIFFERENT blob
> (`cd37d320`), so it is not this file. Read-only, it does carry this item's bare-word unmask and names
> `#1069`, so the two agree on THIS fix and differ somewhere else; nothing here measures where.

> 🔢 **Re-scored 2026-08-20 -> P2.** Value **7/10** · Difficulty **4/10** · _quick win_. Rule 3c still decides on $seg.Scan at worktree_gate.ps1:976-978 while Remove-QuotedSpans at :347-388 blanks every closed quoted span, so a quoted danger key is erased before the disarm regex runs; grep finds no length-preserving mask, no bare-word unmask, and the pinned ALLOW test the item names is absent from tests/. Value 7 because the fail-open needs no unusual spelling and disarms the ledger, claim and leak commit gates for every worktree at once with no compensating detection, but its blast radius is the developer harness rather than a deployment; difficulty 4 because the one written fix was rejected on verification after acquiring five new fail-opens, so the remainder is a scanner rewrite plus an adversarial test round. _(was 8/10 · 3/10.)_
>
> **Filed 2026-08-06 — a fix was WRITTEN and then REJECTED BY VERIFICATION, and ONE SPELLING OF THIS DEFECT REMAINS OPEN BY DESIGN. ⛔ DO NOT SHIP THE BANKED PATCH.** The round that closed this also introduced at least five new fail-opens; see #1061's banner. ⛔ The gate governing this machine is unchanged — still commit `a67838d2`, blob `3e7db362`.
> Verdict: build
> Closing-act: code

**Cluster:** Session-drift controls / gate integrity. **Priority:** P1. **Severity:** a FAIL-OPEN on `core.hooksPath` needing no unusual spelling — quoting an argument is ordinary.

**Mechanism.** Rule 3c matched the danger key against `$seg.Scan`, and `Get-ScannableSegments` BLANKS every quoted span before returning it. Quoting the key therefore erased it before the disarm list ever ran. Measured ALLOW on the committed gate, every one:

```
git -c "core.hooksPath=/dev/null" commit -m x
git -c 'core.hooksPath=/dev/null' commit -m x
git config "core.hooksPath" /dev/null
git config 'core.hooksPath' '/dev/null'
git config --add "core.hooksPath" /dev/null
git -c 'alias.ci=commit --no-verify' ci -m x
```

**Why matching the RAW text instead is not the fix.** It creates a false deny with a shape this workstream writes constantly: a commit message quoting the rule's own name would refuse. The fix is a LENGTH-PRESERVING quote mask that unmasks only a quoted span holding a SINGLE BARE WORD — no whitespace, separators, quotes, parentheses or `$`. Prose has spaces and stays masked; a quoted key does not and is seen. Length preservation is what lets the same offsets read paths back out of the raw text afterwards. Seven prose controls stay green.

**What is NOT closed, and it is the spelling that motivated the item.** A quoted span WITH whitespace stays masked, so `-c 'alias.<name>=<multi-word command>'` is still invisible — and because that value contains a space, quoting is its only writable spelling, so the whole class is open. Pinned as an ALLOW by `test_a_QUOTED_MULTI_WORD_alias_value_is_still_invisible` so a later change cannot close it silently or claim it was never there. Closing it wants a real argument tokeniser, and the one pass that built one acquired five fail-opens elsewhere in the process.

**The consolation is measured, not assumed:** the bare command such an alias exists to smuggle — `git commit --no-verify`, `git commit -n` — is ALLOWED by the committed gate, by the rejected patch and by this fix alike, and `-c` persists nothing (scope `command`, in-memory). The marginal capability the open spelling grants is small. It is not zero.

**Related:** #1066 (whose source note recorded this half and had no number to give it), #1065, #1061, #1072 (the other text shapes this rule cannot read), #1000.

**Source:** found 2026-08-06 by the design pass for the third attempt at rule 3c, measuring what the committed gate's `Scan` string can and cannot see. None of the four earlier verification passes filed it.

## 1070. git carries config in the ENVIRONMENT, and no argv rule can see it -- GIT_CONFIG_COUNT, GIT_CONFIG_PARAMETERS, GIT_CONFIG, config edit

> ✅ **DECLINED-BY-DESIGN 2026-08-25, OWNER RULING, ruled in about an hour after the four-row family (#1066/#1086/#1305/#1336) -- the family is five rows now.** Confirmed one-hop: the Liaison put it to the owner directly and read the answer. The declined alternative was closing this row as BLOCKED on measured evidence instead, keeping the ruling at four rows -- the owner ruled it in rather than holding the line there. **What was NOT independently re-verified, stated so it is not inherited as checked:** the three refutations of this row's fix designs were measured by Builder 2; the Dispatcher confirmed only the ledger citation relationships (this row cites neither #1336 nor #1086; #1336 cites #1086 six times and this row cites #1069 twice); the Liaison confirmed the code structure claim. Three seats, three instruments -- but nobody re-ran the refutations themselves, so treat the underlying fix-rejection as carried forward rather than re-proven here. 🔢 **Re-scored 2026-08-20 -> P1.** Value **8/10** · Difficulty **5/10** · _quick win_. The fail-open is unaddressed in the shipped gate: rule 3c decides from argv at worktree_gate.ps1:960 and the whole file contains no GIT_CONFIG reference, so all four measured channels remain ALLOW. The remainder is a new rule with its own danger match plus a file-identity target resolution inside a 1911-line Windows gate that has regressed before, which is bounded but intricate work with no store, ADR or migration axis. _(was 8/10 · 6/10.)_
Expand Down
Loading
Loading