@hviana/sema 0.5.6 → 0.5.8

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.
@@ -0,0 +1,342 @@
1
+ // 76 — TYPE-LEVEL COMPANY (the halo pour's constituent profile).
2
+ //
3
+ // What is under test is ONE claim: two forms become distributional siblings
4
+ // when their partners are MADE OF a shared content unit, even though the
5
+ // partners share no node at the top of the fold. That is the difference
6
+ // between a halo keyed on a TOKEN ("occurred next to node #4711992") and one
7
+ // keyed on a TYPE ("occurred next to something containing 'Paris'").
8
+ //
9
+ // WHY THESE TESTS CANNOT PASS BY ACCIDENT. Every positive assertion is paired
10
+ // with a NEGATIVE CONTROL drawn from the same fixture, trained in the same
11
+ // store, of the same shape and comparable length — so a change that merely
12
+ // made all halos correlate (the null model collapsing) fails the control
13
+ // instead of passing the positive. Every bar is DERIVED from D, never tuned:
14
+ // `significanceBar` (3/√D) for "this is not chance" and `conceptThreshold` for
15
+ // "these are the same concept". And T1 computes, in-test, the fact that makes
16
+ // the whole file a test of the constituent descent rather than of halos in
17
+ // general: the two partners' depth-1 constituent sets are DISJOINT, so a
18
+ // profile reading only `rec.kids` has literally nothing in common to find.
19
+ //
20
+ // WHAT EACH TEST IS, STATED HONESTLY. T1 and T2 are the CAPABILITY tests:
21
+ // run against the previous depth-1 profile they fail, on the capability
22
+ // assertion itself and not on a precondition — measured -0.0086 against the
23
+ // 0.0938 bar, while the fixture's own preconditions still passed, so the
24
+ // failure is the missing capability and nothing else. T3, T4 and T5 pass
25
+ // under BOTH implementations by construction: they are not evidence for the
26
+ // capability, they are the invariants it must not buy itself with, and each
27
+ // one pins a regression this work actually hit — the null model collapsing
28
+ // when the descent superposed scaffolding, mass tracking constituents instead
29
+ // of episodes, and the profile being read from the deposit's id map instead
30
+ // of the store. Claiming all five as proof of the capability would be false;
31
+ // dropping the three would leave the two unfalsifiable.
32
+ //
33
+ // WHAT IS DELIBERATELY NOT TESTED HERE, AND WHY. A sixth test asserting that
34
+ // company GRADES with shared content (more shared units => more company) was
35
+ // written and removed: it is false as stated. Cosine normalizes by profile
36
+ // size, so a pair sharing 3 constituents out of a larger profile scores BELOW
37
+ // a pair sharing 1 out of a smaller one — measured at 0.085 against 0.111,
38
+ // consistently across all four seeds. The design's own `shared / (1 + k)`
39
+ // reading is size-RELATIVE, and asserting the absolute form encodes a law the
40
+ // system does not obey. Testing the relative form from outside would require
41
+ // re-deriving the profile's term-selection rules inside the test, which makes
42
+ // the test a mirror of the implementation and worthless as a check on it.
43
+ //
44
+ // Also untested, and a real limitation rather than an oversight: on a store
45
+ // this small the hub bound √N is large enough that frame scaffolding is not
46
+ // excluded, so short partners sharing only a frame do keep some company. That
47
+ // is the documented honest floor — a corpus that cannot yet say what
48
+ // discriminates — but it means these fixtures must share genuine CONTENT
49
+ // units, which T1 now asserts rather than assumes.
50
+ //
51
+ // Each test pins a DIFFERENT rule. Deleting any one of them lets a specific,
52
+ // named regression back in; none of them subsumes another.
53
+
54
+ import { test } from "node:test";
55
+ import assert from "node:assert/strict";
56
+ import {
57
+ conceptThreshold,
58
+ cosine,
59
+ Mind,
60
+ significanceBar,
61
+ } from "../dist/src/index.js";
62
+
63
+ const D = 1024;
64
+ const BAR = significanceBar(D); // 3/√D — above chance
65
+ const enc = new TextEncoder();
66
+
67
+ // Company signatures key on NODE ID, not on the alphabet, so a seeded
68
+ // keyring cannot be what makes these comparisons come out — but that is an
69
+ // argument, and the capability tests below check it instead, across seeds.
70
+ const SEEDS = [7, 1, 42, 99];
71
+ const newMind = (seed = 7) => new Mind({ seed, D });
72
+ const idOf = (m, s) => m.resolve(enc.encode(s));
73
+ const haloOf = (m, s) => {
74
+ const id = idOf(m, s);
75
+ return id === null || id === undefined ? null : m.store.halo(id);
76
+ };
77
+
78
+ /** The halo read must work at all before any comparison means anything. A
79
+ * missing halo silently makes every cosine below unreachable, and a broken
80
+ * one makes them meaningless — this is the control whose absence has voided
81
+ * whole investigations on this codebase. */
82
+ const assertHaloControl = (m, cues) => {
83
+ for (const c of cues) {
84
+ const h = haloOf(m, c);
85
+ assert.ok(h, `CONTROL: no halo poured for ${JSON.stringify(c)}`);
86
+ assert.ok(
87
+ Math.abs(cosine(h, h) - 1) < 1e-9,
88
+ `CONTROL: halo of ${JSON.stringify(c)} is not self-identical`,
89
+ );
90
+ }
91
+ };
92
+
93
+ /** The continuation a cue was trained with, as a node id. */
94
+ const partnerOf = (m, cue) => m.store.next(idOf(m, cue))[0];
95
+
96
+ /** Depth-1 constituents — what a profile reading only `rec.kids` would see. */
97
+ const depth1 = (m, node) => new Set(m.store.get(node)?.kids ?? []);
98
+
99
+ /** Every constituent reachable below `node`, to a depth the fold cannot
100
+ * exceed for these fixtures — what the descent can see. */
101
+ const deepConstituents = (m, node, depth = 6, out = new Set()) => {
102
+ if (depth === 0) return out;
103
+ for (const k of m.store.get(node)?.kids ?? []) {
104
+ if (k < 0) continue;
105
+ out.add(k);
106
+ deepConstituents(m, k, depth - 1, out);
107
+ }
108
+ return out;
109
+ };
110
+
111
+ const intersect = (a, b) => [...a].filter((x) => b.has(x));
112
+
113
+ // ═══════════════════════════════════════════════════════════════════════════
114
+ // T1 — THE CAPABILITY, with its own impossibility proof for the old rule.
115
+ //
116
+ // Two sentences in different languages that both mention Paris. Content-
117
+ // defined cuts put the shared unit in DIFFERENT top-level chunks:
118
+ // "The Eiffel Tower is in Paris" -> "The Eiffel " · "Tower is in Paris"
119
+ // "Tour Eiffel dia any Paris" -> "Tour Eiffel " · "dia any Paris"
120
+ // so their depth-1 constituents are disjoint — asserted below, not assumed.
121
+ // ═══════════════════════════════════════════════════════════════════════════
122
+ test("T1: partners sharing a unit BELOW the top of the fold keep company", async () => {
123
+ for (const seed of SEEDS) {
124
+ const m = newMind(seed);
125
+ await m.ingest([
126
+ ["cue_en", "The Eiffel Tower is in Paris"],
127
+ ["cue_mg", "Tour Eiffel dia any Paris"],
128
+ ["cue_zz", "Bananas are grown in humid climates"],
129
+ ]);
130
+ assertHaloControl(m, ["cue_en", "cue_mg", "cue_zz"]);
131
+
132
+ const pEn = partnerOf(m, "cue_en");
133
+ const pMg = partnerOf(m, "cue_mg");
134
+
135
+ // THE IMPOSSIBILITY PROOF. A profile built from `rec.kids` alone sees these
136
+ // sets and nothing else; they do not intersect, so no depth-1 rule — however
137
+ // weighted, however filtered — can make these two partners share a term.
138
+ // This test therefore measures the DESCENT, not halos in general.
139
+ assert.equal(
140
+ intersect(depth1(m, pEn), depth1(m, pMg)).length,
141
+ 0,
142
+ "fixture no longer exercises the descent: the two partners now share a " +
143
+ "depth-1 constituent, so a depth-1 profile could pass T1 as well",
144
+ );
145
+ // And the units the descent is supposed to find must actually be there —
146
+ // AND be eligible to become profile terms. A fixture whose only shared
147
+ // constituents are sub-window shards or frame scaffolding measures frame
148
+ // similarity while reading like a content test; one was written during this
149
+ // work and passed for exactly that wrong reason. The shared unit must be
150
+ // at least the fold's own window wide.
151
+ const W = m.space.maxGroup;
152
+ const shared = intersect(
153
+ deepConstituents(m, pEn),
154
+ deepConstituents(m, pMg),
155
+ );
156
+ assert.ok(
157
+ shared.some((n) => m.store.contentLen(n, W) >= W),
158
+ `fixture is broken: the partners share no constituent of at least W=${W} ` +
159
+ `bytes, so nothing they share can enter a profile`,
160
+ );
161
+
162
+ const related = cosine(haloOf(m, "cue_en"), haloOf(m, "cue_mg"));
163
+ const control = cosine(haloOf(m, "cue_en"), haloOf(m, "cue_zz"));
164
+
165
+ assert.ok(
166
+ related >= BAR,
167
+ `seed ${seed}: partners sharing a content unit must keep measurable ` +
168
+ `company: got ${related.toFixed(4)}, need >= ${
169
+ BAR.toFixed(4)
170
+ } (3/sqrt(D))`,
171
+ );
172
+ // The control is what makes the line above falsifiable: without it, a
173
+ // regression that made EVERY halo correlate would pass.
174
+ assert.ok(
175
+ control < BAR,
176
+ `seed ${seed}: partners sharing nothing must stay at chance: got ` +
177
+ `${control.toFixed(4)}, need < ${
178
+ BAR.toFixed(4)
179
+ } — null model collapsed`,
180
+ );
181
+ await m.store.close();
182
+ }
183
+ });
184
+
185
+ // ═══════════════════════════════════════════════════════════════════════════
186
+ // T2 — ORDER INDEPENDENCE.
187
+ //
188
+ // The tempting stop rule ("descend while a constituent is corpus-unique, stop
189
+ // at the first one attested twice") passes T1 in exactly one training order
190
+ // and fails in the other: when the FIRST partner is poured its shared unit has
191
+ // fan-in 1, so the descent runs past it and only the second partner ever
192
+ // profiles it. Whether two forms become siblings must not depend on which was
193
+ // taught first.
194
+ // ═══════════════════════════════════════════════════════════════════════════
195
+ test("T2: company does not depend on which partner was taught first", async () => {
196
+ const measure = async (first, second, seed) => {
197
+ const m = newMind(seed);
198
+ await m.ingest([
199
+ [first[0], first[1]],
200
+ [second[0], second[1]],
201
+ ["cue_zz", "Bananas are grown in humid climates"],
202
+ ]);
203
+ assertHaloControl(m, ["cue_en", "cue_mg", "cue_zz"]);
204
+ return {
205
+ related: cosine(haloOf(m, "cue_en"), haloOf(m, "cue_mg")),
206
+ control: cosine(haloOf(m, "cue_en"), haloOf(m, "cue_zz")),
207
+ };
208
+ };
209
+ const EN = ["cue_en", "The Eiffel Tower is in Paris"];
210
+ const MG = ["cue_mg", "Tour Eiffel dia any Paris"];
211
+
212
+ for (const seed of SEEDS) {
213
+ const forward = await measure(EN, MG, seed);
214
+ const reverse = await measure(MG, EN, seed);
215
+
216
+ for (const [name, r] of [["forward", forward], ["reverse", reverse]]) {
217
+ assert.ok(
218
+ r.related >= BAR,
219
+ `seed ${seed} ${name} order: shared-unit company must survive ` +
220
+ `training order — got ${r.related.toFixed(4)}, need >= ` +
221
+ `${BAR.toFixed(4)}`,
222
+ );
223
+ assert.ok(
224
+ r.control < BAR,
225
+ `seed ${seed} ${name} order: control must stay at chance, got ` +
226
+ `${r.control.toFixed(4)}`,
227
+ );
228
+ }
229
+ }
230
+ });
231
+
232
+ // ═══════════════════════════════════════════════════════════════════════════
233
+ // T3 — THE NULL MODEL SURVIVES.
234
+ //
235
+ // The failure mode opposite to T1's: a descent that superposed everything it
236
+ // walked past would put terms shared by every deposit into every profile, and
237
+ // ALL halos would correlate. That regression passes T1 handsomely. Here a
238
+ // population of mutually unrelated partners must stay mutually at chance —
239
+ // and, because it is the same store, T1's positive is re-checked against this
240
+ // population's own noise level rather than against a bar alone.
241
+ // ═══════════════════════════════════════════════════════════════════════════
242
+ test("T3: unrelated partners stay mutually at chance", async () => {
243
+ const m = newMind();
244
+ const FACTS = [
245
+ ["c1", "Volcanoes erupt when magma reaches the surface"],
246
+ ["c2", "The violin has four strings tuned in fifths"],
247
+ ["c3", "Penguins are flightless birds of the southern seas"],
248
+ ["c4", "Concrete gains strength for weeks after it is poured"],
249
+ ["c5", "The abacus was used for arithmetic in many cultures"],
250
+ ["c6", "Lightning heats the air it passes through"],
251
+ ];
252
+ await m.ingest(FACTS);
253
+ assertHaloControl(m, FACTS.map((f) => f[0]));
254
+
255
+ let worst = -1, worstPair = "";
256
+ for (let i = 0; i < FACTS.length; i++) {
257
+ for (let j = i + 1; j < FACTS.length; j++) {
258
+ const c = cosine(haloOf(m, FACTS[i][0]), haloOf(m, FACTS[j][0]));
259
+ if (c > worst) {
260
+ worst = c;
261
+ worstPair = `${FACTS[i][0]}~${FACTS[j][0]}`;
262
+ }
263
+ }
264
+ }
265
+ assert.ok(
266
+ worst < BAR,
267
+ `unrelated partners must not keep company: worst pair ${worstPair} at ` +
268
+ `${worst.toFixed(4)}, need < ${BAR.toFixed(4)}. A profile that ` +
269
+ `superposes scaffolding makes every halo correlate.`,
270
+ );
271
+ });
272
+
273
+ // ═══════════════════════════════════════════════════════════════════════════
274
+ // T4 — ONE EPISODE POURS ONE UNIT OF MASS.
275
+ //
276
+ // The profile is normalized precisely so that enriching it cannot inflate the
277
+ // evidence it represents: `haloMass` counts EPISODES, and every mass-based
278
+ // reading in the system (recall's corroboration counts, the disambiguation
279
+ // tiers) depends on that staying true. A profile that forgot to normalize
280
+ // would pass T1 and T3 and silently re-weight the whole distributional layer.
281
+ // ═══════════════════════════════════════════════════════════════════════════
282
+ test("T4: enriching the profile does not inflate halo mass", async () => {
283
+ const m = newMind();
284
+ await m.ingest([
285
+ // A partner with MANY constituents, and one with very few — if mass
286
+ // tracked constituent count instead of episodes, these would differ.
287
+ ["rich", "The quick brown fox jumps over the lazy dog beside the river"],
288
+ ["lean", "Ice melts"],
289
+ ]);
290
+ assertHaloControl(m, ["rich", "lean"]);
291
+
292
+ const massRich = m.store.haloMass(idOf(m, "rich"));
293
+ const massLean = m.store.haloMass(idOf(m, "lean"));
294
+ assert.equal(
295
+ massRich,
296
+ massLean,
297
+ `halo mass must count episodes, not constituents: a 59-byte partner ` +
298
+ `poured ${massRich} against a 9-byte partner's ${massLean}`,
299
+ );
300
+ assert.equal(massRich, 1, `one episode must pour exactly one unit of mass`);
301
+ });
302
+
303
+ // ═══════════════════════════════════════════════════════════════════════════
304
+ // T5 — THE PROFILE IS A FUNCTION OF THE STORE, NOT OF THE DEPOSIT.
305
+ //
306
+ // The constituents must be read from the STORE. Read instead from the
307
+ // depositing tree's id map — which holds only the nodes THIS deposit newly
308
+ // interned — and a partner met a SECOND time profiles differently from the
309
+ // first, because its subtrees are already stored and therefore absent from the
310
+ // map. The exact-partner case then falls from cosine 1 to 1/sqrt(1+k) and the
311
+ // geometry stops meaning anything. Two cues sharing the SAME partner are the
312
+ // direct probe: their halos must be identical, whatever else changed between
313
+ // the two deposits.
314
+ // ═══════════════════════════════════════════════════════════════════════════
315
+ test("T5: the same partner profiles identically on every episode", async () => {
316
+ const m = newMind();
317
+ const PARTNER = "Paris is the capital city of France";
318
+ await m.ingest([
319
+ ["first", PARTNER],
320
+ // An unrelated deposit in between, so the second pour happens against a
321
+ // store that has grown and a tree whose subtrees are all already interned.
322
+ ["filler", "Sandstone forms from compressed grains"],
323
+ ["second", PARTNER],
324
+ ]);
325
+ assertHaloControl(m, ["first", "second"]);
326
+
327
+ const same = cosine(haloOf(m, "first"), haloOf(m, "second"));
328
+ assert.ok(
329
+ same > 1 - 1e-6,
330
+ `two cues sharing one partner must have identical halos: got ` +
331
+ `${same.toFixed(6)}. The profile is being read from the deposit's id ` +
332
+ `map rather than from the store.`,
333
+ );
334
+ // Falsifiability: identical halos must not be an artefact of ALL halos in
335
+ // this store being identical.
336
+ const different = cosine(haloOf(m, "first"), haloOf(m, "filler"));
337
+ assert.ok(
338
+ different < conceptThreshold(D),
339
+ `control: a different partner must not yield the same halo, got ` +
340
+ `${different.toFixed(4)}`,
341
+ );
342
+ });