@hviana/sema 0.7.9 → 0.8.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/AGENTS.md +22 -1
- package/DATASETS.md +1 -1
- package/dist/example/train_base/config.js +2 -2
- package/dist/example/train_base/corpora/massive.js +1 -1
- package/dist/example/train_base/readers.js +1 -1
- package/dist/src/geometry.d.ts +10 -10
- package/dist/src/geometry.js +25 -24
- package/dist/src/meter.d.ts +4 -12
- package/dist/src/meter.js +14 -14
- package/dist/src/mind/attention.js +12 -12
- package/dist/src/mind/bridge.d.ts +8 -8
- package/dist/src/mind/bridge.js +33 -32
- package/dist/src/mind/graph-search.d.ts +0 -8
- package/dist/src/mind/graph-search.js +38 -25
- package/dist/src/mind/junction.d.ts +1 -1
- package/dist/src/mind/junction.js +8 -8
- package/dist/src/mind/learning.js +36 -35
- package/dist/src/mind/match.js +14 -13
- package/dist/src/mind/mechanisms/cover.js +13 -12
- package/dist/src/mind/mechanisms/prefix-completion.js +24 -24
- package/dist/src/mind/mechanisms/recall.js +38 -40
- package/dist/src/mind/mechanisms/reference.js +16 -16
- package/dist/src/mind/mind.d.ts +6 -7
- package/dist/src/mind/pipeline-mechanism.d.ts +10 -8
- package/dist/src/mind/pipeline-mechanism.js +25 -21
- package/dist/src/mind/pipeline.d.ts +9 -9
- package/dist/src/mind/pipeline.js +24 -23
- package/dist/src/mind/primitives.d.ts +5 -5
- package/dist/src/mind/primitives.js +5 -5
- package/dist/src/mind/recognition.d.ts +14 -13
- package/dist/src/mind/recognition.js +53 -38
- package/dist/src/mind/resonance.js +21 -21
- package/dist/src/mind/traverse.d.ts +54 -52
- package/dist/src/mind/traverse.js +74 -72
- package/dist/src/mind/types.d.ts +4 -4
- package/dist/src/store.d.ts +12 -12
- package/dist/src/store.js +12 -12
- package/docs/INDEX.md +2 -2
- package/docs/architecture/exact-vs-approximate.md +2 -1
- package/docs/architecture/fold-contract.md +1 -1
- package/docs/failures/tempting-but-wrong.md +2 -3
- package/docs/harness/gates.md +7 -7
- package/example/train_base/config.ts +2 -2
- package/example/train_base/corpora/massive.ts +1 -1
- package/example/train_base/readers.ts +1 -1
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/geometry.ts +25 -24
- package/src/meter.ts +14 -14
- package/src/mind/attention.ts +12 -12
- package/src/mind/bridge.ts +33 -32
- package/src/mind/graph-search.ts +43 -24
- package/src/mind/junction.ts +8 -8
- package/src/mind/learning.ts +36 -35
- package/src/mind/match.ts +20 -19
- package/src/mind/mechanisms/cover.ts +13 -12
- package/src/mind/mechanisms/prefix-completion.ts +24 -24
- package/src/mind/mechanisms/recall.ts +38 -40
- package/src/mind/mechanisms/reference.ts +16 -16
- package/src/mind/mind.ts +6 -7
- package/src/mind/pipeline-mechanism.ts +25 -21
- package/src/mind/pipeline.ts +33 -32
- package/src/mind/primitives.ts +5 -5
- package/src/mind/recognition.ts +51 -36
- package/src/mind/resonance.ts +21 -21
- package/src/mind/traverse.ts +74 -72
- package/src/mind/types.ts +4 -4
- package/src/store.ts +20 -20
- package/test/08-storage.test.mjs +1 -1
- package/test/35-prefix-edge.test.mjs +1 -1
- package/test/40-choosenext-scale-guard.test.mjs +16 -17
- package/test/46-recognise-multibyte-edge.test.mjs +33 -0
- package/test/56-bridge-identity-admission.test.mjs +6 -6
- package/test/70-prefix-completion.test.mjs +4 -3
- package/test/72-prefix-candidate-supply.test.mjs +3 -3
- package/test/73-scaffolding-only-bridge-abstains.test.mjs +6 -6
- package/test/75-multiturn-context-optimisation.test.mjs +5 -5
- package/test/84-composed-answer-honesty.test.mjs +5 -6
- package/test/88-dependency-footprint.test.mjs +1 -1
- package/test/89-completion-recursion.test.mjs +17 -14
- package/test/90-connector-read-cap.test.mjs +10 -8
- package/test/93-regime-prediction.test.mjs +10 -10
- package/test/94-cross-region-budget.test.mjs +2 -2
- package/test/95-wide-resonance-removed.test.mjs +8 -7
- package/test/96-bytes-walk-termination.test.mjs +3 -3
- package/test/99-fact-join.test.mjs +38 -0
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
// substring search, so it needs the candidate's bytes; it used to reconstruct
|
|
8
8
|
// them in FULL via `read(ctx, answer)`, whose maxLen defaults to ALL.
|
|
9
9
|
//
|
|
10
|
-
//
|
|
10
|
+
// bounded-reads.md, prefix-capped reads: "a candidate that exceeds the cap is
|
|
11
11
|
// rejected without reconstructing it — the weave, the junction walks and the
|
|
12
12
|
// bridge all read this way, and uncapped reads there cost seconds per query on
|
|
13
|
-
// a large store."
|
|
13
|
+
// a large store." This probe was the exception: it runs hubBound(ctx) = √N
|
|
14
14
|
// times PER SITE.
|
|
15
15
|
//
|
|
16
16
|
// The probe's corpus-scale cost was once claimed from a trained-store
|
|
@@ -18,14 +18,15 @@
|
|
|
18
18
|
// prompt" — but that number was measured on a `respond()` query, where the
|
|
19
19
|
// probe does NOT execute (`answeredSpans` is empty there, so the enclosing
|
|
20
20
|
// guard returns first). It is therefore not attributable to the probe and is
|
|
21
|
-
// not repeated here (
|
|
21
|
+
// not repeated here (a comment asserting a measurement inherits Gate 1).
|
|
22
22
|
// The probe runs only on a multi-turn `respondTurn` response; its benefit there
|
|
23
23
|
// is still unmeasured.
|
|
24
24
|
//
|
|
25
|
-
// WHAT THIS PINS.
|
|
26
|
-
// could (see below).
|
|
27
|
-
// and what rescues a SHORT query: candidates averaged 231
|
|
28
|
-
// against a 3-byte prompt.
|
|
25
|
+
// WHAT THIS PINS. The cap cannot reduce the read COUNT — only a semantic change
|
|
26
|
+
// could (see below). It bounds each read by the QUERY, which is what
|
|
27
|
+
// bounded-reads.md asks and what rescues a SHORT query: candidates averaged 231
|
|
28
|
+
// B reconstructed against a 3-byte prompt. So the invariant here is per-read
|
|
29
|
+
// SIZE.
|
|
29
30
|
//
|
|
30
31
|
// It is measured by calling `resolveConnectors` DIRECTLY and diffing the meter
|
|
31
32
|
// across it. A whole-response counter cannot express this: `bytesRead` sums
|
|
@@ -121,7 +122,8 @@ test("connector probe reads by the query, not by the learnt continuation", async
|
|
|
121
122
|
`the connector probe averaged ${perRead.toFixed(0)} B per read for a ` +
|
|
122
123
|
`${QUERY.length} B query — a candidate longer than the query cannot ` +
|
|
123
124
|
`occur inside it, so it must be rejected on an overflow probe of ` +
|
|
124
|
-
`${QUERY.length + 1} B, not reconstructed in full
|
|
125
|
+
`${QUERY.length + 1} B, not reconstructed in full ` +
|
|
126
|
+
`(bounded-reads.md)`,
|
|
125
127
|
);
|
|
126
128
|
} finally {
|
|
127
129
|
mind.endResponse();
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// 93-regime-prediction.test.mjs — the retrieval/composition regime (R8) is
|
|
2
2
|
// exposed as a structured trace step, without changing inference.
|
|
3
3
|
//
|
|
4
|
-
// After the FIRST mechanism runs (cover, which
|
|
5
|
-
// 0), the market's whole outcome is already determined by the one
|
|
6
|
-
// the consensus climb runs exactly when `worthRunning(2 * STEP)`
|
|
7
|
-
// CAST (floor 2·STEP) is the cheapest mechanism that first-touches
|
|
8
|
-
// incumbent at or below that floor prunes CAST and, with it, the climb
|
|
4
|
+
// After the FIRST mechanism runs (cover, which mechanism-market.md places first
|
|
5
|
+
// and floors at 0), the market's whole outcome is already determined by the one
|
|
6
|
+
// cost ladder: the consensus climb runs exactly when `worthRunning(2 * STEP)`
|
|
7
|
+
// is true — CAST (floor 2·STEP) is the cheapest mechanism that first-touches
|
|
8
|
+
// it. An incumbent at or below that floor prunes CAST and, with it, the climb
|
|
9
9
|
// (retrieval); anything above — or no incumbent — runs the full market and the
|
|
10
|
-
// climb (composition).
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
10
|
+
// climb (composition). The step is purely observational: it is built only under
|
|
11
|
+
// a trace (optional-chaining short-circuits it otherwise), and it never alters
|
|
12
|
+
// which candidate wins. The assertions here check the payload's STRUCTURE and
|
|
13
|
+
// its consistency with the actual market outcome, never that inference itself
|
|
14
|
+
// changed.
|
|
15
15
|
|
|
16
16
|
import { test } from "node:test";
|
|
17
17
|
import assert from "node:assert/strict";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// 94-cross-region-budget.test.mjs — the cross-region junction ladder shares ONE
|
|
2
2
|
// k·W allowance per evidence tier once atoms are hubs, instead of letting each
|
|
3
|
-
// candidate pair spend its own √N·W drift budget (attention.ts
|
|
4
|
-
//
|
|
3
|
+
// candidate pair spend its own √N·W drift budget (attention.ts
|
|
4
|
+
// crossRegionVotes, saturation.md's derived gate = traverse.atomIsHub).
|
|
5
5
|
//
|
|
6
6
|
// This is a PERFORMANCE regression test, not a behaviour test: the shared
|
|
7
7
|
// budget is byte-identical at every scale — a pair whose container is not
|
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
// pipeline-mechanism.ts's REMOVED note).
|
|
5
5
|
//
|
|
6
6
|
// This is a PERFORMANCE regression test, not a behaviour test: the wide list
|
|
7
|
-
// was
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
7
|
+
// was
|
|
8
|
+
// a PROPOSAL source whose consumers byte-verify every candidate
|
|
9
|
+
// (exact-vs-approximate.md), so removing it is byte-identical wherever the
|
|
10
|
+
// bounded sources supply the same candidate set — and the meter's phase map is
|
|
11
|
+
// the only observable that says whether the exhaustive machinery still exists.
|
|
12
|
+
// Red-on-revert: re-adding wideResonance re-creates the `wideResonance` phase
|
|
13
|
+
// (and, when the query's top hit clears conceptThreshold, a full-index ANN scan
|
|
14
|
+
// inside it), so the phase-absence assertion below fails.
|
|
14
15
|
|
|
15
16
|
import { test } from "node:test";
|
|
16
17
|
import assert from "node:assert/strict";
|
|
@@ -92,12 +92,12 @@ test("bytes() terminates when its memo cannot hold the working set", async () =>
|
|
|
92
92
|
});
|
|
93
93
|
|
|
94
94
|
test("differsByOneWindow's reads are capped — no ALL-sentinel read on deposit", async () => {
|
|
95
|
-
//
|
|
95
|
+
// bounded-reads.md: the near-dedup byte check used to open with
|
|
96
96
|
// `bytesPrefix(k, Number.MAX_SAFE_INTEGER)` — the ALL sentinel, which routes
|
|
97
|
-
// to the full materialising `bytes()` — and only THEN compare lengths.
|
|
97
|
+
// to the full materialising `bytes()` — and only THEN compare lengths. A
|
|
98
98
|
// candidate the length test was about to reject had already been rebuilt byte
|
|
99
99
|
// for byte, and that read is what dragged the deposit path into the walk
|
|
100
|
-
// above.
|
|
100
|
+
// above. Lengths now decide first, from the `contentLen` memo.
|
|
101
101
|
const src = await import("node:fs").then((fs) =>
|
|
102
102
|
fs.readFileSync(new URL("../src/store.ts", import.meta.url), "utf8")
|
|
103
103
|
);
|
|
@@ -97,3 +97,41 @@ test("naming the intermediate does not need derive-through — the cover reads i
|
|
|
97
97
|
);
|
|
98
98
|
await store.close();
|
|
99
99
|
});
|
|
100
|
+
|
|
101
|
+
/** The TRAP fixture: the query's OWN subject carries the asked relation too, so
|
|
102
|
+
* a join that follows the subject answers about the subject. */
|
|
103
|
+
const TRAP_CHAIN = [
|
|
104
|
+
["Eiffel Tower country", "The country of Eiffel Tower is France."],
|
|
105
|
+
["France capital", "The capital of France is Paris."],
|
|
106
|
+
["France", "The capital of France is Paris."],
|
|
107
|
+
["Eiffel Tower capital", "The capital of Eiffel Tower is Berlin."],
|
|
108
|
+
["Eiffel Tower", "The country of Eiffel Tower is France."],
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
async function trappedFlip() {
|
|
112
|
+
const store = new SQliteStore({ path: ":memory:", D: 1024 });
|
|
113
|
+
const mind = new Mind({ seed: 7, store });
|
|
114
|
+
await mind.ingest(TRAP_CHAIN);
|
|
115
|
+
await mind.ingest(Array.from({ length: 4300 }, (_, i) => filler(i)));
|
|
116
|
+
return { store, mind };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
test("the join answers about the entity the query did NOT name, not the query's own subject", async () => {
|
|
120
|
+
// MEASURED on the pre-change tree: the answer was "The capital of Eiffel
|
|
121
|
+
// Tower country is Berlin." — the join followed the query's OWN subject
|
|
122
|
+
// (Eiffel Tower), which carries a "capital" fact of its own, instead of the
|
|
123
|
+
// entity the produced fact introduces (France). Both candidates are contexts
|
|
124
|
+
// joined by the same relation, so only the preference decides.
|
|
125
|
+
const { store, mind } = await trappedFlip();
|
|
126
|
+
const moves = [];
|
|
127
|
+
const out = await mind.respondText(
|
|
128
|
+
"Eiffel Tower country capital",
|
|
129
|
+
(s) => moves.push(s.mechanism[s.mechanism.length - 1]),
|
|
130
|
+
);
|
|
131
|
+
assert.equal(out.trim(), "The capital of France is Paris.");
|
|
132
|
+
assert.ok(
|
|
133
|
+
!out.includes("Eiffel Tower"),
|
|
134
|
+
`the answer must be about the inferred entity, got ${JSON.stringify(out)}`,
|
|
135
|
+
);
|
|
136
|
+
await store.close();
|
|
137
|
+
});
|