@mnemom/mnemom 0.17.33 → 0.17.34-next.2

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 (236) hide show
  1. package/dist/base-url-proxy.mjs +18 -4
  2. package/dist/commands/agent-config.js +5 -1
  3. package/dist/commands/agent-doctor.d.ts +9 -0
  4. package/dist/commands/agent-doctor.js +4 -0
  5. package/dist/commands/agent-session.d.ts +1 -2
  6. package/dist/commands/agent-session.js +1 -2
  7. package/dist/commands/agent-setup.d.ts +6 -0
  8. package/dist/commands/agent-setup.js +12 -1
  9. package/dist/commands/agent-share-render.d.ts +1 -1
  10. package/dist/commands/agent-share-render.js +1 -1
  11. package/dist/commands/agent.d.ts +26 -0
  12. package/dist/commands/agent.js +228 -53
  13. package/dist/commands/durable-doctor.d.ts +50 -0
  14. package/dist/commands/durable-doctor.js +186 -0
  15. package/dist/commands/durable-lock.d.ts +254 -0
  16. package/dist/commands/durable-lock.js +595 -0
  17. package/dist/commands/durable-sessions.d.ts +87 -0
  18. package/dist/commands/durable-sessions.js +303 -0
  19. package/dist/commands/durable-verbs.d.ts +116 -0
  20. package/dist/commands/durable-verbs.js +393 -0
  21. package/dist/commands/protection.js +1 -1
  22. package/dist/commands/scan.d.ts +97 -0
  23. package/dist/commands/scan.js +238 -0
  24. package/dist/durable/flock.d.ts +26 -0
  25. package/dist/durable/flock.js +80 -0
  26. package/dist/durable/launch-spec.d.ts +7 -1
  27. package/dist/durable/launch-spec.js +10 -3
  28. package/dist/durable/seat-proxy-entry.d.ts +11 -0
  29. package/dist/durable/seat-proxy-entry.js +25 -0
  30. package/dist/durable/seat-proxy.d.ts +107 -0
  31. package/dist/durable/seat-proxy.js +599 -0
  32. package/dist/durable/seat-socket.d.ts +46 -0
  33. package/dist/durable/seat-socket.js +179 -0
  34. package/dist/durable/seat-spec-validator.d.ts +28 -0
  35. package/dist/durable/seat-spec-validator.js +59 -0
  36. package/dist/durable/test-mode.mjs +81 -0
  37. package/dist/durable/turn-chain.d.ts +55 -0
  38. package/dist/durable/turn-chain.js +178 -0
  39. package/dist/host/auto-continue.d.ts +67 -0
  40. package/dist/host/auto-continue.js +118 -0
  41. package/dist/host/bootid.d.ts +13 -0
  42. package/dist/host/bootid.js +41 -0
  43. package/dist/host/client.d.ts +123 -0
  44. package/dist/host/client.js +171 -0
  45. package/dist/host/commands.d.ts +2 -0
  46. package/dist/host/commands.js +122 -0
  47. package/dist/host/control.d.ts +33 -0
  48. package/dist/host/control.js +144 -0
  49. package/dist/host/daemon.d.ts +217 -0
  50. package/dist/host/daemon.js +606 -0
  51. package/dist/host/gate.d.ts +46 -0
  52. package/dist/host/gate.js +82 -0
  53. package/dist/host/grant.d.ts +24 -0
  54. package/dist/host/grant.js +24 -0
  55. package/dist/host/instance.d.ts +35 -0
  56. package/dist/host/instance.js +62 -0
  57. package/dist/host/integrity.d.ts +35 -0
  58. package/dist/host/integrity.js +115 -0
  59. package/dist/host/launchd.d.ts +16 -0
  60. package/dist/host/launchd.js +45 -0
  61. package/dist/host/lock.d.ts +20 -0
  62. package/dist/host/lock.js +63 -0
  63. package/dist/host/owner.d.ts +55 -0
  64. package/dist/host/owner.js +121 -0
  65. package/dist/host/plist.d.ts +16 -0
  66. package/dist/host/plist.js +85 -0
  67. package/dist/host/procs.d.ts +27 -0
  68. package/dist/host/procs.js +105 -0
  69. package/dist/host/run.d.ts +66 -0
  70. package/dist/host/run.js +314 -0
  71. package/dist/host/runtime.d.ts +8 -0
  72. package/dist/host/runtime.js +22 -0
  73. package/dist/host/s1-names.d.ts +22 -0
  74. package/dist/host/s1-names.js +21 -0
  75. package/dist/host/seat-credential.d.ts +27 -0
  76. package/dist/host/seat-credential.js +41 -0
  77. package/dist/host/seat-launch-main.d.ts +1 -0
  78. package/dist/host/seat-launch-main.js +59 -0
  79. package/dist/host/seat-launch.d.ts +116 -0
  80. package/dist/host/seat-launch.js +302 -0
  81. package/dist/host/seat.d.ts +48 -0
  82. package/dist/host/seat.js +149 -0
  83. package/dist/host/state.d.ts +33 -0
  84. package/dist/host/state.js +117 -0
  85. package/dist/host/status.d.ts +101 -0
  86. package/dist/host/status.js +307 -0
  87. package/dist/host/tmux.d.ts +56 -0
  88. package/dist/host/tmux.js +182 -0
  89. package/dist/host/transcript.d.ts +30 -0
  90. package/dist/host/transcript.js +130 -0
  91. package/dist/host/verbs.d.ts +50 -0
  92. package/dist/host/verbs.js +271 -0
  93. package/dist/index.d.ts +8 -6
  94. package/dist/index.js +232 -35
  95. package/dist/lib/agent.d.ts +8 -26
  96. package/dist/lib/agent.js +11 -26
  97. package/dist/lib/api.d.ts +13 -0
  98. package/dist/lib/api.js +8 -0
  99. package/dist/lib/claude-plugin.d.ts +11 -2
  100. package/dist/lib/claude-plugin.js +10 -1
  101. package/dist/lib/durable/api.d.ts +136 -0
  102. package/dist/lib/durable/api.js +220 -0
  103. package/dist/lib/durable/codes.d.ts +8 -0
  104. package/dist/lib/durable/codes.js +2 -0
  105. package/dist/lib/durable/first-turn.d.ts +50 -0
  106. package/dist/lib/durable/first-turn.js +102 -0
  107. package/dist/lib/durable/gate.d.ts +48 -0
  108. package/dist/lib/durable/gate.js +122 -0
  109. package/dist/lib/durable/handover.d.ts +101 -0
  110. package/dist/lib/durable/handover.js +175 -0
  111. package/dist/lib/durable/launch.d.ts +182 -0
  112. package/dist/lib/durable/launch.js +443 -0
  113. package/dist/lib/durable/launching.d.ts +15 -0
  114. package/dist/lib/durable/launching.js +70 -0
  115. package/dist/lib/durable/live.d.ts +194 -0
  116. package/dist/lib/durable/live.js +635 -0
  117. package/dist/lib/durable/refusal.d.ts +57 -0
  118. package/dist/lib/durable/refusal.js +78 -0
  119. package/dist/lib/durable/view.d.ts +83 -0
  120. package/dist/lib/durable/view.js +244 -0
  121. package/dist/lib/experimental.d.ts +0 -9
  122. package/dist/lib/experimental.js +18 -17
  123. package/dist/lib/launcher-config.d.ts +7 -0
  124. package/dist/lib/launcher-config.js +21 -0
  125. package/dist/lib/scan/caps.d.ts +35 -0
  126. package/dist/lib/scan/caps.js +67 -0
  127. package/dist/lib/scan/credential.d.ts +37 -0
  128. package/dist/lib/scan/credential.js +104 -0
  129. package/dist/lib/scan/failure.d.ts +10 -0
  130. package/dist/lib/scan/failure.js +43 -0
  131. package/dist/lib/scan/pr-source.d.ts +57 -0
  132. package/dist/lib/scan/pr-source.js +130 -0
  133. package/dist/lib/scan/record.d.ts +49 -0
  134. package/dist/lib/scan/record.js +85 -0
  135. package/dist/lib/scan/report-email.d.ts +92 -0
  136. package/dist/lib/scan/report-email.js +144 -0
  137. package/dist/lib/scan/report.d.ts +13 -0
  138. package/dist/lib/scan/report.js +30 -0
  139. package/dist/lib/scan/scan.d.ts +64 -0
  140. package/dist/lib/scan/scan.js +182 -0
  141. package/dist/lib/scan/share.d.ts +38 -0
  142. package/dist/lib/scan/share.js +47 -0
  143. package/dist/lib/scan/spend/ai-tool-detect.d.ts +6 -0
  144. package/dist/lib/scan/spend/ai-tool-detect.js +18 -0
  145. package/dist/lib/scan/spend/anthropic-usage.d.ts +57 -0
  146. package/dist/lib/scan/spend/anthropic-usage.js +244 -0
  147. package/dist/lib/scan/spend/cost-corpus.v1.d.ts +56 -0
  148. package/dist/lib/scan/spend/cost-corpus.v1.js +64 -0
  149. package/dist/lib/scan/spend/prices.d.ts +33 -0
  150. package/dist/lib/scan/spend/prices.js +57 -0
  151. package/dist/lib/scan/spend/spend-estimate.d.ts +30 -0
  152. package/dist/lib/scan/spend/spend-estimate.js +70 -0
  153. package/dist/lib/scan/spend/spend-tiers.d.ts +25 -0
  154. package/dist/lib/scan/spend/spend-tiers.js +42 -0
  155. package/dist/lib/scan/spend/token-rate.d.ts +30 -0
  156. package/dist/lib/scan/spend/token-rate.js +54 -0
  157. package/dist/lib/session-key.d.ts +41 -0
  158. package/dist/lib/session-key.js +124 -0
  159. package/dist/lib/subscription-login.d.ts +15 -0
  160. package/dist/lib/subscription-login.js +28 -1
  161. package/dist/rc-key-401.mjs +75 -0
  162. package/dist/rc-proxy.mjs +221 -25
  163. package/dist/vendor/durable-contract/index.js +240 -18
  164. package/dist/vendor/shared/durable-contract/admission.d.ts +240 -0
  165. package/dist/vendor/shared/durable-contract/admission.js +533 -0
  166. package/dist/vendor/shared/durable-contract/arm.d.ts +51 -0
  167. package/dist/vendor/shared/durable-contract/arm.js +133 -0
  168. package/dist/vendor/shared/durable-contract/canonical.d.ts +29 -0
  169. package/dist/vendor/shared/durable-contract/canonical.js +98 -0
  170. package/dist/vendor/shared/durable-contract/cell-id.d.ts +22 -0
  171. package/dist/vendor/shared/durable-contract/cell-id.js +38 -0
  172. package/dist/vendor/shared/durable-contract/cli-output.d.ts +342 -0
  173. package/dist/vendor/shared/durable-contract/cli-output.js +201 -0
  174. package/dist/vendor/shared/durable-contract/cli-surface.d.ts +119 -0
  175. package/dist/vendor/shared/durable-contract/cli-surface.js +270 -0
  176. package/dist/vendor/shared/durable-contract/codes.d.ts +537 -0
  177. package/dist/vendor/shared/durable-contract/codes.js +475 -0
  178. package/dist/vendor/shared/durable-contract/constants.d.ts +153 -0
  179. package/dist/vendor/shared/durable-contract/constants.js +179 -0
  180. package/dist/vendor/shared/durable-contract/doors.d.ts +119 -0
  181. package/dist/vendor/shared/durable-contract/doors.js +249 -0
  182. package/dist/vendor/shared/durable-contract/envelope.d.ts +103 -0
  183. package/dist/vendor/shared/durable-contract/envelope.js +317 -0
  184. package/dist/vendor/shared/durable-contract/events.d.ts +147 -0
  185. package/dist/vendor/shared/durable-contract/events.js +630 -0
  186. package/dist/vendor/shared/durable-contract/executor-state.d.ts +41 -0
  187. package/dist/vendor/shared/durable-contract/executor-state.js +32 -0
  188. package/dist/vendor/shared/durable-contract/fixlines.d.ts +318 -0
  189. package/dist/vendor/shared/durable-contract/fixlines.js +483 -0
  190. package/dist/vendor/shared/durable-contract/freeze-record.d.ts +787 -0
  191. package/dist/vendor/shared/durable-contract/freeze-record.js +361 -0
  192. package/dist/vendor/shared/durable-contract/index.d.ts +36 -0
  193. package/dist/vendor/shared/durable-contract/index.js +37 -0
  194. package/dist/vendor/shared/durable-contract/journal-approvals.d.ts +29 -0
  195. package/dist/vendor/shared/durable-contract/journal-approvals.js +60 -0
  196. package/dist/vendor/shared/durable-contract/keys.d.ts +24 -0
  197. package/dist/vendor/shared/durable-contract/keys.js +66 -0
  198. package/dist/vendor/shared/durable-contract/lock.d.ts +128 -0
  199. package/dist/vendor/shared/durable-contract/lock.js +151 -0
  200. package/dist/vendor/shared/durable-contract/names.d.ts +25 -0
  201. package/dist/vendor/shared/durable-contract/names.js +78 -0
  202. package/dist/vendor/shared/durable-contract/owner-verbs.d.ts +175 -0
  203. package/dist/vendor/shared/durable-contract/owner-verbs.js +403 -0
  204. package/dist/vendor/shared/durable-contract/paths.d.ts +23 -0
  205. package/dist/vendor/shared/durable-contract/paths.js +35 -0
  206. package/dist/vendor/shared/durable-contract/pure-fn.d.ts +48 -0
  207. package/dist/vendor/shared/durable-contract/pure-fn.js +89 -0
  208. package/dist/vendor/shared/durable-contract/routes.d.ts +205 -0
  209. package/dist/vendor/shared/durable-contract/routes.js +315 -0
  210. package/dist/vendor/shared/durable-contract/schema.d.ts +126 -0
  211. package/dist/vendor/shared/durable-contract/schema.js +441 -0
  212. package/dist/vendor/shared/durable-contract/seal.d.ts +54 -0
  213. package/dist/vendor/shared/durable-contract/seal.js +99 -0
  214. package/dist/vendor/shared/durable-contract/secret-scope.d.ts +28 -0
  215. package/dist/vendor/shared/durable-contract/secret-scope.js +76 -0
  216. package/dist/vendor/shared/durable-contract/session-id.d.ts +21 -0
  217. package/dist/vendor/shared/durable-contract/session-id.js +58 -0
  218. package/dist/vendor/shared/durable-contract/spec.d.ts +162 -0
  219. package/dist/vendor/shared/durable-contract/spec.js +286 -0
  220. package/dist/vendor/shared/durable-contract/states.d.ts +96 -0
  221. package/dist/vendor/shared/durable-contract/states.js +218 -0
  222. package/dist/vendor/shared/durable-contract/telemetry.d.ts +94 -0
  223. package/dist/vendor/shared/durable-contract/telemetry.js +180 -0
  224. package/dist/vendor/shared/durable-contract/test-mode.d.ts +62 -0
  225. package/dist/vendor/shared/durable-contract/test-mode.js +140 -0
  226. package/dist/vendor/shared/durable-contract/turn.d.ts +57 -0
  227. package/dist/vendor/shared/durable-contract/turn.js +81 -0
  228. package/dist/vendor/shared/durable-contract/vectors.d.ts +191 -0
  229. package/dist/vendor/shared/durable-contract/vectors.js +208 -0
  230. package/package.json +4 -3
  231. package/plugins/integrity-manifest.json +35 -0
  232. package/plugins/mnemom/hooks/hooks.json +15 -1
  233. package/plugins/mnemom/hooks/register.tsx +60 -2
  234. package/plugins/mnemom/hooks/seat-hello.mjs +116 -0
  235. package/dist/commands/agent-implicit-notice.d.ts +0 -31
  236. package/dist/commands/agent-implicit-notice.js +0 -73
@@ -0,0 +1,133 @@
1
+ // GENERATED from shared/durable-contract/src/arm.ts by cli/scripts/sync-durable-contract.mjs; do not edit.
2
+ /**
3
+ * The x-mnemom-durable-arm header grammar (design §4 I2; BACKBONE G1/C3; C06-R23, C13).
4
+ *
5
+ * <ver>;hold=on|off;fence=on|off;posture=attended|unattended|none
6
+ *
7
+ * posture=none (wave-0 fix ruling 22.1) is the arm of an admit_unchained answer (a count_tokens
8
+ * with no chain): valid only on a count_tokens response (armValidFor); on any other path it is
9
+ * invalid and drops, and armForwards (no path) never forwards it.
10
+ *
11
+ * Frozen strictness (C13 OQ, "anchored exact grammar, fixed key order, lowercase, single header
12
+ * line"): ver is the literal `1`; keys in exactly this order; lowercase; no whitespace anywhere;
13
+ * no trailing `;`. A value carrying `,` (Node's join of duplicate header lines) is unparseable, so
14
+ * duplicate lines (conflicting or not) drop the response, as do a missing header and a trailer.
15
+ * The same bytes are the body of GET /internal/durable/arm.
16
+ */
17
+ import { NOFENCE_ADMIT_VALUE } from "./constants.js";
18
+ import { isCountTokensPath } from "./admission.js";
19
+ export const ARM_HEADER = "x-mnemom-durable-arm";
20
+ export const ARM_VERSION = "1";
21
+ export const ARM_ROUTE = "/internal/durable/arm";
22
+ export const ARM_RE = /^1;hold=(on|off);fence=(on|off);posture=(attended|unattended|none)$/;
23
+ export function formatArm(a) {
24
+ return `${ARM_VERSION};hold=${a.hold};fence=${a.fence};posture=${a.posture}`;
25
+ }
26
+ /** Parse one header value; null when absent or not in the exact grammar. */
27
+ export function parseArm(value) {
28
+ if (typeof value !== "string")
29
+ return null;
30
+ const m = ARM_RE.exec(value);
31
+ if (!m)
32
+ return null;
33
+ return {
34
+ hold: m[1],
35
+ fence: m[2],
36
+ posture: m[3],
37
+ };
38
+ }
39
+ /**
40
+ * The executor/proxy decision (C3, C13): forward only a parseable header, and never an unattended
41
+ * one without hold=on and fence=on. In M1 hold is always off, so every unattended answer drops.
42
+ */
43
+ export function armForwards(value) {
44
+ const a = parseArm(value);
45
+ if (a === null || a.posture === "none")
46
+ return false;
47
+ return a.posture === "attended" || (a.hold === "on" && a.fence === "on");
48
+ }
49
+ /** The arm of a response on `path` (no query string), or null when absent, unparseable, or posture=none off count_tokens. */
50
+ export function armValidFor(path, value) {
51
+ const a = parseArm(value);
52
+ if (a === null || (a.posture === "none" && !isCountTokensPath(path)))
53
+ return null;
54
+ return a;
55
+ }
56
+ /** The C3 decision on `path`: posture=none forwards on count_tokens only; every other arm as armForwards. */
57
+ export function armForwardsFor(path, value) {
58
+ const a = armValidFor(path, value);
59
+ if (a === null)
60
+ return false;
61
+ return a.posture === "none" || armForwards(value);
62
+ }
63
+ /** The M1 gateway's arm: hold=off always (no hold code), fence=off only for the exact bytes `nofence`. */
64
+ export function m1Arm(durableAdmit, posture) {
65
+ return { hold: "off", fence: durableAdmit === NOFENCE_ADMIT_VALUE ? "off" : "on", posture };
66
+ }
67
+ /** The proxy's local drop answer when the arm check fails (frozen template, zero upstream bytes). */
68
+ export const ARM_DROP_STATUS = 502;
69
+ export const ARM_DROP_HEADERS = Object.freeze({
70
+ "content-type": "application/json",
71
+ "x-should-retry": "false",
72
+ });
73
+ export const ARM_DROP_BODY = '{"type":"error","error":{"type":"api_error","message":"durable arm check failed: response dropped"}}';
74
+ /** Golden vectors: header value -> parse result (null = drop). */
75
+ export const ARM_VECTORS = [
76
+ {
77
+ value: "1;hold=off;fence=on;posture=attended",
78
+ parsed: { hold: "off", fence: "on", posture: "attended" },
79
+ forwards: true,
80
+ },
81
+ {
82
+ value: "1;hold=off;fence=off;posture=attended",
83
+ parsed: { hold: "off", fence: "off", posture: "attended" },
84
+ forwards: true,
85
+ },
86
+ {
87
+ value: "1;hold=on;fence=on;posture=unattended",
88
+ parsed: { hold: "on", fence: "on", posture: "unattended" },
89
+ forwards: true,
90
+ },
91
+ {
92
+ value: "1;hold=off;fence=on;posture=unattended",
93
+ parsed: { hold: "off", fence: "on", posture: "unattended" },
94
+ forwards: false,
95
+ },
96
+ {
97
+ value: "1;hold=on;fence=off;posture=unattended",
98
+ parsed: { hold: "on", fence: "off", posture: "unattended" },
99
+ forwards: false,
100
+ },
101
+ {
102
+ value: "1;hold=on;fence=on;posture=attended",
103
+ parsed: { hold: "on", fence: "on", posture: "attended" },
104
+ forwards: true,
105
+ },
106
+ {
107
+ value: "1;hold=off;fence=on;posture=none",
108
+ parsed: { hold: "off", fence: "on", posture: "none" },
109
+ forwards: false,
110
+ },
111
+ { value: null, parsed: null, forwards: false },
112
+ { value: "", parsed: null, forwards: false },
113
+ { value: "v1;hold=off;fence=on;posture=attended", parsed: null, forwards: false },
114
+ { value: "2;hold=off;fence=on;posture=attended", parsed: null, forwards: false },
115
+ { value: "1;fence=on;hold=off;posture=attended", parsed: null, forwards: false },
116
+ { value: "1;HOLD=off;fence=on;posture=attended", parsed: null, forwards: false },
117
+ { value: "1;hold=off;fence=on;posture=Attended", parsed: null, forwards: false },
118
+ { value: "1; hold=off;fence=on;posture=attended", parsed: null, forwards: false },
119
+ { value: "1;hold=off;fence=on;posture=attended ", parsed: null, forwards: false },
120
+ { value: "1;hold=off;fence=on;posture=attended;", parsed: null, forwards: false },
121
+ { value: "1;hold=off;fence=on", parsed: null, forwards: false },
122
+ {
123
+ value: "1;hold=off;fence=on;posture=attended, 1;hold=off;fence=on;posture=attended",
124
+ parsed: null,
125
+ forwards: false,
126
+ },
127
+ {
128
+ value: "1;hold=on;fence=on;posture=attended, 1;hold=off;fence=off;posture=unattended",
129
+ parsed: null,
130
+ forwards: false,
131
+ },
132
+ { value: "1;hold=maybe;fence=on;posture=attended", parsed: null, forwards: false },
133
+ ];
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The one canonical JSON and the hash primitives every durable writer uses (C10-R08, C14-R08,
3
+ * C18-R02). WebCrypto only, so the same code runs in Workers, Node >= 20 and the CLI.
4
+ *
5
+ * canonicalJson is RFC 8785 (JCS) for the JSON value space the durable contract uses:
6
+ * - object keys sorted by UTF-16 code units (Array.prototype.sort's default order, which is what
7
+ * RFC 8785 section 3.2.3 specifies), no whitespace;
8
+ * - strings and numbers serialised exactly as JSON.stringify does (RFC 8785 section 3.2.2 is
9
+ * ECMAScript Number.prototype.toString, which JSON.stringify uses);
10
+ * - an object member whose value is undefined is omitted (as JSON.stringify and the npm
11
+ * `canonicalize` package do), so `{a: undefined}` hashes like `{}`. Writers that need "absent
12
+ * equals null" (the journal preimage, C10-R08) normalise before calling this;
13
+ * - non-finite numbers, bigint, functions and symbols throw TypeError (they have no JSON form).
14
+ * It differs from the api's attestation canonicalJson only on those edge cases (that one emits
15
+ * `"k":undefined` for an undefined member); for plain JSON data the bytes are identical.
16
+ */
17
+ export declare function canonicalJson(value: unknown): string;
18
+ export declare function bytesToHex(bytes: Uint8Array): string;
19
+ export declare function utf8(text: string): Uint8Array;
20
+ /** sha256 of a UTF-8 string or raw bytes, lowercase hex (64 chars). */
21
+ export declare function sha256Hex(input: string | Uint8Array): Promise<string>;
22
+ /** HMAC-SHA256(key, message), lowercase hex. Used for principal_ref (C10-R15). */
23
+ export declare function hmacSha256Hex(key: Uint8Array, message: string): Promise<string>;
24
+ /** RFC 4648 section 5 base64url, no padding. */
25
+ export declare function base64urlEncode(bytes: Uint8Array): string;
26
+ /** Strict base64url decode: null on any character outside the alphabet or an impossible length. */
27
+ export declare function base64urlDecode(text: string): Uint8Array | null;
28
+ export declare const HEX64_RE: RegExp;
29
+ export declare const UUID_RE: RegExp;
@@ -0,0 +1,98 @@
1
+ // GENERATED from shared/durable-contract/src/canonical.ts by cli/scripts/sync-durable-contract.mjs; do not edit.
2
+ /**
3
+ * The one canonical JSON and the hash primitives every durable writer uses (C10-R08, C14-R08,
4
+ * C18-R02). WebCrypto only, so the same code runs in Workers, Node >= 20 and the CLI.
5
+ *
6
+ * canonicalJson is RFC 8785 (JCS) for the JSON value space the durable contract uses:
7
+ * - object keys sorted by UTF-16 code units (Array.prototype.sort's default order, which is what
8
+ * RFC 8785 section 3.2.3 specifies), no whitespace;
9
+ * - strings and numbers serialised exactly as JSON.stringify does (RFC 8785 section 3.2.2 is
10
+ * ECMAScript Number.prototype.toString, which JSON.stringify uses);
11
+ * - an object member whose value is undefined is omitted (as JSON.stringify and the npm
12
+ * `canonicalize` package do), so `{a: undefined}` hashes like `{}`. Writers that need "absent
13
+ * equals null" (the journal preimage, C10-R08) normalise before calling this;
14
+ * - non-finite numbers, bigint, functions and symbols throw TypeError (they have no JSON form).
15
+ * It differs from the api's attestation canonicalJson only on those edge cases (that one emits
16
+ * `"k":undefined` for an undefined member); for plain JSON data the bytes are identical.
17
+ */
18
+ export function canonicalJson(value) {
19
+ return encode(value);
20
+ }
21
+ function encode(value) {
22
+ if (value === null)
23
+ return "null";
24
+ switch (typeof value) {
25
+ case "boolean":
26
+ return value ? "true" : "false";
27
+ case "string":
28
+ return JSON.stringify(value);
29
+ case "number":
30
+ if (!Number.isFinite(value))
31
+ throw new TypeError("canonicalJson: non-finite number");
32
+ return JSON.stringify(value);
33
+ case "object":
34
+ return Array.isArray(value)
35
+ ? encodeArray(value)
36
+ : encodeObject(value);
37
+ default:
38
+ throw new TypeError(`canonicalJson: unsupported type ${typeof value}`);
39
+ }
40
+ }
41
+ function encodeArray(items) {
42
+ // An undefined array slot has no JSON form other than null (JSON.stringify's rule).
43
+ return `[${items.map((v) => (v === undefined ? "null" : encode(v))).join(",")}]`;
44
+ }
45
+ function encodeObject(obj) {
46
+ const parts = [];
47
+ for (const key of Object.keys(obj).sort()) {
48
+ const v = obj[key];
49
+ if (v === undefined)
50
+ continue;
51
+ parts.push(`${JSON.stringify(key)}:${encode(v)}`);
52
+ }
53
+ return `{${parts.join(",")}}`;
54
+ }
55
+ const HEX = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
56
+ export function bytesToHex(bytes) {
57
+ let out = "";
58
+ for (const b of bytes)
59
+ out += HEX[b];
60
+ return out;
61
+ }
62
+ export function utf8(text) {
63
+ return new TextEncoder().encode(text);
64
+ }
65
+ /** sha256 of a UTF-8 string or raw bytes, lowercase hex (64 chars). */
66
+ export async function sha256Hex(input) {
67
+ const bytes = typeof input === "string" ? utf8(input) : input;
68
+ const digest = await crypto.subtle.digest("SHA-256", bytes);
69
+ return bytesToHex(new Uint8Array(digest));
70
+ }
71
+ /** HMAC-SHA256(key, message), lowercase hex. Used for principal_ref (C10-R15). */
72
+ export async function hmacSha256Hex(key, message) {
73
+ const k = await crypto.subtle.importKey("raw", key, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
74
+ const sig = await crypto.subtle.sign("HMAC", k, utf8(message));
75
+ return bytesToHex(new Uint8Array(sig));
76
+ }
77
+ /** RFC 4648 section 5 base64url, no padding. */
78
+ export function base64urlEncode(bytes) {
79
+ let bin = "";
80
+ for (const b of bytes)
81
+ bin += String.fromCharCode(b);
82
+ return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
83
+ }
84
+ const B64URL_RE = /^[A-Za-z0-9_-]*$/;
85
+ /** Strict base64url decode: null on any character outside the alphabet or an impossible length. */
86
+ export function base64urlDecode(text) {
87
+ if (!B64URL_RE.test(text) || text.length % 4 === 1)
88
+ return null;
89
+ const padded = text.replace(/-/g, "+").replace(/_/g, "/") + "===".slice(0, (4 - (text.length % 4)) % 4);
90
+ const bin = atob(padded);
91
+ const out = new Uint8Array(bin.length);
92
+ for (let i = 0; i < bin.length; i++)
93
+ out[i] = bin.charCodeAt(i);
94
+ // Reject non-canonical encodings (trailing bits set), so one byte string has one text form.
95
+ return base64urlEncode(out) === text ? out : null;
96
+ }
97
+ export const HEX64_RE = /^[0-9a-f]{64}$/;
98
+ export const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * normalizeCellId: a byte-faithful port of api src/cells/cell-id.ts (BACKBONE S1; design §0.5).
3
+ * CELL_ID -> test | us-1 | us-2; anything else, unset or a non-string -> null, and a null is never
4
+ * coerced into a default (the caller fails closed: 503 durable_cell_unmapped at create, door
5
+ * `unmapped` at the gateway). Whitespace is String.prototype.trim.
6
+ *
7
+ * The api table is NOT rewired to this one (it sits on the billing path); the two agree through
8
+ * the golden vectors in ./vectors/cell-id-vectors.json, a byte copy of the api file whose sha256
9
+ * is API_CELL_ID_VECTORS_SHA256. This file is also the gateway's pinned copy: the api file's
10
+ * _comment says "the gateway pins a copy of this file", and on this base the gateway has none, so
11
+ * the gateway imports it from here.
12
+ */
13
+ export declare const CANONICAL_CELL_IDS: readonly ["test", "us-1", "us-2"];
14
+ export type CanonicalCellId = (typeof CANONICAL_CELL_IDS)[number];
15
+ /** sha256 of api src/cells/cell-id-vectors.json at api origin/main (c9e1dae8). */
16
+ export declare const API_CELL_ID_VECTORS_SHA256 = "0fe7b8e6583c18e534e6021701d58260be3538073701c0ce87173b9810748cb8";
17
+ export declare const CELL_ID_VECTORS_PATH = "src/vectors/cell-id-vectors.json";
18
+ export declare function normalizeCellId(cellId: unknown): CanonicalCellId | null;
19
+ /** The gateway door attribute (design §3.6 step 3); diagnostic only in M1. */
20
+ export declare const DOOR_VALUES: readonly ["match", "mismatch", "unmapped"];
21
+ export type Door = (typeof DOOR_VALUES)[number];
22
+ export declare function doorOf(envCellId: unknown, homeCell: CanonicalCellId): Door;
@@ -0,0 +1,38 @@
1
+ // GENERATED from shared/durable-contract/src/cell-id.ts by cli/scripts/sync-durable-contract.mjs; do not edit.
2
+ /**
3
+ * normalizeCellId: a byte-faithful port of api src/cells/cell-id.ts (BACKBONE S1; design §0.5).
4
+ * CELL_ID -> test | us-1 | us-2; anything else, unset or a non-string -> null, and a null is never
5
+ * coerced into a default (the caller fails closed: 503 durable_cell_unmapped at create, door
6
+ * `unmapped` at the gateway). Whitespace is String.prototype.trim.
7
+ *
8
+ * The api table is NOT rewired to this one (it sits on the billing path); the two agree through
9
+ * the golden vectors in ./vectors/cell-id-vectors.json, a byte copy of the api file whose sha256
10
+ * is API_CELL_ID_VECTORS_SHA256. This file is also the gateway's pinned copy: the api file's
11
+ * _comment says "the gateway pins a copy of this file", and on this base the gateway has none, so
12
+ * the gateway imports it from here.
13
+ */
14
+ export const CANONICAL_CELL_IDS = ["test", "us-1", "us-2"];
15
+ /** sha256 of api src/cells/cell-id-vectors.json at api origin/main (c9e1dae8). */
16
+ export const API_CELL_ID_VECTORS_SHA256 = "0fe7b8e6583c18e534e6021701d58260be3538073701c0ce87173b9810748cb8";
17
+ export const CELL_ID_VECTORS_PATH = "src/vectors/cell-id-vectors.json";
18
+ export function normalizeCellId(cellId) {
19
+ switch (typeof cellId === "string" ? cellId.trim() : "") {
20
+ case "test":
21
+ return "test";
22
+ case "us-1":
23
+ return "us-1";
24
+ case "us-prod":
25
+ case "us-2-prod":
26
+ return "us-2";
27
+ default:
28
+ return null;
29
+ }
30
+ }
31
+ /** The gateway door attribute (design §3.6 step 3); diagnostic only in M1. */
32
+ export const DOOR_VALUES = ["match", "mismatch", "unmapped"];
33
+ export function doorOf(envCellId, homeCell) {
34
+ const here = normalizeCellId(envCellId);
35
+ if (here === null)
36
+ return "unmapped";
37
+ return here === homeCell ? "match" : "mismatch";
38
+ }
@@ -0,0 +1,342 @@
1
+ /**
2
+ * `mnemom agent <verb> --json` on a refused durable verb (wave-0 fix ruling 19). stdout carries
3
+ * exactly one JSON document, the ruling-14 error envelope: an API or gateway refusal body is passed
4
+ * through unchanged; a refusal the CLI decides itself (S1 codes with status null, such as
5
+ * session_homed_elsewhere or durable_cwd_not_root) is built here in the same shape, with the code's
6
+ * closed fields and the rendered fix line in details.fix. stderr is the same with or without
7
+ * --json (refusal line, fix line, machine code), and nothing reaches stdout on a refusal without it.
8
+ */
9
+ import { type ClaimUnavailableCause, type DurableCode, type DurableErrorBody, type DurableErrorDetails } from "./codes.js";
10
+ import { TRANSCRIPT_GUARD_MODES } from "./paths.js";
11
+ import { type SessionState } from "./states.js";
12
+ /** Exit status of every refused or failed `mnemom agent` verb, with or without --json. */
13
+ export declare const CLI_REFUSAL_EXIT = 1;
14
+ /** Exit status of a usage error and of the experimental gate (C04-R01, ruling 9); never a refusal. */
15
+ export declare const CLI_USAGE_EXIT = 2;
16
+ /**
17
+ * The --json stdout document for a CLI-side refusal: durableErrorBody with details always present
18
+ * and carrying the rendered fix line. Throws on a missing or empty fix, and on a field outside `fix`
19
+ * and the code's closed fields.
20
+ */
21
+ export declare function cliRefusalJson<C extends DurableCode>(code: C, message: string, details: DurableErrorDetails & {
22
+ readonly fix: string;
23
+ }): DurableErrorBody<C>;
24
+ /** Hex characters a fingerprint keeps: the sha256 prefix host status prints (ruling 26; C12-R23). */
25
+ export declare const FINGERPRINT_HEX_CHARS = 12;
26
+ /** A secret's fingerprint: the first FINGERPRINT_HEX_CHARS lowercase hex characters of its sha256. */
27
+ export declare function fingerprint(value: string): Promise<string>;
28
+ /** The host status field type tokens that carry no nested spec. */
29
+ type HostStatusScalarType = "boolean" | "string" | "uuid" | "integer" | "positive_integer" | "pid" | "port" | "hex64" | "fingerprint";
30
+ /**
31
+ * A host status field: a type token and nullability, discriminated by type so an enum always
32
+ * carries its values, an array its item schema and an object its fields.
33
+ */
34
+ export type HostStatusField = {
35
+ readonly type: HostStatusScalarType;
36
+ readonly nullable: boolean;
37
+ } | {
38
+ readonly type: "enum";
39
+ readonly nullable: boolean;
40
+ readonly values: readonly string[];
41
+ } | {
42
+ readonly type: "array";
43
+ readonly nullable: boolean;
44
+ readonly item: Readonly<Record<string, HostStatusField>>;
45
+ } | {
46
+ readonly type: "object";
47
+ readonly nullable: boolean;
48
+ readonly fields: Readonly<Record<string, HostStatusField>>;
49
+ };
50
+ /**
51
+ * One seat row (rulings 26, 26.1; C12-R23): pid is the pane pid; state is the session's stored state
52
+ * (the DB probe); spec_path is the local launch-spec file the daemon spawned the seat from. Every
53
+ * field describes the seat at call time, so a value that does not exist yet (mid-spawn) or any more
54
+ * (claude exited) is null: proxy_pid until the seat proxy runs, proxy_port until it listens,
55
+ * socket_path until the socket exists, claude_pid while claude is not running. A non-null
56
+ * proxy_port implies a non-null proxy_pid.
57
+ */
58
+ export declare const HOST_STATUS_SEAT: Readonly<{
59
+ session_id: {
60
+ type: "uuid";
61
+ nullable: false;
62
+ };
63
+ epoch: {
64
+ type: "integer";
65
+ nullable: false;
66
+ };
67
+ spawn_id: {
68
+ type: "uuid";
69
+ nullable: false;
70
+ };
71
+ state: {
72
+ type: "enum";
73
+ nullable: false;
74
+ values: readonly ["resuming", "running", "detached", "parked", "suspended", "paused", "completed", "failed", "killed", "expired", "ready"];
75
+ };
76
+ pid: {
77
+ type: "pid";
78
+ nullable: false;
79
+ };
80
+ proxy_pid: {
81
+ type: "pid";
82
+ nullable: true;
83
+ };
84
+ claude_pid: {
85
+ type: "pid";
86
+ nullable: true;
87
+ };
88
+ proxy_port: {
89
+ type: "port";
90
+ nullable: true;
91
+ };
92
+ socket_path: {
93
+ type: "string";
94
+ nullable: true;
95
+ };
96
+ spec_path: {
97
+ type: "string";
98
+ nullable: false;
99
+ };
100
+ spec_sha256: {
101
+ type: "hex64";
102
+ nullable: false;
103
+ };
104
+ }>;
105
+ /**
106
+ * One session entry (ruling 24.12, Wassim option 1; C12-R31): claim_unavailable is the last
107
+ * durable_claim_unavailable cause and the count of consecutive unavailable claims, or null when the
108
+ * session's last claim was not unavailable.
109
+ */
110
+ export declare const HOST_STATUS_SESSION: Readonly<{
111
+ session_id: {
112
+ type: "uuid";
113
+ nullable: false;
114
+ };
115
+ claim_unavailable: {
116
+ type: "object";
117
+ nullable: true;
118
+ fields: Readonly<{
119
+ cause: {
120
+ type: "enum";
121
+ nullable: false;
122
+ values: readonly ["schema", "arm_probe", "entitlement_lookup", "protection_probe", "guard", "lease_cap_config"];
123
+ };
124
+ consecutive: {
125
+ type: "positive_integer";
126
+ nullable: false;
127
+ };
128
+ }>;
129
+ };
130
+ }>;
131
+ /**
132
+ * `mnemom agent host status --json` (ruling 26, Wassim option 1; C12-R04, R23, R31): one closed
133
+ * document, key order as frozen. The nonce and key appear only as fingerprints, never raw.
134
+ */
135
+ export declare const HOST_STATUS_JSON: Readonly<{
136
+ installed: {
137
+ type: "boolean";
138
+ nullable: false;
139
+ };
140
+ loaded: {
141
+ type: "boolean";
142
+ nullable: false;
143
+ };
144
+ /** The host instance name (launchd label and tmux socket name), from config/env (C12-R04). */
145
+ instance: {
146
+ type: "string";
147
+ nullable: false;
148
+ };
149
+ daemon_pid: {
150
+ type: "pid";
151
+ nullable: true;
152
+ };
153
+ lock_holder_pid: {
154
+ type: "pid";
155
+ nullable: true;
156
+ };
157
+ lock_path: {
158
+ type: "string";
159
+ nullable: false;
160
+ };
161
+ transcript_guard: {
162
+ type: "enum";
163
+ nullable: false;
164
+ values: readonly ["link", "copy"];
165
+ };
166
+ /** The stored boot-bound nonce's fingerprint; null with no state file or no nonce yet (26.1). */
167
+ nonce_fingerprint: {
168
+ type: "fingerprint";
169
+ nullable: true;
170
+ };
171
+ /** The executor key's fingerprint; null with no readable state file, whatever installed says (26.1). */
172
+ key_fingerprint: {
173
+ type: "fingerprint";
174
+ nullable: true;
175
+ };
176
+ seats: {
177
+ type: "array";
178
+ nullable: false;
179
+ item: Readonly<{
180
+ session_id: {
181
+ type: "uuid";
182
+ nullable: false;
183
+ };
184
+ epoch: {
185
+ type: "integer";
186
+ nullable: false;
187
+ };
188
+ spawn_id: {
189
+ type: "uuid";
190
+ nullable: false;
191
+ };
192
+ state: {
193
+ type: "enum";
194
+ nullable: false;
195
+ values: readonly ["resuming", "running", "detached", "parked", "suspended", "paused", "completed", "failed", "killed", "expired", "ready"];
196
+ };
197
+ pid: {
198
+ type: "pid";
199
+ nullable: false;
200
+ };
201
+ proxy_pid: {
202
+ type: "pid";
203
+ nullable: true;
204
+ };
205
+ claude_pid: {
206
+ type: "pid";
207
+ nullable: true;
208
+ };
209
+ proxy_port: {
210
+ type: "port";
211
+ nullable: true;
212
+ };
213
+ socket_path: {
214
+ type: "string";
215
+ nullable: true;
216
+ };
217
+ spec_path: {
218
+ type: "string";
219
+ nullable: false;
220
+ };
221
+ spec_sha256: {
222
+ type: "hex64";
223
+ nullable: false;
224
+ };
225
+ }>;
226
+ };
227
+ sessions: {
228
+ type: "array";
229
+ nullable: false;
230
+ item: Readonly<{
231
+ session_id: {
232
+ type: "uuid";
233
+ nullable: false;
234
+ };
235
+ claim_unavailable: {
236
+ type: "object";
237
+ nullable: true;
238
+ fields: Readonly<{
239
+ cause: {
240
+ type: "enum";
241
+ nullable: false;
242
+ values: readonly ["schema", "arm_probe", "entitlement_lookup", "protection_probe", "guard", "lease_cap_config"];
243
+ };
244
+ consecutive: {
245
+ type: "positive_integer";
246
+ nullable: false;
247
+ };
248
+ }>;
249
+ };
250
+ }>;
251
+ };
252
+ }>;
253
+ export interface HostStatusSeat {
254
+ readonly session_id: string;
255
+ readonly epoch: number;
256
+ readonly spawn_id: string;
257
+ readonly state: SessionState;
258
+ readonly pid: number;
259
+ readonly proxy_pid: number | null;
260
+ readonly claude_pid: number | null;
261
+ readonly proxy_port: number | null;
262
+ readonly socket_path: string | null;
263
+ readonly spec_path: string;
264
+ readonly spec_sha256: string;
265
+ }
266
+ export interface HostStatusSession {
267
+ readonly session_id: string;
268
+ readonly claim_unavailable: {
269
+ readonly cause: ClaimUnavailableCause;
270
+ readonly consecutive: number;
271
+ } | null;
272
+ }
273
+ export interface HostStatusJson {
274
+ readonly installed: boolean;
275
+ readonly loaded: boolean;
276
+ readonly instance: string;
277
+ readonly daemon_pid: number | null;
278
+ readonly lock_holder_pid: number | null;
279
+ readonly lock_path: string;
280
+ readonly transcript_guard: (typeof TRANSCRIPT_GUARD_MODES)[number];
281
+ readonly nonce_fingerprint: string | null;
282
+ readonly key_fingerprint: string | null;
283
+ readonly seats: readonly HostStatusSeat[];
284
+ readonly sessions: readonly HostStatusSession[];
285
+ }
286
+ /**
287
+ * Host status documents for the three enrollment states ruling 26.1 names. The fingerprints are of
288
+ * "vector-executor-key" (4b27142c3a90) and "vector-nonce" (55ccea8c7f0d).
289
+ */
290
+ export declare const HOST_STATUS_JSON_VECTORS: Readonly<{
291
+ /** Not enrolled: no state file, so neither fingerprint exists. */
292
+ no_state_file: Readonly<{
293
+ installed: false;
294
+ loaded: false;
295
+ daemon_pid: null;
296
+ lock_holder_pid: null;
297
+ nonce_fingerprint: null;
298
+ key_fingerprint: null;
299
+ instance: "ai.mnemom.agent-host.default";
300
+ lock_path: "/Users/dev/.mnemom/durable/host.lock";
301
+ transcript_guard: "link";
302
+ seats: readonly [];
303
+ sessions: readonly [];
304
+ }>;
305
+ /** Enrolled and running, before the daemon has written its first nonce. */
306
+ enrolled_no_nonce: Readonly<{
307
+ nonce_fingerprint: null;
308
+ key_fingerprint: "4b27142c3a90";
309
+ installed: true;
310
+ loaded: true;
311
+ instance: "ai.mnemom.agent-host.default";
312
+ daemon_pid: 4000;
313
+ lock_holder_pid: 4000;
314
+ lock_path: "/Users/dev/.mnemom/durable/host.lock";
315
+ transcript_guard: "link";
316
+ seats: readonly [];
317
+ sessions: readonly [];
318
+ }>;
319
+ /** Uninstalled: the state file and enrollment stay (C12 F6-05, R24). */
320
+ not_installed_with_state_file: Readonly<{
321
+ installed: false;
322
+ loaded: false;
323
+ daemon_pid: null;
324
+ lock_holder_pid: null;
325
+ nonce_fingerprint: "55ccea8c7f0d";
326
+ key_fingerprint: "4b27142c3a90";
327
+ instance: "ai.mnemom.agent-host.default";
328
+ lock_path: "/Users/dev/.mnemom/durable/host.lock";
329
+ transcript_guard: "link";
330
+ seats: readonly [];
331
+ sessions: readonly [];
332
+ }>;
333
+ }>;
334
+ /**
335
+ * True for exactly the frozen document: HOST_STATUS_JSON closed at every level. Given the raw
336
+ * `secrets`, also false when either appears in any key or string value (only fingerprints may).
337
+ */
338
+ export declare function hostStatusJsonOk(v: unknown, secrets?: {
339
+ readonly nonce: string;
340
+ readonly key: string;
341
+ }): v is HostStatusJson;
342
+ export {};