Repository navigation
claude-hooks v1.8.0
claude-hooks v1.8.0 ships the /consultants v2 engine in its mature form — multi-role council with opt-in tool_executor + coder lanes, citation-verified researcher output, and a wired-by-default cross-session memory store with TTL + distillation. Plus the May-18 hardening pass that closed four bugs found during the live regression run.
73 commits since v1.7.0 across 13 task IDs (#199–#220). Full diff at v1.7.0...v1.8.0. Test count: 3939 collected / 3909 passed / 30 skipped in both claude-hooks and claude-hooks-consultants conda envs.
Headlines
/consultants v2 engine (mature form)
- Two new opt-in roles, default OFF as of 2026-05-18:
tool_executor— researcher PLAN-REPORT split with a dedicated tool-call lane (#103, M11c series). Default flipped back to OFF after the live A/B benchmark showed it loses on grep-shaped questions (benchmarks/consultants/results/2026-05-18/tool-executor-ab/report.md); keep enabled for slow-tool-budget questions where the synthesizer would otherwise re-issue tool calls across nine x-tier lanes.coder— sandboxedwrite_filerole (50 KB/file, 1 MB/lane, 16 files/lane) with per-language model routing (task #111). Caps enforced as tool-result errors so the LLM self-corrects.
- Three-layer
CitationLinterat researcher boundary (#204 / #205 / #207): path resolution → line bounds → symbol-match against an mtime-cachedcode_graph.enclosing_symbol_atquery. Annotations propagate viapeer_findings; downstream lanes see only verified cites. - M9 control surface (#214) — runtime_events emission, default sqlite checkpointer, node-enter INFO log; CLI now has
state/inject/control/interrupt/resume/cancel/eventssubcommands. - M12 parity regression suite (#98) — locks today-default behavior as the baseline; every new opt-in must add a cohort-2 test.
M14 cross-session memory store (default-on)
- LangGraph BaseStore wired by default at
effort = high+ viaenable_at_efforts. Four namespaces:(sid, "research")— per-lane findings, TTL 30 days(sid, "tool_results")— per-tool outputs, TTL 24 hours("project", project_id)— per-project durable, never expires("user", user_id)— user-global durable, never expires
- Caliber-style distillation-on-expiry — hourly daemon reaper summarizes expiring research into the durable
("project", pid)namespace BEFORE deleting originals. Primarygemma4:31b-cloud, fallbackglm-5.1:cloud. Critical invariant: research originals only deleted after a successful project-namespace write — failed distillation keeps them for the next sweep. - #215 reaper pacing —
store.ttl.jitter_pct = 0.1,store.distillation.max_groups_per_sweep = 5,store.distillation.pace_seconds_between_distillations = 5.0. Stops a cohort of N sessions with the same expiry from saturating the embedder. - #220 CLI surface — three new
claude-consultants configverbs (set-store,set-store-ttl,set-store-distillation) plus an optionalinstall.pywalkthrough for TTL + distillation knobs. The TOML round-trips through the canonical dataclass renderer.
Stop hook / PreCompact
- PreCompact wrap-up (#217) — preserves AskUserQuestion Q&A across the compaction boundary via the new
wrapupskill. Q&A pairs are extracted from the live transcript before the harness summarizes. - stop_guard (#219) — 5 new commitment-stall patterns parsed from real solidPC sessions: "going to X", "now drafting / writing", verb + tail + "now:", "let me insert / patch / apply", "starting with Phase N: ...". All gated by the existing end_turn + zero-tool_use + last-paragraph stack.
May-18 hardening pass
- #212 —
ProviderBackedStore._do_putno longer swallows provider failures; the M14 reaper's "delete only after successful distillation write" invariant is now load-bearing. - #216 —
tool_executorwrite amplification fixed;record_researchuses a stable per-lane key (L{lane_idx}),_do_putdeletes the prior provider row on overwrite. One row per(namespace, key)regardless of PLAN-REPORT round count. - #218 —
PgvectorProviderread-only methods (expire_before,count,_search_tables,_recall_hybrid_unlocked,_kg_search_nodes) call a new_read_only_finish()at every happy-path exit. Closes the psycopg3 implicit transaction so concurrentALTER TABLE(M14's lazyADD COLUMN IF NOT EXISTS expires_at) doesn't block on AccessShareLock. - #213 — triple-fix for the live cloud regression: KIND_UNKNOWN preservation in
process_tool_block, synthesizer source enumeration that exhaustively walks every researcher report instead of stopping at the first non-empty one, prompt compaction.
Upgrade notes
- Defaults flipped 2026-05-18 (commit
48f1c4e):store.enabled = True,backend = "sqlite_vec",sqlite_vec_path = "~/.claude/consultants-store.db",ttl.enabled = True,distillation.enabled = True. M12 parity holds becausemedium(the default effort) is not inenable_at_efforts— the store stays inactive on the default light tier and only fires athigh/max/ x-tiers. tool_executordefault = OFF. Enable per session viaclaude-consultants config set-role tool_executor --enabled trueonly when the question profile matches the win condition (slow-tool-budget, multiple x-tier lanes that would otherwise re-issue grep).- No
config/claude-hooks.jsonmigration. v1.7.0 configs are forward-compatible; new[store]knobs default to the values shown above. Operators who want to tune at install time can re-runinstall.pyand answer yes to the "Customize TTL + distillation knobs now?" prompt. - Authoritative docs:
docs/consultants.md(runbook),docs/consultants-roles.md(role reference),docs/consultants-skill-eval-protocol.md+docs/consultants-skill-eval-baselines.md(model-pick evidence).
Full changelog
See CHANGELOG.md (51 entries across the v1.8.0 release window). The "Authoritative docs" links above cover everything user-facing.