@ctxr/skill-llm-wiki 1.0.2 → 1.1.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/CHANGELOG.md +118 -0
- package/README.md +2 -2
- package/guide/cli.md +3 -2
- package/guide/substrate/operators.md +1 -1
- package/guide/substrate/tiered-ai.md +6 -5
- package/guide/ux/user-intent.md +1 -1
- package/package.json +4 -2
- package/scripts/cli.mjs +92 -2
- package/scripts/lib/balance.mjs +579 -0
- package/scripts/lib/cluster-detect.mjs +482 -4
- package/scripts/lib/contract.mjs +31 -3
- package/scripts/lib/decision-log.mjs +121 -15
- package/scripts/lib/heal.mjs +5 -0
- package/scripts/lib/intent.mjs +370 -4
- package/scripts/lib/join-constants.mjs +22 -0
- package/scripts/lib/join.mjs +917 -0
- package/scripts/lib/nest-applier.mjs +395 -32
- package/scripts/lib/operators.mjs +472 -38
- package/scripts/lib/orchestrator.mjs +419 -12
- package/scripts/lib/root-containment.mjs +351 -0
- package/scripts/lib/similarity-cache.mjs +115 -20
- package/scripts/lib/similarity.mjs +11 -0
- package/scripts/lib/soft-dag.mjs +726 -0
- package/scripts/lib/tiered.mjs +42 -18
- package/scripts/lib/validate.mjs +22 -0
package/scripts/lib/tiered.mjs
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// circuits the whole ladder.
|
|
11
11
|
//
|
|
12
12
|
// Three quality modes, selected via --quality-mode or the
|
|
13
|
-
// LLM_WIKI_QUALITY_MODE env var:
|
|
13
|
+
// LLM_WIKI_QUALITY_MODE env var (see resolveQualityMode):
|
|
14
14
|
//
|
|
15
15
|
// tiered-fast (default):
|
|
16
16
|
// Tier 0 → Tier 1 → Tier 2, the full ladder. Mid-band Tier 0
|
|
@@ -21,9 +21,16 @@
|
|
|
21
21
|
// obvious decisions) but anything in the Tier 0 mid-band goes
|
|
22
22
|
// straight to Tier 2, skipping Tier 1.
|
|
23
23
|
//
|
|
24
|
-
//
|
|
25
|
-
// Tier 0
|
|
26
|
-
//
|
|
24
|
+
// deterministic:
|
|
25
|
+
// Tier 0 + Tier 1 ladder, but the ladder terminates at Tier 1:
|
|
26
|
+
// mid-band Tier 0 escalates to Tier 1 (as in tiered-fast), but
|
|
27
|
+
// mid-band Tier 1 is resolved by a deterministic threshold
|
|
28
|
+
// (`TIER1_DETERMINISTIC_THRESHOLD`) instead of escalating to
|
|
29
|
+
// Tier 2. No LLM/sub-agent is ever consulted — every decision
|
|
30
|
+
// is produced from TF-IDF + MiniLM cosine alone, so repeated
|
|
31
|
+
// runs on the same inputs are byte-reproducible. This is the
|
|
32
|
+
// mode the clustering pipeline pairs with algorithmic HAC +
|
|
33
|
+
// auto-slug to produce deterministic wiki builds end-to-end.
|
|
27
34
|
//
|
|
28
35
|
// Tier 2 escalation contract: the skill's CLI runs under Node with
|
|
29
36
|
// no access to Claude Code's `Agent` tool, so it cannot spawn
|
|
@@ -64,11 +71,27 @@ import {
|
|
|
64
71
|
export const QUALITY_MODES = Object.freeze([
|
|
65
72
|
"tiered-fast",
|
|
66
73
|
"claude-first",
|
|
67
|
-
"
|
|
74
|
+
"deterministic",
|
|
68
75
|
]);
|
|
69
76
|
|
|
70
77
|
export const DEFAULT_QUALITY_MODE = "tiered-fast";
|
|
71
78
|
|
|
79
|
+
// Deterministic-mode split point for resolving mid-band Tier 1
|
|
80
|
+
// similarities. Derived as the midpoint of the Tier 1 mid-band so
|
|
81
|
+
// future tuning of the decisive-same / decisive-different thresholds
|
|
82
|
+
// propagates here without a separate code-change — no drift between
|
|
83
|
+
// "where the ladder says 'escalate'" and "where deterministic mode
|
|
84
|
+
// says 'same vs different'". Any pair whose Tier 1 cosine sits
|
|
85
|
+
// strictly above this is routed to "same"; anything at-or-below is
|
|
86
|
+
// routed to "different". In this mode there is no mid-band
|
|
87
|
+
// "undecidable" / pending-Tier-2 outcome — Tier 1 always produces a
|
|
88
|
+
// concrete branch without an LLM in the loop. (Note: Tier 0 can still
|
|
89
|
+
// produce an "undecidable" result on insufficient-text inputs — two
|
|
90
|
+
// empty frontmatters — independent of quality mode; that predates
|
|
91
|
+
// deterministic mode and is by design.)
|
|
92
|
+
export const TIER1_DETERMINISTIC_THRESHOLD =
|
|
93
|
+
(TIER1_DECISIVE_SAME + TIER1_DECISIVE_DIFFERENT) / 2;
|
|
94
|
+
|
|
72
95
|
export function resolveQualityMode(flags = {}) {
|
|
73
96
|
const fromFlag = flags.quality_mode;
|
|
74
97
|
const fromEnv = process.env.LLM_WIKI_QUALITY_MODE;
|
|
@@ -244,18 +267,6 @@ export async function decide(
|
|
|
244
267
|
}
|
|
245
268
|
|
|
246
269
|
// Mid-band Tier 0 → escalate. Behaviour depends on quality mode.
|
|
247
|
-
if (qualityMode === "tier0-only") {
|
|
248
|
-
const result = {
|
|
249
|
-
tier: 0,
|
|
250
|
-
similarity: t0.similarity,
|
|
251
|
-
decision: "undecidable",
|
|
252
|
-
confidence_band: t0.confidence_band,
|
|
253
|
-
reason: "tier0-only quality mode — mid-band left unresolved",
|
|
254
|
-
};
|
|
255
|
-
finaliseDecision(result, { a, b, hashA, hashB, wikiRoot, opId, operator, writeLog, writeCache });
|
|
256
|
-
return result;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
270
|
if (qualityMode === "claude-first") {
|
|
260
271
|
// Skip Tier 1 entirely, go straight to Tier 2.
|
|
261
272
|
return await escalateToTier2(
|
|
@@ -308,7 +319,20 @@ export async function decide(
|
|
|
308
319
|
finaliseDecision(result, { a, b, hashA, hashB, wikiRoot, opId, operator, writeLog, writeCache });
|
|
309
320
|
return result;
|
|
310
321
|
}
|
|
311
|
-
// Mid-band Tier 1
|
|
322
|
+
// Mid-band Tier 1. Branch on quality mode: deterministic resolves
|
|
323
|
+
// algorithmically, tiered-fast escalates to Tier 2.
|
|
324
|
+
if (qualityMode === "deterministic") {
|
|
325
|
+
const decision = sim > TIER1_DETERMINISTIC_THRESHOLD ? "same" : "different";
|
|
326
|
+
const result = {
|
|
327
|
+
tier: 1,
|
|
328
|
+
similarity: sim,
|
|
329
|
+
decision,
|
|
330
|
+
confidence_band: "deterministic-mid-band",
|
|
331
|
+
reason: `deterministic mode: sim ${sim.toFixed(3)} ${decision === "same" ? ">" : "≤"} ${TIER1_DETERMINISTIC_THRESHOLD}`,
|
|
332
|
+
};
|
|
333
|
+
finaliseDecision(result, { a, b, hashA, hashB, wikiRoot, opId, operator, writeLog, writeCache });
|
|
334
|
+
return result;
|
|
335
|
+
}
|
|
312
336
|
return await escalateToTier2(
|
|
313
337
|
a, b, hashA, hashB, wikiRoot, opId, operator,
|
|
314
338
|
sim, "tier1 mid-band", writeLog, writeCache,
|
package/scripts/lib/validate.mjs
CHANGED
|
@@ -133,6 +133,28 @@ export function validateWiki(wikiRoot) {
|
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
+
|
|
137
|
+
// LEAF-AT-WIKI-ROOT — the wiki root must hold only `index.md`
|
|
138
|
+
// plus subdirectories. Any `.md` file at the wiki root other
|
|
139
|
+
// than `index.md` itself violates the invariant, regardless of
|
|
140
|
+
// what its frontmatter `type:` claims. Keying off path rather
|
|
141
|
+
// than `data.type` catches the edge case of a hand-authored
|
|
142
|
+
// `foo.md` at root declared as `type: index` — it's still a
|
|
143
|
+
// loose root file the navigational model forbids. The rule is
|
|
144
|
+
// navigational: Claude reading `<root>/index.md` and following
|
|
145
|
+
// its `entries[]` should reach every leaf via a
|
|
146
|
+
// semantically-named category; loose root files bypass that
|
|
147
|
+
// mental model and bloat the top-level index.
|
|
148
|
+
const absDir = dirname(e.absolute);
|
|
149
|
+
const absName = basename(e.absolute);
|
|
150
|
+
if (absDir === wikiRoot && absName !== "index.md") {
|
|
151
|
+
push(
|
|
152
|
+
"error",
|
|
153
|
+
"LEAF-AT-WIKI-ROOT",
|
|
154
|
+
e.absolute,
|
|
155
|
+
`non-index markdown file at wiki root — must live in a subcategory (run 'fix' to contain)`,
|
|
156
|
+
);
|
|
157
|
+
}
|
|
136
158
|
}
|
|
137
159
|
|
|
138
160
|
return findings;
|