@hviana/sema 0.8.2 → 0.8.5
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 +38 -37
- package/README.md +17 -38
- package/TRADEMARKS.md +0 -1
- package/dist/example/demo.js +85 -34
- package/dist/src/config.d.ts +11 -0
- package/dist/src/config.js +2 -0
- package/dist/src/geometry.d.ts +21 -10
- package/dist/src/geometry.js +21 -12
- package/dist/src/meter.d.ts +62 -0
- package/dist/src/meter.js +62 -0
- package/dist/src/mind/articulation.js +1 -1
- package/dist/src/mind/attention.d.ts +4 -0
- package/dist/src/mind/attention.js +167 -17
- package/dist/src/mind/canonical.d.ts +16 -0
- package/dist/src/mind/canonical.js +41 -0
- package/dist/src/mind/derivation.d.ts +201 -0
- package/dist/src/mind/derivation.js +327 -0
- package/dist/src/mind/graph-search.d.ts +2 -1
- package/dist/src/mind/graph-search.js +70 -29
- package/dist/src/mind/match.d.ts +3 -1
- package/dist/src/mind/match.js +7 -3
- package/dist/src/mind/mechanisms/alu.js +0 -2
- package/dist/src/mind/mechanisms/cast.d.ts +1 -5
- package/dist/src/mind/mechanisms/cast.js +16 -19
- package/dist/src/mind/mechanisms/confluence.d.ts +0 -3
- package/dist/src/mind/mechanisms/confluence.js +27 -9
- package/dist/src/mind/mechanisms/cover.js +17 -20
- package/dist/src/mind/mechanisms/extraction.d.ts +0 -1
- package/dist/src/mind/mechanisms/extraction.js +13 -8
- package/dist/src/mind/mechanisms/prefix-completion.js +0 -1
- package/dist/src/mind/mechanisms/recall.d.ts +0 -1
- package/dist/src/mind/mechanisms/recall.js +40 -13
- package/dist/src/mind/mechanisms/reference.js +3 -4
- package/dist/src/mind/mind.d.ts +4 -2
- package/dist/src/mind/mind.js +5 -4
- package/dist/src/mind/pipeline-mechanism.d.ts +7 -3
- package/dist/src/mind/pipeline.js +136 -44
- package/dist/src/mind/primitives.js +9 -1
- package/dist/src/mind/rationale.d.ts +21 -5
- package/dist/src/mind/rationale.js +16 -21
- package/dist/src/mind/reasoning.d.ts +12 -20
- package/dist/src/mind/reasoning.js +190 -106
- 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 +6 -2
- package/dist/src/mind/types.d.ts +36 -13
- package/dist/src/mind/types.js +6 -3
- package/docs/INDEX.md +23 -24
- package/docs/INVARIANTS.md +16 -17
- package/docs/architecture/bounded-reads.md +5 -5
- package/docs/architecture/closure.md +65 -0
- package/docs/architecture/commonality.md +29 -20
- package/docs/architecture/cost-model.md +7 -7
- package/docs/architecture/determinism.md +7 -7
- package/docs/architecture/exact-vs-approximate.md +4 -4
- package/docs/architecture/factored-machinery.md +14 -14
- package/docs/architecture/match-project.md +2 -3
- package/docs/architecture/mechanism-market.md +16 -16
- package/docs/architecture/meter.md +10 -11
- package/docs/architecture/store.md +4 -4
- package/docs/architecture/thresholds.md +1 -1
- package/docs/failures/tempting-but-wrong.md +14 -5
- package/docs/harness/gates.md +7 -7
- package/docs/mechanisms/cast.md +2 -2
- package/docs/mechanisms/cover.md +4 -5
- package/docs/mechanisms/extraction.md +7 -7
- package/docs/mechanisms/recall.md +8 -9
- package/example/demo.ts +90 -37
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/alu/README.md +11 -12
- package/src/config.ts +13 -0
- package/src/geometry.ts +21 -13
- package/src/meter.ts +62 -0
- package/src/mind/articulation.ts +0 -1
- package/src/mind/attention.ts +169 -17
- package/src/mind/canonical.ts +43 -0
- package/src/mind/derivation.ts +473 -0
- package/src/mind/graph-search.ts +76 -34
- package/src/mind/match.ts +7 -3
- package/src/mind/mechanisms/alu.ts +0 -2
- package/src/mind/mechanisms/cast.ts +20 -22
- package/src/mind/mechanisms/confluence.ts +27 -13
- package/src/mind/mechanisms/cover.ts +17 -20
- package/src/mind/mechanisms/extraction.ts +13 -9
- package/src/mind/mechanisms/prefix-completion.ts +0 -1
- package/src/mind/mechanisms/recall.ts +39 -13
- package/src/mind/mechanisms/reference.ts +2 -3
- package/src/mind/mind.ts +6 -4
- package/src/mind/pipeline-mechanism.ts +7 -3
- package/src/mind/pipeline.ts +160 -52
- package/src/mind/primitives.ts +9 -1
- package/src/mind/rationale.ts +27 -23
- package/src/mind/reasoning.ts +227 -120
- 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 +7 -5
- package/src/mind/types.ts +41 -15
- package/test/105-derive-through-reports-its-refusal.test.mjs +24 -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/133-the-decision-point-renders-the-state.test.mjs +204 -0
- package/test/134-the-law-explains-the-engines-own-refusal.test.mjs +237 -0
- package/test/135-one-law-any-producer.test.mjs +289 -0
- package/test/136-the-two-named-limits.test.mjs +205 -0
- package/test/137-the-law-lives-once-and-below.test.mjs +400 -0
- package/test/138-the-remainder-drains-only-what-a-move-declares.test.mjs +62 -0
- package/test/139-the-witness-is-engagement-not-explanation.test.mjs +51 -0
- package/test/140-irrelevant-supply-does-not-change-an-answer.test.mjs +48 -0
- package/test/141-the-question-is-paid-at-construction.test.mjs +98 -0
- package/test/32-confluence.test.mjs +68 -0
- package/test/36-already-answered-fusion.test.mjs +20 -2
- package/test/37-cluster-dispersion-fusion.test.mjs +30 -3
- package/test/38-reason-restate-guard.test.mjs +28 -2
- package/test/43-cast-analog-seat.test.mjs +10 -0
- package/test/55-cost-meter.test.mjs +862 -0
|
@@ -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
|
+
});
|
|
@@ -94,7 +94,16 @@ test("fuseAttention: a root whose continuation is already answered in the query
|
|
|
94
94
|
}),
|
|
95
95
|
guide,
|
|
96
96
|
};
|
|
97
|
-
|
|
97
|
+
// fusion consumes and returns the derivation STATE; these cases exercise the
|
|
98
|
+
// mechanism's own gates, so the state is the minimum one for them.
|
|
99
|
+
const out = dec(
|
|
100
|
+
(await fuseAttention(m, q, {
|
|
101
|
+
product: primary,
|
|
102
|
+
accounted: [],
|
|
103
|
+
remainder: [],
|
|
104
|
+
cost: 0,
|
|
105
|
+
}, pre)).product,
|
|
106
|
+
);
|
|
98
107
|
assert.ok(
|
|
99
108
|
!out.includes("reply-greet"),
|
|
100
109
|
`a root whose continuation is already answered in the query must not fuse in, got "${out}"`,
|
|
@@ -126,7 +135,16 @@ test("fuseAttention: ordinary multi-topic fusion (no embedded answers) is comple
|
|
|
126
135
|
}),
|
|
127
136
|
guide,
|
|
128
137
|
};
|
|
129
|
-
|
|
138
|
+
// fusion consumes and returns the derivation STATE; these cases exercise the
|
|
139
|
+
// mechanism's own gates, so the state is the minimum one for them.
|
|
140
|
+
const out = dec(
|
|
141
|
+
(await fuseAttention(m, q, {
|
|
142
|
+
product: primary,
|
|
143
|
+
accounted: [],
|
|
144
|
+
remainder: [],
|
|
145
|
+
cost: 0,
|
|
146
|
+
}, pre)).product,
|
|
147
|
+
);
|
|
130
148
|
assert.ok(
|
|
131
149
|
out.includes("answer alpha"),
|
|
132
150
|
`an ordinary further topic must still fuse in, got "${out}"`,
|
|
@@ -127,7 +127,16 @@ test("fuseAttention: 2 clusters, low breadth — dispersion alone is enough (gap
|
|
|
127
127
|
}),
|
|
128
128
|
guide,
|
|
129
129
|
};
|
|
130
|
-
|
|
130
|
+
// fusion consumes and returns the derivation STATE; these cases exercise the
|
|
131
|
+
// mechanism's own gates, so the state is the minimum one for them.
|
|
132
|
+
const out = dec(
|
|
133
|
+
(await fuseAttention(m, q, {
|
|
134
|
+
product: primary,
|
|
135
|
+
accounted: [],
|
|
136
|
+
remainder: [],
|
|
137
|
+
cost: 0,
|
|
138
|
+
}, pre)).product,
|
|
139
|
+
);
|
|
131
140
|
assert.equal(
|
|
132
141
|
out,
|
|
133
142
|
"answer alpha" + dec(primary),
|
|
@@ -154,7 +163,16 @@ test("fuseAttention: 1 cluster, dominant breadth — dominance alone is enough (
|
|
|
154
163
|
}),
|
|
155
164
|
guide,
|
|
156
165
|
};
|
|
157
|
-
|
|
166
|
+
// fusion consumes and returns the derivation STATE; these cases exercise the
|
|
167
|
+
// mechanism's own gates, so the state is the minimum one for them.
|
|
168
|
+
const out = dec(
|
|
169
|
+
(await fuseAttention(m, q, {
|
|
170
|
+
product: primary,
|
|
171
|
+
accounted: [],
|
|
172
|
+
remainder: [],
|
|
173
|
+
cost: 0,
|
|
174
|
+
}, pre)).product,
|
|
175
|
+
);
|
|
158
176
|
assert.equal(
|
|
159
177
|
out,
|
|
160
178
|
"answer alpha" + dec(primary),
|
|
@@ -180,7 +198,16 @@ test("fuseAttention: 1 cluster, low breadth — neither measure saves it (the li
|
|
|
180
198
|
}),
|
|
181
199
|
guide,
|
|
182
200
|
};
|
|
183
|
-
|
|
201
|
+
// fusion consumes and returns the derivation STATE; these cases exercise the
|
|
202
|
+
// mechanism's own gates, so the state is the minimum one for them.
|
|
203
|
+
const out = dec(
|
|
204
|
+
(await fuseAttention(m, q, {
|
|
205
|
+
product: primary,
|
|
206
|
+
accounted: [],
|
|
207
|
+
remainder: [],
|
|
208
|
+
cost: 0,
|
|
209
|
+
}, pre)).product,
|
|
210
|
+
);
|
|
184
211
|
assert.equal(
|
|
185
212
|
out,
|
|
186
213
|
dec(primary),
|
|
@@ -57,7 +57,20 @@ 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
|
+
// `reason()` now consumes and returns the derivation STATE; with no remainder
|
|
64
|
+
// the derivation is CLOSED, so the law admits any contained continuation —
|
|
65
|
+
// which is exactly what these two cases exercise. The assertions below are
|
|
66
|
+
// untouched.
|
|
67
|
+
const state = {
|
|
68
|
+
product: answer,
|
|
69
|
+
accounted: [],
|
|
70
|
+
remainder: [],
|
|
71
|
+
cost: 0,
|
|
72
|
+
};
|
|
73
|
+
const out = (await reason(m, query, state, new Set(), pre)).product;
|
|
61
74
|
assert.equal(
|
|
62
75
|
dec(out),
|
|
63
76
|
"bridge context",
|
|
@@ -82,7 +95,20 @@ test("reason(): an ordinary forward hop onto genuinely new content is unaffected
|
|
|
82
95
|
queryResolved: resolve(m, query),
|
|
83
96
|
};
|
|
84
97
|
|
|
85
|
-
|
|
98
|
+
// `reason()` reports the WHOLE extension (bytes + what it carried + how many
|
|
99
|
+
// steps) so a caller can price it; these assertions measure the bytes, and
|
|
100
|
+
// that is all this change touches — the law they pin is untouched.
|
|
101
|
+
// `reason()` now consumes and returns the derivation STATE; with no remainder
|
|
102
|
+
// the derivation is CLOSED, so the law admits any contained continuation —
|
|
103
|
+
// which is exactly what these two cases exercise. The assertions below are
|
|
104
|
+
// untouched.
|
|
105
|
+
const state = {
|
|
106
|
+
product: answer,
|
|
107
|
+
accounted: [],
|
|
108
|
+
remainder: [],
|
|
109
|
+
cost: 0,
|
|
110
|
+
};
|
|
111
|
+
const out = (await reason(m, query, state, new Set(), pre)).product;
|
|
86
112
|
assert.equal(
|
|
87
113
|
dec(out),
|
|
88
114
|
"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,
|