hunch cookbook
Cookbook

Recipes for running Hunch

Copy-paste recipes for day-to-day Hunch. Every recipe says what you should observe when it works — a passing gate, an injected block, a red CI — never "it's configured".

1 · First install on a repo#

terminal
npm i -g @davesheffer/hunch
cd your-repo
hunch init --firmness advisory   # start gentle; raise later
hunch backfill --since 90d       # cold start: seed from history

Observe: .hunch/ appears (git-tracked JSON), .claude/settings.json gains five hook events (PreToolUse, UserPromptSubmit, SessionStart, PostToolUse, Stop), and the next assistant session opens with a 🧠 orientation block.

2 · Choose an enforcement level#

firmnesspre-edit groundingblocking invariants deny editsverification stop-gate
off
advisorynag only
firm✔ blocks unverified turn-end
strict
terminal
hunch firmness firm

No restart needed — the hook reads firmness at run time.

3 · The verification pipeline (v1.4.0+)#

The operating loop — scope → evidence → change → verify → attack → report — is injected at session start and enforced at turn end. Facts, not claims: PostToolUse records which product files were edited and whether a verify-shaped command (test / build / typecheck / plan) ran afterwards. At firm/strict, the Stop hook refuses to end a turn with unverified product edits — at most twice per turn, so a broken gate can never trap you.

📊Why it exists (measured, 2026-07-08): instruction skills installed as files were read in 0/20 benchmark sessions — pass rates identical to no skill at all. Guaranteed delivery of the same content flipped hard-bug diagnosis FAIL→PASS on every discriminating cell (Opus and Haiku). Delivery, not content, is the bottleneck — and hooks are the one delivery mechanism the model can't ignore.
terminal
HUNCH_PIPELINE=0          # kill switch, per env
hunch firmness advisory   # keep grounding, drop the gate

Docs and .claude/ / .hunch/ edits never arm the gate.

4 · Capture a decision that survives the session#

After any non-trivial choice, in your assistant:

text
/capture     # grilling interview: topic, rationale, rejected alternatives

Or mid-flow: hunch_capture_decision(topic) → answer the questions → hunch_record_decision(...) with the returned token.

Observe: the decision shows in hunch now, and editing a file it governs injects it — including what was rejected, so the next session doesn't re-litigate it.

5 · Turn a human correction into a permanent rule#

text
hunch_record_correction({ rule, scope_hint_file, severity: "blocking" })

Observe: at strict, an edit violating the rule is denied with the rule quoted back. Never Twice.

6 · Keep docs honest (doc≠graph)#

Anchor a doc to a topic:

markdown
<!-- hunch:topic auth.session-storage -->
terminal
hunch drift              # CI-gateable: stale anchors fail
hunch heal               # guided reconciliation — never rewrites prose silently
hunch reconcile-topics   # after merges: one live decision per topic

7 · Wire CI#

terminal
hunch ci                 # constraint guard on the diff
hunch drift              # doc anchors still current
hunch reconcile-topics   # merge didn't fork a topic

All exit non-zero on violation — make them required checks.

8 · Make an instruction skill actually fire#

Measured: models under-trigger skills badly — 0/20 sessions read an installed skill whose description was polite prose. If you ship a skill:

  • Write the description as a pushy trigger: “MANDATORY before X — invoke FIRST, do not skip because the task looks simple.” This alone took Opus from never-reads to reads-and-passes.
  • Weaker models (Haiku-class) ignore even pushy descriptions — name the skill in the prompt, or inject the content via hooks (recipe 3 is exactly this, productized).
  • Never conclude a skill “doesn't help” without checking the transcript for an actual Skill invocation — availability ≠ delivery.

9 · Benchmark your own setup#

The repo ships harnesses under bench/:

terminal
npx tsx bench/run.ts --arms A,C --model claude-sonnet-5
npx tsx bench/external/run-zod.ts --arms A,S --no-repro
npx tsx bench/external/run-zod.ts --arms S --force-skill --only zod-5937

Rules learned the hard way: use --no-repro (diagnosis mode) or everything ceilings at PASS; drop tasks that fail for every arm (they measure spec-guessing, not diagnosis); verify skill invocations in transcripts before comparing arms.

10 · Private overlay (public repo, private memory)#

terminal
hunch init --private-sync   # captures go to the HUNCH_PRIVATE_DIR overlay
hunch private               # point a clone at the overlay

Observe: hunch_* tools see the union; the public repo carries only what you curate.

11 · The self-running memory loop (v1.8.0+)#

Nothing to manage. Capture happens on every commit, memory lands trusted-advisory immediately, and renames heal their own bindings:

terminal
hunch log                    # every memory move: capture · adopt · supersede · prune · repair
hunch log --diff <sha>       # what one move changed
hunch revert-move <sha>      # undo one move (local git revert, never pushed)
hunch escalations            # the decisions only YOU can make — normally empty
hunch adopt-drafts           # one-time: clear a legacy draft backlog into advisory memory
hunch push                   # the one deliberate outward step (memory auto-commits locally)

Observe: after a commit that renames a file, hunch log shows a 🔧 repair move — the bindings healed themselves; nothing went stale. In VS Code, the Hunch Memory panel is the same spine with click-to-diff, one-click revert, and the inline activate / demote / withdraw / retire authority actions.

Rule of the loop: advisory is automatic; blocking is always one explicit human click, and a repaired rule asks once for a fresh proof before it can block again.

12 · Use a local or self-hosted model#

Point Hunch at any OpenAI-compatible chat-completions endpoint. Ollama, vLLM, LM Studio, and llama.cpp work without a subscription CLI:

terminal
export HUNCH_SYNTH_PROVIDER=ollama
export HUNCH_SYNTH_BASE_URL=http://localhost:11434/v1
export HUNCH_SYNTH_MODEL=hunch-synth
export HUNCH_SYNTH_TIMEOUT_MS=300000
export HUNCH_SYNTH_MAX_TOKENS=2048

For predictable large-diff synthesis with Ollama, pin the context window in a custom model:

Modelfile
FROM qwen2.5-coder:latest
PARAMETER num_ctx 32768
terminal
ollama create hunch-synth -f Modelfile
hunch doctor

Observe: hunch doctor reports openai-compat and no longer warns that num_ctx is unpinned.

!Public remotes fail closed. Localhost, private/link-local IPs, and conventional LAN names work directly. Every public endpoint requires HUNCH_SYNTH_ALLOW_METERED=1; set it only when you trust the endpoint and understand any billing.