Skip to content

feat(hooks): inject reflections via new SessionStart hook#46

Merged
emp3thy merged 10 commits into
mainfrom
worktree-hooks+session-retrieve
May 6, 2026
Merged

feat(hooks): inject reflections via new SessionStart hook#46
emp3thy merged 10 commits into
mainfrom
worktree-hooks+session-retrieve

Conversation

@emp3thy
Copy link
Copy Markdown
Owner

@emp3thy emp3thy commented May 6, 2026

Summary

  • Adds better_memory.hooks.session_retrieve — a SessionStart hook that fetches the project's distilled reflections (do / dont / neutral, top 10 per bucket, hints truncated to 600 chars) and injects them into Claude's first turn as additionalContext. Eliminates the failure mode where Claude skips memory_retrieve and proceeds memory-blind.
  • Failure-isolated from the existing session_start.py spool-marker hook: on retrieval error, the hook logs a row to hook_errors, writes a stderr line, injects a fallback directive ("better-memory: memory injection failed (...) — call memory_retrieve manually"), and always exits 0. Hook contract verified by test_returncode_always_zero walking 3 distinct failure-states.
  • Docs updated: README.md Manual setup section now registers both SessionStart hooks; website/configuration.md gains a ## Hooks section listing all four shipping hooks and their filesystem interactions.

How it works

  1. SessionStart fires → session_retrieve.main() reads stdin defensively (1 MiB cap, mirrors session_start.py).
  2. Opens memory.db, calls ReflectionSynthesisService.retrieve_reflections(project=cwd-derived, limit_per_bucket=10).
  3. Renders three buckets to Markdown, wraps in {"hookSpecificOutput": {"hookEventName": "SessionStart", "additionalContext": ...}}, prints to stdout.
  4. Empty DB → injects a "no reflections recorded yet — use memory_observe" message instead of silent skip.
  5. Any exception → fallback directive + hook_errors row + stderr line, still exit 0.

Spec: docs/superpowers/specs/2026-05-06-session-memory-injection-hook-design.md
Plan: docs/superpowers/plans/2026-05-06-session-retrieve-hook.md

Test plan

  • uv run pytest tests/hooks/test_session_retrieve.py -v — 7 tests pass (happy path, empty DB, missing DB fallback, simulated SQL error fallback, hint truncation at 600 chars, bucket cap at 10, never-exit-nonzero across 3 states)
  • uv run pytest -m "not integration" -q — full suite green: 717 passed, 22 skipped, 11 deselected (vs. 710 baseline = +7 new tests, zero regressions)
  • uv run pyright better_memory/hooks/session_retrieve.py tests/hooks/test_session_retrieve.py — 0 errors, 0 warnings
  • uv run ruff check — clean
  • uv run mkdocs build --strictwebsite/configuration.md change builds without warnings
  • git merge-tree origin/main e3d58b6 — no conflicts vs current main (post-docs: align website + README with current MCP surface #45 merge)
  • Reviewer smoke test: register both SessionStart hooks per README.md Manual setup, restart Claude Code, open a fresh session in this repo, verify the first turn's system reminder includes the rendered Markdown bucket sections.
  • Reviewer smoke test: in a directory without BETTER_MEMORY_HOME content, verify the hook injects the "no memory yet" message instead of erroring.

Out of scope (deferred to follow-up tracks)

  • Track B — setup-script auto-install. scripts/setup.sh will gain idempotent ~/.claude/settings.json merging so users no longer paste JSON manually. Tracked separately.
  • Surfacing semantic memories, pending synthesis count, open prior-session episodes — future hook extensions.
  • Configurability via env var — YAGNI for v1.

Notes for review

  • 10 commits in the branch (1 spec+plan, 1 feat, 1 fix, 6 test, 2 docs). Each is meaningful — keep granularity or squash at merge time, your call.
  • Subagent-driven development: every task got an implementer + spec compliance reviewer + code quality reviewer before commit. Final composite review on the full branch came back clean (0 Critical, 0 Important, 4 Minor cosmetic items intentionally left as-is).

🤖 Generated with Claude Code

emp3thy and others added 10 commits May 6, 2026 19:02
Adds an approved design + TDD implementation plan for a new SessionStart hook (better_memory.hooks.session_retrieve) that injects the project's distilled reflections as additionalContext at session start, eliminating the failure mode where Claude proceeds memory-blind on first turn.

Spec covers: architecture (sibling hook, never modifies session_start.py), render format (top-10 per bucket, 600-char hint truncation), failure handling (always exit 0, fallback directive on error, hook_errors row, stderr line), out-of-scope deferrals (setup-script auto-install in Track B, semantic memory surfacing in future work).

Plan: 8 TDD tasks, all >= 90% confidence, full test + impl code per step. Self-review pass clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Claude BugBot Analysis

No bugs found. The implementation is well-structured with thorough exception handling throughout. The actual test file correctly imports apply_migrations from better_memory.db.schema (the plan document contains an incorrect example import path better_memory.db.migrations, but this is only in the planning markdown, not the shipped code). The stdin drain using _MAX_STDIN_BYTES + 1 intentionally mirrors session_start.py's pattern. Hint truncation math is correct (599 chars + 1 U+2026 character = 600 chars). The retrieve_reflections call signature matches the service definition exactly.

No bugs were detected in this PR.

@emp3thy emp3thy merged commit effc4a1 into main May 6, 2026
3 checks passed
@emp3thy emp3thy deleted the worktree-hooks+session-retrieve branch May 6, 2026 19:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant