agent-embassy 1.6.1 → 1.7.0

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.
Files changed (97) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +9 -9
  3. package/README.zh-CN.md +9 -9
  4. package/SECURITY.md +34 -77
  5. package/dist/src/gateway/acp-client.d.ts +117 -0
  6. package/dist/src/gateway/acp-client.js +382 -0
  7. package/dist/src/gateway/acp-client.js.map +1 -0
  8. package/dist/src/gateway/acp-provider.d.ts +65 -0
  9. package/dist/src/gateway/acp-provider.js +163 -0
  10. package/dist/src/gateway/acp-provider.js.map +1 -0
  11. package/dist/src/gateway/claude-helper-protocol.d.ts +3 -1
  12. package/dist/src/gateway/claude-helper-protocol.js +15 -5
  13. package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
  14. package/dist/src/gateway/claude-helper-supervisor.d.ts +3 -1
  15. package/dist/src/gateway/claude-helper-supervisor.js +16 -2
  16. package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
  17. package/dist/src/gateway/claude-helper.js +4 -3
  18. package/dist/src/gateway/claude-helper.js.map +1 -1
  19. package/dist/src/gateway/claude-peer.d.ts +1 -1
  20. package/dist/src/gateway/claude-peer.js +11 -13
  21. package/dist/src/gateway/claude-peer.js.map +1 -1
  22. package/dist/src/gateway/claude-runtime.d.ts +0 -20
  23. package/dist/src/gateway/claude-runtime.js +6 -127
  24. package/dist/src/gateway/claude-runtime.js.map +1 -1
  25. package/dist/src/gateway/cli-copy.en.d.ts +1 -1
  26. package/dist/src/gateway/cli-copy.en.js +2 -2
  27. package/dist/src/gateway/cli-copy.zh-CN.d.ts +1 -1
  28. package/dist/src/gateway/cli-copy.zh-CN.js +2 -2
  29. package/dist/src/gateway/cli.d.ts +1 -1
  30. package/dist/src/gateway/cli.js +26 -5
  31. package/dist/src/gateway/cli.js.map +1 -1
  32. package/dist/src/gateway/codex-app-server.d.ts +5 -74
  33. package/dist/src/gateway/codex-app-server.js +9 -599
  34. package/dist/src/gateway/codex-app-server.js.map +1 -1
  35. package/dist/src/gateway/codex-local-transport.d.ts +8 -26
  36. package/dist/src/gateway/codex-local-transport.js +26 -76
  37. package/dist/src/gateway/codex-local-transport.js.map +1 -1
  38. package/dist/src/gateway/compatibility.d.ts +6 -66
  39. package/dist/src/gateway/compatibility.js +14 -296
  40. package/dist/src/gateway/compatibility.js.map +1 -1
  41. package/dist/src/gateway/config.d.ts +9 -0
  42. package/dist/src/gateway/config.js +6 -2
  43. package/dist/src/gateway/config.js.map +1 -1
  44. package/dist/src/gateway/control.d.ts +16 -1
  45. package/dist/src/gateway/control.js +89 -57
  46. package/dist/src/gateway/control.js.map +1 -1
  47. package/dist/src/gateway/dashboard-copy.d.ts +1 -1
  48. package/dist/src/gateway/dashboard-copy.en.d.ts +14 -44
  49. package/dist/src/gateway/dashboard-copy.en.js +37 -67
  50. package/dist/src/gateway/dashboard-copy.en.js.map +1 -1
  51. package/dist/src/gateway/dashboard-copy.js +14 -44
  52. package/dist/src/gateway/dashboard-copy.js.map +1 -1
  53. package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +14 -44
  54. package/dist/src/gateway/dashboard-copy.zh-CN.js +37 -67
  55. package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -1
  56. package/dist/src/gateway/dashboard-model.d.ts +38 -76
  57. package/dist/src/gateway/dashboard-model.js +158 -256
  58. package/dist/src/gateway/dashboard-model.js.map +1 -1
  59. package/dist/src/gateway/dashboard.d.ts +0 -3
  60. package/dist/src/gateway/dashboard.js +75 -76
  61. package/dist/src/gateway/dashboard.js.map +1 -1
  62. package/dist/src/gateway/deepseek-detect.d.ts +7 -6
  63. package/dist/src/gateway/deepseek-detect.js +31 -115
  64. package/dist/src/gateway/deepseek-detect.js.map +1 -1
  65. package/dist/src/gateway/live-dashboard-app/app.js +166 -621
  66. package/dist/src/gateway/live-dashboard-command.js +2 -4
  67. package/dist/src/gateway/live-dashboard-command.js.map +1 -1
  68. package/dist/src/gateway/live-dashboard-http.d.ts +1 -2
  69. package/dist/src/gateway/live-dashboard-http.js +14 -15
  70. package/dist/src/gateway/live-dashboard-http.js.map +1 -1
  71. package/dist/src/gateway/progress-watch-machine.d.ts +1 -4
  72. package/dist/src/gateway/progress-watch-machine.js.map +1 -1
  73. package/dist/src/gateway/provenance-envelope.d.ts +3 -2
  74. package/dist/src/gateway/provenance-envelope.js +44 -11
  75. package/dist/src/gateway/provenance-envelope.js.map +1 -1
  76. package/dist/src/gateway/providers.d.ts +12 -85
  77. package/dist/src/gateway/providers.js +72 -835
  78. package/dist/src/gateway/providers.js.map +1 -1
  79. package/dist/src/gateway/server.d.ts +8 -9
  80. package/dist/src/gateway/server.js +51 -99
  81. package/dist/src/gateway/server.js.map +1 -1
  82. package/dist/src/gateway/service.d.ts +22 -49
  83. package/dist/src/gateway/service.js +196 -437
  84. package/dist/src/gateway/service.js.map +1 -1
  85. package/dist/src/gateway/store.d.ts +20 -29
  86. package/dist/src/gateway/store.js +281 -827
  87. package/dist/src/gateway/store.js.map +1 -1
  88. package/dist/src/gateway/types.d.ts +55 -55
  89. package/dist/src/gateway/types.js +49 -91
  90. package/dist/src/gateway/types.js.map +1 -1
  91. package/docs/CONFIGURATION.md +11 -10
  92. package/docs/CONFIGURATION.zh-CN.md +10 -9
  93. package/docs/DASHBOARD.md +4 -38
  94. package/docs/DASHBOARD.zh-CN.md +4 -2
  95. package/docs/GATEWAY-ARCHITECTURE.md +61 -119
  96. package/package.json +1 -1
  97. package/skills/embassy-peer/SKILL.md +6 -6
@@ -1,13 +1,12 @@
1
1
  import path from "node:path";
2
- import { chmod, lstat, mkdir, mkdtemp, readdir, realpath, rmdir, } from "node:fs/promises";
3
2
  import { BridgeError } from "../errors.js";
4
3
  import { CLAUDE_PEER_COMPATIBILITY, ClaudePeerAdapter, } from "./claude-peer.js";
5
- import { certifiedCompatibilityVersions, compatibilityCoversWrites, compatibilityProbeNames, evaluateCompatibilityAttestation, isCompatibilityAttestation, isCompatibilityVersion, sharesCompatibilityMajor, UNKNOWN_COMPATIBILITY_VERSION, } from "./compatibility.js";
6
- import { CODEX_APP_SERVER_WRITABLE_VERSIONS, CodexAppServerConnector, CodexConnectorError, codexWriteProbeFailure, } from "./codex-app-server.js";
4
+ import { CodexAppServerConnector, CodexConnectorError, } from "./codex-app-server.js";
7
5
  import { LocalCodexTransportError } from "./codex-local-transport.js";
8
6
  import { ClaudeNativeHelperSupervisor, } from "./claude-helper-supervisor.js";
9
7
  import { isDashboardLocale } from "./locale.js";
10
8
  import { composeProvenanceEnvelope } from "./provenance-envelope.js";
9
+ import { gatewayRegistrationIngressPrefixes } from "./types.js";
11
10
  const LOCAL_HOST = "this-mac";
12
11
  const STABLE_CLAUDE_ENDPOINT_GENERATION = "claude_local_endpoint";
13
12
  const NATIVE_CLAUDE_NAME = /^[a-z][a-z0-9_-]{0,31}$/;
@@ -24,13 +23,6 @@ const DEFAULT_CODEX_CLEANUP_POLL_MS = 25;
24
23
  const DEFAULT_CODEX_RECOVERY_INITIAL_MS = 250;
25
24
  const DEFAULT_CODEX_RECOVERY_MAX_MS = 5_000;
26
25
  const MAX_CODEX_ENDPOINT_REFRESH_CANDIDATES = 3;
27
- const COMPATIBILITY_PROBE_THREAD_ID = "00000000-0000-7000-8000-000000000000";
28
- const CODEX_WRITE_PROBE_DIRECTORY_PREFIX = ".codex-write-probe-";
29
- const CODEX_WRITE_PROBE_ROOT = "write-probes";
30
- const MAX_CODEX_WRITE_PROBE_ATTEMPTS = 16;
31
- const CODEX_WRITE_PROBE_TRANSIENT_ERRNOS = new Set([
32
- "EAGAIN", "EIO", "EMFILE", "ENFILE",
33
- ]);
34
26
  const CLAUDE_CLEAN_PREWRITE_RETRY_CODES = new Set([
35
27
  "CLAUDE_PEER_TARGET_UNKNOWN",
36
28
  "CLAUDE_PEER_TARGET_STALE",
@@ -86,105 +78,6 @@ function claudeCleanPrewriteResult(error) {
86
78
  : "CLAUDE_DISPATCH_PREWRITE_FAILED",
87
79
  };
88
80
  }
89
- function passedProbe(name) {
90
- return { name, outcome: "pass" };
91
- }
92
- function failedProbe(name, safeErrorCode) {
93
- return { name, outcome: "fail", safeErrorCode };
94
- }
95
- function systemErrorCode(error) {
96
- return typeof error === "object" &&
97
- error !== null &&
98
- "code" in error &&
99
- typeof error.code === "string"
100
- ? error.code
101
- : undefined;
102
- }
103
- function transientCodexWriteProbeError(error) {
104
- return CODEX_WRITE_PROBE_TRANSIENT_ERRNOS.has(systemErrorCode(error) ?? "");
105
- }
106
- function safeCodexWriteProbeFilesystemFailure(error) {
107
- return (transientCodexWriteProbeError(error) ||
108
- systemErrorCode(error) === "ENOTEMPTY" ||
109
- (error instanceof BridgeError &&
110
- error.code === "CODEX_WRITE_PROBE_THREAD_SETUP_FAILED"));
111
- }
112
- async function attestCodexWriteProbeDirectory(directory) {
113
- try {
114
- const resolved = path.resolve(directory);
115
- const [metadata, canonical, entries] = await Promise.all([
116
- lstat(resolved, { bigint: true }),
117
- realpath(resolved),
118
- readdir(resolved),
119
- ]);
120
- const uid = process.getuid?.();
121
- if (uid === undefined ||
122
- !metadata.isDirectory() ||
123
- canonical !== resolved ||
124
- metadata.uid !== BigInt(uid) ||
125
- (metadata.mode & 511n) !== 448n) {
126
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The disposable Codex probe directory crossed its ownership, mode, or canonical-path boundary.");
127
- }
128
- if (entries.length !== 0) {
129
- throw new BridgeError("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED", "The disposable Codex probe directory was not empty.");
130
- }
131
- return {
132
- dev: metadata.dev,
133
- ino: metadata.ino,
134
- mode: metadata.mode & 511n,
135
- mtimeNs: metadata.mtimeNs,
136
- uid: metadata.uid,
137
- };
138
- }
139
- catch (error) {
140
- if (error instanceof BridgeError)
141
- throw error;
142
- if (transientCodexWriteProbeError(error)) {
143
- throw new BridgeError("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED", "A transient filesystem error prevented disposable probe attestation.");
144
- }
145
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The disposable Codex probe directory could not be attested safely.");
146
- }
147
- }
148
- async function attestCodexWriteProbeRoot(root) {
149
- try {
150
- const resolved = path.resolve(root);
151
- const [metadata, canonical] = await Promise.all([
152
- lstat(resolved, { bigint: true }),
153
- realpath(resolved),
154
- ]);
155
- const uid = process.getuid?.();
156
- if (uid === undefined ||
157
- !metadata.isDirectory() ||
158
- canonical !== resolved ||
159
- metadata.uid !== BigInt(uid) ||
160
- (metadata.mode & 511n) !== 448n) {
161
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "A controller-owned Codex probe root changed outside its exact owned-directory boundary.");
162
- }
163
- return {
164
- dev: metadata.dev,
165
- ino: metadata.ino,
166
- mode: metadata.mode & 511n,
167
- uid: metadata.uid,
168
- };
169
- }
170
- catch (error) {
171
- if (error instanceof BridgeError)
172
- throw error;
173
- if (transientCodexWriteProbeError(error)) {
174
- return null;
175
- }
176
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "A controller-owned Codex probe root could not be attested.");
177
- }
178
- }
179
- function sameCodexWriteProbeDirectory(before, after) {
180
- return sameCodexWriteProbeRoot(before, after) && before.mtimeNs === after.mtimeNs;
181
- }
182
- function sameCodexWriteProbeRoot(before, after) {
183
- return (before.dev === after.dev &&
184
- before.ino === after.ino &&
185
- before.mode === after.mode &&
186
- before.uid === after.uid);
187
- }
188
81
  function exactLocalHost(hostId) {
189
82
  if ((hostId ?? LOCAL_HOST) !== LOCAL_HOST) {
190
83
  throw new BridgeError("GATEWAY_REMOTE_PROVIDER_DISABLED", "This provider is restricted to the exact local host boundary.");
@@ -226,18 +119,6 @@ function invokeCallback(operation) {
226
119
  }
227
120
  }
228
121
  function validateAttestedClaudeRuntime(runtime) {
229
- if (runtime.versionEvidenceFailure !== undefined) {
230
- throw new BridgeError(runtime.versionEvidenceFailure, "The local Claude provider requires bounded, internally consistent runtime version evidence.");
231
- }
232
- const majorEvidence = runtime.claudeCodeVersion === UNKNOWN_COMPATIBILITY_VERSION
233
- ? runtime.launcherVersionEvidence
234
- : runtime.claudeCodeVersion;
235
- if (majorEvidence === undefined ||
236
- !sharesCompatibilityMajor(majorEvidence, CLAUDE_PEER_COMPATIBILITY.claudeCodeVersion)) {
237
- throw new BridgeError(majorEvidence === undefined
238
- ? "CLAUDE_VERSION_UNPARSEABLE"
239
- : "CLAUDE_PEER_VERSION_UNSUPPORTED", "The local Claude provider requires a positively observed supported runtime major.");
240
- }
241
122
  validateClaudeRuntimePathEvidence(runtime);
242
123
  }
243
124
  function validateClaudeRuntimePathEvidence(runtime) {
@@ -286,135 +167,17 @@ function isClaudeRegistryAvailabilityError(error) {
286
167
  error.code === "EPERM" ||
287
168
  error.code === "UNSAFE_PEER_DIRECTORY");
288
169
  }
289
- /**
290
- * A bounded observation-only surface for an installed provider generation
291
- * whose protocol cannot be used safely. It deliberately performs no provider
292
- * discovery, listener construction, route selection, or message write.
293
- */
294
- export class IncompatibleGatewayProvider {
295
- identity;
296
- protocol = "not-attested";
297
- protocolVersion = "unknown";
298
- version;
299
- probes;
300
- safeErrorCode;
301
- initialized = false;
302
- closed = false;
303
- constructor(options) {
304
- const attestation = evaluateCompatibilityAttestation({
305
- surface: options.identity.provider,
306
- version: options.version,
307
- checkedAt: "2000-01-01T00:00:00.000Z",
308
- certifiedVersions: certifiedCompatibilityVersions[options.identity.provider],
309
- probes: options.probes,
310
- });
311
- if (attestation.tier !== "incompatible" ||
312
- attestation.safeErrorCode !== options.safeErrorCode) {
313
- throw new BridgeError("INCOMPATIBLE_PROVIDER_EVIDENCE_INVALID", "A disabled provider requires exact bounded incompatibility evidence.");
314
- }
315
- exactLocalHost(options.identity.hostId);
316
- this.identity = Object.freeze({ ...options.identity });
317
- this.version = options.version;
318
- this.probes = Object.freeze(options.probes.map((probe) => Object.freeze({ ...probe })));
319
- this.safeErrorCode = options.safeErrorCode;
320
- }
321
- compatibilitySurface() {
322
- return { surface: this.identity.provider, version: this.version };
323
- }
324
- async runCompatibilityProbes() {
325
- return this.probes;
326
- }
327
- acceptCompatibilityAttestation(attestation) {
328
- if (!isCompatibilityAttestation(attestation) ||
329
- attestation.surface !== this.identity.provider ||
330
- attestation.version !== this.version ||
331
- attestation.tier !== "incompatible" ||
332
- attestation.safeErrorCode !== this.safeErrorCode ||
333
- attestation.probes.length !== this.probes.length ||
334
- attestation.probes.some((probe, index) => probe.name !== this.probes[index]?.name ||
335
- probe.outcome !== this.probes[index]?.outcome ||
336
- probe.safeErrorCode !== this.probes[index]?.safeErrorCode)) {
337
- throw new BridgeError("INCOMPATIBLE_PROVIDER_ATTESTATION_MISMATCH", "The compatibility attestation does not match this disabled provider surface.");
338
- }
339
- }
340
- async initialize(_callbacks) {
341
- if (this.closed || this.initialized) {
342
- throw new BridgeError("INCOMPATIBLE_PROVIDER_UNAVAILABLE", "The disabled provider surface cannot be initialized again.");
343
- }
344
- this.initialized = true;
345
- return {
346
- health: "degraded",
347
- compatibility: "incompatible",
348
- safeErrorCode: this.safeErrorCode,
349
- };
350
- }
351
- async discoverClaudePeers() {
352
- throw this.unavailable();
353
- }
354
- async selectRoute(_input) {
355
- throw this.unavailable();
356
- }
357
- async assertWorkspaceDisjoint(_routeHandle, _stateRoot) {
358
- throw this.unavailable();
359
- }
360
- async resolveReplyAddress(_address) {
361
- throw this.unavailable();
362
- }
363
- async advertiseNativeCodexPeer(_input) {
364
- throw this.unavailable();
365
- }
366
- async dispatch(_input) {
367
- throw this.unavailable();
368
- }
369
- async releaseRoute(_routeHandle) { }
370
- async close() {
371
- this.closed = true;
372
- }
373
- unavailable() {
374
- return new BridgeError(this.safeErrorCode, "This provider surface is observation-only because its compatibility boundary did not pass.");
375
- }
376
- }
377
- export function createIncompatibleClaudeGatewayProvider(options) {
378
- validateClaudeRuntimePathEvidence(options.runtime);
379
- const [launcher, version, ...unobserved] = compatibilityProbeNames.claude;
380
- return new IncompatibleGatewayProvider({
381
- identity: {
382
- provider: "claude",
383
- hostId: LOCAL_HOST,
384
- endpointGeneration: STABLE_CLAUDE_ENDPOINT_GENERATION,
385
- },
386
- version: options.version,
387
- probes: [
388
- passedProbe(launcher),
389
- failedProbe(version, options.safeErrorCode),
390
- ...unobserved.map((name) => failedProbe(name, options.safeErrorCode)),
391
- ],
392
- safeErrorCode: options.safeErrorCode,
393
- });
394
- }
395
- export function createIncompatibleCodexGatewayProvider(options) {
396
- const [installation, ...unobserved] = compatibilityProbeNames.codex;
397
- return new IncompatibleGatewayProvider({
398
- identity: options.identity,
399
- version: options.version,
400
- probes: [
401
- passedProbe(installation),
402
- ...unobserved.map((name) => failedProbe(name, options.safeErrorCode)),
403
- ],
404
- safeErrorCode: options.safeErrorCode,
405
- });
406
- }
407
170
  export class LocalClaudeGatewayProvider {
408
171
  identity;
409
172
  protocol = "claude-peer";
410
173
  protocolVersion = `${CLAUDE_PEER_COMPATIBILITY.peerProtocol}`;
411
174
  peer;
412
- runtimeVersion;
413
175
  maxPending;
414
176
  discoveryPollMs;
415
177
  now;
416
178
  selectedStateRoots = new Map();
417
179
  nativeHelpers;
180
+ nativeHelperSourceProvider;
418
181
  discovered = new Map();
419
182
  selected = new Map();
420
183
  /** Exact live same-UID sessions observed through native inbound frames. */
@@ -448,25 +211,12 @@ export class LocalClaudeGatewayProvider {
448
211
  retiredNativeCodexListener;
449
212
  /** Fences discovery callbacks and monitor restarts across listener rotation. */
450
213
  nativeCodexSuccessionFreeze;
451
- /** A completed failed probe set fences every authority-bearing operation. */
452
- compatibilityBlocked = false;
453
- compatibilityFailureCode;
214
+ /** External registry trust/availability failures degrade Claude only. */
215
+ unavailableCode;
454
216
  initialized = false;
455
217
  closed = false;
456
218
  constructor(options) {
457
219
  validateAttestedClaudeRuntime(options.runtime);
458
- const compatibilityVersion = options.compatibilityVersion ??
459
- (options.runtime.claudeCodeVersion === UNKNOWN_COMPATIBILITY_VERSION
460
- ? options.runtime.launcherVersionEvidence
461
- : options.runtime.claudeCodeVersion);
462
- if (compatibilityVersion === undefined ||
463
- !isCompatibilityVersion(compatibilityVersion) ||
464
- (compatibilityVersion !== options.runtime.claudeCodeVersion &&
465
- !(options.runtime.claudeCodeVersion ===
466
- UNKNOWN_COMPATIBILITY_VERSION &&
467
- options.runtime.launcherVersionEvidence === compatibilityVersion))) {
468
- throw new BridgeError("CLAUDE_RUNTIME_ATTESTATION_INVALID", "Claude compatibility classification requires exact bounded launcher evidence.");
469
- }
470
220
  if (options.locale !== undefined && !isDashboardLocale(options.locale)) {
471
221
  throw new BridgeError("DASHBOARD_LOCALE_UNSUPPORTED", "The Claude provider notice locale is unsupported.");
472
222
  }
@@ -476,15 +226,12 @@ export class LocalClaudeGatewayProvider {
476
226
  hostId,
477
227
  endpointGeneration: STABLE_CLAUDE_ENDPOINT_GENERATION,
478
228
  };
479
- this.runtimeVersion = compatibilityVersion;
480
229
  this.maxPending = positiveBounded(options.maxPendingMessages, MAX_CLAUDE_PENDING, 4_096);
481
230
  this.discoveryPollMs = positiveBounded(options.discoveryPollMs, DEFAULT_CLAUDE_DISCOVERY_POLL_MS, 30_000);
482
231
  this.now = options.now ?? Date.now;
483
232
  const protocolRuntime = {
484
233
  claudeExecutable: options.runtime.claudeExecutable,
485
- claudeCodeVersion: options.runtime.claudeCodeVersion === UNKNOWN_COMPATIBILITY_VERSION
486
- ? options.runtime.launcherVersionEvidence
487
- : options.runtime.claudeCodeVersion,
234
+ claudeCodeVersion: options.runtime.claudeCodeVersion,
488
235
  sessionsDir: options.runtime.sessionsDir,
489
236
  socketDir: options.runtime.socketDir,
490
237
  };
@@ -506,60 +253,19 @@ export class LocalClaudeGatewayProvider {
506
253
  deliveryNotices: options.deliveryNotices ?? "merged",
507
254
  maxPendingMessages: this.maxPending,
508
255
  maxHelpers: positiveBounded(options.nativeHelpers.maxHelpers, 256, 128),
509
- callbacks: () => this.compatibilityBlocked ? undefined : this.callbacks,
256
+ callbacks: () => this.callbacks,
510
257
  ...(options.nativeHelpers.factory === undefined
511
258
  ? {}
512
259
  : { factory: options.nativeHelpers.factory }),
513
260
  });
514
- }
515
- compatibilitySurface() {
516
- return { surface: "claude", version: this.runtimeVersion };
517
- }
518
- async runCompatibilityProbes() {
519
- const [launcher, version, registry, socket, protocol] = compatibilityProbeNames.claude;
520
- try {
521
- const discovery = await this.peer.discover();
522
- this.registryObservation = claudeRegistryObservation(discovery);
523
- return [
524
- passedProbe(launcher),
525
- passedProbe(version),
526
- passedProbe(registry),
527
- passedProbe(socket),
528
- passedProbe(protocol),
529
- ];
530
- }
531
- catch (error) {
532
- if (!isClaudeRegistryAvailabilityError(error))
533
- throw error;
534
- this.registryObservation = unavailableClaudeRegistryObservation();
535
- // A missing or unreadable registry is provider-local incompatibility:
536
- // keep the broker and the other surface alive, but fence this provider
537
- // before listener construction can turn the same missing path into a
538
- // broker-wide startup failure.
539
- return [
540
- passedProbe(launcher),
541
- passedProbe(version),
542
- failedProbe(registry, "CLAUDE_REGISTRY_UNAVAILABLE"),
543
- failedProbe(socket, "CLAUDE_REGISTRY_UNAVAILABLE"),
544
- passedProbe(protocol),
545
- ];
546
- }
261
+ this.nativeHelperSourceProvider = options.nativeHelperSourceProvider;
547
262
  }
548
263
  latestRegistryObservation() {
549
264
  return this.registryObservation;
550
265
  }
551
- acceptCompatibilityAttestation(attestation) {
552
- if (!isCompatibilityAttestation(attestation) ||
553
- attestation.surface !== "claude" ||
554
- attestation.version !== this.runtimeVersion) {
555
- throw new BridgeError("CLAUDE_COMPATIBILITY_ATTESTATION_MISMATCH", "The Claude compatibility attestation does not match this runtime.");
556
- }
557
- this.compatibilityBlocked = attestation.tier === "incompatible";
558
- this.compatibilityFailureCode = attestation.safeErrorCode;
559
- if (this.compatibilityBlocked) {
560
- if (this.monitorTimer !== undefined)
561
- clearTimeout(this.monitorTimer);
562
- this.monitorTimer = undefined;
266
+ activateEndpointGeneration(endpointGeneration) {
267
+ if (endpointGeneration !== this.identity.endpointGeneration) {
268
+ throw new BridgeError("CLAUDE_ENDPOINT_ACTIVATION_MISMATCH", "Only the exact current Claude endpoint generation can be activated.");
563
269
  }
564
270
  }
565
271
  async initialize(callbacks) {
@@ -570,17 +276,9 @@ export class LocalClaudeGatewayProvider {
570
276
  throw new BridgeError("CLAUDE_PROVIDER_ALREADY_INITIALIZED", "The local Claude provider can be initialized only once.");
571
277
  }
572
278
  this.callbacks = callbacks;
573
- if (this.compatibilityBlocked) {
574
- this.initialized = true;
575
- return {
576
- health: "degraded",
577
- compatibility: "incompatible",
578
- safeErrorCode: this.compatibilityFailureCode ?? "CLAUDE_COMPATIBILITY_CHECK_FAILED",
579
- };
580
- }
581
279
  if (this.nativeHelpers !== undefined) {
582
280
  this.initialized = true;
583
- return { health: "healthy", compatibility: "compatible" };
281
+ return { health: "healthy" };
584
282
  }
585
283
  try {
586
284
  let listenerGeneration;
@@ -615,18 +313,16 @@ export class LocalClaudeGatewayProvider {
615
313
  }
616
314
  this.activeNativeCodexListener = listenerGeneration;
617
315
  this.initialized = true;
618
- return { health: "healthy", compatibility: "compatible" };
316
+ return { health: "healthy" };
619
317
  }
620
318
  catch (error) {
621
319
  if (error instanceof BridgeError &&
622
320
  error.code === "UNSAFE_PEER_DIRECTORY") {
623
- this.compatibilityBlocked = true;
624
- this.compatibilityFailureCode = "CLAUDE_REGISTRY_UNAVAILABLE";
321
+ this.unavailableCode = "CLAUDE_REGISTRY_UNAVAILABLE";
625
322
  this.registryObservation = unavailableClaudeRegistryObservation();
626
323
  this.initialized = true;
627
324
  return {
628
325
  health: "degraded",
629
- compatibility: "incompatible",
630
326
  safeErrorCode: "CLAUDE_REGISTRY_UNAVAILABLE",
631
327
  };
632
328
  }
@@ -671,12 +367,16 @@ export class LocalClaudeGatewayProvider {
671
367
  }
672
368
  return { routeHandle: resolved.targetId };
673
369
  }
674
- async advertiseNativeCodexPeer(input) {
370
+ async advertiseNativeSourcePeer(input) {
675
371
  if (this.nativeHelpers !== undefined) {
676
372
  this.assertReady();
677
373
  await this.nativeHelpers.advertise(input);
678
374
  return;
679
375
  }
376
+ if (input.sourceProvider !== "codex" &&
377
+ input.sourceProvider !== this.nativeHelperSourceProvider) {
378
+ throw new BridgeError("CLAUDE_NATIVE_HELPER_UNAVAILABLE", "A non-Codex source requires a supervised native Claude helper.", true);
379
+ }
680
380
  const registration = this.nativeCodexRegistration(input);
681
381
  await this.serializeNativeCodexRegistration(async () => {
682
382
  this.assertReady();
@@ -763,7 +463,7 @@ export class LocalClaudeGatewayProvider {
763
463
  this.retiredNativeCodexListener !== undefined) {
764
464
  throw new BridgeError("CODEX_PEER_SUCCESSION_CAPACITY", "Only one distinct prepared or retired Codex generation is allowed.");
765
465
  }
766
- const registration = this.nativeCodexRegistration(input);
466
+ const registration = this.nativeCodexRegistration({ ...input, sourceProvider: "codex" });
767
467
  this.nativeCodexPreparationInFlight = input.generation;
768
468
  let prepared;
769
469
  try {
@@ -1027,7 +727,7 @@ export class LocalClaudeGatewayProvider {
1027
727
  }
1028
728
  return purged;
1029
729
  }
1030
- async unadvertiseNativeCodexPeer(alias) {
730
+ async unadvertiseNativeSourcePeer(alias) {
1031
731
  if (this.nativeHelpers !== undefined) {
1032
732
  await this.nativeHelpers.unadvertise(alias);
1033
733
  return;
@@ -1043,7 +743,7 @@ export class LocalClaudeGatewayProvider {
1043
743
  active.provisionalIngressForwarded = false;
1044
744
  });
1045
745
  }
1046
- async updateNativeCodexPeerStatus(alias, status) {
746
+ async updateNativeSourcePeerStatus(alias, status) {
1047
747
  if (this.nativeHelpers !== undefined) {
1048
748
  await this.nativeHelpers.updateStatus(alias, status);
1049
749
  return;
@@ -1105,10 +805,10 @@ export class LocalClaudeGatewayProvider {
1105
805
  active.inboundQuiesced = true;
1106
806
  }
1107
807
  async dispatch(input) {
1108
- if (this.compatibilityBlocked) {
808
+ if (this.unavailableCode !== undefined) {
1109
809
  return {
1110
810
  state: "failed",
1111
- safeErrorCode: this.compatibilityFailureCode ?? "CLAUDE_COMPATIBILITY_CHECK_FAILED",
811
+ safeErrorCode: this.unavailableCode,
1112
812
  };
1113
813
  }
1114
814
  if (this.nativeHelpers !== undefined) {
@@ -1182,7 +882,8 @@ export class LocalClaudeGatewayProvider {
1182
882
  return { state: "failed", safeErrorCode: "CLAUDE_ROUTE_UNAVAILABLE" };
1183
883
  }
1184
884
  }
1185
- if (activeListener.registration?.alias !== input.sourceAlias) {
885
+ if (activeListener.registration?.alias !== input.sourceAlias ||
886
+ activeListener.registration.sourceProvider !== input.sourceProvider) {
1186
887
  return { state: "failed", safeErrorCode: "CLAUDE_ROUTE_UNAVAILABLE" };
1187
888
  }
1188
889
  if (this.activeNativeCodexListener !== activeListener ||
@@ -1201,7 +902,8 @@ export class LocalClaudeGatewayProvider {
1201
902
  let content;
1202
903
  try {
1203
904
  content = composeProvenanceEnvelope({
1204
- direction: "claude",
905
+ sourceProvider: input.sourceProvider,
906
+ recipientProvider: this.identity.provider,
1205
907
  sourceAlias: input.sourceAlias,
1206
908
  targetAlias: input.targetAlias,
1207
909
  conversationId: input.conversationId,
@@ -1392,7 +1094,7 @@ export class LocalClaudeGatewayProvider {
1392
1094
  }
1393
1095
  }
1394
1096
  assertReady() {
1395
- if (!this.initialized || this.closed || this.compatibilityBlocked) {
1097
+ if (!this.initialized || this.closed || this.unavailableCode !== undefined) {
1396
1098
  throw new BridgeError("CLAUDE_PROVIDER_UNAVAILABLE", "The local Claude provider is not available.", true);
1397
1099
  }
1398
1100
  }
@@ -1407,13 +1109,14 @@ export class LocalClaudeGatewayProvider {
1407
1109
  throw new BridgeError("INVALID_CODEX_PEER_ALIAS", "The native Codex peer alias must target this host.");
1408
1110
  }
1409
1111
  const name = input.alias.slice(0, -suffix.length);
1410
- if (!name.startsWith("codex-") || !NATIVE_CLAUDE_NAME.test(name)) {
1411
- throw new BridgeError("INVALID_CODEX_PEER_ALIAS", "The native Codex peer alias must start with codex-.");
1112
+ const prefix = gatewayRegistrationIngressPrefixes[input.sourceProvider];
1113
+ if (prefix === undefined || !name.startsWith(prefix) || !NATIVE_CLAUDE_NAME.test(name)) {
1114
+ throw new BridgeError("INVALID_CODEX_PEER_ALIAS", "The native source peer alias must use its provider prefix.");
1412
1115
  }
1413
1116
  if (!path.isAbsolute(input.cwd) || input.cwd.includes("\0")) {
1414
1117
  throw new BridgeError("INVALID_CODEX_PEER_CWD", "A native Codex peer requires an absolute working directory.");
1415
1118
  }
1416
- return { alias: input.alias, cwd: input.cwd, name };
1119
+ return { alias: input.alias, sourceProvider: input.sourceProvider, cwd: input.cwd, name };
1417
1120
  }
1418
1121
  requireActiveNativeCodexListener() {
1419
1122
  this.assertReady();
@@ -1451,7 +1154,7 @@ export class LocalClaudeGatewayProvider {
1451
1154
  await this.rejectNativeInboundReceipt(listenerGeneration, message.receiptHandle, diagnosticCode);
1452
1155
  }
1453
1156
  };
1454
- if (this.compatibilityBlocked ||
1157
+ if (this.unavailableCode !== undefined ||
1455
1158
  this.closed ||
1456
1159
  listenerGeneration.listener.closed ||
1457
1160
  !this.ownsNativeCodexListener(listenerGeneration)) {
@@ -1801,7 +1504,6 @@ export class LocalClaudeGatewayProvider {
1801
1504
  routeHandle: peer.targetId,
1802
1505
  kind: "interactive",
1803
1506
  state: claudeRouteState(peer),
1804
- compatibility: "compatible",
1805
1507
  };
1806
1508
  this.discovered.set(peer.targetId, row);
1807
1509
  rows.push(row);
@@ -1891,65 +1593,15 @@ export class LocalClaudeGatewayProvider {
1891
1593
  export function createLocalClaudeGatewayProvider(options) {
1892
1594
  return new LocalClaudeGatewayProvider(options);
1893
1595
  }
1894
- function codexVersionFailureCode(version) {
1895
- if (version === UNKNOWN_COMPATIBILITY_VERSION) {
1896
- return "CODEX_APP_SERVER_VERSION_UNPARSEABLE";
1897
- }
1898
- if (!isCompatibilityVersion(version)) {
1899
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The local Codex factory version evidence is malformed.");
1900
- }
1901
- return CODEX_APP_SERVER_WRITABLE_VERSIONS.some((certifiedVersion) => sharesCompatibilityMajor(certifiedVersion, version))
1902
- ? undefined
1903
- : "CODEX_APP_SERVER_VERSION_UNSUPPORTED";
1904
- }
1905
- function validateCodexFactory(factory, options = {}) {
1906
- const schema = factory.schemaCompatibility;
1907
- const write = factory.writeCompatibility;
1908
- const versionFailure = codexVersionFailureCode(factory.appServerVersion);
1909
- const certified = CODEX_APP_SERVER_WRITABLE_VERSIONS.includes(factory.appServerVersion);
1910
- const schemaCandidate = schema.observedSchemaCandidate === true &&
1911
- CODEX_APP_SERVER_WRITABLE_VERSIONS.some((version) => sharesCompatibilityMajor(version, factory.appServerVersion));
1912
- const unsupportedVersionInvalid = versionFailure !== undefined &&
1913
- (options.allowUnsupportedVersion !== true ||
1914
- write !== null ||
1915
- factory.writableReady);
1916
- const supportedSchemaInvalid = versionFailure === undefined &&
1917
- ((!certified &&
1918
- (!schemaCandidate || write !== null || factory.writableReady)) ||
1919
- schema.protocol !== "app-server-v2-stable" ||
1920
- schema.steering?.method !== "turn/steer" ||
1921
- schema.steering.requestSchema !== "expected-turn-id-text-v1" ||
1922
- schema.steering.deliveryBoundary !== "next-tool-call-boundary" ||
1923
- (write !== null &&
1924
- (write.appServerVersion !== schema.appServerVersion ||
1925
- write.endpointGeneration !== schema.endpointGeneration ||
1926
- write.protocol !== schema.protocol ||
1927
- write.observedSchemaCandidate !== schema.observedSchemaCandidate ||
1928
- write.steering?.method !== schema.steering.method ||
1929
- write.steering.requestSchema !== schema.steering.requestSchema ||
1930
- write.steering.deliveryBoundary !==
1931
- schema.steering.deliveryBoundary)) ||
1932
- factory.writableReady !== (write !== null));
1596
+ function validateCodexFactory(factory) {
1933
1597
  if (factory.hostId !== LOCAL_HOST ||
1934
1598
  factory.protocol !== "codex-app-server" ||
1935
1599
  factory.protocolVersion !== factory.appServerVersion ||
1936
- schema.appServerVersion !== factory.appServerVersion ||
1937
- schema.endpointGeneration !== factory.endpointGeneration ||
1938
- unsupportedVersionInvalid ||
1939
- supportedSchemaInvalid) {
1940
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The local Codex provider requires exact schema and write attestations.");
1600
+ factory.appServerVersion.length === 0 ||
1601
+ factory.endpointGeneration.length === 0) {
1602
+ throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The local Codex provider requires exact managed endpoint identity.");
1941
1603
  }
1942
1604
  }
1943
- function codexFactoryWritesEnabled(factory, attestation, writeProbePassed = false) {
1944
- return ((attestation.tier === "certified" &&
1945
- CODEX_APP_SERVER_WRITABLE_VERSIONS.includes(attestation.version) &&
1946
- factory.writableReady &&
1947
- factory.writeCompatibility !== null) ||
1948
- (!factory.writableReady &&
1949
- factory.writeCompatibility === null &&
1950
- writeProbePassed &&
1951
- compatibilityCoversWrites(attestation)));
1952
- }
1953
1605
  function codexRouteState(observation) {
1954
1606
  if (observation.connection !== "ready")
1955
1607
  return "stale";
@@ -1971,9 +1623,6 @@ function codexRouteSafeCode(observation) {
1971
1623
  if (codexRouteState(observation) === "stale") {
1972
1624
  return "CODEX_ROUTE_STALE";
1973
1625
  }
1974
- if (!observation.writableReady) {
1975
- return "CODEX_WRITES_DISABLED";
1976
- }
1977
1626
  return undefined;
1978
1627
  }
1979
1628
  export class LocalCodexGatewayProvider {
@@ -2007,14 +1656,7 @@ export class LocalCodexGatewayProvider {
2007
1656
  endpointActivationRetry;
2008
1657
  endpointActivationRetryTimer;
2009
1658
  callbackDrainFrozen = false;
2010
- writeProbeObservationsByGeneration = new Map();
2011
- writeProbeResults = new Map();
2012
- writeProbeDecline;
2013
- writeProbeOverflow;
2014
- compatibilityAttested;
2015
- compatibilityFailureCode;
2016
1659
  endpointUnavailable = false;
2017
- pendingEndpointAttestation;
2018
1660
  pendingEndpointRefreshEvent;
2019
1661
  pendingEndpointRefreshSelectorClaimed = false;
2020
1662
  initialized = false;
@@ -2025,9 +1667,6 @@ export class LocalCodexGatewayProvider {
2025
1667
  this.factory = options.factory;
2026
1668
  this.refreshFactory = options.refreshFactory;
2027
1669
  exactLocalHost(options.factory.hostId);
2028
- this.compatibilityAttested =
2029
- options.factory.writableReady &&
2030
- options.factory.writeCompatibility !== null;
2031
1670
  this.maxCallbacks = positiveBounded(options.maxCallbackEvents, MAX_CODEX_CALLBACKS, 4_096);
2032
1671
  this.maxRoutes = positiveBounded(options.maxRoutes, MAX_CODEX_ROUTES, 256);
2033
1672
  this.maxReplyBytes = positiveBounded(options.maxReplyBytes, MAX_TRANSIENT_REPLY_BYTES, 1024 * 1024);
@@ -2056,352 +1695,39 @@ export class LocalCodexGatewayProvider {
2056
1695
  get protocolVersion() {
2057
1696
  return this.factory.protocolVersion;
2058
1697
  }
2059
- compatibilitySurface() {
2060
- return { surface: "codex", version: this.factory.appServerVersion };
2061
- }
2062
- acceptCompatibilityAttestation(attestation) {
2063
- const pending = this.pendingEndpointAttestation;
2064
- const pendingMatches = pending === undefined ||
2065
- (attestation.checkedAt === pending.checkedAt &&
2066
- attestation.tier === pending.tier &&
2067
- attestation.safeErrorCode === pending.safeErrorCode &&
2068
- attestation.probes.length === pending.probes.length &&
2069
- attestation.probes.every((probe, index) => probe.name === pending.probes[index]?.name &&
2070
- probe.outcome === pending.probes[index]?.outcome &&
2071
- probe.safeErrorCode === pending.probes[index]?.safeErrorCode));
2072
- if (!isCompatibilityAttestation(attestation) ||
2073
- attestation.surface !== "codex" ||
2074
- attestation.version !== this.factory.appServerVersion ||
2075
- !pendingMatches) {
2076
- throw new BridgeError("CODEX_COMPATIBILITY_ATTESTATION_MISMATCH", "The Codex compatibility attestation does not match this endpoint.");
2077
- }
2078
- if (attestation.tier === "incompatible") {
2079
- this.pendingEndpointAttestation = undefined;
2080
- this.pendingEndpointRefreshEvent = undefined;
2081
- this.pendingEndpointRefreshSelectorClaimed = false;
2082
- this.clearEndpointActivationRetry();
2083
- this.compatibilityAttested = false;
2084
- this.endpointUnavailable = true;
2085
- this.compatibilityFailureCode =
2086
- attestation.safeErrorCode ?? "CODEX_COMPATIBILITY_CHECK_FAILED";
2087
- return;
2088
- }
2089
- const writesEnabled = codexFactoryWritesEnabled(this.factory, attestation, this.latestWriteCompatibilityProbeObservation(this.factory.endpointGeneration)?.outcome === "pass");
2090
- const schemaObserved = attestation.tier === "schema_attested" &&
2091
- !this.factory.writableReady &&
2092
- this.factory.writeCompatibility === null;
2093
- if ((!writesEnabled && !schemaObserved) ||
2094
- (this.endpointUnavailable && pending === undefined) ||
2095
- !pendingMatches) {
2096
- throw new BridgeError("CODEX_COMPATIBILITY_ATTESTATION_MISMATCH", "The Codex compatibility attestation does not match this endpoint.");
1698
+ activateEndpointGeneration(endpointGeneration) {
1699
+ const event = this.pendingEndpointRefreshEvent;
1700
+ if (event === undefined ||
1701
+ event.current.endpointGeneration !== endpointGeneration ||
1702
+ this.factory.endpointGeneration !== endpointGeneration) {
1703
+ throw new BridgeError("CODEX_ENDPOINT_ACTIVATION_MISMATCH", "Only the exact pending managed Codex generation can be activated.");
2097
1704
  }
2098
- this.pendingEndpointAttestation = undefined;
2099
1705
  this.pendingEndpointRefreshEvent = undefined;
2100
1706
  this.pendingEndpointRefreshSelectorClaimed = false;
2101
1707
  this.clearEndpointActivationRetry();
2102
- this.compatibilityAttested = writesEnabled;
2103
- this.endpointUnavailable = !writesEnabled;
2104
- this.compatibilityFailureCode = undefined;
1708
+ this.endpointUnavailable = false;
2105
1709
  }
2106
1710
  releaseEndpointRefreshSelectorClaim(endpointGeneration) {
2107
1711
  const event = this.pendingEndpointRefreshEvent;
2108
- if (event?.current.endpointGeneration === endpointGeneration &&
2109
- this.pendingEndpointAttestation !== undefined) {
1712
+ if (event?.current.endpointGeneration === endpointGeneration) {
2110
1713
  this.pendingEndpointRefreshSelectorClaimed = false;
2111
1714
  }
2112
1715
  }
2113
1716
  rearmEndpointRefreshActivation(endpointGeneration) {
2114
1717
  const event = this.pendingEndpointRefreshEvent;
2115
1718
  if (event?.current.endpointGeneration === endpointGeneration &&
2116
- this.pendingEndpointAttestation !== undefined &&
2117
1719
  !this.closing &&
2118
1720
  !this.closed) {
2119
1721
  this.publishEndpointRefresh(event);
2120
1722
  }
2121
1723
  }
2122
- latestWriteCompatibilityProbeObservation(endpointGeneration) {
2123
- return (this.writeProbeObservationsByGeneration.get(endpointGeneration) ??
2124
- (this.writeProbeOverflow?.endpointGeneration === endpointGeneration
2125
- ? this.writeProbeOverflow.observation
2126
- : undefined) ??
2127
- (this.writeProbeDecline?.endpointGeneration === endpointGeneration
2128
- ? this.writeProbeDecline.observation
2129
- : undefined));
2130
- }
2131
- async runCompatibilityProbes(context) {
2132
- return await this.runCompatibilityProbesFor(this.factory, context === undefined
2133
- ? undefined
2134
- : {
2135
- stateRoot: path.resolve(context.stateRoot),
2136
- forbiddenCodexThreadIds: [...context.forbiddenCodexThreadIds],
2137
- });
2138
- }
2139
- async runCompatibilityProbesFor(factory, context) {
2140
- const [installation, control, initialize, threadList] = compatibilityProbeNames.codex;
2141
- let transport;
2142
- let connector;
2143
- let stage = "transport";
2144
- try {
2145
- transport = await factory.connectTransport();
2146
- stage = "initialize";
2147
- connector = await CodexAppServerConnector.connect({
2148
- compatibility: factory.schemaCompatibility,
2149
- ...(context === undefined
2150
- ? {}
2151
- : { writeCompatibilityProbe: true }),
2152
- writesEnabled: false,
2153
- route: {
2154
- endpointGeneration: factory.endpointGeneration,
2155
- threadId: COMPATIBILITY_PROBE_THREAD_ID,
2156
- },
2157
- transport,
2158
- maxReplyBytes: this.maxReplyBytes,
2159
- now: this.now,
2160
- onEvent: () => undefined,
2161
- onTurnResult: () => undefined,
2162
- });
2163
- stage = "thread_list";
2164
- await connector.observeLoadedThread(connector.guard());
2165
- const requiredProbes = [
2166
- passedProbe(installation),
2167
- passedProbe(control),
2168
- passedProbe(initialize),
2169
- passedProbe(threadList),
2170
- ];
2171
- if (context === undefined)
2172
- return requiredProbes;
2173
- const result = await this.runCodexWriteProbe(factory, connector, context);
2174
- return result.outcome === "pass"
2175
- ? [...requiredProbes, passedProbe("write_attestation")]
2176
- : requiredProbes;
2177
- }
2178
- catch (error) {
2179
- if (this.isEndpointGenerationChanged(error) ||
2180
- (error instanceof BridgeError &&
2181
- error.code === "CODEX_FACTORY_ATTESTATION_INVALID")) {
2182
- throw error;
2183
- }
2184
- if (stage === "transport") {
2185
- const availabilityFailure = error instanceof LocalCodexTransportError &&
2186
- [
2187
- "MANAGED_CODEX_UNAVAILABLE",
2188
- "LOCAL_APP_SERVER_NOT_RUNNING",
2189
- "SPAWN_FAILED",
2190
- "SPAWN_TIMEOUT",
2191
- "PROXY_STDERR_LIMIT",
2192
- "TRANSPORT_CONNECT_FAILED",
2193
- ].includes(error.code);
2194
- if (!availabilityFailure)
2195
- throw error;
2196
- const installationUnavailable = error instanceof LocalCodexTransportError &&
2197
- error.code === "MANAGED_CODEX_UNAVAILABLE";
2198
- return [
2199
- installationUnavailable
2200
- ? failedProbe(installation, "CODEX_INSTALLATION_INVALID")
2201
- : passedProbe(installation),
2202
- failedProbe(control, installationUnavailable
2203
- ? "CODEX_COMPAT_PROBE_BLOCKED"
2204
- : "CODEX_CONTROL_SOCKET_UNAVAILABLE"),
2205
- failedProbe(initialize, "CODEX_COMPAT_PROBE_BLOCKED"),
2206
- failedProbe(threadList, "CODEX_COMPAT_PROBE_BLOCKED"),
2207
- ];
2208
- }
2209
- return [
2210
- passedProbe(installation),
2211
- passedProbe(control),
2212
- stage === "initialize"
2213
- ? failedProbe(initialize, "CODEX_INITIALIZE_SCHEMA_REJECTED")
2214
- : passedProbe(initialize),
2215
- failedProbe(threadList, "CODEX_THREAD_LIST_SCHEMA_REJECTED"),
2216
- ];
2217
- }
2218
- finally {
2219
- if (connector !== undefined) {
2220
- await connector.close();
2221
- }
2222
- else if (transport !== undefined) {
2223
- await transport.close();
2224
- }
2225
- }
2226
- }
2227
- async runCodexWriteProbe(factory, connector, context) {
2228
- const key = `${factory.appServerVersion}\0${factory.endpointGeneration}`;
2229
- const cached = this.writeProbeResults.get(key);
2230
- if (cached !== undefined)
2231
- return await cached;
2232
- if (this.writeProbeOverflow?.key === key) {
2233
- if (this.writeProbeResults.size >= MAX_CODEX_WRITE_PROBE_ATTEMPTS) {
2234
- return this.writeProbeOverflow.observation;
2235
- }
2236
- this.writeProbeOverflow = undefined;
2237
- }
2238
- if (this.writeProbeResults.size >= MAX_CODEX_WRITE_PROBE_ATTEMPTS) {
2239
- const observation = Object.freeze(codexWriteProbeFailure("CODEX_WRITE_PROBE_CAPACITY_EXHAUSTED"));
2240
- this.writeProbeOverflow = Object.freeze({
2241
- endpointGeneration: factory.endpointGeneration,
2242
- key,
2243
- observation,
2244
- });
2245
- if (this.callbacks !== undefined) {
2246
- invokeCallback(() => this.callbacks?.onProtocolNotice?.({
2247
- code: observation.safeErrorCode,
2248
- }));
2249
- }
2250
- return observation;
2251
- }
2252
- const pending = this.executeCodexWriteProbe(connector, context).then((result) => {
2253
- const observation = Object.freeze({ ...result });
2254
- if (observation.outcome === "fail" &&
2255
- (observation.safeErrorCode ===
2256
- "CODEX_WRITE_PROBE_MODEL_PIN_UNAVAILABLE" ||
2257
- observation.safeErrorCode ===
2258
- "CODEX_WRITE_PROBE_RATE_LIMIT_CONSTRAINED")) {
2259
- this.writeProbeResults.delete(key);
2260
- this.writeProbeDecline = Object.freeze({
2261
- endpointGeneration: factory.endpointGeneration,
2262
- observation,
2263
- });
2264
- }
2265
- else {
2266
- this.writeProbeObservationsByGeneration.set(factory.endpointGeneration, observation);
2267
- }
2268
- if (observation.outcome === "fail" && this.callbacks !== undefined) {
2269
- invokeCallback(() => this.callbacks?.onProtocolNotice?.({
2270
- code: observation.safeErrorCode,
2271
- }));
2272
- }
2273
- return observation;
2274
- });
2275
- this.writeProbeResults.set(key, pending);
2276
- return await pending;
2277
- }
2278
- async executeCodexWriteProbe(connector, context) {
2279
- const stateRoot = path.resolve(context.stateRoot);
2280
- const rootBefore = await attestCodexWriteProbeRoot(stateRoot);
2281
- if (rootBefore === null) {
2282
- return codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED");
2283
- }
2284
- const probeRoot = path.join(stateRoot, CODEX_WRITE_PROBE_ROOT);
2285
- let probeRootBefore;
2286
- try {
2287
- let created = false;
2288
- try {
2289
- await mkdir(probeRoot, { mode: 0o700 });
2290
- created = true;
2291
- }
2292
- catch (error) {
2293
- if (systemErrorCode(error) !== "EEXIST")
2294
- throw error;
2295
- }
2296
- if (created)
2297
- await chmod(probeRoot, 0o700);
2298
- const evidence = await attestCodexWriteProbeRoot(probeRoot);
2299
- if (evidence === null) {
2300
- return codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED");
2301
- }
2302
- probeRootBefore = evidence;
2303
- }
2304
- catch (error) {
2305
- if (error instanceof BridgeError &&
2306
- error.code === "CODEX_FACTORY_ATTESTATION_INVALID") {
2307
- throw error;
2308
- }
2309
- if (transientCodexWriteProbeError(error)) {
2310
- return codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED");
2311
- }
2312
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The controller-owned Codex probe root could not be established safely.");
2313
- }
2314
- let cwd;
2315
- let before;
2316
- let result = codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED");
2317
- try {
2318
- cwd = await mkdtemp(path.join(probeRoot, CODEX_WRITE_PROBE_DIRECTORY_PREFIX));
2319
- if (path.dirname(cwd) !== probeRoot) {
2320
- throw new Error("probe directory escaped its dedicated root");
2321
- }
2322
- await chmod(cwd, 0o700);
2323
- before = await attestCodexWriteProbeDirectory(cwd);
2324
- result = await connector.runWriteCompatibilityProbe({
2325
- cwd,
2326
- forbiddenThreadIds: [
2327
- ...new Set([
2328
- COMPATIBILITY_PROBE_THREAD_ID,
2329
- ...context.forbiddenCodexThreadIds,
2330
- ...this.trackedRoutes,
2331
- ]),
2332
- ],
2333
- });
2334
- }
2335
- catch (error) {
2336
- if (!safeCodexWriteProbeFilesystemFailure(error)) {
2337
- if (error instanceof BridgeError)
2338
- throw error;
2339
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The disposable Codex probe directory could not be established safely.");
2340
- }
2341
- result = codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED");
2342
- }
2343
- let unchanged = false;
2344
- let removed = false;
2345
- if (cwd !== undefined && before !== undefined) {
2346
- try {
2347
- const after = await attestCodexWriteProbeDirectory(cwd);
2348
- unchanged = sameCodexWriteProbeDirectory(before, after);
2349
- await rmdir(cwd);
2350
- try {
2351
- await lstat(cwd);
2352
- }
2353
- catch (error) {
2354
- removed = systemErrorCode(error) === "ENOENT";
2355
- }
2356
- }
2357
- catch (error) {
2358
- if (!safeCodexWriteProbeFilesystemFailure(error)) {
2359
- if (error instanceof BridgeError)
2360
- throw error;
2361
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The disposable Codex probe directory could not be re-attested safely.");
2362
- }
2363
- // Never remove a path after its exact ownership evidence changed.
2364
- }
2365
- }
2366
- if (cwd !== undefined && !removed) {
2367
- result = codexWriteProbeFailure("CODEX_WRITE_PROBE_CLEANUP_UNCONFIRMED", result);
2368
- }
2369
- else if (cwd !== undefined && !unchanged) {
2370
- result = codexWriteProbeFailure("CODEX_WRITE_PROBE_TOOL_ACTIVITY_OBSERVED", result);
2371
- }
2372
- const [probeRootAfter, rootAfter] = await Promise.all([
2373
- attestCodexWriteProbeRoot(probeRoot),
2374
- attestCodexWriteProbeRoot(stateRoot),
2375
- ]);
2376
- if (probeRootAfter === null || rootAfter === null) {
2377
- return codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED", result);
2378
- }
2379
- if (!sameCodexWriteProbeRoot(probeRootBefore, probeRootAfter) ||
2380
- !sameCodexWriteProbeRoot(rootBefore, rootAfter)) {
2381
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "A controller-owned Codex probe root changed while the disposable probe ran.");
2382
- }
2383
- return result;
2384
- }
2385
1724
  async initialize(callbacks) {
2386
1725
  if (this.closed || this.initialized) {
2387
1726
  throw new BridgeError("CODEX_PROVIDER_INITIALIZATION_REJECTED", "The local Codex provider cannot be initialized in this state.");
2388
1727
  }
2389
1728
  this.callbacks = callbacks;
2390
1729
  this.initialized = true;
2391
- if (this.compatibilityFailureCode !== undefined) {
2392
- return {
2393
- health: "degraded",
2394
- compatibility: "incompatible",
2395
- safeErrorCode: this.compatibilityFailureCode,
2396
- };
2397
- }
2398
- return !this.compatibilityAttested
2399
- ? {
2400
- health: "degraded",
2401
- compatibility: "compatible",
2402
- safeErrorCode: "CODEX_MONITOR_ONLY",
2403
- }
2404
- : { health: "healthy", compatibility: "compatible" };
1730
+ return { health: "healthy" };
2405
1731
  }
2406
1732
  async selectRoute(input) {
2407
1733
  if (!this.initialized || this.closing || this.closed) {
@@ -2423,9 +1749,8 @@ export class LocalCodexGatewayProvider {
2423
1749
  let selectorRefreshReserved = false;
2424
1750
  let route;
2425
1751
  const stageRefreshedRoute = async (result) => {
2426
- if (result === undefined ||
2427
- result.event.outcome !== "compatible") {
2428
- throw new BridgeError("CODEX_ROUTE_SETUP_REJECTED", "The exact Codex endpoint replacement was not compatibility-attested.");
1752
+ if (result === undefined) {
1753
+ throw new BridgeError("CODEX_ROUTE_SETUP_REJECTED", "The exact Codex endpoint replacement could not be established.");
2429
1754
  }
2430
1755
  refreshResult = result;
2431
1756
  selectorRefreshReserved = this.reserveSelectorRefresh(result);
@@ -2448,7 +1773,7 @@ export class LocalCodexGatewayProvider {
2448
1773
  route = await stageRefreshedRoute(retainedEndpointRefresh);
2449
1774
  }
2450
1775
  else if (this.endpointUnavailable &&
2451
- this.pendingEndpointAttestation === undefined) {
1776
+ this.pendingEndpointRefreshEvent === undefined) {
2452
1777
  route = await stageRefreshedRoute(await this.refreshEndpoint("selector"));
2453
1778
  }
2454
1779
  else {
@@ -2566,7 +1891,6 @@ export class LocalCodexGatewayProvider {
2566
1891
  this.closed ||
2567
1892
  this.endpointUnavailable ||
2568
1893
  this.endpointRefresh !== undefined ||
2569
- !this.compatibilityAttested ||
2570
1894
  input.authorization !== "selected_route" ||
2571
1895
  !sameEndpoint(input.binding, this.identity)) {
2572
1896
  return { state: "failed", safeErrorCode: "CODEX_ROUTE_UNAVAILABLE" };
@@ -2580,9 +1904,6 @@ export class LocalCodexGatewayProvider {
2580
1904
  return { state: "failed", safeErrorCode: "CODEX_ROUTE_UNAVAILABLE" };
2581
1905
  }
2582
1906
  const guard = route.connector.guard();
2583
- if (!guard.writableReady) {
2584
- return { state: "failed", safeErrorCode: "CODEX_WRITES_DISABLED" };
2585
- }
2586
1907
  if (strictDeadline(input.deadlineAt, this.now().getTime()) === undefined) {
2587
1908
  return { state: "failed", safeErrorCode: "MESSAGE_EXPIRED" };
2588
1909
  }
@@ -2592,7 +1913,8 @@ export class LocalCodexGatewayProvider {
2592
1913
  let content;
2593
1914
  try {
2594
1915
  content = composeProvenanceEnvelope({
2595
- direction: "codex",
1916
+ sourceProvider: input.sourceProvider,
1917
+ recipientProvider: this.identity.provider,
2596
1918
  sourceAlias: input.sourceAlias,
2597
1919
  targetAlias: input.targetAlias,
2598
1920
  conversationId: input.conversationId,
@@ -2702,7 +2024,6 @@ export class LocalCodexGatewayProvider {
2702
2024
  this.clearEndpointActivationRetry();
2703
2025
  this.pendingEndpointRefreshEvent = undefined;
2704
2026
  this.pendingEndpointRefreshSelectorClaimed = false;
2705
- this.pendingEndpointAttestation = undefined;
2706
2027
  const refreshResult = this.endpointRefresh === undefined
2707
2028
  ? []
2708
2029
  : await Promise.allSettled([this.endpointRefresh]);
@@ -2728,7 +2049,6 @@ export class LocalCodexGatewayProvider {
2728
2049
  this.closed = true;
2729
2050
  this.closing = false;
2730
2051
  this.callbackQueue.length = 0;
2731
- this.pendingEndpointAttestation = undefined;
2732
2052
  this.pendingEndpointRefreshEvent = undefined;
2733
2053
  this.pendingEndpointRefreshSelectorClaimed = false;
2734
2054
  this.trackedRoutes.clear();
@@ -2741,13 +2061,12 @@ export class LocalCodexGatewayProvider {
2741
2061
  this.closing ||
2742
2062
  this.closed ||
2743
2063
  this.endpointUnavailable ||
2744
- this.endpointRefresh !== undefined ||
2745
- !this.compatibilityAttested) {
2064
+ this.endpointRefresh !== undefined) {
2746
2065
  throw new BridgeError("CODEX_PROVIDER_UNAVAILABLE", "The local Codex provider is unavailable.", true);
2747
2066
  }
2748
2067
  }
2749
- async ensureRoute(threadId, queueInitialObservation = true, allowPendingEndpointAttestation = false) {
2750
- if (allowPendingEndpointAttestation) {
2068
+ async ensureRoute(threadId, queueInitialObservation = true, allowPendingEndpointActivation = false) {
2069
+ if (allowPendingEndpointActivation) {
2751
2070
  if (!this.initialized || this.closing || this.closed) {
2752
2071
  throw new BridgeError("CODEX_PROVIDER_UNAVAILABLE", "The local Codex provider is unavailable.", true);
2753
2072
  }
@@ -2758,7 +2077,7 @@ export class LocalCodexGatewayProvider {
2758
2077
  const pendingRelease = this.routeReleases.get(threadId);
2759
2078
  if (pendingRelease !== undefined) {
2760
2079
  await pendingRelease;
2761
- return await this.ensureRoute(threadId, queueInitialObservation, allowPendingEndpointAttestation);
2080
+ return await this.ensureRoute(threadId, queueInitialObservation, allowPendingEndpointActivation);
2762
2081
  }
2763
2082
  const existing = this.routes.get(threadId);
2764
2083
  if (existing !== undefined) {
@@ -2770,7 +2089,7 @@ export class LocalCodexGatewayProvider {
2770
2089
  // a fresh one. The identity-checked release lets automatic recovery and
2771
2090
  // an explicit selector join the same cleanup safely.
2772
2091
  await this.releaseRouteInternal(threadId);
2773
- return await this.ensureRoute(threadId, queueInitialObservation, allowPendingEndpointAttestation);
2092
+ return await this.ensureRoute(threadId, queueInitialObservation, allowPendingEndpointActivation);
2774
2093
  }
2775
2094
  const pending = this.routeCreations.get(threadId);
2776
2095
  if (pending !== undefined)
@@ -2780,14 +2099,12 @@ export class LocalCodexGatewayProvider {
2780
2099
  }
2781
2100
  const admittedFactory = this.factory;
2782
2101
  const creation = (async () => {
2783
- const route = await this.createRoute(threadId, admittedFactory, queueInitialObservation, this.pendingEndpointAttestation === undefined
2784
- ? this.compatibilityAttested
2785
- : codexFactoryWritesEnabled(admittedFactory, this.pendingEndpointAttestation, this.latestWriteCompatibilityProbeObservation(admittedFactory.endpointGeneration)?.outcome === "pass"));
2102
+ const route = await this.createRoute(threadId, admittedFactory, queueInitialObservation);
2786
2103
  if (this.closing || this.closed) {
2787
2104
  await this.closeRoute(route);
2788
2105
  throw new BridgeError("CODEX_PROVIDER_UNAVAILABLE", "The local Codex provider closed during route creation.");
2789
2106
  }
2790
- if (!allowPendingEndpointAttestation &&
2107
+ if (!allowPendingEndpointActivation &&
2791
2108
  (this.endpointUnavailable ||
2792
2109
  this.endpointRefresh !== undefined ||
2793
2110
  admittedFactory !== this.factory ||
@@ -2806,15 +2123,14 @@ export class LocalCodexGatewayProvider {
2806
2123
  this.routeCreations.delete(threadId);
2807
2124
  }
2808
2125
  }
2809
- async createRoute(threadId, factory, queueInitialObservation, writesEnabled) {
2126
+ async createRoute(threadId, factory, queueInitialObservation) {
2810
2127
  let transport;
2811
2128
  let connector;
2812
2129
  const generation = Symbol(threadId);
2813
2130
  try {
2814
2131
  transport = await factory.connectTransport();
2815
2132
  connector = await CodexAppServerConnector.connect({
2816
- compatibility: factory.writeCompatibility ?? factory.schemaCompatibility,
2817
- writesEnabled,
2133
+ compatibility: { endpointGeneration: factory.endpointGeneration },
2818
2134
  route: {
2819
2135
  endpointGeneration: factory.endpointGeneration,
2820
2136
  threadId,
@@ -2919,12 +2235,11 @@ export class LocalCodexGatewayProvider {
2919
2235
  }
2920
2236
  try {
2921
2237
  if (this.endpointUnavailable) {
2922
- if (this.pendingEndpointAttestation !== undefined) {
2238
+ if (this.pendingEndpointRefreshEvent !== undefined) {
2923
2239
  throw new BridgeError("CODEX_ENDPOINT_REFRESH_PENDING", "The replacement Codex endpoint is awaiting controller activation.", true);
2924
2240
  }
2925
2241
  const refreshed = await this.refreshEndpoint("callback");
2926
- if (refreshed?.event.outcome === "compatible" &&
2927
- refreshed.event.routes.some((route) => route.routeHandle === threadId)) {
2242
+ if (refreshed?.event.routes.some((route) => route.routeHandle === threadId)) {
2928
2243
  this.routesRequiringRecovery.delete(threadId);
2929
2244
  this.routeRecoveryAttempts.delete(threadId);
2930
2245
  return;
@@ -2954,8 +2269,7 @@ export class LocalCodexGatewayProvider {
2954
2269
  if (this.isEndpointGenerationChanged(error)) {
2955
2270
  this.endpointUnavailable = true;
2956
2271
  const refreshed = await this.refreshEndpoint("callback").catch(() => undefined);
2957
- if (refreshed?.event.outcome === "compatible" &&
2958
- refreshed.event.routes.some((route) => route.routeHandle === threadId)) {
2272
+ if (refreshed?.event.routes.some((route) => route.routeHandle === threadId)) {
2959
2273
  this.routesRequiringRecovery.delete(threadId);
2960
2274
  this.routeRecoveryAttempts.delete(threadId);
2961
2275
  return;
@@ -2986,7 +2300,6 @@ export class LocalCodexGatewayProvider {
2986
2300
  const event = this.pendingEndpointRefreshEvent;
2987
2301
  if (event === undefined ||
2988
2302
  this.pendingEndpointRefreshSelectorClaimed ||
2989
- this.pendingEndpointAttestation === undefined ||
2990
2303
  event.current.endpointGeneration !== this.factory.endpointGeneration) {
2991
2304
  return undefined;
2992
2305
  }
@@ -3033,40 +2346,7 @@ export class LocalCodexGatewayProvider {
3033
2346
  try {
3034
2347
  const resolved = await this.resolveEndpointRefreshCandidate(refreshFactory, previousFactory, previous);
3035
2348
  candidate = resolved.factory;
3036
- const { attestation, identity: candidateIdentity } = resolved;
3037
2349
  await this.retireEndpointGeneration(previousFactory, previous.endpointGeneration);
3038
- if (attestation.tier === "incompatible") {
3039
- await candidate.close();
3040
- candidate = undefined;
3041
- this.compatibilityAttested = false;
3042
- this.pendingEndpointAttestation = undefined;
3043
- this.pendingEndpointRefreshEvent = undefined;
3044
- this.pendingEndpointRefreshSelectorClaimed = false;
3045
- for (const routeHandle of this.trackedRoutes) {
3046
- this.routesRequiringRecovery.add(routeHandle);
3047
- }
3048
- if (this.closing || this.closed)
3049
- return undefined;
3050
- const result = {
3051
- event: {
3052
- outcome: "incompatible",
3053
- previous,
3054
- candidate: candidateIdentity,
3055
- attestation,
3056
- },
3057
- delivery: "callback",
3058
- selectorClaimed: true,
3059
- published: false,
3060
- };
3061
- result.published = true;
3062
- this.emitEndpointRefresh(result.event);
3063
- for (const routeHandle of this.routesRequiringRecovery) {
3064
- if (this.trackedRoutes.has(routeHandle)) {
3065
- this.scheduleRouteRecovery(routeHandle);
3066
- }
3067
- }
3068
- return result;
3069
- }
3070
2350
  if (this.closing || this.closed) {
3071
2351
  await candidate.close();
3072
2352
  candidate = undefined;
@@ -3079,7 +2359,7 @@ export class LocalCodexGatewayProvider {
3079
2359
  if (this.closing || this.closed)
3080
2360
  break;
3081
2361
  try {
3082
- const route = await this.createRoute(routeHandle, replacementFactory, false, codexFactoryWritesEnabled(replacementFactory, attestation, this.latestWriteCompatibilityProbeObservation(replacementFactory.endpointGeneration)?.outcome === "pass"));
2362
+ const route = await this.createRoute(routeHandle, replacementFactory, false);
3083
2363
  if (this.closing || this.closed) {
3084
2364
  await this.closeRoute(route);
3085
2365
  break;
@@ -3105,9 +2385,7 @@ export class LocalCodexGatewayProvider {
3105
2385
  this.factory = replacementFactory;
3106
2386
  candidate = undefined;
3107
2387
  this.retiredEndpointGeneration = undefined;
3108
- this.compatibilityAttested = false;
3109
2388
  this.endpointUnavailable = true;
3110
- this.pendingEndpointAttestation = attestation;
3111
2389
  for (const staged of stagedRoutes) {
3112
2390
  this.routes.set(staged.routeHandle, staged.route);
3113
2391
  this.routesRequiringRecovery.delete(staged.routeHandle);
@@ -3119,20 +2397,16 @@ export class LocalCodexGatewayProvider {
3119
2397
  }
3120
2398
  const result = {
3121
2399
  event: {
3122
- outcome: "compatible",
3123
2400
  previous,
3124
2401
  current: this.identity,
3125
- attestation,
3126
2402
  routes: refreshedRoutes,
3127
2403
  },
3128
2404
  delivery: this.endpointRefreshDelivery ?? "callback",
3129
2405
  selectorClaimed: false,
3130
2406
  published: false,
3131
2407
  };
3132
- if (result.event.outcome === "compatible") {
3133
- this.pendingEndpointRefreshEvent = result.event;
3134
- this.pendingEndpointRefreshSelectorClaimed = false;
3135
- }
2408
+ this.pendingEndpointRefreshEvent = result.event;
2409
+ this.pendingEndpointRefreshSelectorClaimed = false;
3136
2410
  if (result.delivery === "callback") {
3137
2411
  result.selectorClaimed = true;
3138
2412
  result.published = true;
@@ -3163,10 +2437,7 @@ export class LocalCodexGatewayProvider {
3163
2437
  let candidate;
3164
2438
  try {
3165
2439
  candidate = await refreshFactory();
3166
- const versionFailure = codexVersionFailureCode(candidate.appServerVersion);
3167
- validateCodexFactory(candidate, {
3168
- allowUnsupportedVersion: versionFailure !== undefined,
3169
- });
2440
+ validateCodexFactory(candidate);
3170
2441
  if (candidate.hostId !== previous.hostId ||
3171
2442
  candidate.protocol !== previousFactory.protocol) {
3172
2443
  throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The replacement Codex factory moved outside its pinned boundary.");
@@ -3176,41 +2447,12 @@ export class LocalCodexGatewayProvider {
3176
2447
  if (candidate !== previousFactory)
3177
2448
  await candidate.close();
3178
2449
  candidate = undefined;
3179
- if (this.endpointUnavailable &&
3180
- this.compatibilityFailureCode === undefined &&
3181
- !this.factory.writableReady &&
3182
- this.factory.writeCompatibility === null) {
3183
- throw new BridgeError("CODEX_MONITOR_ONLY", "This Codex App Server remains monitor-only until a write-attested generation is available.");
3184
- }
3185
2450
  if (attempt + 1 < MAX_CODEX_ENDPOINT_REFRESH_CANDIDATES) {
3186
2451
  continue;
3187
2452
  }
3188
2453
  throw new BridgeError("CODEX_ENDPOINT_GENERATION_CHURN", "The Codex endpoint did not stabilize within its bounded refresh window.", true);
3189
2454
  }
3190
- // Endpoint generations never inherit cached compatibility. A version
3191
- // outside the tested major is classified from OS-attested factory
3192
- // evidence alone; no connector or transport may touch that protocol.
3193
- const probes = versionFailure === undefined
3194
- ? await this.runCompatibilityProbesFor(candidate)
3195
- : compatibilityProbeNames.codex.map((name, index) => index === 0
3196
- ? passedProbe(name)
3197
- : failedProbe(name, versionFailure));
3198
- const attestation = evaluateCompatibilityAttestation({
3199
- surface: "codex",
3200
- version: candidate.appServerVersion,
3201
- checkedAt: this.now().toISOString(),
3202
- certifiedVersions: certifiedCompatibilityVersions.codex,
3203
- probes,
3204
- });
3205
- return {
3206
- factory: candidate,
3207
- identity: {
3208
- provider: "codex",
3209
- hostId: previous.hostId,
3210
- endpointGeneration: candidate.endpointGeneration,
3211
- },
3212
- attestation,
3213
- };
2455
+ return { factory: candidate };
3214
2456
  }
3215
2457
  catch (error) {
3216
2458
  if (candidate !== undefined && candidate !== previousFactory) {
@@ -3266,7 +2508,6 @@ export class LocalCodexGatewayProvider {
3266
2508
  return;
3267
2509
  let event = result.event;
3268
2510
  if (staleRouteHandle !== undefined &&
3269
- event.outcome === "compatible" &&
3270
2511
  event.routes.some((route) => route.routeHandle === staleRouteHandle)) {
3271
2512
  event = {
3272
2513
  ...event,
@@ -3280,9 +2521,7 @@ export class LocalCodexGatewayProvider {
3280
2521
  }
3281
2522
  publishEndpointRefresh(event) {
3282
2523
  this.emitEndpointRefresh(event);
3283
- if (event.outcome === "compatible") {
3284
- this.armEndpointActivationRetry(event);
3285
- }
2524
+ this.armEndpointActivationRetry(event);
3286
2525
  }
3287
2526
  armEndpointActivationRetry(event) {
3288
2527
  this.clearEndpointActivationRetry();
@@ -3295,8 +2534,7 @@ export class LocalCodexGatewayProvider {
3295
2534
  this.closing ||
3296
2535
  this.closed ||
3297
2536
  pending.attempt >= 3 ||
3298
- (pending.event.outcome === "compatible" &&
3299
- this.pendingEndpointAttestation === undefined)) {
2537
+ this.pendingEndpointRefreshEvent !== pending.event) {
3300
2538
  this.clearEndpointActivationRetry();
3301
2539
  return;
3302
2540
  }
@@ -3308,8 +2546,7 @@ export class LocalCodexGatewayProvider {
3308
2546
  const current = this.endpointActivationRetry;
3309
2547
  if (current === undefined || current.event !== pending.event)
3310
2548
  return;
3311
- if (current.event.outcome === "compatible" &&
3312
- this.pendingEndpointAttestation === undefined) {
2549
+ if (this.pendingEndpointRefreshEvent !== current.event) {
3313
2550
  this.clearEndpointActivationRetry();
3314
2551
  return;
3315
2552
  }