@real-life/trust-protocol 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,101 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
Takes up the VTI Mediator Adapter Profile 0.24: the sending form of §3a.
|
|
6
|
+
|
|
7
|
+
- **Two sending modes** (RLTP-VTI-3110 to 3140): `SendMode` is
|
|
8
|
+
`'routed' | 'egress-session'`. Every adapter instance starts in
|
|
9
|
+
`routed`; `MediatorWire.deposit(accessToken, bytes, egressDid, mode)`
|
|
10
|
+
now receives the mode of each deposit, read at the hand-over, so an
|
|
11
|
+
attempt begun before a switch ends in the mode it began in. A wire may
|
|
12
|
+
offer `queueEmpty()` (true when the mediator holds nothing more for
|
|
13
|
+
the connection). Closed: a wire without it never completes a
|
|
14
|
+
collection, and the adapter over it never switches. The consumer a
|
|
15
|
+
wire registers with `onDeliver` now answers a boolean: whether the
|
|
16
|
+
adapter took the frame (buffered, already held, or absorbed); `false`
|
|
17
|
+
(above `max-queue-bytes`, or a retired instance) leaves the frame with
|
|
18
|
+
the mediator, and a wire does not take its queue for drained until the
|
|
19
|
+
frame is offered again.
|
|
20
|
+
- **The send state** (RLTP-VTI-3130), per relationship: the mode and the
|
|
21
|
+
**open routed deposits** (`SendState.open`, each with digest and
|
|
22
|
+
acceptance instant): every document (an entry of kind `document` filed
|
|
23
|
+
by `reconcile`) accepted in `routed` and not yet answered.
|
|
24
|
+
Acknowledgements are no open deposits, so a side that only
|
|
25
|
+
acknowledges never switches by the deadline (profile Open Issue 9). A
|
|
26
|
+
document's acceptance instant is the adapter clock (the last port
|
|
27
|
+
instant) when its deposit resolved; without a port call in between it
|
|
28
|
+
is the hand-over instant. The send state travels in `AckState.send`
|
|
29
|
+
(new type `SendState`); a restore checks it fail-closed: exactly `mode`
|
|
30
|
+
and `open`, a known mode, each entry exactly digest and acceptance
|
|
31
|
+
instant, finite and not after the restore instant, each digest once,
|
|
32
|
+
nothing open in `egress-session` — any other field is refused, not
|
|
33
|
+
ignored. A snapshot without it starts in `routed`. `sendMode` reads the
|
|
34
|
+
current mode. A `submit()` without a digest opens nothing. An open
|
|
35
|
+
deposit falls `routedAckDeadlineMs` plus `duplicateWindowMs` after its
|
|
36
|
+
acceptance, also where no switch check runs; a restore cuts such
|
|
37
|
+
entries instead of refusing them. A routed attempt accepted after the
|
|
38
|
+
switch enters nothing.
|
|
39
|
+
- **Absorption for the give-up horizon** (profile §2, §4): the adapter
|
|
40
|
+
absorbs a byte-identical copy of a concluded item only within
|
|
41
|
+
`give-up-horizon` of its conclusion (or while an acknowledgement for it
|
|
42
|
+
is on the wire); a later copy is a new item for the holder, whose
|
|
43
|
+
absorption answers it with the stored acknowledgement (RLTP-DEL-6330,
|
|
44
|
+
6335); its new conclusion sets the conclusion instant anew. Buffered
|
|
45
|
+
and outstanding go before concluded, so a redelivery of such a copy is
|
|
46
|
+
ignored while the holder has it. The entry and its ack intent stand for
|
|
47
|
+
the duplicate window; while such a later copy waits in the buffer or is outstanding,
|
|
48
|
+
the standing intent is not sent, so it never deletes the copy before
|
|
49
|
+
the holder concluded it (hand off → await → ack).
|
|
50
|
+
- **"Nothing pending" is the binding's statement** (RLTP-VTI-7150):
|
|
51
|
+
`queueEmpty()` true; without it, no switch.
|
|
52
|
+
- **Answers and switch**: `acknowledged(id)`, `receiverRefused(id, code)`
|
|
53
|
+
and the new `answered(digest, now)` (an answer the holder hands a later
|
|
54
|
+
instance: a valid acknowledgement, a validated refusal or a validated
|
|
55
|
+
`idConflict`) answer the open deposit of that document's digest; a
|
|
56
|
+
verdict that outruns the acceptance (`answered` included) keeps the
|
|
57
|
+
document from being opened. An open acknowledgement is answered by nothing. Each answer
|
|
58
|
+
settles its own deposit only. `advance` switches one way to
|
|
59
|
+
`egress-session` when an open routed deposit was accepted
|
|
60
|
+
`DECLARED.routedAckDeadlineMs` (72 h, equal to the give-up horizon) or
|
|
61
|
+
more ago, checked only after the instance concluded a collection that
|
|
62
|
+
left nothing pending (an empty collection counts; `queueEmpty()` true,
|
|
63
|
+
nothing buffered or outstanding) and only while nothing is pending
|
|
64
|
+
again at the check, so an acknowledgement that arrived since is
|
|
65
|
+
collected and reported first. A deposit the wire refuses with the new
|
|
66
|
+
`WireError` kind `'routed-refused'` (a validated refusal of the routed
|
|
67
|
+
form) switches at once; the submission stays
|
|
68
|
+
`awaiting-transport(carrier-refused-retriable)` and goes in
|
|
69
|
+
`egress-session` at its next hand-over. This holds for an attempt the
|
|
70
|
+
holder withdrew while it ran as well: the refusal is evidence about the
|
|
71
|
+
mediator, not about the document. At the switch the open deposits
|
|
72
|
+
leave; nothing returns to `routed`. An accepted submission is never
|
|
73
|
+
deposited again; one still in the holder's custody goes in the new mode
|
|
74
|
+
at its next hand-over (RLTP-VTI-3135, 7130).
|
|
75
|
+
- **What the host owes**: the reports a collection carries are applied
|
|
76
|
+
before its `conclude`, at the latest before the next `advance`, since
|
|
77
|
+
the switch check counts them as applied. A host that persists only
|
|
78
|
+
`concluded` and `pending` starts every opening in `routed` with nothing
|
|
79
|
+
open, so a relationship whose openings last less than 72 hours never
|
|
80
|
+
switches by the deadline; the mode in a restored snapshot is as
|
|
81
|
+
trustworthy as the host's store.
|
|
82
|
+
- **`depositAddressing(mode, self, peerConnection, carrier)`**: the
|
|
83
|
+
addressing of both layers and the session per mode, as
|
|
84
|
+
`vectors/vti-routed-addressing.json` states it (RLTP-VTI-1110, 1120,
|
|
85
|
+
3110, 3115, 3120); the wire binding packs from it.
|
|
86
|
+
- **The app's transport contract**, stated and tested (it held before):
|
|
87
|
+
after a withdrawal by `reconcile` the adapter starts no deposit for that
|
|
88
|
+
submission, and an outcome that resolves late changes nothing, the send
|
|
89
|
+
state included, except a validated refusal of the routed form, which
|
|
90
|
+
switches; a wire call already running cannot be recalled and may
|
|
91
|
+
still land at the mediator (profile §6), and the copy that arrives is a
|
|
92
|
+
duplicate the receiver absorbs (Delivery §6.2). Every deposit is a
|
|
93
|
+
submission with an id of its own, a duplicate's answer included; the
|
|
94
|
+
report handed to the holder carries the digest, and the app pairs it
|
|
95
|
+
with its deposit through the submission id it polls.
|
|
96
|
+
- Breaking for wire implementations: `deposit` takes the mode as its
|
|
97
|
+
fourth argument. `AckState` gains the optional `send`.
|
|
98
|
+
|
|
3
99
|
## 0.6.1
|
|
4
100
|
|
|
5
101
|
One actId, one result.
|
package/README.md
CHANGED
|
@@ -94,7 +94,33 @@ that the adapter holds it and ends nothing (RLTP-DEL-6330), and it stays
|
|
|
94
94
|
retained with its effect for a duplicate (6335).
|
|
95
95
|
`./adapters/vti-mediator` reconciles from the view
|
|
96
96
|
(`reconcile(view, holder, now)`); one adapter serves one opening, so the
|
|
97
|
-
next opening creates a new one.
|
|
97
|
+
next opening creates a new one. The app persists the adapter's
|
|
98
|
+
`ackState()`, which carries the relationship's send state, and restores it
|
|
99
|
+
into the next adapter; it hands that adapter, through `answered(digest,
|
|
100
|
+
now)`, the valid acknowledgements, validated refusals and validated
|
|
101
|
+
`idConflict` answers that arrive for documents an earlier adapter
|
|
102
|
+
deposited, before the adapter's next `advance`. The reports a
|
|
103
|
+
collection carries (`acknowledged`, `receiverRefused`, `answered`) are
|
|
104
|
+
applied before that collection's `conclude`, at the latest before the
|
|
105
|
+
next `advance`: the switch check counts them as applied, and one applied
|
|
106
|
+
late can let a relationship switch although its deposits were answered.
|
|
107
|
+
The send state holds the mode and the open routed deposits: this side's
|
|
108
|
+
documents accepted in `routed` and not yet answered (acknowledgements are
|
|
109
|
+
none, so a side that only acknowledges never switches by the deadline); an open
|
|
110
|
+
deposit 72 hours old switches the relationship to `egress-session`, and
|
|
111
|
+
so does a deposit the wire refuses as `'routed-refused'`, at once. A host
|
|
112
|
+
that persists only `concluded` and `pending` starts every opening in
|
|
113
|
+
`routed` with nothing open, so a relationship whose openings last less
|
|
114
|
+
than 72 hours never switches by the deadline; the mode in a restored
|
|
115
|
+
snapshot is as trustworthy as the host's store. The adapter absorbs a
|
|
116
|
+
byte-identical copy of a concluded item only for the give-up horizon
|
|
117
|
+
after its conclusion; a later copy reaches the holder, which absorbs it
|
|
118
|
+
and answers it with the stored acknowledgement. An open routed deposit
|
|
119
|
+
falls 72 hours plus the 30-day duplicate window after its acceptance, so
|
|
120
|
+
the send state stays bounded. A `submit()` without a
|
|
121
|
+
digest opens nothing: an app that sends only through `submit()` never
|
|
122
|
+
switches by the deadline. The consumer a wire registers with `onDeliver`
|
|
123
|
+
answers whether the adapter took the frame.
|
|
98
124
|
|
|
99
125
|
**The timer.** Every act, receive and resume may name `nextDueAt`: the
|
|
100
126
|
earliest time something is due, delivery work (retries, duties, acks)
|
|
@@ -168,7 +194,7 @@ Other entry points:
|
|
|
168
194
|
|---|---|
|
|
169
195
|
| `./testing` | `InMemoryStore`, `memoryLog`, `scriptedEntropy`, `storeContract`, `emptyState`, `stateBuilder`, `freezeDeep`, `sampleState`, `openPromptModule`, the invariant checks, `forgeMapping` (deniability, Trust 6.1), `SCHEMAS` and the generated `wire` types. For tests, vectors and adapter authors; not for production holders. |
|
|
170
196
|
| `./internal` | The structural `HolderState`, `encodeState` and the codec chain, the engine's module types, the pure view functions, the modules' factories and pure reads. For the library's own modules and tests; not an app contract. |
|
|
171
|
-
| `./adapters/vti-mediator` | The VTI mediator as a
|
|
197
|
+
| `./adapters/vti-mediator` | The VTI mediator as a transport adapter (profile 0.24): its submission states as `DeliveryReport`, collection and ack handling, the selective conclusion of a collection (`conclude(c, now, {keep})`, `concludable(result)`: a `failed(rate-limited)` item stays with the carrier), the sending form of §3a: every deposit names its `SendMode` (`routed`, or `egress-session` after the one-way switch of RLTP-VTI-3130), the send state (mode, open routed deposits) travels in `AckState.send` (a `submit()` without a digest opens nothing), a `WireError('routed-refused')` switches at once, a wire without `queueEmpty()` never completes a collection and so never switches, `answered(digest, now)` carries the holder's answers to a later instance, and `depositAddressing(mode, self, peerConnection, carrier)` gives both layers' addressing. |
|
|
172
198
|
|
|
173
199
|
## The modules and the rules they implement
|
|
174
200
|
|
|
@@ -288,6 +314,7 @@ This package uses its own semver; the specification uses castings.
|
|
|
288
314
|
| membership | Membership Tasks 0.20, Access 0.57 | the Access envelope (Membership 3.3: `access-operation/0.1` with `member.add` and the sealed welcome; this library sends its own `x-membership-welcome/0.1`); an admission prompt after the bound of RLTP-MT-3282; roster replication: a holder knows the members it admitted and the roster its welcome carried |
|
|
289
315
|
| introduction | Trust 0.31 §8 | how a requester learns the mediator's designator (8.3): this library's mediator sends `x-introduction-offer/0.1` |
|
|
290
316
|
| delivery | Delivery 0.83 | transport adapters beyond `./adapters/vti-mediator`; the block of the Trust Layer's types (Message Tasks 6240: their treatments wait for the next casting of the Trust Layer) |
|
|
317
|
+
| transport adapter | VTI Mediator Adapter Profile 0.24 | the TSP framing, which is the wire binding's (profile §7; `binding/` in the repository); a return from `egress-session` to `routed` (profile Open Issue 7) |
|
|
291
318
|
| message | Message Tasks 0.1 | holding a message unsent until its tuple is ready (5020): `sendMessage` answers `not-ready` and the app keeps the message; checking `replyTo` against the relationship's history (5120), which is the app's; multi-device (§9); `failed(task-expired)` for a message: reachable only with a retry horizon beyond P179D, which the engine does not admit (at most P90D), so an undelivered message ends as `failed(expired-by-adapter-policy)` |
|
|
292
319
|
| devices | Identity §5.5 | multi-device production: one writer per holder |
|
|
293
320
|
|
|
@@ -10,8 +10,37 @@ export declare const DECLARED: Readonly<{
|
|
|
10
10
|
readonly queueFloorBytes: 1048576;
|
|
11
11
|
readonly maxQueueBytes: 16777216;
|
|
12
12
|
readonly duplicateWindowMs: number;
|
|
13
|
+
readonly routedAckDeadlineMs: number;
|
|
13
14
|
}>;
|
|
14
|
-
|
|
15
|
+
/** How a deposit reaches the mediator (RLTP-VTI-3110, 3120). */
|
|
16
|
+
export type SendMode = 'routed' | 'egress-session';
|
|
17
|
+
/** One TSP layer's addressing (no keys, no bytes: those are the wire's). */
|
|
18
|
+
export interface LayerAddressing {
|
|
19
|
+
messageType: 'direct' | 'routed';
|
|
20
|
+
sender: string;
|
|
21
|
+
receiver: string;
|
|
22
|
+
route?: string[];
|
|
23
|
+
}
|
|
24
|
+
/** The addressing of a deposit in `mode` (RLTP-VTI-1110, 1120, 3110,
|
|
25
|
+
* 3115, 3120): the inner `direct` message from this side's egress
|
|
26
|
+
* identity to the counterpart's connection DID; in mode `routed` an
|
|
27
|
+
* outer routed message from this side's connection DID to the carrier
|
|
28
|
+
* `C` with the route [counterpart's connection DID], deposited on the
|
|
29
|
+
* connection DID's session; in mode `egress-session` no outer layer,
|
|
30
|
+
* deposited on the egress identity's send-only session. */
|
|
31
|
+
export declare function depositAddressing(mode: SendMode, self: {
|
|
32
|
+
connection: string;
|
|
33
|
+
egress: string;
|
|
34
|
+
}, peerConnection: string, carrier: string): {
|
|
35
|
+
inner: LayerAddressing;
|
|
36
|
+
outer: LayerAddressing | null;
|
|
37
|
+
session: string;
|
|
38
|
+
};
|
|
39
|
+
export type WireErrorKind = 'unreachable' | 'refused-retriable' | 'refused-admission' | 'oversize'
|
|
40
|
+
/** the mediator refused a routed deposit for its routed form, and the
|
|
41
|
+
* binding authenticated that refusal as the mediator's (RLTP-VTI-3130):
|
|
42
|
+
* the relationship switches to egress-session at once */
|
|
43
|
+
| 'routed-refused';
|
|
15
44
|
export declare class WireError extends Error {
|
|
16
45
|
kind: WireErrorKind;
|
|
17
46
|
constructor(kind: WireErrorKind, message?: string);
|
|
@@ -28,11 +57,23 @@ export interface MediatorWire {
|
|
|
28
57
|
}): Promise<TokenSet>;
|
|
29
58
|
refresh(refreshToken: string): Promise<TokenSet>;
|
|
30
59
|
keylistUpdate(accessToken: string, rkids: string[]): Promise<void>;
|
|
31
|
-
|
|
60
|
+
/** `mode` is the sending form of this deposit (profile §3a): the wire
|
|
61
|
+
* packs and sends it as depositAddressing(mode, …) describes. */
|
|
62
|
+
deposit(accessToken: string, bytes: Uint8Array, egressDid: string, mode: SendMode): Promise<void>;
|
|
32
63
|
ackReceived(accessToken: string, queueIds: string[]): Promise<void>;
|
|
33
|
-
|
|
64
|
+
/** The adapter's consumer answers whether it took the frame (buffered,
|
|
65
|
+
* already held, or absorbed as a duplicate): false means the frame is
|
|
66
|
+
* left with the mediator (above max-queue-bytes, or a retired
|
|
67
|
+
* instance), and a wire must not take its queue for drained until the
|
|
68
|
+
* frame is offered again (RLTP-VTI-3130, queueEmpty). */
|
|
69
|
+
onDeliver(cb: (bytes: Uint8Array) => Promise<boolean>): void;
|
|
34
70
|
/** Optional truthful connectivity signal; absent means unknown. */
|
|
35
71
|
offline?(): boolean;
|
|
72
|
+
/** Optional: true when the mediator holds nothing more for this
|
|
73
|
+
* connection (RLTP-VTI-3130: a conclusion that left no frame
|
|
74
|
+
* pending). Closed: absent, no collection counts as complete, so an
|
|
75
|
+
* adapter over a wire without it never switches to egress-session. */
|
|
76
|
+
queueEmpty?(): boolean;
|
|
36
77
|
}
|
|
37
78
|
export interface TokenSet {
|
|
38
79
|
accessToken: string;
|
|
@@ -82,6 +123,20 @@ export interface AckState {
|
|
|
82
123
|
concludedAt: number;
|
|
83
124
|
}>;
|
|
84
125
|
pending: string[];
|
|
126
|
+
/** the relationship's send state (RLTP-VTI-3130); absent → `routed` */
|
|
127
|
+
send?: SendState;
|
|
128
|
+
}
|
|
129
|
+
/** The send state of a relationship (profile §3a, RLTP-VTI-3130),
|
|
130
|
+
* persisted with the ack state: the mode and the open routed deposits —
|
|
131
|
+
* this side's documents accepted in routed and not yet answered, each
|
|
132
|
+
* with its digest and acceptance instant. Acknowledgements are no open
|
|
133
|
+
* deposits. In egress-session `open` is empty. */
|
|
134
|
+
export interface SendState {
|
|
135
|
+
mode: SendMode;
|
|
136
|
+
open: Array<{
|
|
137
|
+
digest: string;
|
|
138
|
+
acceptedAt: number;
|
|
139
|
+
}>;
|
|
85
140
|
}
|
|
86
141
|
/** The holder's side of a hand-over (lib 0.6.0): the holder itself.
|
|
87
142
|
* handOver checks the entry and calls `start` inside the holder's queue;
|
|
@@ -125,6 +180,15 @@ export declare class MediatorCarrierAdapter {
|
|
|
125
180
|
* submission filed without a digest (submit) has no report form. */
|
|
126
181
|
report(id: string): DeliveryReport | null;
|
|
127
182
|
has(id: string): boolean;
|
|
183
|
+
/** The current sending mode of the relationship (profile §3a). */
|
|
184
|
+
get sendMode(): SendMode;
|
|
185
|
+
/** An answer the holder hands this instance for a document an earlier
|
|
186
|
+
* instance deposited (RLTP-VTI-3130): a valid acknowledgement, a
|
|
187
|
+
* validated receiver refusal or a validated `idConflict` answer for
|
|
188
|
+
* `digest`. If the send state names the document as an open routed
|
|
189
|
+
* deposit, it is answered and leaves; otherwise it answers nothing. A
|
|
190
|
+
* no-op on a retired instance, like acknowledged. */
|
|
191
|
+
answered(digest: string, rawNow: number): void;
|
|
128
192
|
/** Host teardown aid, NOT a port operation (profile §6): awaits
|
|
129
193
|
* the in-flight background tasks so a host can drain before
|
|
130
194
|
* persisting ackState. On a hanging wire it waits as long as the
|
|
@@ -144,13 +208,20 @@ export declare class MediatorCarrierAdapter {
|
|
|
144
208
|
* (d) otherwise → no report yet (null)
|
|
145
209
|
* Terminal states and `accepted` are stored and stand. */
|
|
146
210
|
status(id: string): SubmissionState | null;
|
|
211
|
+
/** A valid acknowledgement for submission `id`. Reports that a
|
|
212
|
+
* collection carries are applied before that collection's conclude,
|
|
213
|
+
* at the latest before the next advance: the switch check of
|
|
214
|
+
* RLTP-VTI-3130 counts on them, and a report applied late can let the
|
|
215
|
+
* relationship switch although its deposits were answered. */
|
|
147
216
|
acknowledged(id: string): void;
|
|
148
217
|
/** Refusals act on live submissions only (§6.1 knows exactly one
|
|
149
218
|
* late correction — the valid ack). The code set is closed and
|
|
150
219
|
* TERMINAL: retryable counterpart conditions (unavailable,
|
|
151
220
|
* internalError) are transport outcomes, never receiver verdicts
|
|
152
221
|
* — they have no entry here, and an unknown code is refused
|
|
153
|
-
* fail-closed rather than minted into a verdict (R6-B2).
|
|
222
|
+
* fail-closed rather than minted into a verdict (R6-B2). Applied, like
|
|
223
|
+
* acknowledged, before the conclude of the collection that carried
|
|
224
|
+
* it (RLTP-VTI-3130). */
|
|
154
225
|
receiverRefused(id: string, code: ReceiverRefusalCode): void;
|
|
155
226
|
drainTransitions(): Array<{
|
|
156
227
|
id: string;
|
|
@@ -162,7 +233,11 @@ export declare class MediatorCarrierAdapter {
|
|
|
162
233
|
* is transient (Delivery RLTP-DEL-5810, 5820: `failed(rate-limited)`,
|
|
163
234
|
* or a transaction that could not commit, see `concludable`): they are
|
|
164
235
|
* not concluded and not acknowledged, they go back to the buffer and the
|
|
165
|
-
* next collect offers them again, and the mediator keeps its copy.
|
|
236
|
+
* next collect offers them again, and the mediator keeps its copy.
|
|
237
|
+
* The reports the collection carries (acknowledged, receiverRefused,
|
|
238
|
+
* answered) are applied BEFORE this call, at the latest before the next
|
|
239
|
+
* advance: a conclusion that leaves nothing pending opens the switch
|
|
240
|
+
* check of RLTP-VTI-3130, which counts them as applied. */
|
|
166
241
|
conclude(collection: {
|
|
167
242
|
id: string;
|
|
168
243
|
}, rawNow: number, opts?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vti-mediator.d.ts","sourceRoot":"","sources":["../../src/adapters/vti-mediator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vti-mediator.d.ts","sourceRoot":"","sources":["../../src/adapters/vti-mediator.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,10 +20,50 @@
|
|
|
20
20
|
// about transport; the holder's receive core verifies the delivery-ack
|
|
21
21
|
// itself.
|
|
22
22
|
//
|
|
23
|
-
// Profile: spec/adapter-vti-mediator.md v0.
|
|
23
|
+
// Profile: spec/adapter-vti-mediator.md v0.24 (twenty-fourth casting;
|
|
24
24
|
// round journals under design/adapter-review*). A
|
|
25
25
|
// transport adapter contract — NOT a carrier at the port.
|
|
26
26
|
//
|
|
27
|
+
// Sending form (profile §3a, lib 0.7.0): every deposit names its mode to
|
|
28
|
+
// the wire. Mode `routed` (the mode of every instance from construction):
|
|
29
|
+
// an inner TSP `direct` message egress identity → counterpart's
|
|
30
|
+
// connection DID inside an outer routed message connection DID → C with
|
|
31
|
+
// the route [counterpart's connection DID], on the connection DID's
|
|
32
|
+
// session. Mode `egress-session` (fallback): the inner message alone, on
|
|
33
|
+
// a send-only session of the egress identity. The wire packs the layers
|
|
34
|
+
// (depositAddressing says who addresses whom); the adapter keeps the
|
|
35
|
+
// relationship's send state (the mode and the open routed deposits) in
|
|
36
|
+
// its ack state (RLTP-VTI-3130). Open are: every document with a digest
|
|
37
|
+
// (an entry of kind `document` filed by reconcile) accepted in routed and
|
|
38
|
+
// not yet answered — a valid acknowledgement, a validated refusal or a
|
|
39
|
+
// validated idConflict for its digest answers it. Acknowledgements are
|
|
40
|
+
// no open deposits: a side that only acknowledges never switches by the
|
|
41
|
+
// deadline (Open Issue 9). The adapter switches one way to
|
|
42
|
+
// `egress-session` when an open deposit is routed-ack-deadline (72 h)
|
|
43
|
+
// old, checked in an advance after a conclusion that left nothing
|
|
44
|
+
// pending and while nothing is pending again — "nothing pending" is the
|
|
45
|
+
// binding's statement through queueEmpty() (RLTP-VTI-7150); without it
|
|
46
|
+
// the adapter never switches — and at once on a
|
|
47
|
+
// validated refusal of the routed form (WireError 'routed-refused').
|
|
48
|
+
// At the switch the open deposits leave; nothing returns to routed. A
|
|
49
|
+
// submit() without a digest opens nothing. An attempt
|
|
50
|
+
// ends in the mode it began in; an accepted submission is never
|
|
51
|
+
// deposited again (RLTP-VTI-3135, 7130).
|
|
52
|
+
//
|
|
53
|
+
// The app's transport contract (web-of-trust TRANSPORT.md, rules 5 and
|
|
54
|
+
// 6), as far as it holds here: (5) a withdrawal — reconcile without the
|
|
55
|
+
// entry — means the adapter starts no deposit for that submission
|
|
56
|
+
// afterwards, and an outcome that resolves late changes nothing here
|
|
57
|
+
// (has() false, report() null, no send state) — except a validated refusal
|
|
58
|
+
// of the routed form, which switches the relationship (a finding about the
|
|
59
|
+
// mediator, RLTP-VTI-3130). A wire call already
|
|
60
|
+
// running cannot be recalled and may still land at the mediator (the §6
|
|
61
|
+
// boundary); the copy that then arrives is a duplicate the receiver
|
|
62
|
+
// absorbs (Delivery §6.2). (6) Every deposit is a submission with an id
|
|
63
|
+
// of its own, a duplicate's answer (`resend`) included; the
|
|
64
|
+
// DeliveryReport handed to the holder carries the digest, and the app
|
|
65
|
+
// pairs it with its deposit through the submission id it polls.
|
|
66
|
+
//
|
|
27
67
|
// Beyond the profile (lib 0.5.0): conclude(collection, now, {keep}) leaves
|
|
28
68
|
// the items whose disposition is transient unconcluded and offers them
|
|
29
69
|
// again (Delivery 0.82 RLTP-DEL-5810, 5820: failed(rate-limited) is never
|
|
@@ -53,7 +93,29 @@ export const DECLARED = Object.freeze({
|
|
|
53
93
|
queueFloorBytes: 1_048_576,
|
|
54
94
|
maxQueueBytes: 16_777_216,
|
|
55
95
|
duplicateWindowMs: 30 * 86_400_000,
|
|
96
|
+
routedAckDeadlineMs: 72 * 3_600_000,
|
|
56
97
|
});
|
|
98
|
+
const SEND_MODES = new Set(['routed', 'egress-session']);
|
|
99
|
+
/** The addressing of a deposit in `mode` (RLTP-VTI-1110, 1120, 3110,
|
|
100
|
+
* 3115, 3120): the inner `direct` message from this side's egress
|
|
101
|
+
* identity to the counterpart's connection DID; in mode `routed` an
|
|
102
|
+
* outer routed message from this side's connection DID to the carrier
|
|
103
|
+
* `C` with the route [counterpart's connection DID], deposited on the
|
|
104
|
+
* connection DID's session; in mode `egress-session` no outer layer,
|
|
105
|
+
* deposited on the egress identity's send-only session. */
|
|
106
|
+
export function depositAddressing(mode, self, peerConnection, carrier) {
|
|
107
|
+
if (!SEND_MODES.has(mode))
|
|
108
|
+
throw new Error(`unknown send mode ${String(mode)}`);
|
|
109
|
+
const inner = { messageType: 'direct', sender: self.egress, receiver: peerConnection };
|
|
110
|
+
if (mode === 'routed') {
|
|
111
|
+
return {
|
|
112
|
+
inner,
|
|
113
|
+
outer: { messageType: 'routed', sender: self.connection, receiver: carrier, route: [peerConnection] },
|
|
114
|
+
session: self.connection,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return { inner, outer: null, session: self.egress };
|
|
118
|
+
}
|
|
57
119
|
export class WireError extends Error {
|
|
58
120
|
kind;
|
|
59
121
|
constructor(kind, message) {
|
|
@@ -89,6 +151,45 @@ export function concludable(r) {
|
|
|
89
151
|
}
|
|
90
152
|
/** The adapter's own copy of a wire's token set: the wire keeps no handle on it. */
|
|
91
153
|
const tokenCopy = (t) => ({ accessToken: t.accessToken, accessExpiresAt: t.accessExpiresAt, refreshToken: t.refreshToken, refreshExpiresAt: t.refreshExpiresAt });
|
|
154
|
+
/** how long an open routed deposit stays in the send state at most
|
|
155
|
+
* (RLTP-VTI-3130): the state is bounded even where no switch check runs */
|
|
156
|
+
const OPEN_KEEP_MS = DECLARED.routedAckDeadlineMs + DECLARED.duplicateWindowMs;
|
|
157
|
+
const finite = (x) => typeof x === 'number' && Number.isFinite(x);
|
|
158
|
+
/** A restored send state, checked fail-closed (§4): exactly `mode` and
|
|
159
|
+
* `open`, a known mode, each entry exactly a digest and a finite
|
|
160
|
+
* acceptance instant not after restoredAt, each digest once, nothing open
|
|
161
|
+
* in egress-session. Any other field — the acknowledgement fields of an
|
|
162
|
+
* earlier form included — is refused, not ignored. */
|
|
163
|
+
function restoreSendState(send, restoredAt) {
|
|
164
|
+
const refuse = (why) => { throw new Error(`ack snapshot: send state ${why}`); };
|
|
165
|
+
if (typeof send !== 'object' || send === null)
|
|
166
|
+
return refuse('is not an object');
|
|
167
|
+
const s = send;
|
|
168
|
+
const exactly = (o, keys) => {
|
|
169
|
+
const own = Object.keys(o);
|
|
170
|
+
return own.length === keys.length && keys.every((k) => own.includes(k));
|
|
171
|
+
};
|
|
172
|
+
if (!exactly(s, ['mode', 'open']))
|
|
173
|
+
refuse('has other fields than mode and open');
|
|
174
|
+
if (typeof s.mode !== 'string' || !SEND_MODES.has(s.mode))
|
|
175
|
+
refuse('names an unknown mode');
|
|
176
|
+
if (!Array.isArray(s.open))
|
|
177
|
+
refuse('open deposits are not a list');
|
|
178
|
+
const open = s.open.map((r) => {
|
|
179
|
+
const e = r;
|
|
180
|
+
if (typeof e !== 'object' || e === null || !exactly(e, ['digest', 'acceptedAt']) ||
|
|
181
|
+
typeof e.digest !== 'string' || !finite(e.acceptedAt) || e.acceptedAt > restoredAt) {
|
|
182
|
+
return refuse('open deposit is malformed, non-finite or accepted after restoredAt');
|
|
183
|
+
}
|
|
184
|
+
return { digest: e.digest, acceptedAt: e.acceptedAt };
|
|
185
|
+
});
|
|
186
|
+
if (new Set(open.map((o) => o.digest)).size !== open.length)
|
|
187
|
+
refuse('names an open deposit twice');
|
|
188
|
+
// the switch empties it: an egress-session with open deposits was never produced
|
|
189
|
+
if (s.mode === 'egress-session' && open.length > 0)
|
|
190
|
+
refuse('is egress-session with open routed deposits');
|
|
191
|
+
return { mode: s.mode, open };
|
|
192
|
+
}
|
|
92
193
|
const hex = (b) => Array.from(b, (x) => x.toString(16).padStart(2, '0')).join('');
|
|
93
194
|
// construction capability: only create() holds it
|
|
94
195
|
const KEY = Symbol('MediatorCarrierAdapter.create');
|
|
@@ -126,6 +227,12 @@ export class MediatorCarrierAdapter {
|
|
|
126
227
|
#flushing = false;
|
|
127
228
|
#nextColId = 1;
|
|
128
229
|
#transitions = [];
|
|
230
|
+
// the relationship's send state (RLTP-VTI-3130)
|
|
231
|
+
#mode = 'routed';
|
|
232
|
+
/** open routed deposits (documents), keyed by digest */
|
|
233
|
+
#openDeposits = new Map();
|
|
234
|
+
/** this instance has concluded a collection that left nothing pending */
|
|
235
|
+
#cleanConcluded = false;
|
|
129
236
|
/** The only way to build an adapter: the trio is DERIVED here from
|
|
130
237
|
* one root, one carrier, one nonce — so principal, connection DID
|
|
131
238
|
* and egress identity cannot come from different relationships
|
|
@@ -189,47 +296,66 @@ export class MediatorCarrierAdapter {
|
|
|
189
296
|
if (pending.has(queueId))
|
|
190
297
|
this.#pendingAcks.add(queueId);
|
|
191
298
|
}
|
|
299
|
+
// absent: a host that persisted none starts again in routed
|
|
300
|
+
if (restored.send !== undefined) {
|
|
301
|
+
const send = restoreSendState(restored.send, restoredAt);
|
|
302
|
+
this.#mode = send.mode;
|
|
303
|
+
// an open deposit falls routed-ack-deadline plus duplicate-window
|
|
304
|
+
// after its acceptance: cut here, not refused
|
|
305
|
+
for (const o of send.open)
|
|
306
|
+
if (restoredAt - o.acceptedAt < OPEN_KEEP_MS)
|
|
307
|
+
this.#openDeposits.set(o.digest, o.acceptedAt);
|
|
308
|
+
}
|
|
192
309
|
}
|
|
193
310
|
this.#wire.onDeliver(async (raw) => {
|
|
194
311
|
if (this.#closed)
|
|
195
|
-
return;
|
|
312
|
+
return false;
|
|
196
313
|
// a plain copy of its own: a Node Buffer's slice() would share memory
|
|
197
314
|
const bytes = new Uint8Array(raw);
|
|
198
315
|
const queueId = hex(await sha(bytes));
|
|
199
316
|
if (this.#closed)
|
|
200
|
-
return;
|
|
201
|
-
// Absorption is
|
|
202
|
-
//
|
|
203
|
-
//
|
|
204
|
-
//
|
|
205
|
-
//
|
|
317
|
+
return false;
|
|
318
|
+
// Absorption is checked at the moment it happens (R11-B1): the
|
|
319
|
+
// adapter absorbs a copy only for give-up-horizon after its
|
|
320
|
+
// conclusion (profile §2, §4); a later copy is a new item for the
|
|
321
|
+
// holder, whose absorption answers it again with the stored
|
|
322
|
+
// acknowledgement (RLTP-DEL-6330, 6335) — so a counterpart that
|
|
323
|
+
// resubmits after a lost acknowledgement is answered. The entry and
|
|
324
|
+
// its ack intent stand for the duplicate window, and the window
|
|
325
|
+
// beats everything (round-14 B): beyond it, both fall.
|
|
326
|
+
// buffered and outstanding go before concluded (§3): a redelivery of
|
|
327
|
+
// a later copy the holder has not concluded yet is ignored
|
|
328
|
+
if (this.#inboxDigests.has(queueId))
|
|
329
|
+
return true;
|
|
330
|
+
for (const col of this.#outstanding.values())
|
|
331
|
+
if (col.has(queueId))
|
|
332
|
+
return true;
|
|
206
333
|
const concludedAt = this.#concluded.get(queueId);
|
|
207
334
|
if (concludedAt !== undefined) {
|
|
208
335
|
if (this.#flightAcks.has(queueId) ||
|
|
209
|
-
this.#clock - concludedAt < DECLARED.
|
|
210
|
-
// inside the
|
|
336
|
+
this.#clock - concludedAt < DECLARED.giveUpHorizonMs) {
|
|
337
|
+
// inside the horizon — or deferred: an id inside an
|
|
211
338
|
// in-flight flush keeps absorbing until that flush ends,
|
|
212
339
|
// because its irrecallable ack may still land (R15-B1)
|
|
213
340
|
this.#pendingAcks.add(queueId);
|
|
214
|
-
return;
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
if (this.#clock - concludedAt >= DECLARED.duplicateWindowMs) {
|
|
344
|
+
this.#concluded.delete(queueId);
|
|
345
|
+
this.#pendingAcks.delete(queueId);
|
|
215
346
|
}
|
|
216
|
-
this.#concluded.delete(queueId);
|
|
217
|
-
this.#pendingAcks.delete(queueId);
|
|
218
347
|
}
|
|
219
|
-
if (this.#inboxDigests.has(queueId))
|
|
220
|
-
return;
|
|
221
|
-
for (const col of this.#outstanding.values())
|
|
222
|
-
if (col.has(queueId))
|
|
223
|
-
return;
|
|
224
348
|
const held = this.#inboxBytes + this.#outstandingBytes;
|
|
225
349
|
const underFloor = this.#inbox.length < DECLARED.queueFloorCount &&
|
|
226
350
|
held + bytes.length <= DECLARED.queueFloorBytes;
|
|
227
351
|
const underCap = held + bytes.length <= DECLARED.maxQueueBytes;
|
|
352
|
+
// not acknowledged and not taken: the mediator keeps its copy
|
|
228
353
|
if (!underFloor && !underCap)
|
|
229
|
-
return;
|
|
354
|
+
return false;
|
|
230
355
|
this.#inbox.push({ bytes, queueId });
|
|
231
356
|
this.#inboxBytes += bytes.length;
|
|
232
357
|
this.#inboxDigests.add(queueId);
|
|
358
|
+
return true;
|
|
233
359
|
});
|
|
234
360
|
}
|
|
235
361
|
#now(raw) {
|
|
@@ -343,6 +469,7 @@ export class MediatorCarrierAdapter {
|
|
|
343
469
|
attemptStartedAt: null,
|
|
344
470
|
lastKind: null,
|
|
345
471
|
st: null,
|
|
472
|
+
sentMode: null,
|
|
346
473
|
};
|
|
347
474
|
this.#subs.set(id, sub);
|
|
348
475
|
if (!knownOffline)
|
|
@@ -408,7 +535,7 @@ export class MediatorCarrierAdapter {
|
|
|
408
535
|
bytes: new TextEncoder().encode(jcs(entry.envelope)),
|
|
409
536
|
// a duplicate's ack is a hand-over of its own, from now
|
|
410
537
|
submittedAt: entry.resend !== undefined ? now : Math.min(entry.since, now),
|
|
411
|
-
attemptStartedAt: null, lastKind: null, st: null,
|
|
538
|
+
attemptStartedAt: null, lastKind: null, st: null, sentMode: null,
|
|
412
539
|
};
|
|
413
540
|
this.#subs.set(id, sub);
|
|
414
541
|
refs.push({ submissionId: id, digest: entry.digest });
|
|
@@ -449,14 +576,19 @@ export class MediatorCarrierAdapter {
|
|
|
449
576
|
if (sub.st !== null && sub.st.state !== 'awaiting-transport')
|
|
450
577
|
return;
|
|
451
578
|
let next;
|
|
579
|
+
let routedRefused = false;
|
|
452
580
|
try {
|
|
453
581
|
const token = await this.#ensureAuth(now);
|
|
454
582
|
if (this.#closed)
|
|
455
583
|
return; // retirement between auth and deposit: nothing new starts (R5-B2)
|
|
456
|
-
// each attempt hands the wire a copy: what it does with it never reaches the next
|
|
584
|
+
// each attempt hands the wire a copy: what it does with it never reaches the next.
|
|
585
|
+
// The mode is read at the hand-over itself: from a switch on, every
|
|
586
|
+
// hand-over uses the new mode, and a call already made ends in its own
|
|
587
|
+
// (RLTP-VTI-3135)
|
|
457
588
|
const deposit = () => {
|
|
589
|
+
sub.sentMode = this.#mode;
|
|
458
590
|
try {
|
|
459
|
-
return this.#wire.deposit(token, new Uint8Array(sub.bytes), this.#egressDid);
|
|
591
|
+
return this.#wire.deposit(token, new Uint8Array(sub.bytes), this.#egressDid, sub.sentMode);
|
|
460
592
|
}
|
|
461
593
|
catch (e) {
|
|
462
594
|
return Promise.reject(e);
|
|
@@ -507,7 +639,13 @@ export class MediatorCarrierAdapter {
|
|
|
507
639
|
next = { state: 'accepted' };
|
|
508
640
|
}
|
|
509
641
|
catch (e) {
|
|
510
|
-
|
|
642
|
+
let kind = e instanceof WireError ? e.kind : 'unreachable';
|
|
643
|
+
// a validated refusal of the routed form: the relationship switches
|
|
644
|
+
// below, the submission stays in custody as a retriable refusal
|
|
645
|
+
if (kind === 'routed-refused') {
|
|
646
|
+
routedRefused = sub.sentMode === 'routed';
|
|
647
|
+
kind = 'refused-retriable';
|
|
648
|
+
}
|
|
511
649
|
sub.lastKind = kind;
|
|
512
650
|
next = kind === 'oversize'
|
|
513
651
|
? { state: 'failed', reason: 'oversize' }
|
|
@@ -518,6 +656,24 @@ export class MediatorCarrierAdapter {
|
|
|
518
656
|
}
|
|
519
657
|
if (this.#closed)
|
|
520
658
|
return;
|
|
659
|
+
// evidence against routed (RLTP-VTI-3130): the switch, at once
|
|
660
|
+
if (routedRefused)
|
|
661
|
+
this.#switchToEgress();
|
|
662
|
+
// withdrawn meanwhile (app contract rule 5): the late outcome changes nothing
|
|
663
|
+
if (this.#subs.get(sub.id) !== sub)
|
|
664
|
+
return;
|
|
665
|
+
// a document with a digest accepted in routed is an open routed deposit
|
|
666
|
+
// (RLTP-VTI-3130) — only while the relationship is still routed (an
|
|
667
|
+
// attempt begun before a switch opens nothing after it). Acknowledgements
|
|
668
|
+
// and a submit() without a digest open nothing. Answered already (the
|
|
669
|
+
// verdict outran the deposit's resolution): not opened. acceptedAt is the
|
|
670
|
+
// adapter clock when the deposit resolved, not when it was handed over:
|
|
671
|
+
// later by the deposit's own run time
|
|
672
|
+
if (next.state === 'accepted' && sub.sentMode === 'routed' && this.#mode === 'routed' &&
|
|
673
|
+
sub.digest !== undefined && this.#isDocument(sub) && sub.answered !== true &&
|
|
674
|
+
!this.#openDeposits.has(sub.digest)) {
|
|
675
|
+
this.#openDeposits.set(sub.digest, this.#clock);
|
|
676
|
+
}
|
|
521
677
|
// An interim report (including a horizon-corrected one) never
|
|
522
678
|
// outranks the attempt's real outcome; only a TERMINAL state —
|
|
523
679
|
// a give-up, a refusal, a delivery — stands (R5-B1). Without
|
|
@@ -526,6 +682,45 @@ export class MediatorCarrierAdapter {
|
|
|
526
682
|
if (sub.st === null || sub.st.state === 'awaiting-transport')
|
|
527
683
|
sub.st = next;
|
|
528
684
|
}
|
|
685
|
+
#isDocument(sub) {
|
|
686
|
+
return sub.entry === undefined || sub.entry.kind === 'document';
|
|
687
|
+
}
|
|
688
|
+
/** A verdict on a document answers its open routed deposit
|
|
689
|
+
* (RLTP-VTI-3130), if the send state names it at that moment. A verdict
|
|
690
|
+
* before the acceptance marks the submission, so it is not opened
|
|
691
|
+
* afterwards. Acknowledgements are answered by nothing. */
|
|
692
|
+
#answer(sub) {
|
|
693
|
+
if (!this.#isDocument(sub))
|
|
694
|
+
return;
|
|
695
|
+
sub.answered = true;
|
|
696
|
+
if (sub.digest !== undefined)
|
|
697
|
+
this.#openDeposits.delete(sub.digest);
|
|
698
|
+
}
|
|
699
|
+
/** The switch (RLTP-VTI-3130): one way; the open routed deposits leave
|
|
700
|
+
* the send state. */
|
|
701
|
+
#switchToEgress() {
|
|
702
|
+
this.#mode = 'egress-session';
|
|
703
|
+
this.#openDeposits.clear();
|
|
704
|
+
}
|
|
705
|
+
/** The current sending mode of the relationship (profile §3a). */
|
|
706
|
+
get sendMode() { return this.#mode; }
|
|
707
|
+
/** An answer the holder hands this instance for a document an earlier
|
|
708
|
+
* instance deposited (RLTP-VTI-3130): a valid acknowledgement, a
|
|
709
|
+
* validated receiver refusal or a validated `idConflict` answer for
|
|
710
|
+
* `digest`. If the send state names the document as an open routed
|
|
711
|
+
* deposit, it is answered and leaves; otherwise it answers nothing. A
|
|
712
|
+
* no-op on a retired instance, like acknowledged. */
|
|
713
|
+
answered(digest, rawNow) {
|
|
714
|
+
if (this.#closed)
|
|
715
|
+
return;
|
|
716
|
+
this.#now(rawNow);
|
|
717
|
+
this.#openDeposits.delete(digest);
|
|
718
|
+
// a document of this instance whose attempt still runs is answered too:
|
|
719
|
+
// its acceptance after this opens nothing
|
|
720
|
+
for (const sub of this.#subs.values())
|
|
721
|
+
if (sub.digest === digest && this.#isDocument(sub))
|
|
722
|
+
sub.answered = true;
|
|
723
|
+
}
|
|
529
724
|
/** Host teardown aid, NOT a port operation (profile §6): awaits
|
|
530
725
|
* the in-flight background tasks so a host can drain before
|
|
531
726
|
* persisting ackState. On a hanging wire it waits as long as the
|
|
@@ -563,12 +758,18 @@ export class MediatorCarrierAdapter {
|
|
|
563
758
|
}
|
|
564
759
|
return sub.st === null ? null : { ...sub.st };
|
|
565
760
|
}
|
|
761
|
+
/** A valid acknowledgement for submission `id`. Reports that a
|
|
762
|
+
* collection carries are applied before that collection's conclude,
|
|
763
|
+
* at the latest before the next advance: the switch check of
|
|
764
|
+
* RLTP-VTI-3130 counts on them, and a report applied late can let the
|
|
765
|
+
* relationship switch although its deposits were answered. */
|
|
566
766
|
acknowledged(id) {
|
|
567
767
|
if (this.#closed)
|
|
568
768
|
return;
|
|
569
769
|
const sub = this.#subs.get(id);
|
|
570
770
|
if (!sub)
|
|
571
771
|
return;
|
|
772
|
+
this.#answer(sub);
|
|
572
773
|
if (sub.st?.state === 'delivered')
|
|
573
774
|
return; // idempotent: a duplicate ack never rewrites `late` (R9-M4)
|
|
574
775
|
const late = sub.st?.state === 'failed';
|
|
@@ -581,7 +782,9 @@ export class MediatorCarrierAdapter {
|
|
|
581
782
|
* TERMINAL: retryable counterpart conditions (unavailable,
|
|
582
783
|
* internalError) are transport outcomes, never receiver verdicts
|
|
583
784
|
* — they have no entry here, and an unknown code is refused
|
|
584
|
-
* fail-closed rather than minted into a verdict (R6-B2).
|
|
785
|
+
* fail-closed rather than minted into a verdict (R6-B2). Applied, like
|
|
786
|
+
* acknowledged, before the conclude of the collection that carried
|
|
787
|
+
* it (RLTP-VTI-3130). */
|
|
585
788
|
receiverRefused(id, code) {
|
|
586
789
|
if (this.#closed)
|
|
587
790
|
return;
|
|
@@ -591,6 +794,7 @@ export class MediatorCarrierAdapter {
|
|
|
591
794
|
const sub = this.#subs.get(id);
|
|
592
795
|
if (!sub)
|
|
593
796
|
return;
|
|
797
|
+
this.#answer(sub);
|
|
594
798
|
// A VALIDATED refusal is itself the proof of receipt — the
|
|
595
799
|
// mediator can have accepted and forwarded while our deposit
|
|
596
800
|
// promise is still unresolved, so the report-less phase is a
|
|
@@ -625,13 +829,21 @@ export class MediatorCarrierAdapter {
|
|
|
625
829
|
* is transient (Delivery RLTP-DEL-5810, 5820: `failed(rate-limited)`,
|
|
626
830
|
* or a transaction that could not commit, see `concludable`): they are
|
|
627
831
|
* not concluded and not acknowledged, they go back to the buffer and the
|
|
628
|
-
* next collect offers them again, and the mediator keeps its copy.
|
|
832
|
+
* next collect offers them again, and the mediator keeps its copy.
|
|
833
|
+
* The reports the collection carries (acknowledged, receiverRefused,
|
|
834
|
+
* answered) are applied BEFORE this call, at the latest before the next
|
|
835
|
+
* advance: a conclusion that leaves nothing pending opens the switch
|
|
836
|
+
* check of RLTP-VTI-3130, which counts them as applied. */
|
|
629
837
|
conclude(collection, rawNow, opts = {}) {
|
|
630
838
|
this.#open();
|
|
631
839
|
const now = this.#now(rawNow);
|
|
632
840
|
const col = this.#outstanding.get(collection.id);
|
|
633
|
-
if (!col)
|
|
841
|
+
if (!col) {
|
|
842
|
+
// an empty collection is concluded too: it may be the one that leaves nothing pending
|
|
843
|
+
if (collection.id === 'c-empty')
|
|
844
|
+
this.#concludedClean();
|
|
634
845
|
return;
|
|
846
|
+
}
|
|
635
847
|
this.#outstanding.delete(collection.id);
|
|
636
848
|
const keep = new Set(opts.keep ?? []);
|
|
637
849
|
for (const item of col.values()) {
|
|
@@ -646,12 +858,30 @@ export class MediatorCarrierAdapter {
|
|
|
646
858
|
this.#concluded.set(item.queueId, now);
|
|
647
859
|
this.#pendingAcks.add(item.queueId);
|
|
648
860
|
}
|
|
861
|
+
this.#concludedClean();
|
|
649
862
|
this.#startFlush(now);
|
|
650
863
|
}
|
|
864
|
+
/** Nothing pending for this connection: the wire says the mediator
|
|
865
|
+
* holds nothing more (queueEmpty; a wire without it never says so),
|
|
866
|
+
* nothing waits in the buffer, no collection is outstanding. */
|
|
867
|
+
#nothingPending() {
|
|
868
|
+
return this.#wire.queueEmpty?.() === true && this.#inbox.length === 0 && this.#outstanding.size === 0;
|
|
869
|
+
}
|
|
870
|
+
/** After a conclusion (RLTP-VTI-3130): when it left nothing pending,
|
|
871
|
+
* the switch check may run in a later advance. */
|
|
872
|
+
#concludedClean() {
|
|
873
|
+
if (!this.#nothingPending())
|
|
874
|
+
return;
|
|
875
|
+
this.#cleanConcluded = true;
|
|
876
|
+
}
|
|
651
877
|
ackState() {
|
|
652
878
|
return {
|
|
653
879
|
concluded: [...this.#concluded].map(([queueId, concludedAt]) => ({ queueId, concludedAt })),
|
|
654
880
|
pending: [...this.#pendingAcks],
|
|
881
|
+
send: {
|
|
882
|
+
mode: this.#mode,
|
|
883
|
+
open: [...this.#openDeposits].map(([digest, acceptedAt]) => ({ digest, acceptedAt })),
|
|
884
|
+
},
|
|
655
885
|
};
|
|
656
886
|
}
|
|
657
887
|
#startFlush(now) {
|
|
@@ -687,6 +917,11 @@ export class MediatorCarrierAdapter {
|
|
|
687
917
|
// even if no prune has swept it yet — is never sent.
|
|
688
918
|
const live = ids.filter((id) => {
|
|
689
919
|
const at = this.#concluded.get(id);
|
|
920
|
+
// a later copy of it that the holder has not concluded yet (in the
|
|
921
|
+
// buffer or outstanding) is not acknowledged before it is handled:
|
|
922
|
+
// hand off → await → ack; the intent stays for the next flush
|
|
923
|
+
if (this.#inboxDigests.has(id) || [...this.#outstanding.values()].some((c) => c.has(id)))
|
|
924
|
+
return false;
|
|
690
925
|
return at !== undefined && this.#clock - at < DECLARED.duplicateWindowMs;
|
|
691
926
|
});
|
|
692
927
|
if (live.length === 0)
|
|
@@ -727,6 +962,25 @@ export class MediatorCarrierAdapter {
|
|
|
727
962
|
advance(rawNow) {
|
|
728
963
|
this.#open();
|
|
729
964
|
const now = this.#now(rawNow);
|
|
965
|
+
// open routed deposits fall routed-ack-deadline plus duplicate-window
|
|
966
|
+
// after their acceptance, also where no switch check can run (no
|
|
967
|
+
// statement that nothing is pending, RLTP-VTI-7150)
|
|
968
|
+
for (const [digest, at] of this.#openDeposits)
|
|
969
|
+
if (now - at >= OPEN_KEEP_MS)
|
|
970
|
+
this.#openDeposits.delete(digest);
|
|
971
|
+
// the switch (RLTP-VTI-3130): only after a conclusion that left nothing
|
|
972
|
+
// pending and while nothing is pending again at the check (an
|
|
973
|
+
// acknowledgement that arrived since is collected and reported first),
|
|
974
|
+
// when an open routed deposit is a deadline old — one way; checked
|
|
975
|
+
// before the retries below, which hand over in the new mode
|
|
976
|
+
if (this.#mode === 'routed' && this.#cleanConcluded && this.#nothingPending()) {
|
|
977
|
+
for (const acceptedAt of this.#openDeposits.values()) {
|
|
978
|
+
if (now - acceptedAt >= DECLARED.routedAckDeadlineMs) {
|
|
979
|
+
this.#switchToEgress();
|
|
980
|
+
break;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
}
|
|
730
984
|
for (const sub of this.#subs.values()) {
|
|
731
985
|
const live = sub.st === null || sub.st.state === 'awaiting-transport' || sub.st.state === 'accepted';
|
|
732
986
|
if (!live)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vti-mediator.js","sourceRoot":"","sources":["../../src/adapters/vti-mediator.ts"],"names":[],"mappings":"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","sourcesContent":["// RLTP transport adapter: VTI mediator — published as\n// @real-life/trust-protocol/adapters/vti-mediator (lib Stage 2, note §4.6).\n//\n// It takes the holder's documents from the holder's custody (Delivery 0.83\n// RLTP-DEL-6120 to 6135, lib 0.6.0): reconcile(view, gate, now) files every\n// entry of holder.pendingTransport(when) not yet filed, and withdraws every\n// filed submission still before the trias whose digest the view no longer\n// names — a missing entry means stop, never keep sending. Before every\n// deposit it asks gate.mayHandOver(entry, now) (the holder): false\n// withdraws the submission, an error skips the attempt. It keeps no\n// custody of its own: its copies are volatile and bound to the holder's\n// opening: bound to the holder of its first reconcile, it refuses another,\n// so after holder.close() nothing it holds goes out, and the next opening\n// gets a new adapter (restored from ackState like any other). Its give-up horizon counts\n// from the entry's first submission (`since`), never from when it took the\n// entry over (RLTP-DEL-6130). Its reports reach the holder as the ports'\n// DeliveryReport: report(id) maps the adapter's SubmissionState onto\n// DeliveryReport (deliveryReportOf), keyed by the document digest, which\n// the app hands to holder.report(). An adapter's `delivered` is its claim\n// about transport; the holder's receive core verifies the delivery-ack\n// itself.\n//\n// Profile: spec/adapter-vti-mediator.md v0.23 (twenty-third casting;\n// round journals under design/adapter-review*). A\n// transport adapter contract — NOT a carrier at the port.\n//\n// Beyond the profile (lib 0.5.0): conclude(collection, now, {keep}) leaves\n// the items whose disposition is transient unconcluded and offers them\n// again (Delivery 0.82 RLTP-DEL-5810, 5820: failed(rate-limited) is never\n// concluded); `concludable(result)` says which receive outcomes are\n// terminal. The profile's §4 concludes a collection whole; its next\n// casting is to take this up.\n//\n// Structural rules (reviews 3+4):\n// · No port operation ever awaits the mediator — including\n// register: keylist synchronization is a recorded intent with a\n// tracked background task, retried by advance.\n// · No report is invented, and absence is ABSENT: before the first\n// honest report exists, status() returns null (§6.1 grants the\n// window; representing it as a queryable fourth value was\n// review-4 B2). has() distinguishes an unknown id.\n// · A retired instance mutates nothing and refuses everything\n// except reading its ack state.\n\nimport { jcs } from '../core.js'\nimport { sha } from '../crypto.js'\nimport { carrierPrincipal, carrierScopedIdentity } from '../carrier-identity.js'\nimport type { CarrierPrincipal, CarrierScopedIdentity } from '../carrier-identity.js'\nimport type { DeliveryReport, ReceiverRefusalCode, SubmissionRef } from '../ports.js'\nimport type { TransportEntry, TransportView } from '../engine.js'\nimport type { ReceiveResult } from '../results.js'\nexport type { ReceiverRefusalCode } from '../ports.js'\n\n// ── Declared constants (profile §2) — promises of THIS casting ──────\n// frozen: the declared promises cannot be changed at run time either\nexport const DECLARED = Object.freeze({\n giveUpHorizonMs: 72 * 3_600_000,\n statusHorizonMs: 60_000,\n queueFloorCount: 64,\n queueFloorBytes: 1_048_576,\n maxQueueBytes: 16_777_216,\n duplicateWindowMs: 30 * 86_400_000,\n} as const)\n\n// ── The injected wire ────────────────────────────────────────────────\nexport type WireErrorKind =\n | 'unreachable' | 'refused-retriable' | 'refused-admission' | 'oversize'\n\nexport class WireError extends Error {\n kind: WireErrorKind\n constructor (kind: WireErrorKind, message?: string) {\n super(message ?? kind)\n this.kind = kind\n }\n}\n\nexport interface MediatorWire {\n authChallenge (did: string): Promise<{ challenge: string, sessionId: string }>\n authenticate (answer: { did: string, challenge: string, sessionId: string }): Promise<TokenSet>\n // A transient failure MUST be a WireError 'unreachable' or\n // 'refused-retriable' (the tokens are kept); any other error means the\n // mediator refused the refresh token (the adapter re-runs the handshake).\n refresh (refreshToken: string): Promise<TokenSet>\n keylistUpdate (accessToken: string, rkids: string[]): Promise<void>\n deposit (accessToken: string, bytes: Uint8Array, egressDid: string): Promise<void>\n ackReceived (accessToken: string, queueIds: string[]): Promise<void>\n onDeliver (cb: (bytes: Uint8Array) => Promise<void>): void\n /** Optional truthful connectivity signal; absent means unknown. */\n offline? (): boolean\n}\n\nexport interface TokenSet {\n accessToken: string\n accessExpiresAt: number\n refreshToken: string\n refreshExpiresAt: number\n}\n\n// ── Sender states (§6.1 — the closed sets, nothing else) ────────────\n// ReceiverRefusalCode is the ports' (one closed set, one place)\nconst RECEIVER_REFUSAL_CODES: ReadonlySet<ReceiverRefusalCode> = new Set<ReceiverRefusalCode>([\n 'malformedRequest', 'unsupportedType', 'proofRequired',\n 'proofInvalid', 'wrongRecipient', 'identityMismatch',\n])\n\nexport type SubmissionState =\n | { state: 'awaiting-transport', reason: 'offline' | 'transport-unreachable' | 'carrier-refused-retriable' }\n | { state: 'accepted' }\n | { state: 'delivered', late: boolean }\n | { state: 'failed', reason: 'unroutable' | 'oversize' | 'expired-by-adapter-policy' }\n | { state: 'failed', reason: 'rejected-by-receiver', code: ReceiverRefusalCode }\n\n/** The ports' DeliveryReport for a document `digest` in adapter state `st`\n * (Delivery §6.1): one-to-one, `late` and the refusal code carried over. */\nexport function deliveryReportOf (digest: string, st: SubmissionState): DeliveryReport {\n switch (st.state) {\n case 'awaiting-transport': return { digest, status: 'awaiting-transport', reason: st.reason }\n case 'accepted': return { digest, status: 'accepted' }\n case 'delivered': return { digest, status: 'delivered', late: st.late }\n case 'failed': return st.reason === 'rejected-by-receiver'\n ? { digest, status: 'failed', reason: 'rejected-by-receiver', code: st.code }\n : { digest, status: 'failed', reason: st.reason }\n }\n}\n\n/** Whether a receive outcome is terminal and its item may be concluded\n * (Delivery 5a.8): every disposition but `failed(rate-limited)`, the one\n * failure that is transient (RLTP-DEL-5820). An InfraError of the\n * holder's store is transient as well (RLTP-DEL-5810): an item whose\n * receive threw is kept, too. */\nexport function concludable (r: ReceiveResult): boolean {\n return !(r.disposition === 'failed' && r.reason === 'rate-limited')\n}\n\n/** The adapter's own copy of a wire's token set: the wire keeps no handle on it. */\nconst tokenCopy = (t: TokenSet): TokenSet => ({ accessToken: t.accessToken, accessExpiresAt: t.accessExpiresAt, refreshToken: t.refreshToken, refreshExpiresAt: t.refreshExpiresAt })\n\nexport interface CollectedItem { bytes: Uint8Array, queueId: string }\nexport interface Collection { id: string, items: CollectedItem[] }\n\n/** Ack state for the host to persist (profile §4). Invariant: every\n * pending id names a concluded entry; violations are refused at\n * construction (fail-closed). */\nexport interface AckState {\n concluded: Array<{ queueId: string, concludedAt: number }>\n pending: string[]\n}\n\n/** The holder's side of a hand-over (lib 0.6.0): the holder itself.\n * handOver checks the entry and calls `start` inside the holder's queue;\n * `start` re-checks the adapter's own state, starts the deposit\n * synchronously and says whether it did. `closed` is read in `start`. */\nexport interface TransportGate {\n handOver (entry: TransportEntry, when: number, start: () => boolean): Promise<boolean>\n readonly closed?: boolean\n}\n\ninterface Submission {\n id: string\n /** the document digest, for submissions filed by reconcile */\n digest?: string\n /** the holder's entry and its gate, for submissions filed by reconcile */\n entry?: TransportEntry\n gate?: TransportGate\n bytes: Uint8Array\n submittedAt: number\n attemptStartedAt: number | null\n lastKind: WireErrorKind | null\n st: SubmissionState | null // null = no honest report exists yet\n}\n\nconst hex = (b: Uint8Array): string =>\n Array.from(b, (x) => x.toString(16).padStart(2, '0')).join('')\n\n// construction capability: only create() holds it\nconst KEY = Symbol('MediatorCarrierAdapter.create')\n\n// ── The adapter ──────────────────────────────────────────────────────\nexport class MediatorCarrierAdapter {\n // JS-hard identity fields: TS `readonly` is a compile-time promise\n // only, and §8 claims runtime unforgeability — so the values live\n // in true privates behind getters (R8-B1)\n #principal: string\n #connectionDid: string\n #egressDid: string\n get principal (): string { return this.#principal }\n get connectionDid (): string { return this.#connectionDid }\n get egressDid (): string { return this.#egressDid }\n #wire: MediatorWire\n #tokens: TokenSet | null = null\n #clock = Number.NEGATIVE_INFINITY\n #closed = false\n /** the opening this adapter serves, bound at its first reconcile */\n #gate: TransportGate | null = null\n\n #subs = new Map<string, Submission>()\n #inflight = new Set<Promise<void>>()\n #nextId = 1\n\n #desiredRkids: string[] | null = null\n #keylistSynced = false\n #keylistSyncing = false\n\n #inbox: CollectedItem[] = []\n #inboxBytes = 0\n #inboxDigests = new Set<string>()\n #outstanding = new Map<string, Map<string, CollectedItem>>()\n #outstandingBytes = 0\n #concluded = new Map<string, number>()\n #pendingAcks = new Set<string>()\n #flightAcks = new Set<string>() // ids inside the in-flight flush snapshot\n #flushing = false\n #nextColId = 1\n\n #transitions: Array<{ id: string, to: 'delivered' }> = []\n\n /** The only way to build an adapter: the trio is DERIVED here from\n * one root, one carrier, one nonce — so principal, connection DID\n * and egress identity cannot come from different relationships\n * (R7-B2: the coupling is enforced by construction, not by\n * inspecting caller-supplied identities). */\n static async create (\n rootIkm: Uint8Array, carrier: string, nonce: Uint8Array,\n wire: MediatorWire, restored?: AckState, restoredAt?: number,\n ): Promise<MediatorCarrierAdapter> {\n // ONE tuple, snapshotted at entry: a caller mutating its buffers\n // between the three awaited derivations must not be able to mix\n // identities from two tuples (R8-B2)\n const ikm = new Uint8Array(rootIkm)\n const n = new Uint8Array(nonce)\n const principal = await carrierPrincipal(ikm, carrier, n)\n const connection = await carrierScopedIdentity(ikm, carrier, n, 'connection')\n const egress = await carrierScopedIdentity(ikm, carrier, n, 'egress')\n return new MediatorCarrierAdapter(KEY, principal, connection, egress, wire, restored, restoredAt)\n }\n\n constructor (\n key: symbol,\n principal: CarrierPrincipal,\n connection: CarrierScopedIdentity,\n egress: CarrierScopedIdentity,\n wire: MediatorWire,\n restored?: AckState,\n restoredAt?: number,\n ) {\n if (key !== KEY) {\n throw new Error('use MediatorCarrierAdapter.create — the identity trio must be derived, not supplied (5a.10)')\n }\n if (connection.scope !== 'connection' || egress.scope !== 'egress') {\n throw new Error('scoped identities passed in the wrong roles')\n }\n const three = new Set([principal.principal, connection.did, egress.did])\n if (three.size !== 3) {\n throw new Error('principal, connection DID and egress identity must be pairwise distinct (5a.10)')\n }\n this.#principal = principal.principal\n this.#connectionDid = connection.did\n this.#egressDid = egress.did\n this.#wire = wire\n if (restored) {\n // The restore instant anchors the duplicate-window: an expired,\n // debt-free entry is dropped HERE, not at the first advance —\n // otherwise a redelivery arriving before any port call would be\n // absorbed beyond the declared window (review-4 B4).\n if (typeof restoredAt !== 'number' || !Number.isFinite(restoredAt)) {\n throw new Error('restoring ack state requires a finite restoredAt instant')\n }\n this.#now(restoredAt)\n const pending = new Set(restored.pending)\n const known = new Set(restored.concluded.map((c) => c.queueId))\n for (const id of pending) {\n if (!known.has(id)) {\n throw new Error('ack snapshot violates its invariant: pending intent without a concluded entry')\n }\n }\n for (const { queueId, concludedAt } of restored.concluded) {\n if (!Number.isFinite(concludedAt) || concludedAt > restoredAt) {\n // a conclusion \"from the future\" would stretch the window\n // past its declared span (R5-B4) — fail closed\n throw new Error('ack snapshot: conclusion instant is non-finite or after restoredAt')\n }\n // the window beats everything (round-14 B): an expired entry\n // falls at the restore instant, owed or not — a phantom debt\n // from an ack that landed just before a close can never\n // outlive the window and delete a fresh copy (R14-B2)\n if (restoredAt - concludedAt >= DECLARED.duplicateWindowMs) continue\n this.#concluded.set(queueId, concludedAt)\n if (pending.has(queueId)) this.#pendingAcks.add(queueId)\n }\n }\n this.#wire.onDeliver(async (raw) => {\n if (this.#closed) return\n // a plain copy of its own: a Node Buffer's slice() would share memory\n const bytes = new Uint8Array(raw)\n const queueId = hex(await sha(bytes))\n if (this.#closed) return\n // Absorption is WINDOW-checked at the moment it happens\n // (R11-B1), and the window beats everything (round-14 B):\n // beyond it, entry AND any leftover intent fall, and the frame\n // is a new item — so no acknowledgement, owed or phantom, can\n // ever delete the only fresh copy.\n const concludedAt = this.#concluded.get(queueId)\n if (concludedAt !== undefined) {\n if (this.#flightAcks.has(queueId) ||\n this.#clock - concludedAt < DECLARED.duplicateWindowMs) {\n // inside the window — or deferred: an id inside an\n // in-flight flush keeps absorbing until that flush ends,\n // because its irrecallable ack may still land (R15-B1)\n this.#pendingAcks.add(queueId)\n return\n }\n this.#concluded.delete(queueId)\n this.#pendingAcks.delete(queueId)\n }\n if (this.#inboxDigests.has(queueId)) return\n for (const col of this.#outstanding.values()) if (col.has(queueId)) return\n const held = this.#inboxBytes + this.#outstandingBytes\n const underFloor = this.#inbox.length < DECLARED.queueFloorCount &&\n held + bytes.length <= DECLARED.queueFloorBytes\n const underCap = held + bytes.length <= DECLARED.maxQueueBytes\n if (!underFloor && !underCap) return\n this.#inbox.push({ bytes, queueId })\n this.#inboxBytes += bytes.length\n this.#inboxDigests.add(queueId)\n })\n }\n\n #now (raw: number): number {\n if (!Number.isFinite(raw)) throw new Error('non-finite time')\n if (raw > this.#clock) this.#clock = raw\n return this.#clock\n }\n\n #open (): void { if (this.#closed) throw new Error('retired (5a.10 lifecycle)') }\n\n #track (p: Promise<void>): void {\n const t = p.catch(() => {})\n this.#inflight.add(t)\n void t.finally(() => this.#inflight.delete(t))\n }\n\n // ── auth: silent carrier policy ─────────────────────────────────\n // Single-flight: concurrent callers share one handshake — the ATM\n // challenge/response is a session, and two interleaved sessions\n // under one connection DID would answer each other's challenges.\n #authing: Promise<string> | null = null\n\n #ensureAuth (now: number): Promise<string> {\n if (this.#tokens && now < this.#tokens.accessExpiresAt) return Promise.resolve(this.#tokens.accessToken)\n if (this.#authing) return this.#authing\n const run = (async (): Promise<string> => {\n if (this.#tokens && now < this.#tokens.refreshExpiresAt) {\n try {\n const refreshed = await this.#wire.refresh(this.#tokens.refreshToken)\n if (this.#closed) throw new Error('retired') // as on the handshake path (R6-B1)\n this.#tokens = tokenCopy(refreshed)\n return this.#tokens.accessToken\n } catch (e) {\n if (this.#closed) throw e\n // a transient failure (mediator unreachable, retriable refusal)\n // says nothing about the token: keep it for the next attempt (#9)\n if (e instanceof WireError && (e.kind === 'unreachable' || e.kind === 'refused-retriable')) throw e\n // a refused refresh (revoked before its expiry) is never replayed:\n // drop the tokens and take the challenge handshake below\n this.#tokens = null\n }\n }\n const { challenge, sessionId } = await this.#wire.authChallenge(this.#connectionDid)\n if (this.#closed) throw new Error('retired') // nothing new starts, not even the answer (R6-B1)\n this.#tokens = tokenCopy(await this.#wire.authenticate({ did: this.#connectionDid, challenge, sessionId }))\n return this.#tokens.accessToken\n })()\n this.#authing = run.finally(() => { this.#authing = null })\n return this.#authing\n }\n\n // ── transport registration (profile §3 — NOT §5a.3) ─────────────\n /** Records the desired keylist and returns; synchronization runs\n * as a tracked background task and advance retries it until it\n * lands (review-4 B1). */\n register (rkids: string[], rawNow: number): void {\n this.#open()\n const now = this.#now(rawNow)\n this.#desiredRkids = [...rkids]\n this.#keylistSynced = false\n this.#startKeylistSync(now)\n }\n\n get keylistSynced (): boolean {\n this.#open()\n return this.#keylistSynced\n }\n\n #startKeylistSync (now: number): void {\n if (this.#keylistSyncing || this.#keylistSynced || this.#desiredRkids === null) return\n this.#keylistSyncing = true\n const wanted = [...this.#desiredRkids]\n this.#track((async () => {\n try {\n const token = await this.#ensureAuth(now)\n if (this.#closed) return\n await this.#wire.keylistUpdate(token, [...wanted]) // the wire's own list: `wanted` is compared below\n // land only if the desire has not moved meanwhile\n if (!this.#closed && this.#desiredRkids !== null &&\n wanted.join(' ') === this.#desiredRkids.join(' ')) {\n this.#keylistSynced = true\n }\n } catch {\n // intent survives; advance retries\n } finally {\n this.#keylistSyncing = false\n }\n })())\n }\n\n // ── sender side ─────────────────────────────────────────────────\n /** Returns the submission id synchronously. Before the first\n * honest report exists, status() returns null — §6.1's own\n * pre-report window, represented as absence, not as a value. */\n submit (envelopeBytes: Uint8Array, rawNow: number): string {\n this.#open()\n const now = this.#now(rawNow)\n const id = 's' + this.#nextId++\n const knownOffline = this.#wire.offline?.() === true\n const sub: Submission = {\n id,\n // a plain copy of its own (a Node Buffer's slice() shares memory)\n bytes: new Uint8Array(envelopeBytes),\n submittedAt: now,\n attemptStartedAt: null,\n lastKind: null,\n st: null,\n }\n this.#subs.set(id, sub)\n if (!knownOffline) this.#startAttempt(sub, now)\n return id\n }\n\n /** Takes the holder's custody set (holder.pendingTransport, after a\n * resume of this opening) and the holder as the gate: files every entry\n * not yet filed under its digest (its envelope as JCS bytes; the give-up\n * horizon from entry.since) and returns their SubmissionRefs; withdraws\n * every filed submission still before the trias (no report, or\n * awaiting-transport) whose digest the view does not name. Accepted and\n * terminal submissions stay for their reports. */\n reconcile (view: TransportView, gate: TransportGate, rawNow: number): SubmissionRef[] {\n this.#open()\n if (view?.ok !== true || !Array.isArray(view.entries)) throw new Error('reconcile needs a view of holder.pendingTransport')\n if (typeof gate?.handOver !== 'function') throw new Error('reconcile needs the holder as its gate')\n // one adapter per opening: its copies and the holder's grants belong to\n // that opening, and the next opening gets an adapter of its own\n if (this.#gate === null) this.#gate = gate\n else if (this.#gate !== gate) throw new Error('one adapter per opening: this adapter reconciles with another holder (create a new adapter for the next opening)')\n const now = this.#now(rawNow)\n // a submission's key: the digest, and for a duplicate's answer its\n // grant too — the retries and each answer are hand-overs of their own\n const keyOf = (digest: string, resend: number | undefined): string => resend === undefined ? digest : `${digest}#${resend}`\n const named = new Set(view.entries.map((e) => keyOf(e.digest, e.resend)))\n const filed = new Map<string, Submission>()\n for (const [id, sub] of this.#subs) {\n if (sub.digest === undefined) continue\n const key = keyOf(sub.digest, sub.entry?.resend)\n const before = sub.st === null || sub.st.state === 'awaiting-transport'\n if (before && !named.has(key)) { this.#subs.delete(id); continue }\n filed.set(key, sub)\n }\n const refs: SubmissionRef[] = []\n for (const entry of view.entries) {\n const had = filed.get(keyOf(entry.digest, entry.resend))\n if (had !== undefined) {\n // the newest entry of a live submission is the one its gate checks\n if (had.st === null || had.st.state === 'awaiting-transport') { had.entry = entry; had.gate = gate; continue }\n // an answer the holder still offers is still owed — its hand-over\n // never began, or the holder could not record that it did: a\n // terminal submission of it is filed again (the holder ends it)\n if (entry.resend === undefined) continue\n this.#subs.delete(had.id)\n }\n const id = 's' + this.#nextId++\n const sub: Submission = {\n id, digest: entry.digest, entry, gate,\n bytes: new TextEncoder().encode(jcs(entry.envelope)),\n // a duplicate's ack is a hand-over of its own, from now\n submittedAt: entry.resend !== undefined ? now : Math.min(entry.since, now),\n attemptStartedAt: null, lastKind: null, st: null,\n }\n this.#subs.set(id, sub)\n refs.push({ submissionId: id, digest: entry.digest })\n // taken over past its horizon (counted from the first submission,\n // RLTP-DEL-6130): given up at once, never attempted\n if (now - sub.submittedAt >= DECLARED.giveUpHorizonMs) { sub.st = { state: 'failed', reason: 'expired-by-adapter-policy' }; continue }\n if (this.#wire.offline?.() !== true) this.#startAttempt(sub, now)\n }\n return refs\n }\n\n /** The current state as the ports' DeliveryReport for holder.report(),\n * or null while no honest report exists (and for an unknown id). A\n * submission filed without a digest (submit) has no report form. */\n report (id: string): DeliveryReport | null {\n const st = this.status(id)\n if (st === null) return null\n const digest = this.#subs.get(id)!.digest\n if (digest === undefined) throw new Error('submitted without a document digest: file holder documents through reconcile')\n return deliveryReportOf(digest, st)\n }\n\n has (id: string): boolean {\n this.#open()\n return this.#subs.has(id)\n }\n\n #startAttempt (sub: Submission, now: number): void {\n if (sub.attemptStartedAt !== null) return\n sub.attemptStartedAt = now\n this.#track(this.#trySend(sub, now).finally(() => { sub.attemptStartedAt = null }))\n }\n\n async #trySend (sub: Submission, now: number): Promise<void> {\n if (sub.st !== null && sub.st.state !== 'awaiting-transport') return\n let next: SubmissionState\n try {\n const token = await this.#ensureAuth(now)\n if (this.#closed) return // retirement between auth and deposit: nothing new starts (R5-B2)\n // each attempt hands the wire a copy: what it does with it never reaches the next\n const deposit = (): Promise<void> => {\n try { return this.#wire.deposit(token, new Uint8Array(sub.bytes), this.#egressDid) } catch (e) { return Promise.reject(e) }\n }\n if (sub.gate !== undefined) {\n // the holder decides, and the deposit starts in the same step of its\n // queue (Delivery RLTP-DEL-6125 to 6135); the adapter re-checks its\n // own state there: retired, withdrawn, past the trias, past the\n // entry's deadline or its own horizon → no deposit\n // the deposit's outcome, caught at once: the holder's step may still\n // be committing when the wire answers\n let started: Promise<unknown> | null = null\n let declined = false\n const entry = sub.entry!\n const start = (): boolean => {\n if (this.#closed || this.#subs.get(sub.id) !== sub || sub.gate!.closed === true ||\n (sub.st !== null && sub.st.state !== 'awaiting-transport') || this.#clock >= entry.notAfter ||\n this.#clock - sub.submittedAt >= DECLARED.giveUpHorizonMs) { declined = true; return false }\n started = deposit().then(() => null, (e: unknown) => ({ failed: e }))\n return true\n }\n let ok: boolean | null\n try { ok = await sub.gate.handOver(entry, this.#clock, start) } catch { ok = null }\n if (started === null) {\n // the holder said no: withdrawn; the adapter declined or the\n // holder was unreachable: not this attempt\n if (ok === false && !declined && this.#subs.get(sub.id) === sub) this.#subs.delete(sub.id)\n return\n }\n const outcome = await (started as Promise<unknown>)\n if (outcome !== null) throw (outcome as { failed: unknown }).failed\n } else {\n await deposit()\n }\n sub.lastKind = null\n next = { state: 'accepted' }\n } catch (e) {\n const kind: WireErrorKind = e instanceof WireError ? e.kind : 'unreachable'\n sub.lastKind = kind\n next = kind === 'oversize'\n ? { state: 'failed', reason: 'oversize' }\n : {\n state: 'awaiting-transport',\n reason: kind === 'unreachable' ? 'transport-unreachable' : 'carrier-refused-retriable',\n }\n }\n if (this.#closed) return\n // An interim report (including a horizon-corrected one) never\n // outranks the attempt's real outcome; only a TERMINAL state —\n // a give-up, a refusal, a delivery — stands (R5-B1). Without\n // this, an accepted deposit would stay reported unreachable and\n // be sent a second time.\n if (sub.st === null || sub.st.state === 'awaiting-transport') sub.st = next\n }\n\n /** Host teardown aid, NOT a port operation (profile §6): awaits\n * the in-flight background tasks so a host can drain before\n * persisting ackState. On a hanging wire it waits as long as the\n * wire does — a host bounds it externally (Promise.race) exactly\n * because this library holds no clock of its own. */\n async settle (): Promise<void> {\n while (this.#inflight.size > 0) await Promise.all([...this.#inflight])\n }\n\n /** The §6.1 report, or null while none exists yet (has()\n * distinguishes an unknown id). status is a PORT: after close it\n * refuses like every other port operation (R5-B3).\n *\n * The pre-transport report is an HONEST SNAPSHOT, derived at the\n * moment of observation by one precedence order (Option B of the\n * round-14 halt) — never a stored patchwork:\n * (a) the wire knows itself offline → offline\n * (b) an attempt is overdue → transport-unreachable\n * (c) the last completed attempt's kind → its report\n * (d) otherwise → no report yet (null)\n * Terminal states and `accepted` are stored and stand. */\n status (id: string): SubmissionState | null {\n this.#open()\n const sub = this.#subs.get(id)\n if (!sub) return null\n if (sub.st !== null && sub.st.state !== 'awaiting-transport') return { ...sub.st }\n if (this.#wire.offline?.() === true) {\n return { state: 'awaiting-transport', reason: 'offline' }\n }\n if (sub.attemptStartedAt !== null &&\n this.#clock - sub.attemptStartedAt >= DECLARED.statusHorizonMs) {\n return { state: 'awaiting-transport', reason: 'transport-unreachable' }\n }\n return sub.st === null ? null : { ...sub.st }\n }\n\n acknowledged (id: string): void {\n if (this.#closed) return\n const sub = this.#subs.get(id)\n if (!sub) return\n if (sub.st?.state === 'delivered') return // idempotent: a duplicate ack never rewrites `late` (R9-M4)\n const late = sub.st?.state === 'failed'\n sub.st = { state: 'delivered', late }\n if (late) this.#transitions.push({ id, to: 'delivered' })\n }\n\n /** Refusals act on live submissions only (§6.1 knows exactly one\n * late correction — the valid ack). The code set is closed and\n * TERMINAL: retryable counterpart conditions (unavailable,\n * internalError) are transport outcomes, never receiver verdicts\n * — they have no entry here, and an unknown code is refused\n * fail-closed rather than minted into a verdict (R6-B2). */\n receiverRefused (id: string, code: ReceiverRefusalCode): void {\n if (this.#closed) return\n if (!RECEIVER_REFUSAL_CODES.has(code)) {\n throw new Error('not a terminal receiver refusal code — retryable conditions are transport outcomes')\n }\n const sub = this.#subs.get(id)\n if (!sub) return\n // A VALIDATED refusal is itself the proof of receipt — the\n // mediator can have accepted and forwarded while our deposit\n // promise is still unresolved, so the report-less phase is a\n // legitimate moment for it (R9-B2, reversing the R8-B3\n // overcorrection). Only terminal states stand against it.\n if (sub.st !== null && sub.st.state !== 'awaiting-transport' && sub.st.state !== 'accepted') return\n sub.st = { state: 'failed', reason: 'rejected-by-receiver', code }\n }\n\n drainTransitions (): Array<{ id: string, to: 'delivered' }> {\n this.#open()\n return this.#transitions.splice(0)\n }\n\n // ── receiver side ───────────────────────────────────────────────\n collect (rawNow: number): Collection {\n this.#open()\n this.#now(rawNow)\n if (this.#inbox.length === 0) return { id: 'c-empty', items: [] }\n const items = this.#inbox.splice(0)\n this.#outstandingBytes += this.#inboxBytes\n this.#inboxBytes = 0\n this.#inboxDigests.clear()\n const id = 'c' + this.#nextColId++\n this.#outstanding.set(id, new Map(items.map((i) => [i.queueId, i])))\n // the caller gets its own copies: the outstanding entries stay intact,\n // whatever it does with the bytes, for a conclusion that keeps them\n return { id, items: items.map((i) => ({ ...i, bytes: new Uint8Array(i.bytes) })) }\n }\n\n /** Concludes a collection (profile §4, Delivery 5a.8): its items'\n * digests become ack intent. `keep` names the items whose disposition\n * is transient (Delivery RLTP-DEL-5810, 5820: `failed(rate-limited)`,\n * or a transaction that could not commit, see `concludable`): they are\n * not concluded and not acknowledged, they go back to the buffer and the\n * next collect offers them again, and the mediator keeps its copy. */\n conclude (collection: { id: string }, rawNow: number, opts: { keep?: readonly string[] } = {}): void {\n this.#open()\n const now = this.#now(rawNow)\n const col = this.#outstanding.get(collection.id)\n if (!col) return\n this.#outstanding.delete(collection.id)\n const keep = new Set(opts.keep ?? [])\n for (const item of col.values()) {\n this.#outstandingBytes -= item.bytes.length\n if (keep.has(item.queueId)) {\n // transient: back to the buffer, offered again, never acknowledged\n this.#inbox.push(item)\n this.#inboxBytes += item.bytes.length\n this.#inboxDigests.add(item.queueId)\n continue\n }\n this.#concluded.set(item.queueId, now)\n this.#pendingAcks.add(item.queueId)\n }\n this.#startFlush(now)\n }\n\n ackState (): AckState {\n return {\n concluded: [...this.#concluded].map(([queueId, concludedAt]) => ({ queueId, concludedAt })),\n pending: [...this.#pendingAcks],\n }\n }\n\n #startFlush (now: number): void {\n if (this.#flushing || this.#pendingAcks.size === 0) return\n this.#flushing = true\n const snapshot = new Set(this.#pendingAcks)\n this.#track(this.#flushAcks(now, [...snapshot]).finally(() => {\n this.#flushing = false\n // lost-wake-up guard (review-4 M6): intents that arrived while\n // this flush ran get their own flush now — but only newcomers,\n // so a failing wire waits for the next advance instead of\n // spinning\n if (!this.#closed) {\n for (const id of this.#pendingAcks) {\n if (!snapshot.has(id)) { this.#startFlush(this.#clock); break }\n }\n }\n }))\n }\n\n async #flushAcks (now: number, ids: string[]): Promise<void> {\n try {\n const token = await this.#ensureAuth(now)\n if (this.#closed) return\n // Only NOW does anything become irrecallable (R16-B1): the\n // stay of expiry begins at the wire call itself, never at the\n // snapshot — a hanging auth extends no window. And \"live\" is\n // WINDOW-live (R17-B1): an entry whose window already closed —\n // even if no prune has swept it yet — is never sent.\n const live = ids.filter((id) => {\n const at = this.#concluded.get(id)\n return at !== undefined && this.#clock - at < DECLARED.duplicateWindowMs\n })\n if (live.length === 0) return\n for (const id of live) this.#flightAcks.add(id)\n try {\n // the wire gets its own list: what it does with it never reaches the bookkeeping below\n await this.#wire.ackReceived(token, [...live])\n if (!this.#closed) for (const id of live) this.#pendingAcks.delete(id)\n } finally {\n for (const id of live) this.#flightAcks.delete(id)\n // deferred window sweep: entries whose window closed while\n // the ack flew fall now — intent, entry and absorption\n // together (R15-B1). Never on a retired instance: after\n // close, ackState() is the host's final-persist surface and\n // a late-returning wire mutates nothing (R17-B2).\n if (!this.#closed) {\n for (const id of live) {\n const at = this.#concluded.get(id)\n if (at !== undefined && this.#clock - at >= DECLARED.duplicateWindowMs) {\n this.#concluded.delete(id)\n this.#pendingAcks.delete(id)\n }\n }\n }\n }\n } catch {\n // intent survives; the next advance starts a fresh flush\n }\n }\n\n // ── the adapter clock — never awaits the mediator ───────────────\n advance (rawNow: number): void {\n this.#open()\n const now = this.#now(rawNow)\n for (const sub of this.#subs.values()) {\n const live = sub.st === null || sub.st.state === 'awaiting-transport' || sub.st.state === 'accepted'\n if (!live) continue\n if (now - sub.submittedAt >= DECLARED.giveUpHorizonMs) {\n // unroutable only when the LAST COMPLETED attempt was an\n // admission refusal and no attempt is in flight whose outcome\n // is unknown (review-4 B3)\n // the give-up verdict applies the SAME precedence as every\n // observation (R17-B3): a wire that knows itself offline at\n // the horizon outranks any stored refusal class — unroutable\n // needs a completed admission refusal, no unknown outcome in\n // flight, AND no offline signal standing over it\n sub.st = {\n state: 'failed',\n reason: sub.lastKind === 'refused-admission' && sub.attemptStartedAt === null &&\n this.#wire.offline?.() !== true\n ? 'unroutable'\n : 'expired-by-adapter-policy',\n }\n continue\n }\n if (sub.st !== null && sub.st.state === 'accepted') continue\n // reports are DERIVED at observation (see status()); the clock\n // only decides here whether to start an attempt — and never\n // against a wire that knows itself offline\n if (this.#wire.offline?.() === true) continue\n if (sub.attemptStartedAt === null) this.#startAttempt(sub, now)\n }\n // THE WINDOW BEATS EVERYTHING (Option B of the round-14 halt):\n // an ack intent is retried until the window closes; then intent\n // and absorption fall together. There is no ageless debt whose\n // truth the adapter would have to know — the receiver's §6.2\n // absorption owns everything beyond the window.\n for (const [digest, at] of this.#concluded) {\n if (now - at >= DECLARED.duplicateWindowMs && !this.#flightAcks.has(digest)) {\n this.#concluded.delete(digest)\n this.#pendingAcks.delete(digest)\n }\n }\n this.#startKeylistSync(now)\n this.#startFlush(now)\n }\n\n /** §5a.10 lifecycle boundary: after close, every state port is\n * inert — port operations refuse, inbound reports (acknowledged,\n * receiverRefused) are no-ops, late wire resolutions mutate\n * nothing. Only ackState() stays readable for the host's final\n * persist. */\n close (): void { this.#closed = true }\n\n get closed (): boolean { return this.#closed }\n}\n\nexport const queueIdOf = async (bytes: Uint8Array): Promise<string> => hex(await sha(bytes))\n"]}
|
|
1
|
+
{"version":3,"file":"vti-mediator.js","sourceRoot":"","sources":["../../src/adapters/vti-mediator.ts"],"names":[],"mappings":"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","sourcesContent":["// RLTP transport adapter: VTI mediator — published as\n// @real-life/trust-protocol/adapters/vti-mediator (lib Stage 2, note §4.6).\n//\n// It takes the holder's documents from the holder's custody (Delivery 0.83\n// RLTP-DEL-6120 to 6135, lib 0.6.0): reconcile(view, gate, now) files every\n// entry of holder.pendingTransport(when) not yet filed, and withdraws every\n// filed submission still before the trias whose digest the view no longer\n// names — a missing entry means stop, never keep sending. Before every\n// deposit it asks gate.mayHandOver(entry, now) (the holder): false\n// withdraws the submission, an error skips the attempt. It keeps no\n// custody of its own: its copies are volatile and bound to the holder's\n// opening: bound to the holder of its first reconcile, it refuses another,\n// so after holder.close() nothing it holds goes out, and the next opening\n// gets a new adapter (restored from ackState like any other). Its give-up horizon counts\n// from the entry's first submission (`since`), never from when it took the\n// entry over (RLTP-DEL-6130). Its reports reach the holder as the ports'\n// DeliveryReport: report(id) maps the adapter's SubmissionState onto\n// DeliveryReport (deliveryReportOf), keyed by the document digest, which\n// the app hands to holder.report(). An adapter's `delivered` is its claim\n// about transport; the holder's receive core verifies the delivery-ack\n// itself.\n//\n// Profile: spec/adapter-vti-mediator.md v0.24 (twenty-fourth casting;\n// round journals under design/adapter-review*). A\n// transport adapter contract — NOT a carrier at the port.\n//\n// Sending form (profile §3a, lib 0.7.0): every deposit names its mode to\n// the wire. Mode `routed` (the mode of every instance from construction):\n// an inner TSP `direct` message egress identity → counterpart's\n// connection DID inside an outer routed message connection DID → C with\n// the route [counterpart's connection DID], on the connection DID's\n// session. Mode `egress-session` (fallback): the inner message alone, on\n// a send-only session of the egress identity. The wire packs the layers\n// (depositAddressing says who addresses whom); the adapter keeps the\n// relationship's send state (the mode and the open routed deposits) in\n// its ack state (RLTP-VTI-3130). Open are: every document with a digest\n// (an entry of kind `document` filed by reconcile) accepted in routed and\n// not yet answered — a valid acknowledgement, a validated refusal or a\n// validated idConflict for its digest answers it. Acknowledgements are\n// no open deposits: a side that only acknowledges never switches by the\n// deadline (Open Issue 9). The adapter switches one way to\n// `egress-session` when an open deposit is routed-ack-deadline (72 h)\n// old, checked in an advance after a conclusion that left nothing\n// pending and while nothing is pending again — \"nothing pending\" is the\n// binding's statement through queueEmpty() (RLTP-VTI-7150); without it\n// the adapter never switches — and at once on a\n// validated refusal of the routed form (WireError 'routed-refused').\n// At the switch the open deposits leave; nothing returns to routed. A\n// submit() without a digest opens nothing. An attempt\n// ends in the mode it began in; an accepted submission is never\n// deposited again (RLTP-VTI-3135, 7130).\n//\n// The app's transport contract (web-of-trust TRANSPORT.md, rules 5 and\n// 6), as far as it holds here: (5) a withdrawal — reconcile without the\n// entry — means the adapter starts no deposit for that submission\n// afterwards, and an outcome that resolves late changes nothing here\n// (has() false, report() null, no send state) — except a validated refusal\n// of the routed form, which switches the relationship (a finding about the\n// mediator, RLTP-VTI-3130). A wire call already\n// running cannot be recalled and may still land at the mediator (the §6\n// boundary); the copy that then arrives is a duplicate the receiver\n// absorbs (Delivery §6.2). (6) Every deposit is a submission with an id\n// of its own, a duplicate's answer (`resend`) included; the\n// DeliveryReport handed to the holder carries the digest, and the app\n// pairs it with its deposit through the submission id it polls.\n//\n// Beyond the profile (lib 0.5.0): conclude(collection, now, {keep}) leaves\n// the items whose disposition is transient unconcluded and offers them\n// again (Delivery 0.82 RLTP-DEL-5810, 5820: failed(rate-limited) is never\n// concluded); `concludable(result)` says which receive outcomes are\n// terminal. The profile's §4 concludes a collection whole; its next\n// casting is to take this up.\n//\n// Structural rules (reviews 3+4):\n// · No port operation ever awaits the mediator — including\n// register: keylist synchronization is a recorded intent with a\n// tracked background task, retried by advance.\n// · No report is invented, and absence is ABSENT: before the first\n// honest report exists, status() returns null (§6.1 grants the\n// window; representing it as a queryable fourth value was\n// review-4 B2). has() distinguishes an unknown id.\n// · A retired instance mutates nothing and refuses everything\n// except reading its ack state.\n\nimport { jcs } from '../core.js'\nimport { sha } from '../crypto.js'\nimport { carrierPrincipal, carrierScopedIdentity } from '../carrier-identity.js'\nimport type { CarrierPrincipal, CarrierScopedIdentity } from '../carrier-identity.js'\nimport type { DeliveryReport, ReceiverRefusalCode, SubmissionRef } from '../ports.js'\nimport type { TransportEntry, TransportView } from '../engine.js'\nimport type { ReceiveResult } from '../results.js'\nexport type { ReceiverRefusalCode } from '../ports.js'\n\n// ── Declared constants (profile §2) — promises of THIS casting ──────\n// frozen: the declared promises cannot be changed at run time either\nexport const DECLARED = Object.freeze({\n giveUpHorizonMs: 72 * 3_600_000,\n statusHorizonMs: 60_000,\n queueFloorCount: 64,\n queueFloorBytes: 1_048_576,\n maxQueueBytes: 16_777_216,\n duplicateWindowMs: 30 * 86_400_000,\n routedAckDeadlineMs: 72 * 3_600_000,\n} as const)\n\n// ── The sending form (profile §3a) ───────────────────────────────────\n/** How a deposit reaches the mediator (RLTP-VTI-3110, 3120). */\nexport type SendMode = 'routed' | 'egress-session'\nconst SEND_MODES: ReadonlySet<string> = new Set<SendMode>(['routed', 'egress-session'])\n\n/** One TSP layer's addressing (no keys, no bytes: those are the wire's). */\nexport interface LayerAddressing {\n messageType: 'direct' | 'routed'\n sender: string\n receiver: string\n route?: string[]\n}\n\n/** The addressing of a deposit in `mode` (RLTP-VTI-1110, 1120, 3110,\n * 3115, 3120): the inner `direct` message from this side's egress\n * identity to the counterpart's connection DID; in mode `routed` an\n * outer routed message from this side's connection DID to the carrier\n * `C` with the route [counterpart's connection DID], deposited on the\n * connection DID's session; in mode `egress-session` no outer layer,\n * deposited on the egress identity's send-only session. */\nexport function depositAddressing (\n mode: SendMode, self: { connection: string, egress: string }, peerConnection: string, carrier: string,\n): { inner: LayerAddressing, outer: LayerAddressing | null, session: string } {\n if (!SEND_MODES.has(mode)) throw new Error(`unknown send mode ${String(mode)}`)\n const inner: LayerAddressing = { messageType: 'direct', sender: self.egress, receiver: peerConnection }\n if (mode === 'routed') {\n return {\n inner,\n outer: { messageType: 'routed', sender: self.connection, receiver: carrier, route: [peerConnection] },\n session: self.connection,\n }\n }\n return { inner, outer: null, session: self.egress }\n}\n\n// ── The injected wire ────────────────────────────────────────────────\nexport type WireErrorKind =\n | 'unreachable' | 'refused-retriable' | 'refused-admission' | 'oversize'\n /** the mediator refused a routed deposit for its routed form, and the\n * binding authenticated that refusal as the mediator's (RLTP-VTI-3130):\n * the relationship switches to egress-session at once */\n | 'routed-refused'\n\nexport class WireError extends Error {\n kind: WireErrorKind\n constructor (kind: WireErrorKind, message?: string) {\n super(message ?? kind)\n this.kind = kind\n }\n}\n\nexport interface MediatorWire {\n authChallenge (did: string): Promise<{ challenge: string, sessionId: string }>\n authenticate (answer: { did: string, challenge: string, sessionId: string }): Promise<TokenSet>\n // A transient failure MUST be a WireError 'unreachable' or\n // 'refused-retriable' (the tokens are kept); any other error means the\n // mediator refused the refresh token (the adapter re-runs the handshake).\n refresh (refreshToken: string): Promise<TokenSet>\n keylistUpdate (accessToken: string, rkids: string[]): Promise<void>\n /** `mode` is the sending form of this deposit (profile §3a): the wire\n * packs and sends it as depositAddressing(mode, …) describes. */\n deposit (accessToken: string, bytes: Uint8Array, egressDid: string, mode: SendMode): Promise<void>\n ackReceived (accessToken: string, queueIds: string[]): Promise<void>\n /** The adapter's consumer answers whether it took the frame (buffered,\n * already held, or absorbed as a duplicate): false means the frame is\n * left with the mediator (above max-queue-bytes, or a retired\n * instance), and a wire must not take its queue for drained until the\n * frame is offered again (RLTP-VTI-3130, queueEmpty). */\n onDeliver (cb: (bytes: Uint8Array) => Promise<boolean>): void\n /** Optional truthful connectivity signal; absent means unknown. */\n offline? (): boolean\n /** Optional: true when the mediator holds nothing more for this\n * connection (RLTP-VTI-3130: a conclusion that left no frame\n * pending). Closed: absent, no collection counts as complete, so an\n * adapter over a wire without it never switches to egress-session. */\n queueEmpty? (): boolean\n}\n\nexport interface TokenSet {\n accessToken: string\n accessExpiresAt: number\n refreshToken: string\n refreshExpiresAt: number\n}\n\n// ── Sender states (§6.1 — the closed sets, nothing else) ────────────\n// ReceiverRefusalCode is the ports' (one closed set, one place)\nconst RECEIVER_REFUSAL_CODES: ReadonlySet<ReceiverRefusalCode> = new Set<ReceiverRefusalCode>([\n 'malformedRequest', 'unsupportedType', 'proofRequired',\n 'proofInvalid', 'wrongRecipient', 'identityMismatch',\n])\n\nexport type SubmissionState =\n | { state: 'awaiting-transport', reason: 'offline' | 'transport-unreachable' | 'carrier-refused-retriable' }\n | { state: 'accepted' }\n | { state: 'delivered', late: boolean }\n | { state: 'failed', reason: 'unroutable' | 'oversize' | 'expired-by-adapter-policy' }\n | { state: 'failed', reason: 'rejected-by-receiver', code: ReceiverRefusalCode }\n\n/** The ports' DeliveryReport for a document `digest` in adapter state `st`\n * (Delivery §6.1): one-to-one, `late` and the refusal code carried over. */\nexport function deliveryReportOf (digest: string, st: SubmissionState): DeliveryReport {\n switch (st.state) {\n case 'awaiting-transport': return { digest, status: 'awaiting-transport', reason: st.reason }\n case 'accepted': return { digest, status: 'accepted' }\n case 'delivered': return { digest, status: 'delivered', late: st.late }\n case 'failed': return st.reason === 'rejected-by-receiver'\n ? { digest, status: 'failed', reason: 'rejected-by-receiver', code: st.code }\n : { digest, status: 'failed', reason: st.reason }\n }\n}\n\n/** Whether a receive outcome is terminal and its item may be concluded\n * (Delivery 5a.8): every disposition but `failed(rate-limited)`, the one\n * failure that is transient (RLTP-DEL-5820). An InfraError of the\n * holder's store is transient as well (RLTP-DEL-5810): an item whose\n * receive threw is kept, too. */\nexport function concludable (r: ReceiveResult): boolean {\n return !(r.disposition === 'failed' && r.reason === 'rate-limited')\n}\n\n/** The adapter's own copy of a wire's token set: the wire keeps no handle on it. */\nconst tokenCopy = (t: TokenSet): TokenSet => ({ accessToken: t.accessToken, accessExpiresAt: t.accessExpiresAt, refreshToken: t.refreshToken, refreshExpiresAt: t.refreshExpiresAt })\n\nexport interface CollectedItem { bytes: Uint8Array, queueId: string }\nexport interface Collection { id: string, items: CollectedItem[] }\n\n/** Ack state for the host to persist (profile §4). Invariant: every\n * pending id names a concluded entry; violations are refused at\n * construction (fail-closed). */\nexport interface AckState {\n concluded: Array<{ queueId: string, concludedAt: number }>\n pending: string[]\n /** the relationship's send state (RLTP-VTI-3130); absent → `routed` */\n send?: SendState\n}\n\n/** The send state of a relationship (profile §3a, RLTP-VTI-3130),\n * persisted with the ack state: the mode and the open routed deposits —\n * this side's documents accepted in routed and not yet answered, each\n * with its digest and acceptance instant. Acknowledgements are no open\n * deposits. In egress-session `open` is empty. */\nexport interface SendState {\n mode: SendMode\n open: Array<{ digest: string, acceptedAt: number }>\n}\n\n/** how long an open routed deposit stays in the send state at most\n * (RLTP-VTI-3130): the state is bounded even where no switch check runs */\nconst OPEN_KEEP_MS = DECLARED.routedAckDeadlineMs + DECLARED.duplicateWindowMs\n\nconst finite = (x: unknown): x is number => typeof x === 'number' && Number.isFinite(x)\n\n/** A restored send state, checked fail-closed (§4): exactly `mode` and\n * `open`, a known mode, each entry exactly a digest and a finite\n * acceptance instant not after restoredAt, each digest once, nothing open\n * in egress-session. Any other field — the acknowledgement fields of an\n * earlier form included — is refused, not ignored. */\nfunction restoreSendState (send: unknown, restoredAt: number): SendState {\n const refuse = (why: string): never => { throw new Error(`ack snapshot: send state ${why}`) }\n if (typeof send !== 'object' || send === null) return refuse('is not an object')\n const s = send as Record<string, unknown>\n const exactly = (o: object, keys: string[]): boolean => {\n const own = Object.keys(o)\n return own.length === keys.length && keys.every((k) => own.includes(k))\n }\n if (!exactly(s, ['mode', 'open'])) refuse('has other fields than mode and open')\n if (typeof s.mode !== 'string' || !SEND_MODES.has(s.mode)) refuse('names an unknown mode')\n if (!Array.isArray(s.open)) refuse('open deposits are not a list')\n const open = (s.open as unknown[]).map((r) => {\n const e = r as Record<string, unknown> | null\n if (typeof e !== 'object' || e === null || !exactly(e, ['digest', 'acceptedAt']) ||\n typeof e.digest !== 'string' || !finite(e.acceptedAt) || e.acceptedAt > restoredAt) {\n return refuse('open deposit is malformed, non-finite or accepted after restoredAt')\n }\n return { digest: e.digest, acceptedAt: e.acceptedAt }\n })\n if (new Set(open.map((o) => o.digest)).size !== open.length) refuse('names an open deposit twice')\n // the switch empties it: an egress-session with open deposits was never produced\n if (s.mode === 'egress-session' && open.length > 0) refuse('is egress-session with open routed deposits')\n return { mode: s.mode as SendMode, open }\n}\n\n/** The holder's side of a hand-over (lib 0.6.0): the holder itself.\n * handOver checks the entry and calls `start` inside the holder's queue;\n * `start` re-checks the adapter's own state, starts the deposit\n * synchronously and says whether it did. `closed` is read in `start`. */\nexport interface TransportGate {\n handOver (entry: TransportEntry, when: number, start: () => boolean): Promise<boolean>\n readonly closed?: boolean\n}\n\ninterface Submission {\n id: string\n /** the document digest, for submissions filed by reconcile */\n digest?: string\n /** the holder's entry and its gate, for submissions filed by reconcile */\n entry?: TransportEntry\n gate?: TransportGate\n bytes: Uint8Array\n submittedAt: number\n attemptStartedAt: number | null\n lastKind: WireErrorKind | null\n st: SubmissionState | null // null = no honest report exists yet\n /** the mode of the last deposit call started for it (RLTP-VTI-3135) */\n sentMode: SendMode | null\n /** a verdict on it arrived: its digest is never opened after it */\n answered?: boolean\n}\n\nconst hex = (b: Uint8Array): string =>\n Array.from(b, (x) => x.toString(16).padStart(2, '0')).join('')\n\n// construction capability: only create() holds it\nconst KEY = Symbol('MediatorCarrierAdapter.create')\n\n// ── The adapter ──────────────────────────────────────────────────────\nexport class MediatorCarrierAdapter {\n // JS-hard identity fields: TS `readonly` is a compile-time promise\n // only, and §8 claims runtime unforgeability — so the values live\n // in true privates behind getters (R8-B1)\n #principal: string\n #connectionDid: string\n #egressDid: string\n get principal (): string { return this.#principal }\n get connectionDid (): string { return this.#connectionDid }\n get egressDid (): string { return this.#egressDid }\n #wire: MediatorWire\n #tokens: TokenSet | null = null\n #clock = Number.NEGATIVE_INFINITY\n #closed = false\n /** the opening this adapter serves, bound at its first reconcile */\n #gate: TransportGate | null = null\n\n #subs = new Map<string, Submission>()\n #inflight = new Set<Promise<void>>()\n #nextId = 1\n\n #desiredRkids: string[] | null = null\n #keylistSynced = false\n #keylistSyncing = false\n\n #inbox: CollectedItem[] = []\n #inboxBytes = 0\n #inboxDigests = new Set<string>()\n #outstanding = new Map<string, Map<string, CollectedItem>>()\n #outstandingBytes = 0\n #concluded = new Map<string, number>()\n #pendingAcks = new Set<string>()\n #flightAcks = new Set<string>() // ids inside the in-flight flush snapshot\n #flushing = false\n #nextColId = 1\n\n #transitions: Array<{ id: string, to: 'delivered' }> = []\n\n // the relationship's send state (RLTP-VTI-3130)\n #mode: SendMode = 'routed'\n /** open routed deposits (documents), keyed by digest */\n #openDeposits = new Map<string, number>()\n /** this instance has concluded a collection that left nothing pending */\n #cleanConcluded = false\n\n /** The only way to build an adapter: the trio is DERIVED here from\n * one root, one carrier, one nonce — so principal, connection DID\n * and egress identity cannot come from different relationships\n * (R7-B2: the coupling is enforced by construction, not by\n * inspecting caller-supplied identities). */\n static async create (\n rootIkm: Uint8Array, carrier: string, nonce: Uint8Array,\n wire: MediatorWire, restored?: AckState, restoredAt?: number,\n ): Promise<MediatorCarrierAdapter> {\n // ONE tuple, snapshotted at entry: a caller mutating its buffers\n // between the three awaited derivations must not be able to mix\n // identities from two tuples (R8-B2)\n const ikm = new Uint8Array(rootIkm)\n const n = new Uint8Array(nonce)\n const principal = await carrierPrincipal(ikm, carrier, n)\n const connection = await carrierScopedIdentity(ikm, carrier, n, 'connection')\n const egress = await carrierScopedIdentity(ikm, carrier, n, 'egress')\n return new MediatorCarrierAdapter(KEY, principal, connection, egress, wire, restored, restoredAt)\n }\n\n constructor (\n key: symbol,\n principal: CarrierPrincipal,\n connection: CarrierScopedIdentity,\n egress: CarrierScopedIdentity,\n wire: MediatorWire,\n restored?: AckState,\n restoredAt?: number,\n ) {\n if (key !== KEY) {\n throw new Error('use MediatorCarrierAdapter.create — the identity trio must be derived, not supplied (5a.10)')\n }\n if (connection.scope !== 'connection' || egress.scope !== 'egress') {\n throw new Error('scoped identities passed in the wrong roles')\n }\n const three = new Set([principal.principal, connection.did, egress.did])\n if (three.size !== 3) {\n throw new Error('principal, connection DID and egress identity must be pairwise distinct (5a.10)')\n }\n this.#principal = principal.principal\n this.#connectionDid = connection.did\n this.#egressDid = egress.did\n this.#wire = wire\n if (restored) {\n // The restore instant anchors the duplicate-window: an expired,\n // debt-free entry is dropped HERE, not at the first advance —\n // otherwise a redelivery arriving before any port call would be\n // absorbed beyond the declared window (review-4 B4).\n if (typeof restoredAt !== 'number' || !Number.isFinite(restoredAt)) {\n throw new Error('restoring ack state requires a finite restoredAt instant')\n }\n this.#now(restoredAt)\n const pending = new Set(restored.pending)\n const known = new Set(restored.concluded.map((c) => c.queueId))\n for (const id of pending) {\n if (!known.has(id)) {\n throw new Error('ack snapshot violates its invariant: pending intent without a concluded entry')\n }\n }\n for (const { queueId, concludedAt } of restored.concluded) {\n if (!Number.isFinite(concludedAt) || concludedAt > restoredAt) {\n // a conclusion \"from the future\" would stretch the window\n // past its declared span (R5-B4) — fail closed\n throw new Error('ack snapshot: conclusion instant is non-finite or after restoredAt')\n }\n // the window beats everything (round-14 B): an expired entry\n // falls at the restore instant, owed or not — a phantom debt\n // from an ack that landed just before a close can never\n // outlive the window and delete a fresh copy (R14-B2)\n if (restoredAt - concludedAt >= DECLARED.duplicateWindowMs) continue\n this.#concluded.set(queueId, concludedAt)\n if (pending.has(queueId)) this.#pendingAcks.add(queueId)\n }\n // absent: a host that persisted none starts again in routed\n if (restored.send !== undefined) {\n const send = restoreSendState(restored.send, restoredAt)\n this.#mode = send.mode\n // an open deposit falls routed-ack-deadline plus duplicate-window\n // after its acceptance: cut here, not refused\n for (const o of send.open) if (restoredAt - o.acceptedAt < OPEN_KEEP_MS) this.#openDeposits.set(o.digest, o.acceptedAt)\n }\n }\n this.#wire.onDeliver(async (raw): Promise<boolean> => {\n if (this.#closed) return false\n // a plain copy of its own: a Node Buffer's slice() would share memory\n const bytes = new Uint8Array(raw)\n const queueId = hex(await sha(bytes))\n if (this.#closed) return false\n // Absorption is checked at the moment it happens (R11-B1): the\n // adapter absorbs a copy only for give-up-horizon after its\n // conclusion (profile §2, §4); a later copy is a new item for the\n // holder, whose absorption answers it again with the stored\n // acknowledgement (RLTP-DEL-6330, 6335) — so a counterpart that\n // resubmits after a lost acknowledgement is answered. The entry and\n // its ack intent stand for the duplicate window, and the window\n // beats everything (round-14 B): beyond it, both fall.\n // buffered and outstanding go before concluded (§3): a redelivery of\n // a later copy the holder has not concluded yet is ignored\n if (this.#inboxDigests.has(queueId)) return true\n for (const col of this.#outstanding.values()) if (col.has(queueId)) return true\n const concludedAt = this.#concluded.get(queueId)\n if (concludedAt !== undefined) {\n if (this.#flightAcks.has(queueId) ||\n this.#clock - concludedAt < DECLARED.giveUpHorizonMs) {\n // inside the horizon — or deferred: an id inside an\n // in-flight flush keeps absorbing until that flush ends,\n // because its irrecallable ack may still land (R15-B1)\n this.#pendingAcks.add(queueId)\n return true\n }\n if (this.#clock - concludedAt >= DECLARED.duplicateWindowMs) {\n this.#concluded.delete(queueId)\n this.#pendingAcks.delete(queueId)\n }\n }\n const held = this.#inboxBytes + this.#outstandingBytes\n const underFloor = this.#inbox.length < DECLARED.queueFloorCount &&\n held + bytes.length <= DECLARED.queueFloorBytes\n const underCap = held + bytes.length <= DECLARED.maxQueueBytes\n // not acknowledged and not taken: the mediator keeps its copy\n if (!underFloor && !underCap) return false\n this.#inbox.push({ bytes, queueId })\n this.#inboxBytes += bytes.length\n this.#inboxDigests.add(queueId)\n return true\n })\n }\n\n #now (raw: number): number {\n if (!Number.isFinite(raw)) throw new Error('non-finite time')\n if (raw > this.#clock) this.#clock = raw\n return this.#clock\n }\n\n #open (): void { if (this.#closed) throw new Error('retired (5a.10 lifecycle)') }\n\n #track (p: Promise<void>): void {\n const t = p.catch(() => {})\n this.#inflight.add(t)\n void t.finally(() => this.#inflight.delete(t))\n }\n\n // ── auth: silent carrier policy ─────────────────────────────────\n // Single-flight: concurrent callers share one handshake — the ATM\n // challenge/response is a session, and two interleaved sessions\n // under one connection DID would answer each other's challenges.\n #authing: Promise<string> | null = null\n\n #ensureAuth (now: number): Promise<string> {\n if (this.#tokens && now < this.#tokens.accessExpiresAt) return Promise.resolve(this.#tokens.accessToken)\n if (this.#authing) return this.#authing\n const run = (async (): Promise<string> => {\n if (this.#tokens && now < this.#tokens.refreshExpiresAt) {\n try {\n const refreshed = await this.#wire.refresh(this.#tokens.refreshToken)\n if (this.#closed) throw new Error('retired') // as on the handshake path (R6-B1)\n this.#tokens = tokenCopy(refreshed)\n return this.#tokens.accessToken\n } catch (e) {\n if (this.#closed) throw e\n // a transient failure (mediator unreachable, retriable refusal)\n // says nothing about the token: keep it for the next attempt (#9)\n if (e instanceof WireError && (e.kind === 'unreachable' || e.kind === 'refused-retriable')) throw e\n // a refused refresh (revoked before its expiry) is never replayed:\n // drop the tokens and take the challenge handshake below\n this.#tokens = null\n }\n }\n const { challenge, sessionId } = await this.#wire.authChallenge(this.#connectionDid)\n if (this.#closed) throw new Error('retired') // nothing new starts, not even the answer (R6-B1)\n this.#tokens = tokenCopy(await this.#wire.authenticate({ did: this.#connectionDid, challenge, sessionId }))\n return this.#tokens.accessToken\n })()\n this.#authing = run.finally(() => { this.#authing = null })\n return this.#authing\n }\n\n // ── transport registration (profile §3 — NOT §5a.3) ─────────────\n /** Records the desired keylist and returns; synchronization runs\n * as a tracked background task and advance retries it until it\n * lands (review-4 B1). */\n register (rkids: string[], rawNow: number): void {\n this.#open()\n const now = this.#now(rawNow)\n this.#desiredRkids = [...rkids]\n this.#keylistSynced = false\n this.#startKeylistSync(now)\n }\n\n get keylistSynced (): boolean {\n this.#open()\n return this.#keylistSynced\n }\n\n #startKeylistSync (now: number): void {\n if (this.#keylistSyncing || this.#keylistSynced || this.#desiredRkids === null) return\n this.#keylistSyncing = true\n const wanted = [...this.#desiredRkids]\n this.#track((async () => {\n try {\n const token = await this.#ensureAuth(now)\n if (this.#closed) return\n await this.#wire.keylistUpdate(token, [...wanted]) // the wire's own list: `wanted` is compared below\n // land only if the desire has not moved meanwhile\n if (!this.#closed && this.#desiredRkids !== null &&\n wanted.join(' ') === this.#desiredRkids.join(' ')) {\n this.#keylistSynced = true\n }\n } catch {\n // intent survives; advance retries\n } finally {\n this.#keylistSyncing = false\n }\n })())\n }\n\n // ── sender side ─────────────────────────────────────────────────\n /** Returns the submission id synchronously. Before the first\n * honest report exists, status() returns null — §6.1's own\n * pre-report window, represented as absence, not as a value. */\n submit (envelopeBytes: Uint8Array, rawNow: number): string {\n this.#open()\n const now = this.#now(rawNow)\n const id = 's' + this.#nextId++\n const knownOffline = this.#wire.offline?.() === true\n const sub: Submission = {\n id,\n // a plain copy of its own (a Node Buffer's slice() shares memory)\n bytes: new Uint8Array(envelopeBytes),\n submittedAt: now,\n attemptStartedAt: null,\n lastKind: null,\n st: null,\n sentMode: null,\n }\n this.#subs.set(id, sub)\n if (!knownOffline) this.#startAttempt(sub, now)\n return id\n }\n\n /** Takes the holder's custody set (holder.pendingTransport, after a\n * resume of this opening) and the holder as the gate: files every entry\n * not yet filed under its digest (its envelope as JCS bytes; the give-up\n * horizon from entry.since) and returns their SubmissionRefs; withdraws\n * every filed submission still before the trias (no report, or\n * awaiting-transport) whose digest the view does not name. Accepted and\n * terminal submissions stay for their reports. */\n reconcile (view: TransportView, gate: TransportGate, rawNow: number): SubmissionRef[] {\n this.#open()\n if (view?.ok !== true || !Array.isArray(view.entries)) throw new Error('reconcile needs a view of holder.pendingTransport')\n if (typeof gate?.handOver !== 'function') throw new Error('reconcile needs the holder as its gate')\n // one adapter per opening: its copies and the holder's grants belong to\n // that opening, and the next opening gets an adapter of its own\n if (this.#gate === null) this.#gate = gate\n else if (this.#gate !== gate) throw new Error('one adapter per opening: this adapter reconciles with another holder (create a new adapter for the next opening)')\n const now = this.#now(rawNow)\n // a submission's key: the digest, and for a duplicate's answer its\n // grant too — the retries and each answer are hand-overs of their own\n const keyOf = (digest: string, resend: number | undefined): string => resend === undefined ? digest : `${digest}#${resend}`\n const named = new Set(view.entries.map((e) => keyOf(e.digest, e.resend)))\n const filed = new Map<string, Submission>()\n for (const [id, sub] of this.#subs) {\n if (sub.digest === undefined) continue\n const key = keyOf(sub.digest, sub.entry?.resend)\n const before = sub.st === null || sub.st.state === 'awaiting-transport'\n if (before && !named.has(key)) { this.#subs.delete(id); continue }\n filed.set(key, sub)\n }\n const refs: SubmissionRef[] = []\n for (const entry of view.entries) {\n const had = filed.get(keyOf(entry.digest, entry.resend))\n if (had !== undefined) {\n // the newest entry of a live submission is the one its gate checks\n if (had.st === null || had.st.state === 'awaiting-transport') { had.entry = entry; had.gate = gate; continue }\n // an answer the holder still offers is still owed — its hand-over\n // never began, or the holder could not record that it did: a\n // terminal submission of it is filed again (the holder ends it)\n if (entry.resend === undefined) continue\n this.#subs.delete(had.id)\n }\n const id = 's' + this.#nextId++\n const sub: Submission = {\n id, digest: entry.digest, entry, gate,\n bytes: new TextEncoder().encode(jcs(entry.envelope)),\n // a duplicate's ack is a hand-over of its own, from now\n submittedAt: entry.resend !== undefined ? now : Math.min(entry.since, now),\n attemptStartedAt: null, lastKind: null, st: null, sentMode: null,\n }\n this.#subs.set(id, sub)\n refs.push({ submissionId: id, digest: entry.digest })\n // taken over past its horizon (counted from the first submission,\n // RLTP-DEL-6130): given up at once, never attempted\n if (now - sub.submittedAt >= DECLARED.giveUpHorizonMs) { sub.st = { state: 'failed', reason: 'expired-by-adapter-policy' }; continue }\n if (this.#wire.offline?.() !== true) this.#startAttempt(sub, now)\n }\n return refs\n }\n\n /** The current state as the ports' DeliveryReport for holder.report(),\n * or null while no honest report exists (and for an unknown id). A\n * submission filed without a digest (submit) has no report form. */\n report (id: string): DeliveryReport | null {\n const st = this.status(id)\n if (st === null) return null\n const digest = this.#subs.get(id)!.digest\n if (digest === undefined) throw new Error('submitted without a document digest: file holder documents through reconcile')\n return deliveryReportOf(digest, st)\n }\n\n has (id: string): boolean {\n this.#open()\n return this.#subs.has(id)\n }\n\n #startAttempt (sub: Submission, now: number): void {\n if (sub.attemptStartedAt !== null) return\n sub.attemptStartedAt = now\n this.#track(this.#trySend(sub, now).finally(() => { sub.attemptStartedAt = null }))\n }\n\n async #trySend (sub: Submission, now: number): Promise<void> {\n if (sub.st !== null && sub.st.state !== 'awaiting-transport') return\n let next: SubmissionState\n let routedRefused = false\n try {\n const token = await this.#ensureAuth(now)\n if (this.#closed) return // retirement between auth and deposit: nothing new starts (R5-B2)\n // each attempt hands the wire a copy: what it does with it never reaches the next.\n // The mode is read at the hand-over itself: from a switch on, every\n // hand-over uses the new mode, and a call already made ends in its own\n // (RLTP-VTI-3135)\n const deposit = (): Promise<void> => {\n sub.sentMode = this.#mode\n try { return this.#wire.deposit(token, new Uint8Array(sub.bytes), this.#egressDid, sub.sentMode) } catch (e) { return Promise.reject(e) }\n }\n if (sub.gate !== undefined) {\n // the holder decides, and the deposit starts in the same step of its\n // queue (Delivery RLTP-DEL-6125 to 6135); the adapter re-checks its\n // own state there: retired, withdrawn, past the trias, past the\n // entry's deadline or its own horizon → no deposit\n // the deposit's outcome, caught at once: the holder's step may still\n // be committing when the wire answers\n let started: Promise<unknown> | null = null\n let declined = false\n const entry = sub.entry!\n const start = (): boolean => {\n if (this.#closed || this.#subs.get(sub.id) !== sub || sub.gate!.closed === true ||\n (sub.st !== null && sub.st.state !== 'awaiting-transport') || this.#clock >= entry.notAfter ||\n this.#clock - sub.submittedAt >= DECLARED.giveUpHorizonMs) { declined = true; return false }\n started = deposit().then(() => null, (e: unknown) => ({ failed: e }))\n return true\n }\n let ok: boolean | null\n try { ok = await sub.gate.handOver(entry, this.#clock, start) } catch { ok = null }\n if (started === null) {\n // the holder said no: withdrawn; the adapter declined or the\n // holder was unreachable: not this attempt\n if (ok === false && !declined && this.#subs.get(sub.id) === sub) this.#subs.delete(sub.id)\n return\n }\n const outcome = await (started as Promise<unknown>)\n if (outcome !== null) throw (outcome as { failed: unknown }).failed\n } else {\n await deposit()\n }\n sub.lastKind = null\n next = { state: 'accepted' }\n } catch (e) {\n let kind: WireErrorKind = e instanceof WireError ? e.kind : 'unreachable'\n // a validated refusal of the routed form: the relationship switches\n // below, the submission stays in custody as a retriable refusal\n if (kind === 'routed-refused') { routedRefused = sub.sentMode === 'routed'; kind = 'refused-retriable' }\n sub.lastKind = kind\n next = kind === 'oversize'\n ? { state: 'failed', reason: 'oversize' }\n : {\n state: 'awaiting-transport',\n reason: kind === 'unreachable' ? 'transport-unreachable' : 'carrier-refused-retriable',\n }\n }\n if (this.#closed) return\n // evidence against routed (RLTP-VTI-3130): the switch, at once\n if (routedRefused) this.#switchToEgress()\n // withdrawn meanwhile (app contract rule 5): the late outcome changes nothing\n if (this.#subs.get(sub.id) !== sub) return\n // a document with a digest accepted in routed is an open routed deposit\n // (RLTP-VTI-3130) — only while the relationship is still routed (an\n // attempt begun before a switch opens nothing after it). Acknowledgements\n // and a submit() without a digest open nothing. Answered already (the\n // verdict outran the deposit's resolution): not opened. acceptedAt is the\n // adapter clock when the deposit resolved, not when it was handed over:\n // later by the deposit's own run time\n if (next.state === 'accepted' && sub.sentMode === 'routed' && this.#mode === 'routed' &&\n sub.digest !== undefined && this.#isDocument(sub) && sub.answered !== true &&\n !this.#openDeposits.has(sub.digest)) {\n this.#openDeposits.set(sub.digest, this.#clock)\n }\n // An interim report (including a horizon-corrected one) never\n // outranks the attempt's real outcome; only a TERMINAL state —\n // a give-up, a refusal, a delivery — stands (R5-B1). Without\n // this, an accepted deposit would stay reported unreachable and\n // be sent a second time.\n if (sub.st === null || sub.st.state === 'awaiting-transport') sub.st = next\n }\n\n #isDocument (sub: Submission): boolean {\n return sub.entry === undefined || sub.entry.kind === 'document'\n }\n\n /** A verdict on a document answers its open routed deposit\n * (RLTP-VTI-3130), if the send state names it at that moment. A verdict\n * before the acceptance marks the submission, so it is not opened\n * afterwards. Acknowledgements are answered by nothing. */\n #answer (sub: Submission): void {\n if (!this.#isDocument(sub)) return\n sub.answered = true\n if (sub.digest !== undefined) this.#openDeposits.delete(sub.digest)\n }\n\n /** The switch (RLTP-VTI-3130): one way; the open routed deposits leave\n * the send state. */\n #switchToEgress (): void {\n this.#mode = 'egress-session'\n this.#openDeposits.clear()\n }\n\n /** The current sending mode of the relationship (profile §3a). */\n get sendMode (): SendMode { return this.#mode }\n\n /** An answer the holder hands this instance for a document an earlier\n * instance deposited (RLTP-VTI-3130): a valid acknowledgement, a\n * validated receiver refusal or a validated `idConflict` answer for\n * `digest`. If the send state names the document as an open routed\n * deposit, it is answered and leaves; otherwise it answers nothing. A\n * no-op on a retired instance, like acknowledged. */\n answered (digest: string, rawNow: number): void {\n if (this.#closed) return\n this.#now(rawNow)\n this.#openDeposits.delete(digest)\n // a document of this instance whose attempt still runs is answered too:\n // its acceptance after this opens nothing\n for (const sub of this.#subs.values()) if (sub.digest === digest && this.#isDocument(sub)) sub.answered = true\n }\n\n /** Host teardown aid, NOT a port operation (profile §6): awaits\n * the in-flight background tasks so a host can drain before\n * persisting ackState. On a hanging wire it waits as long as the\n * wire does — a host bounds it externally (Promise.race) exactly\n * because this library holds no clock of its own. */\n async settle (): Promise<void> {\n while (this.#inflight.size > 0) await Promise.all([...this.#inflight])\n }\n\n /** The §6.1 report, or null while none exists yet (has()\n * distinguishes an unknown id). status is a PORT: after close it\n * refuses like every other port operation (R5-B3).\n *\n * The pre-transport report is an HONEST SNAPSHOT, derived at the\n * moment of observation by one precedence order (Option B of the\n * round-14 halt) — never a stored patchwork:\n * (a) the wire knows itself offline → offline\n * (b) an attempt is overdue → transport-unreachable\n * (c) the last completed attempt's kind → its report\n * (d) otherwise → no report yet (null)\n * Terminal states and `accepted` are stored and stand. */\n status (id: string): SubmissionState | null {\n this.#open()\n const sub = this.#subs.get(id)\n if (!sub) return null\n if (sub.st !== null && sub.st.state !== 'awaiting-transport') return { ...sub.st }\n if (this.#wire.offline?.() === true) {\n return { state: 'awaiting-transport', reason: 'offline' }\n }\n if (sub.attemptStartedAt !== null &&\n this.#clock - sub.attemptStartedAt >= DECLARED.statusHorizonMs) {\n return { state: 'awaiting-transport', reason: 'transport-unreachable' }\n }\n return sub.st === null ? null : { ...sub.st }\n }\n\n /** A valid acknowledgement for submission `id`. Reports that a\n * collection carries are applied before that collection's conclude,\n * at the latest before the next advance: the switch check of\n * RLTP-VTI-3130 counts on them, and a report applied late can let the\n * relationship switch although its deposits were answered. */\n acknowledged (id: string): void {\n if (this.#closed) return\n const sub = this.#subs.get(id)\n if (!sub) return\n this.#answer(sub)\n if (sub.st?.state === 'delivered') return // idempotent: a duplicate ack never rewrites `late` (R9-M4)\n const late = sub.st?.state === 'failed'\n sub.st = { state: 'delivered', late }\n if (late) this.#transitions.push({ id, to: 'delivered' })\n }\n\n /** Refusals act on live submissions only (§6.1 knows exactly one\n * late correction — the valid ack). The code set is closed and\n * TERMINAL: retryable counterpart conditions (unavailable,\n * internalError) are transport outcomes, never receiver verdicts\n * — they have no entry here, and an unknown code is refused\n * fail-closed rather than minted into a verdict (R6-B2). Applied, like\n * acknowledged, before the conclude of the collection that carried\n * it (RLTP-VTI-3130). */\n receiverRefused (id: string, code: ReceiverRefusalCode): void {\n if (this.#closed) return\n if (!RECEIVER_REFUSAL_CODES.has(code)) {\n throw new Error('not a terminal receiver refusal code — retryable conditions are transport outcomes')\n }\n const sub = this.#subs.get(id)\n if (!sub) return\n this.#answer(sub)\n // A VALIDATED refusal is itself the proof of receipt — the\n // mediator can have accepted and forwarded while our deposit\n // promise is still unresolved, so the report-less phase is a\n // legitimate moment for it (R9-B2, reversing the R8-B3\n // overcorrection). Only terminal states stand against it.\n if (sub.st !== null && sub.st.state !== 'awaiting-transport' && sub.st.state !== 'accepted') return\n sub.st = { state: 'failed', reason: 'rejected-by-receiver', code }\n }\n\n drainTransitions (): Array<{ id: string, to: 'delivered' }> {\n this.#open()\n return this.#transitions.splice(0)\n }\n\n // ── receiver side ───────────────────────────────────────────────\n collect (rawNow: number): Collection {\n this.#open()\n this.#now(rawNow)\n if (this.#inbox.length === 0) return { id: 'c-empty', items: [] }\n const items = this.#inbox.splice(0)\n this.#outstandingBytes += this.#inboxBytes\n this.#inboxBytes = 0\n this.#inboxDigests.clear()\n const id = 'c' + this.#nextColId++\n this.#outstanding.set(id, new Map(items.map((i) => [i.queueId, i])))\n // the caller gets its own copies: the outstanding entries stay intact,\n // whatever it does with the bytes, for a conclusion that keeps them\n return { id, items: items.map((i) => ({ ...i, bytes: new Uint8Array(i.bytes) })) }\n }\n\n /** Concludes a collection (profile §4, Delivery 5a.8): its items'\n * digests become ack intent. `keep` names the items whose disposition\n * is transient (Delivery RLTP-DEL-5810, 5820: `failed(rate-limited)`,\n * or a transaction that could not commit, see `concludable`): they are\n * not concluded and not acknowledged, they go back to the buffer and the\n * next collect offers them again, and the mediator keeps its copy.\n * The reports the collection carries (acknowledged, receiverRefused,\n * answered) are applied BEFORE this call, at the latest before the next\n * advance: a conclusion that leaves nothing pending opens the switch\n * check of RLTP-VTI-3130, which counts them as applied. */\n conclude (collection: { id: string }, rawNow: number, opts: { keep?: readonly string[] } = {}): void {\n this.#open()\n const now = this.#now(rawNow)\n const col = this.#outstanding.get(collection.id)\n if (!col) {\n // an empty collection is concluded too: it may be the one that leaves nothing pending\n if (collection.id === 'c-empty') this.#concludedClean()\n return\n }\n this.#outstanding.delete(collection.id)\n const keep = new Set(opts.keep ?? [])\n for (const item of col.values()) {\n this.#outstandingBytes -= item.bytes.length\n if (keep.has(item.queueId)) {\n // transient: back to the buffer, offered again, never acknowledged\n this.#inbox.push(item)\n this.#inboxBytes += item.bytes.length\n this.#inboxDigests.add(item.queueId)\n continue\n }\n this.#concluded.set(item.queueId, now)\n this.#pendingAcks.add(item.queueId)\n }\n this.#concludedClean()\n this.#startFlush(now)\n }\n\n /** Nothing pending for this connection: the wire says the mediator\n * holds nothing more (queueEmpty; a wire without it never says so),\n * nothing waits in the buffer, no collection is outstanding. */\n #nothingPending (): boolean {\n return this.#wire.queueEmpty?.() === true && this.#inbox.length === 0 && this.#outstanding.size === 0\n }\n\n /** After a conclusion (RLTP-VTI-3130): when it left nothing pending,\n * the switch check may run in a later advance. */\n #concludedClean (): void {\n if (!this.#nothingPending()) return\n this.#cleanConcluded = true\n }\n\n ackState (): AckState {\n return {\n concluded: [...this.#concluded].map(([queueId, concludedAt]) => ({ queueId, concludedAt })),\n pending: [...this.#pendingAcks],\n send: {\n mode: this.#mode,\n open: [...this.#openDeposits].map(([digest, acceptedAt]) => ({ digest, acceptedAt })),\n },\n }\n }\n\n #startFlush (now: number): void {\n if (this.#flushing || this.#pendingAcks.size === 0) return\n this.#flushing = true\n const snapshot = new Set(this.#pendingAcks)\n this.#track(this.#flushAcks(now, [...snapshot]).finally(() => {\n this.#flushing = false\n // lost-wake-up guard (review-4 M6): intents that arrived while\n // this flush ran get their own flush now — but only newcomers,\n // so a failing wire waits for the next advance instead of\n // spinning\n if (!this.#closed) {\n for (const id of this.#pendingAcks) {\n if (!snapshot.has(id)) { this.#startFlush(this.#clock); break }\n }\n }\n }))\n }\n\n async #flushAcks (now: number, ids: string[]): Promise<void> {\n try {\n const token = await this.#ensureAuth(now)\n if (this.#closed) return\n // Only NOW does anything become irrecallable (R16-B1): the\n // stay of expiry begins at the wire call itself, never at the\n // snapshot — a hanging auth extends no window. And \"live\" is\n // WINDOW-live (R17-B1): an entry whose window already closed —\n // even if no prune has swept it yet — is never sent.\n const live = ids.filter((id) => {\n const at = this.#concluded.get(id)\n // a later copy of it that the holder has not concluded yet (in the\n // buffer or outstanding) is not acknowledged before it is handled:\n // hand off → await → ack; the intent stays for the next flush\n if (this.#inboxDigests.has(id) || [...this.#outstanding.values()].some((c) => c.has(id))) return false\n return at !== undefined && this.#clock - at < DECLARED.duplicateWindowMs\n })\n if (live.length === 0) return\n for (const id of live) this.#flightAcks.add(id)\n try {\n // the wire gets its own list: what it does with it never reaches the bookkeeping below\n await this.#wire.ackReceived(token, [...live])\n if (!this.#closed) for (const id of live) this.#pendingAcks.delete(id)\n } finally {\n for (const id of live) this.#flightAcks.delete(id)\n // deferred window sweep: entries whose window closed while\n // the ack flew fall now — intent, entry and absorption\n // together (R15-B1). Never on a retired instance: after\n // close, ackState() is the host's final-persist surface and\n // a late-returning wire mutates nothing (R17-B2).\n if (!this.#closed) {\n for (const id of live) {\n const at = this.#concluded.get(id)\n if (at !== undefined && this.#clock - at >= DECLARED.duplicateWindowMs) {\n this.#concluded.delete(id)\n this.#pendingAcks.delete(id)\n }\n }\n }\n }\n } catch {\n // intent survives; the next advance starts a fresh flush\n }\n }\n\n // ── the adapter clock — never awaits the mediator ───────────────\n advance (rawNow: number): void {\n this.#open()\n const now = this.#now(rawNow)\n // open routed deposits fall routed-ack-deadline plus duplicate-window\n // after their acceptance, also where no switch check can run (no\n // statement that nothing is pending, RLTP-VTI-7150)\n for (const [digest, at] of this.#openDeposits) if (now - at >= OPEN_KEEP_MS) this.#openDeposits.delete(digest)\n // the switch (RLTP-VTI-3130): only after a conclusion that left nothing\n // pending and while nothing is pending again at the check (an\n // acknowledgement that arrived since is collected and reported first),\n // when an open routed deposit is a deadline old — one way; checked\n // before the retries below, which hand over in the new mode\n if (this.#mode === 'routed' && this.#cleanConcluded && this.#nothingPending()) {\n for (const acceptedAt of this.#openDeposits.values()) {\n if (now - acceptedAt >= DECLARED.routedAckDeadlineMs) { this.#switchToEgress(); break }\n }\n }\n for (const sub of this.#subs.values()) {\n const live = sub.st === null || sub.st.state === 'awaiting-transport' || sub.st.state === 'accepted'\n if (!live) continue\n if (now - sub.submittedAt >= DECLARED.giveUpHorizonMs) {\n // unroutable only when the LAST COMPLETED attempt was an\n // admission refusal and no attempt is in flight whose outcome\n // is unknown (review-4 B3)\n // the give-up verdict applies the SAME precedence as every\n // observation (R17-B3): a wire that knows itself offline at\n // the horizon outranks any stored refusal class — unroutable\n // needs a completed admission refusal, no unknown outcome in\n // flight, AND no offline signal standing over it\n sub.st = {\n state: 'failed',\n reason: sub.lastKind === 'refused-admission' && sub.attemptStartedAt === null &&\n this.#wire.offline?.() !== true\n ? 'unroutable'\n : 'expired-by-adapter-policy',\n }\n continue\n }\n if (sub.st !== null && sub.st.state === 'accepted') continue\n // reports are DERIVED at observation (see status()); the clock\n // only decides here whether to start an attempt — and never\n // against a wire that knows itself offline\n if (this.#wire.offline?.() === true) continue\n if (sub.attemptStartedAt === null) this.#startAttempt(sub, now)\n }\n // THE WINDOW BEATS EVERYTHING (Option B of the round-14 halt):\n // an ack intent is retried until the window closes; then intent\n // and absorption fall together. There is no ageless debt whose\n // truth the adapter would have to know — the receiver's §6.2\n // absorption owns everything beyond the window.\n for (const [digest, at] of this.#concluded) {\n if (now - at >= DECLARED.duplicateWindowMs && !this.#flightAcks.has(digest)) {\n this.#concluded.delete(digest)\n this.#pendingAcks.delete(digest)\n }\n }\n this.#startKeylistSync(now)\n this.#startFlush(now)\n }\n\n /** §5a.10 lifecycle boundary: after close, every state port is\n * inert — port operations refuse, inbound reports (acknowledged,\n * receiverRefused) are no-ops, late wire resolutions mutate\n * nothing. Only ackState() stays readable for the host's final\n * persist. */\n close (): void { this.#closed = true }\n\n get closed (): boolean { return this.#closed }\n}\n\nexport const queueIdOf = async (bytes: Uint8Array): Promise<string> => hex(await sha(bytes))\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@real-life/trust-protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "The Real Life Trust Protocol (RLTP) \u2014 the executable form of the specification: encounters, introductions, trust disclosure, groups, continuity, and the delivery channel. Zero dependencies, WebCrypto only.",
|
|
5
5
|
"license": "CC-BY-4.0",
|
|
6
6
|
"type": "module",
|