@hviana/sema 0.9.0 → 0.9.2

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 (118) hide show
  1. package/AGENTS.md +7 -7
  2. package/dist/src/alu/src/index.d.ts +1 -1
  3. package/dist/src/alu/src/index.js +1 -1
  4. package/dist/src/alu/src/parser.js +2 -6
  5. package/dist/src/alu/src/resonance.d.ts +13 -0
  6. package/dist/src/alu/src/resonance.js +41 -0
  7. package/dist/src/alu/test/alu.test.js +39 -0
  8. package/dist/src/bytes.d.ts +6 -2
  9. package/dist/src/bytes.js +10 -4
  10. package/dist/src/canon.js +44 -0
  11. package/dist/src/geometry.d.ts +19 -1
  12. package/dist/src/geometry.js +125 -141
  13. package/dist/src/meter.d.ts +33 -0
  14. package/dist/src/meter.js +34 -1
  15. package/dist/src/mind/articulation.js +14 -1
  16. package/dist/src/mind/attention.d.ts +12 -0
  17. package/dist/src/mind/attention.js +44 -16
  18. package/dist/src/mind/bridge.js +3 -3
  19. package/dist/src/mind/derivation.d.ts +40 -0
  20. package/dist/src/mind/derivation.js +34 -0
  21. package/dist/src/mind/evidence.d.ts +24 -0
  22. package/dist/src/mind/evidence.js +90 -0
  23. package/dist/src/mind/graph-search.d.ts +89 -15
  24. package/dist/src/mind/graph-search.js +345 -174
  25. package/dist/src/mind/learning.js +1 -1
  26. package/dist/src/mind/mechanisms/cover.d.ts +19 -3
  27. package/dist/src/mind/mechanisms/cover.js +142 -61
  28. package/dist/src/mind/mechanisms/recall.js +10 -3
  29. package/dist/src/mind/mind.d.ts +6 -0
  30. package/dist/src/mind/mind.js +5 -2
  31. package/dist/src/mind/pipeline.d.ts +5 -1
  32. package/dist/src/mind/pipeline.js +220 -90
  33. package/dist/src/mind/primitives.d.ts +25 -5
  34. package/dist/src/mind/primitives.js +107 -44
  35. package/dist/src/mind/reasoning.d.ts +18 -4
  36. package/dist/src/mind/reasoning.js +487 -328
  37. package/dist/src/mind/recognition.js +29 -13
  38. package/dist/src/mind/resonance.js +1 -11
  39. package/dist/src/mind/traverse.d.ts +45 -5
  40. package/dist/src/mind/traverse.js +285 -8
  41. package/dist/src/mind/types.d.ts +16 -1
  42. package/dist/src/store-sqlite.d.ts +25 -0
  43. package/dist/src/store-sqlite.js +89 -1
  44. package/dist/src/store.d.ts +48 -4
  45. package/dist/src/store.js +86 -6
  46. package/docs/INDEX.md +20 -19
  47. package/docs/INVARIANTS.md +17 -16
  48. package/docs/architecture/bounded-reads.md +1 -1
  49. package/docs/architecture/caches.md +5 -4
  50. package/docs/architecture/closure.md +45 -5
  51. package/docs/architecture/cost-model.md +16 -0
  52. package/docs/architecture/evidence.md +113 -0
  53. package/docs/architecture/exact-vs-approximate.md +10 -9
  54. package/docs/architecture/factored-machinery.md +14 -13
  55. package/docs/architecture/fold-contract.md +51 -1
  56. package/docs/architecture/mechanism-market.md +21 -0
  57. package/docs/architecture/memoization.md +3 -3
  58. package/docs/architecture/meter.md +2 -1
  59. package/docs/architecture/saturation.md +12 -0
  60. package/docs/architecture/store.md +25 -2
  61. package/docs/failures/tempting-but-wrong.md +13 -2
  62. package/docs/harness/gates.md +12 -10
  63. package/docs/mechanisms/cover.md +23 -6
  64. package/jsr.json +1 -1
  65. package/package.json +1 -1
  66. package/src/alu/README.md +10 -2
  67. package/src/alu/src/index.ts +1 -0
  68. package/src/alu/src/parser.ts +6 -6
  69. package/src/alu/src/resonance.ts +42 -0
  70. package/src/alu/test/alu.test.ts +40 -0
  71. package/src/bytes.ts +13 -3
  72. package/src/canon.ts +40 -0
  73. package/src/geometry.ts +183 -154
  74. package/src/meter.ts +34 -1
  75. package/src/mind/articulation.ts +14 -2
  76. package/src/mind/attention.ts +47 -25
  77. package/src/mind/bridge.ts +3 -3
  78. package/src/mind/derivation.ts +77 -0
  79. package/src/mind/evidence.ts +107 -0
  80. package/src/mind/graph-search.ts +449 -221
  81. package/src/mind/learning.ts +1 -7
  82. package/src/mind/match.ts +1 -2
  83. package/src/mind/mechanisms/cast.ts +1 -2
  84. package/src/mind/mechanisms/cover.ts +207 -87
  85. package/src/mind/mechanisms/extraction.ts +1 -2
  86. package/src/mind/mechanisms/prefix-completion.ts +1 -1
  87. package/src/mind/mechanisms/recall.ts +17 -5
  88. package/src/mind/mechanisms/reference.ts +1 -1
  89. package/src/mind/mind.ts +9 -30
  90. package/src/mind/pipeline.ts +263 -104
  91. package/src/mind/primitives.ts +119 -43
  92. package/src/mind/reasoning.ts +611 -419
  93. package/src/mind/recognition.ts +24 -9
  94. package/src/mind/resonance.ts +2 -16
  95. package/src/mind/trace.ts +1 -1
  96. package/src/mind/traverse.ts +321 -8
  97. package/src/mind/types.ts +15 -11
  98. package/src/store-sqlite.ts +92 -1
  99. package/src/store.ts +113 -7
  100. package/test/105-derive-through-reports-its-refusal.test.mjs +8 -5
  101. package/test/106-the-join-fires.test.mjs +21 -0
  102. package/test/111-the-cover-assembly-is-counted.test.mjs +8 -5
  103. package/test/128-the-leads-somewhere-pair-agrees.test.mjs +18 -12
  104. package/test/136-the-two-named-limits.test.mjs +3 -2
  105. package/test/137-the-law-lives-once-and-below.test.mjs +21 -0
  106. package/test/148-exact-shortcuts-agree.test.mjs +188 -0
  107. package/test/149-the-closure-engine.test.mjs +138 -0
  108. package/test/150-the-join-is-output-sensitive.test.mjs +66 -0
  109. package/test/151-the-cover-pays-for-what-it-reaches.test.mjs +142 -0
  110. package/test/152-the-read-side-names-as-the-write-side.test.mjs +146 -0
  111. package/test/153-a-cheaper-bound-is-looked-at-first.test.mjs +155 -0
  112. package/test/154-the-question-names-the-step.test.mjs +281 -0
  113. package/test/24-generalization.test.mjs +32 -0
  114. package/test/36-bloom.test.mjs +53 -0
  115. package/test/37-cluster-dispersion-fusion.test.mjs +75 -0
  116. package/test/48-recognise-turn-connective.test.mjs +3 -2
  117. package/test/55-cost-meter.test.mjs +4 -4
  118. package/test/90-connector-read-cap.test.mjs +7 -7
@@ -5,7 +5,7 @@
5
5
  import { addInto, normalize, zeros } from "../vec.js";
6
6
  import { bindSeat, companySignature, isChunk } from "../sema.js";
7
7
  import { changedNodes } from "./types.js";
8
- import { inputBytes, perceiveDeposit, resolve, } from "./primitives.js";
8
+ import { inputBytes, perceiveDeposit, resolve } from "./primitives.js";
9
9
  import { canonicalWindows, leafIdPrefix } from "./canonical.js";
10
10
  import { rItem, rNode } from "./trace.js";
11
11
  import { hubBound } from "./traverse.js";
@@ -1,6 +1,22 @@
1
1
  import type { MindContext } from "../types.js";
2
- import type { Site } from "../graph-search.js";
2
+ import type { ConceptLicence, ConnectorLicence, Site } from "../graph-search.js";
3
3
  import type { PipelineMechanism } from "../pipeline-mechanism.js";
4
- export declare function resolveConcepts(ctx: MindContext, sites: Site[]): Promise<Map<number, number>>;
5
- export declare function resolveConnectors(ctx: MindContext, sites: ReadonlyArray<Site>, query?: Uint8Array): Promise<Map<string, Uint8Array>>;
4
+ /** The concept hops the cover may take, OFFERED up front and looked up only
5
+ * when the search asks (see {@link Licence}): every recognised form with no
6
+ * continuation of its own may borrow a halo sibling's. */
7
+ export interface CoverConcepts extends ConceptLicence {
8
+ /** Look up the asked forms' concept targets not yet granted. */
9
+ grant(nodes: Iterable<number>): Promise<void>;
10
+ }
11
+ export declare function offerConcepts(ctx: MindContext, sites: ReadonlyArray<Site>): CoverConcepts;
12
+ /** The connectors the cover may splice, OFFERED up front and BRIDGED only when
13
+ * the search asks (see {@link ConnectorLicence}): every pair a learnt whole
14
+ * could run together — two touching sites, each side as itself or as its
15
+ * answer, in both orders — and, when three or more answers are recognised, the
16
+ * first answer to each later one (the N-ary whole). */
17
+ export interface CoverConnectors extends ConnectorLicence {
18
+ /** Bridge the asked pairs not yet granted. */
19
+ grant(keys: Iterable<string>): Promise<void>;
20
+ }
21
+ export declare function offerConnectors(ctx: MindContext, sites: ReadonlyArray<Site>, query?: Uint8Array): CoverConnectors;
6
22
  export declare const coverMechanism: PipelineMechanism;
@@ -9,38 +9,45 @@
9
9
  // near-zero-cost incumbent that prunes the other mechanisms through the
10
10
  // ordinary admissible-floor check, with no extension special-case anywhere.
11
11
  import { read, resolve } from "../primitives.js";
12
- import { guidedFirst, hubBound } from "../traverse.js";
12
+ import { guidedFirst, hubBound, namedContinuations, scaffoldSpans, } from "../traverse.js";
13
13
  import { conceptHop } from "../match.js";
14
14
  import { bridge } from "../resonance.js";
15
15
  import { liftAnswer, liftedScaffolding, segRestatesQuery } from "../types.js";
16
16
  import { decodeText } from "../rationale.js";
17
17
  import { insideAnsweredTurn, restates } from "../derivation.js";
18
18
  import { rItem, rNode, traceDerivation } from "../trace.js";
19
- // ── Concept / connector pre-resolution ──────────────────────────────────────
20
- export async function resolveConcepts(ctx, sites) {
21
- const target = new Map();
22
- const visited = new Set();
19
+ export function offerConcepts(ctx, sites) {
20
+ const offered = new Set();
23
21
  for (const { payload: n } of sites) {
24
- if (visited.has(n))
25
- continue;
26
- visited.add(n);
27
- if (ctx.store.hasNext(n))
28
- continue;
29
- const hop = await conceptHop(ctx, n);
30
- if (hop !== null)
31
- target.set(n, hop);
32
- }
33
- if (target.size > 0) {
34
- ctx.trace?.step("resolveConcepts", [...target.keys()].map((n) => rNode(ctx, n, "edgeless-form")), [...target.values()].map((h) => rNode(ctx, h, "concept-sibling")), "borrow a synonym's continuation edge for each edge-less form (a concept/halo hop)");
22
+ if (!offered.has(n) && !ctx.store.hasNext(n))
23
+ offered.add(n);
35
24
  }
36
- return target;
25
+ const granted = new Map();
26
+ return {
27
+ offered,
28
+ granted,
29
+ asked: new Set(),
30
+ async grant(nodes) {
31
+ const found = [];
32
+ for (const n of nodes) {
33
+ if (granted.has(n))
34
+ continue;
35
+ const hop = await conceptHop(ctx, n);
36
+ granted.set(n, hop);
37
+ if (hop !== null)
38
+ found.push([n, hop]);
39
+ }
40
+ if (found.length > 0) {
41
+ ctx.trace?.step("resolveConcepts", found.map(([n]) => rNode(ctx, n, "edgeless-form")), found.map(([, h]) => rNode(ctx, h, "concept-sibling")), "borrow a synonym's continuation edge for each edge-less form the search reached (a concept/halo hop)");
42
+ }
43
+ },
44
+ };
37
45
  }
38
- export async function resolveConnectors(ctx, sites, query) {
39
- const links = new Map();
46
+ export function offerConnectors(ctx, sites, query) {
40
47
  const answerOf = (n) => guidedFirst(ctx, n) ?? n;
41
48
  // A site's continuation already present elsewhere in the query is stale
42
49
  // transcript evidence: cover still needs the site for structural context,
43
- // but liftAnswer will trim that continuation as already answered. Building
50
+ // but liftAnswer will trim that continuation as already answered. Offering
44
51
  // pairwise/n-ary bridges for it can only create connectors that are later
45
52
  // discarded — a semantically neutral gate (it removes work whose product
46
53
  // liftAnswer throws away), and a cumulative (multi-turn) query is exactly
@@ -81,15 +88,7 @@ export async function resolveConnectors(ctx, sites, query) {
81
88
  return restates(query, bytes, 0);
82
89
  });
83
90
  });
84
- const bridgePair = async (l, r) => {
85
- if (l === r || links.has(l + "," + r))
86
- return;
87
- if (ctx.meter)
88
- ctx.meter.coverBridges++;
89
- const link = await bridge(ctx, read(ctx, l), read(ctx, r));
90
- if (link !== null)
91
- links.set(l + "," + r, link);
92
- };
91
+ const pairwise = new Set();
93
92
  for (let i = 0; i + 1 < ordered.length; i++) {
94
93
  if (ordered[i].end !== ordered[i + 1].start)
95
94
  continue;
@@ -97,8 +96,10 @@ export async function resolveConnectors(ctx, sites, query) {
97
96
  const rights = [ordered[i + 1].payload, answerOf(ordered[i + 1].payload)];
98
97
  for (const l of new Set(lefts)) {
99
98
  for (const r of new Set(rights)) {
100
- await bridgePair(l, r);
101
- await bridgePair(r, l);
99
+ if (l === r)
100
+ continue;
101
+ pairwise.add(l + "," + r);
102
+ pairwise.add(r + "," + l);
102
103
  }
103
104
  }
104
105
  }
@@ -111,37 +112,61 @@ export async function resolveConnectors(ctx, sites, query) {
111
112
  seenN.add(node);
112
113
  orderedNodes.push({ node, bytes: read(ctx, node) });
113
114
  }
115
+ const nary = new Map();
114
116
  if (orderedNodes.length >= 3) {
115
117
  const first = orderedNodes[0];
116
118
  const W = ctx.space.maxGroup;
117
119
  let middleBytes = 0; // Σ bytes of the answers BETWEEN first and m-th
118
120
  for (let m = 1; m < orderedNodes.length; m++) {
119
- const key = first.node + "," + orderedNodes[m].node;
120
- if (links.has(key)) {
121
- middleBytes += orderedNodes[m].bytes.length;
122
- continue;
123
- }
124
121
  // The N-ary interior legitimately holds every intermediate answer
125
122
  // plus one W-quantum of glue per joint — pass that allowance so the
126
- // bridge's phrase-scale cap admits the whole learnt run.
127
- const allowance = middleBytes + (m + 1) * W;
128
- if (ctx.meter) {
129
- ctx.meter.coverBridges++;
130
- ctx.meter.coverAllowanceBytes += allowance;
131
- }
132
- const interior = await bridge(ctx, first.bytes, orderedNodes[m].bytes, allowance);
133
- if (interior !== null)
134
- links.set(key, interior);
123
+ // bridge's phrase-scale cap admits the whole learnt run. Asked only
124
+ // when the pairwise bridge of the same key (if offered) found nothing.
125
+ nary.set(first.node + "," + orderedNodes[m].node, {
126
+ left: first.bytes,
127
+ right: orderedNodes[m].bytes,
128
+ allowance: middleBytes + (m + 1) * W,
129
+ });
135
130
  middleBytes += orderedNodes[m].bytes.length;
136
131
  }
137
132
  }
138
- if (links.size > 0) {
139
- ctx.trace?.step("resolveConnectors", ordered.map((s) => rItem(read(ctx, s.payload), "answer", s.payload)), [...links.entries()].map(([pair, bytes]) => ({
140
- text: `${pair}: "${decodeText(bytes)}"`,
141
- role: "connector",
142
- })), "the bytes the graph splices between adjacent answers (asked of the gist space)");
143
- }
144
- return links;
133
+ const granted = new Map();
134
+ return {
135
+ offered: new Set([...pairwise, ...nary.keys()]),
136
+ granted,
137
+ asked: new Set(),
138
+ async grant(keys) {
139
+ const found = [];
140
+ for (const key of keys) {
141
+ if (granted.has(key))
142
+ continue;
143
+ let link = null;
144
+ if (pairwise.has(key)) {
145
+ const comma = key.indexOf(",");
146
+ if (ctx.meter)
147
+ ctx.meter.coverBridges++;
148
+ link = await bridge(ctx, read(ctx, Number(key.slice(0, comma))), read(ctx, Number(key.slice(comma + 1))));
149
+ }
150
+ const whole = nary.get(key);
151
+ if (link === null && whole !== undefined) {
152
+ if (ctx.meter) {
153
+ ctx.meter.coverBridges++;
154
+ ctx.meter.coverAllowanceBytes += whole.allowance;
155
+ }
156
+ link = await bridge(ctx, whole.left, whole.right, whole.allowance);
157
+ }
158
+ granted.set(key, link);
159
+ if (link !== null)
160
+ found.push([key, link]);
161
+ }
162
+ if (found.length > 0) {
163
+ ctx.trace?.step("resolveConnectors", ordered.map((s) => rItem(read(ctx, s.payload), "answer", s.payload)), found.map(([pair, bytes]) => ({
164
+ text: `${pair}: "${decodeText(bytes)}"`,
165
+ role: "connector",
166
+ })), "the bytes the graph splices between adjacent answers the search reached (asked of the gist space)");
167
+ }
168
+ },
169
+ };
145
170
  }
146
171
  // ── Pipeline mechanism ──────────────────────────────────────────────────────
147
172
  export const coverMechanism = {
@@ -154,7 +179,7 @@ export const coverMechanism = {
154
179
  const { rec, computed } = pre;
155
180
  // Masking: computed spans are authoritative. Remove recognised sites
156
181
  // that overlap any computed span before building the cover search.
157
- const sites = computed.length === 0
182
+ let sites = computed.length === 0
158
183
  ? rec.sites
159
184
  : rec.sites.filter((s) => !computed.some((u) => s.start < u.j && u.i < s.end));
160
185
  if (computed.length > 0 && sites.length < rec.sites.length) {
@@ -166,11 +191,40 @@ export const coverMechanism = {
166
191
  s.end,
167
192
  ])), "a computation always wins: recognised forms overlapping a computed span are dropped");
168
193
  }
194
+ // A FRAGMENT ANSWERS OTHER QUESTIONS. A recognised form that sits inside
195
+ // other forms (it has structural parents or containers) holds continuations
196
+ // because the forms it is a piece of were asked — suffix inheritance gives
197
+ // `f death` the answer of every `… place of death` question. Choosing one of
198
+ // several such continuations by popularity voices some other question's
199
+ // answer, and the cover used to account the fragment's bytes as explained by
200
+ // it. A fragment with several continuations leads somewhere FOR THIS
201
+ // QUESTION only when the question names one (traverse.ts, the exact tier).
202
+ // A form that is (nearly) the whole question is not a piece of it: the
203
+ // question says nothing beyond it, so its continuations answer THIS question.
204
+ const asked = ctx._edgeAsked;
205
+ const W0 = ctx.space.maxGroup;
206
+ const leading = asked === null
207
+ ? sites
208
+ : sites.filter((s) => query.length - (s.end - s.start) < W0 ||
209
+ !(ctx.store.hasParents(s.payload) ||
210
+ ctx.store.hasContainers(s.payload)) ||
211
+ ctx.store.nextFirst(s.payload, 2).length < 2 ||
212
+ namedContinuations(ctx, s.payload, asked) !== null);
213
+ if (leading.length < sites.length) {
214
+ if (ctx.meter) {
215
+ ctx.meter.unaskedFragments += sites.length - leading.length;
216
+ }
217
+ ctx.trace?.step("unaskedFragments", sites.filter((s) => !leading.includes(s)).map((s) => rItem(query.subarray(s.start, s.end), "fragment", s.payload, [
218
+ s.start,
219
+ s.end,
220
+ ])), [], "a piece of other forms whose continuations the question names none of — it answers other questions");
221
+ sites = leading;
222
+ }
169
223
  if (sites.length === 0 && computed.length === 0)
170
224
  return [];
171
225
  const connectors = ctx.meter
172
- ? await ctx.meter.time("cover.resolveConnectors", () => resolveConnectors(ctx, sites, query))
173
- : await resolveConnectors(ctx, sites, query);
226
+ ? ctx.meter.timeSync("cover.offerConnectors", () => offerConnectors(ctx, sites, query))
227
+ : offerConnectors(ctx, sites, query);
174
228
  let splits = rec.splits;
175
229
  if (computed.length > 0) {
176
230
  splits = new Set(rec.splits);
@@ -180,13 +234,11 @@ export const coverMechanism = {
180
234
  }
181
235
  }
182
236
  const concepts = ctx.meter
183
- ? await ctx.meter.time("cover.resolveConcepts", () => resolveConcepts(ctx, sites))
184
- : await resolveConcepts(ctx, sites);
237
+ ? ctx.meter.timeSync("cover.offerConcepts", () => offerConcepts(ctx, sites))
238
+ : offerConcepts(ctx, sites);
185
239
  const coverDeps = [
186
240
  ctx.trace?.lastIndex("recognise"),
187
241
  ctx.trace?.lastIndex("computeExtensions"),
188
- ctx.trace?.lastIndex("resolveConcepts"),
189
- ctx.trace?.lastIndex("resolveConnectors"),
190
242
  ].filter((x) => x !== undefined);
191
243
  // Convert ComputedSpan[] to ComputedResult[] for the graph search.
192
244
  const computedResults = computed.map((u) => ({
@@ -202,7 +254,27 @@ export const coverMechanism = {
202
254
  ])),
203
255
  ...computedResults.map((u) => rItem(u.bytes, "computed")),
204
256
  ], coverDeps.length ? coverDeps : undefined);
205
- const solved = ctx.search.cover(query.length, sites, concepts, rec.leaves, splits, undefined, connectors, computedResults, ctx.trace ? (steps) => traceDerivation(ctx, steps) : undefined);
257
+ // COVER, GRANT WHAT IT ASKED, COVER AGAIN — until a cover asks for nothing
258
+ // (see Licence in graph-search.ts). Only the final cover's derivations reach the
259
+ // rationale; a provisional one is superseded, not part of the answer.
260
+ let derivations = [];
261
+ let solved;
262
+ for (;;) {
263
+ derivations = [];
264
+ solved = ctx.search.cover(query.length, sites, concepts, rec.leaves, splits, undefined, connectors, computedResults, ctx.trace ? (steps) => derivations.push(steps) : undefined);
265
+ if (concepts.asked.size === 0 && connectors.asked.size === 0)
266
+ break;
267
+ const grant = async () => {
268
+ await concepts.grant([...concepts.asked]);
269
+ await connectors.grant([...connectors.asked]);
270
+ };
271
+ if (ctx.meter)
272
+ await ctx.meter.time("cover.grant", grant);
273
+ else
274
+ await grant();
275
+ }
276
+ for (const steps of derivations)
277
+ traceDerivation(ctx, steps);
206
278
  const segs = solved && solved.segs;
207
279
  tCover?.done(segs === null
208
280
  ? []
@@ -235,8 +307,17 @@ export const coverMechanism = {
235
307
  // restated span contributes nothing to the composed answer, so it must
236
308
  // not be priced as if it did (PASS-carried bytes are priced already;
237
309
  // the diagnostic label reflects the same distinction).
310
+ //
311
+ // …and a span made of nothing but corpus-global scaffolding names nothing:
312
+ // every window of it is a piece of more than √N stored forms, so the form
313
+ // recognised there — the song `What`, in the trained store — is one of
314
+ // thousands it could be. Voicing that form's fact explains no byte the
315
+ // asker owes: measured, `What country is Jerry Bock a citizen of?` was won
316
+ // by `The performer of What is Melinda Marx.` glued onto the right fact.
317
+ const scaffold = scaffoldSpans(ctx, query);
238
318
  const accounted = segs
239
- .filter((s) => s.rec && !segRestatesQuery(s, query, query.length, W))
319
+ .filter((s) => s.rec && !segRestatesQuery(s, query, query.length, W) &&
320
+ !scaffold.some(([a, b]) => a <= s.i && s.j <= b))
240
321
  .map((s) => [s.i, s.j]);
241
322
  return [{
242
323
  bytes: composed,
@@ -7,7 +7,7 @@ import { cosine } from "../../vec.js";
7
7
  import { consensusFloor, dominates, identityBar, reachThreshold, significanceBar, } from "../../geometry.js";
8
8
  import { gistOf, read, resolve } from "../primitives.js";
9
9
  import { indexOf } from "../../bytes.js";
10
- import { allWindowsAreScaffolding, corpusN, hubBound } from "../traverse.js";
10
+ import { allWindowsAreScaffolding, askedEvidence, corpusN, guidedFirst, hubBound, } from "../traverse.js";
11
11
  import { follow, project, reverseContext, voicesDisplacedFiller, } from "../match.js";
12
12
  import { CONCEPT, STEP } from "../graph-search.js";
13
13
  import { restates as lawRestates } from "../derivation.js";
@@ -32,7 +32,6 @@ export async function recallByResonance(ctx, query, pre) {
32
32
  ...(complete ? { complete } : {}),
33
33
  };
34
34
  };
35
- const k = pre.k;
36
35
  const queryGist = pre.guide;
37
36
  // 0. Exact self-match — content-addressed, deterministic.
38
37
  const qId = pre.queryResolved;
@@ -103,7 +102,15 @@ export async function recallByResonance(ctx, query, pre) {
103
102
  // conversation reads as if it were the next thing to say.
104
103
  if (g !== null && g.length > 0 &&
105
104
  !lawRestates(query, g, 0, { proper: true })) {
106
- return ground(g, "argument binding — the query's sole edge-source constituent, continuation followed", [[arg.start, arg.end]], STEP);
105
+ // EVIDENCE TRAVELS: when the question NAMED the continuation followed
106
+ // (traverse.ts, the exact tier — `Who is the father of Frederick II?`
107
+ // witnesses the father fact's own question `Frederick II father`), the
108
+ // spans that named it are explained too, not only the argument.
109
+ const hop = guidedFirst(ctx, arg.payload);
110
+ const named = hop === undefined
111
+ ? []
112
+ : askedEvidence(ctx, arg.payload, hop);
113
+ return ground(g, "argument binding — the query's sole edge-source constituent, continuation followed", [[arg.start, arg.end], ...named], STEP);
107
114
  }
108
115
  }
109
116
  }
@@ -47,6 +47,7 @@ export interface Conversation {
47
47
  readonly id: number;
48
48
  }
49
49
  import type { AttentionRead, MindContext, Recognition } from "./types.js";
50
+ import type { WindowIndex } from "./evidence.js";
50
51
  export type { AnchorRejectionReason, ClimbConsensusData, ConsensusAnchorTrace, ConsensusReachTrace, ConsensusRegionTrace, CrossRegionTier, JunctionVoteTrace, RegionOutcome, } from "./attention.js";
51
52
  export type { AncestorReach, SaturationReason, SaturationStop, } from "./types.js";
52
53
  import { type CostReport, Meter } from "../meter.js";
@@ -165,6 +166,11 @@ export declare class Mind implements MindContext {
165
166
  * first-edge behaviour) and the reverse projection uses it for
166
167
  * reverse-recall disambiguation via `chooseAmong`. */
167
168
  _edgeGuide: Vec | null;
169
+ /** See {@link MindContext._edgeAsked}. */
170
+ _edgeAsked: {
171
+ bytes: Uint8Array;
172
+ index: WindowIndex;
173
+ } | null;
168
174
  /** Per-response memo of {@link chooseNext} picks — ensures every mechanism
169
175
  * of a single response follows the SAME continuation for each ambiguous
170
176
  * context node. */
@@ -11,14 +11,14 @@
11
11
  import { makeKeyring, rng, setVecConfig } from "../vec.js";
12
12
  import { sampleCorpus, searchCorpus } from "./corpus.js";
13
13
  import { Alphabet } from "../alphabet.js";
14
- import { contentFoldIncremental, reachThreshold, } from "../geometry.js";
14
+ import { contentFoldIncremental, reachThreshold } from "../geometry.js";
15
15
  import { keyEnds } from "./canonical.js";
16
16
  import { BoundedMap } from "../store.js";
17
17
  import { SQliteStore } from "../store-sqlite.js";
18
18
  import { resolveConfig } from "../config.js";
19
19
  import { canonHash, textCanon, textEdgeTrim } from "../canon.js";
20
20
  import { bytesEqual, concat2 } from "../bytes.js";
21
- import { GraphSearch, } from "./graph-search.js";
21
+ import { GraphSearch } from "./graph-search.js";
22
22
  import { Alu } from "../alu/src/index.js";
23
23
  import { decodeText, Rationale, } from "./rationale.js";
24
24
  import { canonResolve as canonResolveImpl, gistOf, inputBytes, perceive as perceiveImpl, perceiveKey, resolve as resolveImpl, } from "./primitives.js";
@@ -104,6 +104,8 @@ export class Mind {
104
104
  * first-edge behaviour) and the reverse projection uses it for
105
105
  * reverse-recall disambiguation via `chooseAmong`. */
106
106
  _edgeGuide = null;
107
+ /** See {@link MindContext._edgeAsked}. */
108
+ _edgeAsked = null;
107
109
  /** Per-response memo of {@link chooseNext} picks — ensures every mechanism
108
110
  * of a single response follows the SAME continuation for each ambiguous
109
111
  * context node. */
@@ -334,6 +336,7 @@ export class Mind {
334
336
  this.canon = null;
335
337
  this.canonMemo = null;
336
338
  this._edgeGuide = null;
339
+ this._edgeAsked = null;
337
340
  this._edgeChoice.clear();
338
341
  }
339
342
  /** Shared response core — the one path from bytes to voiced answer.
@@ -1,6 +1,6 @@
1
1
  import type { MindContext } from "./types.js";
2
2
  import { type PipelineMechanism } from "./pipeline-mechanism.js";
3
- export { resolveConcepts, resolveConnectors } from "./mechanisms/cover.js";
3
+ export { offerConcepts, offerConnectors } from "./mechanisms/cover.js";
4
4
  export { aluToMechanism } from "./mechanisms/alu.js";
5
5
  export declare const defaultMechanisms: PipelineMechanism[];
6
6
  export type Provenance = "cast" | "join" | "cover" | "extract" | "reference" | "recall" | "recall-echo" | "prefix";
@@ -60,6 +60,10 @@ export interface RegimePredictionData {
60
60
  * CAST's floor) — the bar the incumbent must sit at or below for the
61
61
  * consensus climb to be skipped. */
62
62
  climbFloorGrade: number;
63
+ /** The lowest grade reached by a mechanism run AHEAD of a dearer one (see
64
+ * the grounding loop), when one ran and grounded: a bound below
65
+ * `climbFloorGrade` makes the regime retrieval whatever the incumbent. */
66
+ boundGrade?: number;
63
67
  }
64
68
  /** Think: a single lightest-derivation exploration of the Sema graph.
65
69
  *