agent-embassy 1.4.1 → 1.6.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 (86) hide show
  1. package/CHANGELOG.md +40 -1
  2. package/CONTRIBUTING.md +69 -6
  3. package/README.md +8 -5
  4. package/README.zh-CN.md +6 -4
  5. package/SECURITY.md +152 -27
  6. package/dist/src/gateway/claude-peer.d.ts +7 -4
  7. package/dist/src/gateway/claude-peer.js +80 -36
  8. package/dist/src/gateway/claude-peer.js.map +1 -1
  9. package/dist/src/gateway/claude-runtime.d.ts +4 -0
  10. package/dist/src/gateway/claude-runtime.js +50 -39
  11. package/dist/src/gateway/claude-runtime.js.map +1 -1
  12. package/dist/src/gateway/cli-copy.d.ts +1 -1
  13. package/dist/src/gateway/cli-copy.en.d.ts +1 -1
  14. package/dist/src/gateway/cli-copy.en.js +1 -1
  15. package/dist/src/gateway/cli-copy.en.js.map +1 -1
  16. package/dist/src/gateway/cli-copy.js +1 -1
  17. package/dist/src/gateway/cli-copy.js.map +1 -1
  18. package/dist/src/gateway/cli-copy.zh-CN.d.ts +1 -1
  19. package/dist/src/gateway/cli-copy.zh-CN.js +1 -1
  20. package/dist/src/gateway/cli-copy.zh-CN.js.map +1 -1
  21. package/dist/src/gateway/cli.d.ts +1 -1
  22. package/dist/src/gateway/cli.js +6 -7
  23. package/dist/src/gateway/cli.js.map +1 -1
  24. package/dist/src/gateway/codex-app-server.d.ts +44 -2
  25. package/dist/src/gateway/codex-app-server.js +536 -2
  26. package/dist/src/gateway/codex-app-server.js.map +1 -1
  27. package/dist/src/gateway/codex-local-transport.d.ts +10 -6
  28. package/dist/src/gateway/codex-local-transport.js +101 -56
  29. package/dist/src/gateway/codex-local-transport.js.map +1 -1
  30. package/dist/src/gateway/compatibility.d.ts +42 -3
  31. package/dist/src/gateway/compatibility.js +190 -37
  32. package/dist/src/gateway/compatibility.js.map +1 -1
  33. package/dist/src/gateway/control.js +28 -30
  34. package/dist/src/gateway/control.js.map +1 -1
  35. package/dist/src/gateway/dashboard-copy.d.ts +1 -1
  36. package/dist/src/gateway/dashboard-copy.en.d.ts +42 -17
  37. package/dist/src/gateway/dashboard-copy.en.js +56 -31
  38. package/dist/src/gateway/dashboard-copy.en.js.map +1 -1
  39. package/dist/src/gateway/dashboard-copy.js +42 -17
  40. package/dist/src/gateway/dashboard-copy.js.map +1 -1
  41. package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +42 -17
  42. package/dist/src/gateway/dashboard-copy.zh-CN.js +56 -31
  43. package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -1
  44. package/dist/src/gateway/dashboard-model.d.ts +199 -11
  45. package/dist/src/gateway/dashboard-model.js +478 -75
  46. package/dist/src/gateway/dashboard-model.js.map +1 -1
  47. package/dist/src/gateway/dashboard.d.ts +3 -0
  48. package/dist/src/gateway/dashboard.js +62 -137
  49. package/dist/src/gateway/dashboard.js.map +1 -1
  50. package/dist/src/gateway/deepseek-detect.d.ts +13 -0
  51. package/dist/src/gateway/deepseek-detect.js +125 -0
  52. package/dist/src/gateway/deepseek-detect.js.map +1 -0
  53. package/dist/src/gateway/live-dashboard-app/app.js +158 -256
  54. package/dist/src/gateway/live-dashboard-assets.js +2 -1
  55. package/dist/src/gateway/live-dashboard-assets.js.map +1 -1
  56. package/dist/src/gateway/live-dashboard-stream.d.ts +2 -2
  57. package/dist/src/gateway/live-dashboard-stream.js +2 -2
  58. package/dist/src/gateway/live-dashboard-stream.js.map +1 -1
  59. package/dist/src/gateway/progress-watch-machine.d.ts +50 -64
  60. package/dist/src/gateway/progress-watch-machine.js +42 -133
  61. package/dist/src/gateway/progress-watch-machine.js.map +1 -1
  62. package/dist/src/gateway/provenance-envelope.d.ts +2 -0
  63. package/dist/src/gateway/provenance-envelope.js +13 -3
  64. package/dist/src/gateway/provenance-envelope.js.map +1 -1
  65. package/dist/src/gateway/providers.d.ts +80 -16
  66. package/dist/src/gateway/providers.js +782 -115
  67. package/dist/src/gateway/providers.js.map +1 -1
  68. package/dist/src/gateway/server.d.ts +10 -5
  69. package/dist/src/gateway/server.js +100 -13
  70. package/dist/src/gateway/server.js.map +1 -1
  71. package/dist/src/gateway/service.d.ts +46 -3
  72. package/dist/src/gateway/service.js +363 -101
  73. package/dist/src/gateway/service.js.map +1 -1
  74. package/dist/src/gateway/store.d.ts +23 -28
  75. package/dist/src/gateway/store.js +479 -467
  76. package/dist/src/gateway/store.js.map +1 -1
  77. package/dist/src/gateway/types.d.ts +40 -12
  78. package/dist/src/gateway/types.js +145 -4
  79. package/dist/src/gateway/types.js.map +1 -1
  80. package/docs/CONFIGURATION.md +8 -8
  81. package/docs/CONFIGURATION.zh-CN.md +8 -8
  82. package/docs/DASHBOARD.md +35 -6
  83. package/docs/DASHBOARD.zh-CN.md +1 -1
  84. package/docs/GATEWAY-ARCHITECTURE.md +173 -61
  85. package/package.json +1 -1
  86. package/skills/embassy-peer/SKILL.md +2 -2
@@ -29,10 +29,33 @@ edge, created by `pair` or the one-task `select-claude` shorthand. It provides
29
29
  a single private operational view across the two products without rebuilding
30
30
  either agent runtime.
31
31
 
32
- Its exact Claude Code 2.1.227 runtime/peer-protocol pin is fail-closed.
33
- Still-running 2.1.224, 2.1.225, and 2.1.226 sessions remain compatible during a
34
- patch upgrade because their registry records use the same reviewed peer
35
- protocol 1 shape.
32
+ Provider compatibility follows exact OS-boundary attestation, version-major
33
+ evidence, and bounded live-schema probes. A certified same-major build is
34
+ writable; a same-major build whose probes all pass is `schema_attested` and
35
+ writable only when the probes cover the write path. Current Claude probes cover
36
+ their native write path. Ordinary Codex compatibility and registration reads
37
+ remain read-only: they may include `initialize`, `thread/loaded/list`, and
38
+ registration-time `thread/resume`, but do not invoke `turn/start`. The optional
39
+ Codex write-attestation probe is the sole exception. It may create at most one
40
+ disposable broker-owned thread per attempt, under a bounded write fence with
41
+ zero user-thread contact; every created probe thread is archived and confirmed
42
+ absent from the loaded set. The probe resolves the pinned model's lowest
43
+ advertised effort. Whenever that model/effort pin cannot resolve, it declines
44
+ in a zero-spend fail-safe before creating any thread or model turn. An untested
45
+ Codex 0.x build therefore stays monitor-only pending a certified write schema.
46
+ Failed
47
+ probes, a different major, or version evidence that
48
+ cannot establish a safe major leave only that provider degraded, monitor-only,
49
+ and write-fenced while the
50
+ broker and other provider remain available. Probes never promote across a
51
+ major or compensate for unknown major evidence; an exact official launcher
52
+ target may supply separate bounded major evidence even when its banner is
53
+ unparseable. Unsafe OS evidence for Embassy-owned or executed artifacts and
54
+ Embassy callback, control, or state paths refuses broker startup; unsafe UID or
55
+ mode evidence on Claude's external sessions registry root quarantines only
56
+ Claude. A Claude
57
+ session record whose native peer protocol is not 1 is rejected in isolation and
58
+ included in bounded rejection evidence.
36
59
 
37
60
  It is deliberately:
38
61
 
@@ -67,30 +90,39 @@ not wrap, replace, or recreate either provider.
67
90
 
68
91
  ### Claude Code
69
92
 
70
- **Official:** Claude Code 2.1.227 documents cross-session messaging on macOS
93
+ **Official:** Claude Code documents cross-session messaging on macOS
71
94
  and Linux. Real Claude sessions can use `ListAgents` to find other real Claude
72
95
  sessions and `SendMessage` to contact them. A target can accept, hold, or
73
96
  refuse inbound cross-session messages through `crossSessionInbound`. Messages
74
97
  do not bypass the receiver's tool permissions or approval boundary.
75
98
 
76
- **Version-pinned internal boundary:** the installed Claude Code 2.1.227 build
77
- advertises live sessions through registry records and transports peer frames
78
- over per-session Unix-domain sockets using peer protocol 1. Those registry and
79
- wire shapes are not documented as a stable third-party integration API. The
80
- gateway therefore pins the exact Claude Code version and protocol, validates
81
- every record and socket immediately before use, and fails closed after an
82
- update until the adapter is reviewed again.
99
+ **Evidence-gated internal boundary:** the installed Claude Code build advertises
100
+ live sessions through registry records and transports peer frames over
101
+ per-session Unix-domain sockets using peer protocol 1. Those registry and wire
102
+ shapes are not documented as a stable third-party integration API. The gateway
103
+ therefore assigns write authority only from supported-major evidence and
104
+ bounded live-schema probes, and validates every consumed field, frame, and
105
+ socket immediately before use. Unknown top-level registry fields are tolerated
106
+ because Embassy never consumes them; malformed required fields and records
107
+ whose peer protocol is not 1 remain isolated and counted. A passing same-major
108
+ patch outside the tested inventory is writable `schema_attested`; a failed
109
+ probe, different major, or version evidence that cannot establish a safe major
110
+ keeps only the Claude surface monitor-only. An exact official launcher target
111
+ may supply separate bounded major evidence when its banner is unparseable, but
112
+ unknown major evidence is never promoted by probes.
83
113
 
84
114
  For the lowest-impedance native path, the gateway publishes one process-owned
85
- registry record whose name is visibly prefixed `codex-`. The listener remains
86
- gateway-owned and does not claim to be a Claude model session; the explicit
87
- name is the product boundary. The record uses the version-pinned native peer
88
- shape so Claude's own `ListAgents` and `SendMessage` tools work unchanged.
115
+ registry record whose name is visibly prefixed `codex-` and which carries the
116
+ supported explicit versioned Embassy-advertisement marker. The listener remains
117
+ gateway-owned and does not claim to be a Claude model session; the marker, not
118
+ the name prefix alone, distinguishes Embassy's advertisement. The record uses
119
+ the schema-attested native peer shape so Claude's own `ListAgents` and
120
+ `SendMessage` tools work unchanged.
89
121
 
90
122
  Consequences:
91
123
 
92
124
  - Native Claude `ListAgents` discovers real Claude sessions plus the one
93
- explicitly named `codex-*` gateway peer.
125
+ explicitly marked `codex-*` gateway peer.
94
126
  - The gateway discovers compatible real Claude sessions as transient
95
127
  candidates, but publishes only sanitized aliases and state. A send from a
96
128
  registered Codex task may address only an explicitly selected route by its
@@ -162,8 +194,8 @@ The status below is intentionally narrower than the target architecture.
162
194
  | Private JSONL control protocol over a controller-owned UDS | **Implemented**, deterministic synthetic tests; no provider connection required |
163
195
  | Static metadata-only dashboard renderer and atomic publisher | **Implemented**, deterministic security tests; the static renderer requires no browser or HTTP server |
164
196
  | Opt-in live dashboard companion (`embassy dashboard --live`) | **Implemented**, deterministic tests over the stable loopback listener, direct multi-browser access, projection, request guards, and four bounded route actions; it is a separate foreground process, never part of `embassy serve` |
165
- | Claude registry/peer adapter pinned to 2.1.227 / peer protocol 1 | **Implemented** and live-tested, including 2.1.224–2.1.227 patch-overlap discovery, print-session discovery, native status frames, cancellation, and accessible-workspace attestation |
166
- | Automatic exact Claude 2.1.227 binary/runtime validation | **Implemented**; executes only bounded `claude --version` with a scrubbed environment and derives but does not open provider roots |
197
+ | Claude registry/peer adapter gated by supported major / peer protocol 1 / live schema probes | **Implemented** and live-tested through Claude Code 2.1.227, including patch-overlap discovery, print-session discovery, native status frames, cancellation, accessible-workspace attestation, and writable `schema_attested` admission for passing same-major builds outside the tested inventory |
198
+ | Automatic Claude binary/runtime attestation | **Implemented**; validates the exact owned path, executes only bounded `claude --version` with a scrubbed environment, tolerates bounded suffix/stderr observations, and derives but does not open provider roots |
167
199
  | Allowlisted Codex App Server connector with bounded busy behavior | **Implemented** and live-tested against App Server 0.147.0 for external busy observation, registered-route reachability across settings changes, and an automatically started queued turn; exact `STEER:` boundary behavior is covered deterministically |
168
200
  | Attach-only local Codex proxy transport and exact-owned cleanup | **Implemented**, five deterministic tests; no live App Server connection in routine tests |
169
201
  | Local provider adapters | **Implemented**, focused synthetic tests cover genuine-interactive Claude discovery, exact send/callback/receipt settlement and post-dispatch refresh, plus exact opted-in Codex ownership, registered-route reachability, monitor-only fallback, and cleanup; remote adapters remain disabled |
@@ -239,19 +271,39 @@ ambiguous cases fail closed; the browser cannot name a thread ID or endpoint
239
271
  generation.
240
272
 
241
273
  Claude discovery is passive and limited to currently advertised genuine
242
- Claude session records. A validated native record whose current name begins
243
- with reserved `codex-` is another gateway advertisement, not a selectable
244
- Claude destination, and is excluded. Discovery produces a bounded, sanitized `availablePeers`
245
- inventory keyed for display by the latest name. The adapter validates the
246
- exact pinned schema, session UUID, process identity and liveness,
247
- record/socket type, PID and socket-path correlation, allowed roots, and
248
- file/socket generations. Provider-owned Unix owner and mode bits are not
249
- treated as gateway policy; successful filesystem access is sufficient. A
250
- current name resolves to a UUID but never substitutes for it.
274
+ Claude session records. Only a validated native record bearing the supported
275
+ explicit versioned Embassy-advertisement marker is classified as a gateway
276
+ advertisement and excluded as a Claude destination. A genuine unmarked Claude
277
+ session remains selectable even when its current name begins `codex-`.
278
+ Discovery produces a bounded, sanitized `availablePeers` inventory keyed for
279
+ display by the latest name. The adapter
280
+ strictly validates every required and consumed registry field, session UUID,
281
+ process identity and liveness, record/socket type, PID and socket-path
282
+ correlation, allowed roots, and file/socket generations while tolerating
283
+ unknown top-level fields. The existing public Claude connector row may carry
284
+ bounded `registry` evidence: `entriesScanned`, `parseableRecords`, monotonic
285
+ `parseableRecordSeenSinceBoot`, bounded per-safe-code `rejected`, and
286
+ `rejectedCodesOmitted`. A registry directory that has yielded no record with
287
+ parseable required fields since broker start is therefore a loud bounded
288
+ observation rather than a healthy-looking empty list; if Claude is running,
289
+ its registry layout may have changed.
290
+ Before that enumeration, the Claude-owned external sessions registry root must
291
+ belong to the current UID with exact mode 0700; failure quarantines and
292
+ write-fences only Claude. Within an admitted root, individual registry records
293
+ and peer sockets retain the schema, file/socket type, PID/path and allowed-root
294
+ correlation, accessibility, liveness, and generation checks above without an
295
+ invented additional owner or mode rule. A current name resolves to a UUID but
296
+ never substitutes for it.
251
297
 
252
298
  A selected Claude UUID remains the durable route identity until explicit
253
- unselection. Startup never enumerates Claude sessions and every restored route
254
- begins stale. A later, separately authorized discovery operation may reactivate
299
+ unselection. Startup performs a bounded read-only Claude registry scan solely
300
+ for connector-level schema, rejection, and empty-since-boot evidence. It
301
+ publishes no candidates and does not select, connect to, or adopt the identity
302
+ of any peer; every restored route begins stale. The stateful probe may replace
303
+ memory-only validated target bindings, including native IDs and socket-derived
304
+ binding evidence, until a later scan or close. Those bindings are neither
305
+ public nor persisted and confer no candidate publication, selection, or route
306
+ authority. A later, separately authorized discovery operation may reactivate
255
307
  the selection only when the full bounded scan contains exactly one compatible
256
308
  interactive peer with the byte-identical UUID on the same provider, host, and
257
309
  ownership lease. The adapter revalidates the current workspace and provider
@@ -283,7 +335,7 @@ The thin skill/CLI exposes the same safe alias list to either provider.
283
335
  `cross-session-message` textual frame with bounded sender attribution and a
284
336
  first-child reply hint containing the full conversation token, exact aliases,
285
337
  and reply command. It then opens a short-lived connection and writes one
286
- version-pinned peer frame immediately, regardless of whether the current
338
+ peer-protocol-1 frame immediately, regardless of whether the current
287
339
  Claude registry observation says `idle`, `busy`, or `waiting`. A reply
288
340
  request carries the gateway's own
289
341
  anonymous callback UDS as the transport reply address; that path is never
@@ -465,7 +517,7 @@ failures; they can never become ambiguous writes or replay authorizations.
465
517
 
466
518
  The gateway exposes `turn/steer` only through an exact leading `STEER:` body in
467
519
  the Claude-to-Codex direction. The global `EMBASSY_STEERING_ENABLED` switch is
468
- on by default and exact `0` disables classification. The pinned 0.147.0 schema
520
+ on by default and exact `0` disables classification. The tested 0.147.0 schema
469
521
  requires `expectedTurnId`, rejects a nonmatching active turn, reports a clean
470
522
  `activeTurnNotSteerable` condition, and returns the accepted turn ID. Embassy
471
523
  validates all of those temporal correlations before settlement. `turn/interrupt`
@@ -635,11 +687,21 @@ prototype state root is no longer read, locked, or mutated.
635
687
 
636
688
  It emits one normalized ready line, publishes the private dashboard, and
637
689
  holds the process until `SIGINT` or `SIGTERM`, when exact-owned resources are
638
- closed. Startup automatically validates the exact-pinned local Claude and Codex
639
- runtimes and binds controller-owned UDS listeners, but does not discover a Claude peer, write a
640
- provider socket, start a model turn, or contact a remote host. Its ready result
641
- reports local host `this-mac`, dashboard filename `gateway-dashboard.html`, and
642
- `codexMode: "native_messaging"` without exposing paths.
690
+ closed. Startup automatically attests the exact owned Claude and Codex paths,
691
+ observes their version majors, and runs bounded required-schema probes, then
692
+ binds controller-owned UDS listeners. A provider-local compatibility failure
693
+ keeps that surface monitor-only. Unsafe ownership, path, symlink, lease, state,
694
+ or generation evidence for Embassy-owned or executed artifacts and Embassy
695
+ callback, control, or state paths aborts startup; unsafe UID or mode evidence
696
+ on Claude's external sessions registry root quarantines only Claude. The bounded read-only Claude registry
697
+ scan records only connector-level schema, rejection, and empty evidence; it
698
+ does not publish candidates, select or connect to a peer, write a provider
699
+ socket, request provider history, start a model turn, or contact a remote host.
700
+ Validated target bindings may retain private native and socket-derived evidence
701
+ memory-only until rescan or close, but none enters public state or persistence.
702
+ Its ready result reports local host `this-mac`, dashboard filename
703
+ `gateway-dashboard.html`, and `codexMode: "native_messaging"` without exposing
704
+ paths.
643
705
 
644
706
  There is no arbitrary filesystem operation, shell command, SSH command, App
645
707
  Server method, Claude registry mutation, credential argument, approval reply,
@@ -654,8 +716,10 @@ thread/session generation, source alias, bounds, and conversation state.
654
716
  `send-to-claude`, `send-to-codex`, and `reply` each accept an opt-in `--track`
655
717
  flag that opens one progress watch over the resulting conversation, plus an
656
718
  optional `--idle-minutes <n>` that sets how long the watched thread may sit idle
657
- before the watch reports a stall. `n` is an integer from 1 through 1440 and
658
- defaults to 5; supplying it without `--track` is an argument error. A body with
719
+ before each bounded liveness nudge. If the watch ultimately times out, Embassy
720
+ records `settled` / `gateway` / `idle_timeout` only in watch history and emits
721
+ no runtime stall alert. `n` is an integer from 1 through 1440 and defaults to 5;
722
+ supplying it without `--track` is an argument error. A body with
659
723
  an exact leading `TRACK:` prefix opens the same watch at the default idle window
660
724
  without the flag.
661
725
 
@@ -685,19 +749,24 @@ host configuration. The two SSH connectors above remain planned rather than
685
749
  runnable v1 routes.
686
750
 
687
751
  The local connector resolves the managed standalone Codex release by exact
688
- path and version; it does not use `PATH`. That installation is separate from
752
+ owned path; it does not use `PATH`. That installation is separate from
689
753
  any NVM-managed `codex` on the user's `PATH` (for example
690
754
  `~/.nvm/versions/node/*/bin/codex`), does not replace
691
755
  it, and does not edit a shell profile. The two installations therefore do not
692
756
  conflict.
693
757
 
694
- The connector has a fixed App Server method allowlist. It may initialize,
695
- observe loaded tasks, resume/unsubscribe the exact registered task, start a
696
- dedicated turn, and interrupt only its own confirmed turn. Archive, delete,
758
+ The connector has a fixed App Server method allowlist. An ordinary connector
759
+ may initialize, observe loaded tasks, resume/unsubscribe the exact registered
760
+ task, start a dedicated turn, and interrupt only its own confirmed turn. The
761
+ optional write-attestation probe alone may call `thread/archive`, only for its
762
+ validated disposable broker-owned probe thread, then confirms that thread is
763
+ absent from the loaded set. The probe resolves the pinned model's lowest
764
+ advertised effort. Whenever that model/effort pin cannot resolve, it declines
765
+ in a zero-spend fail-safe before creating any thread or model turn. Delete,
697
766
  history, shell, configuration, authentication, plugin, approval-response, and
698
- generic RPC methods are excluded.
767
+ generic RPC methods remain excluded everywhere.
699
768
 
700
- Exact App Server 0.147.0 gates the privacy-preserving
769
+ The App Server capability first tested with 0.147.0 gates the privacy-preserving
701
770
  `thread/resume.excludeTurns` field behind initialization capability
702
771
  `experimentalApi: true`. The connector therefore hard-codes that one
703
772
  non-configurable capability solely to suppress history retrieval. Both initial
@@ -709,8 +778,21 @@ the closed RPC allowlist.
709
778
 
710
779
  Automatic generation validation and controller write activation are distinct
711
780
  gates. A replacement connector may initialize, list, resume, and expose
712
- normalized monitor state after its exact version and required schemas validate
713
- while still reporting its write gate as unavailable. No Claude-initiated turn
781
+ normalized monitor state while still reporting its write gate as unavailable.
782
+ A certified same-major Codex build may activate after the exact generation
783
+ checks pass. A fully probed untested same-major `schema_attested` build does not
784
+ authorize Codex writes. Its ordinary compatibility and registration reads
785
+ remain read-only: they may include `initialize`, `thread/loaded/list`, and
786
+ registration-time `thread/resume`, but do not invoke `turn/start`. The optional
787
+ Codex write-attestation probe is the sole exception. It may create at most one
788
+ disposable broker-owned thread per attempt, under a bounded write fence with
789
+ zero user-thread contact; every created probe thread is archived and confirmed
790
+ absent from the loaded set. The probe resolves the pinned model's lowest
791
+ advertised effort. Whenever that model/effort pin cannot resolve, it declines
792
+ in a zero-spend fail-safe before creating any thread or model turn. That build,
793
+ failed probes, a different major, or version evidence
794
+ that cannot establish a safe major remain on the monitor-only path and cannot
795
+ be promoted by probes. No Claude-initiated turn
714
796
  can start until the controller activates that exact endpoint generation and
715
797
  explicit route ownership is established.
716
798
 
@@ -722,7 +804,8 @@ no policy overrides. Settings notifications cannot make an explicitly
722
804
  registered live route unreachable or discard its accepted queue.
723
805
 
724
806
  Version 1 never changes or independently classifies a Codex task's approval or
725
- sandbox policy. Offline 0.147.0 `TurnStartParams` schema evidence shows that
807
+ sandbox policy. Offline `TurnStartParams` schema evidence from tested App
808
+ Server 0.147.0 shows that
726
809
  policy overrides persist for the current and subsequent turns, so using them
727
810
  as per-message restrictions would silently mutate the native task. Embassy
728
811
  therefore starts the turn without overrides and leaves approval, sandbox, and
@@ -783,7 +866,7 @@ Offline 0.147.0 schema generation also confirms that `TurnSteerParams` requires
783
866
  exact `threadId`, `input`, and `expectedTurnId`; the precondition fails
784
867
  when that ID is not the current active turn. `TurnSteerResponse` returns the
785
868
  accepted `turnId`, and the closed App Server error shape includes
786
- `activeTurnNotSteerable`. Embassy pins and validates this schema, delegates the
869
+ `activeTurnNotSteerable`. Embassy validates this schema at its use boundary, delegates the
787
870
  next-tool-call timing boundary to App Server, treats a clean refusal as normal
788
871
  queue fallback, and treats malformed or write-ambiguous results as terminally
789
872
  uncertain without replay.
@@ -791,10 +874,14 @@ uncertain without replay.
791
874
  The one Desktop restart needed for the local shared-App-Server feasibility
792
875
  test has already been completed. Building, running synthetic tests, starting
793
876
  the gateway, rendering the dashboard, and a future Claude peer-socket test do
794
- not themselves require another Desktop restart. A provider or Desktop upgrade
795
- outside this release's exact pins requires an updated, reviewed Embassy
796
- adapter and, if its attachment mode changes, a separately announced controlled
797
- restart.
877
+ not themselves require another Desktop restart. A provider or Desktop major
878
+ upgrade outside the supported compatibility major leaves only that provider
879
+ monitor-only and requires an Embassy release supporting the observed major
880
+ before writes can resume. A required-schema or declared-protocol change also
881
+ keeps its responsible boundary closed. If the attachment mode changes, the
882
+ supporting release may require a separately announced controlled restart.
883
+ Patch updates within the supported major are admitted according to live
884
+ evidence rather than a release pin.
798
885
 
799
886
  ## Dashboard
800
887
 
@@ -949,14 +1036,14 @@ and fake App Server transports.
949
1036
 
950
1037
  ### Exact default roots on macOS
951
1038
 
952
- The automatic exact-version validator derives these paths from the current OS user's
1039
+ The automatic provider attestor derives these paths from the current OS user's
953
1040
  verified home; it does not scan the home directory. These are the reviewed
954
1041
  boundaries exercised by the live gateway; routine tests substitute synthetic
955
1042
  paths, peers, and transports:
956
1043
 
957
1044
  | Path/capability | Minimum purpose |
958
1045
  | --- | --- |
959
- | `~/.local/bin/claude` (or the absolute `EMBASSY_CLAUDE_BIN` override) and derived expected target `~/.local/share/claude/versions/2.1.227` | Stat the owned launcher/path components and read/execute only the resolved pinned target for bounded `--version`; `PATH` and interactive shell profiles are never searched; live launcher validation succeeded |
1046
+ | `~/.local/bin/claude` (or the absolute `EMBASSY_CLAUDE_BIN` override) and its derived current target under `~/.local/share/claude/versions/` | Stat the owned launcher/path components and read/execute only the resolved version target for bounded `--version`; `PATH` and interactive shell profiles are never searched; live launcher validation succeeded |
960
1047
  | `~/.claude/sessions` | Read/enumerate only live registry JSON during the separately authorized passive-discovery gate |
961
1048
  | `/tmp/cc-socks` | At foreground startup, validate the private directory and create/remove only `/tmp/cc-socks/<gateway-pid>.sock` after inode/generation checks; search/stat genuine peers at passive discovery and connect one validated target only at the separately authorized send gate |
962
1049
  | `~/.local/state/agent-embassy/.agent-embassy-state` | Validate or establish the exact ownership marker before creating the fixed host lease; an existing non-empty unmarked root is rejected without mutation |
@@ -964,7 +1051,7 @@ paths, peers, and transports:
964
1051
  | `/usr/bin/open` | Executed only by the opt-in `embassy dashboard --live` companion, to open the loopback dashboard URL in the operator's browser; no shell, a scrubbed fixed environment, and a bounded timeout and output cap |
965
1052
  | `~/.local/state/agent-embassy/.gateway-host.lock` | Fixed per-login kernel-held lease acquired before provider setup; it remains here even when `EMBASSY_STATE_DIR` is overridden. Its bounded PID/token record is exact-cleanup metadata, not a path-only stale-lock authority; a crash releases the kernel lock and the next foreground process may acquire the existing file |
966
1053
  | `~/.local/state/agent-embassy` (or explicit `EMBASSY_STATE_DIR`) | Default controller-owned store, control UDS, state lock, and static dashboard; an explicit absolute configuration may replace only these state surfaces |
967
- | `~/.codex/packages/standalone` and `~/.codex/app-server-control/app-server-control.sock` | Resolve the pinned managed Codex binary and attach to the already-running private local App Server; never bootstrap or unlink it |
1054
+ | `~/.codex/packages/standalone` and `~/.codex/app-server-control/app-server-control.sock` | Resolve the exact owned managed Codex binary and attach to the already-running private local App Server; never bootstrap or unlink it |
968
1055
 
969
1056
  No grant to `~/.claude/projects`, the rest of
970
1057
  `~/.claude`, Keychain APIs, the full home directory, or
@@ -979,8 +1066,30 @@ the preferred least-context setup, but it is not mandatory.
979
1066
 
980
1067
  ## Failure and upgrade policy
981
1068
 
982
- - Unknown Claude Code version, peer protocol, message version, App Server
983
- response shape, or endpoint generation fails closed.
1069
+ - A certified same-major provider build is writable; a fully probed same-major
1070
+ build is `schema_attested` and writable only where the probes cover writes.
1071
+ Ordinary Codex compatibility and registration reads remain read-only: they
1072
+ may include `initialize`, `thread/loaded/list`, and registration-time
1073
+ `thread/resume`, but do not invoke `turn/start`. The optional Codex
1074
+ write-attestation probe is the sole exception. It may create at most one
1075
+ disposable broker-owned thread per attempt, under a bounded write fence with
1076
+ zero user-thread contact; every created probe thread is archived and
1077
+ confirmed absent from the loaded set. The probe resolves the pinned model's
1078
+ lowest advertised effort. Whenever that model/effort pin cannot resolve, it
1079
+ declines in a zero-spend fail-safe before creating any thread or model turn.
1080
+ Current untested Codex 0.x therefore stays monitor-only. Failed
1081
+ probes, a different major, or
1082
+ version evidence that cannot establish a safe major leave only that provider
1083
+ monitor-only and write-fenced. Probes never promote across a major or
1084
+ compensate for unknown major evidence. A different-major alert names the observed/tested versions
1085
+ and supported major and requires an Embassy release supporting the observed
1086
+ major. A session record whose peer protocol is not 1 is rejected per record
1087
+ and counted without stopping the broker.
1088
+ - Unsafe ownership, path, symlink, lease, state, or generation evidence for
1089
+ Embassy-owned or executed artifacts and Embassy callback, control, or state
1090
+ paths refuses broker startup. Unsafe UID or mode evidence on Claude's
1091
+ external sessions registry root quarantines only Claude. A malformed message version, required App Server response
1092
+ shape, or endpoint generation fails closed on its affected route.
984
1093
  - Alias collisions, stale ownership leases, PID/socket races, unsafe
985
1094
  gateway-owned state, unexpected paths, queue overflow, deadline expiry, and ambiguous writes are
986
1095
  normalized failures, never raw diagnostics.
@@ -1018,9 +1127,12 @@ the preferred least-context setup, but it is not mandatory.
1018
1127
  the process was lost settles `ambiguous` with `CONTROLLER_RESTARTED`; a
1019
1128
  message whose target authority was transient, or whose target route no longer
1020
1129
  exists, settles `abandoned` with the same code.
1021
- - A provider or Desktop update outside the release's exact reviewed pins fails
1022
- closed; retained state never admits an unreviewed version or activates an
1023
- unvalidated replacement endpoint generation.
1130
+ - A provider or Desktop update outside the supported major leaves that surface
1131
+ monitor-only while the broker and other surface remain available. A Claude
1132
+ record outside peer protocol 1 is rejected per record; a required live-schema
1133
+ failure degrades the responsible provider, and retained state never activates
1134
+ an unvalidated replacement endpoint generation. A patch update that passes
1135
+ those checks does not block writes for its version alone.
1024
1136
 
1025
1137
  ## Validation boundary
1026
1138
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-embassy",
3
- "version": "1.4.1",
3
+ "version": "1.6.0",
4
4
  "description": "A local gateway for bidirectional messaging between Claude Code sessions and Codex tasks.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -17,7 +17,7 @@ Address a Claude session by its latest `name@host` or by a user-supplied native
17
17
 
18
18
  Run `embassy status` to read the current snapshot. Run `embassy refresh-dashboard` when passive live discovery is authorized. Claude Code's native `ListAgents` includes genuine Claude sessions plus each explicitly advertised `codex-*` Embassy peer.
19
19
 
20
- Read the status snapshot's `availablePeers` as sanitized current-name candidates. Native `codex-*` gateway advertisements are excluded because they are not Claude destinations. A send never pairs with a Claude session automatically. Create the exact user-chosen edge with `pair` — or the one-task shorthand `select-claude` — before sending; an unpaired destination is not routable.
20
+ Read the status snapshot's `availablePeers` as sanitized current-name candidates. Native records carrying Embassy's supported explicit versioned advertisement marker are excluded because they are not Claude destinations; a genuine unmarked Claude session remains visible even when its name starts with `codex-*`. A send never pairs with a Claude session automatically. Create the exact user-chosen edge with `pair` — or the one-task shorthand `select-claude` — before sending; an unpaired destination is not routable.
21
21
 
22
22
  Accept a Claude session UUID only when the user supplies it or it is already part of the current task context. Never discover one by scanning history or configuration, and never infer a peer from a thread ID, process ID, working directory, socket path, or title.
23
23
 
@@ -31,7 +31,7 @@ embassy health
31
31
 
32
32
  If Embassy is unavailable, stop and report that it must be started in a trusted local terminal with `embassy serve`. `GATEWAY_INSTANCE_IN_USE` means an Embassy or recognized legacy lock already owns this login account; stop that foreground process rather than changing `EMBASSY_STATE_DIR`. If no legacy process remains, the operator may remove only the exact stale legacy controller lock and retry. Do not launch a background copy, retry in a loop, discover sockets, or fall back to a provider CLI.
33
33
 
34
- Compatibility is automatic, exact-version-pinned broker state. Startup validates the release's reviewed Claude and Codex versions and required protocol shapes; there is no separate agent or operator compatibility action. If an unknown version or required shape fails closed, report the safe result and stop rather than probing the provider, sending a test message, or trying to override the gate.
34
+ Compatibility is automatic and evidence-gated. A certified same-major provider is writable; a same-major build whose bounded live schema probes all pass is schema-attested (`schema_attested`) and writable only when those probes cover the write path. Claude's probes cover its native write path. Ordinary Codex compatibility and registration reads remain read-only: they may include `initialize`, `thread/loaded/list`, and registration-time `thread/resume`, but do not invoke `turn/start`. The optional Codex write-attestation probe is the sole exception. It may create at most one disposable broker-owned thread per attempt, under a bounded write fence with zero user-thread contact; every created probe thread is archived and confirmed no longer loaded. The probe resolves the pinned model's lowest advertised effort. Whenever that model/effort pin cannot resolve, it declines in a zero-spend fail-safe before creating any thread or model turn. Untested Codex 0.x therefore stays monitor-only. Failed probes, a different major, or version evidence that cannot establish a safe major leave only that provider degraded, monitor-only, and write-fenced while the broker and other provider remain available; probes never promote across a major or unknown major. A different-major alert safely names the observed/tested versions and supported major and means an Embassy release supporting the observed major is required—`embassy health` is not a recovery step. Claude `peerProtocol 1` is required per registry record; other values are rejected in isolation and counted. Unknown top-level registry fields are tolerated, but every required known field remains strict; bounded rejected-record counts and an observed-empty registry are loud status and dashboard observations. There is no separate agent or operator compatibility action. Report a degraded surface and stop rather than manually probing the provider, sending a test message, or trying to override the fence.
35
35
 
36
36
  List the public snapshot:
37
37