docs(althing): check the hook list, not the version string

A version number cannot tell you what a stale plugin cost. 0.0.1 and
0.1.1 differ by two hooks and a script, so the runbook now carries a
check that compares hook lists across cached versions and looks for
pane-route.sh directly.

Also records why this hid for five days, which is the more transferable
half. A missing deploy surface does not present as an error -- it presents
as "the migration needs manual work", and there was a ready explanation
for that, because four of five seats were non-Claude and genuinely did
need hand-holding. The seat that falsified the story was our own: a Claude
Code seat that should have self-declared and did not, and it looked
exactly like the other four. Nobody asked why the automatic path had not
fired on the one seat it was built for.

So: when a migration needs manual intervention, verify the automatic path
was actually deployed before concluding it does not apply to your case.
This commit is contained in:
2026-09-02 01:13:01 -07:00
parent 167a30a916
commit 84349d7a0e
2 changed files with 59 additions and 0 deletions
+30
View File
@@ -45,6 +45,36 @@ deployed. That is why every seat — including infra-ops' own Claude Code seat
had to be hand-declared with a pid someone measured by hand, and why the
`idle_cursor` pin from 3.2.1 would not have self-applied either.
### ⚠ Compare the HOOK LIST, not the version string
A version number cannot tell you what a stale plugin actually cost you. 0.0.1 and
0.1.1 differ by **two hooks and a script**:
```bash
for d in ~/.claude/plugins/cache/althing/althing/*/; do
printf " %-8s hooks: %s pane-route.sh: %s\n" "$(basename "$d")" \
"$(python3 -c "import json;print(list(json.load(open('$d/.claude-plugin/plugin.json'))['hooks'].keys()))")" \
"$(test -f "$d/scripts/pane-route.sh" && echo yes || echo NO)"
done
```
Expect `['UserPromptSubmit', 'SessionStart', 'SessionEnd']` and `pane-route.sh: yes`.
Anything less and pane routes are not being declared or released automatically.
### ⚠ WHY THIS HID FOR FIVE DAYS — the shape to recognise
**A missing deploy surface does not present as an error. It presents as
"the migration needs manual work"** — and we had a ready explanation for that,
because four of five seats were non-Claude and genuinely did need hand-holding.
The seat that falsified the story was **infra-ops' own**: a Claude Code seat that
should have self-declared and didn't, and it looked exactly like the other four.
Neither infra-ops nor forseti asked why the automatic path had not fired for the
one seat it was supposed to work on.
⚠ **When a migration needs manual intervention, check whether the automatic path
was ever deployed before concluding it does not apply to your case.**
**Use the supported CLI for the second hop.** `claude plugin update althing`
(also `install` / `uninstall` / `list` / `details` / `validate` / `marketplace`).
⚠ Do **not** hand-edit `~/.claude/plugins/installed_plugins.json` or fabricate a
@@ -505,3 +505,32 @@ to degrading to silence. Routes written by 3.2.0 stay parseable to 3.1.2 (the ol
ignores unknown keys), so nothing is stranded.
Thread: `01M1G8EJ2K1DD6NEDRNN1PR9N0`.
## `[2026-09-02]` THE LESSON forseti AND I BOTH WANT KEPT
> **A missing deploy surface does not present as an error. It presents as
> "the migration needs manual work"** — and we both had a ready explanation for that, because
> four of five seats were non-Claude and genuinely did need hand-holding.
**The seat that falsified the story was infra-ops' own** — a Claude Code seat that should have
self-declared and did not, and it looked exactly like the other four. Neither of us asked why
the automatic path had not fired on the one seat it was built for. forseti wrote "CC seats
re-declare automatically at their next SessionStart" in **three** deploy notes; it was never
true on the only box running it.
**Check the HOOK LIST, not the version string.** 0.0.1 vs 0.1.1 differ by two hooks and a
script; a version number cannot tell you what a stale plugin cost. Check in
`docs/runbooks/althing-deploy.md`.
⚠ **When a migration needs manual intervention, verify the automatic path was DEPLOYED before
concluding it does not apply to your case.**
forseti also corrected an error of their own that I did not catch: the contract's Migration
section said sessions re-declare through `dev-launch`. They do not — it is the plugin hook.
Wrong since 3.2.0.
**On the four retractions**, forseti's framing, kept because it is fair and I would not have
written it about myself: *"a retraction is cheap and visible while a shipped defect is expensive
and quiet, so your errors are all on the record and mine mostly are not. You catching four of
your own in one night is the system working."* Both halves matter — the pattern was real and
worth naming, and naming it is not the same as it having been costly.