greprag 5.38.0 → 5.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,12 +7,13 @@ Live push delivery via SSE. Use whenever you'd otherwise loop `greprag inbox` on
7
7
  ```bash
8
8
  greprag inbox watch # tenant-wide stream
9
9
  greprag inbox watch --project <name> # only messages addressed to this project
10
- greprag inbox watch --session <id> # only messages targeting this session (plus broadcasts)
10
+ greprag inbox watch --session <id> # only messages targeting this session (strictest)
11
+ greprag inbox watch --receptionist # also wake on the front desk (cold opens + email)
11
12
  greprag inbox watch --since <id-or-iso> # resume from a known cursor
12
13
  greprag inbox watch --json # one JSON object per line (preferred under Monitor)
13
14
  ```
14
15
 
15
- `--project` and `--session` compose. `--session` is the strictest filter: only messages with matching `to_session_id` (or `to_session_id IS NULL` for broadcasts) get through. This eliminates cross-session noise when several Claude sessions watch the same project's inbox at once.
16
+ `--project` and `--session` compose. `--session` is the strictest filter: only messages with matching `to_session_id` get through. The tenant catch-all (cold open / inbound email — `to_session_id IS NULL`) does NOT reach a session- or project-scoped watcher; only a `--receptionist` watcher wakes on it (Option C). adr: adr/address-grammar.md. This eliminates cross-session noise when several Claude sessions watch the same project's inbox at once.
16
17
 
17
18
  Each message arrives within ~500ms of the sender's `greprag send` (210ms verified end-to-end). Connection auto-reconnects with exponential backoff; the watcher tracks last seen message id and uses it as `since=` on reconnect — nothing dropped, nothing duplicated.
18
19
 
@@ -46,7 +47,7 @@ greprag inbox watch --session <parent-session-id> --json
46
47
 
47
48
  Arm it **bare** — no `while true … sleep 1` wrapper. The wrapper was removed 2026-06-04: it was the orphan that outlived its Monitor task and piled up until the desktop OOM-crashed. The three layers now cover everything without it: Monitor `persistent: true` restarts the command if the supervisor process itself dies; the in-process supervisor respawns the SSE child on any inner crash; and EPIPE-terminal kills the whole tree when the consuming session goes away. Adding a `while`-loop back re-introduces the orphan — don't.
48
49
 
49
- If the parent has no session identity (rare — older sessions before session-scope shipped), fall back to `--project <parent-project>`. The chip then sends without `--session` and the message reaches every watcher under the project.
50
+ If the parent has no session identity (rare — older sessions before session-scope shipped), give it one rather than relying on a fan-out: project broadcasts were removed (2026-06-07), so a chip reaches the parent only by session id, or by cold-opening its front desk (bare `<handle>@greprag.com`, surfaced on a manual `greprag inbox --front-desk` a `--project` watcher won't wake on it).
50
51
 
51
52
  ## Pattern: post-send listens for replies
52
53
 
@@ -58,7 +59,7 @@ Any session that sends a message that could draw a directive in response arms th
58
59
  greprag inbox watch --session <own-session-id> --json
59
60
  ```
60
61
 
61
- The `--from-session` flag on the outgoing message tells the recipient where to address replies; the `--session` filter on the watcher narrows incoming traffic to messages aimed at this exact session (plus broadcasts).
62
+ The `--from-session` flag on the outgoing message tells the recipient where to address replies; the `--session` filter on the watcher narrows incoming traffic to messages aimed at this exact session.
62
63
 
63
64
  ## Why Monitor, not Bash background
64
65
 
@@ -5,13 +5,16 @@ Send and read messages across sessions/projects/tenants. Plus the retract path f
5
5
  ## Read
6
6
 
7
7
  ```bash
8
- greprag inbox # list unread (auto-marks read)
9
- greprag inbox --all # full history
10
- greprag inbox keep <id> # extend a read message's TTL
8
+ greprag inbox # list unread for THIS session — its own lines only
9
+ greprag inbox --front-desk # the front desk: cold opens + inbound email (add --peek to survey)
10
+ greprag inbox --all # full history, every session (audit peek)
11
+ greprag inbox keep <id> # extend a read message's TTL
11
12
  greprag inbox delete <id>
12
13
  ```
13
14
 
14
- Auto-read semantics: any message returned by `greprag inbox` (without `--all`) is marked read in the same call. Once read, it stops appearing in notifications. TTL deletes read messages after 14 days. Use `keep` to extend before expiry.
15
+ Scoping (2026-06-10): the default `greprag inbox` shows only lines where THIS session is an endpoint (sender or recipient). The **front desk** — the tenant catch-all (cold opens + email addressed to the human, not a session) is no longer folded into a session's view; it surfaces as a discreet footer count (`📬 N at the front desk`) and is read on demand via `--front-desk`. This stops cold opens from flooding every session and from being silently marked-read by a working agent.
16
+
17
+ Auto-read semantics: any message returned by `greprag inbox` (without `--all`/`--peek`) is marked read in the same call. Once read, it stops appearing in notifications. TTL deletes read messages after 14 days. Use `keep` to extend before expiry.
15
18
 
16
19
  ## Send
17
20
 
@@ -62,12 +65,11 @@ v0.12+ grammar:
62
65
 
63
66
  | Form | Use | Behavior |
64
67
  |---|---|---|
65
- | `<handle>@greprag.com` | First contact (cold open) | **Tenant catch-all.** Use when you DON'T know the recipient's session. Lands in their inbox for a manual `greprag inbox` check; does NOT wake their live session watcher. No `--broadcast` needed. They reply to your session (pass `--from-session`) to establish the live line. |
68
+ | `<handle>@greprag.com` | First contact (cold open) | **Tenant catch-all.** Use when you DON'T know the recipient's session. Lands at their front desk for a manual `greprag inbox --front-desk` check; does NOT wake their live session watcher. They reply to your session (pass `--from-session`) to establish the live line. |
66
69
  | `<handle>@greprag.com/<session-uuid>` | What you SEND with (normal) | Targets one specific session. UUID or 8-hex short form. Only that session's watcher receives. |
67
- | `<handle>@greprag.com/<project-name>` | What you SEND with (rare) | Project-wide broadcast — every watcher in that project receives. Requires `--broadcast`. Reserve for genuine "everyone in this project should know." |
68
70
  | `me` / `self` | Shortcut for your own tenant | Tenant catch-all to yourself (manual-check note). |
69
71
 
70
- Disambiguation: a single segment after `/` is a session if it matches `[0-9a-f]{8}` (8-hex short form) or full UUID, otherwise a project name. Project names that look like UUIDs are rejected at registration time. The bare handle (no `/`) is the tenant catch-all.
72
+ Disambiguation: a single segment after `/` is a session if it matches `[0-9a-f]{8}` (8-hex short form) or full UUID. Anything else parses as a project name and is **rejected** project broadcasts were removed (2026-06-07); send to a session or the bare front desk instead. The bare handle (no `/`) is the tenant catch-all.
71
73
 
72
74
  First-contact handshake: a sender who doesn't know your session sends to bare `<you>@greprag.com`; you see it on a manual `greprag inbox` (look for `· cold open` and the `from session …` line); you reply with `--to <them>@greprag.com/<their-session> --from-session <yours>`. From then on both sides know each other's session and watchers fire both ways.
73
75
 
@@ -77,7 +79,7 @@ First-contact handshake: a sender who doesn't know your session sends to bare `<
77
79
 
78
80
  **Real emails are NEVER routing addresses.** `users.email` is auth credential only. If you don't know the recipient's numeric handle, ask the user — don't guess from their email. adr: adr/numeric-handles.md
79
81
 
80
- Session targeting is the default and expected form. Project broadcasts are intentional opt-ins. adr: adr/address-grammar.md
82
+ Session targeting is the default and expected form; the bare handle is the cold-open front desk. Project broadcasts were removed (2026-06-07) — a project-name target errors out. adr: adr/address-grammar.md
81
83
 
82
84
  ## retract
83
85
 
@@ -307,7 +307,7 @@ cat > <cwd>/.greprag/project.json <<EOF
307
307
  EOF
308
308
  ```
309
309
 
310
- Register so inbox addressing (`<email>/<project_name>`) resolves:
310
+ Register so the project name resolves for `--project` filters (`greprag inbox --project <name>`, `inbox watch --project <name>`) and is reserved against the session-id pattern. (A project is not a send target — project broadcasts were removed 2026-06-07.)
311
311
  ```bash
312
312
  curl -sf -X POST "https://api.greprag.com/v1/inbox/projects/register" \
313
313
  -H "Authorization: Bearer ${GREPRAG_API_KEY}" \
@@ -29,7 +29,7 @@ The Mechanic keeps the harness healthy. The loop is **friction → fix → repai
29
29
 
30
30
  **Conversational, never autonomous.** Every repair / drop / edit / record goes through the operator one at a time. Bulk actions are forbidden.
31
31
 
32
- > **CLI:** `greprag fix` is the canon — verbs `log · list · repair · delete · search · scopes`. `greprag lore` remains a back-compat alias.
32
+ > **CLI:** `greprag fix` is the canon — verbs `log · list · repair · delete · search · scopes`.
33
33
 
34
34
  ## What it does — four phases (run in order; operator may skip any)
35
35
 
@@ -88,7 +88,7 @@ A fix is a raw, undigested signal. Auto-detected friction fixes carry a type; ha
88
88
 
89
89
  **Typed friction fixes.** The hourly detector writes its fixes tagged `[friction:<type> · scope=…]` with a pre-extracted `Fix:` clause and structured `frictionType`/`resolution` metadata. Do NOT re-derive — repair the provided fix, mapped by type:
90
90
  - `discovery-waste` — agent rediscovered lore. The `text` IS the fact; the repair is to surface it (fact-seed / session-start injection so no one rediscovers it).
91
- - `human-correction` — operator corrected the agent ≥2× on one point. Repair BOTH legs: the `Fix:` is the durable rule (gate it, `lore add`), AND the mechanism gap (a `UserPromptSubmit`/`PreToolUse` injection at the moment it's needed, or a CLAUDE.md/skill addendum). Rarely `(n)oise` — the operator already paid attention twice; default `(b)oth`.
91
+ - `human-correction` — operator corrected the agent ≥2× on one point. Repair BOTH legs: the `Fix:` is the durable rule (gate it, `fix log --repaired`), AND the mechanism gap (a `UserPromptSubmit`/`PreToolUse` injection at the moment it's needed, or a CLAUDE.md/skill addendum). Rarely `(n)oise` — the operator already paid attention twice; default `(b)oth`.
92
92
  - `repetition` / `reversal` — the `Fix:` is the lesson; surface it, and repair the gap that let the loop/rework happen if there is one.
93
93
  - `model-thrash` — usually no clean repair (`resolution` null); record the deciding criterion only if the window settled it.
94
94
 
@@ -188,3 +188,23 @@ Append `(phase <X> skipped)` per skipped phase.
188
188
  - Operator-driven; each phase pauses for input. Don't batch.
189
189
  - Phase B: prefer the summary's phrasing, but rewrite any instance ("sub 3006…") into a clean standing rule.
190
190
  - The friction taxonomy + the detector are documented at `docs/mechanic.md` and `adr/discovery-waste-extraction.md`.
191
+
192
+ ## Control plane — `greprag mechanic` (repairs as data)
193
+
194
+ Repairs (D3 rows attached to fixes) are managed with `greprag mechanic`, not by editing hooks:
195
+
196
+ ```
197
+ greprag mechanic status inventory: live (shadow|active) repairs grouped by status;
198
+ ⚑ marks shadow rows ready to graduate (≥3 fires or ≥7 days)
199
+ greprag mechanic enable <nodeId> ratify: shadow → active (the graduate gate)
200
+ greprag mechanic disable <nodeId> least destructive: active → shadow (logging continues);
201
+ --retire = terminal, row leaves the matchset
202
+ greprag mechanic why <nodeId> provenance: the friction → fix → repair chain
203
+ greprag mechanic off / on PANIC SWITCH — local file, no network; suspends ALL repairs
204
+ ```
205
+
206
+ **Born shadow → graduate.** Every repair is born `shadow`: it matches and logs would-have-fired
207
+ evidence but injects nothing. Graduation is evidence-first — when `status` flags a row `⚑`, review
208
+ its fire history (`why`) and `enable` it. Nothing goes live without the operator; the gates are
209
+ *merge* (code/file repairs) and *graduate* (row repairs), never a conversational queue walk.
210
+ Full doctrine: `docs/mechanic-repairs.md` Part 4, D6–D8.
@@ -2,17 +2,19 @@
2
2
 
3
3
  The `pre-spawn-check` PreToolUse hook **validates** chip prompts at the spawn boundary, but **cannot inject content** — `modifiedInput` is silently dropped by the CCD harness for MCP `spawn_task` calls (see `adr/spawn-task-hook-mode.md` 2026-05-27 entry). The agent writes Block 1 + Block 2 into the prompt itself. Validator rejects with `permissionDecision: deny` and a remediation reason if Block 1 or Block 2 markers are missing.
4
4
 
5
+ > **Part of a multi-chip mission?** If this chip is one of ≥2 aimed at a single objective, you should already be inside a `/chip-leader` plan — your **base branch** and **merge target** (the integration branch, *never* master) come from it. If you're not, stop and run `/chip-leader` first. A lone chip targeting its own objective proceeds here directly.
6
+
5
7
  ## What the agent provides
6
8
 
7
- - `title: "Chip: <verb-phrase>"` — `Chip: ` prefix enforced.
9
+ - `title: "Chip: <verb-phrase>"` — `Chip: ` prefix enforced. **Multi-chip mission?** Use the leader-assigned label: `"Chip <Label>: <verb-phrase>"` (Label = `A`/`B`/`C`… per workstream, from `/chip-leader`) — e.g. `"Chip B: Build freshness engine"`. The validator accepts `Chip: `, `Chip A: `, `Chip 1: ` (regex `^Chip( [A-Za-z0-9]+)?: `). The label is the shared handle the leader and chip both use end-to-end (title → report-back self-ID → merge references).
8
10
  - `prompt:` — Block 1 + task body + Block 2 (templates below).
9
11
  - `cwd:` — optional, lands the chip in a different project root. Repo paths: `~/.greprag/projects.json`.
10
12
 
11
13
  Add `mode: interactive` as the first line of the task body to pause the chip for human reply (default is autonomous).
12
14
 
13
- ## Block 1 — Setup (verbatim, substitute `<slug>` + parent session id)
15
+ ## Block 1 — Setup (verbatim, substitute `<slug>`, `<handle>` + parent session id)
14
16
 
15
- `<slug>` = title slugified (e.g. `Chip: Fix synthesis loop` → `fix-synthesis-loop`). `<8-hex-parent>` = first 8 hex of YOUR session id (printed by SessionStart as "greprag session id: ...").
17
+ `<slug>` = title slugified (e.g. `Chip: Fix synthesis loop` → `fix-synthesis-loop`). `<8-hex-parent>` = first 8 hex of YOUR session id (printed by SessionStart as "greprag session id: ..."). `<handle>` = operator's greprag handle. `<own-session-id>` stays literal — the chip substitutes it from its own SessionStart output.
16
18
 
17
19
  ````
18
20
  **Setup — do this FIRST:**
@@ -22,13 +24,23 @@ main_root=$(git rev-parse --git-common-dir | xargs dirname)
22
24
  cd "$main_root"
23
25
  git worktree add .claude/worktrees/<slug> -b chip/<slug>
24
26
  cd .claude/worktrees/<slug>
27
+ greprag send "IN-FLIGHT: chip/<slug> launched — working" \
28
+ --to <handle>@greprag.com/<8-hex-parent> --from-session <own-session-id>
25
29
  ```
26
30
 
27
- Your parent's session id is `<8-hex-parent>`.
31
+ Your parent's session id is `<8-hex-parent>`. The `IN-FLIGHT` ping is non-negotiable — without it the parent assumes the chip card was never launched.
28
32
 
29
33
  ---
30
34
  ````
31
35
 
36
+ **Multi-chip mission (`/chip-leader`)?** The spawn title alone does NOT reach FleetView's watcher registry — that title is auto-generated by gpt-5.4-nano from your opening turn. So the leader will have you **stamp your registry title in Block 1**, right after the `cd` into the worktree:
37
+
38
+ ```bash
39
+ greprag session retitle <your-own-8hex> "Chip <Label> — <workstream>"
40
+ ```
41
+
42
+ The leader dictates the exact string (e.g. `Chip A — Converter format coverage`); substitute your own 8-hex from SessionStart. This force-sets the registry title so the watcher list + Discord `/switch` line up with the leader's labels. Single chips skip this.
43
+
32
44
  ## Block 2 — Report back (verbatim, substitute `<slug>` + parent session id)
33
45
 
34
46
  Handle is the operator's greprag handle (from `~/.greprag/identity.json`, field `handle` — strip the `@greprag.com` suffix).
@@ -50,16 +62,26 @@ Substitute `<own-session-id>` from your SessionStart hook output.
50
62
  **Cleanup discipline (HARD RULE):** chip prompts forbid `git clean`, `git reset --hard`, `git worktree remove`, `git checkout <other>`, raw `rm -rf` outside the worktree's tracked files.
51
63
  ````
52
64
 
53
- ## After spawning — your watcher is already armed
65
+ ## After spawning — arm YOUR OWN watcher (HARD RULE)
54
66
 
55
- The chip reports back to **your** session id via `greprag send`, and the detection-gated `notify` hook keeps a session-scoped watcher live for you on any unarmed turn (`adr/session-id-awareness.md`). The chip's report is filed with `to_session_id = your session`, which that watcher delivers (filter: `to_session_id = session OR NULL`). So you do **not** arm a watcher per spawn the one auto-armed watcher covers every chip you spawn. The spawn is the whole loop.
67
+ The chip reports back to **your** session id via `greprag send`. Nothing else reliably arms you to receive it: the SessionStart arm-directive and the turn-2 UserPromptSubmit fallback are agent-choice and may not fire, and a report that lands in an unwatched inbox sits silently until someone runs `greprag inbox` by hand. So **immediately after `spawn_task` returns, arm your own watcher** unless you already have one running this session (one watcher covers every chip you spawn; never double-arm):
56
68
 
57
- Safety net: if `greprag inbox watchers` shows none for your 8-hex (auto-arm disabled, or it died and the next turn hasn't re-armed yet), arm one under **Monitor (persistent:true)**: `while true; do greprag inbox watch --session <your-8hex> --json; echo "[restart]" >&2; sleep 1; done`. Never double-arm a session that already has a live watcher.
69
+ ```
70
+ Monitor (persistent:true): `while true; do greprag inbox watch --session <your-8hex> --json; echo "[restart]" >&2; sleep 1; done`
71
+ ```
72
+
73
+ `<your-8hex>` = your own session id (from SessionStart). Arming is what makes the chip's "done" report surface live instead of being lost — the spawn is only half the loop.
74
+
75
+ **Launch state:** the Block 1 `IN-FLIGHT` ping is your only signal the operator actually clicked the chip card. No ping = assume the card is still unpressed — don't wait on results from a chip that was never launched.
58
76
 
59
77
  ## Before composing
60
78
 
61
- `greprag lore query --scope chip-startup --project <chip-project> --limit 10 --format markdown`. If non-empty, paste at top of body as `**Project Lore (do not re-discover):**`. Saves 10-20 startup turns.
79
+ `greprag fix list --repaired --project <chip-project> --format markdown` — take the `## chip-startup` section. (Don't use `fix search` for this pull: it requires a positional query that lexically filters, and the query-less `--scope` form mis-parses `--scope` as the query.) If non-empty, paste at top of body as `**Project Fixes (do not re-discover):**`. Saves 10-20 startup turns.
62
80
 
63
81
  ## Merge before testing globally (HARD RULE)
64
82
 
65
83
  Chips never `npm link` from the worktree — dangling symlinks silently break the CLI everywhere (chained the 2026-05-25 wipe). To test a built CLI globally: merge to main via `/commit`, then `npm i -g <pkg>` from main.
84
+
85
+ ## Parent merge discipline — prune at the merge (HARD RULE)
86
+
87
+ When you (the parent) merge a chip branch — via `/commit` or raw `git merge` — prune in the same breath: junction guard (`~/.claude/skills/commit/guard-junctions.sh <worktree>`), `git worktree remove .claude/worktrees/<slug>`, and `git branch -d chip/<slug>` once merged. Deferred cleanup = stale worktrees piling up (field state 2026-06-10: 3 leftovers). Multi-chip missions: worktree dies at the feature-branch merge; the branch lives until the master merge (`/chip-leader` Phase 4).
@@ -0,0 +1,43 @@
1
+ # Workshop Chip — the Mechanic's repair executor
2
+
3
+ The workshop is a chip (`docs/mechanic-repairs.md` D4). Spawn one when **mechanism-tier** friction
4
+ (hook / gate / trigger / code — anything that isn't words-in-a-file-you-own) needs investigation +
5
+ repair. Doctrine-preloaded, drafts everything, installs nothing — the operator gates by **merge**
6
+ (branch) and **graduate** (rows).
7
+
8
+ Compose: standard chip-spawn **Block 1** (incl. the `IN-FLIGHT` ping) + the preload + mission below
9
+ + standard **Block 2**. Title: `Chip: Workshop — <friction one-liner>`.
10
+
11
+ ## Preload block (paste verbatim after Block 1, fill the fix ids)
12
+
13
+ ````
14
+ **Doctrine — read FIRST, in order:**
15
+
16
+ 1. `docs/mechanic-repairs.md` — repair verbs R1–R20, decision log D1–D8, the ladder
17
+ 2. `docs/harness-control-points.md` — the control-point map (where a repair can plug in)
18
+ 3. The fix(es) under digestion: `greprag fix list --project <project> --format json` → look up: <nodeId, …>
19
+
20
+ You are a WORKSHOP CHIP. You pick the rung yourself — that is why you carry the doctrine.
21
+ ````
22
+
23
+ ## Mission shape (adapt the specifics, keep the spine)
24
+
25
+ 1. **Investigate.** Reproduce or read the code/hooks to confirm the friction is real. Untangle —
26
+ one fix often conflates several mechanisms.
27
+ 2. **Pick the rung** — lowest that holds: file edit (R15) → CLI self-intercept (C1) → hook/row tier
28
+ (R2–R8) → code tier. Name the repair verb you chose and why the cheaper rungs don't hold.
29
+ 3. **Implement on YOUR surfaces only.** Code + file edits commit on your chip branch. Row-tier
30
+ repairs (no engine yet): write the proposed D3 `repair` object into your report instead of
31
+ installing anything.
32
+ 4. **Verify.** Build/tests green for code; for any repair, state how the friction fingerprint
33
+ re-fire would prove it failed (the efficacy loop is the success metric).
34
+ 5. **Report back** (Block 2): rung + verb + why, commit hash, proposed repair rows if any,
35
+ fixes to retire on merge.
36
+
37
+ ## Hard rules
38
+
39
+ - **Never merge, push, deploy, or graduate.** The parent owns every gate.
40
+ - Never edit outside your worktree except paths the brief explicitly assigns.
41
+ - A fix is retired only by the PARENT after the repair lands — never delete queue entries yourself.
42
+ - Standard chip cleanup discipline applies (no `git clean` / `reset --hard` / `worktree remove` /
43
+ `checkout <other>` / `rm -rf` outside tracked files).
@@ -1,70 +0,0 @@
1
- # Lore (LEARNINGS substrate)
2
-
3
- Lore = what was learned. Project-specific emergent knowledge — gotchas, discovered constraints, drift-prone observations. Distinct from static project knowledge (which belongs in CLAUDE.md / docs / code structure).
4
-
5
- Whenever you waste tokens *discovering* something a future agent shouldn't have to re-discover, seed it as project lore. Discovery is fine the first time — the failure mode is repeating it every time a chip spawns or a new session opens.
6
-
7
- ## When to seed
8
-
9
- Three signatures of discovery waste:
10
-
11
- - **Search cascade.** ≥3 `Glob` / `Grep` calls to find a path that should be obvious (where do migrations live? where's the inbox table? which file owns the CLI dispatch?). Seed with `scope: chip-startup`.
12
- - **Schema archaeology.** ≥3 file `Read`s to reconstruct the shape of a data type, a JSONB column, or an API request body. Seed the shape (1–3 lines) with `scope: <subsystem>-touch`.
13
- - **Trial-and-error env probing.** Multiple `Bash` attempts at the same env operation (different SSL flags, different connection strings, repeated "is this var set?" checks). Seed the working invocation with `scope: env`.
14
-
15
- ## How to seed
16
-
17
- ```bash
18
- greprag lore add "<one-sentence learning, optionally with a file path>" --scope <scope> [--project <name>]
19
- ```
20
-
21
- Examples:
22
- ```bash
23
- greprag lore add "Migrations live at repo root: migrations/<NNN>_<name>.sql. Apply with node scripts/apply-migration.cjs migrations/<file>.sql." --scope chip-startup
24
-
25
- greprag lore add "Inbox storage uses JSONB metadata on nodes (store kind='inbox'). No inbox_messages table — dropped in migration 035. See packages/core/src/inbox.ts." --scope inbox-touch
26
-
27
- greprag lore add "Build everything from repo root: npm run build (Turborepo). Forced rebuild: npm run build -- --force." --scope general
28
- ```
29
-
30
- ## Scope naming
31
-
32
- Free-form strings — no enum. Check what's already in use first:
33
-
34
- ```bash
35
- greprag lore scopes [--project <name>]
36
- ```
37
-
38
- Conventional scopes:
39
- - `chip-startup` — what a freshly-spawned chip needs in its first 5 turns. Layout, build commands, test runners, key file paths.
40
- - `general` — applies to almost any session in this project.
41
- - `<subsystem>-touch` — lore that matters only when editing a specific subsystem (`inbox-touch`, `episodic-touch`, `enrichment-touch`).
42
- - `env` — environment / credentials / DB connection gotchas.
43
-
44
- Pick the narrowest scope that still applies. A lore entry about migration paths is `chip-startup` (every chip needs it); one about how the hourly compactor's prompt versioning works is `episodic-touch` (only relevant if you're editing that subsystem).
45
-
46
- ## Reading lore back
47
-
48
- ```bash
49
- greprag lore query --scope chip-startup --limit 10 --format markdown # for inlining into a chip prompt
50
- greprag lore query --scope inbox-touch --query "session routing" # lexical-rank within a scope
51
- greprag lore query --query "how do migrations apply" --limit 5 # cross-scope, lexical-rank only
52
- greprag lore list # human-review every entry, grouped by scope
53
- greprag lore delete <nodeId> # prune stale entry
54
- ```
55
-
56
- `--format markdown` returns a numbered list with no decoration — drop straight into a `**Project Lore**` block when spawning a chip.
57
-
58
- ## Deliberate review
59
-
60
- Lore decays as code moves — paths change, conventions die. Run `/lore-advisor` periodically (especially after a refactor or rename) to audit drift, mine episodic memory for newly-emerged learnings, and promote project-agnostic entries to global rules.
61
-
62
- ## Chip-spawn pull pattern
63
-
64
- When composing a `spawn_task` chip prompt, pull `chip-startup` lore into the prompt before dispatching. Full convention: `~/.claude/docs/chip-spawn.md`. One-liner:
65
-
66
- ```bash
67
- greprag lore query --scope chip-startup --project <project> --limit 10 --format markdown
68
- ```
69
-
70
- Wrap the output in a `**Project Lore**` block at the top of the prompt. Skip the block when the output is empty.