@hviana/sema 0.7.9 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/AGENTS.md +22 -1
  2. package/DATASETS.md +1 -1
  3. package/dist/example/train_base/config.js +2 -2
  4. package/dist/example/train_base/corpora/massive.js +1 -1
  5. package/dist/example/train_base/readers.js +1 -1
  6. package/dist/src/geometry.d.ts +10 -10
  7. package/dist/src/geometry.js +25 -24
  8. package/dist/src/meter.d.ts +4 -12
  9. package/dist/src/meter.js +14 -14
  10. package/dist/src/mind/attention.js +12 -12
  11. package/dist/src/mind/bridge.d.ts +8 -8
  12. package/dist/src/mind/bridge.js +33 -32
  13. package/dist/src/mind/graph-search.d.ts +0 -8
  14. package/dist/src/mind/graph-search.js +38 -25
  15. package/dist/src/mind/junction.d.ts +1 -1
  16. package/dist/src/mind/junction.js +8 -8
  17. package/dist/src/mind/learning.js +36 -35
  18. package/dist/src/mind/match.js +14 -13
  19. package/dist/src/mind/mechanisms/cover.js +13 -12
  20. package/dist/src/mind/mechanisms/prefix-completion.js +24 -24
  21. package/dist/src/mind/mechanisms/recall.js +38 -40
  22. package/dist/src/mind/mechanisms/reference.js +16 -16
  23. package/dist/src/mind/mind.d.ts +6 -7
  24. package/dist/src/mind/pipeline-mechanism.d.ts +10 -8
  25. package/dist/src/mind/pipeline-mechanism.js +25 -21
  26. package/dist/src/mind/pipeline.d.ts +9 -9
  27. package/dist/src/mind/pipeline.js +24 -23
  28. package/dist/src/mind/primitives.d.ts +5 -5
  29. package/dist/src/mind/primitives.js +5 -5
  30. package/dist/src/mind/recognition.d.ts +14 -13
  31. package/dist/src/mind/recognition.js +53 -38
  32. package/dist/src/mind/resonance.js +21 -21
  33. package/dist/src/mind/traverse.d.ts +54 -52
  34. package/dist/src/mind/traverse.js +74 -72
  35. package/dist/src/mind/types.d.ts +4 -4
  36. package/dist/src/store.d.ts +12 -12
  37. package/dist/src/store.js +12 -12
  38. package/docs/INDEX.md +2 -2
  39. package/docs/architecture/exact-vs-approximate.md +2 -1
  40. package/docs/architecture/fold-contract.md +1 -1
  41. package/docs/failures/tempting-but-wrong.md +2 -3
  42. package/docs/harness/gates.md +7 -7
  43. package/example/train_base/config.ts +2 -2
  44. package/example/train_base/corpora/massive.ts +1 -1
  45. package/example/train_base/readers.ts +1 -1
  46. package/jsr.json +1 -1
  47. package/package.json +1 -1
  48. package/src/geometry.ts +25 -24
  49. package/src/meter.ts +14 -14
  50. package/src/mind/attention.ts +12 -12
  51. package/src/mind/bridge.ts +33 -32
  52. package/src/mind/graph-search.ts +43 -24
  53. package/src/mind/junction.ts +8 -8
  54. package/src/mind/learning.ts +36 -35
  55. package/src/mind/match.ts +20 -19
  56. package/src/mind/mechanisms/cover.ts +13 -12
  57. package/src/mind/mechanisms/prefix-completion.ts +24 -24
  58. package/src/mind/mechanisms/recall.ts +38 -40
  59. package/src/mind/mechanisms/reference.ts +16 -16
  60. package/src/mind/mind.ts +6 -7
  61. package/src/mind/pipeline-mechanism.ts +25 -21
  62. package/src/mind/pipeline.ts +33 -32
  63. package/src/mind/primitives.ts +5 -5
  64. package/src/mind/recognition.ts +51 -36
  65. package/src/mind/resonance.ts +21 -21
  66. package/src/mind/traverse.ts +74 -72
  67. package/src/mind/types.ts +4 -4
  68. package/src/store.ts +20 -20
  69. package/test/08-storage.test.mjs +1 -1
  70. package/test/35-prefix-edge.test.mjs +1 -1
  71. package/test/40-choosenext-scale-guard.test.mjs +16 -17
  72. package/test/46-recognise-multibyte-edge.test.mjs +33 -0
  73. package/test/56-bridge-identity-admission.test.mjs +6 -6
  74. package/test/70-prefix-completion.test.mjs +4 -3
  75. package/test/72-prefix-candidate-supply.test.mjs +3 -3
  76. package/test/73-scaffolding-only-bridge-abstains.test.mjs +6 -6
  77. package/test/75-multiturn-context-optimisation.test.mjs +5 -5
  78. package/test/84-composed-answer-honesty.test.mjs +5 -6
  79. package/test/88-dependency-footprint.test.mjs +1 -1
  80. package/test/89-completion-recursion.test.mjs +17 -14
  81. package/test/90-connector-read-cap.test.mjs +10 -8
  82. package/test/93-regime-prediction.test.mjs +10 -10
  83. package/test/94-cross-region-budget.test.mjs +2 -2
  84. package/test/95-wide-resonance-removed.test.mjs +8 -7
  85. package/test/96-bytes-walk-termination.test.mjs +3 -3
  86. package/test/99-fact-join.test.mjs +38 -0
@@ -268,7 +268,8 @@ function constituentSketch(ctx, id, k) {
268
268
  pool.push(g);
269
269
  }
270
270
  }
271
- // Bottom-k by identity, then by id so ties are corpus-determined (§2.1).
271
+ // Bottom-k by identity, then by id so ties are corpus-determined
272
+ // (determinism.md).
272
273
  pool.sort((a, b) => (unitPriority(a) - unitPriority(b)) || (a - b));
273
274
  const seen = new Set();
274
275
  out = [];
@@ -331,15 +332,15 @@ function constituentSketch(ctx, id, k) {
331
332
  * terms unique to that partner, which dilute but never mislead; the shared
332
333
  * units contribute the signal.
333
334
  *
334
- * HUBS ARE THE ONE EXCLUSION, read LIMITed as `parentsFirst(n, bound+1)` —
335
- * the store's own exact hub-or-not probe (a result longer than the bound
336
- * means MORE than the bound), never a fan-in-sized read. A constituent with
337
- * more than √N structural parents is scaffolding by §8.8's bound: " is ",
338
- * "the ". Superposing it would put a term shared by every deposit into every
339
- * profile, ALL halos would correlate, and the concept threshold's null model
340
- * (unrelated halos at 0 ± 1/√D) that §4.1's hygiene note protects would
341
- * collapse. It is still DESCENDED into — a hub chunk can contain a rare
342
- * unit — but contributes nothing itself.
335
+ * HUBS ARE THE ONE EXCLUSION, read LIMITed as `parentsFirst(n, bound+1)` — the
336
+ * store's own exact hub-or-not probe (a result longer than the bound means MORE
337
+ * than the bound), never a fan-in-sized read. A constituent with more than √N
338
+ * structural parents is scaffolding by bounded-reads.md's bound: " is ", "the
339
+ * ". Superposing it would put a term shared by every deposit into every
340
+ * profile, ALL halos would correlate, and the concept threshold's null model
341
+ * (unrelated halos at 0 ± 1/√D) that halo-sketch.md's hygiene note protects
342
+ * would collapse. It is still DESCENDED into — a hub chunk can contain a rare
343
+ * unit — but contributes nothing itself.
343
344
  *
344
345
  * Byte atoms are skipped in BOTH representations (a negative id and a stored
345
346
  * kid-less node): an atom's fan-in is the alphabet's, so it can only ever
@@ -349,32 +350,32 @@ function constituentSketch(ctx, id, k) {
349
350
  * analogy strength 0.3636 -> 0.2004, "no halo-tier company evidence",
350
351
  * test/29 C1).
351
352
  *
352
- * A FUNCTION OF THE NODE AND THE CORPUS STATE — stated precisely, because
353
- * the weaker claim is the true one. The constituents are read from the
354
- * STORE, never from the depositing tree's id map: that map holds only the
355
- * nodes THIS deposit newly interned, so a partner met a second time yielded a
356
- * profile missing exactly those constituents, the exact-partner case fell
357
- * from cosine 1 to 1/√(1+k), and the geometry stopped meaning anything.
358
- * Reading the store fixes that. It does NOT make the profile permanent: the
359
- * hub test reads fan-in against √N and both grow with training, so a partner
360
- * poured early and again late can profile differently. That residue is
361
- * confined to the hub EXCLUSION — which terms are dropped as scaffolding —
362
- * and never to which units are found, because the descent itself is now
363
- * order-independent. The drift is one-directional and benign: a term can
364
- * only ever go from contributing to being excluded as scaffolding. Replay of
365
- * a fixed training order is bit-identical, so §2.1 holds. What must not be
366
- * claimed is that a node's profile is fixed for all time; it is fixed given
367
- * the corpus that has been seen.
353
+ * A FUNCTION OF THE NODE AND THE CORPUS STATE — stated precisely, because the
354
+ * weaker claim is the true one. The constituents are read from the STORE, never
355
+ * from the depositing tree's id map: that map holds only the nodes THIS deposit
356
+ * newly interned, so a partner met a second time yielded a profile missing
357
+ * exactly those constituents, the exact-partner case fell from cosine 1 to
358
+ * 1/√(1+k), and the geometry stopped meaning anything. Reading the store fixes
359
+ * that. It does NOT make the profile permanent: the hub test reads fan-in
360
+ * against √N and both grow with training, so a partner poured early and again
361
+ * late can profile differently. That residue is confined to the hub EXCLUSION —
362
+ * which terms are dropped as scaffolding — and never to which units are found,
363
+ * because the descent itself is now order-independent. The drift is
364
+ * one-directional and benign: a term can only ever go from contributing to
365
+ * being excluded as scaffolding. Replay of a fixed training order is
366
+ * bit-identical, so determinism.md holds. What must not be claimed is that a
367
+ * node's profile is fixed for all time; it is fixed given the corpus that has
368
+ * been seen.
368
369
  *
369
- * THE NULL MODEL IS OTHERWISE UNTOUCHED (§4.1). Every term is still a seeded
370
- * function of a NODE IDENTITY, never a gist, so no byte-similarity between
371
- * partners can leak content similarity into distributional similarity. The
372
- * result is normalized, so ONE episode still pours ONE unit of mass:
373
- * {@link Store.haloMass} keeps counting episodes and every mass-based
374
- * reading is unchanged. Two partners sharing j of k discriminating
375
- * constituents meet at j/(1+k) — graded evidence, above the 1/√D noise floor
376
- * and below conceptThreshold until the overlap is most of the content, which
377
- * is the semantics "same company" should have.
370
+ * THE NULL MODEL IS OTHERWISE UNTOUCHED (halo-sketch.md). Every term is still a
371
+ * seeded function of a NODE IDENTITY, never a gist, so no byte-similarity
372
+ * between partners can leak content similarity into distributional similarity.
373
+ * The result is normalized, so ONE episode still pours ONE unit of mass: {@link
374
+ * Store.haloMass} keeps counting episodes and every mass-based reading is
375
+ * unchanged. Two partners sharing j of k discriminating constituents meet at
376
+ * j/(1+k) — graded evidence, above the 1/√D noise floor and below
377
+ * conceptThreshold until the overlap is most of the content, which is the
378
+ * semantics "same company" should have.
378
379
  *
379
380
  * Bounded: at most {@link PROFILE_VISITS} constituents are classified, each
380
381
  * by ONE LIMITed structural-parent read, so a pour costs O(1) reads in the
@@ -934,24 +934,25 @@ export async function project(ctx, id, guide) {
934
934
  }
935
935
  // ── The span-shape family ───────────────────────────────────────────────────
936
936
  //
937
- // "Is this answer drawn from this context?" has TWO formally distinct
938
- // readings, and the pair plus the anchor classifier built on them are SHARED
939
- // machinery — extraction proposes span-shaped exemplars with them, the
940
- // shared `Precomputed.spanShapedOf` container computes them, and fusion
941
- // (reasoning.ts) gates on the strict one. They lived inside
942
- // mechanisms/extraction.ts, so `pipeline-mechanism.ts` and `reasoning.ts`
943
- // both had to import back OUT of a specific mechanism — an inversion the
944
- // mechanism market forbids (AGENTS §2.6: the shared contract may not depend
945
- // on any one mechanism; §2.5: a shared matcher belongs to this family, never
946
- // to a mechanism's private helpers). Deleting extraction must not break the
947
- // shared container, so they live here.
937
+ // "Is this answer drawn from this context?" has TWO formally distinct readings,
938
+ // and the pair plus the anchor classifier built on them are SHARED machinery —
939
+ // extraction proposes span-shaped exemplars with them, the shared
940
+ // `Precomputed.spanShapedOf` container computes them, and fusion (reasoning.ts)
941
+ // gates on the strict one. They lived inside mechanisms/extraction.ts, so
942
+ // `pipeline-mechanism.ts` and `reasoning.ts` both had to import back OUT of a
943
+ // specific mechanism — an inversion the mechanism market forbids: the shared
944
+ // contract may not depend on any one mechanism (mechanism-market.md), and a
945
+ // shared matcher belongs to this family (match-project.md), never to a
946
+ // mechanism's private helpers. Deleting extraction must not break the shared
947
+ // container, so they live here.
948
948
  //
949
949
  // • isSpanShaped — the OPEN reading (sparse in-order embedding).
950
950
  // • containsSpan — the STRICT reading (contiguous run or resolved node).
951
951
  // • skillExemplar — classify one anchor into (context, answer) using them.
952
952
  //
953
- // The two readings are NOT interchangeable; AGENTS §2.5 pins the distinction
954
- // and each function's own doc states what breaks if it is substituted.
953
+ // The two readings are NOT interchangeable; match-project.md pins the
954
+ // distinction and each function's own doc states what breaks if it is
955
+ // substituted.
955
956
  /** Check whether an anchor is a span-shaped skill exemplar: it represents a
956
957
  * fact whose context and answer together form a span-in-context pattern.
957
958
  * If the anchor has a nextOf continuation, that is the answer and the anchor
@@ -4,7 +4,7 @@
4
4
  // Cover consumes recognition directly (its axioms are the query's own
5
5
  // decomposition) plus the computed spans any parse()-bearing mechanism
6
6
  // contributed: computed spans MASK colliding recognised sites and enter the
7
- // search at zero cost ("computation always wins", §16.3) — which is also why
7
+ // search at zero cost ("computation always wins", alu.md) — which is also why
8
8
  // cover runs FIRST in defaultMechanisms: a computed-backed cover becomes a
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.
@@ -59,22 +59,23 @@ export async function resolveConnectors(ctx, sites, query) {
59
59
  return true;
60
60
  const continuations = ctx.store.nextFirst(s.payload, hubBound(ctx));
61
61
  return !continuations.some((answer) => {
62
- // PREFIX-CAPPED (AGENTS §2.8): a candidate longer than the query cannot
63
- // occur INSIDE it, so read one byte past the query's length — enough to
64
- // detect the overflow — and reject without reconstructing the rest.
65
- // The `+ 1` is what makes the test exact rather than a truncation: a
66
- // result of exactly `query.length + 1` bytes is known to be too long,
67
- // and anything shorter is the candidate's COMPLETE content, so the
68
- // substring test below is the same test as before. (The same overflow
69
- // probe bridge.ts:256 already uses.)
62
+ // PREFIX-CAPPED (bounded-reads.md): a candidate longer than the query
63
+ // cannot occur INSIDE it, so read one byte past the query's length —
64
+ // enough to detect the overflow — and reject without reconstructing the
65
+ // rest. The `+ 1` is what makes the test exact rather than a
66
+ // truncation: a result of exactly `query.length + 1` bytes is known to
67
+ // be too long, and anything shorter is the candidate's COMPLETE
68
+ // content, so the substring test below is the same test as before. (The
69
+ // same overflow probe bridge.ts:256 already uses.)
70
70
  //
71
71
  // This loop runs up to hubBound(ctx) = √N reads PER SITE, and only on a
72
72
  // multi-turn response — `answeredSpans` is empty for a plain respond(),
73
- // so the probe does not execute there. The cap cannot reduce the read
73
+ // so the probe does not execute there. The cap cannot reduce the read
74
74
  // COUNT — only a semantic change to the "already answered" test could —
75
75
  // but it bounds each read by the query instead of by the corpus, which
76
- // is what §2.8 asks for and what rescues a SHORT query: at 3 bytes this
77
- // reads 4 bytes per candidate instead of the ~231 it averaged before.
76
+ // is what bounded-reads.md asks for and what rescues a SHORT query: at
77
+ // 3 bytes this reads 4 bytes per candidate instead of the ~231 it
78
+ // averaged before.
78
79
  const bytes = read(ctx, answer, query.length + 1);
79
80
  return bytes.length <= query.length && indexOf(query, bytes, 0) >= 0;
80
81
  });
@@ -1,15 +1,15 @@
1
1
  // mechanisms/prefix-completion.ts — Grounding a query that IS the opening of a
2
2
  // trained form (Grounding V).
3
3
  //
4
- // A MECHANISM, NOT A TIER. This used to run inside recall's refusal path, in
5
- // a fixed if-chain that first-match-wins — the shape CAST was refactored away
6
- // from, where placement rather than the cost ladder decided. Its claim is
4
+ // A MECHANISM, NOT A TIER. This used to run inside recall's refusal path, in a
5
+ // fixed if-chain that first-match-wins — the shape CAST was refactored away
6
+ // from, where placement rather than the cost ladder decided. Its claim is
7
7
  // maximal (every query byte literally matched, from offset zero, against a
8
8
  // trained form) at one STEP, so as a market candidate it competes honestly and
9
- // the decider weighs it like everything else. It is registered LAST: recall's
9
+ // the decider weighs it like everything else. It is registered LAST: recall's
10
10
  // exact self-match makes an IDENTITY claim about the query while this makes a
11
- // CONTAINMENT one, and on an exact grade tie the identity claim is the
12
- // stronger evidence — the same ordering §2.3's ladders use.
11
+ // CONTAINMENT one, and on an exact grade tie the identity claim is the stronger
12
+ // evidence — the same ordering exact-vs-approximate.md's ladders use.
13
13
  //
14
14
  // Its SUPPLY moved too, and further: `formsOpenedBy` (traverse.ts) answers a
15
15
  // question about the STORE — "which trained forms does this byte run open?" —
@@ -49,12 +49,12 @@
49
49
  //
50
50
  // So this is a RETRIEVABILITY gap, not a semantic one, and the ANN is the wrong
51
51
  // instrument for it: a proper prefix's gist cannot rank its own continuation.
52
- // The repair is CONTENT-ADDRESSED (§2.3) — `formsOpenedBy` (traverse.ts) reads
53
- // the leaf-id WINDOW index the write side already maintains and answers "which
54
- // trained forms does this byte run open?" in a bounded √N walk. That is this
55
- // mechanism's first supply. The response's memoised top-k `resonance()` is the
56
- // second, for prefixes long enough that the gist still ranks the form; it is
57
- // read, never re-issued.
52
+ // The repair is CONTENT-ADDRESSED (exact-vs-approximate.md) — `formsOpenedBy`
53
+ // (traverse.ts) reads the leaf-id WINDOW index the write side already maintains
54
+ // and answers "which trained forms does this byte run open?" in a bounded √N
55
+ // walk. That is this mechanism's first supply. The response's memoised top-k
56
+ // `resonance()` is the second, for prefixes long enough that the gist still
57
+ // ranks the form; it is read, never re-issued.
58
58
  //
59
59
  // AN EXHAUSTIVE ANN LIST IS NOT A SUPPLY HERE, AND WAS REMOVED. This tier once
60
60
  // read `Precomputed.wideResonance()` — a full-index `resonate(guide, √N,
@@ -227,20 +227,20 @@ export const prefixMechanism = {
227
227
  return STEP;
228
228
  },
229
229
  async run(ctx, query, pre) {
230
- // ONE SUPPLY PASS, not a two-tier `??`. The window index (exact,
230
+ // ONE SUPPLY PASS, not a two-tier `??`. The window index (exact,
231
231
  // content-addressed) and the response's memoised top-k (approximate) are
232
- // concatenated and the three guards decide ONCE over the union. A
232
+ // concatenated and the three guards decide ONCE over the union. A
233
233
  // first-then-fallback chain would let the APPROXIMATE tier override the
234
- // EXACT one (§2.3): when formsOpenedBy finds two continuations, guard 3
235
- // returns null and the fallback re-runs the guards on resonance's top-k
236
- // alone — which, seeing only one of the two forms, would voice it. That is
237
- // precisely the disagreement-suppression guard 3 exists to prevent, and it
238
- // is the exact tier's ambiguity being washed away by the approximate tier.
239
- // Evaluating the union means a disagreement the window index saw can never
240
- // be hidden by what the ANN happens to rank. The ANN read is the
241
- // response's ONE memoised top-k (§2.11), already paid by recall's refusal
242
- // path on the queries where this mechanism fires, so reading it here is not
243
- // a second index scan.
234
+ // EXACT one (exact-vs-approximate.md): when formsOpenedBy finds two
235
+ // continuations, guard 3 returns null and the fallback re-runs the guards
236
+ // on resonance's top-k alone — which, seeing only one of the two forms,
237
+ // would voice it. That is precisely the disagreement-suppression guard 3
238
+ // exists to prevent, and it is the exact tier's ambiguity being washed away
239
+ // by the approximate tier. Evaluating the union means a disagreement the
240
+ // window index saw can never be hidden by what the ANN happens to rank. The
241
+ // ANN read is the response's ONE memoised top-k (memoization.md), already
242
+ // paid by recall's refusal path on the queries where this mechanism fires,
243
+ // so reading it here is not a second index scan.
244
244
  const ids = [
245
245
  ...formsOpenedBy(ctx, query),
246
246
  ...(await pre.resonance()).map((h) => h.id),
@@ -159,24 +159,22 @@ export async function recallByResonance(ctx, query, pre) {
159
159
  }
160
160
  }
161
161
  }
162
- // The query-relative grounding fraction, shared by tiers 2–4 — gated on
163
- // the FRACTION OF THE QUERY the grounding explains, not the raw cosine.
164
- // Root gists are unit vectors, but their magnitudes are recoverable from
165
- // the byte lengths (‖·‖ = √len under the linear fold):
166
- // cos = shared/√(lenQ·lenG), so shared/lenQ = cos·√(lenG/lenQ).
167
- // The raw cosine punished honest containment — a query fully inside a
168
- // longer grounded answer scored √(lenQ/lenG) and was refused — and let a
169
- // long answer sharing only scaffolding pass; the query-relative fraction
170
- // measures exactly what the reach bar means: how much of THE QUERY the
171
- // store accounts for.
172
- // Chance similarity survives the length conversion AMPLIFIED: the same
173
- // √(lenG/lenQ) factor that converts an honest shared fraction into a
174
- // query-relative one multiplies the estimator/chance floor too, so a long
175
- // stored form (√(lenG/lenQ) ≈ 10 at 100×) lifted a noise-level cosine past
176
- // the reach bar and grounded pure gibberish (observed). Only the
177
- // ABOVE-CHANCE part of the similarity is evidence of shared content —
178
- // subtract the significance bar (3/√D, §8.3) before converting. Derived
179
- // from the existing bars; never tuned.
162
+ // The query-relative grounding fraction, shared by tiers 2–4 — gated on the
163
+ // FRACTION OF THE QUERY the grounding explains, not the raw cosine. Root
164
+ // gists are unit vectors, but their magnitudes are recoverable from the byte
165
+ // lengths (‖·‖ = √len under the linear fold): cos = shared/√(lenQ·lenG), so
166
+ // shared/lenQ = cos·√(lenG/lenQ). The raw cosine punished honest containment
167
+ // — a query fully inside a longer grounded answer scored √(lenQ/lenG) and was
168
+ // refused — and let a long answer sharing only scaffolding pass; the
169
+ // query-relative fraction measures exactly what the reach bar means: how much
170
+ // of THE QUERY the store accounts for. Chance similarity survives the length
171
+ // conversion AMPLIFIED: the same √(lenG/lenQ) factor that converts an honest
172
+ // shared fraction into a query-relative one multiplies the estimator/chance
173
+ // floor too, so a long stored form (√(lenG/lenQ) ≈ 10 at 100×) lifted a
174
+ // noise-level cosine past the reach bar and grounded pure gibberish
175
+ // (observed). Only the ABOVE-CHANCE part of the similarity is evidence of
176
+ // shared content — subtract the significance bar (3/√D, thresholds.md) before
177
+ // converting. Derived from the existing bars; never tuned.
180
178
  const sig = significanceBar(ctx.store.D);
181
179
  const reach = reachThreshold(ctx.space.maxGroup);
182
180
  const fracOfQuery = (cos, otherLen) => Math.min(1, Math.max(0, cos - sig) *
@@ -305,14 +303,14 @@ export async function recallByResonance(ctx, query, pre) {
305
303
  }
306
304
  }
307
305
  }
308
- // 3b. Corroborated-substitution bridge — refusal-path only (bridge.ts).
309
- // The bridge's proposal source is the response's ONE top-k read — the same
310
- // list recall already ranked above — never an exhaustive √N scan. The
311
- // bridge's own candidate cap is 2·recallQueryK, so top-k proposals are
312
- // exactly the budget it can consume, and every proposal is byte-verified
313
- // downstream (§2.3). Reuse the memoised `resonance()`; scanning every IVF
314
- // cluster here once made every honest refusal cost hundreds of ms regardless
315
- // of k.
306
+ // 3b. Corroborated-substitution bridge — refusal-path only (bridge.ts). The
307
+ // bridge's proposal source is the response's ONE top-k read — the same list
308
+ // recall already ranked above — never an exhaustive √N scan. The bridge's own
309
+ // candidate cap is 2·recallQueryK, so top-k proposals are exactly the budget
310
+ // it can consume, and every proposal is byte-verified downstream
311
+ // (exact-vs-approximate.md). Reuse the memoised `resonance()`; scanning every
312
+ // IVF cluster here once made every honest refusal cost hundreds of ms
313
+ // regardless of k.
316
314
  const wideIds = async () => (await pre.resonance()).map((h) => h.id);
317
315
  // Every gist-based tier has failed; before refusing, align the query
318
316
  // byte-for-byte against the trained contexts its own stored windows
@@ -362,12 +360,12 @@ export async function recallByResonance(ctx, query, pre) {
362
360
  // prefixCompletion runs a few lines below and carries the three guards
363
361
  // this tier lacks — unreadable-continuation veto, sub-quantum
364
362
  // continuation, and UNIQUENESS (distinct continuations ⇒ refuse), which
365
- // is exactly what 4,300 competing values must trip. So this is not a
366
- // new rule and not a new threshold: it is deferring a prefix decision to
367
- // the tier that owns it (§2.5, one factored machinery). Byte-strict on
368
- // purpose — a candidate differing by case or punctuation ("what is the
369
- // capital of france" → "What is the capital of France?") is NOT a byte
370
- // prefix, keeps grounding here, and is unaffected.
363
+ // is exactly what 4,300 competing values must trip. So this is not a new
364
+ // rule and not a new threshold: it is deferring a prefix decision to the
365
+ // tier that owns it (match-project.md, one factored machinery).
366
+ // Byte-strict on purpose — a candidate differing by case or punctuation
367
+ // ("what is the capital of france" → "What is the capital of France?") is
368
+ // NOT a byte prefix, keeps grounding here, and is unaffected.
371
369
  const strictPrefix = g !== null &&
372
370
  cBytes.length > query.length &&
373
371
  indexOf(cBytes, query, 0) === 0;
@@ -425,15 +423,15 @@ export async function recallByResonance(ctx, query, pre) {
425
423
  }
426
424
  }
427
425
  }
428
- // The refusal/echo decision. The echo returns a stored form's bytes AS
429
- // the answer — a near-identity claim about the query — and identity-grade
426
+ // The refusal/echo decision. The echo returns a stored form's bytes AS the
427
+ // answer — a near-identity claim about the query — and identity-grade
430
428
  // decisions are never made on an estimated score ("approximate scores may
431
- // rank and propose; they may never decide", §6.2): the RaBitQ estimate
432
- // overshooting the reach bar echoed a WRONG-entity neighbour ("capital of
433
- // Zamunda?" echoed the Armenia fact, observed). The bytes are read
434
- // anyway to be echoed, so the decision uses their EXACT fold: one river
435
- // fold of the top hit, measured in the same query-relative,
436
- // chance-corrected units as the tier above.
429
+ // rank and propose; they may never decide", exact-vs-approximate.md): the
430
+ // RaBitQ estimate overshooting the reach bar echoed a WRONG-entity neighbour
431
+ // ("capital of Zamunda?" echoed the Armenia fact, observed). The bytes are
432
+ // read anyway to be echoed, so the decision uses their EXACT fold: one river
433
+ // fold of the top hit, measured in the same query-relative, chance-corrected
434
+ // units as the tier above.
437
435
  const topBytes = read(ctx, top.id);
438
436
  const exact = topBytes.length > 0
439
437
  ? cosine(queryGist, gistOf(ctx, topBytes))
@@ -2,8 +2,8 @@
2
2
  // bytes (Grounding IV).
3
3
  //
4
4
  // This file is a CONFIGURATION of the shared frame reading in match.ts, not a
5
- // pipeline of its own. The three parts it configures live where §2.5 puts
6
- // them and are reachable by any mechanism:
5
+ // pipeline of its own. The three parts it configures live where
6
+ // match-project.md puts them and are reachable by any mechanism:
7
7
  //
8
8
  // matcher Precomputed.frames() — the frame INVENTORY: which ranked
9
9
  // candidates read as instances of the query's own frame, and
@@ -29,10 +29,10 @@
29
29
  // candidate's continuation UNSUBSTITUTED, so admitting a slot-gap there would
30
30
  // voice the corpus's filler for the asker's referent — the misreference
31
31
  // measured live on the trained store ("How do you say 'flurbish' in French?"
32
- // answered "the way to say hello is \"Bonjour\""). Nor is CAST rewired: its
32
+ // answered "the way to say hello is \"Bonjour\""). Nor is CAST rewired: its
33
33
  // frame gate is WEAVE-local while a slot is COHORT-local, and substituting one
34
- // population for the other is the error §2.7 names. The notion is made
35
- // AVAILABLE, never imposed.
34
+ // population for the other is the error commonality.md names. The notion is
35
+ // made AVAILABLE, never imposed.
36
36
  import { carriesFillers, distinct, follow, substituteAll } from "../match.js";
37
37
  import { dominates } from "../../geometry.js";
38
38
  import { bytesEqual, indexOf } from "../../bytes.js";
@@ -43,16 +43,16 @@ import { rItem, rNode, traceFail } from "../trace.js";
43
43
  * agrees with nothing, so no carriage is attested — the same "two or no
44
44
  * constituent" reading frame-filler's contentRuns applies.
45
45
  *
46
- * THIS IS ALSO THE MECHANISM'S REACH. Evidence comes from the shared top-k
47
- * resonance, so a frame the corpus instantiates only ONCE within k is not
48
- * reachable here. Measured on the trained store: `How do you say 'flurbish'
49
- * in French?` finds one instance of its frame in the top 24 — the rest are
50
- * `How do you make …`, a different frame — so this abstains and recall's
51
- * scaffolding-dominated tier answers with the CORPUS's filler. That
52
- * misreference is recall's, and widening the supply is not the fix: the
53
- * exhaustive √N list recall's refusal path builds costs hundreds of
54
- * milliseconds and this runs before it. Abstaining on thin evidence is the
55
- * honest reading (§2.13). */
46
+ * THIS IS ALSO THE MECHANISM'S REACH. Evidence comes from the shared top-k
47
+ * resonance, so a frame the corpus instantiates only ONCE within k is not
48
+ * reachable here. Measured on the trained store: `How do you say 'flurbish' in
49
+ * French?` finds one instance of its frame in the top 24 — the rest are `How do
50
+ * you make …`, a different frame — so this abstains and recall's
51
+ * scaffolding-dominated tier answers with the CORPUS's filler. That
52
+ * misreference is recall's, and widening the supply is not the fix: the
53
+ * exhaustive √N list recall's refusal path builds costs hundreds of
54
+ * milliseconds and this runs before it. Abstaining on thin evidence is the
55
+ * honest reading (INVARIANTS.md). */
56
56
  const MIN_INSTANCES = 2;
57
57
  /** THE VOICING GATES — this mechanism's own reading of a pairing, applied here
58
58
  * and NOT in the shared matcher.
@@ -123,7 +123,7 @@ function electFrame(inventory, W, queryLen) {
123
123
  let best = [];
124
124
  for (const group of bySignature.values()) {
125
125
  // Ties keep the FIRST group in insertion order, which is resonance rank —
126
- // corpus-determined, like every other tie-break here (§2.1).
126
+ // corpus-determined, like every other tie-break here (determinism.md).
127
127
  if (group.length > best.length)
128
128
  best = group;
129
129
  }
@@ -64,13 +64,12 @@ export interface MindOptions {
64
64
  /** Factories that receive the {@link ExtensionHost} and return mechanisms. */
65
65
  mechanismFactories?: ((host: import("../extension.js").ExtensionHost) => import("./pipeline-mechanism.js").PipelineMechanism)[];
66
66
  /** Measure the computational usage of every inference call — see
67
- * src/meter.ts. Off by default and free when off (one null check per
68
- * store read); on, each `respond`/`respondTurn` leaves a {@link
69
- * Mind.lastCost} report behind. Counters are deterministic, so two runs
70
- * of the same query on the same store are diffable; the millisecond
71
- * fields are not. Profiling NEVER changes an answer — but note that
72
- * attaching a RATIONALE does (traced responses bypass the ctx memos,
73
- * AGENTS §2.11), so profile without a trace. */
67
+ * src/meter.ts. Off by default and free when off (one null check per store
68
+ * read); on, each `respond`/`respondTurn` leaves a {@link Mind.lastCost}
69
+ * report behind. Counters are deterministic, so two runs of the same query on
70
+ * the same store are diffable; the millisecond fields are not. Profiling
71
+ * NEVER changes an answer — but attaching a RATIONALE does: a traced response
72
+ * bypasses the ctx memos (memoization.md), so profile without a trace. */
74
73
  profile?: boolean;
75
74
  /** Content canonicalizer applied to EVERY response (any modality) for
76
75
  * equivalence-class resolution — see src/canon.ts. Text entry points
@@ -69,14 +69,16 @@ export declare class Precomputed {
69
69
  * ({@link FrameInstance}). The one place the engine represents "a position
70
70
  * whose occupant comes from the context rather than the corpus".
71
71
  *
72
- * AN INVENTORY, NOT AN ELECTION. It reports every pairing and elects no
73
- * frame, deliberately: a slot is a property of a PAIRING, not of the query,
74
- * and different candidates put slots in different places. Committing to one
75
- * reading here would push whichever consumer asked first onto everyone else
76
- * — the market's decoupling (§2.6) broken from inside the shared container,
77
- * and the population error §2.7 names. Each consumer groups and commits
78
- * for its own question; reference elects the modal slot signature, and a
79
- * consumer wanting a different reading is not fighting this one.
72
+ * AN INVENTORY, NOT AN ELECTION. It reports every pairing and elects no
73
+ * frame,
74
+ * deliberately: a slot is a property of a PAIRING, not of the query, and
75
+ * different candidates put slots in different places. Committing to one
76
+ * reading here would push whichever consumer asked first onto everyone else —
77
+ * the market's decoupling (mechanism-market.md) broken from inside the shared
78
+ * container, and the population error commonality.md names. Each consumer
79
+ * groups and commits for its own question; reference elects the modal slot
80
+ * signature, and a consumer wanting a different reading is not fighting this
81
+ * one.
80
82
  *
81
83
  * NO LICENCE EITHER. Knowing a span is variable is safe for every consumer
82
84
  * — it can only improve an alignment. Knowing one may be VOICED through is
@@ -5,7 +5,7 @@
5
5
  // a list of PipelineMechanism objects — it never imports a mechanism-specific
6
6
  // type and never has a special-case branch for any mechanism.
7
7
  //
8
- // The four constraints of the free-will architecture (§14.5):
8
+ // The four constraints of the free-will architecture (mechanism-market.md):
9
9
  // 1. DECOUPLING — mechanisms import nothing from each other or from pipeline.
10
10
  // 2. DECLARED COMPETENCE — floor() returns null when impossible, a number when
11
11
  // possible. Binary, auditable, no learned scores.
@@ -128,31 +128,33 @@ export class Precomputed {
128
128
  resonance() {
129
129
  return this._resonance ??= this.shared("resonance", () => this.ctx.store.resonate(this.guide, this.k));
130
130
  }
131
- // REMOVED — the WIDE exhaustive-√N resonance list (`wideResonance`). It ran
131
+ // REMOVED — the WIDE exhaustive-√N resonance list (`wideResonance`). It ran
132
132
  // `resonate(guide, √N, exhaustive=true)` whenever the top hit cleared
133
- // conceptThreshold, so consumers could look "past the top-k". Every consumer
133
+ // conceptThreshold, so consumers could look "past the top-k". Every consumer
134
134
  // only ever needed ≤ 2·recallQueryK proposals (the substitution bridge's own
135
135
  // candidate cap) or a content-addressed answer (prefix completion's
136
- // formsOpenedBy), and every proposal is byte-verified downstream (§2.3), so
137
- // the exhaustive scan bought recall at O(index) cost for an O(k) need —
138
- // measured: 244K annVectorReads per refusing query, ~1.5 s, every answer
139
- // byte-identical to a top-k read. The two consumers now read `resonance()`
140
- // (the one top-k read) and the write side's window index respectively — see
141
- // recall.ts and prefix-completion.ts.
136
+ // formsOpenedBy), and every proposal is byte-verified downstream
137
+ // (exact-vs-approximate.md), so the exhaustive scan bought recall at O(index)
138
+ // cost for an O(k) need — measured: 244K annVectorReads per refusing query,
139
+ // ~1.5 s, every answer byte-identical to a top-k read. The two consumers now
140
+ // read `resonance()` (the one top-k read) and the write side's window index
141
+ // respectively — see recall.ts and prefix-completion.ts.
142
142
  _frames;
143
143
  /** THE FRAME INVENTORY — every ranked candidate that reads as an instance of
144
144
  * the same frame as the query, each with the query spans it leaves VARIABLE
145
145
  * ({@link FrameInstance}). The one place the engine represents "a position
146
146
  * whose occupant comes from the context rather than the corpus".
147
147
  *
148
- * AN INVENTORY, NOT AN ELECTION. It reports every pairing and elects no
149
- * frame, deliberately: a slot is a property of a PAIRING, not of the query,
150
- * and different candidates put slots in different places. Committing to one
151
- * reading here would push whichever consumer asked first onto everyone else
152
- * — the market's decoupling (§2.6) broken from inside the shared container,
153
- * and the population error §2.7 names. Each consumer groups and commits
154
- * for its own question; reference elects the modal slot signature, and a
155
- * consumer wanting a different reading is not fighting this one.
148
+ * AN INVENTORY, NOT AN ELECTION. It reports every pairing and elects no
149
+ * frame,
150
+ * deliberately: a slot is a property of a PAIRING, not of the query, and
151
+ * different candidates put slots in different places. Committing to one
152
+ * reading here would push whichever consumer asked first onto everyone else —
153
+ * the market's decoupling (mechanism-market.md) broken from inside the shared
154
+ * container, and the population error commonality.md names. Each consumer
155
+ * groups and commits for its own question; reference elects the modal slot
156
+ * signature, and a consumer wanting a different reading is not fighting this
157
+ * one.
156
158
  *
157
159
  * NO LICENCE EITHER. Knowing a span is variable is safe for every consumer
158
160
  * — it can only improve an alignment. Knowing one may be VOICED through is
@@ -168,9 +170,10 @@ export class Precomputed {
168
170
  const capBytes = this.query.length * W;
169
171
  const out = [];
170
172
  for (const h of await this.resonance()) {
171
- // REJECT BY LENGTH BEFORE RECONSTRUCTING (§2.8): `contentLen` is an
172
- // indexed read, `bytesPrefix` rebuilds a subtree. ONLY the phrase-scale
173
- // cap is applied — it is a bounded-read discipline, not a judgement.
173
+ // REJECT BY LENGTH BEFORE RECONSTRUCTING (bounded-reads.md):
174
+ // `contentLen` is an indexed read, `bytesPrefix` rebuilds a subtree.
175
+ // ONLY the phrase-scale cap is applied — it is a bounded-read
176
+ // discipline, not a judgement.
174
177
  //
175
178
  // A LOWER bound was here too (`dominates(len, query.length)`, on the
176
179
  // reasoning that a candidate shorter than half the query cannot supply
@@ -458,7 +461,8 @@ function computeWeave(ctx, query, pre, climb) {
458
461
  // IDF — gates the aligner has no equivalent of.
459
462
  //
460
463
  // So the climb PROPOSES the pairing (which structure, which query span) and
461
- // bytes DECIDE its terms (§2.3). Three gates, each one measured:
464
+ // bytes DECIDE its terms (exact-vs-approximate.md). Three gates, each one
465
+ // measured:
462
466
  //
463
467
  // • it may only take query bytes NO literal run claimed. Run inline with
464
468
  // phase 1 this did the opposite of "exact decides" — a higher-ranked
@@ -38,15 +38,15 @@ export interface NarrowDecisionData {
38
38
  margin: number;
39
39
  }
40
40
  /** Structured payload of the "regimePrediction" rationale step — the R8
41
- * observation exposed as data. After the first mechanism (cover, which §2.6
42
- * runs first) grounds or abstains, the market's whole outcome is already
43
- * determined by the one cost ladder: the consensus climb runs exactly when
44
- * `worthRunning(2 * STEP)` is true — CAST (floor 2·STEP) is the cheapest
45
- * mechanism that first-touches it, and confluence (3·STEP) / extraction
46
- * (CONCEPT+STEP) are only reached after CAST is. An incumbent at or below
47
- * that floor prunes CAST and, with it, the climb (retrieval); anything above
48
- * — or no incumbent — runs the full market and the climb (composition).
49
- * Purely observational; never read by inference. */
41
+ * observation exposed as data. After the first mechanism (cover, which
42
+ * mechanism-market.md runs first) grounds or abstains, the market's whole
43
+ * outcome is already determined by the one cost ladder: the consensus climb
44
+ * runs exactly when `worthRunning(2 * STEP)` is true — CAST (floor 2·STEP) is
45
+ * the cheapest mechanism that first-touches it, and confluence (3·STEP) /
46
+ * extraction (CONCEPT+STEP) are only reached after CAST is. An incumbent at or
47
+ * below that floor prunes CAST and, with it, the climb (retrieval); anything
48
+ * above — or no incumbent — runs the full market and the climb (composition).
49
+ * Purely observational; never read by inference. */
50
50
  export interface RegimePredictionData {
51
51
  version: 1;
52
52
  /** retrieval | composition — the two regimes R1 measured as a ~100× cost