@hviana/sema 0.2.1 → 0.2.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 (44) hide show
  1. package/dist/src/geometry.d.ts +28 -0
  2. package/dist/src/geometry.js +35 -0
  3. package/dist/src/mind/articulation.js +1 -1
  4. package/dist/src/mind/attention.d.ts +4 -0
  5. package/dist/src/mind/attention.js +65 -12
  6. package/dist/src/mind/graph-search.d.ts +16 -1
  7. package/dist/src/mind/graph-search.js +34 -5
  8. package/dist/src/mind/learning.d.ts +1 -1
  9. package/dist/src/mind/learning.js +20 -5
  10. package/dist/src/mind/mechanisms/alu.js +8 -1
  11. package/dist/src/mind/mechanisms/cast.js +35 -11
  12. package/dist/src/mind/mechanisms/cover.js +40 -1
  13. package/dist/src/mind/mechanisms/extraction.js +75 -30
  14. package/dist/src/mind/mechanisms/recall.js +26 -2
  15. package/dist/src/mind/mind.d.ts +3 -2
  16. package/dist/src/mind/mind.js +28 -54
  17. package/dist/src/mind/pipeline.js +34 -2
  18. package/dist/src/mind/primitives.d.ts +16 -9
  19. package/dist/src/mind/primitives.js +58 -22
  20. package/dist/src/mind/reasoning.d.ts +9 -1
  21. package/dist/src/mind/reasoning.js +26 -4
  22. package/dist/src/mind/recognition.js +30 -6
  23. package/dist/src/mind/traverse.js +15 -0
  24. package/dist/src/mind/types.d.ts +58 -10
  25. package/dist/src/mind/types.js +15 -0
  26. package/package.json +1 -1
  27. package/src/geometry.ts +61 -1
  28. package/src/mind/articulation.ts +1 -0
  29. package/src/mind/attention.ts +80 -12
  30. package/src/mind/graph-search.ts +59 -2
  31. package/src/mind/learning.ts +20 -3
  32. package/src/mind/mechanisms/alu.ts +8 -1
  33. package/src/mind/mechanisms/cast.ts +46 -8
  34. package/src/mind/mechanisms/cover.ts +46 -0
  35. package/src/mind/mechanisms/extraction.ts +101 -40
  36. package/src/mind/mechanisms/recall.ts +30 -2
  37. package/src/mind/mind.ts +38 -61
  38. package/src/mind/pipeline.ts +37 -2
  39. package/src/mind/primitives.ts +71 -29
  40. package/src/mind/reasoning.ts +26 -3
  41. package/src/mind/recognition.ts +28 -5
  42. package/src/mind/traverse.ts +18 -0
  43. package/src/mind/types.ts +73 -10
  44. package/test/35-attention-confidence.test.mjs +139 -0
@@ -0,0 +1,139 @@
1
+ // 35-attention-confidence.test.mjs — SCALE-INVARIANT CONFIDENCE for a point
2
+ // of attention (Attention.breadth).
3
+ //
4
+ // commitVotes always admits the DOMINANT root regardless of its IDF-weighted
5
+ // vote (attention.ts: "roots.length === 0 || ..." — the first root is never
6
+ // floor-gated). That is correct for the common case ("give me your best
7
+ // guess"), but it means a query's SOLE root can be either:
8
+ //
9
+ // (a) genuine consensus — most of the query's own regions independently
10
+ // corroborate it (a real fact, or a real cross-region binding), or
11
+ // (b) a coincidental echo — ONE region's resonance happened to land
12
+ // somewhere, with the rest of the query silent on it.
13
+ //
14
+ // The raw IDF vote cannot tell these apart: it is an ABSOLUTE quantity that
15
+ // scales with ln(corpus size), so the same vote means "strong" on a small
16
+ // store and "weak" on a large one (see the session's earlier finding: a
17
+ // genuine root on a 325K-context store scored BELOW its own consensus floor,
18
+ // while a spurious echo on a 15-fact store scored comfortably above its own —
19
+ // much smaller — floor). A SCALE-INVARIANT measure is needed instead: what
20
+ // FRACTION of the query's own regions this root's evidence accounts for —
21
+ // the "N of M sub-regions voted" the rationale already reports, but read
22
+ // PER-ANCHOR instead of globally, and tested against the same half-dominance
23
+ // convention (`dominates`, part*2 > whole) the rest of the codebase already
24
+ // uses for every other "is this real signal or noise" decision.
25
+
26
+ import { test } from "node:test";
27
+ import assert from "node:assert/strict";
28
+ import { Mind } from "../dist/src/index.js";
29
+ import { SQliteStore } from "../dist/src/store-sqlite.js";
30
+
31
+ const enc = (s) => new TextEncoder().encode(s);
32
+ const mk = (seed) =>
33
+ new Mind({ seed, store: new SQliteStore({ path: ":memory:" }) });
34
+
35
+ // ═══════════════════════════════════════════════════════════════════════════
36
+ // GENUINE CONSENSUS — a real cross-region binding (test/34's own corpus).
37
+ // Most of the query's regions agree on the joint context; breadth must
38
+ // DOMINATE (> half of the query's own regions corroborate it).
39
+ // ═══════════════════════════════════════════════════════════════════════════
40
+
41
+ const BINDING_CORPUS = [
42
+ ["red", "is a color"],
43
+ ["blue", "is a color"],
44
+ ["circle", "is a shape"],
45
+ ["square", "is a shape"],
46
+ ["red circle", "answer alpha"],
47
+ ["red square", "answer beta"],
48
+ ["blue circle", "answer gamma"],
49
+ ["blue square", "answer delta"],
50
+ ];
51
+
52
+ test("breadth: a genuine cross-region binding dominates the query's regions", async () => {
53
+ const m = mk(1);
54
+ await m.ingest(BINDING_CORPUS);
55
+ const roots = await m.climbAttention(enc("red then circle"), 24);
56
+ assert.equal(roots.length, 1, "expected exactly one committed root");
57
+ assert.ok(
58
+ typeof roots[0].breadth === "number",
59
+ "Attention must carry a breadth field",
60
+ );
61
+ assert.ok(
62
+ roots[0].breadth > 0.5,
63
+ `genuine binding must dominate (> half the query's own regions), got breadth=${
64
+ roots[0].breadth
65
+ }`,
66
+ );
67
+ await m.store.close();
68
+ });
69
+
70
+ // ═══════════════════════════════════════════════════════════════════════════
71
+ // SPURIOUS ECHO — a short arithmetic query whose consensus climb lands on an
72
+ // UNRELATED fact by coincidental byte-pattern resonance (observed directly
73
+ // this session: "2+2 equals what?" climbs to "1+1", not "2+2"). Only a
74
+ // minority of the query's regions support it; breadth must NOT dominate.
75
+ // ═══════════════════════════════════════════════════════════════════════════
76
+
77
+ const ARITH_CORPUS = [
78
+ ["1+2", "3"],
79
+ ["2+2", "4"],
80
+ ["2+3", "5"],
81
+ ["3+3", "6"],
82
+ ["3+5", "8"],
83
+ ["4+3", "7"],
84
+ ["2+5", "7"],
85
+ ["1+5", "6"],
86
+ ["6+1", "7"],
87
+ ["4+1", "5"],
88
+ ["3+4", "7"],
89
+ ["5+2", "7"],
90
+ ["1+1", "2"],
91
+ ["5+3", "8"],
92
+ ["7+1", "8"],
93
+ ];
94
+
95
+ test("breadth: a coincidental single-region echo does not dominate", async () => {
96
+ const m = mk(1);
97
+ await m.ingest(ARITH_CORPUS);
98
+ const roots = await m.climbAttention(enc("2+2 equals what?"), 24);
99
+ assert.equal(roots.length, 1, "expected exactly one committed root");
100
+ assert.ok(
101
+ typeof roots[0].breadth === "number",
102
+ "Attention must carry a breadth field",
103
+ );
104
+ assert.ok(
105
+ roots[0].breadth <= 0.5,
106
+ `a coincidental echo must NOT dominate the query's own regions, got breadth=${
107
+ roots[0].breadth
108
+ }`,
109
+ );
110
+ await m.store.close();
111
+ });
112
+
113
+ // ═══════════════════════════════════════════════════════════════════════════
114
+ // SCALE INVARIANCE — the whole point: the SAME breadth bar must separate
115
+ // signal from noise whether the corpus has 15 facts or many more, unlike the
116
+ // raw IDF vote (which is an absolute, ln(N)-scaled quantity — see the header
117
+ // comment). Doubling the corpus (more unrelated arithmetic facts) must not
118
+ // flip either verdict merely by changing N.
119
+ // ═══════════════════════════════════════════════════════════════════════════
120
+
121
+ test("breadth: the same bar holds as the corpus grows (scale invariance)", async () => {
122
+ const bigArith = [...ARITH_CORPUS];
123
+ for (let a = 1; a <= 9; a++) {
124
+ for (let b = 1; b <= 9; b++) {
125
+ bigArith.push([`${a}x${b}`, String(a * b)]);
126
+ }
127
+ }
128
+ const m = mk(1);
129
+ await m.ingest(bigArith);
130
+ const roots = await m.climbAttention(enc("2+2 equals what?"), 24);
131
+ assert.equal(roots.length, 1, "expected exactly one committed root");
132
+ assert.ok(
133
+ roots[0].breadth <= 0.5,
134
+ `a coincidental echo must still not dominate on a larger corpus, got breadth=${
135
+ roots[0].breadth
136
+ }`,
137
+ );
138
+ await m.store.close();
139
+ });