fix(hooks): state-line-guard ratchets against current size, not a flat gate

Advisor review caught this before the v0.23.0 tag landed: the guard
compared the projected line count only against the fixed 60-line max,
never against the file's current size, so trimming an already-oversized
STATE.md (e.g. 156 -> 100 lines, still over 60 but smaller) was denied
exactly like growing it would be.

Verified against the real tree: 23 of the machine's STATE.md files are
already over 60 lines today, one at 1405. Shipped as a flat gate, this
hook would have made most of them un-editable except by a single write
landing at <=60 in one shot -- backwards for a guard meant to make
trimming possible.

Fixed with a ratchet: deny only when the projection is over the max AND
larger than the file's current line count (0 for a file that doesn't
exist yet), for both Write and Edit. A compliant file still cannot grow
past the limit and a new file still cannot be created oversized, but an
oversized file can now be edited toward compliance one write at a time.

state-line-guard-selftest.sh: 16 -> 21 checks (new section 8: shrink
allows, same-size allows, grow-while-oversized still denies, new-oversized
still denies). Suite total: 191 + 152 + 69 + 21 = 433.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186kZGKddxfA9N84HqMLbb2
This commit is contained in:
Kjell Tore Guttormsen 2026-08-14 17:10:04 +02:00
commit c1dabf109d
5 changed files with 154 additions and 10 deletions

View file

@ -24,9 +24,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
`old_string` replaced by `new_string` (every occurrence when `replace_all`
is set, mirroring the real Edit tool), so the replace_all case is counted
correctly rather than only the first occurrence. Wired into
`hooks/hooks.json` as `PreToolUse` on `Write|Edit`. Pinned by
`state-line-guard-selftest.sh` (16 checks). Suite total: coord 191 + board
152 + route 69 + state-line-guard 16 = 428.
`hooks/hooks.json` as `PreToolUse` on `Write|Edit`.
### Fixed
- **`pre-state-line-guard.mjs` denied trimming an already-oversized STATE.md,
not just growing one.** Found by advisor review before the tag landed: the
first cut compared the projected line count only against the fixed 60-line
max, never against the file's current size, so shrinking a 156-line
STATE.md to 100 (still over 60, but smaller) was denied identically to
growing it. Verified against the real tree (2026-08-14): 23 of the
machine's STATE.md files were already over 60 lines, one at 1405 — shipped
as a flat gate, the hook would have made most of them un-editable except by
a single write landing at `<=60` in one shot. Fixed with a ratchet: denies
only when the projection is over the max *and* larger than the file's
current line count (0 for a file that doesn't exist yet), for both `Write`
and `Edit`. A compliant file still cannot grow past the limit and a new
file still cannot be created oversized, but an oversized file can now be
edited toward compliance one write at a time. Pinned by
`state-line-guard-selftest.sh` section 8 (4 new checks). Suite total: coord
191 + board 152 + route 69 + state-line-guard 21 = 433.
## [0.22.0] - 2026-08-13