From 84349d7a0e4ac23656cfa659ade1c9016377bc5d Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Wed, 2 Sep 2026 01:13:01 -0700 Subject: [PATCH] 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. --- docs/runbooks/althing-deploy.md | 30 +++++++++++++++++++ .../2026-09-01-althing-320-deploy.md | 29 ++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/docs/runbooks/althing-deploy.md b/docs/runbooks/althing-deploy.md index 962acd0..f5cc5d5 100644 --- a/docs/runbooks/althing-deploy.md +++ b/docs/runbooks/althing-deploy.md @@ -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 diff --git a/persistent-memory.d/2026-09-01-althing-320-deploy.md b/persistent-memory.d/2026-09-01-althing-320-deploy.md index ab6ef0f..4372026 100644 --- a/persistent-memory.d/2026-09-01-althing-320-deploy.md +++ b/persistent-memory.d/2026-09-01-althing-320-deploy.md @@ -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.