magenta-canon 0.1.13 → 0.2.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.
Files changed (107) hide show
  1. package/README.md +6 -3
  2. package/bin/magenta-canon.mjs +11 -2
  3. package/dist/MANIFEST.json +32 -0
  4. package/dist/package.json +3 -0
  5. package/dist/scripts/demo-control-plane.js +171 -0
  6. package/dist/scripts/intake-cli.js +303 -0
  7. package/dist/scripts/magenta-mirror.js +387 -0
  8. package/dist/scripts/magenta-verify.js +194 -0
  9. package/dist/scripts/mcp-gateway.js +304 -0
  10. package/dist/server/agent-policy.js +86 -0
  11. package/dist/server/agent-record.js +72 -0
  12. package/dist/server/crypto.js +135 -0
  13. package/dist/server/execution-receipts.js +79 -0
  14. package/dist/server/intake/categories.js +61 -0
  15. package/dist/server/intake/engine.js +330 -0
  16. package/dist/server/intake/gateway-intake.js +105 -0
  17. package/dist/server/intake/index.js +42 -0
  18. package/{server/intake/intake-witness.ts → dist/server/intake/intake-witness.js} +73 -69
  19. package/dist/server/intake/model-witness.js +144 -0
  20. package/dist/server/intake/persistence.js +181 -0
  21. package/dist/server/intake/queue.js +160 -0
  22. package/dist/server/intake/rationale.js +65 -0
  23. package/dist/server/intake/types.js +17 -0
  24. package/dist/server/intake/witness.js +192 -0
  25. package/dist/server/persistence.js +153 -0
  26. package/dist/server/storage.js +1279 -0
  27. package/dist/server/transparency-log.js +201 -0
  28. package/dist/server/trust-bootstrap.js +149 -0
  29. package/{server/witness.ts → dist/server/witness.js} +68 -64
  30. package/{shared/canonical.ts → dist/shared/canonical.js} +193 -221
  31. package/dist/shared/certificates.js +174 -0
  32. package/dist/shared/schema.js +1955 -0
  33. package/dist/shared/terminating-kernel.js +79 -0
  34. package/docs/MCP_GATEWAY.md +1 -1
  35. package/docs/NPM_PACKAGING.md +39 -9
  36. package/package.json +27 -32
  37. package/scripts/demo.mjs +31 -10
  38. package/scripts/mcp-demo-drive.mjs +8 -3
  39. package/scripts/mirror-feed.mjs +14 -12
  40. package/scripts/intake-cli.ts +0 -343
  41. package/scripts/magenta-mirror.ts +0 -424
  42. package/scripts/magenta-verify.ts +0 -235
  43. package/scripts/mcp-gateway.ts +0 -380
  44. package/scripts/uci-inspector.cjs +0 -624
  45. package/scripts/uci-inspector.js +0 -35
  46. package/scripts/uci-witness.cjs +0 -102
  47. package/scripts/uci-witness.js +0 -28
  48. package/server/agent-auth.ts +0 -126
  49. package/server/agent-policy.ts +0 -97
  50. package/server/agent-record.ts +0 -96
  51. package/server/authority-containment.ts +0 -582
  52. package/server/authority-topology.ts +0 -826
  53. package/server/behavioral-vector.ts +0 -575
  54. package/server/canon-self-audit/checks/01-spine-body.ts +0 -165
  55. package/server/canon-self-audit/checks/02-deps-coherence.ts +0 -164
  56. package/server/canon-self-audit/checks/03-headers-posture.ts +0 -133
  57. package/server/canon-self-audit/checks/04-mutation-absence.ts +0 -87
  58. package/server/canon-self-audit/checks/05-language-discipline.ts +0 -182
  59. package/server/canon-self-audit/checks/06-validator-health.ts +0 -132
  60. package/server/canon-self-audit/index.ts +0 -29
  61. package/server/canon-self-audit/loopback.ts +0 -53
  62. package/server/canon-self-audit/provenance.ts +0 -73
  63. package/server/canon-self-audit/runner.ts +0 -119
  64. package/server/canon-self-audit/types.ts +0 -236
  65. package/server/canon-spine-validator.selftest.ts +0 -281
  66. package/server/canon-spine-validator.ts +0 -446
  67. package/server/conformance.ts +0 -317
  68. package/server/corrigibility.ts +0 -603
  69. package/server/crypto.ts +0 -133
  70. package/server/db.ts +0 -42
  71. package/server/economic-trust.ts +0 -511
  72. package/server/execution-gate.ts +0 -553
  73. package/server/execution-receipts.ts +0 -97
  74. package/server/index.ts +0 -369
  75. package/server/ingestion-generators.ts +0 -140
  76. package/server/intake/categories.ts +0 -63
  77. package/server/intake/engine.ts +0 -410
  78. package/server/intake/gateway-intake.ts +0 -163
  79. package/server/intake/index.ts +0 -29
  80. package/server/intake/ledger.ts +0 -42
  81. package/server/intake/model-witness.ts +0 -208
  82. package/server/intake/persistence.ts +0 -174
  83. package/server/intake/queue.ts +0 -244
  84. package/server/intake/rationale.ts +0 -74
  85. package/server/intake/types.ts +0 -183
  86. package/server/intake/witness.ts +0 -284
  87. package/server/opus-bridge.ts +0 -132
  88. package/server/origin-proof.ts +0 -245
  89. package/server/persistence.ts +0 -130
  90. package/server/precedent-memory.ts +0 -705
  91. package/server/proposal-containment.ts +0 -747
  92. package/server/routes.ts +0 -2942
  93. package/server/sovereign-auth.ts +0 -380
  94. package/server/ssr-templates.ts +0 -1292
  95. package/server/static.ts +0 -36
  96. package/server/storage.ts +0 -2293
  97. package/server/transparency-log.ts +0 -218
  98. package/server/trust-bootstrap.ts +0 -197
  99. package/server/types/semver.d.ts +0 -7
  100. package/server/ucik-normalize.ts +0 -40
  101. package/server/verification-harness.ts +0 -107
  102. package/server/verification.ts +0 -150
  103. package/server/vite.ts +0 -58
  104. package/shared/certificates.ts +0 -233
  105. package/shared/schema.ts +0 -2824
  106. package/shared/terminating-kernel.ts +0 -97
  107. package/tsconfig.json +0 -23
package/README.md CHANGED
@@ -141,9 +141,12 @@ record and shows verification **fails**. It is local/dev only — an ephemeral p
141
141
  and a fresh universe in a temp dir, cleaned up on exit.
142
142
 
143
143
  <details>
144
- <summary>Prefer the manual steps?</summary>
144
+ <summary>Prefer the manual steps? (repo checkout)</summary>
145
145
 
146
146
  ```bash
147
+ # These manual steps run from a REPO CHECKOUT (they boot the full hosted
148
+ # control plane, which does not ship in the npm package). From an npm install,
149
+ # just run `npx magenta-canon demo` — it is the same proof loop, self-contained.
147
150
  # 1. boot the control plane (the witness + evidence surface) and bootstrap trust
148
151
  INTERNAL_API_KEY=operator-secret-xyz MAGENTA_STATE_FILE=/tmp/magenta-state.json \
149
152
  PORT=5000 npx tsx server/index.ts &
@@ -158,7 +161,7 @@ DOWNSTREAM_LOG=/tmp/downstream-calls.log \
158
161
 
159
162
  # 3. publish evidence and verify it independently
160
163
  curl -s :5000/api/trust/evidence > bundle.json
161
- npx tsx scripts/magenta-verify.ts bundle.json # → RESULT: VERIFIED
164
+ npx magenta-canon verify bundle.json # → RESULT: VERIFIED
162
165
  ```
163
166
  </details>
164
167
 
@@ -219,7 +222,7 @@ REFUSED_CALL isError=true :: Blocked by Magenta capability gate: exceeds delega
219
222
  {"name":"refund","args":{"amount_cents":8900,"order_id":"4471"}} ← only the allowed call
220
223
  # the blocked $250 refund is ABSENT — it never reached the tool.
221
224
 
222
- $ npx tsx scripts/magenta-verify.ts bundle.json
225
+ $ npx magenta-canon verify bundle.json
223
226
  [PASS] STH signature verifies
224
227
  [PASS] receipt chain intact
225
228
  [PASS] recomputed Merkle root == signed STH root
@@ -66,12 +66,21 @@ function run(cmd, args, opts = {}) {
66
66
  child.on("error", (e) => { console.error(`magenta-canon: failed to start: ${e.message}`); process.exit(1); });
67
67
  }
68
68
 
69
- // Run one of the package's TypeScript entry scripts via tsx.
69
+ // Run one of the package's entry scripts. The published package carries the
70
+ // PRECOMPILED runtime (dist/**/*.js, plain CommonJS) and executes it directly
71
+ // with Node — no tsx, no esbuild, no install scripts in the consumer graph.
72
+ // A repo checkout (no dist/ built) falls back to running the TypeScript source
73
+ // via tsx, which is a devDependency there.
70
74
  function runTs(relScript, args, opts = {}) {
75
+ const compiled = path.join(ROOT, "dist", relScript.replace(/\.ts$/, ".js"));
76
+ if (existsSync(compiled)) {
77
+ run(process.execPath, [compiled, ...args], opts);
78
+ return;
79
+ }
71
80
  const cli = tsxCli();
72
81
  const script = path.join(ROOT, relScript);
73
82
  if (!existsSync(script)) { console.error(`magenta-canon: missing ${relScript} in package`); process.exit(1); }
74
- if (!cli) { console.error("magenta-canon: could not locate 'tsx' (a dependency). Try reinstalling."); process.exit(1); }
83
+ if (!cli) { console.error("magenta-canon: could not locate 'tsx' (dev fallback for repo checkouts). Run `npm install` first."); process.exit(1); }
75
84
  run(process.execPath, [cli, script, ...args], opts);
76
85
  }
77
86
 
@@ -0,0 +1,32 @@
1
+ {
2
+ "package.json": "8005a3491db7d92f36ac66369861589f9c47123d3a7c71e643fc2c06168cd45a",
3
+ "scripts/demo-control-plane.js": "3357c8de8e3fe32e73e0be99a3bb02179dff3ee041854d4ee6f8d135e4d8dcbf",
4
+ "scripts/intake-cli.js": "189014db22d6fccb034ed1a93ec11efe8905be820bc468366c68bb2cabaf8a97",
5
+ "scripts/magenta-mirror.js": "cf701065f7a6e20f7f44a9b815396aeb5fe031c3f003bcd793b8014ea8801b85",
6
+ "scripts/magenta-verify.js": "3c41d176a435ae8f53dd49c2418f63be5ad82de7e26fbe9f436a6545f521d331",
7
+ "scripts/mcp-gateway.js": "335923004b73511fe42ea0fc6f2e567afe8018dc95464a79027e4c2537e30de1",
8
+ "server/agent-policy.js": "20dd9150f8244c33aaf14ecdf3a09f471210960d246cda9ab8d5abe0e8433518",
9
+ "server/agent-record.js": "790bbfa2a10601c2bdcd98873e6e41babdf96d1df7c7ca34f19791de4c8b860f",
10
+ "server/crypto.js": "ebbcb2929e7b3651e4ec04c9fbf3dcb656e3ae0d30bf8864f3642f72f3be2f39",
11
+ "server/execution-receipts.js": "171a506df7d1e99f3370de9a41c1a4f0b21b38d1f02edc78d9c44e68c93dbee4",
12
+ "server/intake/categories.js": "e9860eee0e2e0fe96c7ade165e5e068fae0874de2c7d39ff796efc91e713013b",
13
+ "server/intake/engine.js": "abb8feacd925520cbf01acc2e932d9ebb037a3d016b053b7b10deaf8f545a605",
14
+ "server/intake/gateway-intake.js": "40514fa489b031c29725e9b837e83998217bbc1ae84cf9259154a16b1faae2e8",
15
+ "server/intake/index.js": "fd287181a5deb2a2141b479851b4e8fc21aefea39a22baecebdef6a7450af752",
16
+ "server/intake/intake-witness.js": "f974ca4637e03536ed84e1ea65d249b628cb52b322ddee344d42dcf4bba4ed00",
17
+ "server/intake/model-witness.js": "a80563a28b31a041fa9b61ed7b2d13dbca6f8464656e0f2abc2c174a22580d65",
18
+ "server/intake/persistence.js": "49b73cbac3f36f19a3d4f0f4dca88da90e0c281c6aaeae00a022093e339c4792",
19
+ "server/intake/queue.js": "f5e4f6a9a425e23ad113b08e35739355ff979d906e05bb95a48e6082757bbcfd",
20
+ "server/intake/rationale.js": "3ea64a1430828ae5a06b41f4e93d06cdd667850d6a2ff9a1e266f98bdfc6c404",
21
+ "server/intake/types.js": "014891c6c8360648d6954b3185ae92d56be625484bf2f0d0f71dac271a59e23b",
22
+ "server/intake/witness.js": "588ad166f4870d65a6ed334c70aaa2deb1d6d96ec97d889902a9eda7528bd34f",
23
+ "server/persistence.js": "2e6b1d0b1c74babbd581780b028c2593256c5ec96c2d60f4c25159e3f54e4e3f",
24
+ "server/storage.js": "4f1660e9542dcb157148f561efd757d8aa452730c3a09064d3b1314feb16e8c9",
25
+ "server/transparency-log.js": "42d0d9fd3de9c60389ca882b546d9784e6ef0003895898dd5958d763d54f2f6b",
26
+ "server/trust-bootstrap.js": "57a53a3ee9cd630ada2867e8b087a34b069ba26f86a696d3ead74888dd7e8d5f",
27
+ "server/witness.js": "e94384a35a4cfce39990e580eb5b572ef9a2d4c4d9bad1a2ed9b5382aba64b1b",
28
+ "shared/canonical.js": "476cee4b5c5702e8a2a198e79c2639cf8ff84000ffb92f68a04433ed2a2f5484",
29
+ "shared/certificates.js": "7844e71a38e1b1324586c7d054b2f5c15222b86446318d1e6dea9bab504a4a73",
30
+ "shared/schema.js": "f89190990e3826e44c722d5e8f5b39fd59b4d3fb9ec047229930a17604e4646c",
31
+ "shared/terminating-kernel.js": "8e2aa68d47d6780e4a70822482e3e410924e9d1af843f301a487da0af37ed047"
32
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * MAGENTA DEMO CONTROL PLANE — minimal, local-only proof harness.
5
+ *
6
+ * This is NOT the production server. It is a deliberately tiny node:http surface
7
+ * that exposes ONLY the four endpoints `scripts/demo.mjs` needs to prove the
8
+ * wedge end-to-end:
9
+ *
10
+ * GET /api/health readiness
11
+ * POST /internal/founder/ceremony bootstrap the trust root (INTERNAL_API_KEY)
12
+ * POST /internal/agent/action gate + witness one agent action (INTERNAL_API_KEY)
13
+ * GET /api/trust/evidence export the signed evidence bundle
14
+ *
15
+ * It reuses the EXACT same core trust modules the production routes use
16
+ * (`witnessLog`, `storage`, `recordAgentAction`, `bootstrapRootAuthority`) — the
17
+ * gate/witness/receipt/evidence semantics are identical; only the HTTP shell is
18
+ * different. This lets the lean npm package keep the one-command `demo` without
19
+ * shipping the hosted Express/Passport/PostgreSQL control plane (server/routes.ts,
20
+ * server/index.ts). The production hosted plane remains intact in the repo as its
21
+ * own artifact; this harness does not replace it.
22
+ *
23
+ * Hard constraints (it is a demo, treated like one):
24
+ * - binds 127.0.0.1 ONLY (never a public interface);
25
+ * - persists nothing unless MAGENTA_STATE_FILE is explicitly set (the demo sets
26
+ * it to an ephemeral temp file);
27
+ * - INTERNAL_API_KEY-gated /internal/* routes, fail closed (503) when unset;
28
+ * - no Express, no Passport, no database driver, no sessions, no founder admin,
29
+ * no production routes — only the proof path.
30
+ */
31
+ const node_http_1 = require("node:http");
32
+ const node_crypto_1 = require("node:crypto");
33
+ const storage_1 = require("../server/storage");
34
+ const witness_1 = require("../server/witness");
35
+ const agent_record_1 = require("../server/agent-record");
36
+ const trust_bootstrap_1 = require("../server/trust-bootstrap");
37
+ const PORT = Number(process.env.PORT ?? 0);
38
+ const HOST = "127.0.0.1";
39
+ const INTERNAL_API_KEY = process.env.INTERNAL_API_KEY;
40
+ function sendJson(res, status, body) {
41
+ const text = JSON.stringify(body);
42
+ res.writeHead(status, { "Content-Type": "application/json" });
43
+ res.end(text);
44
+ }
45
+ function readBody(req) {
46
+ return new Promise((resolve, reject) => {
47
+ let raw = "";
48
+ req.on("data", (c) => {
49
+ raw += c;
50
+ if (raw.length > 1000000)
51
+ reject(new Error("request body too large"));
52
+ });
53
+ req.on("end", () => {
54
+ if (!raw.trim())
55
+ return resolve({});
56
+ try {
57
+ resolve(JSON.parse(raw));
58
+ }
59
+ catch {
60
+ reject(new Error("invalid JSON body"));
61
+ }
62
+ });
63
+ req.on("error", reject);
64
+ });
65
+ }
66
+ // Constant-time INTERNAL_API_KEY check, same posture as the production route.
67
+ function internalAuthOk(req, res) {
68
+ if (!INTERNAL_API_KEY) {
69
+ sendJson(res, 503, { error: "internal_auth_unconfigured", message: "INTERNAL_API_KEY is not set" });
70
+ return false;
71
+ }
72
+ const provided = req.headers["x-internal-key"];
73
+ const ok = typeof provided === "string" &&
74
+ (0, node_crypto_1.timingSafeEqual)((0, node_crypto_1.createHash)("sha256").update(provided).digest(), (0, node_crypto_1.createHash)("sha256").update(INTERNAL_API_KEY).digest());
75
+ if (!ok) {
76
+ sendJson(res, 401, { error: "unauthorized", message: "Valid X-Internal-Key header required" });
77
+ return false;
78
+ }
79
+ return true;
80
+ }
81
+ const server = (0, node_http_1.createServer)(async (req, res) => {
82
+ try {
83
+ const url = (req.url ?? "").split("?")[0];
84
+ const method = req.method ?? "GET";
85
+ // ── GET /api/health ──────────────────────────────────────────────────────
86
+ if (method === "GET" && url === "/api/health") {
87
+ return sendJson(res, 200, { status: "healthy", plane: "demo-control-plane" });
88
+ }
89
+ // ── POST /internal/founder/ceremony ──────────────────────────────────────
90
+ // recordAgentAction only requires the ROOT authority (it signs receipts with
91
+ // the root key), so the minimal ceremony bootstraps the root if absent.
92
+ if (method === "POST" && url === "/internal/founder/ceremony") {
93
+ if (!internalAuthOk(req, res))
94
+ return;
95
+ let rootCert = await storage_1.storage.getRootCertificate();
96
+ if (!rootCert) {
97
+ await (0, trust_bootstrap_1.bootstrapRootAuthority)();
98
+ rootCert = await storage_1.storage.getRootCertificate();
99
+ if (!rootCert)
100
+ return sendJson(res, 500, { error: "ceremony_failed", message: "root bootstrap did not persist" });
101
+ }
102
+ return sendJson(res, 200, {
103
+ status: "FOUNDER_CEREMONY_COMPLETE",
104
+ message: "Demo trust root established (minimal local proof harness).",
105
+ root_public_key: rootCert.subject_pubkey,
106
+ });
107
+ }
108
+ // ── POST /internal/agent/action ──────────────────────────────────────────
109
+ // Same shared core the MCP gateway uses; response shape mirrors the
110
+ // production route so the gateway driver consumes it unchanged.
111
+ if (method === "POST" && url === "/internal/agent/action") {
112
+ if (!internalAuthOk(req, res))
113
+ return;
114
+ let body;
115
+ try {
116
+ body = await readBody(req);
117
+ }
118
+ catch (e) {
119
+ return sendJson(res, 400, { error: "bad_request", message: e.message });
120
+ }
121
+ if (!body?.agent_id || !body?.authorized_by || !Array.isArray(body?.granted_capabilities) || body.granted_capabilities.length === 0 || !body?.action) {
122
+ return sendJson(res, 400, { error: "bad_request", message: "provide {agent_id, authorized_by, granted_capabilities[], action, params?}" });
123
+ }
124
+ let recorded;
125
+ try {
126
+ recorded = await (0, agent_record_1.recordAgentAction)({
127
+ action: body.action,
128
+ params: body.params ?? {},
129
+ grantedCapabilities: body.granted_capabilities,
130
+ agentId: body.agent_id,
131
+ authorizedBy: body.authorized_by,
132
+ intent: body.intent ?? "",
133
+ model: body.model ?? "none(structured-input)",
134
+ session: body.session,
135
+ });
136
+ }
137
+ catch (e) {
138
+ if (e instanceof agent_record_1.TrustNotBootstrappedError) {
139
+ return sendJson(res, 409, { error: "trust_not_bootstrapped", message: e.message });
140
+ }
141
+ throw e;
142
+ }
143
+ const { decision, receipt, index } = recorded;
144
+ return sendJson(res, 200, {
145
+ recorded: true,
146
+ allowed: decision.allowed,
147
+ decision,
148
+ receipt: { action: receipt.action, receipt_hash: receipt.receipt_hash, timestamp: receipt.timestamp },
149
+ witness: { index, latest_sth: witness_1.witnessLog.latestSTH() ?? null },
150
+ });
151
+ }
152
+ // ── GET /api/trust/evidence ──────────────────────────────────────────────
153
+ if (method === "GET" && url === "/api/trust/evidence") {
154
+ const receipts = [...(await storage_1.storage.getExecutionReceipts())].reverse(); // creation order
155
+ return sendJson(res, 200, {
156
+ witness_pubkey: witness_1.witnessLog.witnessPublicKey,
157
+ sth: witness_1.witnessLog.latestSTH() ?? null,
158
+ receipts,
159
+ });
160
+ }
161
+ sendJson(res, 404, { error: "not_found", message: `${method} ${url} is not served by the demo control plane` });
162
+ }
163
+ catch (e) {
164
+ sendJson(res, 500, { error: "internal_error", message: e instanceof Error ? e.message : String(e) });
165
+ }
166
+ });
167
+ server.listen(PORT, HOST, () => {
168
+ const addr = server.address();
169
+ const port = typeof addr === "object" && addr ? addr.port : PORT;
170
+ console.log(`demo-control-plane listening on http://${HOST}:${port}`);
171
+ });
@@ -0,0 +1,303 @@
1
+ #!/usr/bin/env tsx
2
+ "use strict";
3
+ /**
4
+ * Intake Discipline CLI — exercise classification-as-governed-promotion.
5
+ *
6
+ * npx tsx scripts/intake-cli.ts kernel # print + verify the terminating kernel
7
+ * npx tsx scripts/intake-cli.ts demo # worked promote / quarantine / fail-closed
8
+ * npx tsx scripts/intake-cli.ts classify <in.json> # run one classification from a JSON spec
9
+ *
10
+ * The CLI never authorizes runtime/autonomy. It only classifies intake and
11
+ * prints witnessed promote-or-quarantine receipts. Action remains fail-closed:
12
+ * a "promote" here means "admitted to the trusted pipeline", not "executed".
13
+ */
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ const node_fs_1 = require("node:fs");
39
+ const index_1 = require("../server/intake/index");
40
+ const C = {
41
+ reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m",
42
+ green: "\x1b[32m", yellow: "\x1b[33m", red: "\x1b[31m", magenta: "\x1b[35m", cyan: "\x1b[36m",
43
+ };
44
+ const tty = process.stdout.isTTY;
45
+ const c = (code, s) => (tty ? code + s + C.reset : s);
46
+ function printKernel() {
47
+ console.log(c(C.bold, "Terminating Kernel ") + c(C.dim, `(${index_1.TERMINATING_KERNEL.version})`));
48
+ for (const a of index_1.TERMINATING_KERNEL.axioms) {
49
+ console.log(` ${c(C.cyan, a.id)} ${c(C.dim, `[${a.kind}]`)} ${a.law}`);
50
+ }
51
+ const ok = (0, index_1.verifyKernelSeal)();
52
+ console.log("");
53
+ console.log(` seal: ${c(C.dim, index_1.KERNEL_SEAL)}`);
54
+ console.log(` sealed & intact: ${ok ? c(C.green, "yes") : c(C.red, "NO — kernel has been edited without re-sealing")}`);
55
+ }
56
+ function decorrelatedWitnesses(independentVerdict) {
57
+ return [
58
+ index_1.provenanceWitness,
59
+ index_1.structuralRationaleWitness,
60
+ (0, index_1.makeDeterministicReclassifier)("reclass.cli", () => independentVerdict),
61
+ ];
62
+ }
63
+ function runOne(ledger, spec) {
64
+ const raw = ledger.submitRaw(spec.content, spec.source);
65
+ const claim = {
66
+ raw_id: raw.raw_id,
67
+ raw_hash: raw.raw_hash,
68
+ proposed_category: spec.proposed_category,
69
+ classifier_identity: spec.classifier_identity ?? "cli:operator",
70
+ rationale: [{ cites: "raw_hash", value: raw.raw_hash }],
71
+ allowed_downstream_uses: spec.allowed_downstream_uses ?? ["display"],
72
+ confidence: spec.confidence ?? 0.9,
73
+ };
74
+ const witnesses = decorrelatedWitnesses(spec.independent_verdict ?? spec.proposed_category);
75
+ if (spec.authority) {
76
+ // High-authority promotions require agreement across >= 2 mechanism CLASSES;
77
+ // add a rule-class witness alongside the deterministic set.
78
+ witnesses.push((0, index_1.makeRuleWitness)("cli-policy", (_c, r) => ({
79
+ verdict: spec.independent_verdict ?? spec.proposed_category,
80
+ reason: "cli policy table match",
81
+ citations: [{ cites: "raw_hash", value: r.raw_hash }],
82
+ })));
83
+ }
84
+ const outcome = ledger.classify(claim, witnesses, spec.authority);
85
+ const r = outcome.receipt;
86
+ const tag = outcome.decision === "promote"
87
+ ? c(C.green, "● PROMOTE")
88
+ : c(C.yellow, "▲ QUARANTINE");
89
+ console.log("");
90
+ console.log(`${tag} ${c(C.bold, spec.proposed_category)} ${c(C.dim, raw.raw_id)}`);
91
+ console.log(` source ${r.source_identity} @ ${r.source_location}`);
92
+ console.log(` raw_hash ${c(C.dim, r.raw_hash)}`);
93
+ console.log(` classifier ${r.classifier_identity} (confidence ${String(r.confidence)})`);
94
+ console.log(` witnesses ${r.witnesses.map((w) => `${c(C.dim, w.mechanism_class)}/${w.mechanism}:${w.availability !== "available" ? c(C.yellow, w.availability) : w.agree ? c(C.green, "agree") : c(C.red, w.verdict)}`).join(" ")}`);
95
+ console.log(` reconcile ${r.reconciliation.status} (${r.reconciliation.against})`);
96
+ if (r.decision_reasons.length > 0) {
97
+ console.log(c(C.yellow, " held because:"));
98
+ for (const reason of r.decision_reasons)
99
+ console.log(c(C.yellow, ` - ${reason}`));
100
+ }
101
+ console.log(` receipt_hash ${c(C.magenta, r.receipt_hash)}`);
102
+ }
103
+ function demo() {
104
+ console.log(c(C.bold, "Intake Discipline — worked example\n"));
105
+ printKernel();
106
+ const ledger = new index_1.IntakeLedger({ anchor: () => { } });
107
+ console.log("\n" + c(C.dim, "1) clean low-authority classification → PROMOTE"));
108
+ runOne(ledger, {
109
+ content: { observed: "agent read a file" },
110
+ source: { identity: "fs:watcher", location: "/repo/README.md" },
111
+ proposed_category: "observation",
112
+ });
113
+ console.log("\n" + c(C.dim, "2) independent reclassifier disagrees → QUARANTINE (retained, not discarded)"));
114
+ runOne(ledger, {
115
+ content: { text: "the refund is approved" },
116
+ source: { identity: "model:opus", location: "chat" },
117
+ proposed_category: "approval",
118
+ independent_verdict: "claim", // the rule sees a mere claim, not an approval
119
+ authority: { capabilities: ["promote:approval"], grantedBy: "human:cj" },
120
+ });
121
+ console.log("\n" + c(C.dim, "3) high-authority category with NO governed authority → QUARANTINE (fail-closed)"));
122
+ runOne(ledger, {
123
+ content: { do: "refund $5000" },
124
+ source: { identity: "agent:autopilot", location: "tool:stripe" },
125
+ proposed_category: "execution",
126
+ });
127
+ console.log("\n" + c(C.dim, "4) same act WITH a governed authority grant → PROMOTE"));
128
+ runOne(ledger, {
129
+ content: { do: "refund $50" },
130
+ source: { identity: "agent:autopilot", location: "tool:stripe" },
131
+ proposed_category: "execution",
132
+ authority: { capabilities: ["promote:execution"], grantedBy: "human:cj" },
133
+ });
134
+ console.log("\n" + c(C.dim, "5) an UNAVAILABLE model witness (no runtime injected) → QUARANTINE (held, not crashed)"));
135
+ {
136
+ const raw = ledger.submitRaw({ text: "needs a model opinion" }, { identity: "feed", location: "intake" });
137
+ const claim = {
138
+ raw_id: raw.raw_id,
139
+ raw_hash: raw.raw_hash,
140
+ proposed_category: "evidence",
141
+ classifier_identity: "cli:operator",
142
+ rationale: [{ cites: "raw_hash", value: raw.raw_hash }],
143
+ allowed_downstream_uses: ["display"],
144
+ confidence: 0.6,
145
+ };
146
+ const outcome = ledger.classify(claim, [
147
+ index_1.provenanceWitness,
148
+ index_1.structuralRationaleWitness,
149
+ (0, index_1.createModelWitnessAdapter)("opus"), // no decide → unavailable → blocks
150
+ ]);
151
+ const r = outcome.receipt;
152
+ console.log(`${c(C.yellow, "▲ QUARANTINE")} evidence ${c(C.dim, raw.raw_id)}`);
153
+ console.log(` witnesses ${r.witnesses.map((w) => `${c(C.dim, w.mechanism_class)}:${w.availability !== "available" ? c(C.yellow, w.availability) : c(C.green, "agree")}`).join(" ")}`);
154
+ for (const reason of r.decision_reasons)
155
+ console.log(c(C.yellow, ` - ${reason}`));
156
+ }
157
+ const s = ledger.status();
158
+ console.log("\n" + c(C.bold, "ledger ") + `promoted=${s.promoted} quarantined=${s.quarantined} receipts=${s.receipts}`);
159
+ console.log(c(C.dim, `chain head ${s.head}`));
160
+ }
161
+ function queueDemo() {
162
+ console.log(c(C.bold, "Quarantine Escalation Queue — worked example\n"));
163
+ const ledger = new index_1.IntakeLedger({ anchor: () => { } });
164
+ const queue = new index_1.QuarantineQueue();
165
+ // 1) a model-unavailable quarantine lands in the queue
166
+ const raw = ledger.submitRaw({ text: "ambiguous directive" }, { identity: "feed", location: "intake" });
167
+ const claim = {
168
+ raw_id: raw.raw_id,
169
+ raw_hash: raw.raw_hash,
170
+ proposed_category: "claim",
171
+ classifier_identity: "cli:operator",
172
+ rationale: [{ cites: "raw_hash", value: raw.raw_hash }],
173
+ allowed_downstream_uses: ["display"],
174
+ confidence: 0.5,
175
+ };
176
+ const held = ledger.classify(claim, [index_1.provenanceWitness, index_1.structuralRationaleWitness, (0, index_1.createModelWitnessAdapter)("opus")]);
177
+ if (held.decision !== "quarantine")
178
+ throw new Error("expected quarantine");
179
+ const item = queue.ingest(held);
180
+ console.log(c(C.dim, "1) model-unavailable quarantine ingested as a queue item"));
181
+ console.log(` ${c(C.cyan, item.item_id)} status=${item.status} reasons=${item.quarantine_reasons.length} original receipt ${c(C.dim, item.quarantine_receipt_hash.slice(0, 16))}…`);
182
+ // 2) a human reviews it; their decision is ONE witness; the ceremony decides
183
+ console.log(c(C.dim, "\n2) human review supplies a HumanDecision → ceremony re-runs"));
184
+ const { item: reviewed, outcome } = queue.review(ledger, item.item_id, {
185
+ decision: { reviewer: "cj", verdict: "claim", reason: "read it; it is an assertion, not an instruction" },
186
+ witnesses: [index_1.provenanceWitness, index_1.structuralRationaleWitness],
187
+ });
188
+ console.log(` ${c(C.cyan, reviewed.item_id)} status=${c(reviewed.status === "resolved_promoted" ? C.green : C.yellow, reviewed.status)}`);
189
+ console.log(` original receipt ${c(C.dim, reviewed.quarantine_receipt_hash.slice(0, 16))}… preserved`);
190
+ console.log(` new receipt ${c(C.magenta, reviewed.resolution.new_receipt_hash.slice(0, 16))}… (${outcome.decision})`);
191
+ // 3) duplicate processing fails closed
192
+ console.log(c(C.dim, "\n3) duplicate review attempt fails closed"));
193
+ try {
194
+ queue.review(ledger, item.item_id, {
195
+ decision: { reviewer: "cj", verdict: "claim", reason: "again" },
196
+ witnesses: [index_1.provenanceWitness, index_1.structuralRationaleWitness],
197
+ });
198
+ console.log(c(C.red, " UNEXPECTED: duplicate review succeeded"));
199
+ }
200
+ catch (err) {
201
+ console.log(` ${c(C.green, "refused:")} ${err.message}`);
202
+ }
203
+ const qs = queue.status();
204
+ console.log("\n" + c(C.bold, "queue ") + JSON.stringify(qs.byStatus) + c(C.dim, ` ledger receipts=${ledger.status().receipts}`));
205
+ }
206
+ function modelDemo() {
207
+ console.log(c(C.bold, "Model Witness Runtime Adapter — worked example\n"));
208
+ const ledger = new index_1.IntakeLedger({ anchor: () => { } });
209
+ const run = (label, witness, category = "observation", authority) => {
210
+ const raw = ledger.submitRaw({ text: label }, { identity: "feed", location: "intake" });
211
+ const claim = {
212
+ raw_id: raw.raw_id, raw_hash: raw.raw_hash, proposed_category: category,
213
+ classifier_identity: "cli:operator",
214
+ rationale: [{ cites: "raw_hash", value: raw.raw_hash }],
215
+ allowed_downstream_uses: ["display"], confidence: 0.8,
216
+ };
217
+ const outcome = ledger.classify(claim, [index_1.provenanceWitness, index_1.structuralRationaleWitness, witness], authority);
218
+ const m = outcome.receipt.witnesses.find((w) => w.mechanism_class === "model");
219
+ const tag = outcome.decision === "promote" ? c(C.green, "● PROMOTE ") : c(C.yellow, "▲ QUARANTINE");
220
+ console.log(`${tag} ${label}`);
221
+ console.log(` model witness: ${m.availability !== "available" ? c(C.yellow, m.availability) : m.agree ? c(C.green, "agree") : c(C.red, String(m.verdict))} — ${m.reason.slice(0, 100)}`);
222
+ if (outcome.decision === "quarantine") {
223
+ for (const r of outcome.receipt.decision_reasons.slice(0, 2))
224
+ console.log(c(C.dim, ` - ${r.slice(0, 110)}`));
225
+ }
226
+ console.log("");
227
+ };
228
+ run("1) no runtime injected → unavailable, held", (0, index_1.createModelRuntimeWitness)("opus"));
229
+ run("2) configured fake runtime, valid structured decision → usable vote, promotes", (0, index_1.createModelRuntimeWitness)("opus", (0, index_1.makeFakeModelRuntime)("fake:ok", () => "observation", { confidence: 0.85 })));
230
+ run("3) prose-only output → inadmissible, held", (0, index_1.createModelRuntimeWitness)("opus", (0, index_1.makeFakeModelRuntime)("fake:prose", () => "observation", { returnProse: true })));
231
+ run("4) runtime throws → contained, held", (0, index_1.createModelRuntimeWitness)("opus", (0, index_1.makeFakeModelRuntime)("fake:boom", () => "observation", { throwError: true })));
232
+ run("5) model agrees on EXECUTION but no governed authority → held (model is never authority)", (0, index_1.createModelRuntimeWitness)("opus", (0, index_1.makeFakeModelRuntime)("fake:ok", () => "execution")), "execution");
233
+ const s = ledger.status();
234
+ console.log(c(C.bold, "ledger ") + `promoted=${s.promoted} quarantined=${s.quarantined} receipts=${s.receipts}`);
235
+ }
236
+ async function gatewayDemo() {
237
+ const { McpGate } = await Promise.resolve().then(() => __importStar(require("./mcp-gateway")));
238
+ console.log(c(C.bold, "Gateway Intake Integration — worked example (enforce mode)\n"));
239
+ console.log(c(C.dim, "Intake sits in FRONT of the capability gate. A tool call reaches downstream"));
240
+ console.log(c(C.dim, "ONLY IF intake promotes AND the gate allows.\n"));
241
+ const ledger = new index_1.IntakeLedger({ anchor: () => { } });
242
+ const queue = new index_1.QuarantineQueue();
243
+ const checker = (0, index_1.makeGatewayIntakeChecker)({
244
+ ledger, queue,
245
+ baseWitnesses: [index_1.provenanceWitness, index_1.structuralRationaleWitness],
246
+ policy: index_1.conservativeGatewayPolicy,
247
+ });
248
+ const config = { agent: { agentId: "a1", authorizedBy: "op" }, grantedCapabilities: ["agent.mcp.call"] };
249
+ let downstreamHits = 0;
250
+ const forward = async (msg) => { downstreamHits++; return { jsonrpc: "2.0", id: (msg.id ?? null), result: { content: [{ type: "text", text: "DOWNSTREAM REACHED" }] } }; };
251
+ const gateFor = (allowed) => new McpGate(config, async () => ({ allowed, reason: allowed ? "ok" : "ceiling exceeded", receiptHash: "exec" }), forward, { mode: "enforce", check: checker });
252
+ const call = (name, args) => ({ jsonrpc: "2.0", id: 1, method: "tools/call", params: { name, arguments: args } });
253
+ const show = async (label, gateAllowed, args) => {
254
+ const before = downstreamHits;
255
+ const out = await gateFor(gateAllowed).handle(call("refund", args));
256
+ const reached = downstreamHits > before;
257
+ const tag = reached ? c(C.green, "→ DOWNSTREAM REACHED") : c(C.red, "✗ blocked, downstream NOT reached");
258
+ console.log(`${c(C.bold, label)}`);
259
+ console.log(` intake: ${out.intakeQuarantined ? c(C.yellow, "QUARANTINE") : c(C.green, "promote")} | gate: ${gateAllowed ? c(C.green, "allow") : c(C.red, "refuse")} ⇒ ${tag}\n`);
260
+ };
261
+ await show("1) well-formed args, gate allows", true, { amount: 50 });
262
+ await show("2) well-formed args, gate REFUSES (intake promote can't override the gate)", false, { amount: 9999 });
263
+ await show("3) prototype-pollution args, gate would allow (intake quarantines first)", true, { amount: 50, ["__proto__"]: { x: 1 } });
264
+ console.log(c(C.bold, "result ") + `downstream reached ${downstreamHits}/3 times (only case 1)`);
265
+ console.log(c(C.dim, `escalation queue: ${queue.pending().length} item(s) pending review`));
266
+ }
267
+ function classifyFromFile(path) {
268
+ const spec = JSON.parse((0, node_fs_1.readFileSync)(path, "utf8"));
269
+ if (!(0, index_1.isIntakeCategory)(spec.proposed_category)) {
270
+ console.error(`invalid proposed_category: ${spec.proposed_category}`);
271
+ process.exit(2);
272
+ }
273
+ const ledger = new index_1.IntakeLedger({ anchor: () => { } });
274
+ runOne(ledger, spec);
275
+ }
276
+ const [sub, arg] = process.argv.slice(2);
277
+ switch (sub) {
278
+ case "kernel":
279
+ printKernel();
280
+ break;
281
+ case "demo":
282
+ demo();
283
+ break;
284
+ case "queue-demo":
285
+ queueDemo();
286
+ break;
287
+ case "model-demo":
288
+ modelDemo();
289
+ break;
290
+ case "gateway-demo":
291
+ gatewayDemo();
292
+ break;
293
+ case "classify":
294
+ if (!arg) {
295
+ console.error("usage: intake-cli classify <input.json>");
296
+ process.exit(2);
297
+ }
298
+ classifyFromFile(arg);
299
+ break;
300
+ default:
301
+ console.log("usage: intake-cli <kernel|demo|queue-demo|model-demo|gateway-demo|classify <input.json>>");
302
+ process.exit(sub ? 2 : 0);
303
+ }