@mneme-ai/core 2.66.0 → 2.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/protoplasm/auto_wrap.d.ts +33 -0
- package/dist/protoplasm/auto_wrap.d.ts.map +1 -0
- package/dist/protoplasm/auto_wrap.js +72 -0
- package/dist/protoplasm/auto_wrap.js.map +1 -0
- package/dist/protoplasm/crawl_planner.d.ts +14 -0
- package/dist/protoplasm/crawl_planner.d.ts.map +1 -0
- package/dist/protoplasm/crawl_planner.js +50 -0
- package/dist/protoplasm/crawl_planner.js.map +1 -0
- package/dist/protoplasm/criu_pickle.d.ts +49 -0
- package/dist/protoplasm/criu_pickle.d.ts.map +1 -0
- package/dist/protoplasm/criu_pickle.js +73 -0
- package/dist/protoplasm/criu_pickle.js.map +1 -0
- package/dist/protoplasm/extensions.test.d.ts +8 -0
- package/dist/protoplasm/extensions.test.d.ts.map +1 -0
- package/dist/protoplasm/extensions.test.js +175 -0
- package/dist/protoplasm/extensions.test.js.map +1 -0
- package/dist/protoplasm/findings_ledger.d.ts +19 -0
- package/dist/protoplasm/findings_ledger.d.ts.map +1 -0
- package/dist/protoplasm/findings_ledger.js +81 -0
- package/dist/protoplasm/findings_ledger.js.map +1 -0
- package/dist/protoplasm/ghost_cell.d.ts +30 -0
- package/dist/protoplasm/ghost_cell.d.ts.map +1 -0
- package/dist/protoplasm/ghost_cell.js +95 -0
- package/dist/protoplasm/ghost_cell.js.map +1 -0
- package/dist/protoplasm/hydra_quorum.d.ts +43 -0
- package/dist/protoplasm/hydra_quorum.d.ts.map +1 -0
- package/dist/protoplasm/hydra_quorum.js +124 -0
- package/dist/protoplasm/hydra_quorum.js.map +1 -0
- package/dist/protoplasm/immortal.test.d.ts +12 -0
- package/dist/protoplasm/immortal.test.d.ts.map +1 -0
- package/dist/protoplasm/immortal.test.js +118 -0
- package/dist/protoplasm/immortal.test.js.map +1 -0
- package/dist/protoplasm/index.d.ts +52 -0
- package/dist/protoplasm/index.d.ts.map +1 -0
- package/dist/protoplasm/index.js +53 -0
- package/dist/protoplasm/index.js.map +1 -0
- package/dist/protoplasm/lan_gossip.d.ts +75 -0
- package/dist/protoplasm/lan_gossip.d.ts.map +1 -0
- package/dist/protoplasm/lan_gossip.js +140 -0
- package/dist/protoplasm/lan_gossip.js.map +1 -0
- package/dist/protoplasm/orchestrator.d.ts +29 -0
- package/dist/protoplasm/orchestrator.d.ts.map +1 -0
- package/dist/protoplasm/orchestrator.js +60 -0
- package/dist/protoplasm/orchestrator.js.map +1 -0
- package/dist/protoplasm/parasite.d.ts +42 -0
- package/dist/protoplasm/parasite.d.ts.map +1 -0
- package/dist/protoplasm/parasite.js +69 -0
- package/dist/protoplasm/parasite.js.map +1 -0
- package/dist/protoplasm/phoenix_hook.d.ts +49 -0
- package/dist/protoplasm/phoenix_hook.d.ts.map +1 -0
- package/dist/protoplasm/phoenix_hook.js +64 -0
- package/dist/protoplasm/phoenix_hook.js.map +1 -0
- package/dist/protoplasm/protoplasm.test.d.ts +13 -0
- package/dist/protoplasm/protoplasm.test.d.ts.map +1 -0
- package/dist/protoplasm/protoplasm.test.js +142 -0
- package/dist/protoplasm/protoplasm.test.js.map +1 -0
- package/dist/protoplasm/quantum_probe.d.ts +21 -0
- package/dist/protoplasm/quantum_probe.d.ts.map +1 -0
- package/dist/protoplasm/quantum_probe.js +118 -0
- package/dist/protoplasm/quantum_probe.js.map +1 -0
- package/dist/protoplasm/seamless_boot.d.ts +28 -0
- package/dist/protoplasm/seamless_boot.d.ts.map +1 -0
- package/dist/protoplasm/seamless_boot.js +106 -0
- package/dist/protoplasm/seamless_boot.js.map +1 -0
- package/dist/protoplasm/super_quan_probe.d.ts +24 -0
- package/dist/protoplasm/super_quan_probe.d.ts.map +1 -0
- package/dist/protoplasm/super_quan_probe.js +132 -0
- package/dist/protoplasm/super_quan_probe.js.map +1 -0
- package/dist/protoplasm/ts_auto_wrap.d.ts +53 -0
- package/dist/protoplasm/ts_auto_wrap.d.ts.map +1 -0
- package/dist/protoplasm/ts_auto_wrap.js +102 -0
- package/dist/protoplasm/ts_auto_wrap.js.map +1 -0
- package/dist/protoplasm/types.d.ts +84 -0
- package/dist/protoplasm/types.d.ts.map +1 -0
- package/dist/protoplasm/types.js +9 -0
- package/dist/protoplasm/types.js.map +1 -0
- package/dist/protoplasm/usb_soul.d.ts +35 -0
- package/dist/protoplasm/usb_soul.d.ts.map +1 -0
- package/dist/protoplasm/usb_soul.js +162 -0
- package/dist/protoplasm/usb_soul.js.map +1 -0
- package/dist/protoplasm/wal.d.ts +46 -0
- package/dist/protoplasm/wal.d.ts.map +1 -0
- package/dist/protoplasm/wal.js +145 -0
- package/dist/protoplasm/wal.js.map +1 -0
- package/dist/protoplasm/wisdom_space.d.ts +30 -0
- package/dist/protoplasm/wisdom_space.d.ts.map +1 -0
- package/dist/protoplasm/wisdom_space.js +77 -0
- package/dist/protoplasm/wisdom_space.js.map +1 -0
- package/dist/truth_gate/claims.d.ts.map +1 -1
- package/dist/truth_gate/claims.js +18 -0
- package/dist/truth_gate/claims.js.map +1 -1
- package/dist/truth_gate/probes.d.ts.map +1 -1
- package/dist/truth_gate/probes.js +42 -0
- package/dist/truth_gate/probes.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🩸 PROTOPLASM — IMMORTAL ATOM tests
|
|
3
|
+
*
|
|
4
|
+
* Pin 5 invariants that make PROTOPLASM survive process death:
|
|
5
|
+
* I-IMMORTAL-1: WAL persists baseline BEFORE RAM update
|
|
6
|
+
* I-IMMORTAL-2: replay reconstructs baselines from WAL
|
|
7
|
+
* I-IMMORTAL-3: tampered WAL row → verify detects
|
|
8
|
+
* I-IMMORTAL-4: seamlessBoot is idempotent (safe to call N times)
|
|
9
|
+
* I-IMMORTAL-5: parasiteTick writes heartbeat
|
|
10
|
+
*/
|
|
11
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
12
|
+
import { mkdtempSync, rmSync, readFileSync, existsSync, writeFileSync } from "node:fs";
|
|
13
|
+
import { tmpdir } from "node:os";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { Wal } from "./wal.js";
|
|
16
|
+
import { activateParasite, persistBaseline, loadBaseline, _resetParasite } from "./parasite.js";
|
|
17
|
+
import { seamlessBoot, isBooted, _resetBoot } from "./seamless_boot.js";
|
|
18
|
+
let tmpDir;
|
|
19
|
+
let cfg;
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
tmpDir = mkdtempSync(join(tmpdir(), "immortal-test-"));
|
|
22
|
+
cfg = {
|
|
23
|
+
baselineSamplesMin: 5, zScoreWarn: 2, zScoreBroken: 3,
|
|
24
|
+
ledgerDir: tmpDir, hmacKey: "test-immortal-key",
|
|
25
|
+
crawlOnHealthyEvery: 50,
|
|
26
|
+
};
|
|
27
|
+
_resetParasite();
|
|
28
|
+
_resetBoot();
|
|
29
|
+
});
|
|
30
|
+
afterEach(() => { try {
|
|
31
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
32
|
+
}
|
|
33
|
+
catch { /* */ } });
|
|
34
|
+
const sampleBaseline = (fnId, mean) => ({
|
|
35
|
+
fnId, samples: 10, durationMean: mean, durationStdev: 1, errorRate: 0,
|
|
36
|
+
argShapeEntropy: 0, outputShapeEntropy: 0, lastUpdate: new Date().toISOString(),
|
|
37
|
+
});
|
|
38
|
+
describe("I-IMMORTAL-1 — WAL persists BEFORE RAM", () => {
|
|
39
|
+
it("append → row on disk, replay returns it", () => {
|
|
40
|
+
const wal = new Wal(tmpDir, cfg.hmacKey);
|
|
41
|
+
const b = sampleBaseline("fn1", 10);
|
|
42
|
+
wal.append("baseline_set", "fn1", b);
|
|
43
|
+
const replayed = wal.replay();
|
|
44
|
+
expect(replayed.get("fn1")?.durationMean).toBe(10);
|
|
45
|
+
});
|
|
46
|
+
it("write succeeds even after process restart sim (new Wal instance reads same file)", () => {
|
|
47
|
+
const wal1 = new Wal(tmpDir, cfg.hmacKey);
|
|
48
|
+
wal1.append("baseline_set", "fnA", sampleBaseline("fnA", 5));
|
|
49
|
+
// simulate process death + restart by creating new Wal instance
|
|
50
|
+
const wal2 = new Wal(tmpDir, cfg.hmacKey);
|
|
51
|
+
const replayed = wal2.replay();
|
|
52
|
+
expect(replayed.get("fnA")?.durationMean).toBe(5);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe("I-IMMORTAL-2 — replay reconstructs full baseline map", () => {
|
|
56
|
+
it("3 fns × 2 updates each → replay returns latest each", () => {
|
|
57
|
+
const wal = new Wal(tmpDir, cfg.hmacKey);
|
|
58
|
+
wal.append("baseline_set", "fnA", sampleBaseline("fnA", 1));
|
|
59
|
+
wal.append("baseline_set", "fnB", sampleBaseline("fnB", 2));
|
|
60
|
+
wal.append("baseline_set", "fnC", sampleBaseline("fnC", 3));
|
|
61
|
+
wal.append("baseline_set", "fnA", sampleBaseline("fnA", 100)); // update
|
|
62
|
+
const replayed = wal.replay();
|
|
63
|
+
expect(replayed.size).toBe(3);
|
|
64
|
+
expect(replayed.get("fnA")?.durationMean).toBe(100);
|
|
65
|
+
expect(replayed.get("fnB")?.durationMean).toBe(2);
|
|
66
|
+
expect(replayed.get("fnC")?.durationMean).toBe(3);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe("I-IMMORTAL-3 — tampered WAL detected", () => {
|
|
70
|
+
it("flip a byte in row 1 → verify reports broken", () => {
|
|
71
|
+
const wal = new Wal(tmpDir, cfg.hmacKey);
|
|
72
|
+
wal.append("baseline_set", "fnA", sampleBaseline("fnA", 1));
|
|
73
|
+
wal.append("baseline_set", "fnB", sampleBaseline("fnB", 2));
|
|
74
|
+
wal.append("baseline_set", "fnC", sampleBaseline("fnC", 3));
|
|
75
|
+
const walPath = wal.path_for_test();
|
|
76
|
+
const lines = readFileSync(walPath, "utf8").trim().split("\n");
|
|
77
|
+
const row1 = JSON.parse(lines[1]);
|
|
78
|
+
row1.payload.durationMean = 99999; // tamper
|
|
79
|
+
lines[1] = JSON.stringify(row1);
|
|
80
|
+
writeFileSync(walPath, lines.join("\n") + "\n");
|
|
81
|
+
const v = wal.verify();
|
|
82
|
+
expect(v.ok).toBe(false);
|
|
83
|
+
expect(v.brokenAt).toBe(1);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
describe("I-IMMORTAL-4 — seamlessBoot idempotent", () => {
|
|
87
|
+
it("first call boots, second is no-op", () => {
|
|
88
|
+
const r1 = seamlessBoot(cfg);
|
|
89
|
+
const r2 = seamlessBoot(cfg);
|
|
90
|
+
expect(r1.booted).toBe(true);
|
|
91
|
+
expect(r2.booted).toBe(false);
|
|
92
|
+
expect(isBooted()).toBe(true);
|
|
93
|
+
});
|
|
94
|
+
it("writes heartbeat file", () => {
|
|
95
|
+
seamlessBoot(cfg);
|
|
96
|
+
expect(existsSync(join(tmpDir, "heartbeat.json"))).toBe(true);
|
|
97
|
+
const hb = JSON.parse(readFileSync(join(tmpDir, "heartbeat.json"), "utf8"));
|
|
98
|
+
expect(hb.pid).toBe(process.pid);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe("I-IMMORTAL-5 — parasite persists state across calls", () => {
|
|
102
|
+
it("persistBaseline → loadBaseline returns same", () => {
|
|
103
|
+
activateParasite(cfg);
|
|
104
|
+
persistBaseline("fnX", sampleBaseline("fnX", 42));
|
|
105
|
+
const loaded = loadBaseline("fnX");
|
|
106
|
+
expect(loaded?.durationMean).toBe(42);
|
|
107
|
+
});
|
|
108
|
+
it("survives parasite reset (simulating process restart)", () => {
|
|
109
|
+
activateParasite(cfg);
|
|
110
|
+
persistBaseline("fnY", sampleBaseline("fnY", 77));
|
|
111
|
+
_resetParasite();
|
|
112
|
+
// Now simulate fresh process: activate again, should reload from WAL
|
|
113
|
+
activateParasite(cfg);
|
|
114
|
+
const loaded = loadBaseline("fnY");
|
|
115
|
+
expect(loaded?.durationMean).toBe(77);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
//# sourceMappingURL=immortal.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"immortal.test.js","sourceRoot":"","sources":["../../src/protoplasm/immortal.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🦠 PROTOPLASM — public surface
|
|
3
|
+
*
|
|
4
|
+
* The "live atom" infrastructure. Embed `withSuperQuanProbe` in any function
|
|
5
|
+
* to enable continuous statistical + quantum-inspired health monitoring.
|
|
6
|
+
*
|
|
7
|
+
* Composes with:
|
|
8
|
+
* - LIVING LAB (v2.58) — emit findings as living lab events
|
|
9
|
+
* - SUPERNOVA self-heal (v1.30) — broken verdicts trigger restart cycles
|
|
10
|
+
* - MNEMNET federation (v2.33) — healthy bursts can crawl globally
|
|
11
|
+
* - TRUTH GATE — broken cascades raise release block
|
|
12
|
+
* - HGP — broken patterns become hallucination genome entries
|
|
13
|
+
*
|
|
14
|
+
* Wire example:
|
|
15
|
+
* import { withSuperQuanProbe, startOrchestrator } from "@mneme-ai/core/protoplasm";
|
|
16
|
+
*
|
|
17
|
+
* const safeFn = withSuperQuanProbe("auth.lookupUser", lookupUser, DEFAULT_PROTOPLASM_CONFIG);
|
|
18
|
+
* startOrchestrator({
|
|
19
|
+
* onBroken: (v) => console.warn("broken:", v.diagnosis?.hypothesis),
|
|
20
|
+
* onCrawl: (v) => mnemnetCrawl(v.crawl!.searchTopics),
|
|
21
|
+
* });
|
|
22
|
+
*/
|
|
23
|
+
export type { ProbeOutcome, InvocationSnapshot, FunctionBaseline, SuperQuanFinding, QuantumSignals, WisdomRootCause, HealAction, CrawlPlan, ProtoplasmConfig, } from "./types.js";
|
|
24
|
+
export { withSuperQuanProbe, onFinding, snapshotRegistry, clearRegistry, } from "./super_quan_probe.js";
|
|
25
|
+
export { buildBaseline, computeQuantumSignals, gradeOutcome, runQuantumProbe } from "./quantum_probe.js";
|
|
26
|
+
export { appendFinding, readLedger, verifyChain, lastHmac, canonicalJson } from "./findings_ledger.js";
|
|
27
|
+
export { diagnose, ledgerHealth } from "./wisdom_space.js";
|
|
28
|
+
export { planCrawl } from "./crawl_planner.js";
|
|
29
|
+
export { startOrchestrator, manualProbeReport, DEFAULT_PROTOPLASM_CONFIG } from "./orchestrator.js";
|
|
30
|
+
export type { OrchestratorVerdict, OrchestratorHooks } from "./orchestrator.js";
|
|
31
|
+
export { Wal } from "./wal.js";
|
|
32
|
+
export type { WalRow, WalOp } from "./wal.js";
|
|
33
|
+
export { activateParasite, getParasite, persistBaseline, loadBaseline, parasiteTick } from "./parasite.js";
|
|
34
|
+
export type { ParasiteContext } from "./parasite.js";
|
|
35
|
+
export { spawnGhostCell } from "./ghost_cell.js";
|
|
36
|
+
export type { GhostCellOptions } from "./ghost_cell.js";
|
|
37
|
+
export { seamlessBoot, isBooted, getKeyProvenance } from "./seamless_boot.js";
|
|
38
|
+
export { drainHealQueue, registerWithPhoenix, PROTOPLASM_REVIVABLE } from "./phoenix_hook.js";
|
|
39
|
+
export type { PhoenixHookContext, HealQueueEntry, RevivableSpec } from "./phoenix_hook.js";
|
|
40
|
+
export { autoWrapModule, autoWrapModuleProxy, autoWrapClass } from "./auto_wrap.js";
|
|
41
|
+
export type { AutoWrapOptions } from "./auto_wrap.js";
|
|
42
|
+
export { syncTo, syncFrom, pickMount, verifyMount } from "./usb_soul.js";
|
|
43
|
+
export type { UsbSoulResult } from "./usb_soul.js";
|
|
44
|
+
export { statusHydra, tryBecomePrimary, refreshPrimary, releasePrimary, startHydraHeartbeat, HYDRA_TUNING } from "./hydra_quorum.js";
|
|
45
|
+
export type { HydraStatus, HydraRole } from "./hydra_quorum.js";
|
|
46
|
+
export { LanGossip, GOSSIP_TUNING } from "./lan_gossip.js";
|
|
47
|
+
export type { GossipSummary, GossipFrame, PeerRecord, GossipOptions } from "./lan_gossip.js";
|
|
48
|
+
export { scanSourceFile, scanDirectory, rewriteSourceFile } from "./ts_auto_wrap.js";
|
|
49
|
+
export type { ScanResult, ScannedExport, RewriteResult } from "./ts_auto_wrap.js";
|
|
50
|
+
export { probeCriu, snapshot as criuSnapshot, restore as criuRestore } from "./criu_pickle.js";
|
|
51
|
+
export type { CriuAvailability, CriuSnapshotResult, CriuRestoreResult } from "./criu_pickle.js";
|
|
52
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/protoplasm/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,YAAY,EACV,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,UAAU,EACV,SAAS,EACT,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,kBAAkB,EAClB,SAAS,EACT,gBAAgB,EAChB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACzG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACvG,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AACpG,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAShF,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3G,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9F,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpF,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAQtD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACzE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACrI,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACrF,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,SAAS,EAAE,QAAQ,IAAI,YAAY,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/F,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🦠 PROTOPLASM — public surface
|
|
3
|
+
*
|
|
4
|
+
* The "live atom" infrastructure. Embed `withSuperQuanProbe` in any function
|
|
5
|
+
* to enable continuous statistical + quantum-inspired health monitoring.
|
|
6
|
+
*
|
|
7
|
+
* Composes with:
|
|
8
|
+
* - LIVING LAB (v2.58) — emit findings as living lab events
|
|
9
|
+
* - SUPERNOVA self-heal (v1.30) — broken verdicts trigger restart cycles
|
|
10
|
+
* - MNEMNET federation (v2.33) — healthy bursts can crawl globally
|
|
11
|
+
* - TRUTH GATE — broken cascades raise release block
|
|
12
|
+
* - HGP — broken patterns become hallucination genome entries
|
|
13
|
+
*
|
|
14
|
+
* Wire example:
|
|
15
|
+
* import { withSuperQuanProbe, startOrchestrator } from "@mneme-ai/core/protoplasm";
|
|
16
|
+
*
|
|
17
|
+
* const safeFn = withSuperQuanProbe("auth.lookupUser", lookupUser, DEFAULT_PROTOPLASM_CONFIG);
|
|
18
|
+
* startOrchestrator({
|
|
19
|
+
* onBroken: (v) => console.warn("broken:", v.diagnosis?.hypothesis),
|
|
20
|
+
* onCrawl: (v) => mnemnetCrawl(v.crawl!.searchTopics),
|
|
21
|
+
* });
|
|
22
|
+
*/
|
|
23
|
+
export { withSuperQuanProbe, onFinding, snapshotRegistry, clearRegistry, } from "./super_quan_probe.js";
|
|
24
|
+
export { buildBaseline, computeQuantumSignals, gradeOutcome, runQuantumProbe } from "./quantum_probe.js";
|
|
25
|
+
export { appendFinding, readLedger, verifyChain, lastHmac, canonicalJson } from "./findings_ledger.js";
|
|
26
|
+
export { diagnose, ledgerHealth } from "./wisdom_space.js";
|
|
27
|
+
export { planCrawl } from "./crawl_planner.js";
|
|
28
|
+
export { startOrchestrator, manualProbeReport, DEFAULT_PROTOPLASM_CONFIG } from "./orchestrator.js";
|
|
29
|
+
// v2.67 — IMMORTAL ATOM layer: 5-strategy fusion that makes PROTOPLASM
|
|
30
|
+
// survive any kill signal up to and including SIGKILL + OS reboot.
|
|
31
|
+
// WAL → state persists to disk BEFORE RAM (uncatchable-kill safe)
|
|
32
|
+
// PARASITE → atom rides on every Mneme tool call (no daemon needed)
|
|
33
|
+
// GHOST CELL → detached watchdog detects abnormal exit + queues heal
|
|
34
|
+
// PHOENIX HOOK → composes with existing SUPERNOVA / nucleus_daemon
|
|
35
|
+
// SEAMLESS → zero-config auto-init; user does nothing
|
|
36
|
+
export { Wal } from "./wal.js";
|
|
37
|
+
export { activateParasite, getParasite, persistBaseline, loadBaseline, parasiteTick } from "./parasite.js";
|
|
38
|
+
export { spawnGhostCell } from "./ghost_cell.js";
|
|
39
|
+
export { seamlessBoot, isBooted, getKeyProvenance } from "./seamless_boot.js";
|
|
40
|
+
export { drainHealQueue, registerWithPhoenix, PROTOPLASM_REVIVABLE } from "./phoenix_hook.js";
|
|
41
|
+
export { autoWrapModule, autoWrapModuleProxy, autoWrapClass } from "./auto_wrap.js";
|
|
42
|
+
// v2.68.0 — extension primitives:
|
|
43
|
+
// USB SOUL → portable WAL via mount detection
|
|
44
|
+
// HYDRA QUORUM → file-lock based primary-secondary failover
|
|
45
|
+
// LAN GOSSIP → UDP multicast peer discovery + HMAC-signed gossip
|
|
46
|
+
// TS AUTO-WRAP → static scan + non-AST regex rewrite of exports
|
|
47
|
+
// CRIU PICKLE → Linux CRIU snapshot/restore (Linux-only)
|
|
48
|
+
export { syncTo, syncFrom, pickMount, verifyMount } from "./usb_soul.js";
|
|
49
|
+
export { statusHydra, tryBecomePrimary, refreshPrimary, releasePrimary, startHydraHeartbeat, HYDRA_TUNING } from "./hydra_quorum.js";
|
|
50
|
+
export { LanGossip, GOSSIP_TUNING } from "./lan_gossip.js";
|
|
51
|
+
export { scanSourceFile, scanDirectory, rewriteSourceFile } from "./ts_auto_wrap.js";
|
|
52
|
+
export { probeCriu, snapshot as criuSnapshot, restore as criuRestore } from "./criu_pickle.js";
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/protoplasm/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAcH,OAAO,EACL,kBAAkB,EAClB,SAAS,EACT,gBAAgB,EAChB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACzG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACvG,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAGpG,uEAAuE;AACvE,mEAAmE;AACnE,6EAA6E;AAC7E,0EAA0E;AAC1E,yEAAyE;AACzE,qEAAqE;AACrE,4DAA4D;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE3G,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9F,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpF,kCAAkC;AAClC,qDAAqD;AACrD,+DAA+D;AAC/D,sEAAsE;AACtE,mEAAmE;AACnE,6DAA6D;AAC7D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAErI,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAErF,OAAO,EAAE,SAAS,EAAE,QAAQ,IAAI,YAAY,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🌐 PROTOPLASM — LAN GOSSIP
|
|
3
|
+
*
|
|
4
|
+
* Mneme instances on the same LAN can discover each other via UDP
|
|
5
|
+
* multicast and gossip per-host health summaries. Each gossip frame is
|
|
6
|
+
* HMAC-signed so a hostile peer cannot inject false findings.
|
|
7
|
+
*
|
|
8
|
+
* Wire format (UTF-8 JSON over UDP):
|
|
9
|
+
* {
|
|
10
|
+
* v: 1,
|
|
11
|
+
* hostId: string, // stable per-machine id
|
|
12
|
+
* pid: number,
|
|
13
|
+
* ts: ISO,
|
|
14
|
+
* summary: { healthy, warn, broken, totalFns, walRows },
|
|
15
|
+
* hmac: hex16 // HMAC of canonical(body)
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* Default multicast: 239.42.42.42 : 42424. Configurable via env.
|
|
19
|
+
* TTL=1 keeps it on LAN (no internet leak).
|
|
20
|
+
*
|
|
21
|
+
* Discovery: instances announce every ANNOUNCE_MS. Receivers maintain
|
|
22
|
+
* a peer map with last-seen + summary.
|
|
23
|
+
*/
|
|
24
|
+
export interface GossipSummary {
|
|
25
|
+
healthy: number;
|
|
26
|
+
warn: number;
|
|
27
|
+
broken: number;
|
|
28
|
+
totalFns: number;
|
|
29
|
+
walRows: number;
|
|
30
|
+
}
|
|
31
|
+
export interface GossipFrame {
|
|
32
|
+
v: 1;
|
|
33
|
+
hostId: string;
|
|
34
|
+
pid: number;
|
|
35
|
+
ts: string;
|
|
36
|
+
summary: GossipSummary;
|
|
37
|
+
hmac: string;
|
|
38
|
+
}
|
|
39
|
+
export interface PeerRecord extends GossipFrame {
|
|
40
|
+
lastSeenAt: string;
|
|
41
|
+
fromAddress: string;
|
|
42
|
+
}
|
|
43
|
+
export interface GossipOptions {
|
|
44
|
+
secret: string;
|
|
45
|
+
hostId?: string;
|
|
46
|
+
group?: string;
|
|
47
|
+
port?: number;
|
|
48
|
+
onPeer?: (peer: PeerRecord) => void;
|
|
49
|
+
}
|
|
50
|
+
export declare class LanGossip {
|
|
51
|
+
readonly opts: GossipOptions;
|
|
52
|
+
private sock;
|
|
53
|
+
private peers;
|
|
54
|
+
private announceTimer?;
|
|
55
|
+
private stop;
|
|
56
|
+
constructor(opts: GossipOptions);
|
|
57
|
+
start(): Promise<{
|
|
58
|
+
ok: boolean;
|
|
59
|
+
reason?: string;
|
|
60
|
+
group: string;
|
|
61
|
+
port: number;
|
|
62
|
+
}>;
|
|
63
|
+
private handleMessage;
|
|
64
|
+
announce(summary: GossipSummary): boolean;
|
|
65
|
+
startAnnouncing(summaryFn: () => GossipSummary): void;
|
|
66
|
+
listPeers(): PeerRecord[];
|
|
67
|
+
close(): void;
|
|
68
|
+
}
|
|
69
|
+
export declare const GOSSIP_TUNING: {
|
|
70
|
+
DEFAULT_GROUP: string;
|
|
71
|
+
DEFAULT_PORT: number;
|
|
72
|
+
ANNOUNCE_MS: number;
|
|
73
|
+
PEER_STALE_MS: number;
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=lan_gossip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lan_gossip.d.ts","sourceRoot":"","sources":["../../src/protoplasm/lan_gossip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAWH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,CAAC,CAAC;IACL,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,aAAa,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAkBD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACrC;AAED,qBAAa,SAAS;aAMQ,IAAI,EAAE,aAAa;IAL/C,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,aAAa,CAAC,CAAiB;IACvC,OAAO,CAAC,IAAI,CAAS;gBAEO,IAAI,EAAE,aAAa;IAEzC,KAAK,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAqBrF,OAAO,CAAC,aAAa;IAYrB,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO;IAiBzC,eAAe,CAAC,SAAS,EAAE,MAAM,aAAa,GAAG,IAAI;IAOrD,SAAS,IAAI,UAAU,EAAE;IAKzB,KAAK,IAAI,IAAI;CAKd;AAED,eAAO,MAAM,aAAa;;;;;CAA8D,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🌐 PROTOPLASM — LAN GOSSIP
|
|
3
|
+
*
|
|
4
|
+
* Mneme instances on the same LAN can discover each other via UDP
|
|
5
|
+
* multicast and gossip per-host health summaries. Each gossip frame is
|
|
6
|
+
* HMAC-signed so a hostile peer cannot inject false findings.
|
|
7
|
+
*
|
|
8
|
+
* Wire format (UTF-8 JSON over UDP):
|
|
9
|
+
* {
|
|
10
|
+
* v: 1,
|
|
11
|
+
* hostId: string, // stable per-machine id
|
|
12
|
+
* pid: number,
|
|
13
|
+
* ts: ISO,
|
|
14
|
+
* summary: { healthy, warn, broken, totalFns, walRows },
|
|
15
|
+
* hmac: hex16 // HMAC of canonical(body)
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* Default multicast: 239.42.42.42 : 42424. Configurable via env.
|
|
19
|
+
* TTL=1 keeps it on LAN (no internet leak).
|
|
20
|
+
*
|
|
21
|
+
* Discovery: instances announce every ANNOUNCE_MS. Receivers maintain
|
|
22
|
+
* a peer map with last-seen + summary.
|
|
23
|
+
*/
|
|
24
|
+
import { createSocket } from "node:dgram";
|
|
25
|
+
import { createHmac } from "node:crypto";
|
|
26
|
+
import { hostname } from "node:os";
|
|
27
|
+
const DEFAULT_GROUP = process.env.MNEME_GOSSIP_GROUP ?? "239.42.42.42";
|
|
28
|
+
const DEFAULT_PORT = Number(process.env.MNEME_GOSSIP_PORT ?? 42424);
|
|
29
|
+
const ANNOUNCE_MS = 30_000;
|
|
30
|
+
const PEER_STALE_MS = 90_000;
|
|
31
|
+
function canonical(o) {
|
|
32
|
+
if (o === null || typeof o !== "object")
|
|
33
|
+
return JSON.stringify(o);
|
|
34
|
+
if (Array.isArray(o))
|
|
35
|
+
return "[" + o.map(canonical).join(",") + "]";
|
|
36
|
+
const keys = Object.keys(o).sort();
|
|
37
|
+
return "{" + keys.map((k) => JSON.stringify(k) + ":" + canonical(o[k])).join(",") + "}";
|
|
38
|
+
}
|
|
39
|
+
function signFrame(body, secret) {
|
|
40
|
+
return createHmac("sha256", secret).update(canonical(body)).digest("hex").slice(0, 16);
|
|
41
|
+
}
|
|
42
|
+
function verifyFrame(frame, secret) {
|
|
43
|
+
const { hmac, ...body } = frame;
|
|
44
|
+
return signFrame(body, secret) === hmac;
|
|
45
|
+
}
|
|
46
|
+
export class LanGossip {
|
|
47
|
+
opts;
|
|
48
|
+
sock = null;
|
|
49
|
+
peers = new Map();
|
|
50
|
+
announceTimer;
|
|
51
|
+
stop = false;
|
|
52
|
+
constructor(opts) {
|
|
53
|
+
this.opts = opts;
|
|
54
|
+
}
|
|
55
|
+
async start() {
|
|
56
|
+
const group = this.opts.group ?? DEFAULT_GROUP;
|
|
57
|
+
const port = this.opts.port ?? DEFAULT_PORT;
|
|
58
|
+
return await new Promise((resolve) => {
|
|
59
|
+
const sock = createSocket({ type: "udp4", reuseAddr: true });
|
|
60
|
+
sock.on("error", (err) => { try {
|
|
61
|
+
sock.close();
|
|
62
|
+
}
|
|
63
|
+
catch { /* */ } resolve({ ok: false, reason: err.message, group, port }); });
|
|
64
|
+
sock.on("message", (buf, rinfo) => this.handleMessage(buf, rinfo));
|
|
65
|
+
sock.bind(port, () => {
|
|
66
|
+
try {
|
|
67
|
+
sock.setMulticastTTL(1);
|
|
68
|
+
sock.setBroadcast(true);
|
|
69
|
+
sock.addMembership(group);
|
|
70
|
+
this.sock = sock;
|
|
71
|
+
resolve({ ok: true, group, port });
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
resolve({ ok: false, reason: e.message, group, port });
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
handleMessage(buf, rinfo) {
|
|
80
|
+
if (this.stop)
|
|
81
|
+
return;
|
|
82
|
+
try {
|
|
83
|
+
const frame = JSON.parse(buf.toString("utf8"));
|
|
84
|
+
if (frame.v !== 1)
|
|
85
|
+
return;
|
|
86
|
+
if (!verifyFrame(frame, this.opts.secret))
|
|
87
|
+
return; // silent reject hostile
|
|
88
|
+
const peer = { ...frame, lastSeenAt: new Date().toISOString(), fromAddress: rinfo.address };
|
|
89
|
+
this.peers.set(frame.hostId, peer);
|
|
90
|
+
this.opts.onPeer?.(peer);
|
|
91
|
+
}
|
|
92
|
+
catch { /* malformed → drop */ }
|
|
93
|
+
}
|
|
94
|
+
announce(summary) {
|
|
95
|
+
if (!this.sock)
|
|
96
|
+
return false;
|
|
97
|
+
const body = {
|
|
98
|
+
v: 1,
|
|
99
|
+
hostId: this.opts.hostId ?? hostname(),
|
|
100
|
+
pid: process.pid,
|
|
101
|
+
ts: new Date().toISOString(),
|
|
102
|
+
summary,
|
|
103
|
+
};
|
|
104
|
+
const frame = { ...body, hmac: signFrame(body, this.opts.secret) };
|
|
105
|
+
const payload = Buffer.from(JSON.stringify(frame), "utf8");
|
|
106
|
+
try {
|
|
107
|
+
this.sock.send(payload, this.opts.port ?? DEFAULT_PORT, this.opts.group ?? DEFAULT_GROUP);
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
startAnnouncing(summaryFn) {
|
|
115
|
+
if (this.announceTimer)
|
|
116
|
+
return;
|
|
117
|
+
this.announce(summaryFn());
|
|
118
|
+
this.announceTimer = setInterval(() => this.announce(summaryFn()), ANNOUNCE_MS);
|
|
119
|
+
if (typeof this.announceTimer.unref === "function")
|
|
120
|
+
this.announceTimer.unref();
|
|
121
|
+
}
|
|
122
|
+
listPeers() {
|
|
123
|
+
const now = Date.now();
|
|
124
|
+
return [...this.peers.values()].filter((p) => now - new Date(p.lastSeenAt).getTime() < PEER_STALE_MS);
|
|
125
|
+
}
|
|
126
|
+
close() {
|
|
127
|
+
this.stop = true;
|
|
128
|
+
if (this.announceTimer)
|
|
129
|
+
clearInterval(this.announceTimer);
|
|
130
|
+
if (this.sock) {
|
|
131
|
+
try {
|
|
132
|
+
this.sock.close();
|
|
133
|
+
}
|
|
134
|
+
catch { /* */ }
|
|
135
|
+
this.sock = null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export const GOSSIP_TUNING = { DEFAULT_GROUP, DEFAULT_PORT, ANNOUNCE_MS, PEER_STALE_MS };
|
|
140
|
+
//# sourceMappingURL=lan_gossip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lan_gossip.js","sourceRoot":"","sources":["../../src/protoplasm/lan_gossip.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🦠 PROTOPLASM — orchestrator
|
|
3
|
+
*
|
|
4
|
+
* Central brain that:
|
|
5
|
+
* - receives findings via PROBE_LISTENERS
|
|
6
|
+
* - dispatches to wisdom_space when broken
|
|
7
|
+
* - triggers crawl_planner when healthy bursts accumulate
|
|
8
|
+
*
|
|
9
|
+
* Stateless w.r.t. file IO — all chain writes are via findings_ledger.
|
|
10
|
+
*/
|
|
11
|
+
import type { SuperQuanFinding, WisdomRootCause, CrawlPlan, ProtoplasmConfig } from "./types.js";
|
|
12
|
+
import { ledgerHealth } from "./wisdom_space.js";
|
|
13
|
+
export interface OrchestratorVerdict {
|
|
14
|
+
finding: SuperQuanFinding;
|
|
15
|
+
diagnosis?: WisdomRootCause;
|
|
16
|
+
crawl?: CrawlPlan;
|
|
17
|
+
}
|
|
18
|
+
export interface OrchestratorHooks {
|
|
19
|
+
onBroken?: (v: OrchestratorVerdict) => void;
|
|
20
|
+
onCrawl?: (v: OrchestratorVerdict) => void;
|
|
21
|
+
onHealthy?: (v: OrchestratorVerdict) => void;
|
|
22
|
+
}
|
|
23
|
+
export declare function startOrchestrator(hooks?: OrchestratorHooks, cfg?: ProtoplasmConfig): () => void;
|
|
24
|
+
export declare function manualProbeReport(cfg?: ProtoplasmConfig): {
|
|
25
|
+
health: ReturnType<typeof ledgerHealth>;
|
|
26
|
+
lastFindings: SuperQuanFinding[];
|
|
27
|
+
};
|
|
28
|
+
export declare const DEFAULT_PROTOPLASM_CONFIG: ProtoplasmConfig;
|
|
29
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/protoplasm/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEjG,OAAO,EAAY,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAI3D,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC3C,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAC9C;AAcD,wBAAgB,iBAAiB,CAAC,KAAK,GAAE,iBAAsB,EAAE,GAAG,GAAE,gBAA8B,GAAG,MAAM,IAAI,CAMhH;AAsBD,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,gBAA8B,GAAG;IAAE,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;IAAC,YAAY,EAAE,gBAAgB,EAAE,CAAA;CAAE,CAGpJ;AAED,eAAO,MAAM,yBAAyB,kBAAc,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🦠 PROTOPLASM — orchestrator
|
|
3
|
+
*
|
|
4
|
+
* Central brain that:
|
|
5
|
+
* - receives findings via PROBE_LISTENERS
|
|
6
|
+
* - dispatches to wisdom_space when broken
|
|
7
|
+
* - triggers crawl_planner when healthy bursts accumulate
|
|
8
|
+
*
|
|
9
|
+
* Stateless w.r.t. file IO — all chain writes are via findings_ledger.
|
|
10
|
+
*/
|
|
11
|
+
import { onFinding } from "./super_quan_probe.js";
|
|
12
|
+
import { diagnose, ledgerHealth } from "./wisdom_space.js";
|
|
13
|
+
import { planCrawl } from "./crawl_planner.js";
|
|
14
|
+
import { readLedger } from "./findings_ledger.js";
|
|
15
|
+
const DEFAULT_CFG = {
|
|
16
|
+
baselineSamplesMin: 5,
|
|
17
|
+
zScoreWarn: 2,
|
|
18
|
+
zScoreBroken: 3,
|
|
19
|
+
ledgerDir: ".mneme/protoplasm",
|
|
20
|
+
hmacKey: process.env.MNEME_PROTOPLASM_KEY ?? "dev-protoplasm-key",
|
|
21
|
+
crawlOnHealthyEvery: 50,
|
|
22
|
+
};
|
|
23
|
+
let healthyBurstCount = 0;
|
|
24
|
+
let activeHooks = {};
|
|
25
|
+
export function startOrchestrator(hooks = {}, cfg = DEFAULT_CFG) {
|
|
26
|
+
activeHooks = hooks;
|
|
27
|
+
const stop = onFinding((finding) => {
|
|
28
|
+
handle(finding, cfg);
|
|
29
|
+
});
|
|
30
|
+
return stop;
|
|
31
|
+
}
|
|
32
|
+
function handle(finding, cfg) {
|
|
33
|
+
const verdict = { finding };
|
|
34
|
+
if (finding.outcome === "broken") {
|
|
35
|
+
const recent = readLedger(cfg.ledgerDir + "/findings.jsonl").slice(-200);
|
|
36
|
+
verdict.diagnosis = diagnose({ brokenFinding: finding, recentLedger: recent });
|
|
37
|
+
healthyBurstCount = 0;
|
|
38
|
+
activeHooks.onBroken?.(verdict);
|
|
39
|
+
}
|
|
40
|
+
else if (finding.outcome === "healthy") {
|
|
41
|
+
healthyBurstCount++;
|
|
42
|
+
activeHooks.onHealthy?.(verdict);
|
|
43
|
+
if (healthyBurstCount >= cfg.crawlOnHealthyEvery) {
|
|
44
|
+
healthyBurstCount = 0;
|
|
45
|
+
const recent = readLedger(cfg.ledgerDir + "/findings.jsonl").slice(-200);
|
|
46
|
+
const crawl = planCrawl(recent);
|
|
47
|
+
if (crawl) {
|
|
48
|
+
verdict.crawl = crawl;
|
|
49
|
+
activeHooks.onCrawl?.(verdict);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return verdict;
|
|
54
|
+
}
|
|
55
|
+
export function manualProbeReport(cfg = DEFAULT_CFG) {
|
|
56
|
+
const recent = readLedger(cfg.ledgerDir + "/findings.jsonl").slice(-100);
|
|
57
|
+
return { health: ledgerHealth(recent), lastFindings: recent.slice(-10) };
|
|
58
|
+
}
|
|
59
|
+
export const DEFAULT_PROTOPLASM_CONFIG = DEFAULT_CFG;
|
|
60
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/protoplasm/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAiB,MAAM,sBAAsB,CAAC;AAcjE,MAAM,WAAW,GAAqB;IACpC,kBAAkB,EAAE,CAAC;IACrB,UAAU,EAAE,CAAC;IACb,YAAY,EAAE,CAAC;IACf,SAAS,EAAE,mBAAmB;IAC9B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,oBAAoB;IACjE,mBAAmB,EAAE,EAAE;CACxB,CAAC;AAEF,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAC1B,IAAI,WAAW,GAAsB,EAAE,CAAC;AAExC,MAAM,UAAU,iBAAiB,CAAC,QAA2B,EAAE,EAAE,MAAwB,WAAW;IAClG,WAAW,GAAG,KAAK,CAAC;IACpB,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE;QACjC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,MAAM,CAAC,OAAyB,EAAE,GAAqB;IAC9D,MAAM,OAAO,GAAwB,EAAE,OAAO,EAAE,CAAC;IACjD,IAAI,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,GAAG,iBAAiB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;QACzE,OAAO,CAAC,SAAS,GAAG,QAAQ,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/E,iBAAiB,GAAG,CAAC,CAAC;QACtB,WAAW,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;SAAM,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACzC,iBAAiB,EAAE,CAAC;QACpB,WAAW,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,iBAAiB,IAAI,GAAG,CAAC,mBAAmB,EAAE,CAAC;YACjD,iBAAiB,GAAG,CAAC,CAAC;YACtB,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,GAAG,iBAAiB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;YACzE,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YAChC,IAAI,KAAK,EAAE,CAAC;gBAAC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;gBAAC,WAAW,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC;YAAC,CAAC;QACvE,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAwB,WAAW;IACnE,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,GAAG,iBAAiB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;IACzE,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED,MAAM,CAAC,MAAM,yBAAyB,GAAG,WAAW,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🐍 PROTOPLASM — PARASITE pattern
|
|
3
|
+
*
|
|
4
|
+
* "If the host lives, the atom lives."
|
|
5
|
+
*
|
|
6
|
+
* Why parasite: most resilience strategies need a persistent process.
|
|
7
|
+
* Mneme CLI is one-shot → no persistent process possible by design.
|
|
8
|
+
* Solution: PROTOPLASM rides on EVERY Mneme tool invocation.
|
|
9
|
+
*
|
|
10
|
+
* ANY mneme <cmd> → parasite.activate() runs
|
|
11
|
+
* → loads WAL baselines
|
|
12
|
+
* → ticks orchestrator once
|
|
13
|
+
* → flushes recent findings
|
|
14
|
+
* → exits with parent
|
|
15
|
+
*
|
|
16
|
+
* Cost: ~1-2ms per CLI invocation.
|
|
17
|
+
* Benefit: state survives forever even though no daemon needed.
|
|
18
|
+
*
|
|
19
|
+
* Combined with WAL = TRUE 24/7 monitoring without any daemon process.
|
|
20
|
+
*/
|
|
21
|
+
import { Wal } from "./wal.js";
|
|
22
|
+
import type { FunctionBaseline, ProtoplasmConfig } from "./types.js";
|
|
23
|
+
export interface ParasiteContext {
|
|
24
|
+
wal: Wal;
|
|
25
|
+
baselines: Map<string, FunctionBaseline>;
|
|
26
|
+
loadedAt: string;
|
|
27
|
+
cfg: ProtoplasmConfig;
|
|
28
|
+
}
|
|
29
|
+
/** Idempotent: first call boots, subsequent calls return cached. */
|
|
30
|
+
export declare function activateParasite(cfg: ProtoplasmConfig): ParasiteContext;
|
|
31
|
+
export declare function getParasite(): ParasiteContext | null;
|
|
32
|
+
/** Persist baseline update via WAL BEFORE updating in-memory.
|
|
33
|
+
* This is the critical order: disk first, RAM second.
|
|
34
|
+
* Even SIGKILL between these calls leaves state durable. */
|
|
35
|
+
export declare function persistBaseline(fnId: string, baseline: FunctionBaseline): void;
|
|
36
|
+
/** Load baseline from persistent state (used on first wrap of a fn). */
|
|
37
|
+
export declare function loadBaseline(fnId: string): FunctionBaseline | null;
|
|
38
|
+
/** Called by every Mneme tool invocation as the first line. */
|
|
39
|
+
export declare function parasiteTick(cfg: ProtoplasmConfig): void;
|
|
40
|
+
/** Reset for tests. */
|
|
41
|
+
export declare function _resetParasite(): void;
|
|
42
|
+
//# sourceMappingURL=parasite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parasite.d.ts","sourceRoot":"","sources":["../../src/protoplasm/parasite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErE,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,GAAG,CAAC;IACT,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,gBAAgB,CAAC;CACvB;AAID,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,eAAe,CAMvE;AAED,wBAAgB,WAAW,IAAI,eAAe,GAAG,IAAI,CAEpD;AAED;;6DAE6D;AAC7D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAI9E;AAED,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAGlE;AAED,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAWxD;AAED,uBAAuB;AACvB,wBAAgB,cAAc,IAAI,IAAI,CAErC"}
|