@hviana/sema 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/package.json +1 -1
  2. package/src/geometry.ts +52 -3
  3. package/src/mind/attention.ts +1469 -120
  4. package/src/mind/index.ts +16 -0
  5. package/src/mind/junction.ts +125 -16
  6. package/src/mind/mind.ts +15 -0
  7. package/src/mind/rationale.ts +12 -4
  8. package/src/mind/traverse.ts +75 -7
  9. package/src/mind/types.ts +25 -0
  10. package/test/51-structural-resonance-ladder.test.mjs +552 -0
  11. package/test/52-climb-consensus-instrumentation.test.mjs +324 -0
  12. package/test/53-cross-region-probe-instrumentation.test.mjs +356 -0
  13. package/dist/example/demo.d.ts +0 -1
  14. package/dist/example/demo.js +0 -39
  15. package/dist/example/train_base.d.ts +0 -87
  16. package/dist/example/train_base.js +0 -2252
  17. package/dist/src/alphabet.d.ts +0 -7
  18. package/dist/src/alphabet.js +0 -33
  19. package/dist/src/alu/src/alu.d.ts +0 -185
  20. package/dist/src/alu/src/alu.js +0 -440
  21. package/dist/src/alu/src/expr.d.ts +0 -61
  22. package/dist/src/alu/src/expr.js +0 -318
  23. package/dist/src/alu/src/index.d.ts +0 -11
  24. package/dist/src/alu/src/index.js +0 -19
  25. package/dist/src/alu/src/kernel-arith.d.ts +0 -16
  26. package/dist/src/alu/src/kernel-arith.js +0 -264
  27. package/dist/src/alu/src/kernel-bits.d.ts +0 -19
  28. package/dist/src/alu/src/kernel-bits.js +0 -152
  29. package/dist/src/alu/src/kernel-logic.d.ts +0 -4
  30. package/dist/src/alu/src/kernel-logic.js +0 -60
  31. package/dist/src/alu/src/kernel-nd.d.ts +0 -3
  32. package/dist/src/alu/src/kernel-nd.js +0 -208
  33. package/dist/src/alu/src/kernel-numeric.d.ts +0 -54
  34. package/dist/src/alu/src/kernel-numeric.js +0 -366
  35. package/dist/src/alu/src/operation.d.ts +0 -168
  36. package/dist/src/alu/src/operation.js +0 -189
  37. package/dist/src/alu/src/parser.d.ts +0 -221
  38. package/dist/src/alu/src/parser.js +0 -577
  39. package/dist/src/alu/src/resonance.d.ts +0 -55
  40. package/dist/src/alu/src/resonance.js +0 -126
  41. package/dist/src/alu/src/text.d.ts +0 -31
  42. package/dist/src/alu/src/text.js +0 -73
  43. package/dist/src/alu/src/value.d.ts +0 -109
  44. package/dist/src/alu/src/value.js +0 -300
  45. package/dist/src/alu/test/alu.test.d.ts +0 -1
  46. package/dist/src/alu/test/alu.test.js +0 -764
  47. package/dist/src/bytes.d.ts +0 -14
  48. package/dist/src/bytes.js +0 -59
  49. package/dist/src/canon.d.ts +0 -26
  50. package/dist/src/canon.js +0 -57
  51. package/dist/src/config.d.ts +0 -111
  52. package/dist/src/config.js +0 -91
  53. package/dist/src/derive/src/deduction.d.ts +0 -125
  54. package/dist/src/derive/src/deduction.js +0 -155
  55. package/dist/src/derive/src/index.d.ts +0 -7
  56. package/dist/src/derive/src/index.js +0 -11
  57. package/dist/src/derive/src/priority-queue.d.ts +0 -20
  58. package/dist/src/derive/src/priority-queue.js +0 -73
  59. package/dist/src/derive/src/rewrite.d.ts +0 -56
  60. package/dist/src/derive/src/rewrite.js +0 -100
  61. package/dist/src/derive/src/trie.d.ts +0 -90
  62. package/dist/src/derive/src/trie.js +0 -217
  63. package/dist/src/derive/test/derive.test.d.ts +0 -1
  64. package/dist/src/derive/test/derive.test.js +0 -122
  65. package/dist/src/extension.d.ts +0 -37
  66. package/dist/src/extension.js +0 -7
  67. package/dist/src/geometry.d.ts +0 -176
  68. package/dist/src/geometry.js +0 -546
  69. package/dist/src/index.d.ts +0 -16
  70. package/dist/src/index.js +0 -18
  71. package/dist/src/ingest-cache.d.ts +0 -41
  72. package/dist/src/ingest-cache.js +0 -161
  73. package/dist/src/mind/articulation.d.ts +0 -6
  74. package/dist/src/mind/articulation.js +0 -99
  75. package/dist/src/mind/attention.d.ts +0 -88
  76. package/dist/src/mind/attention.js +0 -997
  77. package/dist/src/mind/bridge.d.ts +0 -30
  78. package/dist/src/mind/bridge.js +0 -569
  79. package/dist/src/mind/canonical.d.ts +0 -29
  80. package/dist/src/mind/canonical.js +0 -88
  81. package/dist/src/mind/graph-search.d.ts +0 -285
  82. package/dist/src/mind/graph-search.js +0 -956
  83. package/dist/src/mind/index.d.ts +0 -5
  84. package/dist/src/mind/index.js +0 -5
  85. package/dist/src/mind/junction.d.ts +0 -95
  86. package/dist/src/mind/junction.js +0 -262
  87. package/dist/src/mind/learning.d.ts +0 -47
  88. package/dist/src/mind/learning.js +0 -248
  89. package/dist/src/mind/match.d.ts +0 -126
  90. package/dist/src/mind/match.js +0 -441
  91. package/dist/src/mind/mechanisms/alu.d.ts +0 -4
  92. package/dist/src/mind/mechanisms/alu.js +0 -36
  93. package/dist/src/mind/mechanisms/cast.d.ts +0 -89
  94. package/dist/src/mind/mechanisms/cast.js +0 -716
  95. package/dist/src/mind/mechanisms/confluence.d.ts +0 -24
  96. package/dist/src/mind/mechanisms/confluence.js +0 -225
  97. package/dist/src/mind/mechanisms/cover.d.ts +0 -6
  98. package/dist/src/mind/mechanisms/cover.js +0 -203
  99. package/dist/src/mind/mechanisms/extraction.d.ts +0 -67
  100. package/dist/src/mind/mechanisms/extraction.js +0 -387
  101. package/dist/src/mind/mechanisms/recall.d.ts +0 -13
  102. package/dist/src/mind/mechanisms/recall.js +0 -325
  103. package/dist/src/mind/mind.d.ts +0 -274
  104. package/dist/src/mind/mind.js +0 -572
  105. package/dist/src/mind/pipeline-mechanism.d.ts +0 -142
  106. package/dist/src/mind/pipeline-mechanism.js +0 -213
  107. package/dist/src/mind/pipeline.d.ts +0 -20
  108. package/dist/src/mind/pipeline.js +0 -217
  109. package/dist/src/mind/primitives.d.ts +0 -70
  110. package/dist/src/mind/primitives.js +0 -287
  111. package/dist/src/mind/rationale.d.ts +0 -134
  112. package/dist/src/mind/rationale.js +0 -162
  113. package/dist/src/mind/reasoning.d.ts +0 -34
  114. package/dist/src/mind/reasoning.js +0 -240
  115. package/dist/src/mind/recognition.d.ts +0 -20
  116. package/dist/src/mind/recognition.js +0 -390
  117. package/dist/src/mind/resonance.d.ts +0 -23
  118. package/dist/src/mind/resonance.js +0 -0
  119. package/dist/src/mind/trace.d.ts +0 -15
  120. package/dist/src/mind/trace.js +0 -73
  121. package/dist/src/mind/traverse.d.ts +0 -113
  122. package/dist/src/mind/traverse.js +0 -504
  123. package/dist/src/mind/types.d.ts +0 -271
  124. package/dist/src/mind/types.js +0 -130
  125. package/dist/src/rabitq-ivf/src/database.d.ts +0 -113
  126. package/dist/src/rabitq-ivf/src/database.js +0 -201
  127. package/dist/src/rabitq-ivf/src/index.d.ts +0 -7
  128. package/dist/src/rabitq-ivf/src/index.js +0 -4
  129. package/dist/src/rabitq-ivf/src/ivf.d.ts +0 -200
  130. package/dist/src/rabitq-ivf/src/ivf.js +0 -1165
  131. package/dist/src/rabitq-ivf/src/prng.d.ts +0 -19
  132. package/dist/src/rabitq-ivf/src/prng.js +0 -36
  133. package/dist/src/rabitq-ivf/src/rabitq.d.ts +0 -95
  134. package/dist/src/rabitq-ivf/src/rabitq.js +0 -283
  135. package/dist/src/sema.d.ts +0 -31
  136. package/dist/src/sema.js +0 -63
  137. package/dist/src/store-sqlite.d.ts +0 -184
  138. package/dist/src/store-sqlite.js +0 -942
  139. package/dist/src/store.d.ts +0 -663
  140. package/dist/src/store.js +0 -1618
  141. package/dist/src/vec.d.ts +0 -31
  142. package/dist/src/vec.js +0 -109
@@ -1,126 +0,0 @@
1
- import { Vec } from "../vec.js";
2
- import type { Hit } from "../store.js";
3
- import type { MindContext } from "./types.js";
4
- import type { Site } from "./graph-search.js";
5
- /** The graded LOCATE ladder: find `needle` in `haystack` starting at
6
- * `fromPos`, strictest matcher first, relaxing only when the stricter one
7
- * fails. This is the read-out matcher skill extraction locates exemplar
8
- * frames with.
9
- *
10
- * 1. exact — literal byte match (the fast path).
11
- * 2. halo — the needle's distributional role matches a recognised query
12
- * form (gate: conceptThreshold).
13
- * 3. gist — the needle's perceived gist matches a query segment
14
- * (gate: identityBar — scale-aware).
15
- *
16
- * Returns the absolute byte position, or −1. */
17
- export declare function locate(ctx: MindContext, haystack: Uint8Array, needle: Uint8Array, fromPos: number, sites?: ReadonlyArray<Site>): number;
18
- /** The ALIGNED matcher: maximal literal matching runs between `query` and
19
- * `ct` (a learned context's bytes), by seed-and-extend over
20
- * `space.maxGroup`-sized n-gram seeds. Where locate() finds ONE position of
21
- * a short frame, this finds EVERY run two whole structures share — the
22
- * matcher CAST detects a woven query with. Returns non-overlapping runs
23
- * sorted by query position. */
24
- export declare function alignRuns(ctx: MindContext, query: Uint8Array, ct: Uint8Array): Array<{
25
- qs: number;
26
- qe: number;
27
- cs: number;
28
- }>;
29
- /** A run from {@link alignGraded} — the ALIGNED matcher extended with the
30
- * same graded-evidence ladder as {@link locate}. Literal runs carry
31
- * `weight = 1` (exact match is full evidence); halo-matched site runs carry
32
- * `weight = cosine` (measured evidence — the halo similarity itself).
33
- * `cs` is the structural byte position in the context regardless of run
34
- * kind, so the substitution/redirection schemas work unchanged on conceptual
35
- * alignment. */
36
- export interface GradedRun {
37
- qs: number;
38
- qe: number;
39
- cs: number;
40
- weight: number;
41
- }
42
- /** The GRADED alignment matcher: extends literal W-gram alignment
43
- * ({@link alignRuns}) with halo-matched recognised sites in query regions
44
- * that have no literal coverage. Same ladder as {@link locate}: literal
45
- * first, then distributional role (halo-matched sites, gate:
46
- * conceptThreshold, enforced by {@link bestHaloMate}). Returns weighted
47
- * runs sorted by query position.
48
- *
49
- * `querySites` are the pre-computed recognition sites for the query
50
- * (optional — when absent, only literal alignment fires and graded degrades
51
- * to the original behaviour). Context sites are recognised internally. */
52
- export declare function alignGraded(ctx: MindContext, query: Uint8Array, contextBytes: Uint8Array, querySites?: ReadonlyArray<Site>): GradedRun[];
53
- /** The IN-LIST halo matcher: the best halo-mate for `halo` among EXPLICIT
54
- * candidates, above the concept threshold — the list counterpart of
55
- * {@link haloSiblings}, which asks the halo INDEX for candidates instead.
56
- * Behind locate()'s halo step and articulation's voice matching; a third
57
- * "best halo among these" decision must come here, not inline. */
58
- export declare function bestHaloMate<T>(ctx: MindContext, halo: Vec, items: Iterable<T>, haloOf: (item: T) => Vec | null | undefined): {
59
- item: T;
60
- score: number;
61
- } | null;
62
- export declare function haloSiblings(ctx: MindContext, id: number, halo?: Vec | null, bar?: number): Promise<Hit[]>;
63
- /** The DISTRIBUTIONAL matcher between two nodes: mutual-nearest-neighbour
64
- * strength, not a pick. Returns the direct halo cosine, or failing that the
65
- * highest mutual-halo-sibling min-score (second-order analogy), or failing
66
- * that the SHARED-FRAME strength (below) — the gate CAST's comparison
67
- * schema validates genuine analogs with (bar: significanceBar).
68
- *
69
- * The result names its TIER alongside the score: `halo: true` means the
70
- * score cleared a significanceBar-gated HALO tier (direct company cosine
71
- * or mutual-sibling) — genuine distributional evidence; `halo: false`
72
- * means only the structural shared-frame fallback matched, a coverage
73
- * fraction with no bar of its own. CAST's comparison gate treats the two
74
- * differently (see cast.ts): halo evidence stands alone, frame evidence
75
- * needs the query to have named the analog or the climb root to be
76
- * trusted. */
77
- export interface AnalogyEvidence {
78
- score: number;
79
- halo: boolean;
80
- }
81
- export declare function analogyStrength(ctx: MindContext, a: number, b: number): Promise<AnalogyEvidence>;
82
- /** The STRUCTURAL analogy tier: two nodes are analogs when their byte
83
- * streams share a LEARNT frame — a content-addressed flat form of at least
84
- * one full river window (W bytes, the perception quantum) that occurs in
85
- * BOTH. This is what "playing the same role" means structurally: "Ice is
86
- * cold" and "Steel is hard" share the learnt " is " frame even though they
87
- * keep disjoint distributional company. Halos measure company by IDENTITY
88
- * (company signatures — see sema.ts), so unrelated-company analogs must be
89
- * validated by the frame itself, not by content leaking through halo
90
- * vectors. Strength is the shared learnt coverage of the SHORTER side —
91
- * a fraction, comparable to the cosine tiers above. Derived: the window
92
- * is maxGroup, the same quantum differsByOneWindow and canonicalChunkId
93
- * measure by; no tuned constants. */
94
- export declare function sharedFrameStrength(ctx: MindContext, a: number, b: number): number;
95
- /** FORWARD through a synonym: the continuation an edge-less node borrows from
96
- * a concept (halo) sibling — resonate the node's halo, take the first
97
- * sibling above the concept threshold that itself has a direct edge. */
98
- export declare function conceptHop(ctx: MindContext, id: number): Promise<number | null>;
99
- /** FORWARD projection: follow continuation edges from a node to its fixpoint.
100
- * The first hop may cross a concept (halo) link — a synonym. The rest
101
- * follow direct edges. Convergence is intrinsic: the seen set guards
102
- * against cycles. `guide` disambiguates multi-continuation nodes by
103
- * resonance. */
104
- export declare function follow(ctx: MindContext, id: number, guide?: Vec | null): Promise<Uint8Array | null>;
105
- /** REVERSE projection: the context a learnt continuation follows, voiced as
106
- * bytes. A common continuation ("Yes.") follows MANY contexts; with a
107
- * `guide` the context whose gist resonates with the query wins (seat
108
- * symmetry) — without one, the most-corroborated context wins (poured halo
109
- * MASS, the direct measure of how many episodes established it), falling
110
- * back to first-learnt on equal mass. Among many predecessors RECIPROCAL
111
- * ones (mutual edges) are preferred when any exist (RC5). Callers that
112
- * HAVE a query gist must pass it, or they silently change disambiguation
113
- * regime.
114
- *
115
- * `rev`, when the caller has already materialised prevOf (one read per
116
- * relation — a hub's reverse fan-in is corpus-sized), is reused instead of
117
- * refetched. Returns null when there is no predecessor or the picked
118
- * context reads empty (a zero-length context is no grounding: an empty
119
- * Uint8Array is truthy, and returning it would flow a hollow "answer"
120
- * onward). */
121
- export declare function reverseContext(ctx: MindContext, id: number, guide?: Vec | null, rev?: readonly number[]): Uint8Array | null;
122
- /** THE projection: ground a matched node to answer bytes — FORWARD to its
123
- * continuation fixpoint (which may cross a concept hop), else REVERSE to
124
- * the context it follows. This is the direction ladder every mechanism's
125
- * final grounding step reduces to. */
126
- export declare function project(ctx: MindContext, id: number, guide?: Vec | null): Promise<Uint8Array | null>;
@@ -1,441 +0,0 @@
1
- // match.ts — the ONE elementary operation behind every generalising mechanism:
2
- // MATCH a learned structure against bytes, then PROJECT along a learned
3
- // relation, gated by a derived threshold.
4
- //
5
- // Every grounding/generalisation mechanism in the mind is a configuration of
6
- // this single (matcher, direction, gate) operation:
7
- //
8
- // mechanism matcher direction gate
9
- // ─────────────────── ────────────────────────────── ───────────── ────────────────
10
- // cover follow-edge exact (content-addressed) forward —
11
- // concept hop halo sibling forward conceptThreshold
12
- // recall tier 0–1 identity / whole-query gist fwd/reverse identityBar
13
- // skill extraction locate() ladder (exact→halo→ read-out per-step gates
14
- // gist) on the exemplar's frames
15
- // CAST substitution alignGraded() (graded ladder: insert frame shapes
16
- // literal W-grams → halo sites)
17
- // CAST comparison analogyStrength() (halo, juxtapose significanceBar
18
- // direct or mutual-sibling)
19
- // multi-hop pivot byte containment forward —
20
- // articulation halo sibling substitute conceptThreshold
21
- //
22
- // This module holds the shared vocabulary those configurations are built
23
- // from — the MATCHERS (locate, alignRuns, alignGraded, analogyStrength) and
24
- // the PROJECTIONS (follow, conceptHop, reverseContext, project) — so each
25
- // mechanism file states only its configuration, never its own copy of the
26
- // machinery. The gates all live in geometry.ts (derived, never tuned).
27
- import { cosine } from "../vec.js";
28
- import { conceptThreshold, identityBar, significanceBar } from "../geometry.js";
29
- import { indexOf } from "../bytes.js";
30
- import { leafIdRun } from "./canonical.js";
31
- import { gistOf, read, resolve } from "./primitives.js";
32
- import { argmaxCosine, chooseAmong, chooseNext, guidedFirst, hubBound, hubCap, } from "./traverse.js";
33
- import { recognise, segment } from "./recognition.js";
34
- // ═══════════════════════════════════════════════════════════════════════════
35
- // MATCHERS — locating learned structure in/against bytes, by graded strictness
36
- // ═══════════════════════════════════════════════════════════════════════════
37
- /** The graded LOCATE ladder: find `needle` in `haystack` starting at
38
- * `fromPos`, strictest matcher first, relaxing only when the stricter one
39
- * fails. This is the read-out matcher skill extraction locates exemplar
40
- * frames with.
41
- *
42
- * 1. exact — literal byte match (the fast path).
43
- * 2. halo — the needle's distributional role matches a recognised query
44
- * form (gate: conceptThreshold).
45
- * 3. gist — the needle's perceived gist matches a query segment
46
- * (gate: identityBar — scale-aware).
47
- *
48
- * Returns the absolute byte position, or −1. */
49
- export function locate(ctx, haystack, needle, fromPos, sites) {
50
- // 1. Exact match — fast, preserves backward compatibility.
51
- const exact = indexOf(haystack.subarray(fromPos), needle, 0);
52
- if (exact >= 0)
53
- return fromPos + exact;
54
- // 2. Halo-based: the frame bytes' distributional role matches a query form.
55
- if (sites && sites.length > 0) {
56
- const frameId = resolve(ctx, needle);
57
- if (frameId !== null) {
58
- const frameHalo = ctx.store.halo(frameId);
59
- if (frameHalo) {
60
- const bestSite = bestHaloMate(ctx, frameHalo, sites.filter((s) => s.start >= fromPos), (s) => ctx.store.halo(s.payload));
61
- if (bestSite !== null)
62
- return bestSite.item.start;
63
- }
64
- }
65
- }
66
- // 3. Gist resonance: the frame's perceived gist against query segments.
67
- const frameGist = gistOf(ctx, needle);
68
- const segments = segment(ctx, haystack.subarray(fromPos));
69
- // The gist tier claims the WHOLE needle appears as a segment — an
70
- // identity claim over `needle.length` bytes, so its bar is the
71
- // scale-aware {@link identityBar} (one river window of tolerated foreign
72
- // bytes), not the fixed estimator floor. For quantum-sized frames the
73
- // two coincide; for long needles the fixed bar accepted segments that
74
- // differed by whole windows.
75
- const bestSeg = argmaxCosine(frameGist, segments, (s) => s.v, identityBar(ctx.store.D, ctx.space.maxGroup, needle.length), true);
76
- if (bestSeg !== null)
77
- return fromPos + bestSeg.item.start;
78
- return -1;
79
- }
80
- /** The ALIGNED matcher: maximal literal matching runs between `query` and
81
- * `ct` (a learned context's bytes), by seed-and-extend over
82
- * `space.maxGroup`-sized n-gram seeds. Where locate() finds ONE position of
83
- * a short frame, this finds EVERY run two whole structures share — the
84
- * matcher CAST detects a woven query with. Returns non-overlapping runs
85
- * sorted by query position. */
86
- export function alignRuns(ctx, query, ct) {
87
- const quantum = Math.min(ctx.space.maxGroup, ct.length);
88
- if (quantum < 1 || query.length < quantum)
89
- return [];
90
- const gram = (b, at) => {
91
- let s = "";
92
- for (let i = 0; i < quantum; i++)
93
- s += String.fromCharCode(b[at + i]);
94
- return s;
95
- };
96
- const seeds = new Map();
97
- for (let i = 0; i + quantum <= query.length; i++) {
98
- const k2 = gram(query, i);
99
- const bucket = seeds.get(k2);
100
- if (bucket === undefined)
101
- seeds.set(k2, [i]);
102
- else
103
- bucket.push(i);
104
- }
105
- const found = [];
106
- for (let j = 0; j + quantum <= ct.length; j++) {
107
- const bucket = seeds.get(gram(ct, j));
108
- if (bucket === undefined)
109
- continue;
110
- for (const i of bucket) {
111
- if (i > 0 && j > 0 && query[i - 1] === ct[j - 1])
112
- continue;
113
- let len = quantum;
114
- while (i + len < query.length && j + len < ct.length &&
115
- query[i + len] === ct[j + len])
116
- len++;
117
- found.push({ qs: i, qe: i + len, cs: j, len });
118
- }
119
- }
120
- found.sort((a, b) => b.len - a.len);
121
- const runs = [];
122
- for (const r of found) {
123
- const clash = runs.some((o) => (r.qs < o.qe && o.qs < r.qe) ||
124
- (r.cs < o.cs + (o.qe - o.qs) && o.cs < r.cs + r.len));
125
- if (!clash)
126
- runs.push({ qs: r.qs, qe: r.qe, cs: r.cs });
127
- }
128
- return runs.sort((a, b) => a.qs - b.qs);
129
- }
130
- /** The GRADED alignment matcher: extends literal W-gram alignment
131
- * ({@link alignRuns}) with halo-matched recognised sites in query regions
132
- * that have no literal coverage. Same ladder as {@link locate}: literal
133
- * first, then distributional role (halo-matched sites, gate:
134
- * conceptThreshold, enforced by {@link bestHaloMate}). Returns weighted
135
- * runs sorted by query position.
136
- *
137
- * `querySites` are the pre-computed recognition sites for the query
138
- * (optional — when absent, only literal alignment fires and graded degrades
139
- * to the original behaviour). Context sites are recognised internally. */
140
- export function alignGraded(ctx, query, contextBytes, querySites) {
141
- const lit = alignRuns(ctx, query, contextBytes);
142
- const out = lit.map((r) => ({ ...r, weight: 1 }));
143
- if (!querySites || querySites.length === 0)
144
- return out;
145
- // Mark query positions ALREADY covered by literal runs — halo fills gaps.
146
- // If literal coverage is already complete, skip the halo step entirely
147
- // (recognise is O(|ctx|·W) — wasted when every byte is accounted for).
148
- const covered = new Uint8Array(query.length);
149
- let gaps = false;
150
- for (const r of lit) {
151
- for (let i = r.qs; i < r.qe; i++)
152
- covered[i] = 1;
153
- }
154
- for (let i = 0; i < query.length; i++) {
155
- if (!covered[i]) {
156
- gaps = true;
157
- break;
158
- }
159
- }
160
- if (!gaps)
161
- return out;
162
- // Recognise sites in the exemplar context — structural positions for halo
163
- // matching. (Circular import with recognition.ts is safe: recognise() is
164
- // called lazily, never at module load — the same pattern `segment` uses.)
165
- const ctxSites = recognise(ctx, contextBytes).sites;
166
- if (ctxSites.length === 0)
167
- return out;
168
- // Context sites with halos, hoisted: the same set serves every query site.
169
- const ctxCands = ctxSites.filter((cs) => ctx.store.hasHalo(cs.payload));
170
- if (ctxCands.length === 0)
171
- return out;
172
- // Candidate halos, also hoisted (lazily, first query site that needs them):
173
- // bestHaloMate consults every candidate's halo PER QUERY SITE, and sites
174
- // share the candidate set — without this memo the same few dozen halos were
175
- // re-fetched thousands of times per response. Distinct payloads can repeat
176
- // across sites, hence the map by payload id.
177
- const ctxHalos = new Map();
178
- const ctxHaloOf = (cs) => {
179
- let h = ctxHalos.get(cs.payload);
180
- if (h === undefined) {
181
- h = ctx.store.halo(cs.payload);
182
- ctxHalos.set(cs.payload, h);
183
- }
184
- return h;
185
- };
186
- for (const qs of querySites) {
187
- // Only sites that overlap UNCOVERED query regions add new evidence.
188
- let touchesGap = false;
189
- for (let i = qs.start; i < qs.end; i++) {
190
- if (!covered[i]) {
191
- touchesGap = true;
192
- break;
193
- }
194
- }
195
- if (!touchesGap)
196
- continue;
197
- const qHalo = ctx.store.halo(qs.payload);
198
- if (!qHalo)
199
- continue;
200
- // bestHaloMate already gates at conceptThreshold — no second check needed.
201
- const match = bestHaloMate(ctx, qHalo, ctxCands, ctxHaloOf);
202
- if (match === null)
203
- continue;
204
- out.push({
205
- qs: qs.start,
206
- qe: qs.end,
207
- cs: match.item.start,
208
- weight: match.score,
209
- });
210
- }
211
- out.sort((a, b) => a.qs - b.qs);
212
- return out;
213
- }
214
- /** The IN-LIST halo matcher: the best halo-mate for `halo` among EXPLICIT
215
- * candidates, above the concept threshold — the list counterpart of
216
- * {@link haloSiblings}, which asks the halo INDEX for candidates instead.
217
- * Behind locate()'s halo step and articulation's voice matching; a third
218
- * "best halo among these" decision must come here, not inline. */
219
- export function bestHaloMate(ctx, halo, items, haloOf) {
220
- return argmaxCosine(halo, items, haloOf, conceptThreshold(ctx.store.D));
221
- }
222
- /** The HALO-SIBLING matcher: the nodes that keep the same distributional
223
- * company as `id`, nearest first — `resonateHalo` filtered to exclude the
224
- * node itself and everything below `bar` (default: the concept threshold).
225
- * `halo`, when the caller has already read the node's halo row, is reused
226
- * instead of refetched (one read per relation). Returns [] for a node with
227
- * no halo. The one sibling enumeration behind the concept hop, the
228
- * reasoning stage's synonym expansion, and the analogy matcher below. */
229
- const haloSiblingMemo = new WeakMap();
230
- export async function haloSiblings(ctx, id, halo, bar = conceptThreshold(ctx.store.D)) {
231
- // Per-response memo for the DEFAULT-ARGUMENT reading (the one the concept
232
- // hop, the bridge's synonym tier, and reasoning's synonym expansion all
233
- // use): the same node's siblings are asked for repeatedly within one
234
- // response (bridge pairs share sides), each a full halo-ANN query, and the
235
- // store is read-only while a response is in flight. Keyed by the response
236
- // lifecycle object (ctx.climbMemo — fresh per respond, nulled after).
237
- // Calls with an explicit halo or bar (analogyStrength's gated reading)
238
- // bypass the memo — their filter differs.
239
- const memoable = halo === undefined &&
240
- bar === conceptThreshold(ctx.store.D) && ctx.climbMemo !== null;
241
- let memo;
242
- if (memoable) {
243
- memo = haloSiblingMemo.get(ctx.climbMemo);
244
- if (memo === undefined) {
245
- haloSiblingMemo.set(ctx.climbMemo, memo = new Map());
246
- }
247
- const hit = memo.get(id);
248
- if (hit !== undefined)
249
- return hit;
250
- }
251
- const h = halo ?? ctx.store.halo(id);
252
- const out = h
253
- ? (await ctx.store.resonateHalo(h, ctx.cfg.haloQueryK))
254
- .filter((sib) => sib.id !== id && sib.score >= bar)
255
- : [];
256
- if (memo !== undefined)
257
- memo.set(id, out);
258
- return out;
259
- }
260
- export async function analogyStrength(ctx, a, b) {
261
- const ha = ctx.store.halo(a);
262
- const hb = ctx.store.halo(b);
263
- if (ha && hb) {
264
- const bar = significanceBar(ctx.store.D);
265
- const direct = cosine(ha, hb);
266
- if (direct >= bar)
267
- return { score: direct, halo: true };
268
- const sibsA = await haloSiblings(ctx, a, ha, bar);
269
- const sibsB = await haloSiblings(ctx, b, hb, bar);
270
- let best = 0;
271
- for (const x of sibsA) {
272
- if (x.id === b)
273
- continue;
274
- const y = sibsB.find((s) => s.id === x.id);
275
- if (y !== undefined) {
276
- best = Math.max(best, Math.min(x.score, y.score));
277
- }
278
- }
279
- if (best > 0)
280
- return { score: best, halo: true };
281
- }
282
- return { score: sharedFrameStrength(ctx, a, b), halo: false };
283
- }
284
- /** The STRUCTURAL analogy tier: two nodes are analogs when their byte
285
- * streams share a LEARNT frame — a content-addressed flat form of at least
286
- * one full river window (W bytes, the perception quantum) that occurs in
287
- * BOTH. This is what "playing the same role" means structurally: "Ice is
288
- * cold" and "Steel is hard" share the learnt " is " frame even though they
289
- * keep disjoint distributional company. Halos measure company by IDENTITY
290
- * (company signatures — see sema.ts), so unrelated-company analogs must be
291
- * validated by the frame itself, not by content leaking through halo
292
- * vectors. Strength is the shared learnt coverage of the SHORTER side —
293
- * a fraction, comparable to the cosine tiers above. Derived: the window
294
- * is maxGroup, the same quantum differsByOneWindow and canonicalChunkId
295
- * measure by; no tuned constants. */
296
- export function sharedFrameStrength(ctx, a, b) {
297
- const W = ctx.space.maxGroup;
298
- const A = read(ctx, a);
299
- const B = read(ctx, b);
300
- if (A.length < W || B.length < W)
301
- return 0;
302
- // Mark every byte of the shorter side covered by a learnt W-window that
303
- // also occurs in the longer side.
304
- const [s, l] = A.length <= B.length ? [A, B] : [B, A];
305
- const covered = new Uint8Array(s.length);
306
- for (let off = 0; off + W <= s.length; off++) {
307
- const win = s.subarray(off, off + W);
308
- // Learnt: the window resolves as a content-addressed flat form.
309
- const ids = leafIdRun(ctx, s, off, off + W);
310
- if (ids === null || ctx.store.findBranch(ids) === null)
311
- continue;
312
- if (indexOf(l, win, 0) < 0)
313
- continue;
314
- covered.fill(1, off, off + W);
315
- }
316
- let n = 0;
317
- for (let i = 0; i < s.length; i++)
318
- n += covered[i];
319
- return n >= W ? n / s.length : 0;
320
- }
321
- // ═══════════════════════════════════════════════════════════════════════════
322
- // PROJECTIONS — what a matched node is projected ALONG (the direction)
323
- // ═══════════════════════════════════════════════════════════════════════════
324
- /** FORWARD through a synonym: the continuation an edge-less node borrows from
325
- * a concept (halo) sibling — resonate the node's halo, take the first
326
- * sibling above the concept threshold that itself has a direct edge. */
327
- export async function conceptHop(ctx, id) {
328
- for (const sib of await haloSiblings(ctx, id)) {
329
- const hop = guidedFirst(ctx, sib.id);
330
- if (hop !== undefined)
331
- return hop;
332
- }
333
- return null;
334
- }
335
- /** FORWARD projection: follow continuation edges from a node to its fixpoint.
336
- * The first hop may cross a concept (halo) link — a synonym. The rest
337
- * follow direct edges. Convergence is intrinsic: the seen set guards
338
- * against cycles. `guide` disambiguates multi-continuation nodes by
339
- * resonance. */
340
- export async function follow(ctx, id, guide) {
341
- const seen = new Set([id]);
342
- // First hop: a direct edge, else a concept sibling's edge (the synonym).
343
- let next = chooseNext(ctx, id, guide);
344
- if (next === undefined) {
345
- const hop = await conceptHop(ctx, id);
346
- if (hop === null)
347
- return null;
348
- next = hop;
349
- }
350
- // Direct successors to the fixpoint. Only the FIXPOINT's bytes are
351
- // returned, so the walk tracks node ids and reads bytes exactly once at
352
- // the end — a K-hop chain used to pay K full reconstructions and discard
353
- // K−1 of them.
354
- while (!seen.has(next)) {
355
- seen.add(next);
356
- const fwd = chooseNext(ctx, next, guide);
357
- if (fwd === undefined || seen.has(fwd))
358
- break;
359
- next = fwd;
360
- }
361
- return read(ctx, next);
362
- }
363
- /** REVERSE projection: the context a learnt continuation follows, voiced as
364
- * bytes. A common continuation ("Yes.") follows MANY contexts; with a
365
- * `guide` the context whose gist resonates with the query wins (seat
366
- * symmetry) — without one, the most-corroborated context wins (poured halo
367
- * MASS, the direct measure of how many episodes established it), falling
368
- * back to first-learnt on equal mass. Among many predecessors RECIPROCAL
369
- * ones (mutual edges) are preferred when any exist (RC5). Callers that
370
- * HAVE a query gist must pass it, or they silently change disambiguation
371
- * regime.
372
- *
373
- * `rev`, when the caller has already materialised prevOf (one read per
374
- * relation — a hub's reverse fan-in is corpus-sized), is reused instead of
375
- * refetched. Returns null when there is no predecessor or the picked
376
- * context reads empty (a zero-length context is no grounding: an empty
377
- * Uint8Array is truthy, and returning it would flow a hollow "answer"
378
- * onward). */
379
- export function reverseContext(ctx, id, guide, rev) {
380
- // CAPPED default read: only the first √N predecessors are ever candidates
381
- // (hubCap below / in chooseAmong), so only they are read. hubBound ≥ 2
382
- // keeps the single-predecessor shortcut exact.
383
- const candidates = rev ?? ctx.store.prevFirst(id, hubBound(ctx));
384
- if (candidates.length === 0)
385
- return null;
386
- // RECIPROCAL PREFERENCE: among many predecessors, one that `id` also
387
- // continues TO (cand → id AND id → cand both learnt) is a mutually
388
- // established pairing — the strongest structural evidence a predecessor
389
- // can carry (bidirectional training deposits both directions of a genuine
390
- // pair). A bare predecessor is one episode's adjacency; guide-resonance
391
- // over bare predecessors favours whichever stored document merely
392
- // CONTAINS the query's bytes (the linear fold's cosine is byte overlap —
393
- // the observed "merci → unrelated French document" failure). One capped
394
- // forward read decides; when no reciprocal exists, behaviour is unchanged
395
- // — bare predecessors ARE the honest answer for a shared deposited
396
- // continuation (two questions → one answer; audited by 31-audit C1), and
397
- // this arm serves every mechanism's reverse projection, so abstaining
398
- // here starves far more than the one containment failure it would fix.
399
- let pool = candidates;
400
- if (candidates.length > 1) {
401
- const fwd = new Set(ctx.store.nextFirst(id, hubBound(ctx)));
402
- if (fwd.size > 0) {
403
- const mutual = candidates.filter((c) => fwd.has(c));
404
- if (mutual.length > 0)
405
- pool = mutual;
406
- }
407
- }
408
- const pick = pool.length === 1
409
- ? pool[0]
410
- : guide
411
- ? chooseAmong(ctx, pool, guide).id
412
- : pickByMass(ctx, pool);
413
- const g = read(ctx, pick);
414
- return g.length > 0 ? g : null;
415
- }
416
- /** The most-corroborated candidate by poured halo mass (first-seen wins a
417
- * tie). Capped at √N candidates by insertion order — the same hub bound
418
- * every fan-out walk uses. */
419
- function pickByMass(ctx, ids) {
420
- const capped = hubCap(ctx, ids);
421
- let best = capped[0];
422
- let bestMass = ctx.store.haloMass(best);
423
- for (let i = 1; i < capped.length; i++) {
424
- const mass = ctx.store.haloMass(capped[i]);
425
- if (mass > bestMass) {
426
- best = capped[i];
427
- bestMass = mass;
428
- }
429
- }
430
- return best;
431
- }
432
- /** THE projection: ground a matched node to answer bytes — FORWARD to its
433
- * continuation fixpoint (which may cross a concept hop), else REVERSE to
434
- * the context it follows. This is the direction ladder every mechanism's
435
- * final grounding step reduces to. */
436
- export async function project(ctx, id, guide) {
437
- const fc = await follow(ctx, id, guide);
438
- if (fc)
439
- return fc;
440
- return reverseContext(ctx, id, guide);
441
- }
@@ -1,4 +0,0 @@
1
- import type { Alu } from "../../alu/src/alu.js";
2
- import type { PipelineMechanism } from "../pipeline-mechanism.js";
3
- /** Wrap the ALU as a {@link PipelineMechanism}. */
4
- export declare function aluToMechanism(alu: Alu): PipelineMechanism;
@@ -1,36 +0,0 @@
1
- // mechanisms/alu.ts — the ALU wrapped as an ordinary PipelineMechanism.
2
- //
3
- // The ALU is a self-contained sublibrary (src/alu) that knows nothing about
4
- // the pipeline; this adapter is the whole coupling. Its `parse` populates
5
- // `pre.computed` before the grounding loop; the cover mechanism handles
6
- // masking (see mechanisms/cover.ts). The ALU's own trace steps
7
- // (`evalComputation`) are emitted inside its `parse()`. A user extension
8
- // joins the same way — see MindOptions.mechanismFactories.
9
- import { STEP } from "../graph-search.js";
10
- import { unexplainedLabel } from "../rationale.js";
11
- /** Wrap the ALU as a {@link PipelineMechanism}. */
12
- export function aluToMechanism(alu) {
13
- return {
14
- name: "alu",
15
- // Not a cover derivation: cover.ts composes an answer by walking
16
- // recognised query STRUCTURE; the ALU evaluates a recognised expression
17
- // to its authoritative result and hands the bytes back untouched. It
18
- // shares cover's near-zero floor (computation always wins, masked into
19
- // cover's own search — see mechanisms/cover.ts), but the candidate this
20
- // produces is not one of cover's derivations, so it carries its own
21
- // honest label, the same way extract/cast/recall each carry theirs.
22
- provenance: "alu",
23
- parse: (query) => alu.parse(query),
24
- async floor(_ctx, _query, pre, _worthRunning) {
25
- return pre.computed.length > 0 ? 0 : null;
26
- },
27
- async run(_ctx, query, pre) {
28
- return pre.computed.map((u) => ({
29
- bytes: u.bytes,
30
- accounted: [[u.i, u.j]],
31
- moves: STEP,
32
- unexplained: unexplainedLabel(query, [[u.i, u.j]]),
33
- }));
34
- },
35
- };
36
- }