@essentialai/cogent-bridge 3.21.9 → 3.22.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 +57 -0
- package/dist/backend/http-backend.d.ts +9 -1
- package/dist/backend/http-backend.d.ts.map +1 -1
- package/dist/backend/http-backend.js +59 -4
- package/dist/backend/http-backend.js.map +1 -1
- package/dist/backend/relay-version-cache.d.ts +18 -0
- package/dist/backend/relay-version-cache.d.ts.map +1 -1
- package/dist/backend/relay-version-cache.js +46 -2
- package/dist/backend/relay-version-cache.js.map +1 -1
- package/dist/backend/storage-backend.d.ts +7 -1
- package/dist/backend/storage-backend.d.ts.map +1 -1
- package/dist/cloud/credential-store.d.ts +14 -0
- package/dist/cloud/credential-store.d.ts.map +1 -1
- package/dist/cloud/credential-store.js.map +1 -1
- package/dist/services/auto-relay.d.ts +30 -12
- package/dist/services/auto-relay.d.ts.map +1 -1
- package/dist/services/auto-relay.js +85 -33
- package/dist/services/auto-relay.js.map +1 -1
- package/dist/startup.d.ts.map +1 -1
- package/dist/startup.js +3 -1
- package/dist/startup.js.map +1 -1
- package/dist/tools/register-peer.d.ts +15 -0
- package/dist/tools/register-peer.d.ts.map +1 -1
- package/dist/tools/register-peer.js +58 -9
- package/dist/tools/register-peer.js.map +1 -1
- package/dist/tools/send-message.d.ts.map +1 -1
- package/dist/tools/send-message.js +19 -1
- package/dist/tools/send-message.js.map +1 -1
- package/package.json +10 -3
- package/server.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,60 @@
|
|
|
1
|
+
## 3.22.0 — 2026-09-03 — audited-by-codex_2026-09-03
|
|
2
|
+
|
|
3
|
+
Closes an independent code + QA audit (12 findings) plus 4 from our own gate audit. **Every fix is
|
|
4
|
+
mutation-proven**: reverted in the shipped source, its tests observed RED, restored — 14/14.
|
|
5
|
+
|
|
6
|
+
### Security
|
|
7
|
+
|
|
8
|
+
- **Peer identity is now enforced (AUD-003).** A bearer token proved only "I know the channel
|
|
9
|
+
secret" and carried no identity, so any channel member could register over any peer, send as
|
|
10
|
+
them, connect as them, and FORGE their delivery acknowledgments. Ownership is per-PEER (a token
|
|
11
|
+
owns the peers it created; a `peerSecret` reclaims one after a re-join) — deliberately NOT
|
|
12
|
+
per-token, because the Slack adapter registers one peer per human on a single token. Peers
|
|
13
|
+
predating this are adopted on first touch, so live channels keep working.
|
|
14
|
+
- **Path traversal in the file session store (AUD-008).** `getSession("../outside")` read other
|
|
15
|
+
files and `deleteSession("../victim")` deleted them. Two-layer confinement.
|
|
16
|
+
- **Relay state permissions (AUD-007).** Token hashes, secret hashes and full history were written
|
|
17
|
+
0775/0664. Now 0700/0600.
|
|
18
|
+
- **WebSocket auth is header-only (AUD-010).** The `?token=` fallback for pre-3.1.0 clients is gone;
|
|
19
|
+
URL credentials leak into proxy logs and these tokens have no expiry.
|
|
20
|
+
- **Allocation limits (AUD-009).** 4 MiB body cap, field maxima (`FIELD_LIMITS`), and a throttle on
|
|
21
|
+
unauthenticated channel creation, which ran bcrypt + a durable write with nothing bounding it.
|
|
22
|
+
|
|
23
|
+
### Delivery integrity
|
|
24
|
+
|
|
25
|
+
- **Delivery acks are correlated by MESSAGE ID (AUD-002).** Waiters were keyed by peer, so a second
|
|
26
|
+
concurrent send RESOLVED the first — reporting "delivered" with no acknowledgment from anyone.
|
|
27
|
+
- **Shutdown and cancellation now REJECT (AUD-012)** instead of resolving, so "we stopped mid-flight"
|
|
28
|
+
is no longer indistinguishable from "delivered".
|
|
29
|
+
- **The relay stops fabricating `success: true`.** It stamped that on every record for ~7 months
|
|
30
|
+
while its `.strict()` schema made it impossible for a client to report the truth. Four consumers
|
|
31
|
+
branched on that constant — including the production check-on-stop hook, which read the bridge's
|
|
32
|
+
own "could not wake" notice as an ANSWER and went silent on exactly the busy-miss it exists to
|
|
33
|
+
catch. `success`/`error`/`durationMs` are now accepted and persisted.
|
|
34
|
+
- **`pending:true` is persisted (AUD-005)** instead of being silently dropped by a non-strict schema.
|
|
35
|
+
- **Deregistration reports real failures (AUD-006).** 401/500/timeout/DNS were all reported as the
|
|
36
|
+
benign "peer was not registered" while the peer and mailbox stayed live.
|
|
37
|
+
|
|
38
|
+
### Compatibility
|
|
39
|
+
|
|
40
|
+
- The relay advertises `capabilities` on `GET /api/health`
|
|
41
|
+
(`message-delivery-fields`, `peer-ownership`) and the client gates every new wire field on them,
|
|
42
|
+
failing SAFE when unknown. **There is no deploy-ordering dependency** — an un-upgraded relay
|
|
43
|
+
simply never receives the new fields. This replaces a rule that was forgotten once and took every
|
|
44
|
+
paying Team agent dark for two days (2026-08-07).
|
|
45
|
+
|
|
46
|
+
### Assurance (AUD-011 — the reason the rest survived)
|
|
47
|
+
|
|
48
|
+
- The E2E harness was structurally dead (it instantiated an interface); `npm test` was RED and the
|
|
49
|
+
publish gate excluded the failures. Repaired, and it now exercises the real delivery-ack path.
|
|
50
|
+
- Tests are type-checked for the first time (`npm run typecheck`, new `tsconfig.test.json`) — 70
|
|
51
|
+
latent errors fixed.
|
|
52
|
+
- `npm run verify` = typecheck → all 8 packages → artifact staleness → **black-box of the real
|
|
53
|
+
`server/dist`**, which no test had ever executed. CI runs it on every change (both prior jobs were
|
|
54
|
+
path-gated to `server/**`, so a change to `src/` ran nothing).
|
|
55
|
+
- `npm test` had been exiting 1 on 7 unhandled rejections while reporting "892 passed" — a real
|
|
56
|
+
product bug (an abandoned response waiter) now fixed.
|
|
57
|
+
|
|
1
58
|
# Changelog
|
|
2
59
|
|
|
3
60
|
## 3.21.9 — 2026-09-02
|
|
@@ -26,7 +26,15 @@ export declare class HttpBackend implements StorageBackend {
|
|
|
26
26
|
* The sessionId parameter from StorageBackend is the local CC sessionId;
|
|
27
27
|
* in cloud mode we ignore it and use this.sessionId (the cloud session).
|
|
28
28
|
*/
|
|
29
|
-
registerPeer(peerId: string, _sessionId: string, cwd: string, label: string, clientVersion?: string, mode?: "observer" | "agent", _channelSessionId?: string, capabilities?: string[], workspaceId?: string, threadId?: string
|
|
29
|
+
registerPeer(peerId: string, _sessionId: string, cwd: string, label: string, clientVersion?: string, mode?: "observer" | "agent", _channelSessionId?: string, capabilities?: string[], workspaceId?: string, threadId?: string,
|
|
30
|
+
/**
|
|
31
|
+
* AUD-003 ownership proof, replayed from the local credential file when this agent's token has
|
|
32
|
+
* changed since the peer was created (a re-join). Gated on the relay advertising
|
|
33
|
+
* `peer-ownership`: the register schema is .strict(), so sending it to a relay that does not
|
|
34
|
+
* know the field would 400 EVERY registration — the exact shape of AUD-001 and of the
|
|
35
|
+
* 2026-08-07 outage.
|
|
36
|
+
*/
|
|
37
|
+
peerSecret?: string): Promise<PeerInfo>;
|
|
30
38
|
/**
|
|
31
39
|
* Deregister a peer from the cloud session.
|
|
32
40
|
* DELETE /api/sessions/:sessionId/peers/:peerId
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-backend.d.ts","sourceRoot":"","sources":["../../src/backend/http-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"http-backend.d.ts","sourceRoot":"","sources":["../../src/backend/http-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7E,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAQ1E,OAAO,EAAE,KAAK,iBAAiB,EAAqB,MAAM,6BAA6B,CAAC;AACxF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAkB1D;;;;;;;;;;;;GAYG;AACH,qBAAa,WAAY,YAAW,cAAc;IAE9C,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM;IAGpC;;;;;;OAMG;IACG,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,EACtB,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,EAG3B,iBAAiB,CAAC,EAAE,MAAM,EAI1B,YAAY,CAAC,EAAE,MAAM,EAAE,EAIvB,WAAW,CAAC,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM;IACjB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,QAAQ,CAAC;IAiDpB;;;;;;;;OAQG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAwB/D;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAK5D;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAMtC;;;OAGG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;;;;;;OAOG;IACG,aAAa,CACjB,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,WAAW,CAAC,GAC9C,OAAO,CAAC,aAAa,CAAC;IAiEzB;;;;;OAKG;IACG,UAAU,CACd,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,EACd,kBAAkB,CAAC,EAAE,OAAO,EAC5B,YAAY,CAAC,EAAE,OAAO,EACtB,mBAAmB,CAAC,EAAE,OAAO,GAC5B,OAAO,CAAC,aAAa,EAAE,CAAC;IAmC3B;;;;;;OAMG;IACG,qBAAqB,CACzB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,IAAI,CAAC;IAchB;;;;OAIG;IACG,eAAe,CACnB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC;IAInB;;;;;;;OAOG;IACG,UAAU,CACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,aAAa,CAAC;IAQzB;;;;;;OAMG;IACG,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;IA4C/C;;;;;;;;;OASG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAGhD"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { relaySupports } from "./relay-version-cache.js";
|
|
2
|
+
import { BridgeError, BridgeErrorCode } from "../errors.js";
|
|
1
3
|
/**
|
|
2
4
|
* Relay response header (Cogent Mail F3) set on DELETE /peers when a Team mailbox was reaped.
|
|
3
5
|
* MUST match the relay's `MAILBOX_DEPROVISIONED_HEADER` (server/src/routes/peers.ts) — the bridge
|
|
@@ -58,7 +60,15 @@ export class HttpBackend {
|
|
|
58
60
|
// Slice 5 / Story 8.6: durable identity that DOES go on the wire (unlike the
|
|
59
61
|
// local-only rails above) — the relay's .strict() schema was extended in
|
|
60
62
|
// lockstep (relay-first deploy) to accept these optional fields.
|
|
61
|
-
workspaceId, threadId
|
|
63
|
+
workspaceId, threadId,
|
|
64
|
+
/**
|
|
65
|
+
* AUD-003 ownership proof, replayed from the local credential file when this agent's token has
|
|
66
|
+
* changed since the peer was created (a re-join). Gated on the relay advertising
|
|
67
|
+
* `peer-ownership`: the register schema is .strict(), so sending it to a relay that does not
|
|
68
|
+
* know the field would 400 EVERY registration — the exact shape of AUD-001 and of the
|
|
69
|
+
* 2026-08-07 outage.
|
|
70
|
+
*/
|
|
71
|
+
peerSecret) {
|
|
62
72
|
const path = PATHS.peers.replace(":sessionId", this.sessionId);
|
|
63
73
|
// Build body conditionally: omit clientVersion entirely for older clients
|
|
64
74
|
// / undefined inputs so the wire payload stays clean (no JSON null) and
|
|
@@ -101,6 +111,9 @@ export class HttpBackend {
|
|
|
101
111
|
body.role = roleCap.slice("role:".length);
|
|
102
112
|
}
|
|
103
113
|
}
|
|
114
|
+
if (peerSecret !== undefined && (await relaySupports(this.http, "peer-ownership"))) {
|
|
115
|
+
body.peerSecret = peerSecret;
|
|
116
|
+
}
|
|
104
117
|
return this.http.post(path, body);
|
|
105
118
|
}
|
|
106
119
|
/**
|
|
@@ -121,9 +134,19 @@ export class HttpBackend {
|
|
|
121
134
|
const mailboxDeprovisioned = headers.get(MAILBOX_DEPROVISIONED_HEADER) === "true";
|
|
122
135
|
return { removed: true, mailboxDeprovisioned };
|
|
123
136
|
}
|
|
124
|
-
catch {
|
|
125
|
-
//
|
|
126
|
-
|
|
137
|
+
catch (err) {
|
|
138
|
+
// 🔴 AUD-006. This used to be a bare `catch {}` returning removed:false for ANY failure, so
|
|
139
|
+
// 401, 403, 500, timeout, DNS and transport errors were all reported to the operator as the
|
|
140
|
+
// benign "peer was not registered" — while the peer and its mailbox stayed live and nothing
|
|
141
|
+
// suggested action was needed.
|
|
142
|
+
//
|
|
143
|
+
// A not-found answer is a FACT about the server's state. A network failure is the ABSENCE of
|
|
144
|
+
// any answer. They must not share a return value: only a verified PEER_NOT_FOUND is
|
|
145
|
+
// "already gone"; everything else is an unknown outcome and must reach the caller.
|
|
146
|
+
if (err instanceof BridgeError && err.code === BridgeErrorCode.PEER_NOT_FOUND) {
|
|
147
|
+
return { removed: false, mailboxDeprovisioned: false };
|
|
148
|
+
}
|
|
149
|
+
throw err;
|
|
127
150
|
}
|
|
128
151
|
}
|
|
129
152
|
/**
|
|
@@ -174,6 +197,38 @@ export class HttpBackend {
|
|
|
174
197
|
if (record.isRelayEcho === true) {
|
|
175
198
|
body.isRelayEcho = true;
|
|
176
199
|
}
|
|
200
|
+
// 🔴 REPORT A FAILED WAKE — BUT ONLY TO A RELAY THAT SAID IT ACCEPTS THE REPORT.
|
|
201
|
+
//
|
|
202
|
+
// The problem: until 2026-09-02 this method dropped `success`/`error`/`durationMs`, so the
|
|
203
|
+
// bridge's own `success: false` (auto-relay.ts:1082/1165/1245/1248) never reached anyone and
|
|
204
|
+
// the relay stamped `true` on every record. Four consumers then branched on that constant —
|
|
205
|
+
// rail C in production among them, which read the bridge's "could not wake" notice as an
|
|
206
|
+
// ANSWER and went silent on exactly the busy-miss it exists to catch.
|
|
207
|
+
//
|
|
208
|
+
// The trap in the obvious fix: the relay's POST schema is `.strict()`, so an unknown key is a
|
|
209
|
+
// hard 400 on EVERY send, not a degraded record. send-message.ts:214-222 passes a computed
|
|
210
|
+
// NUMERIC durationMs on every ordinary cloud send, so forwarding unconditionally would have
|
|
211
|
+
// 400'd the entire fabric against the then-deployed 3.13.3 relays (AUD-001).
|
|
212
|
+
//
|
|
213
|
+
// A deploy-ORDER rule ("relay first, both tiers") is the standing mitigation and it was
|
|
214
|
+
// forgotten once already — 2026-08-07, two days of dark paying agents. So the client ASKS
|
|
215
|
+
// instead: the relay advertises `message-delivery-fields` on /api/health, and unknown fails
|
|
216
|
+
// SAFE (omit). Cost is nothing — capabilities ride the same 60s-TTL cached health probe the
|
|
217
|
+
// version already uses.
|
|
218
|
+
//
|
|
219
|
+
// Within that gate, the same omit-when-empty convention as isRelayEcho above: a field is sent
|
|
220
|
+
// only when it carries information.
|
|
221
|
+
if (await relaySupports(this.http, "message-delivery-fields")) {
|
|
222
|
+
if (record.success === false) {
|
|
223
|
+
body.success = false;
|
|
224
|
+
}
|
|
225
|
+
if (record.error != null) {
|
|
226
|
+
body.error = record.error;
|
|
227
|
+
}
|
|
228
|
+
if (record.durationMs != null) {
|
|
229
|
+
body.durationMs = record.durationMs;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
177
232
|
// Cogent Mail M2.5: forward file references only when present (same
|
|
178
233
|
// omit-when-empty convention as isRelayEcho) so no-attachment records stay
|
|
179
234
|
// byte-identical on the wire and older relays simply ignore an absent field.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-backend.js","sourceRoot":"","sources":["../../src/backend/http-backend.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http-backend.js","sourceRoot":"","sources":["../../src/backend/http-backend.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,24 @@ import type { HttpClient } from "../cloud/http-client.js";
|
|
|
7
7
|
* @param nowFn Override for `Date.now()` (test seam). Defaults to `Date.now`.
|
|
8
8
|
*/
|
|
9
9
|
export declare function getRelayVersion(http: HttpClient, nowFn?: () => number): Promise<string | null>;
|
|
10
|
+
/**
|
|
11
|
+
* Wire contracts the relay advertises, or null when the relay could not be reached.
|
|
12
|
+
*
|
|
13
|
+
* 🔴 null and [] MEAN DIFFERENT THINGS and callers must treat both as "no support":
|
|
14
|
+
* - `[]` the relay answered and named nothing (an older build).
|
|
15
|
+
* - `null` we do not know (unreachable / malformed).
|
|
16
|
+
* Use relaySupports() rather than inspecting this directly.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getRelayCapabilities(http: HttpClient, nowFn?: () => number): Promise<string[] | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Does the relay accept this wire contract?
|
|
21
|
+
*
|
|
22
|
+
* 🔴 FAILS SAFE. Unknown is NOT support. The message POST schema is `.strict()`, so guessing wrong
|
|
23
|
+
* in the optimistic direction is a hard 400 on every send — the 2026-08-07 outage and the
|
|
24
|
+
* 2026-09-02 near-miss were both exactly that. Guessing wrong in this direction merely omits an
|
|
25
|
+
* optional field.
|
|
26
|
+
*/
|
|
27
|
+
export declare function relaySupports(http: HttpClient, capability: string, nowFn?: () => number): Promise<boolean>;
|
|
10
28
|
/**
|
|
11
29
|
* Test-only helper to clear the module-scoped cache. Call from beforeEach
|
|
12
30
|
* in test suites that exercise the cache.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-version-cache.d.ts","sourceRoot":"","sources":["../../src/backend/relay-version-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"relay-version-cache.d.ts","sourceRoot":"","sources":["../../src/backend/relay-version-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAqC1D;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,UAAU,EAChB,KAAK,GAAE,MAAM,MAAiB,GAC7B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQxB;AA2CD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,UAAU,EAChB,KAAK,GAAE,MAAM,MAAiB,GAC7B,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAM1B;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,MAAM,MAAiB,GAC7B,OAAO,CAAC,OAAO,CAAC,CAElB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
|
@@ -35,6 +35,16 @@ export async function getRelayVersion(http, nowFn = Date.now) {
|
|
|
35
35
|
if (cached !== null && now - cached.fetchedAt < TTL_MS) {
|
|
36
36
|
return cached.version;
|
|
37
37
|
}
|
|
38
|
+
return (await _refresh(http, now))?.version ?? null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Fetch and cache /api/health. Returns null (and caches nothing) on transport failure or a
|
|
42
|
+
* payload with no usable `version`, so the next call retries.
|
|
43
|
+
*
|
|
44
|
+
* Shared by getRelayVersion and getRelayCapabilities so gating a wire field costs no extra
|
|
45
|
+
* request — both read the same 60s-TTL entry.
|
|
46
|
+
*/
|
|
47
|
+
async function _refresh(http, now) {
|
|
38
48
|
try {
|
|
39
49
|
const resp = await http.get("/api/health");
|
|
40
50
|
const version = resp?.version;
|
|
@@ -43,8 +53,16 @@ export async function getRelayVersion(http, nowFn = Date.now) {
|
|
|
43
53
|
logger.debug(`relay-version-cache: /api/health response missing string 'version' field`);
|
|
44
54
|
return null;
|
|
45
55
|
}
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
// A relay older than 2026-09-03 advertises nothing. That is a VALID answer meaning "supports
|
|
57
|
+
// no new wire contracts", not a failure — so it is cached like any other. Anything that is
|
|
58
|
+
// not an array of strings is ignored rather than trusted: a malformed field must never be
|
|
59
|
+
// read as support, because the cost of a false positive is a 400 on every send.
|
|
60
|
+
const raw = resp?.capabilities;
|
|
61
|
+
const capabilities = Array.isArray(raw)
|
|
62
|
+
? raw.filter((c) => typeof c === "string")
|
|
63
|
+
: [];
|
|
64
|
+
cached = { version, capabilities, fetchedAt: now };
|
|
65
|
+
return cached;
|
|
48
66
|
}
|
|
49
67
|
catch (err) {
|
|
50
68
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -53,6 +71,32 @@ export async function getRelayVersion(http, nowFn = Date.now) {
|
|
|
53
71
|
return null;
|
|
54
72
|
}
|
|
55
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Wire contracts the relay advertises, or null when the relay could not be reached.
|
|
76
|
+
*
|
|
77
|
+
* 🔴 null and [] MEAN DIFFERENT THINGS and callers must treat both as "no support":
|
|
78
|
+
* - `[]` the relay answered and named nothing (an older build).
|
|
79
|
+
* - `null` we do not know (unreachable / malformed).
|
|
80
|
+
* Use relaySupports() rather than inspecting this directly.
|
|
81
|
+
*/
|
|
82
|
+
export async function getRelayCapabilities(http, nowFn = Date.now) {
|
|
83
|
+
const now = nowFn();
|
|
84
|
+
if (cached !== null && now - cached.fetchedAt < TTL_MS) {
|
|
85
|
+
return cached.capabilities;
|
|
86
|
+
}
|
|
87
|
+
return (await _refresh(http, now))?.capabilities ?? null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Does the relay accept this wire contract?
|
|
91
|
+
*
|
|
92
|
+
* 🔴 FAILS SAFE. Unknown is NOT support. The message POST schema is `.strict()`, so guessing wrong
|
|
93
|
+
* in the optimistic direction is a hard 400 on every send — the 2026-08-07 outage and the
|
|
94
|
+
* 2026-09-02 near-miss were both exactly that. Guessing wrong in this direction merely omits an
|
|
95
|
+
* optional field.
|
|
96
|
+
*/
|
|
97
|
+
export async function relaySupports(http, capability, nowFn = Date.now) {
|
|
98
|
+
return (await getRelayCapabilities(http, nowFn))?.includes(capability) ?? false;
|
|
99
|
+
}
|
|
56
100
|
/**
|
|
57
101
|
* Test-only helper to clear the module-scoped cache. Call from beforeEach
|
|
58
102
|
* in test suites that exercise the cache.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-version-cache.js","sourceRoot":"","sources":["../../src/backend/relay-version-cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"relay-version-cache.js","sourceRoot":"","sources":["../../src/backend/relay-version-cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,GAAG,MAAM,CAAC;AAStB,IAAI,MAAM,GAAsB,IAAI,CAAC;AAErC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAgB,EAChB,QAAsB,IAAI,CAAC,GAAG;IAE9B,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;IAEpB,IAAI,MAAM,KAAK,IAAI,IAAI,GAAG,GAAG,MAAM,CAAC,SAAS,GAAG,MAAM,EAAE,CAAC;QACvD,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC;AACtD,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,QAAQ,CACrB,IAAgB,EAChB,GAAW;IAEX,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CACzB,aAAa,CACd,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,CAAC;QAC9B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxD,mEAAmE;YACnE,MAAM,CAAC,KAAK,CACV,0EAA0E,CAC3E,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,6FAA6F;QAC7F,2FAA2F;QAC3F,0FAA0F;QAC1F,gFAAgF;QAChF,MAAM,GAAG,GAAG,IAAI,EAAE,YAAY,CAAC;QAC/B,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YACrC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YACvD,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;QACnD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,CAAC,KAAK,CAAC,kDAAkD,GAAG,EAAE,CAAC,CAAC;QACtE,8CAA8C;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAgB,EAChB,QAAsB,IAAI,CAAC,GAAG;IAE9B,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;IACpB,IAAI,MAAM,KAAK,IAAI,IAAI,GAAG,GAAG,MAAM,CAAC,SAAS,GAAG,MAAM,EAAE,CAAC;QACvD,OAAO,MAAM,CAAC,YAAY,CAAC;IAC7B,CAAC;IACD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,YAAY,IAAI,IAAI,CAAC;AAC3D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAgB,EAChB,UAAkB,EAClB,QAAsB,IAAI,CAAC,GAAG;IAE9B,OAAO,CAAC,MAAM,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC;AAClF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,GAAG,IAAI,CAAC;AAChB,CAAC"}
|
|
@@ -30,7 +30,13 @@ export interface StorageBackend {
|
|
|
30
30
|
/** Durable workspace id — on the wire in cloud mode (Slice 5 / Story 8.6). */
|
|
31
31
|
workspaceId?: string,
|
|
32
32
|
/** Durable thread/conversation id — on the wire in cloud mode (Slice 5 / Story 8.6). */
|
|
33
|
-
threadId?: string
|
|
33
|
+
threadId?: string,
|
|
34
|
+
/**
|
|
35
|
+
* AUD-003 ownership proof, replayed from local credentials when this agent's token changed
|
|
36
|
+
* since the peer was created (a re-join). Cloud-only, and only sent when the relay advertises
|
|
37
|
+
* `peer-ownership` — the register schema is .strict().
|
|
38
|
+
*/
|
|
39
|
+
peerSecret?: string): Promise<PeerInfo>;
|
|
34
40
|
deregisterPeer(peerId: string): Promise<DeregisterResult>;
|
|
35
41
|
getPeer(peerId: string): Promise<PeerInfo | undefined>;
|
|
36
42
|
listPeers(): Promise<PeerInfo[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-backend.d.ts","sourceRoot":"","sources":["../../src/backend/storage-backend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAE7B,YAAY,CACV,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM;IACb,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM;IACtB,4FAA4F;IAC5F,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO;IAC3B,0FAA0F;IAC1F,gBAAgB,CAAC,EAAE,MAAM;IACzB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,EAAE;IACvB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM;IACpB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"storage-backend.d.ts","sourceRoot":"","sources":["../../src/backend/storage-backend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAE7B,YAAY,CACV,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM;IACb,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM;IACtB,4FAA4F;IAC5F,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO;IAC3B,0FAA0F;IAC1F,gBAAgB,CAAC,EAAE,MAAM;IACzB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,EAAE;IACvB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM;IACpB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,MAAM;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,QAAQ,CAAC,CAAC;IAErB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAE1D,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAEvD,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAEjC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAG9C,aAAa,CACX,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,WAAW,CAAC,GAC9C,OAAO,CAAC,aAAa,CAAC,CAAC;IAE1B;;;;;;;;;;;;;OAaG;IACH,UAAU,CACR,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,EACd,kBAAkB,CAAC,EAAE,OAAO,EAC5B,YAAY,CAAC,EAAE,OAAO,EACtB,mBAAmB,CAAC,EAAE,OAAO,GAC5B,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAG5B,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAElE,UAAU,CACR,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC,CAAC;IAG1B;;;;;;;;;OASG;IACH,qBAAqB,CAAC,CACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,IAAI,CAAC,CAAC;IAGjB,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAE1C;;;;;OAKG;IACH,eAAe,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC5C"}
|
|
@@ -18,6 +18,20 @@ export interface PersistedCredentials {
|
|
|
18
18
|
* a register) omit it, and the hook falls back to the state file.
|
|
19
19
|
*/
|
|
20
20
|
peerId?: string;
|
|
21
|
+
/**
|
|
22
|
+
* AUD-003 peer-ownership credential, issued once by the relay when this peer was first
|
|
23
|
+
* registered.
|
|
24
|
+
*
|
|
25
|
+
* WHY IT MUST BE PERSISTED: a peer is owned by the token that created it, and re-joining a
|
|
26
|
+
* channel issues a NEW token. Without this secret an agent that re-joins can never re-register
|
|
27
|
+
* its own peerId again — it would be locked out of its own identity by the very check that
|
|
28
|
+
* protects it. Stored here (0600, same file as the bearer token, same threat model) and replayed
|
|
29
|
+
* on register.
|
|
30
|
+
*
|
|
31
|
+
* Optional: absent for peers created before ownership existed, and absent on the common path
|
|
32
|
+
* where the token has not changed.
|
|
33
|
+
*/
|
|
34
|
+
peerSecret?: string;
|
|
21
35
|
savedAt: string;
|
|
22
36
|
}
|
|
23
37
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-store.d.ts","sourceRoot":"","sources":["../../src/cloud/credential-store.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAsBF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAKrE;AAaD,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAErD;AAkBD,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED,wBAAgB,wBAAwB,IAAI,OAAO,CAElD;AAED;;GAEG;AACH,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D;AAMD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAQtC;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,oBAAoB,EAC3B,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,OAAO,CAAC,CAOrE"}
|
|
1
|
+
{"version":3,"file":"credential-store.d.ts","sourceRoot":"","sources":["../../src/cloud/credential-store.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAsBF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAKrE;AAaD,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAErD;AAkBD,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED,wBAAgB,wBAAwB,IAAI,OAAO,CAElD;AAED;;GAEG;AACH,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D;AAMD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAQtC;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,oBAAoB,EAC3B,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,OAAO,CAAC,CAOrE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../src/cloud/credential-store.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../src/cloud/credential-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -83,7 +83,24 @@ export declare class AutoRelayService {
|
|
|
83
83
|
private awarenessOnly;
|
|
84
84
|
private expectingResponseFrom;
|
|
85
85
|
private responseWaiters;
|
|
86
|
+
/**
|
|
87
|
+
* Pending delivery-ack waiters, keyed by MESSAGE ID.
|
|
88
|
+
*
|
|
89
|
+
* 🔴 AUD-002. This used to be keyed by PEER ID, so a peer could have only one outstanding
|
|
90
|
+
* waiter and a second concurrent send displaced the first — resolving it, so the first send
|
|
91
|
+
* reported "delivered" with no acknowledgment from anyone. Delivery acknowledgment is the one
|
|
92
|
+
* claim this system must never fabricate.
|
|
93
|
+
*/
|
|
86
94
|
private deliveryAckWaiters;
|
|
95
|
+
/**
|
|
96
|
+
* Acks that arrived before their waiter existed, keyed by message id.
|
|
97
|
+
*
|
|
98
|
+
* The recipient acknowledges over WS as soon as it receives the message, which can beat our own
|
|
99
|
+
* POST response. Waiters used to be registered BEFORE the send to dodge that race, which is what
|
|
100
|
+
* forced peer-keying. Buffering the early ack instead lets registration happen after the message
|
|
101
|
+
* id is known, so correlation stays exact. Entries are consumed once and expire.
|
|
102
|
+
*/
|
|
103
|
+
private recentAcks;
|
|
87
104
|
private sendDeliveryAckFn;
|
|
88
105
|
/**
|
|
89
106
|
* Set the local peer info. Called from register-peer tool after
|
|
@@ -165,10 +182,6 @@ export declare class AutoRelayService {
|
|
|
165
182
|
* response should still be treated as inject-only.
|
|
166
183
|
*/
|
|
167
184
|
cancelResponseWaiter(fromPeerId: string): void;
|
|
168
|
-
/**
|
|
169
|
-
* Cancel only the active delivery ack waiter for a peer.
|
|
170
|
-
*/
|
|
171
|
-
cancelDeliveryAckWaiter(fromPeerId: string): void;
|
|
172
185
|
/**
|
|
173
186
|
* Cancel ALL pending response waiters for a peer by rejecting them with
|
|
174
187
|
* a clear error. Used by clearExpectation()/cancelResponseWaiter() to
|
|
@@ -183,16 +196,21 @@ export declare class AutoRelayService {
|
|
|
183
196
|
* resolves when the target peer's MCP sends a delivery_ack frame, or
|
|
184
197
|
* rejects on timeout (recipient likely offline).
|
|
185
198
|
*/
|
|
186
|
-
waitForDeliveryAck(fromPeerId: string, timeoutMs: number): Promise<void>;
|
|
187
|
-
/**
|
|
188
|
-
* Resolve a pending delivery ack waiter. Called by startup.ts onDeliveryAck
|
|
189
|
-
* callback when the server routes a delivery_ack frame to us.
|
|
190
|
-
*/
|
|
191
|
-
resolveDeliveryAck(fromPeerId: string): void;
|
|
199
|
+
waitForDeliveryAck(fromPeerId: string, messageId: string, timeoutMs: number): Promise<void>;
|
|
192
200
|
/**
|
|
193
|
-
*
|
|
194
|
-
*
|
|
201
|
+
* Settle the waiter for exactly this message.
|
|
202
|
+
*
|
|
203
|
+
* 🔴 Correlation is by MESSAGE ID, and the acknowledging peer must match the peer we sent to.
|
|
204
|
+
* The frame has carried `messageId` all along (src/cloud/ws-client.ts:52); startup.ts used to
|
|
205
|
+
* drop it and resolve by peer, so any ack settled any outstanding send to that peer — and an ack
|
|
206
|
+
* naming a peer the sender never messaged could settle a waiter outright (AUD-003).
|
|
207
|
+
*
|
|
208
|
+
* An ack with no matching waiter is BUFFERED rather than discarded: the recipient can legitimately
|
|
209
|
+
* acknowledge before our POST response returns.
|
|
195
210
|
*/
|
|
211
|
+
resolveDeliveryAck(fromPeerId: string, messageId: string): void;
|
|
212
|
+
/** Remember an ack whose waiter does not exist yet, with bounded retention. */
|
|
213
|
+
private _bufferEarlyAck;
|
|
196
214
|
private _cancelDeliveryAckWaiter;
|
|
197
215
|
/**
|
|
198
216
|
* Process an incoming cloud message by calling the local agent CLI via execRemote()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-relay.d.ts","sourceRoot":"","sources":["../../src/services/auto-relay.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAiB,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAQ/E;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC;AACX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAW3E;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAeR;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAGrE;AA0BD,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,UAAU,EAAE,GACzB,MAAM,CAWR;AA8ED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CA8ER;
|
|
1
|
+
{"version":3,"file":"auto-relay.d.ts","sourceRoot":"","sources":["../../src/services/auto-relay.ts"],"names":[],"mappings":"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"}
|