@openvtc/trust-tasks 0.26.10 → 0.26.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +351 -0
  2. package/dist/_shared/components.d.ts +18 -0
  3. package/dist/_shared/components.d.ts.map +1 -1
  4. package/dist/index.d.ts +14 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +14 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/rooms/keys/act/0.2/payload.d.ts +546 -0
  9. package/dist/rooms/keys/act/0.2/payload.d.ts.map +1 -0
  10. package/dist/rooms/keys/act/0.2/payload.js +305 -0
  11. package/dist/rooms/keys/act/0.2/payload.js.map +1 -0
  12. package/dist/rooms/keys/act/0.3/payload.d.ts +546 -0
  13. package/dist/rooms/keys/act/0.3/payload.d.ts.map +1 -0
  14. package/dist/rooms/keys/act/0.3/payload.js +305 -0
  15. package/dist/rooms/keys/act/0.3/payload.js.map +1 -0
  16. package/dist/rooms/keys/file-key/0.2/payload.d.ts +306 -0
  17. package/dist/rooms/keys/file-key/0.2/payload.d.ts.map +1 -0
  18. package/dist/rooms/keys/file-key/0.2/payload.js +167 -0
  19. package/dist/rooms/keys/file-key/0.2/payload.js.map +1 -0
  20. package/dist/rooms/keys/open/0.2/payload.d.ts +323 -0
  21. package/dist/rooms/keys/open/0.2/payload.d.ts.map +1 -0
  22. package/dist/rooms/keys/open/0.2/payload.js +171 -0
  23. package/dist/rooms/keys/open/0.2/payload.js.map +1 -0
  24. package/dist/rooms/owner/group/add/0.2/payload.d.ts +417 -0
  25. package/dist/rooms/owner/group/add/0.2/payload.d.ts.map +1 -0
  26. package/dist/rooms/owner/group/add/0.2/payload.js +218 -0
  27. package/dist/rooms/owner/group/add/0.2/payload.js.map +1 -0
  28. package/dist/vta/_shared/0.6/witness-party.d.ts +16 -0
  29. package/dist/vta/_shared/0.6/witness-party.d.ts.map +1 -0
  30. package/dist/vta/_shared/0.6/witness-party.js +6 -0
  31. package/dist/vta/_shared/0.6/witness-party.js.map +1 -0
  32. package/dist/vta/witness/accept/0.2/payload.d.ts +499 -0
  33. package/dist/vta/witness/accept/0.2/payload.d.ts.map +1 -0
  34. package/dist/vta/witness/accept/0.2/payload.js +278 -0
  35. package/dist/vta/witness/accept/0.2/payload.js.map +1 -0
  36. package/dist/vta/witness/open/0.2/payload.d.ts +500 -0
  37. package/dist/vta/witness/open/0.2/payload.d.ts.map +1 -0
  38. package/dist/vta/witness/open/0.2/payload.js +259 -0
  39. package/dist/vta/witness/open/0.2/payload.js.map +1 -0
  40. package/dist/vta/witness/present/0.2/payload.d.ts +303 -0
  41. package/dist/vta/witness/present/0.2/payload.d.ts.map +1 -0
  42. package/dist/vta/witness/present/0.2/payload.js +170 -0
  43. package/dist/vta/witness/present/0.2/payload.js.map +1 -0
  44. package/dist/vtc/members/personhood/assert/0.2/payload.d.ts +536 -0
  45. package/dist/vtc/members/personhood/assert/0.2/payload.d.ts.map +1 -0
  46. package/dist/vtc/members/personhood/assert/0.2/payload.js +228 -0
  47. package/dist/vtc/members/personhood/assert/0.2/payload.js.map +1 -0
  48. package/dist/vtc/members/registry-consent/0.1/payload.d.ts +311 -0
  49. package/dist/vtc/members/registry-consent/0.1/payload.d.ts.map +1 -0
  50. package/dist/vtc/members/registry-consent/0.1/payload.js +183 -0
  51. package/dist/vtc/members/registry-consent/0.1/payload.js.map +1 -0
  52. package/dist/vtc/members/update/0.1/payload.d.ts +3 -3
  53. package/dist/vtc/members/update/0.1/payload.js +1 -1
  54. package/dist/vtc/members/update/0.1/payload.js.map +1 -1
  55. package/dist/witness/_shared/0.1/outcome-evidence.d.ts +16 -0
  56. package/dist/witness/_shared/0.1/outcome-evidence.d.ts.map +1 -0
  57. package/dist/witness/_shared/0.1/outcome-evidence.js +6 -0
  58. package/dist/witness/_shared/0.1/outcome-evidence.js.map +1 -0
  59. package/dist/witness/session/0.2/payload.d.ts +274 -0
  60. package/dist/witness/session/0.2/payload.d.ts.map +1 -0
  61. package/dist/witness/session/0.2/payload.js +152 -0
  62. package/dist/witness/session/0.2/payload.js.map +1 -0
  63. package/dist/witness/session/submit/0.2/payload.d.ts +295 -0
  64. package/dist/witness/session/submit/0.2/payload.d.ts.map +1 -0
  65. package/dist/witness/session/submit/0.2/payload.js +166 -0
  66. package/dist/witness/session/submit/0.2/payload.js.map +1 -0
  67. package/package.json +1 -1
  68. package/src/_shared/components.ts +17 -0
  69. package/src/index.ts +14 -0
  70. package/src/rooms/keys/act/0.2/payload.ts +380 -0
  71. package/src/rooms/keys/act/0.3/payload.ts +380 -0
  72. package/src/rooms/keys/file-key/0.2/payload.ts +224 -0
  73. package/src/rooms/keys/open/0.2/payload.ts +237 -0
  74. package/src/rooms/owner/group/add/0.2/payload.ts +288 -0
  75. package/src/vta/_shared/0.6/witness-party.ts +17 -0
  76. package/src/vta/witness/accept/0.2/payload.ts +330 -0
  77. package/src/vta/witness/open/0.2/payload.ts +336 -0
  78. package/src/vta/witness/present/0.2/payload.ts +210 -0
  79. package/src/vtc/members/personhood/assert/0.2/payload.ts +421 -0
  80. package/src/vtc/members/registry-consent/0.1/payload.ts +231 -0
  81. package/src/vtc/members/update/0.1/payload.ts +2 -2
  82. package/src/witness/_shared/0.1/outcome-evidence.ts +17 -0
  83. package/src/witness/session/0.2/payload.ts +197 -0
  84. package/src/witness/session/submit/0.2/payload.ts +212 -0
package/CHANGELOG.md CHANGED
@@ -11,6 +11,357 @@ The package versions over **its own API** — what a consumer compiles against
11
11
  not over `SPEC.md`. Below 1.0 a breaking change bumps the leading non-zero
12
12
  component.
13
13
 
14
+ ## 0.26.12 — 2026-10-16
15
+
16
+
17
+ ### Added
18
+
19
+ - **vtc/members**: Registry-consent — a member grants or withdraws their own trust-registry consent (#798)
20
+
21
+
22
+ ### Documentation
23
+
24
+ - **keys**: Sign-jws and sign-csr name their known implementation (#792)
25
+
26
+ keys/sign-jws/0.1 and keys/sign-csr/0.1 declared no knownImplementations,
27
+ so the registry showed "Not declared" for both, although a runtime
28
+ implementation exists: OpenVTC/verifiable-trust-infrastructure#2057 (VTA
29
+ custodian; merged 2026-10-13 at dda501d) serves both tasks. Its test
30
+ suite reproduces the sign-jws example's signing input and SHA-256 digest,
31
+ and checks that a sign-csr request's signature verifies.
32
+
33
+ Front matter only; no wire or binding change.
34
+
35
+
36
+
37
+ ### Specifications
38
+
39
+ - **witness**: Add 0.2 — a member presentation on submit, and outcome evidence on personhood/assert, replace the ext stop-gaps (#799)
40
+
41
+ Two members implementations carried in a vendor extension,
42
+ ext["org.openvtc.witness"], become specified members, so any witness and
43
+ any community reads them.
44
+
45
+ - witness/session/submit/0.2: optional memberPresentation — a VP by the
46
+ member DID, for authentication, bound to the session's challenge and
47
+ domain, carrying the eligibility credentials (a membership credential
48
+ naming the member DID). Neither party nor the witness; a failure where
49
+ relied on is presentationInvalid; a witness not using it MUST NOT treat it
50
+ as satisfying anything. The member DID never appears in the VWC, and the
51
+ witness keeps neither it nor the presentation. Privacy: links the pairwise
52
+ relationship DID to the member DID at the witness; proves co-possession in
53
+ one session, not one person; the alternatives are recorded.
54
+ - witness/session/0.2: same payload; its outcomeEvidence names
55
+ submit/0.2#response. The declaration belongs to the initiating document's
56
+ specification (SPEC §7.3 item 20, §4.9.4 check 3), so a 0.1 session cannot
57
+ close with a 0.2 submit. Versions pair one to one.
58
+ - vtc/members/personhood/assert/0.2: optional outcomeEvidence (1–16
59
+ entries, each {session, outcome} carried byte for byte). A VWC counts only
60
+ from a trusted witness, paired by §4.9.4's four checks and the witnessing
61
+ checks; unpaired entries are ignored. A member presents only the VWCs it
62
+ selects.
63
+ - witness/_shared/0.1/outcome-evidence: OutcomeEvidence, shared by
64
+ personhood/assert/0.2 and vta/witness/accept/0.2.
65
+ - vta/witness/{open,present,accept}/0.2 + vta/_shared/0.6 conventions:
66
+ conduct 0.2 sessions; present puts the member presentation in
67
+ memberPresentation; open drops memberLinkUnsupported; a 0.2 session is
68
+ continued only by 0.2 tasks. The 0.1 tasks are unchanged.
69
+
70
+ Bindings regenerated (Rust, TS, Go, Dart).
71
+
72
+ - **rooms/keys**: Act 0.3 — a member takes up a community's offer of a room as themself, with only a KeyPackage their key holder minted (#797)
73
+
74
+ `vtc/rooms/offers/list/0.1` and `vtc/rooms/offers/accept/0.1` must be signed
75
+ as the DID the community addressed its offer to. That DID is the member as
76
+ the community knows them — typically a persona their key holder holds — so
77
+ no surface the member acts from can sign either, and `rooms/keys/act/0.2`
78
+ could not complete them: its `type` pattern admits only `rooms/`, and its
79
+ closed table lists neither. A member could be offered a room and never
80
+ reach it.
81
+
82
+ act 0.3:
83
+ - The table gains `vtc/rooms/offers/list/0.1` and
84
+ `vtc/rooms/offers/accept/0.1`, with no presentation inserted: the member
85
+ holds no room authority yet, and the community checks the offer against
86
+ the document's proof. The `type` pattern admits `vtc/rooms/offers/` beside
87
+ `rooms/` and nothing else of the vtc family (new invalid example: an
88
+ administrator's `vtc/rooms/community/members/add` is refused by schema).
89
+ - Producer item 2: `issuer` REQUIRED for the offer types (the DID the offer
90
+ is addressed to); `recipient` is the community.
91
+ - Recipient item 2b (new): for the offer types, act as `issuer` iff the
92
+ recipient holds a key `issuer`'s DID document lists for `authentication`
93
+ and the caller may act as it; `issuerNotPrincipal` otherwise,
94
+ `principalAmbiguous` when absent; never pick for the caller. No room
95
+ credential is required.
96
+ - Recipient item 10 / Producer item 5 (new): an acceptance's `keyPackage`
97
+ is completed only when the recipient minted it with rooms/keys/key-package
98
+ for that room and that member and still holds its private half (unused,
99
+ unexpired), compared by KeyPackageRef, never by its leaf credential;
100
+ otherwise the new code `keyPackageNotHeld`.
101
+ - Security & Privacy: why item 10 is required — a KeyPackage the key holder
102
+ did not mint becomes the member's leaf with keys someone else holds (the
103
+ client), opening every later record and signing group messages as the
104
+ member outside the key holder and beyond any withdrawal of the client's
105
+ standing; the leaf credential is signed by the leaf key, not the member's
106
+ DID, so the community cannot tell, and only the minting key holder can.
107
+ And why the offer types belong in act rather than a task of their own:
108
+ same entitlement, same delegate refusal (item 3), same closed table — one
109
+ signing-as-the-member surface to audit, not two — and a key holder that
110
+ accepted itself would call the community and route the answer, which item
111
+ 7 rules out.
112
+ - Examples: an acceptance completed as the member; a `keyPackageNotHeld`
113
+ refusal.
114
+
115
+ vtc/rooms/offers/{list,accept}/0.1, in place: one paragraph each under
116
+ Authorization pointing a surface without the member's keys at act 0.3.
117
+ Prose only; their wire is unchanged (SPEC §5.2 editorial, as #783).
118
+
119
+ - **vtc/rooms/community/members/remove**: The answer says what removal did in its structured members, not in a notice — clarified in place (#796)
120
+
121
+ Item 4 required the community to "say in its record and its answer that
122
+ removal does not recall what was read", but the response schema has no
123
+ member to say it in (`additionalProperties: false`). An implementation
124
+ could comply only through `ext`, which a caller cannot depend on — so the
125
+ requirement promised callers something the wire never guaranteed.
126
+
127
+ Two ways out: add an optional `notice` member, or drop "and its answer".
128
+ This drops it, and puts the obligation where it does its work:
129
+
130
+ - Community item 4: MUST NOT represent a removal, in its record or answer,
131
+ as recalling what was read, re-sealing what was written, or revoking the
132
+ authority credential. The answer's structured members are what it says:
133
+ `member.state` `removed`, `member.validUntil` (when a host stops honouring
134
+ the authority credential), and `epoch` (sealed tier, admitted member: the
135
+ first epoch sealed without them; absent means nothing was withdrawn
136
+ cryptographically — an open room, or a withdrawn offer).
137
+ - Producer (new): the administrator's surface SHOULD show what removal does
138
+ and does not do on the room's tier, and the member's `validUntil`, before
139
+ the request is signed and before any step-up gesture bound to it; SHOULD
140
+ report the answer from `validUntil`/`epoch`; MUST NOT report any removal
141
+ as ending access to what was already read.
142
+ - New subsection *Why the answer carries no notice*.
143
+
144
+ Why not a field: the statement is identical for every removal on a tier, so
145
+ it carries nothing the caller cannot render from the specification, the
146
+ tier, `validUntil` and `epoch`; as a field it would be server-chosen,
147
+ unlocalised prose shown to an administrator as guidance; and it would
148
+ arrive after the decision. The moment it matters is before the requester
149
+ commits, when a bound step-up ties them to this one document — which is a
150
+ producer obligation, not a response member. An implementation MAY still
151
+ carry a statement under `ext`; a caller MUST NOT depend on one.
152
+
153
+ - **rooms/owner/group**: Add 0.2 — a repeated admission is answered with its Welcome, not alreadyMember (#795)
154
+
155
+ `rooms/owner/group/add/0.1` item 6 settles a pending admission at the next
156
+ request, which keeps the room and the owner's group in step across a lost
157
+ host reply. But the next request is, in the case that matters, the same
158
+ request again: the caller lost the answer and retries. 0.1 settled the
159
+ pending admission, found `member` already in the group, and refused the
160
+ retry `alreadyMember`. The Welcome — the only way the newcomer can join —
161
+ was returned to nobody. The same happens when the recipient applied the
162
+ admission and its own reply to its caller was lost. `vtc/rooms/offers/accept`
163
+ already promises its callers that retrying is safe; under 0.1 it was not.
164
+
165
+ add 0.2:
166
+ - Item 8 (new): the recipient keeps, with the group state, the last
167
+ admission it applied for the room — `member`, the KeyPackage's
168
+ `KeyPackageRef` (RFC 9420 §5.2), epoch, Welcome and ratchet tree — until
169
+ its next advance of the room or 24 hours, whichever comes first. A request
170
+ naming the same room, the same `member` (string-equal) and a KeyPackage of
171
+ the same `KeyPackageRef` is answered, once item 1 and the authorization
172
+ checks pass, with that admission's epoch, Welcome and tree; the recipient
173
+ does not advance the room, contact the host, change its group or build a
174
+ fresh Welcome. Anything else for a member with a leaf is `alreadyMember`.
175
+ - Item 6 hands over to item 8 when the pending admission it applies is the
176
+ one the request repeats.
177
+ - New section *Repeating an admission*: why re-serving is safe (the Welcome
178
+ is HPKE-sealed to the KeyPackage's init key and addressed by its
179
+ KeyPackageRef, RFC 9420 §12.4.3.1; the joiner discards the private half on
180
+ use or expiry, so a late copy opens nothing), why the match is exact (equal
181
+ KeyPackageRefs mean byte-identical KeyPackages, hence the same init key; a
182
+ different KeyPackage for the same member would be a second leaf), and why
183
+ retention is short.
184
+ - `alreadyMember` and `hostUnreachable` meanings updated; retention and
185
+ exposure rationales say what is kept. No code added; payload and response
186
+ schemas unchanged.
187
+
188
+ vtc/rooms/offers/accept/0.1, in place: "Repeating an accept" now points at
189
+ group/add 0.2 items 6 and 8, says the community repeats its own request to
190
+ its VTA unchanged, and that the community's VTA serves group/add at 0.2 or
191
+ later. Prose only; its wire is unchanged, and it now describes what its own
192
+ existing retry promise requires (SPEC §5.2 editorial, as #783).
193
+
194
+ - **vtc/vetting/vetters/pcs-root**: A member may recover a lost enrolment answer within the same label (#791)
195
+
196
+ pcs-root/0.1 refused every second enrolment under a label as
197
+ alreadyEnrolled. That is right for counting, but it made a lost answer
198
+ unrecoverable for the rest of the label: if the community issued and the
199
+ answer never reached the vetter in a form it could open (late arrival, a
200
+ client restart losing the blinding state, a transport drop), the vetter
201
+ held no credential and was locked out of hidden vetting until the next
202
+ vetter/<YYYY-MM> label. This happened in a live run.
203
+
204
+ vtc/vetting/vetters/pcs-root/0.1 (draft, in place per SPEC §5.2), new
205
+ "Recovering a lost answer" section under Authorization:
206
+ - A community MAY answer a second request under a label the member is
207
+ enrolled in with a fresh issuance over the new blinded request, when its
208
+ `id` is the one recorded for the member. Every first-enrolment check still
209
+ applies (live grant, proof, issuedAt, wrongLabel, badRequest).
210
+ - It MUST NOT re-issue unless its suite binds the blinded request to the
211
+ secret `id` is derived from, so every credential under one `id` yields
212
+ the same tags. That binding is what stops a re-issue counting as a second
213
+ vetter; without it the community refuses with alreadyEnrolled.
214
+ - A different `id` is still identifierRebound. No second enrolment is
215
+ recorded. Re-issues SHOULD be bounded per member per label, refused beyond
216
+ the bound with alreadyEnrolled, and audited.
217
+ - What this gives up is "exactly one credential object per member per
218
+ label", not "each member counted once". Distinctness is by tag.
219
+ - Client note: re-run vta/pcs/root-request for the label (it replaces the
220
+ blinding state and keeps the key, so the `id`), send, and pass the answer
221
+ to vta/pcs/root-accept. alreadyEnrolled now means the community does not
222
+ re-issue, or no longer will for this label.
223
+
224
+ The alreadyEnrolled meaning, the proof rationale and the "record only after
225
+ signing" note say the same. hidden/publish/0.1's pointer to pcs-root no
226
+ longer says a second enrolment is impossible. Bindings regenerated.
227
+
228
+ The issue's alternative, an administrator task to clear an enrolment, is
229
+ not taken: re-issuance under the same `id` recovers without an operator
230
+ and without a record of the member's enrolment being erased.
231
+
232
+ - **vtc/join-requests**: Submit and supplement say why a hidden-vetting challenge was refused (#790)
233
+
234
+ A hidden-vetting proof is bound to a single-use challenge issued over
235
+ vtc/vetting/pcs-challenge, and the community spends that challenge when it
236
+ counts the proof. Neither vtc/join-requests/submit nor
237
+ vtc/join-requests/supplement declared a code for a refused challenge, so
238
+ implementations fell back to malformedRequest. An applicant could not tell
239
+ an expired challenge from a spent one, or either from a client bug.
240
+
241
+ submit/0.2, submit/0.3 and supplement/0.1 (draft, in place per SPEC §5.2)
242
+ each declare four codes under the task's own name, none retryable:
243
+ - challengeNotIssued: no challenge held for the applicant's DID;
244
+ - challengeAlreadyUsed: spent by an earlier submission or supplement;
245
+ - challengeExpired: past expiresAt, details MAY carry expiredAt (the
246
+ details schema does not close the object, so an implementation's own
247
+ markers still validate);
248
+ - challengeMismatch: bound to a value other than the open challenge,
249
+ which this attempt spends.
250
+
251
+ A new "Hidden-vetting challenge" section in each says where the proof
252
+ travels (extensions.hiddenVetting), that counting it spends the open
253
+ challenge whether or not the applicant is then admitted, that the message
254
+ never echoes the challenge value, that the value is discarded on use, and
255
+ that a value-free spent marker MAY be kept until expiry so a repeat attempt
256
+ is told challengeAlreadyUsed rather than challengeNotIssued. Recovery is a
257
+ new challenge and a new proof. submit/0.3 adds that a producer SHOULD name
258
+ its criterion on a hidden-vetting submission. supplement/0.1's
259
+ `extensions` is no longer described as wholly uninterpreted, and
260
+ pcs-challenge/0.1's Retention permits the spent marker and points at the
261
+ codes.
262
+
263
+ The issue's note about several hidden-vetting criteria spending one
264
+ challenge is moot: vtc/vetting/hidden/publish refuses a second criterion
265
+ (otherCriterion, #734). Bindings regenerated (Rust ERROR_CODES).
266
+
267
+ - **vtc/members/update**: PublishConsent may be withdrawn by an administrator, never granted — consentGrantForbidden (#789)
268
+
269
+ A member's consent to trust-registry publication is the member's own
270
+ privacy decision, given with `registryConsent` on vtc/join-requests/submit.
271
+ update/0.1 listed `publishConsent` among the fields an administrator may
272
+ change with no direction, so an administrator could raise it and publish
273
+ someone who said no.
274
+
275
+ vtc/members/update/0.1 (draft, in place per SPEC §5.2):
276
+ - `publishConsent` MAY lower consent (true -> false, e.g. a takedown) and
277
+ MAY restate the current value. It MUST NOT raise it: consent becomes true
278
+ only through the member's own registryConsent on a join submit, including
279
+ a rejoin, which writes a fresh member record.
280
+ - New error vtc/members/update:consentGrantForbidden (not retryable),
281
+ checked after notFound and adminRoleForbidden. A refused raise rejects the
282
+ whole update; no other field in the request is applied.
283
+ - A withdrawal: the community SHOULD remove the member's published registry
284
+ record at its next sync, and MUST NOT publish the member again until the
285
+ member consents anew.
286
+ - Security & Privacy says why consent runs one way. Bindings regenerated.
287
+
288
+ ## 0.26.11 — 2026-10-16
289
+
290
+
291
+ ### Specifications
292
+
293
+ - **rooms/keys**: Act 0.2 — the member is the subject, and a document that names no room names its member (#787)
294
+
295
+ `rooms/keys/act/0.1` declared `subjectPath: /document/payload/roomId` and
296
+ resolved the member to act as "among the members of the document's room".
297
+ Three types in its own table carry no `roomId` — `rooms/blobs/chunk/0.1`
298
+ (`downloadId`, `index`) and `rooms/blobs/upload/{commit,abort}/0.2`
299
+ (`uploadId`) — and for them 0.1 defined neither the subject nor how the
300
+ recipient finds the document's room, while a producer MAY omit `issuer`.
301
+ A conforming request could leave the recipient nothing to resolve the
302
+ member from.
303
+
304
+ act 0.2:
305
+ - The table: these types carry no `roomId`; the member is the document's
306
+ `issuer`, which the producer MUST set to the member whose request
307
+ opened the transfer.
308
+ - Producer item 2: `issuer` MUST be set for a type that names no room
309
+ (MAY → MUST for those types; unchanged otherwise).
310
+ - Recipient item 2a: for a type that names no room, act as `issuer` if it
311
+ is a member the recipient holds keys for and the caller may act as;
312
+ otherwise `issuerNotPrincipal`; `issuer` absent is `principalAmbiguous`.
313
+ The recipient MUST NOT pick a member for the caller (not its only one,
314
+ not one inferred from the transfer identifier).
315
+ - `subjectPath` moves to `/document/issuer`. The subject is the party
316
+ whose authority the task exercises (`actsAsSubject: true`) — the
317
+ member, whose key signs — which is the question a delegated-execution
318
+ policy point asks of `subjectPath` ("does the executing agent speak
319
+ for this subject?") and exactly what Recipient item 2 decides. The room
320
+ is the resource the completed document addresses, not a party the caller
321
+ speaks for, and three of the table's types do not name one. Where
322
+ `issuer` is absent (a room-naming type, one candidate member) the
323
+ subject is the member item 2 resolves, and a recipient evaluating
324
+ policy or audit against the subject MUST use it and MUST NOT treat the
325
+ unresolved pointer as "no subject".
326
+ - `principalAmbiguous` / `issuerNotPrincipal` meanings cover the
327
+ room-less case. No code added; payload and response schemas unchanged
328
+ except the `issuer` description.
329
+ - Examples: a direct upload's commit completed as the member; a chunk
330
+ refused `principalAmbiguous`. Invalid example: a non-DID `issuer`.
331
+
332
+ - **rooms/keys**: File-key and open 0.2 — unknownEpoch says `removed` when catching up cannot help (#786)
333
+
334
+ `rooms/keys/file-key/0.1` gave `unknownEpoch` two reasons in a closed
335
+ details schema — `notDelivered` and `beyondChain` — and defined
336
+ `notDelivered` as "E is later than any epoch it holds". A removal leaves
337
+ the oracle's group where it was, so a file sealed after the oracle's
338
+ principal was removed matches that definition too. The oracle could only
339
+ say `notDelivered`, telling the caller to catch up with the room's
340
+ commits, and no commit will ever make that epoch derivable for a removed
341
+ member: a caller following the reason retried forever.
342
+ `rooms/keys/open/0.1` declared `unknownEpoch` with no details schema at
343
+ all, so a caller could not tell the two cases apart there either, and an
344
+ implementation already sends an undeclared `reason: removed`.
345
+
346
+ file-key 0.2:
347
+ - `unknownEpoch.details.reason` gains `removed`, and `details` gains
348
+ `removedAtEpoch` (integer, minimum 1).
349
+ - Oracle item 4: `removed`, with `removedAtEpoch`, when a commit the
350
+ oracle processed removed its principal from the room's group at
351
+ `removedAtEpoch` and E is at or after it — no later commit will make E
352
+ derivable, so the caller MUST NOT be told to catch up. It takes
353
+ precedence: an oracle that knows of such a removal MUST NOT answer
354
+ `notDelivered` for an E at or after it.
355
+ - Caller: acts on `details.reason`, never on the message; after `removed`
356
+ it MUST NOT retry after catching up.
357
+ - A `removed` refusal example, a Security & Privacy sentence, and a
358
+ "What changed from 0.1" section.
359
+
360
+ open 0.2 declares the same three reasons and the same details schema for
361
+ `rooms/keys/open:unknownEpoch`, with the same conformance text
362
+ (`beyondChain` for an epoch earlier than the oracle's current one that its
363
+ retained chain does not reach).
364
+
14
365
  ## 0.26.10 — 2026-10-16
15
366
 
16
367
 
@@ -5537,6 +5537,11 @@ export interface EpochLink {
5537
5537
  */
5538
5538
  nonce: string;
5539
5539
  }
5540
+ /**
5541
+ * A whole Trust Task document — `id`, `type`, `payload` and every other member, `proof` included — carried exactly as it was sent or received, never re-serialised: a task digest and a proof are taken over its members, and a re-serialised copy reproduces neither reliably. Typed as an open object so every member survives; the checks that give it meaning belong to the task that reads it.
5542
+ */
5543
+ export interface EvidenceDocument {
5544
+ }
5540
5545
  /**
5541
5546
  * The authoritative SPEC §7.3 item 14 exposure class of the pending task, derived by the executor from the compiled handler it is about to invoke — never from the registry's declared value.
5542
5547
  */
@@ -6617,6 +6622,19 @@ export interface OfferCredentials {
6617
6622
  */
6618
6623
  authority: string;
6619
6624
  }
6625
+ /**
6626
+ * One witnessing session's outcome evidence. `session` is the initiating witness/session document; `outcome` is the terminal witness/session/submit #response that the initiating document's own specification declares as its outcome evidence, under the witness's proof, delivering the VWC and its vwcDigestMultibase. A consumer pairs them with a presented VWC by SPEC §4.9.4's four checks and the witnessing checks of witness/session/submit (This response is the outcome evidence).
6627
+ */
6628
+ export interface OutcomeEvidence {
6629
+ /**
6630
+ * The witness/session document that opened the session. The VWC's taskContext is its id and its taskDigestMultibase is computed over it (SPEC §4.9.3).
6631
+ */
6632
+ session: EvidenceDocument;
6633
+ /**
6634
+ * The witness/session/submit #response that closed the session, under the witness's proof. It carries the VWC and its vwcDigestMultibase.
6635
+ */
6636
+ outcome: EvidenceDocument;
6637
+ }
6620
6638
  /**
6621
6639
  * How the uploader will cut a blob for direct transfer, committed before any byte moves: one storage object, written in `partCount` parts of `partSize` bytes (the last may be shorter), each with its digest. Independent of the chunk manifest, because storage imposes part sizes a chunk document cannot carry; the chunk manifest still describes the blob and readers still check it.
6622
6640
  *