@hviana/sema 0.9.2 → 0.9.3

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 (40) hide show
  1. package/dist/src/meter.d.ts +6 -0
  2. package/dist/src/meter.js +6 -0
  3. package/dist/src/mind/evidence.d.ts +6 -0
  4. package/dist/src/mind/evidence.js +19 -7
  5. package/dist/src/mind/mechanisms/cast.d.ts +1 -1
  6. package/dist/src/mind/mechanisms/cast.js +73 -12
  7. package/dist/src/mind/mechanisms/cover.js +4 -20
  8. package/dist/src/mind/mechanisms/recall.js +84 -8
  9. package/dist/src/mind/mechanisms/reference.js +25 -0
  10. package/dist/src/mind/mind.d.ts +1 -0
  11. package/dist/src/mind/pipeline-mechanism.js +15 -1
  12. package/dist/src/mind/pipeline.js +5 -4
  13. package/dist/src/mind/reasoning.js +28 -16
  14. package/dist/src/mind/resonance.d.ts +3 -2
  15. package/dist/src/mind/resonance.js +3 -2
  16. package/dist/src/mind/traverse.d.ts +52 -0
  17. package/dist/src/mind/traverse.js +334 -7
  18. package/dist/src/mind/types.d.ts +4 -1
  19. package/docs/INDEX.md +17 -17
  20. package/docs/INVARIANTS.md +1 -1
  21. package/docs/architecture/evidence.md +172 -29
  22. package/jsr.json +1 -1
  23. package/package.json +1 -1
  24. package/src/meter.ts +6 -0
  25. package/src/mind/evidence.ts +22 -4
  26. package/src/mind/mechanisms/cast.ts +77 -3
  27. package/src/mind/mechanisms/cover.ts +6 -22
  28. package/src/mind/mechanisms/recall.ts +107 -9
  29. package/src/mind/mechanisms/reference.ts +24 -1
  30. package/src/mind/mind.ts +3 -1
  31. package/src/mind/pipeline-mechanism.ts +15 -1
  32. package/src/mind/pipeline.ts +5 -4
  33. package/src/mind/reasoning.ts +33 -15
  34. package/src/mind/resonance.ts +3 -2
  35. package/src/mind/traverse.ts +338 -6
  36. package/src/mind/types.ts +6 -2
  37. package/test/154-the-question-names-the-step.test.mjs +88 -1
  38. package/test/155-the-relation-read-off-another-instance.test.mjs +376 -0
  39. package/test/29-counterfactual.test.mjs +21 -11
  40. package/test/76-reference-binding.test.mjs +32 -0
@@ -207,6 +207,12 @@ export declare class Meter {
207
207
  * came back at the √N cap, or its predecessor budget ran out before every
208
208
  * continuation was asked about — the distributional ladder decided. */
209
209
  askedReadsSaturated: number;
210
+ /** Picks named by a CO-INSTANCE of the question — another instance of its
211
+ * frame whose continuation carries the relation over to this node by an
212
+ * exact substitution (traverse.ts, `byCoInstance`). */
213
+ coInstanceNamings: number;
214
+ /** Proposed co-instances that tier read and witnessed. */
215
+ coInstanceReads: number;
210
216
  /** Cover sites dropped as FRAGMENTS whose several continuations the question
211
217
  * names none of (mechanisms/cover.ts). */
212
218
  unaskedFragments: number;
package/dist/src/meter.js CHANGED
@@ -217,6 +217,12 @@ export class Meter {
217
217
  * came back at the √N cap, or its predecessor budget ran out before every
218
218
  * continuation was asked about — the distributional ladder decided. */
219
219
  askedReadsSaturated = 0;
220
+ /** Picks named by a CO-INSTANCE of the question — another instance of its
221
+ * frame whose continuation carries the relation over to this node by an
222
+ * exact substitution (traverse.ts, `byCoInstance`). */
223
+ coInstanceNamings = 0;
224
+ /** Proposed co-instances that tier read and witnessed. */
225
+ coInstanceReads = 0;
220
226
  /** Cover sites dropped as FRAGMENTS whose several continuations the question
221
227
  * names none of (mechanisms/cover.ts). */
222
228
  unaskedFragments = 0;
@@ -17,6 +17,12 @@ export interface Witnessing {
17
17
  spans: Array<[number, number]>;
18
18
  /** Bytes of source 0 inside `spans`. */
19
19
  bytes: number;
20
+ /** The form's own bytes no source witnesses, as merged spans of the FORM —
21
+ * empty exactly when `complete`. ONE residue span is the shape of a
22
+ * co-instance: the same frame around a different filler (`When was Peter
23
+ * Jackson born?` read against `When was the director of film Jinpa
24
+ * born?` leaves `Peter Jackson`). */
25
+ residue: Array<[number, number]>;
20
26
  }
21
27
  /** Witness `form` against `sources` (their window indexes, same order). A
22
28
  * window is credited to the LAST source holding it — so source 0 is credited
@@ -48,9 +48,14 @@ export function unspoken(index, spoken) {
48
48
  * window is credited to the LAST source holding it — so source 0 is credited
49
49
  * only with what nothing else at hand supplies. */
50
50
  export function witness(form, indexes, W) {
51
- const none = { complete: false, spans: [], bytes: 0 };
52
- if (form.length < W || indexes.length === 0)
53
- return none;
51
+ if (form.length < W || indexes.length === 0) {
52
+ return {
53
+ complete: false,
54
+ spans: [],
55
+ bytes: 0,
56
+ residue: form.length > 0 ? [[0, form.length]] : [],
57
+ };
58
+ }
54
59
  const covered = new Uint8Array(form.length);
55
60
  const own = [];
56
61
  for (let o = 0; o + W <= form.length; o++) {
@@ -71,9 +76,16 @@ export function witness(form, indexes, W) {
71
76
  if (from === 0)
72
77
  own.push([at, at + W]);
73
78
  }
74
- for (let i = 0; i < form.length; i++)
75
- if (!covered[i])
76
- return none;
79
+ const residue = [];
80
+ for (let i = 0; i < form.length; i++) {
81
+ if (covered[i])
82
+ continue;
83
+ const last = residue[residue.length - 1];
84
+ if (last !== undefined && last[1] === i)
85
+ last[1] = i + 1;
86
+ else
87
+ residue.push([i, i + 1]);
88
+ }
77
89
  own.sort((a, b) => a[0] - b[0]);
78
90
  const spans = [];
79
91
  for (const [s, e] of own) {
@@ -86,5 +98,5 @@ export function witness(form, indexes, W) {
86
98
  let bytes = 0;
87
99
  for (const [s, e] of spans)
88
100
  bytes += e - s;
89
- return { complete: true, spans, bytes };
101
+ return { complete: residue.length === 0, spans, bytes, residue };
90
102
  }
@@ -37,7 +37,7 @@ export interface CastResult {
37
37
  * painted by Leonardo da Vinci.") must be seated by that establishing
38
38
  * sentence, NOT by its own biography fact — voicing the bio leaks exactly
39
39
  * what a comparison must keep out, and loses the embedded "Mona Lisa"
40
- * term C3 relies on for a further hop.
40
+ * term C3's further-hop candidate lives in.
41
41
  *
42
42
  * The distinguishing signal is content-addressed, not a count: a genuine
43
43
  * establishing predecessor's bytes CONTAIN id's own bytes — it names or
@@ -11,11 +11,11 @@
11
11
  // gate = the frame gate below + analogyStrength, projection = insert / project /
12
12
  // juxtapose.
13
13
  import { read } from "../primitives.js";
14
- import { argmaxBy, corpusN, edgeAncestors, hubBound, sharedReachMemo, } from "../traverse.js";
14
+ import { answersOtherQuestions, argmaxBy, coInstanceFiller, corpusN, edgeAncestors, hubBound, hubWindows, offsetCanon, sharedReachMemo, } from "../traverse.js";
15
15
  import { analogyStrength, follow, project, reverseContext, sharedFrameStrengthOf, } from "../match.js";
16
16
  import { joinWithBridge } from "../resonance.js";
17
17
  import { CONCEPT, STEP } from "../graph-search.js";
18
- import { indexOf } from "../../bytes.js";
18
+ import { indexOf, latin1 } from "../../bytes.js";
19
19
  import { consensusFloor, dominates } from "../../geometry.js";
20
20
  import { restates, unexplainedSpans } from "../derivation.js";
21
21
  import { rItem, rNode } from "../trace.js";
@@ -81,7 +81,7 @@ const MIN_WEAVE = 2;
81
81
  * painted by Leonardo da Vinci.") must be seated by that establishing
82
82
  * sentence, NOT by its own biography fact — voicing the bio leaks exactly
83
83
  * what a comparison must keep out, and loses the embedded "Mona Lisa"
84
- * term C3 relies on for a further hop.
84
+ * term C3's further-hop candidate lives in.
85
85
  *
86
86
  * The distinguishing signal is content-addressed, not a count: a genuine
87
87
  * establishing predecessor's bytes CONTAIN id's own bytes — it names or
@@ -591,8 +591,16 @@ export async function counterfactualTransfer(ctx, query, pre) {
591
591
  // its own fact — so the same bar applies. The displaced structure is only
592
592
  // recognised as the slot being overridden and is never voiced, so it is
593
593
  // deliberately not gated here.
594
+ // …and the substitute must lead somewhere FOR THIS QUESTION: a fragment
595
+ // whose continuations the question names none of answers other questions
596
+ // (traverse.ts, `answersOtherQuestions`). `ong)?`, the tail of every
597
+ // `… (… Song)?` question, was "named" by `What is the place of birth of the
598
+ // performer of song Heaven (Namie Amuro Song)?`, and redirection voiced
599
+ // its most-poured stranger's birthplace.
600
+ const stranger = last !== undefined &&
601
+ answersOtherQuestions(ctx, last.point.anchor, query.length, last.run.qe - last.run.qs);
594
602
  if (last !== undefined && last.point !== dominant && displaced &&
595
- voiceable(last.point)) {
603
+ voiceable(last.point) && !stranger) {
596
604
  const g = await project(ctx, last.point.anchor, qv);
597
605
  if (g !== null) {
598
606
  ctx.trace?.step("projectCounterfactual", [
@@ -939,6 +947,42 @@ export async function counterfactualTransfer(ctx, query, pre) {
939
947
  : [];
940
948
  const cmpGaps = unexplainedSpans(query.length, cmpAccounted);
941
949
  const cmpMaxGap = cmpGaps.reduce((n, [s, e]) => Math.max(n, e - s), 0);
950
+ // TWO THINGS NAMED. A comparison voices two structures, so the question
951
+ // must evidence the second one with material of its own: a W-window of the
952
+ // question that the analog holds — on its aligned runs, or anywhere in its
953
+ // own form under the response's equivalence (the witness reading,
954
+ // evidence.md) — and that is neither inside the dominant's runs nor corpus
955
+ // scaffolding (`hubWindows`, the reading of "what the question owes").
956
+ // `father of Frederick II?` reached `Peter III of Aragon father` through
957
+ // ` father`, which the dominant `Frederick II father` already holds, and
958
+ // ` of `, which every fact holds — one structure named, and the comparison
959
+ // glued the analog's bare question onto the answer (`…is Peter III of
960
+ // Aragon.Peter III of Aragon father`). `How is ice like steel?` names
961
+ // `Ice is cold` with `ice `, a window no byte-exact run aligns (the case
962
+ // differs) and the dominant `Steel is hard` lacks.
963
+ const analogOwnsEvidence = () => {
964
+ if (bestAnalog === null)
965
+ return false;
966
+ const W = ctx.space.maxGroup;
967
+ const hub = hubWindows(ctx, query);
968
+ const mine = runSpans(dominant);
969
+ const owns = (o) => !hub[o] && !mine.some(([ms, me]) => o >= ms && o + W <= me);
970
+ for (const [s, e] of runSpans(bestAnalog.point ?? bestAnalog.src)) {
971
+ for (let o = s; o + W <= e; o++)
972
+ if (owns(o))
973
+ return true;
974
+ }
975
+ const asked = ctx._edgeAsked;
976
+ if (asked === null)
977
+ return false;
978
+ const form = offsetCanon(ctx, read(ctx, bestAnalog.anchor, asked.bytes.length * W));
979
+ for (let o = 0; o + W <= form.length; o++) {
980
+ const at = asked.index.get(latin1(form.subarray(o, o + W)));
981
+ if (at !== undefined && owns(at))
982
+ return true;
983
+ }
984
+ return false;
985
+ };
942
986
  // An analog that is not itself a directly ALIGNED point (point !== null —
943
987
  // its own runs are query bytes, the query NAMED it) was only reached
944
988
  // through a continuation hop or the structural-hub fallback. Voicing
@@ -1066,8 +1110,18 @@ export async function counterfactualTransfer(ctx, query, pre) {
1066
1110
  // supply were never the ones that test is about.
1067
1111
  const cmpDismisses = !bestHalo &&
1068
1112
  dismissedKnownContent(ctx, query, cmpAccounted);
1113
+ // …and the dominant must be something the question is ABOUT. A co-instance
1114
+ // of the question (traverse.ts, `coInstanceFiller`) is its frame around
1115
+ // another filler, and its seat is that filler's own answer: `Where was the
1116
+ // performer of song God (Lennon Song) born?` compared `Where was Shakira
1117
+ // (Shakira Song) born?` with `John Lennon` and voiced Shakira's birthplace.
1118
+ const asked = ctx._edgeAsked;
1119
+ const dominantOtherInstance = asked !== null &&
1120
+ coInstanceFiller(ctx, read(ctx, dominant.anchor, 2 * query.length + 1), [asked.index], asked.bytes) !== null;
1069
1121
  if (bestAnalog !== null &&
1070
1122
  (bestHalo || analogNamed || rootTrusted) &&
1123
+ analogOwnsEvidence() &&
1124
+ !dominantOtherInstance &&
1071
1125
  !cmpDismisses &&
1072
1126
  queryScale(dominant.ctx.length) &&
1073
1127
  roots.length <= 1 &&
@@ -1187,14 +1241,21 @@ export async function counterfactualTransfer(ctx, query, pre) {
1187
1241
  ? `the best analog carries no halo-tier company evidence, was never ` +
1188
1242
  `named by the query, and no committed root's consensus vote ` +
1189
1243
  `clears the floor, so comparison refuses to voice it`
1190
- : cmpDismisses
1191
- ? `a frame-tier analog under an untrusted root dismisses stored ` +
1192
- `query content its alignment never accounted for — comparison ` +
1193
- `refuses to ignore what the store knows`
1194
- : `comparison's own accounted evidence leaves a ${cmpMaxGap}-byte gap in ` +
1195
- `a ${query.length}-byte query against a ${dominant.ctx.length}-byte ` +
1196
- `dominant — too large to be mere framing — so it refuses rather ` +
1197
- `than paper over it with an analog the query never asked about`);
1244
+ : dominantOtherInstance
1245
+ ? `the dominant is another instance of the question's frame — its ` +
1246
+ `seat is another filler's answer, not what the question asks about`
1247
+ : !analogOwnsEvidence()
1248
+ ? `the question evidences the analog only with windows the dominant ` +
1249
+ `already holds or the corpus' scaffolding — it names one structure, ` +
1250
+ `not two, so there is nothing to compare`
1251
+ : cmpDismisses
1252
+ ? `a frame-tier analog under an untrusted root dismisses stored ` +
1253
+ `query content its alignment never accounted for — comparison ` +
1254
+ `refuses to ignore what the store knows`
1255
+ : `comparison's own accounted evidence leaves a ${cmpMaxGap}-byte gap in ` +
1256
+ `a ${query.length}-byte query against a ${dominant.ctx.length}-byte ` +
1257
+ `dominant — too large to be mere framing — so it refuses rather ` +
1258
+ `than paper over it with an analog the query never asked about`);
1198
1259
  }
1199
1260
  t?.done(results.map((r) => rItem(r.bytes, "answer")), results.length > 0
1200
1261
  ? `${results.length} counterfactual schema(s) fired — the grounding decider weighs them`
@@ -9,7 +9,7 @@
9
9
  // near-zero-cost incumbent that prunes the other mechanisms through the
10
10
  // ordinary admissible-floor check, with no extension special-case anywhere.
11
11
  import { read, resolve } from "../primitives.js";
12
- import { guidedFirst, hubBound, namedContinuations, scaffoldSpans, } from "../traverse.js";
12
+ import { answersOtherQuestions, guidedFirst, hubBound, scaffoldSpans, } from "../traverse.js";
13
13
  import { conceptHop } from "../match.js";
14
14
  import { bridge } from "../resonance.js";
15
15
  import { liftAnswer, liftedScaffolding, segRestatesQuery } from "../types.js";
@@ -191,25 +191,9 @@ export const coverMechanism = {
191
191
  s.end,
192
192
  ])), "a computation always wins: recognised forms overlapping a computed span are dropped");
193
193
  }
194
- // A FRAGMENT ANSWERS OTHER QUESTIONS. A recognised form that sits inside
195
- // other forms (it has structural parents or containers) holds continuations
196
- // because the forms it is a piece of were asked — suffix inheritance gives
197
- // `f death` the answer of every `… place of death` question. Choosing one of
198
- // several such continuations by popularity voices some other question's
199
- // answer, and the cover used to account the fragment's bytes as explained by
200
- // it. A fragment with several continuations leads somewhere FOR THIS
201
- // QUESTION only when the question names one (traverse.ts, the exact tier).
202
- // A form that is (nearly) the whole question is not a piece of it: the
203
- // question says nothing beyond it, so its continuations answer THIS question.
204
- const asked = ctx._edgeAsked;
205
- const W0 = ctx.space.maxGroup;
206
- const leading = asked === null
207
- ? sites
208
- : sites.filter((s) => query.length - (s.end - s.start) < W0 ||
209
- !(ctx.store.hasParents(s.payload) ||
210
- ctx.store.hasContainers(s.payload)) ||
211
- ctx.store.nextFirst(s.payload, 2).length < 2 ||
212
- namedContinuations(ctx, s.payload, asked) !== null);
194
+ // A FRAGMENT ANSWERS OTHER QUESTIONS (traverse.ts) — and the cover used to
195
+ // account the fragment's bytes as explained by the stranger's answer.
196
+ const leading = sites.filter((s) => !answersOtherQuestions(ctx, s.payload, query.length, s.end - s.start));
213
197
  if (leading.length < sites.length) {
214
198
  if (ctx.meter) {
215
199
  ctx.meter.unaskedFragments += sites.length - leading.length;
@@ -7,7 +7,7 @@ import { cosine } from "../../vec.js";
7
7
  import { consensusFloor, dominates, identityBar, reachThreshold, significanceBar, } from "../../geometry.js";
8
8
  import { gistOf, read, resolve } from "../primitives.js";
9
9
  import { indexOf } from "../../bytes.js";
10
- import { allWindowsAreScaffolding, askedEvidence, corpusN, guidedFirst, hubBound, } from "../traverse.js";
10
+ import { allWindowsAreScaffolding, answersOtherQuestions, askedEvidence, canonHeldPoints, coInstanceFiller, corpusN, guidedFirst, hubBound, namedContinuations, } from "../traverse.js";
11
11
  import { follow, project, reverseContext, voicesDisplacedFiller, } from "../match.js";
12
12
  import { CONCEPT, STEP } from "../graph-search.js";
13
13
  import { restates as lawRestates } from "../derivation.js";
@@ -55,11 +55,10 @@ export async function recallByResonance(ctx, query, pre) {
55
55
  // constituent bar is the same two-quanta (2W) reading confluence binds
56
56
  // under, nested recognitions collapse to their MAXIMAL span, and two
57
57
  // distinct maximal arguments mean the query asks about neither alone.
58
- if (qId === null) {
59
- const W2 = 2 * ctx.space.maxGroup;
60
- const args = pre.rec.sites.filter((s) => s.end - s.start >= W2 &&
61
- s.end - s.start < query.length &&
62
- ctx.store.hasNext(s.payload));
58
+ // The argument binding, given its candidate arguments (`args`) and the
59
+ // recognised fragments that answer other questions (`strangerIds`).
60
+ const W2 = 2 * ctx.space.maxGroup;
61
+ const bindArgument = async (args, strangerIds) => {
63
62
  // Maximal spans by one sorted sweep (starts ascending, ties longest
64
63
  // first): every earlier span starts at or before s, so s is contained
65
64
  // exactly when the running max end already covers it. O(m log m) — a
@@ -86,11 +85,22 @@ export async function recallByResonance(ctx, query, pre) {
86
85
  // binding to the argument's continuation would answer past content
87
86
  // the query itself already carries forward. Derived from the same W2
88
87
  // bar the argument itself is held to, never a separate tuned number.
88
+ // A fragment that answers other questions is not such a piece.
89
89
  const hasSubstantialOutside = maximal.length === 1 &&
90
- pre.rec.sites.some((s) => s.end - s.start >= W2 &&
90
+ pre.rec.sites.some((s) => s.end - s.start >= W2 && !strangerIds.has(s.payload) &&
91
91
  (s.end <= maximal[0].start || s.start >= maximal[0].end));
92
92
  if (maximal.length === 1 && !hasSubstantialOutside) {
93
93
  const arg = maximal[0];
94
+ // An argument whose several continuations the question names none of
95
+ // outright would be followed by popularity. Another instance of the
96
+ // question may name one (traverse.ts, `byCoInstance`), and its
97
+ // proposals are the consensus climb's points — so the climb is asked
98
+ // for first, exactly where the choice would otherwise be blind.
99
+ const asked = ctx._edgeAsked;
100
+ if (asked !== null && asked.points === undefined &&
101
+ ctx.store.nextFirst(arg.payload, 2).length >= 2 &&
102
+ namedContinuations(ctx, arg.payload, asked) === null)
103
+ await pre.attention();
94
104
  const g = await follow(ctx, arg.payload, queryGist);
95
105
  // The same "no restated fragment" guard tier 2 applies below (§ "the
96
106
  // anchor cleared the consensus floor..."): a followed continuation
@@ -113,6 +123,45 @@ export async function recallByResonance(ctx, query, pre) {
113
123
  return ground(g, "argument binding — the query's sole edge-source constituent, continuation followed", [[arg.start, arg.end], ...named], STEP);
114
124
  }
115
125
  }
126
+ return null;
127
+ };
128
+ let canonArgumentPending = false;
129
+ let strangers = new Set();
130
+ if (qId === null) {
131
+ const recognised = pre.rec.sites.filter((s) => s.end - s.start >= W2 &&
132
+ s.end - s.start < query.length &&
133
+ ctx.store.hasNext(s.payload));
134
+ // An argument must lead somewhere FOR THIS QUESTION: a fragment whose
135
+ // continuations the question names none of answers other questions
136
+ // (traverse.ts) — `director`, inside `When was the director of film Jinpa
137
+ // born?`, bound the most-poured of fifty-five directors. Such a fragment
138
+ // is no argument, and no independent piece of the query either.
139
+ const strangerIds = new Set();
140
+ for (const s of recognised) {
141
+ if (answersOtherQuestions(ctx, s.payload, query.length, s.end - s.start))
142
+ strangerIds.add(s.payload);
143
+ }
144
+ const args = recognised.filter((s) => !strangerIds.has(s.payload));
145
+ if (args.length === 0 && strangerIds.size > 0) {
146
+ if (ctx.meter)
147
+ ctx.meter.unaskedFragments += strangerIds.size;
148
+ ctx.trace?.step("unaskedFragments", recognised.filter((s) => strangerIds.has(s.payload)).map((s) => rItem(query.subarray(s.start, s.end), "fragment", s.payload, [
149
+ s.start,
150
+ s.end,
151
+ ])), [], "the only arguments are pieces of other forms whose continuations the question names none of — they answer other questions");
152
+ }
153
+ const bound = await bindArgument(args, strangerIds);
154
+ if (bound !== null)
155
+ return bound;
156
+ // NO ARGUMENT BY BYTES IS NOT NO ARGUMENT. Recognition matches bytes, so
157
+ // `Man At Bath` (2Wiki title-cases its questions) is no site of the stored
158
+ // `Man at Bath`. When nothing recognised can bind, the points the
159
+ // consensus climb reaches that the question holds under the response's
160
+ // equivalence are arguments too (traverse.ts, `canonHeldPoints`) — read
161
+ // after the clean-resonance tier, which answers a near-identical question
162
+ // without any climb.
163
+ canonArgumentPending = ctx.canon !== null && args.length === 0;
164
+ strangers = strangerIds;
116
165
  }
117
166
  // The response's ONE top-k read (Precomputed.resonance) — the same list the
118
167
  // frame inventory is assembled from, so a query that reaches both pays for a
@@ -186,6 +235,18 @@ export async function recallByResonance(ctx, query, pre) {
186
235
  const reach = reachThreshold(ctx.space.maxGroup);
187
236
  const fracOfQuery = (cos, otherLen) => Math.min(1, Math.max(0, cos - sig) *
188
237
  Math.sqrt(otherLen / Math.max(1, query.length)));
238
+ // The argument the question holds only under the response's equivalence
239
+ // (above). Not gated on the whole-query resonance: a question whose only
240
+ // argument is a case variant (`… film Man At Bath work at?`) resonates
241
+ // below the significance bar as a whole.
242
+ if (canonArgumentPending) {
243
+ await pre.attention();
244
+ const held = canonHeldPoints(ctx, W2).filter((s) => ctx.store.hasNext(s.payload) &&
245
+ !answersOtherQuestions(ctx, s.payload, query.length, s.end - s.start));
246
+ const bound = await bindArgument(held, strangers);
247
+ if (bound !== null)
248
+ return bound;
249
+ }
189
250
  // 2. Scaffolding-dominated.
190
251
  if (top.score >= sig) {
191
252
  // The committed points of attention ARE the shared climb's roots (same
@@ -311,7 +372,22 @@ export async function recallByResonance(ctx, query, pre) {
311
372
  // is a stronger claim that needs the corpus's own carriage evidence, and
312
373
  // that is `reference`'s job.
313
374
  const anchorBytes = read(ctx, forest[0].anchor, query.length * ctx.space.maxGroup + 1);
314
- if (g !== null && voicesDisplacedFiller(ctx, query, anchorBytes, g)) {
375
+ // …and the same refusal read from the anchor's side: an anchor the query
376
+ // witnesses in every byte but one filler of its own is ANOTHER INSTANCE
377
+ // of the question (traverse.ts, `coInstanceFiller`). The query-side
378
+ // reading above needs the shared frame to dominate the QUERY, which a
379
+ // long slot defeats: `Where was the performer of song God (John Lennon
380
+ // Song) born?` elected `Where was Nicki Minaj (Nicki Minaj Song) born?`
381
+ // and answered Nicki Minaj's birthplace.
382
+ const asked = ctx._edgeAsked;
383
+ const co = asked === null
384
+ ? null
385
+ : coInstanceFiller(ctx, anchorBytes, [asked.index], asked.bytes);
386
+ if (co !== null) {
387
+ ctx.trace?.step("coInstanceAnchor", [rItem(query, "query"), rNode(ctx, forest[0].anchor, "anchor")], [rItem(anchorBytes.subarray(co.span[0], co.span[1]), "filler")], "refused — the anchor is another instance of the question's frame, " +
388
+ "and its continuation speaks of its own filler");
389
+ }
390
+ else if (g !== null && voicesDisplacedFiller(ctx, query, anchorBytes, g)) {
315
391
  ctx.trace?.step("displacedFiller", [rItem(query, "query"), rNode(ctx, forest[0].anchor, "anchor")], [rItem(g, "withheld")], "refused — the anchor's continuation speaks the anchor's own " +
316
392
  "occupant of a position this query fills differently");
317
393
  } // The anchor cleared the consensus floor, but the floor prices the
@@ -34,6 +34,8 @@
34
34
  // population for the other is the error commonality.md names. The notion is
35
35
  // made AVAILABLE, never imposed.
36
36
  import { carriesFillers, distinct, follow, substituteAll } from "../match.js";
37
+ import { resolve } from "../primitives.js";
38
+ import { hubBound } from "../traverse.js";
37
39
  import { dominates } from "../../geometry.js";
38
40
  import { bytesEqual } from "../../bytes.js";
39
41
  import { restates } from "../derivation.js";
@@ -172,13 +174,36 @@ export async function bindReference(ctx, query, pre) {
172
174
  // discard them. Each goes through the shared projection, so an ambiguous
173
175
  // instance is disambiguated exactly as it would be anywhere else.
174
176
  const leadsNowhere = "an instance of the frame leads nowhere";
177
+ // A FACT FILED UNDER ITS FILLER IS NOT A CARRIAGE. When an instance's
178
+ // filler is itself a stored context leading to that instance's answer, the
179
+ // answer is something the corpus knows ABOUT that filler (`The place of
180
+ // birth of Peter Jackson is Wellington.` is a continuation of `Peter
181
+ // Jackson`), not a form any occupant takes — and two such facts can agree
182
+ // by chance (two people born in Wellington). `Run gcc hello.c` is filed
183
+ // under the question alone.
184
+ const filedUnderFiller = (inst, cont) => {
185
+ const c = resolve(ctx, cont);
186
+ if (c === null)
187
+ return false;
188
+ return inst.slots.some((s) => {
189
+ const f = resolve(ctx, s.filler);
190
+ return f !== null &&
191
+ ctx.store.nextFirst(f, hubBound(ctx)).includes(c);
192
+ });
193
+ };
175
194
  const first = await follow(ctx, frame[0].id, pre.guide);
176
195
  if (first === null || first.length === 0)
177
196
  return fail(leadsNowhere);
197
+ if (filedUnderFiller(frame[0], first)) {
198
+ return fail("the frame's answer is a fact filed under its filler");
199
+ }
178
200
  for (let i = 1; i < frame.length; i++) {
179
201
  const cont = await follow(ctx, frame[i].id, pre.guide);
180
202
  if (cont === null || cont.length === 0)
181
203
  return fail(leadsNowhere);
204
+ if (filedUnderFiller(frame[i], cont)) {
205
+ return fail("the frame's answer is a fact filed under its filler");
206
+ }
182
207
  if (!carriesFillers(first, fillersOf(frame[0]), cont, fillersOf(frame[i]))) {
183
208
  ctx.trace?.step("referenceLicence", [rItem(first, "instance"), rNode(ctx, frame[i].id, "against")], [rItem(cont, "attested")], "refused — the frame's answer carries content that depends on WHICH " +
184
209
  "filler, so the corpus cannot supply it for a new one");
@@ -170,6 +170,7 @@ export declare class Mind implements MindContext {
170
170
  _edgeAsked: {
171
171
  bytes: Uint8Array;
172
172
  index: WindowIndex;
173
+ points?: readonly number[];
173
174
  } | null;
174
175
  /** Per-response memo of {@link chooseNext} picks — ensures every mechanism
175
176
  * of a single response follows the SAME continuation for each ambiguous
@@ -203,7 +203,21 @@ export class Precomputed {
203
203
  * fusion all share. Computed on first access; a query no mechanism
204
204
  * climbs for (e.g. one an extension decided outright) never pays for it. */
205
205
  attention() {
206
- return this._attention ??= this.shared("attention", () => climbAttentionAll(this.ctx, this.query, this.k));
206
+ return this._attention ??= this.shared("attention", () => climbAttentionAll(this.ctx, this.query, this.k)).then((read) => {
207
+ // The climb's scored anchors are what the exact tier reads co-instances
208
+ // of the question from (traverse.ts, `relationFrames`): the
209
+ // approximate climb proposes, witnessing decides.
210
+ // A pick made before the points existed read less evidence than one
211
+ // made after, so the response's pick memo starts over (traverse.ts,
212
+ // guidedNext: a pick is a function of the store, the guide AND the
213
+ // points — traced and untraced responses must agree).
214
+ const asked = this.ctx._edgeAsked;
215
+ if (asked !== null && asked.points === undefined) {
216
+ asked.points = read.ranked.map((a) => a.anchor);
217
+ this.ctx._edgeChoice.clear();
218
+ }
219
+ return read;
220
+ });
207
221
  }
208
222
  _weave;
209
223
  /** Result of {@link alignGraded} for the first k ranked anchors —
@@ -538,13 +538,14 @@ export async function think(ctx, query, mechs) {
538
538
  // Reading the used anchors' OWN bytes here says something stronger and
539
539
  // wrong: that nothing INSIDE what was voiced may be pivoted through. A
540
540
  // comparison's seat sentence legitimately contains further terms with
541
- // their own unrelated facts, and C3 pins exactly that — `Mona Lisa`, inside
542
- // the voiced seat `The Mona Lisa was painted by Leonardo da Vinci.`, leads
543
- // on to `Mona Lisa hangs in the Louvre`, which is about neither analog.
541
+ // their own unrelated facts — `Mona Lisa`, inside the voiced seat `The Mona
542
+ // Lisa was painted by Leonardo da Vinci.`, leads on to `Mona Lisa hangs in
543
+ // the Louvre`, which is about neither analog (test/29 C3: a candidate the
544
+ // walk takes only when the question names it).
544
545
  // The withheld content is the used anchors' CONTINUATIONS, so that is what
545
546
  // the containment rule reads: `speare` is contained in `Shakespeare wrote
546
547
  // 39 plays` and stays refused, while `Mona Lisa` appears in no withheld
547
- // continuation and the genuine further hop fires.
548
+ // continuation and stays a candidate.
548
549
  //
549
550
  // Only a mechanism carrying its own `used` set (cast/join) gets this: there
550
551
  // `preConsumed` is a deliberate, short list of the anchors the answer
@@ -6,7 +6,7 @@ import { rItem, rNode } from "./trace.js";
6
6
  import { bytesEqual, indexOf, latin1 } from "../bytes.js";
7
7
  import { read, resolve } from "./primitives.js";
8
8
  import { countClusters } from "./attention.js";
9
- import { guidedFirst, hubBound, namedContinuations, offsetCanon, } from "./traverse.js";
9
+ import { coInstanceFiller, guidedFirst, hubBound, namedContinuations, offsetCanon, } from "./traverse.js";
10
10
  import { unspoken, windowIndex } from "./evidence.js";
11
11
  import { containsSpan, follow, haloSiblings, project } from "./match.js";
12
12
  import { joinWithBridge, pivotInto } from "./resonance.js";
@@ -211,16 +211,12 @@ export function walkLayer(ctx, query, preConsumed, pre, voiced = []) {
211
211
  // 30 s); and raising it from 12 to 200 changed neither the answer nor
212
212
  // `pivotSteps` on the chain fixtures.
213
213
  const qv = pre.guide; // the response-wide guide IS the query's gist
214
- // WHOSE EXTENSION IS THIS? `voiced` is what the mechanism WITHHELD (the
215
- // pipeline sends the used anchors' CONTINUATIONS, not their bytes), so a
216
- // non-empty `voiced` means exactly what that note says: the grounding came
217
- // from a mechanism that carries its own short `used` set (cast/join) and
218
- // therefore OWNS the shape of its answer. The further terms inside such a
219
- // seat are legitimately followable (test/29 C3's `Mona Lisa` lives inside the
220
- // voiced seat and leads on to a fact about neither analog), which the law
221
- // expresses as the identity species of progress — `moves` — declared by the
222
- // reporter and never inferred from the mechanism's name.
223
- const producerOwnsShape = voiced.length > 0;
214
+ // NO PRODUCER OWNS THE NEXT STEP. A grounding that declared what it voiced
215
+ // (cast/join) used to MOVE through any further term inside its answer,
216
+ // unasked — `Who is the director of The Jerk?` grounded by CAST walked on to
217
+ // `The country of citizenship of Carl Reiner is American.` What it voiced
218
+ // still bounds what may be pivoted through (`voiced`, pivotInto); whether a
219
+ // step is taken is the naming rule below, the same for every mechanism.
224
220
  let hop = 0;
225
221
  let t;
226
222
  // WHAT THE OFFERED STEP WOULD BE. The law decides, so the accepted step is
@@ -358,20 +354,19 @@ export function walkLayer(ctx, query, preConsumed, pre, voiced = []) {
358
354
  const hop = guidedFirst(ctx, pivot);
359
355
  named = names !== null && hop !== undefined && names.includes(hop);
360
356
  }
361
- if (!named && !producerOwnsShape && closed(d)) {
357
+ if (!named && closed(d)) {
362
358
  ctx.trace?.step("pivotUnasked", [rItem(cur, "answer"), rNode(ctx, pivot, "pivot")], [rItem(fc, "withheld")], "the derivation owes nothing and the question names no further step — not offered");
363
359
  return null;
364
360
  }
365
361
  pending = { kind: "pivot", cur, pivot, fc };
366
- // Offered with the identity species when the grounding declared what it
367
- // speaks for, or when the question names the step; otherwise the law
368
- // requires this step to carry question material the grounding left
362
+ // Offered with the identity species when the question names the step;
363
+ // otherwise the law requires this step to carry question material the grounding left
369
364
  // unaccounted, which is the drift the extension tests pin — refused by the
370
365
  // law's own measure, not by a private window test.
371
366
  return {
372
367
  product: fc,
373
368
  contains: true,
374
- reaches: producerOwnsShape || named,
369
+ reaches: named,
375
370
  cost: STEP,
376
371
  };
377
372
  };
@@ -681,6 +676,23 @@ primarySpans = []) {
681
676
  // again would only restate it. Deliberately NOT a magnitude measure:
682
677
  // it fires on exact content-addressed recurrence, not on how strongly
683
678
  // the root resonates.
679
+ // ANOTHER INSTANCE IS NOT ANOTHER TOPIC. A root the question witnesses
680
+ // in every byte but one contiguous span is the question's own frame
681
+ // around a different filler (evidence.ts, `coInstanceFiller`): the climb
682
+ // committed `Where was Peter Jackson born?` as a second point of
683
+ // `Where was the director of film Beat Girl born?` on the frame windows
684
+ // alone, and fusing it voiced Peter Jackson's birthplace beside the
685
+ // answer. Such a root says what the question's relation IS (traverse.ts,
686
+ // `byCoInstance`), never what it asks about.
687
+ const asked = ctx._edgeAsked;
688
+ if (asked !== null) {
689
+ const form = read(ctx, root.anchor, 2 * query.length);
690
+ const co = coInstanceFiller(ctx, form, [asked.index], asked.bytes);
691
+ if (co !== null) {
692
+ ctx.trace?.step("coInstanceRoot", [rNode(ctx, root.anchor, "point", root.vote)], [rItem(form.subarray(co.span[0], co.span[1]), "filler")], "the question witnesses this point in every byte but one filler of its own — another instance of the question's frame, not a further topic");
693
+ continue;
694
+ }
695
+ }
684
696
  const cont = await follow(ctx, root.anchor, qv);
685
697
  if (cont !== null && cont.length > 0 &&
686
698
  // The law's positional reading: the caller knows the material it is
@@ -26,8 +26,9 @@ export declare function joinWithBridge(ctx: MindContext, left: Uint8Array, right
26
26
  * Shakespeare" (id 676) and the pivot hopped through "speare" (id 606, not
27
27
  * in `consumed`) straight into that analog's own biography, which is exactly
28
28
  * what the comparison had refused to voice. The rule is CONTAINMENT, not
29
- * overlap, so C3's genuine further hop — "Mona Lisa", a term inside the seat
30
- * sentence but part of NEITHER analog — still fires. */
29
+ * overlap, so C3's further term — "Mona Lisa", inside the seat sentence but
30
+ * part of NEITHER analog — stays a candidate; whether the walk steps through
31
+ * it is the naming rule's decision (reasoning.ts, evidence.md). */
31
32
  export declare function pivotInto(ctx: MindContext, answer: Uint8Array, consumed: ReadonlySet<number>, voiced?: readonly Uint8Array[]): Promise<number | null>;
32
33
  export declare function meaningOf(ctx: MindContext, bytes: Uint8Array, anchors: ReadonlyArray<{
33
34
  name: string;
@@ -236,8 +236,9 @@ export async function joinWithBridge(ctx, left, right) {
236
236
  * Shakespeare" (id 676) and the pivot hopped through "speare" (id 606, not
237
237
  * in `consumed`) straight into that analog's own biography, which is exactly
238
238
  * what the comparison had refused to voice. The rule is CONTAINMENT, not
239
- * overlap, so C3's genuine further hop — "Mona Lisa", a term inside the seat
240
- * sentence but part of NEITHER analog — still fires. */
239
+ * overlap, so C3's further term — "Mona Lisa", inside the seat sentence but
240
+ * part of NEITHER analog — stays a candidate; whether the walk steps through
241
+ * it is the naming rule's decision (reasoning.ts, evidence.md). */
241
242
  export async function pivotInto(ctx, answer, consumed, voiced = []) {
242
243
  // The pivot's OWN shortlist capacity — not `recallQueryK`: they are different
243
244
  // quantities (a mechanical sweep's probe budget vs the bridge's candidate-read