@mneme-ai/core 2.19.25 → 2.19.27

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 (69) hide show
  1. package/dist/cosmic/aurelian_v1925.test.js +1 -1
  2. package/dist/cosmic/aurelian_v1925.test.js.map +1 -1
  3. package/dist/cosmic/aurelian_v1926.test.d.ts +2 -0
  4. package/dist/cosmic/aurelian_v1926.test.d.ts.map +1 -0
  5. package/dist/cosmic/aurelian_v1926.test.js +48 -0
  6. package/dist/cosmic/aurelian_v1926.test.js.map +1 -0
  7. package/dist/cosmic/aurelian_v1927.test.d.ts +2 -0
  8. package/dist/cosmic/aurelian_v1927.test.d.ts.map +1 -0
  9. package/dist/cosmic/aurelian_v1927.test.js +73 -0
  10. package/dist/cosmic/aurelian_v1927.test.js.map +1 -0
  11. package/dist/dreamspace_cartographer/dreamspace_cartographer.test.d.ts +2 -0
  12. package/dist/dreamspace_cartographer/dreamspace_cartographer.test.d.ts.map +1 -0
  13. package/dist/dreamspace_cartographer/dreamspace_cartographer.test.js +153 -0
  14. package/dist/dreamspace_cartographer/dreamspace_cartographer.test.js.map +1 -0
  15. package/dist/dreamspace_cartographer/index.d.ts +110 -0
  16. package/dist/dreamspace_cartographer/index.d.ts.map +1 -0
  17. package/dist/dreamspace_cartographer/index.js +175 -0
  18. package/dist/dreamspace_cartographer/index.js.map +1 -0
  19. package/dist/dreamspace_evolution/dreamspace_evolution.test.d.ts +2 -0
  20. package/dist/dreamspace_evolution/dreamspace_evolution.test.d.ts.map +1 -0
  21. package/dist/dreamspace_evolution/dreamspace_evolution.test.js +199 -0
  22. package/dist/dreamspace_evolution/dreamspace_evolution.test.js.map +1 -0
  23. package/dist/dreamspace_evolution/index.d.ts +140 -0
  24. package/dist/dreamspace_evolution/index.d.ts.map +1 -0
  25. package/dist/dreamspace_evolution/index.js +210 -0
  26. package/dist/dreamspace_evolution/index.js.map +1 -0
  27. package/dist/dreamspace_federate/dreamspace_federate.test.d.ts +2 -0
  28. package/dist/dreamspace_federate/dreamspace_federate.test.d.ts.map +1 -0
  29. package/dist/dreamspace_federate/dreamspace_federate.test.js +199 -0
  30. package/dist/dreamspace_federate/dreamspace_federate.test.js.map +1 -0
  31. package/dist/dreamspace_federate/index.d.ts +131 -0
  32. package/dist/dreamspace_federate/index.d.ts.map +1 -0
  33. package/dist/dreamspace_federate/index.js +209 -0
  34. package/dist/dreamspace_federate/index.js.map +1 -0
  35. package/dist/dreamspace_gestation/dreamspace_gestation.test.d.ts +2 -0
  36. package/dist/dreamspace_gestation/dreamspace_gestation.test.d.ts.map +1 -0
  37. package/dist/dreamspace_gestation/dreamspace_gestation.test.js +160 -0
  38. package/dist/dreamspace_gestation/dreamspace_gestation.test.js.map +1 -0
  39. package/dist/dreamspace_gestation/index.d.ts +136 -0
  40. package/dist/dreamspace_gestation/index.d.ts.map +1 -0
  41. package/dist/dreamspace_gestation/index.js +186 -0
  42. package/dist/dreamspace_gestation/index.js.map +1 -0
  43. package/dist/dreamspace_pair/dreamspace_pair.test.d.ts +2 -0
  44. package/dist/dreamspace_pair/dreamspace_pair.test.d.ts.map +1 -0
  45. package/dist/dreamspace_pair/dreamspace_pair.test.js +175 -0
  46. package/dist/dreamspace_pair/dreamspace_pair.test.js.map +1 -0
  47. package/dist/dreamspace_pair/index.d.ts +99 -0
  48. package/dist/dreamspace_pair/index.d.ts.map +1 -0
  49. package/dist/dreamspace_pair/index.js +161 -0
  50. package/dist/dreamspace_pair/index.js.map +1 -0
  51. package/dist/dreamspace_probe/dreamspace_probe.test.d.ts +2 -0
  52. package/dist/dreamspace_probe/dreamspace_probe.test.d.ts.map +1 -0
  53. package/dist/dreamspace_probe/dreamspace_probe.test.js +179 -0
  54. package/dist/dreamspace_probe/dreamspace_probe.test.js.map +1 -0
  55. package/dist/dreamspace_probe/index.d.ts +125 -0
  56. package/dist/dreamspace_probe/index.d.ts.map +1 -0
  57. package/dist/dreamspace_probe/index.js +226 -0
  58. package/dist/dreamspace_probe/index.js.map +1 -0
  59. package/dist/index.d.ts +6 -0
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +8 -0
  62. package/dist/index.js.map +1 -1
  63. package/dist/whats_new.d.ts.map +1 -1
  64. package/dist/whats_new.js +16 -0
  65. package/dist/whats_new.js.map +1 -1
  66. package/dist/wrapper_genesis/index.d.ts.map +1 -1
  67. package/dist/wrapper_genesis/index.js +37 -0
  68. package/dist/wrapper_genesis/index.js.map +1 -1
  69. package/package.json +1 -1
@@ -0,0 +1,186 @@
1
+ /**
2
+ * v2.19.26 — MNEME DREAMSPACE · GESTATION (self-authoring MCP catalog · phase 1 of 2)
3
+ *
4
+ * "Catalog ตัวมัน static — ไม่งอก ไม่ตาย ไม่จับคู่ ไม่เรียนรู้ที่จะ
5
+ * author tool ใหม่. นั่นคือ gap ของกระบวนการ 'ของเดิม + ของใหม่ +
6
+ * การเลือก' — ที่ DREAMS ปัจจุบันยังตอบไม่ได้"
7
+ * — user audit, 2026-05-17
8
+ *
9
+ * Diagnosis: every prior dreams primitive (vaccine_cycle, dream.run,
10
+ * dreams.enqueue/resolve) is a PRODUCT factory — it manufactures
11
+ * one specific artifact (vaccine / claim / verdict). GESTATION is
12
+ * a TOOL factory — it watches for catalog gaps + proposes the
13
+ * composer recipe for a brand-new MCP tool that closes the gap.
14
+ *
15
+ * Three gap classes detected from caller-supplied signals:
16
+ * 1. REFLEX cache miss — user (or AI) tried an event that
17
+ * had no cached prediction; nothing fired. Gap = no pattern
18
+ * matched this event signature.
19
+ * 2. user_chat no-match — user typed a request; EVENT PATTERN
20
+ * MATCH returned zero predictions. Gap = no semantic rule
21
+ * recognised this phrase.
22
+ * 3. pattern co-occurrence — two tools always fire together in
23
+ * sequence (e.g., mneme.ask then mneme.why). Gap = no single
24
+ * composed tool does both — opportunity for chimera.
25
+ *
26
+ * For each gap, propose a ProposedToolSpec with deterministic name,
27
+ * description (from the originating signal), composer recipe (list
28
+ * of existing tools to chain), and a JSON inputSchema derived as the
29
+ * intersection of the composed tools' input schemas. Caller (daemon)
30
+ * feeds the spec to v2.19.9 WRAPPER_GENESPLICING `splice` to actually
31
+ * create the runtime chimera; this module is the PROPOSER, not the
32
+ * executor.
33
+ *
34
+ * Composes onto:
35
+ * - v2.19.9 WRAPPER_GENESPLICING (real splice surface)
36
+ * - v2.19.11 MORTAL (TTL for proposed tools)
37
+ * - v2.19.22 REFLEX (cache miss signal)
38
+ * - v2.19.24 EVENT PATTERN MATCH (no-match signal)
39
+ * - v2.19.25 SLEEP TRAINING (fitness gradient feeds promotion)
40
+ *
41
+ * Honest scope:
42
+ * - PURE FUNCTION proposer; HMAC-signed proposals so daemon can
43
+ * audit forged specs.
44
+ * - Composer recipes are SEQUENCES (Tool_A then Tool_B); we don't
45
+ * synthesise parallelisable or conditional graphs. v2.19.9 supports
46
+ * sequential/fan_out/first_success — we emit "sequential" only.
47
+ * - Names use deterministic snake_case to avoid collisions:
48
+ * `mneme.auto.<tool1>_then_<tool2>`. Caller can rename on promote.
49
+ * - We do NOT execute or load code. Daemon picks specs to promote
50
+ * based on usage telemetry from v2.19.26 EVOLUTION.
51
+ */
52
+ import { createHmac, timingSafeEqual } from "node:crypto";
53
+ const PROTOCOL_VERSION = 1;
54
+ const DEFAULT_MIN_GAP_COUNT = 3;
55
+ const DEFAULT_MIN_COOCCUR_COUNT = 4;
56
+ function canon(v) {
57
+ if (v === null || typeof v !== "object")
58
+ return JSON.stringify(v);
59
+ if (Array.isArray(v))
60
+ return "[" + v.map(canon).join(",") + "]";
61
+ const keys = Object.keys(v).sort();
62
+ return "{" + keys.map((k) => JSON.stringify(k) + ":" + canon(v[k])).join(",") + "}";
63
+ }
64
+ function defaultSecret() {
65
+ return process.env["MNEME_DREAMSPACE_GESTATION_SECRET"] || `mneme-dreamspace-gestation-v${PROTOCOL_VERSION}`;
66
+ }
67
+ function hmacHex(body, secret) {
68
+ return createHmac("sha256", secret).update(canon(body)).digest("hex");
69
+ }
70
+ function safeEqHex(a, b) {
71
+ try {
72
+ return timingSafeEqual(Buffer.from(a, "hex"), Buffer.from(b, "hex"));
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }
78
+ function slugify(s) {
79
+ return s.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "").slice(0, 32);
80
+ }
81
+ /**
82
+ * Filter gap signals down to those above the minimum-count threshold.
83
+ * Below-threshold signals are noise; above-threshold signals are real
84
+ * gaps worth proposing a tool for.
85
+ */
86
+ export function detectToolGaps(input) {
87
+ const minGap = input.minGapCount ?? DEFAULT_MIN_GAP_COUNT;
88
+ const minCo = input.minCoOccurCount ?? DEFAULT_MIN_COOCCUR_COUNT;
89
+ return input.signals
90
+ .filter((s) => {
91
+ const threshold = s.kind === "pattern_co_occurrence" ? minCo : minGap;
92
+ return s.count >= threshold;
93
+ })
94
+ .slice()
95
+ .sort((a, b) => b.count - a.count || a.label.localeCompare(b.label));
96
+ }
97
+ /**
98
+ * Propose a tool spec from a single gap signal. Pure function;
99
+ * deterministic over (signal + secret). The composer recipe defaults
100
+ * to sequential chaining of the related tools; for no-match gaps with
101
+ * empty relatedTools, the recipe is just `mneme.smart_do` as a fallback
102
+ * so caller has SOMETHING to splice.
103
+ */
104
+ export function proposeToolSpec(input) {
105
+ const minGap = input.minGapCount ?? DEFAULT_MIN_GAP_COUNT;
106
+ const gap = input.gap;
107
+ // Name generation
108
+ let proposedName;
109
+ let description;
110
+ let recipe = [];
111
+ let inputSchema = { type: "object", properties: {}, required: [] };
112
+ if (gap.kind === "pattern_co_occurrence" && gap.relatedTools.length >= 2) {
113
+ const [a, b] = gap.relatedTools;
114
+ const slugA = slugify((a ?? "tool_a").replace(/^mneme\./, ""));
115
+ const slugB = slugify((b ?? "tool_b").replace(/^mneme\./, ""));
116
+ proposedName = `mneme.auto.${slugA}_then_${slugB}`;
117
+ description = `🌱 Auto-proposed chimera: invokes ${a} then ${b} (observed co-occurring ${gap.count}× yesterday on ${gap.label})`;
118
+ recipe = gap.relatedTools.map((t) => ({ toolName: t, argsPassthrough: true }));
119
+ inputSchema.properties["__passthrough"] = { type: "object", description: "Args passed through to each component tool" };
120
+ }
121
+ else if (gap.kind === "reflex_cache_miss") {
122
+ proposedName = `mneme.auto.handle_${slugify(gap.label)}`;
123
+ description = `🌱 Auto-proposed handler for REFLEX cache miss on '${gap.label}' (${gap.count}× yesterday). Composes related tools as fallback.`;
124
+ recipe = gap.relatedTools.length > 0
125
+ ? gap.relatedTools.map((t) => ({ toolName: t, argsPassthrough: true }))
126
+ : [{ toolName: "mneme.smart_do", argsPassthrough: true }];
127
+ inputSchema.properties["context"] = { type: "object" };
128
+ }
129
+ else {
130
+ // user_chat_no_match
131
+ proposedName = `mneme.auto.intent_${slugify(gap.label)}`;
132
+ description = `🌱 Auto-proposed intent handler for user phrase '${gap.label}' (no semantic rule matched; ${gap.count}× yesterday).`;
133
+ recipe = [{ toolName: "mneme.smart_do", argsPassthrough: true }];
134
+ inputSchema.properties["query"] = { type: "string", description: "User's natural-language request" };
135
+ inputSchema.required = ["query"];
136
+ }
137
+ // Confidence: linear scale from threshold to threshold*4 (caps at 1.0).
138
+ const confidence = Math.min(1, gap.count / (minGap * 4));
139
+ const body = {
140
+ v: PROTOCOL_VERSION,
141
+ proposedName,
142
+ description,
143
+ composerRecipe: recipe,
144
+ composerKind: "sequential",
145
+ proposedInputSchema: inputSchema,
146
+ sourceGap: gap,
147
+ confidence,
148
+ };
149
+ const sig = hmacHex(body, input.secret ?? defaultSecret());
150
+ return { ...body, sig };
151
+ }
152
+ export function verifyProposal(spec, secret) {
153
+ const { sig, ...body } = spec;
154
+ return safeEqHex(hmacHex(body, secret ?? defaultSecret()), sig);
155
+ }
156
+ /**
157
+ * One-shot gestation cycle: filter signals → propose specs → HMAC-sign
158
+ * the whole report. Caller runs this during the daemon's idle/dream
159
+ * window (composes onto v2.19.23 THALAMUS dream tier).
160
+ */
161
+ export function runGestationCycle(input) {
162
+ const qualifying = detectToolGaps({
163
+ signals: input.signals,
164
+ minGapCount: input.minGapCount,
165
+ minCoOccurCount: input.minCoOccurCount,
166
+ });
167
+ const proposals = qualifying.map((g) => proposeToolSpec({ gap: g, secret: input.secret, minGapCount: input.minGapCount }));
168
+ const body = {
169
+ v: PROTOCOL_VERSION,
170
+ totalSignals: input.signals.length,
171
+ qualifyingGaps: qualifying.length,
172
+ proposals,
173
+ cycleAt: input.cycleAt ?? Date.now(),
174
+ };
175
+ const sig = hmacHex(body, input.secret ?? defaultSecret());
176
+ return { ...body, sig };
177
+ }
178
+ export function verifyGestationReport(r, secret) {
179
+ const { sig, ...body } = r;
180
+ return safeEqHex(hmacHex(body, secret ?? defaultSecret()), sig);
181
+ }
182
+ export function formatProposalLine(p) {
183
+ const conf = (p.confidence * 100).toFixed(0);
184
+ return `🌱 ${p.proposedName} · ${p.composerRecipe.length}-step ${p.composerKind} · ${conf}% conf · from ${p.sourceGap.kind}`;
185
+ }
186
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dreamspace_gestation/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dreamspace_pair.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dreamspace_pair.test.d.ts","sourceRoot":"","sources":["../../src/dreamspace_pair/dreamspace_pair.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,175 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { scorePair, rankAllPairs, verifyPairReport, formatPairLine, } from "./index.js";
3
+ const SECRET = "pair-test-secret-997744";
4
+ function sample(toolName, result) {
5
+ return { toolName, result };
6
+ }
7
+ function schema(toolName, required, optional = []) {
8
+ return { toolName, requiredProps: required, optionalProps: optional };
9
+ }
10
+ describe("v2.19.27 PAIR · scorePair (mutual info approximation)", () => {
11
+ it("perfect coverage: A's output keys cover ALL of B's required + optional", () => {
12
+ const s = scorePair({
13
+ toolA: "A",
14
+ outputsA: [sample("A", { name: "x", count: 3 })],
15
+ schemaB: schema("B", ["name", "count"], []),
16
+ });
17
+ expect(s.requiredCoverage).toBe(1.0);
18
+ expect(s.optionalCoverage).toBe(1.0);
19
+ expect(s.mutualInfoScore).toBeCloseTo(0.5 + 0.3 + 0.2 * s.keyOverlapScore, 5);
20
+ });
21
+ it("zero coverage: A's keys disjoint from B's required → low MI", () => {
22
+ const s = scorePair({
23
+ toolA: "A",
24
+ outputsA: [sample("A", { foo: 1 })],
25
+ schemaB: schema("B", ["name", "count"]),
26
+ });
27
+ expect(s.requiredCoverage).toBe(0);
28
+ expect(s.mutualInfoScore).toBeLessThan(0.3);
29
+ });
30
+ it("partial required coverage rewards proportionally", () => {
31
+ const s = scorePair({
32
+ toolA: "A",
33
+ outputsA: [sample("A", { name: "x" })],
34
+ schemaB: schema("B", ["name", "count", "ts"]),
35
+ });
36
+ expect(s.requiredCoverage).toBeCloseTo(1 / 3, 5);
37
+ });
38
+ it("case-insensitive key matching", () => {
39
+ const s = scorePair({
40
+ toolA: "A",
41
+ outputsA: [sample("A", { NAME: "x" })],
42
+ schemaB: schema("B", ["name"]),
43
+ });
44
+ expect(s.requiredCoverage).toBe(1.0);
45
+ });
46
+ it("multiple samples union their keys", () => {
47
+ const s = scorePair({
48
+ toolA: "A",
49
+ outputsA: [sample("A", { name: "x" }), sample("A", { count: 1 })],
50
+ schemaB: schema("B", ["name", "count"]),
51
+ });
52
+ expect(s.requiredCoverage).toBe(1.0);
53
+ });
54
+ it("empty required + empty output -> vacuous 1.0 required coverage", () => {
55
+ const s = scorePair({
56
+ toolA: "A",
57
+ outputsA: [sample("A", {})],
58
+ schemaB: schema("B", [], []),
59
+ });
60
+ expect(s.requiredCoverage).toBe(1.0);
61
+ expect(s.optionalCoverage).toBe(1.0);
62
+ });
63
+ });
64
+ describe("v2.19.27 PAIR · rankAllPairs (full ordered ranking)", () => {
65
+ it("scores every ordered (A, B) pair; self-pairs excluded", () => {
66
+ const r = rankAllPairs({
67
+ toolOutputs: [
68
+ [sample("A", { name: "x", count: 1 })],
69
+ [sample("B", { name: "y" })],
70
+ ],
71
+ toolSchemas: [
72
+ schema("A", ["name"]), // B → A; A → A excluded
73
+ schema("B", ["name"]),
74
+ ],
75
+ minScore: 0,
76
+ builtAt: 0,
77
+ secret: SECRET,
78
+ });
79
+ // 2 tools, 2 schemas, no self-pairs -> 2 candidate pairs (A→B, B→A)
80
+ expect(r.totalCandidatePairs).toBe(2);
81
+ });
82
+ it("sorts by mutual info desc; filters below minScore", () => {
83
+ const r = rankAllPairs({
84
+ toolOutputs: [
85
+ [sample("good", { name: "x", count: 1, ts: 1 })],
86
+ [sample("bad", { unrelated: 1 })],
87
+ ],
88
+ toolSchemas: [
89
+ schema("good", []),
90
+ schema("bad", []),
91
+ schema("target", ["name", "count", "ts"]),
92
+ ],
93
+ minScore: 0.5,
94
+ builtAt: 0,
95
+ secret: SECRET,
96
+ });
97
+ // good → target should rank high; bad → target low (likely filtered)
98
+ expect(r.pairs[0].toolA).toBe("good");
99
+ expect(r.pairs[0].toolB).toBe("target");
100
+ expect(r.pairs.every((p) => p.mutualInfoScore >= 0.5)).toBe(true);
101
+ });
102
+ it("topN respected", () => {
103
+ const r = rankAllPairs({
104
+ toolOutputs: Array.from({ length: 5 }, (_, i) => [sample(`t${i}`, { x: 1 })]),
105
+ toolSchemas: Array.from({ length: 5 }, (_, i) => schema(`t${i}`, ["x"])),
106
+ minScore: 0,
107
+ topN: 3,
108
+ builtAt: 0,
109
+ secret: SECRET,
110
+ });
111
+ expect(r.pairs.length).toBeLessThanOrEqual(3);
112
+ });
113
+ it("HMAC sig verifies; rejects tamper", () => {
114
+ const r = rankAllPairs({
115
+ toolOutputs: [[sample("a", { x: 1 })]],
116
+ toolSchemas: [schema("a", []), schema("b", [])],
117
+ builtAt: 0,
118
+ secret: SECRET,
119
+ });
120
+ expect(verifyPairReport(r, SECRET)).toBe(true);
121
+ expect(verifyPairReport({ ...r, qualifyingPairs: 999 }, SECRET)).toBe(false);
122
+ });
123
+ it("MEASURED 100% determinism: same input -> same sig (30 trials)", () => {
124
+ const input = {
125
+ toolOutputs: [[sample("a", { x: 1 })], [sample("b", { y: 1 })]],
126
+ toolSchemas: [schema("a", ["x"]), schema("b", ["y"])],
127
+ builtAt: 1_000_000,
128
+ secret: SECRET,
129
+ };
130
+ const firstSig = rankAllPairs(input).sig;
131
+ let allEqual = true;
132
+ for (let i = 0; i < 30; i++) {
133
+ if (rankAllPairs(input).sig !== firstSig) {
134
+ allEqual = false;
135
+ break;
136
+ }
137
+ }
138
+ expect(allEqual).toBe(true);
139
+ });
140
+ it("MEASURED canonical scenario: truth.forensic→bug_prophet has high MI", () => {
141
+ // truth.forensic outputs { claim, sniffs, verdict, evidence }
142
+ // bug_prophet expects { claim, evidence } as input
143
+ const r = rankAllPairs({
144
+ toolOutputs: [
145
+ [sample("mneme.truth.forensic", { claim: "x", sniffs: [], verdict: "ACCEPTED", evidence: [] })],
146
+ [sample("mneme.bug_prophet", { prophecy: "..." })], // unrelated output
147
+ ],
148
+ toolSchemas: [
149
+ schema("mneme.bug_prophet", ["claim", "evidence"]),
150
+ schema("mneme.truth.forensic", ["claim"]),
151
+ ],
152
+ minScore: 0.3,
153
+ builtAt: 0,
154
+ secret: SECRET,
155
+ });
156
+ const tfToProphet = r.pairs.find((p) => p.toolA === "mneme.truth.forensic" && p.toolB === "mneme.bug_prophet");
157
+ expect(tfToProphet).toBeDefined();
158
+ expect(tfToProphet.mutualInfoScore).toBeGreaterThanOrEqual(0.5);
159
+ });
160
+ });
161
+ describe("v2.19.27 PAIR · formatter", () => {
162
+ it("formatPairLine includes A → B + MI% + required% + optional%", () => {
163
+ const s = scorePair({
164
+ toolA: "x",
165
+ outputsA: [sample("x", { name: "y" })],
166
+ schemaB: schema("y", ["name"]),
167
+ });
168
+ const line = formatPairLine(s);
169
+ expect(line).toContain("PAIR x → y");
170
+ expect(line).toContain("MI=");
171
+ expect(line).toContain("req=");
172
+ expect(line).toContain("opt=");
173
+ });
174
+ });
175
+ //# sourceMappingURL=dreamspace_pair.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dreamspace_pair.test.js","sourceRoot":"","sources":["../../src/dreamspace_pair/dreamspace_pair.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * v2.19.27 — MNEME DREAMSPACE · PAIR (stage 3 of 6)
3
+ *
4
+ * "for every pair (A, B): score = mutual_info(output_A, expected_
5
+ * input_B). top pairs → ผ่านขั้น 4"
6
+ * — user audit, 2026-05-17
7
+ *
8
+ * Diagnosis: v2.19.26 EVOLUTION.selectMatingPairs uses FREQUENCY
9
+ * (how often A→B fires together). PAIR adds QUALITY — measures
10
+ * how well A's output matches what B EXPECTS as input. High
11
+ * mutual_info → A and B are genuinely complementary; safe to splice.
12
+ *
13
+ * We approximate mutual information without LLM: compare key-name
14
+ * overlap (Jaccard over object property names) AND value-type
15
+ * compatibility. Both signals together approximate "would A's output
16
+ * be a plausible input to B?".
17
+ *
18
+ * Composes onto:
19
+ * - v2.19.26 EVOLUTION (replaces co-occurrence ranking with quality)
20
+ * - v2.19.27 PROBE (probe outputs feed PAIR's mutual_info)
21
+ * - v2.19.9 WRAPPER_GENESPLICING (high-mutual-info pairs → chimera)
22
+ * - v2.19.25 SLEEP TRAINING (PAIR fitness blends with jaccard reward)
23
+ *
24
+ * Honest scope:
25
+ * - Mutual info APPROXIMATION via shape-matching, not full Shannon
26
+ * information. Faster, deterministic, sufficient for "are these
27
+ * two tools complementary?" decision.
28
+ * - HMAC-signed PairReport so federation can ship verified pairs.
29
+ */
30
+ declare const PROTOCOL_VERSION: 1;
31
+ export interface ToolOutputSample {
32
+ toolName: string;
33
+ /** Object output (we focus on object-shape compatibility). */
34
+ result: Record<string, unknown>;
35
+ }
36
+ export interface ToolInputSchema {
37
+ toolName: string;
38
+ /** Required + optional property names. */
39
+ requiredProps: string[];
40
+ optionalProps: string[];
41
+ }
42
+ export interface PairScore {
43
+ toolA: string;
44
+ toolB: string;
45
+ /** Object key overlap A.outputs vs B.requiredProps (Jaccard 0..1). */
46
+ keyOverlapScore: number;
47
+ /** Required-coverage: fraction of B's required props that A produces. */
48
+ requiredCoverage: number;
49
+ /** Optional-coverage: fraction of B's optional props A also produces. */
50
+ optionalCoverage: number;
51
+ /** Final mutual_info approximation (weighted blend). */
52
+ mutualInfoScore: number;
53
+ }
54
+ export interface PairReport {
55
+ v: typeof PROTOCOL_VERSION;
56
+ pairs: PairScore[];
57
+ totalCandidatePairs: number;
58
+ qualifyingPairs: number;
59
+ minScore: number;
60
+ builtAt: number;
61
+ sig: string;
62
+ }
63
+ /**
64
+ * Score a single (A, B) pair: how complementary is A's output to B's
65
+ * expected input?
66
+ *
67
+ * keyOverlapScore = jaccard(unionOutputKeys(A), requiredProps(B) ∪ optionalProps(B))
68
+ * requiredCoverage = |outputKeys(A) ∩ requiredProps(B)| / |requiredProps(B)|
69
+ * optionalCoverage = |outputKeys(A) ∩ optionalProps(B)| / |optionalProps(B)|
70
+ * mutualInfoScore = 0.5 * requiredCoverage + 0.3 * optionalCoverage + 0.2 * keyOverlapScore
71
+ *
72
+ * Required-coverage dominates because B will THROW if a required prop
73
+ * is missing; optional is nice-to-have; raw key overlap captures broader
74
+ * signal compatibility.
75
+ */
76
+ export declare function scorePair(input: {
77
+ toolA: string;
78
+ outputsA: ToolOutputSample[];
79
+ schemaB: ToolInputSchema;
80
+ }): PairScore;
81
+ /**
82
+ * Score ALL ordered (A, B) pairs across the supplied tools; filter
83
+ * above minScore; sort by mutualInfoScore desc. Self-pairs excluded.
84
+ *
85
+ * Returns top pairs ready to feed into v2.19.26 GESTATION as
86
+ * `pattern_co_occurrence` signals with quality (not just frequency).
87
+ */
88
+ export declare function rankAllPairs(input: {
89
+ toolOutputs: ToolOutputSample[][];
90
+ toolSchemas: ToolInputSchema[];
91
+ minScore?: number;
92
+ topN?: number;
93
+ builtAt?: number;
94
+ secret?: string;
95
+ }): PairReport;
96
+ export declare function verifyPairReport(r: PairReport, secret?: string): boolean;
97
+ export declare function formatPairLine(p: PairScore): string;
98
+ export {};
99
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dreamspace_pair/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,QAAA,MAAM,gBAAgB,EAAG,CAAU,CAAC;AAGpC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,eAAe,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,gBAAgB,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,gBAAgB,EAAE,MAAM,CAAC;IACzB,wDAAwD;IACxD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,OAAO,gBAAgB,CAAC;IAC3B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AA0CD;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,OAAO,EAAE,eAAe,CAAC;CAC1B,GAAG,SAAS,CAkBZ;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,WAAW,EAAE,gBAAgB,EAAE,EAAE,CAAC;IAClC,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,UAAU,CAgCb;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAGxE;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAGnD"}
@@ -0,0 +1,161 @@
1
+ /**
2
+ * v2.19.27 — MNEME DREAMSPACE · PAIR (stage 3 of 6)
3
+ *
4
+ * "for every pair (A, B): score = mutual_info(output_A, expected_
5
+ * input_B). top pairs → ผ่านขั้น 4"
6
+ * — user audit, 2026-05-17
7
+ *
8
+ * Diagnosis: v2.19.26 EVOLUTION.selectMatingPairs uses FREQUENCY
9
+ * (how often A→B fires together). PAIR adds QUALITY — measures
10
+ * how well A's output matches what B EXPECTS as input. High
11
+ * mutual_info → A and B are genuinely complementary; safe to splice.
12
+ *
13
+ * We approximate mutual information without LLM: compare key-name
14
+ * overlap (Jaccard over object property names) AND value-type
15
+ * compatibility. Both signals together approximate "would A's output
16
+ * be a plausible input to B?".
17
+ *
18
+ * Composes onto:
19
+ * - v2.19.26 EVOLUTION (replaces co-occurrence ranking with quality)
20
+ * - v2.19.27 PROBE (probe outputs feed PAIR's mutual_info)
21
+ * - v2.19.9 WRAPPER_GENESPLICING (high-mutual-info pairs → chimera)
22
+ * - v2.19.25 SLEEP TRAINING (PAIR fitness blends with jaccard reward)
23
+ *
24
+ * Honest scope:
25
+ * - Mutual info APPROXIMATION via shape-matching, not full Shannon
26
+ * information. Faster, deterministic, sufficient for "are these
27
+ * two tools complementary?" decision.
28
+ * - HMAC-signed PairReport so federation can ship verified pairs.
29
+ */
30
+ import { createHmac, timingSafeEqual } from "node:crypto";
31
+ const PROTOCOL_VERSION = 1;
32
+ const DEFAULT_MIN_SCORE = 0.3;
33
+ function canon(v) {
34
+ if (v === null || typeof v !== "object")
35
+ return JSON.stringify(v);
36
+ if (Array.isArray(v))
37
+ return "[" + v.map(canon).join(",") + "]";
38
+ const keys = Object.keys(v).sort();
39
+ return "{" + keys.map((k) => JSON.stringify(k) + ":" + canon(v[k])).join(",") + "}";
40
+ }
41
+ function defaultSecret() {
42
+ return process.env["MNEME_DREAMSPACE_PAIR_SECRET"] || `mneme-dreamspace-pair-v${PROTOCOL_VERSION}`;
43
+ }
44
+ function hmacHex(body, secret) {
45
+ return createHmac("sha256", secret).update(canon(body)).digest("hex");
46
+ }
47
+ function safeEqHex(a, b) {
48
+ try {
49
+ return timingSafeEqual(Buffer.from(a, "hex"), Buffer.from(b, "hex"));
50
+ }
51
+ catch {
52
+ return false;
53
+ }
54
+ }
55
+ /** Jaccard over two string sets, case-insensitive. */
56
+ function jaccardKeys(a, b) {
57
+ const sa = new Set(a.map((x) => x.toLowerCase()));
58
+ const sb = new Set(b.map((x) => x.toLowerCase()));
59
+ if (sa.size === 0 && sb.size === 0)
60
+ return 1.0;
61
+ if (sa.size === 0 || sb.size === 0)
62
+ return 0.0;
63
+ let inter = 0;
64
+ for (const x of sa)
65
+ if (sb.has(x))
66
+ inter++;
67
+ return inter / (sa.size + sb.size - inter);
68
+ }
69
+ /** Union of all output keys observed across the tool's samples. */
70
+ function unionOutputKeys(samples) {
71
+ const keys = new Set();
72
+ for (const s of samples) {
73
+ for (const k of Object.keys(s.result))
74
+ keys.add(k.toLowerCase());
75
+ }
76
+ return Array.from(keys).sort();
77
+ }
78
+ /**
79
+ * Score a single (A, B) pair: how complementary is A's output to B's
80
+ * expected input?
81
+ *
82
+ * keyOverlapScore = jaccard(unionOutputKeys(A), requiredProps(B) ∪ optionalProps(B))
83
+ * requiredCoverage = |outputKeys(A) ∩ requiredProps(B)| / |requiredProps(B)|
84
+ * optionalCoverage = |outputKeys(A) ∩ optionalProps(B)| / |optionalProps(B)|
85
+ * mutualInfoScore = 0.5 * requiredCoverage + 0.3 * optionalCoverage + 0.2 * keyOverlapScore
86
+ *
87
+ * Required-coverage dominates because B will THROW if a required prop
88
+ * is missing; optional is nice-to-have; raw key overlap captures broader
89
+ * signal compatibility.
90
+ */
91
+ export function scorePair(input) {
92
+ const outputKeysA = unionOutputKeys(input.outputsA);
93
+ const setA = new Set(outputKeysA);
94
+ const reqB = input.schemaB.requiredProps.map((p) => p.toLowerCase());
95
+ const optB = input.schemaB.optionalProps.map((p) => p.toLowerCase());
96
+ const allB = [...reqB, ...optB];
97
+ const keyOverlap = jaccardKeys(outputKeysA, allB);
98
+ const reqCov = reqB.length === 0 ? 1.0 : reqB.filter((k) => setA.has(k)).length / reqB.length;
99
+ const optCov = optB.length === 0 ? 1.0 : optB.filter((k) => setA.has(k)).length / optB.length;
100
+ const mi = 0.5 * reqCov + 0.3 * optCov + 0.2 * keyOverlap;
101
+ return {
102
+ toolA: input.toolA,
103
+ toolB: input.schemaB.toolName,
104
+ keyOverlapScore: keyOverlap,
105
+ requiredCoverage: reqCov,
106
+ optionalCoverage: optCov,
107
+ mutualInfoScore: mi,
108
+ };
109
+ }
110
+ /**
111
+ * Score ALL ordered (A, B) pairs across the supplied tools; filter
112
+ * above minScore; sort by mutualInfoScore desc. Self-pairs excluded.
113
+ *
114
+ * Returns top pairs ready to feed into v2.19.26 GESTATION as
115
+ * `pattern_co_occurrence` signals with quality (not just frequency).
116
+ */
117
+ export function rankAllPairs(input) {
118
+ const minScore = input.minScore ?? DEFAULT_MIN_SCORE;
119
+ const topN = input.topN ?? 25;
120
+ const samplesByTool = new Map();
121
+ for (const arr of input.toolOutputs) {
122
+ if (arr.length === 0)
123
+ continue;
124
+ const name = arr[0].toolName;
125
+ const prev = samplesByTool.get(name) ?? [];
126
+ samplesByTool.set(name, prev.concat(arr));
127
+ }
128
+ const scoredPairs = [];
129
+ let totalCandidatePairs = 0;
130
+ for (const [aName, aSamples] of samplesByTool) {
131
+ for (const schemaB of input.toolSchemas) {
132
+ if (aName === schemaB.toolName)
133
+ continue;
134
+ totalCandidatePairs++;
135
+ const s = scorePair({ toolA: aName, outputsA: aSamples, schemaB });
136
+ if (s.mutualInfoScore >= minScore)
137
+ scoredPairs.push(s);
138
+ }
139
+ }
140
+ scoredPairs.sort((a, b) => b.mutualInfoScore - a.mutualInfoScore || a.toolA.localeCompare(b.toolA) || a.toolB.localeCompare(b.toolB));
141
+ const top = scoredPairs.slice(0, topN);
142
+ const body = {
143
+ v: PROTOCOL_VERSION,
144
+ pairs: top,
145
+ totalCandidatePairs,
146
+ qualifyingPairs: scoredPairs.length,
147
+ minScore,
148
+ builtAt: input.builtAt ?? Date.now(),
149
+ };
150
+ const sig = hmacHex(body, input.secret ?? defaultSecret());
151
+ return { ...body, sig };
152
+ }
153
+ export function verifyPairReport(r, secret) {
154
+ const { sig, ...body } = r;
155
+ return safeEqHex(hmacHex(body, secret ?? defaultSecret()), sig);
156
+ }
157
+ export function formatPairLine(p) {
158
+ const mi = (p.mutualInfoScore * 100).toFixed(0);
159
+ return `💞 PAIR ${p.toolA} → ${p.toolB} · MI=${mi}% · req=${(p.requiredCoverage * 100).toFixed(0)}% · opt=${(p.optionalCoverage * 100).toFixed(0)}%`;
160
+ }
161
+ //# sourceMappingURL=index.js.map