@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.
package/package.json
CHANGED
package/plugins/kk/plugin.json
CHANGED
|
@@ -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 =
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|