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

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.
@@ -200,6 +200,9 @@ var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_DOCUMENT_FIELDS = Object.freeze([..
200
200
  function vocabulary(words) {
201
201
  return Object.freeze(words);
202
202
  }
203
+ function isVocabularyWord(words, value) {
204
+ return words.some((word) => word === value);
205
+ }
203
206
 
204
207
  // packages/ceal-client-protocol/src/gateway-response-types.ts
205
208
  var CEAL_OPERATION_READINESS_VALUES = vocabulary(["ready", "degraded", "unavailable", "unknown"]);
@@ -212,7 +215,7 @@ var CEAL_GATEWAY_DERIVED_STORE_FAILURE_CLASSES = vocabulary(["storage_unavailabl
212
215
  var CEAL_POLICY_DECISIONS = vocabulary(["allowed", "denied", "not_evaluated"]);
213
216
  var CEAL_CONNECTOR_ROUTE_PHASES = vocabulary(["scope_observation", "target_selection", "route_resolution"]);
214
217
  var CEAL_CONNECTOR_ROUTE_CAUSES = vocabulary(["provider_throttled", "provider_unavailable", "binding_invalid", "scope_limit_exceeded"]);
215
- var CEAL_WRITE_SOURCE_KINDS = vocabulary(["authenticated_registered_client", "agent_lease_admission", "provider_authenticated_event"]);
218
+ var CEAL_WRITE_SOURCE_KINDS = vocabulary(["authenticated_registered_client", "provider_authenticated_event"]);
216
219
  var CEAL_REFRESH_DELIVERIES = vocabulary(["initial", "recovery", "replay", "terminal_failure", "recovery_unavailable"]);
217
220
  var CEAL_CLIENT_OPERATIONS = vocabulary(["handshake", "discover", "call", "readback"]);
218
221
  var CEAL_WRITE_IDEMPOTENCY_POSTURES = vocabulary(["required", "optional", "not_required"]);
@@ -365,6 +368,7 @@ var CEAL_OPERATION_WITHHELD_CAUSES = vocabulary(["provider_permission", "access_
365
368
  // packages/ceal-client-protocol/src/operation-contract-types.ts
366
369
  var CEAL_JSON_SCHEMA_2020_12 = "https://json-schema.org/draft/2020-12/schema";
367
370
  var CEAL_OPERATION_ERROR_SCHEMA_VERSION = "ceal.operation_error.v1";
371
+ var CEAL_ARTIFACT_STAGE_TERMINALS = vocabulary(["chunk_accepted", "artifact_ready", "idempotency_replayed"]);
368
372
  var CEAL_RETRY_AFTER_MAX_MS = 60 * 60 * 1e3;
369
373
  var CEAL_JSON_SCHEMA_TYPES = vocabulary(["object", "array", "string", "integer", "number", "boolean", "null"]);
370
374
  var OBSERVATION_POSTURES = vocabulary(["direct_readback", "approved_no_readback", "operator_mediated", "excluded"]);
@@ -738,9 +742,6 @@ var CEAL_OPERATION_AUTHORITY_POLICY_KEYS = Object.freeze(["access_group", "insta
738
742
  var MAX_OPERATION_INPUT_RESOLVER_BINDINGS = 96;
739
743
  var CEAL_OPERATION_DESCRIPTOR_REQUIRED_ENVELOPE_KEYS = Object.freeze(["schema_version", "id", "input_contract", "result_contract", "policy"]);
740
744
  var CEAL_OPERATION_DESCRIPTOR_OPTIONAL_ENVELOPE_KEYS = Object.freeze(["input_resolution", "summary"]);
741
- var CEAL_OPERATION_RESULT_KEYS = vocabulary(["ok", "operation_id", "operation_receipt", "schema_version", "value"]);
742
- var CEAL_OPERATION_COMPACT_RESULT_KEYS = vocabulary(["ok", "operation_evidence", "operation_id", "schema_version", "value"]);
743
- var CEAL_OPERATION_RESULT_OPTIONAL_KEYS = vocabulary(["model_disclosure", "result_complete", "resume"]);
744
745
 
745
746
  // packages/ceal-client-protocol/src/operation-catalog.ts
746
747
  var CEAL_OPERATION_CATALOG_SCHEMA_VERSION = "ceal.catalog.v3";
@@ -804,10 +805,6 @@ var CEAL_SCHEMA_LITERALS = [
804
805
  "ceal.host_observation.v1",
805
806
  "ceal.host_registration_request.v1",
806
807
  "ceal.host_registration_result.v1",
807
- "ceal.leased-resource-stream.v1",
808
- "ceal.leased_consumer_attachment_stream_frame.v1",
809
- "ceal.leased_consumer_attachment_stream_request.v1",
810
- "ceal.leased_consumer_attachment_stream_transport.v1",
811
808
  "ceal.operation_descriptor.v1",
812
809
  "ceal.operation_error.v1",
813
810
  "ceal.operation_failure.v1",
@@ -833,12 +830,6 @@ var CEAL_SCHEMA_LITERAL_SET = new Set(CEAL_SCHEMA_LITERALS);
833
830
  // packages/ceal-client-protocol/src/bounded-series.ts
834
831
  import { join } from "node:path";
835
832
  var CEAL_BOUNDED_SERIES_CATALOG = Object.freeze({
836
- usage_record: (root) => join(root, "run-usage.jsonl"),
837
- control_commit: (root) => join(root, "control-auto-commit.jsonl"),
838
- engagement_signal: (root) => join(root, "runtime-state", "slack-feedback.jsonl"),
839
- runtime_error: (root) => join(root, "runtime-state", "runtime-errors.jsonl"),
840
- turn_bridge_request: (root) => join(root, ".ceal", "turn-bridge", "requests.jsonl"),
841
- thread_run_events: (root) => join(root, "run-events.jsonl"),
842
833
  bounded_store_sidecar: (root) => `${root}.jsonl`,
843
834
  gateway_audit_archive: (root) => `${root}.jsonl`,
844
835
  gateway_access_group_connector_control_audit: (root) => `${root}.audit.jsonl`,
@@ -872,35 +863,6 @@ var CEAL_HOST_INSTALLATION_REF_PATTERN = new RegExp(`^host-installation:${CEAL_L
872
863
  var CEAL_HOST_SOURCE_REF_PATTERN = new RegExp(`^host-source:${CEAL_LOWERCASE_UUID_PATTERN}$`, "u");
873
864
  var CEAL_HOST_ACCESS_TOKEN_PATTERN = /^ceal_host_[A-Za-z0-9_-]{43}$/u;
874
865
 
875
- // packages/ceal-client-protocol/src/agent-session-handoff.ts
876
- var CEAL_AGENT_ADMISSION_PHASES = vocabulary([
877
- "incumbent_admitted",
878
- "incumbent_draining",
879
- "drained",
880
- "candidate_admitted",
881
- "candidate_draining",
882
- "rollback_admitted"
883
- ]);
884
- var CEAL_AGENT_SERVICE_SESSION_RECORD_KEYS = vocabulary([
885
- "admission_fence",
886
- "admission_state",
887
- "admission_state_generation",
888
- "bearer",
889
- "consumer_ref",
890
- "credential_generation",
891
- "expires_at",
892
- "gateway_instance",
893
- "gateway_origin",
894
- "gateway_serving_generation",
895
- "issued_at",
896
- "record_sha256",
897
- "renew_after",
898
- "renew_by",
899
- "schema_version",
900
- "session_revision"
901
- ]);
902
- var CEAL_AGENT_SESSION_COMMIT_KEYS = vocabulary(["attempt_ref", "expected_session_revision", "session_revision"]);
903
-
904
866
  // packages/ceal-client-protocol/src/operation-result-completeness.ts
905
867
  var CEAL_READ_VALUE_CONTINUATION_KEYS = vocabulary(["continuation", "continuation_ref", "next_cursor"]);
906
868
 
@@ -911,7 +873,9 @@ var CEAL_OPERATION_INVOKE_COMMAND = "invoke";
911
873
  var CEAL_OPERATION_INPUT_FLAG = "--input";
912
874
  var CEAL_OPERATION_ID_PLACEHOLDER = "<operation-id>";
913
875
  var CEAL_OPERATION_INPUT_PLACEHOLDER = "<json-object>";
914
- var CEAL_MODEL_INVOCATION_ARGUMENTS = [CEAL_OPERATION_INVOKE_COMMAND, CEAL_OPERATION_ID_PLACEHOLDER, CEAL_OPERATION_INPUT_FLAG, shellSingleQuoted(CEAL_OPERATION_INPUT_PLACEHOLDER)].join(" ");
876
+ var MODEL_INVOCATION_BASE_ARGUMENTS = [CEAL_OPERATION_INVOKE_COMMAND, CEAL_OPERATION_ID_PLACEHOLDER].join(" ");
877
+ var CEAL_MODEL_INVOCATION_ARGUMENTS = [MODEL_INVOCATION_BASE_ARGUMENTS, CEAL_OPERATION_INPUT_FLAG, shellSingleQuoted(CEAL_OPERATION_INPUT_PLACEHOLDER)].join(" ");
878
+ var CEAL_MODEL_INPUT_SOURCE_GUIDANCE = `For caller-owned fields, add ${CEAL_OPERATION_INPUT_FLAG} ${shellSingleQuoted(CEAL_OPERATION_INPUT_PLACEHOLDER)}. Use inline JSON for short input; for longer or generated input, put exactly one JSON object in a caller-owned regular non-symlink UTF-8 JSON file and pass --input @path; relative paths resolve from the command working directory.`;
915
879
  function shellSingleQuoted(value) {
916
880
  return `'${value.replaceAll("'", "'\\''")}'`;
917
881
  }
@@ -943,19 +907,73 @@ var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_JSON_SCHEMA = Object.freeze({
943
907
  }
944
908
  });
945
909
 
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
+ // packages/ceal-client-protocol/src/opaque-reference.ts
946
+ var CEAL_OPAQUE_HANDLE_KINDS = vocabulary(["target", "message", "thread", "artifact", "document", "block", "object"]);
947
+ var CEAL_OPAQUE_REF_KINDS = vocabulary([...CEAL_OPAQUE_HANDLE_KINDS, "result", "operation-receipt", "reply-receipt", "field", "notion-data-source"]);
948
+
946
949
  // packages/ceal-client-protocol/src/bare-document.ts
947
950
  var REQUIRED_FIELDS = CEAL_CLIENT_WIRE_CONTRACT.command_response.bare_document_fields;
948
951
  var OPTIONAL_FIELDS = CEAL_CLIENT_WIRE_CONTRACT.command_response.bare_document_optional_fields;
949
952
 
950
- // packages/ceal-client-protocol/src/leased-consumer-vocabulary.ts
951
- var CEAL_TERMINAL_DISPOSITIONS = vocabulary(["completed", "failed", "cancelled"]);
952
- var CEAL_LEASE_DISPOSITIONS = vocabulary([...CEAL_TERMINAL_DISPOSITIONS, "deferred"]);
953
- var CEAL_AUTOMATIC_FEEDBACK_INTENTS = vocabulary(["initial"]);
954
- var CEAL_LEASED_MESSAGE_DELIVERY_OPERATION_IDS = vocabulary(["message.send", "message.update", "message.delete"]);
953
+ // packages/ceal-client-protocol/src/resource-row.ts
954
+ var CEAL_RESOURCE_SEARCH_ORDERS = vocabulary(["relevance", "modified", "viewed", "created"]);
955
+ var CEAL_RESOURCE_SEARCH_DIRECTIONS = vocabulary(["ascending", "descending"]);
956
+ 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"]);
957
+ var CEAL_RESOURCE_TIME_BASES = vocabulary(["created", "modified", "viewed"]);
955
958
  var CEAL_REPOSITORY_VISIBILITIES = vocabulary(["public", "private", "internal"]);
956
- var CEAL_RESULT_DELIVERY_OFFERS = vocabulary(["pending", "offered", "transport_lost"]);
957
- var CEAL_RESULT_DELIVERY_STATES = vocabulary(["unavailable", ...CEAL_RESULT_DELIVERY_OFFERS]);
958
- var CEAL_PROVIDER_OUTCOMES = vocabulary(["not_attempted", "outcome_unknown", "verified"]);
959
+ var CEAL_ACTIVITY_V3_KINDS = vocabulary(["authored", "edited", "messaged", "responded"]);
960
+ var CEAL_ACTIVITY_TIMESTAMP_BASES = vocabulary([
961
+ "message_created",
962
+ "commit_authored",
963
+ "resource_created",
964
+ "review_submitted",
965
+ "comment_created",
966
+ "event_start",
967
+ "all_day_start",
968
+ "file_created",
969
+ "file_modified",
970
+ "file_modified_by_me",
971
+ "file_viewed_by_me",
972
+ "page_created",
973
+ "page_last_edited",
974
+ "resource_modified"
975
+ ]);
976
+ var CEAL_ACTIVITY_CONNECTOR_KINDS = vocabulary(["slack", "github", "google-calendar", "google-drive", "notion"]);
959
977
  var CEAL_ACTIVITY_GAP_CODES = vocabulary([
960
978
  "provider_page_budget",
961
979
  "call_deadline",
@@ -966,8 +984,6 @@ var CEAL_ACTIVITY_GAP_CODES = vocabulary([
966
984
  "unsupported_event_kind",
967
985
  "direct_messages_excluded"
968
986
  ]);
969
- var CEAL_ACTIVITY_CONNECTOR_KINDS = vocabulary(["slack", "github", "google-calendar", "google-drive", "notion"]);
970
- var CEAL_ACTIVITY_COVERAGE_STATUSES = vocabulary(["complete_for_target", "continuation_required", "blocked"]);
971
987
  var CEAL_ACTIVITY_EVENT_KINDS = vocabulary([
972
988
  "slack.message",
973
989
  "slack.reply",
@@ -1008,73 +1024,6 @@ var CEAL_ACTIVITY_EVENT_TIMESTAMP_BASIS_MAP = Object.freeze({
1008
1024
  "notion.page.created": "page_created",
1009
1025
  "notion.page.edited": "page_last_edited"
1010
1026
  });
1011
- var CEAL_ACTIVITY_TIMESTAMP_BASES = vocabulary([
1012
- "message_created",
1013
- "commit_authored",
1014
- "resource_created",
1015
- "review_submitted",
1016
- "comment_created",
1017
- "event_start",
1018
- "all_day_start",
1019
- "file_created",
1020
- "file_modified",
1021
- "file_modified_by_me",
1022
- "file_viewed_by_me",
1023
- "page_created",
1024
- "page_last_edited",
1025
- "resource_modified"
1026
- ]);
1027
- var CEAL_ACTIVITY_V3_KINDS = vocabulary(["authored", "edited", "messaged", "responded"]);
1028
- var CEAL_RESOURCE_TIME_BASES = vocabulary(["created", "modified", "viewed"]);
1029
- var CEAL_RESOURCE_SEARCH_ORDERS = vocabulary(["relevance", "modified", "viewed", "created"]);
1030
- var CEAL_RESOURCE_SEARCH_DIRECTIONS = vocabulary(["ascending", "descending"]);
1031
- var CEAL_RESOURCE_SEARCH_FILTERS = vocabulary(["query", "modified_since", "since", "until", "authored_by_me", "include_replies", "kinds", "container_ref", "container_refs", "container_names", "addressed_to_me", "unread"]);
1032
- var CEAL_ARTIFACT_STAGE_TERMINALS = vocabulary(["chunk_accepted", "artifact_ready", "idempotency_replayed"]);
1033
- var CEAL_READ_ITEM_KINDS = vocabulary(["conversation", "identity", "usergroup", "message", "file", "document"]);
1034
- var CEAL_LEASED_MESSAGE_SEARCH_COMPLETENESS = vocabulary(["complete", "continuation_available", "truncated"]);
1035
- var CEAL_OPAQUE_HANDLE_KINDS = vocabulary(["target", "message", "thread", "artifact", "document", "block", "object"]);
1036
- var CEAL_OPAQUE_REF_KINDS = vocabulary([...CEAL_OPAQUE_HANDLE_KINDS, "result", "operation-receipt", "reply-receipt", "field", "notion-data-source"]);
1037
- var CEAL_WRITE_OBJECT_KINDS = vocabulary(["document", "comment", "cell_range"]);
1038
- var CEAL_CONVERSATION_KINDS = vocabulary(["channel", "dm", "group"]);
1039
- var CEAL_FILE_TYPE_FAMILIES = vocabulary(["all", "image", "pdf"]);
1040
- var CEAL_GITHUB_ISSUE_STATES = vocabulary(["open", "closed", "all"]);
1041
- var CEAL_NOTION_UPDATABLE_BLOCK_TYPES = vocabulary([
1042
- "paragraph",
1043
- "heading_1",
1044
- "heading_2",
1045
- "heading_3",
1046
- "bulleted_list_item",
1047
- "numbered_list_item",
1048
- "to_do",
1049
- "code"
1050
- ]);
1051
- var CEAL_NOTION_NEUTRAL_TYPES = vocabulary([
1052
- "text",
1053
- "number",
1054
- "boolean",
1055
- "date",
1056
- "select",
1057
- "multi_select",
1058
- "people",
1059
- "url",
1060
- "email",
1061
- "phone",
1062
- "unsupported"
1063
- ]);
1064
- var CEAL_NOTION_IDENTITY_GAP_REASONS = vocabulary([
1065
- "identity_unavailable",
1066
- "identity_stale",
1067
- "identity_ambiguous",
1068
- "identity_revoked",
1069
- "identity_unlinked"
1070
- ]);
1071
- var CEAL_NOTION_STRING_VALUE_TYPES = vocabulary(["text", "select", "url", "email", "phone"]);
1072
- var CEAL_UNREAD_REASONS = vocabulary(["blocked", "unavailable", "too_large", "unsupported", "download_failed", "permission_denied"]);
1073
- var CEAL_PLAN_ITEM_STATUSES = vocabulary(["pending", "active", "completed"]);
1074
- var CEAL_FINAL_PRESENTATION_INTENTS = vocabulary(["final", "stop", "transient_notice"]);
1075
- var CEAL_PRESENTATION_INTENTS = vocabulary(["progress", ...CEAL_FINAL_PRESENTATION_INTENTS]);
1076
-
1077
- // packages/ceal-client-protocol/src/resource-row.ts
1078
1027
  var CEAL_DATED_NOTE_BASES = vocabulary(["recording", "calendar_event", "created_time"]);
1079
1028
  var CEAL_DATED_NOTE_TRANSCRIPT_STATES = vocabulary(["present", "absent", "unestablished"]);
1080
1029
  var CEAL_READ_SEARCH_COST_CLASSES = vocabulary(["native_index", "scan"]);
@@ -1083,6 +1032,7 @@ var RESOURCE_ROW_KEY_RULES = Object.freeze({
1083
1032
  ref: { required: true, timestamp: false },
1084
1033
  next: { required: true, timestamp: false },
1085
1034
  kind: { required: true, timestamp: false },
1035
+ matched_kinds: { required: false, timestamp: false },
1086
1036
  title: { required: true, timestamp: false },
1087
1037
  container_label: { required: true, timestamp: false },
1088
1038
  container_ref: { required: false, timestamp: false },
@@ -1159,17 +1109,6 @@ var CEAL_REFRESH_FAILURE_CODES = vocabulary([
1159
1109
  "refresh_recovery_expired"
1160
1110
  ]);
1161
1111
 
1162
- // packages/ceal-client-protocol/src/leased-artifact-contract.ts
1163
- var CEAL_LEASED_CONSUMER_ARTIFACT_CHUNK_MAX_BYTES = 12 * 1024;
1164
-
1165
- // packages/ceal-client-protocol/src/leased-resource-stream.ts
1166
- var CEAL_LEASED_CONSUMER_ATTACHMENT_STREAM_MAGIC = new Uint8Array([67, 69, 65, 76, 82, 83, 50, 0]);
1167
- var CEAL_LEASED_CONSUMER_ATTACHMENT_STREAM_RECORD_PREFIX_BYTES = 8;
1168
- var CEAL_LEASED_CONSUMER_ATTACHMENT_STREAM_MAX_HEADER_BYTES = 16 * 1024;
1169
- var CEAL_LEASED_CONSUMER_ATTACHMENT_STREAM_CHUNK_BYTES = 64 * 1024;
1170
- 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;
1171
- var CEAL_ATTACHMENT_UNREAD_REASONS = vocabulary(["blocked", "unavailable", "too_large", "unsupported", "download_failed", "digest_mismatch"]);
1172
-
1173
1112
  // packages/ceal-client-protocol/src/request-validation-primitives.ts
1174
1113
  import { createHash } from "node:crypto";
1175
1114
  var DIGEST = /^[a-f0-9]{64}$/u;
@@ -1336,6 +1275,10 @@ var CEAL_REQUEST_RUN_BATCH_JSON_SCHEMA = {
1336
1275
  };
1337
1276
 
1338
1277
  // packages/ceal-client-protocol/src/host-observation.ts
1278
+ var CEAL_HOST_INPUT_KINDS = vocabulary(["human", "host_automatic"]);
1279
+ function isCealHostInputKind(value) {
1280
+ return typeof value === "string" && CEAL_HOST_INPUT_KINDS.some((kind) => kind === value);
1281
+ }
1339
1282
  var CEAL_HOST_OBSERVATION_REF_PREFIX = "host-observation:";
1340
1283
  function validateCealHostObservationDraft(value) {
1341
1284
  const record6 = operationRecord(value, "Ceal Host observation draft is invalid.");
@@ -1392,12 +1335,6 @@ var OWNER_WRITE_STATES = Object.freeze(["attempt_started", "provider_acknowledge
1392
1335
  var OWNER_EFFECT_STATES = Object.freeze(["none", "applied", "failed", "unknown", "reconciled"]);
1393
1336
  var OWNER_RECEIPT_STATES = Object.freeze(["pending", "available", "failed", "unknown", "reconciled"]);
1394
1337
 
1395
- // packages/ceal-client-protocol/src/thread-excerpt.ts
1396
- var CEAL_THREAD_RECENT_WINDOW = 6;
1397
- var CEAL_THREAD_LAST_APP_MESSAGES_WINDOW = 3;
1398
- var CEAL_THREAD_OLDER_SUMMARY_WINDOW = 4;
1399
- var CEAL_FED_THREAD_MESSAGE_LIMIT = CEAL_THREAD_RECENT_WINDOW + CEAL_THREAD_OLDER_SUMMARY_WINDOW + CEAL_THREAD_LAST_APP_MESSAGES_WINDOW;
1400
-
1401
1338
  // packages/ceal-client-protocol/src/request-graph-readiness.ts
1402
1339
  var REQUEST_GRAPH_PRODUCER_TO_APPEND_SCHEMA = {
1403
1340
  type: "object",
@@ -1486,6 +1423,16 @@ var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_MAX_BYTES = new TextEncoder().enc
1486
1423
  expires_at: (/* @__PURE__ */ new Date("+010000-01-01T00:00:00.000Z")).toISOString()
1487
1424
  })}
1488
1425
  `).byteLength;
1426
+ var CEAL_HOST_MINT_REQUEST_CONTEXT_REFUSAL_REASONS = vocabulary([
1427
+ "request_authority_unavailable",
1428
+ "request_missing",
1429
+ "authority_mismatch",
1430
+ "host_source_mismatch",
1431
+ "host_session_mismatch",
1432
+ "host_turn_mismatch",
1433
+ "host_input_mismatch",
1434
+ "host_prompt_mismatch"
1435
+ ]);
1489
1436
  function decodeCealHostInvocationAuthenticationResult(value, now = /* @__PURE__ */ new Date()) {
1490
1437
  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)) {
1491
1438
  throw new TypeError("The Host invocation authentication result is invalid.");
@@ -1502,25 +1449,10 @@ function exactKeys(value, expected) {
1502
1449
  }
1503
1450
 
1504
1451
  // packages/ceal-client-protocol/src/client-result-materialization.ts
1452
+ var CEAL_UNREAD_REASONS = vocabulary(["blocked", "unavailable", "too_large", "unsupported", "download_failed", "permission_denied"]);
1505
1453
  var CEAL_MODEL_VISIBLE_COMMAND_OUTPUT_MAX_BYTES = 32 * 1024;
1506
- var REQUIRED_FIELDS2 = Object.freeze(["schema_version", "operation_id"]);
1507
- var FIELDS = /* @__PURE__ */ new Set([...REQUIRED_FIELDS2, "read_argv", "local_result_root", "continue_argv", "model_disclosure", "item_read_argv"]);
1508
-
1509
- // packages/ceal-client-protocol/src/session-start-affordance.ts
1510
- var CEAL_SESSION_ENTRY_INVOCATION = "ceal";
1511
- var CEAL_LINK_RESOURCE_PRECEDENCE = `When the user asks to use Ceal or provides a link to information that may be available through installed organizational capabilities, run bare \`${CEAL_SESSION_ENTRY_INVOCATION}\`. The Host supplies the current user prompt without exposing it to the client command, and the Gateway returns the applicable entry in that one response. Treat a supplied link as a candidate Ceal resource rather than a public web-search target. Reach for a generic web fetch or web search only when the Gateway offered nothing.`;
1512
-
1513
- // packages/ceal-client-protocol/src/conversation-contracts.ts
1514
- var CEAL_APPROVAL_POLICY_KINDS = vocabulary(["requester_only", "named_users", "role_based"]);
1515
- var CEAL_APPROVAL_TARGET_KINDS = vocabulary([
1516
- "repo_change",
1517
- "investigation",
1518
- "skill_creation",
1519
- "command_creation",
1520
- "connector_creation",
1521
- "generic"
1522
- ]);
1523
- var CEAL_PROGRESS_PHASES = vocabulary(["request_review", "information_gathering", "work_execution", "result_check"]);
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"]);
1524
1456
 
1525
1457
  // packages/ceal-client-protocol/src/gateway-cache-origin-validation.ts
1526
1458
  var CEAL_MAX_CACHE_ORIGIN_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
@@ -1731,7 +1663,7 @@ function assertHostRelaySourcePaths(stateRoot, config, platform = process.platfo
1731
1663
  // host/relay/src/host-relay-runtime.ts
1732
1664
  import { O_NOFOLLOW as O_NOFOLLOW3, O_RDONLY as O_RDONLY4 } from "node:constants";
1733
1665
  import { lstat as lstat4, open as open5 } from "node:fs/promises";
1734
- import { dirname as dirname3, join as join6 } from "node:path";
1666
+ import { dirname as dirname4, join as join7 } from "node:path";
1735
1667
 
1736
1668
  // host/abortable-wait.ts
1737
1669
  function waitForAbort(signal, milliseconds) {
@@ -1835,6 +1767,9 @@ var HostProducerFrameError = class extends Error {
1835
1767
  this.code = code;
1836
1768
  }
1837
1769
  };
1770
+ function assertHostProducerFrame(value) {
1771
+ validateFrame(value);
1772
+ }
1838
1773
  function encodeHostProducerFrame(frame) {
1839
1774
  validateFrame(frame);
1840
1775
  const json = Buffer.from(JSON.stringify(frame), "utf8");
@@ -1911,13 +1846,13 @@ function validTurn(value) {
1911
1846
  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);
1912
1847
  }
1913
1848
  function validInput(value) {
1914
- 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);
1849
+ return exactOptional(value, ["local_session_ref", "local_turn_ref", "local_input_ref", "input_kind", "origin_input", "observations"], ["local_turn_aliases", "context_expires_at"]) && safeRef(value.local_session_ref) && safeRef(value.local_turn_ref) && safeRef(value.local_input_ref) && validInputObservations(value.observations) && isCealHostInputKind(value.input_kind) && typeof value.origin_input === "boolean" && validInputOptionals(value);
1915
1850
  }
1916
1851
  function validInputObservations(value) {
1917
1852
  return validObservations(value) && Array.isArray(value) && value.filter((item) => record(item) && item.observation_kind === "prompt").length === 1;
1918
1853
  }
1919
1854
  function validInputOptionals(value) {
1920
- return validDecision(value.decision) && optionalRefs(value.local_turn_aliases) && (value.context_expires_at === void 0 || timestamp(value.context_expires_at));
1855
+ return optionalRefs(value.local_turn_aliases) && (value.context_expires_at === void 0 || timestamp(value.context_expires_at));
1921
1856
  }
1922
1857
  function validTerminal(value) {
1923
1858
  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);
@@ -1928,9 +1863,6 @@ function validTerminalDisposition(state, reason) {
1928
1863
  function validStatus(value) {
1929
1864
  return exactOptional(value, ["status", "reason_code"], ["detail"]) && ["ready", "degraded", "stopping"].includes(String(value.status)) && safeRef(value.reason_code) && optionalText(value.detail, 4096);
1930
1865
  }
1931
- function validDecision(value) {
1932
- return value === void 0 || record(value) && exactKeys2(value, ["decision", "approval_ref"]) && (value.decision === "approved" || value.decision === "denied") && safeRef(value.approval_ref);
1933
- }
1934
1866
  function optionalText(value, maxLength) {
1935
1867
  return value === void 0 || typeof value === "string" && value.length > 0 && value.length <= maxLength;
1936
1868
  }
@@ -2518,31 +2450,53 @@ var RelayAdmissionStore = class {
2518
2450
  for (const producerId of PRODUCER_ORDER) {
2519
2451
  const head = state.entries.find((entry2) => entry2.producer_id === producerId);
2520
2452
  if (!head || head.retry_at_ms > options.now_ms) continue;
2521
- const input = { frame: structuredClone(head.frame), host_source_ref: options.host_source_ref, submission_ref: hostProducerSubmissionRef(options.host_source_ref, head.frame) };
2522
- const outcome = await deliver(input);
2523
- const exhausted = retryExhausted(outcome, head);
2524
- if (outcome.status === "retryable" && !exhausted) {
2525
- scheduleRetry(head, options.now_ms, outcome.reason);
2526
- retained.push(input.submission_ref);
2527
- await this.write(state);
2528
- continue;
2529
- }
2530
- const installation2 = state.installations[installationKey(head.frame)];
2531
- if (!installation2) throw new TypeError("Host Relay delivery installation is unavailable.");
2532
- if (outcome.status === "refused" || exhausted) {
2533
- await this.quarantine.retainFrame(head.frame, "gateway_refused");
2534
- installation2.last_refusal = { sequence: head.sequence, submission_ref: input.submission_ref, ...refusalCause(outcome, head), refused_at_ms: options.now_ms };
2535
- refused.push(input.submission_ref);
2536
- } else {
2537
- await options.after_gateway_accept_before_delivery_fsync?.({ fault_point: "after_gateway_accept_before_delivery_fsync", delivery: structuredClone(input) });
2538
- delivered.push(input.submission_ref);
2539
- }
2540
- state.entries.splice(state.entries.indexOf(head), 1);
2541
- installation2.delivered_through_sequence = Math.max(installation2.delivered_through_sequence, head.sequence);
2542
- await this.write(state);
2453
+ if (await this.refusePoisonHead(state, head, options, refused)) continue;
2454
+ await this.deliverHead(state, head, deliver, options, delivered, retained, refused);
2543
2455
  }
2544
2456
  return { delivered, retained, refused };
2545
2457
  }
2458
+ async deliverHead(state, head, deliver, options, delivered, retained, refused) {
2459
+ const input = { frame: structuredClone(head.frame), host_source_ref: options.host_source_ref, submission_ref: hostProducerSubmissionRef(options.host_source_ref, head.frame) };
2460
+ const outcome = await deliver(input);
2461
+ const exhausted = retryExhausted(outcome, head);
2462
+ if (outcome.status === "retryable" && !exhausted) {
2463
+ scheduleRetry(head, options.now_ms, outcome.reason);
2464
+ retained.push(input.submission_ref);
2465
+ await this.write(state);
2466
+ return;
2467
+ }
2468
+ const installation2 = state.installations[installationKey(head.frame)];
2469
+ if (!installation2) throw new TypeError("Host Relay delivery installation is unavailable.");
2470
+ 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 };
2473
+ refused.push(input.submission_ref);
2474
+ } else {
2475
+ await options.after_gateway_accept_before_delivery_fsync?.({ fault_point: "after_gateway_accept_before_delivery_fsync", delivery: structuredClone(input) });
2476
+ delivered.push(input.submission_ref);
2477
+ }
2478
+ state.entries.splice(state.entries.indexOf(head), 1);
2479
+ installation2.delivered_through_sequence = Math.max(installation2.delivered_through_sequence, head.sequence);
2480
+ await this.write(state);
2481
+ }
2482
+ async refusePoisonHead(state, head, options, refused) {
2483
+ const poison = poisonFrameError(head.frame);
2484
+ if (poison === null) return false;
2485
+ const installation2 = state.installations[installationKey(head)];
2486
+ if (!hasIntactAdmissionEnvelope(head, installation2)) throw new TypeError("Host Relay admission state is invalid.");
2487
+ const json = Buffer.from(JSON.stringify(head.frame), "utf8");
2488
+ const raw = Buffer.allocUnsafe(json.byteLength + 4);
2489
+ raw.writeUInt32BE(json.byteLength, 0);
2490
+ json.copy(raw, 4);
2491
+ await this.quarantine.retainMalformed(raw, poison.code);
2492
+ const submissionRef = hostProducerSubmissionRef(options.host_source_ref, { producer_id: head.producer_id, producer_installation_ref: head.producer_installation_ref, sequence: head.sequence });
2493
+ installation2.last_refusal = { sequence: head.sequence, submission_ref: submissionRef, code: poison.code, message: `Host Relay persisted frame is invalid: ${poison.code}.`, refused_at_ms: options.now_ms };
2494
+ refused.push(submissionRef);
2495
+ state.entries.splice(state.entries.indexOf(head), 1);
2496
+ installation2.delivered_through_sequence = Math.max(installation2.delivered_through_sequence, head.sequence);
2497
+ await this.write(state);
2498
+ return true;
2499
+ }
2546
2500
  async read() {
2547
2501
  try {
2548
2502
  return decodeState3(JSON.parse(await readFile2(join4(this.root, "admission.json"), "utf8")));
@@ -2608,6 +2562,8 @@ function decodeState3(value) {
2608
2562
  const entries = [];
2609
2563
  for (const item of value.entries) {
2610
2564
  if (!entry(item)) throw new TypeError("Host Relay entry state is invalid.");
2565
+ poisonFrameError(item.frame);
2566
+ if (!hasIntactAdmissionEnvelope(item, installations[installationKey(item)])) throw new TypeError("Host Relay admission state is invalid.");
2611
2567
  entries.push(item);
2612
2568
  }
2613
2569
  return { schema_version: "ceal.host_relay_admission_state.v1", installations, entries };
@@ -2630,6 +2586,60 @@ function producer2(value) {
2630
2586
  function object(value) {
2631
2587
  return typeof value === "object" && value !== null && !Array.isArray(value);
2632
2588
  }
2589
+ function poisonFrameError(frame) {
2590
+ try {
2591
+ assertHostProducerFrame(frame);
2592
+ return null;
2593
+ } catch (error) {
2594
+ if (error instanceof HostProducerFrameError) return error;
2595
+ throw error;
2596
+ }
2597
+ }
2598
+ function hasIntactAdmissionEnvelope(entryValue, installation2) {
2599
+ if (installation2 === void 0) return false;
2600
+ return poisonIdentityValid(entryValue) && poisonEnvelopeMatches(entryValue, installation2) && poisonIntegrityMatches(entryValue) && poisonSequenceInRange(entryValue, installation2);
2601
+ }
2602
+ function poisonIdentityValid(entryValue) {
2603
+ if (entryValue.producer_id !== "codex" && entryValue.producer_id !== "claude") return false;
2604
+ if (!opaqueHostSourceRef(entryValue.producer_installation_ref)) return false;
2605
+ return Number.isSafeInteger(entryValue.sequence) && entryValue.sequence > 0;
2606
+ }
2607
+ function poisonEnvelopeMatches(entryValue, installation2) {
2608
+ const frame = entryValue.frame;
2609
+ if (!object(frame)) return false;
2610
+ return poisonEnvelopeSchema(frame) && poisonEnvelopeProducer(frame, entryValue) && poisonEnvelopeInstallation(frame, entryValue) && poisonEnvelopeEpoch(frame, installation2) && poisonEnvelopeSequence(frame, entryValue) && poisonEnvelopeKind(frame) && poisonEnvelopeTimestamp(frame);
2611
+ }
2612
+ function poisonEnvelopeSchema(frame) {
2613
+ return frame.schema_version === "ceal.host_producer_frame.v1";
2614
+ }
2615
+ function poisonEnvelopeProducer(frame, entryValue) {
2616
+ return producer2(frame.producer_id) && frame.producer_id === entryValue.producer_id;
2617
+ }
2618
+ function poisonEnvelopeInstallation(frame, entryValue) {
2619
+ return opaqueHostSourceRef(frame.producer_installation_ref) && frame.producer_installation_ref === entryValue.producer_installation_ref;
2620
+ }
2621
+ function poisonEnvelopeEpoch(frame, installation2) {
2622
+ return Number.isSafeInteger(frame.producer_epoch) && typeof frame.producer_epoch === "number" && frame.producer_epoch > 0 && frame.producer_epoch <= installation2.epoch;
2623
+ }
2624
+ function poisonEnvelopeSequence(frame, entryValue) {
2625
+ return Number.isSafeInteger(frame.sequence) && frame.sequence === entryValue.sequence;
2626
+ }
2627
+ function poisonEnvelopeKind(frame) {
2628
+ return isHostProducerFrameKind(frame.frame_kind);
2629
+ }
2630
+ function poisonEnvelopeTimestamp(frame) {
2631
+ return typeof frame.occurred_at === "string" && Number.isFinite(Date.parse(frame.occurred_at));
2632
+ }
2633
+ function poisonIntegrityMatches(entryValue) {
2634
+ const frame = entryValue.frame;
2635
+ if (!object(frame)) return false;
2636
+ const json = JSON.stringify(frame);
2637
+ return entryValue.charged_bytes === 4 + Buffer.byteLength(json, "utf8") && entryValue.hash === hostProducerFrameHash(entryValue.frame);
2638
+ }
2639
+ function poisonSequenceInRange(entryValue, installation2) {
2640
+ if (entryValue.sequence <= installation2.delivered_through_sequence) return false;
2641
+ return entryValue.sequence <= installation2.admitted_through_sequence;
2642
+ }
2633
2643
 
2634
2644
  // host/relay/src/relay-gateway-bridge.ts
2635
2645
  import { readFile as readFile3 } from "node:fs/promises";
@@ -2693,6 +2703,8 @@ var RelayGatewayBridge = class {
2693
2703
  }
2694
2704
  async deliverInput(state, input) {
2695
2705
  const prepared = prepareInput(state, input, this.hostSourceRef);
2706
+ const priorRefusal = refusedUnboundInput(prepared.turn);
2707
+ if (priorRefusal !== void 0) return priorRefusal;
2696
2708
  const outcome = await this.submit(prepared.submission);
2697
2709
  if ("refusal" in outcome) {
2698
2710
  if (outcome.refusal.definitive && prepared.turn !== void 0) await this.writeState({ ...state, turns: { ...state.turns, [prepared.refs.host_turn_ref]: { ...prepared.turn, input_refused: { code: outcome.refusal.code, message: outcome.refusal.message } } } });
@@ -2701,14 +2713,18 @@ var RelayGatewayBridge = class {
2701
2713
  const acknowledgement2 = outcome.acknowledgement;
2702
2714
  const nextTurn = bindInput(prepared, acknowledgement2.request_ref, input.submission_ref);
2703
2715
  await this.writeState({ ...state, turns: { ...state.turns, [prepared.refs.host_turn_ref]: nextTurn } });
2704
- const binding = { frame: structuredClone(input.frame), request_ref: acknowledgement2.request_ref, prompt_ref: prepared.promptRef, host_binding: {
2716
+ if (!bindsOriginInput(prepared)) return { status: "created" };
2717
+ const bindingRequestRef = nextTurn.request_ref ?? acknowledgement2.request_ref;
2718
+ const bindingPromptRef = nextTurn.prompt_ref ?? prepared.promptRef;
2719
+ const bindingInputRef = nextTurn.origin_host_input_ref ?? prepared.hostInputRef;
2720
+ const binding = { frame: structuredClone(input.frame), request_ref: bindingRequestRef, prompt_ref: bindingPromptRef, host_binding: {
2705
2721
  host_source_ref: prepared.submission.identity.host_source_ref,
2706
2722
  host_session_ref: prepared.submission.identity.host_session_ref,
2707
2723
  host_turn_ref: prepared.submission.identity.host_turn_ref,
2708
- host_input_ref: prepared.hostInputRef,
2709
- prompt_ref: prepared.promptRef
2724
+ host_input_ref: bindingInputRef,
2725
+ prompt_ref: bindingPromptRef
2710
2726
  } };
2711
- const context = createRelayRequestWorkContext({ request_ref: acknowledgement2.request_ref, host_binding: binding.host_binding });
2727
+ const context = createRelayRequestWorkContext({ request_ref: bindingRequestRef, host_binding: binding.host_binding });
2712
2728
  try {
2713
2729
  await this.onRequestBound(binding, context);
2714
2730
  } catch (error) {
@@ -2728,6 +2744,7 @@ var RelayGatewayBridge = class {
2728
2744
  const outcome = await this.submit({
2729
2745
  identity: { host_source_ref: this.hostSourceRef, host_session_ref: refs.host_session_ref, host_turn_ref: refs.host_turn_ref },
2730
2746
  host_input_ref: turn.origin_host_input_ref,
2747
+ input_kind: "host_automatic",
2731
2748
  prompt_ref: turn.prompt_ref,
2732
2749
  observations: payloadObservations(input.frame),
2733
2750
  request_ref: turn.request_ref,
@@ -2789,9 +2806,9 @@ function prepareInput(state, input, hostSourceRef) {
2789
2806
  const submission = compactSubmission({
2790
2807
  identity: { host_source_ref: hostSourceRef, host_session_ref: refs.host_session_ref, host_turn_ref: refs.host_turn_ref },
2791
2808
  host_input_ref: hostInputRef,
2809
+ input_kind: payloadInputKind(input.frame),
2792
2810
  prompt_ref: promptRef,
2793
2811
  observations,
2794
- decision: payloadDecision(input.frame),
2795
2812
  request_ref: turn?.request_ref,
2796
2813
  submission_ref: input.submission_ref
2797
2814
  });
@@ -2802,11 +2819,18 @@ function bindInput(prepared, requestRef, submissionRef) {
2802
2819
  host_session_ref: prepared.refs.host_session_ref,
2803
2820
  observations: prepared.turn?.observations ?? [],
2804
2821
  submission_ref: prepared.turn?.submission_ref ?? submissionRef,
2805
- request_ref: requestRef,
2806
- prompt_ref: prepared.promptRef,
2822
+ request_ref: prepared.turn?.request_ref ?? requestRef,
2823
+ prompt_ref: prepared.turn?.prompt_ref ?? prepared.promptRef,
2807
2824
  origin_host_input_ref: prepared.turn?.origin_host_input_ref ?? prepared.hostInputRef
2808
2825
  };
2809
2826
  }
2827
+ function refusedUnboundInput(turn) {
2828
+ if (turn?.request_ref !== void 0 || turn?.input_refused === void 0) return void 0;
2829
+ return { status: "refused", code: "origin_input_refused", message: `The input frame names a turn whose origin input was refused (${turn.input_refused.code}: ${turn.input_refused.message}).` };
2830
+ }
2831
+ function bindsOriginInput(prepared) {
2832
+ return prepared.turn?.request_ref === void 0 || prepared.turn.origin_host_input_ref === prepared.hostInputRef;
2833
+ }
2810
2834
  function payloadRef(frame, key) {
2811
2835
  const value = frame.payload[key];
2812
2836
  if (typeof value !== "string" || !SAFE_REF4.test(value)) throw new TypeError("Host Relay frame reference is invalid.");
@@ -2820,16 +2844,17 @@ function payloadPromptDigest(frame) {
2820
2844
  function payloadObservations(frame) {
2821
2845
  return Array.isArray(frame.payload.observations) ? frame.payload.observations.filter(isObservation) : [];
2822
2846
  }
2823
- function payloadDecision(frame) {
2824
- const value = frame.payload.decision;
2825
- return isRecord(value) && (value.decision === "approved" || value.decision === "denied") && typeof value.approval_ref === "string" ? { decision: value.decision, approval_ref: value.approval_ref } : void 0;
2847
+ function payloadInputKind(frame) {
2848
+ const value = frame.payload.input_kind;
2849
+ if (!isCealHostInputKind(value)) throw new TypeError("Host Relay input kind is invalid.");
2850
+ return value;
2826
2851
  }
2827
2852
  function uniqueObservations(values) {
2828
2853
  const seen = /* @__PURE__ */ new Set();
2829
2854
  return values.filter((value) => !seen.has(value.observation_ref) && Boolean(seen.add(value.observation_ref)));
2830
2855
  }
2831
2856
  function compactSubmission(value) {
2832
- return { identity: value.identity, host_input_ref: value.host_input_ref, prompt_ref: value.prompt_ref, observations: value.observations, submission_ref: value.submission_ref, ...value.decision === void 0 ? {} : { decision: value.decision }, ...value.request_ref === void 0 ? {} : { request_ref: value.request_ref } };
2857
+ return { identity: value.identity, host_input_ref: value.host_input_ref, input_kind: value.input_kind, prompt_ref: value.prompt_ref, observations: value.observations, submission_ref: value.submission_ref, ...value.request_ref === void 0 ? {} : { request_ref: value.request_ref } };
2833
2858
  }
2834
2859
  function isObservation(value) {
2835
2860
  try {
@@ -2895,6 +2920,7 @@ import { dirname as dirname2 } from "node:path";
2895
2920
  // host/gateway-http.ts
2896
2921
  var SAFE_HOST_REF = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
2897
2922
  function hostIngressBody(input, invalidEventTime) {
2923
+ if (!isCealHostInputKind(input.input_kind)) throw new TypeError("Host ingress input kind is invalid.");
2898
2924
  const prompt = input.observations.find((observation) => observation.observation_kind === "prompt");
2899
2925
  const observedAt = prompt?.observed_at ?? input.observations[0]?.observed_at;
2900
2926
  if (observedAt === void 0 || !Number.isFinite(Date.parse(observedAt))) throw invalidEventTime();
@@ -2904,11 +2930,11 @@ function hostIngressBody(input, invalidEventTime) {
2904
2930
  host_session_ref: input.identity.host_session_ref,
2905
2931
  host_turn_ref: input.identity.host_turn_ref,
2906
2932
  host_input_ref: input.host_input_ref,
2933
+ input_kind: input.input_kind,
2907
2934
  prompt_ref: input.prompt_ref,
2908
2935
  observed_at: observedAt,
2909
2936
  observations: input.observations,
2910
- ...input.request_ref === void 0 ? {} : { request_ref: input.request_ref },
2911
- ...input.decision === void 0 ? {} : { decision: input.decision.decision, approval_ref: input.decision.approval_ref }
2937
+ ...input.request_ref === void 0 ? {} : { request_ref: input.request_ref }
2912
2938
  };
2913
2939
  }
2914
2940
  async function responseJson(response2, invalidResponse2) {
@@ -2958,20 +2984,29 @@ var HostRelayGatewayError = class extends Error {
2958
2984
  status;
2959
2985
  /** The Gateway's own refusal word, when it named one; a bounded token, never its message. */
2960
2986
  error_code;
2961
- constructor(code, message, status, errorCode9) {
2987
+ /** The Gateway mint refusal's bounded continuity reason, when it named one; a fixed token, never its message. */
2988
+ refusal_reason;
2989
+ constructor(code, message, status, errorCode9, refusalReason) {
2962
2990
  super(message);
2963
2991
  this.code = code;
2964
2992
  if (status !== void 0) this.status = status;
2965
2993
  if (errorCode9 !== void 0) this.error_code = errorCode9;
2994
+ if (refusalReason !== void 0) this.refusal_reason = refusalReason;
2966
2995
  }
2967
2996
  };
2968
2997
  var GATEWAY_REFUSAL_CODE_PATTERN = /^[a-z][a-z0-9_]{0,63}$/u;
2969
- async function gatewayRefusalCode(response2) {
2998
+ async function gatewayRefusal(response2) {
2970
2999
  try {
2971
3000
  const body = await response2.json();
2972
- return isCealJsonRecord(body) && typeof body.error_code === "string" && GATEWAY_REFUSAL_CODE_PATTERN.test(body.error_code) ? body.error_code : void 0;
3001
+ if (!isCealJsonRecord(body)) return {};
3002
+ const code = typeof body.error_code === "string" && GATEWAY_REFUSAL_CODE_PATTERN.test(body.error_code) ? body.error_code : void 0;
3003
+ const reason = code === "request_context_refused" && typeof body.reason === "string" && GATEWAY_REFUSAL_CODE_PATTERN.test(body.reason) && isVocabularyWord(CEAL_HOST_MINT_REQUEST_CONTEXT_REFUSAL_REASONS, body.reason) ? body.reason : void 0;
3004
+ return {
3005
+ ...code === void 0 ? {} : { code },
3006
+ ...reason === void 0 ? {} : { reason }
3007
+ };
2973
3008
  } catch {
2974
- return void 0;
3009
+ return {};
2975
3010
  }
2976
3011
  }
2977
3012
  function refusalMessage(status, body) {
@@ -3019,7 +3054,10 @@ function createHostRelayGatewayHttpPort(options) {
3019
3054
  } catch {
3020
3055
  throw new HostRelayGatewayError("gateway_unavailable", "Gateway Host invocation context is unavailable.");
3021
3056
  }
3022
- if (!response2.ok) throw new HostRelayGatewayError(response2.status === 401 ? "credential" : "gateway_refused", `Gateway Host invocation context was refused (${response2.status}).`, response2.status, await gatewayRefusalCode(response2));
3057
+ if (!response2.ok) {
3058
+ const refusal = await gatewayRefusal(response2);
3059
+ throw new HostRelayGatewayError(response2.status === 401 ? "credential" : "gateway_refused", `Gateway Host invocation context was refused (${response2.status}).`, response2.status, refusal.code, refusal.reason);
3060
+ }
3023
3061
  let value;
3024
3062
  try {
3025
3063
  value = await response2.json();
@@ -3140,8 +3178,9 @@ function acknowledgement(value) {
3140
3178
  }
3141
3179
 
3142
3180
  // host/relay/src/relay-ipc.ts
3143
- import { chmod, lstat as lstat3, unlink as unlink2 } from "node:fs/promises";
3181
+ import { chmod, lstat as lstat3, rename as rename2, unlink as unlink2 } from "node:fs/promises";
3144
3182
  import { createConnection, createServer } from "node:net";
3183
+ import { dirname as dirname3, join as join6 } from "node:path";
3145
3184
 
3146
3185
  // host/relay/src/current-prompt-custody.ts
3147
3186
  import { createHash as createHash5 } from "node:crypto";
@@ -3222,7 +3261,15 @@ var HOST_RELAY_INVOCATION_MINT_REFUSAL_REASONS = vocabulary([
3222
3261
  "deadline",
3223
3262
  "cancelled",
3224
3263
  "mint_failed",
3225
- "relay_failed"
3264
+ "relay_failed",
3265
+ "request_authority_unavailable",
3266
+ "request_missing",
3267
+ "authority_mismatch",
3268
+ "host_source_mismatch",
3269
+ "host_session_mismatch",
3270
+ "host_turn_mismatch",
3271
+ "host_input_mismatch",
3272
+ "host_prompt_mismatch"
3226
3273
  ]);
3227
3274
  var HostRelayInvocationMintRefusal = class extends Error {
3228
3275
  reason;
@@ -3254,15 +3301,42 @@ var HostRelayIpcError = class extends Error {
3254
3301
  }
3255
3302
  };
3256
3303
  async function startHostRelayIpcServer(options) {
3257
- await assertEndpointVacant(options.endpoint);
3258
- const active = /* @__PURE__ */ new Map();
3259
- const sockets = /* @__PURE__ */ new Set();
3260
- const quarantine = options.quarantine ?? options.admission.quarantine;
3261
- const currentPrompts = options.currentPrompts ?? new HostCurrentPromptCustody();
3262
- const server = createServer((socket) => serveSocket(socket, options, currentPrompts, quarantine, active, sockets));
3263
- await listen(server, options.endpoint);
3264
- if (process.platform !== "win32") await chmod(options.endpoint, 384);
3265
- return { endpoint: options.endpoint, close: () => closeServer(server, sockets, options.endpoint) };
3304
+ return withRelayEndpointLock(options.endpoint, async () => {
3305
+ if (process.platform === "win32") {
3306
+ await assertEndpointVacant(options.endpoint);
3307
+ } else {
3308
+ await assertTrustedEndpointParent(options.endpoint);
3309
+ await removeStaleRelayEndpoint(options.endpoint, options.testHooks);
3310
+ }
3311
+ const active = /* @__PURE__ */ new Map();
3312
+ const sockets = /* @__PURE__ */ new Set();
3313
+ const quarantine = options.quarantine ?? options.admission.quarantine;
3314
+ const currentPrompts = options.currentPrompts ?? new HostCurrentPromptCustody();
3315
+ const server = createServer((socket) => serveSocket(socket, options, currentPrompts, quarantine, active, sockets));
3316
+ if (process.platform === "win32") {
3317
+ try {
3318
+ await listen(server, options.endpoint);
3319
+ } catch (error) {
3320
+ await abandonRelayServer(server, sockets);
3321
+ throw error;
3322
+ }
3323
+ return { endpoint: options.endpoint, close: () => closeServer(server, sockets, options.endpoint) };
3324
+ }
3325
+ const staging = stagingRelayEndpoint(options.endpoint);
3326
+ await listenStagingRelayEndpoint(server, sockets, staging);
3327
+ let owned;
3328
+ try {
3329
+ await options.testHooks?.beforeCaptureOwnedEndpoint?.(options.endpoint);
3330
+ owned = await readStagingRelayEndpointIdentity(staging);
3331
+ await chmod(staging, 384);
3332
+ const identity = await publishStagingRelayEndpoint(staging, owned, options.endpoint);
3333
+ return { endpoint: options.endpoint, close: () => closeRelayServer(server, sockets, options.endpoint, identity, options.testHooks) };
3334
+ } catch (error) {
3335
+ if (owned !== void 0) await releaseOwnedRelayEndpoint(server, sockets, options.endpoint, owned);
3336
+ else await abandonRelayServer(server, sockets);
3337
+ throw error;
3338
+ }
3339
+ });
3266
3340
  }
3267
3341
  function encodeHostRelayIpcResponse(response2) {
3268
3342
  const body = Buffer.from(JSON.stringify(response2), "utf8");
@@ -3424,8 +3498,9 @@ function writeCurrentPromptResponse(socket, status) {
3424
3498
  async function resolveInvocationContext(request2, admission, bindings, currentPrompts, mint, signal) {
3425
3499
  if (mint === void 0) throw new HostRelayIpcError("relay_unavailable");
3426
3500
  const query = bindingQueryFromRequest(request2);
3501
+ const expectedSequences = pendingAdmissionSequences(await admission.snapshot(), query);
3427
3502
  const binding = await waitForRequestBinding(query, admission, bindings, signal);
3428
- if (binding.status !== "ready") return { schema_version: HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA, status: "no_binding" };
3503
+ if (binding.status !== "ready") return unboundInvocationContextRefusal(await admission.snapshot(), query, expectedSequences) ?? { schema_version: HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA, status: "no_binding" };
3429
3504
  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 });
3430
3505
  let result2;
3431
3506
  try {
@@ -3435,6 +3510,24 @@ async function resolveInvocationContext(request2, admission, bindings, currentPr
3435
3510
  }
3436
3511
  return { schema_version: HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA, status: "ready", result: result2 };
3437
3512
  }
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" };
3518
+ }
3519
+ function pendingAdmissionSequences(snapshot, query) {
3520
+ const sequences = [];
3521
+ 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;
3527
+ sequences.push(entry2.sequence);
3528
+ }
3529
+ return sequences;
3530
+ }
3438
3531
  async function waitForRequestBinding(query, admission, bindings, signal) {
3439
3532
  let binding = await bindings.query(query);
3440
3533
  if (binding.status === "ready") return binding;
@@ -3610,6 +3703,160 @@ async function closeServer(server, sockets, endpoint) {
3610
3703
  await new Promise((resolve) => server.close(() => resolve()));
3611
3704
  if (process.platform !== "win32") await unlink2(endpoint).catch(() => void 0);
3612
3705
  }
3706
+ var relayEndpointLocks = /* @__PURE__ */ new Map();
3707
+ function withRelayEndpointLock(endpoint, run) {
3708
+ const prior = relayEndpointLocks.get(endpoint) ?? Promise.resolve();
3709
+ let release;
3710
+ const gate = new Promise((resolve) => {
3711
+ release = resolve;
3712
+ });
3713
+ const tail = prior.then(() => gate);
3714
+ relayEndpointLocks.set(endpoint, tail);
3715
+ return prior.then(run).finally(() => {
3716
+ release?.();
3717
+ if (relayEndpointLocks.get(endpoint) === tail) relayEndpointLocks.delete(endpoint);
3718
+ });
3719
+ }
3720
+ function currentUid(fallback) {
3721
+ return typeof process.geteuid === "function" ? process.geteuid() : fallback;
3722
+ }
3723
+ async function assertTrustedEndpointParent(endpoint) {
3724
+ const parent = dirname3(endpoint);
3725
+ let stats;
3726
+ try {
3727
+ stats = await lstat3(parent);
3728
+ } catch {
3729
+ throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC endpoint parent is unavailable; leaving it untouched.");
3730
+ }
3731
+ if (!stats.isDirectory() || stats.uid !== currentUid(stats.uid) || (stats.mode & 63) !== 0) throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC endpoint parent is not an owner-private directory; leaving it untouched.");
3732
+ }
3733
+ var HOST_RELAY_ENDPOINT_PROBE_TIMEOUT_MS = 1e3;
3734
+ function probeRelayEndpoint(endpoint) {
3735
+ return new Promise((resolve) => {
3736
+ let settled = false;
3737
+ const socket = createConnection(endpoint);
3738
+ const finish = (outcome) => {
3739
+ if (settled) return;
3740
+ settled = true;
3741
+ clearTimeout(timer);
3742
+ socket.destroy();
3743
+ resolve(outcome);
3744
+ };
3745
+ const timer = setTimeout(() => finish("ambiguous"), HOST_RELAY_ENDPOINT_PROBE_TIMEOUT_MS);
3746
+ timer.unref?.();
3747
+ socket.once("connect", () => finish("live"));
3748
+ socket.once("error", (error) => {
3749
+ const code = errorCode8(error);
3750
+ if (code === "ECONNREFUSED") finish("stale");
3751
+ else if (code === "ENOENT") finish("missing");
3752
+ else finish("ambiguous");
3753
+ });
3754
+ });
3755
+ }
3756
+ async function removeStaleRelayEndpoint(endpoint, testHooks) {
3757
+ const observed = await readEndpointStats(endpoint);
3758
+ if (observed === null) return;
3759
+ if (!observed.isSocket()) throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC endpoint is already present and is not a socket; leaving it untouched.");
3760
+ if (observed.uid !== currentUid(observed.uid)) throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC endpoint is not owned by the current uid; leaving it untouched.");
3761
+ const captured = { uid: observed.uid, dev: observed.dev, ino: observed.ino };
3762
+ await requireStaleEndpoint(endpoint);
3763
+ await testHooks?.beforeRemoveStaleEndpoint?.(endpoint);
3764
+ const current = await readEndpointStats(endpoint);
3765
+ if (current === null) return;
3766
+ requireSameEndpointIdentity(current, captured, "Host Relay IPC endpoint changed before cleanup; leaving it untouched.");
3767
+ await unlinkRelayEndpoint(endpoint);
3768
+ }
3769
+ async function requireStaleEndpoint(endpoint) {
3770
+ switch (await probeRelayEndpoint(endpoint)) {
3771
+ case "missing":
3772
+ case "stale":
3773
+ return;
3774
+ case "live":
3775
+ throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC endpoint is already served by a live Relay; leaving it untouched.");
3776
+ case "ambiguous":
3777
+ throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC endpoint liveness is ambiguous; leaving it untouched.");
3778
+ }
3779
+ }
3780
+ async function readEndpointStats(endpoint) {
3781
+ try {
3782
+ return await lstat3(endpoint);
3783
+ } catch (error) {
3784
+ if (errorCode8(error) === "ENOENT") return null;
3785
+ throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC endpoint identity is ambiguous; leaving it untouched.");
3786
+ }
3787
+ }
3788
+ function requireSameEndpointIdentity(current, owned, message) {
3789
+ if (!current.isSocket() || current.uid !== owned.uid || current.dev !== owned.dev || current.ino !== owned.ino) throw new HostRelayIpcError("relay_unavailable", message);
3790
+ }
3791
+ async function unlinkRelayEndpoint(endpoint) {
3792
+ try {
3793
+ await unlink2(endpoint);
3794
+ } catch (error) {
3795
+ if (errorCode8(error) !== "ENOENT") throw error;
3796
+ }
3797
+ }
3798
+ var relayStagingSequence = 0;
3799
+ function stagingRelayEndpoint(canonical) {
3800
+ const parent = dirname3(canonical);
3801
+ const pid = process.pid.toString(36);
3802
+ const sequence = (relayStagingSequence++ % (36 * 36)).toString(36);
3803
+ return join6(parent, `.r${pid}${sequence}`);
3804
+ }
3805
+ async function readStagingRelayEndpointIdentity(staging) {
3806
+ let created;
3807
+ try {
3808
+ created = await lstat3(staging);
3809
+ } catch {
3810
+ throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC endpoint is unavailable after listen; leaving it untouched.");
3811
+ }
3812
+ if (!created.isSocket()) throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC endpoint was replaced before this server listened; leaving it untouched.");
3813
+ if (created.uid !== currentUid(created.uid)) throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC endpoint is not owned by the current uid after listen; leaving it untouched.");
3814
+ return { uid: created.uid, dev: created.dev, ino: created.ino };
3815
+ }
3816
+ async function listenStagingRelayEndpoint(server, sockets, staging) {
3817
+ try {
3818
+ await listen(server, staging);
3819
+ } catch (error) {
3820
+ await abandonRelayServer(server, sockets);
3821
+ throw error;
3822
+ }
3823
+ }
3824
+ async function publishStagingRelayEndpoint(staging, owned, canonical) {
3825
+ const incumbent = await readEndpointStats(canonical);
3826
+ if (incumbent !== null) throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC endpoint was replaced before this server listened; leaving it untouched.");
3827
+ await rename2(staging, canonical);
3828
+ const published = await readEndpointStats(canonical);
3829
+ if (published === null) throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC endpoint is unavailable after listen; leaving it untouched.");
3830
+ requireSameEndpointIdentity(published, owned, "Host Relay IPC endpoint was replaced before this server listened; leaving it untouched.");
3831
+ return { uid: published.uid, dev: published.dev, ino: published.ino };
3832
+ }
3833
+ async function releaseOwnedRelayEndpoint(server, sockets, endpoint, owned) {
3834
+ await abandonRelayServer(server, sockets);
3835
+ try {
3836
+ const current = await readEndpointStats(endpoint);
3837
+ if (current === null) return;
3838
+ requireSameEndpointIdentity(current, owned, "Host Relay IPC endpoint changed while releasing a failed startup; leaving it untouched.");
3839
+ await unlinkRelayEndpoint(endpoint);
3840
+ } catch {
3841
+ }
3842
+ }
3843
+ async function closeRelayServer(server, sockets, endpoint, owned, testHooks) {
3844
+ await withRelayEndpointLock(endpoint, async () => {
3845
+ for (const socket of sockets) socket.destroy();
3846
+ await new Promise((resolve) => server.close(() => resolve()));
3847
+ await testHooks?.beforeRemoveOwnedEndpoint?.(endpoint);
3848
+ const current = await readEndpointStats(endpoint);
3849
+ if (current === null) return;
3850
+ requireSameEndpointIdentity(current, owned, "Host Relay IPC endpoint was replaced after this server listened; leaving it untouched.");
3851
+ await unlinkRelayEndpoint(endpoint);
3852
+ });
3853
+ }
3854
+ async function abandonRelayServer(server, sockets) {
3855
+ for (const socket of sockets) socket.destroy();
3856
+ await new Promise((resolve) => {
3857
+ server.close(() => resolve());
3858
+ });
3859
+ }
3613
3860
  function errorCode8(error) {
3614
3861
  return record4(error) && typeof error.code === "string" ? error.code : null;
3615
3862
  }
@@ -3631,7 +3878,7 @@ async function readHostRelayConfig(path) {
3631
3878
  if (!isAbsoluteNormalizedNonRootPath(path, process.platform, true)) throw new HostRelayConfigError("invalid_config_path", `invalid_config_path: Host Relay config path is invalid: ${refusalFact("config_path", path, "absolute, normalized, and non-root")}.`);
3632
3879
  let handle;
3633
3880
  try {
3634
- await assertOwnerPrivateDirectory2(dirname3(path));
3881
+ await assertOwnerPrivateDirectory2(dirname4(path));
3635
3882
  handle = await open5(path, O_RDONLY4 | O_NOFOLLOW3);
3636
3883
  const stats = await handle.stat();
3637
3884
  if (!stats.isFile() || !ownerPrivate4(stats)) throw new HostRelayConfigError("config_not_private", "Host Relay config file is not owner-private.");
@@ -3656,7 +3903,7 @@ async function readHostRelayConfig(path) {
3656
3903
  }
3657
3904
  function validateHostRelaySourcePaths(config) {
3658
3905
  try {
3659
- assertHostRelaySourcePaths(dirname3(config.registration_state_file), config);
3906
+ assertHostRelaySourcePaths(dirname4(config.registration_state_file), config);
3660
3907
  } catch (error) {
3661
3908
  throw new HostRelayConfigError("invalid_config", error instanceof Error ? error.message : "Host Relay source tuple is invalid.");
3662
3909
  }
@@ -3686,10 +3933,10 @@ function validConfigRuntime(value) {
3686
3933
  var HOST_RELAY_INVOCATION_MINT_LOG_TAG = "[host-relay-invocation-mint]";
3687
3934
  var HOST_RELAY_INVOCATION_MINT_LINE = new RegExp(`^${HOST_RELAY_INVOCATION_MINT_LOG_TAG.replace(/[[\]]/gu, "\\$&")} outcome=([a-z_]+)(?: reason=([a-z][a-z0-9_]{0,63}))? elapsed_ms=[0-9]+$`, "u");
3688
3935
  async function serveHostRelay(config, signal, dependencies = {}) {
3689
- const admission = new RelayAdmissionStore(join6(config.state_root, "admission"));
3690
- const bindings = new RelayRequestBindingStore(join6(config.state_root, "bindings"));
3936
+ const admission = new RelayAdmissionStore(join7(config.state_root, "admission"));
3937
+ const bindings = new RelayRequestBindingStore(join7(config.state_root, "bindings"));
3691
3938
  const gateway = (dependencies.createGateway ?? createHostRelayGatewayHttpPort)({ registration_state_file: config.registration_state_file, host_source_ref: config.host_source_ref });
3692
- const bridge = new RelayGatewayBridge({ state_root: join6(config.state_root, "gateway"), host_source_ref: config.host_source_ref, gateway, timeout_ms: config.gateway_timeout_ms, on_request_bound: async (binding) => {
3939
+ const bridge = new RelayGatewayBridge({ state_root: join7(config.state_root, "gateway"), host_source_ref: config.host_source_ref, gateway, timeout_ms: config.gateway_timeout_ms, on_request_bound: async (binding) => {
3693
3940
  await bindings.bind(binding);
3694
3941
  } });
3695
3942
  let server;
@@ -3730,7 +3977,11 @@ function invocationMintRefusalReason(error, cancellation) {
3730
3977
  if (error.code === "gateway_unavailable") return "gateway_unavailable";
3731
3978
  if (error.code === "invalid_response") return "gateway_response_invalid";
3732
3979
  if (error.code !== "gateway_refused") return "mint_failed";
3733
- return (error.error_code === void 0 ? void 0 : GATEWAY_MINT_REFUSAL_REASONS.get(error.error_code)) ?? "gateway_refused";
3980
+ return gatewayMintRefusalReason(error);
3981
+ }
3982
+ function gatewayMintRefusalReason(error) {
3983
+ if (error.error_code === "request_context_refused" && isVocabularyWord(CEAL_HOST_MINT_REQUEST_CONTEXT_REFUSAL_REASONS, error.refusal_reason)) return error.refusal_reason;
3984
+ return GATEWAY_MINT_REFUSAL_REASONS.get(error.error_code ?? "") ?? "gateway_refused";
3734
3985
  }
3735
3986
  var GATEWAY_MINT_REFUSAL_REASONS = /* @__PURE__ */ new Map([
3736
3987
  ["request_context_refused", "context_stale"],