@hviana/sema 0.1.5 → 0.1.6

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 (160) 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 +1687 -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 +17 -42
  51. package/dist/src/geometry.js +235 -266
  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 +749 -871
  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 +126 -185
  82. package/dist/src/mind/mind.d.ts +129 -154
  83. package/dist/src/mind/mind.js +258 -288
  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 +8 -32
  89. package/dist/src/mind/primitives.js +99 -117
  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 +183 -208
  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 +16 -58
  101. package/dist/src/mind/traverse.js +304 -357
  102. package/dist/src/mind/types.d.ts +120 -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 +169 -166
  117. package/dist/src/store-sqlite.js +762 -662
  118. package/dist/src/store.d.ts +586 -630
  119. package/dist/src/store.js +1423 -1581
  120. package/dist/src/vec.d.ts +5 -9
  121. package/dist/src/vec.js +61 -73
  122. package/example/train_base.ts +13 -10
  123. package/package.json +1 -1
  124. package/src/alu/README.md +1 -1
  125. package/src/alu/src/index.ts +1 -1
  126. package/src/config.ts +19 -27
  127. package/src/index.ts +6 -11
  128. package/src/rabitq-ivf/README.md +56 -0
  129. package/src/rabitq-ivf/src/database.ts +276 -0
  130. package/src/{rabitq-hnsw → rabitq-ivf}/src/index.ts +2 -5
  131. package/src/rabitq-ivf/src/ivf.ts +1330 -0
  132. package/src/{rabitq-hnsw → rabitq-ivf}/src/prng.ts +1 -1
  133. package/src/store-sqlite.ts +196 -9
  134. package/src/store.ts +8 -32
  135. package/test/08-storage.test.mjs +3 -3
  136. package/test/14-scaling.test.mjs +2 -2
  137. package/test/35-ivf.test.mjs +263 -0
  138. package/test/36-bloom.test.mjs +123 -0
  139. package/dist/src/rabitq-hnsw/src/database.d.ts +0 -202
  140. package/dist/src/rabitq-hnsw/src/database.js +0 -405
  141. package/dist/src/rabitq-hnsw/src/heap.d.ts +0 -22
  142. package/dist/src/rabitq-hnsw/src/heap.js +0 -94
  143. package/dist/src/rabitq-hnsw/src/hnsw.d.ts +0 -125
  144. package/dist/src/rabitq-hnsw/src/hnsw.js +0 -500
  145. package/dist/src/rabitq-hnsw/src/index.d.ts +0 -15
  146. package/dist/src/rabitq-hnsw/src/prng.d.ts +0 -19
  147. package/dist/src/rabitq-hnsw/src/prng.js +0 -38
  148. package/dist/src/rabitq-hnsw/src/rabitq.d.ts +0 -95
  149. package/dist/src/rabitq-hnsw/src/rabitq.js +0 -299
  150. package/dist/src/rabitq-hnsw/src/store.d.ts +0 -162
  151. package/dist/src/rabitq-hnsw/src/store.js +0 -916
  152. package/dist/src/rabitq-hnsw/test/hnsw.test.d.ts +0 -1
  153. package/dist/src/rabitq-hnsw/test/hnsw.test.js +0 -1197
  154. package/src/rabitq-hnsw/README.md +0 -303
  155. package/src/rabitq-hnsw/src/database.ts +0 -492
  156. package/src/rabitq-hnsw/src/heap.ts +0 -90
  157. package/src/rabitq-hnsw/src/hnsw.ts +0 -514
  158. package/src/rabitq-hnsw/src/store.ts +0 -994
  159. package/src/rabitq-hnsw/test/hnsw.test.ts +0 -1213
  160. /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
  }
@@ -3,12 +3,7 @@ import { Sema } from "../sema.js";
3
3
  import type { Input, MindContext } from "./types.js";
4
4
  /** Perceive input into a content-defined tree (the river fold).
5
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;
6
+ export declare function perceive(ctx: MindContext, input: Input, leafAt?: (i: number) => number | null, lookup?: (ids: number[]) => number | null): Sema;
12
7
  /** The DEPOSIT-shaped perceive: the PLAIN fold (bit-identical to inference
13
8
  * perception — that structural train/inference agreement is load-bearing
14
9
  * for exact recall), computed INCREMENTALLY via the fold's level pyramid
@@ -17,10 +12,7 @@ export declare function perceive(
17
12
  * (ctx._depositTrees), and this deposit refolds only the right edge of
18
13
  * each level — O(turn) instead of O(context) per turn. Purely a cache:
19
14
  * the produced tree never depends on cache state. */
20
- export declare function perceiveDeposit(
21
- ctx: MindContext,
22
- bytes: Uint8Array,
23
- ): Sema;
15
+ export declare function perceiveDeposit(ctx: MindContext, bytes: Uint8Array): Sema;
24
16
  /** The raw bytes of an input — modality-neutral conversion. */
25
17
  export declare function inputBytes(ctx: MindContext, input: Input): Uint8Array;
26
18
  /** Convenience: the gist vector of a byte span. */
@@ -30,22 +22,14 @@ export declare function gistOf(ctx: MindContext, bytes: Uint8Array): Vec;
30
22
  * ids (null the moment any child is unknown). `visit`, when given, sees each
31
23
  * node with its byte span and resolved id. Returns the node's byte end and
32
24
  * 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;
25
+ export declare function foldTree(ctx: MindContext, n: Sema, start: number, visit?: (n: Sema, start: number, end: number, node: number | null) => void): {
26
+ end: number;
27
+ node: number | null;
41
28
  };
42
29
  /** The canonical node id of a byte span: perceive it in isolation — the way
43
30
  * training did — and recover its root bottom-up. Returns null if any part is
44
31
  * unknown. */
45
- export declare function resolve(
46
- ctx: MindContext,
47
- bytes: Uint8Array,
48
- ): number | null;
32
+ export declare function resolve(ctx: MindContext, bytes: Uint8Array): number | null;
49
33
  /** Walk a perceived tree in POST-ORDER with byte offsets — children before
50
34
  * their parent, `visit(node, start, end)` for every node including leaves.
51
35
  * Returns the byte end. The one shared traversal the offset-carrying tree
@@ -54,14 +38,6 @@ export declare function resolve(
54
38
  * re-derive the offset bookkeeping. (recognition.segment keeps its own
55
39
  * walk: its flush semantics need PRE-order decisions at leaf-parents, which
56
40
  * 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;
41
+ export declare function walkTree(n: Sema, start: number, visit: (node: Sema, start: number, end: number) => void): number;
62
42
  /** 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;
43
+ export declare function read(ctx: MindContext, id: number, maxLen?: number): Uint8Array;