@corca-org/ceal-host-linux-arm64 1.0.8 → 1.0.10
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/README.md +2 -2
- package/bin/ceal-host +0 -0
- package/libexec/ceal-host/claude-hook.mjs +149 -46
- package/libexec/ceal-host/claude-invocation-authentication.mjs +103 -127
- package/libexec/ceal-host/claude-producer.mjs +76 -24
- package/libexec/ceal-host/codex-hook.mjs +148 -47
- package/libexec/ceal-host/codex-invocation-authentication.mjs +136 -131
- package/libexec/ceal-host/codex-producer.mjs +136 -32
- package/libexec/ceal-host/control.mjs +157 -40
- package/libexec/ceal-host/relay.mjs +240 -58
- package/package.json +1 -1
- package/share/ceal-host/bundle-manifest.json +12 -12
- package/share/ceal-host/bundle-manifest.sigstore.json +1 -1
|
@@ -74,11 +74,28 @@ var client_wire_contract_default = {
|
|
|
74
74
|
],
|
|
75
75
|
bare_document_fields: [
|
|
76
76
|
"invocation",
|
|
77
|
-
"
|
|
77
|
+
"required_action_sequence",
|
|
78
|
+
"entrypoints",
|
|
78
79
|
"common_concepts",
|
|
79
80
|
"operations",
|
|
80
81
|
"catalog_revision"
|
|
81
82
|
],
|
|
83
|
+
prompt_field: "prompt",
|
|
84
|
+
prompt_schema_version: "ceal.prompt.v1",
|
|
85
|
+
focused_prompt_document_fields: [
|
|
86
|
+
"catalog_revision",
|
|
87
|
+
"prompt"
|
|
88
|
+
],
|
|
89
|
+
focused_prompt_continuation_document_fields: [
|
|
90
|
+
"catalog_revision",
|
|
91
|
+
"remaining_work",
|
|
92
|
+
"prompt"
|
|
93
|
+
],
|
|
94
|
+
discovery_command: "discovery",
|
|
95
|
+
discovery_manifest_schema_version: "ceal.discovery_manifest.v1",
|
|
96
|
+
discovery_manifest_document_fields: [
|
|
97
|
+
"discovery_manifest"
|
|
98
|
+
],
|
|
82
99
|
exit_code_max: 125,
|
|
83
100
|
bare_document_max_bytes: 65536,
|
|
84
101
|
complete_max_bytes: 66019,
|
|
@@ -105,8 +122,15 @@ var CEAL_VERIFIED_ARTIFACT_MAX_BYTES = artifact.max_bytes;
|
|
|
105
122
|
var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_MAX_BYTES = artifact.envelope_max_bytes;
|
|
106
123
|
var CEAL_COMMAND_REQUEST_SCHEMA_VERSION = request.schema_version;
|
|
107
124
|
var CEAL_COMMAND_REQUEST_MAX_BYTES = request.absolute_transport_max_bytes;
|
|
108
|
-
var CEAL_COMMAND_RESPONSE_BARE_DOCUMENT_FIELDS = response.bare_document_fields;
|
|
109
125
|
var CEAL_COMMAND_RESPONSE_BARE_DOCUMENT_MAX_BYTES = response.bare_document_max_bytes;
|
|
126
|
+
var CEAL_COMMAND_RESPONSE_PROMPT_FIELD = response.prompt_field;
|
|
127
|
+
var CEAL_COMMAND_RESPONSE_PROMPT_SCHEMA_VERSION = response.prompt_schema_version;
|
|
128
|
+
var CEAL_COMMAND_RESPONSE_PROMPT_DOCUMENT_FIELDS = Object.freeze([...response.bare_document_fields, response.prompt_field]);
|
|
129
|
+
var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_DOCUMENT_FIELDS = Object.freeze([...response.focused_prompt_document_fields]);
|
|
130
|
+
var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_CONTINUATION_DOCUMENT_FIELDS = Object.freeze([...response.focused_prompt_continuation_document_fields]);
|
|
131
|
+
var CEAL_COMMAND_RESPONSE_DISCOVERY_COMMAND = response.discovery_command;
|
|
132
|
+
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_SCHEMA_VERSION = response.discovery_manifest_schema_version;
|
|
133
|
+
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_DOCUMENT_FIELDS = Object.freeze([...response.discovery_manifest_document_fields]);
|
|
110
134
|
var CEAL_COMMAND_RESPONSE_MAX_BYTES = response.absolute_transport_max_bytes;
|
|
111
135
|
|
|
112
136
|
// packages/ceal-client-protocol/src/vocabulary.ts
|
|
@@ -142,7 +166,7 @@ var CEAL_OPERATION_RECOVERY_KINDS = vocabulary(["none", "reconcile", "compensate
|
|
|
142
166
|
var CEAL_OPERATION_RECOVERY_STATUSES = vocabulary(["not_started", "active", "completed"]);
|
|
143
167
|
var CEAL_OPERATION_PROVIDER_READBACK_AVAILABILITY = vocabulary(["not_started", "not_applicable", "not_available", "pending", "available"]);
|
|
144
168
|
var CEAL_OPERATION_OFFERED_HANDOFF_STATES = vocabulary(["accepted", "rejected", "unknown"]);
|
|
145
|
-
var CEAL_OPERATION_RECEIPT_AUTHORITY_KEYS = Object.freeze(["instance_ref", "
|
|
169
|
+
var CEAL_OPERATION_RECEIPT_AUTHORITY_KEYS = Object.freeze(["instance_ref", "access_group_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]);
|
|
146
170
|
var CEAL_OPERATION_APPROVAL_DISPOSITIONS = vocabulary([
|
|
147
171
|
"approval_not_required_by_policy",
|
|
148
172
|
"interactive_pending",
|
|
@@ -157,6 +181,8 @@ var CEAL_CAPABILITY_READINESS_VALUES = vocabulary(["ready", "degraded", "unavail
|
|
|
157
181
|
var CEAL_TARGET_REQUIREMENTS = vocabulary(["required", "optional", "none"]);
|
|
158
182
|
var CEAL_AUDIT_OUTCOMES = vocabulary(["succeeded", "denied", "failed"]);
|
|
159
183
|
var CEAL_GATEWAY_PROVIDER_STEP_OUTCOMES = vocabulary(["completed", "rejected", "throttled", "failed"]);
|
|
184
|
+
var CEAL_GATEWAY_READ_REUSE_DISPOSITIONS = vocabulary(["response_cache_hit", "corpus_hit", "corpus_hit_after_revalidation", "corpus_partial_provider_supplement", "provider_direct", "provider_continuation", "reuse_unavailable"]);
|
|
185
|
+
var CEAL_GATEWAY_READ_REUSE_UNAVAILABLE_REASONS = vocabulary(["not_reported", "storage_unavailable", "coverage_incomplete", "freshness_refresh_required", "not_reusable", "bypassed"]);
|
|
160
186
|
var CEAL_POLICY_DECISIONS = vocabulary(["allowed", "denied", "not_evaluated"]);
|
|
161
187
|
var CEAL_CONNECTOR_ROUTE_PHASES = vocabulary(["scope_observation", "target_selection", "route_resolution"]);
|
|
162
188
|
var CEAL_CONNECTOR_ROUTE_CAUSES = vocabulary(["provider_throttled", "provider_unavailable", "binding_invalid", "scope_limit_exceeded"]);
|
|
@@ -429,8 +455,10 @@ function requireIsoTimestamp(value, message) {
|
|
|
429
455
|
var JSON_DESCRIPTION_CONTROL_CHARACTER = new RegExp("\\p{Cc}", "u");
|
|
430
456
|
|
|
431
457
|
// packages/ceal-client-protocol/src/operation-contract-validation.ts
|
|
432
|
-
var CEAL_OPERATION_AUTHORITY_POLICY_KEYS = Object.freeze(["
|
|
458
|
+
var CEAL_OPERATION_AUTHORITY_POLICY_KEYS = Object.freeze(["access_group", "instance_binding", "target", "admission_recheck"]);
|
|
433
459
|
var MAX_OPERATION_INPUT_RESOLVER_BINDINGS = 96;
|
|
460
|
+
var CEAL_OPERATION_DESCRIPTOR_REQUIRED_ENVELOPE_KEYS = Object.freeze(["schema_version", "id", "input_contract", "result_contract", "policy"]);
|
|
461
|
+
var CEAL_OPERATION_DESCRIPTOR_OPTIONAL_ENVELOPE_KEYS = Object.freeze(["input_resolution", "summary"]);
|
|
434
462
|
var CEAL_OPERATION_RESULT_KEYS = vocabulary(["ok", "operation_id", "operation_receipt", "schema_version", "value"]);
|
|
435
463
|
var CEAL_OPERATION_COMPACT_RESULT_KEYS = vocabulary(["ok", "operation_evidence", "operation_id", "schema_version", "value"]);
|
|
436
464
|
|
|
@@ -504,6 +532,7 @@ var CEAL_SCHEMA_LITERALS = [
|
|
|
504
532
|
"ceal.operation_descriptor.v1",
|
|
505
533
|
"ceal.operation_error.v1",
|
|
506
534
|
"ceal.operation_failure.v1",
|
|
535
|
+
"ceal.operation_failure.compact.v1",
|
|
507
536
|
"ceal.operation_receipt.v1",
|
|
508
537
|
"ceal.operation_result.v1",
|
|
509
538
|
"ceal.operation_result.compact.v1",
|
|
@@ -529,17 +558,16 @@ var CEAL_BOUNDED_SERIES_CATALOG = Object.freeze({
|
|
|
529
558
|
engagement_signal: (root) => join(root, "runtime-state", "slack-feedback.jsonl"),
|
|
530
559
|
runtime_error: (root) => join(root, "runtime-state", "runtime-errors.jsonl"),
|
|
531
560
|
turn_bridge_request: (root) => join(root, ".ceal", "turn-bridge", "requests.jsonl"),
|
|
532
|
-
channel_log: (root) => join(root, "log.jsonl"),
|
|
533
561
|
thread_run_events: (root) => join(root, "run-events.jsonl"),
|
|
534
562
|
bounded_store_sidecar: (root) => `${root}.jsonl`,
|
|
535
563
|
gateway_audit_archive: (root) => `${root}.jsonl`,
|
|
536
564
|
gateway_capability_audit: (root) => join(root, "capability-audit.jsonl"),
|
|
537
565
|
gateway_retrieval_waste_partition: (root) => `${root}.jsonl`,
|
|
538
566
|
gateway_access_policy_publication: (root) => join(root, "access-policy-publications.jsonl"),
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
567
|
+
gateway_access_group_connector_control_audit: (root) => `${root}.audit.jsonl`,
|
|
568
|
+
gateway_access_group_connector_scope_audit: (root) => join(root, "profile-connector-scope-audit.jsonl"),
|
|
569
|
+
gateway_access_group_connector_activity_scope_audit: (root) => join(root, "profile-connector-activity-scope-audit.jsonl"),
|
|
570
|
+
gateway_access_group_connector_readiness_audit: (root) => join(root, "profile-connector-readiness.audit.jsonl"),
|
|
543
571
|
gateway_organization_audit_ledger: (root) => join(root, "organization-ledger.jsonl"),
|
|
544
572
|
gateway_personal_client_audit: (root) => join(root, "audit.jsonl"),
|
|
545
573
|
gateway_personal_client_access_audit: (root) => join(root, "access-audit.jsonl"),
|
|
@@ -590,12 +618,6 @@ var CEAL_AGENT_SESSION_COMMIT_KEYS = vocabulary(["attempt_ref", "expected_sessio
|
|
|
590
618
|
// packages/ceal-client-protocol/src/operation-next-actions.ts
|
|
591
619
|
var CALLER_RECOVERABLE_NEXT_ACTION_VALUES = [
|
|
592
620
|
"select_did_you_mean",
|
|
593
|
-
// The graph, not the argument list, is what the caller must change: the
|
|
594
|
-
// resolver that owns this input has no producing node upstream, and no edit
|
|
595
|
-
// to the invocation can conjure one. `resolver_dependency_absent` carried no
|
|
596
|
-
// remedy at all rather than borrow a word that means something else, so the
|
|
597
|
-
// scorer read a fully-diagnosed, caller-fixable refusal as a failed run.
|
|
598
|
-
"request.graph.append",
|
|
599
621
|
"choose_new_output_path",
|
|
600
622
|
"choose_new_idempotency_key",
|
|
601
623
|
"restart_search",
|
|
@@ -647,8 +669,6 @@ var NON_REMEDY_NEXT_ACTION_VALUES = [
|
|
|
647
669
|
"reconcile_occurrence",
|
|
648
670
|
"reduce_request_size",
|
|
649
671
|
"repair_or_adopt_session",
|
|
650
|
-
"request.effect_approval.read",
|
|
651
|
-
"request.run",
|
|
652
672
|
"retry",
|
|
653
673
|
// The owner -- a correlation hook, an approval hook -- is not serving right
|
|
654
674
|
// now. The caller changes nothing and the same call succeeds once the owner
|
|
@@ -745,12 +765,12 @@ var CEAL_REQUEST_JSON_SCHEMA = {
|
|
|
745
765
|
additionalProperties: false,
|
|
746
766
|
properties: {
|
|
747
767
|
instance_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
748
|
-
|
|
768
|
+
access_group_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
749
769
|
principal_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
750
770
|
execution_subject_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
751
771
|
authority_revision_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source }
|
|
752
772
|
},
|
|
753
|
-
required: ["instance_ref", "
|
|
773
|
+
required: ["instance_ref", "access_group_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]
|
|
754
774
|
},
|
|
755
775
|
prompt_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
756
776
|
host_session_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
@@ -882,7 +902,7 @@ var CEAL_HOST_OBSERVATION_KINDS = vocabulary(["prompt", "session", "turn", "mode
|
|
|
882
902
|
function isCealHostPromptObservationValue(value) {
|
|
883
903
|
return isOperationRecord(value) && Object.keys(value).length === 1 && isCealDigest(value.body_sha256);
|
|
884
904
|
}
|
|
885
|
-
var HOST_RESERVED_KEY = /^(?:admission|approval|audit|authorization|cancellation|capability|effect|grant|occurrence|operation|policy|profile|provider_readback|receipt|reconciliation|replay|target|write_request)(?:_|$)/iu;
|
|
905
|
+
var HOST_RESERVED_KEY = /^(?:access_group|admission|approval|audit|authorization|cancellation|capability|effect|grant|occurrence|operation|policy|profile|provider_readback|receipt|reconciliation|replay|target|write_request)(?:_|$)/iu;
|
|
886
906
|
function assertHostObservationValue(value, kind) {
|
|
887
907
|
if (value === void 0) invalid("Ceal Host observation value is invalid.");
|
|
888
908
|
if (kind === "prompt" && !isCealHostPromptObservationValue(value)) invalid("Ceal Host prompt observation must contain only its body digest.");
|
|
@@ -902,6 +922,14 @@ function inspectHostKeys(value) {
|
|
|
902
922
|
}
|
|
903
923
|
}
|
|
904
924
|
|
|
925
|
+
// packages/ceal-client-protocol/src/host-prompt-ref.ts
|
|
926
|
+
var CEAL_HOST_PROMPT_DIGEST_PATTERN = "^[a-f0-9]{64}$";
|
|
927
|
+
var PROMPT_DIGEST = new RegExp(CEAL_HOST_PROMPT_DIGEST_PATTERN, "u");
|
|
928
|
+
function hostProducerPromptRef(promptSha256) {
|
|
929
|
+
if (!PROMPT_DIGEST.test(promptSha256)) throw new TypeError("Canonical Host prompt digest is invalid.");
|
|
930
|
+
return `ceal-host-prompt:${promptSha256}`;
|
|
931
|
+
}
|
|
932
|
+
|
|
905
933
|
// packages/ceal-client-protocol/src/request-effect-approval.ts
|
|
906
934
|
var CEAL_EFFECT_APPROVAL_DECISION_CHECK_PHRASES = Object.freeze([
|
|
907
935
|
"observed after this approval was raised and before it expires",
|
|
@@ -917,6 +945,12 @@ var OWNER_WRITE_STATES = Object.freeze(["attempt_started", "provider_acknowledge
|
|
|
917
945
|
var OWNER_EFFECT_STATES = Object.freeze(["none", "applied", "failed", "unknown", "reconciled"]);
|
|
918
946
|
var OWNER_RECEIPT_STATES = Object.freeze(["pending", "available", "failed", "unknown", "reconciled"]);
|
|
919
947
|
|
|
948
|
+
// packages/ceal-client-protocol/src/thread-excerpt.ts
|
|
949
|
+
var CEAL_THREAD_RECENT_WINDOW = 6;
|
|
950
|
+
var CEAL_THREAD_LAST_APP_MESSAGES_WINDOW = 3;
|
|
951
|
+
var CEAL_THREAD_OLDER_SUMMARY_WINDOW = 4;
|
|
952
|
+
var CEAL_FED_THREAD_MESSAGE_LIMIT = CEAL_THREAD_RECENT_WINDOW + CEAL_THREAD_OLDER_SUMMARY_WINDOW + CEAL_THREAD_LAST_APP_MESSAGES_WINDOW;
|
|
953
|
+
|
|
920
954
|
// packages/ceal-client-protocol/src/request-graph-readiness.ts
|
|
921
955
|
var REQUEST_GRAPH_PRODUCER_TO_APPEND_SCHEMA = {
|
|
922
956
|
type: "object",
|
|
@@ -1022,21 +1056,12 @@ function exactKeys(value, expected) {
|
|
|
1022
1056
|
var REQUIRED_FIELDS = Object.freeze(["schema_version", "operation_id", "local_path", "content_json_pointer", "size_bytes", "sha256", "read_argv"]);
|
|
1023
1057
|
var FIELDS = /* @__PURE__ */ new Set([...REQUIRED_FIELDS, "local_result_root", "model_disclosure"]);
|
|
1024
1058
|
|
|
1025
|
-
// packages/ceal-client-protocol/src/
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
if (!isCealJsonRecord(authority) || typeof authority.instance_ref !== "string" || typeof authority.profile_ref !== "string") return null;
|
|
1032
|
-
return Object.freeze({ instance_ref: authority.instance_ref, profile_ref: authority.profile_ref });
|
|
1033
|
-
}
|
|
1034
|
-
function isProfileReadResult(value) {
|
|
1035
|
-
return isCealJsonRecord(value) && value.schema_version === "ceal.operation_result.v1" && value.ok === true && value.operation_id === "profile.read";
|
|
1036
|
-
}
|
|
1037
|
-
function isUnaffectingAvailableReceipt(value) {
|
|
1038
|
-
return isCealJsonRecord(value) && value.effect === "none" && value.provider_handoff === "not_offered" && isCealJsonRecord(value.terminal) && value.terminal.availability === "available";
|
|
1039
|
-
}
|
|
1059
|
+
// packages/ceal-client-protocol/src/session-start-affordance.ts
|
|
1060
|
+
var CEAL_SESSION_ENTRY_INVOCATION = "ceal";
|
|
1061
|
+
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.`;
|
|
1062
|
+
|
|
1063
|
+
// packages/ceal-client-protocol/src/discovery-manifest.ts
|
|
1064
|
+
var CEAL_DISCOVERY_MANIFEST_CONNECTOR_KINDS = vocabulary(["github", "google-workspace", "notion", "slack"]);
|
|
1040
1065
|
|
|
1041
1066
|
// packages/ceal-client-protocol/src/conversation-contracts.ts
|
|
1042
1067
|
var CEAL_APPROVAL_POLICY_KINDS = vocabulary(["requester_only", "named_users", "role_based"]);
|
|
@@ -1254,7 +1279,7 @@ var CEAL_PRESENTATION_INTENTS = vocabulary(["progress", ...CEAL_FINAL_PRESENTATI
|
|
|
1254
1279
|
|
|
1255
1280
|
// packages/ceal-client-protocol/src/personal-client-vocabulary.ts
|
|
1256
1281
|
var CEAL_PERSONAL_CLIENT_BINDING_KEYS = vocabulary([
|
|
1257
|
-
"
|
|
1282
|
+
"access_group_ref",
|
|
1258
1283
|
"membership_ref",
|
|
1259
1284
|
"registration_ref",
|
|
1260
1285
|
"client_ref",
|
|
@@ -1269,7 +1294,8 @@ var CEAL_REFRESH_FAILURE_CODES = vocabulary([
|
|
|
1269
1294
|
"refresh_replayed",
|
|
1270
1295
|
"refresh_revoked",
|
|
1271
1296
|
"authority_replaced",
|
|
1272
|
-
"refresh_recovery_unavailable"
|
|
1297
|
+
"refresh_recovery_unavailable",
|
|
1298
|
+
"refresh_recovery_expired"
|
|
1273
1299
|
]);
|
|
1274
1300
|
|
|
1275
1301
|
// packages/ceal-client-protocol/src/device-enrollment.ts
|
|
@@ -1296,8 +1322,8 @@ function hostTerminalFailure(error, component) {
|
|
|
1296
1322
|
if (code === "ENOENT") return { code: "host_dependency_unavailable", message: `A command or file the ${component} Host needs is unavailable: ${detail}`, next_action: "Install the missing dependency or restore the missing file, then rerun this command." };
|
|
1297
1323
|
if (code === "EACCES" || code === "EPERM") return { code: "host_permission_denied", message: `The ${component} Host was refused access to a local path: ${detail}`, next_action: "Repair the ownership or mode of the named path, then rerun this command." };
|
|
1298
1324
|
if (code === "ENOSPC") return { code: "host_storage_unavailable", message: `The ${component} Host could not write local state: ${detail}`, next_action: "Free local disk space, then rerun this command." };
|
|
1299
|
-
if (code !== null && HOST_OWNED_CODE.test(code)) return { code, message: `The ${component} Host command failed: ${detail}`, next_action: `Resolve the named failure above; run \`ceal-host doctor
|
|
1300
|
-
return { code: "host_failure_unclassified", message: `The ${component} Host command failed for a cause it cannot classify: ${detail}`, next_action: `Run \`ceal-host doctor
|
|
1325
|
+
if (code !== null && HOST_OWNED_CODE.test(code)) return { code, message: `The ${component} Host command failed: ${detail}`, next_action: `Resolve the named failure above; run \`ceal-host doctor\` only if it reports installed ${component} Host drift.` };
|
|
1326
|
+
return { code: "host_failure_unclassified", message: `The ${component} Host command failed for a cause it cannot classify: ${detail}`, next_action: `Run \`ceal-host doctor\`; if it reports no drift then the ${component} Host configuration is not the cause, and the message above is the only evidence of what is.` };
|
|
1301
1327
|
}
|
|
1302
1328
|
var DOCTOR_FLAGS = Object.freeze({
|
|
1303
1329
|
"--expected-sha256": "expected_sha256",
|
|
@@ -1392,8 +1418,6 @@ async function doctorClient(options = {}, component) {
|
|
|
1392
1418
|
const contextInspection = await inspectCanonicalContext(options, executable, environment, run, component);
|
|
1393
1419
|
if (!contextInspection.ok) return contextInspection.failure;
|
|
1394
1420
|
const selected = contextInspection.value;
|
|
1395
|
-
const readbackFailure = await inspectAuthenticatedReadback(executable, selected, environment, run, component);
|
|
1396
|
-
if (readbackFailure !== null) return readbackFailure;
|
|
1397
1421
|
return {
|
|
1398
1422
|
ok: true,
|
|
1399
1423
|
status: "ready",
|
|
@@ -1404,9 +1428,7 @@ async function doctorClient(options = {}, component) {
|
|
|
1404
1428
|
source_tree: version.source_tree,
|
|
1405
1429
|
context_source: "canonical_user_config",
|
|
1406
1430
|
context_name: selected.name,
|
|
1407
|
-
instance_ref: selected.instance_ref
|
|
1408
|
-
profile_ref: selected.profile_ref,
|
|
1409
|
-
authenticated_readback: "profile.read"
|
|
1431
|
+
instance_ref: selected.instance_ref
|
|
1410
1432
|
};
|
|
1411
1433
|
}
|
|
1412
1434
|
async function inspectExecutable(options, environment, component) {
|
|
@@ -1437,16 +1459,11 @@ function probeCode(code) {
|
|
|
1437
1459
|
return "ceal_output_unreadable";
|
|
1438
1460
|
}
|
|
1439
1461
|
async function inspectCanonicalContext(options, executable, environment, run, component) {
|
|
1440
|
-
const probe = hostClientProbe(await safeRun(run, executable.path, ["
|
|
1441
|
-
if (probe.kind === "unreachable") return probeFailure(probe, "
|
|
1462
|
+
const probe = hostClientProbe(await safeRun(run, executable.path, ["access-group", "list"], environment), (result) => selectedContext(commandDocument(result)));
|
|
1463
|
+
if (probe.kind === "unreachable") return probeFailure(probe, "access-group list", component, options);
|
|
1442
1464
|
if (probe.kind !== "value" || options.expected_instance_ref !== void 0 && probe.value.instance_ref !== options.expected_instance_ref) return inspectedFailure("canonical_context_unavailable", `The ${component} Host cannot select the intended authenticated context from Ceal's canonical user configuration (${refusalFacts([{ name: "probe_kind", value: probe.kind, expected: "value" }, { name: "instance_ref", value: probe.kind === "value" ? probe.value.instance_ref : "unavailable", expected: options.expected_instance_ref ?? "a selected context" }])}).`, `Run \`ceal session adopt --email <email>\` without CEAL context overrides, then restart ${component}.`);
|
|
1443
1465
|
return { ok: true, value: probe.value };
|
|
1444
1466
|
}
|
|
1445
|
-
async function inspectAuthenticatedReadback(executable, selected, environment, run, component) {
|
|
1446
|
-
const result = await safeRun(run, executable.path, ["profile", "show"], environment);
|
|
1447
|
-
if (result !== null && result.exit_code === 0 && readbackProvesSelectedContext(commandDocument(result), selected)) return null;
|
|
1448
|
-
return failure("gateway_context_unavailable", "The canonical Ceal context could not complete an authenticated Gateway readback.", `Inspect the structured \`ceal profile show\` failure, repair or re-adopt the context, then restart ${component} if its environment changed.`);
|
|
1449
|
-
}
|
|
1450
1467
|
function inspectedFailure(code, message, nextAction) {
|
|
1451
1468
|
return { ok: false, failure: failure(code, message, nextAction) };
|
|
1452
1469
|
}
|
|
@@ -1518,25 +1535,21 @@ function commandDocument(result) {
|
|
|
1518
1535
|
}
|
|
1519
1536
|
}
|
|
1520
1537
|
function selectedContext(value) {
|
|
1521
|
-
if (value?.schema_version !== "ceal.
|
|
1538
|
+
if (value?.schema_version !== "ceal.access-group.v1" || value.ok !== true || !Array.isArray(value.contexts)) return null;
|
|
1522
1539
|
const selected = value.contexts.filter((item) => isRecord(item) && item.selected === true);
|
|
1523
1540
|
if (selected.length !== 1) return null;
|
|
1524
1541
|
return selectedContextRecord(selected[0]);
|
|
1525
1542
|
}
|
|
1526
1543
|
function selectedContextRecord(item) {
|
|
1527
|
-
if (!isRecord(item) || typeof item.name !== "string" || typeof item.instance_ref !== "string"
|
|
1528
|
-
if (!SAFE_REF2.test(item.instance_ref)
|
|
1529
|
-
return { name: item.name, instance_ref: item.instance_ref
|
|
1544
|
+
if (!isRecord(item) || typeof item.name !== "string" || typeof item.instance_ref !== "string") return null;
|
|
1545
|
+
if (!SAFE_REF2.test(item.instance_ref)) return null;
|
|
1546
|
+
return { name: item.name, instance_ref: item.instance_ref };
|
|
1530
1547
|
}
|
|
1531
1548
|
function versionIdentity(value) {
|
|
1532
1549
|
if (value?.schema_version !== "ceal.version.v1" || value.ok !== true || typeof value.version !== "string" || typeof value.source_commit !== "string" || typeof value.source_tree !== "string") return null;
|
|
1533
1550
|
if (value.version.length === 0 || !GIT_OID.test(value.source_commit) || !GIT_OID.test(value.source_tree)) return null;
|
|
1534
1551
|
return { version: value.version, source_commit: value.source_commit, source_tree: value.source_tree };
|
|
1535
1552
|
}
|
|
1536
|
-
function readbackProvesSelectedContext(value, selected) {
|
|
1537
|
-
const authority = cealAuthenticatedProfileReadback(value);
|
|
1538
|
-
return authority?.instance_ref === selected.instance_ref && authority.profile_ref === selected.profile_ref;
|
|
1539
|
-
}
|
|
1540
1553
|
function validExpectations(options) {
|
|
1541
1554
|
return (options.expected_sha256 === void 0 || SHA2562.test(options.expected_sha256)) && (options.expected_source_commit === void 0 || GIT_OID.test(options.expected_source_commit)) && (options.expected_instance_ref === void 0 || SAFE_REF2.test(options.expected_instance_ref));
|
|
1542
1555
|
}
|
|
@@ -1558,7 +1571,6 @@ var HOST_PRODUCER_FRAME_SCHEMA = "ceal.host_producer_frame.v1";
|
|
|
1558
1571
|
var HOST_PRODUCER_MAX_JSON_BYTES = 262144;
|
|
1559
1572
|
var HOST_PRODUCER_FRAME_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
|
|
1560
1573
|
var SAFE_REF3 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
1561
|
-
var DIGEST2 = /^[a-f0-9]{64}$/u;
|
|
1562
1574
|
var PRODUCERS = /* @__PURE__ */ new Set(["codex", "claude"]);
|
|
1563
1575
|
var HOST_PRODUCER_FRAME_KINDS = ["session_started", "turn_started", "user_input", "turn_terminal", "producer_status"];
|
|
1564
1576
|
var FRAME_KINDS = new Set(HOST_PRODUCER_FRAME_KINDS);
|
|
@@ -1599,10 +1611,6 @@ function decodeHostProducerFrame(input) {
|
|
|
1599
1611
|
validateFrame(value);
|
|
1600
1612
|
return value;
|
|
1601
1613
|
}
|
|
1602
|
-
function hostProducerPromptRef(promptSha256) {
|
|
1603
|
-
if (!DIGEST2.test(promptSha256)) throw new TypeError("Canonical Host prompt digest is invalid.");
|
|
1604
|
-
return `ceal-host-prompt:${promptSha256}`;
|
|
1605
|
-
}
|
|
1606
1614
|
function validateFrame(value) {
|
|
1607
1615
|
if (!record(value)) throw new HostProducerFrameError("invalid_frame_shape");
|
|
1608
1616
|
if (value.schema_version !== HOST_PRODUCER_FRAME_SCHEMA) throw new HostProducerFrameError("unsupported_frame_schema", `unsupported_frame_schema: ${refusalFact("schema_version", value.schema_version, HOST_PRODUCER_FRAME_SCHEMA)}`);
|
|
@@ -1712,12 +1720,19 @@ var RELAY_QUARANTINE_MAX_BYTES = 16 * 1024 * 1024;
|
|
|
1712
1720
|
|
|
1713
1721
|
// host/relay/src/relay-admission-store.ts
|
|
1714
1722
|
var DEFAULT_LIMITS = { global_count: 8192, global_bytes: 64 * 1024 * 1024, producer_count: 4096, producer_bytes: 32 * 1024 * 1024 };
|
|
1723
|
+
var RETRY_SECONDS = [1, 2, 4, 8, 16, 32, 60];
|
|
1724
|
+
var MAX_RETRYABLE_ATTEMPTS = RETRY_SECONDS.length + 10;
|
|
1715
1725
|
|
|
1716
1726
|
// host/relay/src/relay-request-binding-store.ts
|
|
1717
1727
|
var MAX_STATE_BYTES = 8 * 1024 * 1024;
|
|
1718
1728
|
|
|
1719
1729
|
// host/relay/src/relay-ipc.ts
|
|
1720
1730
|
import { createConnection, createServer } from "node:net";
|
|
1731
|
+
|
|
1732
|
+
// host/relay/src/current-prompt-custody.ts
|
|
1733
|
+
var HOST_CURRENT_PROMPT_MAX_BYTES = 256 * 1024;
|
|
1734
|
+
|
|
1735
|
+
// host/relay/src/relay-ipc.ts
|
|
1721
1736
|
var HOST_RELAY_REQUEST_BINDING_KEYS = Object.freeze([
|
|
1722
1737
|
"schema_version",
|
|
1723
1738
|
"producer_id",
|
|
@@ -1734,10 +1749,10 @@ var HOST_RELAY_REQUEST_BINDING_KEYS = Object.freeze([
|
|
|
1734
1749
|
"host_input_ref"
|
|
1735
1750
|
]);
|
|
1736
1751
|
var HOST_RELAY_IPC_RESPONSE_SCHEMA = "ceal.host_relay_admission.v1";
|
|
1737
|
-
var HOST_RELAY_BINDING_QUERY_SCHEMA = "ceal.host_relay_binding_query.v1";
|
|
1738
|
-
var HOST_RELAY_BINDING_RESULT_SCHEMA = "ceal.host_relay_binding_result.v1";
|
|
1739
1752
|
var HOST_RELAY_INVOCATION_CONTEXT_QUERY_SCHEMA = "ceal.host_relay_invocation_context_query.v1";
|
|
1740
1753
|
var HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA = "ceal.host_relay_invocation_context_result.v1";
|
|
1754
|
+
var HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA = "ceal.host_relay_current_prompt_register.v1";
|
|
1755
|
+
var HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA = "ceal.host_relay_current_prompt_result.v1";
|
|
1741
1756
|
var HOST_RELAY_IPC_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
|
|
1742
1757
|
var HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES = 4096;
|
|
1743
1758
|
var HOST_RELAY_QUERY_RESPONSE_MAX_BYTES = 8192;
|
|
@@ -1748,18 +1763,13 @@ var HostRelayIpcError = class extends Error {
|
|
|
1748
1763
|
this.code = code;
|
|
1749
1764
|
}
|
|
1750
1765
|
};
|
|
1751
|
-
var
|
|
1766
|
+
var HostRelayInvocationContextPort = class {
|
|
1752
1767
|
endpoint;
|
|
1753
|
-
|
|
1754
|
-
constructor(endpoint, timeoutMs = 5e3) {
|
|
1768
|
+
constructor(endpoint) {
|
|
1755
1769
|
this.endpoint = endpoint;
|
|
1756
|
-
this.timeout_ms = timeoutMs;
|
|
1757
|
-
}
|
|
1758
|
-
query(input) {
|
|
1759
|
-
return queryHostRelayRequestBinding(this.endpoint, input, this.timeout_ms);
|
|
1760
1770
|
}
|
|
1761
|
-
mintInvocationContext(input) {
|
|
1762
|
-
return queryHostRelayInvocationContext(this.endpoint, input,
|
|
1771
|
+
mintInvocationContext(input, signal) {
|
|
1772
|
+
return queryHostRelayInvocationContext(this.endpoint, input, signal);
|
|
1763
1773
|
}
|
|
1764
1774
|
};
|
|
1765
1775
|
var HostRelayIpcAdmissionPort = class {
|
|
@@ -1775,35 +1785,45 @@ var HostRelayIpcAdmissionPort = class {
|
|
|
1775
1785
|
return { code: response2.code, admitted_through_sequence: response2.admitted_through_sequence, delivered_through_sequence: response2.delivered_through_sequence };
|
|
1776
1786
|
}
|
|
1777
1787
|
};
|
|
1788
|
+
var HostRelayCurrentPromptPort = class {
|
|
1789
|
+
endpoint;
|
|
1790
|
+
timeout_ms;
|
|
1791
|
+
constructor(endpoint, timeoutMs = 5e3) {
|
|
1792
|
+
this.endpoint = endpoint;
|
|
1793
|
+
this.timeout_ms = timeoutMs;
|
|
1794
|
+
}
|
|
1795
|
+
async register(input) {
|
|
1796
|
+
const request2 = { schema_version: HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA, ...input };
|
|
1797
|
+
const response2 = await exchange(this.endpoint, encodeLengthPrefixed(request2), this.timeout_ms, decodeCurrentPromptResponseBuffer);
|
|
1798
|
+
if (response2.status !== "registered") throw new HostRelayIpcError("relay_unavailable", response2.status);
|
|
1799
|
+
}
|
|
1800
|
+
};
|
|
1778
1801
|
function submitHostProducerFrame(endpoint, frame, timeoutMs = 5e3) {
|
|
1779
1802
|
return exchange(endpoint, encodeHostProducerFrame(frame), timeoutMs, decodeResponseBuffer);
|
|
1780
1803
|
}
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
const response2 = await exchange(endpoint, request2, timeoutMs, decodeBindingResponseBuffer);
|
|
1784
|
-
if (response2.status === "no_binding") return { status: "no_binding" };
|
|
1785
|
-
return { status: "ready", binding: response2.binding };
|
|
1786
|
-
}
|
|
1787
|
-
function decodeHostRelayBindingQueryResult(value) {
|
|
1788
|
-
if (!validBindingResponse(value)) throw new HostRelayIpcError("relay_unavailable", "Host Relay binding response is invalid.");
|
|
1789
|
-
return value.status === "no_binding" ? { status: "no_binding" } : { status: "ready", binding: value.binding };
|
|
1790
|
-
}
|
|
1791
|
-
function queryHostRelayInvocationContext(endpoint, query, timeoutMs = 5e3) {
|
|
1792
|
-
return exchange(endpoint, encodeInvocationContextQuery(query), timeoutMs, decodeInvocationContextResponseBuffer);
|
|
1804
|
+
function queryHostRelayInvocationContext(endpoint, query, signal) {
|
|
1805
|
+
return exchange(endpoint, encodeInvocationContextQuery(query), void 0, decodeInvocationContextResponseBuffer, signal);
|
|
1793
1806
|
}
|
|
1794
|
-
function exchange(endpoint, encoded, timeoutMs, decode) {
|
|
1807
|
+
function exchange(endpoint, encoded, timeoutMs, decode, signal) {
|
|
1795
1808
|
return new Promise((resolve, reject2) => {
|
|
1796
1809
|
const socket = createConnection(endpoint);
|
|
1797
1810
|
let buffer = Buffer.alloc(0);
|
|
1798
1811
|
let settled = false;
|
|
1812
|
+
const aborted = () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC was cancelled."));
|
|
1799
1813
|
const finish = (error, response2) => {
|
|
1800
1814
|
if (settled) return;
|
|
1801
1815
|
settled = true;
|
|
1816
|
+
signal?.removeEventListener("abort", aborted);
|
|
1802
1817
|
socket.destroy();
|
|
1803
1818
|
if (error !== null) reject2(error);
|
|
1804
1819
|
else if (response2 !== void 0) resolve(response2);
|
|
1805
1820
|
};
|
|
1806
|
-
socket.setTimeout(timeoutMs, () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC timed out.")));
|
|
1821
|
+
if (timeoutMs !== void 0) socket.setTimeout(timeoutMs, () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC timed out.")));
|
|
1822
|
+
if (signal?.aborted === true) {
|
|
1823
|
+
aborted();
|
|
1824
|
+
return;
|
|
1825
|
+
}
|
|
1826
|
+
signal?.addEventListener("abort", aborted, { once: true });
|
|
1807
1827
|
socket.once("error", () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC is unavailable.")));
|
|
1808
1828
|
socket.once("connect", () => socket.write(encoded));
|
|
1809
1829
|
socket.on("data", (chunk) => {
|
|
@@ -1856,42 +1876,29 @@ function decodeResponseBuffer(buffer) {
|
|
|
1856
1876
|
if (buffer.length !== length + HOST_RELAY_IPC_LENGTH_BYTES) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC returned trailing bytes: ${refusalFacts([{ name: "declared_bytes", value: length, expected: `the received message length minus ${HOST_RELAY_IPC_LENGTH_BYTES}` }, { name: "received_bytes", value: buffer.byteLength, expected: `exactly ${length + HOST_RELAY_IPC_LENGTH_BYTES}` }])}.`);
|
|
1857
1877
|
return decodeHostRelayIpcResponse(buffer);
|
|
1858
1878
|
}
|
|
1859
|
-
function decodeBindingResponseBuffer(buffer) {
|
|
1860
|
-
const value = decodeLengthPrefixedJson(buffer, HOST_RELAY_QUERY_RESPONSE_MAX_BYTES);
|
|
1861
|
-
if (value === null) return null;
|
|
1862
|
-
const decoded = decodeHostRelayBindingQueryResult(value);
|
|
1863
|
-
return decoded.status === "no_binding" ? { schema_version: HOST_RELAY_BINDING_RESULT_SCHEMA, status: "no_binding" } : { schema_version: HOST_RELAY_BINDING_RESULT_SCHEMA, status: "ready", binding: decoded.binding };
|
|
1864
|
-
}
|
|
1865
1879
|
function decodeInvocationContextResponseBuffer(buffer) {
|
|
1866
1880
|
const value = decodeLengthPrefixedJson(buffer, HOST_RELAY_QUERY_RESPONSE_MAX_BYTES);
|
|
1867
1881
|
if (value === null) return null;
|
|
1868
1882
|
if (!validInvocationContextResponse(value)) throw new HostRelayIpcError("relay_unavailable", "Host Relay invocation context response is invalid.");
|
|
1869
1883
|
return value;
|
|
1870
1884
|
}
|
|
1871
|
-
function
|
|
1872
|
-
const value =
|
|
1873
|
-
if (
|
|
1874
|
-
|
|
1885
|
+
function decodeCurrentPromptResponseBuffer(buffer) {
|
|
1886
|
+
const value = decodeLengthPrefixedJson(buffer, HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES);
|
|
1887
|
+
if (value === null) return null;
|
|
1888
|
+
if (!record2(value) || !exactKeys3(value, ["schema_version", "status"]) || value.schema_version !== HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA || value.status !== "registered" && value.status !== "current_prompt_unavailable") throw new HostRelayIpcError("relay_unavailable");
|
|
1889
|
+
return { schema_version: HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA, status: value.status };
|
|
1875
1890
|
}
|
|
1876
1891
|
function encodeInvocationContextQuery(query) {
|
|
1877
1892
|
const value = { schema_version: HOST_RELAY_INVOCATION_CONTEXT_QUERY_SCHEMA, ...query };
|
|
1878
1893
|
if (!validInvocationContextQueryRequest(value)) throw new HostRelayIpcError("invalid_frame_shape");
|
|
1879
1894
|
return encodeLengthPrefixed(value);
|
|
1880
1895
|
}
|
|
1881
|
-
function validBindingQueryRequest(value) {
|
|
1882
|
-
return validQueryIdentity(value, HOST_RELAY_BINDING_QUERY_SCHEMA) && exactKeys3(value, ["schema_version", "producer_id", "producer_installation_ref", "local_session_ref", "local_turn_ref"]);
|
|
1883
|
-
}
|
|
1884
1896
|
function validInvocationContextQueryRequest(value) {
|
|
1885
1897
|
return validQueryIdentity(value, HOST_RELAY_INVOCATION_CONTEXT_QUERY_SCHEMA) && exactKeys3(value, ["schema_version", "producer_id", "producer_installation_ref", "local_session_ref", "local_turn_ref", "client_nonce"]) && typeof value.client_nonce === "string" && CEAL_HOST_CLIENT_NONCE_PATTERN.test(value.client_nonce);
|
|
1886
1898
|
}
|
|
1887
1899
|
function validQueryIdentity(value, schema) {
|
|
1888
1900
|
return record2(value) && value.schema_version === schema && (value.producer_id === "codex" || value.producer_id === "claude") && safeRef2(value.producer_installation_ref) && safeRef2(value.local_session_ref) && safeRef2(value.local_turn_ref);
|
|
1889
1901
|
}
|
|
1890
|
-
function validBindingResponse(value) {
|
|
1891
|
-
if (!record2(value) || value.schema_version !== HOST_RELAY_BINDING_RESULT_SCHEMA) return false;
|
|
1892
|
-
if (value.status === "no_binding") return Object.keys(value).length === 2;
|
|
1893
|
-
return value.status === "ready" && Object.keys(value).length === 3 && validWireBinding(value.binding);
|
|
1894
|
-
}
|
|
1895
1902
|
function validInvocationContextResponse(value) {
|
|
1896
1903
|
if (!record2(value) || value.schema_version !== HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA) return false;
|
|
1897
1904
|
if (value.status === "no_binding") return Object.keys(value).length === 2;
|
|
@@ -1903,19 +1910,6 @@ function validInvocationContextResponse(value) {
|
|
|
1903
1910
|
return false;
|
|
1904
1911
|
}
|
|
1905
1912
|
}
|
|
1906
|
-
function validWireBinding(value) {
|
|
1907
|
-
if (!record2(value) || value.schema_version !== "ceal.host_relay_request_binding.v1" || value.producer_id !== "codex" && value.producer_id !== "claude") return false;
|
|
1908
|
-
const required = HOST_RELAY_REQUEST_BINDING_KEYS;
|
|
1909
|
-
const keys = Object.keys(value);
|
|
1910
|
-
return required.every((key) => Object.hasOwn(value, key)) && keys.every((key) => required.includes(key) || key === "context_expires_at") && validWireBindingRefs(value) && validWireBindingTimes(value);
|
|
1911
|
-
}
|
|
1912
|
-
function validWireBindingRefs(value) {
|
|
1913
|
-
const tuple = [value.host_source_ref, value.host_session_ref, value.host_turn_ref, value.host_input_ref];
|
|
1914
|
-
return [value.producer_installation_ref, value.local_session_ref, value.local_turn_ref, value.prompt_ref, value.request_ref].every(safeRef2) && Array.isArray(value.local_turn_aliases) && value.local_turn_aliases.length <= 16 && value.local_turn_aliases.every(safeRef2) && tuple.every(safeRef2);
|
|
1915
|
-
}
|
|
1916
|
-
function validWireBindingTimes(value) {
|
|
1917
|
-
return validTimestamp(value.bound_at) && (value.context_expires_at === void 0 || validTimestamp(value.context_expires_at));
|
|
1918
|
-
}
|
|
1919
1913
|
function decodeLengthPrefixedJson(input, maximum) {
|
|
1920
1914
|
if (input.length < HOST_RELAY_IPC_LENGTH_BYTES) return null;
|
|
1921
1915
|
const length = input.readUInt32BE(0);
|
|
@@ -1941,14 +1935,12 @@ function exactKeys3(value, keys) {
|
|
|
1941
1935
|
function safeRef2(value) {
|
|
1942
1936
|
return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u.test(value);
|
|
1943
1937
|
}
|
|
1944
|
-
function validTimestamp(value) {
|
|
1945
|
-
return typeof value === "string" && Number.isFinite(Date.parse(value));
|
|
1946
|
-
}
|
|
1947
1938
|
|
|
1948
1939
|
// host/invocation-authentication-command.ts
|
|
1949
1940
|
var HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX = ["authenticate", "--client-nonce"];
|
|
1941
|
+
var REFUSAL_REASON_PATTERN = /^[a-z][a-z0-9_ ]{0,63}$/u;
|
|
1950
1942
|
function installedHostInvocationAuthenticationCommandOptions(config) {
|
|
1951
|
-
const port = new
|
|
1943
|
+
const port = new HostRelayInvocationContextPort(config.relay_endpoint);
|
|
1952
1944
|
return {
|
|
1953
1945
|
host_source_ref: config.host_source_ref,
|
|
1954
1946
|
outbox_dir: config.outbox_dir,
|
|
@@ -1963,15 +1955,19 @@ async function runHostInvocationAuthenticationCommand(descriptor, args, options)
|
|
|
1963
1955
|
sink = resolved.options.output_sink;
|
|
1964
1956
|
writeResult(await authenticateHostInvocation(descriptor, resolved.input, resolved.options), sink);
|
|
1965
1957
|
return 0;
|
|
1966
|
-
} catch {
|
|
1967
|
-
writeResult({ ok: false, code: "invocation_authentication_unavailable" }, sink);
|
|
1958
|
+
} catch (error) {
|
|
1959
|
+
writeResult({ ok: false, code: "invocation_authentication_unavailable", reason: authenticationRefusalReason(error) }, sink);
|
|
1968
1960
|
return 2;
|
|
1969
1961
|
}
|
|
1970
1962
|
}
|
|
1963
|
+
function authenticationRefusalReason(error) {
|
|
1964
|
+
const message = error instanceof Error ? error.message : "";
|
|
1965
|
+
return REFUSAL_REASON_PATTERN.test(message) ? message : "unclassified";
|
|
1966
|
+
}
|
|
1971
1967
|
async function authenticateHostInvocation(descriptor, input, options) {
|
|
1972
1968
|
if (input.length !== HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX.length + 1 || input[0] !== HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX[0] || input[1] !== HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX[1]) throw new TypeError("invalid arguments");
|
|
1973
1969
|
const request2 = decodeCealHostInvocationAuthenticationRequest({ schema_version: CEAL_HOST_INVOCATION_AUTHENTICATION_REQUEST_SCHEMA, client_nonce: input[2] });
|
|
1974
|
-
const config = validateOptions(options
|
|
1970
|
+
const config = validateOptions(options);
|
|
1975
1971
|
const now = (config.now ?? (() => /* @__PURE__ */ new Date()))();
|
|
1976
1972
|
const { store, current } = await currentInvocation(descriptor, config, now);
|
|
1977
1973
|
if (config.mint_invocation_context === void 0) throw new TypeError("mint unavailable");
|
|
@@ -2009,9 +2005,9 @@ async function resolveOptions(descriptor, args, options) {
|
|
|
2009
2005
|
options: installedHostInvocationAuthenticationCommandOptions(await descriptor.read_producer_config(configPath))
|
|
2010
2006
|
};
|
|
2011
2007
|
}
|
|
2012
|
-
function validateOptions(options
|
|
2008
|
+
function validateOptions(options) {
|
|
2013
2009
|
if (typeof options.outbox_dir !== "string" || options.outbox_dir.length === 0 || typeof options.host_source_ref !== "string" || !SAFE_REF.test(options.host_source_ref) || typeof options.producer_installation_ref !== "string" || !SAFE_REF.test(options.producer_installation_ref) || !validOptionalSession(options.session_id)) {
|
|
2014
|
-
throw new TypeError(
|
|
2010
|
+
throw new TypeError("options invalid");
|
|
2015
2011
|
}
|
|
2016
2012
|
return options;
|
|
2017
2013
|
}
|
|
@@ -3578,6 +3574,8 @@ var CodexTranscriptWatcher = class {
|
|
|
3578
3574
|
now;
|
|
3579
3575
|
log;
|
|
3580
3576
|
retriedMalformedQuarantines = /* @__PURE__ */ new Set();
|
|
3577
|
+
producerInstallationRef;
|
|
3578
|
+
registerCurrentPrompt;
|
|
3581
3579
|
constructor(options) {
|
|
3582
3580
|
if (typeof options.outbox_dir !== "string" || options.outbox_dir.length === 0) throw new CodexHostAdapterError("configuration", "Codex transcript watcher outbox is invalid.");
|
|
3583
3581
|
this.store = new CodexOutboxStore(options.outbox_dir);
|
|
@@ -3587,6 +3585,8 @@ var CodexTranscriptWatcher = class {
|
|
|
3587
3585
|
process.stderr.write(`${line}
|
|
3588
3586
|
`);
|
|
3589
3587
|
});
|
|
3588
|
+
this.producerInstallationRef = options.producer_installation_ref;
|
|
3589
|
+
this.registerCurrentPrompt = options.register_current_prompt;
|
|
3590
3590
|
}
|
|
3591
3591
|
async scanOnce() {
|
|
3592
3592
|
const registrations = await this.store.listTranscriptRegistrations();
|
|
@@ -3731,10 +3731,15 @@ var CodexTranscriptWatcher = class {
|
|
|
3731
3731
|
created_at: record3.timestamp,
|
|
3732
3732
|
expires_at: expiration(this.now, this.outboxRetentionMs)
|
|
3733
3733
|
};
|
|
3734
|
+
await this.registerPrompt(origin, registration, activeTask, currentPromptRef, record3.prompt, envelope.expires_at);
|
|
3734
3735
|
await this.store.put(envelope);
|
|
3735
3736
|
if (origin) await this.store.activateInvocationContext(identity, promptRef, envelope.expires_at);
|
|
3736
3737
|
return { activeTask: { ...activeTask, origin_host_input_ref: activeTask.origin_host_input_ref ?? hostInputRef, prompt_ref: activeTask.prompt_ref ?? currentPromptRef }, enqueued: 1 };
|
|
3737
3738
|
}
|
|
3739
|
+
async registerPrompt(origin, registration, activeTask, promptRef, prompt, expiresAt) {
|
|
3740
|
+
if (!origin || this.producerInstallationRef === void 0 || this.registerCurrentPrompt === void 0) return;
|
|
3741
|
+
await this.registerCurrentPrompt({ producer_id: "codex", producer_installation_ref: this.producerInstallationRef, local_session_ref: registration.host_session_ref, local_turn_ref: activeTask.host_turn_ref, prompt_ref: promptRef, current_prompt: prompt, context_expires_at: expiresAt });
|
|
3742
|
+
}
|
|
3738
3743
|
async processTerminal(registration, activeTask, record3) {
|
|
3739
3744
|
if (activeTask === void 0 || activeTask.codex_turn_id !== record3.turn_id || activeTask.origin_host_input_ref === void 0 || activeTask.prompt_ref === void 0) return { ...activeTask === void 0 ? {} : { activeTask }, enqueued: 0 };
|
|
3740
3745
|
const identity = { host_source_ref: registration.host_source_ref, host_session_ref: registration.host_session_ref, host_turn_ref: activeTask.host_turn_ref };
|
|
@@ -3939,7 +3944,8 @@ function expiration(now, retentionMs) {
|
|
|
3939
3944
|
|
|
3940
3945
|
// host/codex/src/codex-producer-runtime.ts
|
|
3941
3946
|
async function drainCodexProducerOnce(options) {
|
|
3942
|
-
const
|
|
3947
|
+
const promptPort = new HostRelayCurrentPromptPort(options.relay_endpoint, options.timeout_ms);
|
|
3948
|
+
const scan = await new CodexTranscriptWatcher({ outbox_dir: options.outbox_dir, producer_installation_ref: options.producer_installation_ref, register_current_prompt: (input) => promptPort.register(input) }).scanOnce();
|
|
3943
3949
|
const producer = new CodexProducer({ outbox_dir: options.outbox_dir, producer_installation_ref: options.producer_installation_ref, relay: new HostRelayIpcAdmissionPort(options.relay_endpoint, options.timeout_ms), ...options.producer_epoch === void 0 ? {} : { producer_epoch: options.producer_epoch }, ...options.now === void 0 ? {} : { now: options.now } });
|
|
3944
3950
|
return { scanned: scan.enqueued, ...await producer.drainOutbox() };
|
|
3945
3951
|
}
|
|
@@ -3963,7 +3969,6 @@ var CODEX_PRODUCER_DESCRIPTOR = {
|
|
|
3963
3969
|
|
|
3964
3970
|
// host/codex/src/codex-invocation-authentication-command.ts
|
|
3965
3971
|
var CODEX_INVOCATION_AUTHENTICATION_DESCRIPTOR = {
|
|
3966
|
-
command_name: "ceal-codex-invocation-authentication",
|
|
3967
3972
|
producer_id: "codex",
|
|
3968
3973
|
create_store: (directory) => new CodexOutboxStore(directory),
|
|
3969
3974
|
session_id_env: CODEX_THREAD_ID_ENVIRONMENT,
|