@hviana/sema 0.1.4 → 0.1.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.
Files changed (122) hide show
  1. package/dist/example/demo.js +25 -25
  2. package/dist/example/train_base.d.ts +21 -19
  3. package/dist/example/train_base.js +1952 -1684
  4. package/dist/src/alphabet.d.ts +3 -3
  5. package/dist/src/alphabet.js +27 -24
  6. package/dist/src/alu/src/alu.d.ts +194 -169
  7. package/dist/src/alu/src/alu.js +414 -374
  8. package/dist/src/alu/src/expr.d.ts +43 -36
  9. package/dist/src/alu/src/expr.js +278 -252
  10. package/dist/src/alu/src/index.d.ts +98 -9
  11. package/dist/src/alu/src/index.js +63 -9
  12. package/dist/src/alu/src/kernel-arith.d.ts +5 -1
  13. package/dist/src/alu/src/kernel-arith.js +285 -195
  14. package/dist/src/alu/src/kernel-bits.d.ts +5 -1
  15. package/dist/src/alu/src/kernel-bits.js +115 -81
  16. package/dist/src/alu/src/kernel-logic.js +63 -33
  17. package/dist/src/alu/src/kernel-nd.js +195 -155
  18. package/dist/src/alu/src/kernel-numeric.d.ts +80 -16
  19. package/dist/src/alu/src/kernel-numeric.js +331 -259
  20. package/dist/src/alu/src/operation.d.ts +132 -112
  21. package/dist/src/alu/src/operation.js +163 -149
  22. package/dist/src/alu/src/parser.d.ts +175 -168
  23. package/dist/src/alu/src/parser.js +421 -382
  24. package/dist/src/alu/src/resonance.d.ts +25 -16
  25. package/dist/src/alu/src/resonance.js +56 -49
  26. package/dist/src/alu/src/text.d.ts +7 -3
  27. package/dist/src/alu/src/text.js +37 -31
  28. package/dist/src/alu/src/value.d.ts +14 -14
  29. package/dist/src/alu/src/value.js +160 -150
  30. package/dist/src/alu/test/alu.test.js +656 -543
  31. package/dist/src/bytes.d.ts +5 -1
  32. package/dist/src/bytes.js +40 -33
  33. package/dist/src/config.d.ts +102 -102
  34. package/dist/src/config.js +83 -83
  35. package/dist/src/derive/src/deduction.d.ts +62 -60
  36. package/dist/src/derive/src/deduction.js +109 -103
  37. package/dist/src/derive/src/index.d.ts +7 -1
  38. package/dist/src/derive/src/priority-queue.d.ts +8 -8
  39. package/dist/src/derive/src/priority-queue.js +61 -57
  40. package/dist/src/derive/src/rewrite.d.ts +18 -15
  41. package/dist/src/derive/src/rewrite.js +67 -59
  42. package/dist/src/derive/src/trie.d.ts +56 -56
  43. package/dist/src/derive/src/trie.js +179 -175
  44. package/dist/src/derive/test/derive.test.js +100 -96
  45. package/dist/src/extension.d.ts +16 -13
  46. package/dist/src/geometry.d.ts +42 -17
  47. package/dist/src/geometry.js +266 -235
  48. package/dist/src/index.d.ts +17 -2
  49. package/dist/src/index.js +7 -1
  50. package/dist/src/ingest-cache.d.ts +30 -25
  51. package/dist/src/ingest-cache.js +127 -108
  52. package/dist/src/mind/articulation.d.ts +5 -1
  53. package/dist/src/mind/articulation.js +112 -77
  54. package/dist/src/mind/attention.d.ts +108 -40
  55. package/dist/src/mind/attention.js +871 -749
  56. package/dist/src/mind/canonical.d.ts +19 -4
  57. package/dist/src/mind/canonical.js +31 -27
  58. package/dist/src/mind/graph-search.d.ts +225 -201
  59. package/dist/src/mind/graph-search.js +821 -742
  60. package/dist/src/mind/index.d.ts +10 -2
  61. package/dist/src/mind/junction.d.ts +58 -31
  62. package/dist/src/mind/junction.js +237 -172
  63. package/dist/src/mind/learning.d.ts +52 -16
  64. package/dist/src/mind/learning.js +165 -143
  65. package/dist/src/mind/match.d.ts +69 -20
  66. package/dist/src/mind/match.js +318 -259
  67. package/dist/src/mind/mechanisms/alu.js +16 -16
  68. package/dist/src/mind/mechanisms/cast.d.ts +13 -9
  69. package/dist/src/mind/mechanisms/cast.js +456 -363
  70. package/dist/src/mind/mechanisms/confluence.d.ts +12 -8
  71. package/dist/src/mind/mechanisms/confluence.js +183 -152
  72. package/dist/src/mind/mechanisms/cover.d.ts +8 -2
  73. package/dist/src/mind/mechanisms/cover.js +210 -148
  74. package/dist/src/mind/mechanisms/extraction.d.ts +34 -8
  75. package/dist/src/mind/mechanisms/extraction.js +288 -234
  76. package/dist/src/mind/mechanisms/recall.d.ts +10 -6
  77. package/dist/src/mind/mechanisms/recall.js +185 -126
  78. package/dist/src/mind/mind.d.ts +154 -129
  79. package/dist/src/mind/mind.js +288 -258
  80. package/dist/src/mind/pipeline-mechanism.d.ts +124 -112
  81. package/dist/src/mind/pipeline-mechanism.js +172 -161
  82. package/dist/src/mind/pipeline.d.ts +14 -4
  83. package/dist/src/mind/pipeline.js +189 -125
  84. package/dist/src/mind/primitives.d.ts +32 -8
  85. package/dist/src/mind/primitives.js +117 -99
  86. package/dist/src/mind/rationale.d.ts +98 -86
  87. package/dist/src/mind/rationale.js +121 -113
  88. package/dist/src/mind/reasoning.d.ts +13 -2
  89. package/dist/src/mind/reasoning.js +166 -129
  90. package/dist/src/mind/recognition.d.ts +4 -1
  91. package/dist/src/mind/recognition.js +208 -183
  92. package/dist/src/mind/resonance.d.ts +22 -5
  93. package/dist/src/mind/resonance.js +0 -0
  94. package/dist/src/mind/trace.d.ts +25 -6
  95. package/dist/src/mind/trace.js +58 -50
  96. package/dist/src/mind/traverse.d.ts +58 -16
  97. package/dist/src/mind/traverse.js +357 -304
  98. package/dist/src/mind/types.d.ts +127 -120
  99. package/dist/src/mind/types.js +69 -60
  100. package/dist/src/rabitq-hnsw/src/database.d.ts +179 -177
  101. package/dist/src/rabitq-hnsw/src/database.js +359 -342
  102. package/dist/src/rabitq-hnsw/src/heap.d.ts +12 -12
  103. package/dist/src/rabitq-hnsw/src/heap.js +80 -75
  104. package/dist/src/rabitq-hnsw/src/hnsw.d.ts +103 -103
  105. package/dist/src/rabitq-hnsw/src/hnsw.js +454 -428
  106. package/dist/src/rabitq-hnsw/src/index.d.ts +6 -1
  107. package/dist/src/rabitq-hnsw/src/prng.d.ts +10 -10
  108. package/dist/src/rabitq-hnsw/src/prng.js +27 -25
  109. package/dist/src/rabitq-hnsw/src/rabitq.d.ts +69 -69
  110. package/dist/src/rabitq-hnsw/src/rabitq.js +262 -246
  111. package/dist/src/rabitq-hnsw/src/store.d.ts +132 -132
  112. package/dist/src/rabitq-hnsw/src/store.js +843 -752
  113. package/dist/src/rabitq-hnsw/test/hnsw.test.js +1054 -805
  114. package/dist/src/sema.d.ts +13 -9
  115. package/dist/src/sema.js +40 -26
  116. package/dist/src/store-sqlite.d.ts +166 -144
  117. package/dist/src/store-sqlite.js +660 -578
  118. package/dist/src/store.d.ts +630 -593
  119. package/dist/src/store.js +1581 -1440
  120. package/dist/src/vec.d.ts +9 -5
  121. package/dist/src/vec.js +73 -61
  122. package/package.json +2 -2
@@ -2,7 +2,13 @@
2
2
  //
3
3
  // Address — bytes → node (perceive, foldTree, resolve)
4
4
  // Read — node → bytes (read)
5
- import { bytesToTree, bytesToTreePyramid, gridToTree, hilbertBytes, stackGrids, } from "../geometry.js";
5
+ import {
6
+ bytesToTree,
7
+ bytesToTreePyramid,
8
+ gridToTree,
9
+ hilbertBytes,
10
+ stackGrids,
11
+ } from "../geometry.js";
6
12
  import { ALL } from "./types.js";
7
13
  // ── Address: bytes → node ──────────────────────────────────────────────
8
14
  /** The content key of a byte span — one latin1 char per byte, an exact,
@@ -10,45 +16,46 @@ import { ALL } from "./types.js";
10
16
  * (windows, regions, candidate spans), so key construction is far cheaper
11
17
  * than the river fold it deduplicates. */
12
18
  function latin1Key(bytes) {
13
- // Batched String.fromCharCode — avoids the O(n²) cost of repeated += on
14
- // potentially-large query spans, and stays well under the ~65536 arg limit.
15
- const n = bytes.length;
16
- let s = "";
17
- for (let i = 0; i < n; i += 4096) {
18
- s += String.fromCharCode(...bytes.subarray(i, Math.min(i + 4096, n)));
19
- }
20
- return s;
19
+ // Batched String.fromCharCode — avoids the O(n²) cost of repeated += on
20
+ // potentially-large query spans, and stays well under the ~65536 arg limit.
21
+ const n = bytes.length;
22
+ let s = "";
23
+ for (let i = 0; i < n; i += 4096) {
24
+ s += String.fromCharCode(...bytes.subarray(i, Math.min(i + 4096, n)));
25
+ }
26
+ return s;
21
27
  }
22
28
  /** Perceive input into a content-defined tree (the river fold).
23
29
  * Deterministic — identical bytes always produce an identical tree. */
24
30
  export function perceive(ctx, input, leafAt, lookup) {
25
- if (typeof input === "string" || input instanceof Uint8Array) {
26
- const bytes = typeof input === "string"
27
- ? new TextEncoder().encode(input)
28
- : input;
29
- if (leafAt === undefined && lookup === undefined) {
30
- // Per-response memo (see MindContext.perceiveMemo): only the plain
31
- // inference shape — raw bytes, no store capabilities — is memoised,
32
- // keyed by CONTENT so byte-identical spans in fresh arrays still hit.
33
- // The tree is shared by reference; Sema nodes are never mutated.
34
- const memo = ctx.perceiveMemo;
35
- if (memo) {
36
- const key = latin1Key(bytes);
37
- const hit = memo.get(key);
38
- if (hit !== undefined)
39
- return hit;
40
- const tree = bytesToTree(ctx.space, ctx.alphabet, bytes);
41
- memo.set(key, tree);
42
- return tree;
43
- }
44
- return bytesToTree(ctx.space, ctx.alphabet, bytes);
31
+ if (typeof input === "string" || input instanceof Uint8Array) {
32
+ const bytes = typeof input === "string"
33
+ ? new TextEncoder().encode(input)
34
+ : input;
35
+ if (leafAt === undefined && lookup === undefined) {
36
+ // Per-response memo (see MindContext.perceiveMemo): only the plain
37
+ // inference shape — raw bytes, no store capabilities — is memoised,
38
+ // keyed by CONTENT so byte-identical spans in fresh arrays still hit.
39
+ // The tree is shared by reference; Sema nodes are never mutated.
40
+ const memo = ctx.perceiveMemo;
41
+ if (memo) {
42
+ const key = latin1Key(bytes);
43
+ const hit = memo.get(key);
44
+ if (hit !== undefined) {
45
+ return hit;
45
46
  }
46
- return bytesToTree(ctx.space, ctx.alphabet, bytes, leafAt, lookup);
47
+ const tree = bytesToTree(ctx.space, ctx.alphabet, bytes);
48
+ memo.set(key, tree);
49
+ return tree;
50
+ }
51
+ return bytesToTree(ctx.space, ctx.alphabet, bytes);
47
52
  }
48
- if (Array.isArray(input)) {
49
- return gridToTree(ctx.space, ctx.alphabet, stackGrids(input));
50
- }
51
- return gridToTree(ctx.space, ctx.alphabet, input);
53
+ return bytesToTree(ctx.space, ctx.alphabet, bytes, leafAt, lookup);
54
+ }
55
+ if (Array.isArray(input)) {
56
+ return gridToTree(ctx.space, ctx.alphabet, stackGrids(input));
57
+ }
58
+ return gridToTree(ctx.space, ctx.alphabet, input);
52
59
  }
53
60
  /** The DEPOSIT-shaped perceive: the PLAIN fold (bit-identical to inference
54
61
  * perception — that structural train/inference agreement is load-bearing
@@ -59,45 +66,53 @@ export function perceive(ctx, input, leafAt, lookup) {
59
66
  * each level — O(turn) instead of O(context) per turn. Purely a cache:
60
67
  * the produced tree never depends on cache state. */
61
68
  export function perceiveDeposit(ctx, bytes) {
62
- let prev;
63
- // Longest cached PROPER prefix first.
64
- const lens = [...ctx._depositLens]
65
- .filter((L) => L >= 2 && L < bytes.length)
66
- .sort((a, b) => b - a);
67
- for (const L of lens) {
68
- const hit = ctx._depositTrees.get(latin1Key(bytes.subarray(0, L)));
69
- if (hit !== undefined) {
70
- prev = hit;
71
- break;
72
- }
69
+ let prev;
70
+ // Longest cached PROPER prefix first.
71
+ const lens = [...ctx._depositLens]
72
+ .filter((L) => L >= 2 && L < bytes.length)
73
+ .sort((a, b) => b - a);
74
+ for (const L of lens) {
75
+ const hit = ctx._depositTrees.get(latin1Key(bytes.subarray(0, L)));
76
+ if (hit !== undefined) {
77
+ prev = hit;
78
+ break;
73
79
  }
74
- const { tree, pyramid } = bytesToTreePyramid(ctx.space, ctx.alphabet, bytes, prev);
75
- if (bytes.length >= 2) {
76
- // The lengths set drifts as the map evicts; past the probe budget the
77
- // drift itself becomes the cost (each stale length is an O(len) key
78
- // build), so both reset together — losing only warm-up on live chains.
79
- if (ctx._depositLens.size > 64) {
80
- ctx._depositLens.clear();
81
- ctx._depositTrees.clear();
82
- }
83
- ctx._depositTrees.set(latin1Key(bytes), pyramid);
84
- ctx._depositLens.add(bytes.length);
80
+ }
81
+ const { tree, pyramid } = bytesToTreePyramid(
82
+ ctx.space,
83
+ ctx.alphabet,
84
+ bytes,
85
+ prev,
86
+ );
87
+ if (bytes.length >= 2) {
88
+ // The lengths set drifts as the map evicts; past the probe budget the
89
+ // drift itself becomes the cost (each stale length is an O(len) key
90
+ // build), so both reset together — losing only warm-up on live chains.
91
+ if (ctx._depositLens.size > 64) {
92
+ ctx._depositLens.clear();
93
+ ctx._depositTrees.clear();
85
94
  }
86
- return tree;
95
+ ctx._depositTrees.set(latin1Key(bytes), pyramid);
96
+ ctx._depositLens.add(bytes.length);
97
+ }
98
+ return tree;
87
99
  }
88
100
  /** The raw bytes of an input — modality-neutral conversion. */
89
101
  export function inputBytes(ctx, input) {
90
- if (typeof input === "string")
91
- return new TextEncoder().encode(input);
92
- if (input instanceof Uint8Array)
93
- return input;
94
- if (Array.isArray(input))
95
- return hilbertBytes(stackGrids(input));
96
- return hilbertBytes(input);
102
+ if (typeof input === "string") {
103
+ return new TextEncoder().encode(input);
104
+ }
105
+ if (input instanceof Uint8Array) {
106
+ return input;
107
+ }
108
+ if (Array.isArray(input)) {
109
+ return hilbertBytes(stackGrids(input));
110
+ }
111
+ return hilbertBytes(input);
97
112
  }
98
113
  /** Convenience: the gist vector of a byte span. */
99
114
  export function gistOf(ctx, bytes) {
100
- return perceive(ctx, bytes).v;
115
+ return perceive(ctx, bytes).v;
101
116
  }
102
117
  /** Fold a perceived tree bottom-up against the store's content-addressed maps:
103
118
  * every leaf is named by findLeaf, every branch by findBranch over its kids'
@@ -105,35 +120,37 @@ export function gistOf(ctx, bytes) {
105
120
  * node with its byte span and resolved id. Returns the node's byte end and
106
121
  * resolved id. */
107
122
  export function foldTree(ctx, n, start, visit) {
108
- if (n.kids === null) {
109
- const b = n.leaf ?? new Uint8Array(0);
110
- const end = start + b.length;
111
- const node = ctx.store.findLeaf(b);
112
- visit?.(n, start, end, node);
113
- return { end, node };
123
+ if (n.kids === null) {
124
+ const b = n.leaf ?? new Uint8Array(0);
125
+ const end = start + b.length;
126
+ const node = ctx.store.findLeaf(b);
127
+ visit?.(n, start, end, node);
128
+ return { end, node };
129
+ }
130
+ let pos = start;
131
+ let known = true;
132
+ const kids = [];
133
+ for (const k of n.kids) {
134
+ const r = foldTree(ctx, k, pos, visit);
135
+ if (r.node === null) {
136
+ known = false;
137
+ } else if (known) {
138
+ kids.push(r.node);
114
139
  }
115
- let pos = start;
116
- let known = true;
117
- const kids = [];
118
- for (const k of n.kids) {
119
- const r = foldTree(ctx, k, pos, visit);
120
- if (r.node === null)
121
- known = false;
122
- else if (known)
123
- kids.push(r.node);
124
- pos = r.end;
125
- }
126
- const node = known ? ctx.store.findBranch(kids) : null;
127
- visit?.(n, start, pos, node);
128
- return { end: pos, node };
140
+ pos = r.end;
141
+ }
142
+ const node = known ? ctx.store.findBranch(kids) : null;
143
+ visit?.(n, start, pos, node);
144
+ return { end: pos, node };
129
145
  }
130
146
  /** The canonical node id of a byte span: perceive it in isolation — the way
131
147
  * training did — and recover its root bottom-up. Returns null if any part is
132
148
  * unknown. */
133
149
  export function resolve(ctx, bytes) {
134
- if (bytes.length === 0)
135
- return null;
136
- return foldTree(ctx, perceive(ctx, bytes), 0).node;
150
+ if (bytes.length === 0) {
151
+ return null;
152
+ }
153
+ return foldTree(ctx, perceive(ctx, bytes), 0).node;
137
154
  }
138
155
  /** Walk a perceived tree in POST-ORDER with byte offsets — children before
139
156
  * their parent, `visit(node, start, end)` for every node including leaves.
@@ -144,19 +161,20 @@ export function resolve(ctx, bytes) {
144
161
  * walk: its flush semantics need PRE-order decisions at leaf-parents, which
145
162
  * a post-order visitor cannot express.) */
146
163
  export function walkTree(n, start, visit) {
147
- if (n.kids === null) {
148
- const end = start + (n.leaf?.length ?? 0);
149
- visit(n, start, end);
150
- return end;
151
- }
152
- let pos = start;
153
- for (const k of n.kids)
154
- pos = walkTree(k, pos, visit);
155
- visit(n, start, pos);
156
- return pos;
164
+ if (n.kids === null) {
165
+ const end = start + (n.leaf?.length ?? 0);
166
+ visit(n, start, end);
167
+ return end;
168
+ }
169
+ let pos = start;
170
+ for (const k of n.kids) {
171
+ pos = walkTree(k, pos, visit);
172
+ }
173
+ visit(n, start, pos);
174
+ return pos;
157
175
  }
158
176
  // ── Read: node → bytes ──────────────────────────────────────────────────
159
177
  /** Reconstruct a node's byte content from the DAG, up to `maxLen` bytes. */
160
178
  export function read(ctx, id, maxLen = ALL) {
161
- return ctx.store.bytesPrefix(id, maxLen);
179
+ return ctx.store.bytesPrefix(id, maxLen);
162
180
  }
@@ -7,25 +7,25 @@ import type { Vec } from "../vec.js";
7
7
  * the ones that carry meaning for what it did. `text` is always present (the
8
8
  * human-readable rendering); the rest is provenance a debugger can lean on. */
9
9
  export interface RationaleItem {
10
- /** Human-readable rendering — decoded text for a byte span, else a label like
11
- * "‹none›" or an operator name. Always set, so a step always reads. */
12
- text: string;
13
- /** The graph node this element is, or resolved to, when known — the handle to
14
- * point back at the exact stored fact in the content-addressed DAG. */
15
- node?: number;
16
- /** The `[start, end)` span this element occupies in its step's frame of
17
- * reference (usually the query or the answer being composed). */
18
- span?: [number, number];
19
- /** The resonance / cosine score that selected this element, when it was chosen
20
- * by similarity rather than by exact structure. */
21
- score?: number;
22
- /** A short role tag — "query", "leaf", "form", "hit", "connector", "answer",
23
- * … — naming what KIND of element this is within the step. */
24
- role?: string;
25
- /** The gist vector, only when the element fundamentally IS a vector and a
26
- * caller asked to carry it (off by default — a D-float array per item would
27
- * bury the reasoning it is meant to explain). */
28
- v?: Vec;
10
+ /** Human-readable rendering — decoded text for a byte span, else a label like
11
+ * "‹none›" or an operator name. Always set, so a step always reads. */
12
+ text: string;
13
+ /** The graph node this element is, or resolved to, when known — the handle to
14
+ * point back at the exact stored fact in the content-addressed DAG. */
15
+ node?: number;
16
+ /** The `[start, end)` span this element occupies in its step's frame of
17
+ * reference (usually the query or the answer being composed). */
18
+ span?: [number, number];
19
+ /** The resonance / cosine score that selected this element, when it was chosen
20
+ * by similarity rather than by exact structure. */
21
+ score?: number;
22
+ /** A short role tag — "query", "leaf", "form", "hit", "connector", "answer",
23
+ * … — naming what KIND of element this is within the step. */
24
+ role?: string;
25
+ /** The gist vector, only when the element fundamentally IS a vector and a
26
+ * caller asked to carry it (off by default — a D-float array per item would
27
+ * bury the reasoning it is meant to explain). */
28
+ v?: Vec;
29
29
  }
30
30
  /** A single completed act of inference — one mechanism, run once.
31
31
  *
@@ -35,30 +35,30 @@ export interface RationaleItem {
35
35
  * parent's `index` is always lower than its children's, and the two orderings
36
36
  * together give a valid topological reading of the dependency graph. */
37
37
  export interface RationaleStep {
38
- /** This step's index, assigned when the mechanism was ENTERED — a strict,
39
- * incremental ordering over the whole inference. */
40
- index: number;
41
- /** The mechanism and its enclosing mechanisms, outermost → innermost, e.g.
42
- * `["respond", "think", "recognise"]`. The last entry is this step; the
43
- * prefix is the nest of sub-mechanisms it ran inside. */
44
- mechanism: string[];
45
- /** The enclosing mechanism's step index, or -1 at the root — the NESTING edge
46
- * of the dependency graph (which step this one is a part of). */
47
- parent: number;
48
- /** The earlier steps whose OUTPUTS became this step's inputs — the DATA-FLOW
49
- * edges of the dependency graph. Defaults to the previous sibling (the step
50
- * run just before this one inside the same mechanism), or the parent when
51
- * this is the first sub-step; a mechanism that fuses several earlier results
52
- * names them all explicitly. */
53
- dependsOn: number[];
54
- /** The vector of elements handed to the mechanism (one or more). */
55
- inputs: RationaleItem[];
56
- /** The vector of elements the mechanism produced (one or more) — longer than
57
- * `inputs` when it decomposed, shorter when it combined. */
58
- outputs: RationaleItem[];
59
- /** A one-line, human account of what the mechanism did and why — the sentence
60
- * that turns the data into an explanation. */
61
- note?: string;
38
+ /** This step's index, assigned when the mechanism was ENTERED — a strict,
39
+ * incremental ordering over the whole inference. */
40
+ index: number;
41
+ /** The mechanism and its enclosing mechanisms, outermost → innermost, e.g.
42
+ * `["respond", "think", "recognise"]`. The last entry is this step; the
43
+ * prefix is the nest of sub-mechanisms it ran inside. */
44
+ mechanism: string[];
45
+ /** The enclosing mechanism's step index, or -1 at the root — the NESTING edge
46
+ * of the dependency graph (which step this one is a part of). */
47
+ parent: number;
48
+ /** The earlier steps whose OUTPUTS became this step's inputs — the DATA-FLOW
49
+ * edges of the dependency graph. Defaults to the previous sibling (the step
50
+ * run just before this one inside the same mechanism), or the parent when
51
+ * this is the first sub-step; a mechanism that fuses several earlier results
52
+ * names them all explicitly. */
53
+ dependsOn: number[];
54
+ /** The vector of elements handed to the mechanism (one or more). */
55
+ inputs: RationaleItem[];
56
+ /** The vector of elements the mechanism produced (one or more) — longer than
57
+ * `inputs` when it decomposed, shorter when it combined. */
58
+ outputs: RationaleItem[];
59
+ /** A one-line, human account of what the mechanism did and why — the sentence
60
+ * that turns the data into an explanation. */
61
+ note?: string;
62
62
  }
63
63
  /** The callback {@link Mind.respond} / {@link Mind.respondText} accept. It is
64
64
  * invoked once per completed step, AS the inference unfolds — never batched at
@@ -70,23 +70,29 @@ export declare function decodeText(bytes: Uint8Array): string;
70
70
  /** The `[start, end)` gaps of `[0, queryLen)` NOT covered by `accounted` —
71
71
  * the same union-of-spans reading think's grounding decider prices at PASS
72
72
  * per byte, exposed here so a mechanism can turn it into a human label. */
73
- export declare function unexplainedSpans(queryLen: number, accounted: ReadonlyArray<[number, number]>): Array<[number, number]>;
73
+ export declare function unexplainedSpans(
74
+ queryLen: number,
75
+ accounted: ReadonlyArray<[number, number]>,
76
+ ): Array<[number, number]>;
74
77
  /** A human-readable label for the query bytes a mechanism's `accounted`
75
78
  * spans leave unexplained — purely diagnostic (Task 2's negative evidence):
76
79
  * it never changes a candidate's weight, only what the rationale trace
77
80
  * says the mechanism left on the table. `""` when nothing is unexplained. */
78
- export declare function unexplainedLabel(query: Uint8Array, accounted: ReadonlyArray<[number, number]>): string;
81
+ export declare function unexplainedLabel(
82
+ query: Uint8Array,
83
+ accounted: ReadonlyArray<[number, number]>,
84
+ ): string;
79
85
  /** An open mechanism — the handle {@link Rationale.enter} returns. Hold it for
80
86
  * the duration of the mechanism and call {@link Scope.done} with the outputs
81
87
  * when it finishes; that emits the step and pops the nesting. */
82
88
  export interface Scope {
83
- /** The step index reserved for this mechanism at entry — pass it as an
84
- * explicit dependency of a later step that consumes this one's output. */
85
- readonly index: number;
86
- /** Close the mechanism: emit its step with these outputs and pop it off the
87
- * nesting stack. Idempotent — a second call is ignored, so a `finally` that
88
- * closes after an early return is safe. */
89
- done(outputs: RationaleItem[], note?: string): void;
89
+ /** The step index reserved for this mechanism at entry — pass it as an
90
+ * explicit dependency of a later step that consumes this one's output. */
91
+ readonly index: number;
92
+ /** Close the mechanism: emit its step with these outputs and pop it off the
93
+ * nesting stack. Idempotent — a second call is ignored, so a `finally` that
94
+ * closes after an early return is safe. */
95
+ done(outputs: RationaleItem[], note?: string): void;
90
96
  }
91
97
  /** The live tracer: a stack of open mechanisms over one {@link Mind.respond}.
92
98
  *
@@ -97,38 +103,44 @@ export interface Scope {
97
103
  * sub-steps) is the two fused. The tracer never branches the control flow; it
98
104
  * only records it. */
99
105
  export declare class Rationale {
100
- private readonly sink;
101
- private next;
102
- /** Open mechanisms, outermost first. Each frame remembers the last child it
103
- * has spawned so the next sibling can default its data-flow edge to it. */
104
- private readonly stack;
105
- /** The most recent step index emitted under each mechanism name — the handle
106
- * a later step uses to name an EARLIER mechanism as its data-flow producer
107
- * (e.g. cover depends on the latest recognise / computeExtensions). One tracer is
108
- * built per response and inference is sequential, so "most recent" is exactly
109
- * "the one that produced the inputs I am about to consume". */
110
- private readonly lastByName;
111
- constructor(sink: InspectRationale);
112
- /** The index of the most recent step with this mechanism name, or undefined if
113
- * none has run. Used to wire an explicit producer edge into {@link
114
- * Scope.done} / {@link step}'s `deps`. */
115
- lastIndex(name: string): number | undefined;
116
- /** The mechanism names currently open, outermost → innermost. */
117
- private path;
118
- /** The default data-flow edge for a step entering now: the previous sibling
119
- * inside the current mechanism, else the enclosing mechanism, else nothing
120
- * (the root). An explicit `deps` overrides this. */
121
- private defaultDeps;
122
- /** Reserve this step's index and register it as the current mechanism's most
123
- * recent child (so the NEXT sibling chains to it) and as the most recent step
124
- * of its own NAME (so a later mechanism can name it as a producer). */
125
- private reserve;
126
- private emit;
127
- /** Enter a mechanism that has sub-steps. Captures its inputs and the nesting
128
- * now; the matching {@link Scope.done} supplies the outputs when it finishes.
129
- * `deps` overrides the default data-flow edge (previous sibling / parent). */
130
- enter(name: string, inputs: RationaleItem[], deps?: number[]): Scope;
131
- /** Record a mechanism that has no sub-steps — its inputs and outputs are both
132
- * known at the call site. Returns its index, for a later step to depend on. */
133
- step(name: string, inputs: RationaleItem[], outputs: RationaleItem[], note?: string, deps?: number[]): number;
106
+ private readonly sink;
107
+ private next;
108
+ /** Open mechanisms, outermost first. Each frame remembers the last child it
109
+ * has spawned so the next sibling can default its data-flow edge to it. */
110
+ private readonly stack;
111
+ /** The most recent step index emitted under each mechanism name — the handle
112
+ * a later step uses to name an EARLIER mechanism as its data-flow producer
113
+ * (e.g. cover depends on the latest recognise / computeExtensions). One tracer is
114
+ * built per response and inference is sequential, so "most recent" is exactly
115
+ * "the one that produced the inputs I am about to consume". */
116
+ private readonly lastByName;
117
+ constructor(sink: InspectRationale);
118
+ /** The index of the most recent step with this mechanism name, or undefined if
119
+ * none has run. Used to wire an explicit producer edge into {@link
120
+ * Scope.done} / {@link step}'s `deps`. */
121
+ lastIndex(name: string): number | undefined;
122
+ /** The mechanism names currently open, outermost → innermost. */
123
+ private path;
124
+ /** The default data-flow edge for a step entering now: the previous sibling
125
+ * inside the current mechanism, else the enclosing mechanism, else nothing
126
+ * (the root). An explicit `deps` overrides this. */
127
+ private defaultDeps;
128
+ /** Reserve this step's index and register it as the current mechanism's most
129
+ * recent child (so the NEXT sibling chains to it) and as the most recent step
130
+ * of its own NAME (so a later mechanism can name it as a producer). */
131
+ private reserve;
132
+ private emit;
133
+ /** Enter a mechanism that has sub-steps. Captures its inputs and the nesting
134
+ * now; the matching {@link Scope.done} supplies the outputs when it finishes.
135
+ * `deps` overrides the default data-flow edge (previous sibling / parent). */
136
+ enter(name: string, inputs: RationaleItem[], deps?: number[]): Scope;
137
+ /** Record a mechanism that has no sub-steps — its inputs and outputs are both
138
+ * known at the call site. Returns its index, for a later step to depend on. */
139
+ step(
140
+ name: string,
141
+ inputs: RationaleItem[],
142
+ outputs: RationaleItem[],
143
+ note?: string,
144
+ deps?: number[],
145
+ ): number;
134
146
  }