agent-embassy 1.7.0 → 1.8.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 (118) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/CONTRIBUTING.md +51 -47
  3. package/README.md +26 -9
  4. package/README.zh-CN.md +22 -9
  5. package/SECURITY.md +48 -35
  6. package/dist/src/gateway/acp-client.d.ts +12 -19
  7. package/dist/src/gateway/acp-client.js +90 -65
  8. package/dist/src/gateway/acp-client.js.map +1 -1
  9. package/dist/src/gateway/acp-provider.d.ts +11 -10
  10. package/dist/src/gateway/acp-provider.js +165 -53
  11. package/dist/src/gateway/acp-provider.js.map +1 -1
  12. package/dist/src/gateway/claude-helper-client.d.ts +2 -43
  13. package/dist/src/gateway/claude-helper-client.js +1 -211
  14. package/dist/src/gateway/claude-helper-client.js.map +1 -1
  15. package/dist/src/gateway/claude-helper-protocol.d.ts +16 -74
  16. package/dist/src/gateway/claude-helper-protocol.js +99 -378
  17. package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
  18. package/dist/src/gateway/claude-helper-supervisor.d.ts +56 -44
  19. package/dist/src/gateway/claude-helper-supervisor.js +265 -456
  20. package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
  21. package/dist/src/gateway/claude-helper.js +184 -210
  22. package/dist/src/gateway/claude-helper.js.map +1 -1
  23. package/dist/src/gateway/claude-peer.d.ts +20 -87
  24. package/dist/src/gateway/claude-peer.js +310 -1009
  25. package/dist/src/gateway/claude-peer.js.map +1 -1
  26. package/dist/src/gateway/claude-runtime.d.ts +13 -15
  27. package/dist/src/gateway/claude-runtime.js +14 -168
  28. package/dist/src/gateway/claude-runtime.js.map +1 -1
  29. package/dist/src/gateway/cli-copy.en.d.ts +2 -2
  30. package/dist/src/gateway/cli-copy.en.js +4 -2
  31. package/dist/src/gateway/cli-copy.en.js.map +1 -1
  32. package/dist/src/gateway/cli-copy.zh-CN.d.ts +2 -2
  33. package/dist/src/gateway/cli-copy.zh-CN.js +4 -2
  34. package/dist/src/gateway/cli-copy.zh-CN.js.map +1 -1
  35. package/dist/src/gateway/cli.d.ts +7 -2
  36. package/dist/src/gateway/cli.js +277 -575
  37. package/dist/src/gateway/cli.js.map +1 -1
  38. package/dist/src/gateway/codex-app-server.d.ts +5 -227
  39. package/dist/src/gateway/codex-app-server.js +18 -1463
  40. package/dist/src/gateway/codex-app-server.js.map +1 -1
  41. package/dist/src/gateway/codex-doctor.d.ts +36 -0
  42. package/dist/src/gateway/codex-doctor.js +127 -0
  43. package/dist/src/gateway/codex-doctor.js.map +1 -0
  44. package/dist/src/gateway/codex-local-transport.d.ts +6 -6
  45. package/dist/src/gateway/codex-local-transport.js +13 -10
  46. package/dist/src/gateway/codex-local-transport.js.map +1 -1
  47. package/dist/src/gateway/codex-stateless-transport.d.ts +114 -0
  48. package/dist/src/gateway/codex-stateless-transport.js +1108 -0
  49. package/dist/src/gateway/codex-stateless-transport.js.map +1 -0
  50. package/dist/src/gateway/config.d.ts +2 -9
  51. package/dist/src/gateway/config.js +62 -100
  52. package/dist/src/gateway/config.js.map +1 -1
  53. package/dist/src/gateway/control.d.ts +36 -90
  54. package/dist/src/gateway/control.js +465 -1123
  55. package/dist/src/gateway/control.js.map +1 -1
  56. package/dist/src/gateway/dashboard-copy.d.ts +1 -1
  57. package/dist/src/gateway/dashboard-copy.en.d.ts +8 -26
  58. package/dist/src/gateway/dashboard-copy.en.js +19 -37
  59. package/dist/src/gateway/dashboard-copy.en.js.map +1 -1
  60. package/dist/src/gateway/dashboard-copy.js +8 -26
  61. package/dist/src/gateway/dashboard-copy.js.map +1 -1
  62. package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +8 -26
  63. package/dist/src/gateway/dashboard-copy.zh-CN.js +19 -37
  64. package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -1
  65. package/dist/src/gateway/dashboard-model.d.ts +8 -22
  66. package/dist/src/gateway/dashboard-model.js +44 -130
  67. package/dist/src/gateway/dashboard-model.js.map +1 -1
  68. package/dist/src/gateway/dashboard.d.ts +0 -6
  69. package/dist/src/gateway/dashboard.js +3 -7
  70. package/dist/src/gateway/dashboard.js.map +1 -1
  71. package/dist/src/gateway/live-dashboard-app/app.js +20 -34
  72. package/dist/src/gateway/live-dashboard-command.js +2 -2
  73. package/dist/src/gateway/live-dashboard-command.js.map +1 -1
  74. package/dist/src/gateway/live-dashboard-http.d.ts +1 -1
  75. package/dist/src/gateway/live-dashboard-http.js +2 -2
  76. package/dist/src/gateway/live-dashboard-http.js.map +1 -1
  77. package/dist/src/gateway/progress-watch-machine.d.ts +1 -37
  78. package/dist/src/gateway/progress-watch-machine.js +4 -15
  79. package/dist/src/gateway/progress-watch-machine.js.map +1 -1
  80. package/dist/src/gateway/providers.d.ts +58 -191
  81. package/dist/src/gateway/providers.js +637 -2434
  82. package/dist/src/gateway/providers.js.map +1 -1
  83. package/dist/src/gateway/server.d.ts +16 -25
  84. package/dist/src/gateway/server.js +165 -240
  85. package/dist/src/gateway/server.js.map +1 -1
  86. package/dist/src/gateway/service.d.ts +149 -427
  87. package/dist/src/gateway/service.js +1639 -5662
  88. package/dist/src/gateway/service.js.map +1 -1
  89. package/dist/src/gateway/state-v2-to-v3.d.ts +23 -0
  90. package/dist/src/gateway/state-v2-to-v3.js +994 -0
  91. package/dist/src/gateway/state-v2-to-v3.js.map +1 -0
  92. package/dist/src/gateway/store.d.ts +54 -309
  93. package/dist/src/gateway/store.js +1560 -3510
  94. package/dist/src/gateway/store.js.map +1 -1
  95. package/dist/src/gateway/types.d.ts +181 -225
  96. package/dist/src/gateway/types.js +115 -251
  97. package/dist/src/gateway/types.js.map +1 -1
  98. package/docs/CONFIGURATION.md +22 -9
  99. package/docs/CONFIGURATION.zh-CN.md +21 -9
  100. package/docs/DASHBOARD.md +10 -10
  101. package/docs/DASHBOARD.zh-CN.md +3 -3
  102. package/docs/DELIVERY.md +4 -4
  103. package/docs/DELIVERY.zh-CN.md +4 -4
  104. package/docs/GATEWAY-ARCHITECTURE.md +158 -187
  105. package/package.json +1 -1
  106. package/skills/embassy-peer/SKILL.md +28 -22
  107. package/dist/src/gateway/codex-registration-generation.d.ts +0 -5
  108. package/dist/src/gateway/codex-registration-generation.js +0 -19
  109. package/dist/src/gateway/codex-registration-generation.js.map +0 -1
  110. package/dist/src/gateway/codex-registration-succession.d.ts +0 -209
  111. package/dist/src/gateway/codex-registration-succession.js +0 -588
  112. package/dist/src/gateway/codex-registration-succession.js.map +0 -1
  113. package/dist/src/gateway/compatibility.d.ts +0 -22
  114. package/dist/src/gateway/compatibility.js +0 -23
  115. package/dist/src/gateway/compatibility.js.map +0 -1
  116. package/dist/src/gateway/delivery-machine.d.ts +0 -235
  117. package/dist/src/gateway/delivery-machine.js +0 -540
  118. package/dist/src/gateway/delivery-machine.js.map +0 -1
@@ -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
- Embassy presents Claude, Codex, DeepSeek, and Grok as first-class providers. Runtime status is best-effort: use route staleness, connector health, observed metadata, and the last safe code to explain what is available now. Provider versions are diagnostic metadata, not routing authority; the release-owned offline support matrix is the record of tested artifacts, capabilities, limitations, and test dates. There is no agent or operator compatibility action. Report a degraded surface and stop rather than sending a test message or trying to override a failed route.
34
+ Embassy presents Claude, Codex, DeepSeek, and Grok as first-class providers. Runtime status is best-effort: use observation freshness, connector health, observed metadata, and the last safe code to explain what is available now. Provider versions are diagnostic metadata, not routing authority; the release-owned offline support matrix is the record of tested artifacts, capabilities, limitations, and test dates. There is no agent or operator compatibility action. Report a degraded surface and stop rather than sending a test message or trying to override a failed operation.
35
35
 
36
36
  List the public snapshot:
37
37
 
@@ -93,27 +93,25 @@ Register only from the Codex task being named:
93
93
  embassy register-codex --alias codex-reviewer@this-mac
94
94
  ```
95
95
 
96
- Let the CLI read that task's inherited `CODEX_THREAD_ID`. Never supply the thread ID as an argument, print it, persist it, or register another task by guessing its identity. The alias must start with `codex-`; a successful registration advertises that task for native inbound turns.
96
+ Let the CLI read that task's inherited `CODEX_THREAD_ID`. Never supply the thread ID as an argument, print it, persist it, or register another task by guessing its identity. The alias must start with `codex-`. Registration commits only the logical route record and performs no provider or App Server I/O. Advertisement reconciles separately and best-effort; bounded observation is display-only and never routing authority or a dispatch gate. Every Codex operation independently attests the current interface and resumes the exact registered task before final write authorization.
97
97
 
98
98
  The first successful Codex registration fixes its exact alias, task, and host
99
- until it is explicitly succeeded. Exact re-registration remains available for
100
- connector recovery. To hand the registration to a different task on the same
101
- host, run this from inside the successor task:
99
+ until it is removed or explicitly succeeded. To hand the registration to a
100
+ different task on the same host, run this from inside the successor task:
102
101
 
103
102
  ```sh
104
103
  embassy register-codex --alias codex-successor@this-mac --succeeds codex-reviewer@this-mac
105
104
  ```
106
105
 
107
- This is the only supported identity change without restarting the broker.
108
- Embassy freezes the outgoing route, drains its accepted work to terminal
109
- settlement, and publishes the successor on a fresh listener generation.
110
- Nothing transfers: no queued body, conversation, reply capability, or delivery
111
- token. A succession that cannot be completed pins the identity fail-closed
112
- until manual recovery rather than leaving two live registrations.
113
-
114
- Embassy also pins the exact identity fail-closed when a retained route cannot fully reactivate or a fresh registration cannot confirm complete rollback. Retry only that exact identity; choose another only after the old route is confirmed unregistered and Embassy is restarted.
115
-
116
- A Codex App Server generation change or broker restart can reattach an exact registered task automatically. Each replacement generation negotiates its current interface and must observe the exact task before the controller re-anchors it. A normal broker restart therefore needs no manual registration. If boot reactivation cannot find the task exactly once, the route remains stale with `REOBSERVATION_REQUIRED`; once the task is observable, recover it only from that exact Codex task by rerunning `embassy register-codex --alias <same-alias>`. Do not unregister first, supply a thread ID, or replay any ambiguously written body.
106
+ This is one atomic logical replacement. The commit cancels queued or reserved
107
+ work with `ROUTE_UNREGISTERED`, settles armed work `ambiguous` and accepted
108
+ work `unconfirmed`, removes every incident consent edge and capability, and
109
+ installs only the successor. It never waits for a model turn and has no
110
+ prepared listener, activation, re-anchoring, succession journal, or recovery
111
+ generation. Nothing transfers: no conversation, reply or native capability,
112
+ pairing authority, rate ownership, or deduplication ownership. Advertisement
113
+ of the successor reconciles asynchronously and cannot roll back the committed
114
+ logical identity.
117
115
 
118
116
  Unregister from the same Codex task:
119
117
 
@@ -122,6 +120,10 @@ embassy unregister-codex --alias codex-reviewer@this-mac
122
120
  ```
123
121
 
124
122
  If the task identity or selector does not match, stop on the fail-closed result.
123
+ Successful unregister is the exact-owner form of the same atomic removal: it
124
+ removes incident consent edges and conversation, reply, or native capabilities,
125
+ cancels queued/reserved work, settles armed work `ambiguous`, and settles
126
+ accepted work `unconfirmed`.
125
127
 
126
128
  ## Send a message
127
129
 
@@ -146,7 +148,7 @@ The foreground launcher supports native bidirectional messaging for each explici
146
148
 
147
149
  Direction determines timing. Once routing and pre-write checks pass, every Claude-bound send or correlated reply writes immediately to Claude's native mailbox regardless of its observed busy or idle state. Do not wait for Claude to become idle or report its busy state as a queue reason. `transport_written` is the terminal `delivered` boundary for that direction and means mailbox write, not read or consumption. Codex-bound ordinary work remains idle/turn-boundary gated; only the exact `STEER:` behavior below may target the active turn's next tool-call boundary.
148
150
 
149
- An accepted send returns a public conversation token and a fresh delivery token. The delivery token is an opaque, memory-only correlation handle, exactly `dlv_` plus 24 base64url characters. Use the exact returned values only for their intended CLI calls; do not construct, shorten, log, persist, or place either token in an agent-created file.
151
+ An accepted send returns a public conversation token and a fresh delivery token. The conversation token and reply capability are memory-only. The delivery token is an opaque correlation handle, exactly `dlv_` plus 24 base64url characters, retained only with its bounded private v3 message row. Use the exact returned values only for their intended CLI calls; do not construct, shorten, log, persist yourself, or place either token in an agent-created file.
150
152
 
151
153
  Use exactly one send for one user-authorized message. A send never selects a Claude session automatically. Do not automatically retry, fan out, hand-roll a poll loop, or fall back to Claude Code's native `SendMessage`.
152
154
 
@@ -192,15 +194,15 @@ embassy wait-delivery --token dlv_0123456789abcdefghijklmn
192
194
 
193
195
  It checks every 250 ms and emits only a terminal result. It stops at the delivery deadline plus 3 seconds; an unknown token fails immediately. Exit `0` means `delivered`; every other terminal state (`unconfirmed`, `expired`, `failed`, `ambiguous`, or `cancelled`) preserves its exact JSON result and uses the shared delivery-failure exit `6`. An unknown token exits `3`. A local waiter timeout exits `4`, is not a terminal result, and is not permission to resend. A terminal result closes only that delivery attempt: `delivered` does not promise a reply, and `unconfirmed` or `ambiguous` must never be retried automatically.
194
196
 
195
- The in-memory status table is bounded. Under pressure, only its oldest terminal handle may be evicted; active `queued` or `stalled` handles are retained. An evicted handle returns `{"found":false}`.
197
+ The private v3 message ledger is bounded. Under pressure, its oldest terminal row may be evicted while active `queued` or `stalled` rows are retained. A token absent from bounded retention returns `{"found":false}`.
196
198
 
197
199
  ## Interpret queue state
198
200
 
199
201
  Treat `accepted` as gateway ownership, not proof that the peer read or answered the message. Use `delivery-status` for the accepted delivery, or `status` and the dashboard for aggregate route state, when the user asks for progress. The optional `pendingForMs` field is age since acceptance, including in-flight time. `stalled` remains nonterminal. A Claude-bound tracker may be briefly `queued` for routing or pre-write work, but a busy Claude observation never idle-gates it: after those checks, the native mailbox write is immediate and `transport_written` settles `delivered`.
200
202
 
201
- For native Claude-to-Codex ingress, Embassy first attempts immediate dispatch. A terminal result observed before the one-second prompt boundary produces only its terminal acknowledgement; native `held` is sent only when the body truly remains queued or dispatch is still nonterminal at that boundary, followed later by the terminal acknowledgement. Claude's rendered “approved and released” notice means only that the paired-consent gateway accepted and released the body to the recipient queue — released is not read, and no human approval is implied. The default `merged` notice policy separately sends at most one nonterminal stall user frame exactly at `floor(messageDeadlineMs / 2)`, containing only a bounded pending age and allowlisted reason. The operator may choose `verbose` to retain the additional terminal diagnostic user frame or `quiet` to suppress gateway-authored user-frame notices; native status and dashboard truth do not change. Codex-bound ordinary work queues while the Codex task is active or temporarily unavailable. Only when the user explicitly asks to steer the active Codex turn may a Claude sender put the exact prefix `STEER:` at the beginning of the body. Embassy submits that input at the next tool-call boundary, never mid-generation or by interrupting; clean boundary refusal silently returns it to the normal queue. At most three steering messages remain queued per route, and the dashboard journal labels their lifecycle with `STEER`. If a registered Codex connector is closed or faulted, an explicit `register-codex` replaces it and wakes held work when the recovered route is idle; it never retries an ambiguous write.
203
+ For native Claude-to-Codex ingress, Embassy first attempts immediate dispatch. A terminal result observed before the one-second prompt boundary produces only its terminal acknowledgement; native `held` is sent only when the body truly remains queued or dispatch is still nonterminal at that boundary, followed later by the terminal acknowledgement. Claude's rendered “approved and released” notice means only that the paired-consent gateway accepted and released the body to the recipient queue — released is not read, and no human approval is implied. The default `merged` notice policy separately sends at most one nonterminal stall user frame exactly at `floor(messageDeadlineMs / 2)`, containing only a bounded pending age and allowlisted reason. The operator may choose `verbose` to retain the additional terminal diagnostic user frame or `quiet` to suppress gateway-authored user-frame notices; native status and dashboard truth do not change. Codex-bound ordinary work queues while the Codex task is active or temporarily unavailable. Only when the user explicitly asks to steer the active Codex turn may a Claude sender put the exact prefix `STEER:` at the beginning of the body. Embassy uses the exact accepted operation's same-session capability at the next tool-call boundary, never mid-generation or by interruption. Clean boundary refusal returns it to the normal queue; the cap is three steers per exact active operation. Embassy never calls `turn/interrupt` and never retries an ambiguous write.
202
204
 
203
- Do not synthesize `STEER:`, use it from Codex to Claude, approve permissions, widen tools, alter inbound-message policy, or interrupt a turn to force delivery. Report `held`, refused, incompatible, full, expired, unavailable, or `STEER_QUEUE_SUPERSEDED` outcomes or safe error codes without treating them as additional `delivery-status` states and without retrying. Native receipt settlement follows the originating Claude session's stable UUID and revalidates its current endpoint before every stall or terminal write; names, PIDs, and sockets are not receipt identity. Ordinary process/socket rotation for the same Claude UUID is therefore refreshed automatically. After a gateway restart, the prior UUID-bound selection starts stale, but the next authorized complete discovery may reactivate exactly that UUID and adopt its latest name. A changed UUID, name or UUID collision, incomplete discovery, or failed workspace/provider revalidation stays stale; do not retry around it. Queued or in-flight text, callbacks, native receipt handles, delivery tokens/status trackers, pending replies, and conversation capabilities do not survive. A pre-restart delivery token is unknown and no body is replayed.
205
+ Do not synthesize `STEER:`, use it from Codex to Claude, approve permissions, widen tools, alter inbound-message policy, or interrupt a turn to force delivery. Report `held`, refused, incompatible, full, expired, unavailable, or `STEER_QUEUE_SUPERSEDED` outcomes or safe error codes without treating them as additional `delivery-status` states and without retrying. Native receipt settlement follows the originating Claude session's stable UUID and revalidates its current endpoint before every stall or terminal write; names, PIDs, and sockets are not receipt identity. Ordinary process/socket rotation for the same Claude UUID is refreshed for that write. After a gateway restart, queued or reserved messages and their delivery tokens/status remain inspectable in the bounded private v3 ledger and may resume once within their deadline and attempt budget against the same exact route and consent edge. Armed work settles `ambiguous`; accepted work settles `unconfirmed`; neither is replayed. Conversations, reply/native capabilities, raw provider frames, callbacks, pending replies, and socket paths remain memory-only. Best-effort observation may refresh what status displays, but it never authorizes or gates delivery.
204
206
 
205
207
  ## Preserve the boundary
206
208
 
@@ -219,9 +221,13 @@ per-invocation `--port <n>`. It deliberately has no login, token, cookie, browse
219
221
  session, or local-process/UID authentication and assumes a trusted single-user
220
222
  machine; local software that can reach or spoof loopback can use it. Its only
221
223
  mutations are explicitly confirmed two-endpoint pair, unpair,
222
- refresh-discovery, and broker-guarded stale-registration-removal actions. It
223
- has no registration creation, live unregistration, send, reply, approval,
224
+ refresh-discovery, and named Codex-registration-removal actions. Confirmed
225
+ `remove_codex_registration` may remove any named Codex registration; its atomic
226
+ commit removes incident consent edges and conversation, reply, or native
227
+ capabilities, and settles queued/reserved work `cancelled`, armed work
228
+ `ambiguous`, and accepted work `unconfirmed`. It has no registration creation,
229
+ send, reply, approval,
224
230
  interruption, settings, or generic provider authority. Agent-facing paths
225
231
  remain `embassy status` for a sanitized snapshot and the static
226
232
  `gateway-dashboard.html` for offline metadata. A status snapshot observation
227
- may settle already-due lifecycle deliveries before projecting state.
233
+ may settle already-due delivery deadlines before projecting state.
@@ -1,5 +0,0 @@
1
- /** Closed grammar for opaque Codex listener and succession generations. */
2
- export declare function isCodexRegistrationGeneration(value: unknown): value is string;
3
- export declare function assertCodexRegistrationGeneration(value: unknown, label?: string): asserts value is string;
4
- /** A fresh 128-bit token that is safe in the closed generation grammar. */
5
- export declare function createCodexRegistrationGeneration(): string;
@@ -1,19 +0,0 @@
1
- import { randomBytes } from "node:crypto";
2
- const CODEX_REGISTRATION_GENERATION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$/u;
3
- /** Closed grammar for opaque Codex listener and succession generations. */
4
- export function isCodexRegistrationGeneration(value) {
5
- return (typeof value === "string" &&
6
- CODEX_REGISTRATION_GENERATION_PATTERN.test(value));
7
- }
8
- export function assertCodexRegistrationGeneration(value, label = "Codex registration generation") {
9
- if (!isCodexRegistrationGeneration(value)) {
10
- throw new TypeError(`${label} must match the bounded opaque generation grammar.`);
11
- }
12
- }
13
- /** A fresh 128-bit token that is safe in the closed generation grammar. */
14
- export function createCodexRegistrationGeneration() {
15
- const generation = `g_${randomBytes(16).toString("base64url")}`;
16
- assertCodexRegistrationGeneration(generation);
17
- return generation;
18
- }
19
- //# sourceMappingURL=codex-registration-generation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"codex-registration-generation.js","sourceRoot":"","sources":["../../../src/gateway/codex-registration-generation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,qCAAqC,GACzC,mCAAmC,CAAC;AAEtC,2EAA2E;AAC3E,MAAM,UAAU,6BAA6B,CAC3C,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,qCAAqC,CAAC,IAAI,CAAC,KAAK,CAAC,CAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iCAAiC,CAC/C,KAAc,EACd,KAAK,GAAG,+BAA+B;IAEvC,IAAI,CAAC,6BAA6B,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,SAAS,CACjB,GAAG,KAAK,oDAAoD,CAC7D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,iCAAiC;IAC/C,MAAM,UAAU,GAAG,KAAK,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;IAChE,iCAAiC,CAAC,UAAU,CAAC,CAAC;IAC9C,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -1,209 +0,0 @@
1
- /**
2
- * Pure lifecycle for replacing one registered Codex task with another.
3
- *
4
- * The reducer owns no sockets, registry files, message bodies, conversations,
5
- * timers, or provider clients. A controller executes the returned effects and
6
- * feeds the resulting observations back as events. Listener generations are
7
- * deliberately opaque; this module never derives a socket path or assumes a
8
- * suffixed-socket naming scheme.
9
- *
10
- * Publication arming is the conservative irreversible boundary: the reducer
11
- * enters it before emitting any durable-journal or registry-write effect.
12
- * Cleanup may restore the old registration only before arming, or after a
13
- * controller positively proves that neither the arm nor registry write was
14
- * persisted. At or after any armed/published/unknown observation, the old
15
- * registration can never be restored by this machine.
16
- */
17
- export declare const codexRegistrationSuccessionPhases: readonly ["active_old", "freezing", "prepared_new", "published_new", "active_new", "offline_poisoned", "recovery_required", "resuming_old"];
18
- export type CodexRegistrationSuccessionPhase = (typeof codexRegistrationSuccessionPhases)[number];
19
- export type CodexRegistrationIdentity = Readonly<{
20
- alias: string;
21
- threadId: string;
22
- hostId: string;
23
- generation: string;
24
- }>;
25
- type StablePhase = "active_old" | "active_new";
26
- type FreezingStage = "barrier_pending" | "listener_pending" | "store_pending";
27
- type PublicationBoundary = "not_armed" | "armed_or_unknown" | "published";
28
- export declare const codexSuccessionFailurePhases: readonly ["freeze", "barrier", "listener", "store", "publication_arm", "registry", "activation", "retirement", "cleanup", "resume"];
29
- export type CodexSuccessionFailurePhase = (typeof codexSuccessionFailurePhases)[number];
30
- type SuccessionContext = Readonly<{
31
- oldRegistration: CodexRegistrationIdentity;
32
- newRegistration: CodexRegistrationIdentity;
33
- priorStablePhase: StablePhase;
34
- }>;
35
- export type ActiveOldSuccessionState = Readonly<{
36
- phase: "active_old";
37
- active: CodexRegistrationIdentity;
38
- }>;
39
- export type ActiveNewSuccessionState = Readonly<{
40
- phase: "active_new";
41
- active: CodexRegistrationIdentity;
42
- /** At most one prior listener generation may await confirmed retirement. */
43
- retired: CodexRegistrationIdentity | null;
44
- }>;
45
- export type FreezingSuccessionState = SuccessionContext & Readonly<{
46
- phase: "freezing";
47
- stage: FreezingStage;
48
- }>;
49
- export type PreparedNewSuccessionState = SuccessionContext & Readonly<{
50
- phase: "prepared_new";
51
- /**
52
- * `publication_arming` begins the rollback-forbidden window before the
53
- * durable journal effect is executed. `registry_publishing` means the arm
54
- * was confirmed and the registry write may be in flight.
55
- */
56
- stage: "publication_arming" | "registry_publishing";
57
- }>;
58
- export type PublishedNewSuccessionState = SuccessionContext & Readonly<{
59
- phase: "published_new";
60
- }>;
61
- export type OfflinePoisonedSuccessionState = SuccessionContext & Readonly<{
62
- phase: "offline_poisoned";
63
- failedPhase: CodexSuccessionFailurePhase | "abort" | "barrier_busy";
64
- safeErrorCode: string;
65
- rollback: "old_allowed" | "forbidden";
66
- publicationBoundary: PublicationBoundary;
67
- }>;
68
- export type RecoveryRequiredSuccessionState = SuccessionContext & Readonly<{
69
- phase: "recovery_required";
70
- failedPhase: CodexSuccessionFailurePhase | "abort" | "barrier_busy";
71
- safeErrorCode: string;
72
- rollback: "old_allowed" | "forbidden";
73
- publicationBoundary: PublicationBoundary;
74
- }>;
75
- export type ResumingOldSuccessionState = SuccessionContext & Readonly<{
76
- phase: "resuming_old";
77
- failedPhase: CodexSuccessionFailurePhase | "abort" | "barrier_busy";
78
- safeErrorCode: string;
79
- }>;
80
- export type CodexRegistrationSuccessionState = ActiveOldSuccessionState | ActiveNewSuccessionState | FreezingSuccessionState | PreparedNewSuccessionState | PublishedNewSuccessionState | OfflinePoisonedSuccessionState | RecoveryRequiredSuccessionState | ResumingOldSuccessionState;
81
- type CorrelatedEvent = Readonly<{
82
- generation: string;
83
- }>;
84
- export type CodexRegistrationSuccessionEvent = Readonly<{
85
- type: "begin";
86
- registration: CodexRegistrationIdentity;
87
- }> | (CorrelatedEvent & Readonly<{
88
- type: "barrier_clean";
89
- }>) | (CorrelatedEvent & Readonly<{
90
- type: "barrier_busy";
91
- safeErrorCode: string;
92
- }>) | (CorrelatedEvent & Readonly<{
93
- type: "listener_prepared";
94
- }>) | (CorrelatedEvent & Readonly<{
95
- type: "store_prepared";
96
- }>) | (CorrelatedEvent & Readonly<{
97
- type: "publication_armed";
98
- }>) | (CorrelatedEvent & Readonly<{
99
- type: "publication_absence_confirmed";
100
- }>) | (CorrelatedEvent & Readonly<{
101
- type: "registry_published";
102
- }>) | (CorrelatedEvent & Readonly<{
103
- type: "activate";
104
- }>) | (CorrelatedEvent & Readonly<{
105
- type: "cleanup_confirmed";
106
- }>) | (CorrelatedEvent & Readonly<{
107
- type: "resume_confirmed";
108
- }>) | (CorrelatedEvent & Readonly<{
109
- type: "abort";
110
- safeErrorCode: string;
111
- }>) | (CorrelatedEvent & Readonly<{
112
- type: "phase_failed";
113
- phase: CodexSuccessionFailurePhase;
114
- safeErrorCode: string;
115
- }>) | (CorrelatedEvent & Readonly<{
116
- type: "restart_evidence";
117
- publication: "absent" | "armed" | "published" | "unknown";
118
- safeErrorCode: string;
119
- }>);
120
- export type CodexRegistrationSuccessionEffect = Readonly<{
121
- type: "freeze_old_ingress";
122
- registration: CodexRegistrationIdentity;
123
- }> | Readonly<{
124
- type: "freeze_old_dispatch";
125
- registration: CodexRegistrationIdentity;
126
- }> | Readonly<{
127
- type: "quiesce_and_join_old";
128
- registration: CodexRegistrationIdentity;
129
- }> | Readonly<{
130
- type: "verify_full_barrier";
131
- registration: CodexRegistrationIdentity;
132
- }> | Readonly<{
133
- type: "create_fresh_listener_generation";
134
- registration: CodexRegistrationIdentity;
135
- }> | Readonly<{
136
- type: "purge_old_conversations";
137
- registration: CodexRegistrationIdentity;
138
- }> | Readonly<{
139
- type: "purge_old_reply_capabilities";
140
- registration: CodexRegistrationIdentity;
141
- }> | Readonly<{
142
- type: "prepare_new_store";
143
- registration: CodexRegistrationIdentity;
144
- }> | Readonly<{
145
- /**
146
- * Persist the irreversible publication intent. The controller must
147
- * durably save the returned `publication_arming` machine state before
148
- * executing this effect.
149
- */
150
- type: "arm_publication_journal";
151
- registration: CodexRegistrationIdentity;
152
- }> | Readonly<{
153
- type: "publish_new_registry";
154
- registration: CodexRegistrationIdentity;
155
- }> | Readonly<{
156
- type: "activate_new_registration";
157
- registration: CodexRegistrationIdentity;
158
- }> | Readonly<{
159
- type: "retire_old_generation";
160
- registration: CodexRegistrationIdentity;
161
- }> | Readonly<{
162
- type: "close_old_listener";
163
- registration: CodexRegistrationIdentity;
164
- /**
165
- * Registry cleanup is a generation-owned compare-and-delete. It may
166
- * unlink only the retired record and must preserve the active record.
167
- */
168
- registryUnlink: Readonly<{
169
- onlyIfOwnedGeneration: string;
170
- protectedActiveGeneration: string;
171
- }>;
172
- }> | Readonly<{
173
- type: "cleanup_unpublished_generation";
174
- registration: CodexRegistrationIdentity;
175
- }> | Readonly<{
176
- type: "resume_old_ingress";
177
- registration: CodexRegistrationIdentity;
178
- }> | Readonly<{
179
- type: "resume_old_dispatch";
180
- registration: CodexRegistrationIdentity;
181
- }> | Readonly<{
182
- type: "poison_new_generation";
183
- registration: CodexRegistrationIdentity;
184
- }> | Readonly<{
185
- type: "take_registrations_offline";
186
- oldRegistration: CodexRegistrationIdentity;
187
- newRegistration: CodexRegistrationIdentity;
188
- }> | Readonly<{
189
- type: "cleanup_poisoned_generations";
190
- oldRegistration: CodexRegistrationIdentity;
191
- newRegistration: CodexRegistrationIdentity;
192
- }> | Readonly<{
193
- type: "manual_recovery_required";
194
- registration: CodexRegistrationIdentity;
195
- safeErrorCode: string;
196
- }>;
197
- export type CodexRegistrationSuccessionTransition = Readonly<{
198
- state: CodexRegistrationSuccessionState;
199
- effects: readonly CodexRegistrationSuccessionEffect[];
200
- }>;
201
- export declare function createCodexRegistrationSuccession(active: CodexRegistrationIdentity): ActiveOldSuccessionState;
202
- export declare function transitionCodexRegistrationSuccession(state: CodexRegistrationSuccessionState, event: CodexRegistrationSuccessionEvent): CodexRegistrationSuccessionTransition;
203
- /**
204
- * Runtime assertion for controller boundaries and exhaustive state-machine
205
- * tests. It intentionally validates identities without interpreting their
206
- * opaque generation strings.
207
- */
208
- export declare function assertCodexRegistrationSuccessionInvariant(state: CodexRegistrationSuccessionState): void;
209
- export {};