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.
- package/CHANGELOG.md +32 -0
- package/CONTRIBUTING.md +51 -47
- package/README.md +26 -9
- package/README.zh-CN.md +22 -9
- package/SECURITY.md +48 -35
- package/dist/src/gateway/acp-client.d.ts +12 -19
- package/dist/src/gateway/acp-client.js +90 -65
- package/dist/src/gateway/acp-client.js.map +1 -1
- package/dist/src/gateway/acp-provider.d.ts +11 -10
- package/dist/src/gateway/acp-provider.js +165 -53
- package/dist/src/gateway/acp-provider.js.map +1 -1
- package/dist/src/gateway/claude-helper-client.d.ts +2 -43
- package/dist/src/gateway/claude-helper-client.js +1 -211
- package/dist/src/gateway/claude-helper-client.js.map +1 -1
- package/dist/src/gateway/claude-helper-protocol.d.ts +16 -74
- package/dist/src/gateway/claude-helper-protocol.js +99 -378
- package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
- package/dist/src/gateway/claude-helper-supervisor.d.ts +56 -44
- package/dist/src/gateway/claude-helper-supervisor.js +265 -456
- package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
- package/dist/src/gateway/claude-helper.js +184 -210
- package/dist/src/gateway/claude-helper.js.map +1 -1
- package/dist/src/gateway/claude-peer.d.ts +20 -87
- package/dist/src/gateway/claude-peer.js +310 -1009
- package/dist/src/gateway/claude-peer.js.map +1 -1
- package/dist/src/gateway/claude-runtime.d.ts +13 -15
- package/dist/src/gateway/claude-runtime.js +14 -168
- package/dist/src/gateway/claude-runtime.js.map +1 -1
- package/dist/src/gateway/cli-copy.en.d.ts +2 -2
- package/dist/src/gateway/cli-copy.en.js +4 -2
- package/dist/src/gateway/cli-copy.en.js.map +1 -1
- package/dist/src/gateway/cli-copy.zh-CN.d.ts +2 -2
- package/dist/src/gateway/cli-copy.zh-CN.js +4 -2
- package/dist/src/gateway/cli-copy.zh-CN.js.map +1 -1
- package/dist/src/gateway/cli.d.ts +7 -2
- package/dist/src/gateway/cli.js +277 -575
- package/dist/src/gateway/cli.js.map +1 -1
- package/dist/src/gateway/codex-app-server.d.ts +5 -227
- package/dist/src/gateway/codex-app-server.js +18 -1463
- package/dist/src/gateway/codex-app-server.js.map +1 -1
- package/dist/src/gateway/codex-doctor.d.ts +36 -0
- package/dist/src/gateway/codex-doctor.js +127 -0
- package/dist/src/gateway/codex-doctor.js.map +1 -0
- package/dist/src/gateway/codex-local-transport.d.ts +6 -6
- package/dist/src/gateway/codex-local-transport.js +13 -10
- package/dist/src/gateway/codex-local-transport.js.map +1 -1
- package/dist/src/gateway/codex-stateless-transport.d.ts +114 -0
- package/dist/src/gateway/codex-stateless-transport.js +1108 -0
- package/dist/src/gateway/codex-stateless-transport.js.map +1 -0
- package/dist/src/gateway/config.d.ts +2 -9
- package/dist/src/gateway/config.js +62 -100
- package/dist/src/gateway/config.js.map +1 -1
- package/dist/src/gateway/control.d.ts +36 -90
- package/dist/src/gateway/control.js +465 -1123
- package/dist/src/gateway/control.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.d.ts +1 -1
- package/dist/src/gateway/dashboard-copy.en.d.ts +8 -26
- package/dist/src/gateway/dashboard-copy.en.js +19 -37
- package/dist/src/gateway/dashboard-copy.en.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.js +8 -26
- package/dist/src/gateway/dashboard-copy.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +8 -26
- package/dist/src/gateway/dashboard-copy.zh-CN.js +19 -37
- package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -1
- package/dist/src/gateway/dashboard-model.d.ts +8 -22
- package/dist/src/gateway/dashboard-model.js +44 -130
- package/dist/src/gateway/dashboard-model.js.map +1 -1
- package/dist/src/gateway/dashboard.d.ts +0 -6
- package/dist/src/gateway/dashboard.js +3 -7
- package/dist/src/gateway/dashboard.js.map +1 -1
- package/dist/src/gateway/live-dashboard-app/app.js +20 -34
- package/dist/src/gateway/live-dashboard-command.js +2 -2
- package/dist/src/gateway/live-dashboard-command.js.map +1 -1
- package/dist/src/gateway/live-dashboard-http.d.ts +1 -1
- package/dist/src/gateway/live-dashboard-http.js +2 -2
- package/dist/src/gateway/live-dashboard-http.js.map +1 -1
- package/dist/src/gateway/progress-watch-machine.d.ts +1 -37
- package/dist/src/gateway/progress-watch-machine.js +4 -15
- package/dist/src/gateway/progress-watch-machine.js.map +1 -1
- package/dist/src/gateway/providers.d.ts +58 -191
- package/dist/src/gateway/providers.js +637 -2434
- package/dist/src/gateway/providers.js.map +1 -1
- package/dist/src/gateway/server.d.ts +16 -25
- package/dist/src/gateway/server.js +165 -240
- package/dist/src/gateway/server.js.map +1 -1
- package/dist/src/gateway/service.d.ts +149 -427
- package/dist/src/gateway/service.js +1639 -5662
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/state-v2-to-v3.d.ts +23 -0
- package/dist/src/gateway/state-v2-to-v3.js +994 -0
- package/dist/src/gateway/state-v2-to-v3.js.map +1 -0
- package/dist/src/gateway/store.d.ts +54 -309
- package/dist/src/gateway/store.js +1560 -3510
- package/dist/src/gateway/store.js.map +1 -1
- package/dist/src/gateway/types.d.ts +181 -225
- package/dist/src/gateway/types.js +115 -251
- package/dist/src/gateway/types.js.map +1 -1
- package/docs/CONFIGURATION.md +22 -9
- package/docs/CONFIGURATION.zh-CN.md +21 -9
- package/docs/DASHBOARD.md +10 -10
- package/docs/DASHBOARD.zh-CN.md +3 -3
- package/docs/DELIVERY.md +4 -4
- package/docs/DELIVERY.zh-CN.md +4 -4
- package/docs/GATEWAY-ARCHITECTURE.md +158 -187
- package/package.json +1 -1
- package/skills/embassy-peer/SKILL.md +28 -22
- package/dist/src/gateway/codex-registration-generation.d.ts +0 -5
- package/dist/src/gateway/codex-registration-generation.js +0 -19
- package/dist/src/gateway/codex-registration-generation.js.map +0 -1
- package/dist/src/gateway/codex-registration-succession.d.ts +0 -209
- package/dist/src/gateway/codex-registration-succession.js +0 -588
- package/dist/src/gateway/codex-registration-succession.js.map +0 -1
- package/dist/src/gateway/compatibility.d.ts +0 -22
- package/dist/src/gateway/compatibility.js +0 -23
- package/dist/src/gateway/compatibility.js.map +0 -1
- package/dist/src/gateway/delivery-machine.d.ts +0 -235
- package/dist/src/gateway/delivery-machine.js +0 -540
- 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
|
|
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
|
|
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.
|
|
100
|
-
|
|
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
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
223
|
-
|
|
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
|
|
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 {};
|