@hviana/sema 0.8.1 → 0.8.3
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/AGENTS.md +29 -29
- package/TRADEMARKS.md +0 -1
- package/dist/src/config.d.ts +28 -0
- package/dist/src/config.js +20 -0
- package/dist/src/geometry.d.ts +21 -0
- package/dist/src/geometry.js +21 -0
- package/dist/src/meter.d.ts +76 -0
- package/dist/src/meter.js +95 -0
- package/dist/src/mind/attention.d.ts +4 -0
- package/dist/src/mind/attention.js +165 -16
- package/dist/src/mind/canonical.d.ts +16 -0
- package/dist/src/mind/canonical.js +41 -0
- package/dist/src/mind/corpus.d.ts +40 -0
- package/dist/src/mind/corpus.js +149 -0
- package/dist/src/mind/graph-search.d.ts +7 -0
- package/dist/src/mind/graph-search.js +254 -24
- package/dist/src/mind/index.d.ts +3 -1
- package/dist/src/mind/index.js +1 -0
- package/dist/src/mind/match.d.ts +9 -4
- package/dist/src/mind/match.js +147 -61
- package/dist/src/mind/mechanisms/cast.js +19 -3
- package/dist/src/mind/mechanisms/confluence.js +24 -0
- package/dist/src/mind/mechanisms/cover.js +6 -0
- package/dist/src/mind/mechanisms/recall.js +32 -4
- package/dist/src/mind/mind.d.ts +57 -0
- package/dist/src/mind/mind.js +72 -1
- package/dist/src/mind/pipeline-mechanism.d.ts +7 -0
- package/dist/src/mind/pipeline.js +66 -20
- package/dist/src/mind/primitives.js +9 -1
- package/dist/src/mind/rationale.d.ts +28 -1
- package/dist/src/mind/rationale.js +22 -1
- package/dist/src/mind/reasoning.d.ts +25 -3
- package/dist/src/mind/reasoning.js +125 -20
- package/dist/src/mind/recognition.js +4 -8
- package/dist/src/mind/resonance.js +20 -1
- package/dist/src/mind/trace.js +1 -0
- package/dist/src/mind/traverse.js +15 -3
- package/dist/src/mind/types.d.ts +49 -4
- package/docs/INVARIANTS.md +2 -2
- package/docs/architecture/bounded-reads.md +1 -1
- package/docs/architecture/commonality.md +2 -2
- package/docs/architecture/cost-model.md +2 -2
- package/docs/architecture/determinism.md +7 -7
- package/docs/architecture/match-project.md +2 -3
- package/docs/architecture/mechanism-market.md +10 -10
- package/docs/architecture/meter.md +5 -5
- package/docs/architecture/store.md +3 -3
- package/docs/failures/tempting-but-wrong.md +34 -6
- package/docs/harness/gates.md +2 -2
- package/docs/mechanisms/cast.md +2 -2
- package/docs/mechanisms/cover.md +2 -3
- package/docs/mechanisms/extraction.md +7 -7
- package/docs/mechanisms/recall.md +8 -9
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/alu/README.md +11 -12
- package/src/config.ts +48 -0
- package/src/geometry.ts +21 -0
- package/src/meter.ts +98 -0
- package/src/mind/attention.ts +167 -16
- package/src/mind/canonical.ts +43 -0
- package/src/mind/corpus.ts +202 -0
- package/src/mind/graph-search.ts +277 -23
- package/src/mind/index.ts +8 -1
- package/src/mind/match.ts +148 -57
- package/src/mind/mechanisms/cast.ts +20 -2
- package/src/mind/mechanisms/confluence.ts +24 -0
- package/src/mind/mechanisms/cover.ts +5 -0
- package/src/mind/mechanisms/recall.ts +32 -4
- package/src/mind/mind.ts +125 -0
- package/src/mind/pipeline-mechanism.ts +7 -0
- package/src/mind/pipeline.ts +79 -22
- package/src/mind/primitives.ts +9 -1
- package/src/mind/rationale.ts +35 -1
- package/src/mind/reasoning.ts +145 -13
- package/src/mind/recognition.ts +4 -8
- package/src/mind/resonance.ts +19 -1
- package/src/mind/trace.ts +1 -0
- package/src/mind/traverse.ts +16 -6
- package/src/mind/types.ts +53 -4
- package/test/100-complete-grounding-trace.test.mjs +109 -0
- package/test/101-alignment-gap-bound.test.mjs +106 -0
- package/test/102-production-composes-at-scale.test.mjs +110 -0
- package/test/103-alignment-gap-budget.test.mjs +89 -0
- package/test/104-composition-is-reported.test.mjs +90 -0
- package/test/105-derive-through-reports-its-refusal.test.mjs +137 -0
- package/test/106-the-join-fires.test.mjs +94 -0
- package/test/107-the-join-is-counted.test.mjs +81 -0
- package/test/108-the-join-chains.test.mjs +78 -0
- package/test/109-the-pivot-is-counted.test.mjs +60 -0
- package/test/110-the-reasoner-stops-when-the-question-is-answered.test.mjs +91 -0
- package/test/111-the-cover-assembly-is-counted.test.mjs +74 -0
- package/test/112-the-exploration-does-not-grow-with-the-hub.test.mjs +89 -0
- package/test/113-the-rationale-payload-is-bounded.test.mjs +84 -0
- package/test/114-alignment-budget-is-per-sweep.test.mjs +93 -0
- package/test/116-the-extension-is-gated-by-the-pipelines-own-remainder.test.mjs +100 -0
- package/test/117-corpus-search.test.mjs +171 -0
- package/test/118-the-join-reaches-a-key-off-the-cut.test.mjs +74 -0
- package/test/119-the-work-does-not-grow-with-the-corpus.test.mjs +122 -0
- package/test/120-composition-is-consequence.test.mjs +132 -0
- package/test/121-the-extension-does-not-grow-with-the-corpus.test.mjs +128 -0
- package/test/122-the-climb-search-does-not-grow-with-the-corpus.test.mjs +117 -0
- package/test/123-the-paired-formulas-agree.test.mjs +90 -0
- package/test/125-the-post-grounding-branch-publishes-its-operand.test.mjs +51 -0
- package/test/126-the-pipeline-does-not-name-mechanisms.test.mjs +42 -0
- package/test/128-the-leads-somewhere-pair-agrees.test.mjs +83 -0
- package/test/129-the-trace-payload-shape.test.mjs +164 -0
- package/test/14-scaling.test.mjs +10 -7
- package/test/32-confluence.test.mjs +68 -0
- package/test/38-reason-restate-guard.test.mjs +8 -2
- package/test/43-cast-analog-seat.test.mjs +10 -0
- package/test/55-cost-meter.test.mjs +859 -0
- package/test/76-reference-binding.test.mjs +6 -1
- package/test/89-completion-recursion.test.mjs +30 -5
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// 129-the-trace-payload-shape.test.mjs — THE PAYLOAD'S SHAPE, PINNED
|
|
2
|
+
//
|
|
3
|
+
// The climb's trace payload (`ClimbConsensusData`, `version: 1`) is built by
|
|
4
|
+
// hand next to the internal `TraceDraft` that feeds it, and the pair has
|
|
5
|
+
// already drifted once (`visited?` — "Absent on payloads recorded before this
|
|
6
|
+
// field existed"). The draft is NOT exported, so a test cannot compare the two
|
|
7
|
+
// side by side (and exporting it just for a test would be new plumbing the
|
|
8
|
+
// architecture forbids). What CAN be pinned from outside is the payload's
|
|
9
|
+
// SHAPE: a closed key set per section, so that a field added, removed or
|
|
10
|
+
// renamed on one side of the pair cannot pass unnoticed.
|
|
11
|
+
//
|
|
12
|
+
// The sets below are MEASURED from a real payload (printed before being
|
|
13
|
+
// written), not chosen. If this test fails, the payload changed: update the
|
|
14
|
+
// section it names AND the draft that feeds it AND the note in attention.ts
|
|
15
|
+
// that says which fields older payloads lack.
|
|
16
|
+
//
|
|
17
|
+
// The sections are optional by design (that is what keeps recorded payloads
|
|
18
|
+
// valid); this query produces ALL of them, and the test asserts that too, so a
|
|
19
|
+
// section silently disappearing is caught rather than tolerated.
|
|
20
|
+
|
|
21
|
+
import { test } from "node:test";
|
|
22
|
+
import assert from "node:assert/strict";
|
|
23
|
+
import { Mind } from "../dist/src/index.js";
|
|
24
|
+
import { SQliteStore } from "../dist/src/store-sqlite.js";
|
|
25
|
+
|
|
26
|
+
const CORPUS = [
|
|
27
|
+
["red", "is a color"],
|
|
28
|
+
["blue", "is a color"],
|
|
29
|
+
["circle", "is a shape"],
|
|
30
|
+
["square", "is a shape"],
|
|
31
|
+
["red circle", "answer alpha"],
|
|
32
|
+
["red square", "answer beta"],
|
|
33
|
+
["blue circle", "answer gamma"],
|
|
34
|
+
["blue square", "answer delta"],
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
const TOP = [
|
|
38
|
+
"anchors",
|
|
39
|
+
"cache",
|
|
40
|
+
"candidates",
|
|
41
|
+
"config",
|
|
42
|
+
"crossRegion",
|
|
43
|
+
"pooling",
|
|
44
|
+
"reaches",
|
|
45
|
+
"regions",
|
|
46
|
+
"result",
|
|
47
|
+
"saturation",
|
|
48
|
+
"version",
|
|
49
|
+
];
|
|
50
|
+
const REQUIRED = ["cache", "candidates", "config", "result", "version"];
|
|
51
|
+
const SECTIONS = {
|
|
52
|
+
cache: ["detailAvailable", "hit"],
|
|
53
|
+
config: [
|
|
54
|
+
"annK",
|
|
55
|
+
"consensusFloor",
|
|
56
|
+
"corpusN",
|
|
57
|
+
"crossRegionProbeLimit",
|
|
58
|
+
"dimension",
|
|
59
|
+
"estimatorNoise",
|
|
60
|
+
"hubBound",
|
|
61
|
+
"mode",
|
|
62
|
+
"naturalBreak",
|
|
63
|
+
],
|
|
64
|
+
candidates: ["perceived", "recognised", "total"],
|
|
65
|
+
crossRegion: [
|
|
66
|
+
"eligibleRegions",
|
|
67
|
+
"junctionVotes",
|
|
68
|
+
"maximalRegions",
|
|
69
|
+
"probeLimit",
|
|
70
|
+
"probes",
|
|
71
|
+
"probesAttempted",
|
|
72
|
+
"stopReason",
|
|
73
|
+
"supersededOrdinaryVotes",
|
|
74
|
+
],
|
|
75
|
+
saturation: ["hasLeading", "leadingEnd", "regionIntervals"],
|
|
76
|
+
pooling: ["eligibleVotes", "inputVotes", "saturationMaskedVotes"],
|
|
77
|
+
};
|
|
78
|
+
const ANCHOR = [
|
|
79
|
+
"anchor",
|
|
80
|
+
"breadth",
|
|
81
|
+
"candidateBreadth",
|
|
82
|
+
"clusters",
|
|
83
|
+
"commit",
|
|
84
|
+
"contributingEvidence",
|
|
85
|
+
"contributingSpans",
|
|
86
|
+
"contributingVotes",
|
|
87
|
+
"idfVote",
|
|
88
|
+
"peak",
|
|
89
|
+
"pooledVote",
|
|
90
|
+
"rank",
|
|
91
|
+
];
|
|
92
|
+
const REGION = [
|
|
93
|
+
"annHitsExamined",
|
|
94
|
+
"annHitsReturned",
|
|
95
|
+
"annQueried",
|
|
96
|
+
"canonicalFailed",
|
|
97
|
+
"canonicalId",
|
|
98
|
+
"canonicalUsable",
|
|
99
|
+
"chunk",
|
|
100
|
+
"dfWeight",
|
|
101
|
+
"focusWeightPerRoot",
|
|
102
|
+
"idf",
|
|
103
|
+
"index",
|
|
104
|
+
"known",
|
|
105
|
+
"mutualWeight",
|
|
106
|
+
"ordinaryVoteProduced",
|
|
107
|
+
"outcome",
|
|
108
|
+
"reachNode",
|
|
109
|
+
"selected",
|
|
110
|
+
"source",
|
|
111
|
+
"span",
|
|
112
|
+
"superseded",
|
|
113
|
+
"voteWeightPerRoot",
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
/** The payload, found the way a reader finds it: deep in the recorded steps. */
|
|
117
|
+
function findPayload(steps) {
|
|
118
|
+
const walk = (o, depth) => {
|
|
119
|
+
if (o === null || typeof o !== "object" || depth > 6) return null;
|
|
120
|
+
if (o.version === 1 && o.config && o.result) return o;
|
|
121
|
+
for (const v of Object.values(o)) {
|
|
122
|
+
const hit = walk(v, depth + 1);
|
|
123
|
+
if (hit) return hit;
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
};
|
|
127
|
+
for (const step of steps) {
|
|
128
|
+
const hit = walk(step.data, 0);
|
|
129
|
+
if (hit) return hit;
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
test("the climb trace payload keeps its published shape", async () => {
|
|
135
|
+
const m = new Mind({ seed: 1, store: new SQliteStore({ path: ":memory:" }) });
|
|
136
|
+
await m.ingest(CORPUS);
|
|
137
|
+
const steps = [];
|
|
138
|
+
await m.respondText("red then circle", (step) => steps.push(step));
|
|
139
|
+
const payload = findPayload(steps);
|
|
140
|
+
assert.ok(payload, "no version:1 payload with config+result was recorded");
|
|
141
|
+
|
|
142
|
+
assert.deepEqual(Object.keys(payload).sort(), TOP);
|
|
143
|
+
for (const key of REQUIRED) {
|
|
144
|
+
assert.ok(key in payload, `required section ${key} is missing`);
|
|
145
|
+
}
|
|
146
|
+
for (const [name, keys] of Object.entries(SECTIONS)) {
|
|
147
|
+
assert.ok(payload[name] !== undefined, `section ${name} is absent`);
|
|
148
|
+
assert.deepEqual(
|
|
149
|
+
Object.keys(payload[name]).sort(),
|
|
150
|
+
keys,
|
|
151
|
+
`section ${name} changed shape`,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
assert.ok(payload.anchors.length > 0, "no anchors recorded");
|
|
155
|
+
assert.deepEqual(Object.keys(payload.anchors[0]).sort(), ANCHOR);
|
|
156
|
+
assert.ok(payload.regions.length > 0, "no regions recorded");
|
|
157
|
+
assert.deepEqual(Object.keys(payload.regions[0]).sort(), REGION);
|
|
158
|
+
assert.ok(
|
|
159
|
+
Array.isArray(payload.anchors[0].commit.rejectionReasons),
|
|
160
|
+
"an anchor's commit no longer carries its rejection reasons",
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
await m.store.close();
|
|
164
|
+
});
|
package/test/14-scaling.test.mjs
CHANGED
|
@@ -158,14 +158,17 @@ test("training: recall work does NOT grow with the store (storage reads, not tim
|
|
|
158
158
|
for (let i = from; i < to; i++) await mind.ingest(novelExperience(i, "g"));
|
|
159
159
|
};
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
// 6x in RATIO is the signal; the absolute size is the cost. 100 -> 600
|
|
162
|
+
// keeps the same 6x step (and a SMALLER N makes the log-N growth relatively
|
|
163
|
+
// LARGER, so the 3x band below is not loosened by shrinking it).
|
|
164
|
+
await grow(0, 100);
|
|
162
165
|
const small = await readsNow();
|
|
163
|
-
await grow(
|
|
166
|
+
await grow(100, 600); // 6x the corpus
|
|
164
167
|
const large = await readsNow();
|
|
165
168
|
await store.close();
|
|
166
169
|
|
|
167
170
|
console.log(
|
|
168
|
-
` content-index reads for one recall: N=
|
|
171
|
+
` content-index reads for one recall: N=100 → ${small}, N=600 → ${large}`,
|
|
169
172
|
);
|
|
170
173
|
|
|
171
174
|
// 6x the corpus must not cost anywhere near 6x the reads. A genuinely
|
|
@@ -194,7 +197,7 @@ test("training: absolute deposition throughput clears a sane floor", async () =>
|
|
|
194
197
|
// not one-time setup.
|
|
195
198
|
for (let i = 0; i < 200; i++) await mind.ingest(novelExperience(i, "warm"));
|
|
196
199
|
|
|
197
|
-
const N =
|
|
200
|
+
const N = 400;
|
|
198
201
|
let bytes = 0;
|
|
199
202
|
const t0 = performance.now();
|
|
200
203
|
for (let i = 0; i < N; i++) {
|
|
@@ -322,7 +325,7 @@ test("training: exact recall is preserved at scale", async () => {
|
|
|
322
325
|
// growth exponent in corpus size is the proof — it must be well below linear.
|
|
323
326
|
test("inference: cost is sublinear in corpus size (independent corpora)", async () => {
|
|
324
327
|
const query = unknownInput(1024);
|
|
325
|
-
const sizes = [50, 200, 800
|
|
328
|
+
const sizes = [50, 200, 800];
|
|
326
329
|
const times = [];
|
|
327
330
|
|
|
328
331
|
for (const n of sizes) {
|
|
@@ -370,7 +373,7 @@ test("inference: input is processed at a roughly constant KB/s (linear, not quad
|
|
|
370
373
|
const mind = new Mind({ seed: 7, store });
|
|
371
374
|
await mind.ingest(corpus(200, "inflen"));
|
|
372
375
|
|
|
373
|
-
const kbs = [0.5, 1, 2, 4
|
|
376
|
+
const kbs = [0.5, 1, 2, 4];
|
|
374
377
|
const queries = kbs.map((kb) => unknownInput(kb * 1024));
|
|
375
378
|
const bytes = queries.map((q) => new TextEncoder().encode(q).length);
|
|
376
379
|
|
|
@@ -452,7 +455,7 @@ test("inference: completion still fires inside long inputs", async () => {
|
|
|
452
455
|
});
|
|
453
456
|
await mind.ingest([["ice", "cold"], ["fire", "hot"], ["2+2", "4"]]);
|
|
454
457
|
|
|
455
|
-
for (const pad of [16, 64, 256
|
|
458
|
+
for (const pad of [16, 64, 256]) {
|
|
456
459
|
const filler = unknownInput(pad);
|
|
457
460
|
const mid = filler.slice(0, filler.length >> 1);
|
|
458
461
|
const end = filler.slice(filler.length >> 1);
|
|
@@ -171,3 +171,71 @@ test("E1 — the intersection is seed-independent (it is exact, not resonant)",
|
|
|
171
171
|
await m.store.close();
|
|
172
172
|
}
|
|
173
173
|
});
|
|
174
|
+
|
|
175
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
176
|
+
// Section F — the early-exit budget: live, but never pruning
|
|
177
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
178
|
+
|
|
179
|
+
test("F1 — the two streams are found well inside the early-exit's budget", async () => {
|
|
180
|
+
// The mechanism scans the climb's ranked anchors with two cuts: `ranked.slice(0,
|
|
181
|
+
// pre.k)` and an early exit after `2W` anchors that returns null when fewer than
|
|
182
|
+
// two constraint streams exist. Both are spec-legal (a capacity, and a formula
|
|
183
|
+
// over W — config.ts's default `maxGroup` is 4) but neither was DERIVED; what
|
|
184
|
+
// makes them legitimate is that they do not prune the case they exist to protect.
|
|
185
|
+
//
|
|
186
|
+
// MEASURED on this corpus: the two streams appear at ranks 1 and 4 against the
|
|
187
|
+
// budget of 8, while `ranked` is 9 — the cut IS live (it would have returned
|
|
188
|
+
// null at the 8th anchor) and it does NOT prune. The last assertion is the
|
|
189
|
+
// anti-vacuity guard: if `ranked` ever fell to 8 or below, this test would be
|
|
190
|
+
// pinning nothing at all.
|
|
191
|
+
const W = 4; // the engine's default quantum: config.ts, geometry.maxGroup
|
|
192
|
+
const m = new Mind({
|
|
193
|
+
seed: 7,
|
|
194
|
+
store: new SQliteStore({ path: ":memory:" }),
|
|
195
|
+
profile: true,
|
|
196
|
+
});
|
|
197
|
+
await m.ingest(materials);
|
|
198
|
+
const steps = [];
|
|
199
|
+
await m.respondText(
|
|
200
|
+
"Which material is translucent and featherlight?",
|
|
201
|
+
(s) => steps.push(s),
|
|
202
|
+
);
|
|
203
|
+
await m.store.close();
|
|
204
|
+
|
|
205
|
+
const findAnchors = (o, depth = 0) => {
|
|
206
|
+
if (o === null || typeof o !== "object" || depth > 5) return null;
|
|
207
|
+
if (Array.isArray(o.anchors) && o.anchors.length) return o;
|
|
208
|
+
for (const v of Object.values(o)) {
|
|
209
|
+
const r = findAnchors(v, depth + 1);
|
|
210
|
+
if (r) return r;
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
};
|
|
214
|
+
const step = steps.find((s) => findAnchors(s.data ?? s) !== null);
|
|
215
|
+
const td = step ? findAnchors(step.data ?? step) : null;
|
|
216
|
+
assert.ok(td, "the climb must report its anchors");
|
|
217
|
+
|
|
218
|
+
const meet = steps.find((s) =>
|
|
219
|
+
(s.mechanism ?? []).join("/").includes("intersectEvidence")
|
|
220
|
+
);
|
|
221
|
+
assert.ok(meet, "confluence must ENTER on a conjunctive query");
|
|
222
|
+
|
|
223
|
+
const ranks = (meet.inputs ?? [])
|
|
224
|
+
.filter((i) => typeof i.node === "number")
|
|
225
|
+
.map((i) => (td.anchors.find((a) => a.anchor === i.node) ?? {}).rank);
|
|
226
|
+
assert.ok(
|
|
227
|
+
ranks.length >= 2,
|
|
228
|
+
`the meet needs two streams (got ${ranks.length})`,
|
|
229
|
+
);
|
|
230
|
+
assert.ok(
|
|
231
|
+
Math.max(...ranks) < 2 * W,
|
|
232
|
+
`the streams must appear inside the budget (ranks ${
|
|
233
|
+
ranks.join(",")
|
|
234
|
+
} vs 2W=${2 * W})`,
|
|
235
|
+
);
|
|
236
|
+
assert.ok(
|
|
237
|
+
td.anchors.length > 2 * W,
|
|
238
|
+
`and the cut must be live on this fixture, else this test pins nothing ` +
|
|
239
|
+
`(ranked=${td.anchors.length}, 2W=${2 * W})`,
|
|
240
|
+
);
|
|
241
|
+
});
|
|
@@ -57,7 +57,10 @@ test("reason(): a forward hop landing on bytes already present in the query is r
|
|
|
57
57
|
queryResolved: resolve(m, query),
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
// `reason()` reports the WHOLE extension (bytes + what it carried + how many
|
|
61
|
+
// steps) so a caller can price it; these assertions measure the bytes, and
|
|
62
|
+
// that is all this change touches — the law they pin is untouched.
|
|
63
|
+
const out = (await reason(m, query, answer, new Set(), pre)).bytes;
|
|
61
64
|
assert.equal(
|
|
62
65
|
dec(out),
|
|
63
66
|
"bridge context",
|
|
@@ -82,7 +85,10 @@ test("reason(): an ordinary forward hop onto genuinely new content is unaffected
|
|
|
82
85
|
queryResolved: resolve(m, query),
|
|
83
86
|
};
|
|
84
87
|
|
|
85
|
-
|
|
88
|
+
// `reason()` reports the WHOLE extension (bytes + what it carried + how many
|
|
89
|
+
// steps) so a caller can price it; these assertions measure the bytes, and
|
|
90
|
+
// that is all this change touches — the law they pin is untouched.
|
|
91
|
+
const out = (await reason(m, query, answer, new Set(), pre)).bytes;
|
|
86
92
|
assert.equal(
|
|
87
93
|
dec(out),
|
|
88
94
|
"a wholly new fact never mentioned in any query",
|
|
@@ -65,6 +65,7 @@ test("CAST comparison: a nextOf-descendant analog is seated by its own bytes, no
|
|
|
65
65
|
const dominant = {
|
|
66
66
|
anchor: franceId,
|
|
67
67
|
vote: 100,
|
|
68
|
+
idfVote: 100, // the fixture builds an Attention: the field has to exist
|
|
68
69
|
ctx: enc("What is the capital of France?"),
|
|
69
70
|
runs: [{ qs: 0, qe: 30, cs: 0, weight: 1 }],
|
|
70
71
|
};
|
|
@@ -75,6 +76,7 @@ test("CAST comparison: a nextOf-descendant analog is seated by its own bytes, no
|
|
|
75
76
|
const spainPoint = {
|
|
76
77
|
anchor: spainAnalogSrcId,
|
|
77
78
|
vote: 50,
|
|
79
|
+
idfVote: 50, // the fixture builds an Attention: the field has to exist
|
|
78
80
|
ctx: enc("some other prompt"),
|
|
79
81
|
runs: [{ qs: 32, qe: 62, cs: 0, weight: 1 }],
|
|
80
82
|
};
|
|
@@ -85,6 +87,7 @@ test("CAST comparison: a nextOf-descendant analog is seated by its own bytes, no
|
|
|
85
87
|
{
|
|
86
88
|
anchor: franceId,
|
|
87
89
|
vote: 100,
|
|
90
|
+
idfVote: 100, // the fixture builds an Attention: the field has to exist
|
|
88
91
|
start: 0,
|
|
89
92
|
end: 30,
|
|
90
93
|
breadth: 1,
|
|
@@ -95,6 +98,7 @@ test("CAST comparison: a nextOf-descendant analog is seated by its own bytes, no
|
|
|
95
98
|
{
|
|
96
99
|
anchor: franceId,
|
|
97
100
|
vote: 100,
|
|
101
|
+
idfVote: 100, // the fixture builds an Attention: the field has to exist
|
|
98
102
|
start: 0,
|
|
99
103
|
end: 30,
|
|
100
104
|
breadth: 1,
|
|
@@ -103,6 +107,7 @@ test("CAST comparison: a nextOf-descendant analog is seated by its own bytes, no
|
|
|
103
107
|
{
|
|
104
108
|
anchor: spainAnalogSrcId,
|
|
105
109
|
vote: 50,
|
|
110
|
+
idfVote: 50, // the fixture builds an Attention: the field has to exist
|
|
106
111
|
start: 32,
|
|
107
112
|
end: 62,
|
|
108
113
|
breadth: 0.5,
|
|
@@ -174,6 +179,7 @@ test("CAST comparison: a DIRECTLY aligned analog is never re-projected past its
|
|
|
174
179
|
const dominant = {
|
|
175
180
|
anchor: franceId,
|
|
176
181
|
vote: 100,
|
|
182
|
+
idfVote: 100, // the fixture builds an Attention: the field has to exist
|
|
177
183
|
ctx: enc("What is the capital of France?"),
|
|
178
184
|
runs: [{ qs: 0, qe: 30, cs: 0, weight: 1 }],
|
|
179
185
|
};
|
|
@@ -182,6 +188,7 @@ test("CAST comparison: a DIRECTLY aligned analog is never re-projected past its
|
|
|
182
188
|
const japanPoint = {
|
|
183
189
|
anchor: japanId,
|
|
184
190
|
vote: 50,
|
|
191
|
+
idfVote: 50, // the fixture builds an Attention: the field has to exist
|
|
185
192
|
ctx: enc("What is the capital of Japan? Tokyo is the capital of Japan."),
|
|
186
193
|
runs: [{ qs: 32, qe: 62, cs: 0, weight: 1 }],
|
|
187
194
|
};
|
|
@@ -192,6 +199,7 @@ test("CAST comparison: a DIRECTLY aligned analog is never re-projected past its
|
|
|
192
199
|
{
|
|
193
200
|
anchor: franceId,
|
|
194
201
|
vote: 100,
|
|
202
|
+
idfVote: 100, // the fixture builds an Attention: the field has to exist
|
|
195
203
|
start: 0,
|
|
196
204
|
end: 30,
|
|
197
205
|
breadth: 1,
|
|
@@ -202,6 +210,7 @@ test("CAST comparison: a DIRECTLY aligned analog is never re-projected past its
|
|
|
202
210
|
{
|
|
203
211
|
anchor: franceId,
|
|
204
212
|
vote: 100,
|
|
213
|
+
idfVote: 100, // the fixture builds an Attention: the field has to exist
|
|
205
214
|
start: 0,
|
|
206
215
|
end: 30,
|
|
207
216
|
breadth: 1,
|
|
@@ -210,6 +219,7 @@ test("CAST comparison: a DIRECTLY aligned analog is never re-projected past its
|
|
|
210
219
|
{
|
|
211
220
|
anchor: japanId,
|
|
212
221
|
vote: 50,
|
|
222
|
+
idfVote: 50, // the fixture builds an Attention: the field has to exist
|
|
213
223
|
start: 32,
|
|
214
224
|
end: 62,
|
|
215
225
|
breadth: 0.5,
|