@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.
- package/bin/ceal-host +0 -0
- package/libexec/ceal-host/claude-hook.mjs +2041 -514
- package/libexec/ceal-host/claude-invocation-authentication.mjs +1899 -330
- package/libexec/ceal-host/claude-producer.mjs +1860 -406
- package/libexec/ceal-host/codex-hook.mjs +1618 -1013
- package/libexec/ceal-host/codex-invocation-authentication.mjs +3222 -505
- package/libexec/ceal-host/codex-producer.mjs +1126 -581
- package/libexec/ceal-host/control.mjs +2857 -1134
- package/libexec/ceal-host/relay.mjs +559 -116
- package/package.json +1 -1
- package/share/ceal-host/bundle-manifest.json +12 -12
- package/share/ceal-host/bundle-manifest.sigstore.json +1 -1
|
@@ -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
|
|
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", "
|
|
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.
|
|
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
|
-
|
|
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:
|
|
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
|
|
1454
|
-
var
|
|
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) ||
|
|
2333
|
-
return
|
|
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
|
-
|
|
2472
|
-
|
|
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
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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.#
|
|
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 &&
|
|
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 =
|
|
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
|
-
|
|
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
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
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
|
-
|
|
3523
|
-
|
|
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
|
|
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
|
|
3676
|
-
return
|
|
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);
|