2026-06-25 Vault Capture Nudge Hook
What I set out to do
Close the known hole from yesterday’s 2026-06-24 Proactive Vault Capture Directive: the standing instruction journals at work-completion by judgment, so a session that just goes quiet can miss its capture. Yesterday’s note flagged a thin hook as the real fix if it bit. Today was the hook design and build.
What I actually did
- Designed a two-hook architecture, then cut it down. The pieces: a
SessionStartprimer injecting live vault state (active projects, today’s journal), and a per-turn nudge that fires only when a turn passed with nomcp__obsidian__tool use. - Chose
UserPromptSubmitoverStopfor the nudge.Stop’s only lever is the harddecision:block, which forces a continuation every vault-less turn (disruptive, expensive).UserPromptSubmitinjects softadditionalContextinto the next turn instead. Both are per-turn; the soft one is the right fit for a reminder. - Dropped the
SessionStartprimer (option B). Key realization: a hook is a plain shell subprocess and cannot call MCP tools (those are model-loop-only). The only way to put live vault data inSessionStartwas reading the filesystem directly, which couples the hook to the vault path +status:frontmatter format. Without that data the primer just restated the always-loaded CLAUDE.md rule (DRY violation), so it earned nothing. The agent consults via MCP per the standing directive instead. - Shipped the nudge.
knowledge-capture-nudge.sh, wired toUserPromptSubmit. It countsmcp__obsidian__occurrences in the transcript, persists count + a stale-streak per session under~/.local/state/claude/vault-nudge/<session>. First prompt is silent (no prior turn); a turn that touched the vault resets the streak; once the streak hitsNUDGE_AFTER_STALE_TURNS(=1) it injects a one-line consult/capture reminder and resets. Soft only, never blocks.shellcheck+just checkgreen, functional gate test passed all four cases, committedec08355.
What was striking
- The MCP-vs-filesystem constraint killed the more interesting hook. I wanted
SessionStartto seed real data, but hooks live outside the agent loop where MCP doesn’t exist. The localmcpvaultMCP just readsvaultPathunder the hood anyway, so a filesystem peek would have returned identical data: not bypassing the abstraction, reading the same source. Adam still preferred no filesystem coupling, so the nudge carries the value alone. - The nudge gate needed file-existence, not just a count delta. A naive “count unchanged since last turn” can’t tell the first prompt (no prior turn) from a later vault-less turn, and a zero-obsidian session keeps count at 0 forever. Using the mark-file’s existence as the “is this the first prompt” signal fixes both.
- This running session won’t see the hook. Settings load at session start, so the nudge goes live next session, not this one.
Related
- 2026-06-24 Proactive Vault Capture Directive — yesterday’s standing instruction; this hook is the “thin hook” fix it predicted