@real-life/trust-protocol 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,74 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0
4
+
5
+ Takes up the VTI Mediator Adapter Profile 0.25 (§1b, the delivery hint)
6
+ and Encounter 0.31.1: a card carries the hints by which its side is
7
+ reachable in the relationship the card opens. A minor version: the
8
+ public API grows (`CarrierOffer`, a new `ActError` member, new
9
+ `RelationshipView` fields, three adapter exports); the storage format
10
+ does not change.
11
+
12
+ - **The carrier offer** of `show` and `scan`: `carrier: {nonce,
13
+ deliveryHints}` (new type `CarrierOffer`). `nonce` is the
14
+ relationship's carrier nonce N, 32 bytes the app draws fresh (Identity
15
+ §7a.3); `deliveryHints` are the hints the app built from the wire
16
+ identities its adapter derives from N. The displayed card (`show`) or
17
+ the scanner's sent card (`scan`) carries the hints under its proof.
18
+ The library interprets no hint. The offer is act input: bound and
19
+ journaled with the act, so a repeat under the same actId answers the
20
+ same card and another offer under it is `actid-conflict`.
21
+ - **N in the register** (`register.carriers`, generation 1) under the
22
+ relationship the card opens: at `show` already, as the card's pair
23
+ label enters the register before display (Encounter 4110); a card that
24
+ ages unscanned leaves its entry, as it leaves its label. At `scan`
25
+ under the scanner's fresh relationship. The storage format is
26
+ unchanged (codec 3).
27
+ - **Refusals**: more than eight hints or a hint over 512 characters
28
+ (Encounter RLTP-ENC-6090) is `card-invalid` with `ref`
29
+ `RLTP-ENC-6090`; an offer without a hint, or with a hint that is no
30
+ string, is `card-invalid` without a `ref` (an empty offer announces
31
+ nothing; a card without hints needs no offer, 6080); a nonce that is not 32 bytes in canonical base64url,
32
+ or that the register already holds as a carrier or pair nonce, is the
33
+ new code `carrier-nonce-invalid`. Nothing commits on a refusal.
34
+ - **The view**: each `RelationshipView` names the relationship's
35
+ canonical carrier-nonce entry (`carrierNonce: {nonce, generation}`) and
36
+ the counterpart's hints from the card of the enactment that opened it
37
+ (`counterpartDeliveryHints`), as signed. A re-encounter chained into
38
+ the relationship changes neither (profile RLTP-VTI-1230). Without an
39
+ offer both are absent.
40
+ - `cardBody` takes `deliveryHints`.
41
+ - **The adapter builds and reads the hint** (`./adapters/vti-mediator`,
42
+ below the port line): `deliveryHint(rootIkm, C, N)` derives this
43
+ side's connection DID and egress identity from (root, `C`, `N`), as
44
+ the factory derives the instance's trio (derived, not supplied), and
45
+ gives its hint (RLTP-VTI-1210: the JCS form of the `TSPTransport`
46
+ entry);
47
+ `readDeliveryHint(hint, C)` reads one hint strictly (1210, 1220: JSON,
48
+ byte-equal to its JCS form, exactly the four members, both identities
49
+ canonical Ed25519 `did:key` that decode to `0xed01` and 32 bytes,
50
+ `serviceEndpoint` = `C`) into `{connectionDid, egressDid, carrier}` or null;
51
+ `readDeliveryHints(hints, C, self)` reads a card's list as the side
52
+ `self` (its own connection DID and egress identity): a hint naming one
53
+ of them is ignored (RLTP-VTI-1227), then exactly one hint for `C`
54
+ (1225), else null. Both readers are total (RLTP-VTI-1220): any input
55
+ answers null or the complete identities, nothing throws — a hint that
56
+ parses but has no JCS form (a lone surrogate) included; tested over the
57
+ vector's corpus and 20 000 seeded mutations. The app passes the
58
+ identities to the wire (`peerDid`, `peerEgressDid` of the binding),
59
+ which refuses a counterpart identity that is one of its own.
60
+ - **No change of N.** The library offers no rotation of a carrier nonce
61
+ (Identity §7a.3, `generation + 1`) and no replacement after loss:
62
+ `register.carriers` is written once per relationship, at `show` or
63
+ `scan`. The profile carries none either (RLTP-VTI-1245). With one
64
+ writer of the register per holder, as in this library, `carrierNonce`
65
+ is the `N` whose identities the counterpart saw; two devices writing a
66
+ first `N` apart would make that untrue (profile Open Issue 13). A
67
+ relationship chained into another is no `RelationshipView` of its own
68
+ (only an id in `chainedFrom`) and shows no `carrierNonce`: the app
69
+ closes the adapter instance of a relationship once its id appears in
70
+ another relationship's `chainedFrom` (RLTP-VTI-1230).
71
+
3
72
  ## 0.7.0
4
73
 
5
74
  Takes up the VTI Mediator Adapter Profile 0.24: the sending form of §3a.
package/README.md CHANGED
@@ -146,6 +146,44 @@ human: `receive`, `report`, `resume`, `tick`, `recover`, `takeMessages`.
146
146
  Reads: `contacts`, `contact`, `groups`, `profile`, `prompts`, `inbox`,
147
147
  `deliveryStatus`, `deviceKey`, `replay`, `snapshot`, `subscribe`.
148
148
 
149
+ **Delivery hints** (Encounter RLTP-ENC-6080, 6090; Identity §7a.3; VTI
150
+ Mediator Adapter Profile 0.25 §1b). `show` and `scan` take a carrier
151
+ offer, `carrier: {nonce, deliveryHints}`: the relationship's carrier
152
+ nonce N (32 bytes the app draws fresh) and the hints the app built from
153
+ the wire identities its adapter derives from N. The card (the displayed
154
+ card, or the scanner's sent card) carries the hints under its proof, and
155
+ N enters the register under the relationship the card opens — at `show`
156
+ already, as the card's pair label does. More than eight hints or a hint
157
+ over 512 characters is `card-invalid` with `ref` `RLTP-ENC-6090`; an
158
+ offer without a hint, or with a hint that is no string, is
159
+ `card-invalid` without a `ref`; a nonce
160
+ that is not 32 bytes or that the register already holds is
161
+ `carrier-nonce-invalid`. The offer is act input, journaled with the act.
162
+ The library interprets no hint. Each relationship of a contact view names
163
+ the own canonical carrier-nonce entry (`carrierNonce: {nonce,
164
+ generation}`) and the counterpart's hints from the card of the enactment
165
+ that opened it (`counterpartDeliveryHints`); a re-encounter chained into
166
+ the relationship changes neither, and the chained relationship shows no
167
+ `carrierNonce`: the app closes the adapter instance of a relationship
168
+ once its id appears in another relationship's `chainedFrom`. The
169
+ library offers no rotation or replacement of N (profile RLTP-VTI-1245);
170
+ with its one writer per holder, `carrierNonce` is the N the counterpart
171
+ saw. The VTI adapter module builds and reads the hint:
172
+ `deliveryHint(rootIkm, C, N)` (derived like the adapter's trio),
173
+ `readDeliveryHint(hint, C)`, `readDeliveryHints(hints, C, self)` (profile
174
+ §1b; total readers, a hint naming `self`'s identities ignored).
175
+
176
+ ```ts
177
+ import { deliveryHint } from '@real-life/trust-protocol/adapters/vti-mediator'
178
+
179
+ // rootIkm and C: the same inputs the app gives MediatorCarrierAdapter.create
180
+ const nonce = crypto.getRandomValues(new Uint8Array(32))
181
+ const hint = await deliveryHint(rootIkm, C, nonce)
182
+ const shown = await holder.show({ when: Date.now(), actId: crypto.randomUUID(), carrier: { nonce, deliveryHints: [hint] } })
183
+ const [rel] = (await holder.contacts())[0]?.relationships ?? []
184
+ // rel?.carrierNonce: this side's N; rel?.counterpartDeliveryHints: the counterpart's hints, as signed
185
+ ```
186
+
149
187
  One actId, one result: every human act is journaled under its actId with
150
188
  its result. A repeat under the same actId answers the journaled events
151
189
  (for `sendMessage` the same `mid`) at any clock and across a lock and a
@@ -167,7 +205,7 @@ journal, and acting anew is the human's decision. Custody:
167
205
 
168
206
  ## What the root exports
169
207
 
170
- - `createHolder` and its types (`Holder`, `HolderOptions`, `HumanActOptions`,
208
+ - `createHolder` and its types (`Holder`, `HolderOptions`, `HumanActOptions`, `CarrierOffer`,
171
209
  `HolderSnapshot`).
172
210
  - The ports: `Store`, `KeyProvider`, `Entropy`, `Log`, `Access`,
173
211
  `RetryPolicy`, `DeliveryReport`, `Outbound`; `seedKeys(seed)` is the
@@ -194,7 +232,7 @@ Other entry points:
194
232
  |---|---|
195
233
  | `./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. |
196
234
  | `./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. |
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. |
235
+ | `./adapters/vti-mediator` | The VTI mediator as a transport adapter (profile 0.25): 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, `depositAddressing(mode, self, peerConnection, carrier)` gives both layers' addressing, and `deliveryHint(rootIkm, C, N)`, `readDeliveryHint(hint, C)`, `readDeliveryHints(hints, C, self)` build and read the delivery hint of §1b (total readers). |
198
236
 
199
237
  ## The modules and the rules they implement
200
238
 
@@ -314,7 +352,7 @@ This package uses its own semver; the specification uses castings.
314
352
  | 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 |
315
353
  | 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` |
316
354
  | 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) |
355
+ | transport adapter | VTI Mediator Adapter Profile 0.25 | a change of the carrier nonce N (RLTP-VTI-1245; profile Open Issue 13); 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) |
318
356
  | 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)` |
319
357
  | devices | Identity §5.5 | multi-device production: one writer per holder |
320
358
 
@@ -12,6 +12,38 @@ export declare const DECLARED: Readonly<{
12
12
  readonly duplicateWindowMs: number;
13
13
  readonly routedAckDeadlineMs: number;
14
14
  }>;
15
+ /** The counterpart's wire identities at one carrier, as its hint names them. */
16
+ export interface DeliveryHintIdentities {
17
+ connectionDid: string;
18
+ egressDid: string;
19
+ carrier: string;
20
+ }
21
+ /** This side's hint for carrier `C` in the relationship of carrier nonce
22
+ * `N` (RLTP-VTI-1210, 1215): the connection DID and the egress identity
23
+ * derived here from (root, `C`, `N`), exactly as the factory derives the
24
+ * instance's trio — derived, not supplied, so the two cannot come from
25
+ * different relationships — as the JCS form of the TSPTransport service
26
+ * entry naming the connection DID (`id`, with `#tsp`), `C`
27
+ * (`serviceEndpoint`) and the egress identity (`rltpEgress`). */
28
+ export declare function deliveryHint(rootIkm: Uint8Array, carrier: string, nonce: Uint8Array): Promise<string>;
29
+ /** One hint read strictly (RLTP-VTI-1210, 1220) for carrier `C`: JSON,
30
+ * byte-equal to its JCS form, exactly the four members, type
31
+ * TSPTransport, an `id` ending in `#tsp`, both identities distinct
32
+ * canonical Ed25519 did:key, `serviceEndpoint` byte-equal to `C`.
33
+ * Total (RLTP-VTI-1220): any other input — not a string, not JSON, no JCS
34
+ * form (a lone surrogate), any other shape — is null, ignored; it never
35
+ * throws. */
36
+ export declare function readDeliveryHint(hint: unknown, carrier: unknown): DeliveryHintIdentities | null;
37
+ /** The counterpart's wire identities at `C` from the hints of the card
38
+ * that opened the relationship, read by the side `self` (its own
39
+ * connection DID and egress identity of this relationship and carrier):
40
+ * every hint read as readDeliveryHint does; a hint naming one of `self`'s
41
+ * identities is ignored (RLTP-VTI-1227); of what remains, the one hint
42
+ * for `C` (RLTP-VTI-1225, 1240) — none, or more than one, is null: the
43
+ * relationship is not carried at `C` (RLTP-VTI-1235). Total: any input
44
+ * answers null or the identities, never a throw; without a well-formed
45
+ * `self` nothing is read. */
46
+ export declare function readDeliveryHints(hints: unknown, carrier: unknown, self: unknown): DeliveryHintIdentities | null;
15
47
  /** How a deposit reaches the mediator (RLTP-VTI-3110, 3120). */
16
48
  export type SendMode = 'routed' | 'egress-session';
17
49
  /** One TSP layer's addressing (no keys, no bytes: those are the wire's). */
@@ -1 +1 @@
1
- {"version":3,"file":"vti-mediator.d.ts","sourceRoot":"","sources":["../../src/adapters/vti-mediator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vti-mediator.d.ts","sourceRoot":"","sources":["../../src/adapters/vti-mediator.ts"],"names":[],"mappings":"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"}
@@ -20,9 +20,14 @@
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.24 (twenty-fourth casting;
23
+ // Profile: spec/adapter-vti-mediator.md v0.25 (twenty-fifth casting;
24
24
  // round journals under design/adapter-review*). A
25
- // transport adapter contract — NOT a carrier at the port.
25
+ // transport adapter contract — NOT a carrier at the port. The
26
+ // counterpart's connection DID and egress identity the wire needs come
27
+ // from the counterpart's delivery hint in the card that opened the
28
+ // relationship (profile §1b); the holder hands the hints on uninterpreted
29
+ // (RelationshipView.counterpartDeliveryHints) and this adapter derives its
30
+ // own trio from the relationship's carrier nonce (RelationshipView.carrierNonce).
26
31
  //
27
32
  // Sending form (profile §3a, lib 0.7.0): every deposit names its mode to
28
33
  // the wire. Mode `routed` (the mode of every instance from construction):
@@ -82,7 +87,7 @@
82
87
  // · A retired instance mutates nothing and refuses everything
83
88
  // except reading its ack state.
84
89
  import { jcs } from '../core.js';
85
- import { sha } from '../crypto.js';
90
+ import { anchorOfEd, edRawOfAnchor, sha } from '../crypto.js';
86
91
  import { carrierPrincipal, carrierScopedIdentity } from '../carrier-identity.js';
87
92
  // ── Declared constants (profile §2) — promises of THIS casting ──────
88
93
  // frozen: the declared promises cannot be changed at run time either
@@ -95,6 +100,89 @@ export const DECLARED = Object.freeze({
95
100
  duplicateWindowMs: 30 * 86_400_000,
96
101
  routedAckDeadlineMs: 72 * 3_600_000,
97
102
  });
103
+ const HINT_MEMBERS = jcs(['id', 'rltpEgress', 'serviceEndpoint', 'type']);
104
+ /** An Ed25519 did:key in the form RLTP-VTI-1210 fixes: `did:key:z` and the
105
+ * base58btc of multicodec 0xed01 followed by the 32-byte key, rendered
106
+ * canonically (decoding and re-encoding gives the same string). */
107
+ const edDidKey = (x) => {
108
+ // the canonical form has exactly 56 characters; checked first, so no long input reaches the base58 decoder
109
+ if (typeof x !== 'string' || x.length !== 56)
110
+ return false;
111
+ const raw = edRawOfAnchor(x);
112
+ return raw !== null && anchorOfEd(raw) === x;
113
+ };
114
+ /** This side's hint for carrier `C` in the relationship of carrier nonce
115
+ * `N` (RLTP-VTI-1210, 1215): the connection DID and the egress identity
116
+ * derived here from (root, `C`, `N`), exactly as the factory derives the
117
+ * instance's trio — derived, not supplied, so the two cannot come from
118
+ * different relationships — as the JCS form of the TSPTransport service
119
+ * entry naming the connection DID (`id`, with `#tsp`), `C`
120
+ * (`serviceEndpoint`) and the egress identity (`rltpEgress`). */
121
+ export async function deliveryHint(rootIkm, carrier, nonce) {
122
+ // snapshot at entry, as create does (R8-B2): a caller's buffer changed
123
+ // between the two derivations must not couple two relationships
124
+ const ikm = new Uint8Array(rootIkm);
125
+ const n = new Uint8Array(nonce);
126
+ const connection = await carrierScopedIdentity(ikm, carrier, n, 'connection');
127
+ const egress = await carrierScopedIdentity(ikm, carrier, n, 'egress');
128
+ return jcs({ id: connection.did + '#tsp', type: 'TSPTransport', serviceEndpoint: carrier, rltpEgress: egress.did });
129
+ }
130
+ /** One hint read strictly (RLTP-VTI-1210, 1220) for carrier `C`: JSON,
131
+ * byte-equal to its JCS form, exactly the four members, type
132
+ * TSPTransport, an `id` ending in `#tsp`, both identities distinct
133
+ * canonical Ed25519 did:key, `serviceEndpoint` byte-equal to `C`.
134
+ * Total (RLTP-VTI-1220): any other input — not a string, not JSON, no JCS
135
+ * form (a lone surrogate), any other shape — is null, ignored; it never
136
+ * throws. */
137
+ export function readDeliveryHint(hint, carrier) {
138
+ try {
139
+ return readStrict(hint, carrier);
140
+ }
141
+ catch {
142
+ return null;
143
+ }
144
+ }
145
+ function readStrict(hint, carrier) {
146
+ if (typeof hint !== 'string' || typeof carrier !== 'string' || carrier.length === 0)
147
+ return null;
148
+ const o = JSON.parse(hint);
149
+ if (o === null || typeof o !== 'object' || Array.isArray(o) || jcs(o) !== hint)
150
+ return null;
151
+ const e = o;
152
+ if (jcs(Object.keys(e).sort()) !== HINT_MEMBERS || e.type !== 'TSPTransport' || e.serviceEndpoint !== carrier)
153
+ return null;
154
+ if (typeof e.id !== 'string' || !e.id.endsWith('#tsp'))
155
+ return null;
156
+ const connectionDid = e.id.slice(0, -'#tsp'.length);
157
+ if (!edDidKey(connectionDid) || !edDidKey(e.rltpEgress) || connectionDid === e.rltpEgress)
158
+ return null;
159
+ return { connectionDid, egressDid: e.rltpEgress, carrier };
160
+ }
161
+ /** The counterpart's wire identities at `C` from the hints of the card
162
+ * that opened the relationship, read by the side `self` (its own
163
+ * connection DID and egress identity of this relationship and carrier):
164
+ * every hint read as readDeliveryHint does; a hint naming one of `self`'s
165
+ * identities is ignored (RLTP-VTI-1227); of what remains, the one hint
166
+ * for `C` (RLTP-VTI-1225, 1240) — none, or more than one, is null: the
167
+ * relationship is not carried at `C` (RLTP-VTI-1235). Total: any input
168
+ * answers null or the identities, never a throw; without a well-formed
169
+ * `self` nothing is read. */
170
+ export function readDeliveryHints(hints, carrier, self) {
171
+ try {
172
+ if (!Array.isArray(hints))
173
+ return null;
174
+ const me = self;
175
+ if (me === null || typeof me !== 'object' || !edDidKey(me.connection) || !edDidKey(me.egress))
176
+ return null;
177
+ const own = new Set([me.connection, me.egress]);
178
+ const read = hints.map((h) => readDeliveryHint(h, carrier))
179
+ .filter((x) => x !== null && !own.has(x.connectionDid) && !own.has(x.egressDid));
180
+ return read.length === 1 ? read[0] : null;
181
+ }
182
+ catch {
183
+ return null;
184
+ }
185
+ }
98
186
  const SEND_MODES = new Set(['routed', 'egress-session']);
99
187
  /** The addressing of a deposit in `mode` (RLTP-VTI-1110, 1120, 3110,
100
188
  * 3115, 3120): the inner `direct` message from this side's egress