Skip to content

feat(cli): add brain hooks so the memory loop runs by itself - #2

Merged
luuuc merged 5 commits into
mainfrom
feat/hooks
Sep 18, 2026
Merged

luuuc merged 5 commits into
mainfrom
feat/hooks

Conversation

@luuuc

@luuuc luuuc commented Sep 18, 2026

Copy link
Copy Markdown
Owner

Summary

brAIn shipped every part of the memory loop and nothing ever called it — a session
started cold unless someone remembered to type brain recall first. This adds the
editor integration that closes it: a session-start hook that loads project memory
automatically, plus the rules covering what a hook cannot know.

Pitch

.doc/pitches/02-04-claude-code-hooks.md — local only, since .doc/ stays out of
the public repo.

Changes

New command

  • brain hooks prints Claude Code's settings.json block and the CLAUDE.md rules;
    --tool cursor prints .cursor/rules/brain.mdc
  • brain hooks session-start injects the top five memories, ranked by layer authority

Display

  • Memory.Title() is now shared by recall, the MCP tools, and the hook. Effectiveness
    memories no longer render as ## Outcomes

This repository

  • .brain/ seeded with sixteen memories and committed
  • README documents the setup path and what a fresh clone actually gets

Architecture Highlights

  • The hook is a subcommand, not a shell script. Shaped as a script; a script adds
    an install step, a chmod, a bash dependency, and a test that has to reconstruct a
    hostile PATH to exercise ten lines.
  • session-start always exits 0. A SessionStart hook exiting 2 blocks the session,
    and brain recall exits 2 on an empty store — an ordinary state, not an error.
  • No automatic trust recording. The placeholder called for a post-commit hook. A
    local commit is not a ship: ten of them would walk a domain from ask to notify on
    typing alone. Recording stays with merges, deploys, and Beacon.
  • brAIn prints, the human installs. It never edits a settings file someone else owns.
  • The matcher covers startup|clear|compact. Compaction matters most — it is where
    a correction gets summarised away. resume and fork inherit a context that already
    has the injection.

Test Plan

  • Session start exits 0 and prints nothing with no .brain/, an empty one, or a stale --dir
  • With memories present, output is ordered correction → decision → fact and capped at five
  • Effectiveness memories render as persona and domain, never as ## Outcomes
  • The settings snippet parses as JSON, carries a timeout, and the command it names executes
  • Every brain <command> in the printed setup and in the README resolves against the real
    command tree — mutation-checked by injecting brain verify, which fails the test
  • Cursor frontmatter parses as YAML with alwaysApply: true; the Cursor setup never claims
    a hook loads memory
  • Unknown --tool exits 3
  • make ci passes (build + test + lint, 0 issues); coverage internal/cmd 79.5% → 82.6%,
    internal/memory 0% → 62.5%

Follow-ups

  • Two definition docs are stale: 08-ai-workflow.md shows .cursorrules, which is absent from
    Cursor's current docs, and 06-mcp-and-cli.md documents brain recall --for council, a flag
    that has never existed.
  • Seeding surfaced that corrections outrank by layer rather than relevance, so a narrow
    correction permanently occupies a session-start slot ahead of any decision. Worth its own pitch.

Adds Memory.Title(), which every display path now shares. Effectiveness
memories previously rendered as "## Outcomes" — their body's first line
is a markdown heading, not a summary — so they reached users and models
as a stray fragment. Their identity is structured, so the title is built
from persona and domain rather than parsed back out of prose.

- Removes the duplicated firstLine helpers in recall and the MCP handlers
- Keeps recall, the MCP tools, and the session-start hook from drifting
  into three different answers for the same memory
Adds brain hooks, which prints the configuration that makes the memory
loop run by itself, and brain hooks session-start, the hook that injects
a project's highest-authority memories into a new session. brAIn prints
and the human installs — it never edits a settings file someone else owns.

- session-start always exits 0: a hook exiting 2 blocks the session, and
  an empty or absent .brain/ is ordinary rather than exceptional
- --tool cursor emits .cursor/rules/brain.mdc; the default emits Claude
  Code's settings.json block and the CLAUDE.md rules
- The settings block carries a timeout, since nothing inside the hook can
  bound a wedged recall portably
- hooks joins the commands that run without a .brain/, building its own
  engine per the contract documented in root.go
Pins the behaviour that would otherwise fail invisibly inside someone's
editor. The scan resolving every "brain <command>" in the printed setup
and in the README against the real command tree is the load-bearing one:
the definition docs already carry "brain recall --for council", a flag
that has never existed.

- Session start exits 0 and stays silent with no .brain/, an empty one,
  or a stale --dir
- Authority ordering and the five-memory cap are asserted, not assumed
- The settings snippet is parsed as JSON and its named command executed
Adds an Editor Setup section covering install, brain hooks, paste, done,
and updates Status now that editor integration ships. States the split a
fresh clone actually gets: memories are committed and travel with the
repository, while hook configuration is per-developer.
brAIn is ten pitches deep and has never remembered anything about its own
construction. Seeds sixteen memories: settled decisions that otherwise
live only in gitignored files, and lessons from building that exist
nowhere else.

- Decisions and corrections from .doc/ and CLAUDE.md, neither of which git
  carries, so a session could never reach them
- Lessons the work taught, including that definition-doc examples drift
  from the CLI
@luuuc luuuc added the enhancement New feature or request label Sep 18, 2026
@luuuc luuuc self-assigned this Sep 18, 2026
@luuuc
luuuc merged commit af2ec87 into main Sep 18, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant