@hviana/sema 0.8.3 → 0.8.5
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 +11 -10
- package/README.md +17 -38
- package/dist/example/demo.js +85 -34
- package/dist/src/geometry.d.ts +0 -10
- package/dist/src/geometry.js +0 -12
- package/dist/src/meter.d.ts +11 -0
- package/dist/src/meter.js +11 -0
- package/dist/src/mind/articulation.js +1 -1
- package/dist/src/mind/attention.js +2 -1
- package/dist/src/mind/derivation.d.ts +201 -0
- package/dist/src/mind/derivation.js +327 -0
- package/dist/src/mind/graph-search.d.ts +2 -1
- package/dist/src/mind/graph-search.js +37 -15
- package/dist/src/mind/match.d.ts +2 -0
- package/dist/src/mind/match.js +2 -0
- package/dist/src/mind/mechanisms/alu.js +0 -2
- package/dist/src/mind/mechanisms/cast.d.ts +1 -5
- package/dist/src/mind/mechanisms/cast.js +15 -18
- package/dist/src/mind/mechanisms/confluence.d.ts +0 -3
- package/dist/src/mind/mechanisms/confluence.js +3 -9
- package/dist/src/mind/mechanisms/cover.js +17 -20
- package/dist/src/mind/mechanisms/extraction.d.ts +0 -1
- package/dist/src/mind/mechanisms/extraction.js +13 -8
- package/dist/src/mind/mechanisms/prefix-completion.js +0 -1
- package/dist/src/mind/mechanisms/recall.d.ts +0 -1
- package/dist/src/mind/mechanisms/recall.js +8 -9
- package/dist/src/mind/mechanisms/reference.js +3 -4
- package/dist/src/mind/pipeline-mechanism.d.ts +1 -4
- package/dist/src/mind/pipeline.js +106 -41
- package/dist/src/mind/rationale.d.ts +0 -11
- package/dist/src/mind/rationale.js +6 -32
- package/dist/src/mind/reasoning.d.ts +4 -30
- package/dist/src/mind/reasoning.js +183 -151
- package/dist/src/mind/types.js +6 -3
- package/docs/INDEX.md +23 -24
- package/docs/INVARIANTS.md +16 -17
- package/docs/architecture/bounded-reads.md +4 -4
- package/docs/architecture/closure.md +65 -0
- package/docs/architecture/commonality.md +27 -18
- package/docs/architecture/cost-model.md +5 -5
- package/docs/architecture/exact-vs-approximate.md +4 -4
- package/docs/architecture/factored-machinery.md +14 -14
- package/docs/architecture/mechanism-market.md +9 -9
- package/docs/architecture/meter.md +4 -5
- package/docs/architecture/store.md +2 -2
- package/docs/architecture/thresholds.md +1 -1
- package/docs/failures/tempting-but-wrong.md +11 -1
- package/docs/harness/gates.md +6 -6
- package/docs/mechanisms/cover.md +2 -2
- package/example/demo.ts +90 -37
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/geometry.ts +0 -13
- package/src/meter.ts +11 -0
- package/src/mind/articulation.ts +0 -1
- package/src/mind/attention.ts +2 -1
- package/src/mind/derivation.ts +473 -0
- package/src/mind/graph-search.ts +37 -20
- package/src/mind/match.ts +2 -0
- package/src/mind/mechanisms/alu.ts +0 -2
- package/src/mind/mechanisms/cast.ts +17 -21
- package/src/mind/mechanisms/confluence.ts +3 -13
- package/src/mind/mechanisms/cover.ts +17 -20
- package/src/mind/mechanisms/extraction.ts +13 -9
- package/src/mind/mechanisms/prefix-completion.ts +0 -1
- package/src/mind/mechanisms/recall.ts +7 -9
- package/src/mind/mechanisms/reference.ts +2 -3
- package/src/mind/pipeline-mechanism.ts +1 -4
- package/src/mind/pipeline.ts +121 -46
- package/src/mind/rationale.ts +6 -36
- package/src/mind/reasoning.ts +208 -178
- package/src/mind/types.ts +5 -2
- package/test/133-the-decision-point-renders-the-state.test.mjs +204 -0
- package/test/134-the-law-explains-the-engines-own-refusal.test.mjs +237 -0
- package/test/135-one-law-any-producer.test.mjs +289 -0
- package/test/136-the-two-named-limits.test.mjs +205 -0
- package/test/137-the-law-lives-once-and-below.test.mjs +400 -0
- package/test/138-the-remainder-drains-only-what-a-move-declares.test.mjs +62 -0
- package/test/139-the-witness-is-engagement-not-explanation.test.mjs +51 -0
- package/test/140-irrelevant-supply-does-not-change-an-answer.test.mjs +48 -0
- package/test/141-the-question-is-paid-at-construction.test.mjs +98 -0
- package/test/36-already-answered-fusion.test.mjs +20 -2
- package/test/37-cluster-dispersion-fusion.test.mjs +30 -3
- package/test/38-reason-restate-guard.test.mjs +22 -2
- package/test/55-cost-meter.test.mjs +4 -1
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
|
|
10
10
|
import type { Alu } from "../../alu/src/alu.js";
|
|
11
11
|
import { STEP } from "../graph-search.js";
|
|
12
|
-
import { unexplainedLabel } from "../rationale.js";
|
|
13
12
|
import type { PipelineMechanism } from "../pipeline-mechanism.js";
|
|
14
13
|
|
|
15
14
|
/** Wrap the ALU as a {@link PipelineMechanism}. */
|
|
@@ -35,7 +34,6 @@ export function aluToMechanism(alu: Alu): PipelineMechanism {
|
|
|
35
34
|
bytes: u.bytes,
|
|
36
35
|
accounted: [[u.i, u.j]],
|
|
37
36
|
moves: STEP,
|
|
38
|
-
unexplained: unexplainedLabel(query, [[u.i, u.j]]),
|
|
39
37
|
}));
|
|
40
38
|
},
|
|
41
39
|
};
|
|
@@ -30,15 +30,11 @@ import {
|
|
|
30
30
|
sharedFrameStrengthOf,
|
|
31
31
|
} from "../match.js";
|
|
32
32
|
import { joinWithBridge } from "../resonance.js";
|
|
33
|
-
import { restatesQuery } from "../reasoning.js";
|
|
34
33
|
import { CONCEPT, STEP } from "../graph-search.js";
|
|
35
34
|
import { concat2, indexOf } from "../../bytes.js";
|
|
36
35
|
import { consensusFloor, dominates } from "../../geometry.js";
|
|
37
|
-
import {
|
|
38
|
-
|
|
39
|
-
unexplainedLabel,
|
|
40
|
-
unexplainedSpans,
|
|
41
|
-
} from "../rationale.js";
|
|
36
|
+
import { decodeText } from "../rationale.js";
|
|
37
|
+
import { restates, unexplainedSpans } from "../derivation.js";
|
|
42
38
|
import { rItem, rNode } from "../trace.js";
|
|
43
39
|
import { dismissedKnownContent } from "../bridge.js";
|
|
44
40
|
import { leafIdRun } from "../canonical.js";
|
|
@@ -92,7 +88,6 @@ export interface CastResult {
|
|
|
92
88
|
/** A human-readable label for the query bytes this schema left
|
|
93
89
|
* unexplained — purely diagnostic, never priced (see the module's
|
|
94
90
|
* Task 2 note in pipeline.ts's Candidate interface). */
|
|
95
|
-
unexplained: string;
|
|
96
91
|
}
|
|
97
92
|
|
|
98
93
|
/** The seat that establishes a node's role in an analogical comparison:
|
|
@@ -129,7 +124,7 @@ export interface CastResult {
|
|
|
129
124
|
* describes id ("...painted by Leonardo da Vinci." contains "Leonardo da
|
|
130
125
|
* Vinci"). An incidental adjacency predecessor never does — it merely
|
|
131
126
|
* preceded id in some unrelated document without ever mentioning it. No
|
|
132
|
-
* new tuned constant: containment is the same primitive `
|
|
127
|
+
* new tuned constant: containment is the same primitive `restates`
|
|
133
128
|
* and `dominates`-style checks already use throughout this codebase.
|
|
134
129
|
*
|
|
135
130
|
* `allowForward` (default true) gates the FORWARD branch specifically —
|
|
@@ -499,7 +494,6 @@ export async function counterfactualTransfer(
|
|
|
499
494
|
used: used ?? new Set(),
|
|
500
495
|
accounted,
|
|
501
496
|
moves,
|
|
502
|
-
unexplained: unexplainedLabel(query, accounted),
|
|
503
497
|
});
|
|
504
498
|
};
|
|
505
499
|
ctx.trace?.step(
|
|
@@ -613,7 +607,7 @@ export async function counterfactualTransfer(
|
|
|
613
607
|
const fwd = await follow(ctx, proj.anchor, qv);
|
|
614
608
|
if (
|
|
615
609
|
fwd !== null && indexOf(answer, fwd, 0) < 0 &&
|
|
616
|
-
!
|
|
610
|
+
!restates(query, fwd, 0, { proper: true })
|
|
617
611
|
) {
|
|
618
612
|
// THROUGH THE SHARED JOINER, not a bare concatenation.
|
|
619
613
|
//
|
|
@@ -695,7 +689,7 @@ export async function counterfactualTransfer(
|
|
|
695
689
|
// cap the test reads "none of the established continuations appears".
|
|
696
690
|
const domNext = ctx.store.nextFirst(dominant.anchor, hubBound(ctx));
|
|
697
691
|
const displaced = domNext
|
|
698
|
-
.every((n) =>
|
|
692
|
+
.every((n) => !restates(query, read(ctx, n), 0));
|
|
699
693
|
// The SUBSTITUTE is what redirection speaks — the answer IS `project(last)`,
|
|
700
694
|
// its own fact — so the same bar applies. The displaced structure is only
|
|
701
695
|
// recognised as the slot being overridden and is never voiced, so it is
|
|
@@ -791,7 +785,7 @@ export async function counterfactualTransfer(
|
|
|
791
785
|
queryScale(p.ctx.length) &&
|
|
792
786
|
indexOf(dominant.ctx, p.ctx, 0) < 0 &&
|
|
793
787
|
indexOf(p.ctx, dominant.ctx, 0) < 0 &&
|
|
794
|
-
|
|
788
|
+
!restates(query, p.ctx, 0)
|
|
795
789
|
) {
|
|
796
790
|
analogs.push({ anchor: p.anchor, point: p, src: p });
|
|
797
791
|
}
|
|
@@ -810,7 +804,7 @@ export async function counterfactualTransfer(
|
|
|
810
804
|
!queryScale(nctx.length) ||
|
|
811
805
|
indexOf(dominant.ctx, nctx, 0) >= 0 ||
|
|
812
806
|
indexOf(nctx, dominant.ctx, 0) >= 0 ||
|
|
813
|
-
|
|
807
|
+
restates(query, nctx, 0)
|
|
814
808
|
) continue;
|
|
815
809
|
analogs.push({ anchor: nid, point: null, src: p });
|
|
816
810
|
}
|
|
@@ -1286,13 +1280,16 @@ export async function counterfactualTransfer(
|
|
|
1286
1280
|
// consulting it here is the same fallback `resolve` already makes when an
|
|
1287
1281
|
// exact content lookup misses, and it keeps this mechanism from carrying
|
|
1288
1282
|
// any idea of its own about what a character is.
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1283
|
+
// TWO WITNESSES, ONE LAW: the byte reading, and — when the response carries
|
|
1284
|
+
// one — the same reading under the response's own equivalence. Asked twice
|
|
1285
|
+
// rather than branched on, because the equivalence is a property of the
|
|
1286
|
+
// injected canonicalizer (a substring-monotone function is the usual case,
|
|
1287
|
+
// not a guarantee), and the two readings are OR-ed here exactly as they were
|
|
1288
|
+
// before this became one definition.
|
|
1289
|
+
const echoesQuery = (x: Uint8Array): boolean =>
|
|
1290
|
+
restates(query, x, 0, { proper: true }) ||
|
|
1291
|
+
(ctx.canon !== null &&
|
|
1292
|
+
restates(query, x, 0, { equate: ctx.canon, proper: true }));
|
|
1296
1293
|
if (echoesQuery(b)) {
|
|
1297
1294
|
const fwd = await follow(ctx, bestAnalog.anchor, qv);
|
|
1298
1295
|
if (fwd !== null && fwd.length > 0 && !echoesQuery(fwd)) b = fwd;
|
|
@@ -1406,7 +1403,6 @@ export const castMechanism: PipelineMechanism = {
|
|
|
1406
1403
|
accounted: c.accounted,
|
|
1407
1404
|
moves: c.moves,
|
|
1408
1405
|
used: c.used,
|
|
1409
|
-
unexplained: c.unexplained,
|
|
1410
1406
|
}));
|
|
1411
1407
|
},
|
|
1412
1408
|
};
|
|
@@ -44,7 +44,7 @@ import { read } from "../primitives.js";
|
|
|
44
44
|
import { corpusN, reachOf } from "../traverse.js";
|
|
45
45
|
import { dominates } from "../../geometry.js";
|
|
46
46
|
import { STEP } from "../graph-search.js";
|
|
47
|
-
import {
|
|
47
|
+
import { insideAnsweredTurn } from "../derivation.js";
|
|
48
48
|
import type { PipelineMechanism, Precomputed } from "../pipeline-mechanism.js";
|
|
49
49
|
import { rItem, rNode } from "../trace.js";
|
|
50
50
|
|
|
@@ -58,9 +58,6 @@ export interface JoinResult {
|
|
|
58
58
|
used: ReadonlySet<number>;
|
|
59
59
|
accounted: Array<[number, number]>;
|
|
60
60
|
moves: number;
|
|
61
|
-
/** A human-readable label for the query bytes the meet left unexplained —
|
|
62
|
-
* purely diagnostic, never priced. */
|
|
63
|
-
unexplained: string;
|
|
64
61
|
}
|
|
65
62
|
|
|
66
63
|
/** The main confluence entry point. Given a query, detect whether it weaves
|
|
@@ -98,14 +95,9 @@ export async function confluenceJoin(
|
|
|
98
95
|
// Recognition and attention still see the full transcript; only this
|
|
99
96
|
// mechanism's constraint population excludes answered spans.
|
|
100
97
|
const queryWin = new Map<number, number>();
|
|
101
|
-
|
|
98
|
+
const answered = { at: 0 };
|
|
102
99
|
for (const [off, id] of pre.queryWindows) {
|
|
103
|
-
|
|
104
|
-
answered < ctx.answeredSpans.length &&
|
|
105
|
-
ctx.answeredSpans[answered][1] <= off
|
|
106
|
-
) answered++;
|
|
107
|
-
const span = ctx.answeredSpans[answered];
|
|
108
|
-
if (span && span[0] <= off && off + W <= span[1]) continue;
|
|
100
|
+
if (insideAnsweredTurn(ctx.answeredSpans, answered, off, off + W)) continue;
|
|
109
101
|
queryWin.set(off, id);
|
|
110
102
|
}
|
|
111
103
|
const queryIds = new Set(queryWin.values());
|
|
@@ -315,7 +307,6 @@ export async function confluenceJoin(
|
|
|
315
307
|
used: new Set([met.a.anchor, met.b.anchor]),
|
|
316
308
|
accounted,
|
|
317
309
|
moves: 3 * STEP,
|
|
318
|
-
unexplained: unexplainedLabel(query, accounted),
|
|
319
310
|
};
|
|
320
311
|
}
|
|
321
312
|
|
|
@@ -344,7 +335,6 @@ export const confluenceMechanism: PipelineMechanism = {
|
|
|
344
335
|
accounted: met.accounted,
|
|
345
336
|
moves: met.moves,
|
|
346
337
|
used: met.used,
|
|
347
|
-
unexplained: met.unexplained,
|
|
348
338
|
}];
|
|
349
339
|
},
|
|
350
340
|
};
|
|
@@ -16,7 +16,8 @@ import { guidedFirst, hubBound } from "../traverse.js";
|
|
|
16
16
|
import { conceptHop } from "../match.js";
|
|
17
17
|
import { bridge } from "../resonance.js";
|
|
18
18
|
import { liftAnswer, liftedScaffolding, segRestatesQuery } from "../types.js";
|
|
19
|
-
import { decodeText
|
|
19
|
+
import { decodeText } from "../rationale.js";
|
|
20
|
+
import { insideAnsweredTurn, restates } from "../derivation.js";
|
|
20
21
|
import { indexOf } from "../../bytes.js";
|
|
21
22
|
import type { RationaleItem } from "../rationale.js";
|
|
22
23
|
import { rItem, rNode, traceDerivation } from "../trace.js";
|
|
@@ -62,16 +63,13 @@ export async function resolveConnectors(
|
|
|
62
63
|
// discarded — a semantically neutral gate (it removes work whose product
|
|
63
64
|
// liftAnswer throws away), and a cumulative (multi-turn) query is exactly
|
|
64
65
|
// where such already-answered continuations recur.
|
|
65
|
-
|
|
66
|
+
const answered = { at: 0 };
|
|
66
67
|
const ordered = [...sites]
|
|
67
68
|
.sort((a, b) => a.start - b.start)
|
|
68
69
|
.filter((s) => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
) answered++;
|
|
73
|
-
const span = ctx.answeredSpans[answered];
|
|
74
|
-
if (span && span[0] <= s.start && s.end <= span[1]) return false;
|
|
70
|
+
if (insideAnsweredTurn(ctx.answeredSpans, answered, s.start, s.end)) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
75
73
|
if (query === undefined || ctx.answeredSpans.length === 0) return true;
|
|
76
74
|
const continuations = ctx.store.nextFirst(s.payload, hubBound(ctx));
|
|
77
75
|
return !continuations.some((answer) => {
|
|
@@ -93,7 +91,11 @@ export async function resolveConnectors(
|
|
|
93
91
|
// 3 bytes this reads 4 bytes per candidate instead of the ~231 it
|
|
94
92
|
// averaged before.
|
|
95
93
|
const bytes = read(ctx, answer, query.length + 1);
|
|
96
|
-
|
|
94
|
+
// THE CONTENT READING of the same exclusion: the site's own
|
|
95
|
+
// continuation already occurs in the query, so voicing it back adds
|
|
96
|
+
// nothing. It is the restatement law with no `proper` flag — the
|
|
97
|
+
// containment reading that also admits the whole query.
|
|
98
|
+
return restates(query, bytes, 0);
|
|
97
99
|
});
|
|
98
100
|
});
|
|
99
101
|
const bridgePair = async (l: number, r: number) => {
|
|
@@ -210,18 +212,11 @@ export const coverMechanism: PipelineMechanism = {
|
|
|
210
212
|
)
|
|
211
213
|
: await resolveConnectors(ctx, sites, query);
|
|
212
214
|
let splits = rec.splits;
|
|
213
|
-
let starts = rec.starts;
|
|
214
215
|
if (computed.length > 0) {
|
|
215
216
|
splits = new Set(rec.splits);
|
|
216
|
-
starts = new Set(rec.starts);
|
|
217
217
|
for (const u of computed) {
|
|
218
218
|
splits.add(u.i);
|
|
219
219
|
splits.add(u.j);
|
|
220
|
-
// A computation's own boundaries carry the same fold-level evidence
|
|
221
|
-
// a chunk boundary does — "computation always wins" (see the header
|
|
222
|
-
// comment) extends to being trusted ground for cross-leaf recovery.
|
|
223
|
-
starts.add(u.i);
|
|
224
|
-
starts.add(u.j);
|
|
225
220
|
}
|
|
226
221
|
}
|
|
227
222
|
const concepts = ctx.meter
|
|
@@ -262,7 +257,6 @@ export const coverMechanism: PipelineMechanism = {
|
|
|
262
257
|
concepts,
|
|
263
258
|
rec.leaves,
|
|
264
259
|
splits,
|
|
265
|
-
starts,
|
|
266
260
|
undefined,
|
|
267
261
|
connectors,
|
|
268
262
|
computedResults,
|
|
@@ -330,9 +324,12 @@ export const coverMechanism: PipelineMechanism = {
|
|
|
330
324
|
return [{
|
|
331
325
|
bytes: composed,
|
|
332
326
|
accounted,
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
327
|
+
// The derivation's DISCRETE work. The bytes the chart could not
|
|
328
|
+
// recognise are NOT priced here: they are exactly the spans `accounted`
|
|
329
|
+
// leaves uncovered, and the pipeline's one formula charges them at PASS —
|
|
330
|
+
// the same formula that prices every other mechanism's candidate. No
|
|
331
|
+
// mechanism spells a cost of its own.
|
|
332
|
+
moves: solved!.moves,
|
|
336
333
|
// How much of the composed answer is the asker's own unexplained words
|
|
337
334
|
// (the spans the liftAnswer trace above labels "scaffolding"). Cover is
|
|
338
335
|
// the mechanism that can carry them, because a PASS span still lands in
|
|
@@ -11,7 +11,7 @@ import type { MindContext } from "../types.js";
|
|
|
11
11
|
import { read } from "../primitives.js";
|
|
12
12
|
import { follow, isSpanShaped, locate, skillExemplar } from "../match.js";
|
|
13
13
|
import { concatBytes, indexOf } from "../../bytes.js";
|
|
14
|
-
import { decodeText
|
|
14
|
+
import { decodeText } from "../rationale.js";
|
|
15
15
|
import type {
|
|
16
16
|
PipelineMechanism,
|
|
17
17
|
Precomputed,
|
|
@@ -46,7 +46,6 @@ export async function extractBySkill(
|
|
|
46
46
|
{
|
|
47
47
|
bytes: Uint8Array;
|
|
48
48
|
accounted: Array<[number, number]>;
|
|
49
|
-
unexplained: string;
|
|
50
49
|
} | null
|
|
51
50
|
> {
|
|
52
51
|
const t = ctx.trace?.enter("extractBySkill", [
|
|
@@ -102,6 +101,12 @@ export async function extractBySkill(
|
|
|
102
101
|
const searched = ranked.slice(0, pre.k);
|
|
103
102
|
let shapeMisses = 0;
|
|
104
103
|
let subQuantum = 0;
|
|
104
|
+
// A SECOND refusal counter, because the note below used to call an UNANCHORED
|
|
105
|
+
// read "sub-quantum" — which is false, and it is the kind of instrumentation
|
|
106
|
+
// defect AGENTS §6 says to close where it lives: a reader could not tell from
|
|
107
|
+
// the trace which of the two gates refused. Neither counter reaches a
|
|
108
|
+
// decision (meter.ts contract 1); they exist so the refusal is legible.
|
|
109
|
+
let unanchored = 0;
|
|
105
110
|
for (const cand of searched) {
|
|
106
111
|
const exemplar = await pre.spanShapedOf(cand.anchor);
|
|
107
112
|
if (!exemplar) {
|
|
@@ -137,22 +142,23 @@ export async function extractBySkill(
|
|
|
137
142
|
// Here the field is this mechanism's own output and carries its documented
|
|
138
143
|
// meaning, so the test is sound exactly where the convention does not reach.
|
|
139
144
|
if (built.accounted.length === 0) {
|
|
140
|
-
|
|
145
|
+
unanchored++;
|
|
141
146
|
continue;
|
|
142
147
|
}
|
|
143
|
-
if (shapeMisses > 0 || subQuantum > 0) {
|
|
148
|
+
if (shapeMisses > 0 || subQuantum > 0 || unanchored > 0) {
|
|
144
149
|
ctx.trace?.step(
|
|
145
150
|
"trySkillAnchors",
|
|
146
151
|
[
|
|
147
152
|
rItem(
|
|
148
153
|
query.subarray(0, 0),
|
|
149
|
-
`skipped ${shapeMisses + subQuantum}`,
|
|
154
|
+
`skipped ${shapeMisses + subQuantum + unanchored}`,
|
|
150
155
|
),
|
|
151
156
|
rNode(ctx, cand.anchor, "chosen"),
|
|
152
157
|
],
|
|
153
158
|
[],
|
|
154
|
-
`skipped ${shapeMisses} non-exemplar
|
|
155
|
-
|
|
159
|
+
`skipped ${shapeMisses} non-exemplar, ${subQuantum} sub-quantum and ` +
|
|
160
|
+
`${unanchored} unanchored anchor(s) before one yielded a usable ` +
|
|
161
|
+
`extraction`,
|
|
156
162
|
);
|
|
157
163
|
}
|
|
158
164
|
t?.done(
|
|
@@ -170,7 +176,6 @@ export async function extractBySkill(
|
|
|
170
176
|
return {
|
|
171
177
|
bytes: built.bytes,
|
|
172
178
|
accounted: built.accounted,
|
|
173
|
-
unexplained: unexplainedLabel(query, built.accounted),
|
|
174
179
|
};
|
|
175
180
|
}
|
|
176
181
|
if (shapeMisses === searched.length) {
|
|
@@ -403,7 +408,6 @@ export const extractionMechanism: PipelineMechanism = {
|
|
|
403
408
|
bytes: ex.bytes,
|
|
404
409
|
accounted: ex.accounted,
|
|
405
410
|
moves: CONCEPT + STEP * ex.accounted.length,
|
|
406
|
-
unexplained: ex.unexplained,
|
|
407
411
|
}];
|
|
408
412
|
},
|
|
409
413
|
};
|
|
@@ -300,7 +300,6 @@ export const prefixMechanism: PipelineMechanism = {
|
|
|
300
300
|
// IDENTITY bridge takes.
|
|
301
301
|
accounted: [[0, query.length]],
|
|
302
302
|
moves: STEP,
|
|
303
|
-
unexplained: "",
|
|
304
303
|
// NOT complete: the query is a proper PREFIX, so the form may carry more
|
|
305
304
|
// past the remainder this voiced.
|
|
306
305
|
}];
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
voicesDisplacedFiller,
|
|
25
25
|
} from "../match.js";
|
|
26
26
|
import { CONCEPT, STEP } from "../graph-search.js";
|
|
27
|
-
import {
|
|
27
|
+
import { restates as lawRestates } from "../derivation.js";
|
|
28
28
|
import type { PipelineMechanism, Precomputed } from "../pipeline-mechanism.js";
|
|
29
29
|
import { rItem, rNode } from "../trace.js";
|
|
30
30
|
import { substitutionBridge } from "../bridge.js";
|
|
@@ -35,7 +35,6 @@ export interface RecallResult {
|
|
|
35
35
|
echoed: boolean;
|
|
36
36
|
accounted: Array<[number, number]>;
|
|
37
37
|
moves: number;
|
|
38
|
-
unexplained: string;
|
|
39
38
|
/** See {@link import("../pipeline-mechanism.js").MechanismResult.complete}
|
|
40
39
|
* — set by the IDENTITY-bridge tier alone. */
|
|
41
40
|
complete?: boolean;
|
|
@@ -71,7 +70,6 @@ export async function recallByResonance(
|
|
|
71
70
|
echoed,
|
|
72
71
|
accounted,
|
|
73
72
|
moves,
|
|
74
|
-
unexplained: unexplainedLabel(query, accounted),
|
|
75
73
|
...(complete ? { complete } : {}),
|
|
76
74
|
};
|
|
77
75
|
};
|
|
@@ -156,7 +154,7 @@ export async function recallByResonance(
|
|
|
156
154
|
// conversation reads as if it were the next thing to say.
|
|
157
155
|
if (
|
|
158
156
|
g !== null && g.length > 0 &&
|
|
159
|
-
!(
|
|
157
|
+
!lawRestates(query, g, 0, { proper: true })
|
|
160
158
|
) {
|
|
161
159
|
return ground(
|
|
162
160
|
g,
|
|
@@ -196,10 +194,11 @@ export async function recallByResonance(
|
|
|
196
194
|
// same principle that keeps cast from voicing stored questions), and
|
|
197
195
|
// projecting them forward is reverse recall's containment failure in the
|
|
198
196
|
// other direction — "whatever followed these bytes in some document".
|
|
199
|
-
|
|
197
|
+
// THE EQUALITY READING of the restatement law: this tier rejects an answer
|
|
198
|
+
// that IS the question (an echo), and a proper fragment is handled by the
|
|
199
|
+
// tier's own subspan tests further down — so the law is asked with `whole`.
|
|
200
200
|
const restates = (b: Uint8Array): boolean =>
|
|
201
|
-
|
|
202
|
-
(ctx.canon !== null && bytesEqual(ctx.canon(b), qKey));
|
|
201
|
+
lawRestates(query, b, 0, { equate: ctx.canon, whole: true });
|
|
203
202
|
const idBar = identityBar(ctx.store.D, ctx.space.maxGroup, query.length);
|
|
204
203
|
if (top.score >= idBar) {
|
|
205
204
|
for (const h of whole) {
|
|
@@ -408,7 +407,7 @@ export async function recallByResonance(
|
|
|
408
407
|
// — never an answer (the same principle as `restates` above, extended
|
|
409
408
|
// to fragments). Genuine anchor groundings — longer than the query,
|
|
410
409
|
// or disjoint from it — pass untouched.
|
|
411
|
-
else if (g && !(
|
|
410
|
+
else if (g && !lawRestates(query, g, 0, { proper: true })) {
|
|
412
411
|
return ground(
|
|
413
412
|
g,
|
|
414
413
|
"scaffolding-dominated query — ground the consensus-climb anchor",
|
|
@@ -627,7 +626,6 @@ export const recallMechanism: PipelineMechanism = {
|
|
|
627
626
|
bytes: r.bytes,
|
|
628
627
|
accounted: r.accounted,
|
|
629
628
|
moves: r.moves,
|
|
630
|
-
unexplained: r.unexplained,
|
|
631
629
|
provenance: r.echoed ? "recall-echo" : "recall",
|
|
632
630
|
used: new Set<number>(),
|
|
633
631
|
...(r.complete ? { complete: true } : {}),
|
|
@@ -39,7 +39,7 @@ import type { FrameInstance } from "../match.js";
|
|
|
39
39
|
import { carriesFillers, distinct, follow, substituteAll } from "../match.js";
|
|
40
40
|
import { dominates } from "../../geometry.js";
|
|
41
41
|
import { bytesEqual, indexOf } from "../../bytes.js";
|
|
42
|
-
import {
|
|
42
|
+
import { restates } from "../derivation.js";
|
|
43
43
|
import { STEP } from "../graph-search.js";
|
|
44
44
|
import type {
|
|
45
45
|
MechanismResult,
|
|
@@ -231,7 +231,7 @@ export async function bindReference(
|
|
|
231
231
|
if (bytes.length === 0) return fail("the binding produced nothing");
|
|
232
232
|
// Answering with the question is not answering — the same restated-fragment
|
|
233
233
|
// guard every recall tier applies.
|
|
234
|
-
if (
|
|
234
|
+
if (restates(query, bytes, 0, { proper: true })) {
|
|
235
235
|
return fail("the binding restates part of the question");
|
|
236
236
|
}
|
|
237
237
|
const carried = !bytesEqual(bytes, first);
|
|
@@ -278,7 +278,6 @@ export async function bindReference(
|
|
|
278
278
|
// binding claims strictly more than a one-slot binding, so where both are
|
|
279
279
|
// licensed the smaller claim wins.
|
|
280
280
|
moves: STEP * slots.length + STEP,
|
|
281
|
-
unexplained: unexplainedLabel(query, accounted),
|
|
282
281
|
// NOT scaffolding. That field counts answer bytes carried through BECAUSE
|
|
283
282
|
// NOTHING EXPLAINED THEM; a referent is carried because the frame's slot
|
|
284
283
|
// explains it, and it is accounted above. Reporting it would make every
|
|
@@ -677,15 +677,12 @@ export interface MechanismResult {
|
|
|
677
677
|
moves: number;
|
|
678
678
|
/** WHAT THIS ANSWER SPEAKS FOR — the anchors it voices, and therefore the
|
|
679
679
|
* content the reasoner must not pivot back through. Declared by the
|
|
680
|
-
* mechanism about its OWN result, exactly like `accounted`/`
|
|
680
|
+
* mechanism about its OWN result, exactly like `accounted`/`used`/
|
|
681
681
|
* `complete`: post-grounding honours the property and NEVER ASKS WHICH
|
|
682
682
|
* MECHANISM SET IT, so the market stays uniform. An EMPTY set is a real
|
|
683
683
|
* declaration — "this answer voices nothing" (recall) — and withholds
|
|
684
684
|
* nothing; omit the field and the pipeline re-recognises the answer. */
|
|
685
685
|
used?: ReadonlySet<number>;
|
|
686
|
-
unexplained: string;
|
|
687
|
-
/** Explicit weight override. When absent, weight = moves + PASS·unaccounted. */
|
|
688
|
-
weight?: number;
|
|
689
686
|
/** Bytes of `bytes` that came from spans nothing recognised — the asker's
|
|
690
687
|
* own words carried through verbatim rather than derived (see
|
|
691
688
|
* {@link liftedScaffolding}). Reported, not priced: the ladder prices what
|