Skip to content

Hooks

mage has no background daemon and no watcher process. Everything it learns, it learns by riding the events your coding host already fires. When you run mage connect, mage writes a small set of mage:* hook groups into your host’s settings (for Claude Code, .claude/settings.local.json), each tagged with a stable id so mage can update or remove exactly its own groups and never touch yours. Capture is the host calling these commands at the right moment — when nothing happens in the host, nothing runs.

The table below is generated from the MAGE_HOOKS list in the code (via pnpm docs:gen) and guarded by a drift test, so it always matches what mage connect actually installs.

Event Hook id Command Purpose
SessionStart mage:observe:SessionStart mage observe Capture session-start context into the git-ignored learnings scratch.
SessionStart mage:nudge:SessionStart mage nudge The boundary nudge: on a post-compaction SessionStart, surface the just-closed chapter's earned-signal digest (failures, external commands, corrections) as additionalContext for the agent to mine and `mage stage` (ADR-0029). The additionalContext is scaled by the per-KB autonomy level (Operator/Approver/Overseer, ADR-0030): at Operator it is a reminder; at Approver/Overseer it becomes the agent's mandate to groom and write durable notes into the working tree (uncommitted, Gate-2 enforced). It also carries a deterministic capped backlog tally — staged drafts, unmined closed chapters (capped at 9+), and graduation-eligible signatures from the persisted promote tally — rendered as one work-list line. Fires on SessionStart source compact/startup/resume (clear stays a fast no-op); the backlog scan is mtime-gated so a no-new-scratch startup/resume stays ~instant.
UserPromptSubmit mage:observe:UserPromptSubmit mage observe Capture the prompt's intent.
PostToolUse mage:observe:PostToolUse mage observe Capture each tool use — which tool, which files, which skill loaded.
PostToolUseFailure mage:observe:PostToolUseFailure mage observe Capture tool failures (a distinct salient signal).
PreCompact mage:observe:PreCompact mage observe Mark the chapter boundary just before the host compacts.
SessionEnd mage:observe:SessionEnd mage observe Capture session end.
Stop mage:metrics:Stop mage skills --metrics --quiet Roll up context-match: did the skills that auto-loaded actually match the work that followed?
Stop mage:observe:Stop mage observe Capture the agent's final reply (ADR-0019 amendment to ADR-0015).
SubagentStop mage:observe:SubagentStop mage observe Capture autonomous subagent work — a Task subagent's final reply, the one capture point for multi-agent workflows.
PreToolUse mage:memory:PreToolUse mage memory-hook Gate-0 (ADR-0032): redirect + scrub a native-memory write into mage's note schema before it touches disk, or deny a write to a generated index.
PostToolUse mage:memory:PostToolUse mage memory-hook Nudge `mage groom` after a captured topic-note write (ADR-0032).
Stop mage:flatten:Stop mage flatten --quiet ADR-0035 working-tree sweep: at turn-end, after CC's async restamp settles, flatten any note CC restamped this turn back to mage's flat schema — keeping the working tree neutral between commits (commit-flatten stays the durable guarantee).

Each row is one hook group mage owns:

  • Event — the host lifecycle moment that fires the command (for example SessionStart, PostToolUse, Stop).
  • Hook id — the stable mage:<role>:<event> tag. mage upserts and removes groups by this id, so re-running mage connect is idempotent and self-healing (a drifted command is replaced in place). mage doctor compares the installed ids against this list to detect drift.
  • Command — the mage CLI invocation the host runs. Most are mage observe; these are plumbing you never type by hand.
  • Purpose — what that capture point records.

The mage:observe:* rows are the workhorses. They fan out across the host’s lifecycle — session start, each prompt you submit, each tool use, tool failures, the pre-compaction boundary, session end, the agent’s final reply, and a subagent’s final reply — and append one event apiece to a gitignored capture scratch under your knowledge base. They carry no matcher, so they observe every tool, not a subset.

Two design rules matter for trust:

  • observe never blocks the host. Capture is append-only and best-effort: if a capture step errors, it stays out of your way and the host keeps going. mage is memory, not a gate.
  • Capture rides the host, with no runtime daemon. There is no separate process to start, supervise, or leak. The hooks are the entire runtime surface.

The one capture-adjacent hook that does more than append is mage:nudge:SessionStart — the boundary nudge. A compaction is when your host summarizes a long conversation and starts a fresh chapter; the detail of the chapter that just closed is exactly what is most at risk of being forgotten.

The nudge runs on SessionStart and writes nothing itself — it hands the host agent a read-only digest as additional context, and the agent decides what to stage. It has two halves with different triggers: the fresh-chapter digest renders only when the host reports source === "compact" (the one boundary where a chapter just closed), while the autonomy-scaled backlog mandate can fire on compact, startup, or resume. Only /clear is a fast no-op — there is nothing to reflect on.

It lives on SessionStart, not PreCompact or SessionEnd, for two concrete reasons baked into the code:

  • PreCompact fires before the chapter closes, so the chapter is not yet complete to distill.
  • SessionEnd cannot inject context — its output has nowhere to go because the session is already ending.

SessionStart with source === "compact" is the first moment that can both see the closed chapter and hand text back to you.

See The boundary nudge for the full digest-and-mandate contract and how the agent’s resulting drafts flow into Stage and groom, and the Commands reference for the CLI surface behind these hooks.