@lorekit/cli 1.62.0 → 1.63.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.62.0",
3
+ "version": "1.63.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": {
@@ -193,6 +193,20 @@ export function scopeReadLimit(maxLessons) {
193
193
  return Math.min(Math.max(ceiling, SCOPE_READ_LIMIT), MAX_STORE_LIST_LIMIT);
194
194
  }
195
195
 
196
+ // Is this row fit for the generic SessionStart digest? `kind: 'bus'` /
197
+ // `'signal'` rows (a reviewer's PR-state record, a comment-relevance filter)
198
+ // are loop-owned state with their own dedicated reader — an exact scope+key
199
+ // read or a tag-filtered list, both bypassing this scope-wide, untagged read
200
+ // entirely — not advice for whichever agent next opens a session in that
201
+ // scope. Left in, one renders as a raw JSON blob dressed up as a lesson line
202
+ // (`lessonHook` has no way to know it isn't prose) and the other misstates a
203
+ // state record as considered guidance. `kind` absent or `'lesson'` passes: an
204
+ // explicit kind is opt-in, so a row that never set one — the common case for
205
+ // hand-written and pre-`kind` lessons — must not be silently dropped. Pure.
206
+ function isGeneralLesson(kind) {
207
+ return kind == null || kind === 'lesson';
208
+ }
209
+
196
210
  // `scope` may be injected instead of derived from `cwd` — a seam for callers
197
211
  // that already hold a resolved scope and for tests that need a deterministic
198
212
  // branch (deriveScope shells out to git, so the ambient branch — often a
@@ -238,7 +252,7 @@ export async function fetchLessons(
238
252
  const raw = Array.isArray(res.entries) ? res.entries : [];
239
253
  if (raw.length >= readLimit) truncatedScopes.add(s);
240
254
  const entries = raw
241
- .filter((e) => e && e.key)
255
+ .filter((e) => e && e.key && isGeneralLesson(e.kind))
242
256
  .map((e) => ({ ...e, scope: s }));
243
257
  groups.push({ scope: s, error: null, entries });
244
258
  }
@@ -179,6 +179,18 @@ export const SURFACE_PARTNER_MAP = [
179
179
  guard: null,
180
180
  note: 'The flag table and per-command help in bin/lorekit.mjs is the origin of every flag claim; docs/cli.md, the package README (prose AND its flag table) and CLAUDE.md each restate it. Found by running this command against its own changed-set while changing the meaning of --strict: nothing fired, because the map covered every generated surface and no hand-written one. A path proxy, not a content predicate — bin/lorekit.mjs changes for reasons unrelated to flags — so advisory by construction, like error-code-doc.',
181
181
  },
182
+ {
183
+ id: 'digest-contract-doc',
184
+ state: 'advisory',
185
+ owner: '@mthines',
186
+ added: '2026-09-01',
187
+ reviewBy: '2026-12-01',
188
+ match: 'packages/cli/src/core/lessons.mjs',
189
+ obliges: ['packages/cli/skill/lorekit-setup/rules/ci-state-records.md'],
190
+ cluster: 'copies-a-claim',
191
+ guard: null,
192
+ note: 'lessons.mjs owns the SessionStart digest contract (fetchLessons\' isGeneralLesson kind filter); ci-state-records.md documents that contract for authors of non-lesson records. This is the second instance of the same class in two consecutive changes — the first was cli-flag-doc (bin/lorekit.mjs → the docs copying its flag claims) — which is the recurrence the whole compile pipeline exists to notice. Advisory, no guard: lessons.mjs changes for many reasons unrelated to the digest contract, so this is a path proxy, not a content predicate.',
193
+ },
182
194
  {
183
195
  id: 'perf-index',
184
196
  state: 'advisory',