@corca-org/ceal-host-linux-arm64 1.0.5 → 1.0.6

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.
@@ -0,0 +1,2680 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __cealCreateRequire } from "node:module";
3
+ const require = __cealCreateRequire(import.meta.url);
4
+
5
+ // packages/ceal-client-protocol/src/canonical-json.ts
6
+ function cealCanonicalJson(value) {
7
+ if (value === null || typeof value === "string" || typeof value === "boolean") return JSON.stringify(value);
8
+ if (typeof value === "number") {
9
+ if (!Number.isFinite(value)) throw new TypeError("Ceal canonical JSON does not support non-finite numbers.");
10
+ return JSON.stringify(value);
11
+ }
12
+ if (value === void 0) throw new TypeError("Ceal canonical JSON does not support undefined values.");
13
+ if (Array.isArray(value)) {
14
+ const entries = [];
15
+ for (let index = 0; index < value.length; index += 1) {
16
+ if (!Object.hasOwn(value, index)) throw new TypeError("Ceal canonical JSON does not support sparse arrays.");
17
+ entries.push(cealCanonicalJson(value[index]));
18
+ }
19
+ return `[${entries.join(",")}]`;
20
+ }
21
+ if (!isPlainRecord(value)) throw new TypeError("Ceal canonical JSON only supports JSON data.");
22
+ return `{${Object.keys(value).sort(cealCompareOrdered).map((key) => `${JSON.stringify(key)}:${cealCanonicalJson(value[key])}`).join(",")}}`;
23
+ }
24
+ function cealCompareOrdered(left, right) {
25
+ return left < right ? -1 : left > right ? 1 : 0;
26
+ }
27
+ function isPlainRecord(value) {
28
+ const prototype = Object.getPrototypeOf(value);
29
+ return prototype === Object.prototype || prototype === null;
30
+ }
31
+
32
+ // packages/ceal-client-protocol/client-wire-contract.json
33
+ var client_wire_contract_default = {
34
+ schema_version: "ceal.client_wire_contract.v1",
35
+ canonical_json: {
36
+ ordering: "utf16_code_unit_ascending"
37
+ },
38
+ artifact_descriptor: {
39
+ operation_contract_bundle_schema_version: "ceal.operation_contract_bundle.v1",
40
+ schema_version: "ceal.verified_artifact_descriptor.v1",
41
+ binding_schema_version: "ceal.verified_artifact_binding.v1",
42
+ kind: "verified_artifact",
43
+ binding_kind: "catalog",
44
+ media_type: "application/json",
45
+ digest: {
46
+ algorithm: "sha256",
47
+ encoding: "lowercase_hex",
48
+ length: 64,
49
+ pattern: "^[a-f0-9]{64}$"
50
+ },
51
+ catalog_revision: {
52
+ prefix: "catalog:",
53
+ digest_length: 64,
54
+ length: 72,
55
+ pattern: "^catalog:[a-f0-9]{64}$"
56
+ },
57
+ max_bytes: 4194304,
58
+ envelope_max_bytes: 389
59
+ },
60
+ command_request: {
61
+ schema_version: "ceal.command_request.v1",
62
+ absolute_transport_max_bytes: 65536
63
+ },
64
+ command_response: {
65
+ schema_version: "ceal.command_response.v1",
66
+ descriptor_field: "verified_artifact",
67
+ required_fields: [
68
+ "schema_version",
69
+ "exit_code",
70
+ "document"
71
+ ],
72
+ optional_fields: [
73
+ "verified_artifact"
74
+ ],
75
+ bare_document_fields: [
76
+ "invocation",
77
+ "next",
78
+ "common_concepts",
79
+ "operations",
80
+ "catalog_revision"
81
+ ],
82
+ exit_code_max: 125,
83
+ bare_document_max_bytes: 65536,
84
+ complete_max_bytes: 66019,
85
+ absolute_transport_max_bytes: 4194304
86
+ }
87
+ };
88
+
89
+ // packages/ceal-client-protocol/src/client-wire-contract.ts
90
+ var CEAL_CLIENT_WIRE_CONTRACT = Object.freeze(client_wire_contract_default);
91
+ var artifact = CEAL_CLIENT_WIRE_CONTRACT.artifact_descriptor;
92
+ var request = CEAL_CLIENT_WIRE_CONTRACT.command_request;
93
+ var response = CEAL_CLIENT_WIRE_CONTRACT.command_response;
94
+ var CEAL_OPERATION_CONTRACT_BUNDLE_SCHEMA_VERSION = artifact.operation_contract_bundle_schema_version;
95
+ var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_SCHEMA_VERSION = artifact.schema_version;
96
+ var CEAL_VERIFIED_ARTIFACT_BINDING_SCHEMA_VERSION = artifact.binding_schema_version;
97
+ var CEAL_VERIFIED_ARTIFACT_KIND = artifact.kind;
98
+ var CEAL_VERIFIED_ARTIFACT_BINDING_KIND = artifact.binding_kind;
99
+ var CEAL_VERIFIED_ARTIFACT_MEDIA_TYPE = artifact.media_type;
100
+ var CEAL_VERIFIED_ARTIFACT_DIGEST_LENGTH = artifact.digest.length;
101
+ var CEAL_VERIFIED_ARTIFACT_DIGEST_PATTERN = artifact.digest.pattern;
102
+ var CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_LENGTH = artifact.catalog_revision.length;
103
+ var CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_PATTERN = artifact.catalog_revision.pattern;
104
+ var CEAL_VERIFIED_ARTIFACT_MAX_BYTES = artifact.max_bytes;
105
+ var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_MAX_BYTES = artifact.envelope_max_bytes;
106
+ var CEAL_COMMAND_REQUEST_SCHEMA_VERSION = request.schema_version;
107
+ var CEAL_COMMAND_REQUEST_MAX_BYTES = request.absolute_transport_max_bytes;
108
+ var CEAL_COMMAND_RESPONSE_BARE_DOCUMENT_FIELDS = response.bare_document_fields;
109
+ var CEAL_COMMAND_RESPONSE_BARE_DOCUMENT_MAX_BYTES = response.bare_document_max_bytes;
110
+ var CEAL_COMMAND_RESPONSE_MAX_BYTES = response.absolute_transport_max_bytes;
111
+
112
+ // packages/ceal-client-protocol/src/vocabulary.ts
113
+ function vocabulary(words) {
114
+ return Object.freeze(words);
115
+ }
116
+
117
+ // packages/ceal-client-protocol/src/operation-contract-types.ts
118
+ var CEAL_JSON_SCHEMA_2020_12 = "https://json-schema.org/draft/2020-12/schema";
119
+ var CEAL_OPERATION_ERROR_SCHEMA_VERSION = "ceal.operation_error.v1";
120
+ var CEAL_JSON_SCHEMA_TYPES = vocabulary(["object", "array", "string", "integer", "number", "boolean", "null"]);
121
+ var OBSERVATION_POSTURES = vocabulary(["direct_readback", "approved_no_readback", "operator_mediated", "excluded"]);
122
+ var EFFECT_DOMAINS = vocabulary(["none", "gateway_state", "provider", "external_world"]);
123
+ var SAFETY_CLASSES = vocabulary(["routine", "sensitive", "high_impact"]);
124
+ var IDEMPOTENCY_CLASSES = vocabulary(["idempotent", "conditionally_idempotent", "non_idempotent"]);
125
+ var REVERSIBILITY_CLASSES = vocabulary(["none", "reversible", "compensatable", "irreversible"]);
126
+ var COMPENSATION_OWNERS = vocabulary(["none", "connector", "operator"]);
127
+ var CANCELLATION_BOUNDARIES = vocabulary(["before_admission", "before_handoff", "after_handoff_reconcile"]);
128
+ var HANDOFF_CLASSES = vocabulary(["not_applicable", "submission", "effect"]);
129
+ var AUTHORITATIVE_READBACK_CLASSES = vocabulary(["required", "unavailable"]);
130
+ var PROVIDER_READBACK_CLASSES = vocabulary(["required", "not_available", "not_applicable"]);
131
+ var RECONCILIATION_CLASSES = vocabulary(["none", "automatic", "operator"]);
132
+ var NO_READBACK_APPROVAL_CLASSES = vocabulary(["not_applicable", "explicit", "operator"]);
133
+ var REPLAY_PREREQUISITES = vocabulary(["never", "fresh_admission", "reconciled_non_application", "operator_approval"]);
134
+ var UNKNOWN_OUTCOMES = vocabulary(["reconcile", "operator_action", "excluded"]);
135
+ var RECOVERY_OWNERS = vocabulary(["gateway", "connector", "operator"]);
136
+ var CEAL_OPERATION_ADMISSION_STATES = vocabulary(["proposed", "refused", "admitted"]);
137
+ var CEAL_OPERATION_EXECUTION_STATES = vocabulary(["not_started", "started", "completed"]);
138
+ var CEAL_OPERATION_PROVIDER_HANDOFF_STATES = vocabulary(["not_offered", "offered", "accepted", "rejected", "unknown"]);
139
+ var CEAL_OPERATION_EFFECT_STATES = vocabulary(["none", "applied", "failed", "unknown", "compensated"]);
140
+ var CEAL_OPERATION_OBSERVATION_STATES = vocabulary(["not_started", "not_required", "pending", "observed", "unavailable"]);
141
+ var CEAL_OPERATION_RECOVERY_KINDS = vocabulary(["none", "reconcile", "compensate", "operator_action"]);
142
+ var CEAL_OPERATION_RECOVERY_STATUSES = vocabulary(["not_started", "active", "completed"]);
143
+ var CEAL_OPERATION_PROVIDER_READBACK_AVAILABILITY = vocabulary(["not_started", "not_applicable", "not_available", "pending", "available"]);
144
+ var CEAL_OPERATION_OFFERED_HANDOFF_STATES = vocabulary(["accepted", "rejected", "unknown"]);
145
+ var CEAL_OPERATION_RECEIPT_AUTHORITY_KEYS = Object.freeze(["instance_ref", "profile_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]);
146
+ var CEAL_OPERATION_APPROVAL_DISPOSITIONS = vocabulary([
147
+ "approval_not_required_by_policy",
148
+ "interactive_pending",
149
+ "interactive_granted",
150
+ "interactive_denied",
151
+ "interactive_expired",
152
+ "interactive_unavailable"
153
+ ]);
154
+
155
+ // packages/ceal-client-protocol/src/gateway-response-types.ts
156
+ var CEAL_CAPABILITY_READINESS_VALUES = vocabulary(["ready", "degraded", "unavailable", "unknown"]);
157
+ var CEAL_TARGET_REQUIREMENTS = vocabulary(["required", "optional", "none"]);
158
+ var CEAL_AUDIT_OUTCOMES = vocabulary(["succeeded", "denied", "failed"]);
159
+ var CEAL_GATEWAY_PROVIDER_STEP_OUTCOMES = vocabulary(["completed", "rejected", "throttled", "failed"]);
160
+ var CEAL_POLICY_DECISIONS = vocabulary(["allowed", "denied", "not_evaluated"]);
161
+ var CEAL_CONNECTOR_ROUTE_PHASES = vocabulary(["scope_observation", "target_selection", "route_resolution"]);
162
+ var CEAL_CONNECTOR_ROUTE_CAUSES = vocabulary(["provider_throttled", "provider_unavailable", "binding_invalid", "scope_limit_exceeded"]);
163
+ var CEAL_WRITE_SOURCE_KINDS = vocabulary(["authenticated_registered_client", "agent_lease_admission", "provider_authenticated_event"]);
164
+ var CEAL_REFRESH_DELIVERIES = vocabulary(["initial", "recovery", "replay", "terminal_failure", "recovery_unavailable"]);
165
+ var CEAL_CLIENT_OPERATIONS = vocabulary(["handshake", "discover", "call", "readback"]);
166
+ var CEAL_WRITE_IDEMPOTENCY_POSTURES = vocabulary(["required", "optional", "not_required"]);
167
+ var CEAL_WRITE_PROVIDER_READBACK_POSTURES = vocabulary(["required", "best_effort", "not_available"]);
168
+ var CEAL_WRITE_ATTRIBUTIONS = vocabulary(["subject", "requester_event", "connector_integration"]);
169
+ var CEAL_PROTOCOL_VERSION = "1.4.0";
170
+ var CEAL_CONNECTOR_ROUTE_FAILURE_KEYS = vocabulary(["connector_kind", "phase", "schema_version"]);
171
+ var CEAL_CLASSIFIED_CONNECTOR_ROUTE_FAILURE_KEYS = vocabulary(["cause", ...CEAL_CONNECTOR_ROUTE_FAILURE_KEYS]);
172
+ var CEAL_UNCLASSIFIED_CONNECTOR_ROUTE_FAILURE_KEYS = vocabulary(["connector_kind", "error_class", "phase", "schema_version"]);
173
+
174
+ // packages/ceal-client-protocol/src/gateway-validation-primitives.ts
175
+ var CealProtocolValidationError = class extends Error {
176
+ name = "CealProtocolValidationError";
177
+ code;
178
+ constructor(code3) {
179
+ super(code3 === "invalid_gateway_request" ? "Ceal Gateway request is invalid." : "Ceal client response is invalid.");
180
+ this.code = code3;
181
+ }
182
+ };
183
+ var SAFE_REF = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
184
+ var MAX_SAFE_TOKEN_LENGTH = 64;
185
+ var SAFE_CODE = new RegExp(`^[a-z][a-z0-9_]{0,${MAX_SAFE_TOKEN_LENGTH - 1}}$`, "u");
186
+ var SAFE_CONNECTOR_KIND = new RegExp(`^[a-z][a-z0-9-]{0,${MAX_SAFE_TOKEN_LENGTH - 1}}$`, "u");
187
+ var FORBIDDEN_SECRET_KEY = /^(?:[a-z0-9_]*(?:token|secret|password|credential(?:s)?|private_?key)|api_?key|authorization|bearer|raw_?provider_?payload|provider_?payload)$/iu;
188
+ var FORBIDDEN_AUTHORITY_KEY = /^(?:actor_?ref|owner_?ref|registration_?ref|runner_?ref|auth_?decision|policy_?decision|host_?decision)$/iu;
189
+ var TEXT_ENCODER = new TextEncoder();
190
+ var CEAL_WIRE_SAFE_TEXT_MAX_BYTES = 8 * 1024;
191
+ function assertSafeJsonValue(value, options, depth = 0, count = { value: 0 }) {
192
+ count.value += 1;
193
+ if (depth > 8 || count.value > (options.maxNodes ?? 512)) invalidByContext(options);
194
+ if (value === null || typeof value === "boolean") return;
195
+ if (typeof value === "number") return assertSafeJsonNumber(value, options);
196
+ if (typeof value === "string") return assertSafeJsonString(value, options);
197
+ if (Array.isArray(value)) {
198
+ return assertSafeJsonArray(value, options, depth, count);
199
+ }
200
+ assertSafeJsonRecord(requireRecord(value), options, depth, count);
201
+ }
202
+ function assertSafeJsonNumber(value, options) {
203
+ if (!Number.isFinite(value)) invalidByContext(options);
204
+ }
205
+ function assertSafeJsonString(value, options) {
206
+ if (byteLength(value) > CEAL_WIRE_SAFE_TEXT_MAX_BYTES || firstDisallowedControl(value, "multi_line") !== null) invalidByContext(options);
207
+ }
208
+ function assertSafeJsonArray(value, options, depth, count) {
209
+ if (value.length > 128) invalidByContext(options);
210
+ for (const item of value) assertSafeJsonValue(item, options, depth + 1, count);
211
+ }
212
+ function assertSafeJsonRecord(record6, options, depth, count) {
213
+ const entries = Object.entries(record6);
214
+ if (entries.length > 128) invalidByContext(options);
215
+ const sourceUrlColumn = options.allowHttpsUrl ? compactSourceUrlColumn(record6.fields) : null;
216
+ for (const [key, child] of entries) {
217
+ if (key === "credential_material_included" && child !== false) invalidByContext(options);
218
+ if (!isSafeNegativeMaterialAssertion(key, child)) assertSafeJsonKey(key, options);
219
+ if (key === "rows" && sourceUrlColumn !== null) {
220
+ assertSafeJsonCompactRows(child, sourceUrlColumn, options, depth, count);
221
+ continue;
222
+ }
223
+ assertSafeJsonRecordChild(key, child, options, depth, count);
224
+ }
225
+ }
226
+ function assertSafeJsonRecordChild(key, child, options, depth, count) {
227
+ if (options.allowResultContent && (key === "text" || key === "text_preview")) {
228
+ if (!isSafeResultContent(child, key)) invalidByContext(options);
229
+ return;
230
+ }
231
+ if ((key === "url" || key === "source_url") && options.allowHttpsUrl && isSafeExternalHttpsUrl(child)) return;
232
+ assertSafeJsonValue(child, options, depth + 1, count);
233
+ }
234
+ function compactSourceUrlColumn(fields) {
235
+ if (!Array.isArray(fields)) return null;
236
+ const index = fields.indexOf("source_url");
237
+ return index < 0 ? null : index;
238
+ }
239
+ function assertSafeJsonCompactRows(value, sourceUrlColumn, options, depth, count) {
240
+ if (!Array.isArray(value) || value.length > 128) invalidByContext(options);
241
+ for (const row of value) {
242
+ if (!Array.isArray(row) || row.length > 128) invalidByContext(options);
243
+ for (const [index, cell] of row.entries()) {
244
+ if (index === sourceUrlColumn && (cell === null || isSafeExternalHttpsUrl(cell))) continue;
245
+ assertSafeJsonValue(cell, options, depth + 2, count);
246
+ }
247
+ }
248
+ }
249
+ function isSafeNegativeMaterialAssertion(key, value) {
250
+ return key === "credential_material_included" && value === false;
251
+ }
252
+ function assertSafeJsonKey(key, options) {
253
+ const invalid2 = !/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(key) || FORBIDDEN_SECRET_KEY.test(key) || options.forbidAuthorityKeys && FORBIDDEN_AUTHORITY_KEY.test(key);
254
+ if (invalid2) invalidByContext(options);
255
+ }
256
+ function isSafeExternalHttpsUrl(value) {
257
+ if (!isSafeExternalHttpsUrlInput(value)) return false;
258
+ try {
259
+ const url = new URL(value);
260
+ return isSafeExternalHttpsUrlShape(url);
261
+ } catch {
262
+ return false;
263
+ }
264
+ }
265
+ function isSafeExternalHttpsUrlInput(value) {
266
+ return typeof value === "string" && byteLength(value) <= 2048;
267
+ }
268
+ function isSafeExternalHttpsUrlShape(url) {
269
+ return url.protocol === "https:" && url.username === "" && url.password === "" && url.hash === "";
270
+ }
271
+ function isSafeResultContent(value, key) {
272
+ const maximum = key === "text" ? 8192 : 1024;
273
+ return typeof value === "string" && byteLength(value) <= maximum && firstDisallowedControl(value, "multi_line") === null;
274
+ }
275
+ function normalizeCealSingleLineText(value) {
276
+ return value.split("").map((character) => hasControlCharacter(character) ? " " : character).join("").trim();
277
+ }
278
+ function byteLength(value) {
279
+ return TEXT_ENCODER.encode(value).byteLength;
280
+ }
281
+ var LAYOUT_CODE_POINTS = [9, 10, 13];
282
+ function firstDisallowedControl(value, shape) {
283
+ let index = 0;
284
+ for (const character of value) {
285
+ const codePoint = character.codePointAt(0) ?? 0;
286
+ const laysOutALine = shape === "multi_line" && LAYOUT_CODE_POINTS.includes(codePoint);
287
+ if (!laysOutALine && (codePoint <= 31 || codePoint === 127)) return { codePoint, index };
288
+ index += character.length;
289
+ }
290
+ return null;
291
+ }
292
+ function hasControlCharacter(value) {
293
+ return firstDisallowedControl(value, "single_line") !== null;
294
+ }
295
+ var AUTHORITY_METADATA_SUFFIX = "(?:_(?:refs?|revisions?|versions?|generations?|ids?))*$";
296
+ var UNDECLARED_AUTHORITY_STATE_KEY = new RegExp(`(?:^|_)(?:decisions?|authority|grants?|policy|policies|scopes?|tokens?|credentials?|secrets?|permissions?|roles?)${AUTHORITY_METADATA_SUFFIX}`, "iu");
297
+ var UNDECLARED_HANDLE_REF_KEY = new RegExp(`(?:^|_)refs?${AUTHORITY_METADATA_SUFFIX}`, "iu");
298
+ function requireRecord(value) {
299
+ if (!isCealJsonRecord(value)) invalidRequestOrResponse();
300
+ const prototype = Object.getPrototypeOf(value);
301
+ if (prototype !== Object.prototype && prototype !== null) invalidRequestOrResponse();
302
+ return value;
303
+ }
304
+ function isCealJsonRecord(value) {
305
+ return value !== null && typeof value === "object" && !Array.isArray(value);
306
+ }
307
+ var CEAL_VALIDATION_STATUSES = vocabulary(["not_applicable", "valid", "invalid"]);
308
+ var CEAL_PARSE_STATUSES = vocabulary(["not_applicable", "parsed", "parse_failed"]);
309
+ function invalidByContext(options) {
310
+ if (options.forbidAuthorityKeys) invalidRequest();
311
+ invalidResponse();
312
+ }
313
+ var InvalidWireShapeError = class extends Error {
314
+ };
315
+ function invalidRequestOrResponse() {
316
+ throw new InvalidWireShapeError();
317
+ }
318
+ function invalidRequest() {
319
+ throw new CealProtocolValidationError("invalid_gateway_request");
320
+ }
321
+ function invalidResponse() {
322
+ throw new CealProtocolValidationError("invalid_client_response");
323
+ }
324
+
325
+ // packages/ceal-client-protocol/src/refusal-fact.ts
326
+ var REFUSAL_VALUE_MAX_CHARS = 160;
327
+ function renderText(value) {
328
+ return normalizeCealSingleLineText(value);
329
+ }
330
+ var REFUSAL_LIST_HEAD = 5;
331
+ var REFUSAL_FACTS_MAX_CHARS = 360;
332
+ var REFUSAL_SENTENCE_MAX_BYTES = 384;
333
+ var REFUSAL_CLOSING_MAX_BYTES = REFUSAL_SENTENCE_MAX_BYTES / 2;
334
+ function refusalFact(name, value, expected) {
335
+ const rendered = `${JSON.stringify(name)}=${renderRefusalValue(value)}`;
336
+ return expected === void 0 ? rendered : `${rendered}; expected ${cut(renderText(expected))}`;
337
+ }
338
+ function refusalFacts(facts) {
339
+ const joined = facts.map((fact) => refusalFact(fact.name, fact.value, fact.expected)).join("; ");
340
+ return joined.length <= REFUSAL_FACTS_MAX_CHARS ? joined : `${joined.slice(0, REFUSAL_FACTS_MAX_CHARS)}...(+${joined.length - REFUSAL_FACTS_MAX_CHARS} chars, ${facts.length} facts)`;
341
+ }
342
+ function renderRefusalValue(value) {
343
+ if (typeof value === "object" && value !== null) return renderStructure(value);
344
+ if (typeof value === "string") return cut(JSON.stringify(renderText(value)));
345
+ if (typeof value === "function") return `function ${value.name === "" ? "(anonymous)" : value.name} -- a fact must be a value`;
346
+ if (typeof value === "symbol") return value.toString();
347
+ if (typeof value === "bigint") return `${value}n`;
348
+ return String(value);
349
+ }
350
+ function renderStructure(value) {
351
+ if (Array.isArray(value)) return cut(renderList(value));
352
+ if (value instanceof Error) return `${value.name}${"code" in value && typeof value.code === "string" ? `(${value.code})` : ""}`;
353
+ if (value instanceof Date) return value.toISOString();
354
+ if (ArrayBuffer.isView(value)) return `<${value.byteLength} bytes>`;
355
+ return renderRecord(value);
356
+ }
357
+ function renderRecord(value) {
358
+ if (value instanceof Map) return cut(renderList([...value].map(([key, entry]) => `${renderRefusalValue(key)}=${renderRefusalValue(entry)}`), true));
359
+ if (value instanceof Set) return cut(renderList([...value]));
360
+ if (isStatRecord(value)) return `{"mode":"0o${Number(value.mode).toString(8)}","size":${Number(value.size)},"kind":"${statKind(value)}"}`;
361
+ return cut(renderText(JSON.stringify(value, serializable) ?? String(value)));
362
+ }
363
+ function statKind(value) {
364
+ if (value.isDirectory()) return "directory";
365
+ return value.isFile() ? "file" : "other";
366
+ }
367
+ function isStatRecord(value) {
368
+ return "mode" in value && (typeof value.mode === "number" || typeof value.mode === "bigint") && "size" in value && (typeof value.size === "number" || typeof value.size === "bigint") && "isDirectory" in value && typeof value.isDirectory === "function" && "isFile" in value && typeof value.isFile === "function";
369
+ }
370
+ function serializable(_key, entry) {
371
+ if (typeof entry === "bigint") return `${entry}n`;
372
+ return ArrayBuffer.isView(entry) ? `<${entry.byteLength} bytes>` : entry;
373
+ }
374
+ function renderList(value, rendered = false) {
375
+ const head = value.slice(0, REFUSAL_LIST_HEAD).map((item) => rendered ? String(item) : renderRefusalValue(item));
376
+ const rest = value.length - head.length;
377
+ return `[${head.join(", ")}${rest > 0 ? `, ...${rest} more` : ""}] (${value.length} items)`;
378
+ }
379
+ function cut(text) {
380
+ return text.length <= REFUSAL_VALUE_MAX_CHARS ? text : `${text.slice(0, REFUSAL_VALUE_MAX_CHARS)}...(+${text.length - REFUSAL_VALUE_MAX_CHARS} chars)`;
381
+ }
382
+
383
+ // packages/ceal-client-protocol/src/safe-json-budget.ts
384
+ var SAFE_JSON_MIN_BYTES_PER_NODE = 4;
385
+ function safeJsonNodeBudgetForBytes(maxBytes) {
386
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < SAFE_JSON_MIN_BYTES_PER_NODE) {
387
+ throw new RangeError(`safe-JSON byte cap is invalid: ${refusalFact("maxBytes", maxBytes, `at least ${SAFE_JSON_MIN_BYTES_PER_NODE} bytes`)}`);
388
+ }
389
+ return Math.floor(maxBytes / SAFE_JSON_MIN_BYTES_PER_NODE);
390
+ }
391
+
392
+ // packages/ceal-client-protocol/src/protocol-bounds.ts
393
+ var CEAL_PROTOCOL_RESPONSE_VALUE_MAX_BYTES = 64 * 1024;
394
+ var CEAL_PROTOCOL_RESPONSE_VALUE_MAX_NODES = safeJsonNodeBudgetForBytes(CEAL_PROTOCOL_RESPONSE_VALUE_MAX_BYTES);
395
+ var OPERATION_SCHEMA_LITERAL_MAX_BYTES = CEAL_PROTOCOL_RESPONSE_VALUE_MAX_BYTES / 4;
396
+ var CEAL_OPERATION_JSON_SCHEMA_BUDGET = Object.freeze({
397
+ max_depth: 8,
398
+ max_properties: 96,
399
+ max_string_length: OPERATION_SCHEMA_LITERAL_MAX_BYTES / 4,
400
+ max_alternatives: 8,
401
+ max_enum_values: 64,
402
+ max_literal_bytes: OPERATION_SCHEMA_LITERAL_MAX_BYTES,
403
+ /** @basis our_policy -- bounds explanatory schema prose carried in one catalog. */
404
+ max_description_characters: 1024,
405
+ /** @basis our_policy -- bounds regular-expression compilation input from one schema. */
406
+ max_pattern_characters: 256,
407
+ /** @basis our_policy -- bounds traversal work inside one already byte-bounded schema literal. */
408
+ max_literal_nodes: 512
409
+ });
410
+
411
+ // packages/ceal-client-protocol/src/operation-validation-primitives.ts
412
+ var ISO_TIMESTAMP = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/u;
413
+ function isOperationRecord(value) {
414
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
415
+ const prototype = Object.getPrototypeOf(value);
416
+ return prototype === Object.prototype || prototype === null;
417
+ }
418
+ function requireOperationRecord(value, message) {
419
+ if (!isOperationRecord(value)) throw new TypeError(message);
420
+ }
421
+ function requireClosedValue(value, members, message) {
422
+ if (typeof value !== "string" || !members.includes(value)) throw new TypeError(message);
423
+ }
424
+ function requireIsoTimestamp(value, message) {
425
+ if (typeof value !== "string" || !ISO_TIMESTAMP.test(value) || !Number.isFinite(Date.parse(value))) throw new TypeError(message);
426
+ }
427
+
428
+ // packages/ceal-client-protocol/src/operation-json-schema.ts
429
+ var JSON_DESCRIPTION_CONTROL_CHARACTER = new RegExp("\\p{Cc}", "u");
430
+
431
+ // packages/ceal-client-protocol/src/operation-contract-validation.ts
432
+ var CEAL_OPERATION_AUTHORITY_POLICY_KEYS = Object.freeze(["profile", "instance_binding", "target", "admission_recheck"]);
433
+ var MAX_OPERATION_INPUT_RESOLVER_BINDINGS = 96;
434
+ var CEAL_OPERATION_RESULT_KEYS = vocabulary(["ok", "operation_id", "operation_receipt", "schema_version", "value"]);
435
+ var CEAL_OPERATION_COMPACT_RESULT_KEYS = vocabulary(["ok", "operation_evidence", "operation_id", "schema_version", "value"]);
436
+
437
+ // packages/ceal-client-protocol/src/operation-catalog.ts
438
+ var CEAL_OPERATION_CATALOG_SCHEMA_VERSION = "ceal.catalog.v3";
439
+ var CLIENT_AUDIENCES = Object.freeze(["ceal", "cealctl", "agent"]);
440
+ var CLIENT_AUDIENCE_SET = new Set(CLIENT_AUDIENCES);
441
+
442
+ // packages/ceal-client-protocol/src/schema-literals.ts
443
+ var CEAL_SCHEMA_LITERALS = [
444
+ "ceal.activation_transport.v1",
445
+ "ceal.capability_access.v1",
446
+ CEAL_OPERATION_CATALOG_SCHEMA_VERSION,
447
+ "ceal.client_refresh_request.v2",
448
+ "ceal.client_refresh_result.v2",
449
+ "ceal.client_revoke_request.v1",
450
+ "ceal.client_revoke_result.v1",
451
+ CEAL_COMMAND_REQUEST_SCHEMA_VERSION,
452
+ "ceal.device_enrollment_challenge.v1",
453
+ "ceal.device_enrollment_challenge_request.v1",
454
+ "ceal.device_enrollment_hpke_aad.v1",
455
+ "ceal.device_enrollment_hpke_info.v1",
456
+ "ceal.device_enrollment_poll.v1",
457
+ "ceal.device_enrollment_poll_result.v1",
458
+ "ceal.device_enrollment_proof.v1",
459
+ "ceal.device_enrollment_start.v1",
460
+ "ceal.device_enrollment_start_result.v1",
461
+ "ceal.effect_approval.v1",
462
+ "ceal.effect_approval_confirmation.v1",
463
+ "ceal.enrollment_create.v1",
464
+ "ceal.enrollment_create_result.v1",
465
+ "ceal.enrollment_exchange.v1",
466
+ "ceal.enrollment_result.v1",
467
+ "ceal.first_activation_causal_join.v1",
468
+ "ceal.gateway_aggregate_authorization_snapshot.v2",
469
+ "ceal.gateway_announcement_policy.v1",
470
+ "ceal.gateway_audit_call_detail.v1",
471
+ "ceal.gateway_audit_event.v1",
472
+ "ceal.gateway_audit_readback.v1",
473
+ "ceal.gateway_authorization_snapshot.v1",
474
+ "ceal.gateway_cache_origin.v1",
475
+ "ceal.gateway_call_result.v1",
476
+ "ceal.gateway_command_resolution.v1",
477
+ "ceal.gateway_connector_route_failure.v1",
478
+ "ceal.gateway_discovery.v3",
479
+ "ceal.gateway_handshake.v1",
480
+ "ceal.gateway_installation_activation_code_issue_request.v1",
481
+ "ceal.gateway_installation_activation_code_issue_result.v1",
482
+ "ceal.gateway_installation_activation_code_list_result.v1",
483
+ "ceal.gateway_installation_activation_code_revoke_request.v1",
484
+ "ceal.gateway_installation_activation_code_revoke_result.v1",
485
+ "ceal.gateway_installation_activation_credential.v1",
486
+ "ceal.gateway_installation_activation_request.v1",
487
+ "ceal.gateway_installation_active_state.v1",
488
+ "ceal.gateway_installation_list_result.v1",
489
+ "ceal.gateway_installation_revoke_request.v1",
490
+ "ceal.gateway_installation_revoke_result.v1",
491
+ "ceal.gateway_policy_denial.v1",
492
+ "ceal.gateway_rate_limit_policy.v1",
493
+ "ceal.gateway_refresh_audit_detail.v1",
494
+ "ceal.gateway_scoped_identity_projection.v1",
495
+ "ceal.gateway_write_receipt_readback.v1",
496
+ "ceal.gateway_write_request_receipt.v1",
497
+ "ceal.host_observation.v1",
498
+ "ceal.host_registration_request.v1",
499
+ "ceal.host_registration_result.v1",
500
+ "ceal.leased-resource-stream.v2",
501
+ "ceal.leased_consumer_attachment_stream_frame.v2",
502
+ "ceal.leased_consumer_attachment_stream_request.v2",
503
+ "ceal.leased_consumer_attachment_stream_transport.v2",
504
+ "ceal.operation_descriptor.v1",
505
+ "ceal.operation_error.v1",
506
+ "ceal.operation_failure.v1",
507
+ "ceal.operation_receipt.v1",
508
+ "ceal.operation_result.v1",
509
+ "ceal.operation_result.compact.v1",
510
+ "ceal.local_result_materialization.v1",
511
+ "ceal.local_result_root.v1",
512
+ "ceal.owner_bootstrap_exchange_request.v1",
513
+ "ceal.owner_bootstrap_exchange_result.v1",
514
+ "ceal.protocol_negotiation.v1",
515
+ "ceal.request.v1",
516
+ "ceal.request_artifact.v1",
517
+ "ceal.request_cancellation.v1",
518
+ "ceal.request_graph_revision.v1",
519
+ "ceal.request_occurrence_correlation.v1",
520
+ "ceal.request_projection.v1"
521
+ ];
522
+ var CEAL_SCHEMA_LITERAL_SET = new Set(CEAL_SCHEMA_LITERALS);
523
+
524
+ // packages/ceal-client-protocol/src/bounded-series.ts
525
+ import { join } from "node:path";
526
+ var CEAL_BOUNDED_SERIES_CATALOG = Object.freeze({
527
+ usage_record: (root) => join(root, "run-usage.jsonl"),
528
+ control_commit: (root) => join(root, "control-auto-commit.jsonl"),
529
+ engagement_signal: (root) => join(root, "runtime-state", "slack-feedback.jsonl"),
530
+ runtime_error: (root) => join(root, "runtime-state", "runtime-errors.jsonl"),
531
+ turn_bridge_request: (root) => join(root, ".ceal", "turn-bridge", "requests.jsonl"),
532
+ channel_log: (root) => join(root, "log.jsonl"),
533
+ thread_run_events: (root) => join(root, "run-events.jsonl"),
534
+ bounded_store_sidecar: (root) => `${root}.jsonl`,
535
+ gateway_audit_archive: (root) => `${root}.jsonl`,
536
+ gateway_capability_audit: (root) => join(root, "capability-audit.jsonl"),
537
+ gateway_retrieval_waste_partition: (root) => `${root}.jsonl`,
538
+ gateway_access_policy_publication: (root) => join(root, "access-policy-publications.jsonl"),
539
+ gateway_profile_connector_control_audit: (root) => `${root}.audit.jsonl`,
540
+ gateway_profile_connector_scope_audit: (root) => join(root, "profile-connector-scope-audit.jsonl"),
541
+ gateway_profile_connector_activity_scope_audit: (root) => join(root, "profile-connector-activity-scope-audit.jsonl"),
542
+ gateway_profile_connector_readiness_audit: (root) => join(root, "profile-connector-readiness.audit.jsonl"),
543
+ gateway_organization_audit_ledger: (root) => join(root, "organization-ledger.jsonl"),
544
+ gateway_personal_client_audit: (root) => join(root, "audit.jsonl"),
545
+ gateway_personal_client_access_audit: (root) => join(root, "access-audit.jsonl"),
546
+ gateway_admin_enrollment: (root) => join(root, "enrollments.jsonl"),
547
+ gateway_admin_login: (root) => join(root, "logins.jsonl"),
548
+ gateway_admin_family: (root) => join(root, "families.jsonl"),
549
+ gateway_admin_refresh_token: (root) => join(root, "refresh-tokens.jsonl"),
550
+ gateway_admin_access_token: (root) => join(root, "access-tokens.jsonl")
551
+ });
552
+
553
+ // packages/ceal-client-protocol/src/gateway-installation-activation.ts
554
+ var CEAL_GATEWAY_INSTALLATION_ACTIVATION_CODE_DATA_CHARACTERS = 32;
555
+ var CEAL_GATEWAY_INSTALLATION_ACTIVATION_CODE_CHECK_CHARACTERS = 8;
556
+ var CEAL_GATEWAY_INSTALLATION_ACTIVATION_CODE_COMPACT_CHARACTERS = CEAL_GATEWAY_INSTALLATION_ACTIVATION_CODE_DATA_CHARACTERS + CEAL_GATEWAY_INSTALLATION_ACTIVATION_CODE_CHECK_CHARACTERS;
557
+
558
+ // packages/ceal-client-protocol/src/host-registration.ts
559
+ var CEAL_HOST_REGISTRATION_RESULT_KEYS = Object.freeze(["credential_generation", "host_access_token", "host_installation_ref", "host_source_ref", "ok", "registration_attempt_ref", "schema_version", "status"]);
560
+
561
+ // packages/ceal-client-protocol/src/agent-session-handoff.ts
562
+ var CEAL_AGENT_ADMISSION_PHASES = vocabulary([
563
+ "incumbent_admitted",
564
+ "incumbent_draining",
565
+ "drained",
566
+ "candidate_admitted",
567
+ "candidate_draining",
568
+ "rollback_admitted"
569
+ ]);
570
+ var CEAL_AGENT_SERVICE_SESSION_RECORD_KEYS = vocabulary([
571
+ "admission_fence",
572
+ "admission_state",
573
+ "admission_state_generation",
574
+ "bearer",
575
+ "consumer_ref",
576
+ "credential_generation",
577
+ "expires_at",
578
+ "gateway_instance",
579
+ "gateway_origin",
580
+ "gateway_serving_generation",
581
+ "issued_at",
582
+ "record_sha256",
583
+ "renew_after",
584
+ "renew_by",
585
+ "schema_version",
586
+ "session_revision"
587
+ ]);
588
+ var CEAL_AGENT_SESSION_COMMIT_KEYS = vocabulary(["attempt_ref", "expected_session_revision", "session_revision"]);
589
+
590
+ // packages/ceal-client-protocol/src/operation-next-actions.ts
591
+ var CALLER_RECOVERABLE_NEXT_ACTION_VALUES = [
592
+ "select_did_you_mean",
593
+ // The graph, not the argument list, is what the caller must change: the
594
+ // resolver that owns this input has no producing node upstream, and no edit
595
+ // to the invocation can conjure one. `resolver_dependency_absent` carried no
596
+ // remedy at all rather than borrow a word that means something else, so the
597
+ // scorer read a fully-diagnosed, caller-fixable refusal as a failed run.
598
+ "request.graph.append",
599
+ "choose_new_output_path",
600
+ "choose_new_idempotency_key",
601
+ "restart_search",
602
+ "repeat_original_arguments",
603
+ "choose_new_request_identity",
604
+ // A refusal that names the argument (invalid_argument with `property`) tells the caller exactly what to change.
605
+ "correct_argument",
606
+ // A resolver-owned input must move from caller operands into the declared
607
+ // resolver selection field.
608
+ "supply_resolver_selections",
609
+ // The graph names an upstream node whose Operation produces the resolver's
610
+ // occurrence, and it has not produced one yet. The caller runs that node
611
+ // first; the refusal used to share a code with a malformed resolver result,
612
+ // which is not fixable, so neither could carry a remedy.
613
+ "run_resolver_dependency",
614
+ // A replay carries the input the occurrence durably admitted, and this one
615
+ // carries a different one. The caller fixes it by presenting the original
616
+ // invocation, so it is a remedy; the coordinator minted the word at the
617
+ // replay guard and never declared it, which read as unguided to the scorer.
618
+ "use_original_input",
619
+ // The same mismatch on the Request binding rather than the input: the
620
+ // occurrence was admitted under one binding and the replay presents another.
621
+ "use_original_request_binding"
622
+ ];
623
+ var CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS = Object.freeze(CALLER_RECOVERABLE_NEXT_ACTION_VALUES);
624
+ var NON_REMEDY_NEXT_ACTION_VALUES = [
625
+ "await_pending_approval",
626
+ "check_gateway",
627
+ "inspect_context_store",
628
+ "inspect_gateway",
629
+ "inspect_local_cache",
630
+ // The thin client prints these on its own behalf, before or after the wire.
631
+ // They were declared only as `CealClientLocalRemedy` keys and, for two of
632
+ // them, only as Go string literals -- a second and third vocabulary for one
633
+ // thing. `CealClientLocalRemedy` derives from this list now, so the client's
634
+ // remedies cannot drift from the words the protocol knows.
635
+ "inspect_local_client",
636
+ "inspect_local_command",
637
+ "inspect_local_output",
638
+ "inspect_local_route",
639
+ "inspect_receipt",
640
+ "inspect_request",
641
+ "none",
642
+ "recover",
643
+ "reconcile",
644
+ // Reconciliation of one named occurrence, not of the deployment: a legacy
645
+ // occurrence with no admitted input commitment cannot be replayed safely and
646
+ // no edit to the call changes that. `reconcile` is the deployment-wide word.
647
+ "reconcile_occurrence",
648
+ "reduce_request_size",
649
+ "repair_or_adopt_session",
650
+ "request.effect_approval.read",
651
+ "request.run",
652
+ "retry",
653
+ // The owner -- a correlation hook, an approval hook -- is not serving right
654
+ // now. The caller changes nothing and the same call succeeds once the owner
655
+ // is back, so this is not a remedy the scorer may count as guidance.
656
+ "retry_after_owner_recovery",
657
+ "retry_same_receipt_read",
658
+ "run_file_search_again",
659
+ "select_exact_approval"
660
+ ];
661
+ var CEAL_NON_REMEDY_NEXT_ACTIONS = Object.freeze(NON_REMEDY_NEXT_ACTION_VALUES);
662
+ var DECLARED = /* @__PURE__ */ new Set([...CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS, ...CEAL_NON_REMEDY_NEXT_ACTIONS]);
663
+ var RECOVERABLE = new Set(CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS);
664
+
665
+ // packages/ceal-client-protocol/src/operation-contract-artifact.ts
666
+ var CATALOG_REVISION = new RegExp(CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_PATTERN, "u");
667
+ var SHA256 = new RegExp(CEAL_VERIFIED_ARTIFACT_DIGEST_PATTERN, "u");
668
+ var CEAL_OPERATION_CONTRACT_REQUIRED_FIELDS = Object.freeze(["input_schema", "result_schema"]);
669
+ var CEAL_OPERATION_CONTRACT_OPTIONAL_FIELDS = Object.freeze(["summary", "input_resolution"]);
670
+ var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_JSON_SCHEMA = Object.freeze({
671
+ $schema: CEAL_JSON_SCHEMA_2020_12,
672
+ $id: "https://ceal.dev/schemas/verified-artifact-descriptor.v1.schema.json",
673
+ title: "Ceal verified artifact descriptor",
674
+ type: "object",
675
+ additionalProperties: false,
676
+ required: ["schema_version", "kind", "media_type", "byte_count", "sha256", "binding"],
677
+ properties: {
678
+ schema_version: { const: CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_SCHEMA_VERSION },
679
+ kind: { const: CEAL_VERIFIED_ARTIFACT_KIND },
680
+ media_type: { const: CEAL_VERIFIED_ARTIFACT_MEDIA_TYPE },
681
+ byte_count: { type: "integer", minimum: 1, maximum: CEAL_VERIFIED_ARTIFACT_MAX_BYTES },
682
+ sha256: { type: "string", minLength: CEAL_VERIFIED_ARTIFACT_DIGEST_LENGTH, maxLength: CEAL_VERIFIED_ARTIFACT_DIGEST_LENGTH, pattern: CEAL_VERIFIED_ARTIFACT_DIGEST_PATTERN },
683
+ binding: {
684
+ type: "object",
685
+ additionalProperties: false,
686
+ required: ["schema_version", "kind", "catalog_revision"],
687
+ properties: {
688
+ schema_version: { const: CEAL_VERIFIED_ARTIFACT_BINDING_SCHEMA_VERSION },
689
+ kind: { const: CEAL_VERIFIED_ARTIFACT_BINDING_KIND },
690
+ catalog_revision: { type: "string", minLength: CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_LENGTH, maxLength: CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_LENGTH, pattern: CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_PATTERN }
691
+ }
692
+ }
693
+ }
694
+ });
695
+
696
+ // packages/ceal-client-protocol/src/operation-occurrence.ts
697
+ var MAX_RECEIPT_REVISION = Number.MAX_SAFE_INTEGER - 1;
698
+
699
+ // packages/ceal-client-protocol/src/leased-resource-stream.ts
700
+ var CEAL_LEASED_CONSUMER_ATTACHMENT_STREAM_MAGIC = new Uint8Array([67, 69, 65, 76, 82, 83, 50, 0]);
701
+ var CEAL_LEASED_CONSUMER_ATTACHMENT_STREAM_RECORD_PREFIX_BYTES = 8;
702
+ var CEAL_LEASED_CONSUMER_ATTACHMENT_STREAM_MAX_HEADER_BYTES = 16 * 1024;
703
+ var CEAL_LEASED_CONSUMER_ATTACHMENT_STREAM_CHUNK_BYTES = 64 * 1024;
704
+ var CEAL_LEASED_CONSUMER_ATTACHMENT_STREAM_MAX_RECORD_BYTES = CEAL_LEASED_CONSUMER_ATTACHMENT_STREAM_RECORD_PREFIX_BYTES + CEAL_LEASED_CONSUMER_ATTACHMENT_STREAM_MAX_HEADER_BYTES + CEAL_LEASED_CONSUMER_ATTACHMENT_STREAM_CHUNK_BYTES;
705
+ var CEAL_ATTACHMENT_UNREAD_REASONS = vocabulary(["blocked", "unavailable", "too_large", "unsupported", "download_failed", "digest_mismatch"]);
706
+
707
+ // packages/ceal-client-protocol/src/request-validation-primitives.ts
708
+ import { createHash } from "node:crypto";
709
+ var DIGEST = /^[a-f0-9]{64}$/u;
710
+ function isCealDigest(value) {
711
+ return typeof value === "string" && DIGEST.test(value);
712
+ }
713
+ function cealRequestSha256(value) {
714
+ return createHash("sha256").update(cealCanonicalJson(value), "utf8").digest("hex");
715
+ }
716
+ function operationRecord(value, message) {
717
+ requireOperationRecord(value, message);
718
+ return value;
719
+ }
720
+ function invalid(message) {
721
+ throw new TypeError(message);
722
+ }
723
+ function requirePrefixedRef(value, prefix, message) {
724
+ if (typeof value !== "string" || !SAFE_REF.test(value) || !value.startsWith(prefix)) invalid(message);
725
+ }
726
+
727
+ // packages/ceal-client-protocol/src/request-authority.ts
728
+ var CEAL_REQUEST_SCHEMA_VERSION = "ceal.request.v1";
729
+ var CEAL_REQUEST_ARTIFACT_OWNERS = vocabulary(["gateway", "host", "connector"]);
730
+ var CEAL_REQUEST_HOST_BINDING_KEYS = vocabulary(["prompt_ref", "host_session_ref", "host_turn_ref", "host_source_ref"]);
731
+ var CEAL_REQUEST_ARTIFACT_RETENTION_CLASSES = vocabulary(["request", "source", "result"]);
732
+ var CANCELLATION_STATES = vocabulary(["requested", "cancelled"]);
733
+ var CEAL_REQUEST_KEYS = Object.freeze(["schema_version", "ceal_request_ref", "created_at", "authority", "prompt_ref", "host_session_ref", "host_turn_ref", "host_source_ref"]);
734
+ var CEAL_REQUEST_JSON_SCHEMA = {
735
+ type: "object",
736
+ maxProperties: 9,
737
+ additionalProperties: false,
738
+ properties: {
739
+ schema_version: { type: "string", const: CEAL_REQUEST_SCHEMA_VERSION, maxLength: 32 },
740
+ ceal_request_ref: { type: "string", minLength: 1, maxLength: 128, pattern: "^ceal-request:[A-Za-z0-9][A-Za-z0-9._:-]{0,114}$" },
741
+ created_at: { type: "string", minLength: 1, maxLength: 64 },
742
+ authority: {
743
+ type: "object",
744
+ maxProperties: 5,
745
+ additionalProperties: false,
746
+ properties: {
747
+ instance_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
748
+ profile_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
749
+ principal_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
750
+ execution_subject_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
751
+ authority_revision_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source }
752
+ },
753
+ required: ["instance_ref", "profile_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]
754
+ },
755
+ prompt_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
756
+ host_session_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
757
+ host_turn_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
758
+ host_input_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
759
+ host_source_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source }
760
+ },
761
+ required: CEAL_REQUEST_KEYS
762
+ };
763
+
764
+ // packages/ceal-client-protocol/src/request-operands.ts
765
+ var CEAL_REQUEST_MAX_RESOLVER_SELECTIONS = 128;
766
+ var CEAL_REQUEST_MAX_SELECTOR_PROPERTIES = 16;
767
+ var CEAL_REQUEST_MAX_SELECTOR_VALUE_LENGTH = 1024;
768
+ var CEAL_REQUEST_RESOLVER_SELECTION_JSON_SCHEMA = {
769
+ type: "object",
770
+ maxProperties: 2,
771
+ additionalProperties: false,
772
+ properties: {
773
+ property: { type: "string", minLength: 1, maxLength: 128 },
774
+ selectors: {
775
+ type: "object",
776
+ maxProperties: CEAL_REQUEST_MAX_SELECTOR_PROPERTIES,
777
+ properties: {},
778
+ additionalProperties: { type: "string", minLength: 1, maxLength: CEAL_REQUEST_MAX_SELECTOR_VALUE_LENGTH }
779
+ }
780
+ },
781
+ required: ["property", "selectors"]
782
+ };
783
+
784
+ // packages/ceal-client-protocol/src/request-graph.ts
785
+ var CEAL_REQUEST_MAX_GRAPH_NODES = 128;
786
+
787
+ // packages/ceal-client-protocol/src/request-run.ts
788
+ var CEAL_REQUEST_NODE_STANDING_OCCURRENCE_SCHEMA_VERSION = "ceal.request_node_standing_occurrence.v1";
789
+ var CEAL_REQUEST_RUN_BATCH_SCHEMA_VERSION = "ceal.request_run_batch.v3";
790
+ var REQUEST_ACTION_SAFE_REF_SCHEMA = { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source };
791
+ var REQUEST_ACTION_DIGEST_SCHEMA = { type: "string", minLength: 64, maxLength: 64, pattern: "^[a-f0-9]{64}$" };
792
+ var REQUEST_NODE_STANDING_OCCURRENCE_SCHEMA = {
793
+ type: "object",
794
+ maxProperties: 9,
795
+ additionalProperties: false,
796
+ properties: {
797
+ schema_version: { type: "string", const: CEAL_REQUEST_NODE_STANDING_OCCURRENCE_SCHEMA_VERSION, maxLength: 64 },
798
+ node_ref: REQUEST_ACTION_SAFE_REF_SCHEMA,
799
+ operation_id: REQUEST_ACTION_SAFE_REF_SCHEMA,
800
+ correlation_ref: REQUEST_ACTION_SAFE_REF_SCHEMA,
801
+ occurrence_ref: REQUEST_ACTION_SAFE_REF_SCHEMA,
802
+ graph_revision: { type: "integer", minimum: 1, maximum: Number.MAX_SAFE_INTEGER },
803
+ graph_revision_digest: REQUEST_ACTION_DIGEST_SCHEMA,
804
+ admitted_input_sha256: REQUEST_ACTION_DIGEST_SCHEMA,
805
+ reason: { type: "string", minLength: 1, maxLength: 1024 }
806
+ },
807
+ required: ["schema_version", "node_ref", "operation_id", "correlation_ref", "occurrence_ref", "graph_revision", "graph_revision_digest", "admitted_input_sha256", "reason"]
808
+ };
809
+ var REQUEST_EXECUTION_PREPARE_REFUSAL_SCHEMA = {
810
+ type: "object",
811
+ additionalProperties: false,
812
+ maxProperties: 9,
813
+ properties: {
814
+ schema_version: { type: "string", const: CEAL_OPERATION_ERROR_SCHEMA_VERSION, maxLength: 64 },
815
+ code: REQUEST_ACTION_SAFE_REF_SCHEMA,
816
+ message: { type: "string", minLength: 1, maxLength: 2048 },
817
+ property: { type: "string", minLength: 1, maxLength: 256 },
818
+ next_action: REQUEST_ACTION_SAFE_REF_SCHEMA,
819
+ retryable: { type: "boolean" },
820
+ repaired_input: {},
821
+ unrepaired_pointers: { type: "array", maxItems: 128, items: { type: "string", minLength: 1, maxLength: 256 } },
822
+ provider_handoff: { type: "string", const: "not_offered", maxLength: 32 }
823
+ },
824
+ required: ["schema_version", "code", "message", "next_action", "retryable"]
825
+ };
826
+ var CEAL_REQUEST_EXECUTION_ORDERS = vocabulary(["graph_dependency", "caller"]);
827
+ var CEAL_REQUEST_CALL_BUDGET_JSON_SCHEMA = {
828
+ type: "object",
829
+ additionalProperties: false,
830
+ maxProperties: 2,
831
+ properties: {
832
+ gateway_calls_so_far: { type: "integer", minimum: 1, maximum: Number.MAX_SAFE_INTEGER },
833
+ floor_for_this_graph: { type: "integer", minimum: 1, maximum: Number.MAX_SAFE_INTEGER }
834
+ },
835
+ required: ["gateway_calls_so_far", "floor_for_this_graph"]
836
+ };
837
+ var CEAL_REQUEST_RUN_BATCH_JSON_SCHEMA = {
838
+ type: "object",
839
+ additionalProperties: false,
840
+ maxProperties: 5,
841
+ properties: {
842
+ schema_version: { type: "string", const: CEAL_REQUEST_RUN_BATCH_SCHEMA_VERSION, maxLength: 64 },
843
+ order: { enum: [...CEAL_REQUEST_EXECUTION_ORDERS] },
844
+ nodes: {
845
+ type: "array",
846
+ minItems: 1,
847
+ maxItems: CEAL_REQUEST_MAX_GRAPH_NODES,
848
+ items: {
849
+ // The runtime validator owns "exactly one of a result, a refusal
850
+ // and a standing run". The result envelope already names the
851
+ // Operation that ran.
852
+ type: "object",
853
+ additionalProperties: false,
854
+ maxProperties: 4,
855
+ properties: { node_ref: REQUEST_ACTION_SAFE_REF_SCHEMA, result: {}, refusal: REQUEST_EXECUTION_PREPARE_REFUSAL_SCHEMA, standing: REQUEST_ACTION_SAFE_REF_SCHEMA },
856
+ required: ["node_ref"]
857
+ }
858
+ },
859
+ standing_reading: { type: "string", minLength: 1, maxLength: 512 },
860
+ call_budget: CEAL_REQUEST_CALL_BUDGET_JSON_SCHEMA
861
+ },
862
+ required: ["schema_version", "order", "nodes", "call_budget"]
863
+ };
864
+
865
+ // packages/ceal-client-protocol/src/host-observation.ts
866
+ var CEAL_HOST_OBSERVATION_REF_PREFIX = "host-observation:";
867
+ function validateCealHostObservationDraft(value) {
868
+ const record6 = operationRecord(value, "Ceal Host observation draft is invalid.");
869
+ requirePrefixedRef(record6.observation_ref, CEAL_HOST_OBSERVATION_REF_PREFIX, "Ceal Host observation reference is invalid.");
870
+ requireClosedValue(record6.observation_kind, CEAL_HOST_OBSERVATION_KINDS, "Ceal Host observation kind is invalid.");
871
+ requireIsoTimestamp(record6.observed_at, "Ceal Host observation time is invalid.");
872
+ assertHostObservationValue(record6.value, record6.observation_kind);
873
+ }
874
+ var CEAL_REQUEST_MAX_OBSERVATION_VALUE_BYTES = 64 * 1024;
875
+ var CEAL_HOST_OBSERVATION_KINDS = vocabulary(["prompt", "session", "turn", "model", "token", "cost", "timing"]);
876
+ function isCealHostPromptObservationValue(value) {
877
+ return isOperationRecord(value) && Object.keys(value).length === 1 && isCealDigest(value.body_sha256);
878
+ }
879
+ var HOST_RESERVED_KEY = /^(?:admission|approval|audit|authorization|cancellation|capability|effect|grant|occurrence|operation|policy|profile|provider_readback|receipt|reconciliation|replay|target|write_request)(?:_|$)/iu;
880
+ function assertHostObservationValue(value, kind) {
881
+ if (value === void 0) invalid("Ceal Host observation value is invalid.");
882
+ if (kind === "prompt" && !isCealHostPromptObservationValue(value)) invalid("Ceal Host prompt observation must contain only its body digest.");
883
+ assertSafeJsonValue(value, { forbidAuthorityKeys: true, maxNodes: 512 });
884
+ if (byteLength(JSON.stringify(value) ?? "") > CEAL_REQUEST_MAX_OBSERVATION_VALUE_BYTES) invalid("Ceal Host observation value is oversized.");
885
+ inspectHostKeys(value);
886
+ }
887
+ function inspectHostKeys(value) {
888
+ if (Array.isArray(value)) {
889
+ for (const entry of value) inspectHostKeys(entry);
890
+ return;
891
+ }
892
+ if (value === null || typeof value !== "object") return;
893
+ for (const [key, child] of Object.entries(value)) {
894
+ if (HOST_RESERVED_KEY.test(key)) invalid("Ceal Host observation cannot restate Gateway-owned facts.");
895
+ inspectHostKeys(child);
896
+ }
897
+ }
898
+
899
+ // packages/ceal-client-protocol/src/request-effect-approval.ts
900
+ var CEAL_EFFECT_APPROVAL_DECISION_CHECK_PHRASES = Object.freeze([
901
+ "observed after this approval was raised and before it expires",
902
+ "from this same Host session and Host source",
903
+ "not the Host input that opened the Request",
904
+ "an input that has decided no other approval"
905
+ ]);
906
+ var CEAL_EFFECT_APPROVAL_DECISION_INSTRUCTION = `Submit exactly one phrase below in a Host input ${CEAL_EFFECT_APPROVAL_DECISION_CHECK_PHRASES.join(", ")}.`;
907
+
908
+ // packages/ceal-client-protocol/src/request-projection.ts
909
+ var CEAL_REQUEST_STATUSES = vocabulary(["pending", "partial", "completed", "cancelled", "failed", "unknown_effect", "reconciled", "incomplete", "contradiction"]);
910
+ var OWNER_WRITE_STATES = Object.freeze(["attempt_started", "provider_acknowledged", "verified", "outcome_unknown", "reconciled"]);
911
+ var OWNER_EFFECT_STATES = Object.freeze(["none", "applied", "failed", "unknown", "reconciled"]);
912
+ var OWNER_RECEIPT_STATES = Object.freeze(["pending", "available", "failed", "unknown", "reconciled"]);
913
+
914
+ // packages/ceal-client-protocol/src/request-graph-readiness.ts
915
+ var REQUEST_GRAPH_PRODUCER_TO_APPEND_SCHEMA = {
916
+ type: "object",
917
+ maxProperties: 4,
918
+ additionalProperties: false,
919
+ properties: {
920
+ operation_id: { type: "string", minLength: 1, maxLength: 128 },
921
+ edge_to_node_ref: { type: "string", minLength: 1, maxLength: 128 },
922
+ edge_from_node_refs: { type: "array", minItems: 1, maxItems: CEAL_REQUEST_MAX_GRAPH_NODES, items: { type: "string", minLength: 1, maxLength: 128 } },
923
+ remedy: { type: "string", minLength: 1, maxLength: 512 }
924
+ },
925
+ required: ["operation_id", "edge_to_node_ref", "remedy"]
926
+ };
927
+ var REQUEST_GRAPH_RESOLVER_CONSUMERS_SCHEMA = {
928
+ type: "object",
929
+ maxProperties: 2,
930
+ additionalProperties: false,
931
+ properties: {
932
+ consumer_node_refs: { type: "array", minItems: 1, maxItems: CEAL_REQUEST_MAX_GRAPH_NODES, items: { type: "string", minLength: 1, maxLength: 128 } },
933
+ remedy: { type: "string", minLength: 1, maxLength: 512 }
934
+ },
935
+ required: ["consumer_node_refs", "remedy"]
936
+ };
937
+ var REQUEST_GRAPH_RESOLVER_REUSE_SCHEMA = {
938
+ type: "object",
939
+ maxProperties: 3,
940
+ additionalProperties: false,
941
+ properties: {
942
+ reuse_node_ref: { type: "string", minLength: 1, maxLength: 128 },
943
+ consumer_node_refs: { type: "array", maxItems: CEAL_REQUEST_MAX_GRAPH_NODES, items: { type: "string", minLength: 1, maxLength: 128 } },
944
+ remedy: { type: "string", minLength: 1, maxLength: 512 }
945
+ },
946
+ required: ["reuse_node_ref", "consumer_node_refs", "remedy"]
947
+ };
948
+ var RESOLVER_OWNED_INPUT_SCHEMA = {
949
+ type: "object",
950
+ maxProperties: 5,
951
+ additionalProperties: false,
952
+ properties: {
953
+ property: { type: "string", minLength: 1, maxLength: 128 },
954
+ resolver_operation_id: { type: "string", minLength: 1, maxLength: 128 },
955
+ resolver_selection_template: CEAL_REQUEST_RESOLVER_SELECTION_JSON_SCHEMA,
956
+ producing_node_refs: { type: "array", maxItems: CEAL_REQUEST_MAX_RESOLVER_SELECTIONS, items: { type: "string", minLength: 1, maxLength: 128 } },
957
+ append_producer: REQUEST_GRAPH_PRODUCER_TO_APPEND_SCHEMA
958
+ },
959
+ required: ["property", "resolver_operation_id", "producing_node_refs"]
960
+ };
961
+ var USER_OPERANDS_TEMPLATE_SCHEMA = {
962
+ type: "object",
963
+ maxProperties: 2,
964
+ additionalProperties: false,
965
+ properties: {
966
+ required_properties: { type: "array", maxItems: MAX_OPERATION_INPUT_RESOLVER_BINDINGS, items: { type: "string", minLength: 1, maxLength: 128 } },
967
+ operands: { type: "object", properties: {}, maxProperties: MAX_OPERATION_INPUT_RESOLVER_BINDINGS, additionalProperties: {} }
968
+ },
969
+ required: ["required_properties", "operands"]
970
+ };
971
+ var CEAL_REQUEST_GRAPH_NODE_PREPARE_READINESS_JSON_SCHEMA = {
972
+ type: "object",
973
+ maxProperties: 9,
974
+ additionalProperties: false,
975
+ properties: {
976
+ node_ref: { type: "string", minLength: 1, maxLength: 128 },
977
+ operation_id: { type: "string", minLength: 1, maxLength: 128 },
978
+ resolver_owned: { type: "array", maxItems: MAX_OPERATION_INPUT_RESOLVER_BINDINGS, items: RESOLVER_OWNED_INPUT_SCHEMA },
979
+ gateway_derived: { type: "array", maxItems: MAX_OPERATION_INPUT_RESOLVER_BINDINGS, items: { type: "string", minLength: 1, maxLength: 128 } },
980
+ result_bound: { type: "array", maxItems: MAX_OPERATION_INPUT_RESOLVER_BINDINGS, items: { type: "string", minLength: 1, maxLength: 128 } },
981
+ user_operands_template: { type: "array", maxItems: CEAL_OPERATION_JSON_SCHEMA_BUDGET.max_alternatives, items: USER_OPERANDS_TEMPLATE_SCHEMA },
982
+ unfed_resolver: REQUEST_GRAPH_RESOLVER_CONSUMERS_SCHEMA,
983
+ redundant_resolver: REQUEST_GRAPH_RESOLVER_REUSE_SCHEMA,
984
+ standing_occurrence: REQUEST_NODE_STANDING_OCCURRENCE_SCHEMA
985
+ },
986
+ required: ["node_ref", "operation_id", "resolver_owned", "gateway_derived"]
987
+ };
988
+
989
+ // packages/ceal-client-protocol/src/host-invocation-authentication.ts
990
+ var CEAL_HOST_INVOCATION_AUTHENTICATION_REQUEST_SCHEMA = "ceal.host_invocation_authentication_request.v1";
991
+ var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA = "ceal.host_invocation_authentication_result.v1";
992
+ var CEAL_HOST_CLIENT_NONCE_PATTERN = /^[A-Za-z0-9_-]{43}$/u;
993
+ var CEAL_HOST_CONTEXT_TOKEN_PATTERN = /^ceal_context_[A-Za-z0-9_-]{43}$/u;
994
+ function decodeCealHostInvocationAuthenticationRequest(value) {
995
+ if (!isCealJsonRecord(value) || !exactKeys(value, ["schema_version", "client_nonce"]) || value.schema_version !== CEAL_HOST_INVOCATION_AUTHENTICATION_REQUEST_SCHEMA || typeof value.client_nonce !== "string" || !CEAL_HOST_CLIENT_NONCE_PATTERN.test(value.client_nonce)) {
996
+ throw new TypeError("The Host invocation authentication request is invalid.");
997
+ }
998
+ return Object.freeze({ schema_version: CEAL_HOST_INVOCATION_AUTHENTICATION_REQUEST_SCHEMA, client_nonce: value.client_nonce });
999
+ }
1000
+ function decodeCealHostInvocationAuthenticationResult(value, now = /* @__PURE__ */ new Date()) {
1001
+ if (!isCealJsonRecord(value) || !exactKeys(value, ["schema_version", "context_token", "expires_at"]) || value.schema_version !== CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA || typeof value.context_token !== "string" || !CEAL_HOST_CONTEXT_TOKEN_PATTERN.test(value.context_token) || typeof value.expires_at !== "string" || !validFutureTimestamp(value.expires_at, now)) {
1002
+ throw new TypeError("The Host invocation authentication result is invalid.");
1003
+ }
1004
+ return Object.freeze({ schema_version: CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA, context_token: value.context_token, expires_at: value.expires_at });
1005
+ }
1006
+ function validFutureTimestamp(value, now) {
1007
+ const timestamp4 = Date.parse(value);
1008
+ return Number.isFinite(timestamp4) && new Date(timestamp4).toISOString() === value && timestamp4 > now.getTime();
1009
+ }
1010
+ function exactKeys(value, expected) {
1011
+ const keys = Object.keys(value);
1012
+ return keys.length === expected.length && expected.every((key) => Object.hasOwn(value, key));
1013
+ }
1014
+
1015
+ // packages/ceal-client-protocol/src/client-result-materialization.ts
1016
+ var REQUIRED_FIELDS = Object.freeze(["schema_version", "operation_id", "local_path", "content_json_pointer", "size_bytes", "sha256", "read_argv"]);
1017
+ var FIELDS = /* @__PURE__ */ new Set([...REQUIRED_FIELDS, "local_result_root", "model_disclosure"]);
1018
+
1019
+ // packages/ceal-client-protocol/src/profile-readback.ts
1020
+ function cealAuthenticatedProfileReadback(value) {
1021
+ if (!isProfileReadResult(value)) return null;
1022
+ const receipt = value.operation_receipt;
1023
+ if (!isUnaffectingAvailableReceipt(receipt)) return null;
1024
+ const authority = receipt.authority;
1025
+ if (!isCealJsonRecord(authority) || typeof authority.instance_ref !== "string" || typeof authority.profile_ref !== "string") return null;
1026
+ return Object.freeze({ instance_ref: authority.instance_ref, profile_ref: authority.profile_ref });
1027
+ }
1028
+ function isProfileReadResult(value) {
1029
+ return isCealJsonRecord(value) && value.schema_version === "ceal.operation_result.v1" && value.ok === true && value.operation_id === "profile.read";
1030
+ }
1031
+ function isUnaffectingAvailableReceipt(value) {
1032
+ return isCealJsonRecord(value) && value.effect === "none" && value.provider_handoff === "not_offered" && isCealJsonRecord(value.terminal) && value.terminal.availability === "available";
1033
+ }
1034
+
1035
+ // packages/ceal-client-protocol/src/conversation-contracts.ts
1036
+ var CEAL_APPROVAL_POLICY_KINDS = vocabulary(["requester_only", "named_users", "role_based"]);
1037
+ var CEAL_APPROVAL_TARGET_KINDS = vocabulary([
1038
+ "repo_change",
1039
+ "investigation",
1040
+ "skill_creation",
1041
+ "command_creation",
1042
+ "connector_creation",
1043
+ "generic"
1044
+ ]);
1045
+ var CEAL_PROGRESS_PHASES = vocabulary(["request_review", "information_gathering", "work_execution", "result_check"]);
1046
+
1047
+ // packages/ceal-client-protocol/src/gateway-cache-origin-validation.ts
1048
+ var CEAL_MAX_CACHE_ORIGIN_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
1049
+
1050
+ // packages/ceal-client-protocol/src/gateway-write-contract.ts
1051
+ var CEAL_GATEWAY_WRITE_CONTRACT_CLOSED_VOCABULARIES = Object.freeze({
1052
+ idempotency: CEAL_WRITE_IDEMPOTENCY_POSTURES,
1053
+ provider_readback: CEAL_WRITE_PROVIDER_READBACK_POSTURES,
1054
+ dry_run: Object.freeze(["supported", "unsupported"]),
1055
+ attribution: CEAL_WRITE_ATTRIBUTIONS,
1056
+ provenance_binding: Object.freeze(["gateway_attested_requester_event_v1"])
1057
+ });
1058
+ var REQUIRED_KEYS = Object.freeze(["side_effect_class", "idempotency", "provider_readback"]);
1059
+
1060
+ // packages/ceal-client-protocol/src/gateway-proof-claims.ts
1061
+ var CEAL_GATEWAY_PROOF_AXES = Object.freeze(["host_decision", "provider_execution", "production_audit"]);
1062
+ var CEAL_GATEWAY_PROOF_AXIS_NON_CLAIMS = Object.freeze({
1063
+ host_decision: null,
1064
+ provider_execution: "provider_execution_not_reached",
1065
+ production_audit: "production_audit_not_reached"
1066
+ });
1067
+ var CEAL_PROOF_LEVELS = vocabulary(["surface", "readiness", "worker_queued", "host_decision", "provider_roundtrip"]);
1068
+ var CEAL_GATEWAY_HOST_NON_CLAIM_ORDER = Object.freeze(["provider_execution_not_reached", "target_authorization_not_observed", "production_audit_not_reached"]);
1069
+ var CEAL_GATEWAY_ANNOUNCEMENT_POLICY_NON_CLAIMS = vocabulary([
1070
+ "policy_projection_does_not_authorize",
1071
+ "provider_roundtrip_not_established_by_discovery",
1072
+ "target_specific_scope_not_declared"
1073
+ ]);
1074
+
1075
+ // packages/ceal-client-protocol/src/gateway-discovery-response-validation.ts
1076
+ var ANNOUNCEMENT_POLICY_CAPABILITY_BINDINGS = Object.freeze({
1077
+ "github.repository.get": [{ effect: "read", scopeStatementKind: "github_app_installation_repositories", providerAuthorityKind: "github_app" }],
1078
+ "collection.search": [{ effect: "read", scopeStatementKind: "github_app_installation_repositories", providerAuthorityKind: "github_app" }],
1079
+ "github.issue.get": [{ effect: "read", scopeStatementKind: "github_app_installation_repositories", providerAuthorityKind: "github_app" }],
1080
+ "github.pull_request.get": [{ effect: "read", scopeStatementKind: "github_app_installation_repositories", providerAuthorityKind: "github_app" }],
1081
+ "github.workflow_run.get": [{ effect: "read", scopeStatementKind: "github_app_installation_repositories", providerAuthorityKind: "github_app" }],
1082
+ "message.search": [{ effect: "read", scopeStatementKind: "slack_public_app_member_channels_only", providerAuthorityKind: "slack_app" }],
1083
+ "message.get": [{ effect: "read", scopeStatementKind: "slack_public_app_member_channels_only", providerAuthorityKind: "slack_app" }],
1084
+ "resource.resolve": [
1085
+ { effect: "read", scopeStatementKind: "slack_public_app_member_channels_only", providerAuthorityKind: "slack_app" },
1086
+ { effect: "read", scopeStatementKind: "notion_connected_logical_area", providerAuthorityKind: "notion_integration" }
1087
+ ],
1088
+ "conversation.thread.get": [{ effect: "read", scopeStatementKind: "slack_public_app_member_channels_only", providerAuthorityKind: "slack_app" }],
1089
+ "notion.search": [{ effect: "read", scopeStatementKind: "notion_connected_logical_area", providerAuthorityKind: "notion_integration" }],
1090
+ "notion.page.get": [{ effect: "read", scopeStatementKind: "notion_connected_logical_area", providerAuthorityKind: "notion_integration" }],
1091
+ "calendar.availability": [{ effect: "read", scopeStatementKind: "google_workspace_calendar_read_only", providerAuthorityKind: "google_service_account" }],
1092
+ "calendar.event.search": [{ effect: "read", scopeStatementKind: "google_workspace_calendar_read_only", providerAuthorityKind: "google_service_account" }],
1093
+ "calendar.event.get": [{ effect: "read", scopeStatementKind: "google_workspace_calendar_read_only", providerAuthorityKind: "google_service_account" }],
1094
+ "file.search": [{ effect: "read", scopeStatementKind: "google_workspace_ceal_drive_or_direct_share_metadata", providerAuthorityKind: "google_service_account" }],
1095
+ "sheets.values.read": [{ effect: "read", scopeStatementKind: "google_workspace_ceal_drive_or_direct_share_sheet_ranges", providerAuthorityKind: "google_service_account" }],
1096
+ "sheets.tabs.list": [{ effect: "read", scopeStatementKind: "google_workspace_ceal_drive_or_direct_share_sheet_tabs", providerAuthorityKind: "google_service_account" }],
1097
+ "sheets.values.update": [{ effect: "write", scopeStatementKind: "google_workspace_ceal_drive_or_direct_share_editable_sheet_ranges", providerAuthorityKind: "google_service_account" }],
1098
+ "sheets.values.clear": [{ effect: "write", scopeStatementKind: "google_workspace_ceal_drive_or_direct_share_editable_sheet_clear_ranges", providerAuthorityKind: "google_service_account" }]
1099
+ });
1100
+ var ANNOUNCEMENT_SCOPE_STATEMENTS = Object.freeze({
1101
+ github_app_installation_repositories: "Repositories in the installed GitHub App installation.",
1102
+ slack_public_app_member_channels_only: "Public channels where the installed Slack app is a member; private channels, direct messages, multi-person direct messages, and requester membership are not declared by this connector.",
1103
+ notion_connected_logical_area: "Connected Notion logical area under provider-enforced sharing; descendant inventory is not declared.",
1104
+ google_workspace_calendar_read_only: "Approved Calendar availability and event reads only; Calendar mutation is not declared.",
1105
+ google_workspace_ceal_drive_or_direct_share_metadata: "Metadata search for files in the organization shared drive named Ceal Drive and files directly shared with the provider application; file-content read and mutation are not declared.",
1106
+ google_workspace_ceal_drive_or_direct_share_sheet_ranges: "Bounded values reads from governed Google Sheets in the organization shared drive named Ceal Drive and directly shared files; file mutation is not declared.",
1107
+ google_workspace_ceal_drive_or_direct_share_editable_sheet_ranges: "Bounded values updates in governed editable Google Sheets in the organization shared drive named Ceal Drive and directly shared files; Docs, Slides, and other Drive file mutation are not declared.",
1108
+ google_workspace_ceal_drive_or_direct_share_editable_sheet_clear_ranges: "Bounded values clears in governed editable Google Sheets in the organization shared drive named Ceal Drive and directly shared files; Docs, Slides, and other Drive file mutation are not declared."
1109
+ });
1110
+
1111
+ // packages/ceal-client-protocol/src/gateway-write-identity.ts
1112
+ var CEAL_GATEWAY_WRITE_IDENTITY_ROLES = Object.freeze(["replay_identity", "lookup_handle", "collision_evidence"]);
1113
+ var CEAL_GATEWAY_WRITE_IDENTITY_FIELDS = Object.freeze({
1114
+ replay_identity: "idempotency_claim_sha256",
1115
+ lookup_handle: "write_request_sha256",
1116
+ collision_evidence: "normalized_mutation_sha256"
1117
+ });
1118
+
1119
+ // packages/ceal-client-protocol/src/gateway-scoped-identity-projection-validation.ts
1120
+ var PROJECTION_REVISION_KEYS = Object.freeze(["graph_revision", "subject_key_revision", "projection_revision"]);
1121
+
1122
+ // packages/ceal-client-protocol/src/protocol-negotiation.ts
1123
+ var CEAL_SUPPORTED_GATEWAY_PROTOCOL_RANGE = Object.freeze({
1124
+ minimum: CEAL_PROTOCOL_VERSION,
1125
+ maximum: CEAL_PROTOCOL_VERSION
1126
+ });
1127
+
1128
+ // packages/ceal-client-protocol/src/admin-projection-vocabulary.ts
1129
+ var ADMIN_PROJECTION_STATES = vocabulary(["ready", "empty", "partial", "unknown"]);
1130
+ var ADMIN_VIEW_KINDS = vocabulary(["request_detail", "resource_access_timeline", "weekly_usage"]);
1131
+ var ADMIN_GAP_KINDS = vocabulary(["unknown", "unavailable", "partial"]);
1132
+ var ADMIN_UNAVAILABLE_REASONS = vocabulary([
1133
+ "not_recorded",
1134
+ "legacy",
1135
+ "invalid_observation",
1136
+ "redacted",
1137
+ "owner_unavailable",
1138
+ "unit_unknown",
1139
+ "retention_gap",
1140
+ "source_owner_limit"
1141
+ ]);
1142
+ var ADMIN_SOURCE_OWNERS = vocabulary([
1143
+ "request",
1144
+ "operation",
1145
+ "authority",
1146
+ "occurrence",
1147
+ "approval",
1148
+ "audit",
1149
+ "provider_readback",
1150
+ "host_observation",
1151
+ "person",
1152
+ "resource",
1153
+ "prompt",
1154
+ "usage"
1155
+ ]);
1156
+ var ADMIN_COMPLETENESS_STATES = vocabulary(["complete", "partial", "unknown"]);
1157
+ var ADMIN_OPERATION_OUTCOMES = vocabulary(["completed", "failed", "denied", "cancelled", "unknown"]);
1158
+ var ADMIN_APPROVAL_DISPOSITIONS = CEAL_OPERATION_APPROVAL_DISPOSITIONS;
1159
+ var ADMIN_APPROVAL_POSTURES = vocabulary([...ADMIN_APPROVAL_DISPOSITIONS, "not_applicable"]);
1160
+ var ADMIN_LINEAGE_NODE_KINDS = vocabulary(["source_read", "synthesis_preview", "approval", "effect", "readback"]);
1161
+
1162
+ // packages/ceal-client-protocol/src/actor-kind.ts
1163
+ var CEAL_ACTOR_KINDS = vocabulary(["human", "bot", "app", "unknown"]);
1164
+
1165
+ // packages/ceal-client-protocol/src/leased-consumer-vocabulary.ts
1166
+ var CEAL_TERMINAL_DISPOSITIONS = vocabulary(["completed", "failed", "cancelled"]);
1167
+ var CEAL_LEASE_DISPOSITIONS = vocabulary([...CEAL_TERMINAL_DISPOSITIONS, "deferred"]);
1168
+ var CEAL_AUTOMATIC_FEEDBACK_INTENTS = vocabulary(["initial"]);
1169
+ var CEAL_LEASED_MESSAGE_DELIVERY_CAPABILITY_IDS = vocabulary(["message.create", "message.update", "message.delete"]);
1170
+ var CEAL_REPOSITORY_VISIBILITIES = vocabulary(["public", "private", "internal"]);
1171
+ var CEAL_RESULT_DELIVERY_OFFERS = vocabulary(["pending", "offered", "transport_lost"]);
1172
+ var CEAL_RESULT_DELIVERY_STATES = vocabulary(["unavailable", ...CEAL_RESULT_DELIVERY_OFFERS]);
1173
+ var CEAL_PROVIDER_OUTCOMES = vocabulary(["not_attempted", "outcome_unknown", "verified"]);
1174
+ var CEAL_ACTIVITY_GAP_CODES = vocabulary([
1175
+ "provider_page_budget",
1176
+ "related_item_budget",
1177
+ "provider_cursor_unavailable",
1178
+ "malformed_provider_page",
1179
+ "visibility_incomplete",
1180
+ "unsupported_event_kind"
1181
+ ]);
1182
+ var CEAL_ACTIVITY_COVERAGE_STATUSES = vocabulary(["complete_for_target", "continuation_required", "blocked"]);
1183
+ var CEAL_ACTIVITY_EVENT_KINDS = vocabulary([
1184
+ "slack.message",
1185
+ "slack.reply",
1186
+ "github.commit.authored",
1187
+ "github.issue.opened",
1188
+ "github.pull_request.opened",
1189
+ "github.review.submitted",
1190
+ "github.issue_comment.created",
1191
+ "github.review_comment.created",
1192
+ "calendar.organized",
1193
+ "calendar.accepted_invite",
1194
+ "calendar.recorded"
1195
+ ]);
1196
+ var CEAL_ACTIVITY_TIMESTAMP_BASES = vocabulary([
1197
+ "message_created",
1198
+ "commit_authored",
1199
+ "resource_created",
1200
+ "review_submitted",
1201
+ "comment_created",
1202
+ "event_start",
1203
+ "all_day_start"
1204
+ ]);
1205
+ var CEAL_ARTIFACT_STAGE_TERMINALS = vocabulary(["chunk_accepted", "artifact_ready", "idempotency_replayed"]);
1206
+ var CEAL_READ_ITEM_KINDS = vocabulary(["conversation", "identity", "usergroup", "message", "file", "document"]);
1207
+ var CEAL_RESOURCE_RESOLVE_KINDS = vocabulary(["conversation", "identity", "usergroup", "permalink"]);
1208
+ var CEAL_OPAQUE_HANDLE_KINDS = vocabulary(["target", "message", "thread", "artifact", "document", "object"]);
1209
+ var CEAL_WRITE_OBJECT_KINDS = vocabulary(["document", "comment", "cell_range"]);
1210
+ var CEAL_CONVERSATION_KINDS = vocabulary(["channel", "dm", "group"]);
1211
+ var CEAL_FILE_TYPE_FAMILIES = vocabulary(["all", "image", "pdf"]);
1212
+ var CEAL_GITHUB_ISSUE_STATES = vocabulary(["open", "closed", "all"]);
1213
+ var CEAL_NOTION_UPDATABLE_BLOCK_TYPES = vocabulary([
1214
+ "paragraph",
1215
+ "heading_1",
1216
+ "heading_2",
1217
+ "heading_3",
1218
+ "bulleted_list_item",
1219
+ "numbered_list_item",
1220
+ "to_do",
1221
+ "code"
1222
+ ]);
1223
+ var CEAL_NOTION_NEUTRAL_TYPES = vocabulary([
1224
+ "text",
1225
+ "number",
1226
+ "boolean",
1227
+ "date",
1228
+ "select",
1229
+ "multi_select",
1230
+ "people",
1231
+ "url",
1232
+ "email",
1233
+ "phone",
1234
+ "unsupported"
1235
+ ]);
1236
+ var CEAL_NOTION_IDENTITY_GAP_REASONS = vocabulary([
1237
+ "identity_unavailable",
1238
+ "identity_stale",
1239
+ "identity_ambiguous",
1240
+ "identity_revoked",
1241
+ "identity_unlinked"
1242
+ ]);
1243
+ var CEAL_NOTION_STRING_VALUE_TYPES = vocabulary(["text", "select", "url", "email", "phone"]);
1244
+ var CEAL_UNREAD_REASONS = vocabulary(["blocked", "unavailable", "too_large", "unsupported", "download_failed", "permission_denied"]);
1245
+ var CEAL_PLAN_ITEM_STATUSES = vocabulary(["pending", "active", "completed"]);
1246
+ var CEAL_FINAL_PRESENTATION_INTENTS = vocabulary(["final", "stop", "transient_notice"]);
1247
+ var CEAL_PRESENTATION_INTENTS = vocabulary(["progress", ...CEAL_FINAL_PRESENTATION_INTENTS]);
1248
+
1249
+ // packages/ceal-client-protocol/src/personal-client-vocabulary.ts
1250
+ var CEAL_PERSONAL_CLIENT_BINDING_KEYS = vocabulary([
1251
+ "profile_ref",
1252
+ "membership_ref",
1253
+ "registration_ref",
1254
+ "client_ref",
1255
+ "subject_ref",
1256
+ "instance_ref"
1257
+ ]);
1258
+ var CEAL_ENROLLMENT_FAILURE_CODES = vocabulary(["enrollment_invalid", "enrollment_expired", "enrollment_used"]);
1259
+ var CEAL_REFRESH_FAILURE_CODES = vocabulary([
1260
+ "refresh_invalid",
1261
+ "refresh_expired",
1262
+ "refresh_inactive",
1263
+ "refresh_replayed",
1264
+ "refresh_revoked",
1265
+ "authority_replaced",
1266
+ "refresh_recovery_unavailable"
1267
+ ]);
1268
+
1269
+ // packages/ceal-client-protocol/src/device-enrollment.ts
1270
+ var CEAL_DEVICE_ENROLLMENT_POLL_FAILURE_CODES = Object.freeze(["unsupported_feature", "recovery_required", "expired"]);
1271
+ var POLL_RESULT_KEYS = Object.freeze(["retry_after_ms", "schema_version", "status"]);
1272
+
1273
+ // packages/ceal-client-protocol/src/personal-client-session.ts
1274
+ var REFRESH_FAILURE_CODES = new Set(CEAL_REFRESH_FAILURE_CODES);
1275
+
1276
+ // packages/ceal-client-protocol/src/index.ts
1277
+ var MAX_REQUEST_BYTES = 32 * 1024;
1278
+ var MAX_ARGUMENT_BYTES = 16 * 1024;
1279
+ var HANDSHAKE_IDENTITY_KEYS = Object.freeze(["membership_ref", "registration_ref", "client_ref", "subject_ref", "instance_ref"]);
1280
+ var AUDIT_IDENTITY_KEYS = Object.freeze(["event_ref", "membership_ref", "registration_ref", "client_ref", "subject_ref", "instance_ref"]);
1281
+ var FAILURE_RESPONSE_KEYS = Object.freeze(["error", "ok", "proof_ref_or_unavailable", "protocol_version", "request_id"]);
1282
+ var MAX_RECOVERY_RETRY_AFTER_MS = 60 * 60 * 1e3;
1283
+
1284
+ // host/invocation-authentication-client-command.ts
1285
+ var MAX_DETAIL_CHARACTERS = 240;
1286
+ var HOST_OWNED_CODE = /^[a-z][a-z0-9]*(?:_[a-z0-9]+){0,7}$/u;
1287
+ function hostTerminalFailure(error, component) {
1288
+ const code3 = errorCode(error);
1289
+ const detail = failureDetail(error);
1290
+ if (code3 === "ENOENT") return { code: "host_dependency_unavailable", message: `A command or file the ${component} Host needs is unavailable: ${detail}`, next_action: "Install the missing dependency or restore the missing file, then rerun this command." };
1291
+ if (code3 === "EACCES" || code3 === "EPERM") return { code: "host_permission_denied", message: `The ${component} Host was refused access to a local path: ${detail}`, next_action: "Repair the ownership or mode of the named path, then rerun this command." };
1292
+ if (code3 === "ENOSPC") return { code: "host_storage_unavailable", message: `The ${component} Host could not write local state: ${detail}`, next_action: "Free local disk space, then rerun this command." };
1293
+ if (code3 !== null && HOST_OWNED_CODE.test(code3)) return { code: code3, message: `The ${component} Host command failed: ${detail}`, next_action: `Resolve the named failure above; run \`ceal-host doctor --json\` only if it reports installed ${component} Host drift.` };
1294
+ return { code: "host_failure_unclassified", message: `The ${component} Host command failed for a cause it cannot classify: ${detail}`, next_action: `Run \`ceal-host doctor --json\`; if it reports no drift then the ${component} Host configuration is not the cause, and the message above is the only evidence of what is.` };
1295
+ }
1296
+ var DOCTOR_FLAGS = Object.freeze({
1297
+ "--expected-sha256": "expected_sha256",
1298
+ "--expected-source-commit": "expected_source_commit",
1299
+ "--expected-instance-ref": "expected_instance_ref"
1300
+ });
1301
+ function parseHostClientDoctorOptions(args) {
1302
+ if (args.length % 2 !== 0) return null;
1303
+ const result = {};
1304
+ for (let index = 0; index < args.length; index += 2) {
1305
+ const field = DOCTOR_FLAGS[args[index] ?? ""];
1306
+ const value = args[index + 1];
1307
+ if (field === void 0 || value === void 0 || value.startsWith("-") || result[field] !== void 0) return null;
1308
+ result[field] = value;
1309
+ }
1310
+ return result;
1311
+ }
1312
+ async function runHostInvocationAuthenticationClientCommand(command, argv, write = writeStdout) {
1313
+ const doctor = argv[0] === "doctor";
1314
+ const schemaVersion = doctor ? command.doctorSchemaVersion : command.authenticationSchemaVersion;
1315
+ try {
1316
+ if (!doctor) return await command.runAuthentication(argv);
1317
+ return await runHostClientDoctor(command, argv.slice(1), write);
1318
+ } catch (error) {
1319
+ write(hostClientFailureLine(schemaVersion, hostTerminalFailure(error, command.component)));
1320
+ return 2;
1321
+ }
1322
+ }
1323
+ async function runHostClientDoctor(command, args, write) {
1324
+ const options = parseHostClientDoctorOptions(args);
1325
+ if (options === null) {
1326
+ write(hostClientFailureLine(command.doctorSchemaVersion, {
1327
+ code: "invalid_command",
1328
+ message: `The ${command.component} client doctor arguments are invalid.`,
1329
+ next_action: `Run \`${command.executable} doctor\` with optional exact candidate expectations.`
1330
+ }));
1331
+ return 2;
1332
+ }
1333
+ const result = await command.runDoctor(options);
1334
+ write(`${JSON.stringify(result)}
1335
+ `);
1336
+ return result.ok ? 0 : 1;
1337
+ }
1338
+ function hostClientFailureLine(schemaVersion, error) {
1339
+ return `${JSON.stringify({ schema_version: schemaVersion, ok: false, status: "failure", error })}
1340
+ `;
1341
+ }
1342
+ function writeStdout(line) {
1343
+ process.stdout.write(line);
1344
+ }
1345
+ function failureDetail(error) {
1346
+ const text = error instanceof Error ? `${error.name}: ${error.message}` : typeof error === "string" ? error : "";
1347
+ const safe = normalizeCealSingleLineText(text).slice(0, MAX_DETAIL_CHARACTERS);
1348
+ return safe === "" ? "the command threw no readable error text" : safe;
1349
+ }
1350
+ function errorCode(error) {
1351
+ return typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : null;
1352
+ }
1353
+ function hostClientProbe(result, read) {
1354
+ if (result === null) return { kind: "unreachable" };
1355
+ if (result.exit_code !== 0) return { kind: "refused", exit_code: result.exit_code };
1356
+ const value = read(result);
1357
+ return value === null ? { kind: "unreadable" } : { kind: "value", value };
1358
+ }
1359
+ function hostClientProbeRefusal(probe, subject) {
1360
+ const invocation = `\`ceal ${subject.command}\``;
1361
+ if (probe.kind === "unreachable") return { code: "ceal_execution_failed", message: `The ${invocation} command did not run to completion from the ${subject.component} Host.`, next_action: `Run ${invocation} from that Host and resolve the local execution failure; the installed client bytes were already ${subject.executable_identity}.` };
1362
+ if (probe.kind === "refused") return { code: "ceal_command_refused", message: `The ${invocation} command exited ${probe.exit_code} from the ${subject.component} Host.`, next_action: `Run ${invocation} from that Host and read its own structured failure.` };
1363
+ return { code: "ceal_output_unreadable", message: `The ${invocation} command returned output the ${subject.component} Host cannot read.`, next_action: `Verify the installed Ceal client matches the protocol this ${subject.component} Host expects, then run this doctor again.` };
1364
+ }
1365
+
1366
+ // host/relay/src/producer-frame.ts
1367
+ var HOST_PRODUCER_FRAME_SCHEMA = "ceal.host_producer_frame.v1";
1368
+ var HOST_PRODUCER_MAX_JSON_BYTES = 262144;
1369
+ var HOST_PRODUCER_FRAME_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
1370
+ var SAFE_REF2 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
1371
+ var PRODUCERS = /* @__PURE__ */ new Set(["codex", "claude"]);
1372
+ var HOST_PRODUCER_FRAME_KINDS = ["session_started", "turn_started", "user_input", "turn_terminal", "producer_status"];
1373
+ var FRAME_KINDS = new Set(HOST_PRODUCER_FRAME_KINDS);
1374
+ function isHostProducerFrameKind(value) {
1375
+ return typeof value === "string" && FRAME_KINDS.has(value);
1376
+ }
1377
+ var HostProducerFrameError = class extends Error {
1378
+ code;
1379
+ constructor(code3, message = code3) {
1380
+ super(message);
1381
+ this.code = code3;
1382
+ }
1383
+ };
1384
+ function encodeHostProducerFrame(frame) {
1385
+ validateFrame(frame);
1386
+ const json = Buffer.from(JSON.stringify(frame), "utf8");
1387
+ if (json.byteLength > HOST_PRODUCER_MAX_JSON_BYTES) throw new HostProducerFrameError("frame_too_large", `frame_too_large: ${refusalFact("frame_bytes", json.byteLength, `at most ${HOST_PRODUCER_MAX_JSON_BYTES}`)}`);
1388
+ const result = Buffer.allocUnsafe(json.byteLength + HOST_PRODUCER_FRAME_LENGTH_BYTES);
1389
+ result.writeUInt32BE(json.byteLength, 0);
1390
+ json.copy(result, HOST_PRODUCER_FRAME_LENGTH_BYTES);
1391
+ return result;
1392
+ }
1393
+ function decodeHostProducerFrame(input) {
1394
+ if (input.byteLength < HOST_PRODUCER_FRAME_LENGTH_BYTES) throw new HostProducerFrameError("frame_truncated", `frame_truncated: ${refusalFact("frame_bytes", input.byteLength, `at least ${HOST_PRODUCER_FRAME_LENGTH_BYTES}`)}`);
1395
+ const length = input.readUInt32BE(0);
1396
+ if (length > HOST_PRODUCER_MAX_JSON_BYTES) throw new HostProducerFrameError("frame_too_large", `frame_too_large: ${refusalFact("declared_bytes", length, `at most ${HOST_PRODUCER_MAX_JSON_BYTES}`)}`);
1397
+ if (length === 0) throw new HostProducerFrameError("invalid_frame_length");
1398
+ if (input.byteLength !== length + HOST_PRODUCER_FRAME_LENGTH_BYTES) throw new HostProducerFrameError(input.byteLength < length + HOST_PRODUCER_FRAME_LENGTH_BYTES ? "frame_truncated" : "invalid_frame_length");
1399
+ const bytes = input.subarray(HOST_PRODUCER_FRAME_LENGTH_BYTES);
1400
+ const text = new TextDecoder("utf-8", { fatal: true });
1401
+ let value;
1402
+ try {
1403
+ value = JSON.parse(text.decode(bytes));
1404
+ } catch (error) {
1405
+ if (error instanceof TypeError) throw new HostProducerFrameError("invalid_frame_encoding");
1406
+ throw new HostProducerFrameError("frame_truncated");
1407
+ }
1408
+ validateFrame(value);
1409
+ return value;
1410
+ }
1411
+ function validateFrame(value) {
1412
+ if (!record(value)) throw new HostProducerFrameError("invalid_frame_shape");
1413
+ if (value.schema_version !== HOST_PRODUCER_FRAME_SCHEMA) throw new HostProducerFrameError("unsupported_frame_schema", `unsupported_frame_schema: ${refusalFact("schema_version", value.schema_version, HOST_PRODUCER_FRAME_SCHEMA)}`);
1414
+ if (!exactKeys2(value, ["schema_version", "producer_id", "producer_installation_ref", "producer_epoch", "sequence", "frame_kind", "occurred_at", "payload"])) throw new HostProducerFrameError("invalid_frame_shape");
1415
+ if (!PRODUCERS.has(String(value.producer_id)) || !safeRef(value.producer_installation_ref)) throw new HostProducerFrameError("invalid_producer_identity");
1416
+ if (!positive(value.producer_epoch) || !positive(value.sequence) || !hostProducerFrameKind(value.frame_kind) || !timestamp(value.occurred_at) || !record(value.payload)) throw new HostProducerFrameError("invalid_frame_shape");
1417
+ validatePayload(value.frame_kind, value.payload);
1418
+ }
1419
+ function validatePayload(kind, value) {
1420
+ const valid = kind === "session_started" ? validSession(value) : kind === "turn_started" ? validTurn(value) : kind === "user_input" ? validInput(value) : kind === "turn_terminal" ? validTerminal(value) : validStatus(value);
1421
+ if (!valid) throw new HostProducerFrameError("invalid_frame_shape");
1422
+ }
1423
+ function validSession(value) {
1424
+ return exactOptional(value, ["local_session_ref", "working_directory_ref"], ["model", "host_version", "observations"]) && safeRef(value.local_session_ref) && safeRef(value.working_directory_ref) && optionalText(value.model, 256) && optionalText(value.host_version, 256) && validObservations(value.observations);
1425
+ }
1426
+ function validTurn(value) {
1427
+ return exactOptional(value, ["local_session_ref", "local_turn_ref"], ["model", "observations"]) && safeRef(value.local_session_ref) && safeRef(value.local_turn_ref) && optionalText(value.model, 256) && validObservations(value.observations);
1428
+ }
1429
+ function validInput(value) {
1430
+ return exactOptional(value, ["local_session_ref", "local_turn_ref", "local_input_ref", "origin_input", "observations"], ["decision", "local_turn_aliases", "context_expires_at"]) && safeRef(value.local_session_ref) && safeRef(value.local_turn_ref) && safeRef(value.local_input_ref) && validInputObservations(value.observations) && typeof value.origin_input === "boolean" && validInputOptionals(value);
1431
+ }
1432
+ function validInputObservations(value) {
1433
+ return validObservations(value) && Array.isArray(value) && value.filter((item) => record(item) && item.observation_kind === "prompt").length === 1;
1434
+ }
1435
+ function validInputOptionals(value) {
1436
+ return validDecision(value.decision) && optionalRefs(value.local_turn_aliases) && (value.context_expires_at === void 0 || timestamp(value.context_expires_at));
1437
+ }
1438
+ function validTerminal(value) {
1439
+ return exactOptional(value, ["local_session_ref", "local_turn_ref", "terminal_state"], ["abort_reason", "duration_ms", "time_to_first_token_ms", "usage", "observations"]) && safeRef(value.local_session_ref) && safeRef(value.local_turn_ref) && validTerminalDisposition(value.terminal_state, value.abort_reason) && optionalNonNegative(value.duration_ms) && optionalNonNegative(value.time_to_first_token_ms) && (value.usage === void 0 || jsonValue(value.usage)) && validObservations(value.observations);
1440
+ }
1441
+ function validTerminalDisposition(state, reason) {
1442
+ return (state === "completed" || state === "aborted") && (reason === void 0 || state === "aborted" && safeRef(reason));
1443
+ }
1444
+ function validStatus(value) {
1445
+ return exactOptional(value, ["status", "reason_code"], ["detail"]) && ["ready", "degraded", "stopping"].includes(String(value.status)) && safeRef(value.reason_code) && optionalText(value.detail, 4096);
1446
+ }
1447
+ function validDecision(value) {
1448
+ return value === void 0 || record(value) && exactKeys2(value, ["decision", "approval_ref"]) && (value.decision === "approved" || value.decision === "denied") && safeRef(value.approval_ref);
1449
+ }
1450
+ function optionalText(value, maxLength) {
1451
+ return value === void 0 || typeof value === "string" && value.length > 0 && value.length <= maxLength;
1452
+ }
1453
+ function optionalNonNegative(value) {
1454
+ return value === void 0 || typeof value === "number" && Number.isFinite(value) && value >= 0;
1455
+ }
1456
+ function optionalRefs(value) {
1457
+ return value === void 0 || Array.isArray(value) && value.length <= 16 && value.every(safeRef);
1458
+ }
1459
+ function validObservations(value) {
1460
+ if (value === void 0) return true;
1461
+ if (!Array.isArray(value) || value.length > 32) return false;
1462
+ return value.every((item) => {
1463
+ try {
1464
+ validateCealHostObservationDraft(item);
1465
+ return true;
1466
+ } catch {
1467
+ return false;
1468
+ }
1469
+ });
1470
+ }
1471
+ function jsonValue(value, depth = 0) {
1472
+ if (depth > 16) return false;
1473
+ if (value === null || typeof value === "string" || typeof value === "boolean") return true;
1474
+ if (typeof value === "number") return Number.isFinite(value);
1475
+ if (Array.isArray(value)) return value.length <= 256 && value.every((item) => jsonValue(item, depth + 1));
1476
+ return record(value) && Object.keys(value).length <= 256 && Object.entries(value).every(([key, item]) => key.length > 0 && key.length <= 128 && jsonValue(item, depth + 1));
1477
+ }
1478
+ function record(value) {
1479
+ return value !== null && typeof value === "object" && !Array.isArray(value);
1480
+ }
1481
+ function safeRef(value) {
1482
+ return typeof value === "string" && SAFE_REF2.test(value);
1483
+ }
1484
+ function positive(value) {
1485
+ return Number.isSafeInteger(value) && Number(value) > 0;
1486
+ }
1487
+ function timestamp(value) {
1488
+ return typeof value === "string" && Number.isFinite(Date.parse(value));
1489
+ }
1490
+ function hostProducerFrameKind(value) {
1491
+ return isHostProducerFrameKind(value);
1492
+ }
1493
+ function exactKeys2(value, keys) {
1494
+ return JSON.stringify(Object.keys(value).sort()) === JSON.stringify([...keys].sort());
1495
+ }
1496
+ function exactOptional(value, required, optional) {
1497
+ const keys = Object.keys(value);
1498
+ return required.every((key) => keys.includes(key)) && keys.every((key) => required.includes(key) || optional.includes(key));
1499
+ }
1500
+
1501
+ // host/relay/src/durable-atomic-replacement.ts
1502
+ import { O_RDONLY } from "node:constants";
1503
+ import { lstat, mkdir, open, rename, unlink } from "node:fs/promises";
1504
+ import { dirname } from "node:path";
1505
+ var DEFAULT_PORT = {
1506
+ platform: process.platform,
1507
+ mkdir: (path, options) => mkdir(path, options),
1508
+ lstat: (path) => lstat(path),
1509
+ open_file: (path) => open(path, "wx", 384),
1510
+ rename,
1511
+ unlink,
1512
+ open_directory: (path) => open(path, O_RDONLY),
1513
+ unique_ref: () => `${process.pid}.${crypto.randomUUID()}`
1514
+ };
1515
+ async function durableAtomicReplace(target, data, port = DEFAULT_PORT) {
1516
+ const parent = dirname(target);
1517
+ await port.mkdir(parent, { recursive: true, mode: 448 });
1518
+ const parentStats = await port.lstat(parent);
1519
+ if (!parentStats.isDirectory() || parentStats.isSymbolicLink() || !ownerPrivate(parentStats, port.platform)) throw new TypeError(`Host Relay durable-state directory is unsafe: ${refusalFacts([{ name: "parent_stats", value: parentStats, expected: "an owner-private directory" }, { name: "platform", value: port.platform }])}.`);
1520
+ const temporary = `${target}.${port.unique_ref()}.new`;
1521
+ let staged;
1522
+ const failures = [];
1523
+ try {
1524
+ staged = await port.open_file(temporary);
1525
+ await staged.writeFile(data, typeof data === "string" ? { encoding: "utf8" } : void 0);
1526
+ await staged.sync();
1527
+ const closing = staged;
1528
+ staged = void 0;
1529
+ await closing.close();
1530
+ await port.rename(temporary, target);
1531
+ await syncParentDirectory(parent, port);
1532
+ } catch (error) {
1533
+ failures.push(error);
1534
+ }
1535
+ await closeStaged(staged, failures);
1536
+ await removeTemporary(temporary, port, failures);
1537
+ throwFailures(failures);
1538
+ }
1539
+ async function syncParentDirectory(path, port) {
1540
+ if (port.platform === "win32") return;
1541
+ const handle = await port.open_directory(path);
1542
+ let failure2;
1543
+ try {
1544
+ await handle.sync();
1545
+ } catch (error) {
1546
+ if (!directorySyncUnsupported(error)) failure2 = error;
1547
+ }
1548
+ try {
1549
+ await handle.close();
1550
+ } catch (error) {
1551
+ if (failure2 === void 0) failure2 = error;
1552
+ else failure2 = new AggregateError([failure2, error], "Host Relay directory sync and close failed.");
1553
+ }
1554
+ if (failure2 !== void 0) throw failure2;
1555
+ }
1556
+ function ownerPrivate(stats, platform) {
1557
+ if (platform === "win32") return true;
1558
+ const uid = typeof process.geteuid === "function" ? process.geteuid() : stats.uid;
1559
+ return stats.uid === uid && (stats.mode & 63) === 0;
1560
+ }
1561
+ async function closeStaged(staged, failures) {
1562
+ if (staged !== void 0) try {
1563
+ await staged.close();
1564
+ } catch (error) {
1565
+ failures.push(error);
1566
+ }
1567
+ }
1568
+ async function removeTemporary(path, port, failures) {
1569
+ try {
1570
+ await port.unlink(path);
1571
+ } catch (error) {
1572
+ if (errorCode2(error) !== "ENOENT") failures.push(error);
1573
+ }
1574
+ }
1575
+ function throwFailures(failures) {
1576
+ if (failures.length === 1) throw failures[0];
1577
+ if (failures.length > 1) throw new AggregateError(failures, "Host Relay durable replacement and cleanup failed.");
1578
+ }
1579
+ function directorySyncUnsupported(error) {
1580
+ return ["EINVAL", "ENOSYS", "ENOTSUP"].includes(errorCode2(error) ?? "");
1581
+ }
1582
+ function errorCode2(error) {
1583
+ return typeof error === "object" && error !== null && "code" in error ? String(error.code) : null;
1584
+ }
1585
+
1586
+ // host/relay/src/relay-quarantine-store.ts
1587
+ var RELAY_QUARANTINE_MAX_BYTES = 16 * 1024 * 1024;
1588
+
1589
+ // host/relay/src/relay-admission-store.ts
1590
+ var DEFAULT_LIMITS = { global_count: 8192, global_bytes: 64 * 1024 * 1024, producer_count: 4096, producer_bytes: 32 * 1024 * 1024 };
1591
+
1592
+ // host/relay/src/relay-request-binding-store.ts
1593
+ var MAX_STATE_BYTES = 8 * 1024 * 1024;
1594
+
1595
+ // host/relay/src/relay-ipc.ts
1596
+ import { createConnection, createServer } from "node:net";
1597
+ var HOST_RELAY_REQUEST_BINDING_KEYS = Object.freeze([
1598
+ "schema_version",
1599
+ "producer_id",
1600
+ "producer_installation_ref",
1601
+ "local_session_ref",
1602
+ "local_turn_ref",
1603
+ "local_turn_aliases",
1604
+ "prompt_ref",
1605
+ "request_ref",
1606
+ "bound_at",
1607
+ "host_source_ref",
1608
+ "host_session_ref",
1609
+ "host_turn_ref",
1610
+ "host_input_ref"
1611
+ ]);
1612
+ var HOST_RELAY_IPC_RESPONSE_SCHEMA = "ceal.host_relay_admission.v1";
1613
+ var HOST_RELAY_BINDING_QUERY_SCHEMA = "ceal.host_relay_binding_query.v1";
1614
+ var HOST_RELAY_BINDING_RESULT_SCHEMA = "ceal.host_relay_binding_result.v1";
1615
+ var HOST_RELAY_INVOCATION_CONTEXT_QUERY_SCHEMA = "ceal.host_relay_invocation_context_query.v1";
1616
+ var HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA = "ceal.host_relay_invocation_context_result.v1";
1617
+ var HOST_RELAY_IPC_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
1618
+ var HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES = 4096;
1619
+ var HOST_RELAY_QUERY_RESPONSE_MAX_BYTES = 8192;
1620
+ var HostRelayIpcError = class extends Error {
1621
+ code;
1622
+ constructor(code3, message = code3) {
1623
+ super(message);
1624
+ this.code = code3;
1625
+ }
1626
+ };
1627
+ var HostRelayRequestBindingPort = class {
1628
+ endpoint;
1629
+ timeout_ms;
1630
+ constructor(endpoint, timeoutMs = 5e3) {
1631
+ this.endpoint = endpoint;
1632
+ this.timeout_ms = timeoutMs;
1633
+ }
1634
+ query(input) {
1635
+ return queryHostRelayRequestBinding(this.endpoint, input, this.timeout_ms);
1636
+ }
1637
+ mintInvocationContext(input) {
1638
+ return queryHostRelayInvocationContext(this.endpoint, input, this.timeout_ms);
1639
+ }
1640
+ };
1641
+ var HostRelayIpcAdmissionPort = class {
1642
+ endpoint;
1643
+ timeout_ms;
1644
+ constructor(endpoint, timeoutMs = 5e3) {
1645
+ this.endpoint = endpoint;
1646
+ this.timeout_ms = timeoutMs;
1647
+ }
1648
+ async admit(frame) {
1649
+ const response2 = await submitHostProducerFrame(this.endpoint, frame, this.timeout_ms);
1650
+ if (!relayAdmissionCode(response2.code)) throw new HostRelayIpcError(response2.code);
1651
+ return { code: response2.code, admitted_through_sequence: response2.admitted_through_sequence, delivered_through_sequence: response2.delivered_through_sequence };
1652
+ }
1653
+ };
1654
+ function submitHostProducerFrame(endpoint, frame, timeoutMs = 5e3) {
1655
+ return exchange(endpoint, encodeHostProducerFrame(frame), timeoutMs, decodeResponseBuffer);
1656
+ }
1657
+ async function queryHostRelayRequestBinding(endpoint, query, timeoutMs = 5e3) {
1658
+ const request2 = encodeBindingQuery(query);
1659
+ const response2 = await exchange(endpoint, request2, timeoutMs, decodeBindingResponseBuffer);
1660
+ if (response2.status === "no_binding") return { status: "no_binding" };
1661
+ return { status: "ready", binding: response2.binding };
1662
+ }
1663
+ function decodeHostRelayBindingQueryResult(value) {
1664
+ if (!validBindingResponse(value)) throw new HostRelayIpcError("relay_unavailable", "Host Relay binding response is invalid.");
1665
+ return value.status === "no_binding" ? { status: "no_binding" } : { status: "ready", binding: value.binding };
1666
+ }
1667
+ function queryHostRelayInvocationContext(endpoint, query, timeoutMs = 5e3) {
1668
+ return exchange(endpoint, encodeInvocationContextQuery(query), timeoutMs, decodeInvocationContextResponseBuffer);
1669
+ }
1670
+ function exchange(endpoint, encoded, timeoutMs, decode) {
1671
+ return new Promise((resolve, reject) => {
1672
+ const socket = createConnection(endpoint);
1673
+ let buffer = Buffer.alloc(0);
1674
+ let settled = false;
1675
+ const finish = (error, response2) => {
1676
+ if (settled) return;
1677
+ settled = true;
1678
+ socket.destroy();
1679
+ if (error !== null) reject(error);
1680
+ else if (response2 !== void 0) resolve(response2);
1681
+ };
1682
+ socket.setTimeout(timeoutMs, () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC timed out.")));
1683
+ socket.once("error", () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC is unavailable.")));
1684
+ socket.once("connect", () => socket.write(encoded));
1685
+ socket.on("data", (chunk) => {
1686
+ try {
1687
+ buffer = Buffer.concat([buffer, Buffer.from(chunk)]);
1688
+ const decoded = decode(buffer);
1689
+ if (decoded !== null) finish(null, decoded);
1690
+ } catch (error) {
1691
+ finish(error instanceof Error ? error : new HostRelayIpcError("relay_unavailable"));
1692
+ }
1693
+ });
1694
+ socket.once("end", () => {
1695
+ if (!settled) finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC closed without a response."));
1696
+ });
1697
+ });
1698
+ }
1699
+ function decodeHostRelayIpcResponse(input) {
1700
+ if (input.length < HOST_RELAY_IPC_LENGTH_BYTES) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC response is truncated: ${refusalFact("response_bytes", input.byteLength, `at least ${HOST_RELAY_IPC_LENGTH_BYTES}`)}.`);
1701
+ const length = input.readUInt32BE(0);
1702
+ if (length === 0 || length > HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES || input.length !== length + HOST_RELAY_IPC_LENGTH_BYTES) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC response length is invalid: ${refusalFacts([{ name: "declared_bytes", value: length, expected: `between 1 and ${HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES}` }, { name: "received_bytes", value: input.byteLength, expected: `exactly ${length + HOST_RELAY_IPC_LENGTH_BYTES}` }])}.`);
1703
+ let value;
1704
+ try {
1705
+ value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(input.subarray(HOST_RELAY_IPC_LENGTH_BYTES)));
1706
+ } catch {
1707
+ throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC response is invalid.");
1708
+ }
1709
+ if (!validResponse(value)) throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC response shape is invalid.");
1710
+ return value;
1711
+ }
1712
+ function relayAdmissionCode(value) {
1713
+ return value === "admitted" || value === "already_admitted" || value === "producer_epoch_stale" || value === "sequence_gap" || value === "frame_identity_conflict" || value === "producer_queue_full" || value === "relay_queue_full" || value === "producer_already_connected" || value === "invalid_producer_identity";
1714
+ }
1715
+ function validResponse(value) {
1716
+ return record2(value) && value.schema_version === HOST_RELAY_IPC_RESPONSE_SCHEMA && hostRelayIpcCode(value.code) && nonnegative(value.admitted_through_sequence) && nonnegative(value.delivered_through_sequence) && Object.keys(value).length === 4;
1717
+ }
1718
+ function hostRelayIpcCode(value) {
1719
+ return typeof value === "string" && ["admitted", "already_admitted", "producer_epoch_stale", "sequence_gap", "frame_identity_conflict", "producer_queue_full", "relay_queue_full", "invalid_frame_encoding", "invalid_frame_length", "frame_truncated", "unsupported_frame_schema", "invalid_frame_shape", "invalid_producer_identity", "frame_too_large", "producer_already_connected", "relay_unavailable"].includes(value);
1720
+ }
1721
+ function nonnegative(value) {
1722
+ return Number.isSafeInteger(value) && Number(value) >= 0;
1723
+ }
1724
+ function record2(value) {
1725
+ return value !== null && typeof value === "object" && !Array.isArray(value);
1726
+ }
1727
+ function decodeResponseBuffer(buffer) {
1728
+ if (buffer.length < HOST_RELAY_IPC_LENGTH_BYTES) return null;
1729
+ const length = buffer.readUInt32BE(0);
1730
+ if (length === 0 || length > HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC response length is invalid: ${refusalFact("declared_bytes", length, `between 1 and ${HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES}`)}.`);
1731
+ if (buffer.length < length + HOST_RELAY_IPC_LENGTH_BYTES) return null;
1732
+ if (buffer.length !== length + HOST_RELAY_IPC_LENGTH_BYTES) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC returned trailing bytes: ${refusalFacts([{ name: "declared_bytes", value: length, expected: `the received message length minus ${HOST_RELAY_IPC_LENGTH_BYTES}` }, { name: "received_bytes", value: buffer.byteLength, expected: `exactly ${length + HOST_RELAY_IPC_LENGTH_BYTES}` }])}.`);
1733
+ return decodeHostRelayIpcResponse(buffer);
1734
+ }
1735
+ function decodeBindingResponseBuffer(buffer) {
1736
+ const value = decodeLengthPrefixedJson(buffer, HOST_RELAY_QUERY_RESPONSE_MAX_BYTES);
1737
+ if (value === null) return null;
1738
+ const decoded = decodeHostRelayBindingQueryResult(value);
1739
+ return decoded.status === "no_binding" ? { schema_version: HOST_RELAY_BINDING_RESULT_SCHEMA, status: "no_binding" } : { schema_version: HOST_RELAY_BINDING_RESULT_SCHEMA, status: "ready", binding: decoded.binding };
1740
+ }
1741
+ function decodeInvocationContextResponseBuffer(buffer) {
1742
+ const value = decodeLengthPrefixedJson(buffer, HOST_RELAY_QUERY_RESPONSE_MAX_BYTES);
1743
+ if (value === null) return null;
1744
+ if (!validInvocationContextResponse(value)) throw new HostRelayIpcError("relay_unavailable", "Host Relay invocation context response is invalid.");
1745
+ return value;
1746
+ }
1747
+ function encodeBindingQuery(query) {
1748
+ const value = { schema_version: HOST_RELAY_BINDING_QUERY_SCHEMA, ...query };
1749
+ if (!validBindingQueryRequest(value)) throw new HostRelayIpcError("invalid_frame_shape", "Host Relay binding query is invalid.");
1750
+ return encodeLengthPrefixed(value);
1751
+ }
1752
+ function encodeInvocationContextQuery(query) {
1753
+ const value = { schema_version: HOST_RELAY_INVOCATION_CONTEXT_QUERY_SCHEMA, ...query };
1754
+ if (!validInvocationContextQueryRequest(value)) throw new HostRelayIpcError("invalid_frame_shape");
1755
+ return encodeLengthPrefixed(value);
1756
+ }
1757
+ function validBindingQueryRequest(value) {
1758
+ return validQueryIdentity(value, HOST_RELAY_BINDING_QUERY_SCHEMA) && exactKeys3(value, ["schema_version", "producer_id", "producer_installation_ref", "local_session_ref", "local_turn_ref"]);
1759
+ }
1760
+ function validInvocationContextQueryRequest(value) {
1761
+ return validQueryIdentity(value, HOST_RELAY_INVOCATION_CONTEXT_QUERY_SCHEMA) && exactKeys3(value, ["schema_version", "producer_id", "producer_installation_ref", "local_session_ref", "local_turn_ref", "client_nonce"]) && typeof value.client_nonce === "string" && CEAL_HOST_CLIENT_NONCE_PATTERN.test(value.client_nonce);
1762
+ }
1763
+ function validQueryIdentity(value, schema) {
1764
+ return record2(value) && value.schema_version === schema && (value.producer_id === "codex" || value.producer_id === "claude") && safeRef2(value.producer_installation_ref) && safeRef2(value.local_session_ref) && safeRef2(value.local_turn_ref);
1765
+ }
1766
+ function validBindingResponse(value) {
1767
+ if (!record2(value) || value.schema_version !== HOST_RELAY_BINDING_RESULT_SCHEMA) return false;
1768
+ if (value.status === "no_binding") return Object.keys(value).length === 2;
1769
+ return value.status === "ready" && Object.keys(value).length === 3 && validWireBinding(value.binding);
1770
+ }
1771
+ function validInvocationContextResponse(value) {
1772
+ if (!record2(value) || value.schema_version !== HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA) return false;
1773
+ if (value.status === "no_binding") return Object.keys(value).length === 2;
1774
+ if (value.status !== "ready" || Object.keys(value).length !== 3) return false;
1775
+ try {
1776
+ decodeCealHostInvocationAuthenticationResult(value.result);
1777
+ return true;
1778
+ } catch {
1779
+ return false;
1780
+ }
1781
+ }
1782
+ function validWireBinding(value) {
1783
+ if (!record2(value) || value.schema_version !== "ceal.host_relay_request_binding.v1" || value.producer_id !== "codex" && value.producer_id !== "claude") return false;
1784
+ const required = HOST_RELAY_REQUEST_BINDING_KEYS;
1785
+ const keys = Object.keys(value);
1786
+ return required.every((key) => Object.hasOwn(value, key)) && keys.every((key) => required.includes(key) || key === "context_expires_at") && validWireBindingRefs(value) && validWireBindingTimes(value);
1787
+ }
1788
+ function validWireBindingRefs(value) {
1789
+ const tuple = [value.host_source_ref, value.host_session_ref, value.host_turn_ref, value.host_input_ref];
1790
+ return [value.producer_installation_ref, value.local_session_ref, value.local_turn_ref, value.prompt_ref, value.request_ref].every(safeRef2) && Array.isArray(value.local_turn_aliases) && value.local_turn_aliases.length <= 16 && value.local_turn_aliases.every(safeRef2) && tuple.every(safeRef2);
1791
+ }
1792
+ function validWireBindingTimes(value) {
1793
+ return validTimestamp(value.bound_at) && (value.context_expires_at === void 0 || validTimestamp(value.context_expires_at));
1794
+ }
1795
+ function decodeLengthPrefixedJson(input, maximum) {
1796
+ if (input.length < HOST_RELAY_IPC_LENGTH_BYTES) return null;
1797
+ const length = input.readUInt32BE(0);
1798
+ if (length === 0 || length > maximum) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC message length is invalid: ${refusalFact("declared_bytes", length, `between 1 and ${maximum}`)}.`);
1799
+ if (input.length < length + HOST_RELAY_IPC_LENGTH_BYTES) return null;
1800
+ if (input.length !== length + HOST_RELAY_IPC_LENGTH_BYTES) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC message has trailing bytes: ${refusalFacts([{ name: "declared_bytes", value: length, expected: `the received message length minus ${HOST_RELAY_IPC_LENGTH_BYTES}` }, { name: "received_bytes", value: input.byteLength, expected: `exactly ${length + HOST_RELAY_IPC_LENGTH_BYTES}` }])}.`);
1801
+ try {
1802
+ return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(input.subarray(HOST_RELAY_IPC_LENGTH_BYTES)));
1803
+ } catch {
1804
+ throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC message is invalid.");
1805
+ }
1806
+ }
1807
+ function encodeLengthPrefixed(value) {
1808
+ const body = Buffer.from(JSON.stringify(value), "utf8");
1809
+ const output = Buffer.allocUnsafe(body.length + HOST_RELAY_IPC_LENGTH_BYTES);
1810
+ output.writeUInt32BE(body.length, 0);
1811
+ body.copy(output, HOST_RELAY_IPC_LENGTH_BYTES);
1812
+ return output;
1813
+ }
1814
+ function exactKeys3(value, keys) {
1815
+ return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
1816
+ }
1817
+ function safeRef2(value) {
1818
+ return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u.test(value);
1819
+ }
1820
+ function validTimestamp(value) {
1821
+ return typeof value === "string" && Number.isFinite(Date.parse(value));
1822
+ }
1823
+
1824
+ // host/invocation-authentication-command.ts
1825
+ var HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX = ["authenticate", "--client-nonce"];
1826
+ function installedHostInvocationAuthenticationCommandOptions(config) {
1827
+ const port = new HostRelayRequestBindingPort(config.relay_endpoint, config.ipc_timeout_ms);
1828
+ return {
1829
+ host_source_ref: config.host_source_ref,
1830
+ outbox_dir: config.outbox_dir,
1831
+ producer_installation_ref: config.producer_installation_ref,
1832
+ mint_invocation_context: (input) => port.mintInvocationContext({ ...input, producer_id: input.producer_id })
1833
+ };
1834
+ }
1835
+ async function runHostInvocationAuthenticationCommand(descriptor, args, options) {
1836
+ let sink = options?.output_sink;
1837
+ try {
1838
+ const resolved = await resolveOptions(descriptor, args, options);
1839
+ sink = resolved.options.output_sink;
1840
+ writeResult(await authenticateHostInvocation(descriptor, resolved.input, resolved.options), sink);
1841
+ return 0;
1842
+ } catch {
1843
+ writeResult({ ok: false, code: "invocation_authentication_unavailable" }, sink);
1844
+ return 2;
1845
+ }
1846
+ }
1847
+ async function authenticateHostInvocation(descriptor, input, options) {
1848
+ if (input.length !== HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX.length + 1 || input[0] !== HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX[0] || input[1] !== HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX[1]) throw new TypeError("invalid arguments");
1849
+ const request2 = decodeCealHostInvocationAuthenticationRequest({ schema_version: CEAL_HOST_INVOCATION_AUTHENTICATION_REQUEST_SCHEMA, client_nonce: input[2] });
1850
+ const config = validateOptions(options, descriptor.command_name);
1851
+ const now = (config.now ?? (() => /* @__PURE__ */ new Date()))();
1852
+ const { store, current } = await currentInvocation(descriptor, config, now);
1853
+ if (config.mint_invocation_context === void 0) throw new TypeError("mint unavailable");
1854
+ const query = {
1855
+ producer_id: descriptor.producer_id,
1856
+ producer_installation_ref: config.producer_installation_ref,
1857
+ local_session_ref: current.identity.host_session_ref,
1858
+ local_turn_ref: current.identity.host_turn_ref,
1859
+ client_nonce: request2.client_nonce
1860
+ };
1861
+ const response2 = await config.mint_invocation_context(query);
1862
+ if (response2.status !== "ready") throw new TypeError(response2.status);
1863
+ const rechecked = await store.readInvocationContext(current.identity.host_source_ref, current.identity.host_session_ref, (config.now ?? (() => /* @__PURE__ */ new Date()))());
1864
+ if (rechecked === null || !sameTurn(current, rechecked)) throw new TypeError("context replaced");
1865
+ return decodeCealHostInvocationAuthenticationResult(response2.result, now);
1866
+ }
1867
+ async function currentInvocation(descriptor, config, now) {
1868
+ const store = descriptor.create_store(config.outbox_dir);
1869
+ const identity = resolveIdentity(descriptor, config);
1870
+ if (identity.status !== "ready") throw new TypeError(identity.status);
1871
+ const current = await store.readInvocationContext(identity.identity.host_source_ref, identity.identity.host_session_ref, now);
1872
+ if (current === null || Date.parse(current.expires_at) <= now.getTime()) throw new TypeError("context unavailable");
1873
+ return { store, current };
1874
+ }
1875
+ function resolveIdentity(descriptor, options) {
1876
+ const sessionId = options.session_id === null ? void 0 : options.session_id ?? process.env[descriptor.session_id_env];
1877
+ if (isHostSessionId(sessionId)) return { status: "ready", identity: { host_source_ref: options.host_source_ref, host_session_ref: descriptor.session_ref(options.host_source_ref, sessionId) } };
1878
+ return { status: "unavailable" };
1879
+ }
1880
+ async function resolveOptions(descriptor, args, options) {
1881
+ if (options !== void 0) return { input: [...args], options };
1882
+ const configPath = descriptor.parse_config_flag(args);
1883
+ return {
1884
+ input: args.filter((argument) => !argument.startsWith(`${descriptor.config_flag}=`)),
1885
+ options: installedHostInvocationAuthenticationCommandOptions(await descriptor.read_producer_config(configPath))
1886
+ };
1887
+ }
1888
+ function validateOptions(options, commandName) {
1889
+ if (typeof options.outbox_dir !== "string" || options.outbox_dir.length === 0 || typeof options.host_source_ref !== "string" || !SAFE_REF.test(options.host_source_ref) || typeof options.producer_installation_ref !== "string" || !SAFE_REF.test(options.producer_installation_ref) || !validOptionalSession(options.session_id)) {
1890
+ throw new TypeError(`${commandName} invocation authentication command options are invalid.`);
1891
+ }
1892
+ return options;
1893
+ }
1894
+ function isHostSessionId(value) {
1895
+ return typeof value === "string" && value.length > 0 && value.length <= 256 && !value.includes("\0");
1896
+ }
1897
+ function validOptionalSession(value) {
1898
+ return value === void 0 || value === null || typeof value === "string";
1899
+ }
1900
+ function sameTurn(left, right) {
1901
+ return left.identity.host_turn_ref === right.identity.host_turn_ref;
1902
+ }
1903
+ function writeResult(value, sink) {
1904
+ (sink ?? ((document) => process.stdout.write(`${JSON.stringify(document)}
1905
+ `)))(value);
1906
+ }
1907
+
1908
+ // host/producer-service.ts
1909
+ import { constants } from "node:fs";
1910
+ import { lstat as lstat2, open as open2 } from "node:fs/promises";
1911
+
1912
+ // host/absolute-path.ts
1913
+ import { posix, win32 } from "node:path";
1914
+ function isAbsoluteNormalizedNonRootPath(value, flavor = process.platform, allowRoot = false) {
1915
+ const pathApi = flavor === "win32" || flavor === "windows" ? win32 : posix;
1916
+ return typeof value === "string" && value.length <= 4096 && !value.includes("\0") && pathApi.isAbsolute(value) && pathApi.normalize(value) === value && (allowRoot || pathApi.parse(value).root !== value);
1917
+ }
1918
+
1919
+ // host/producer-service.ts
1920
+ var MAX_CONFIG_BYTES = 32 * 1024;
1921
+ var SAFE_REF3 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
1922
+ var HOST_PRODUCER_CONFIG_FLAG = "--ceal-host-config";
1923
+ var HostProducerServiceError = class extends Error {
1924
+ code;
1925
+ constructor(code3, message = code3) {
1926
+ super(message === code3 ? code3 : `${code3}: ${message}`);
1927
+ this.name = "HostProducerServiceError";
1928
+ this.code = code3;
1929
+ }
1930
+ };
1931
+ var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint", "reconcile_interval_ms", "retry_backoff_ms", "ipc_timeout_ms"];
1932
+ function parseHostProducerConfigFlag(args, platform = process.platform) {
1933
+ return parseProducerHostConfigFlag(args, HOST_PRODUCER_CONFIG_FLAG, platform, hostProducerError);
1934
+ }
1935
+ async function readHostProducerConfig(descriptor, configPath, platform = process.platform) {
1936
+ return decodeHostProducerConfigText(descriptor, await readProducerConfigText(configPath, platform, hostProducerError), platform);
1937
+ }
1938
+ function decodeHostProducerConfigText(descriptor, text, platform = process.platform) {
1939
+ const extraPaths = descriptor.extra_paths ?? [];
1940
+ const decoded = decodeProducerConfigCore(text, { schema: descriptor.schema, keys: [...HOST_PRODUCER_CONFIG_KEYS, ...extraPaths], platform, extraPaths, error: hostProducerError });
1941
+ const { extra_paths: extras, ...core } = decoded;
1942
+ return Object.freeze(descriptor.config({ schema_version: descriptor.schema, ...core }, extras));
1943
+ }
1944
+ function hostProducerError(code3, message = code3) {
1945
+ return new HostProducerServiceError(code3, message);
1946
+ }
1947
+ function parseProducerHostConfigFlag(args, flag, platform, error) {
1948
+ const prefix = `${flag}=`;
1949
+ const values = args.filter((argument) => argument.startsWith(prefix));
1950
+ if (values.length !== 1) throw error("invalid_arguments", refusalFact("config_flags", values, "exactly one"));
1951
+ const value = values[0]?.slice(prefix.length);
1952
+ assertProducerAbsolutePath(value, platform, "config", error);
1953
+ return value;
1954
+ }
1955
+ async function readProducerConfigText(configPath, platform, error) {
1956
+ assertProducerAbsolutePath(configPath, platform, "config", error);
1957
+ const pathStat = await configPathStat(configPath, error);
1958
+ validateConfigFile(pathStat, platform, error);
1959
+ const noFollow = typeof constants.O_NOFOLLOW === "number" ? constants.O_NOFOLLOW : 0;
1960
+ const handle = await openConfigFile(configPath, constants.O_RDONLY | noFollow, error);
1961
+ try {
1962
+ validateOpenedFile(await handle.stat(), pathStat, platform, error);
1963
+ return await readBoundedConfig(handle, error);
1964
+ } finally {
1965
+ await handle.close();
1966
+ }
1967
+ }
1968
+ function decodeProducerConfigCore(text, options) {
1969
+ const value = parseCanonicalJson(text, options.error);
1970
+ if (!isRecord(value) || !hasExactKeys2(value, options.keys) || value.schema_version !== options.schema) throw options.error("invalid_config");
1971
+ const hostSourceRef = typeof value.host_source_ref === "string" ? value.host_source_ref : "";
1972
+ const installationRef = typeof value.producer_installation_ref === "string" ? value.producer_installation_ref : "";
1973
+ const producerEpoch = validateIdentity(hostSourceRef, installationRef, value.producer_epoch, options.error);
1974
+ assertProducerAbsolutePath(value.outbox_dir, options.platform, "runtime", options.error);
1975
+ assertProducerRelayEndpoint(value.relay_endpoint, options.platform, options.error);
1976
+ const extraPaths = {};
1977
+ for (const key of options.extraPaths ?? []) {
1978
+ assertProducerAbsolutePath(value[key], options.platform, "runtime", options.error);
1979
+ extraPaths[key] = value[key];
1980
+ }
1981
+ const intervals = validateIntervals(value.reconcile_interval_ms, value.retry_backoff_ms, value.ipc_timeout_ms, options.error);
1982
+ return {
1983
+ extra_paths: Object.freeze(extraPaths),
1984
+ host_source_ref: hostSourceRef,
1985
+ producer_installation_ref: installationRef,
1986
+ producer_epoch: producerEpoch,
1987
+ outbox_dir: value.outbox_dir,
1988
+ relay_endpoint: value.relay_endpoint,
1989
+ reconcile_interval_ms: intervals[0],
1990
+ retry_backoff_ms: intervals[1],
1991
+ ipc_timeout_ms: intervals[2]
1992
+ };
1993
+ }
1994
+ function assertProducerRelayEndpoint(value, platform, error) {
1995
+ if (platform === "win32" && typeof value === "string" && /^\\\\\.\\pipe\\[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(value)) return;
1996
+ assertProducerAbsolutePath(value, platform, "runtime", error);
1997
+ }
1998
+ function assertProducerAbsolutePath(value, platform, kind, error) {
1999
+ if (!isAbsoluteNormalizedNonRootPath(value, platform) || /[\r\n]/u.test(value)) throw error(kind === "config" ? "invalid_config_path" : "invalid_config", refusalFact("path", value, "absolute, normalized, non-root, and without line breaks"));
2000
+ }
2001
+ async function configPathStat(configPath, error) {
2002
+ try {
2003
+ return await lstat2(configPath);
2004
+ } catch {
2005
+ throw error("config_unavailable");
2006
+ }
2007
+ }
2008
+ function validateConfigFile(value, platform, error) {
2009
+ if (!value.isFile() || value.isSymbolicLink()) throw error("invalid_config", refusalFacts([{ name: "config_is_file", value: value.isFile(), expected: "true" }, { name: "config_is_symlink", value: value.isSymbolicLink(), expected: "false" }]));
2010
+ if (value.size <= 0 || value.size > MAX_CONFIG_BYTES) throw error("invalid_config", refusalFact("config_bytes", value.size, `between 1 and ${MAX_CONFIG_BYTES}`));
2011
+ if (platform !== "win32" && (value.uid !== process.getuid?.() || (value.mode & 63) !== 0)) throw error("config_not_private", refusalFacts([{ name: "platform", value: platform, expected: "win32 or owner-private" }, { name: "config_uid", value: value.uid, expected: "the current user" }, { name: "config_mode", value: value.mode, expected: "owner-private" }]));
2012
+ }
2013
+ async function openConfigFile(configPath, flags, error) {
2014
+ try {
2015
+ return await open2(configPath, flags);
2016
+ } catch {
2017
+ throw error("config_unavailable");
2018
+ }
2019
+ }
2020
+ function validateOpenedFile(opened, pathStat, platform, error) {
2021
+ if (!opened.isFile()) throw error("config_unavailable", refusalFacts([{ name: "opened_is_file", value: opened.isFile(), expected: "true" }, { name: "opened_mode", value: opened.mode.toString(8), expected: "a regular file mode" }]));
2022
+ if (platform !== "win32" && (opened.dev !== pathStat.dev || opened.ino !== pathStat.ino)) throw error("config_unavailable", refusalFacts([{ name: "platform", value: platform, expected: "win32, or the same file the path named" }, { name: "opened_device", value: opened.dev, expected: String(pathStat.dev) }, { name: "opened_inode", value: opened.ino, expected: String(pathStat.ino) }]));
2023
+ }
2024
+ async function readBoundedConfig(handle, error) {
2025
+ const buffer = Buffer.allocUnsafe(MAX_CONFIG_BYTES + 1);
2026
+ const { bytesRead } = await handle.read(buffer, 0, buffer.byteLength, 0);
2027
+ if (bytesRead === 0 || bytesRead > MAX_CONFIG_BYTES) throw error("invalid_config", refusalFact("bytes_read", bytesRead, `between 1 and ${MAX_CONFIG_BYTES}`));
2028
+ try {
2029
+ return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0, bytesRead));
2030
+ } catch {
2031
+ throw error("invalid_config");
2032
+ }
2033
+ }
2034
+ function parseCanonicalJson(text, error) {
2035
+ try {
2036
+ const value = JSON.parse(text);
2037
+ const canonical = JSON.stringify(value);
2038
+ if (canonical !== text.trim()) throw new Error(`noncanonical: ${refusalFacts([{ name: "config_bytes", value: Buffer.byteLength(text.trim(), "utf8"), expected: `the ${Buffer.byteLength(canonical, "utf8")} bytes of its canonical form` }, { name: "first_difference_index", value: firstDifferenceIndex(text.trim(), canonical) }])}`);
2039
+ return value;
2040
+ } catch (parseError) {
2041
+ throw error("invalid_config", refusalFacts([{ name: "parse_error", value: parseError }, { name: "config_bytes", value: Buffer.byteLength(text, "utf8"), expected: "canonical JSON" }]));
2042
+ }
2043
+ }
2044
+ function firstDifferenceIndex(left, right) {
2045
+ const shared = Math.min(left.length, right.length);
2046
+ for (let index = 0; index < shared; index += 1) if (left[index] !== right[index]) return index;
2047
+ return shared;
2048
+ }
2049
+ function validateIdentity(sourceRef, installationRef, epoch, error) {
2050
+ if (!SAFE_REF3.test(sourceRef) || !SAFE_REF3.test(installationRef) || !positive2(epoch, 2147483647)) throw error("invalid_config");
2051
+ return epoch;
2052
+ }
2053
+ function validateIntervals(reconcile, retry, timeout, error) {
2054
+ if (!boundedMilliseconds(reconcile) || !boundedMilliseconds(retry) || !boundedMilliseconds(timeout)) throw error("invalid_config");
2055
+ return [reconcile, retry, timeout];
2056
+ }
2057
+ function hasExactKeys2(value, keys) {
2058
+ const observed = Object.keys(value);
2059
+ return observed.length === keys.length && keys.every((key) => Object.hasOwn(value, key));
2060
+ }
2061
+ function isRecord(value) {
2062
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2063
+ }
2064
+ function positive2(value, maximum) {
2065
+ return Number.isSafeInteger(value) && Number(value) > 0 && Number(value) <= maximum;
2066
+ }
2067
+ function boundedMilliseconds(value) {
2068
+ return positive2(value, 6e4) && Number(value) >= 25;
2069
+ }
2070
+
2071
+ // host/claude/src/claude-decoder.ts
2072
+ import { createHash as createHash2 } from "node:crypto";
2073
+
2074
+ // host/claude/src/claude-types.ts
2075
+ var CLAUDE_HOST_ERROR_CODES = ["invalid_input", "storage", "configuration"];
2076
+ function isClaudeHostErrorCode(value) {
2077
+ return typeof value === "string" && CLAUDE_HOST_ERROR_CODES.some((code3) => code3 === value);
2078
+ }
2079
+ var CLAUDE_OUTBOX_SCHEMA = "ceal.claude_hook_outbox.v1";
2080
+ var CLAUDE_INVOCATION_CONTEXT_SCHEMA_VERSION = "ceal.claude_invocation_context.v1";
2081
+ var ClaudeHostError = class extends Error {
2082
+ name = "ClaudeHostError";
2083
+ code;
2084
+ constructor(code3, message) {
2085
+ super(message);
2086
+ if (!isClaudeHostErrorCode(code3)) throw new TypeError("Claude Host error code is invalid.");
2087
+ this.code = code3;
2088
+ }
2089
+ };
2090
+
2091
+ // host/claude/src/claude-decoder.ts
2092
+ var MAX_HOOK_BYTES = 256 * 1024;
2093
+ var MAX_TEXT = 128 * 1024;
2094
+ function claudeLocalSessionRef(sessionId) {
2095
+ return `claude-session:${digest(sessionId)}`;
2096
+ }
2097
+ function digest(value) {
2098
+ return createHash2("sha256").update(value, "utf8").digest("hex");
2099
+ }
2100
+
2101
+ // host/claude/src/claude-outbox.ts
2102
+ import { open as open3, mkdir as mkdir2, readdir, readFile, unlink as unlink2 } from "node:fs/promises";
2103
+ import { join as join2 } from "node:path";
2104
+
2105
+ // host/invocation-context.ts
2106
+ var HOST_INVOCATION_IDENTITY_KEYS = ["host_session_ref", "host_turn_ref", "host_source_ref"];
2107
+ var HOST_INVOCATION_CONTEXT_REQUIRED_KEYS = ["schema_version", "identity", "prompt_ref", "expires_at"];
2108
+ function invocationContextKey(identity) {
2109
+ return cealRequestSha256({ host_source_ref: identity.host_source_ref, host_session_ref: identity.host_session_ref });
2110
+ }
2111
+ function hasHostInvocationIdentityKeys(value) {
2112
+ return exactKeys4(value, HOST_INVOCATION_IDENTITY_KEYS);
2113
+ }
2114
+ function hasHostInvocationContextKeys(value, optional = []) {
2115
+ return requiredKeys(value, HOST_INVOCATION_CONTEXT_REQUIRED_KEYS, optional);
2116
+ }
2117
+ function invocationContextFromTurn(identity, promptRef, expiresAt, descriptor) {
2118
+ const context = {
2119
+ schema_version: descriptor.schema_version,
2120
+ identity,
2121
+ prompt_ref: promptRef,
2122
+ expires_at: expiresAt,
2123
+ ...descriptor.working_directory === void 0 ? {} : { working_directory: descriptor.working_directory }
2124
+ };
2125
+ descriptor.validate(context);
2126
+ return Object.freeze(context);
2127
+ }
2128
+ function exactKeys4(value, keys) {
2129
+ const actual = Object.keys(value);
2130
+ return actual.length === keys.length && keys.every((key) => Object.hasOwn(value, key)) && actual.every((key) => keys.includes(key));
2131
+ }
2132
+ function requiredKeys(value, required, optional) {
2133
+ const actual = Object.keys(value);
2134
+ const allowed = /* @__PURE__ */ new Set([...required, ...optional]);
2135
+ return actual.length >= required.length && actual.length <= allowed.size && required.every((key) => Object.hasOwn(value, key)) && actual.every((key) => allowed.has(key));
2136
+ }
2137
+
2138
+ // host/claude/src/claude-invocation-context.ts
2139
+ function claudeInvocationContextFromTurn(identity, promptRef, expiresAt, workingDirectory) {
2140
+ return invocationContextFromTurn(identity, promptRef, expiresAt, { schema_version: CLAUDE_INVOCATION_CONTEXT_SCHEMA_VERSION, validate: validateClaudeHostInvocationContext, working_directory: workingDirectory });
2141
+ }
2142
+ function validateClaudeHostInvocationContext(value) {
2143
+ if (!contextShape(value)) throw new ClaudeHostError("storage", "Claude Host invocation context is malformed.");
2144
+ validateIdentity2(value.identity);
2145
+ validateContextReferences(value);
2146
+ validateContextTimes(value);
2147
+ }
2148
+ function contextShape(value) {
2149
+ return record3(value) && value.schema_version === CLAUDE_INVOCATION_CONTEXT_SCHEMA_VERSION && hasHostInvocationContextKeys(value, ["request_ref", "bound_at", "working_directory"]);
2150
+ }
2151
+ function validateIdentity2(value) {
2152
+ if (!validIdentity(value)) throw new ClaudeHostError("storage", "Claude Host invocation identity is malformed.");
2153
+ }
2154
+ function validateContextReferences(value) {
2155
+ if (!safeRef3(value.prompt_ref) || !optionalSafeRef(value.request_ref)) throw new ClaudeHostError("storage", "Claude Host invocation context is malformed.");
2156
+ }
2157
+ function validateContextTimes(value) {
2158
+ if (!timestamp2(value.expires_at) || !optionalTimestamp(value.bound_at) || !optionalDirectory(value.working_directory)) throw new ClaudeHostError("storage", "Claude Host invocation context is malformed.");
2159
+ if (typeof value.bound_at === "string" && Date.parse(value.bound_at) > Date.parse(String(value.expires_at))) throw new ClaudeHostError("storage", `Claude Host invocation context has invalid binding time (${refusalFact("bound_at", value.bound_at, `at or before ${String(value.expires_at)}`)}).`);
2160
+ }
2161
+ function validIdentity(value) {
2162
+ return record3(value) && hasHostInvocationIdentityKeys(value) && [value.host_session_ref, value.host_turn_ref, value.host_source_ref].every(safeRef3);
2163
+ }
2164
+ function optionalSafeRef(value) {
2165
+ return value === void 0 || safeRef3(value);
2166
+ }
2167
+ function optionalTimestamp(value) {
2168
+ return value === void 0 || timestamp2(value);
2169
+ }
2170
+ function optionalDirectory(value) {
2171
+ return value === void 0 || typeof value === "string" && value.startsWith("/") && !value.includes("\0") && value.length <= 4096;
2172
+ }
2173
+ function safeRef3(value) {
2174
+ return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u.test(value);
2175
+ }
2176
+ function timestamp2(value) {
2177
+ return typeof value === "string" && value.length <= 64 && Number.isFinite(Date.parse(value));
2178
+ }
2179
+ function record3(value) {
2180
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2181
+ }
2182
+
2183
+ // host/claude/src/claude-outbox.ts
2184
+ var SAFE_REF4 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
2185
+ var ClaudeOutboxStore = class {
2186
+ entries;
2187
+ directory;
2188
+ activeContexts;
2189
+ constructor(directory) {
2190
+ if (!directory.startsWith("/")) throw new ClaudeHostError("configuration", "Claude outbox directory must be absolute.");
2191
+ this.directory = directory;
2192
+ this.entries = join2(directory, "entries");
2193
+ this.activeContexts = join2(directory, "active-contexts");
2194
+ }
2195
+ async prepare() {
2196
+ await mkdir2(this.entries, { recursive: true, mode: 448 });
2197
+ await mkdir2(this.activeContexts, { recursive: true, mode: 448 });
2198
+ }
2199
+ async activateInvocationContext(identity, promptRef, expiresAt, workingDirectory) {
2200
+ const context = claudeInvocationContextFromTurn(identity, promptRef, expiresAt, workingDirectory);
2201
+ await this.prepare();
2202
+ await durableAtomicReplace(this.activeContextPath(identity), JSON.stringify(context));
2203
+ }
2204
+ async readInvocationContext(hostSourceRef, hostSessionRef, now = /* @__PURE__ */ new Date()) {
2205
+ validateInvocationContextReadArguments(hostSourceRef, hostSessionRef, now);
2206
+ await this.prepare();
2207
+ return readInvocationContextFile(this.activeContextPath({ host_source_ref: hostSourceRef, host_session_ref: hostSessionRef }), hostSourceRef, hostSessionRef, now);
2208
+ }
2209
+ async listInvocationContexts(now = /* @__PURE__ */ new Date()) {
2210
+ await this.prepare();
2211
+ const contexts = [];
2212
+ for (const name of await readdir(this.activeContexts)) {
2213
+ if (!name.endsWith(".json")) continue;
2214
+ try {
2215
+ const value = JSON.parse(await readFile(join2(this.activeContexts, name), "utf8"));
2216
+ validateClaudeHostInvocationContext(value);
2217
+ if (Date.parse(value.expires_at) > now.getTime()) contexts.push(value);
2218
+ } catch {
2219
+ }
2220
+ }
2221
+ return contexts;
2222
+ }
2223
+ async put(batch) {
2224
+ validateBatch(batch);
2225
+ await this.prepare();
2226
+ const path = this.path(batch.batch_ref);
2227
+ try {
2228
+ const handle = await open3(path, "wx", 384);
2229
+ try {
2230
+ await handle.writeFile(JSON.stringify(batch));
2231
+ await handle.sync();
2232
+ } finally {
2233
+ await handle.close();
2234
+ }
2235
+ } catch (error) {
2236
+ if (code(error) !== "EEXIST") throw new ClaudeHostError("storage", `Unable to persist Claude hook batch (${refusalFact("error_code", code(error), "EEXIST for an idempotent retry")}).`);
2237
+ const existing = JSON.parse(await readFile(path, "utf8"));
2238
+ validateBatch(existing);
2239
+ if (JSON.stringify(existing) !== JSON.stringify(batch)) throw new ClaudeHostError("storage", "Claude hook batch identity conflicts with different bytes.");
2240
+ }
2241
+ }
2242
+ async list() {
2243
+ await this.prepare();
2244
+ const batches = [];
2245
+ let malformed = 0;
2246
+ for (const name of await readdir(this.entries)) {
2247
+ if (!name.endsWith(".json")) continue;
2248
+ try {
2249
+ const value = JSON.parse(await readFile(join2(this.entries, name), "utf8"));
2250
+ validateBatch(value);
2251
+ batches.push(value);
2252
+ } catch {
2253
+ malformed += 1;
2254
+ }
2255
+ }
2256
+ batches.sort(compareBatch);
2257
+ return { entries: batches, malformed };
2258
+ }
2259
+ async remove(batch) {
2260
+ try {
2261
+ await unlink2(this.path(batch.batch_ref));
2262
+ } catch (error) {
2263
+ if (code(error) !== "ENOENT") throw error;
2264
+ }
2265
+ }
2266
+ path(ref) {
2267
+ return join2(this.entries, `${cealRequestSha256(ref)}.json`);
2268
+ }
2269
+ activeContextPath(identity) {
2270
+ return join2(this.activeContexts, `${invocationContextKey(identity)}.json`);
2271
+ }
2272
+ };
2273
+ function validateInvocationContextReadArguments(hostSourceRef, hostSessionRef, now) {
2274
+ if (!SAFE_REF4.test(hostSourceRef) || !SAFE_REF4.test(hostSessionRef) || !(now instanceof Date) || !Number.isFinite(now.getTime())) throw new ClaudeHostError("invalid_input", "Claude Host context identity or clock is invalid.");
2275
+ }
2276
+ async function readInvocationContextFile(file, hostSourceRef, hostSessionRef, now) {
2277
+ try {
2278
+ const context = JSON.parse(await readFile(file, "utf8"));
2279
+ validateClaudeHostInvocationContext(context);
2280
+ return contextMatches(context, hostSourceRef, hostSessionRef) && Date.parse(context.expires_at) > now.getTime() ? context : null;
2281
+ } catch (error) {
2282
+ if (code(error) === "ENOENT") return null;
2283
+ if (error instanceof ClaudeHostError) throw error;
2284
+ throw new ClaudeHostError("storage", "Unable to read the Claude Host invocation context.");
2285
+ }
2286
+ }
2287
+ function contextMatches(context, hostSourceRef, hostSessionRef) {
2288
+ return context.identity.host_source_ref === hostSourceRef && context.identity.host_session_ref === hostSessionRef;
2289
+ }
2290
+ function compareBatch(left, right) {
2291
+ return rank(left.hook_event) - rank(right.hook_event) || left.occurred_at.localeCompare(right.occurred_at) || left.batch_ref.localeCompare(right.batch_ref);
2292
+ }
2293
+ function rank(event) {
2294
+ return event === "SessionStart" ? 0 : event === "UserPromptSubmit" ? 1 : 2;
2295
+ }
2296
+ function validateBatch(value) {
2297
+ if (!validBatchHeader(value)) throw new ClaudeHostError("storage", "Claude hook batch is malformed.");
2298
+ for (const [index, draft] of value.frames.entries()) {
2299
+ if (!record4(draft) || !hostFrameKind(draft.frame_kind) || !record4(draft.payload)) throw new ClaudeHostError("storage", "Claude frame draft is malformed.");
2300
+ encodeHostProducerFrame({ schema_version: "ceal.host_producer_frame.v1", producer_id: "claude", producer_installation_ref: "validation", producer_epoch: 1, sequence: index + 1, frame_kind: draft.frame_kind, occurred_at: value.occurred_at, payload: draft.payload });
2301
+ }
2302
+ }
2303
+ function validBatchHeader(value) {
2304
+ return record4(value) && value.schema_version === CLAUDE_OUTBOX_SCHEMA && safeRef4(value.batch_ref) && claudeEvent(value.hook_event) && safeRef4(value.local_session_ref) && optionalRef(value.local_turn_ref) && timestamp3(value.occurred_at) && Array.isArray(value.frames) && value.frames.length > 0 && value.frames.length <= 3;
2305
+ }
2306
+ function claudeEvent(value) {
2307
+ return typeof value === "string" && ["SessionStart", "UserPromptSubmit", "Stop", "StopFailure"].includes(value);
2308
+ }
2309
+ function hostFrameKind(value) {
2310
+ return isHostProducerFrameKind(value);
2311
+ }
2312
+ function safeRef4(value) {
2313
+ return typeof value === "string" && SAFE_REF4.test(value);
2314
+ }
2315
+ function optionalRef(value) {
2316
+ return value === void 0 || typeof value === "string" && SAFE_REF4.test(value);
2317
+ }
2318
+ function timestamp3(value) {
2319
+ return typeof value === "string" && Number.isFinite(Date.parse(value));
2320
+ }
2321
+ function record4(value) {
2322
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2323
+ }
2324
+ function code(error) {
2325
+ return record4(error) && typeof error.code === "string" ? error.code : null;
2326
+ }
2327
+
2328
+ // host/claude/src/claude-producer.ts
2329
+ import { mkdir as mkdir3, readFile as readFile2, rename as rename2, writeFile } from "node:fs/promises";
2330
+ import { join as join3 } from "node:path";
2331
+ var STATE_SCHEMA = "ceal.claude_producer_state.v1";
2332
+ var SAFE_REF5 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
2333
+ var ClaudeProducer = class {
2334
+ store;
2335
+ statePath;
2336
+ installation;
2337
+ epoch;
2338
+ options;
2339
+ tail = Promise.resolve();
2340
+ constructor(options) {
2341
+ if (!SAFE_REF5.test(options.producer_installation_ref)) throw new ClaudeHostError("configuration", "Claude producer installation identity is invalid.");
2342
+ this.options = options;
2343
+ this.epoch = options.producer_epoch ?? 1;
2344
+ if (!Number.isSafeInteger(this.epoch) || this.epoch <= 0) throw new ClaudeHostError("configuration", "Claude producer epoch is invalid.");
2345
+ this.store = new ClaudeOutboxStore(options.outbox_dir);
2346
+ this.statePath = join3(options.outbox_dir, "claude-producer-state.json");
2347
+ this.installation = options.producer_installation_ref;
2348
+ }
2349
+ drainOutbox() {
2350
+ const run = this.tail.then(() => this.drainLocked());
2351
+ this.tail = run.then(() => void 0, () => void 0);
2352
+ return run;
2353
+ }
2354
+ async drainLocked() {
2355
+ const read = await this.store.list();
2356
+ let admitted = 0;
2357
+ let retained = 0;
2358
+ for (const batch of read.entries) {
2359
+ const frames = await this.reserve(batch);
2360
+ let complete = true;
2361
+ for (const frame of frames) {
2362
+ const outcome = await this.options.relay.admit(frame);
2363
+ if (outcome.code !== "admitted" && outcome.code !== "already_admitted") {
2364
+ complete = false;
2365
+ break;
2366
+ }
2367
+ }
2368
+ if (!complete) {
2369
+ retained += 1;
2370
+ break;
2371
+ }
2372
+ await this.store.remove(batch);
2373
+ await this.release(batch.batch_ref);
2374
+ admitted += 1;
2375
+ }
2376
+ return { admitted, retained: retained + Math.max(0, read.entries.length - admitted - retained), malformed: read.malformed };
2377
+ }
2378
+ async reserve(batch) {
2379
+ const state = await this.readState();
2380
+ const existing = state.pending[batch.batch_ref];
2381
+ if (existing !== void 0) return existing;
2382
+ const frames = batch.frames.map((draft, offset) => ({ schema_version: "ceal.host_producer_frame.v1", producer_id: "claude", producer_installation_ref: this.installation, producer_epoch: this.epoch, sequence: state.next_sequence + offset, frame_kind: draft.frame_kind, occurred_at: batch.occurred_at, payload: draft.payload }));
2383
+ await this.writeState({ ...state, next_sequence: state.next_sequence + frames.length, pending: { ...state.pending, [batch.batch_ref]: frames } });
2384
+ return frames;
2385
+ }
2386
+ async release(ref) {
2387
+ const state = await this.readState();
2388
+ if (state.pending[ref] === void 0) return;
2389
+ const pending = { ...state.pending };
2390
+ delete pending[ref];
2391
+ await this.writeState({ ...state, pending });
2392
+ }
2393
+ async readState() {
2394
+ try {
2395
+ return decodeState(JSON.parse(await readFile2(this.statePath, "utf8")), this.installation, this.epoch);
2396
+ } catch (error) {
2397
+ if (code2(error) !== "ENOENT") throw error;
2398
+ return { schema_version: STATE_SCHEMA, producer_installation_ref: this.installation, producer_epoch: this.epoch, next_sequence: 1, pending: {} };
2399
+ }
2400
+ }
2401
+ async writeState(state) {
2402
+ await mkdir3(this.store.directory, { recursive: true, mode: 448 });
2403
+ const temp = `${this.statePath}.${process.pid}.new`;
2404
+ await writeFile(temp, JSON.stringify(state), { mode: 384 });
2405
+ await rename2(temp, this.statePath);
2406
+ }
2407
+ };
2408
+ function decodeState(value, installation, epoch) {
2409
+ if (!validStateHeader(value, installation)) throw new ClaudeHostError("storage", `Claude producer state header is malformed or belongs to another installation (${refusalFacts([
2410
+ { name: "schema_version", value: record5(value) ? value.schema_version : void 0, expected: STATE_SCHEMA },
2411
+ { name: "producer_installation_ref", value: record5(value) ? value.producer_installation_ref : void 0, expected: installation }
2412
+ ])}).`);
2413
+ if (Number(value.producer_epoch) > epoch) throw new ClaudeHostError("storage", `Claude producer state epoch is ahead of this installation (${refusalFact("producer_epoch", value.producer_epoch, `at most ${epoch}`)}).`);
2414
+ const pending = {};
2415
+ for (const [ref, frames] of Object.entries(value.pending)) {
2416
+ if (!SAFE_REF5.test(ref) || !Array.isArray(frames) || frames.length === 0) throw new ClaudeHostError("storage", "Claude producer reservation is malformed.");
2417
+ pending[ref] = frames.map((frame) => decodeFrame(frame, installation, Number(value.producer_epoch)));
2418
+ }
2419
+ return { schema_version: STATE_SCHEMA, producer_installation_ref: installation, producer_epoch: epoch, next_sequence: Number(value.next_sequence), pending };
2420
+ }
2421
+ function validStateHeader(value, installation) {
2422
+ return record5(value) && value.schema_version === STATE_SCHEMA && value.producer_installation_ref === installation && positiveInteger(value.producer_epoch) && positiveInteger(value.next_sequence) && record5(value.pending);
2423
+ }
2424
+ function positiveInteger(value) {
2425
+ return Number.isSafeInteger(value) && Number(value) > 0;
2426
+ }
2427
+ function decodeFrame(value, installation, epoch) {
2428
+ const json = Buffer.from(JSON.stringify(value));
2429
+ const encoded = Buffer.allocUnsafe(json.length + 4);
2430
+ encoded.writeUInt32BE(json.length, 0);
2431
+ json.copy(encoded, 4);
2432
+ const frame = decodeHostProducerFrame(encoded);
2433
+ if (frame.producer_id !== "claude" || frame.producer_installation_ref !== installation || frame.producer_epoch > epoch) throw new ClaudeHostError("storage", `Claude producer frame identity is malformed (${refusalFacts([{ name: "producer_id", value: frame.producer_id, expected: "claude" }, { name: "producer_installation_ref", value: frame.producer_installation_ref, expected: installation }, { name: "producer_epoch", value: frame.producer_epoch, expected: `at most ${epoch}` }])}).`);
2434
+ return frame;
2435
+ }
2436
+ function record5(value) {
2437
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2438
+ }
2439
+ function code2(error) {
2440
+ return record5(error) && typeof error.code === "string" ? error.code : null;
2441
+ }
2442
+
2443
+ // host/claude/src/claude-producer-runtime.ts
2444
+ async function drainClaudeProducerOnce(options) {
2445
+ return new ClaudeProducer({ outbox_dir: options.outbox_dir, producer_installation_ref: options.producer_installation_ref, relay: new HostRelayIpcAdmissionPort(options.relay_endpoint, options.timeout_ms), ...options.producer_epoch === void 0 ? {} : { producer_epoch: options.producer_epoch } }).drainOutbox();
2446
+ }
2447
+
2448
+ // host/claude/src/claude-producer-service.ts
2449
+ var CLAUDE_PRODUCER_CONFIG_SCHEMA = "ceal.claude_producer_config.v1";
2450
+ var CLAUDE_PRODUCER_DESCRIPTOR = {
2451
+ schema: CLAUDE_PRODUCER_CONFIG_SCHEMA,
2452
+ config: (shared) => shared,
2453
+ runtime_options: (config) => Object.freeze({
2454
+ outbox_dir: config.outbox_dir,
2455
+ producer_installation_ref: config.producer_installation_ref,
2456
+ producer_epoch: config.producer_epoch,
2457
+ relay_endpoint: config.relay_endpoint,
2458
+ timeout_ms: config.ipc_timeout_ms
2459
+ }),
2460
+ drain: drainClaudeProducerOnce
2461
+ };
2462
+
2463
+ // host/claude/src/claude-invocation-authentication-command.ts
2464
+ var CLAUDE_INVOCATION_AUTHENTICATION_DESCRIPTOR = {
2465
+ command_name: "ceal-claude-invocation-authentication",
2466
+ producer_id: "claude",
2467
+ create_store: (directory) => new ClaudeOutboxStore(directory),
2468
+ session_id_env: "CLAUDE_SESSION_ID",
2469
+ session_ref: (_hostSourceRef, sessionId) => claudeLocalSessionRef(sessionId),
2470
+ config_flag: HOST_PRODUCER_CONFIG_FLAG,
2471
+ parse_config_flag: parseHostProducerConfigFlag,
2472
+ read_producer_config: (configPath) => readHostProducerConfig(CLAUDE_PRODUCER_DESCRIPTOR, configPath)
2473
+ };
2474
+ function runClaudeInvocationAuthenticationCommand(args, options) {
2475
+ return runHostInvocationAuthenticationCommand(CLAUDE_INVOCATION_AUTHENTICATION_DESCRIPTOR, args, options);
2476
+ }
2477
+
2478
+ // host/client-doctor.ts
2479
+ import { createHash as createHash3 } from "node:crypto";
2480
+ import { execFile } from "node:child_process";
2481
+ import { access, open as open4, readFile as readFile3, realpath, stat } from "node:fs/promises";
2482
+ import { delimiter, isAbsolute, join as join4 } from "node:path";
2483
+ import { promisify } from "node:util";
2484
+ var execFileAsync = promisify(execFile);
2485
+ var GIT_OID = /^[a-f0-9]{40}$/u;
2486
+ var SHA2562 = /^[a-f0-9]{64}$/u;
2487
+ var SAFE_REF6 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/u;
2488
+ var CEAL_ENVIRONMENT_OVERRIDES = ["CEAL_GATEWAY_ORIGIN", "CEAL_GATEWAY_TRANSPORT_ORIGIN", "CEAL_ACCESS_TOKEN", "CEAL_CONTEXT_STORE_PATH"];
2489
+ async function doctorClient(options = {}, component) {
2490
+ const environment = canonicalClientEnvironment(options.environment ?? process.env);
2491
+ const run = options.run ?? executeCealCommand;
2492
+ const executableInspection = await inspectExecutable(options, environment, component);
2493
+ if (!executableInspection.ok) return executableInspection.failure;
2494
+ const executable = executableInspection.value;
2495
+ const versionInspection = await inspectVersion(options, executable, environment, run, component);
2496
+ if (!versionInspection.ok) return versionInspection.failure;
2497
+ const version = versionInspection.value;
2498
+ const contextInspection = await inspectCanonicalContext(options, executable, environment, run, component);
2499
+ if (!contextInspection.ok) return contextInspection.failure;
2500
+ const selected = contextInspection.value;
2501
+ const readbackFailure = await inspectAuthenticatedReadback(executable, selected, environment, run, component);
2502
+ if (readbackFailure !== null) return readbackFailure;
2503
+ return {
2504
+ ok: true,
2505
+ status: "ready",
2506
+ executable_path: executable.path,
2507
+ executable_sha256: executable.sha256,
2508
+ version: version.version,
2509
+ source_commit: version.source_commit,
2510
+ source_tree: version.source_tree,
2511
+ context_source: "canonical_user_config",
2512
+ context_name: selected.name,
2513
+ instance_ref: selected.instance_ref,
2514
+ profile_ref: selected.profile_ref,
2515
+ authenticated_readback: "profile.read"
2516
+ };
2517
+ }
2518
+ async function inspectExecutable(options, environment, component) {
2519
+ let executable;
2520
+ try {
2521
+ executable = await (options.resolve_executable ?? resolveCealExecutable)(options.executable ?? "ceal", environment);
2522
+ } catch (error) {
2523
+ return inspectedFailure("ceal_unavailable", `The ${component} Host cannot resolve an executable Ceal client from its current environment (${refusalFact("error", error)}).`, `Install the intended Ceal client in the Host PATH, restart ${component}, and run this doctor again.`);
2524
+ }
2525
+ if (!validExpectations(options) || options.expected_sha256 !== void 0 && executable.sha256 !== options.expected_sha256) return inspectedFailure("ceal_identity_mismatch", `The Ceal executable visible to the ${component} Host does not match the intended candidate.`, `Install the exact candidate bytes, restart ${component}, and run this doctor with the expected identity.`);
2526
+ return { ok: true, value: executable };
2527
+ }
2528
+ async function inspectVersion(options, executable, environment, run, component) {
2529
+ const probe = hostClientProbe(await safeRun(run, executable.path, ["version"], environment), (result) => versionIdentity(commandDocument(result)));
2530
+ if (probe.kind !== "value") return probeFailure(probe, "version", component, options);
2531
+ if (options.expected_source_commit !== void 0 && probe.value.source_commit !== options.expected_source_commit) return inspectedFailure("ceal_identity_mismatch", `The Ceal executable visible to the ${component} Host did not return the expected source identity (${refusalFact("source_commit", probe.value.source_commit, `expected ${options.expected_source_commit}`)}).`, `Install the exact candidate, restart ${component}, and verify \`ceal version\` from that Host.`);
2532
+ return { ok: true, value: probe.value };
2533
+ }
2534
+ function executableIdentity(options) {
2535
+ return options.expected_sha256 === void 0 ? "resolved" : "verified";
2536
+ }
2537
+ function probeFailure(probe, command, component, options) {
2538
+ const refusal = hostClientProbeRefusal(probe, { component, command, executable_identity: executableIdentity(options) });
2539
+ return inspectedFailure(probeCode(refusal.code), refusal.message, refusal.next_action);
2540
+ }
2541
+ function probeCode(code3) {
2542
+ if (code3 === "ceal_execution_failed" || code3 === "ceal_command_refused") return code3;
2543
+ return "ceal_output_unreadable";
2544
+ }
2545
+ async function inspectCanonicalContext(options, executable, environment, run, component) {
2546
+ const probe = hostClientProbe(await safeRun(run, executable.path, ["profile", "list"], environment), (result) => selectedContext(commandDocument(result)));
2547
+ if (probe.kind === "unreachable") return probeFailure(probe, "profile list", component, options);
2548
+ if (probe.kind !== "value" || options.expected_instance_ref !== void 0 && probe.value.instance_ref !== options.expected_instance_ref) return inspectedFailure("canonical_context_unavailable", `The ${component} Host cannot select the intended authenticated context from Ceal's canonical user configuration (${refusalFacts([{ name: "probe_kind", value: probe.kind, expected: "value" }, { name: "instance_ref", value: probe.kind === "value" ? probe.value.instance_ref : "unavailable", expected: options.expected_instance_ref ?? "a selected context" }])}).`, `Run \`ceal session adopt --email <email>\` without CEAL context overrides, then restart ${component}.`);
2549
+ return { ok: true, value: probe.value };
2550
+ }
2551
+ async function inspectAuthenticatedReadback(executable, selected, environment, run, component) {
2552
+ const result = await safeRun(run, executable.path, ["profile", "show"], environment);
2553
+ if (result !== null && result.exit_code === 0 && readbackProvesSelectedContext(commandDocument(result), selected)) return null;
2554
+ return failure("gateway_context_unavailable", "The canonical Ceal context could not complete an authenticated Gateway readback.", `Inspect the structured \`ceal profile show\` failure, repair or re-adopt the context, then restart ${component} if its environment changed.`);
2555
+ }
2556
+ function inspectedFailure(code3, message, nextAction) {
2557
+ return { ok: false, failure: failure(code3, message, nextAction) };
2558
+ }
2559
+ function canonicalClientEnvironment(input) {
2560
+ const environment = { ...input };
2561
+ for (const name of CEAL_ENVIRONMENT_OVERRIDES) delete environment[name];
2562
+ return environment;
2563
+ }
2564
+ async function resolveCealExecutable(command, environment) {
2565
+ const candidates = isAbsolute(command) ? [command] : (environment.PATH ?? "").split(delimiter).filter((entry) => entry.length > 0).map((entry) => join4(entry, command));
2566
+ for (const candidate of candidates) {
2567
+ try {
2568
+ await access(candidate);
2569
+ const path = await realpath(candidate);
2570
+ const metadata = await stat(path);
2571
+ if (!metadata.isFile()) continue;
2572
+ if (await isLauncher(path)) return resolveLauncherBinary(path, environment);
2573
+ return { path, sha256: createHash3("sha256").update(await readFile3(path)).digest("hex") };
2574
+ } catch {
2575
+ }
2576
+ }
2577
+ throw new Error("ceal executable unavailable");
2578
+ }
2579
+ async function isLauncher(path) {
2580
+ if (/\.(?:bat|cjs|cmd|js|mjs|ps1)$/u.test(path)) return true;
2581
+ const handle = await open4(path, "r");
2582
+ try {
2583
+ const buffer = Buffer.alloc(128);
2584
+ const { bytesRead } = await handle.read(buffer, 0, buffer.byteLength, 0);
2585
+ const prefix = buffer.subarray(0, bytesRead).toString("utf8");
2586
+ return prefix.startsWith("#!") && /\bnode\b/u.test(prefix.split("\n", 1)[0] ?? "");
2587
+ } finally {
2588
+ await handle.close();
2589
+ }
2590
+ }
2591
+ async function resolveLauncherBinary(launcherPath, environment) {
2592
+ const result = await execFileAsync(launcherPath, ["doctor"], { env: environment, timeout: 15e3, encoding: "utf8", windowsHide: false });
2593
+ let parsed;
2594
+ try {
2595
+ parsed = JSON.parse(result.stdout);
2596
+ } catch {
2597
+ throw new Error("launcher doctor returned unreadable output");
2598
+ }
2599
+ if (!isRecord2(parsed) || parsed.schema_version !== "ceal.doctor.v1" || parsed.ok !== true || typeof parsed.binary_path !== "string" || parsed.binary_path.length === 0) throw new Error("launcher doctor did not report a binary path");
2600
+ const binaryPath = await realpath(parsed.binary_path);
2601
+ const metadata = await stat(binaryPath);
2602
+ if (!metadata.isFile()) throw new Error("launcher doctor reported a non-file binary path");
2603
+ return { path: binaryPath, sha256: createHash3("sha256").update(await readFile3(binaryPath)).digest("hex") };
2604
+ }
2605
+ async function executeCealCommand(executable, args, environment) {
2606
+ try {
2607
+ const result = await execFileAsync(executable, [...args], { env: environment, timeout: 15e3, encoding: "utf8" });
2608
+ return { exit_code: 0, stdout: result.stdout, stderr: result.stderr };
2609
+ } catch (error) {
2610
+ if (isRecord2(error)) return { exit_code: typeof error.code === "number" ? error.code : 1, stdout: typeof error.stdout === "string" ? error.stdout : "", stderr: typeof error.stderr === "string" ? error.stderr : "" };
2611
+ throw error;
2612
+ }
2613
+ }
2614
+ function safeRun(run, executable, args, environment) {
2615
+ return run(executable, args, environment).catch(() => null);
2616
+ }
2617
+ function commandDocument(result) {
2618
+ if (result === null) return null;
2619
+ try {
2620
+ const value = JSON.parse(result.stdout);
2621
+ return isRecord2(value) ? value : null;
2622
+ } catch {
2623
+ return null;
2624
+ }
2625
+ }
2626
+ function selectedContext(value) {
2627
+ if (value?.schema_version !== "ceal.profile.v1" || value.ok !== true || !Array.isArray(value.contexts)) return null;
2628
+ const selected = value.contexts.filter((item) => isRecord2(item) && item.selected === true);
2629
+ if (selected.length !== 1) return null;
2630
+ return selectedContextRecord(selected[0]);
2631
+ }
2632
+ function selectedContextRecord(item) {
2633
+ if (!isRecord2(item) || typeof item.name !== "string" || typeof item.instance_ref !== "string" || typeof item.profile_ref !== "string") return null;
2634
+ if (!SAFE_REF6.test(item.instance_ref) || !SAFE_REF6.test(item.profile_ref)) return null;
2635
+ return { name: item.name, instance_ref: item.instance_ref, profile_ref: item.profile_ref };
2636
+ }
2637
+ function versionIdentity(value) {
2638
+ if (value?.schema_version !== "ceal.version.v1" || value.ok !== true || typeof value.version !== "string" || typeof value.source_commit !== "string" || typeof value.source_tree !== "string") return null;
2639
+ if (value.version.length === 0 || !GIT_OID.test(value.source_commit) || !GIT_OID.test(value.source_tree)) return null;
2640
+ return { version: value.version, source_commit: value.source_commit, source_tree: value.source_tree };
2641
+ }
2642
+ function readbackProvesSelectedContext(value, selected) {
2643
+ const authority = cealAuthenticatedProfileReadback(value);
2644
+ return authority?.instance_ref === selected.instance_ref && authority.profile_ref === selected.profile_ref;
2645
+ }
2646
+ function validExpectations(options) {
2647
+ return (options.expected_sha256 === void 0 || SHA2562.test(options.expected_sha256)) && (options.expected_source_commit === void 0 || GIT_OID.test(options.expected_source_commit)) && (options.expected_instance_ref === void 0 || SAFE_REF6.test(options.expected_instance_ref));
2648
+ }
2649
+ function failure(code3, message, next_action) {
2650
+ return { ok: false, status: "failure", error: { code: code3, message, next_action } };
2651
+ }
2652
+ function isRecord2(value) {
2653
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2654
+ }
2655
+
2656
+ // host/claude/src/claude-client-doctor.ts
2657
+ var CLAUDE_CLIENT_DOCTOR_SCHEMA_VERSION = "ceal.claude_client_doctor.v1";
2658
+ async function doctorClaudeClient(options = {}) {
2659
+ return { schema_version: CLAUDE_CLIENT_DOCTOR_SCHEMA_VERSION, ...await doctorClient(options, "Claude") };
2660
+ }
2661
+
2662
+ // host/claude/bin/ceal-claude-invocation-authentication.ts
2663
+ var CLAUDE_INVOCATION_AUTHENTICATION_CLIENT_COMMAND = {
2664
+ component: "Claude",
2665
+ executable: "ceal-claude-invocation-authentication",
2666
+ authenticationSchemaVersion: CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA,
2667
+ doctorSchemaVersion: CLAUDE_CLIENT_DOCTOR_SCHEMA_VERSION,
2668
+ runAuthentication: runClaudeInvocationAuthenticationCommand,
2669
+ runDoctor: doctorClaudeClient
2670
+ };
2671
+ async function main() {
2672
+ return runHostInvocationAuthenticationClientCommand(CLAUDE_INVOCATION_AUTHENTICATION_CLIENT_COMMAND, process.argv.slice(2));
2673
+ }
2674
+ void main().then((exitCode) => {
2675
+ process.exitCode = exitCode;
2676
+ });
2677
+ export {
2678
+ CLAUDE_INVOCATION_AUTHENTICATION_CLIENT_COMMAND,
2679
+ main
2680
+ };