@gobing-ai/knowledge-kit 0.1.0 → 0.1.1

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.
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "plugins": [
8
8
  {
9
- "version": "0.1.0",
9
+ "version": "0.1.1",
10
10
  "name": "kk",
11
11
  "source": "./plugins/kk",
12
12
  "description": "knowledge-kit — a set of toolkit for knowledge management"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/knowledge-kit",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "An ingest → create → publish content pipeline CLI (Bun).",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "kk",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "knowledge-kit Claude Code plugin: skills, commands, subagents, hooks, and rules"
5
5
  }
@@ -91,17 +91,22 @@ export function buildCompactEvidencePacket(
91
91
 
92
92
  /**
93
93
  * Execute spur decision run via child process with strict bounds.
94
+ *
95
+ * `options.subjectUrl` is ledger display metadata, never a decision parameter: every SEO catalog
96
+ * declares `subject_id`/`locale` (plus `candidates` on kk-seo-keyword-page), and spur rejects an
97
+ * undeclared `--param` before any maker runs — so forwarding a display value in `params` would turn
98
+ * the whole judgment into a silent fallback.
94
99
  */
95
100
  export function executeDecisionRun(
96
101
  decisionId: string,
97
102
  params: Record<string, string>,
98
103
  evidencePaths: string[],
99
- options: { spurBin?: string; timeoutMs?: number; stub?: DecisionStubHandler } = {},
104
+ options: { spurBin?: string; timeoutMs?: number; stub?: DecisionStubHandler; subjectUrl?: string } = {},
100
105
  ): JudgmentEntry {
101
106
  const spurBin = options.spurBin || 'spur';
102
107
  const timeoutMs = options.timeoutMs ?? 30000;
103
108
  const subjectId = params.subject_id || '';
104
- const subjectUrl = params.url || subjectId;
109
+ const subjectUrl = options.subjectUrl || subjectId;
105
110
 
106
111
  if (options.stub) {
107
112
  try {
@@ -206,7 +211,16 @@ export function validateAndNormalizeDecisionResult(
206
211
  ): JudgmentEntry {
207
212
  const type = (typeof raw.type === 'string' ? raw.type : 'choice') as 'choice' | 'score' | 'noul';
208
213
  const val = raw.value !== undefined ? raw.value : raw.choice !== undefined ? raw.choice : raw.noul;
209
- const confidence = typeof raw.confidence === 'number' && Number.isFinite(raw.confidence) ? raw.confidence : null;
214
+ // Documented validation is "null or finite 0–1" (design §7): an out-of-range number is not a
215
+ // confidence. Preserving it would let a bad maker payload pass the >= 0.8 sufficiency gate while
216
+ // spur bands the same value LOW.
217
+ const confidence =
218
+ typeof raw.confidence === 'number' &&
219
+ Number.isFinite(raw.confidence) &&
220
+ raw.confidence >= 0 &&
221
+ raw.confidence <= 1
222
+ ? raw.confidence
223
+ : null;
210
224
  const maker = typeof raw.maker === 'string' && raw.maker.trim() !== '' ? raw.maker : 'unknown';
211
225
  const source = typeof raw.source === 'string' && raw.source.trim() !== '' ? raw.source : 'default';
212
226
  const reason = typeof raw.reason === 'string' ? raw.reason : '';
@@ -361,9 +375,9 @@ export async function executeSeoJudgeStage(
361
375
  callCount += 1;
362
376
  const entry = executeDecisionRun(
363
377
  dId,
364
- { subject_id: page.url, locale: opts.locale, url: page.url },
378
+ { subject_id: page.url, locale: opts.locale },
365
379
  [pFactsFile, pExcerptFile, siteContextFile],
366
- options,
380
+ { ...options, subjectUrl: page.url },
367
381
  );
368
382
  entries.push(entry);
369
383
  }
@@ -394,9 +408,9 @@ export async function executeSeoJudgeStage(
394
408
  callCount += 1;
395
409
  const entry = executeDecisionRun(
396
410
  'kk-seo-intent-overlap',
397
- { subject_id: pairId, locale: opts.locale, url: `${pA.url} :: ${pB.url}` },
411
+ { subject_id: pairId, locale: opts.locale },
398
412
  [pairEvFile],
399
- options,
413
+ { ...options, subjectUrl: `${pA.url} :: ${pB.url}` },
400
414
  );
401
415
  entries.push(entry);
402
416
  }
@@ -52,6 +52,13 @@ no catalogs. Do not run an audit that silently writes user-global configuration;
52
52
  is a one-time operator setup, and it is repeated only when an upgrade changes the resolved
53
53
  package root.
54
54
 
55
+ Every decision in those catalogs declares exactly two parameters — `subject_id` and `locale`
56
+ (plus `candidates` on `kk-seo-keyword-page`). Spur treats a declared parameter with no default as
57
+ required and rejects an undeclared one, so a direct probe like `spur decision run
58
+ kk-seo-page-type --param subject_id=…` is an input rejection before any maker runs, not a
59
+ judgment. Pass both parameters, and never invent a third (`url`, for example, is carried inside
60
+ the compact evidence packets, not as a parameter).
61
+
55
62
  **The catalogs' declared schema must resolve from where they live.** Each shipped SEO catalog
56
63
  declares `$schema: "@gobing-ai/spur/schemas/decision-catalog.schema.json"`, and Spur resolves that
57
64
  schema through the module tree above the catalog's own directory. A global install satisfies this