agent-embassy 1.6.0 → 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 +31 -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 -597
  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 -84
  77. package/dist/src/gateway/providers.js +69 -806
  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 -432
  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, 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,53 +1593,13 @@ 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
1605
  function codexRouteState(observation) {
@@ -1961,9 +1623,6 @@ function codexRouteSafeCode(observation) {
1961
1623
  if (codexRouteState(observation) === "stale") {
1962
1624
  return "CODEX_ROUTE_STALE";
1963
1625
  }
1964
- if (!observation.writableReady) {
1965
- return "CODEX_WRITES_DISABLED";
1966
- }
1967
1626
  return undefined;
1968
1627
  }
1969
1628
  export class LocalCodexGatewayProvider {
@@ -1997,13 +1656,7 @@ export class LocalCodexGatewayProvider {
1997
1656
  endpointActivationRetry;
1998
1657
  endpointActivationRetryTimer;
1999
1658
  callbackDrainFrozen = false;
2000
- writeProbeObservationsByGeneration = new Map();
2001
- writeProbeResults = new Map();
2002
- writeProbeOverflow;
2003
- compatibilityAttested;
2004
- compatibilityFailureCode;
2005
1659
  endpointUnavailable = false;
2006
- pendingEndpointAttestation;
2007
1660
  pendingEndpointRefreshEvent;
2008
1661
  pendingEndpointRefreshSelectorClaimed = false;
2009
1662
  initialized = false;
@@ -2014,7 +1667,6 @@ export class LocalCodexGatewayProvider {
2014
1667
  this.factory = options.factory;
2015
1668
  this.refreshFactory = options.refreshFactory;
2016
1669
  exactLocalHost(options.factory.hostId);
2017
- this.compatibilityAttested = CODEX_APP_SERVER_WRITABLE_VERSIONS.includes(options.factory.appServerVersion);
2018
1670
  this.maxCallbacks = positiveBounded(options.maxCallbackEvents, MAX_CODEX_CALLBACKS, 4_096);
2019
1671
  this.maxRoutes = positiveBounded(options.maxRoutes, MAX_CODEX_ROUTES, 256);
2020
1672
  this.maxReplyBytes = positiveBounded(options.maxReplyBytes, MAX_TRANSIENT_REPLY_BYTES, 1024 * 1024);
@@ -2043,336 +1695,39 @@ export class LocalCodexGatewayProvider {
2043
1695
  get protocolVersion() {
2044
1696
  return this.factory.protocolVersion;
2045
1697
  }
2046
- compatibilitySurface() {
2047
- return { surface: "codex", version: this.factory.appServerVersion };
2048
- }
2049
- acceptCompatibilityAttestation(attestation) {
2050
- const pending = this.pendingEndpointAttestation;
2051
- const pendingMatches = pending === undefined ||
2052
- (attestation.checkedAt === pending.checkedAt &&
2053
- attestation.tier === pending.tier &&
2054
- attestation.safeErrorCode === pending.safeErrorCode &&
2055
- attestation.probes.length === pending.probes.length &&
2056
- attestation.probes.every((probe, index) => probe.name === pending.probes[index]?.name &&
2057
- probe.outcome === pending.probes[index]?.outcome &&
2058
- probe.safeErrorCode === pending.probes[index]?.safeErrorCode));
2059
- if (!isCompatibilityAttestation(attestation) ||
2060
- attestation.surface !== "codex" ||
2061
- attestation.version !== this.factory.appServerVersion ||
2062
- !pendingMatches) {
2063
- throw new BridgeError("CODEX_COMPATIBILITY_ATTESTATION_MISMATCH", "The Codex compatibility attestation does not match this endpoint.");
2064
- }
2065
- if (attestation.tier === "incompatible") {
2066
- this.pendingEndpointAttestation = undefined;
2067
- this.pendingEndpointRefreshEvent = undefined;
2068
- this.pendingEndpointRefreshSelectorClaimed = false;
2069
- this.clearEndpointActivationRetry();
2070
- this.compatibilityAttested = false;
2071
- this.endpointUnavailable = true;
2072
- this.compatibilityFailureCode =
2073
- attestation.safeErrorCode ?? "CODEX_COMPATIBILITY_CHECK_FAILED";
2074
- return;
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.");
2075
1704
  }
2076
- const writableCertified = attestation.tier === "certified" &&
2077
- CODEX_APP_SERVER_WRITABLE_VERSIONS.includes(attestation.version) &&
2078
- this.factory.writableReady &&
2079
- this.factory.writeCompatibility !== null;
2080
- const schemaObserved = attestation.tier === "schema_attested" &&
2081
- !this.factory.writableReady &&
2082
- this.factory.writeCompatibility === null;
2083
- if ((!writableCertified && !schemaObserved) ||
2084
- (this.endpointUnavailable && pending === undefined) ||
2085
- !pendingMatches) {
2086
- throw new BridgeError("CODEX_COMPATIBILITY_ATTESTATION_MISMATCH", "The Codex compatibility attestation does not match this endpoint.");
2087
- }
2088
- this.pendingEndpointAttestation = undefined;
2089
1705
  this.pendingEndpointRefreshEvent = undefined;
2090
1706
  this.pendingEndpointRefreshSelectorClaimed = false;
2091
1707
  this.clearEndpointActivationRetry();
2092
- this.compatibilityAttested = writableCertified;
2093
- this.endpointUnavailable = !writableCertified;
2094
- this.compatibilityFailureCode = undefined;
1708
+ this.endpointUnavailable = false;
2095
1709
  }
2096
1710
  releaseEndpointRefreshSelectorClaim(endpointGeneration) {
2097
1711
  const event = this.pendingEndpointRefreshEvent;
2098
- if (event?.current.endpointGeneration === endpointGeneration &&
2099
- this.pendingEndpointAttestation !== undefined) {
1712
+ if (event?.current.endpointGeneration === endpointGeneration) {
2100
1713
  this.pendingEndpointRefreshSelectorClaimed = false;
2101
1714
  }
2102
1715
  }
2103
1716
  rearmEndpointRefreshActivation(endpointGeneration) {
2104
1717
  const event = this.pendingEndpointRefreshEvent;
2105
1718
  if (event?.current.endpointGeneration === endpointGeneration &&
2106
- this.pendingEndpointAttestation !== undefined &&
2107
1719
  !this.closing &&
2108
1720
  !this.closed) {
2109
1721
  this.publishEndpointRefresh(event);
2110
1722
  }
2111
1723
  }
2112
- latestWriteCompatibilityProbeObservation(endpointGeneration) {
2113
- return (this.writeProbeObservationsByGeneration.get(endpointGeneration) ??
2114
- (this.writeProbeOverflow?.endpointGeneration === endpointGeneration
2115
- ? this.writeProbeOverflow.observation
2116
- : undefined));
2117
- }
2118
- async runCompatibilityProbes(context) {
2119
- return await this.runCompatibilityProbesFor(this.factory, context === undefined
2120
- ? undefined
2121
- : {
2122
- stateRoot: path.resolve(context.stateRoot),
2123
- forbiddenCodexThreadIds: [...context.forbiddenCodexThreadIds],
2124
- });
2125
- }
2126
- async runCompatibilityProbesFor(factory, context) {
2127
- const [installation, control, initialize, threadList] = compatibilityProbeNames.codex;
2128
- let transport;
2129
- let connector;
2130
- let stage = "transport";
2131
- try {
2132
- transport = await factory.connectTransport();
2133
- stage = "initialize";
2134
- connector = await CodexAppServerConnector.connect({
2135
- compatibility: factory.schemaCompatibility,
2136
- ...(context === undefined
2137
- ? {}
2138
- : { writeCompatibilityProbe: true }),
2139
- writesEnabled: false,
2140
- route: {
2141
- endpointGeneration: factory.endpointGeneration,
2142
- threadId: COMPATIBILITY_PROBE_THREAD_ID,
2143
- },
2144
- transport,
2145
- maxReplyBytes: this.maxReplyBytes,
2146
- now: this.now,
2147
- onEvent: () => undefined,
2148
- onTurnResult: () => undefined,
2149
- });
2150
- stage = "thread_list";
2151
- await connector.observeLoadedThread(connector.guard());
2152
- const requiredProbes = [
2153
- passedProbe(installation),
2154
- passedProbe(control),
2155
- passedProbe(initialize),
2156
- passedProbe(threadList),
2157
- ];
2158
- if (context === undefined)
2159
- return requiredProbes;
2160
- const result = await this.runCodexWriteProbe(factory, connector, context);
2161
- return result.outcome === "pass"
2162
- ? [...requiredProbes, passedProbe("write_attestation")]
2163
- : requiredProbes;
2164
- }
2165
- catch (error) {
2166
- if (this.isEndpointGenerationChanged(error) ||
2167
- (error instanceof BridgeError &&
2168
- error.code === "CODEX_FACTORY_ATTESTATION_INVALID")) {
2169
- throw error;
2170
- }
2171
- if (stage === "transport") {
2172
- const availabilityFailure = error instanceof LocalCodexTransportError &&
2173
- [
2174
- "MANAGED_CODEX_UNAVAILABLE",
2175
- "LOCAL_APP_SERVER_NOT_RUNNING",
2176
- "SPAWN_FAILED",
2177
- "SPAWN_TIMEOUT",
2178
- "PROXY_STDERR_LIMIT",
2179
- "TRANSPORT_CONNECT_FAILED",
2180
- ].includes(error.code);
2181
- if (!availabilityFailure)
2182
- throw error;
2183
- const installationUnavailable = error instanceof LocalCodexTransportError &&
2184
- error.code === "MANAGED_CODEX_UNAVAILABLE";
2185
- return [
2186
- installationUnavailable
2187
- ? failedProbe(installation, "CODEX_INSTALLATION_INVALID")
2188
- : passedProbe(installation),
2189
- failedProbe(control, installationUnavailable
2190
- ? "CODEX_COMPAT_PROBE_BLOCKED"
2191
- : "CODEX_CONTROL_SOCKET_UNAVAILABLE"),
2192
- failedProbe(initialize, "CODEX_COMPAT_PROBE_BLOCKED"),
2193
- failedProbe(threadList, "CODEX_COMPAT_PROBE_BLOCKED"),
2194
- ];
2195
- }
2196
- return [
2197
- passedProbe(installation),
2198
- passedProbe(control),
2199
- stage === "initialize"
2200
- ? failedProbe(initialize, "CODEX_INITIALIZE_SCHEMA_REJECTED")
2201
- : passedProbe(initialize),
2202
- failedProbe(threadList, "CODEX_THREAD_LIST_SCHEMA_REJECTED"),
2203
- ];
2204
- }
2205
- finally {
2206
- if (connector !== undefined) {
2207
- await connector.close();
2208
- }
2209
- else if (transport !== undefined) {
2210
- await transport.close();
2211
- }
2212
- }
2213
- }
2214
- async runCodexWriteProbe(factory, connector, context) {
2215
- const key = `${factory.appServerVersion}\0${factory.endpointGeneration}`;
2216
- const cached = this.writeProbeResults.get(key);
2217
- if (cached !== undefined)
2218
- return await cached;
2219
- if (this.writeProbeOverflow?.key === key) {
2220
- return this.writeProbeOverflow.observation;
2221
- }
2222
- if (this.writeProbeResults.size >= MAX_CODEX_WRITE_PROBE_ATTEMPTS) {
2223
- const observation = Object.freeze(codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED"));
2224
- this.writeProbeOverflow = Object.freeze({
2225
- endpointGeneration: factory.endpointGeneration,
2226
- key,
2227
- observation,
2228
- });
2229
- if (this.callbacks !== undefined) {
2230
- invokeCallback(() => this.callbacks?.onProtocolNotice?.({
2231
- code: observation.safeErrorCode,
2232
- }));
2233
- }
2234
- return observation;
2235
- }
2236
- const pending = this.executeCodexWriteProbe(connector, context).then((result) => {
2237
- const observation = Object.freeze({ ...result });
2238
- this.writeProbeObservationsByGeneration.set(factory.endpointGeneration, observation);
2239
- if (observation.outcome === "fail" && this.callbacks !== undefined) {
2240
- invokeCallback(() => this.callbacks?.onProtocolNotice?.({
2241
- code: observation.safeErrorCode,
2242
- }));
2243
- }
2244
- return observation;
2245
- });
2246
- this.writeProbeResults.set(key, pending);
2247
- return await pending;
2248
- }
2249
- async executeCodexWriteProbe(connector, context) {
2250
- const stateRoot = path.resolve(context.stateRoot);
2251
- const rootBefore = await attestCodexWriteProbeRoot(stateRoot);
2252
- if (rootBefore === null) {
2253
- return codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED");
2254
- }
2255
- const probeRoot = path.join(stateRoot, CODEX_WRITE_PROBE_ROOT);
2256
- let probeRootBefore;
2257
- try {
2258
- let created = false;
2259
- try {
2260
- await mkdir(probeRoot, { mode: 0o700 });
2261
- created = true;
2262
- }
2263
- catch (error) {
2264
- if (systemErrorCode(error) !== "EEXIST")
2265
- throw error;
2266
- }
2267
- if (created)
2268
- await chmod(probeRoot, 0o700);
2269
- const evidence = await attestCodexWriteProbeRoot(probeRoot);
2270
- if (evidence === null) {
2271
- return codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED");
2272
- }
2273
- probeRootBefore = evidence;
2274
- }
2275
- catch (error) {
2276
- if (error instanceof BridgeError &&
2277
- error.code === "CODEX_FACTORY_ATTESTATION_INVALID") {
2278
- throw error;
2279
- }
2280
- if (transientCodexWriteProbeError(error)) {
2281
- return codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED");
2282
- }
2283
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The controller-owned Codex probe root could not be established safely.");
2284
- }
2285
- let cwd;
2286
- let before;
2287
- let result = codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED");
2288
- try {
2289
- cwd = await mkdtemp(path.join(probeRoot, CODEX_WRITE_PROBE_DIRECTORY_PREFIX));
2290
- if (path.dirname(cwd) !== probeRoot) {
2291
- throw new Error("probe directory escaped its dedicated root");
2292
- }
2293
- await chmod(cwd, 0o700);
2294
- before = await attestCodexWriteProbeDirectory(cwd);
2295
- result = await connector.runWriteCompatibilityProbe({
2296
- cwd,
2297
- forbiddenThreadIds: [
2298
- ...new Set([
2299
- COMPATIBILITY_PROBE_THREAD_ID,
2300
- ...context.forbiddenCodexThreadIds,
2301
- ...this.trackedRoutes,
2302
- ]),
2303
- ],
2304
- });
2305
- }
2306
- catch (error) {
2307
- if (!safeCodexWriteProbeFilesystemFailure(error)) {
2308
- if (error instanceof BridgeError)
2309
- throw error;
2310
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The disposable Codex probe directory could not be established safely.");
2311
- }
2312
- result = codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED");
2313
- }
2314
- let unchanged = false;
2315
- let removed = false;
2316
- if (cwd !== undefined && before !== undefined) {
2317
- try {
2318
- const after = await attestCodexWriteProbeDirectory(cwd);
2319
- unchanged = sameCodexWriteProbeDirectory(before, after);
2320
- await rmdir(cwd);
2321
- try {
2322
- await lstat(cwd);
2323
- }
2324
- catch (error) {
2325
- removed = systemErrorCode(error) === "ENOENT";
2326
- }
2327
- }
2328
- catch (error) {
2329
- if (!safeCodexWriteProbeFilesystemFailure(error)) {
2330
- if (error instanceof BridgeError)
2331
- throw error;
2332
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The disposable Codex probe directory could not be re-attested safely.");
2333
- }
2334
- // Never remove a path after its exact ownership evidence changed.
2335
- }
2336
- }
2337
- if (cwd !== undefined && !removed) {
2338
- result = codexWriteProbeFailure("CODEX_WRITE_PROBE_CLEANUP_UNCONFIRMED", result);
2339
- }
2340
- else if (cwd !== undefined && !unchanged) {
2341
- result = codexWriteProbeFailure("CODEX_WRITE_PROBE_TOOL_ACTIVITY_OBSERVED", result);
2342
- }
2343
- const [probeRootAfter, rootAfter] = await Promise.all([
2344
- attestCodexWriteProbeRoot(probeRoot),
2345
- attestCodexWriteProbeRoot(stateRoot),
2346
- ]);
2347
- if (probeRootAfter === null || rootAfter === null) {
2348
- return codexWriteProbeFailure("CODEX_WRITE_PROBE_THREAD_SETUP_FAILED", result);
2349
- }
2350
- if (!sameCodexWriteProbeRoot(probeRootBefore, probeRootAfter) ||
2351
- !sameCodexWriteProbeRoot(rootBefore, rootAfter)) {
2352
- throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "A controller-owned Codex probe root changed while the disposable probe ran.");
2353
- }
2354
- return result;
2355
- }
2356
1724
  async initialize(callbacks) {
2357
1725
  if (this.closed || this.initialized) {
2358
1726
  throw new BridgeError("CODEX_PROVIDER_INITIALIZATION_REJECTED", "The local Codex provider cannot be initialized in this state.");
2359
1727
  }
2360
1728
  this.callbacks = callbacks;
2361
1729
  this.initialized = true;
2362
- if (this.compatibilityFailureCode !== undefined) {
2363
- return {
2364
- health: "degraded",
2365
- compatibility: "incompatible",
2366
- safeErrorCode: this.compatibilityFailureCode,
2367
- };
2368
- }
2369
- return this.factory.writeCompatibility === null
2370
- ? {
2371
- health: "degraded",
2372
- compatibility: "compatible",
2373
- safeErrorCode: "CODEX_MONITOR_ONLY",
2374
- }
2375
- : { health: "healthy", compatibility: "compatible" };
1730
+ return { health: "healthy" };
2376
1731
  }
2377
1732
  async selectRoute(input) {
2378
1733
  if (!this.initialized || this.closing || this.closed) {
@@ -2394,9 +1749,8 @@ export class LocalCodexGatewayProvider {
2394
1749
  let selectorRefreshReserved = false;
2395
1750
  let route;
2396
1751
  const stageRefreshedRoute = async (result) => {
2397
- if (result === undefined ||
2398
- result.event.outcome !== "compatible") {
2399
- 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.");
2400
1754
  }
2401
1755
  refreshResult = result;
2402
1756
  selectorRefreshReserved = this.reserveSelectorRefresh(result);
@@ -2419,7 +1773,7 @@ export class LocalCodexGatewayProvider {
2419
1773
  route = await stageRefreshedRoute(retainedEndpointRefresh);
2420
1774
  }
2421
1775
  else if (this.endpointUnavailable &&
2422
- this.pendingEndpointAttestation === undefined) {
1776
+ this.pendingEndpointRefreshEvent === undefined) {
2423
1777
  route = await stageRefreshedRoute(await this.refreshEndpoint("selector"));
2424
1778
  }
2425
1779
  else {
@@ -2537,7 +1891,6 @@ export class LocalCodexGatewayProvider {
2537
1891
  this.closed ||
2538
1892
  this.endpointUnavailable ||
2539
1893
  this.endpointRefresh !== undefined ||
2540
- !this.compatibilityAttested ||
2541
1894
  input.authorization !== "selected_route" ||
2542
1895
  !sameEndpoint(input.binding, this.identity)) {
2543
1896
  return { state: "failed", safeErrorCode: "CODEX_ROUTE_UNAVAILABLE" };
@@ -2550,14 +1903,7 @@ export class LocalCodexGatewayProvider {
2550
1903
  route.endpointGeneration !== this.factory.endpointGeneration) {
2551
1904
  return { state: "failed", safeErrorCode: "CODEX_ROUTE_UNAVAILABLE" };
2552
1905
  }
2553
- if (!this.factory.writableReady ||
2554
- this.factory.writeCompatibility === null) {
2555
- return { state: "failed", safeErrorCode: "CODEX_WRITES_DISABLED" };
2556
- }
2557
1906
  const guard = route.connector.guard();
2558
- if (!guard.writableReady) {
2559
- return { state: "failed", safeErrorCode: "CODEX_WRITES_DISABLED" };
2560
- }
2561
1907
  if (strictDeadline(input.deadlineAt, this.now().getTime()) === undefined) {
2562
1908
  return { state: "failed", safeErrorCode: "MESSAGE_EXPIRED" };
2563
1909
  }
@@ -2567,7 +1913,8 @@ export class LocalCodexGatewayProvider {
2567
1913
  let content;
2568
1914
  try {
2569
1915
  content = composeProvenanceEnvelope({
2570
- direction: "codex",
1916
+ sourceProvider: input.sourceProvider,
1917
+ recipientProvider: this.identity.provider,
2571
1918
  sourceAlias: input.sourceAlias,
2572
1919
  targetAlias: input.targetAlias,
2573
1920
  conversationId: input.conversationId,
@@ -2677,7 +2024,6 @@ export class LocalCodexGatewayProvider {
2677
2024
  this.clearEndpointActivationRetry();
2678
2025
  this.pendingEndpointRefreshEvent = undefined;
2679
2026
  this.pendingEndpointRefreshSelectorClaimed = false;
2680
- this.pendingEndpointAttestation = undefined;
2681
2027
  const refreshResult = this.endpointRefresh === undefined
2682
2028
  ? []
2683
2029
  : await Promise.allSettled([this.endpointRefresh]);
@@ -2703,7 +2049,6 @@ export class LocalCodexGatewayProvider {
2703
2049
  this.closed = true;
2704
2050
  this.closing = false;
2705
2051
  this.callbackQueue.length = 0;
2706
- this.pendingEndpointAttestation = undefined;
2707
2052
  this.pendingEndpointRefreshEvent = undefined;
2708
2053
  this.pendingEndpointRefreshSelectorClaimed = false;
2709
2054
  this.trackedRoutes.clear();
@@ -2716,13 +2061,12 @@ export class LocalCodexGatewayProvider {
2716
2061
  this.closing ||
2717
2062
  this.closed ||
2718
2063
  this.endpointUnavailable ||
2719
- this.endpointRefresh !== undefined ||
2720
- !this.compatibilityAttested) {
2064
+ this.endpointRefresh !== undefined) {
2721
2065
  throw new BridgeError("CODEX_PROVIDER_UNAVAILABLE", "The local Codex provider is unavailable.", true);
2722
2066
  }
2723
2067
  }
2724
- async ensureRoute(threadId, queueInitialObservation = true, allowPendingEndpointAttestation = false) {
2725
- if (allowPendingEndpointAttestation) {
2068
+ async ensureRoute(threadId, queueInitialObservation = true, allowPendingEndpointActivation = false) {
2069
+ if (allowPendingEndpointActivation) {
2726
2070
  if (!this.initialized || this.closing || this.closed) {
2727
2071
  throw new BridgeError("CODEX_PROVIDER_UNAVAILABLE", "The local Codex provider is unavailable.", true);
2728
2072
  }
@@ -2733,7 +2077,7 @@ export class LocalCodexGatewayProvider {
2733
2077
  const pendingRelease = this.routeReleases.get(threadId);
2734
2078
  if (pendingRelease !== undefined) {
2735
2079
  await pendingRelease;
2736
- return await this.ensureRoute(threadId, queueInitialObservation, allowPendingEndpointAttestation);
2080
+ return await this.ensureRoute(threadId, queueInitialObservation, allowPendingEndpointActivation);
2737
2081
  }
2738
2082
  const existing = this.routes.get(threadId);
2739
2083
  if (existing !== undefined) {
@@ -2745,7 +2089,7 @@ export class LocalCodexGatewayProvider {
2745
2089
  // a fresh one. The identity-checked release lets automatic recovery and
2746
2090
  // an explicit selector join the same cleanup safely.
2747
2091
  await this.releaseRouteInternal(threadId);
2748
- return await this.ensureRoute(threadId, queueInitialObservation, allowPendingEndpointAttestation);
2092
+ return await this.ensureRoute(threadId, queueInitialObservation, allowPendingEndpointActivation);
2749
2093
  }
2750
2094
  const pending = this.routeCreations.get(threadId);
2751
2095
  if (pending !== undefined)
@@ -2760,7 +2104,7 @@ export class LocalCodexGatewayProvider {
2760
2104
  await this.closeRoute(route);
2761
2105
  throw new BridgeError("CODEX_PROVIDER_UNAVAILABLE", "The local Codex provider closed during route creation.");
2762
2106
  }
2763
- if (!allowPendingEndpointAttestation &&
2107
+ if (!allowPendingEndpointActivation &&
2764
2108
  (this.endpointUnavailable ||
2765
2109
  this.endpointRefresh !== undefined ||
2766
2110
  admittedFactory !== this.factory ||
@@ -2785,10 +2129,8 @@ export class LocalCodexGatewayProvider {
2785
2129
  const generation = Symbol(threadId);
2786
2130
  try {
2787
2131
  transport = await factory.connectTransport();
2788
- const writesEnabled = factory.writableReady && factory.writeCompatibility !== null;
2789
2132
  connector = await CodexAppServerConnector.connect({
2790
- compatibility: factory.writeCompatibility ?? factory.schemaCompatibility,
2791
- writesEnabled,
2133
+ compatibility: { endpointGeneration: factory.endpointGeneration },
2792
2134
  route: {
2793
2135
  endpointGeneration: factory.endpointGeneration,
2794
2136
  threadId,
@@ -2893,12 +2235,11 @@ export class LocalCodexGatewayProvider {
2893
2235
  }
2894
2236
  try {
2895
2237
  if (this.endpointUnavailable) {
2896
- if (this.pendingEndpointAttestation !== undefined) {
2238
+ if (this.pendingEndpointRefreshEvent !== undefined) {
2897
2239
  throw new BridgeError("CODEX_ENDPOINT_REFRESH_PENDING", "The replacement Codex endpoint is awaiting controller activation.", true);
2898
2240
  }
2899
2241
  const refreshed = await this.refreshEndpoint("callback");
2900
- if (refreshed?.event.outcome === "compatible" &&
2901
- refreshed.event.routes.some((route) => route.routeHandle === threadId)) {
2242
+ if (refreshed?.event.routes.some((route) => route.routeHandle === threadId)) {
2902
2243
  this.routesRequiringRecovery.delete(threadId);
2903
2244
  this.routeRecoveryAttempts.delete(threadId);
2904
2245
  return;
@@ -2928,8 +2269,7 @@ export class LocalCodexGatewayProvider {
2928
2269
  if (this.isEndpointGenerationChanged(error)) {
2929
2270
  this.endpointUnavailable = true;
2930
2271
  const refreshed = await this.refreshEndpoint("callback").catch(() => undefined);
2931
- if (refreshed?.event.outcome === "compatible" &&
2932
- refreshed.event.routes.some((route) => route.routeHandle === threadId)) {
2272
+ if (refreshed?.event.routes.some((route) => route.routeHandle === threadId)) {
2933
2273
  this.routesRequiringRecovery.delete(threadId);
2934
2274
  this.routeRecoveryAttempts.delete(threadId);
2935
2275
  return;
@@ -2960,7 +2300,6 @@ export class LocalCodexGatewayProvider {
2960
2300
  const event = this.pendingEndpointRefreshEvent;
2961
2301
  if (event === undefined ||
2962
2302
  this.pendingEndpointRefreshSelectorClaimed ||
2963
- this.pendingEndpointAttestation === undefined ||
2964
2303
  event.current.endpointGeneration !== this.factory.endpointGeneration) {
2965
2304
  return undefined;
2966
2305
  }
@@ -3007,40 +2346,7 @@ export class LocalCodexGatewayProvider {
3007
2346
  try {
3008
2347
  const resolved = await this.resolveEndpointRefreshCandidate(refreshFactory, previousFactory, previous);
3009
2348
  candidate = resolved.factory;
3010
- const { attestation, identity: candidateIdentity } = resolved;
3011
2349
  await this.retireEndpointGeneration(previousFactory, previous.endpointGeneration);
3012
- if (attestation.tier === "incompatible") {
3013
- await candidate.close();
3014
- candidate = undefined;
3015
- this.compatibilityAttested = false;
3016
- this.pendingEndpointAttestation = undefined;
3017
- this.pendingEndpointRefreshEvent = undefined;
3018
- this.pendingEndpointRefreshSelectorClaimed = false;
3019
- for (const routeHandle of this.trackedRoutes) {
3020
- this.routesRequiringRecovery.add(routeHandle);
3021
- }
3022
- if (this.closing || this.closed)
3023
- return undefined;
3024
- const result = {
3025
- event: {
3026
- outcome: "incompatible",
3027
- previous,
3028
- candidate: candidateIdentity,
3029
- attestation,
3030
- },
3031
- delivery: "callback",
3032
- selectorClaimed: true,
3033
- published: false,
3034
- };
3035
- result.published = true;
3036
- this.emitEndpointRefresh(result.event);
3037
- for (const routeHandle of this.routesRequiringRecovery) {
3038
- if (this.trackedRoutes.has(routeHandle)) {
3039
- this.scheduleRouteRecovery(routeHandle);
3040
- }
3041
- }
3042
- return result;
3043
- }
3044
2350
  if (this.closing || this.closed) {
3045
2351
  await candidate.close();
3046
2352
  candidate = undefined;
@@ -3079,9 +2385,7 @@ export class LocalCodexGatewayProvider {
3079
2385
  this.factory = replacementFactory;
3080
2386
  candidate = undefined;
3081
2387
  this.retiredEndpointGeneration = undefined;
3082
- this.compatibilityAttested = false;
3083
2388
  this.endpointUnavailable = true;
3084
- this.pendingEndpointAttestation = attestation;
3085
2389
  for (const staged of stagedRoutes) {
3086
2390
  this.routes.set(staged.routeHandle, staged.route);
3087
2391
  this.routesRequiringRecovery.delete(staged.routeHandle);
@@ -3093,20 +2397,16 @@ export class LocalCodexGatewayProvider {
3093
2397
  }
3094
2398
  const result = {
3095
2399
  event: {
3096
- outcome: "compatible",
3097
2400
  previous,
3098
2401
  current: this.identity,
3099
- attestation,
3100
2402
  routes: refreshedRoutes,
3101
2403
  },
3102
2404
  delivery: this.endpointRefreshDelivery ?? "callback",
3103
2405
  selectorClaimed: false,
3104
2406
  published: false,
3105
2407
  };
3106
- if (result.event.outcome === "compatible") {
3107
- this.pendingEndpointRefreshEvent = result.event;
3108
- this.pendingEndpointRefreshSelectorClaimed = false;
3109
- }
2408
+ this.pendingEndpointRefreshEvent = result.event;
2409
+ this.pendingEndpointRefreshSelectorClaimed = false;
3110
2410
  if (result.delivery === "callback") {
3111
2411
  result.selectorClaimed = true;
3112
2412
  result.published = true;
@@ -3137,10 +2437,7 @@ export class LocalCodexGatewayProvider {
3137
2437
  let candidate;
3138
2438
  try {
3139
2439
  candidate = await refreshFactory();
3140
- const versionFailure = codexVersionFailureCode(candidate.appServerVersion);
3141
- validateCodexFactory(candidate, {
3142
- allowUnsupportedVersion: versionFailure !== undefined,
3143
- });
2440
+ validateCodexFactory(candidate);
3144
2441
  if (candidate.hostId !== previous.hostId ||
3145
2442
  candidate.protocol !== previousFactory.protocol) {
3146
2443
  throw new BridgeError("CODEX_FACTORY_ATTESTATION_INVALID", "The replacement Codex factory moved outside its pinned boundary.");
@@ -3150,41 +2447,12 @@ export class LocalCodexGatewayProvider {
3150
2447
  if (candidate !== previousFactory)
3151
2448
  await candidate.close();
3152
2449
  candidate = undefined;
3153
- if (this.endpointUnavailable &&
3154
- this.compatibilityFailureCode === undefined &&
3155
- !this.factory.writableReady &&
3156
- this.factory.writeCompatibility === null) {
3157
- throw new BridgeError("CODEX_MONITOR_ONLY", "This Codex App Server remains monitor-only until a write-attested generation is available.");
3158
- }
3159
2450
  if (attempt + 1 < MAX_CODEX_ENDPOINT_REFRESH_CANDIDATES) {
3160
2451
  continue;
3161
2452
  }
3162
2453
  throw new BridgeError("CODEX_ENDPOINT_GENERATION_CHURN", "The Codex endpoint did not stabilize within its bounded refresh window.", true);
3163
2454
  }
3164
- // Endpoint generations never inherit cached compatibility. A version
3165
- // outside the tested major is classified from OS-attested factory
3166
- // evidence alone; no connector or transport may touch that protocol.
3167
- const probes = versionFailure === undefined
3168
- ? await this.runCompatibilityProbesFor(candidate)
3169
- : compatibilityProbeNames.codex.map((name, index) => index === 0
3170
- ? passedProbe(name)
3171
- : failedProbe(name, versionFailure));
3172
- const attestation = evaluateCompatibilityAttestation({
3173
- surface: "codex",
3174
- version: candidate.appServerVersion,
3175
- checkedAt: this.now().toISOString(),
3176
- certifiedVersions: certifiedCompatibilityVersions.codex,
3177
- probes,
3178
- });
3179
- return {
3180
- factory: candidate,
3181
- identity: {
3182
- provider: "codex",
3183
- hostId: previous.hostId,
3184
- endpointGeneration: candidate.endpointGeneration,
3185
- },
3186
- attestation,
3187
- };
2455
+ return { factory: candidate };
3188
2456
  }
3189
2457
  catch (error) {
3190
2458
  if (candidate !== undefined && candidate !== previousFactory) {
@@ -3240,7 +2508,6 @@ export class LocalCodexGatewayProvider {
3240
2508
  return;
3241
2509
  let event = result.event;
3242
2510
  if (staleRouteHandle !== undefined &&
3243
- event.outcome === "compatible" &&
3244
2511
  event.routes.some((route) => route.routeHandle === staleRouteHandle)) {
3245
2512
  event = {
3246
2513
  ...event,
@@ -3254,9 +2521,7 @@ export class LocalCodexGatewayProvider {
3254
2521
  }
3255
2522
  publishEndpointRefresh(event) {
3256
2523
  this.emitEndpointRefresh(event);
3257
- if (event.outcome === "compatible") {
3258
- this.armEndpointActivationRetry(event);
3259
- }
2524
+ this.armEndpointActivationRetry(event);
3260
2525
  }
3261
2526
  armEndpointActivationRetry(event) {
3262
2527
  this.clearEndpointActivationRetry();
@@ -3269,8 +2534,7 @@ export class LocalCodexGatewayProvider {
3269
2534
  this.closing ||
3270
2535
  this.closed ||
3271
2536
  pending.attempt >= 3 ||
3272
- (pending.event.outcome === "compatible" &&
3273
- this.pendingEndpointAttestation === undefined)) {
2537
+ this.pendingEndpointRefreshEvent !== pending.event) {
3274
2538
  this.clearEndpointActivationRetry();
3275
2539
  return;
3276
2540
  }
@@ -3282,8 +2546,7 @@ export class LocalCodexGatewayProvider {
3282
2546
  const current = this.endpointActivationRetry;
3283
2547
  if (current === undefined || current.event !== pending.event)
3284
2548
  return;
3285
- if (current.event.outcome === "compatible" &&
3286
- this.pendingEndpointAttestation === undefined) {
2549
+ if (this.pendingEndpointRefreshEvent !== current.event) {
3287
2550
  this.clearEndpointActivationRetry();
3288
2551
  return;
3289
2552
  }