@mneme-ai/core 2.21.8 โ†’ 2.22.0-lite

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 (45) hide show
  1. package/dist/agent_manifest.d.ts +1 -1
  2. package/dist/agent_manifest.d.ts.map +1 -1
  3. package/dist/agent_manifest.js +12 -1
  4. package/dist/agent_manifest.js.map +1 -1
  5. package/dist/companion/autospec.d.ts +58 -0
  6. package/dist/companion/autospec.d.ts.map +1 -0
  7. package/dist/companion/autospec.js +150 -0
  8. package/dist/companion/autospec.js.map +1 -0
  9. package/dist/companion/companion.test.d.ts +2 -0
  10. package/dist/companion/companion.test.d.ts.map +1 -0
  11. package/dist/companion/companion.test.js +215 -0
  12. package/dist/companion/companion.test.js.map +1 -0
  13. package/dist/companion/contract.d.ts +56 -0
  14. package/dist/companion/contract.d.ts.map +1 -0
  15. package/dist/companion/contract.js +209 -0
  16. package/dist/companion/contract.js.map +1 -0
  17. package/dist/companion/doppelganger.d.ts +84 -0
  18. package/dist/companion/doppelganger.d.ts.map +1 -0
  19. package/dist/companion/doppelganger.js +227 -0
  20. package/dist/companion/doppelganger.js.map +1 -0
  21. package/dist/companion/index.d.ts +67 -0
  22. package/dist/companion/index.d.ts.map +1 -0
  23. package/dist/companion/index.js +100 -0
  24. package/dist/companion/index.js.map +1 -0
  25. package/dist/companion/learn_loop.d.ts +55 -0
  26. package/dist/companion/learn_loop.d.ts.map +1 -0
  27. package/dist/companion/learn_loop.js +105 -0
  28. package/dist/companion/learn_loop.js.map +1 -0
  29. package/dist/companion/storyline.d.ts +40 -0
  30. package/dist/companion/storyline.d.ts.map +1 -0
  31. package/dist/companion/storyline.js +95 -0
  32. package/dist/companion/storyline.js.map +1 -0
  33. package/dist/conductor/conductor.test.d.ts +2 -0
  34. package/dist/conductor/conductor.test.d.ts.map +1 -0
  35. package/dist/conductor/conductor.test.js +182 -0
  36. package/dist/conductor/conductor.test.js.map +1 -0
  37. package/dist/conductor/index.d.ts +130 -0
  38. package/dist/conductor/index.d.ts.map +1 -0
  39. package/dist/conductor/index.js +273 -0
  40. package/dist/conductor/index.js.map +1 -0
  41. package/dist/index.d.ts +2 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +11 -0
  44. package/dist/index.js.map +1 -1
  45. package/package.json +2 -5
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=companion.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"companion.test.d.ts","sourceRoot":"","sources":["../../src/companion/companion.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,215 @@
1
+ import { describe, expect, it, beforeEach, afterEach } from "vitest";
2
+ import { mkdtempSync, rmSync, writeFileSync, mkdirSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { contractFor, findContract, formatContract, parseArgSchema, validateArgs, dryRun, stageCommit, applyCommit, predictNext, formatStoryline, computeOutcomeStats, commonMistakes, companionFor, formatCompanion, companionableCoverage, listCompanionable, } from "./index.js";
6
+ import { dropPheromone } from "../atlas/pheromone.js";
7
+ const SAMPLE_VERIFY = { command: "mneme verify-self --score", since: "2.21.4", group: "trust", what: "๐Ÿ”’ Emit ONE NUMBER 0-100 trust score.", when: "CI gate." };
8
+ const SAMPLE_DESTRUCTIVE = { command: "mneme mortuary fire", since: "2.21.2", group: "mortuary", what: "โšฑ๏ธ Force the dead-man switch to fire NOW and generate all encrypted bundles.", when: "Testing." };
9
+ const SAMPLE_NETWORK = { command: "mneme apoptosis federation-push", since: "2.21.0", group: "apoptosis_network", what: "Push the local apoptosis corpus to a peer via HMAC-signed bundle.", when: "Periodic federation." };
10
+ describe("companion (v2.22.0)", () => {
11
+ let repo;
12
+ beforeEach(() => { repo = mkdtempSync(join(tmpdir(), "mneme-companion-")); });
13
+ afterEach(() => { try {
14
+ rmSync(repo, { recursive: true, force: true });
15
+ }
16
+ catch { /* */ } });
17
+ // โ”€โ”€โ”€ CONTRACT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
18
+ describe("contract derivation", () => {
19
+ it("read-only verb gets DEFCON 5", () => {
20
+ const c = contractFor(SAMPLE_VERIFY);
21
+ expect(c.defcon).toBe(5);
22
+ expect(c.readOnly).toBe(true);
23
+ expect(c.idempotency).toBe("read-only");
24
+ });
25
+ it("destructive verb gets DEFCON 1 or 2", () => {
26
+ const c = contractFor(SAMPLE_DESTRUCTIVE);
27
+ expect([1, 2]).toContain(c.defcon);
28
+ expect(c.readOnly).toBe(false);
29
+ });
30
+ it("network verb sets reachesNetwork", () => {
31
+ const c = contractFor(SAMPLE_NETWORK);
32
+ expect(c.reachesNetwork).toBe(true);
33
+ });
34
+ it("findContract resolves real catalog verb", () => {
35
+ const c = findContract("mneme verify-self --score");
36
+ expect(c?.verb).toContain("verify-self");
37
+ });
38
+ it("findContract returns null on unknown", () => {
39
+ expect(findContract("mneme totally-not-a-verb-xyz")).toBeNull();
40
+ });
41
+ it("formatContract includes DEFCON badge + summary", () => {
42
+ const out = formatContract(contractFor(SAMPLE_VERIFY));
43
+ expect(out).toContain("CONTRACT");
44
+ expect(out).toContain("DEFCON");
45
+ expect(out).toContain("read-only");
46
+ });
47
+ });
48
+ // โ”€โ”€โ”€ AUTOSPEC โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
49
+ describe("autospec arg schema", () => {
50
+ it("parseArgSchema picks up required + optional positionals", () => {
51
+ const s = parseArgSchema("mneme some <required> [optional]");
52
+ expect(s.positional).toHaveLength(2);
53
+ expect(s.positional[0].required).toBe(true);
54
+ expect(s.positional[1].required).toBe(false);
55
+ });
56
+ it("variadic positional captured", () => {
57
+ const s = parseArgSchema("mneme do <words...>");
58
+ expect(s.positional[0].variadic).toBe(true);
59
+ });
60
+ it("--flag with value vs without value", () => {
61
+ const s = parseArgSchema("mneme x --vendor <v> --json");
62
+ expect(s.options.vendor?.type).toBe("string");
63
+ expect(s.options.vendor?.required).toBe(true);
64
+ expect(s.options.json?.type).toBe("boolean");
65
+ });
66
+ it("validateArgs rejects missing required positional", () => {
67
+ const s = parseArgSchema("mneme x <required>");
68
+ const r = validateArgs(s, { positional: [] });
69
+ expect(r.ok).toBe(false);
70
+ expect(r.errors[0]?.field).toBe("positional");
71
+ });
72
+ it("validateArgs accepts complete args", () => {
73
+ const s = parseArgSchema("mneme x <name> --vendor <v>");
74
+ const r = validateArgs(s, { positional: ["alice"], options: { vendor: "claude" } });
75
+ expect(r.ok).toBe(true);
76
+ });
77
+ it("validateArgs flags missing required option", () => {
78
+ const s = parseArgSchema("mneme x --vendor <v>");
79
+ const r = validateArgs(s, { positional: [], options: {} });
80
+ expect(r.ok).toBe(false);
81
+ expect(r.errors[0]?.field).toContain("vendor");
82
+ });
83
+ });
84
+ // โ”€โ”€โ”€ DOPPELGANGER โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
85
+ describe("doppelganger (copy-on-write dry-run)", () => {
86
+ it("dryRun returns no fileEffects when the simulator does nothing", async () => {
87
+ mkdirSync(join(repo, ".mneme"), { recursive: true });
88
+ writeFileSync(join(repo, ".mneme/a.json"), "{}");
89
+ const r = await dryRun(repo, () => { });
90
+ expect(r.fileEffects).toEqual([]);
91
+ expect(r.exitCode).toBe(0);
92
+ });
93
+ it("dryRun captures added file in shadow", async () => {
94
+ mkdirSync(join(repo, ".mneme"), { recursive: true });
95
+ const r = await dryRun(repo, (shadow) => {
96
+ writeFileSync(join(shadow, ".mneme/b.json"), "{}");
97
+ });
98
+ expect(r.fileEffects.some((e) => e.kind === "added" && e.path === ".mneme/b.json")).toBe(true);
99
+ });
100
+ it("dryRun captures changed file", async () => {
101
+ mkdirSync(join(repo, ".mneme"), { recursive: true });
102
+ writeFileSync(join(repo, ".mneme/c.json"), "{}");
103
+ const r = await dryRun(repo, (shadow) => {
104
+ writeFileSync(join(shadow, ".mneme/c.json"), "{\"k\":1}");
105
+ });
106
+ expect(r.fileEffects.some((e) => e.kind === "changed" && e.path === ".mneme/c.json")).toBe(true);
107
+ });
108
+ it("dryRun exit code captures verb error", async () => {
109
+ mkdirSync(join(repo, ".mneme"), { recursive: true });
110
+ const r = await dryRun(repo, () => { throw Object.assign(new Error("boom"), { code: 7 }); });
111
+ expect(r.exitCode).toBe(7);
112
+ expect(r.stderrSample).toContain("boom");
113
+ });
114
+ it("known network use โ†’ leakage=possible", async () => {
115
+ mkdirSync(join(repo, ".mneme"), { recursive: true });
116
+ const r = await dryRun(repo, () => { }, { knownNetworkUse: true });
117
+ expect(r.leakage).toBe("possible");
118
+ });
119
+ it("stageCommit + applyCommit round-trip writes files into repo", () => {
120
+ mkdirSync(join(repo, ".mneme"), { recursive: true });
121
+ const stage = stageCommit(repo);
122
+ mkdirSync(join(stage.stagePath, ".mneme"), { recursive: true });
123
+ writeFileSync(join(stage.stagePath, ".mneme/staged.json"), JSON.stringify({ committed: true }));
124
+ applyCommit(stage.stagePath, repo);
125
+ const out = require("node:fs").readFileSync(join(repo, ".mneme/staged.json"), "utf8");
126
+ expect(JSON.parse(out).committed).toBe(true);
127
+ });
128
+ it("stageCommit.rollback removes staged files", () => {
129
+ const stage = stageCommit(repo);
130
+ writeFileSync(join(stage.stagePath, "x"), "");
131
+ stage.rollback();
132
+ expect(require("node:fs").existsSync(stage.stagePath)).toBe(false);
133
+ });
134
+ });
135
+ // โ”€โ”€โ”€ STORYLINE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
136
+ describe("storyline (Markov over pheromone)", () => {
137
+ it("predictNext + predictPrior work after dropping pheromones in sequence", () => {
138
+ dropPheromone(repo, { verb: "mneme earthquake probe" });
139
+ dropPheromone(repo, { verb: "mneme earthquake drift" });
140
+ dropPheromone(repo, { verb: "mneme earthquake probe" });
141
+ dropPheromone(repo, { verb: "mneme earthquake drift" });
142
+ const next = predictNext(repo, "mneme earthquake probe");
143
+ expect(next.length).toBeGreaterThan(0);
144
+ expect(next[0].to).toContain("earthquake drift");
145
+ });
146
+ it("returns [] when no pheromone data yet", () => {
147
+ expect(predictNext(repo, "mneme whatever")).toEqual([]);
148
+ });
149
+ it("formatStoryline handles empty + populated cases", () => {
150
+ expect(formatStoryline("mneme x", [], [])).toContain("STORYLINE");
151
+ expect(formatStoryline("mneme x", [], [])).toContain("no data yet");
152
+ });
153
+ });
154
+ // โ”€โ”€โ”€ LEARN LOOP โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
155
+ describe("learn loop", () => {
156
+ it("computeOutcomeStats counts success vs failure", () => {
157
+ dropPheromone(repo, { verb: "mneme x", outcome: "success" });
158
+ dropPheromone(repo, { verb: "mneme x", outcome: "success" });
159
+ dropPheromone(repo, { verb: "mneme x", outcome: "failure" });
160
+ const s = computeOutcomeStats(repo, "mneme x");
161
+ expect(s.successes).toBe(2);
162
+ expect(s.failures).toBe(1);
163
+ expect(s.successRate).toBeCloseTo(2 / 3, 2);
164
+ });
165
+ it("commonMistakes surfaces recent-failure-cluster when recent rate < 60%", () => {
166
+ for (let i = 0; i < 5; i++)
167
+ dropPheromone(repo, { verb: "mneme y", outcome: "failure" });
168
+ dropPheromone(repo, { verb: "mneme y", outcome: "success" });
169
+ const m = commonMistakes(repo, "mneme y");
170
+ expect(m.length).toBeGreaterThan(0);
171
+ expect(m[0].pattern).toBe("recent-failure-cluster");
172
+ });
173
+ it("commonMistakes returns [] when no failures recorded", () => {
174
+ dropPheromone(repo, { verb: "mneme z", outcome: "success" });
175
+ expect(commonMistakes(repo, "mneme z")).toEqual([]);
176
+ });
177
+ });
178
+ // โ”€โ”€โ”€ COMPOSED COMPANION โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
179
+ describe("companionFor composed view", () => {
180
+ it("returns a Companion for a known catalog verb", () => {
181
+ const c = companionFor("mneme verify-self --score", { repoRoot: repo });
182
+ expect(c?.verb).toContain("verify-self");
183
+ expect(c?.contract.readOnly).toBe(true);
184
+ expect(c?.argSchema).toBeDefined();
185
+ });
186
+ it("hasLiveData=false on fresh repo; true after pheromone hit", () => {
187
+ const a = companionFor("mneme verify-self --score", { repoRoot: repo });
188
+ expect(a?.hasLiveData).toBe(false);
189
+ dropPheromone(repo, { verb: "mneme verify-self --score" });
190
+ const b = companionFor("mneme verify-self --score", { repoRoot: repo });
191
+ expect(b?.hasLiveData).toBe(true);
192
+ });
193
+ it("formatCompanion includes all 5 sections", () => {
194
+ const out = formatCompanion(companionFor("mneme verify-self --score", { repoRoot: repo }));
195
+ expect(out).toContain("CONTRACT");
196
+ expect(out).toContain("ARG SCHEMA");
197
+ expect(out).toContain("STORYLINE");
198
+ expect(out).toContain("OUTCOME STATS");
199
+ expect(out).toContain("COMMON MISTAKES");
200
+ });
201
+ it("listCompanionable returns the whole catalog sorted", () => {
202
+ const list = listCompanionable();
203
+ expect(list.length).toBeGreaterThan(50);
204
+ const sorted = [...list].sort();
205
+ expect(list).toEqual(sorted);
206
+ });
207
+ it("companionableCoverage reports contract + autospec coverage", () => {
208
+ const cov = companionableCoverage(repo);
209
+ expect(cov.total).toBeGreaterThan(50);
210
+ expect(cov.coverageContract).toBeGreaterThan(0.9);
211
+ expect(cov.coverageAutospec).toBeGreaterThan(0.9);
212
+ });
213
+ });
214
+ });
215
+ //# sourceMappingURL=companion.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"companion.test.js","sourceRoot":"","sources":["../../src/companion/companion.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * v2.22.0 โ€” COMPANION ยท CONTRACT.
3
+ *
4
+ * Each verb in the catalog gets a derived contract: preconditions,
5
+ * postconditions, side-effects, idempotency level, DEFCON impact.
6
+ * The contract is auto-derived from the manifest entry first, then
7
+ * optionally overridden by a hand-authored file at
8
+ * `packages/core/src/companion/overrides/<verb-slug>.json`.
9
+ *
10
+ * Why this lives apart from `agent_manifest.ts`:
11
+ * - manifest is the single-line "what + when" surface AI agents
12
+ * read by default;
13
+ * - contract is the deep structured form AI agents read BEFORE
14
+ * invoking a verb the first time. They serve different audiences.
15
+ */
16
+ import { type ManifestCommand } from "../agent_manifest.js";
17
+ export type DefconLevel = 1 | 2 | 3 | 4 | 5;
18
+ export type IdempotencyLevel = "read-only" | "idempotent" | "additive" | "destructive";
19
+ export interface VerbContract {
20
+ v: 1;
21
+ verb: string;
22
+ since: string;
23
+ group: string;
24
+ /** Plain-English summary (= manifest `what`). */
25
+ summary: string;
26
+ /** When to invoke (= manifest `when`). */
27
+ invokeWhen: string;
28
+ /** Preconditions that MUST hold or invocation should be refused. */
29
+ preconditions: string[];
30
+ /** Outcome guarantees. */
31
+ postconditions: string[];
32
+ /** Files/state Mneme writes when this verb succeeds. */
33
+ sideEffects: string[];
34
+ /** Repeatable without harm? */
35
+ idempotency: IdempotencyLevel;
36
+ /** Impact tier โ€” drives doppelganger requirement. */
37
+ defcon: DefconLevel;
38
+ /** Whether the verb is read-only (no fs/network mutation). */
39
+ readOnly: boolean;
40
+ /** Whether the verb consults an external network endpoint. */
41
+ reachesNetwork: boolean;
42
+ /** Cross-verb storyline hints โ€” common predecessors / successors. */
43
+ comesAfter: string[];
44
+ comesBefore: string[];
45
+ /** Where the contract came from. */
46
+ source: "auto" | "override" | "hybrid";
47
+ }
48
+ /** Derive (and override if a file exists) the contract for a single
49
+ * catalog entry. Pure function โ€” no disk writes. */
50
+ export declare function contractFor(entry: ManifestCommand): VerbContract;
51
+ /** Return contracts for every catalog verb. Used by the conductor's
52
+ * planner + as the canonical companion seed. */
53
+ export declare function allContracts(catalog?: ManifestCommand[]): VerbContract[];
54
+ export declare function findContract(verb: string, catalog?: ManifestCommand[]): VerbContract | null;
55
+ export declare function formatContract(c: VerbContract): string;
56
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/companion/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEnF,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAO5C,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,aAAa,CAAC;AAEvF,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,CAAC,CAAC;IACL,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,0BAA0B;IAC1B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,wDAAwD;IACxD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,+BAA+B;IAC/B,WAAW,EAAE,gBAAgB,CAAC;IAC9B,qDAAqD;IACrD,MAAM,EAAE,WAAW,CAAC;IACpB,8DAA8D;IAC9D,QAAQ,EAAE,OAAO,CAAC;IAClB,8DAA8D;IAC9D,cAAc,EAAE,OAAO,CAAC;IACxB,qEAAqE;IACrE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,oCAAoC;IACpC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC;CACxC;AA4GD;qDACqD;AACrD,wBAAgB,WAAW,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CAsBhE;AAED;iDACiD;AACjD,wBAAgB,YAAY,CAAC,OAAO,GAAE,eAAe,EAA0B,GAAG,YAAY,EAAE,CAE/F;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAe,EAA0B,GAAG,YAAY,GAAG,IAAI,CAQlH;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAwBtD"}
@@ -0,0 +1,209 @@
1
+ /**
2
+ * v2.22.0 โ€” COMPANION ยท CONTRACT.
3
+ *
4
+ * Each verb in the catalog gets a derived contract: preconditions,
5
+ * postconditions, side-effects, idempotency level, DEFCON impact.
6
+ * The contract is auto-derived from the manifest entry first, then
7
+ * optionally overridden by a hand-authored file at
8
+ * `packages/core/src/companion/overrides/<verb-slug>.json`.
9
+ *
10
+ * Why this lives apart from `agent_manifest.ts`:
11
+ * - manifest is the single-line "what + when" surface AI agents
12
+ * read by default;
13
+ * - contract is the deep structured form AI agents read BEFORE
14
+ * invoking a verb the first time. They serve different audiences.
15
+ */
16
+ import { existsSync, readFileSync } from "node:fs";
17
+ import { join, dirname } from "node:path";
18
+ import { fileURLToPath } from "node:url";
19
+ import { MNEME_COMMAND_CATALOG } from "../agent_manifest.js";
20
+ // โ”€โ”€โ”€ HEURISTIC AUTO-DERIVATION โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
21
+ // Hints are matched as whole words in the description and as substrings
22
+ // inside the command verb. Terms here MUST be unambiguous โ€” e.g. "abort"
23
+ // + "rollback" appear in many neutral descriptions ("exit on ABORT
24
+ // band", "rollback safety"), so we drop them from destructive list.
25
+ const READ_HINTS = ["list", "show", "print", "verify", "audit", "diagnose", "probe", "scan", "report", "status", "view", "stats", "leaderboard", "atlas", "tags", "hot", "bloom", "route", "rights", "doctor"];
26
+ const DESTRUCTIVE_HINTS = ["delete", "remove", "uninstall", "purge", "wipe", "nuke", "destroy", "revoke"];
27
+ const IRREVERSIBLE_HINTS = ["uninstall", "publish to npm", "deploy", "fire", "cull"];
28
+ const NETWORK_HINTS = ["push", "fetch", "sync", "transmit", "broadcast", "federation"];
29
+ /** Match a hint as a whole word in the command-verb portion (heavier
30
+ * weight) or in the description (lighter weight). Avoids false
31
+ * positives like "ABORT" inside a trust-band enum string. */
32
+ function hintHits(entry, hints) {
33
+ // Command-name is the strongest signal โ€” match anywhere in the verb token.
34
+ const cmd = entry.command.toLowerCase();
35
+ for (const h of hints)
36
+ if (cmd.includes(h))
37
+ return true;
38
+ // Description: word-boundary only, to skip enum-value spelunking.
39
+ const desc = entry.what.toLowerCase();
40
+ for (const h of hints) {
41
+ const re = new RegExp(`\\b${h.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&")}\\b`);
42
+ if (re.test(desc))
43
+ return true;
44
+ }
45
+ return false;
46
+ }
47
+ function detectReadOnly(entry) {
48
+ const isRead = hintHits(entry, READ_HINTS);
49
+ const isDestructive = hintHits(entry, DESTRUCTIVE_HINTS);
50
+ return isRead && !isDestructive;
51
+ }
52
+ function detectNetwork(entry) {
53
+ const haystack = `${entry.command} ${entry.what}`.toLowerCase();
54
+ // some verbs say "no network" explicitly โ€” respect that
55
+ if (/(no network|offline|pure local|no\s+llm)/.test(haystack))
56
+ return false;
57
+ return hintHits(entry, NETWORK_HINTS);
58
+ }
59
+ function detectDefcon(entry) {
60
+ if (hintHits(entry, IRREVERSIBLE_HINTS))
61
+ return 1;
62
+ if (hintHits(entry, DESTRUCTIVE_HINTS))
63
+ return 2;
64
+ if (detectNetwork(entry))
65
+ return 3;
66
+ if (detectReadOnly(entry))
67
+ return 5;
68
+ return 4; // local-mutating default
69
+ }
70
+ function detectIdempotency(entry) {
71
+ if (detectReadOnly(entry))
72
+ return "read-only";
73
+ const haystack = `${entry.command} ${entry.what}`.toLowerCase();
74
+ if (DESTRUCTIVE_HINTS.some((h) => haystack.includes(h)))
75
+ return "destructive";
76
+ if (/(append|record|log|drop\s+pheromone|capture|inscribe)/.test(haystack))
77
+ return "additive";
78
+ return "idempotent";
79
+ }
80
+ function detectSideEffects(entry) {
81
+ const out = [];
82
+ const m = entry.what.match(/`(\.mneme\/[^`]+|node_modules\/[^`]+|\$HOME[^`]+|~\/\.mneme[^`]+)`/g);
83
+ if (m)
84
+ for (const path of m)
85
+ out.push(`writes ${path.replace(/`/g, "")}`);
86
+ if (detectNetwork(entry))
87
+ out.push("reaches an external network endpoint");
88
+ if (out.length === 0 && !detectReadOnly(entry))
89
+ out.push("mutates local state (unspecified โ€” improve the manifest entry)");
90
+ return out;
91
+ }
92
+ function detectPreconditions(entry) {
93
+ const out = [];
94
+ // very simple rule-based โ€” works for the obvious cases
95
+ const w = entry.what.toLowerCase();
96
+ if (/baseline|probes/.test(w))
97
+ out.push("โ‰ฅ5 probes recorded for the target vendor");
98
+ if (/key|hmac|sig/.test(w))
99
+ out.push("install HMAC key exists at .mneme/<feature>/*.key");
100
+ if (/inbox|pulse|daemon/.test(w))
101
+ out.push("Mneme daemon is reachable OR the verb falls back to disk read");
102
+ if (out.length === 0)
103
+ out.push("none beyond installed Mneme + readable repo root");
104
+ return out;
105
+ }
106
+ function detectPostconditions(entry) {
107
+ if (detectReadOnly(entry))
108
+ return ["returns stdout payload; no state change"];
109
+ return ["records a side-effect listed above OR returns a non-zero exit code"];
110
+ }
111
+ // โ”€โ”€โ”€ OVERRIDE LOADING โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
112
+ function overrideDir() {
113
+ try {
114
+ const here = dirname(fileURLToPath(import.meta.url));
115
+ return join(here, "overrides");
116
+ }
117
+ catch {
118
+ return ""; // no overrides reachable
119
+ }
120
+ }
121
+ function slugify(command) {
122
+ return command.replace(/^mneme\s+/, "").replace(/[\s<>\[\]|'"]+/g, "_").toLowerCase();
123
+ }
124
+ function loadOverride(verb) {
125
+ const dir = overrideDir();
126
+ if (!dir)
127
+ return null;
128
+ const p = join(dir, `${slugify(verb)}.json`);
129
+ if (!existsSync(p))
130
+ return null;
131
+ try {
132
+ return JSON.parse(readFileSync(p, "utf8"));
133
+ }
134
+ catch {
135
+ return null;
136
+ }
137
+ }
138
+ // โ”€โ”€โ”€ PUBLIC API โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
139
+ /** Derive (and override if a file exists) the contract for a single
140
+ * catalog entry. Pure function โ€” no disk writes. */
141
+ export function contractFor(entry) {
142
+ const auto = {
143
+ v: 1,
144
+ verb: entry.command,
145
+ since: entry.since,
146
+ group: entry.group,
147
+ summary: entry.what,
148
+ invokeWhen: entry.when,
149
+ preconditions: detectPreconditions(entry),
150
+ postconditions: detectPostconditions(entry),
151
+ sideEffects: detectSideEffects(entry),
152
+ idempotency: detectIdempotency(entry),
153
+ defcon: detectDefcon(entry),
154
+ readOnly: detectReadOnly(entry),
155
+ reachesNetwork: detectNetwork(entry),
156
+ comesAfter: [],
157
+ comesBefore: [],
158
+ source: "auto",
159
+ };
160
+ const override = loadOverride(entry.command);
161
+ if (!override)
162
+ return auto;
163
+ return { ...auto, ...override, source: "hybrid" };
164
+ }
165
+ /** Return contracts for every catalog verb. Used by the conductor's
166
+ * planner + as the canonical companion seed. */
167
+ export function allContracts(catalog = MNEME_COMMAND_CATALOG) {
168
+ return catalog.map(contractFor);
169
+ }
170
+ export function findContract(verb, catalog = MNEME_COMMAND_CATALOG) {
171
+ const stems = [verb, "mneme " + verb, verb.replace(/^mneme\s+/, "")];
172
+ for (const entry of catalog) {
173
+ if (stems.includes(entry.command))
174
+ return contractFor(entry);
175
+ // prefix match โ€” `mneme earthquake` matches `mneme earthquake drift`
176
+ if (entry.command.startsWith(verb) || entry.command.startsWith(stems[1]))
177
+ return contractFor(entry);
178
+ }
179
+ return null;
180
+ }
181
+ export function formatContract(c) {
182
+ const lines = [];
183
+ const defconBadge = c.defcon === 5 ? "๐ŸŸข 5 read-only"
184
+ : c.defcon === 4 ? "๐ŸŸก 4 mutates local state"
185
+ : c.defcon === 3 ? "๐ŸŸ  3 reaches network"
186
+ : c.defcon === 2 ? "๐Ÿ”ด 2 destructive (recoverable)"
187
+ : "๐Ÿ’€ 1 irreversible";
188
+ lines.push(`๐Ÿ“œ CONTRACT โ€” ${c.verb}`);
189
+ lines.push("");
190
+ lines.push(` Since: ${c.since} ยท group: ${c.group} ยท source: ${c.source}`);
191
+ lines.push(` DEFCON: ${defconBadge}`);
192
+ lines.push(` Idempotency: ${c.idempotency}`);
193
+ lines.push(` Read-only: ${c.readOnly ? "yes" : "no"} ยท Network: ${c.reachesNetwork ? "yes" : "no"}`);
194
+ lines.push("");
195
+ lines.push(` Summary: ${c.summary}`);
196
+ lines.push(` Invoke when: ${c.invokeWhen}`);
197
+ lines.push("");
198
+ lines.push(` Preconditions:`);
199
+ for (const x of c.preconditions)
200
+ lines.push(` - ${x}`);
201
+ lines.push(` Postconditions:`);
202
+ for (const x of c.postconditions)
203
+ lines.push(` - ${x}`);
204
+ lines.push(` Side-effects:`);
205
+ for (const x of c.sideEffects)
206
+ lines.push(` - ${x}`);
207
+ return lines.join("\n");
208
+ }
209
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/companion/contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * v2.22.0 โ€” COMPANION ยท DOPPELGANGER.
3
+ *
4
+ * Copy-on-write fs overlay that runs a verb's effects in a SHADOW
5
+ * directory and returns the diff. AI agent sees EXACT changes before
6
+ * committing.
7
+ *
8
+ * Implementation strategy:
9
+ * 1. Caller hands us a `repoRoot` + a function that simulates the
10
+ * verb (no real I/O).
11
+ * 2. We seed the shadow by copying repo state lazily (overlay style
12
+ * โ€” only files the verb touches are materialised).
13
+ * 3. We invoke the verb against the shadow via dependency injection
14
+ * (`fs` proxy + `process.exit` shim).
15
+ * 4. We compute the diff: files added / changed / removed; exit
16
+ * code; would-be network calls.
17
+ *
18
+ * Limitations (honest):
19
+ * - Verbs that call native C++ code (sharp, sqlite native) bypass
20
+ * the proxy. We catch *most* of them via the existing DLL-extract
21
+ * mechanism but cannot guarantee 100 % coverage. Doppelganger
22
+ * reports a `leakage: "possible"` flag for verbs known to use
23
+ * native modules.
24
+ * - Network I/O is currently *blocked* in shadow mode (any outbound
25
+ * request returns a "would-fetch" record instead of executing).
26
+ * This means doppelganger preview for network-bound verbs is
27
+ * approximate: we can predict "would call URL X" but not the
28
+ * response.
29
+ */
30
+ export interface FileEffect {
31
+ path: string;
32
+ kind: "added" | "changed" | "removed";
33
+ beforeSha?: string;
34
+ afterSha?: string;
35
+ beforeBytes?: number;
36
+ afterBytes?: number;
37
+ }
38
+ export interface DoppelgangerResult {
39
+ /** What the verb would do if executed for real. */
40
+ fileEffects: FileEffect[];
41
+ /** Process exit code the verb would return. */
42
+ exitCode: number;
43
+ /** Network endpoints the verb would have called (URLs, not responses). */
44
+ wouldFetch: string[];
45
+ /** Stdout the verb would have written. */
46
+ stdoutSample: string;
47
+ /** Stderr the verb would have written. */
48
+ stderrSample: string;
49
+ /** Honest signal: parts of the verb that escaped the doppelganger. */
50
+ leakage: "none" | "possible" | "definite";
51
+ leakageReason?: string;
52
+ }
53
+ export interface DoppelgangerOptions {
54
+ /** Whether the verb is known to call native code (sharp, sqlite). */
55
+ knownNativeUse?: boolean;
56
+ /** Whether the verb reaches network. */
57
+ knownNetworkUse?: boolean;
58
+ }
59
+ /** Run `verbFn` in a shadow copy of `repoRoot` and return the diff.
60
+ * `verbFn` receives the shadow path; it should perform its work
61
+ * AGAINST THAT PATH (the caller wires its own dependency injection;
62
+ * see conductor.executePlan for the canonical usage). */
63
+ export declare function dryRun<T = void>(repoRoot: string, verbFn: (shadowRoot: string) => Promise<T> | T, opts?: DoppelgangerOptions): Promise<DoppelgangerResult & {
64
+ result?: T;
65
+ }>;
66
+ export interface CommitOptions {
67
+ /** Where to stage; defaults to a sibling temp dir. */
68
+ stageRoot?: string;
69
+ }
70
+ /** Two-phase commit primitive used by the conductor: stage to a temp
71
+ * dir, atomically move into place, or rollback by deleting the stage.
72
+ * Returns the staged path so the conductor can either rename or
73
+ * remove. */
74
+ export declare function stageCommit(repoRoot: string, opts?: CommitOptions): {
75
+ stagePath: string;
76
+ rollback: () => void;
77
+ };
78
+ /** Atomically apply staged files into `repoRoot`. Uses `rename` when
79
+ * same filesystem; falls back to `cp -r + rm` otherwise. Caller-side
80
+ * contract: every file in `stagePath` has been verified by the
81
+ * doppelganger. */
82
+ export declare function applyCommit(stagePath: string, repoRoot: string): void;
83
+ export declare function formatDoppelganger(r: DoppelgangerResult): string;
84
+ //# sourceMappingURL=doppelganger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doppelganger.d.ts","sourceRoot":"","sources":["../../src/companion/doppelganger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAOH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA6CD,MAAM,WAAW,mBAAmB;IAClC,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wCAAwC;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;0DAG0D;AAC1D,wBAAsB,MAAM,CAAC,CAAC,GAAG,IAAI,EACnC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAC9C,IAAI,GAAE,mBAAwB,GAC7B,OAAO,CAAC,kBAAkB,GAAG;IAAE,MAAM,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC,CAiC9C;AAED,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;cAGc;AACd,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;CAAE,CAOnH;AAED;;;oBAGoB;AACpB,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAwBrE;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAsBhE"}