greprag 5.36.0 → 5.38.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.
@@ -1,241 +0,0 @@
1
- ---
2
- name: lore-advisor
3
- description: |
4
- Digest the smell queue (raw field signals → fix the broken mechanism + instantiate
5
- durable lore), audit project lore for drift, mine episodic memory for emergent
6
- learnings, promote project-agnostic lore to global. One-at-a-time conversational
7
- review — never bulk-prune.
8
-
9
- Trigger phrases: "/lore-advisor", "/lore", "digest smells", "drain the smell queue",
10
- "any smells", "review my lore", "audit lore", "lore is stale", "prune lore",
11
- "mine episodic for lore".
12
- metadata:
13
- author: travsteward
14
- version: "1.2.0"
15
- repository: https://github.com/travsteward/greprag
16
- license: MIT
17
- ---
18
-
19
- # Lore Advisor
20
-
21
- Project lore = durable LEARNINGS — reusable system properties, constraints, and gotchas worth re-surfacing in a future session. Seeded via `greprag lore add`, mined from episodic memory's `learned` / `ruled_out` claims. Distinct from static project knowledge (CLAUDE.md, docs, code) AND from session narration / transient run-state. Lore decays — paths change, conventions die, "learned that X" stops being true. This skill keeps the substrate healthy.
22
-
23
- **The advisor's core skill is one judgment: durable lore vs ephemeral noise.** Episodic memory is a firehose — only ~1 claim in 10 is durable lore; the rest is session narration, run-state, or docs material. No regex finds the keepers; the advisor's read does. The durability gate below makes that judgment explicit.
24
-
25
- Lore is moving from a passive list toward **event-bound / semantic injection** — pushed at the agent when relevant, not browsed (greprag design: `docs/lore-triggers.md`). Until PUSH ships, add lore durable-first so it is injection-ready.
26
-
27
- The skill is **conversational**, not autonomous. Every prune / promote / edit / add decision goes through the operator one at a time. Bulk actions are forbidden.
28
-
29
- **Two feeds, one digestion.** Lore now has two supplies: the *deliberate* smell queue (`greprag lore smell`, raw field signals — `docs/lore-smell.md`) and the *automatic* episodic `learned` / `ruled_out` claims. Phase 0 drains the smell queue first; Phase B mines episodic. Both pass through the same durability gate — but a smell additionally asks whether a broken **mechanism** in the harness needs fixing (the fix ladder in Phase 0), not just whether a durable truth needs recording.
30
-
31
- ## Trigger phrases
32
-
33
- `/lore-advisor`, `/lore`, "digest smells", "drain the smell queue", "any smells", "review my lore", "audit lore", "lore is stale", "prune lore", "mine episodic for lore".
34
-
35
- ## What it does
36
-
37
- Four phases, run in order (Phase 0 first). Operator may skip any phase. Each phase walks one entry at a time — never bulk-prune.
38
-
39
- - **Phase 0 — Smell digestion.** Drain the raw smell queue (`greprag lore smells`): per smell, fix the broken mechanism (hooks first, code second) and/or instantiate the durable truth, then retire it. Deliberate field signals outrank auto-mined claims, so this runs first.
40
- - **Phase A — Drift check.** Scan current lore for rot: stale file paths, conventions the codebase no longer follows (derived live, NOT from a static list), misfiled static-knowledge, age-based decay.
41
- - **Phase B — Episodic mining.** Mine episodic memory's `learned` / `ruled_out` claims; surface only candidates that pass the durability gate; offer to add.
42
- - **Phase C — Global promotion.** Identify project-agnostic lore that belongs in `~/.claude/docs/chip-spawn.md` as a universal rule.
43
-
44
- ## The durability gate (core discipline)
45
-
46
- Before lore is kept (Phase A), added (Phase B), or promoted (Phase C), it must pass three tests. Fail ANY → it is not lore.
47
-
48
- 1. **DURABLE** — a standing property, rule, constraint, or gotcha true beyond one session. NOT point-in-time state. ✗ "no watcher was running", "the id was still e582edf0", "the corpus is proven end-to-end".
49
- 2. **REUSABLE** — would help a FUTURE session understand the system or avoid a mistake. NOT narration of work done. ✗ "Chip C split corpus.ts into eight modules", "the CLI was bumped to v5.16.0". Abstract instances to rules: "sub 3006's price is archived" → "an inactive Stripe price blocks dunning-recovery".
50
- 3. **NON-OBVIOUS** — a property you could not read off the surface. ✓ "Postgres caps a statement at 65,535 bind parameters". ✗ "the API runs on Cloudflare Workers" (ambient project knowledge → belongs in docs, not lore).
51
-
52
- This is the same gate the hourly compactor applies at write-time (greprag, 2026-06-01) — advisor and compactor converge on one filter.
53
-
54
- ## Forbidden practices (HARD RULES)
55
-
56
- - **Never delete lore without explicit operator confirmation.** Each delete is its own y/n.
57
- - **Never edit `~/.claude/docs/chip-spawn.md` without explicit operator confirmation.** Global rules are sticky.
58
- - **Never bulk-prune.** Walk one at a time. If the operator says "just prune all the obvious ones," confirm the list aloud first ("I'd delete: A, B, C — confirm?") before any action.
59
- - **Never modify lore from a different project.** The skill only operates on the current project (resolved via `greprag lore list`).
60
-
61
- ## Phases
62
-
63
- ### Phase 0 — Smell digestion
64
-
65
- Smells are the *deliberate* lore feed: raw, undigested signals dropped from the field via `greprag lore smell` (`docs/lore-smell.md`). Unlike an episodic claim, a smell often names a **broken mechanism in the harness**, not just a fact. Digestion does two jobs per smell — **fix** the mechanism and **instantiate** the durable truth — and runs FIRST, because a deliberate signal outranks auto-mined claims.
66
-
67
- 1. Pull the queue:
68
- ```bash
69
- greprag lore smells --format json
70
- ```
71
- Parse `smells[]` (`nodeId`, `text`, `createdAt`). Empty → say "No smells awaiting digestion." and move to Phase A.
72
-
73
- 2. Walk one smell at a time. First **untangle** it — a single drop often conflates several mechanisms and truths (e.g. a dead-mailbox bug AND a "re-task ≠ launch a chip" insight). Separate them before triaging.
74
-
75
- 3. For each, **investigate** (reproduce / read the relevant code or hooks to confirm it's real), then ask the two questions:
76
-
77
- - **Is there a broken MECHANISM?** Fix it via the **fix ladder** — lowest rung that holds the fix:
78
- 1. **First pass — fix it in the hooks.** A PreToolUse guard, a UserPromptSubmit injection, a notification. Cheapest, reversible, and the same machinery as lore-triggers — ships as DATA, no deploy. Most mechanism smells resolve here.
79
- 2. **Second pass — fancier coding.** Only when a hook can't express the fix: server-side logic, a bounce, a schema or CLI change. The advisor does NOT implement code-tier fixes inline — spawn a chip (`spawn_task`, per `~/.claude/docs/chip-spawn.md`) or hand to the operator.
80
-
81
- If the fix is architectural (a recurring failure class), route through `/root-cause` — fix the pattern that makes the bug possible, never slap a guard on today's trigger.
82
-
83
- - **Is there a durable TRUTH?** Apply the durability gate (below). If it passes, instantiate as durable lore — and, once triggers ship, attach its injection rule (`docs/lore-triggers.md`):
84
- ```bash
85
- greprag lore add "<clean standing rule>" --scope <scope>
86
- ```
87
-
88
- 4. **Summarize + confirm before ANY action** — a smell is a brief, and the hard rule is the advisor never auto-acts on a brief. Present:
89
- ```
90
- SMELL [<nodeId>] (<date>)
91
- "<text>"
92
- Triage:
93
- • mechanism: <...> → fix: [hook|code|root-cause] <proposal>
94
- • truth: <...> → lore: "<rule>" scope=<s>
95
- Action? (f)ix / (i)nstantiate / (b)oth / (s)kip / (n)oise
96
- ```
97
- - **fix** → apply the hook-tier fix (after confirm), or spawn the chip for a code-tier fix.
98
- - **instantiate** → `greprag lore add "<rule>" --scope <scope>` with the durability-gated rule.
99
- - **both** → fix and instantiate.
100
- - **skip** → leave the smell in the queue for a later pass (no retire).
101
- - **noise** → already-handled or not real; retire without action.
102
-
103
- 5. **Retire** only once the smell's content is preserved — the fix landed, a durable lore entry captures the constraint, OR a chip/TODO owns the code-tier fix. Never retire a smell whose fix is merely *planned*. Retire = delete (interim, until a real `status` field exists):
104
- ```bash
105
- greprag lore delete <nodeId>
106
- ```
107
- Confirm by printing `Retired smell [<nodeId>].`
108
-
109
- 6. Phase summary: `Phase 0: N smells. Fixed F (H hooks, C chips). Instantiated I. Skipped S. Noise X.`
110
-
111
- ### Phase A — Drift check
112
-
113
- 1. Pull the current project's lore as JSON:
114
- ```bash
115
- greprag lore list --format json
116
- ```
117
- Parse `lore[]`. Each entry has `nodeId`, `text`, `scope`, `createdAt`.
118
-
119
- 2. For each entry, run three heuristic checks:
120
-
121
- - **File-path check.** Extract any path matching `packages/<...>/<file.ext>`, `~/.claude/<...>`, `adr/<...>`, `docs/<...>`, `migrations/<...>`, `scripts/<...>`, `tests/<...>`. For each, verify the file exists relative to the project root:
122
- ```bash
123
- test -f <path> && echo OK || echo MISSING
124
- ```
125
- If MISSING → flag with `reason: "file-not-found:<path>"`.
126
-
127
- - **Killed-convention check.** A convention can die — a renamed command, a replaced address grammar, a removed hook. The drift signal is NOT a hardcoded list: a static list of dead conventions rots like any other frozen artifact (it has no provenance and no one maintains it — the exact failure this skill exists to fight). Derive it live instead. Cross-reference the lore text against recent `ruled_out` claims and the project CHANGELOG / releases:
128
- ```bash
129
- greprag memory search "<key term> renamed OR removed OR replaced OR deprecated"
130
- ```
131
- If the lore asserts a convention the codebase no longer follows → flag `reason: "dead-convention"`.
132
-
133
- - **Misfiled-convention check.** Flag lore that is really *static project knowledge* — a build/deploy command, a file-path map, an architecture rule, a coding standard — which belongs in CLAUDE.md / `docs/`, not in decay-prone lore. This is the most common rot: a bulk seed of conventions poured into lore that then drifts out of sync with the docs (it fails the durability gate's REUSABLE/NON-OBVIOUS tests — it is ambient knowledge, usually already documented elsewhere). Flag `reason: "misfiled-convention"`.
134
-
135
- - **Age check.** If `createdAt` is older than 90 days from today AND no other heuristic fired, flag with `reason: "age-90d:<days>"`. Not automatically stale — just worth re-verifying.
136
-
137
- 3. Surface each flagged entry one at a time. Format:
138
- ```
139
- [<nodeId>] scope=<scope> reason=<reason>
140
- Text: <text>
141
- Action? (k)eep / (e)dit / (d)elete / (s)kip
142
- ```
143
- - **keep** → no-op, move to next entry.
144
- - **edit** → ask for the new text, then:
145
- ```bash
146
- greprag lore delete <nodeId>
147
- greprag lore add "<new-text>" --scope <scope>
148
- ```
149
- - **delete** → `greprag lore delete <nodeId>`. Confirm by printing `Deleted [<nodeId>].`
150
- - **skip** → no-op, move to next entry.
151
-
152
- 4. Phase summary: `Phase A: reviewed N. Kept K. Edited E. Deleted D. Skipped S.`
153
-
154
- ### Phase B — Episodic mining
155
-
156
- The richest lore source is the compactor's structured `learned` / `ruled_out` claims (tagged nodes, one per durable learning). As of greprag 2026-06-01 the hourly compactor applies the durability gate at write-time, so these claims are already durable-first — but the advisor's read is still what separates lore-grade from the rest.
157
-
158
- 1. Resolve the current project's `projectId`:
159
- ```bash
160
- greprag project-id
161
- ```
162
-
163
- 2. Pull recent episodic memory (last 30 days). Claims are not yet exposed via a dedicated CLI surface, so mine the daily/hourly summaries — which now carry the compactor's durable claims:
164
- ```bash
165
- FROM=$(date -u -d '30 days ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)
166
- TO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
167
- curl -sf "https://api.greprag.com/v1/memory/by-period?projectId=<projectId>&type=daily&from=$FROM&to=$TO&limit=30" \
168
- -H "Authorization: Bearer $GREPRAG_API_KEY"
169
- ```
170
- Parse `rows[]` (`created_at`, `body`). *(When a `greprag memory claims --tag learned,ruled_out` surface exists, prefer it — it returns the structured claims directly, no prose scan.)*
171
-
172
- 3. Find candidate learnings — sentences signalling a durable property. Markers: `learned that`, `the gotcha is`, `won't work because`, `turns out`, `requires`, `only … if`, `caps at`, `blocks`. Skip < 30 or > 300 chars.
173
-
174
- 4. **Apply the durability gate to every candidate.** Most fail — that is correct and expected (~90% of raw learnings are not lore). Surface ONLY candidates that pass all three tests, one at a time:
175
- ```
176
- Candidate (durable · reusable · non-obvious):
177
- "<sentence>"
178
- Add to lore? (a)dd / (e)dit / (s)kip
179
- ```
180
- - **add** → ask for scope (`general`; `env` for credentials/vars; or a `<subsystem>-touch` tag naming the moment it would be injected). Then:
181
- ```bash
182
- greprag lore add "<sentence>" --scope <scope>
183
- ```
184
- - **edit** → polish to a clean standing rule (abstract any instance → rule), then add.
185
- - **skip** → no-op.
186
-
187
- 5. Phase summary: `Phase B: scanned N summaries, M passed the durability gate. Added A. Skipped S.`
188
-
189
- ### Phase C — Global promotion
190
-
191
- 1. Re-pull current lore (`greprag lore list --format json`).
192
-
193
- 2. For each entry, classify as **project-specific** or **project-agnostic** by these heuristics:
194
- - **Project-specific** (skip): mentions a project-specific path (`packages/`, `migrations/`, `adr/`, project-specific module names), a project-specific table/column, an internal service name.
195
- - **Project-agnostic** (candidate): mentions only universal concepts — `worktree`, `npm`, `git`, `node_modules`, `Claude Code`, `hook`, `~/.claude/`, `npm link`, `npm publish`, env var names that are obviously generic (`PATH`, `HOME`, `NODE_ENV`).
196
-
197
- 3. For each agnostic candidate, before showing it, verify `~/.claude/docs/chip-spawn.md` and `packages/cli/skill/templates/chip-spawn.md` (in the current repo if it's the `greprag` repo, otherwise fetch from `npm show greprag` or skip) are in sync:
198
- ```bash
199
- diff ~/.claude/docs/chip-spawn.md <(npm exec --package=greprag -- cat ../skill/templates/chip-spawn.md 2>/dev/null || echo MISSING)
200
- ```
201
- If they DIFFER, stop Phase C and tell the operator:
202
- > `chip-spawn.md drift detected between ~/.claude/docs/chip-spawn.md and the template. Resolve manually before promoting any lore.`
203
-
204
- 4. Present each candidate:
205
- ```
206
- [<nodeId>] This lore mentions only universal concepts:
207
- "<text>"
208
- Promote to ~/.claude/docs/chip-spawn.md as a global rule? (y)es / (n)o / (e)dit
209
- ```
210
- - **yes** →
211
- 1. Append to BOTH `~/.claude/docs/chip-spawn.md` AND (when in the greprag repo) `packages/cli/skill/templates/chip-spawn.md`. The append goes under the numbered "Every chip prompt:" list as the next item, preserving HARD-RULE styling when appropriate.
212
- 2. Delete the per-project entry: `greprag lore delete <nodeId>`.
213
- 3. Confirm: `Promoted [<nodeId>] → global chip-spawn rule.`
214
- - **edit** → ask for polished text, then yes-path with the new text.
215
- - **no** → no-op, move to next entry.
216
-
217
- 5. Phase summary: `Phase C: evaluated N. Promoted P to global. Skipped S.`
218
-
219
- ## Report
220
-
221
- After all three phases, print one combined line:
222
-
223
- ```
224
- Digested D smells (fixed F, instantiated I). Reviewed N lore. Pruned X. Edited Y. Added Z from episodic. Promoted W to global.
225
- ```
226
-
227
- If any phase was skipped (operator pressed q / Ctrl-C / typed "skip phase"), include `(phase <X> skipped)` per skipped phase.
228
-
229
- ## When this skill should be invoked
230
-
231
- - Operator types `/lore-advisor` or `/lore`, or says "digest smells," "drain the smell queue," "any smells."
232
- - The `⚠ N smells awaiting digestion` footer fires on a greprag command — the smell-queue nudge. Offer to run Phase 0.
233
- - Operator says "audit my lore," "lore is stale," "prune lore," "mine episodic for lore," "any new learnings worth saving?"
234
- - Proactively offer the skill at the end of a `/greprag` briefing if `greprag lore smells` is non-empty, if `greprag lore list` shows entries older than 90 days, OR if the operator just finished a refactor / rename and lore drift is likely.
235
-
236
- ## Notes
237
-
238
- - This skill is operator-driven. Each phase pauses for input. Don't batch decisions — that defeats the purpose.
239
- - For new lore added in Phase B, prefer the compactor's phrasing — but rewrite to a clean standing rule when it embeds an instance ("sub 3006…") or transient framing.
240
- - For Phase C promotions, prefer the original phrasing too — but rewrite if the lore embeds a project-specific noun that needs generalizing.
241
- - **Convergence:** the compactor's write-time durability gate (greprag `docs/episodic-memory-changelog.md`, 2026-06-01) and this skill's gate are the same filter. As the compactor tightens, Phase B's yield rises and this skill shifts from "find lore" toward "wire lore to its injection trigger" (`docs/lore-triggers.md`).