fix(topdata): let pinned TLK ids evict stale state owners #48

Merged
archvillainette merged 1 commits from fix/tlk-pin-evicts-stale-state into main 2026-07-22 18:17:04 +00:00
Owner

Problem

The custom palette taxonomy (#46) pins display strings to fixed TLK ids in tlk/custom.tlk.yml, and registerInlineAtID demanded each pinned id be free. But .tlk_state.json is gitignored and per-machine — each dev grows their own copy, and before #46 every ref got its id dynamically (first-come-first-served).

On any machine whose state predates #46, a ref could have already parked on a now-pinned id. That fails the build:

topdata validation failed with 1 error(s): error: native topdata buildability check failed:
TLK id 2689 is already reserved by "feat:yuanti/alternate_form.feat"

It only passes on machines whose state was regenerated after #46 (pinned window already clean). The allocateID reserved-skip that #46 added protects a fresh build, but does nothing about a stale cache.

Fix

Make the pin authoritative over the per-machine cache. A stale cached owner sitting on a pinned id is evicted and reallocated a fresh id when next made active; only two pins fighting over the same id in custom.tlk.yml is now an error. This self-heals on the next build — no manual .tlk_state.json deletion needed.

Caveat: the evicted ref's strref shifts on affected machines. That's unavoidable (something must move off the pinned id), and dynamic strrefs were never stable across machines anyway.

Tests

Added TestBuildStandaloneTLKPinEvictsStaleStateOwner (seeds a pre-#46 state with a feat parked on the pinned id, asserts the build succeeds, the pin owns it, and the feat is reallocated). Full internal/topdata suite + go vet pass.

🤖 Generated with Claude Code

## Problem The custom palette taxonomy (#46) pins display strings to fixed TLK ids in `tlk/custom.tlk.yml`, and `registerInlineAtID` demanded each pinned id be free. But `.tlk_state.json` is **gitignored and per-machine** — each dev grows their own copy, and before #46 every ref got its id dynamically (first-come-first-served). On any machine whose state predates #46, a ref could have already parked on a now-pinned id. That fails the build: ``` topdata validation failed with 1 error(s): error: native topdata buildability check failed: TLK id 2689 is already reserved by "feat:yuanti/alternate_form.feat" ``` It only passes on machines whose state was regenerated after #46 (pinned window already clean). The `allocateID` reserved-skip that #46 added protects a *fresh* build, but does nothing about a *stale cache*. ## Fix Make the pin authoritative over the per-machine cache. A stale cached owner sitting on a pinned id is evicted and reallocated a fresh id when next made active; only two pins fighting over the same id in `custom.tlk.yml` is now an error. This self-heals on the next build — no manual `.tlk_state.json` deletion needed. Caveat: the evicted ref's strref shifts on affected machines. That's unavoidable (something must move off the pinned id), and dynamic strrefs were never stable across machines anyway. ## Tests Added `TestBuildStandaloneTLKPinEvictsStaleStateOwner` (seeds a pre-#46 state with a feat parked on the pinned id, asserts the build succeeds, the pin owns it, and the feat is reallocated). Full `internal/topdata` suite + `go vet` pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
archvillainette added 1 commit 2026-07-22 18:11:12 +00:00
fix(topdata): let pinned TLK ids evict stale state owners
ci / ci (pull_request) Successful in 3m17s
32cfb9a013
The custom palette taxonomy (#46) pins display strings to fixed TLK
ids in tlk/custom.tlk.yml. registerInlineAtID demanded those ids be
free, but .tlk_state.json is a gitignored, per-machine cache: on any
machine built before #46, a ref could have dynamically grabbed a
now-pinned id (e.g. feat:yuanti/alternate_form.feat holding 2689),
failing the build with "TLK id N is already reserved by ...".

Make the pin authoritative over the cache: a stale cached owner on a
pinned id is evicted and reallocated a fresh id when next made active.
Only two pins fighting over one id in custom.tlk.yml is now an error.
This self-heals on the next build without deleting the state file.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
xtul approved these changes 2026-07-22 18:12:14 +00:00
archvillainette merged commit 4d38967078 into main 2026-07-22 18:17:04 +00:00
archvillainette deleted branch fix/tlk-pin-evicts-stale-state 2026-07-22 18:17:05 +00:00
Sign in to join this conversation.