@hviana/sema 0.9.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +7 -7
- package/dist/src/alu/src/index.d.ts +1 -1
- package/dist/src/alu/src/index.js +1 -1
- package/dist/src/alu/src/parser.js +2 -6
- package/dist/src/alu/src/resonance.d.ts +13 -0
- package/dist/src/alu/src/resonance.js +41 -0
- package/dist/src/alu/test/alu.test.js +39 -0
- package/dist/src/bytes.d.ts +6 -2
- package/dist/src/bytes.js +10 -4
- package/dist/src/canon.js +44 -0
- package/dist/src/geometry.d.ts +19 -1
- package/dist/src/geometry.js +125 -141
- package/dist/src/meter.d.ts +33 -0
- package/dist/src/meter.js +34 -1
- package/dist/src/mind/articulation.js +14 -1
- package/dist/src/mind/attention.d.ts +12 -0
- package/dist/src/mind/attention.js +44 -16
- package/dist/src/mind/bridge.js +3 -3
- package/dist/src/mind/derivation.d.ts +40 -0
- package/dist/src/mind/derivation.js +34 -0
- package/dist/src/mind/evidence.d.ts +24 -0
- package/dist/src/mind/evidence.js +90 -0
- package/dist/src/mind/graph-search.d.ts +89 -15
- package/dist/src/mind/graph-search.js +345 -174
- package/dist/src/mind/learning.js +1 -1
- package/dist/src/mind/mechanisms/cover.d.ts +19 -3
- package/dist/src/mind/mechanisms/cover.js +142 -61
- package/dist/src/mind/mechanisms/recall.js +10 -3
- package/dist/src/mind/mind.d.ts +6 -0
- package/dist/src/mind/mind.js +5 -2
- package/dist/src/mind/pipeline.d.ts +5 -1
- package/dist/src/mind/pipeline.js +220 -90
- package/dist/src/mind/primitives.d.ts +25 -5
- package/dist/src/mind/primitives.js +107 -44
- package/dist/src/mind/reasoning.d.ts +18 -4
- package/dist/src/mind/reasoning.js +487 -328
- package/dist/src/mind/recognition.js +29 -13
- package/dist/src/mind/resonance.js +1 -11
- package/dist/src/mind/traverse.d.ts +45 -5
- package/dist/src/mind/traverse.js +285 -8
- package/dist/src/mind/types.d.ts +16 -1
- package/dist/src/store-sqlite.d.ts +25 -0
- package/dist/src/store-sqlite.js +89 -1
- package/dist/src/store.d.ts +48 -4
- package/dist/src/store.js +86 -6
- package/docs/INDEX.md +20 -19
- package/docs/INVARIANTS.md +17 -16
- package/docs/architecture/bounded-reads.md +1 -1
- package/docs/architecture/caches.md +5 -4
- package/docs/architecture/closure.md +45 -5
- package/docs/architecture/cost-model.md +16 -0
- package/docs/architecture/evidence.md +113 -0
- package/docs/architecture/exact-vs-approximate.md +10 -9
- package/docs/architecture/factored-machinery.md +14 -13
- package/docs/architecture/fold-contract.md +51 -1
- package/docs/architecture/mechanism-market.md +21 -0
- package/docs/architecture/memoization.md +3 -3
- package/docs/architecture/meter.md +2 -1
- package/docs/architecture/saturation.md +12 -0
- package/docs/architecture/store.md +25 -2
- package/docs/failures/tempting-but-wrong.md +13 -2
- package/docs/harness/gates.md +12 -10
- package/docs/mechanisms/cover.md +23 -6
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/alu/README.md +10 -2
- package/src/alu/src/index.ts +1 -0
- package/src/alu/src/parser.ts +6 -6
- package/src/alu/src/resonance.ts +42 -0
- package/src/alu/test/alu.test.ts +40 -0
- package/src/bytes.ts +13 -3
- package/src/canon.ts +40 -0
- package/src/geometry.ts +183 -154
- package/src/meter.ts +34 -1
- package/src/mind/articulation.ts +14 -2
- package/src/mind/attention.ts +47 -25
- package/src/mind/bridge.ts +3 -3
- package/src/mind/derivation.ts +77 -0
- package/src/mind/evidence.ts +107 -0
- package/src/mind/graph-search.ts +449 -221
- package/src/mind/learning.ts +1 -7
- package/src/mind/match.ts +1 -2
- package/src/mind/mechanisms/cast.ts +1 -2
- package/src/mind/mechanisms/cover.ts +207 -87
- package/src/mind/mechanisms/extraction.ts +1 -2
- package/src/mind/mechanisms/prefix-completion.ts +1 -1
- package/src/mind/mechanisms/recall.ts +17 -5
- package/src/mind/mechanisms/reference.ts +1 -1
- package/src/mind/mind.ts +9 -30
- package/src/mind/pipeline.ts +263 -104
- package/src/mind/primitives.ts +119 -43
- package/src/mind/reasoning.ts +611 -419
- package/src/mind/recognition.ts +24 -9
- package/src/mind/resonance.ts +2 -16
- package/src/mind/trace.ts +1 -1
- package/src/mind/traverse.ts +321 -8
- package/src/mind/types.ts +15 -11
- package/src/store-sqlite.ts +92 -1
- package/src/store.ts +113 -7
- package/test/105-derive-through-reports-its-refusal.test.mjs +8 -5
- package/test/106-the-join-fires.test.mjs +21 -0
- package/test/111-the-cover-assembly-is-counted.test.mjs +8 -5
- package/test/128-the-leads-somewhere-pair-agrees.test.mjs +18 -12
- package/test/136-the-two-named-limits.test.mjs +3 -2
- package/test/137-the-law-lives-once-and-below.test.mjs +21 -0
- package/test/148-exact-shortcuts-agree.test.mjs +188 -0
- package/test/149-the-closure-engine.test.mjs +138 -0
- package/test/150-the-join-is-output-sensitive.test.mjs +66 -0
- package/test/151-the-cover-pays-for-what-it-reaches.test.mjs +142 -0
- package/test/152-the-read-side-names-as-the-write-side.test.mjs +146 -0
- package/test/153-a-cheaper-bound-is-looked-at-first.test.mjs +155 -0
- package/test/154-the-question-names-the-step.test.mjs +281 -0
- package/test/24-generalization.test.mjs +32 -0
- package/test/36-bloom.test.mjs +53 -0
- package/test/37-cluster-dispersion-fusion.test.mjs +75 -0
- package/test/48-recognise-turn-connective.test.mjs +3 -2
- package/test/55-cost-meter.test.mjs +4 -4
- package/test/90-connector-read-cap.test.mjs +7 -7
|
@@ -2,25 +2,11 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Address — bytes → node (perceive, foldTree, resolve)
|
|
4
4
|
// Read — node → bytes (read)
|
|
5
|
-
import { bytesToTree, contentFoldIncremental, gridToTree, hilbertBytes, stackGrids, } from "../geometry.js";
|
|
5
|
+
import { bytesToTree, contentFoldIncremental, contentIdentity, gridToTree, hilbertBytes, stackGrids, } from "../geometry.js";
|
|
6
6
|
import { canonHash } from "../canon.js";
|
|
7
|
-
import { bytesEqual } from "../bytes.js";
|
|
7
|
+
import { bytesEqual, concatBytes, latin1 } from "../bytes.js";
|
|
8
8
|
import { ALL } from "./types.js";
|
|
9
9
|
// ── Address: bytes → node ──────────────────────────────────────────────
|
|
10
|
-
/** The content key of a byte span — one latin1 char per byte, an exact,
|
|
11
|
-
* collision-free encoding. Spans on the perception path are query-scale
|
|
12
|
-
* (windows, regions, candidate spans), so key construction is far cheaper
|
|
13
|
-
* than the river fold it deduplicates. */
|
|
14
|
-
export function latin1Key(bytes) {
|
|
15
|
-
// Batched String.fromCharCode — avoids the O(n²) cost of repeated += on
|
|
16
|
-
// potentially-large query spans, and stays well under the ~65536 arg limit.
|
|
17
|
-
const n = bytes.length;
|
|
18
|
-
let s = "";
|
|
19
|
-
for (let i = 0; i < n; i += 4096) {
|
|
20
|
-
s += String.fromCharCode(...bytes.subarray(i, Math.min(i + 4096, n)));
|
|
21
|
-
}
|
|
22
|
-
return s;
|
|
23
|
-
}
|
|
24
10
|
/** The {@link perceive} memo key: the span's content PLUS the boundary set it
|
|
25
11
|
* was folded under. The tree is a function of BOTH — the same bytes fold
|
|
26
12
|
* plainly with no boundaries and into a left-nested stable-prefix shape with
|
|
@@ -32,7 +18,7 @@ export function latin1Key(bytes) {
|
|
|
32
18
|
* the boundary rendering is digits and commas, so no content byte can forge
|
|
33
19
|
* the split. */
|
|
34
20
|
export function perceiveKey(bytes, boundaries) {
|
|
35
|
-
const k =
|
|
21
|
+
const k = latin1(bytes);
|
|
36
22
|
return boundaries === undefined || boundaries.length === 0
|
|
37
23
|
? k
|
|
38
24
|
: k + "\u0000" + boundaries.join(",");
|
|
@@ -111,7 +97,7 @@ export function perceiveDeposit(ctx, bytes, conversational = false) {
|
|
|
111
97
|
.filter((L) => L >= 2 && L < bytes.length)
|
|
112
98
|
.sort((a, b) => b - a);
|
|
113
99
|
for (const L of lens) {
|
|
114
|
-
const hit = ctx._depositTrees.get(
|
|
100
|
+
const hit = ctx._depositTrees.get(latin1(bytes.subarray(0, L)));
|
|
115
101
|
if (hit !== undefined) {
|
|
116
102
|
prev = hit.content;
|
|
117
103
|
break;
|
|
@@ -130,7 +116,7 @@ export function perceiveDeposit(ctx, bytes, conversational = false) {
|
|
|
130
116
|
ctx._depositLens.clear();
|
|
131
117
|
ctx._depositTrees.clear();
|
|
132
118
|
}
|
|
133
|
-
ctx._depositTrees.set(
|
|
119
|
+
ctx._depositTrees.set(latin1(bytes), { content: folded.fold });
|
|
134
120
|
ctx._depositLens.add(bytes.length);
|
|
135
121
|
}
|
|
136
122
|
return folded.tree;
|
|
@@ -203,14 +189,10 @@ export function foldTree(ctx, n, start, visit) {
|
|
|
203
189
|
return { end, node };
|
|
204
190
|
}
|
|
205
191
|
let pos = start;
|
|
206
|
-
let known = true;
|
|
207
192
|
const kids = [];
|
|
208
193
|
for (const k of n.kids) {
|
|
209
194
|
const r = foldTree(ctx, k, pos, visit);
|
|
210
|
-
|
|
211
|
-
known = false;
|
|
212
|
-
else if (known)
|
|
213
|
-
kids.push(r.node);
|
|
195
|
+
kids.push(r.node);
|
|
214
196
|
pos = r.end;
|
|
215
197
|
}
|
|
216
198
|
// Same store-probe elision as the leaf case: a cached entry already names
|
|
@@ -218,17 +200,103 @@ export function foldTree(ctx, n, start, visit) {
|
|
|
218
200
|
// id need not be re-derived. Using it also keeps a warm walk's ids
|
|
219
201
|
// bit-identical to a cold walk's rather than re-deriving them from children
|
|
220
202
|
// that may themselves have come from cache.
|
|
221
|
-
const
|
|
222
|
-
? cached.id
|
|
223
|
-
:
|
|
224
|
-
|
|
225
|
-
: null;
|
|
203
|
+
const named = cached !== undefined
|
|
204
|
+
? { id: cached.id, byBytes: false }
|
|
205
|
+
: branchNaming(ctx, kids, treeBytes(n));
|
|
206
|
+
const node = named.id;
|
|
226
207
|
visit?.(n, start, pos, node);
|
|
227
208
|
if (node !== null && ctx._resolvedSubtrees) {
|
|
228
209
|
ctx._resolvedSubtrees.set(n, { id: node, len: pos - start });
|
|
229
210
|
}
|
|
230
211
|
return { end: pos, node };
|
|
231
212
|
}
|
|
213
|
+
/** A perceived subtree's bytes, its leaves in order. */
|
|
214
|
+
function treeBytes(n) {
|
|
215
|
+
const parts = [];
|
|
216
|
+
const walk = (x) => {
|
|
217
|
+
if (x.kids === null)
|
|
218
|
+
parts.push(x.leaf ?? new Uint8Array(0));
|
|
219
|
+
else
|
|
220
|
+
for (const k of x.kids)
|
|
221
|
+
walk(k);
|
|
222
|
+
};
|
|
223
|
+
walk(n);
|
|
224
|
+
return concatBytes(parts);
|
|
225
|
+
}
|
|
226
|
+
/** The EXACT content-addressed node of a byte stream — `foldTree(perceive)`,
|
|
227
|
+
* read for identity alone.
|
|
228
|
+
*
|
|
229
|
+
* A fold names a branch only when every child is named, so identity needs the
|
|
230
|
+
* fold's SHAPE and the store's answer per node, never its vectors:
|
|
231
|
+
* {@link contentIdentity} walks the same shape (geometry.ts — one grouping
|
|
232
|
+
* rule, two algebras) and asks the store bottom-up, building no D-dimensional
|
|
233
|
+
* gist and leaving nothing in the perception memo. Each node is named the
|
|
234
|
+
* way the store's write side names it ({@link branchNaming}). `test/148` pins
|
|
235
|
+
* the agreement with the full fold over random and corpus spans. */
|
|
236
|
+
export function exactNode(ctx, bytes) {
|
|
237
|
+
return exactNaming(ctx, bytes).id;
|
|
238
|
+
}
|
|
239
|
+
/** {@link exactNode}, with whether the span's own name was found only through
|
|
240
|
+
* its BYTES — its children named no branch, and the flat node over the same
|
|
241
|
+
* bytes did ({@link branchNaming}). That is where the exact lookup used to
|
|
242
|
+
* MISS, so it is where {@link resolve} still asks the canonical class: the
|
|
243
|
+
* class may hold the learnt member that leads somewhere, which a flat index
|
|
244
|
+
* entry need not (measured: `tonight` named an edge-less window and
|
|
245
|
+
* pre-empted the case-folded `Tonight` whose edge a composition stood on).
|
|
246
|
+
* Recognition's probes reach it through `resolve`; asking it again for the
|
|
247
|
+
* perceived tree's own byte-named groups changed none of 116 real queries and
|
|
248
|
+
* no test, so it is not asked there. */
|
|
249
|
+
export function exactNaming(ctx, bytes) {
|
|
250
|
+
if (bytes.length === 0) {
|
|
251
|
+
return { id: foldTree(ctx, perceive(ctx, bytes), 0).node, byBytes: false };
|
|
252
|
+
}
|
|
253
|
+
if (ctx.meter)
|
|
254
|
+
ctx.meter.identityBytes += bytes.length;
|
|
255
|
+
let byBytes = false;
|
|
256
|
+
const id = contentIdentity(ctx.space, ctx.alphabet, bytes, (from, to) => to - from === 1
|
|
257
|
+
? ctx.store.findLeaf(bytes.subarray(from, to))
|
|
258
|
+
: flatNode(ctx, bytes.subarray(from, to)), (kids, from, to) => {
|
|
259
|
+
const named = branchNaming(ctx, kids, bytes.subarray(from, to));
|
|
260
|
+
if (from === 0 && to === bytes.length)
|
|
261
|
+
byBytes = named.byBytes;
|
|
262
|
+
return named.id;
|
|
263
|
+
});
|
|
264
|
+
return { id, byBytes };
|
|
265
|
+
}
|
|
266
|
+
/** The flat node over a span's single-byte atoms — the node every deposit
|
|
267
|
+
* interns for its whole input and for each canonical window (learning.ts
|
|
268
|
+
* `deposit`, `indexSubSpans`). The store's negative filter refuses most
|
|
269
|
+
* misses without a lookup. */
|
|
270
|
+
function flatNode(ctx, span) {
|
|
271
|
+
const store = ctx.store;
|
|
272
|
+
return store.findFlatBranch
|
|
273
|
+
? store.findFlatBranch(span)
|
|
274
|
+
: store.findBranch(Array.from(span, (b) => -(b + 1)));
|
|
275
|
+
}
|
|
276
|
+
/** THE READ SIDE NAMES A BRANCH EXACTLY AS THE WRITE SIDE DID. `intern`
|
|
277
|
+
* (store.ts) names a branch by its children; when they name none, it looks up
|
|
278
|
+
* the flat node over the same bytes and REUSES it (step 1b, "same bytes, same
|
|
279
|
+
* node") — so a deposit whose fold grouped `ver` + `!` was stored with the
|
|
280
|
+
* window `ver!` as that child. Reading by the children alone could never
|
|
281
|
+
* name such a deposit again: measured on the 31.7M-node store, 8 of 80 stored
|
|
282
|
+
* dialogue turns asked verbatim resolved to nothing (a 25-byte turn, a final
|
|
283
|
+
* `?` or `!`, …) and fell to the composition path. Same order as the write
|
|
284
|
+
* side: the children first, the bytes when they name nothing — and an unnamed
|
|
285
|
+
* child does not settle it, since the write side minted that child and still
|
|
286
|
+
* reached step 1b. */
|
|
287
|
+
function branchNaming(ctx, kids, span) {
|
|
288
|
+
if (kids.every((k) => k !== null)) {
|
|
289
|
+
const id = ctx.store.findBranch(kids);
|
|
290
|
+
if (id !== null)
|
|
291
|
+
return { id, byBytes: false };
|
|
292
|
+
}
|
|
293
|
+
if (kids.length < 2)
|
|
294
|
+
return { id: null, byBytes: false };
|
|
295
|
+
const id = flatNode(ctx, span);
|
|
296
|
+
if (id !== null && ctx.meter)
|
|
297
|
+
ctx.meter.flatBranchNames++;
|
|
298
|
+
return { id, byBytes: id !== null };
|
|
299
|
+
}
|
|
232
300
|
/** The canonical node id of a byte span: perceive it in isolation — the way
|
|
233
301
|
* training did — and recover its root bottom-up. Returns null if any part is
|
|
234
302
|
* unknown. */
|
|
@@ -237,10 +305,10 @@ export function resolve(ctx, bytes) {
|
|
|
237
305
|
return null;
|
|
238
306
|
if (ctx.meter)
|
|
239
307
|
ctx.meter.resolves++;
|
|
240
|
-
const exact =
|
|
241
|
-
if (exact !== null)
|
|
308
|
+
const { id: exact, byBytes } = exactNaming(ctx, bytes);
|
|
309
|
+
if (exact !== null && !byBytes)
|
|
242
310
|
return exact;
|
|
243
|
-
return canonResolve(ctx, bytes);
|
|
311
|
+
return canonResolve(ctx, bytes) ?? exact;
|
|
244
312
|
}
|
|
245
313
|
/** Equivalence-class resolution: when the exact content-addressed lookup
|
|
246
314
|
* misses, find a stored node whose CANONICAL key equals the span's — the
|
|
@@ -258,7 +326,7 @@ export function canonResolve(ctx, bytes) {
|
|
|
258
326
|
if (bytes.length < 2)
|
|
259
327
|
return null;
|
|
260
328
|
const memo = ctx.canonMemo;
|
|
261
|
-
const memoKey = memo ?
|
|
329
|
+
const memoKey = memo ? latin1(bytes) : "";
|
|
262
330
|
if (memo) {
|
|
263
331
|
const hit = memo.get(memoKey);
|
|
264
332
|
if (hit !== undefined)
|
|
@@ -275,7 +343,7 @@ export function canonResolve(ctx, bytes) {
|
|
|
275
343
|
// skips identity rows) — the exact content-addressed lookup of the
|
|
276
344
|
// canonical bytes finds it directly.
|
|
277
345
|
if (key.length !== bytes.length || !bytesEqual(key, bytes)) {
|
|
278
|
-
const direct =
|
|
346
|
+
const direct = exactNode(ctx, key);
|
|
279
347
|
if (direct !== null)
|
|
280
348
|
return set(direct);
|
|
281
349
|
}
|
|
@@ -295,17 +363,12 @@ export function canonResolve(ctx, bytes) {
|
|
|
295
363
|
// resolved for these bytes is their FOLD — the deposit-shaped node that
|
|
296
364
|
// carries the edges and halos. Re-folding the candidate's bytes lands
|
|
297
365
|
// on exactly the node the canonical-case query would have found.
|
|
298
|
-
const folded =
|
|
366
|
+
const folded = exactNode(ctx, bytesOf);
|
|
299
367
|
const use = folded ?? id;
|
|
300
|
-
// THE ADMISSION PREDICATE,
|
|
301
|
-
//
|
|
302
|
-
//
|
|
303
|
-
|
|
304
|
-
// bar and this site would rank a node as leading on evidence the law
|
|
305
|
-
// refuses. Calling `leadsSomewhere` here is not possible — `traverse.ts`
|
|
306
|
-
// imports THIS file, so it would be a cycle — which is why the pair is
|
|
307
|
-
// spelled out rather than named.
|
|
308
|
-
const leads = store.hasNext(use) || store.hasHalo(use);
|
|
368
|
+
// THE ADMISSION PREDICATE, asked of the store that owns it (edge or halo,
|
|
369
|
+
// the halo tier carrying the mass bar). Asking `haloMass(use) > 0` instead
|
|
370
|
+
// would agree only while `minHaloMass <= 1`.
|
|
371
|
+
const leads = store.leadsSomewhere(use);
|
|
309
372
|
if (best === null || (leads && !bestLeads) ||
|
|
310
373
|
(leads === bestLeads && use < best)) {
|
|
311
374
|
best = use;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { MindContext } from "./types.js";
|
|
2
|
+
import { type ClosureLayer, type DerivationState, type Span } from "./derivation.js";
|
|
2
3
|
import type { Precomputed } from "./pipeline-mechanism.js";
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
/** Extend a grounded answer forward across facts (multi-hop reasoning) — the
|
|
5
|
+
* WALK, run as one layer of the closure engine ({@link walkLayer}).
|
|
5
6
|
* Pivots on the longest unconsumed learnt context each answer contains,
|
|
6
7
|
* then follows the pivot's continuation to the next fact. **The chain ends
|
|
7
8
|
* when it STOPS, never when a count runs out**: every exit is a refusal (no
|
|
@@ -17,11 +18,24 @@ import { type DerivationState, type Span } from "./derivation.js";
|
|
|
17
18
|
* response's shared pre-computation — the post-grounding stages read the
|
|
18
19
|
* same container the mechanisms did. */
|
|
19
20
|
export declare function reason(ctx: MindContext, query: Uint8Array, d0: DerivationState, preConsumed: ReadonlySet<number>, pre: Precomputed, voiced?: readonly Uint8Array[]): Promise<DerivationState>;
|
|
21
|
+
/** The multi-hop walk as a {@link ClosureLayer}: it OFFERS a forward absorb or a
|
|
22
|
+
* pivot, the law admits. Its preamble — the two guards that say the question
|
|
23
|
+
* was already answered by the query's own position in the graph, and the
|
|
24
|
+
* pre-consumption of what the grounding spoke for — runs on the FIRST offer,
|
|
25
|
+
* against the state the engine hands it; a guard that fires makes that first
|
|
26
|
+
* offer `null`, so the walk ends where it begins and reports nothing more. */
|
|
27
|
+
export declare function walkLayer(ctx: MindContext, query: Uint8Array, preConsumed: ReadonlySet<number>, pre: Precomputed, voiced?: readonly Uint8Array[]): ClosureLayer;
|
|
20
28
|
/** Fuse independent points of attention into one answer (multi-topic).
|
|
21
29
|
* When the consensus climb finds more than one dominant point, each
|
|
22
30
|
* independent point grounds its own answer; they are bridged together
|
|
23
31
|
* by any learnt connector the graph holds between them. */
|
|
24
|
-
export declare function fuseAttention(ctx: MindContext, query: Uint8Array, state: DerivationState, pre: Precomputed,
|
|
32
|
+
export declare function fuseAttention(ctx: MindContext, query: Uint8Array, state: DerivationState, pre: Precomputed, unclimbed?: boolean, primarySpans?: ReadonlyArray<Span>): Promise<DerivationState>;
|
|
33
|
+
/** Fusion as a {@link ClosureLayer}: ONE transition, offered once — the fused
|
|
34
|
+
* product of the independent points of attention, or nothing. The law admits
|
|
35
|
+
* it (`reaches`: the fusion composed structure this derivation had not stood
|
|
36
|
+
* on); the layer's own structural gates below decide whether there is a
|
|
37
|
+
* fusion to offer at all. */
|
|
38
|
+
export declare function fusionLayer(ctx: MindContext, query: Uint8Array, pre: Precomputed,
|
|
25
39
|
/** True when `primary` never touched the consensus climb at all — e.g. a
|
|
26
40
|
* pure ALU computation, which has no anchor of its own. commitVotes
|
|
27
41
|
* ALWAYS admits the dominant root regardless of its vote (attention.ts:
|
|
@@ -35,4 +49,4 @@ unclimbed?: boolean,
|
|
|
35
49
|
* which is the layer that knows how a given grounding records its evidence;
|
|
36
50
|
* fuseAttention just reads a position from it. Empty or absent preserves
|
|
37
51
|
* the original behaviour exactly. */
|
|
38
|
-
primarySpans?: ReadonlyArray<Span>):
|
|
52
|
+
primarySpans?: ReadonlyArray<Span>): ClosureLayer;
|