@lorekit/cli 1.67.0 → 1.68.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lorekit/cli",
3
- "version": "1.67.0",
3
+ "version": "1.68.0",
4
4
  "description": "Install the LoreKit shared-memory skill and run health checks for the LoreKit MCP server.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -175,3 +175,13 @@ new count. Then either move to the next scope or close out the pass.
175
175
  - **Someone else's lesson deserves more caution.** A lesson tagged from another
176
176
  agent or a teammate is not automatically yours to delete — when in doubt,
177
177
  archive rather than hard-delete, and flag it in the plan.
178
+ - **`codebase-knowledge` is durable structure, not an audit log.** The shared
179
+ `codebase-knowledge` bucket (tag `codebase-knowledge`, `knowledge::<symbol>@<path>`
180
+ and `hotspot::<path>` keys — see the `lorekit-setup` skill) is a live,
181
+ multi-loop signal store: every LoreKit loop in the repo both reads and feeds it.
182
+ Groom it like a signal store, never like the audit-log prose it superficially
183
+ resembles. Lint its structure and dedupe genuine key collisions, but do **not**
184
+ mass-archive by age or volume, and do **not** re-key a `knowledge::<symbol>@<path>`
185
+ entry off its structural key — that key is the join a reader matches against.
186
+ A stale fact carries `verified_at_sha`; prefer letting its TTL expire or the
187
+ owning loop overwrite it over hand-removing it.
@@ -75,7 +75,12 @@ Read at the moments where prior lessons change what you do:
75
75
 
76
76
  Follow [rules/intake.md](./rules/intake.md).
77
77
  The short version: resolve the current scope, list lessons narrow-to-broad,
78
- and treat matches as *considerations*, not commands.
78
+ and treat matches as *considerations*, not commands. When a run is about to
79
+ change code, intake step 6 reads the standard shared **`codebase-knowledge`**
80
+ bucket — the cross-loop `hotspot::<path>` / `knowledge::<symbol>@<path>` record
81
+ for the files this run will touch, matched by `symbol@path`. A run that verifies
82
+ a structural fact contributes it back, so the layer compounds across every
83
+ LoreKit loop in the repo (contract in the `lorekit-setup` skill).
79
84
 
80
85
  ## When to write (retrospective)
81
86
 
@@ -59,3 +59,44 @@ If lessons matched, note them in one or two lines before proceeding
59
59
  ("LoreKit: 2 relevant lessons — worktree naming, migration order").
60
60
  If nothing matched, say nothing and continue.
61
61
  If the MCP tools are not connected, note it once and continue without them.
62
+
63
+ ## 6. When the run will change code — read the shared codebase-knowledge
64
+
65
+ Steps 1–4 read **your own** bucket. When this run is about to change code, do one
66
+ more read — not optional, it is how the cross-loop synergy reaches you: the shared
67
+ **`codebase-knowledge`** bucket. This is the repo-scoped, cross-loop record of what
68
+ the codebase has taught every LoreKit loop that touched it
69
+ (`knowledge::<symbol>@<path>` facts, `hotspot::<path>` counters). Its keys are
70
+ **structural** (`symbol@path`, a file path) rather than prose, so you match them
71
+ against the concrete files and symbols this run will touch and pull only the
72
+ records that apply. Read it for exactly the files you will change:
73
+
74
+ ```text
75
+ memory.list { scope: "repo::{owner}/{repo}", tags: ["codebase-knowledge"], limit: 100 }
76
+ # keep only hotspot::<path> / knowledge::<symbol>@<path> whose <path> (and <symbol>)
77
+ # the current change will actually touch — a known regression hotspot or a
78
+ # repeatedly-flagged symbol is then planned with that history in hand.
79
+ ```
80
+
81
+ If this run **verifies** a structural fact about a symbol or file (a consumer
82
+ count you swept, an invariant you confirmed, a defect you fixed at a SHA),
83
+ contribute it back so the next code-changer benefits — write it to
84
+ `codebase-knowledge` under the write contract in the `lorekit-setup` skill,
85
+ `rules/self-improvement-loops.md § Shared codebase-knowledge`. The layer fills
86
+ because its readers also feed it.
87
+
88
+ Four rules make this safe, and they are non-negotiable:
89
+
90
+ - Match **structurally and narrowly** — the paths/symbols of this run, never the
91
+ whole bucket.
92
+ - It **raises care, never lowers a bar** — plan more coverage on a hotspot; an
93
+ absent record is not evidence of safety.
94
+ - A fact may be **stale** (it carries the writer's `verified_at_sha`) — treat it
95
+ as a consideration and re-verify against the code.
96
+ - **Read-only.** Never write another host's bucket; write ownership stays with
97
+ its one owner.
98
+
99
+ Do **not** cross-read another host's `loop::<host>-lessons` — those are prose
100
+ advice with no structural key to match on. The full contract and when to wire a
101
+ cross-read into a host is the `lorekit-setup` skill,
102
+ `rules/self-improvement-loops.md § Cross-bucket reads (targeted, read-only)`.
@@ -14,6 +14,13 @@ Ask the 30-second question:
14
14
  If no, stop — write nothing. Empty retrospectives are skipped.
15
15
  If yes, continue.
16
16
 
17
+ > A retrospective records **prose advice** ("last time X went wrong when Y"). A
18
+ > *structural fact* this run verified about a symbol or file — a consumer count
19
+ > you swept, an invariant you confirmed, a defect you fixed at a SHA — is a
20
+ > different thing: it belongs in the shared **`codebase-knowledge`** bucket under
21
+ > a `knowledge::<symbol>@<path>` key, not here. See the intake step 6 write-back
22
+ > note and the `lorekit-setup` skill, `§ Shared codebase-knowledge`.
23
+
17
24
  ## 2. Phrase it as an observation
18
25
 
19
26
  Write what happened and what worked, not a commandment.
@@ -93,6 +93,23 @@ It covers: when to add a loop (and when not to), the bucket convention (tag
93
93
  read/write steps, the promotion gate, the entrenchment guards, a wiring
94
94
  checklist, and an interactive setup flow.
95
95
 
96
+ ## The shared codebase-knowledge layer (automatic cross-loop synergy)
97
+
98
+ A per-host lessons bucket is private to one host. There is also **one shared
99
+ bucket every code-touching host reads and, under a contract, writes**:
100
+ `codebase-knowledge` — a repo-scoped, structurally-keyed record
101
+ (`knowledge::<symbol>@<path>` facts, `hotspot::<path>` counters) of what the
102
+ codebase has taught every LoreKit loop that touched it. Because the name is fixed
103
+ and the key is structural, a loop wired by one person compounds with a loop wired
104
+ by another: a host about to change code reads the history for exactly the files it
105
+ will touch, and a host that verifies a structural fact contributes it back. That
106
+ is the synergy that appears for a user who wired a single skill and nothing else.
107
+
108
+ Wire it whenever a host changes code (read at its plan/apply seam) or verifies a
109
+ durable structural fact (write under the contract). The full specification — the
110
+ bucket table, the automatic read side, and the seven-bullet multi-writer write
111
+ contract — is [rules/self-improvement-loops.md § Shared codebase-knowledge](./rules/self-improvement-loops.md#shared-codebase-knowledge-the-standard-cross-loop-layer).
112
+
96
113
  ## Set up CI state (deterministic hosts)
97
114
 
98
115
  Follow [rules/ci-state-records.md](./rules/ci-state-records.md). It covers: when
@@ -21,6 +21,8 @@ The design has two tiers connected by a recurrence gate. Both run on LoreKit.
21
21
  - [Read step (start of every run)](#read-step-start-of-every-run)
22
22
  - [Write step (on failure / at the end of a run)](#write-step-on-failure--at-the-end-of-a-run)
23
23
  - [The reconcile-on-re-run flow (resolve + record)](#the-reconcile-on-re-run-flow-resolve--record)
24
+ - [Cross-bucket reads (targeted, read-only)](#cross-bucket-reads-targeted-read-only)
25
+ - [Shared codebase-knowledge (the standard cross-loop layer)](#shared-codebase-knowledge-the-standard-cross-loop-layer)
24
26
  - [Promotion (fast → slow)](#promotion-fast--slow)
25
27
  - [Entrenchment guards (do not skip these)](#entrenchment-guards-do-not-skip-these)
26
28
  - [Wiring checklist](#wiring-checklist)
@@ -247,6 +249,134 @@ record shape are specified in `agents/shared/rules/comment-relevance-memory.md`.
247
249
 
248
250
  ---
249
251
 
252
+ ## Cross-bucket reads (targeted, read-only)
253
+
254
+ The default is strict: a loop reads **only its own bucket**, filtered by
255
+ `loop::<host>-lessons`. That isolation is deliberate — it keeps one loop's
256
+ lessons from drowning another's, and lets each read fire at its own cadence
257
+ against its own decision point. Wholesale "read every lesson this repo knows"
258
+ is an **anti-pattern**: it reintroduces exactly the noise the tag split exists
259
+ to prevent, and buries the matches that would have fired.
260
+
261
+ There is **one** shape of cross-bucket read that is safe and worth wiring: a host
262
+ reading **another host's Signal or Knowledge bucket, matched by a structural key,
263
+ strictly read-only**. Wire it only when all four hold:
264
+
265
+ 1. **The other bucket is keyed by something structural** — a `symbol@path`, a
266
+ file path, a stable fingerprint — never by prose. A structural key is what
267
+ makes a cross-host read meaningful: it matches the reader's own concrete work
268
+ (the files or symbols it is about to touch), not a vague topic.
269
+ 2. **The read is bounded to the reader's current work.** Match the other bucket's
270
+ keys against the paths / symbols this run will actually touch and ignore the
271
+ rest — never load the whole bucket as advice.
272
+ 3. **The reader treats it as advisory and re-verifies.** A cross-host fact can be
273
+ stale — it carries the *writer's* `verified_at_sha`, not the reader's. It
274
+ **raises care** (more coverage on a hotspot, design around a known invariant)
275
+ but never lowers a bar, skips a step, or suppresses a finding. An absent
276
+ record is never evidence of safety.
277
+ 4. **The reader never writes the other bucket.** Write ownership stays with the
278
+ one owning host; a second writer corrupts its provenance. Cross-host is a
279
+ **read** relationship only.
280
+
281
+ Do **not** cross-read another host's `loop::<host>-lessons`. Lessons are prose
282
+ "how to do better" advice tuned to that host's own decisions; they re-key on
283
+ rephrasing and carry no structural anchor to match against, so a cross-read of
284
+ them is the wholesale anti-pattern above. Only Signal / Knowledge buckets with
285
+ structural keys qualify.
286
+
287
+ LoreKit ships **one** standard instance of this pattern — the shared
288
+ `codebase-knowledge` bucket that every code-touching loop reads and writes. It is
289
+ the mechanism behind the automatic synergy below, and it is what makes a
290
+ structural key worth insisting on: a fixed name plus a `symbol@path` key is what
291
+ lets a loop wired by one person be consumed by a loop wired by another. It is
292
+ specified in full next.
293
+
294
+ ---
295
+
296
+ ## Shared codebase-knowledge (the standard cross-loop layer)
297
+
298
+ The cross-bucket read above becomes **automatic** through one bucket every LoreKit
299
+ loop shares by name: `codebase-knowledge`. This is the reason two skills wired
300
+ independently — by different people, in different sessions, in the same repo —
301
+ still compound: they read and write the *same* repo-scoped, structurally-keyed
302
+ record of what the codebase has taught every loop that touched it. A code-changing
303
+ loop plans and edits with that history in hand instead of blind; and because the
304
+ loops that consume it also feed it, the synergy appears for a user who wired a
305
+ single skill and nothing else.
306
+
307
+ ### The bucket
308
+
309
+ | Field | Value |
310
+ | --- | --- |
311
+ | **Tag** | `codebase-knowledge` |
312
+ | **Kind** | `signal` (a durable per-repo filter, read on every run that touches code) |
313
+ | **Scope** | `repo::{owner}/{repo}` — a codebase fact is repo-bound |
314
+ | **TTL** | ~90 days, refreshed on re-verification |
315
+ | **Keys** | `knowledge::<symbol>@<path>` — verified facts about one symbol (an invariant it holds, its consumer/dependent count, a defect it produced before); `hotspot::<path>` — per-file counters (`confirmed`, `regressed`, `missed`) |
316
+
317
+ The keys are **structural** (`symbol@path`, `path`) on purpose: a key survives a
318
+ rename of the *finding* but not a rename of the *code*, which is exactly the
319
+ sensitivity that lets a different loop match it against the files it is about to
320
+ touch. Set `kind: signal` and `host` explicitly on every write — LoreKit infers
321
+ them only from a `loop::` tag, and this bucket is not tagged that way.
322
+
323
+ ### Read side — automatic for any code-touching host
324
+
325
+ Wire it at the host's **plan/apply seam** — the moment it has the concrete
326
+ file/symbol list it will change (a plan's File Changes list, an apply pack, a
327
+ fix's target file):
328
+
329
+ ```text
330
+ memory.list { scope: "repo::{owner}/{repo}", tags: ["codebase-knowledge"], limit: 100 }
331
+ # keep only hotspot::<path> / knowledge::<symbol>@<path> whose <path> (and <symbol>)
332
+ # this run will actually touch. Apply as PLANNING INPUTS: raise coverage on a
333
+ # hotspot, design around a known invariant / consumer count. Advisory and
334
+ # re-verified against the code — never a reason to skip a step or suppress a finding.
335
+ ```
336
+
337
+ This is the read-side contract from [Cross-bucket reads](#cross-bucket-reads-targeted-read-only)
338
+ made concrete: structural match, bounded to this run, advisory, an absent record
339
+ never evidence of safety.
340
+
341
+ ### Write side — how the layer fills, and why many writers stay safe
342
+
343
+ A host that **verifies** a structural fact contributes it back, so the next loop
344
+ reads it. This is what makes the synergy automatic even for a user with one skill
345
+ and no dedicated reviewer: the loops that consume the layer also feed it.
346
+ Multi-writer is safe **only** behind this write contract — bake in every bullet,
347
+ or do not wire the write:
348
+
349
+ - **Structural key from a real symbol/path list**, never composed from prose. A
350
+ prose key accumulates nothing and no reader can match it.
351
+ - **`verified_at_sha` on every fact** — the HEAD this run verified it at. It is the
352
+ whole mechanism the next reader uses to decide "fact stands" vs "re-verify"; an
353
+ absent or stale SHA makes the fact permanently unverifiable, and it is dropped.
354
+ - **`source_agent` stamped** — which host verified it. Together with
355
+ `verified_at_sha` this is what makes many writers safe: a reader sees who
356
+ verified what, and when, so no writer silently overwrites another's provenance.
357
+ - **Only what THIS run actually verified**, grounded in the code — never a guess,
358
+ and never a value about a person or a telemetry reading. A fact about code,
359
+ keyed to code.
360
+ - **Merge, never clobber.** Read the existing record first; append to `history[]`
361
+ or increment counters (each capped) and carry the rest through unchanged. A
362
+ clobbered counter is indistinguishable from a first write.
363
+ - **Raise care, never suppress.** These records only raise priority/coverage on a
364
+ file or symbol. They never lower a bar or silence a finding, and an absent record
365
+ is never evidence of safety. Suppression, if a host needs it, is a different
366
+ bucket behind verification (the Signal in the reconcile flow above).
367
+ - **Explicit `kind: signal` + `host`, a TTL, and the privacy pre-flight** — as
368
+ every write in this skill.
369
+
370
+ Because the name is fixed, the read is the same call in every host, and the write
371
+ follows one contract, **any two LoreKit-wired loops in the same repo compound
372
+ automatically** — which is the whole reason to standardize the name instead of
373
+ letting each host invent its own. The reference ecosystem is `agent-skills`: the
374
+ `pr-reviewer` agent is the primary writer (it verifies symbol facts and file
375
+ hotspots during review), and every code-changing host — `aw`, `implement-suggestion`,
376
+ `fix-bug`, `ci-auto-fix` — reads the layer at its plan/apply seam.
377
+
378
+ ---
379
+
250
380
  ## Promotion (fast → slow)
251
381
 
252
382
  After a read or write, a lesson is **promotion-eligible** when either:
@@ -316,6 +446,10 @@ To add a loop to a host called `<host>`:
316
446
  - [ ] State the **entrenchment guards** so a future maintainer does not "optimize
317
447
  them away".
318
448
  - [ ] Confirm the loop **degrades silently** when `memory.*` is not connected.
449
+ - [ ] If the host **touches code**, wire the **[codebase-knowledge](#shared-codebase-knowledge-the-standard-cross-loop-layer)
450
+ read** at its plan/apply seam (match `hotspot::<path>` /
451
+ `knowledge::<symbol>@<path>` to the files it will change). If it **verifies**
452
+ a structural fact, wire the **write** behind that section's contract.
319
453
 
320
454
  ---
321
455