# Init Mentoring

> Install the self-updating memory automation for this mentoring setup. Copies the hook scripts into the current project and registers them in .claude/settings.json. Run once, right after cloning/copying claude-code-mentoring into a project.

- Skill: `redavocado22/init-mentoring` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add redavocado22/init-mentoring`
- Raw SKILL.md: https://api.skillmd.com/api/skills/redavocado22/init-mentoring/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: RedAvocado22 (https://skillmd.com/u/redavocado22)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/redavocado22/init-mentoring

---


Install the memory automation into the **current project** (`${CLAUDE_PROJECT_DIR}`), so `./memory/` keeps growing on its own instead of relying on anyone remembering to update it by hand.

## What this does

Three scripts, two hooks:

- **`memory-filter.sh`** (`Stop` hook) — fires after every response. Reads
  `transcript_path`/`cwd` from stdin and immediately forks
  `memory-filter-worker.sh` as a detached background process, then exits.
  This must stay near-instant: `Stop` is synchronous (Claude Code waits for
  it), so the actual work cannot happen here.
- **`memory-filter-worker.sh`** (background only, never registered as a
  hook) — does the real work. Pulls the last real user message plus every
  bit of assistant narration since then out of the transcript, sends it to
  a cheap/fast model (Haiku) with a rubric asking "is this a decision /
  feedback / progress update / pattern worth remembering?", and if `YES`,
  writes a one-line summary to `.claude/hooks/.memory-pending.json`. A `NO`
  writes nothing — costs nothing, leaves no trace anywhere.
- **`memory-pending-check.sh`** (`UserPromptSubmit` hook) — fires when the
  user submits their next message. Reads `.memory-pending.json` if it
  exists, surfaces it as `additionalContext` for that prompt, then deletes
  it (read-once). At that point the **main agent** (not Haiku) decides what
  to actually write and where, following `memory/mentoring_rules.md`'s
  SESSION UPDATE PROTOCOL — the filter never writes memory itself.

**Why split into three instead of one hook doing everything:** measured
latency for a real headless `claude -p` call is ~5-35s (mostly CLI/network
overhead, not the model). A single synchronous `Stop` hook would add that
delay after *every single response*, which defeats the point of a "cheap"
background check. Splitting the slow part into a detached background
process means `Stop` returns in single-digit milliseconds — the check
still happens, it just surfaces on the next turn instead of blocking this
one. Best-effort, not guaranteed-immediate: if the user replies faster than
the worker finishes, that one reminder is skipped and the next turn's
worker run catches up instead.

## Steps

1. **Check dependencies.** Run `command -v jq` and `command -v claude`. If
   either is missing, stop and tell the user which one — everything here
   fails open (never breaks a session) but is a no-op without them.

2. **Copy the hook scripts.**
   - `mkdir -p ${CLAUDE_PROJECT_DIR}/.claude/hooks`
   - Copy this skill's `memory-filter.sh`, `memory-filter-worker.sh`, and
     `memory-pending-check.sh` (all co-located next to this `SKILL.md`) to
     `${CLAUDE_PROJECT_DIR}/.claude/hooks/`.
   - `chmod +x` all three copies.
   - If files already exist at the destination, diff each against its
     source first — if identical, skip; if different, ask the user before
     overwriting (they may have customized it).

3. **Register both hooks in `.claude/settings.json`.**
   - Read the file if it exists; otherwise start from `{}`.
   - This is a **merge**, never a blind overwrite — preserve every existing
     key. Add (or extend, if either array already has entries) this block:
     ```json
     {
       "hooks": {
         "Stop": [
           {
             "type": "command",
             "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/memory-filter.sh",
             "timeout": 10,
             "suppressOutput": true
           }
         ],
         "UserPromptSubmit": [
           {
             "type": "command",
             "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/memory-pending-check.sh",
             "timeout": 5,
             "suppressOutput": true
           }
         ]
       }
     }
     ```
     Both timeouts are short on purpose — `memory-filter.sh` only forks a
     background process, and `memory-pending-check.sh` only reads/deletes a
     small file. Neither should ever take more than a second or two; if one
     does, something is broken, not just slow.
   - Idempotency: before adding, check whether these hooks are already
     registered — if so, don't duplicate the entries.
   - If the `update-config` skill is available in this session, prefer
     delegating this merge to it instead of hand-editing the JSON — it
     knows the current settings.json schema authoritatively and this
     skill's copy of the schema can drift out of date.

4. **Gitignore the pending file.** Add `.claude/hooks/.memory-pending.json`
   to `.gitignore` if it's not already covered — it's ephemeral scratch
   state (may briefly contain a snippet of conversation content) and should
   never be committed.

5. **Verify `memory/feedback_log.md` exists.** The filter's rubric routes
   "confirmation of a working approach" signals there. If the project
   copied an older version of this template without that file, create it
   from `memory/feedback_log.md` in this repo (or prompt the user to pull
   the latest template).

6. **Confirm to the user** in one or two sentences: both hooks installed,
   `Stop` returns instantly (background worker does the real check), a
   flagged turn surfaces as a reminder on the *next* message rather than
   blocking the current one. Mention they can remove it by deleting both
   hook entries from `.claude/settings.json`.

## Do not

- Do not put the Haiku call directly in the `Stop` hook — `Stop` is
  synchronous, so anything slow there blocks the user after every single
  response. Always fork it into `memory-filter-worker.sh` in the
  background.
- Do not make either hook `decision: block` the turn — that risks loops if
  the filter is noisy, and defeats the non-blocking design. Both hooks only
  ever use `additionalContext`.
- Do not run this skill's logic silently as a side effect of something else
  — it edits `settings.json`, which is why `disable-model-invocation: true`
  is set. Only run it when the user explicitly asks (`/init-mentoring`).

