@hviana/sema 0.1.5 → 0.1.7

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.
Files changed (170) hide show
  1. package/AGENTS.md +6 -5
  2. package/CITATION.cff +49 -0
  3. package/HOW_IT_WORKS.md +11 -12
  4. package/README.md +7 -5
  5. package/dist/example/demo.js +25 -25
  6. package/dist/example/train_base.d.ts +19 -21
  7. package/dist/example/train_base.js +1700 -1952
  8. package/dist/src/alphabet.d.ts +3 -3
  9. package/dist/src/alphabet.js +24 -27
  10. package/dist/src/alu/src/alu.d.ts +169 -194
  11. package/dist/src/alu/src/alu.js +374 -414
  12. package/dist/src/alu/src/expr.d.ts +36 -43
  13. package/dist/src/alu/src/expr.js +252 -278
  14. package/dist/src/alu/src/index.d.ts +9 -98
  15. package/dist/src/alu/src/index.js +10 -64
  16. package/dist/src/alu/src/kernel-arith.d.ts +1 -5
  17. package/dist/src/alu/src/kernel-arith.js +195 -285
  18. package/dist/src/alu/src/kernel-bits.d.ts +1 -5
  19. package/dist/src/alu/src/kernel-bits.js +81 -115
  20. package/dist/src/alu/src/kernel-logic.js +33 -63
  21. package/dist/src/alu/src/kernel-nd.js +155 -195
  22. package/dist/src/alu/src/kernel-numeric.d.ts +16 -80
  23. package/dist/src/alu/src/kernel-numeric.js +259 -331
  24. package/dist/src/alu/src/operation.d.ts +112 -132
  25. package/dist/src/alu/src/operation.js +149 -163
  26. package/dist/src/alu/src/parser.d.ts +168 -175
  27. package/dist/src/alu/src/parser.js +382 -421
  28. package/dist/src/alu/src/resonance.d.ts +16 -25
  29. package/dist/src/alu/src/resonance.js +49 -56
  30. package/dist/src/alu/src/text.d.ts +3 -7
  31. package/dist/src/alu/src/text.js +31 -37
  32. package/dist/src/alu/src/value.d.ts +14 -14
  33. package/dist/src/alu/src/value.js +150 -160
  34. package/dist/src/alu/test/alu.test.js +543 -656
  35. package/dist/src/bytes.d.ts +1 -5
  36. package/dist/src/bytes.js +33 -40
  37. package/dist/src/config.d.ts +99 -102
  38. package/dist/src/config.js +78 -83
  39. package/dist/src/derive/src/deduction.d.ts +60 -62
  40. package/dist/src/derive/src/deduction.js +103 -109
  41. package/dist/src/derive/src/index.d.ts +1 -7
  42. package/dist/src/derive/src/priority-queue.d.ts +8 -8
  43. package/dist/src/derive/src/priority-queue.js +57 -61
  44. package/dist/src/derive/src/rewrite.d.ts +15 -18
  45. package/dist/src/derive/src/rewrite.js +59 -67
  46. package/dist/src/derive/src/trie.d.ts +56 -56
  47. package/dist/src/derive/src/trie.js +175 -179
  48. package/dist/src/derive/test/derive.test.js +96 -100
  49. package/dist/src/extension.d.ts +13 -16
  50. package/dist/src/geometry.d.ts +29 -43
  51. package/dist/src/geometry.js +324 -268
  52. package/dist/src/index.d.ts +2 -17
  53. package/dist/src/index.js +2 -12
  54. package/dist/src/ingest-cache.d.ts +25 -30
  55. package/dist/src/ingest-cache.js +108 -127
  56. package/dist/src/mind/articulation.d.ts +1 -5
  57. package/dist/src/mind/articulation.js +77 -112
  58. package/dist/src/mind/attention.d.ts +40 -108
  59. package/dist/src/mind/attention.js +754 -872
  60. package/dist/src/mind/canonical.d.ts +4 -19
  61. package/dist/src/mind/canonical.js +27 -31
  62. package/dist/src/mind/graph-search.d.ts +201 -225
  63. package/dist/src/mind/graph-search.js +742 -821
  64. package/dist/src/mind/index.d.ts +2 -10
  65. package/dist/src/mind/junction.d.ts +31 -58
  66. package/dist/src/mind/junction.js +172 -237
  67. package/dist/src/mind/learning.d.ts +16 -52
  68. package/dist/src/mind/learning.js +143 -165
  69. package/dist/src/mind/match.d.ts +20 -69
  70. package/dist/src/mind/match.js +259 -318
  71. package/dist/src/mind/mechanisms/alu.js +16 -16
  72. package/dist/src/mind/mechanisms/cast.d.ts +9 -13
  73. package/dist/src/mind/mechanisms/cast.js +363 -456
  74. package/dist/src/mind/mechanisms/confluence.d.ts +8 -12
  75. package/dist/src/mind/mechanisms/confluence.js +152 -183
  76. package/dist/src/mind/mechanisms/cover.d.ts +2 -8
  77. package/dist/src/mind/mechanisms/cover.js +148 -210
  78. package/dist/src/mind/mechanisms/extraction.d.ts +8 -34
  79. package/dist/src/mind/mechanisms/extraction.js +234 -288
  80. package/dist/src/mind/mechanisms/recall.d.ts +6 -10
  81. package/dist/src/mind/mechanisms/recall.js +141 -185
  82. package/dist/src/mind/mind.d.ts +194 -155
  83. package/dist/src/mind/mind.js +392 -289
  84. package/dist/src/mind/pipeline-mechanism.d.ts +112 -124
  85. package/dist/src/mind/pipeline-mechanism.js +161 -172
  86. package/dist/src/mind/pipeline.d.ts +4 -14
  87. package/dist/src/mind/pipeline.js +125 -189
  88. package/dist/src/mind/primitives.d.ts +20 -33
  89. package/dist/src/mind/primitives.js +124 -120
  90. package/dist/src/mind/rationale.d.ts +86 -98
  91. package/dist/src/mind/rationale.js +113 -121
  92. package/dist/src/mind/reasoning.d.ts +2 -13
  93. package/dist/src/mind/reasoning.js +129 -166
  94. package/dist/src/mind/recognition.d.ts +1 -4
  95. package/dist/src/mind/recognition.js +198 -210
  96. package/dist/src/mind/resonance.d.ts +5 -22
  97. package/dist/src/mind/resonance.js +0 -0
  98. package/dist/src/mind/trace.d.ts +6 -25
  99. package/dist/src/mind/trace.js +50 -58
  100. package/dist/src/mind/traverse.d.ts +29 -58
  101. package/dist/src/mind/traverse.js +344 -356
  102. package/dist/src/mind/types.d.ts +122 -127
  103. package/dist/src/mind/types.js +60 -69
  104. package/dist/src/rabitq-ivf/src/database.d.ts +113 -0
  105. package/dist/src/rabitq-ivf/src/database.js +201 -0
  106. package/dist/src/rabitq-ivf/src/index.d.ts +7 -0
  107. package/dist/src/{rabitq-hnsw → rabitq-ivf}/src/index.js +1 -3
  108. package/dist/src/rabitq-ivf/src/ivf.d.ts +200 -0
  109. package/dist/src/rabitq-ivf/src/ivf.js +1165 -0
  110. package/dist/src/rabitq-ivf/src/prng.d.ts +19 -0
  111. package/dist/src/rabitq-ivf/src/prng.js +36 -0
  112. package/dist/src/rabitq-ivf/src/rabitq.d.ts +95 -0
  113. package/dist/src/rabitq-ivf/src/rabitq.js +283 -0
  114. package/dist/src/sema.d.ts +9 -13
  115. package/dist/src/sema.js +26 -40
  116. package/dist/src/store-sqlite.d.ts +171 -166
  117. package/dist/src/store-sqlite.js +768 -662
  118. package/dist/src/store.d.ts +597 -630
  119. package/dist/src/store.js +1434 -1581
  120. package/dist/src/vec.d.ts +5 -9
  121. package/dist/src/vec.js +61 -73
  122. package/example/train_base.ts +33 -15
  123. package/index.html +65 -0
  124. package/package.json +1 -1
  125. package/src/alu/README.md +1 -1
  126. package/src/alu/src/index.ts +1 -1
  127. package/src/config.ts +19 -27
  128. package/src/geometry.ts +93 -1
  129. package/src/index.ts +6 -11
  130. package/src/mind/attention.ts +11 -6
  131. package/src/mind/mechanisms/recall.ts +29 -13
  132. package/src/mind/mind.ts +250 -19
  133. package/src/mind/primitives.ts +43 -6
  134. package/src/mind/recognition.ts +26 -8
  135. package/src/mind/traverse.ts +47 -0
  136. package/src/mind/types.ts +20 -21
  137. package/src/rabitq-ivf/README.md +56 -0
  138. package/src/rabitq-ivf/src/database.ts +276 -0
  139. package/src/{rabitq-hnsw → rabitq-ivf}/src/index.ts +2 -5
  140. package/src/rabitq-ivf/src/ivf.ts +1330 -0
  141. package/src/{rabitq-hnsw → rabitq-ivf}/src/prng.ts +1 -1
  142. package/src/store-sqlite.ts +204 -9
  143. package/src/store.ts +27 -34
  144. package/test/08-storage.test.mjs +3 -3
  145. package/test/13-conversation.test.mjs +190 -20
  146. package/test/14-scaling.test.mjs +2 -2
  147. package/test/35-ivf.test.mjs +263 -0
  148. package/test/36-bloom.test.mjs +123 -0
  149. package/dist/src/rabitq-hnsw/src/database.d.ts +0 -202
  150. package/dist/src/rabitq-hnsw/src/database.js +0 -405
  151. package/dist/src/rabitq-hnsw/src/heap.d.ts +0 -22
  152. package/dist/src/rabitq-hnsw/src/heap.js +0 -94
  153. package/dist/src/rabitq-hnsw/src/hnsw.d.ts +0 -125
  154. package/dist/src/rabitq-hnsw/src/hnsw.js +0 -500
  155. package/dist/src/rabitq-hnsw/src/index.d.ts +0 -15
  156. package/dist/src/rabitq-hnsw/src/prng.d.ts +0 -19
  157. package/dist/src/rabitq-hnsw/src/prng.js +0 -38
  158. package/dist/src/rabitq-hnsw/src/rabitq.d.ts +0 -95
  159. package/dist/src/rabitq-hnsw/src/rabitq.js +0 -299
  160. package/dist/src/rabitq-hnsw/src/store.d.ts +0 -162
  161. package/dist/src/rabitq-hnsw/src/store.js +0 -916
  162. package/dist/src/rabitq-hnsw/test/hnsw.test.d.ts +0 -1
  163. package/dist/src/rabitq-hnsw/test/hnsw.test.js +0 -1197
  164. package/src/rabitq-hnsw/README.md +0 -303
  165. package/src/rabitq-hnsw/src/database.ts +0 -492
  166. package/src/rabitq-hnsw/src/heap.ts +0 -90
  167. package/src/rabitq-hnsw/src/hnsw.ts +0 -514
  168. package/src/rabitq-hnsw/src/store.ts +0 -994
  169. package/src/rabitq-hnsw/test/hnsw.test.ts +0 -1213
  170. /package/src/{rabitq-hnsw → rabitq-ivf}/src/rabitq.ts +0 -0
@@ -3,16 +3,10 @@ import { type PipelineMechanism } from "./pipeline-mechanism.js";
3
3
  export { resolveConcepts, resolveConnectors } from "./mechanisms/cover.js";
4
4
  export { aluToMechanism } from "./mechanisms/alu.js";
5
5
  export declare const defaultMechanisms: PipelineMechanism[];
6
- export type Provenance =
7
- | "cast"
8
- | "join"
9
- | "cover"
10
- | "extract"
11
- | "recall"
12
- | "recall-echo";
6
+ export type Provenance = "cast" | "join" | "cover" | "extract" | "recall" | "recall-echo";
13
7
  export interface Thought {
14
- bytes: Uint8Array;
15
- provenance: Provenance;
8
+ bytes: Uint8Array;
9
+ provenance: Provenance;
16
10
  }
17
11
  /** Think: a single lightest-derivation exploration of the Sema graph.
18
12
  *
@@ -23,8 +17,4 @@ export interface Thought {
23
17
  * cost ladder; the lightest grounding derivation wins.
24
18
  * 3. Post-grounding — diagnostics (narrowDecision, thinGrounding),
25
19
  * reasoning (multi-hop), fusion (multi-topic). */
26
- export declare function think(
27
- ctx: MindContext,
28
- query: Uint8Array,
29
- mechs?: readonly PipelineMechanism[],
30
- ): Promise<Thought | null>;
20
+ export declare function think(ctx: MindContext, query: Uint8Array, mechs?: readonly PipelineMechanism[]): Promise<Thought | null>;
@@ -26,13 +26,12 @@ export { resolveConcepts, resolveConnectors } from "./mechanisms/cover.js";
26
26
  export { aluToMechanism } from "./mechanisms/alu.js";
27
27
  // ── Extension dispatch (pre-loop parse) ─────────────────────────────────────
28
28
  async function collectComputed(mechanisms, query) {
29
- const out = [];
30
- for (const m of mechanisms) {
31
- if (m.parse) {
32
- out.push(...await m.parse(query));
29
+ const out = [];
30
+ for (const m of mechanisms) {
31
+ if (m.parse)
32
+ out.push(...await m.parse(query));
33
33
  }
34
- }
35
- return out;
34
+ return out;
36
35
  }
37
36
  // ── Built-in mechanisms ─────────────────────────────────────────────────────
38
37
  // ORDER MATTERS, but only through the uniform floor/worthRunning pruning —
@@ -46,11 +45,11 @@ async function collectComputed(mechanisms, query) {
46
45
  // order is also the tie-break priority: cover, cast, confluence, extraction,
47
46
  // recall.
48
47
  export const defaultMechanisms = [
49
- coverMechanism,
50
- castMechanism,
51
- confluenceMechanism,
52
- extractionMechanism,
53
- recallMechanism,
48
+ coverMechanism,
49
+ castMechanism,
50
+ confluenceMechanism,
51
+ extractionMechanism,
52
+ recallMechanism,
54
53
  ];
55
54
  /** Think: a single lightest-derivation exploration of the Sema graph.
56
55
  *
@@ -62,188 +61,125 @@ export const defaultMechanisms = [
62
61
  * 3. Post-grounding — diagnostics (narrowDecision, thinGrounding),
63
62
  * reasoning (multi-hop), fusion (multi-topic). */
64
63
  export async function think(ctx, query, mechs) {
65
- if (query.length === 0) {
66
- return null;
67
- }
68
- ctx._edgeGuide = gistOf(ctx, query);
69
- ctx._edgeChoice.clear();
70
- const t = ctx.trace?.enter("think", [rItem(query, "query")]);
71
- const done = (answer, note) => {
72
- t?.done(
73
- answer
74
- ? [rItem(answer, "answer", resolve(ctx, answer) ?? undefined)]
75
- : [],
76
- note,
77
- );
78
- return answer;
79
- };
80
- // ── Pre-computation ──────────────────────────────────────────────────
81
- const mechanisms = mechs ?? defaultMechanisms;
82
- const rec = recognise(ctx, query);
83
- // Phase 1: collect computed spans from mechanisms that implement parse()
84
- const computed = await collectComputed(mechanisms, query);
85
- if (computed.length > 0) {
86
- ctx.trace?.step(
87
- "computeExtensions",
88
- [rItem(query, "query")],
89
- computed.map((u) =>
90
- rItem(query.subarray(u.i, u.j), "operand", undefined, [u.i, u.j])
91
- ),
92
- `extensions recognised and evaluated ${computed.length} computation(s)`,
93
- );
94
- for (const u of computed) {
95
- ctx.trace?.step(
96
- "evalComputation",
97
- [rItem(query.subarray(u.i, u.j), "expression", undefined, [u.i, u.j])],
98
- [rItem(u.bytes, "result", resolve(ctx, u.bytes) ?? undefined)],
99
- "evaluate the recognised operation to its authoritative result",
100
- );
101
- }
102
- }
103
- // Phase 2: the shared pre-computation container. Eager fields only
104
- // (recognition, computed spans, guide) — every expensive analysis
105
- // (consensus climb, weave, span-shape classification) is a lazily-cached
106
- // method on Precomputed, first-touched by whichever mechanism's floor
107
- // survives its cheap gates and the worthRunning check. A query no
108
- // mechanism climbs for (e.g. one an extension decided) never climbs.
109
- const pre = new Precomputed(ctx, query, rec, computed, ctx._edgeGuide);
110
- const grade = (w) => Math.floor(w / STEP);
111
- const unaccounted = (spans) =>
112
- unexplainedSpans(query.length, spans)
113
- .reduce((sum, [s, e]) => sum + (e - s), 0);
114
- const weigh = (accounted, moves) => moves + PASS * unaccounted(accounted);
115
- const candidates = [];
116
- let best = null;
117
- const consider = (c) => {
118
- if (c.bytes.length === 0) {
119
- return;
120
- }
121
- candidates.push(c);
122
- if (best === null || grade(c.weight) < grade(best.weight)) {
123
- best = c;
124
- }
125
- };
126
- const worthRunning = (floor) =>
127
- best === null || grade(floor) < grade(best.weight);
128
- // Phase 3: grounding loop
129
- for (const mech of mechanisms) {
130
- const floor = await mech.floor(ctx, query, pre, worthRunning);
131
- if (floor === null) {
132
- ctx.trace?.step(
133
- "skipMechanism",
134
- [],
135
- [],
136
- `${mech.name} skipped — structural precondition failed`,
137
- );
138
- continue;
139
- }
140
- if (!worthRunning(floor)) {
141
- ctx.trace?.step(
142
- "skipMechanism",
143
- [],
144
- [],
145
- `${mech.name} skipped — floor ${floor} cannot beat incumbent (grade ${
146
- grade(best.weight)
147
- })`,
148
- );
149
- continue;
150
- }
151
- const results = await mech.run(ctx, query, pre);
152
- for (const r of results) {
153
- const weight = r.weight ?? weigh(r.accounted, r.moves);
154
- consider({
155
- bytes: r.bytes,
156
- provenance: r.provenance ?? mech.provenance,
157
- weight,
158
- used: r.used,
159
- accounted: r.accounted,
160
- unexplained: r.unexplained,
161
- });
64
+ if (query.length === 0)
65
+ return null;
66
+ ctx._edgeGuide = gistOf(ctx, query);
67
+ ctx._edgeChoice.clear();
68
+ const t = ctx.trace?.enter("think", [rItem(query, "query")]);
69
+ const done = (answer, note) => {
70
+ t?.done(answer
71
+ ? [rItem(answer, "answer", resolve(ctx, answer) ?? undefined)]
72
+ : [], note);
73
+ return answer;
74
+ };
75
+ // ── Pre-computation ──────────────────────────────────────────────────
76
+ const mechanisms = mechs ?? defaultMechanisms;
77
+ const rec = recognise(ctx, query);
78
+ // Phase 1: collect computed spans from mechanisms that implement parse()
79
+ const computed = await collectComputed(mechanisms, query);
80
+ if (computed.length > 0) {
81
+ ctx.trace?.step("computeExtensions", [rItem(query, "query")], computed.map((u) => rItem(query.subarray(u.i, u.j), "operand", undefined, [u.i, u.j])), `extensions recognised and evaluated ${computed.length} computation(s)`);
82
+ for (const u of computed) {
83
+ ctx.trace?.step("evalComputation", [rItem(query.subarray(u.i, u.j), "expression", undefined, [u.i, u.j])], [rItem(u.bytes, "result", resolve(ctx, u.bytes) ?? undefined)], "evaluate the recognised operation to its authoritative result");
84
+ }
162
85
  }
163
- }
164
- // (TS cannot see the closure assignments into `best` and narrows it to its
165
- // initial null, so the read-back needs the assertion.)
166
- const decided = best;
167
- if (candidates.length > 1) {
168
- ctx.trace?.step(
169
- "decideGrounding",
170
- candidates.map((c) =>
171
- rItem(
172
- c.bytes,
173
- `${c.provenance} (weight ${c.weight.toFixed(3)}${
174
- c.unexplained ? `, unexplained: "${c.unexplained}"` : ""
175
- })`,
176
- )
177
- ),
178
- decided ? [rItem(decided.bytes, decided.provenance)] : [],
179
- "the lightest grounding derivation wins — every mechanism weighed in the one cost ladder",
180
- );
181
- if (decided !== null) {
182
- let runnerUp = null;
183
- for (const c of candidates) {
184
- if (c === decided) {
185
- continue;
86
+ // Phase 2: the shared pre-computation container. Eager fields only
87
+ // (recognition, computed spans, guide) every expensive analysis
88
+ // (consensus climb, weave, span-shape classification) is a lazily-cached
89
+ // method on Precomputed, first-touched by whichever mechanism's floor
90
+ // survives its cheap gates and the worthRunning check. A query no
91
+ // mechanism climbs for (e.g. one an extension decided) never climbs.
92
+ const pre = new Precomputed(ctx, query, rec, computed, ctx._edgeGuide);
93
+ const grade = (w) => Math.floor(w / STEP);
94
+ const unaccounted = (spans) => unexplainedSpans(query.length, spans)
95
+ .reduce((sum, [s, e]) => sum + (e - s), 0);
96
+ const weigh = (accounted, moves) => moves + PASS * unaccounted(accounted);
97
+ const candidates = [];
98
+ let best = null;
99
+ const consider = (c) => {
100
+ if (c.bytes.length === 0)
101
+ return;
102
+ candidates.push(c);
103
+ if (best === null || grade(c.weight) < grade(best.weight))
104
+ best = c;
105
+ };
106
+ const worthRunning = (floor) => best === null || grade(floor) < grade(best.weight);
107
+ // Phase 3: grounding loop
108
+ for (const mech of mechanisms) {
109
+ const floor = await mech.floor(ctx, query, pre, worthRunning);
110
+ if (floor === null) {
111
+ ctx.trace?.step("skipMechanism", [], [], `${mech.name} skipped — structural precondition failed`);
112
+ continue;
113
+ }
114
+ if (!worthRunning(floor)) {
115
+ ctx.trace?.step("skipMechanism", [], [], `${mech.name} skipped — floor ${floor} cannot beat incumbent (grade ${grade(best.weight)})`);
116
+ continue;
186
117
  }
187
- if (runnerUp === null || grade(c.weight) < grade(runnerUp.weight)) {
188
- runnerUp = c;
118
+ const results = await mech.run(ctx, query, pre);
119
+ for (const r of results) {
120
+ const weight = r.weight ?? weigh(r.accounted, r.moves);
121
+ consider({
122
+ bytes: r.bytes,
123
+ provenance: r.provenance ?? mech.provenance,
124
+ weight,
125
+ used: r.used,
126
+ accounted: r.accounted,
127
+ unexplained: r.unexplained,
128
+ });
189
129
  }
190
- }
191
- if (runnerUp !== null) {
192
- const margin = grade(runnerUp.weight) - grade(decided.weight);
193
- if (margin <= 1) {
194
- ctx.trace?.step(
195
- "narrowDecision",
196
- [
197
- rItem(
198
- decided.bytes,
199
- `${decided.provenance} (weight ${decided.weight.toFixed(3)})`,
200
- ),
201
- ],
202
- [
203
- rItem(
204
- runnerUp.bytes,
205
- `${runnerUp.provenance} (weight ${runnerUp.weight.toFixed(3)})`,
206
- ),
207
- ],
208
- `margin ${margin} grade-unit(s) — the decision could change with one more training fact`,
209
- );
130
+ }
131
+ // (TS cannot see the closure assignments into `best` and narrows it to its
132
+ // initial null, so the read-back needs the assertion.)
133
+ const decided = best;
134
+ if (candidates.length > 1) {
135
+ ctx.trace?.step("decideGrounding", candidates.map((c) => rItem(c.bytes, `${c.provenance} (weight ${c.weight.toFixed(3)}${c.unexplained ? `, unexplained: "${c.unexplained}"` : ""})`)), decided ? [rItem(decided.bytes, decided.provenance)] : [], "the lightest grounding derivation wins — every mechanism weighed in the one cost ladder");
136
+ if (decided !== null) {
137
+ let runnerUp = null;
138
+ for (const c of candidates) {
139
+ if (c === decided)
140
+ continue;
141
+ if (runnerUp === null || grade(c.weight) < grade(runnerUp.weight)) {
142
+ runnerUp = c;
143
+ }
144
+ }
145
+ if (runnerUp !== null) {
146
+ const margin = grade(runnerUp.weight) - grade(decided.weight);
147
+ if (margin <= 1) {
148
+ ctx.trace?.step("narrowDecision", [
149
+ rItem(decided.bytes, `${decided.provenance} (weight ${decided.weight.toFixed(3)})`),
150
+ ], [
151
+ rItem(runnerUp.bytes, `${runnerUp.provenance} (weight ${runnerUp.weight.toFixed(3)})`),
152
+ ], `margin ${margin} grade-unit(s) — the decision could change with one more training fact`);
153
+ }
154
+ }
210
155
  }
211
- }
212
156
  }
213
- }
214
- if (decided === null) {
215
- done(null, "no mechanism grounded an answer");
216
- return null;
217
- }
218
- // Honesty density
219
- {
220
- const covered = query.length - unaccounted(decided.accounted);
221
- const density = query.length > 0 ? covered / query.length : 1;
222
- const thinBar = 1 / ctx.space.maxGroup;
223
- if (density < thinBar) {
224
- ctx.trace?.step(
225
- "thinGrounding",
226
- [rItem(decided.bytes, decided.provenance)],
227
- [],
228
- `grounded but thin — density ${density.toFixed(3)} is below 1/W (${
229
- thinBar.toFixed(3)
230
- })`,
231
- );
157
+ if (decided === null) {
158
+ done(null, "no mechanism grounded an answer");
159
+ return null;
160
+ }
161
+ // Honesty density
162
+ {
163
+ const covered = query.length - unaccounted(decided.accounted);
164
+ const density = query.length > 0 ? covered / query.length : 1;
165
+ const thinBar = 1 / ctx.space.maxGroup;
166
+ if (density < thinBar) {
167
+ ctx.trace?.step("thinGrounding", [rItem(decided.bytes, decided.provenance)], [], `grounded but thin — density ${density.toFixed(3)} is below 1/W (${thinBar.toFixed(3)})`);
168
+ }
232
169
  }
233
- }
234
- const answer = decided.bytes;
235
- const provenance = decided.provenance;
236
- const castUsed = decided.used ?? new Set();
237
- // ── Post-grounding, gated by provenance ──────────────────────────────
238
- const preConsumed = provenance === "cast" || provenance === "join"
239
- ? castUsed
240
- : provenance === "recall" || provenance === "recall-echo"
241
- ? new Set()
242
- : new Set(recognise(ctx, answer).sites.map((s) => s.payload));
243
- const reasoned = await reason(ctx, query, answer, preConsumed, pre);
244
- const fused = provenance === "recall" || provenance === "recall-echo"
245
- ? await fuseAttention(ctx, query, reasoned, pre)
246
- : reasoned;
247
- done(fused, "grounded, reasoned forward, fused across points of attention");
248
- return { bytes: fused, provenance };
170
+ const answer = decided.bytes;
171
+ const provenance = decided.provenance;
172
+ const castUsed = decided.used ?? new Set();
173
+ // ── Post-grounding, gated by provenance ──────────────────────────────
174
+ const preConsumed = provenance === "cast" || provenance === "join"
175
+ ? castUsed
176
+ : provenance === "recall" || provenance === "recall-echo"
177
+ ? new Set()
178
+ : new Set(recognise(ctx, answer).sites.map((s) => s.payload));
179
+ const reasoned = await reason(ctx, query, answer, preConsumed, pre);
180
+ const fused = provenance === "recall" || provenance === "recall-echo"
181
+ ? await fuseAttention(ctx, query, reasoned, pre)
182
+ : reasoned;
183
+ done(fused, "grounded, reasoned forward, fused across points of attention");
184
+ return { bytes: fused, provenance };
249
185
  }
@@ -1,14 +1,20 @@
1
1
  import { Vec } from "../vec.js";
2
2
  import { Sema } from "../sema.js";
3
3
  import type { Input, MindContext } from "./types.js";
4
+ /** The content key of a byte span — one latin1 char per byte, an exact,
5
+ * collision-free encoding. Spans on the perception path are query-scale
6
+ * (windows, regions, candidate spans), so key construction is far cheaper
7
+ * than the river fold it deduplicates. */
8
+ export declare function latin1Key(bytes: Uint8Array): string;
4
9
  /** Perceive input into a content-defined tree (the river fold).
5
- * Deterministic — identical bytes always produce an identical tree. */
6
- export declare function perceive(
7
- ctx: MindContext,
8
- input: Input,
9
- leafAt?: (i: number) => number | null,
10
- lookup?: (ids: number[]) => number | null,
11
- ): Sema;
10
+ * Deterministic — identical bytes always produce an identical tree.
11
+ *
12
+ * `boundaries` is an optional sorted list of proper byte offsets where the
13
+ * fold must split so that each prefix segment folds identically to how it
14
+ * folded when it was learned (§10.3 stable-prefix contract). Only the
15
+ * CALLER who assembled the multi-turn context — knows where those
16
+ * boundaries are; the geometry never guesses them from the bytes. */
17
+ export declare function perceive(ctx: MindContext, input: Input, leafAt?: (i: number) => number | null, lookup?: (ids: number[]) => number | null, boundaries?: readonly number[]): Sema;
12
18
  /** The DEPOSIT-shaped perceive: the PLAIN fold (bit-identical to inference
13
19
  * perception — that structural train/inference agreement is load-bearing
14
20
  * for exact recall), computed INCREMENTALLY via the fold's level pyramid
@@ -17,10 +23,7 @@ export declare function perceive(
17
23
  * (ctx._depositTrees), and this deposit refolds only the right edge of
18
24
  * each level — O(turn) instead of O(context) per turn. Purely a cache:
19
25
  * the produced tree never depends on cache state. */
20
- export declare function perceiveDeposit(
21
- ctx: MindContext,
22
- bytes: Uint8Array,
23
- ): Sema;
26
+ export declare function perceiveDeposit(ctx: MindContext, bytes: Uint8Array): Sema;
24
27
  /** The raw bytes of an input — modality-neutral conversion. */
25
28
  export declare function inputBytes(ctx: MindContext, input: Input): Uint8Array;
26
29
  /** Convenience: the gist vector of a byte span. */
@@ -30,22 +33,14 @@ export declare function gistOf(ctx: MindContext, bytes: Uint8Array): Vec;
30
33
  * ids (null the moment any child is unknown). `visit`, when given, sees each
31
34
  * node with its byte span and resolved id. Returns the node's byte end and
32
35
  * resolved id. */
33
- export declare function foldTree(
34
- ctx: MindContext,
35
- n: Sema,
36
- start: number,
37
- visit?: (n: Sema, start: number, end: number, node: number | null) => void,
38
- ): {
39
- end: number;
40
- node: number | null;
36
+ export declare function foldTree(ctx: MindContext, n: Sema, start: number, visit?: (n: Sema, start: number, end: number, node: number | null) => void): {
37
+ end: number;
38
+ node: number | null;
41
39
  };
42
40
  /** The canonical node id of a byte span: perceive it in isolation — the way
43
41
  * training did — and recover its root bottom-up. Returns null if any part is
44
42
  * unknown. */
45
- export declare function resolve(
46
- ctx: MindContext,
47
- bytes: Uint8Array,
48
- ): number | null;
43
+ export declare function resolve(ctx: MindContext, bytes: Uint8Array): number | null;
49
44
  /** Walk a perceived tree in POST-ORDER with byte offsets — children before
50
45
  * their parent, `visit(node, start, end)` for every node including leaves.
51
46
  * Returns the byte end. The one shared traversal the offset-carrying tree
@@ -54,14 +49,6 @@ export declare function resolve(
54
49
  * re-derive the offset bookkeeping. (recognition.segment keeps its own
55
50
  * walk: its flush semantics need PRE-order decisions at leaf-parents, which
56
51
  * a post-order visitor cannot express.) */
57
- export declare function walkTree(
58
- n: Sema,
59
- start: number,
60
- visit: (node: Sema, start: number, end: number) => void,
61
- ): number;
52
+ export declare function walkTree(n: Sema, start: number, visit: (node: Sema, start: number, end: number) => void): number;
62
53
  /** Reconstruct a node's byte content from the DAG, up to `maxLen` bytes. */
63
- export declare function read(
64
- ctx: MindContext,
65
- id: number,
66
- maxLen?: number,
67
- ): Uint8Array;
54
+ export declare function read(ctx: MindContext, id: number, maxLen?: number): Uint8Array;