@openvtc/trust-tasks 0.27.1 → 0.27.3

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 (228) hide show
  1. package/CHANGELOG.md +218 -0
  2. package/dist/_runtime/consume.d.ts +2 -1
  3. package/dist/_runtime/consume.d.ts.map +1 -1
  4. package/dist/_runtime/consume.js +26 -1
  5. package/dist/_runtime/consume.js.map +1 -1
  6. package/dist/_runtime/document.d.ts +9 -0
  7. package/dist/_runtime/document.d.ts.map +1 -1
  8. package/dist/_runtime/document.js +15 -1
  9. package/dist/_runtime/document.js.map +1 -1
  10. package/dist/_runtime/freshness.d.ts +4 -2
  11. package/dist/_runtime/freshness.d.ts.map +1 -1
  12. package/dist/_runtime/freshness.js +9 -6
  13. package/dist/_runtime/freshness.js.map +1 -1
  14. package/dist/_shared/components.d.ts +346 -23
  15. package/dist/_shared/components.d.ts.map +1 -1
  16. package/dist/device/list/0.1/payload.d.ts +4 -4
  17. package/dist/device/list/0.1/payload.d.ts.map +1 -1
  18. package/dist/device/list/0.1/payload.js +4 -2
  19. package/dist/device/list/0.1/payload.js.map +1 -1
  20. package/dist/device/list/0.2/payload.d.ts +4 -4
  21. package/dist/device/list/0.2/payload.d.ts.map +1 -1
  22. package/dist/device/list/0.2/payload.js +4 -2
  23. package/dist/device/list/0.2/payload.js.map +1 -1
  24. package/dist/device/register/0.1/payload.d.ts +4 -4
  25. package/dist/device/register/0.1/payload.d.ts.map +1 -1
  26. package/dist/device/register/0.1/payload.js +4 -2
  27. package/dist/device/register/0.1/payload.js.map +1 -1
  28. package/dist/device/register/0.2/payload.d.ts +4 -4
  29. package/dist/device/register/0.2/payload.d.ts.map +1 -1
  30. package/dist/device/register/0.2/payload.js +4 -2
  31. package/dist/device/register/0.2/payload.js.map +1 -1
  32. package/dist/index.d.ts +25 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +25 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/rooms/_shared/0.1/room.d.ts +1 -1
  37. package/dist/rooms/_shared/0.1/room.d.ts.map +1 -1
  38. package/dist/rooms/create/0.2/payload.d.ts +534 -0
  39. package/dist/rooms/create/0.2/payload.d.ts.map +1 -0
  40. package/dist/rooms/create/0.2/payload.js +293 -0
  41. package/dist/rooms/create/0.2/payload.js.map +1 -0
  42. package/dist/rooms/epoch/chain/0.2/payload.d.ts +534 -0
  43. package/dist/rooms/epoch/chain/0.2/payload.d.ts.map +1 -0
  44. package/dist/rooms/epoch/chain/0.2/payload.js +292 -0
  45. package/dist/rooms/epoch/chain/0.2/payload.js.map +1 -0
  46. package/dist/rooms/epoch/prune/0.2/payload.d.ts +467 -0
  47. package/dist/rooms/epoch/prune/0.2/payload.d.ts.map +1 -0
  48. package/dist/rooms/epoch/prune/0.2/payload.js +251 -0
  49. package/dist/rooms/epoch/prune/0.2/payload.js.map +1 -0
  50. package/dist/rooms/info/0.2/payload.d.ts +1129 -0
  51. package/dist/rooms/info/0.2/payload.d.ts.map +1 -0
  52. package/dist/rooms/info/0.2/payload.js +618 -0
  53. package/dist/rooms/info/0.2/payload.js.map +1 -0
  54. package/dist/rooms/keys/backfill/0.2/payload.d.ts +380 -0
  55. package/dist/rooms/keys/backfill/0.2/payload.d.ts.map +1 -0
  56. package/dist/rooms/keys/backfill/0.2/payload.js +197 -0
  57. package/dist/rooms/keys/backfill/0.2/payload.js.map +1 -0
  58. package/dist/rooms/keys/browse/0.1/payload.d.ts +4 -4
  59. package/dist/rooms/keys/browse/0.1/payload.js +2 -2
  60. package/dist/rooms/keys/browse/0.1/payload.js.map +1 -1
  61. package/dist/rooms/keys/browse/0.2/payload.d.ts +941 -0
  62. package/dist/rooms/keys/browse/0.2/payload.d.ts.map +1 -0
  63. package/dist/rooms/keys/browse/0.2/payload.js +558 -0
  64. package/dist/rooms/keys/browse/0.2/payload.js.map +1 -0
  65. package/dist/rooms/keys/chain/0.2/payload.d.ts +450 -0
  66. package/dist/rooms/keys/chain/0.2/payload.d.ts.map +1 -0
  67. package/dist/rooms/keys/chain/0.2/payload.js +248 -0
  68. package/dist/rooms/keys/chain/0.2/payload.js.map +1 -0
  69. package/dist/rooms/keys/profile/read/0.1/payload.d.ts +4 -4
  70. package/dist/rooms/keys/profile/read/0.1/payload.js +2 -2
  71. package/dist/rooms/keys/profile/read/0.1/payload.js.map +1 -1
  72. package/dist/rooms/keys/read/0.1/payload.d.ts +4 -4
  73. package/dist/rooms/keys/read/0.1/payload.js +2 -2
  74. package/dist/rooms/keys/read/0.1/payload.js.map +1 -1
  75. package/dist/rooms/owner/anchor/0.1/payload.d.ts +4 -4
  76. package/dist/rooms/owner/anchor/0.1/payload.js +2 -2
  77. package/dist/rooms/owner/anchor/0.1/payload.js.map +1 -1
  78. package/dist/rooms/records/get/0.1/payload.d.ts +4 -4
  79. package/dist/rooms/records/get/0.1/payload.js +2 -2
  80. package/dist/rooms/records/get/0.1/payload.js.map +1 -1
  81. package/dist/rooms/records/get/0.2/payload.d.ts +4 -4
  82. package/dist/rooms/records/get/0.2/payload.js +2 -2
  83. package/dist/rooms/records/get/0.2/payload.js.map +1 -1
  84. package/dist/rooms/records/list/0.1/payload.d.ts +4 -4
  85. package/dist/rooms/records/list/0.1/payload.js +2 -2
  86. package/dist/rooms/records/list/0.1/payload.js.map +1 -1
  87. package/dist/rooms/records/list/0.2/payload.d.ts +4 -4
  88. package/dist/rooms/records/list/0.2/payload.js +2 -2
  89. package/dist/rooms/records/list/0.2/payload.js.map +1 -1
  90. package/dist/rooms/records/list/0.3/payload.d.ts +970 -0
  91. package/dist/rooms/records/list/0.3/payload.d.ts.map +1 -0
  92. package/dist/rooms/records/list/0.3/payload.js +526 -0
  93. package/dist/rooms/records/list/0.3/payload.js.map +1 -0
  94. package/dist/rooms/records/prune/0.1/payload.d.ts +706 -0
  95. package/dist/rooms/records/prune/0.1/payload.d.ts.map +1 -0
  96. package/dist/rooms/records/prune/0.1/payload.js +374 -0
  97. package/dist/rooms/records/prune/0.1/payload.js.map +1 -0
  98. package/dist/rooms/records/put/0.3/payload.d.ts +1212 -0
  99. package/dist/rooms/records/put/0.3/payload.d.ts.map +1 -0
  100. package/dist/rooms/records/put/0.3/payload.js +646 -0
  101. package/dist/rooms/records/put/0.3/payload.js.map +1 -0
  102. package/dist/rooms/records/retention/set/0.1/payload.d.ts +521 -0
  103. package/dist/rooms/records/retention/set/0.1/payload.d.ts.map +1 -0
  104. package/dist/rooms/records/retention/set/0.1/payload.js +276 -0
  105. package/dist/rooms/records/retention/set/0.1/payload.js.map +1 -0
  106. package/dist/vault/credentials/present/0.1/payload.d.ts +407 -0
  107. package/dist/vault/credentials/present/0.1/payload.d.ts.map +1 -0
  108. package/dist/vault/credentials/present/0.1/payload.js +217 -0
  109. package/dist/vault/credentials/present/0.1/payload.js.map +1 -0
  110. package/dist/vault/credentials/query/0.1/payload.d.ts +12 -0
  111. package/dist/vault/credentials/query/0.1/payload.d.ts.map +1 -1
  112. package/dist/vault/credentials/query/0.1/payload.js +4 -0
  113. package/dist/vault/credentials/query/0.1/payload.js.map +1 -1
  114. package/dist/vta/webvh/dids/create/1.2/payload.d.ts +961 -0
  115. package/dist/vta/webvh/dids/create/1.2/payload.d.ts.map +1 -0
  116. package/dist/vta/webvh/dids/create/1.2/payload.js +480 -0
  117. package/dist/vta/webvh/dids/create/1.2/payload.js.map +1 -0
  118. package/dist/vtc/_shared/0.1/room-migration.d.ts +16 -0
  119. package/dist/vtc/_shared/0.1/room-migration.d.ts.map +1 -0
  120. package/dist/vtc/_shared/0.1/room-migration.js +6 -0
  121. package/dist/vtc/_shared/0.1/room-migration.js.map +1 -0
  122. package/dist/vtc/_shared/0.1/room-storage.d.ts +1 -1
  123. package/dist/vtc/_shared/0.1/room-storage.d.ts.map +1 -1
  124. package/dist/vtc/_shared/0.2/room-storage.d.ts +16 -0
  125. package/dist/vtc/_shared/0.2/room-storage.d.ts.map +1 -0
  126. package/dist/vtc/_shared/0.2/room-storage.js +6 -0
  127. package/dist/vtc/_shared/0.2/room-storage.js.map +1 -0
  128. package/dist/vtc/admin/events/_shared/0.4/topic.d.ts +31 -0
  129. package/dist/vtc/admin/events/_shared/0.4/topic.d.ts.map +1 -0
  130. package/dist/vtc/admin/events/_shared/0.4/topic.js +6 -0
  131. package/dist/vtc/admin/events/_shared/0.4/topic.js.map +1 -0
  132. package/dist/vtc/admin/events/event/0.4/payload.d.ts +172 -0
  133. package/dist/vtc/admin/events/event/0.4/payload.d.ts.map +1 -0
  134. package/dist/vtc/admin/events/event/0.4/payload.js +103 -0
  135. package/dist/vtc/admin/events/event/0.4/payload.js.map +1 -0
  136. package/dist/vtc/admin/events/subscribe/0.4/payload.d.ts +409 -0
  137. package/dist/vtc/admin/events/subscribe/0.4/payload.d.ts.map +1 -0
  138. package/dist/vtc/admin/events/subscribe/0.4/payload.js +238 -0
  139. package/dist/vtc/admin/events/subscribe/0.4/payload.js.map +1 -0
  140. package/dist/vtc/rooms/get/0.2/payload.d.ts +1966 -0
  141. package/dist/vtc/rooms/get/0.2/payload.d.ts.map +1 -0
  142. package/dist/vtc/rooms/get/0.2/payload.js +976 -0
  143. package/dist/vtc/rooms/get/0.2/payload.js.map +1 -0
  144. package/dist/vtc/rooms/storage/migrate/0.2/payload.d.ts +595 -0
  145. package/dist/vtc/rooms/storage/migrate/0.2/payload.d.ts.map +1 -0
  146. package/dist/vtc/rooms/storage/migrate/0.2/payload.js +336 -0
  147. package/dist/vtc/rooms/storage/migrate/0.2/payload.js.map +1 -0
  148. package/dist/vtc/storage/configs/create/0.1/payload.d.ts +1 -1
  149. package/dist/vtc/storage/configs/create/0.1/payload.d.ts.map +1 -1
  150. package/dist/vtc/storage/configs/create/0.2/payload.d.ts +1360 -0
  151. package/dist/vtc/storage/configs/create/0.2/payload.d.ts.map +1 -0
  152. package/dist/vtc/storage/configs/create/0.2/payload.js +783 -0
  153. package/dist/vtc/storage/configs/create/0.2/payload.js.map +1 -0
  154. package/dist/vtc/storage/configs/get/0.1/payload.d.ts +1 -1
  155. package/dist/vtc/storage/configs/get/0.1/payload.d.ts.map +1 -1
  156. package/dist/vtc/storage/configs/get/0.2/payload.d.ts +1854 -0
  157. package/dist/vtc/storage/configs/get/0.2/payload.d.ts.map +1 -0
  158. package/dist/vtc/storage/configs/get/0.2/payload.js +1075 -0
  159. package/dist/vtc/storage/configs/get/0.2/payload.js.map +1 -0
  160. package/dist/vtc/storage/configs/list/0.1/payload.d.ts +1 -1
  161. package/dist/vtc/storage/configs/list/0.1/payload.d.ts.map +1 -1
  162. package/dist/vtc/storage/configs/list/0.2/payload.d.ts +1955 -0
  163. package/dist/vtc/storage/configs/list/0.2/payload.d.ts.map +1 -0
  164. package/dist/vtc/storage/configs/list/0.2/payload.js +1125 -0
  165. package/dist/vtc/storage/configs/list/0.2/payload.js.map +1 -0
  166. package/dist/vtc/storage/configs/update/0.1/payload.d.ts +1 -1
  167. package/dist/vtc/storage/configs/update/0.1/payload.d.ts.map +1 -1
  168. package/dist/vtc/storage/configs/update/0.2/payload.d.ts +1362 -0
  169. package/dist/vtc/storage/configs/update/0.2/payload.d.ts.map +1 -0
  170. package/dist/vtc/storage/configs/update/0.2/payload.js +782 -0
  171. package/dist/vtc/storage/configs/update/0.2/payload.js.map +1 -0
  172. package/dist/vtc/storage/credentials/set/0.1/payload.d.ts +1 -1
  173. package/dist/vtc/storage/credentials/set/0.1/payload.d.ts.map +1 -1
  174. package/dist/vtc/storage/credentials/set/0.2/payload.d.ts +979 -0
  175. package/dist/vtc/storage/credentials/set/0.2/payload.d.ts.map +1 -0
  176. package/dist/vtc/storage/credentials/set/0.2/payload.js +573 -0
  177. package/dist/vtc/storage/credentials/set/0.2/payload.js.map +1 -0
  178. package/package.json +1 -1
  179. package/src/_runtime/consume.ts +26 -2
  180. package/src/_runtime/document.ts +17 -1
  181. package/src/_runtime/freshness.ts +9 -7
  182. package/src/_shared/components.ts +372 -23
  183. package/src/device/list/0.1/payload.ts +4 -2
  184. package/src/device/list/0.2/payload.ts +4 -2
  185. package/src/device/register/0.1/payload.ts +4 -2
  186. package/src/device/register/0.2/payload.ts +4 -2
  187. package/src/index.ts +25 -0
  188. package/src/rooms/_shared/0.1/room.ts +1 -1
  189. package/src/rooms/create/0.2/payload.ts +364 -0
  190. package/src/rooms/epoch/chain/0.2/payload.ts +347 -0
  191. package/src/rooms/epoch/prune/0.2/payload.ts +315 -0
  192. package/src/rooms/info/0.2/payload.ts +700 -0
  193. package/src/rooms/keys/backfill/0.2/payload.ts +260 -0
  194. package/src/rooms/keys/browse/0.1/payload.ts +2 -2
  195. package/src/rooms/keys/browse/0.2/payload.ts +628 -0
  196. package/src/rooms/keys/chain/0.2/payload.ts +308 -0
  197. package/src/rooms/keys/profile/read/0.1/payload.ts +2 -2
  198. package/src/rooms/keys/read/0.1/payload.ts +2 -2
  199. package/src/rooms/owner/anchor/0.1/payload.ts +2 -2
  200. package/src/rooms/records/get/0.1/payload.ts +2 -2
  201. package/src/rooms/records/get/0.2/payload.ts +2 -2
  202. package/src/rooms/records/list/0.1/payload.ts +2 -2
  203. package/src/rooms/records/list/0.2/payload.ts +2 -2
  204. package/src/rooms/records/list/0.3/payload.ts +601 -0
  205. package/src/rooms/records/prune/0.1/payload.ts +451 -0
  206. package/src/rooms/records/put/0.3/payload.ts +741 -0
  207. package/src/rooms/records/retention/set/0.1/payload.ts +338 -0
  208. package/src/vault/credentials/present/0.1/payload.ts +283 -0
  209. package/src/vault/credentials/query/0.1/payload.ts +8 -0
  210. package/src/vta/webvh/dids/create/1.2/payload.ts +660 -0
  211. package/src/vtc/_shared/0.1/room-migration.ts +17 -0
  212. package/src/vtc/_shared/0.1/room-storage.ts +1 -1
  213. package/src/vtc/_shared/0.2/room-storage.ts +17 -0
  214. package/src/vtc/admin/events/_shared/0.4/topic.ts +32 -0
  215. package/src/vtc/admin/events/event/0.4/payload.ts +137 -0
  216. package/src/vtc/admin/events/subscribe/0.4/payload.ts +318 -0
  217. package/src/vtc/rooms/get/0.2/payload.ts +1372 -0
  218. package/src/vtc/rooms/storage/migrate/0.2/payload.ts +408 -0
  219. package/src/vtc/storage/configs/create/0.1/payload.ts +1 -1
  220. package/src/vtc/storage/configs/create/0.2/payload.ts +830 -0
  221. package/src/vtc/storage/configs/get/0.1/payload.ts +1 -1
  222. package/src/vtc/storage/configs/get/0.2/payload.ts +1110 -0
  223. package/src/vtc/storage/configs/list/0.1/payload.ts +1 -1
  224. package/src/vtc/storage/configs/list/0.2/payload.ts +1177 -0
  225. package/src/vtc/storage/configs/update/0.1/payload.ts +1 -1
  226. package/src/vtc/storage/configs/update/0.2/payload.ts +829 -0
  227. package/src/vtc/storage/credentials/set/0.1/payload.ts +1 -1
  228. package/src/vtc/storage/credentials/set/0.2/payload.ts +619 -0
@@ -413,6 +413,10 @@ export type AuthModel =
413
413
  export type AuthorityScope = AuthorityScopeAll | AuthorityScopeNone | AuthorityScopeContexts;
414
414
  export type AwsArn = string;
415
415
  export type AwsRegion = string;
416
+ /**
417
+ * The ARN of an AWS IAM role, in any AWS partition (`arn:aws:`, `arn:aws-cn:`, `arn:aws-us-gov:`). Validated here because the community passes it to STS AssumeRole and derives the partition of the session policy's resources from it; it must never carry anything but a role ARN.
418
+ */
419
+ export type AwsRoleArn = string;
416
420
  export type BindingId = string;
417
421
  export type BindingSpec = RoomBindingSpec | GrantsBindingSpec | RoleBindingSpec;
418
422
  /**
@@ -491,7 +495,8 @@ export type Capability_DeviceV0_1 =
491
495
  | "pcs-applicant"
492
496
  | "witness-request"
493
497
  | "pcs-voter"
494
- | "pcs-trustee";
498
+ | "pcs-trustee"
499
+ | "credential-present";
495
500
  /**
496
501
  * Fine-grained capability flag scoped to the device's allowed contexts. See SPEC.md for the full semantics of each. Capability values are additive: a consumer MUST ignore a value it does not recognise rather than reject the binding, and MUST NOT treat an unrecognised value as conferring anything.
497
502
  */
@@ -521,7 +526,8 @@ export type Capability_DeviceV0_2 =
521
526
  | "pcsApplicant"
522
527
  | "witnessRequest"
523
528
  | "pcsVoter"
524
- | "pcsTrustee";
529
+ | "pcsTrustee"
530
+ | "credentialPresent";
525
531
  /**
526
532
  * Number of chunks in the bundle, equal to ceil(expectedSizeBytes / chunkSize). Bounded at 4096 so that the manifest itself — one digest per chunk — fits in the single document that carries it under the same message-size reasoning as a chunk.
527
533
  */
@@ -732,6 +738,26 @@ export type EnrolledVia = "install" | "invite" | "selfService" | "offline";
732
738
  * Opaque identifier of one directory entry: `dir_` followed by 16 to 64 base64url characters. Random, scoped to one community, and stable for the life of the membership — it survives a rotation of the member's DID, which is why groups, notes and cards are keyed by it. It MUST NOT be derived from, and MUST NOT reveal, any DID of the member, and the same person's entries in two communities MUST NOT share one. Compared by exact string equality.
733
739
  */
734
740
  export type EntryId = string;
741
+ /**
742
+ * The earliest epoch whose storage key a room still lets anybody derive: its chain was pruned below it (`rooms/epoch/prune`), and every epoch under it is meant to be unreadable — at the host, and, as far as each of them conforms, at every member's key holder. Absent means the room's chain has never been pruned.
743
+ *
744
+ * **The off-by-one, stated once.** A rung (`EpochLink`) numbered `e` opens with epoch `e`'s key and yields epoch `e − 1`'s. A prune with `beforeEpoch: N` drops the rungs numbered below `N`, so rung `N` survives and still yields epoch `N − 1`'s key; the floor after it is therefore `N − 1`, never `N`. A party applying a floor `F` discards the rungs numbered `F` and below — rung `F` would yield `F − 1` — and every key for an epoch below `F`.
745
+ *
746
+ * **Monotonic.** A floor only rises. A host raises the room's to the higher of the floor it held and `beforeEpoch − 1` at each prune it performs, and never lowers it; every other party keeps the highest it has learnt for the room, from any source, and never lowers it either. A lower floor learnt later — from a stale response, or a host that has not been pruned — changes nothing.
747
+ *
748
+ * **A host** that holds a floor for a room MUST NOT store, accept or serve a rung numbered at or below it, and MUST serve the floor wherever a response can carry it (`rooms/epoch/chain` 0.2, `rooms/epoch/prune` 0.2).
749
+ *
750
+ * **A member's key holder** — and any client of the member that keeps the room's rungs or keys itself — on learning a floor `F` above the one it held, by any means (`rooms/epoch/chain` 0.2 in its own reads, `rooms/keys/backfill` 0.2, `rooms/keys/chain` 0.2 from its principal):
751
+ * 1. MUST discard every rung it holds for the room numbered `F` or below, and every storage key, file key or other key material it holds or has cached for an epoch below `F` — including one it derived in passing while applying commits through those epochs (`rooms/keys/commit`, `rooms/epoch/commits`);
752
+ * 2. MUST NOT store such a rung or key again from any source — a delivery from its principal, a backfill, a repair, a catch-up, or a host that has not been pruned — and MUST NOT ask for one;
753
+ * 3. MUST refuse to derive or use a key for an epoch below `F`, answering exactly as it answers for an epoch its chain does not reach (`beyondChain`, with an earliest epoch at or above `F`), whatever it still holds;
754
+ * 4. MUST keep `F` itself for as long as it holds anything for the room, since it is what makes items 2 and 3 enforceable after the material is gone.
755
+ *
756
+ * A key holder SHOULD learn the floor whenever it fetches rungs or catches up, and SHOULD ask for it — a `rooms/epoch/chain` 0.2 read carries it whatever `fromEpoch` and `limit` it names — at least as often as it otherwise reads the room. One that never asks never learns, and keeps what it held.
757
+ *
758
+ * **What a floor does not do, stated plainly.** It is honoured by parties that conform; it does not reach into one that does not, and it recalls nothing. Plaintext a key holder already returned, records a member already opened, files already downloaded and decrypted, exports, and any key a member's own software extracted are beyond it. What it guarantees cryptographically is what the prune guarantees: a party that had not derived a key below the floor before the host erased its rungs can never derive it afterwards. What it adds is that every conforming key holder stops being able to — so that a restart, a new device or an agent's next recall reads nothing below the floor, rather than everything its holder happened to keep.
759
+ */
760
+ export type EpochFloor = number;
735
761
  /**
736
762
  * Lowercase hex SHA-256 of the whole bundle's bytes. Kept in the hex form the 1.0 descriptor published rather than moved to DigestMultibase, because it is an unchanged member of an existing descriptor and re-encoding it would break every stream producer for no gain in what it checks. For a chunked transfer it is the check over the reassembled bundle, applied after every chunk has verified individually, so that a correct set of chunks assembled in the wrong order is still caught.
737
763
  */
@@ -890,7 +916,7 @@ export type Handle = string;
890
916
  *
891
917
  * **Derived from the same set as the root, and not read from the room's own counter.** The two agree for any host that has never erased a record — versions are assigned strictly increasing and a retraction keeps its tombstone — but they are not interchangeable, because a root and a counter are *two reads*, and two reads are not a snapshot. A write landing between them yields a pair that is individually correct and jointly false: two members holding roots taken over different trees, labelled with one version. That reads as equivocation and is not, and a **false accusation discredits the mechanism rather than the host** — the worst outcome available here. Taken from the committed set, the version cannot disagree with the root it labels, whatever else is happening to the room.
892
918
  *
893
- * The corollary is worth stating: a host that **erases** a record — as distinct from retracting it, which leaves a tombstone in the tree — moves the root without necessarily moving this value, and two members straddling that erasure would see one version over two roots. Erasure is a retention act with its own answer, and a family that exposes one owes this definition another look.
919
+ * **A prune is the one mutation that removes leaves, and it takes a version too.** A host that **erases** records — as distinct from retracting them, which leaves a tombstone in the tree — moves the root, and taken from the records alone this value need not move with it: it would stay put, or even fall if the erased record held the highest version, and two members straddling the erasure would see one version over two roots, which reads as equivocation and is not. So on a room whose records have been pruned (`rooms/records/prune`), this value is the higher of the highest version among the records the tree covers and the `version` of the room's latest `RecordPrune`, computed from the same snapshot as the root. A prune takes the next version from the room's counter exactly as a put or a curation does, so the pair stays a snapshot: a root and a head that agree before a prune and a root and a head that agree after it, never one head over two roots. A room that has never been pruned is unaffected.
894
920
  *
895
921
  * **This is what makes two roots comparable at all**, and without it the comparison this family is built on cannot be performed. A room moves: every put, curate and retraction assigns a new version, so two roots taken at two moments differ legitimately and a reader learns nothing from the difference. Shown two different roots, a host that equivocated and a host that was merely written to are indistinguishable — the first can always answer *the room moved between your reads*, and nothing contradicts it.
896
922
  *
@@ -1030,6 +1056,18 @@ export type MembershipSource = "added" | "joined" | "requestApproved" | "rule";
1030
1056
  * @maxItems 64
1031
1057
  */
1032
1058
  export type MerklePath = DigestMultibase[];
1059
+ /**
1060
+ * A one-line summary of the last failure, for an administrator: the step, the config and the backend's error code or status (`put to eu-s3-primary: 503 SlowDown`). Never a credential, a presigned URL, a signed request, a room identifier or anything derived from a room's contents.
1061
+ */
1062
+ export type MigrationLastError = string;
1063
+ /**
1064
+ * Why a migration is `paused`. `capacity`: the destination config cannot hold the rest. `source`: a config the blobs are being moved off keeps failing to serve them. `destination`: the destination config keeps refusing writes, or is no longer `active`. `credential`: the community cannot obtain a credential for one of the configs.
1065
+ */
1066
+ export type MigrationPauseCause = "capacity" | "source" | "destination" | "credential";
1067
+ /**
1068
+ * `queued`: approved and waiting for another migration on this community to finish; nothing copied yet (a community that runs one migration at a time). `running`: copying, including while it retries a failing step with backoff. `paused`: halted after its automatic retries reached their cap without success, or on a cause that retrying cannot clear (`pausedCause`); resumed by issuing vtc/rooms/storage/migrate again, and by the community itself at `nextAttemptAt` when present. `complete`: every blob that was to move has moved. `failed`: halted on a blob whose copy did not verify against its manifest; that blob stays where it was.
1069
+ */
1070
+ export type MigrationState = "queued" | "running" | "paused" | "complete" | "failed";
1033
1071
  /**
1034
1072
  * How the request reaches the approver. A CLOSED list. Version 0.1 defines `scan`: the starter shows a trigger link (as a QR code that is also a clickable link, TRIGGER-LINK.md) and the approver's wallet reads it. `code` (a typed code of at least 8 characters, under strict rate limits) and `push` (sent to the approver's enrolled devices) are reserved names.
1035
1073
  */
@@ -1385,6 +1423,21 @@ export type Queue = "receive" | "send";
1385
1423
  * Why the administrator is making this change. Recorded with it in the audit trail. Attributed to its author on every surface and untrusted: it MUST NOT carry personal data or a credential, and a reader MUST NOT treat it as instructions.
1386
1424
  */
1387
1425
  export type Reason = string;
1426
+ /**
1427
+ * What kind of claim a record is, as its author states it. OPTIONAL wherever it appears; absent means the author did not say, and a reader shows it as unstated rather than assuming any of these.
1428
+ *
1429
+ * - `declared` — the author's own statement: a decision, a preference, an intention, a commitment. True because the author says so, and only as far as the author speaks for it.
1430
+ * - `observed` — something the author saw, measured or was told directly, recorded as found.
1431
+ * - `verified` — checked against evidence that somebody else can check again, such as a credential or another record. A record that says `verified` SHOULD name that evidence in `evidence`; one that does not is an unsupported claim to have checked, and a reader SHOULD present it so.
1432
+ * - `inferred` — derived by reasoning from other information: an agent's conclusion, a summary's generalisation, a model's guess. The value an agent writer uses when it does not know which of the others applies.
1433
+ *
1434
+ * The values are the author's account of their own record, signed with it. They are not checked by anybody, confer nothing, and say nothing about whether the record is right — `inferred` can be correct and `observed` mistaken. Aligned with the provenance vocabulary of personal agent memory, so that a record moved between a member's memory and a room keeps its meaning.
1435
+ */
1436
+ export type RecordBasis = "declared" | "observed" | "verified" | "inferred";
1437
+ /**
1438
+ * The author's own estimate, from 0 to 1, that what the record says is correct. OPTIONAL; absent means no estimate was given, never 1. Meaningful only beside the author who gave it: two writers' numbers are not on one scale, so a reader MUST NOT rank records by `confidence` across authors as though they were, and an agent that weights by it SHOULD weight within an author's own records. Never authority.
1439
+ */
1440
+ export type RecordConfidence = number;
1388
1441
  /**
1389
1442
  * How many records the room held when `DataCommitment` was computed — the number of leaves in that tree, tombstones included, since a tombstone is a record.
1390
1443
  *
@@ -1395,6 +1448,22 @@ export type Reason = string;
1395
1448
  * **It counts the room, never the page.** The same rule `DataCommitment` states, and the same trap: a count scoped to what was returned is one a host satisfies by construction. So this is only comparable against a listing read to the end with **no** `prefix` and **no** `sinceVersion` — a filtered listing legitimately holds fewer, and a reader that compares one against this has found a discrepancy it created itself.
1396
1449
  */
1397
1450
  export type RecordCount = number;
1451
+ /**
1452
+ * One thing a record cites in its support, discriminated by `kind`.
1453
+ *
1454
+ * - `record` names a record of a room by its key, and optionally the version cited and the room. Absent `roomId` means the record's own room.
1455
+ * - `credential` names a credential by its `id`, and optionally a digest of the credential as cited.
1456
+ *
1457
+ * **A reference, never a locator, and never proof.** A reader MUST NOT fetch, resolve or dereference a `credentialId` because a record names it, and MUST NOT read a record of another room on the strength of a citation: the rule that a room's identifiers are identifiers and not addresses (`AuthorityPresentation`) applies here for the same reasons — fetching would signal to whoever answers which member read which record, and when. A reader MAY show a cited record of the same room that it already holds or reads anyway, and MAY match a cited credential against ones its member already holds. What the citation proves is only that the author cited it; whether the evidence exists, says what the author claims, or supports the record is for whoever follows it up to judge.
1458
+ */
1459
+ export type RecordEvidence = RecordEvidenceRecord | RecordEvidenceCredential;
1460
+ /**
1461
+ * What the author offers in support of the record: other records and credentials, by reference. OPTIONAL; absent means none was named, and an empty array is not a permitted spelling of that. Order carries no meaning. Bounded so that a reader's cost of showing a record's support is bounded too.
1462
+ *
1463
+ * @minItems 1
1464
+ * @maxItems 32
1465
+ */
1466
+ export type RecordEvidenceList = [RecordEvidence, ...RecordEvidence[]];
1398
1467
  /**
1399
1468
  * The path from one record's leaf to the room's `DataCommitment` — a Merkle inclusion proof, in the vocabulary this work already uses for it.
1400
1469
  *
@@ -1429,6 +1498,10 @@ export type RecordTrace = {
1429
1498
  * Whether the record asserts an authorization or a recognition relationship.
1430
1499
  */
1431
1500
  export type RecordType = "authorization" | "recognition";
1501
+ /**
1502
+ * The instant after which the record's author no longer stands behind it as current. OPTIONAL; absent means the record does not expire. A reader hides a record whose `validUntil` has passed from default listings, search and recall, and shows it only on explicit request (`SealedRecordBody`, **Expiry**). No host enforces it.
1503
+ */
1504
+ export type RecordValidUntil = string;
1432
1505
  /**
1433
1506
  * What it takes to let a value LEAVE. Distinct from `Sensitivity`, which governs showing it to the holder.
1434
1507
  *
@@ -1578,6 +1651,51 @@ export type SealedEnvelope_VaultV0_2 =
1578
1651
  | DidcommAuthcryptEnvelope_VaultV0_2
1579
1652
  | HpkeArmoredEnvelope_VaultV0_2
1580
1653
  | TspMessageEnvelope_VaultV0_2;
1654
+ /**
1655
+ * The cleartext inside the sealed block of vtc/storage/credentials/set/0.2, discriminated by `kind`, which must equal the config's kind. It names the config it is for inside the seal, so that a block captured on its way to one config cannot be replayed into another: a community MUST refuse a block whose `configId` differs from the request's. Never appears on the wire outside a seal, and is never returned. A `local` config has no credential.
1656
+ */
1657
+ export type SealedStorageCredential =
1658
+ | {
1659
+ kind: "s3";
1660
+ configId: StorageConfigId;
1661
+ /**
1662
+ * The access key's identifier.
1663
+ */
1664
+ accessKeyId: string;
1665
+ /**
1666
+ * The secret half.
1667
+ */
1668
+ secretAccessKey: string;
1669
+ /**
1670
+ * Present when the pair is a temporary one that needs it. A temporary pair stops working at its own expiry, after which the config reports failures until another is set; it is accepted for evaluation, never recommended.
1671
+ */
1672
+ sessionToken?: string;
1673
+ }
1674
+ | {
1675
+ kind: "gcs";
1676
+ configId: StorageConfigId;
1677
+ /**
1678
+ * The service-account key exactly as Google issues it — the JSON key file, as an object, its member names carried verbatim in Google's own snake_case. Members beyond the four required (`project_id`, `client_id`, `token_uri`, `universe_domain` and the rest) are permitted, and a community MAY discard them: it authenticates with `client_email`, `private_key_id` and `private_key` alone, against Google's own token endpoint, and never against a `token_uri` the key file names.
1679
+ */
1680
+ serviceAccountKey: {
1681
+ type: "service_account";
1682
+ client_email: string;
1683
+ private_key_id: string;
1684
+ /**
1685
+ * The PKCS #8 PEM private key.
1686
+ */
1687
+ private_key: string;
1688
+ [k: string]: unknown | undefined;
1689
+ };
1690
+ }
1691
+ | {
1692
+ kind: "walrus";
1693
+ configId: StorageConfigId;
1694
+ /**
1695
+ * The private key in Sui's Bech32 `suiprivkey` encoding (SIP-15), which carries its signature scheme.
1696
+ */
1697
+ suiPrivateKey: string;
1698
+ };
1581
1699
  /**
1582
1700
  * A sealed-transfer bundle: OpenPGP-style ASCII armor around an HPKE-sealed `SealedPayloadV1` (base mode, X25519-HKDF-SHA256 KEM, HKDF-SHA256 KDF, ChaCha20-Poly1305 AEAD, info string `vta-sealed-transfer/v1`), with a producer assertion and Bundle-Id, Chunk and Digest-Algo headers bound into the associated data. Each task states the key it is sealed to: a single-use wrapping key from keys/import-wrapping-key for external/accounts/secret/set, and the caller's key-agreement key for external/credentials/issue. Its cleartext is an ExternalSecretPayload, an ExternalCredentialPayload or, from external/credentials/issue 0.2 for `s3-static-presign`, a PresignedRequestSet. The only form in which secret material crosses the wire in this family, in either direction: the seal is what keeps a terminating proxy, a relay, a request log or a debug dump of "the response" from ever holding a usable secret, whatever transport carried the document.
1583
1701
  */
@@ -1706,7 +1824,30 @@ export type Slot = string;
1706
1824
  *
1707
1825
  * `sealed` (discouraged): a long-lived credential stored by the community, set with vtc/storage/credentials/set. Protects against every administrator through every surface the community offers; does not protect against whoever operates the machine.
1708
1826
  */
1709
- export type StorageAuth =
1827
+ export type StorageAuth_VtcV0_1 =
1828
+ | {
1829
+ mode: "vta-account";
1830
+ context: ExternalAccountContextId;
1831
+ account: ExternalAccountId;
1832
+ }
1833
+ | {
1834
+ mode: "ambient";
1835
+ }
1836
+ | {
1837
+ mode: "sealed";
1838
+ };
1839
+ /**
1840
+ * How the community authenticates to a config's backend. Absent on a `local` config, which needs none.
1841
+ *
1842
+ * `vta-account` (RECOMMENDED): an external account in the community's VTA, named by the context that owns it and its identifier there. The VTA holds the long-lived authority; the community holds nothing that outlives a credential lifetime, and asks for credentials scoped to one room's prefix for at most 15 minutes, every issuance audited at the VTA. Required for a `walrus` config other than a `sealed` one, since the VTA's `sui-signer` account signs its storage transactions.
1843
+ *
1844
+ * `ambient`: the cloud identity of the machine the community runs on (an instance role, workload identity), downscoped to one room's prefix by the community itself under the rules of vtc/storage/configs/create/0.2 — on `s3`, by assuming `roleArn` (or the role the host is configured with) with an inline session policy; on `gcs`, by a Credential Access Boundary. Not audited or rate-limited by the VTA, and usable by anything on that machine that reaches the metadata endpoint. Not valid for `walrus`; `roleArn` is valid only on `s3`.
1845
+ *
1846
+ * `sealed` (discouraged): a long-lived credential stored by the community, set with vtc/storage/credentials/set (0.2: a `SealedStorageCredential`). Protects against every administrator through every surface the community offers; does NOT protect against whoever operates the machine, and a community labels it so wherever the config is shown.
1847
+ *
1848
+ * `ambient` and `sealed` are host-operator choices: a community MAY refuse either by its own host configuration, whatever its administrators ask.
1849
+ */
1850
+ export type StorageAuth_VtcV0_2 =
1710
1851
  | {
1711
1852
  mode: "vta-account";
1712
1853
  context: ExternalAccountContextId;
@@ -1714,6 +1855,10 @@ export type StorageAuth =
1714
1855
  }
1715
1856
  | {
1716
1857
  mode: "ambient";
1858
+ /**
1859
+ * `s3` only: the IAM role the community assumes, with the machine's ambient identity, to obtain each room-scoped session. Absent, the community assumes the role its host configuration names, and with none configured, the role of the ambient identity itself (which must then trust itself to be assumed). Refused on any other kind with `authNotAllowed`.
1860
+ */
1861
+ roleArn?: AwsRoleArn;
1717
1862
  }
1718
1863
  | {
1719
1864
  mode: "sealed";
@@ -1786,6 +1931,20 @@ export type Topic_VtcAdminEventsV0_3 =
1786
1931
  | "rooms"
1787
1932
  | "directory"
1788
1933
  | "groups";
1934
+ /**
1935
+ * One kind of change a console can be told about. A closed set: a topic not listed here is a new MINOR version of this component, not an `ext` member, because each topic is bound to the read that authorizes it.
1936
+ */
1937
+ export type Topic_VtcAdminEventsV0_4 =
1938
+ | "actions"
1939
+ | "acknowledgements"
1940
+ | "joinRequests"
1941
+ | "members"
1942
+ | "singleAdminMode"
1943
+ | "config"
1944
+ | "rooms"
1945
+ | "directory"
1946
+ | "groups"
1947
+ | "communityRooms";
1789
1948
  /**
1790
1949
  * How the traffic reached or left the mediator. `peerMediator` is mediator-to-mediator forwarding.
1791
1950
  */
@@ -5785,7 +5944,7 @@ export interface CredentialScopeCeiling {
5785
5944
  /**
5786
5945
  * Whether a config can authenticate now, and how — never the credential. `status`: `vta-account`, `ambient` and `sealed` are usable; `required` means the config cannot store until a credential is provided (a `sealed` config never set, or set before a restore, which carries no credential); `none` is a `local` config.
5787
5946
  */
5788
- export interface CredentialState {
5947
+ export interface CredentialState_VtcV0_1 {
5789
5948
  status: "vta-account" | "ambient" | "sealed" | "required" | "none";
5790
5949
  /**
5791
5950
  * Present with `vta-account`.
@@ -5808,6 +5967,32 @@ export interface CredentialState {
5808
5967
  */
5809
5968
  roomsHoldingCredentials?: number;
5810
5969
  }
5970
+ /**
5971
+ * Whether a config can authenticate now, and how — never the credential. `status`: `vta-account`, `ambient` and `sealed` are usable; `required` means the config cannot store until a credential is provided (a `sealed` config never set, or set before a restore, which carries no credential); `notAllowed` means the config's mode is one the community's host configuration no longer permits, so it cannot store until its `auth` is changed; `none` is a `local` config.
5972
+ */
5973
+ export interface CredentialState_VtcV0_2 {
5974
+ status: "vta-account" | "ambient" | "sealed" | "required" | "notAllowed" | "none";
5975
+ /**
5976
+ * Present with `vta-account`.
5977
+ */
5978
+ context?: ExternalAccountContextId;
5979
+ /**
5980
+ * Present with `vta-account`.
5981
+ */
5982
+ account?: ExternalAccountId;
5983
+ /**
5984
+ * Present with `sealed`: a digest identifying the stored credential, so an administrator can tell which one is set without anyone being able to read it. Computed over the credential with a community-held key, never a bare hash of a low-entropy secret.
5985
+ */
5986
+ fingerprint?: DigestMultibase;
5987
+ /**
5988
+ * Present with `sealed`: when the stored credential was last set.
5989
+ */
5990
+ setAt?: string;
5991
+ /**
5992
+ * Present with `vta-account`, `ambient` and `sealed`: how many rooms the community currently holds a live room-scoped credential for.
5993
+ */
5994
+ roomsHoldingCredentials?: number;
5995
+ }
5811
5996
  /**
5812
5997
  * A W3C Data Integrity proof by the card's publisher. Additional Data Integrity members (e.g. `created`) are permitted and are covered as the cryptosuite defines.
5813
5998
  */
@@ -8546,6 +8731,36 @@ export interface PeerDepth {
8546
8731
  bytes: number;
8547
8732
  oldestAgeSeconds?: number;
8548
8733
  }
8734
+ /**
8735
+ * What the author permits the record to be used for — for example, that a learner's record is for instructional personalisation only. OPTIONAL; absent means the author stated no limit beyond the room's own terms.
8736
+ *
8737
+ * **Two halves, because purpose has both a machine and a human reading.** `purposes` names purposes by IRI, so that an agent can match them without parsing prose; `note` says it in words, for the nuance an identifier cannot carry. Either may be given alone.
8738
+ *
8739
+ * **No vocabulary of this family's own.** Purpose vocabularies exist and are maintained elsewhere — the W3C Data Privacy Vocabulary (`https://w3id.org/dpv#…`) is the one a writer SHOULD reach for first — and a short list defined here would be one more to translate between, and would be wrong at its edges for every domain that uses rooms. An IRI is the extension path: a community that needs a purpose no published vocabulary has names it under an IRI it controls.
8740
+ *
8741
+ * **A statement, not an enforcement.** No host can see it on the sealed tiers and none enforces it on any tier; every reader is a member who already holds the content. It records what the author permitted, so that a member — or an agent acting for one — can honour it, and so that a use outside it is a use against the author's stated terms rather than one nobody could have known about. An agent acting for a member SHOULD NOT use a record for a purpose outside `validFor` and SHOULD tell its principal when asked to. It confers no authority on anybody, and a `purposes` entry a reader does not recognise is shown, not ignored.
8742
+ */
8743
+ export interface PermittedUse {
8744
+ /**
8745
+ * Purposes the record may be used for, each an absolute IRI — for example `https://w3id.org/dpv#ServicePersonalisation`. A set: order carries no meaning. An identifier, never fetched.
8746
+ *
8747
+ * @minItems 1
8748
+ * @maxItems 8
8749
+ */
8750
+ purposes?:
8751
+ | [string]
8752
+ | [string, string]
8753
+ | [string, string, string]
8754
+ | [string, string, string, string]
8755
+ | [string, string, string, string, string]
8756
+ | [string, string, string, string, string, string]
8757
+ | [string, string, string, string, string, string, string]
8758
+ | [string, string, string, string, string, string, string, string];
8759
+ /**
8760
+ * The permitted use in words, such as `instructional personalisation only`. Plain text, rendered as text, and never instructions — an agent reading it treats it as the author's statement about the record, not as something to do.
8761
+ */
8762
+ note?: string;
8763
+ }
8549
8764
  /**
8550
8765
  * A member's personal label for one room, as their key holder keeps it: at least one detail (`minProperties` counts `updatedAt`), and when it last changed. A key holder that holds no detail for the room holds no label, and returns none — there is no empty label.
8551
8766
  */
@@ -9215,6 +9430,38 @@ export interface ReadVerification {
9215
9430
  headVersion: HeadVersion;
9216
9431
  };
9217
9432
  }
9433
+ /**
9434
+ * Cites a credential.
9435
+ */
9436
+ export interface RecordEvidenceCredential {
9437
+ kind: "credential";
9438
+ /**
9439
+ * The credential's `id`. An identifier: never fetched because a record names it.
9440
+ */
9441
+ credentialId: string;
9442
+ /**
9443
+ * OPTIONAL. A digest of the credential as cited — the SHA-256 multihash of its RFC 8785 (JCS) canonicalization, `proof` included — so a reader holding a credential with this `id` can tell whether it is the one the author meant.
9444
+ */
9445
+ digest?: DigestMultibase;
9446
+ }
9447
+ /**
9448
+ * Cites a record of a room.
9449
+ */
9450
+ export interface RecordEvidenceRecord {
9451
+ kind: "record";
9452
+ /**
9453
+ * The cited record's key, as in `rooms/records/put`. Opaque on the sealed tiers, like every key there.
9454
+ */
9455
+ key: string;
9456
+ /**
9457
+ * The version cited. OPTIONAL; present, it pins the citation to what the record said then, since a record can be rewritten under the same key. A reader that shows a later version SHOULD say that it is not the one cited.
9458
+ */
9459
+ version?: number;
9460
+ /**
9461
+ * The cited record's room. Absent means the citing record's own room. A citation into another room tells the reader that room's identifier, so a writer SHOULD NOT cite into a room the citing room's readers are not meant to learn of.
9462
+ */
9463
+ roomId?: string;
9464
+ }
9218
9465
  /**
9219
9466
  * What `rooms/records/list` returns. Never the body: ranking happens on the client, and a host that returned every body would make the caller pay for the whole room on every listing.
9220
9467
  */
@@ -9290,6 +9537,50 @@ export interface RecordMetadataV2 {
9290
9537
  */
9291
9538
  blobs?: [BlobRef];
9292
9539
  }
9540
+ /**
9541
+ * The mark a prune leaves: **that** records were removed, when, and how many — never which, and never anything they said.
9542
+ *
9543
+ * A prune removes records outright, tombstones included, so the room's record tree loses leaves and an incremental reader has nothing left to learn the removal from. This is what it learns from instead. A host keeps the latest one per room and serves it with every listing that can carry it (`rooms/records/list` 0.3, as `lastPrune`); a reader whose own copy of the room was synchronised to a version below `version` MUST rebuild that copy from a full listing — no `sinceVersion` — and drop every record the full listing no longer holds. Without that, a record the room removed lives on in every cache that synchronised before the prune, and a record retracted while the reader was away comes back as current.
9544
+ *
9545
+ * **What a host keeps and what it does not.** A host keeps this marker, and in its audit trail the prune's `reason`, its requester where the tier discloses one, and the retention it was made under. It MUST NOT keep anything a pruned record said — body, ciphertext, cleartext, title, description, file or blob — and SHOULD NOT keep pruned records' keys: the count is the audit, and a list of keys on an `open` room, where keys may be descriptive, is content by another name.
9546
+ */
9547
+ export interface RecordPrune {
9548
+ /**
9549
+ * The version the prune took from the room's counter, as a put or a curation would. No record carries it; it is what moves `HeadVersion` past the removal, so that a root taken before and a root taken after are never labelled with one version.
9550
+ */
9551
+ version: number;
9552
+ /**
9553
+ * When the host performed it.
9554
+ */
9555
+ at: string;
9556
+ /**
9557
+ * How many records were removed, tombstones included. A prune that removed nothing leaves no mark.
9558
+ */
9559
+ removed: number;
9560
+ }
9561
+ /**
9562
+ * How long a room keeps its records, by age: the room's **record retention**. Records older than it states become **eligible** to be removed by `rooms/records/prune`; nothing is removed until a holder of `admin` asks for a prune, and nothing a prune removes can be brought back.
9563
+ *
9564
+ * **Not `retentionPolicy`, and not `retentionDays`.** Both names are taken in this family and mean other things. `retentionPolicy` (`RetentionPolicy`) is whether a room's *key chain* lets a member read epochs from before they joined, fixed at creation because key material either exists for an epoch or it does not. `retentionDays` (`rooms/create`) is how long a host keeps a whole room after it lapses unrenewed. This is a third question — how long the room keeps its *records* while it is live — and unlike the first it is a decision a room revisits, so it is changeable (`rooms/records/retention/set`). A name sharing either's would invite a reader to apply one's rules to the other.
9565
+ *
9566
+ * **Age is the host's to measure, so age is `updatedAt`.** On the sealed tiers a host can read nothing of a record but its key, version, status, pinning and when it last changed, so a policy the host applies can only be stated in those terms. That is also why it cannot use a record's own `validUntil`, which is sealed: expiry is a reader's rule, retention a host's. A curation is a change, so it restarts a record's age — a retraction starts a tombstone's.
9567
+ *
9568
+ * **Absent, or `{}`, means no record is ever eligible by age**, and that is the reading a host MUST apply whenever it cannot read a policy: removing data under a rule nobody stated is the failure this member exists to prevent. Every member can read the policy in force (`rooms/info`), so a record is never removed under a rule its readers could not have known.
9569
+ */
9570
+ export interface RecordRetention {
9571
+ /**
9572
+ * Days a retracted record's tombstone is kept after its retraction. A tombstone whose `updatedAt` is more than this long ago is eligible. Tombstones exist so that a member syncing incrementally learns of a retraction (`rooms/records/curate`); this is how long a member may stay away and still learn of one that way rather than by rebuilding their copy of the room. Absent means tombstones are never eligible.
9573
+ */
9574
+ tombstoneDays?: number;
9575
+ /**
9576
+ * Days a record is kept after it last changed, whatever its standing. A record — `active`, `deprecated` or `retracted` — whose `updatedAt` is more than this long ago is eligible, **unless it is pinned**: pinning says what matters in the room, and a room that wants a pinned record gone unpins it first. Absent means records are never eligible by age.
9577
+ */
9578
+ recordDays?: number;
9579
+ /**
9580
+ * Ecosystem-defined extension members per SPEC.md §4.5.1. A host MUST NOT treat a member here as making more records eligible: a removal rule a member's reader cannot understand is one they were never told about.
9581
+ */
9582
+ ext?: Ext;
9583
+ }
9293
9584
  /**
9294
9585
  * A passkey already bound to a subject, as listed by `auth/passkey/list` and targeted by `auth/passkey/revoke/*`. This is the auth service's own management view of a credential — not a WebAuthn dictionary — so its members are camelCase per SPEC.md §4.10. The exception is `transports`, whose values are the externally-owned WebAuthn transport tokens and are carried verbatim.
9295
9586
  */
@@ -10639,34 +10930,42 @@ export interface StepUpProof_VaultV0_2 {
10639
10930
  challengeId: string;
10640
10931
  }
10641
10932
  /**
10642
- * One storage config as the community holds it. Carries no secret.
10933
+ * What a config holds and whether it works, computed at the time of the read. Ciphertext bytes throughout.
10643
10934
  */
10644
- export interface StorageConfig {
10645
- id: StorageConfigId;
10935
+ export interface StorageConfigFacts_VtcV0_1 {
10646
10936
  /**
10647
- * A display name for administrators (`EU — S3 (main account)`). Shown to a room's creator with the config's kind when the community lets them choose.
10937
+ * Rooms assigned to this config.
10648
10938
  */
10649
- label: string;
10650
- settings: StorageSettings;
10651
- auth?: StorageAuth;
10939
+ rooms: number;
10652
10940
  /**
10653
- * Total ciphertext bytes the community will store on this config, across every room assigned to it. A capacity, not a policy: an upload that would cross it is refused with scope `storage`. Absent means no capacity set.
10941
+ * Blobs stored on this config that are not yet deleted, wherever their rooms are now assigned.
10654
10942
  */
10655
- capacityBytes?: number;
10656
- state: ConfigState;
10943
+ files: number;
10657
10944
  /**
10658
- * True for the config a room is assigned to when neither the community's policy nor its creator names one.
10945
+ * Their total size. Counts against `capacityBytes` until the backend deletion has actually happened, unlike room and member usage, which stop counting an orphaned blob at once.
10659
10946
  */
10660
- isDefault?: boolean;
10661
- createdBy: string;
10662
- createdAt: string;
10663
- updatedBy?: string;
10664
- updatedAt?: string;
10947
+ bytes: number;
10948
+ /**
10949
+ * Bytes of orphaned blobs awaiting deletion after their grace window.
10950
+ */
10951
+ pendingDeleteBytes: number;
10952
+ credential: CredentialState_VtcV0_1;
10953
+ health: StorageHealth;
10954
+ /**
10955
+ * Present on a `walrus` config.
10956
+ */
10957
+ walrus?: {
10958
+ /**
10959
+ * The Sui address that pays for storage, derived from the VTA account's key.
10960
+ */
10961
+ signerAddress?: string;
10962
+ nextExtensionDueAt?: string;
10963
+ };
10665
10964
  }
10666
10965
  /**
10667
10966
  * What a config holds and whether it works, computed at the time of the read. Ciphertext bytes throughout.
10668
10967
  */
10669
- export interface StorageConfigFacts {
10968
+ export interface StorageConfigFacts_VtcV0_2 {
10670
10969
  /**
10671
10970
  * Rooms assigned to this config.
10672
10971
  */
@@ -10683,7 +10982,7 @@ export interface StorageConfigFacts {
10683
10982
  * Bytes of orphaned blobs awaiting deletion after their grace window.
10684
10983
  */
10685
10984
  pendingDeleteBytes: number;
10686
- credential: CredentialState;
10985
+ credential: CredentialState_VtcV0_2;
10687
10986
  health: StorageHealth;
10688
10987
  /**
10689
10988
  * Present on a `walrus` config.
@@ -10696,6 +10995,56 @@ export interface StorageConfigFacts {
10696
10995
  nextExtensionDueAt?: string;
10697
10996
  };
10698
10997
  }
10998
+ /**
10999
+ * One storage config as the community holds it. Carries no secret.
11000
+ */
11001
+ export interface StorageConfig_VtcV0_1 {
11002
+ id: StorageConfigId;
11003
+ /**
11004
+ * A display name for administrators (`EU — S3 (main account)`). Shown to a room's creator with the config's kind when the community lets them choose.
11005
+ */
11006
+ label: string;
11007
+ settings: StorageSettings;
11008
+ auth?: StorageAuth_VtcV0_1;
11009
+ /**
11010
+ * Total ciphertext bytes the community will store on this config, across every room assigned to it. A capacity, not a policy: an upload that would cross it is refused with scope `storage`. Absent means no capacity set.
11011
+ */
11012
+ capacityBytes?: number;
11013
+ state: ConfigState;
11014
+ /**
11015
+ * True for the config a room is assigned to when neither the community's policy nor its creator names one.
11016
+ */
11017
+ isDefault?: boolean;
11018
+ createdBy: string;
11019
+ createdAt: string;
11020
+ updatedBy?: string;
11021
+ updatedAt?: string;
11022
+ }
11023
+ /**
11024
+ * One storage config as the community holds it. Carries no secret.
11025
+ */
11026
+ export interface StorageConfig_VtcV0_2 {
11027
+ id: StorageConfigId;
11028
+ /**
11029
+ * A display name for administrators (`EU — S3 (main account)`). Shown to a room's creator with the config's kind when the community lets them choose.
11030
+ */
11031
+ label: string;
11032
+ settings: StorageSettings;
11033
+ auth?: StorageAuth_VtcV0_2;
11034
+ /**
11035
+ * Total ciphertext bytes the community will store on this config, across every room assigned to it. A capacity, not a policy: an upload that would cross it is refused with scope `storage`. Absent means no capacity set.
11036
+ */
11037
+ capacityBytes?: number;
11038
+ state: ConfigState;
11039
+ /**
11040
+ * True for the config a room is assigned to when neither the community's policy nor its creator names one.
11041
+ */
11042
+ isDefault?: boolean;
11043
+ createdBy: string;
11044
+ createdAt: string;
11045
+ updatedBy?: string;
11046
+ updatedAt?: string;
11047
+ }
10699
11048
  /**
10700
11049
  * The last evidence the community has that a config works. Every member is optional: a config never probed and never used has none.
10701
11050
  */
@@ -259,7 +259,8 @@ export const PAYLOAD_SCHEMA = {
259
259
  "pcs-applicant",
260
260
  "witness-request",
261
261
  "pcs-voter",
262
- "pcs-trustee"
262
+ "pcs-trustee",
263
+ "credential-present"
263
264
  ],
264
265
  "description": "Fine-grained capability flag scoped to the device's allowed contexts. See SPEC.md for the full semantics of each. Capability values are additive: a consumer MUST ignore a value it does not recognise rather than reject the binding, and MUST NOT treat an unrecognised value as conferring anything."
265
266
  },
@@ -609,7 +610,8 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
609
610
  "pcs-applicant",
610
611
  "witness-request",
611
612
  "pcs-voter",
612
- "pcs-trustee"
613
+ "pcs-trustee",
614
+ "credential-present"
613
615
  ],
614
616
  "description": "Fine-grained capability flag scoped to the device's allowed contexts. See SPEC.md for the full semantics of each. Capability values are additive: a consumer MUST ignore a value it does not recognise rather than reject the binding, and MUST NOT treat an unrecognised value as conferring anything."
615
617
  },
@@ -259,7 +259,8 @@ export const PAYLOAD_SCHEMA = {
259
259
  "pcsApplicant",
260
260
  "witnessRequest",
261
261
  "pcsVoter",
262
- "pcsTrustee"
262
+ "pcsTrustee",
263
+ "credentialPresent"
263
264
  ],
264
265
  "description": "Fine-grained capability flag scoped to the device's allowed contexts. See SPEC.md for the full semantics of each. Capability values are additive: a consumer MUST ignore a value it does not recognise rather than reject the binding, and MUST NOT treat an unrecognised value as conferring anything."
265
266
  },
@@ -609,7 +610,8 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
609
610
  "pcsApplicant",
610
611
  "witnessRequest",
611
612
  "pcsVoter",
612
- "pcsTrustee"
613
+ "pcsTrustee",
614
+ "credentialPresent"
613
615
  ],
614
616
  "description": "Fine-grained capability flag scoped to the device's allowed contexts. See SPEC.md for the full semantics of each. Capability values are additive: a consumer MUST ignore a value it does not recognise rather than reject the binding, and MUST NOT treat an unrecognised value as conferring anything."
615
617
  },
@@ -227,7 +227,8 @@ export const PAYLOAD_SCHEMA = {
227
227
  "pcs-applicant",
228
228
  "witness-request",
229
229
  "pcs-voter",
230
- "pcs-trustee"
230
+ "pcs-trustee",
231
+ "credential-present"
231
232
  ],
232
233
  "description": "Fine-grained capability flag scoped to the device's allowed contexts. See SPEC.md for the full semantics of each. Capability values are additive: a consumer MUST ignore a value it does not recognise rather than reject the binding, and MUST NOT treat an unrecognised value as conferring anything."
233
234
  },
@@ -567,7 +568,8 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
567
568
  "pcs-applicant",
568
569
  "witness-request",
569
570
  "pcs-voter",
570
- "pcs-trustee"
571
+ "pcs-trustee",
572
+ "credential-present"
571
573
  ],
572
574
  "description": "Fine-grained capability flag scoped to the device's allowed contexts. See SPEC.md for the full semantics of each. Capability values are additive: a consumer MUST ignore a value it does not recognise rather than reject the binding, and MUST NOT treat an unrecognised value as conferring anything."
573
575
  },
@@ -227,7 +227,8 @@ export const PAYLOAD_SCHEMA = {
227
227
  "pcsApplicant",
228
228
  "witnessRequest",
229
229
  "pcsVoter",
230
- "pcsTrustee"
230
+ "pcsTrustee",
231
+ "credentialPresent"
231
232
  ],
232
233
  "description": "Fine-grained capability flag scoped to the device's allowed contexts. See SPEC.md for the full semantics of each. Capability values are additive: a consumer MUST ignore a value it does not recognise rather than reject the binding, and MUST NOT treat an unrecognised value as conferring anything."
233
234
  },
@@ -567,7 +568,8 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
567
568
  "pcsApplicant",
568
569
  "witnessRequest",
569
570
  "pcsVoter",
570
- "pcsTrustee"
571
+ "pcsTrustee",
572
+ "credentialPresent"
571
573
  ],
572
574
  "description": "Fine-grained capability flag scoped to the device's allowed contexts. See SPEC.md for the full semantics of each. Capability values are additive: a consumer MUST ignore a value it does not recognise rather than reject the binding, and MUST NOT treat an unrecognised value as conferring anything."
573
575
  },