@corca-org/ceal-host-linux-arm64 1.0.18 → 1.0.20

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.
@@ -109,6 +109,9 @@ var client_wire_contract_default = {
109
109
  "document"
110
110
  ],
111
111
  optional_fields: [
112
+ "operation_id",
113
+ "visible_output_max_bytes",
114
+ "local_delivery",
112
115
  "verified_artifact"
113
116
  ],
114
117
  bare_document_fields: [
@@ -195,6 +198,7 @@ var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_CONTINUATION_DOCUMENT_FIELDS = Object.f
195
198
  var CEAL_COMMAND_RESPONSE_DISCOVERY_COMMAND = response.discovery_command;
196
199
  var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_SCHEMA_VERSION = response.discovery_manifest_schema_version;
197
200
  var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_DOCUMENT_FIELDS = Object.freeze([...response.discovery_manifest_document_fields]);
201
+ var CEAL_COMMAND_RESPONSE_MAX_BYTES = CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES;
198
202
 
199
203
  // packages/ceal-client-protocol/src/vocabulary.ts
200
204
  function vocabulary(words) {
@@ -225,6 +229,7 @@ var CEAL_WRITE_RECEIPT_PROVIDER_STATES = vocabulary(["outcome_unknown", "verifie
225
229
  var CEAL_WRITE_RECEIPT_PROVIDER_READBACKS = vocabulary(["outcome_unknown", "verified", "not_applied"]);
226
230
  var CEAL_PROTOCOL_VERSION = "1.4.0";
227
231
  var CEAL_OPERATION_ACCESS_SCHEMA_VERSION = "ceal.operation_access.v1";
232
+ var CEAL_GATEWAY_CONTINUATION_CURSOR_PHASES = vocabulary(["scan", "delivery", "terminal"]);
228
233
  var CEAL_GATEWAY_ACTIVE_CALL_PHASES = vocabulary([
229
234
  "audited_call_pending",
230
235
  "continuation_read_pending",
@@ -248,6 +253,7 @@ var CEAL_GATEWAY_ORGANIZATION_ROUTE_FACT_CALL_KEYS = Object.freeze([
248
253
  // packages/ceal-client-protocol/src/operation-next-actions.ts
249
254
  var CEAL_REPEAT_REQUEST_NEXT_ACTION = "repeat_request";
250
255
  var CEAL_INSPECT_RECEIPT_NEXT_ACTION = "inspect_receipt";
256
+ var CEAL_ANSWER_WITH_GAP_NEXT_ACTION = "answer_with_gap";
251
257
  var CALLER_RECOVERABLE_NEXT_ACTION_VALUES = [
252
258
  "select_did_you_mean",
253
259
  "choose_new_output_path",
@@ -301,10 +307,20 @@ var CALLER_RECOVERABLE_NEXT_ACTION_VALUES = [
301
307
  "retry_after",
302
308
  // The ref names a container of rows (a Notion database or data source), which
303
309
  // has no body of its own; the caller searches its rows instead of reading it.
304
- "search_container_rows"
310
+ "search_container_rows",
311
+ // A settled unknown write names the exact receipt Operation that can inspect
312
+ // its outcome without issuing another provider mutation.
313
+ "write_receipt.get",
314
+ // Command resolution carries the exact required Operation sequence beside
315
+ // this action, so the caller can execute each declared input in order.
316
+ "follow_required_action_sequence",
317
+ // The command needs caller-owned local materialization (for example an
318
+ // @path file) before the Gateway can receive the argument.
319
+ "materialize_local_argument"
305
320
  ];
306
321
  var CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS = Object.freeze(CALLER_RECOVERABLE_NEXT_ACTION_VALUES);
307
322
  var NON_REMEDY_NEXT_ACTION_VALUES = [
323
+ CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
308
324
  // Only an administrator can take the named step -- approving a place for an
309
325
  // Operation, granting a withheld capability -- so a non-administrator asks
310
326
  // one. The refusal names the administrator step; this word is the ask.
@@ -352,7 +368,58 @@ var NON_REMEDY_NEXT_ACTION_VALUES = [
352
368
  "select_exact_approval"
353
369
  ];
354
370
  var CEAL_NON_REMEDY_NEXT_ACTIONS = Object.freeze(NON_REMEDY_NEXT_ACTION_VALUES);
355
- var DECLARED = /* @__PURE__ */ new Set([...CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS, ...CEAL_NON_REMEDY_NEXT_ACTIONS]);
371
+ var CEAL_DECLARED_NEXT_ACTIONS = Object.freeze([...CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS, ...CEAL_NON_REMEDY_NEXT_ACTIONS]);
372
+ var DECLARED = new Set(CEAL_DECLARED_NEXT_ACTIONS);
373
+ function defineCealNonModelNextActions(actions) {
374
+ return actions;
375
+ }
376
+ var NON_MODEL_NEXT_ACTION_VALUES = defineCealNonModelNextActions([
377
+ CEAL_INSPECT_RECEIPT_NEXT_ACTION,
378
+ "await_pending_approval",
379
+ "inspect_gateway",
380
+ "operator_action",
381
+ "none",
382
+ "check_gateway",
383
+ "inspect_context_store",
384
+ "inspect_local_cache",
385
+ "inspect_local_client",
386
+ "inspect_local_command",
387
+ "inspect_local_output",
388
+ "inspect_local_route",
389
+ "inspect_request",
390
+ "reconcile",
391
+ "reconcile_occurrence",
392
+ "retry_after_owner_recovery",
393
+ "select_exact_approval"
394
+ ]);
395
+ var NON_MODEL_NEXT_ACTIONS = new Set(NON_MODEL_NEXT_ACTION_VALUES);
396
+ function isCealModelActionableNonRemedyNextAction(action) {
397
+ return !NON_MODEL_NEXT_ACTIONS.has(action);
398
+ }
399
+ var CEAL_MODEL_ACTIONABLE_NEXT_ACTIONS = Object.freeze([
400
+ ...CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS,
401
+ ...CEAL_NON_REMEDY_NEXT_ACTIONS.filter(isCealModelActionableNonRemedyNextAction)
402
+ ]);
403
+ var MODEL_ACTIONABLE = new Set(CEAL_MODEL_ACTIONABLE_NEXT_ACTIONS);
404
+ var NON_MODEL_ACTION_TO_MODEL_ACTION = Object.freeze({
405
+ [CEAL_INSPECT_RECEIPT_NEXT_ACTION]: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
406
+ await_pending_approval: "ask_admin",
407
+ inspect_gateway: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
408
+ operator_action: "ask_admin",
409
+ none: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
410
+ check_gateway: "ask_admin",
411
+ inspect_context_store: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
412
+ inspect_local_cache: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
413
+ inspect_local_client: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
414
+ inspect_local_command: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
415
+ inspect_local_output: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
416
+ inspect_local_route: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
417
+ inspect_request: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
418
+ reconcile: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
419
+ reconcile_occurrence: "ask_admin",
420
+ retry_after_owner_recovery: "ask_admin",
421
+ select_exact_approval: "ask_admin"
422
+ });
356
423
  var RETRY_PROMISE_NEXT_ACTIONS = ["retry", "retry_after"];
357
424
  var RETRY_PROMISE = new Set(RETRY_PROMISE_NEXT_ACTIONS);
358
425
  var RECOVERABLE = new Set(CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS);
@@ -622,21 +689,15 @@ var CEAL_OPERATION_ACCESS_CLASSES = vocabulary(["read", "write"]);
622
689
  // packages/ceal-client-protocol/src/domain-vocabulary.ts
623
690
  var CEAL_CONNECTOR_STATUSES = vocabulary(["active", "disabled", "disconnected"]);
624
691
  var CEAL_CONNECTOR_CUSTODIES = vocabulary(["organization", "personal"]);
625
- var CEAL_PROVIDER_BOUNDARY_KINDS = vocabulary([
626
- "github_account",
627
- "github_organization",
628
- "google_workspace_domain",
629
- "notion_workspace",
630
- "slack_workspace"
631
- ]);
632
- var CEAL_PROVIDER_BOUNDARY_EVIDENCE = vocabulary(["provider_readback", "operator_stated"]);
633
692
  var CEAL_ACCESS_LEVELS = vocabulary(["none", "read", "read_write"]);
634
693
  var CEAL_PERSONAL_ACCESS_CEILINGS = vocabulary(["disabled", "read", "read_write"]);
635
694
  var CEAL_TARGET_REF_PATTERN = "^[^\\p{Cc}]+$";
636
695
  var TARGET_REF = new RegExp(CEAL_TARGET_REF_PATTERN, "u");
637
696
  var CEAL_TARGET_VISIBILITIES = vocabulary(["public", "private"]);
638
- var CEAL_PRINCIPAL_KINDS = vocabulary(["human", "service", "runtime"]);
697
+ var CEAL_PRINCIPAL_KINDS = vocabulary(["human", "runtime"]);
698
+ var CEAL_PERSISTED_PRINCIPAL_KINDS = vocabulary(["human", "service", "runtime"]);
639
699
  var CEAL_ORGANIZATION_ROLES = vocabulary(["member", "admin"]);
700
+ var CEAL_CALENDAR_PERIODS = vocabulary(["day", "week", "month"]);
640
701
  var LABEL_EXPECTATION = `public-safe display text of at most ${CEAL_PUBLIC_DISPLAY_NAME_MAX_BYTES} bytes`;
641
702
 
642
703
  // packages/ceal-client-protocol/src/safe-json-budget.ts
@@ -812,7 +873,7 @@ var CEAL_SCHEMA_LITERALS = [
812
873
  "ceal.operation_receipt.v1",
813
874
  "ceal.operation_result.v1",
814
875
  "ceal.operation_result.compact.v1",
815
- "ceal.local_result_materialization.v1",
876
+ "ceal.local_result_file.v1",
816
877
  "ceal.local_result_root.v1",
817
878
  "ceal.owner_bootstrap_exchange_request.v1",
818
879
  "ceal.owner_bootstrap_exchange_result.v1",
@@ -842,6 +903,9 @@ var CEAL_BOUNDED_SERIES_CATALOG = Object.freeze({
842
903
  gateway_personal_client_access_audit: (root) => join(root, "access-audit.jsonl")
843
904
  });
844
905
 
906
+ // packages/ceal-client-protocol/src/canonical-http-boundary.ts
907
+ var CEAL_CANONICAL_HTTP_MAX_RESPONSE_BYTES = CEAL_COMMAND_RESPONSE_MAX_BYTES;
908
+
845
909
  // packages/ceal-client-protocol/src/gateway-installation-activation.ts
846
910
  var CEAL_GATEWAY_INSTALLATION_ACTIVATION_CODE_DATA_CHARACTERS = 32;
847
911
  var CEAL_GATEWAY_INSTALLATION_ACTIVATION_CODE_CHECK_CHARACTERS = 8;
@@ -907,41 +971,6 @@ var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_JSON_SCHEMA = Object.freeze({
907
971
  }
908
972
  });
909
973
 
910
- // packages/ceal-client-protocol/src/provider-operation-vocabulary.ts
911
- var CEAL_FILE_TYPE_FAMILIES = vocabulary(["all", "image", "pdf"]);
912
- var CEAL_GITHUB_ISSUE_STATES = vocabulary(["open", "closed", "all"]);
913
- var CEAL_NOTION_UPDATABLE_BLOCK_TYPES = vocabulary([
914
- "paragraph",
915
- "heading_1",
916
- "heading_2",
917
- "heading_3",
918
- "bulleted_list_item",
919
- "numbered_list_item",
920
- "to_do",
921
- "code"
922
- ]);
923
- var CEAL_NOTION_NEUTRAL_TYPES = vocabulary([
924
- "text",
925
- "number",
926
- "boolean",
927
- "date",
928
- "select",
929
- "multi_select",
930
- "people",
931
- "url",
932
- "email",
933
- "phone",
934
- "unsupported"
935
- ]);
936
- var CEAL_NOTION_IDENTITY_GAP_REASONS = vocabulary([
937
- "identity_unavailable",
938
- "identity_stale",
939
- "identity_ambiguous",
940
- "identity_revoked",
941
- "identity_unlinked"
942
- ]);
943
- var CEAL_NOTION_STRING_VALUE_TYPES = vocabulary(["text", "select", "url", "email", "phone"]);
944
-
945
974
  // packages/ceal-client-protocol/src/opaque-reference.ts
946
975
  var CEAL_OPAQUE_HANDLE_KINDS = vocabulary(["target", "message", "thread", "artifact", "document", "block", "object"]);
947
976
  var CEAL_OPAQUE_REF_KINDS = vocabulary([...CEAL_OPAQUE_HANDLE_KINDS, "result", "operation-receipt", "reply-receipt", "field", "notion-data-source"]);
@@ -951,6 +980,7 @@ var REQUIRED_FIELDS = CEAL_CLIENT_WIRE_CONTRACT.command_response.bare_document_f
951
980
  var OPTIONAL_FIELDS = CEAL_CLIENT_WIRE_CONTRACT.command_response.bare_document_optional_fields;
952
981
 
953
982
  // packages/ceal-client-protocol/src/resource-row.ts
983
+ var CEAL_RESOURCE_ROW_TITLE_MATCH_DISPOSITIONS = vocabulary(["exact", "not_exact", "unknown"]);
954
984
  var CEAL_RESOURCE_SEARCH_ORDERS = vocabulary(["relevance", "modified", "viewed", "created"]);
955
985
  var CEAL_RESOURCE_SEARCH_DIRECTIONS = vocabulary(["ascending", "descending"]);
956
986
  var CEAL_RESOURCE_SEARCH_FILTERS = vocabulary(["query", "modified_since", "since", "until", "authored_by_me", "authored_by", "include_replies", "kinds", "container_ref", "container_refs", "container_names", "addressed_to_me", "unread"]);
@@ -974,6 +1004,7 @@ var CEAL_ACTIVITY_TIMESTAMP_BASES = vocabulary([
974
1004
  "resource_modified"
975
1005
  ]);
976
1006
  var CEAL_ACTIVITY_CONNECTOR_KINDS = vocabulary(["slack", "github", "google-calendar", "google-drive", "notion"]);
1007
+ var CEAL_ACTIVITY_UNSUPPORTED_EVENT_KIND_CODE = "unsupported_event_kind";
977
1008
  var CEAL_ACTIVITY_GAP_CODES = vocabulary([
978
1009
  "provider_page_budget",
979
1010
  "call_deadline",
@@ -981,7 +1012,7 @@ var CEAL_ACTIVITY_GAP_CODES = vocabulary([
981
1012
  "provider_cursor_unavailable",
982
1013
  "malformed_provider_page",
983
1014
  "visibility_incomplete",
984
- "unsupported_event_kind",
1015
+ CEAL_ACTIVITY_UNSUPPORTED_EVENT_KIND_CODE,
985
1016
  "direct_messages_excluded"
986
1017
  ]);
987
1018
  var CEAL_ACTIVITY_EVENT_KINDS = vocabulary([
@@ -1033,6 +1064,7 @@ var RESOURCE_ROW_KEY_RULES = Object.freeze({
1033
1064
  next: { required: true, timestamp: false },
1034
1065
  kind: { required: true, timestamp: false },
1035
1066
  matched_kinds: { required: false, timestamp: false },
1067
+ title_match: { required: false, timestamp: false },
1036
1068
  title: { required: true, timestamp: false },
1037
1069
  container_label: { required: true, timestamp: false },
1038
1070
  container_ref: { required: false, timestamp: false },
@@ -1046,6 +1078,8 @@ var RESOURCE_ROW_KEY_RULES = Object.freeze({
1046
1078
  modified_at: { required: false, timestamp: true },
1047
1079
  modified_at_local: { required: false, timestamp: true },
1048
1080
  viewed_by_me_at: { required: false, timestamp: true },
1081
+ own_ceal_write: { required: false, timestamp: false },
1082
+ owned_by_me: { required: false, timestamp: false },
1049
1083
  visibility: { required: false, timestamp: false },
1050
1084
  start: { required: false, timestamp: false },
1051
1085
  end: { required: false, timestamp: false },
@@ -1079,6 +1113,15 @@ function cealExcludedTargetCoverageJsonSchema() {
1079
1113
  };
1080
1114
  }
1081
1115
 
1116
+ // packages/ceal-client-protocol/src/gateway-write-identity.ts
1117
+ var CEAL_GATEWAY_WRITE_IDENTITY_ROLES = Object.freeze(["replay_identity", "lookup_handle", "collision_evidence"]);
1118
+ var CEAL_GATEWAY_WRITE_REQUEST_REF_PATTERN = /^gateway-write-request:[a-f0-9]{8}-(?:[a-f0-9]{4}-){3}[a-f0-9]{12}$/u;
1119
+ var CEAL_GATEWAY_WRITE_IDENTITY_FIELDS = Object.freeze({
1120
+ replay_identity: "idempotency_claim_sha256",
1121
+ lookup_handle: "write_request_sha256",
1122
+ collision_evidence: "normalized_mutation_sha256"
1123
+ });
1124
+
1082
1125
  // packages/ceal-client-protocol/src/write-safety-finding.ts
1083
1126
  var CEAL_WRITE_SAFETY_FINDING_STATUSES = vocabulary(["warning", "unchecked"]);
1084
1127
  var CEAL_WRITE_SAFETY_AUDIENCES = vocabulary(["workspace", "person", "members", "unknown"]);
@@ -1106,7 +1149,11 @@ var CEAL_REFRESH_FAILURE_CODES = vocabulary([
1106
1149
  "refresh_revoked",
1107
1150
  "authority_replaced",
1108
1151
  "refresh_recovery_unavailable",
1109
- "refresh_recovery_expired"
1152
+ "refresh_recovery_expired",
1153
+ // The serving gate answers this while the Gateway is still starting and the
1154
+ // refresh was never attempted; the same attempt stays retryable. It is never
1155
+ // stored by the session owner, only answered at the serving edge.
1156
+ "gateway_starting"
1110
1157
  ]);
1111
1158
 
1112
1159
  // packages/ceal-client-protocol/src/request-validation-primitives.ts
@@ -1139,7 +1186,7 @@ var CANCELLATION_STATES = vocabulary(["requested", "cancelled"]);
1139
1186
  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"]);
1140
1187
  var CEAL_REQUEST_JSON_SCHEMA = {
1141
1188
  type: "object",
1142
- maxProperties: 10,
1189
+ maxProperties: 11,
1143
1190
  additionalProperties: false,
1144
1191
  properties: {
1145
1192
  schema_version: { type: "string", const: CEAL_REQUEST_SCHEMA_VERSION, maxLength: 32 },
@@ -1163,7 +1210,8 @@ var CEAL_REQUEST_JSON_SCHEMA = {
1163
1210
  host_turn_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
1164
1211
  host_input_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
1165
1212
  host_source_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
1166
- requester_timezone: { type: "string", minLength: 1, maxLength: 128, description: "IANA timezone observed for the requester on this Request." }
1213
+ requester_timezone: { type: "string", minLength: 1, maxLength: 128, description: "IANA timezone observed for the requester on this Request." },
1214
+ device_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source, description: "Device that submitted this Request through its client session; absent for Host turns and older records." }
1167
1215
  },
1168
1216
  required: CEAL_REQUEST_KEYS
1169
1217
  };
@@ -1222,6 +1270,7 @@ var REQUEST_EXECUTION_PREPARE_REFUSAL_PROPERTIES = {
1222
1270
  retryable: { type: "boolean" },
1223
1271
  source: { type: "string", enum: ["provider", "gateway"] },
1224
1272
  retry_after_ms: { type: "integer", minimum: 0, maximum: CEAL_RETRY_AFTER_MAX_MS },
1273
+ write_request_ref: { type: "string", pattern: CEAL_GATEWAY_WRITE_REQUEST_REF_PATTERN.source, maxLength: 128 },
1225
1274
  excluded_targets: cealExcludedTargetCoverageJsonSchema(),
1226
1275
  repaired_input: {},
1227
1276
  unrepaired_pointers: { type: "array", maxItems: 128, items: { type: "string", minLength: 1, maxLength: 256 } },
@@ -1280,6 +1329,7 @@ function isCealHostInputKind(value) {
1280
1329
  return typeof value === "string" && CEAL_HOST_INPUT_KINDS.some((kind) => kind === value);
1281
1330
  }
1282
1331
  var CEAL_HOST_OBSERVATION_REF_PREFIX = "host-observation:";
1332
+ var HOST_TOKEN_OBSERVATION_BREAKDOWN_KEYS = vocabulary(["cached_input", "cache_write_input", "reasoning_output"]);
1283
1333
  function validateCealHostObservationDraft(value) {
1284
1334
  const record6 = operationRecord(value, "Ceal Host observation draft is invalid.");
1285
1335
  requirePrefixedRef(record6.observation_ref, CEAL_HOST_OBSERVATION_REF_PREFIX, "Ceal Host observation reference is invalid.");
@@ -1433,6 +1483,94 @@ var CEAL_HOST_MINT_REQUEST_CONTEXT_REFUSAL_REASONS = vocabulary([
1433
1483
  "host_input_mismatch",
1434
1484
  "host_prompt_mismatch"
1435
1485
  ]);
1486
+ var CEAL_HOST_AUTHENTICATION_CAUSES = vocabulary([
1487
+ "invalid_arguments",
1488
+ "options_invalid",
1489
+ "session_unavailable",
1490
+ "context_unavailable",
1491
+ "context_replaced",
1492
+ "no_binding",
1493
+ "context_stale",
1494
+ "context_expired",
1495
+ "host_source_refused",
1496
+ "host_credential_refused",
1497
+ "gateway_unavailable",
1498
+ "gateway_rate_limited",
1499
+ "gateway_refused",
1500
+ "gateway_response_invalid",
1501
+ "producer_frame_invalid",
1502
+ "relay_permission_denied",
1503
+ "relay_unavailable",
1504
+ "transient_retryable",
1505
+ "mint_failed",
1506
+ "relay_failed",
1507
+ "host_refusal_invalid"
1508
+ ]);
1509
+ var CEAL_HOST_AUTHENTICATION_POLICY = Object.freeze({
1510
+ invalid_arguments: Object.freeze({ classification: "host_arguments_invalid", next_action: "answer_with_gap" }),
1511
+ options_invalid: Object.freeze({ classification: "host_configuration_invalid", next_action: "answer_with_gap" }),
1512
+ session_unavailable: Object.freeze({ classification: "host_session_unavailable", next_action: "answer_with_gap" }),
1513
+ context_unavailable: Object.freeze({ classification: "host_context_unavailable", next_action: "refresh_host_invocation_context", remedy: "the Host has no invocation context from the current transcript turn; send a new message to start a fresh Host turn, then retry this command on that turn (run `ceal-host install` only if the Host hook registration is missing or drifted)" }),
1514
+ context_replaced: Object.freeze({ classification: "host_invocation_context_stale", next_action: "refresh_host_invocation_context" }),
1515
+ no_binding: Object.freeze({ classification: "host_binding_unavailable", next_action: "refresh_host_invocation_context" }),
1516
+ context_stale: Object.freeze({ classification: "host_invocation_context_stale", next_action: "refresh_host_invocation_context" }),
1517
+ context_expired: Object.freeze({ classification: "host_invocation_context_expired", next_action: "refresh_host_invocation_context" }),
1518
+ host_source_refused: Object.freeze({ classification: "host_source_refused", next_action: "answer_with_gap" }),
1519
+ host_credential_refused: Object.freeze({ classification: "host_registration_credential_refused", next_action: "ask_admin" }),
1520
+ gateway_unavailable: Object.freeze({ classification: "host_mint_gateway_unavailable", next_action: "ask_admin" }),
1521
+ gateway_rate_limited: Object.freeze({ classification: "host_mint_gateway_rate_limited", next_action: "answer_with_gap" }),
1522
+ gateway_refused: Object.freeze({ classification: "host_mint_gateway_refused", next_action: "answer_with_gap" }),
1523
+ gateway_response_invalid: Object.freeze({ classification: "host_mint_gateway_response_invalid", next_action: "answer_with_gap" }),
1524
+ producer_frame_invalid: Object.freeze({ classification: "host_producer_frame_invalid", next_action: "ask_admin", remedy: "ask an administrator to inspect and repair the producer frame, then start a fresh Host turn" }),
1525
+ relay_permission_denied: Object.freeze({ classification: "host_relay_permission_denied", next_action: "rerun_outside_agent_sandbox", remedy: "an agent sandbox denied the Host Relay socket; run `ceal` as the only command, with no pipe, redirect, or `&&`, so the Host allow rule runs it outside the sandbox" }),
1526
+ relay_unavailable: Object.freeze({ classification: "host_relay_unavailable", next_action: "answer_with_gap" }),
1527
+ transient_retryable: Object.freeze({ classification: "host_mint_transient_retryable", next_action: "retry" }),
1528
+ mint_failed: Object.freeze({ classification: "host_mint_failed", next_action: "answer_with_gap" }),
1529
+ relay_failed: Object.freeze({ classification: "host_relay_failed", next_action: "answer_with_gap" }),
1530
+ host_refusal_invalid: Object.freeze({ classification: "host_refusal_invalid", next_action: "answer_with_gap" })
1531
+ });
1532
+ function projectCealHostAuthenticationCause(diagnostic) {
1533
+ return projectRelayCodeCause(diagnostic) ?? projectGatewayCodeCause(diagnostic) ?? projectGatewayStatusCause(diagnostic) ?? "mint_failed";
1534
+ }
1535
+ function projectRelayCodeCause(diagnostic) {
1536
+ switch (diagnostic.relayCode) {
1537
+ case "credential":
1538
+ return "host_credential_refused";
1539
+ case "configuration":
1540
+ return "options_invalid";
1541
+ case "payload_rejected":
1542
+ return "producer_frame_invalid";
1543
+ case "invalid_response":
1544
+ return "gateway_response_invalid";
1545
+ case "gateway_refused":
1546
+ return projectGatewayRefusedCause(diagnostic);
1547
+ case "gateway_unavailable":
1548
+ return diagnostic.exhausted === true ? void 0 : "gateway_unavailable";
1549
+ case void 0:
1550
+ case "":
1551
+ return void 0;
1552
+ default:
1553
+ return "mint_failed";
1554
+ }
1555
+ }
1556
+ function projectGatewayRefusedCause(diagnostic) {
1557
+ if (diagnostic.gatewayStatus === 401 || diagnostic.gatewayStatus === 403) return "host_credential_refused";
1558
+ const stale = projectGatewayCodeCause(diagnostic);
1559
+ if (stale !== void 0) return stale;
1560
+ if (diagnostic.exhausted === true && (diagnostic.gatewayStatus === 408 || diagnostic.gatewayStatus === 429)) return "gateway_rate_limited";
1561
+ return "gateway_refused";
1562
+ }
1563
+ function projectGatewayCodeCause(diagnostic) {
1564
+ if (diagnostic.gatewayCode === "request_context_refused" && diagnostic.gatewayReason !== void 0 && isVocabularyWord(CEAL_HOST_MINT_REQUEST_CONTEXT_REFUSAL_REASONS, diagnostic.gatewayReason)) return "context_stale";
1565
+ if (diagnostic.gatewayCode === "context_expired") return "context_expired";
1566
+ if (diagnostic.gatewayCode === "host_source_refused") return "host_source_refused";
1567
+ return void 0;
1568
+ }
1569
+ function projectGatewayStatusCause(diagnostic) {
1570
+ if (diagnostic.gatewayStatus === 401 || diagnostic.gatewayStatus === 403) return "host_credential_refused";
1571
+ if (diagnostic.exhausted === true && (diagnostic.gatewayStatus === 408 || diagnostic.gatewayStatus === 429)) return "gateway_rate_limited";
1572
+ return void 0;
1573
+ }
1436
1574
  function decodeCealHostInvocationAuthenticationResult(value, now = /* @__PURE__ */ new Date()) {
1437
1575
  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)) {
1438
1576
  throw new TypeError("The Host invocation authentication result is invalid.");
@@ -1448,11 +1586,38 @@ function exactKeys(value, expected) {
1448
1586
  return keys.length === expected.length && expected.every((key) => Object.hasOwn(value, key));
1449
1587
  }
1450
1588
 
1589
+ // packages/ceal-client-protocol/src/host-service-diagnostic.ts
1590
+ var CEAL_HOST_SERVICE_DIAGNOSTIC_SCHEMA = "ceal.host_service_diagnostic.v1";
1591
+ var CEAL_HOST_SERVICE_DIAGNOSTIC_PRODUCERS = vocabulary(["claude", "codex"]);
1592
+ var CEAL_HOST_SERVICE_DIAGNOSTIC_EVENTS = vocabulary([
1593
+ "hook_invoked",
1594
+ "registration_written",
1595
+ "hook_failed",
1596
+ "watcher_turn_observed",
1597
+ "current_prompt_registered",
1598
+ "current_prompt_registration_failed",
1599
+ "current_prompt_capacity_exhausted",
1600
+ "activation_recorded",
1601
+ "activation_failed",
1602
+ "watcher_scan_failed",
1603
+ "activation_wait_skipped",
1604
+ "activation_wait_engaged",
1605
+ "activation_wait_completed",
1606
+ "activation_wait_exhausted"
1607
+ ]);
1608
+ var CEAL_HOST_SERVICE_DIAGNOSTIC_FAILURE_KINDS = vocabulary([
1609
+ "malformed_line",
1610
+ "other",
1611
+ "payload_rejected",
1612
+ "read_error",
1613
+ "size_budget",
1614
+ "symlink"
1615
+ ]);
1616
+
1451
1617
  // packages/ceal-client-protocol/src/client-result-materialization.ts
1452
1618
  var CEAL_UNREAD_REASONS = vocabulary(["blocked", "unavailable", "too_large", "unsupported", "download_failed", "permission_denied"]);
1453
- var CEAL_MODEL_VISIBLE_COMMAND_OUTPUT_MAX_BYTES = 32 * 1024;
1454
- var REQUIRED_FIELDS2 = Object.freeze(["schema_version", "operation_id", "read_argv"]);
1455
- var FIELDS = /* @__PURE__ */ new Set([...REQUIRED_FIELDS2, "local_result_root", "continue_argv", "model_disclosure"]);
1619
+ var REQUIRED_FIELDS2 = Object.freeze(["schema_version", "operation_id", "path", "sha256"]);
1620
+ var FIELDS = /* @__PURE__ */ new Set([...REQUIRED_FIELDS2, "items_path", "row_count", "result_complete", "coverage", "local_result_root", "model_disclosure", "continue_argv", "how_to_read"]);
1456
1621
 
1457
1622
  // packages/ceal-client-protocol/src/gateway-cache-origin-validation.ts
1458
1623
  var CEAL_MAX_CACHE_ORIGIN_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
@@ -1482,14 +1647,6 @@ var CEAL_GATEWAY_ANNOUNCEMENT_POLICY_NON_CLAIMS = vocabulary([
1482
1647
  "target_specific_scope_not_declared"
1483
1648
  ]);
1484
1649
 
1485
- // packages/ceal-client-protocol/src/gateway-write-identity.ts
1486
- var CEAL_GATEWAY_WRITE_IDENTITY_ROLES = Object.freeze(["replay_identity", "lookup_handle", "collision_evidence"]);
1487
- var CEAL_GATEWAY_WRITE_IDENTITY_FIELDS = Object.freeze({
1488
- replay_identity: "idempotency_claim_sha256",
1489
- lookup_handle: "write_request_sha256",
1490
- collision_evidence: "normalized_mutation_sha256"
1491
- });
1492
-
1493
1650
  // packages/ceal-client-protocol/src/gateway-scoped-identity-projection-validation.ts
1494
1651
  var PROJECTION_REVISION_KEYS = Object.freeze(["graph_revision", "subject_key_revision", "projection_revision"]);
1495
1652
 
@@ -1502,6 +1659,18 @@ var CEAL_SUPPORTED_GATEWAY_PROTOCOL_RANGE = Object.freeze({
1502
1659
  // packages/ceal-client-protocol/src/admin-projection-vocabulary.ts
1503
1660
  var ADMIN_PROJECTION_STATES = vocabulary(["ready", "empty", "partial", "unknown"]);
1504
1661
  var ADMIN_VIEW_KINDS = vocabulary(["request_detail", "resource_access_timeline", "weekly_usage"]);
1662
+ var ADMIN_RECORD_PROJECTION_KINDS = vocabulary([
1663
+ "request_list",
1664
+ "usage_series",
1665
+ "connector_health",
1666
+ "person_connections",
1667
+ "client_sessions",
1668
+ "knowledge_base",
1669
+ "change_history",
1670
+ "approval_queue",
1671
+ "access_group_list",
1672
+ "capability_catalogue"
1673
+ ]);
1505
1674
  var ADMIN_GAP_KINDS = vocabulary(["unknown", "unavailable", "partial"]);
1506
1675
  var ADMIN_UNAVAILABLE_REASONS = vocabulary([
1507
1676
  "not_recorded",
@@ -1525,7 +1694,11 @@ var ADMIN_SOURCE_OWNERS = vocabulary([
1525
1694
  "person",
1526
1695
  "resource",
1527
1696
  "prompt",
1528
- "usage"
1697
+ "usage",
1698
+ "connector",
1699
+ "session",
1700
+ "knowledge",
1701
+ "policy"
1529
1702
  ]);
1530
1703
  var ADMIN_COMPLETENESS_STATES = vocabulary(["complete", "partial", "unknown"]);
1531
1704
  var ADMIN_OPERATION_OUTCOMES = vocabulary(["completed", "failed", "denied", "cancelled", "unknown"]);
@@ -1580,6 +1753,17 @@ function errorCode(error) {
1580
1753
  import { copyFile, open, stat, truncate } from "node:fs/promises";
1581
1754
  import { isAbsolute } from "node:path";
1582
1755
  var HOST_SERVICE_LOG_ENVIRONMENT = "CEAL_HOST_SERVICE_LOG";
1756
+ function writeHostServiceDiagnostic(producer_id, event, failure_kind, cause, sink) {
1757
+ const line = `${JSON.stringify({ schema_version: CEAL_HOST_SERVICE_DIAGNOSTIC_SCHEMA, producer_id, event, ...event === "watcher_scan_failed" && failure_kind !== void 0 ? { failure_kind } : {}, ...event === "watcher_scan_failed" && cause !== void 0 ? { cause } : {} })}
1758
+ `;
1759
+ try {
1760
+ (sink ?? defaultHostServiceDiagnosticSink)(line);
1761
+ } catch {
1762
+ }
1763
+ }
1764
+ function defaultHostServiceDiagnosticSink(line) {
1765
+ process.stderr.write(line);
1766
+ }
1583
1767
  var HOST_SERVICE_LOG_MAX_BYTES = 1024 * 1024;
1584
1768
  var HOST_SERVICE_LOG_CHECK_INTERVAL_MS = 6e4;
1585
1769
  function hostServiceLogPreviousPath(path) {
@@ -1760,6 +1944,15 @@ var FRAME_KINDS = new Set(HOST_PRODUCER_FRAME_KINDS);
1760
1944
  function isHostProducerFrameKind(value) {
1761
1945
  return typeof value === "string" && FRAME_KINDS.has(value);
1762
1946
  }
1947
+ var HOST_PRODUCER_FRAME_ERROR_CODES = [
1948
+ "invalid_frame_encoding",
1949
+ "invalid_frame_length",
1950
+ "frame_truncated",
1951
+ "unsupported_frame_schema",
1952
+ "invalid_frame_shape",
1953
+ "invalid_producer_identity",
1954
+ "frame_too_large"
1955
+ ];
1763
1956
  var HostProducerFrameError = class extends Error {
1764
1957
  code;
1765
1958
  constructor(code, message = code) {
@@ -1800,6 +1993,30 @@ function decodeHostProducerFrame(input) {
1800
1993
  function hostProducerFrameHash(frame) {
1801
1994
  return createHash3("sha256").update(JSON.stringify(frame), "utf8").digest("hex");
1802
1995
  }
1996
+ function extractHostBindingSelector(frame) {
1997
+ if (frame.frame_kind !== "user_input") return null;
1998
+ if (!PRODUCERS.has(frame.producer_id) || !safeRef(frame.producer_installation_ref)) return null;
1999
+ const payload = frame.payload;
2000
+ if (!safeRef(payload.local_session_ref) || !safeRef(payload.local_turn_ref)) return null;
2001
+ const aliases = payload.local_turn_aliases;
2002
+ if (aliases === void 0) {
2003
+ return Object.freeze({
2004
+ producer_id: frame.producer_id,
2005
+ producer_installation_ref: frame.producer_installation_ref,
2006
+ local_session_ref: payload.local_session_ref,
2007
+ local_turn_ref: payload.local_turn_ref,
2008
+ local_turn_aliases: Object.freeze([])
2009
+ });
2010
+ }
2011
+ if (!Array.isArray(aliases) || aliases.length > 16 || !aliases.every(safeRef) || new Set(aliases).size !== aliases.length) return null;
2012
+ return Object.freeze({
2013
+ producer_id: frame.producer_id,
2014
+ producer_installation_ref: frame.producer_installation_ref,
2015
+ local_session_ref: payload.local_session_ref,
2016
+ local_turn_ref: payload.local_turn_ref,
2017
+ local_turn_aliases: Object.freeze([...aliases])
2018
+ });
2019
+ }
1803
2020
  function hostProducerIdentityRefs(hostSourceRef, frame, localSessionRef, localTurnRef, localInputRef) {
1804
2021
  if (!opaqueHostSourceRef(hostSourceRef)) throw new TypeError("Gateway host source reference is invalid.");
1805
2022
  const host_session_ref = localSessionRef === void 0 ? void 0 : `ceal-host-session:${cealRequestSha256({ host_source_ref: hostSourceRef, producer_id: frame.producer_id, producer_installation_ref: frame.producer_installation_ref, local_session_ref: localSessionRef })}`;
@@ -1823,6 +2040,31 @@ function hostProducerSubmissionRef(hostSourceRef, frame) {
1823
2040
  function opaqueHostSourceRef(value) {
1824
2041
  return typeof value === "string" && SAFE_REF2.test(value) && !value.startsWith("ceal-host-source:");
1825
2042
  }
2043
+ function isHostSafeRef(value) {
2044
+ return safeRef(value);
2045
+ }
2046
+ var BOUNDED_REFUSAL_WORD = /^[a-z][a-z0-9_]{0,63}$/u;
2047
+ function isBoundedRefusalWord(value) {
2048
+ return typeof value === "string" && BOUNDED_REFUSAL_WORD.test(value);
2049
+ }
2050
+ function hasExactKeys2(value, required, optional = []) {
2051
+ return required.every((key) => Object.hasOwn(value, key)) && Object.keys(value).every((key) => required.includes(key) || optional.includes(key));
2052
+ }
2053
+ function isUndefinedOr(value, guard) {
2054
+ return value === void 0 || guard(value);
2055
+ }
2056
+ var HOST_RELAY_GATEWAY_ERROR_CODES = [
2057
+ "configuration",
2058
+ "credential",
2059
+ "gateway_unavailable",
2060
+ "gateway_refused",
2061
+ "invalid_response",
2062
+ "payload_rejected"
2063
+ ];
2064
+ function isRelayGatewayErrorCode(value) {
2065
+ return isVocabularyWord(HOST_RELAY_GATEWAY_ERROR_CODES, value);
2066
+ }
2067
+ var RELAY_DELIVERY_DIAGNOSTIC_KEYS = ["relayCode", "gatewayStatus", "gatewayCode", "gatewayReason", "exhausted"];
1826
2068
  function requiredIdentity(value) {
1827
2069
  if (value === void 0) throw new TypeError("Canonical Host identity is incomplete.");
1828
2070
  return value;
@@ -2251,6 +2493,8 @@ var RELAY_QUARANTINE_MAX_RECORDS = 512;
2251
2493
  var RELAY_QUARANTINE_MAX_BYTES = 16 * 1024 * 1024;
2252
2494
  var MAX_CAPTURE_BYTES = 262148;
2253
2495
  var PRODUCERS2 = ["codex", "claude", "unknown"];
2496
+ var RELAY_QUARANTINE_FRAME_REASONS = ["frame_identity_conflict", "sequence_gap", "gateway_refused"];
2497
+ var RELAY_QUARANTINE_REASONS = [...RELAY_QUARANTINE_FRAME_REASONS, ...HOST_PRODUCER_FRAME_ERROR_CODES];
2254
2498
  var RelayQuarantineStore = class {
2255
2499
  root;
2256
2500
  maxRecords;
@@ -2263,8 +2507,8 @@ var RelayQuarantineStore = class {
2263
2507
  if (!Number.isSafeInteger(this.maxRecords) || this.maxRecords < 1 || this.maxRecords > RELAY_QUARANTINE_MAX_RECORDS) throw new TypeError(`Relay quarantine record cap is invalid: ${refusalFact("max_records", this.maxRecords, `between 1 and ${RELAY_QUARANTINE_MAX_RECORDS}`)}.`);
2264
2508
  if (!Number.isSafeInteger(this.maxBytes) || this.maxBytes < 1 || this.maxBytes > RELAY_QUARANTINE_MAX_BYTES) throw new TypeError(`Relay quarantine byte cap is invalid: ${refusalFact("max_bytes", this.maxBytes, `between 1 and ${RELAY_QUARANTINE_MAX_BYTES}`)}.`);
2265
2509
  }
2266
- async retainFrame(frame, reason, capturedAt = (/* @__PURE__ */ new Date()).toISOString()) {
2267
- await this.retain(encodeHostProducerFrame(frame), frame.producer_id, reason, capturedAt);
2510
+ async retainFrame(frame, reason, attribution, capturedAt = (/* @__PURE__ */ new Date()).toISOString()) {
2511
+ await this.retain(encodeHostProducerFrame(frame), frame.producer_id, reason, capturedAt, attribution);
2268
2512
  }
2269
2513
  async retainMalformed(rawFrame, reason, capturedAt = (/* @__PURE__ */ new Date()).toISOString()) {
2270
2514
  await this.retain(rawFrame, inferProducer(rawFrame), reason, capturedAt);
@@ -2276,11 +2520,26 @@ var RelayQuarantineStore = class {
2276
2520
  const records = state.producers[producerId].slice(-Math.min(limit, this.maxRecords)).map((record6) => structuredClone(record6));
2277
2521
  return { producer_id: producerId, records, total_bytes: records.reduce((total, record6) => total + record6.charged_bytes, 0) };
2278
2522
  }
2523
+ /**
2524
+ * The newest quarantined record whose exact-turn attribution matches the
2525
+ * query, or null when evicted, unattributed, or for another turn. The
2526
+ * file-backed state survives drain, restart, and overwrite.
2527
+ */
2528
+ async findNewestAttributedMatch(query) {
2529
+ await this.tail;
2530
+ const state = await this.readState();
2531
+ const bucket = query.producer_id === "codex" || query.producer_id === "claude" ? state.producers[query.producer_id] : [];
2532
+ for (let index = bucket.length - 1; index >= 0; index -= 1) {
2533
+ const record6 = bucket[index];
2534
+ if (record6 !== void 0 && attributedRecordMatchesQuery(record6, query)) return structuredClone(record6);
2535
+ }
2536
+ return null;
2537
+ }
2279
2538
  async snapshot() {
2280
2539
  await this.tail;
2281
2540
  return this.readState();
2282
2541
  }
2283
- async retain(rawFrame, producerId, reason, capturedAt) {
2542
+ async retain(rawFrame, producerId, reason, capturedAt, attribution) {
2284
2543
  const run = this.tail.then(async () => {
2285
2544
  if (!PRODUCERS2.includes(producerId) || !Number.isFinite(Date.parse(capturedAt))) throw new TypeError("Relay quarantine record identity is invalid.");
2286
2545
  const raw = Buffer.from(rawFrame).subarray(0, MAX_CAPTURE_BYTES);
@@ -2292,7 +2551,8 @@ var RelayQuarantineStore = class {
2292
2551
  captured_at: capturedAt,
2293
2552
  frame_sha256: createHash4("sha256").update(raw).digest("hex"),
2294
2553
  charged_bytes: raw.byteLength,
2295
- raw_frame_base64: raw.toString("base64")
2554
+ raw_frame_base64: raw.toString("base64"),
2555
+ ...attribution === void 0 ? {} : { attribution: structuredClone(attribution) }
2296
2556
  };
2297
2557
  const records = state.producers[producerId];
2298
2558
  records.push(record6);
@@ -2329,8 +2589,47 @@ function decodeState2(value) {
2329
2589
  return state;
2330
2590
  }
2331
2591
  function validRecord(value) {
2332
- if (!record3(value) || typeof value.quarantine_ref !== "string" || !quarantineProducer(value.producer_id) || typeof value.reason !== "string" || !Number.isFinite(Date.parse(String(value.captured_at))) || typeof value.frame_sha256 !== "string" || typeof value.charged_bytes !== "number" || !Number.isSafeInteger(value.charged_bytes) || value.charged_bytes < 0 || typeof value.raw_frame_base64 !== "string") return false;
2333
- return true;
2592
+ if (!record3(value) || !validRecordIdentity(value)) return false;
2593
+ return value.attribution === void 0 || validAttribution(value.attribution);
2594
+ }
2595
+ function validRecordIdentity(value) {
2596
+ return typeof value.quarantine_ref === "string" && quarantineProducer(value.producer_id) && validReason(value.reason) && Number.isFinite(Date.parse(String(value.captured_at))) && typeof value.frame_sha256 === "string" && typeof value.raw_frame_base64 === "string" && validChargedBytes(value.charged_bytes);
2597
+ }
2598
+ function validReason(value) {
2599
+ return typeof value === "string" && RELAY_QUARANTINE_REASONS.includes(value);
2600
+ }
2601
+ function validChargedBytes(value) {
2602
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
2603
+ }
2604
+ var ATTRIBUTION_REQUIRED_KEYS = ["producer_id", "producer_installation_ref", "local_session_ref", "local_turn_ref", "local_turn_aliases", "sequence", "frame_sha256"];
2605
+ var ATTRIBUTION_OPTIONAL_KEYS = ["diagnostic"];
2606
+ function validAttribution(value) {
2607
+ if (!record3(value) || !hasExactKeys2(value, ATTRIBUTION_REQUIRED_KEYS, ATTRIBUTION_OPTIONAL_KEYS)) return false;
2608
+ return validAttributionIdentity(value) && validAttributionAliases(value.local_turn_aliases) && validAttributionEnvelope(value) && (value.diagnostic === void 0 || validAttributionDiagnostic(value.diagnostic));
2609
+ }
2610
+ function validAttributionIdentity(value) {
2611
+ return (value.producer_id === "codex" || value.producer_id === "claude") && isHostSafeRef(value.producer_installation_ref) && isHostSafeRef(value.local_session_ref) && isHostSafeRef(value.local_turn_ref);
2612
+ }
2613
+ function validAttributionAliases(value) {
2614
+ return Array.isArray(value) && value.length <= 16 && value.every(isHostSafeRef);
2615
+ }
2616
+ function validAttributionEnvelope(value) {
2617
+ return typeof value.sequence === "number" && Number.isSafeInteger(value.sequence) && value.sequence > 0 && typeof value.frame_sha256 === "string";
2618
+ }
2619
+ function validAttributionDiagnostic(value) {
2620
+ if (!record3(value) || !hasExactKeys2(value, [], RELAY_DELIVERY_DIAGNOSTIC_KEYS)) return false;
2621
+ return isUndefinedOr(value.relayCode, isRelayGatewayErrorCode) && isUndefinedOr(value.gatewayStatus, isSafeInteger) && isUndefinedOr(value.gatewayCode, isBoundedRefusalWord) && isUndefinedOr(value.gatewayReason, isBoundedRefusalWord) && isUndefinedOr(value.exhausted, isBoolean);
2622
+ }
2623
+ function isSafeInteger(value) {
2624
+ return Number.isSafeInteger(value);
2625
+ }
2626
+ function isBoolean(value) {
2627
+ return typeof value === "boolean";
2628
+ }
2629
+ function attributedRecordMatchesQuery(recordValue, query) {
2630
+ const attribution = recordValue.attribution;
2631
+ if (attribution === void 0) return false;
2632
+ return attribution.producer_id === query.producer_id && attribution.producer_installation_ref === query.producer_installation_ref && attribution.local_session_ref === query.local_session_ref && (attribution.local_turn_ref === query.local_turn_ref || attribution.local_turn_aliases.includes(query.local_turn_ref));
2334
2633
  }
2335
2634
  function quarantineProducer(value) {
2336
2635
  return value === "codex" || value === "claude" || value === "unknown";
@@ -2418,11 +2717,11 @@ var RelayAdmissionStore = class {
2418
2717
  const hash = hostProducerFrameHash(frame);
2419
2718
  const replay = replayCode(existing, hash, frame.sequence, installation2);
2420
2719
  if (replay !== null) {
2421
- if (replay === "frame_identity_conflict") await this.quarantine.retainFrame(frame, replay);
2720
+ if (replay === "frame_identity_conflict") await this.quarantine.retainFrame(frame, replay, attributionForFrame(frame, hash, frame.sequence));
2422
2721
  return result(replay, installation2);
2423
2722
  }
2424
2723
  if (frame.sequence !== installation2.admitted_through_sequence + 1) {
2425
- await this.quarantine.retainFrame(frame, "sequence_gap");
2724
+ await this.quarantine.retainFrame(frame, "sequence_gap", attributionForFrame(frame, hash, frame.sequence));
2426
2725
  return result("sequence_gap", installation2);
2427
2726
  }
2428
2727
  const chargedBytes = 4 + Buffer.byteLength(JSON.stringify(frame), "utf8");
@@ -2468,8 +2767,9 @@ var RelayAdmissionStore = class {
2468
2767
  const installation2 = state.installations[installationKey(head.frame)];
2469
2768
  if (!installation2) throw new TypeError("Host Relay delivery installation is unavailable.");
2470
2769
  if (outcome.status === "refused" || exhausted) {
2471
- await this.quarantine.retainFrame(head.frame, "gateway_refused");
2472
- installation2.last_refusal = { sequence: head.sequence, submission_ref: input.submission_ref, ...refusalCause(outcome, head), refused_at_ms: options.now_ms };
2770
+ const diagnostic = exhaustedDiagnostic(outcome, exhausted);
2771
+ await this.quarantine.retainFrame(head.frame, "gateway_refused", attributionForFrame(head.frame, head.hash, head.sequence, diagnostic));
2772
+ installation2.last_refusal = { sequence: head.sequence, submission_ref: input.submission_ref, ...refusalCause(outcome, head), ...diagnostic === void 0 ? {} : { diagnostic }, refused_at_ms: options.now_ms };
2473
2773
  refused.push(input.submission_ref);
2474
2774
  } else {
2475
2775
  await options.after_gateway_accept_before_delivery_fsync?.({ fault_point: "after_gateway_accept_before_delivery_fsync", delivery: structuredClone(input) });
@@ -2513,17 +2813,22 @@ function installationKey(frame) {
2513
2813
  return `${frame.producer_id}\0${frame.producer_installation_ref}`;
2514
2814
  }
2515
2815
  function pendingFrameMatchesBindingQuery(entry2, query) {
2516
- if (entry2.frame.frame_kind !== "user_input") return false;
2517
- const payload = entry2.frame.payload;
2518
- if (typeof payload.local_session_ref !== "string" || typeof payload.local_turn_ref !== "string") return false;
2519
- const aliases = Array.isArray(payload.local_turn_aliases) ? payload.local_turn_aliases.filter((value) => typeof value === "string") : [];
2520
- return relayRequestBindingMatchesQuery(query, {
2521
- producer_id: entry2.frame.producer_id,
2522
- producer_installation_ref: entry2.frame.producer_installation_ref,
2523
- local_session_ref: payload.local_session_ref,
2524
- local_turn_ref: payload.local_turn_ref,
2525
- local_turn_aliases: aliases
2526
- });
2816
+ const selector = extractHostBindingSelector(entry2.frame);
2817
+ if (selector === null) return false;
2818
+ return relayRequestBindingMatchesQuery(query, selector);
2819
+ }
2820
+ function attributionForFrame(frame, hash, sequence, diagnostic) {
2821
+ const selector = extractHostBindingSelector(frame);
2822
+ if (selector === null) return void 0;
2823
+ if (frame.producer_id !== selector.producer_id || frame.producer_installation_ref !== selector.producer_installation_ref || frame.sequence !== sequence) return void 0;
2824
+ if (hostProducerFrameHash(frame) !== hash) return void 0;
2825
+ return { ...selector, sequence, frame_sha256: hash, ...diagnostic === void 0 ? {} : { diagnostic } };
2826
+ }
2827
+ function exhaustedDiagnostic(outcome, exhausted) {
2828
+ if (outcome.status !== "retryable" && outcome.status !== "refused") return void 0;
2829
+ if (outcome.diagnostic !== void 0) return exhausted ? { ...outcome.diagnostic, exhausted: true } : outcome.diagnostic;
2830
+ if (exhausted) return { exhausted: true };
2831
+ return void 0;
2527
2832
  }
2528
2833
  function replayCode(existing, hash, sequence, installation2) {
2529
2834
  if (existing !== void 0) return existing.hash === hash ? "already_admitted" : "frame_identity_conflict";
@@ -2575,7 +2880,17 @@ function installation(value) {
2575
2880
  return typeof value === "object" && value !== null && !Array.isArray(value) && "epoch" in value && "admitted_through_sequence" in value && "delivered_through_sequence" in value && [value.epoch, value.admitted_through_sequence, value.delivered_through_sequence].every(Number.isSafeInteger) && (!("last_refusal" in value) || refusalRecord(value.last_refusal));
2576
2881
  }
2577
2882
  function refusalRecord(value) {
2578
- return object(value) && Number.isSafeInteger(value.sequence) && typeof value.submission_ref === "string" && typeof value.code === "string" && typeof value.message === "string" && Number.isSafeInteger(value.refused_at_ms);
2883
+ return object(value) && Number.isSafeInteger(value.sequence) && typeof value.submission_ref === "string" && typeof value.code === "string" && typeof value.message === "string" && Number.isSafeInteger(value.refused_at_ms) && (value.diagnostic === void 0 || validDiagnostic(value.diagnostic));
2884
+ }
2885
+ function validDiagnostic(value) {
2886
+ if (!object(value) || !hasExactKeys2(value, [], RELAY_DELIVERY_DIAGNOSTIC_KEYS)) return false;
2887
+ return isUndefinedOr(value.relayCode, isRelayGatewayErrorCode) && isUndefinedOr(value.gatewayStatus, isSafeInteger2) && isUndefinedOr(value.gatewayCode, isBoundedRefusalWord) && isUndefinedOr(value.gatewayReason, isBoundedRefusalWord) && isUndefinedOr(value.exhausted, isBoolean2);
2888
+ }
2889
+ function isSafeInteger2(value) {
2890
+ return Number.isSafeInteger(value);
2891
+ }
2892
+ function isBoolean2(value) {
2893
+ return typeof value === "boolean";
2579
2894
  }
2580
2895
  function entry(value) {
2581
2896
  return object(value) && producer2(value.producer_id) && typeof value.producer_installation_ref === "string" && Number.isSafeInteger(value.sequence) && typeof value.hash === "string" && Number.isSafeInteger(value.charged_bytes) && object(value.frame) && Number.isSafeInteger(value.retry_attempts) && Number.isSafeInteger(value.retry_at_ms);
@@ -2783,10 +3098,22 @@ function submissionRefusal(error) {
2783
3098
  const status = isRecord(error) && typeof error.status === "number" ? error.status : void 0;
2784
3099
  const code = errorCode7(error) ?? "gateway_unavailable";
2785
3100
  const definitive = code === "payload_rejected" || status !== void 0 && status >= 400 && status < 500 && !RETRYABLE_HTTP_STATUSES.has(status);
2786
- return { code, message: errorMessage(error), definitive };
3101
+ return { code, message: errorMessage(error), definitive, diagnostic: typedDiagnostic(error, status) };
3102
+ }
3103
+ function typedDiagnostic(error, status) {
3104
+ if (!isRecord(error)) return status === void 0 ? {} : { gatewayStatus: status };
3105
+ const gatewayCode = isBoundedRefusalWord(error.error_code) ? error.error_code : void 0;
3106
+ const gatewayReason = isBoundedRefusalWord(error.refusal_reason) ? error.refusal_reason : void 0;
3107
+ return {
3108
+ ...typeof error.code === "string" ? { relayCode: error.code } : {},
3109
+ ...status === void 0 ? {} : { gatewayStatus: status },
3110
+ ...gatewayCode === void 0 ? {} : { gatewayCode },
3111
+ ...gatewayReason === void 0 ? {} : { gatewayReason }
3112
+ };
2787
3113
  }
2788
3114
  function deliveryRefusal(refusal) {
2789
- return refusal.definitive ? { status: "refused", code: refusal.code, message: refusal.message } : { status: "retryable", reason: `${refusal.code}: ${refusal.message}` };
3115
+ const diagnostic = refusal.diagnostic === void 0 ? {} : { diagnostic: refusal.diagnostic };
3116
+ return refusal.definitive ? { status: "refused", code: refusal.code, message: refusal.message, ...diagnostic } : { status: "retryable", reason: `${refusal.code}: ${refusal.message}`, ...diagnostic };
2790
3117
  }
2791
3118
  function errorMessage(error) {
2792
3119
  return error instanceof Error ? error.message : String(error);
@@ -3009,6 +3336,10 @@ async function gatewayRefusal(response2) {
3009
3336
  return {};
3010
3337
  }
3011
3338
  }
3339
+ function submitRefusalCode(body) {
3340
+ if (!isCealJsonRecord(body) || typeof body.error_code !== "string" || !GATEWAY_REFUSAL_CODE_PATTERN.test(body.error_code)) return void 0;
3341
+ return body.error_code;
3342
+ }
3012
3343
  function refusalMessage(status, body) {
3013
3344
  const record6 = isCealJsonRecord(body) ? body : {};
3014
3345
  const code = typeof record6.error_code === "string" ? record6.error_code : "unknown";
@@ -3036,7 +3367,7 @@ function createHostRelayGatewayHttpPort(options) {
3036
3367
  invalidEventTime: () => new HostRelayGatewayError("payload_rejected", "Host Relay submission has no event time."),
3037
3368
  unavailable: () => new HostRelayGatewayError("gateway_unavailable", "Gateway Host ingress is unavailable."),
3038
3369
  invalidResponse: () => new HostRelayGatewayError("invalid_response", "Gateway Host ingress response is not JSON."),
3039
- refused: (status, body) => new HostRelayGatewayError("gateway_refused", refusalMessage(status, body), status),
3370
+ refused: (status, body) => new HostRelayGatewayError("gateway_refused", refusalMessage(status, body), status, submitRefusalCode(body)),
3040
3371
  acknowledgement
3041
3372
  });
3042
3373
  },
@@ -3186,10 +3517,20 @@ import { dirname as dirname3, join as join6 } from "node:path";
3186
3517
  import { createHash as createHash5 } from "node:crypto";
3187
3518
  var HOST_CURRENT_PROMPT_MAX_BYTES = 256 * 1024;
3188
3519
  var MAX_CURRENT_PROMPTS = 1024;
3520
+ var MAX_CONSUMED_PROMPTS = 1024;
3521
+ var HostCurrentPromptCapacityError = class extends Error {
3522
+ report_diagnostic;
3523
+ constructor(reportDiagnostic) {
3524
+ super("current_prompt_unavailable");
3525
+ this.name = "HostCurrentPromptCapacityError";
3526
+ this.report_diagnostic = reportDiagnostic;
3527
+ }
3528
+ };
3189
3529
  var HostCurrentPromptCustody = class {
3190
3530
  #records = /* @__PURE__ */ new Map();
3191
3531
  #consumed = /* @__PURE__ */ new Map();
3192
3532
  #now;
3533
+ #capacityDiagnosticReported = false;
3193
3534
  constructor(now = Date.now) {
3194
3535
  this.#now = now;
3195
3536
  }
@@ -3201,10 +3542,14 @@ var HostCurrentPromptCustody = class {
3201
3542
  this.#purge();
3202
3543
  const key = promptKey(identity);
3203
3544
  if (this.#consumed.has(key)) return;
3204
- if (!this.#records.has(key) && this.#records.size + this.#consumed.size >= MAX_CURRENT_PROMPTS) throw new TypeError("current_prompt_unavailable");
3545
+ if (!this.#records.has(key) && this.#records.size >= MAX_CURRENT_PROMPTS) {
3546
+ const reportDiagnostic = !this.#capacityDiagnosticReported;
3547
+ this.#capacityDiagnosticReported = true;
3548
+ throw new HostCurrentPromptCapacityError(reportDiagnostic);
3549
+ }
3205
3550
  this.#records.set(key, { prompt, expires_at_ms: expiry });
3206
3551
  }
3207
- /** Transfer this turn's prompt into at most one authenticated invocation. */
3552
+ /** Transfer this turn's prompt once while its bounded recent replay guard retains the identity. */
3208
3553
  take(identity) {
3209
3554
  this.#purge();
3210
3555
  const key = promptKey(identity);
@@ -3212,14 +3557,38 @@ var HostCurrentPromptCustody = class {
3212
3557
  if (prompt !== void 0) {
3213
3558
  const expiresAt = this.#records.get(key)?.expires_at_ms;
3214
3559
  this.#records.delete(key);
3215
- if (expiresAt !== void 0) this.#consumed.set(key, expiresAt);
3560
+ if (expiresAt !== void 0) this.#rememberConsumed(key, expiresAt);
3561
+ this.#resetCapacityDiagnosticIfAvailable();
3216
3562
  }
3217
3563
  return prompt;
3218
3564
  }
3565
+ /** Release a prompt after its turn ends while retaining the same bounded replay guard. */
3566
+ release(identity) {
3567
+ this.#purge();
3568
+ const key = promptKey(identity);
3569
+ const record6 = this.#records.get(key);
3570
+ if (record6 === void 0) return false;
3571
+ this.#records.delete(key);
3572
+ this.#rememberConsumed(key, record6.expires_at_ms);
3573
+ this.#resetCapacityDiagnosticIfAvailable();
3574
+ return true;
3575
+ }
3576
+ #rememberConsumed(key, expiresAt) {
3577
+ this.#consumed.set(key, expiresAt);
3578
+ while (this.#consumed.size > MAX_CONSUMED_PROMPTS) {
3579
+ const oldest = this.#consumed.keys().next().value;
3580
+ if (oldest === void 0) return;
3581
+ this.#consumed.delete(oldest);
3582
+ }
3583
+ }
3219
3584
  #purge() {
3220
3585
  const now = this.#now();
3221
3586
  for (const [key, value] of this.#records) if (value.expires_at_ms <= now) this.#records.delete(key);
3222
3587
  for (const [key, expiresAt] of this.#consumed) if (expiresAt <= now) this.#consumed.delete(key);
3588
+ this.#resetCapacityDiagnosticIfAvailable();
3589
+ }
3590
+ #resetCapacityDiagnosticIfAvailable() {
3591
+ if (this.#records.size < MAX_CURRENT_PROMPTS) this.#capacityDiagnosticReported = false;
3223
3592
  }
3224
3593
  };
3225
3594
  function promptKey(value) {
@@ -3248,6 +3617,7 @@ var HOST_RELAY_BINDING_RESULT_SCHEMA = "ceal.host_relay_binding_result.v1";
3248
3617
  var HOST_RELAY_INVOCATION_CONTEXT_QUERY_SCHEMA = "ceal.host_relay_invocation_context_query.v1";
3249
3618
  var HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA = "ceal.host_relay_invocation_context_result.v1";
3250
3619
  var HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA = "ceal.host_relay_current_prompt_register.v1";
3620
+ var HOST_RELAY_CURRENT_PROMPT_RELEASE_SCHEMA = "ceal.host_relay_current_prompt_release.v1";
3251
3621
  var HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA = "ceal.host_relay_current_prompt_result.v1";
3252
3622
  var HOST_RELAY_IPC_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
3253
3623
  var HOST_RELAY_INVOCATION_MINT_REFUSAL_REASONS = vocabulary([
@@ -3258,6 +3628,8 @@ var HOST_RELAY_INVOCATION_MINT_REFUSAL_REASONS = vocabulary([
3258
3628
  "gateway_unavailable",
3259
3629
  "gateway_refused",
3260
3630
  "gateway_response_invalid",
3631
+ "gateway_rate_limited",
3632
+ "producer_frame_invalid",
3261
3633
  "deadline",
3262
3634
  "cancelled",
3263
3635
  "mint_failed",
@@ -3271,6 +3643,17 @@ var HOST_RELAY_INVOCATION_MINT_REFUSAL_REASONS = vocabulary([
3271
3643
  "host_input_mismatch",
3272
3644
  "host_prompt_mismatch"
3273
3645
  ]);
3646
+ var HOST_RELAY_DIRECT_WIRE_MINT_REASONS = vocabulary([
3647
+ "context_stale",
3648
+ "context_expired",
3649
+ "host_source_refused",
3650
+ "host_credential_refused",
3651
+ "gateway_unavailable",
3652
+ "gateway_rate_limited",
3653
+ "gateway_refused",
3654
+ "gateway_response_invalid",
3655
+ "producer_frame_invalid"
3656
+ ]);
3274
3657
  var HostRelayInvocationMintRefusal = class extends Error {
3275
3658
  reason;
3276
3659
  constructor(reason) {
@@ -3358,7 +3741,7 @@ function serveSocket(socket, options, currentPrompts, quarantine, active, socket
3358
3741
  socket.once("error", () => closeConnection(socket, state, active, sockets));
3359
3742
  socket.once("close", () => closeConnection(socket, state, active, sockets));
3360
3743
  socket.once("end", () => {
3361
- if (state.buffer.length > 0 && currentPromptWire(state.buffer)) {
3744
+ if (state.buffer.length > 0 && isCurrentPromptWire(state.buffer)) {
3362
3745
  writeCurrentPromptResponse(socket, "current_prompt_unavailable");
3363
3746
  socket.end();
3364
3747
  } else if (state.buffer.length > 0) void quarantine.retainMalformed(state.buffer, "frame_truncated").finally(() => {
@@ -3374,7 +3757,7 @@ async function drainFrames(socket, state, options, currentPrompts, quarantine, a
3374
3757
  }
3375
3758
  async function processBufferedRequest(socket, state, options, currentPrompts, quarantine, active) {
3376
3759
  const length = state.buffer.readUInt32BE(0);
3377
- const promptWire = currentPromptWire(state.buffer);
3760
+ const promptWire = isCurrentPromptWire(state.buffer);
3378
3761
  const maximum = promptWire ? HOST_CURRENT_PROMPT_MAX_BYTES + 4096 : HOST_PRODUCER_MAX_JSON_BYTES;
3379
3762
  if (length === 0 || length > maximum) {
3380
3763
  await refuseInvalidBufferedRequest(socket, state.buffer, length, promptWire, quarantine);
@@ -3392,13 +3775,8 @@ async function processBufferedRequest(socket, state, options, currentPrompts, qu
3392
3775
  await refuseMalformedRequest(socket, encoded, promptWire, error, quarantine);
3393
3776
  return true;
3394
3777
  }
3395
- if (request2.schema_version === HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA) {
3396
- try {
3397
- currentPrompts.register(request2, request2.current_prompt, request2.context_expires_at);
3398
- writeCurrentPromptResponse(socket, "registered");
3399
- } catch {
3400
- writeCurrentPromptResponse(socket, "current_prompt_unavailable");
3401
- }
3778
+ if (request2.schema_version === HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA || request2.schema_version === HOST_RELAY_CURRENT_PROMPT_RELEASE_SCHEMA) {
3779
+ answerCurrentPromptRequest(socket, request2, currentPrompts, options.diagnostic_sink);
3402
3780
  return true;
3403
3781
  }
3404
3782
  const answered = await processHostQuery(socket, request2, options, currentPrompts, state.abort.signal);
@@ -3410,6 +3788,22 @@ async function processBufferedRequest(socket, state, options, currentPrompts, qu
3410
3788
  await processProducerRequest(socket, state, request2, encoded, options.admission, quarantine, active);
3411
3789
  return true;
3412
3790
  }
3791
+ function answerCurrentPromptRequest(socket, request2, currentPrompts, sink) {
3792
+ if (request2.schema_version === HOST_RELAY_CURRENT_PROMPT_RELEASE_SCHEMA) {
3793
+ currentPrompts.release(request2);
3794
+ writeCurrentPromptResponse(socket, "released");
3795
+ return;
3796
+ }
3797
+ try {
3798
+ currentPrompts.register(request2, request2.current_prompt, request2.context_expires_at);
3799
+ writeCurrentPromptResponse(socket, "registered");
3800
+ } catch (error) {
3801
+ if (error instanceof HostCurrentPromptCapacityError) {
3802
+ if (error.report_diagnostic) writeHostServiceDiagnostic(request2.producer_id, "current_prompt_capacity_exhausted", void 0, void 0, sink);
3803
+ writeCurrentPromptResponse(socket, "capacity_exhausted");
3804
+ } else writeCurrentPromptResponse(socket, "current_prompt_unavailable");
3805
+ }
3806
+ }
3413
3807
  async function refuseInvalidBufferedRequest(socket, rawBuffer, length, promptWire, quarantine) {
3414
3808
  if (promptWire) {
3415
3809
  writeCurrentPromptResponse(socket, "current_prompt_unavailable");
@@ -3500,30 +3894,62 @@ async function resolveInvocationContext(request2, admission, bindings, currentPr
3500
3894
  const query = bindingQueryFromRequest(request2);
3501
3895
  const expectedSequences = pendingAdmissionSequences(await admission.snapshot(), query);
3502
3896
  const binding = await waitForRequestBinding(query, admission, bindings, signal);
3503
- if (binding.status !== "ready") return unboundInvocationContextRefusal(await admission.snapshot(), query, expectedSequences) ?? { schema_version: HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA, status: "no_binding" };
3897
+ if (binding.status !== "ready") return await unboundInvocationContextRefusal(admission, await admission.snapshot(), query, expectedSequences) ?? { schema_version: HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA, status: "no_binding" };
3504
3898
  const currentPrompt = currentPrompts.take({ producer_id: request2.producer_id, producer_installation_ref: request2.producer_installation_ref, local_session_ref: request2.local_session_ref, local_turn_ref: request2.local_turn_ref, prompt_ref: binding.binding.prompt_ref });
3505
3899
  let result2;
3506
3900
  try {
3507
- result2 = await mint({ client_nonce: request2.client_nonce, context_expires_at: binding.binding.context_expires_at ?? binding.binding.bound_at, request_work_context: relayRequestWorkContextFromBinding(binding.binding), ...currentPrompt === void 0 ? {} : { current_prompt: currentPrompt } }, signal);
3901
+ result2 = await mint({ client_nonce: request2.client_nonce, context_expires_at: binding.binding.context_expires_at ?? binding.binding.bound_at, request_work_context: relayRequestWorkContextFromBinding(binding.binding), ...currentPrompt === void 0 ? {} : { current_prompt: currentPrompt }, ...request2.visible_output_max_bytes === void 0 ? {} : { visible_output_max_bytes: request2.visible_output_max_bytes } }, signal);
3508
3902
  } catch (error) {
3509
3903
  return { schema_version: HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA, status: "refused", reason: error instanceof HostRelayInvocationMintRefusal ? error.reason : "mint_failed" };
3510
3904
  }
3511
3905
  return { schema_version: HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA, status: "ready", result: result2 };
3512
3906
  }
3513
- function unboundInvocationContextRefusal(snapshot, query, expectedSequences) {
3514
- if (expectedSequences.length === 0) return null;
3515
- const refusal = snapshot.installations[`${query.producer_id}\0${query.producer_installation_ref}`]?.last_refusal;
3516
- if (refusal === void 0 || !expectedSequences.includes(refusal.sequence) || refusal.code !== "gateway_refused") return null;
3517
- return { schema_version: HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA, status: "refused", reason: "gateway_refused" };
3907
+ async function unboundInvocationContextRefusal(admission, snapshot, query, expectedSequences) {
3908
+ if (expectedSequences.length > 0) {
3909
+ const refusal = snapshot.installations[`${query.producer_id}\0${query.producer_installation_ref}`]?.last_refusal;
3910
+ if (refusal !== void 0 && expectedSequences.includes(refusal.sequence)) {
3911
+ const reason2 = mintReasonForDeliveryRefusal(refusal.code, refusal.diagnostic);
3912
+ if (reason2 !== void 0) return { schema_version: HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA, status: "refused", reason: reason2 };
3913
+ }
3914
+ }
3915
+ const selector = Object.freeze({
3916
+ producer_id: query.producer_id,
3917
+ producer_installation_ref: query.producer_installation_ref,
3918
+ local_session_ref: query.local_session_ref,
3919
+ local_turn_ref: query.local_turn_ref,
3920
+ local_turn_aliases: Object.freeze([])
3921
+ });
3922
+ const match = await admission.quarantine.findNewestAttributedMatch(selector);
3923
+ if (match === null) return null;
3924
+ const reason = mintReasonForQuarantinedMatch(match);
3925
+ if (reason === void 0) return null;
3926
+ return { schema_version: HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA, status: "refused", reason };
3927
+ }
3928
+ function mintReasonForDeliveryRefusal(code, diagnostic) {
3929
+ if (code !== "gateway_refused") return void 0;
3930
+ if (diagnostic === void 0) return "gateway_refused";
3931
+ return mintReasonForWireCause(projectCealHostAuthenticationCause(diagnostic));
3932
+ }
3933
+ function mintReasonForQuarantinedMatch(match) {
3934
+ if (match === null) return void 0;
3935
+ if (match.reason !== "gateway_refused") return "producer_frame_invalid";
3936
+ const diagnostic = match.attribution?.diagnostic;
3937
+ if (diagnostic === void 0) return void 0;
3938
+ return mintReasonForWireCause(projectCealHostAuthenticationCause(diagnostic));
3939
+ }
3940
+ function mintReasonForWireCause(cause) {
3941
+ if (isDirectWireCause(cause)) return cause;
3942
+ if (cause === "relay_failed" || cause === "relay_unavailable" || cause === "options_invalid") return "relay_failed";
3943
+ return "mint_failed";
3944
+ }
3945
+ function isDirectWireCause(cause) {
3946
+ return isVocabularyWord(HOST_RELAY_DIRECT_WIRE_MINT_REASONS, cause);
3518
3947
  }
3519
3948
  function pendingAdmissionSequences(snapshot, query) {
3520
3949
  const sequences = [];
3521
3950
  for (const entry2 of snapshot.entries) {
3522
- if (entry2.frame.frame_kind !== "user_input") continue;
3523
- const payload = entry2.frame.payload;
3524
- if (typeof payload.local_session_ref !== "string" || typeof payload.local_turn_ref !== "string") continue;
3525
- const aliases = Array.isArray(payload.local_turn_aliases) ? payload.local_turn_aliases.filter((value) => typeof value === "string") : [];
3526
- if (!relayRequestBindingMatchesQuery(query, { producer_id: entry2.frame.producer_id, producer_installation_ref: entry2.frame.producer_installation_ref, local_session_ref: payload.local_session_ref, local_turn_ref: payload.local_turn_ref, local_turn_aliases: aliases })) continue;
3951
+ const selector = extractHostBindingSelector(entry2.frame);
3952
+ if (selector === null || !relayRequestBindingMatchesQuery(query, selector)) continue;
3527
3953
  sequences.push(entry2.sequence);
3528
3954
  }
3529
3955
  return sequences;
@@ -3625,6 +4051,10 @@ function decodeLocalRequest(value) {
3625
4051
  if (!validCurrentPromptRegisterRequest(value)) throw new HostProducerFrameError("invalid_frame_shape");
3626
4052
  return value;
3627
4053
  }
4054
+ if (value.schema_version === HOST_RELAY_CURRENT_PROMPT_RELEASE_SCHEMA) {
4055
+ if (!validCurrentPromptReleaseRequest(value)) throw new HostProducerFrameError("invalid_frame_shape");
4056
+ return value;
4057
+ }
3628
4058
  if (value.schema_version === HOST_RELAY_BINDING_QUERY_SCHEMA) {
3629
4059
  if (!validBindingQueryRequest(value)) throw new HostProducerFrameError("invalid_frame_shape");
3630
4060
  return value;
@@ -3638,6 +4068,9 @@ function decodeLocalRequest(value) {
3638
4068
  function validCurrentPromptRegisterRequest(value) {
3639
4069
  return validQueryIdentity(value, HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA) && exactKeys4(value, ["schema_version", "producer_id", "producer_installation_ref", "local_session_ref", "local_turn_ref", "prompt_ref", "current_prompt", "context_expires_at"]) && safeRef3(value.prompt_ref) && typeof value.current_prompt === "string" && Buffer.byteLength(value.current_prompt, "utf8") > 0 && Buffer.byteLength(value.current_prompt, "utf8") <= HOST_CURRENT_PROMPT_MAX_BYTES && validTimestamp2(value.context_expires_at);
3640
4070
  }
4071
+ function validCurrentPromptReleaseRequest(value) {
4072
+ return validQueryIdentity(value, HOST_RELAY_CURRENT_PROMPT_RELEASE_SCHEMA) && exactKeys4(value, ["schema_version", "producer_id", "producer_installation_ref", "local_session_ref", "local_turn_ref", "prompt_ref"]) && safeRef3(value.prompt_ref);
4073
+ }
3641
4074
  function validBindingQueryRequest(value) {
3642
4075
  return validQueryIdentity(value, HOST_RELAY_BINDING_QUERY_SCHEMA) && exactKeys4(value, ["schema_version", "producer_id", "producer_installation_ref", "local_session_ref", "local_turn_ref"]);
3643
4076
  }
@@ -3645,11 +4078,14 @@ function bindingQueryFromRequest(value) {
3645
4078
  return { producer_id: value.producer_id, producer_installation_ref: value.producer_installation_ref, local_session_ref: value.local_session_ref, local_turn_ref: value.local_turn_ref };
3646
4079
  }
3647
4080
  function validInvocationContextQueryRequest(value) {
3648
- return validQueryIdentity(value, HOST_RELAY_INVOCATION_CONTEXT_QUERY_SCHEMA) && exactKeys4(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);
4081
+ return validQueryIdentity(value, HOST_RELAY_INVOCATION_CONTEXT_QUERY_SCHEMA) && exactKeys4(value, ["schema_version", "producer_id", "producer_installation_ref", "local_session_ref", "local_turn_ref", "client_nonce"], ["visible_output_max_bytes"]) && typeof value.client_nonce === "string" && CEAL_HOST_CLIENT_NONCE_PATTERN.test(value.client_nonce) && (value.visible_output_max_bytes === void 0 || validVisibleOutputBudget(value.visible_output_max_bytes));
3649
4082
  }
3650
4083
  function validQueryIdentity(value, schema) {
3651
4084
  return record4(value) && value.schema_version === schema && (value.producer_id === "codex" || value.producer_id === "claude") && safeRef3(value.producer_installation_ref) && safeRef3(value.local_session_ref) && safeRef3(value.local_turn_ref);
3652
4085
  }
4086
+ function validVisibleOutputBudget(value) {
4087
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0 && value <= CEAL_CANONICAL_HTTP_MAX_RESPONSE_BYTES;
4088
+ }
3653
4089
  function decodeLengthPrefixedJson(input, maximum) {
3654
4090
  if (input.length < HOST_RELAY_IPC_LENGTH_BYTES) return null;
3655
4091
  const length = input.readUInt32BE(0);
@@ -3669,11 +4105,18 @@ function encodeLengthPrefixed(value) {
3669
4105
  body.copy(output, HOST_RELAY_IPC_LENGTH_BYTES);
3670
4106
  return output;
3671
4107
  }
3672
- function currentPromptWire(value) {
4108
+ function isCurrentPromptWire(value) {
4109
+ return currentPromptRegisterWire(value) || currentPromptReleaseWire(value);
4110
+ }
4111
+ function currentPromptRegisterWire(value) {
3673
4112
  return value.subarray(HOST_RELAY_IPC_LENGTH_BYTES, Math.min(value.length, HOST_RELAY_IPC_LENGTH_BYTES + 128)).includes(Buffer.from(`"schema_version":"${HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA}"`, "utf8"));
3674
4113
  }
3675
- function exactKeys4(value, keys) {
3676
- return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
4114
+ function currentPromptReleaseWire(value) {
4115
+ return value.subarray(HOST_RELAY_IPC_LENGTH_BYTES, Math.min(value.length, HOST_RELAY_IPC_LENGTH_BYTES + 128)).includes(Buffer.from(`"schema_version":"${HOST_RELAY_CURRENT_PROMPT_RELEASE_SCHEMA}"`, "utf8"));
4116
+ }
4117
+ function exactKeys4(value, required, optional = []) {
4118
+ const keys = Object.keys(value);
4119
+ return required.every((key) => Object.hasOwn(value, key)) && keys.every((key) => required.includes(key) || optional.includes(key));
3677
4120
  }
3678
4121
  function safeRef3(value) {
3679
4122
  return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u.test(value);