The three harnesses moved under the engine — Codex Desktop relocated its data, OpenCode's ids stopped sorting, Claude Code added a session source — and each one broke a piece of the loop silently. This release is where the engine caught up, and where the update notice finally reaches the person, not only the model.
cd ~/llmwiki && git pull && ./setup.sh # clone install
/plugin update llmwiki # Claude Code plugin
Harness drift, measured
- Codex is no longer a single-home harness. Codex Desktop runs each signed-in account against its own relocated
CODEX_HOMEand exports it only to the processes it launches; a capture daemon pinned to~/.codexwent blind the day work moved into the app, and the only symptom was "nothing captured in 11 days". On the machine this was found on,~/.codex/sessionshad frozen on 2026-08-22 (its rollouts hardlinked into the account home at migration) while the account home kept writing — 40 rollouts, 6 in enrolled repositories, never captured. Homes are now discovered by signature (asessions/dir or astate_*.sqlite, never a name), an explicitCODEX_HOMEstays exclusive, and routes are de-duplicated by inode so the hardlinked copies cannot enqueue a conversation twice. Restarting the daemon on this code recovered exactly those 6 sessions. - OpenCode ids are not chronological any more. Its identifier packs
timestamp*4096into 48 bits, so the printed prefix wraps every ~795 days — most recently on 2026-08-14. Ids minted after a wrap sort below every earlier id, and the v1 cursor'sid > watermarkthen skips every later message of an older session forever. Every bound, ordering and the never-rewind guard now compare(time_created, id); the stored watermark carries its own time. A session whose later messages have smaller ids is pinned by a regression test. - Claude Code's SessionStart has a fifth source.
fork(v2.1.214) covers--fork-session,/forkand/branch; the plugin's matcher enumerated the previous four, and an enumerated matcher is an exact string list, so forked sessions got no cold-start context. The matcher is open now, a source test holds all three install surfaces to it, and the shared hook file documents which fields it may carry (Codex parses it withdeny_unknown_fields).
The notice reaches the person
The engine has always compared package.json versions and told the model at session start. Two gaps: 49 commits shipped on main under an unchanged version number were invisible to every clone, and a person only heard about any of it if the model chose to mention it. Now:
- a third notice kind covers code behind origin at the same version, measured live from local refs so it clears the moment you pull;
- the same fact is rendered for you — as the hook envelope's
systemMessageon Claude Code and Codex (a declared, user-visible field on both), as a toast in OpenCode, and as onestderrline before anyllmwikicommand; - plugin installs hear nothing, because every line ends in a clone command they do not have.
Doctor names the cause
The daemon runs with the environment frozen into its service definition at install time; a shell inherits whatever launched it. When they disagree, capture keeps succeeding against a directory the harness stopped writing to. The daemon now records the locations it actually resolved on every sweep, and llmwiki doctor reports any location your shell can see that the daemon never swept — with the command that fixes it — above the old "nothing captured" line.
Also in this release
- Skills that leave the plugin. Engine resolution is three-tier, so a host that copies the skill folder out (OpenClaw, Hermes,
skills add) still finds it; OpenClaw gateway adapter, Hermes session export for explicitingest, and an Orca note. - Human-invocation gate on the wiki skills —
disable-model-invocationfor Claude Code,agents/openai.yamlfor Codex, emitted from one policy module for both the clone install and the plugin bundle. Measured before it existed: 16 Codex sessions ran 275 write-classllmwikicommands after finishing unrelated work. llmwiki verify— one receipt for machine wiring, enrollment, index and non-empty cold-start memory; a unified launcher; self-guidedllmwiki <command> --help; a contributor entry contract (bun run check).- Faster hooks. A slim session-start path, batched OpenCode revision polling, and the legacy v1 poll gated — the per-turn hook stays interactive.
- Quiz asks its questions in one pass and grades at the end, and no longer puts the right answer in slot 1.
- Turn-context pointers say why they were picked; read observability counts a
Bashopen as a read and records what an injection cost, not only whether it paid off. daemon-syncrestarts the capture daemon when it predates the code on disk, and the close-out folds the two standing chores in.- Public clone usability gates, a cross-harness capture-scale bench, and the machine-readable support contract at version 4 (
codex.session_stores = all-discovered-homes, OpenCode projection re-verified on 1.18.27).
Upgrading
Clone installs: git pull && ./setup.sh. Plugin installs: /plugin update llmwiki (Claude Code) or codex plugin add llmwiki against the refreshed marketplace. After this release you will not have to check for the next one — the notice tells you, in the terminal.
Verified: 1240 tests, typecheck clean, CI green on Linux (Bun 1.1.45 floor and latest), macOS and the Windows platform contract; a fresh clone of the tagged commit ran the release-gate suites (42) and its own publish preflight; and a live end-to-end pass with real Claude Code, Codex and OpenCode sessions confirmed injection, capture and close-out on all three.