Two more shards were red on generated artifacts nobody regenerated:
- api_controller_boundary_baseline.json: the attachment round rewrote
_persist_user_message to build the row before adding it, so the fingerprint
moved from `db.session.add(AiMessage(...))` to `db.session.add(message)`.
Same crossing, same category, count unchanged at 509 -- one line.
- docs/MIGRATION_INVENTORY.md: three measured numbers had moved without a
regeneration -- bare @jwt_required() routes 577 -> 576, and the two frontend
rows whose totals come from maps inside check-frontend-boundaries.mjs
(setInterval pollers 10 -> 9, hex colour literals 151 -> 150). All three are
deterministic AST/constant counts, so these are CI's numbers, not this box's.
The reason nobody caught the inventory locally is the third fix here: the
generator hardcoded `node`, and under WSL the Windows nvm directory is on PATH
but exposes only `node.exe`, so test_migration_inventory.py skipped on the dev
box. Both the generator and the test now resolve $NODE / node / node.exe, and
the test runs instead of skipping.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
docs/MIGRATION_INVENTORY.md is generated from the live censuses and the
frontend boundary checker's new --inventory JSON mode — no hand-typed
numbers, so the plan cannot claim completion while a door is bypassed. A
freshness test fails whenever a ratchet number moves without regenerating
the document, making the regeneration part of every migration commit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>