@cello-protocol/daemon 0.0.86 → 0.0.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cello-daemon.js +104 -0
- package/dist/bin/cello-daemon.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +49 -11
- package/dist/daemon.js.map +1 -1
- package/dist/gateway-config-handlers.d.ts +18 -0
- package/dist/gateway-config-handlers.d.ts.map +1 -0
- package/dist/gateway-config-handlers.js +345 -0
- package/dist/gateway-config-handlers.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/session-node-manager.d.ts +3 -2
- package/dist/session-node-manager.d.ts.map +1 -1
- package/dist/session-node-manager.js +14 -2
- package/dist/session-node-manager.js.map +1 -1
- package/dist/testing.d.ts +10 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +10 -0
- package/dist/testing.js.map +1 -0
- package/dist/types.d.ts +23 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vocabulary.d.ts.map +1 -1
- package/dist/vocabulary.js +9 -0
- package/dist/vocabulary.js.map +1 -1
- package/package.json +7 -3
package/dist/bin/cello-daemon.js
CHANGED
|
@@ -11,7 +11,10 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { homedir } from "node:os";
|
|
13
13
|
import { join } from "node:path";
|
|
14
|
+
import { mkdirSync } from "node:fs";
|
|
15
|
+
import { LocalSidecarGatewayClient, spawnGatewaySidecar } from "@cello-protocol/gateway";
|
|
14
16
|
import { startDaemon } from "../daemon.js";
|
|
17
|
+
import { resolveDbKey, dbKeyPathFor } from "../sqlcipher-db.js";
|
|
15
18
|
import { createDirectoryEndpointResolver } from "../directory-bootstrap.js";
|
|
16
19
|
import { buildManifestDeps } from "../manifest-deps.js";
|
|
17
20
|
import { RandomizedPollScheduler } from "../manifest-poll-scheduler.js";
|
|
@@ -49,6 +52,82 @@ const celloDir = process.env.CELLO_DIR || join(homedir(), ".cello");
|
|
|
49
52
|
const socketPath = join(celloDir, "daemon.sock");
|
|
50
53
|
const lockFilePath = join(celloDir, "daemon.lock");
|
|
51
54
|
const version = process.env.CELLO_VERSION || "0.0.1";
|
|
55
|
+
/**
|
|
56
|
+
* Bring up the security and governance layer (DOD-M9C-WIRE-1, policy D-2).
|
|
57
|
+
*
|
|
58
|
+
* THE DEFECT THIS EXISTS TO CLOSE: this function did not exist. `startDaemon` was called without a
|
|
59
|
+
* gateway, fell back to an always-allow stub, and every shipped daemon screened nothing while
|
|
60
|
+
* logging `security.gateway.connected`. The layer was fully built, unit-green and gate-green the
|
|
61
|
+
* whole time — the gate injected the client the product never did.
|
|
62
|
+
*
|
|
63
|
+
* Fail-closed, never passthrough (M9C-D12): if the sidecar cannot be spawned, the client is STILL
|
|
64
|
+
* the enforcing one. It fails closed on every call (`gateway_unavailable`, INV-6), the failure is
|
|
65
|
+
* announced, and the daemon stays up so the operator can run `cello config` / `cello policy log`
|
|
66
|
+
* against it and find out why. A dead agent with a cryptic startup error diagnoses nothing, and a
|
|
67
|
+
* silent downgrade to passthrough is the original bug wearing a hat.
|
|
68
|
+
*/
|
|
69
|
+
async function startSecurityLayer() {
|
|
70
|
+
const socketPath = join(celloDir, "gateway.sock");
|
|
71
|
+
const client = new LocalSidecarGatewayClient({ socketPath, logger });
|
|
72
|
+
// The sidecar opens the encrypted store at startup, but the key file is only created when the
|
|
73
|
+
// daemon first opens its own database — which happens AFTER this. So resolve it here (M9C-D13):
|
|
74
|
+
// the same idempotent call the daemon makes, which on a fresh install is the one that generates
|
|
75
|
+
// the key. The bytes are deliberately unused; only the side effect matters, and the key never
|
|
76
|
+
// travels to the child — the child gets the PATH (M9C-D8).
|
|
77
|
+
const keyFilePath = dbKeyPathFor(join(celloDir, "sessions.db"));
|
|
78
|
+
let sidecar;
|
|
79
|
+
try {
|
|
80
|
+
mkdirSync(celloDir, { recursive: true, mode: 0o700 });
|
|
81
|
+
resolveDbKey(join(celloDir, "sessions.db"), keyFilePath);
|
|
82
|
+
sidecar = await spawnGatewaySidecar({
|
|
83
|
+
socketPath,
|
|
84
|
+
env: {
|
|
85
|
+
CELLO_GATEWAY_STORE_DB: join(celloDir, "gateway.db"),
|
|
86
|
+
CELLO_GATEWAY_STORE_KEY_FILE: keyFilePath,
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
logger.info("security.gateway.spawned", { pid: sidecar.pid ?? -1, socketPath });
|
|
90
|
+
sidecar.process.once("exit", (code, signal) => {
|
|
91
|
+
// No auto-restart (M9C-D14). Every subsequent screen fails closed with a real cause; this
|
|
92
|
+
// line is how the operator learns the screening process died rather than inferring it from
|
|
93
|
+
// a wall of blocked sends.
|
|
94
|
+
logger.error("security.gateway.exited", { code: code ?? -1, signal: signal ?? "none" });
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
99
|
+
// The gateway's own errors carry a code and actionable guidance; the spawner appends the
|
|
100
|
+
// child's stderr tail. Keep BOTH, and hand them to the client so every later refusal names
|
|
101
|
+
// this cause instead of the generic "could not be reached, retry" (review F2) — which points
|
|
102
|
+
// at the transport when the fault was a key file, a lock, or a stale plaintext store, and
|
|
103
|
+
// suggests a retry that can never succeed.
|
|
104
|
+
const code = err?.code ?? "sidecar_spawn_failed";
|
|
105
|
+
const guidance = err?.guidance
|
|
106
|
+
?? "The security layer could not start, so nothing can be sent or received: every message " +
|
|
107
|
+
"fails closed. Fix the cause below and restart the daemon.";
|
|
108
|
+
logger.error("security.gateway.spawn_failed", { reason: code, error: message, guidance });
|
|
109
|
+
client.setUnavailableCause(code, `${guidance} (cause: ${message})`);
|
|
110
|
+
}
|
|
111
|
+
return { client, sidecar };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Stop the screening sidecar. Idempotent, and safe to call when the spawn failed.
|
|
115
|
+
*
|
|
116
|
+
* An orphaned gateway holds the encrypted store's write lock against the NEXT daemon, and its
|
|
117
|
+
* stdio pipes keep this process's event loop alive — so a daemon stopped over IPC would never
|
|
118
|
+
* actually exit. Both are why this is wired into the daemon's own stop() rather than only into
|
|
119
|
+
* the signal handler.
|
|
120
|
+
*/
|
|
121
|
+
let securityLayer;
|
|
122
|
+
async function stopSecurityLayer() {
|
|
123
|
+
if (!securityLayer)
|
|
124
|
+
return;
|
|
125
|
+
await securityLayer.client.close();
|
|
126
|
+
if (securityLayer.sidecar) {
|
|
127
|
+
await securityLayer.sidecar.stop();
|
|
128
|
+
logger.info("security.gateway.stopped", {});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
52
131
|
async function main() {
|
|
53
132
|
// M7 Keystone (Part 1): give the daemon its door to the directory. The resolver
|
|
54
133
|
// discovers the directory endpoint via GET ${CELLO_DIRECTORY_URL}/bootstrap (the
|
|
@@ -70,6 +149,25 @@ async function main() {
|
|
|
70
149
|
// When a manifest is active, the daemon verifies the directory's step-6 identity proof against the
|
|
71
150
|
// node pubkeys in it. Both dialers (keystone + per-agent) receive the verifier via startDaemon.
|
|
72
151
|
const manifest = buildManifestDeps(logger);
|
|
152
|
+
// D-2: the security and governance layer runs ENFORCING in the shipped daemon. This is the line
|
|
153
|
+
// whose absence made every guard M9 built inert.
|
|
154
|
+
const security = await startSecurityLayer();
|
|
155
|
+
securityLayer = security;
|
|
156
|
+
/**
|
|
157
|
+
* Restart the sidecar so a stored config change takes effect (M9C-D17). The gateway reads its
|
|
158
|
+
* config only at boot, so without this a confirmed loosening is recorded and does nothing.
|
|
159
|
+
* The socket path is unchanged and `LocalSidecarGatewayClient` reconnects lazily, so the client
|
|
160
|
+
* needs no involvement. A failure PROPAGATES — the caller reports stored-but-not-applied rather
|
|
161
|
+
* than telling the operator a guard changed when it did not.
|
|
162
|
+
*/
|
|
163
|
+
const restartSecurityGateway = async () => {
|
|
164
|
+
if (security.sidecar)
|
|
165
|
+
await security.sidecar.stop();
|
|
166
|
+
const restarted = await startSecurityLayer();
|
|
167
|
+
security.sidecar = restarted.sidecar;
|
|
168
|
+
if (!restarted.sidecar)
|
|
169
|
+
throw new Error("the screening process did not come back up");
|
|
170
|
+
};
|
|
73
171
|
const handle = await startDaemon({
|
|
74
172
|
celloDir,
|
|
75
173
|
socketPath,
|
|
@@ -79,10 +177,16 @@ async function main() {
|
|
|
79
177
|
logger,
|
|
80
178
|
directoryEndpointResolver,
|
|
81
179
|
...manifest,
|
|
180
|
+
securityGateway: security.client,
|
|
181
|
+
restartSecurityGateway,
|
|
182
|
+
onShutdown: stopSecurityLayer,
|
|
82
183
|
registryPubkey: REGISTRY_SIGNER_PUBKEY,
|
|
83
184
|
registryPollScheduler: new RandomizedPollScheduler({ minMs: REGISTRY_POLL_MIN_MS, maxMs: REGISTRY_POLL_MAX_MS }),
|
|
84
185
|
});
|
|
85
186
|
const shutdown = async (signal) => {
|
|
187
|
+
// handle.stop() runs onShutdown (stopSecurityLayer) for us — the teardown lives there so that
|
|
188
|
+
// `cello logout`, which stops the daemon over IPC and never reaches this handler, tears the
|
|
189
|
+
// sidecar down too.
|
|
86
190
|
await handle.stop(signal);
|
|
87
191
|
process.exit(0);
|
|
88
192
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cello-daemon.js","sourceRoot":"","sources":["../../src/bin/cello-daemon.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cello-daemon.js","sourceRoot":"","sources":["../../src/bin/cello-daemon.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EAKrB,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EAKrB,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAO/D,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAiB7G,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAsB,MAAM,2BAA2B,CAAC;AAO5G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAIlE,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAkBnF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAQlD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,SAAS,IAAI,oBAAoB,CAAC;IAClC;;;;OAIG;IACH,qBAAqB,IAAI,kBAAkB,CAAC;IAC5C;;;;OAIG;IACH,oBAAoB,IAAI,kBAAkB,CAAC;IAC3C;;;OAGG;IACH,iBAAiB,IAAI,eAAe,CAAC;IACrC;;OAEG;IACH,eAAe,IAAI,YAAY,CAAC;CACjC;AAYD,qBAAa,4BAA6B,YAAW,mBAAmB;IAChE,UAAU,CAAC,MAAM,EAAE,iBAAiB;CA8B3C;AAID,eAAO,MAAM,sBAAsB,QAAsB,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAS7E"}
|
package/dist/daemon.js
CHANGED
|
@@ -34,7 +34,7 @@ import { acquireSingletonLock } from "./singleton-lock.js";
|
|
|
34
34
|
import { createIpcServer } from "./ipc-server.js";
|
|
35
35
|
import { renderForSurface } from "./vocabulary.js";
|
|
36
36
|
import { SessionNodeManager } from "./session-node-manager.js";
|
|
37
|
-
import {
|
|
37
|
+
import { registerGatewayConfigHandlers } from "./gateway-config-handlers.js";
|
|
38
38
|
import { RetryQueue } from "./retry-queue.js";
|
|
39
39
|
import { NonceDedupStore } from "./nonce-dedup.js";
|
|
40
40
|
import { ContentParkClient } from "./content-park-client.js";
|
|
@@ -183,16 +183,24 @@ async function startDaemonHoldingLock(config, singletonLock) {
|
|
|
183
183
|
// the OS lock is what decides whether a daemon may run. This file never gates startup.
|
|
184
184
|
await acquireLock(lockFilePath, { pid: process.pid, socketPath, version });
|
|
185
185
|
// M9-CORE-001: one security-gateway client, shared by both seams — the outbound screen in
|
|
186
|
-
// cello_send and the inbound screen inside SessionNodeManager.
|
|
187
|
-
//
|
|
188
|
-
//
|
|
189
|
-
|
|
190
|
-
//
|
|
191
|
-
//
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
186
|
+
// cello_send and the inbound screen inside SessionNodeManager. REQUIRED (INV-9): there is no
|
|
187
|
+
// fallback, because the fallback WAS the bug — an always-allow default that nothing in the
|
|
188
|
+
// product ever overrode.
|
|
189
|
+
// The type says required, but tests are excluded from typecheck and JS callers exist, so the
|
|
190
|
+
// absence has to be LOUD here rather than a TypeError three lines later that names the wrong
|
|
191
|
+
// subsystem. A test that genuinely does not screen says so by passing the passthrough client.
|
|
192
|
+
if (!config.securityGateway) {
|
|
193
|
+
throw new Error("startDaemon: securityGateway is required (INV-9). The daemon no longer defaults to " +
|
|
194
|
+
"always-allow screening, because that default shipped a security layer that never ran. " +
|
|
195
|
+
"Pass a LocalSidecarGatewayClient in production, or new PassthroughGatewayClient() if " +
|
|
196
|
+
"this caller deliberately does not screen.");
|
|
197
|
+
}
|
|
198
|
+
const securityGateway = config.securityGateway;
|
|
199
|
+
// Observability: announce the mode the CLIENT declares (M9C-D11), never a ternary over the
|
|
200
|
+
// config. The sidecar socket connects lazily on the first screen, so this reports which adapter
|
|
201
|
+
// is wired, not a live socket handshake — but it reports it from the object that will do the
|
|
202
|
+
// screening, so a wiring mistake shows up here instead of hiding behind a correct-looking line.
|
|
203
|
+
logger.info("security.gateway.connected", { mode: securityGateway.mode });
|
|
196
204
|
const sessionNodeManager = new SessionNodeManager({
|
|
197
205
|
factory: sessionNodeFactory ?? new ProductionSessionNodeFactory(),
|
|
198
206
|
logger,
|
|
@@ -2255,6 +2263,16 @@ async function startDaemonHoldingLock(config, singletonLock) {
|
|
|
2255
2263
|
return { ok: false, reason: "not_implemented", guidance: `'${tool}' is not yet implemented in the daemon. This feature will be available in a future milestone.` };
|
|
2256
2264
|
});
|
|
2257
2265
|
}
|
|
2266
|
+
// DOD-M9C-SURFACE-1: the security layer's control surface. Registered here, defined in its own
|
|
2267
|
+
// module — it needs the cello dir, a logger, and the connection's client type, and nothing else
|
|
2268
|
+
// about sessions or ceremonies.
|
|
2269
|
+
registerGatewayConfigHandlers({
|
|
2270
|
+
handlers,
|
|
2271
|
+
celloDir,
|
|
2272
|
+
logger,
|
|
2273
|
+
getClientType: (connectionId) => perConnectionState.get(connectionId)?.clientType,
|
|
2274
|
+
...(config.restartSecurityGateway ? { restartSecurityGateway: config.restartSecurityGateway } : {}),
|
|
2275
|
+
});
|
|
2258
2276
|
// The session READ surface (session-read-handlers.ts): sealed receipt, transcript, list, name.
|
|
2259
2277
|
// All four read the PERSISTED store, so they survive a restart and a fresh connection.
|
|
2260
2278
|
registerSessionReadHandlers({
|
|
@@ -2611,6 +2629,26 @@ async function startDaemonHoldingLock(config, singletonLock) {
|
|
|
2611
2629
|
await ipcServer.stop();
|
|
2612
2630
|
}
|
|
2613
2631
|
finally {
|
|
2632
|
+
// DOD-M9C-WIRE-1: tear down whatever the composition root started alongside us — today the
|
|
2633
|
+
// screening sidecar. Two reasons it is HERE and not only in the bin's signal handler:
|
|
2634
|
+
// `cello logout` stops the daemon through the IPC `shutdown` verb, which reaches this
|
|
2635
|
+
// function and never touches the signal path; and a spawned child's stdio pipes keep this
|
|
2636
|
+
// process's event loop alive, so a daemon stopped that way would never actually exit.
|
|
2637
|
+
//
|
|
2638
|
+
// FIRST in the finally, BEFORE the singleton lock is released (review F4). The comment below
|
|
2639
|
+
// states the property the lock provides — "while we hold it, no successor daemon can start"
|
|
2640
|
+
// — and the sidecar teardown needs exactly that property: the `shutdown` verb acknowledges
|
|
2641
|
+
// immediately without awaiting this drain, so `cello logout && cello login` can race a new
|
|
2642
|
+
// daemon into existence. Releasing the lock first would let its gateway spawn while ours
|
|
2643
|
+
// still holds gateway.db's write lock, which the 3s busy_timeout usually hides — making the
|
|
2644
|
+
// failure intermittent rather than absent.
|
|
2645
|
+
if (config.onShutdown) {
|
|
2646
|
+
await config.onShutdown().catch((err) => {
|
|
2647
|
+
logger.error("daemon.shutdown.hook_failed", {
|
|
2648
|
+
error: err instanceof Error ? err.message : String(err),
|
|
2649
|
+
});
|
|
2650
|
+
});
|
|
2651
|
+
}
|
|
2614
2652
|
// DOD-SINGLE-DAEMON-1: in a `finally`, because a throw anywhere above must not leave the lock
|
|
2615
2653
|
// held. In the real binary the process exits and the kernel reclaims it — but an in-process
|
|
2616
2654
|
// caller (vitest, an embedder) whose shutdown throws would otherwise find every subsequent
|