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

@ -14,7 +14,7 @@ Session A in repo X leaves a message for repo Y; the next session in repo Y gets
![Hooks](https://img.shields.io/badge/hooks-1-green)
![Skills](https://img.shields.io/badge/skills-3-orange)
![CLI scripts](https://img.shields.io/badge/CLI_scripts-8-blue)
![Selftest checks](https://img.shields.io/badge/selftest_checks-428-blue)
![Selftest checks](https://img.shields.io/badge/selftest_checks-433-blue)
---
@ -166,7 +166,7 @@ Note that raising the inbox's priority (Rule 7) deliberately does **not** widen
bash scripts/coord-selftest.sh # 191 checks against a throwaway mailbox
bash scripts/board-selftest.sh # 152 checks against a throwaway repo tree
bash scripts/route-selftest.sh # 69 checks, incl. the route->board round trip
bash scripts/state-line-guard-selftest.sh # 16 checks, incl. the Edit replace_all projection
bash scripts/state-line-guard-selftest.sh # 21 checks, incl. the Edit replace_all projection and the ratchet
npm test # all four selftests via node --test
TDD is the house rule: every behavior change lands with a failing selftest check first.