@hviana/sema 0.4.1 → 0.4.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 (152) hide show
  1. package/package.json +1 -1
  2. package/src/ingest-cache.ts +4 -0
  3. package/src/meter.ts +5 -0
  4. package/src/mind/attention.ts +18 -1
  5. package/src/mind/bridge.ts +292 -54
  6. package/src/mind/junction.ts +21 -7
  7. package/src/mind/match.ts +92 -1
  8. package/src/mind/mechanisms/cast.ts +12 -0
  9. package/src/mind/mechanisms/confluence.ts +30 -1
  10. package/src/mind/mechanisms/cover.ts +36 -4
  11. package/src/mind/mechanisms/recall.ts +21 -44
  12. package/src/mind/mind.ts +39 -2
  13. package/src/mind/pipeline-mechanism.ts +86 -4
  14. package/src/mind/pipeline.ts +1 -1
  15. package/src/mind/reasoning.ts +15 -8
  16. package/src/mind/recognition.ts +40 -0
  17. package/src/mind/resonance.ts +0 -0
  18. package/src/mind/traverse.ts +17 -15
  19. package/src/mind/types.ts +10 -0
  20. package/test/49-natural-units-synonym-bridge.test.mjs +56 -15
  21. package/dist/example/demo.d.ts +0 -1
  22. package/dist/example/demo.js +0 -39
  23. package/dist/example/train_base.d.ts +0 -87
  24. package/dist/example/train_base.js +0 -2252
  25. package/dist/src/alphabet.d.ts +0 -7
  26. package/dist/src/alphabet.js +0 -33
  27. package/dist/src/alu/src/alu.d.ts +0 -185
  28. package/dist/src/alu/src/alu.js +0 -440
  29. package/dist/src/alu/src/expr.d.ts +0 -61
  30. package/dist/src/alu/src/expr.js +0 -318
  31. package/dist/src/alu/src/index.d.ts +0 -11
  32. package/dist/src/alu/src/index.js +0 -19
  33. package/dist/src/alu/src/kernel-arith.d.ts +0 -16
  34. package/dist/src/alu/src/kernel-arith.js +0 -264
  35. package/dist/src/alu/src/kernel-bits.d.ts +0 -19
  36. package/dist/src/alu/src/kernel-bits.js +0 -152
  37. package/dist/src/alu/src/kernel-logic.d.ts +0 -4
  38. package/dist/src/alu/src/kernel-logic.js +0 -60
  39. package/dist/src/alu/src/kernel-nd.d.ts +0 -3
  40. package/dist/src/alu/src/kernel-nd.js +0 -208
  41. package/dist/src/alu/src/kernel-numeric.d.ts +0 -54
  42. package/dist/src/alu/src/kernel-numeric.js +0 -366
  43. package/dist/src/alu/src/operation.d.ts +0 -168
  44. package/dist/src/alu/src/operation.js +0 -189
  45. package/dist/src/alu/src/parser.d.ts +0 -221
  46. package/dist/src/alu/src/parser.js +0 -577
  47. package/dist/src/alu/src/resonance.d.ts +0 -55
  48. package/dist/src/alu/src/resonance.js +0 -126
  49. package/dist/src/alu/src/text.d.ts +0 -31
  50. package/dist/src/alu/src/text.js +0 -73
  51. package/dist/src/alu/src/value.d.ts +0 -109
  52. package/dist/src/alu/src/value.js +0 -300
  53. package/dist/src/alu/test/alu.test.d.ts +0 -1
  54. package/dist/src/alu/test/alu.test.js +0 -764
  55. package/dist/src/bytes.d.ts +0 -14
  56. package/dist/src/bytes.js +0 -59
  57. package/dist/src/canon.d.ts +0 -26
  58. package/dist/src/canon.js +0 -57
  59. package/dist/src/config.d.ts +0 -111
  60. package/dist/src/config.js +0 -91
  61. package/dist/src/derive/src/deduction.d.ts +0 -136
  62. package/dist/src/derive/src/deduction.js +0 -159
  63. package/dist/src/derive/src/index.d.ts +0 -8
  64. package/dist/src/derive/src/index.js +0 -11
  65. package/dist/src/derive/src/priority-queue.d.ts +0 -20
  66. package/dist/src/derive/src/priority-queue.js +0 -73
  67. package/dist/src/derive/src/rewrite.d.ts +0 -56
  68. package/dist/src/derive/src/rewrite.js +0 -100
  69. package/dist/src/derive/src/trie.d.ts +0 -90
  70. package/dist/src/derive/src/trie.js +0 -217
  71. package/dist/src/derive/test/derive.test.d.ts +0 -1
  72. package/dist/src/derive/test/derive.test.js +0 -122
  73. package/dist/src/extension.d.ts +0 -37
  74. package/dist/src/extension.js +0 -7
  75. package/dist/src/geometry.d.ts +0 -175
  76. package/dist/src/geometry.js +0 -823
  77. package/dist/src/index.d.ts +0 -17
  78. package/dist/src/index.js +0 -19
  79. package/dist/src/ingest-cache.d.ts +0 -41
  80. package/dist/src/ingest-cache.js +0 -161
  81. package/dist/src/meter.d.ts +0 -171
  82. package/dist/src/meter.js +0 -269
  83. package/dist/src/mind/articulation.d.ts +0 -6
  84. package/dist/src/mind/articulation.js +0 -99
  85. package/dist/src/mind/attention.d.ts +0 -414
  86. package/dist/src/mind/attention.js +0 -2065
  87. package/dist/src/mind/bridge.d.ts +0 -39
  88. package/dist/src/mind/bridge.js +0 -738
  89. package/dist/src/mind/canonical.d.ts +0 -34
  90. package/dist/src/mind/canonical.js +0 -93
  91. package/dist/src/mind/graph-search.d.ts +0 -294
  92. package/dist/src/mind/graph-search.js +0 -996
  93. package/dist/src/mind/index.d.ts +0 -9
  94. package/dist/src/mind/index.js +0 -5
  95. package/dist/src/mind/junction.d.ts +0 -134
  96. package/dist/src/mind/junction.js +0 -331
  97. package/dist/src/mind/learning.d.ts +0 -75
  98. package/dist/src/mind/learning.js +0 -270
  99. package/dist/src/mind/match.d.ts +0 -166
  100. package/dist/src/mind/match.js +0 -565
  101. package/dist/src/mind/mechanisms/alu.d.ts +0 -4
  102. package/dist/src/mind/mechanisms/alu.js +0 -36
  103. package/dist/src/mind/mechanisms/cast.d.ts +0 -89
  104. package/dist/src/mind/mechanisms/cast.js +0 -773
  105. package/dist/src/mind/mechanisms/confluence.d.ts +0 -24
  106. package/dist/src/mind/mechanisms/confluence.js +0 -225
  107. package/dist/src/mind/mechanisms/cover.d.ts +0 -6
  108. package/dist/src/mind/mechanisms/cover.js +0 -203
  109. package/dist/src/mind/mechanisms/extraction.d.ts +0 -33
  110. package/dist/src/mind/mechanisms/extraction.js +0 -300
  111. package/dist/src/mind/mechanisms/recall.d.ts +0 -16
  112. package/dist/src/mind/mechanisms/recall.js +0 -388
  113. package/dist/src/mind/mind.d.ts +0 -330
  114. package/dist/src/mind/mind.js +0 -594
  115. package/dist/src/mind/pipeline-mechanism.d.ts +0 -172
  116. package/dist/src/mind/pipeline-mechanism.js +0 -382
  117. package/dist/src/mind/pipeline.d.ts +0 -49
  118. package/dist/src/mind/pipeline.js +0 -275
  119. package/dist/src/mind/primitives.d.ts +0 -66
  120. package/dist/src/mind/primitives.js +0 -306
  121. package/dist/src/mind/rationale.d.ts +0 -139
  122. package/dist/src/mind/rationale.js +0 -163
  123. package/dist/src/mind/reasoning.d.ts +0 -40
  124. package/dist/src/mind/reasoning.js +0 -272
  125. package/dist/src/mind/recognition.d.ts +0 -20
  126. package/dist/src/mind/recognition.js +0 -463
  127. package/dist/src/mind/resonance.d.ts +0 -23
  128. package/dist/src/mind/resonance.js +0 -0
  129. package/dist/src/mind/trace.d.ts +0 -15
  130. package/dist/src/mind/trace.js +0 -73
  131. package/dist/src/mind/traverse.d.ts +0 -124
  132. package/dist/src/mind/traverse.js +0 -649
  133. package/dist/src/mind/types.d.ts +0 -323
  134. package/dist/src/mind/types.js +0 -130
  135. package/dist/src/rabitq-ivf/src/database.d.ts +0 -113
  136. package/dist/src/rabitq-ivf/src/database.js +0 -201
  137. package/dist/src/rabitq-ivf/src/index.d.ts +0 -7
  138. package/dist/src/rabitq-ivf/src/index.js +0 -4
  139. package/dist/src/rabitq-ivf/src/ivf.d.ts +0 -200
  140. package/dist/src/rabitq-ivf/src/ivf.js +0 -1165
  141. package/dist/src/rabitq-ivf/src/prng.d.ts +0 -19
  142. package/dist/src/rabitq-ivf/src/prng.js +0 -36
  143. package/dist/src/rabitq-ivf/src/rabitq.d.ts +0 -95
  144. package/dist/src/rabitq-ivf/src/rabitq.js +0 -283
  145. package/dist/src/sema.d.ts +0 -31
  146. package/dist/src/sema.js +0 -63
  147. package/dist/src/store-sqlite.d.ts +0 -184
  148. package/dist/src/store-sqlite.js +0 -942
  149. package/dist/src/store.d.ts +0 -678
  150. package/dist/src/store.js +0 -1703
  151. package/dist/src/vec.d.ts +0 -31
  152. package/dist/src/vec.js +0 -109
@@ -1,172 +0,0 @@
1
- import type { AncestorReach, MindContext, Recognition } from "./types.js";
2
- import type { AttentionRead } from "./types.js";
3
- import type { ComputedSpan } from "../extension.js";
4
- import type { Vec } from "../vec.js";
5
- import { type GradedRun } from "./match.js";
6
- export declare class Precomputed {
7
- readonly ctx: MindContext;
8
- readonly query: Uint8Array;
9
- /** Recognition result (structural + canonical). */
10
- readonly rec: Recognition;
11
- /** Computed spans from mechanisms that implement `parse()` (e.g. ALU). */
12
- readonly computed: ComputedSpan[];
13
- /** The query's gist — the response-wide disambiguation guide. */
14
- readonly guide: Vec;
15
- /** The response's evidence-breadth constant: how many ranked candidates the
16
- * resonance probes, the weave alignment, and the climb all consider.
17
- * Derived once from config; every consumer reads it here. */
18
- readonly k: number;
19
- constructor(ctx: MindContext, query: Uint8Array,
20
- /** Recognition result (structural + canonical). */
21
- rec: Recognition,
22
- /** Computed spans from mechanisms that implement `parse()` (e.g. ALU). */
23
- computed: ComputedSpan[],
24
- /** The query's gist — the response-wide disambiguation guide. */
25
- guide: Vec);
26
- private _windows?;
27
- /** Content-addressed W-window identities for every position in the query
28
- * (offset → node id). O(|query|) probes. */
29
- get queryWindows(): Map<number, number>;
30
- private _resolved?;
31
- /** The node id of the query itself, or null when it is not a stored form.
32
- * O(|query|) probes. */
33
- get queryResolved(): number | null;
34
- private _anchorWindows;
35
- /** Content-addressed W-window identities of one anchor's own bytes
36
- * (offset → node id), memoised per anchor. Confluence intersects these;
37
- * any future identity-based mechanism reads the same cache. */
38
- windowsOf(anchor: number): Map<number, number>;
39
- /** Shared memo for {@link reachOf} (structural-IDF reads): a window's
40
- * ancestor reach is a pure function of the read-only store, so one memo
41
- * serves every mechanism that prices commonality — AND the consensus
42
- * climb, which is the largest consumer and used to build its own. The
43
- * ONE definition of its lifetime lives in traverse.ts
44
- * ({@link sharedReachMemo}): response-scoped for respond(),
45
- * conversation-scoped across turns, always cold under a trace. */
46
- private _reach?;
47
- get reachMemo(): Map<number, AncestorReach>;
48
- /** Charge a lazily-shared analysis to its OWN phase rather than to the
49
- * mechanism that happened to first-touch it. Without this the profile
50
- * reads as "cast.floor costs 2 s" when what actually cost 2 s is the
51
- * consensus climb — which cast merely paid for on everyone's behalf, and
52
- * which every later consumer then got free. Attribution must follow the
53
- * work, not the caller. */
54
- private shared;
55
- private _attention?;
56
- /** The full consensus climb (roots + ranked anchors) — the query-level
57
- * evidence CAST, confluence, extraction, recall's scaffolding tier, and
58
- * fusion all share. Computed on first access; a query no mechanism
59
- * climbs for (e.g. one an extension decided outright) never pays for it. */
60
- attention(): Promise<AttentionRead>;
61
- private _weave?;
62
- /** Result of {@link alignGraded} for the first k ranked anchors —
63
- * O(k · |query| · |ctx|). Consumed by CAST; reusable by any future
64
- * mechanism doing analogical transfer. */
65
- weave(): Promise<WeaveInfo>;
66
- /** Span-shaped classification of one ranked anchor, memoised per anchor id
67
- * so repeated calls (extraction's own early-exit scan, any future
68
- * template-based mechanism) never redo the work. Deliberately NOT an
69
- * eager all-anchors map: `skillExemplar` is the expensive part of
70
- * extraction (capped fan-out reads plus an O(|ctx|) scan), and most
71
- * queries are answered by the FIRST ranked anchor that qualifies — paying
72
- * for every ranked anchor regardless of where the scan stops would turn
73
- * an early-exit lookup into full O(k) work on every query. */
74
- private _spanShaped;
75
- spanShapedOf(anchor: number): Promise<SkillInfo | null>;
76
- /** Every ranked anchor's classification at once, sharing the same
77
- * per-anchor cache as {@link spanShapedOf} — for a mechanism that
78
- * genuinely needs the full picture (not an early-exit scan). Mixing
79
- * access patterns across mechanisms never duplicates work: whichever
80
- * anchors an early-exit consumer already asked for are reused here, and
81
- * whichever this computes first are reused by a later early-exit scan. */
82
- spanShapedAll(): Promise<Map<number, SkillInfo | null>>;
83
- }
84
- /** The weave-local structural alignment, computed once and consumed by CAST
85
- * (and any future mechanism doing analogical transfer). */
86
- export interface WeaveInfo {
87
- /** Per-anchor alignment: context bytes, vote weight, and graded runs. */
88
- points: Array<{
89
- anchor: number;
90
- vote: number;
91
- ctx: Uint8Array;
92
- runs: GradedRun[];
93
- }>;
94
- /** Weighted depth at each query byte — sum of alignment weights.
95
- * `depth[i]` is the total evidence that byte i is shared among the
96
- * aligned structures. */
97
- depth: Float64Array;
98
- }
99
- /** Span-shaped classification of one anchor — the structural information
100
- * extraction uses to decide whether a learned fact can serve as a template
101
- * for reading an analogous span out of the query. */
102
- export interface SkillInfo {
103
- contextBytes: Uint8Array;
104
- answerBytes: Uint8Array;
105
- }
106
- /** Raw result from a mechanism's `run()`. The pipeline computes the weight
107
- * from `moves` + `PASS * unaccounted(accounted)` — the mechanism does not
108
- * know about the cost ladder.
109
- *
110
- * When `weight` is present, the pipeline uses it directly instead of
111
- * computing `weigh(accounted, moves)`. This is for mechanisms whose cost
112
- * is derived externally (e.g. cover: the A*LD derivation's g-value). */
113
- export interface MechanismResult {
114
- bytes: Uint8Array;
115
- accounted: Array<[number, number]>;
116
- moves: number;
117
- used?: ReadonlySet<number>;
118
- unexplained: string;
119
- /** Explicit weight override. When absent, weight = moves + PASS·unaccounted. */
120
- weight?: number;
121
- /** Override the mechanism's default provenance for this result.
122
- * When absent, the pipeline uses `mech.provenance`. */
123
- provenance?: string;
124
- /** This grounding is a COMPLETE trained answer — post-grounding must not
125
- * extend it. Declared by the mechanism about its own result, exactly like
126
- * `accounted`/`used`/`unexplained`; the decider honours the property and
127
- * never asks which mechanism set it, so the market stays uniform.
128
- *
129
- * Set it only when the answer is a stored form's OWN continuation reached
130
- * through an identity claim about the query — i.e. the query IS some
131
- * trained context, so its continuation is the whole read-out and a further
132
- * multi-hop pivot would chain PAST the fact that produced the answer.
133
- * That is the same reasoning `reason`'s echo guard already applies to a
134
- * query that resolves exactly (see reasoning.ts); this carries the claim
135
- * for the mechanisms that establish the identity by another route.
136
- *
137
- * Observed without it: the correct "What is the process of
138
- * photosynthesis?" grounding was pivoted forward four times, out of the
139
- * fact that answered it and into an unrelated "Hello! How can I assist you
140
- * today?" conversational turn. */
141
- complete?: boolean;
142
- }
143
- export interface PipelineMechanism {
144
- /** Stable identifier for trace/debug. */
145
- readonly name: string;
146
- /** Which provenance tag the pipeline attaches to this mechanism's answers. */
147
- readonly provenance: string;
148
- /** Parse authoritative spans BEFORE the grounding loop.
149
- * Only needed by computational mechanisms (e.g. ALU). Results from ALL
150
- * mechanisms that implement this are collected into `Precomputed.computed`
151
- * before any `floor()` or `run()` is called. */
152
- parse?(query: Uint8Array): Promise<ComputedSpan[]>;
153
- /** Admissible lower bound on this mechanism's weight.
154
- * Returns `null` when the mechanism structurally cannot fire.
155
- *
156
- * `worthRunning(cheapFloor)` reports whether the CURRENT incumbent
157
- * (established by mechanisms that already ran this response, cover being
158
- * first — see `defaultMechanisms`) could still be beaten by a floor no
159
- * tighter than `cheapFloor`. THE INVESTMENT DISCIPLINE: before
160
- * first-touching an expensive shared analysis (`pre.attention()`,
161
- * `pre.weave()`, …), check `worthRunning(bound)` with this mechanism's
162
- * cheapest possible bound — and when it fails, RETURN THE BOUND rather
163
- * than null. The bound is still admissible (it never overstates cost),
164
- * the pipeline's own check then prunes `run()` and records the truthful
165
- * "cannot beat incumbent" trace note, and no analysis was computed just
166
- * to be discarded. This is uniform: no mechanism asks what produced the
167
- * incumbent — a computed extension result and an ordinary cheap cover
168
- * prune the same way. */
169
- floor(ctx: MindContext, query: Uint8Array, pre: Precomputed, worthRunning: (floor: number) => boolean): Promise<number | null>;
170
- /** Produce candidate answers. */
171
- run(ctx: MindContext, query: Uint8Array, pre: Precomputed): Promise<MechanismResult[]>;
172
- }
@@ -1,382 +0,0 @@
1
- // pipeline-mechanism.ts — the uniform grounding-mechanism interface.
2
- //
3
- // Every grounding mechanism (CAST, confluence, cover, extraction, recall, ALU,
4
- // user extensions) implements this ONE interface. The pipeline (think()) sees
5
- // a list of PipelineMechanism objects — it never imports a mechanism-specific
6
- // type and never has a special-case branch for any mechanism.
7
- //
8
- // The four constraints of the free-will architecture (§14.5):
9
- // 1. DECOUPLING — mechanisms import nothing from each other or from pipeline.
10
- // 2. DECLARED COMPETENCE — floor() returns null when impossible, a number when
11
- // possible. Binary, auditable, no learned scores.
12
- // 3. VISIBLE BUDGET — every mechanism carries its own caps internally (√N, k).
13
- // 4. TRAVELING EVIDENCE — run() returns MechanismResult with accounted, moves,
14
- // and unexplained. The pipeline computes the weight.
15
- import { indexOf } from "../bytes.js";
16
- import { dominates } from "../geometry.js";
17
- import { windowIds } from "./canonical.js";
18
- import { read, resolve } from "./primitives.js";
19
- import { alignGraded, skillExemplar } from "./match.js";
20
- import { climbAttentionAll } from "./attention.js";
21
- import { sharedReachMemo } from "./traverse.js";
22
- // ── Precomputed ──────────────────────────────────────────────────────────────
23
- //
24
- // Precomputed is a LAZY container for structural analyses of the query — the
25
- // ONE place a response's shared evidence lives, for inter-mechanism exchange
26
- // and for analyses future mechanisms will want. Eager fields (rec, computed,
27
- // guide) are populated by the pipeline before the mechanism loop; everything
28
- // expensive is a lazily-cached method that computes on first access. A
29
- // mechanism that never asks for an analysis pays nothing for it; two
30
- // mechanisms asking for the same analysis pay once.
31
- //
32
- // This design serves THREE purposes:
33
- // 1. SHARING — when two mechanisms need the same analysis, it's computed once
34
- // (even under trace, where the ctx-level memos are deliberately bypassed).
35
- // 2. EXTENSIBILITY — a new analysis is one method in one file.
36
- // 3. DECLARATIVE COST — a mechanism's floor() checks its cheap gates and the
37
- // pipeline's `worthRunning` predicate BEFORE first-touching an expensive
38
- // analysis, so lazy analyses are only ever computed for a mechanism that
39
- // could still win.
40
- export class Precomputed {
41
- ctx;
42
- query;
43
- rec;
44
- computed;
45
- guide;
46
- /** The response's evidence-breadth constant: how many ranked candidates the
47
- * resonance probes, the weave alignment, and the climb all consider.
48
- * Derived once from config; every consumer reads it here. */
49
- k;
50
- constructor(ctx, query,
51
- /** Recognition result (structural + canonical). */
52
- rec,
53
- /** Computed spans from mechanisms that implement `parse()` (e.g. ALU). */
54
- computed,
55
- /** The query's gist — the response-wide disambiguation guide. */
56
- guide) {
57
- this.ctx = ctx;
58
- this.query = query;
59
- this.rec = rec;
60
- this.computed = computed;
61
- this.guide = guide;
62
- this.k = ctx.cfg.recallQueryK * 2;
63
- }
64
- // ── Cheap lazy analyses ───────────────────────────────────────────────
65
- _windows;
66
- /** Content-addressed W-window identities for every position in the query
67
- * (offset → node id). O(|query|) probes. */
68
- get queryWindows() {
69
- return this._windows ??= windowIds(this.ctx, this.query);
70
- }
71
- _resolved;
72
- /** The node id of the query itself, or null when it is not a stored form.
73
- * O(|query|) probes. */
74
- get queryResolved() {
75
- if (this._resolved === undefined) {
76
- this._resolved = resolve(this.ctx, this.query);
77
- }
78
- return this._resolved;
79
- }
80
- _anchorWindows = new Map();
81
- /** Content-addressed W-window identities of one anchor's own bytes
82
- * (offset → node id), memoised per anchor. Confluence intersects these;
83
- * any future identity-based mechanism reads the same cache. */
84
- windowsOf(anchor) {
85
- let w = this._anchorWindows.get(anchor);
86
- if (w === undefined) {
87
- w = windowIds(this.ctx, read(this.ctx, anchor));
88
- this._anchorWindows.set(anchor, w);
89
- }
90
- return w;
91
- }
92
- /** Shared memo for {@link reachOf} (structural-IDF reads): a window's
93
- * ancestor reach is a pure function of the read-only store, so one memo
94
- * serves every mechanism that prices commonality — AND the consensus
95
- * climb, which is the largest consumer and used to build its own. The
96
- * ONE definition of its lifetime lives in traverse.ts
97
- * ({@link sharedReachMemo}): response-scoped for respond(),
98
- * conversation-scoped across turns, always cold under a trace. */
99
- _reach;
100
- get reachMemo() {
101
- return this._reach ??= sharedReachMemo(this.ctx);
102
- }
103
- // ── Expensive lazy analyses ───────────────────────────────────────────
104
- //
105
- // Async, cached-by-promise: the first caller starts the computation, every
106
- // later caller (any mechanism, any phase) awaits the same promise. A
107
- // mechanism MUST check its cheap floor gates and the pipeline's
108
- // `worthRunning` predicate before first-touching one of these.
109
- /** Charge a lazily-shared analysis to its OWN phase rather than to the
110
- * mechanism that happened to first-touch it. Without this the profile
111
- * reads as "cast.floor costs 2 s" when what actually cost 2 s is the
112
- * consensus climb — which cast merely paid for on everyone's behalf, and
113
- * which every later consumer then got free. Attribution must follow the
114
- * work, not the caller. */
115
- shared(phase, fn) {
116
- const meter = this.ctx.meter;
117
- return meter ? meter.time(phase, fn) : fn();
118
- }
119
- _attention;
120
- /** The full consensus climb (roots + ranked anchors) — the query-level
121
- * evidence CAST, confluence, extraction, recall's scaffolding tier, and
122
- * fusion all share. Computed on first access; a query no mechanism
123
- * climbs for (e.g. one an extension decided outright) never pays for it. */
124
- attention() {
125
- return this._attention ??= this.shared("attention", () => climbAttentionAll(this.ctx, this.query, this.k));
126
- }
127
- _weave;
128
- /** Result of {@link alignGraded} for the first k ranked anchors —
129
- * O(k · |query| · |ctx|). Consumed by CAST; reusable by any future
130
- * mechanism doing analogical transfer. */
131
- weave() {
132
- return this._weave ??= this.attention().then((climb) => this.shared("weave", async () => computeWeave(this.ctx, this.query, this, climb)));
133
- }
134
- /** Span-shaped classification of one ranked anchor, memoised per anchor id
135
- * so repeated calls (extraction's own early-exit scan, any future
136
- * template-based mechanism) never redo the work. Deliberately NOT an
137
- * eager all-anchors map: `skillExemplar` is the expensive part of
138
- * extraction (capped fan-out reads plus an O(|ctx|) scan), and most
139
- * queries are answered by the FIRST ranked anchor that qualifies — paying
140
- * for every ranked anchor regardless of where the scan stops would turn
141
- * an early-exit lookup into full O(k) work on every query. */
142
- _spanShaped = new Map();
143
- spanShapedOf(anchor) {
144
- let p = this._spanShaped.get(anchor);
145
- if (p === undefined) {
146
- p = this.shared("spanShaped", () => skillExemplar(this.ctx, anchor, this.guide));
147
- this._spanShaped.set(anchor, p);
148
- }
149
- return p;
150
- }
151
- /** Every ranked anchor's classification at once, sharing the same
152
- * per-anchor cache as {@link spanShapedOf} — for a mechanism that
153
- * genuinely needs the full picture (not an early-exit scan). Mixing
154
- * access patterns across mechanisms never duplicates work: whichever
155
- * anchors an early-exit consumer already asked for are reused here, and
156
- * whichever this computes first are reused by a later early-exit scan. */
157
- async spanShapedAll() {
158
- const { ranked } = await this.attention();
159
- const out = new Map();
160
- for (const cand of ranked) {
161
- if (out.has(cand.anchor))
162
- continue;
163
- out.set(cand.anchor, await this.spanShapedOf(cand.anchor));
164
- }
165
- return out;
166
- }
167
- }
168
- function computeWeave(ctx, query, pre, climb) {
169
- const quantum = ctx.space.maxGroup;
170
- const { ranked } = climb;
171
- const rankedCapped = ranked.length > pre.k ? ranked.slice(0, pre.k) : ranked;
172
- const depth = new Float64Array(query.length);
173
- const points = [];
174
- const byAnchor = new Map();
175
- // WEAVE-SCALE anchors only: CAST transfers structure between things the
176
- // QUERY weaves together — query-scale structures. A context an order of
177
- // magnitude beyond the query is not woven BY the query (the query can at
178
- // most quote a fragment of it, and fragment-level evidence is exactly what
179
- // recognition and the cover already handle); CAST's own comparison gate
180
- // demands `ctx.length ≤ query.length` before it fires, and its
181
- // substitution seats sit within a quantum of a context's start. W is the
182
- // perceptual quantum — the same scale multiplier the bridge's phrase-scale
183
- // contract uses. The prefix-capped read makes an oversized anchor cost a
184
- // bounded read instead of reconstructing (and then canonically
185
- // recognising) a corpus-sized deposit: profiled on a 17.7M-node store,
186
- // uncapped weaves spent 5–8s per query recognising conversation-length
187
- // anchors that could never form a weave point.
188
- const capBytes = query.length * quantum;
189
- // EXCLUSIVITY IS ARBITRATED BY THE CLIMB'S VOTE ORDER, DELIBERATELY. A query
190
- // byte can only be independent evidence for ONE point, so points are built in
191
- // ranked order and each new point's runs are trimmed against every point
192
- // already accepted; a point left with no run of a full quantum drops out of
193
- // the weave.
194
- //
195
- // That reads like first-come-wins — a point that merely ranked higher taking
196
- // a span from the point that actually explains it — and arbitrating by LOCAL
197
- // evidence instead (ownership of each byte to the longest covering run, then
198
- // the heavier weight, then rank) was implemented and MEASURED: test/29 went
199
- // 9/2 to 7/4, and the new failures name the reason. CAST requires the weave
200
- // to touch a COMMITTED point of attention ("2 aligned structure(s), but none
201
- // is one of the climb's 1 committed root(s)"), and it was precisely the vote
202
- // order that kept the committed root's own point alive in the weave. Local
203
- // run length knows nothing about what the climb settled on, so it evicted the
204
- // root's evidence and left CAST refusing on its own consistency check.
205
- //
206
- // So the vote order here is not an accident of construction — it is what
207
- // holds the weave and the climb to the same conclusion. Weave-local
208
- // measures decide what is FRAME inside the weave (see the frame gates in
209
- // cast.ts); which structures are in the weave at all stays the climb's call.
210
- //
211
- // TWO PASSES. `depth` — how much of the weave agrees on each query byte, and
212
- // therefore what counts as FRAME — must be the whole weave's, not "whatever
213
- // has been processed so far": read in one pass it made a candidate's own
214
- // frame reading depend on its rank, and the proposed-run gate below needs the
215
- // real thing.
216
- const cands = [];
217
- for (const cand of rankedCapped) {
218
- const ctxBytes = read(ctx, cand.anchor, capBytes + 1);
219
- if (ctxBytes.length === 0 || ctxBytes.length > capBytes)
220
- continue;
221
- const raw = alignGraded(ctx, query, ctxBytes, pre.rec.sites);
222
- if (raw.length === 0)
223
- continue;
224
- for (const r of raw) {
225
- for (let i = r.qs; i < r.qe; i++)
226
- depth[i] += r.weight;
227
- }
228
- cands.push({ cand, ctxBytes, raw });
229
- }
230
- for (const { cand, ctxBytes, raw } of cands) {
231
- const free = [];
232
- for (const r of raw) {
233
- let { qs, qe, cs, weight } = r;
234
- for (const p of points) {
235
- for (const o of p.runs) {
236
- if (qs >= qe)
237
- break;
238
- if (o.qe <= qs || o.qs >= qe)
239
- continue;
240
- const left = Math.max(0, o.qs - qs);
241
- const right = Math.max(0, qe - o.qe);
242
- if (left >= right)
243
- qe = qs + left;
244
- else {
245
- cs += qe - right - qs;
246
- qs = qe - right;
247
- }
248
- }
249
- }
250
- if (qe - qs >= Math.min(quantum, ctxBytes.length)) {
251
- free.push({ qs, qe, cs, weight });
252
- }
253
- }
254
- if (free.length > 0) {
255
- const pt = {
256
- anchor: cand.anchor,
257
- vote: cand.vote,
258
- ctx: ctxBytes,
259
- runs: free,
260
- };
261
- byAnchor.set(cand.anchor, pt);
262
- points.push(pt);
263
- }
264
- }
265
- // A byte is FRAME when more than half the weave shares it, and a SPAN is
266
- // frame when more than half its bytes are — the same two-level
267
- // half-dominance reading cast.ts's own frame gate uses, over the same
268
- // `depth`. Read against the accepted POINTS (as cast.ts does), so it is
269
- // only meaningful once phase 1 has run.
270
- const framed = (from, to) => {
271
- let n = 0;
272
- for (let i = from; i < to; i++)
273
- if (dominates(depth[i], points.length))
274
- n++;
275
- return dominates(n, to - from);
276
- };
277
- // PHASE 2 — THE CLIMB'S OWN CONCLUSION IS AN ALIGNMENT THE LITERAL MATCHER
278
- // CANNOT SEE. `alignRuns` seeds on W-grams, so two forms differing by a
279
- // single byte share no run at all: on `How is ice like steel?` against a
280
- // store holding `Ice is cold`, the query's `ice` and the stored `Ice` agree
281
- // on only `ce ` — three bytes, never seeded — so that structure entered the
282
- // weave carrying nothing but the ` is ` scaffolding every exemplar shares,
283
- // lost it to the first point that claimed it, and vanished. The climb had
284
- // ALREADY identified it: its resonance elected `Ice is cold` from the query
285
- // span `ce l` and `Steel is hard` from `stee`, two disjoint spans each naming
286
- // its own structure, weighed through the region's contrastive margin and its
287
- // IDF — gates the aligner has no equivalent of.
288
- //
289
- // So the climb PROPOSES the pairing (which structure, which query span) and
290
- // bytes DECIDE its terms (§2.3). Three gates, each one measured:
291
- //
292
- // • it may only take query bytes NO literal run claimed. Run inline with
293
- // phase 1 this did the opposite of "exact decides" — a higher-ranked
294
- // candidate's proposal trimmed a lower-ranked candidate's byte-for-byte
295
- // match out of existence (`he W`, proposed for `a nickname meaning the
296
- // divine one`, cut the literal `The ` out of `The Starry Night was
297
- // painted by Vincent van Gogh.` and CAST's redirection lost its
298
- // dominant — test/29 C4). Hence a second pass, after every literal run
299
- // is placed.
300
- // • the literal agreement must DOMINATE the span. A climb vote is not by
301
- // itself an alignment: on `The Persistence of Memory was painted by
302
- // Salvador Dali.` the climb elects `The Starry Night…` from the span
303
- // ` Dali.`, which shares barely a byte with it — the resonance was
304
- // carried by the frame those exemplars share. Admitting it let CAST
305
- // weave points out of pure scaffolding and out-account the correct
306
- // extraction (test/00, test/24). Where the proposal is real the
307
- // agreement is overwhelming: both C1 spans agree on three of four bytes.
308
- // • and the span must not be FRAME. Literal dominance alone is too weak
309
- // at this scale — a 4-byte span agrees three-of-four with half the
310
- // corpus by accident (`he W` against `a nickname meaning the divine
311
- // one`). Frame is the weave-local measure of exactly that.
312
- const claimed = new Uint8Array(query.length);
313
- for (const p of points) {
314
- for (const r of p.runs)
315
- claimed.fill(1, r.qs, r.qe);
316
- }
317
- for (const { cand, ctxBytes } of cands) {
318
- if (cand.end > cand.start) {
319
- let qs = cand.start;
320
- let qe = cand.end;
321
- while (qs < qe && claimed[qs])
322
- qs++;
323
- while (qe > qs && claimed[qe - 1])
324
- qe--;
325
- let clear = true;
326
- for (let i = qs; i < qe; i++)
327
- if (claimed[i])
328
- clear = false;
329
- if (clear && qe - qs >= Math.min(quantum, ctxBytes.length)) {
330
- // The gate only asks whether the agreement DOMINATES the span, so
331
- // search DOWNWARD from the whole span and stop at the first hit: the
332
- // first length found is both the longest agreement and, by
333
- // construction, already past the dominance bar. At most O(W²) bounded
334
- // substring probes — a span is one segment (≤ 2W) — where a full
335
- // longest-common-substring scan would be O(|span|² · |ctx|) against a
336
- // context that may be W× the query.
337
- const span = query.subarray(qs, qe);
338
- const bar = Math.floor(span.length / 2) + 1; // dominates(bar, length)
339
- let bestLen = 0;
340
- let bestCs = 0;
341
- for (let len = span.length; len >= bar && bestLen === 0; len--) {
342
- for (let off = 0; off + len <= span.length; off++) {
343
- const at = indexOf(ctxBytes, span.subarray(off, off + len), 0);
344
- if (at < 0)
345
- continue;
346
- bestLen = len;
347
- // Where the span's FIRST byte lands, so `cs` means the same thing
348
- // it does for a literal run: the context offset the run starts at.
349
- bestCs = Math.max(0, at - off);
350
- break;
351
- }
352
- }
353
- if (bestLen > 0 && !framed(qs, qe)) {
354
- const run = {
355
- qs,
356
- qe,
357
- cs: bestCs,
358
- weight: bestLen / (qe - qs),
359
- proposed: true,
360
- };
361
- claimed.fill(1, qs, qe);
362
- const pt = byAnchor.get(cand.anchor);
363
- if (!pt) {
364
- const made = {
365
- anchor: cand.anchor,
366
- vote: cand.vote,
367
- ctx: ctxBytes,
368
- runs: [run],
369
- };
370
- byAnchor.set(cand.anchor, made);
371
- points.push(made);
372
- }
373
- else {
374
- pt.runs.push(run);
375
- pt.runs.sort((x, y) => x.qs - y.qs);
376
- }
377
- }
378
- }
379
- }
380
- }
381
- return { points, depth };
382
- }
@@ -1,49 +0,0 @@
1
- import type { MindContext } from "./types.js";
2
- import { type PipelineMechanism } from "./pipeline-mechanism.js";
3
- export { resolveConcepts, resolveConnectors } from "./mechanisms/cover.js";
4
- export { aluToMechanism } from "./mechanisms/alu.js";
5
- export declare const defaultMechanisms: PipelineMechanism[];
6
- export type Provenance = "cast" | "join" | "cover" | "extract" | "recall" | "recall-echo";
7
- export interface Thought {
8
- bytes: Uint8Array;
9
- provenance: Provenance;
10
- }
11
- /** Structured payload of the "decideGrounding" rationale step — the same
12
- * numbers the human-readable candidate labels already carry, exposed as
13
- * data so a downstream tool need not parse free text. Purely additive
14
- * instrumentation: built only under `ctx.trace?.` (optional chaining
15
- * short-circuits its arguments), never read by inference. */
16
- export interface DecideGroundingData {
17
- version: 1;
18
- /** Every grounding candidate weighed, in consideration order. */
19
- candidates: Array<{
20
- provenance: string;
21
- /** The candidate's exact weight in the one cost ladder. */
22
- weight: number;
23
- /** The DISCRETE grade the decision actually compares (floor(weight/STEP)). */
24
- grade: number;
25
- /** Query bytes the candidate's accounted spans leave unexplained. */
26
- unexplainedBytes: number;
27
- /** Whether this candidate won the decision. */
28
- decided: boolean;
29
- }>;
30
- /** Grade margin between the winner and the runner-up, when both exist —
31
- * the same quantity the "narrowDecision" step reports as narrow when
32
- * ≤ 1. Absent for a single-candidate decision. */
33
- runnerUpMargin?: number;
34
- }
35
- /** Structured payload of the "narrowDecision" rationale step. */
36
- export interface NarrowDecisionData {
37
- version: 1;
38
- margin: number;
39
- }
40
- /** Think: a single lightest-derivation exploration of the Sema graph.
41
- *
42
- * Every answer travels the same path:
43
- * 1. Pre-computation — recognise, extension parse, guide; everything
44
- * expensive stays lazy on Precomputed until a mechanism asks.
45
- * 2. Grounding — every mechanism yields candidates weighed in the one
46
- * cost ladder; the lightest grounding derivation wins.
47
- * 3. Post-grounding — diagnostics (narrowDecision, thinGrounding),
48
- * reasoning (multi-hop), fusion (multi-topic). */
49
- export declare function think(ctx: MindContext, query: Uint8Array, mechs?: readonly PipelineMechanism[]): Promise<Thought | null>;