Development record
Durable state lives where the platform says it survives
The rule. State that must outlive an event the platform owns — an update, a re-clone, a garbage-collection sweep — is stored only in a location the platform documents as surviving that event. Never fight the host lifecycle inside a directory the host replaces or deletes on its own schedule, and never guess at a survivable location the platform did not hand over: a wrong guess plants trusted state in an untracked place, which is worse than losing it.
Why. The 2026-08-21 plugin-update post-mortem (iss-2608210934566221) priced the violation precisely: the downloaded hook binary lived in the harness's commit-stamped plugin directory — re-cloned on every update, documented as not preserving extra files, garbage-collected roughly fourteen days after being orphaned. One routine update cost a full re-download, a first-hook window with no binary, one binary copy per plugin version left for the sweeper, and a PATH symlink two weeks from dangling (iss-2608210934566222). None of that was a bug in abcd or in the harness: each side behaved as documented, and the loss was the storage decision itself. The same harness documents a persistent per-plugin data directory that survives updates and dies only on full uninstall — the platform-sanctioned home the binary cache moved to (itd-132 / spc-35, seeded as iss-2608210934566227).
Bounds.
- The warrant is the platform's documentation, not observed behaviour: a directory that happens to survive today is not a home, and a documented home is taken on its documented terms (deleted at uninstall means gone at uninstall — plan for that, not against it).
- The rule cuts both ways: transient, per-version state (the executing binary paired with its plugin surface) rightly stays in the per-version directory; only what must outlive the lifecycle event moves out.
- Location changes trust obligations, never trust bars: state promoted into a longer-lived home keeps every verification it needed in the short-lived one, plus whatever the longer at-rest window now demands (adr-46).
- When the platform hands over no survivable location, degrade loudly to the transient behaviour — deriving the undocumented path is the guess this rule forbids.
Promotion. Unenforced. A lint that flags writes of long-lived artefacts into known-transient roots (the plugin root, temp dirs) would promote this to a discipline-kind intent; until then it is applied at review time.
.abcd/development/principles/durable-state-lives-where-the-platform-says-it-survives.md
open on GitHub ↗ · commit history ↗
mentions6
- adr-46Persisting the hook binary never weakens the verification posture — every promotion re-verifies, and SessionEnd performs no network work
- iss-2608210934566221Relocate the hook binary and .binary-meta from the plugin cache dir to the harness persistent data dir (CLAUDE_PLUGIN_DATA, ~/.claude/plugins/data/abcd-abcd-marketplace/). The harness re-clones every update into a fresh commit-stamped cache dir and its docs state extra files there are NOT preserved across updates, so the ~11MB binary is re-fetched on every plugin update by design. The data dir survives updates and is deleted only on full uninstall. Fixes in one move: the per-update re-download, the SessionEnd bootstrap-cancellation window, per-version binary disk copies (orphaned cache dirs are GC'd ~14 days after .orphaned_at), and the PATH-symlink rot captured separately. Reworks the itd-105/spc-21 bootstrap fast path and every pluginBinaryPath consumer.
- iss-2608210934566222The pinned PATH symlink written by ahoy install targets pluginBinaryPath(pluginRoot) — a commit-stamped plugin cache directory. Every plugin update orphans that directory and the harness garbage-collects it ~14 days after .orphaned_at, so for a marketplace user the ~/.local/bin/abcd symlink silently dangles within two weeks of every update. The heal path (symlink.dangling gap + re-running ahoy install) exists but nothing triggers it automatically. Fix follows the persistent-data-dir relocation: point the pinned symlink at the data-dir binary, whose path is stable across updates.
- iss-2608210934566227Principle to draft at itd-132 planning (SPLIT-routed stance): store durable state where the platform documents it survives — never fight the host lifecycle inside a directory the host re-clones or garbage-collects. Surfaced by the 2026-08-21 plugin-update post-mortem (binary in the re-cloned cache dir). Candidate home: .abcd/development/principles/. File alongside the itd-132 spec.
- itd-132The hook binary survives plugin updates
- spc-35hook-binary-to-persistent-data-dir