@openvtc/trust-tasks 0.18.1 → 0.18.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 (33) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/dist/_shared/components.d.ts +75 -1
  3. package/dist/_shared/components.d.ts.map +1 -1
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/rooms/_shared/0.1/room.d.ts +1 -1
  9. package/dist/rooms/_shared/0.1/room.d.ts.map +1 -1
  10. package/dist/rooms/keys/browse/0.1/payload.d.ts +805 -0
  11. package/dist/rooms/keys/browse/0.1/payload.d.ts.map +1 -0
  12. package/dist/rooms/keys/browse/0.1/payload.js +470 -0
  13. package/dist/rooms/keys/browse/0.1/payload.js.map +1 -0
  14. package/dist/rooms/keys/read/0.1/payload.d.ts +683 -0
  15. package/dist/rooms/keys/read/0.1/payload.d.ts.map +1 -0
  16. package/dist/rooms/keys/read/0.1/payload.js +400 -0
  17. package/dist/rooms/keys/read/0.1/payload.js.map +1 -0
  18. package/dist/rooms/records/get/0.1/payload.d.ts +107 -11
  19. package/dist/rooms/records/get/0.1/payload.d.ts.map +1 -1
  20. package/dist/rooms/records/get/0.1/payload.js +56 -4
  21. package/dist/rooms/records/get/0.1/payload.js.map +1 -1
  22. package/dist/rooms/records/list/0.1/payload.d.ts +110 -6
  23. package/dist/rooms/records/list/0.1/payload.d.ts.map +1 -1
  24. package/dist/rooms/records/list/0.1/payload.js +58 -2
  25. package/dist/rooms/records/list/0.1/payload.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/_shared/components.ts +75 -1
  28. package/src/index.ts +2 -0
  29. package/src/rooms/_shared/0.1/room.ts +1 -1
  30. package/src/rooms/keys/browse/0.1/payload.ts +536 -0
  31. package/src/rooms/keys/read/0.1/payload.ts +474 -0
  32. package/src/rooms/records/get/0.1/payload.ts +67 -7
  33. package/src/rooms/records/list/0.1/payload.ts +68 -4
@@ -89,7 +89,9 @@ export type CredentialId = string;
89
89
  /**
90
90
  * The root of the room's record tree — a host's commitment to *which records the room holds*, as distinct from what any one of them says.
91
91
  *
92
- * A room's records are already signed and room-bound, so a host cannot forge, alter or relocate one. What it can do for free is stay silent: a listing that omits a record is indistinguishable from a room that never held it. This value is what makes that omission detectable, so it is only worth anything when the reader can compare it against a copy the host did not choose for them — one it gave another member, one it gave the same member earlier, or the witnessed anchor. A commitment read once, in isolation, proves nothing; a host that shows two members two different roots has been caught.
92
+ * A room's records are already signed and room-bound, so a host cannot forge, alter or relocate one. What it can do for free is stay silent: a listing that omits a record is indistinguishable from a room that never held it. This value is what makes that omission detectable, so it is only worth anything when the reader can compare it against a copy the host did not choose for them — one it gave another member, one it gave the same member earlier, or the witnessed anchor. A commitment read once, in isolation, proves nothing.
93
+ *
94
+ * **A root on its own is not comparable, and an earlier revision of this description said it was.** It claimed a host showing two members two different roots had been caught, which is false while a room can move between two reads: the host answers *there was a write*, and nothing contradicts it. Comparison needs the state each root describes, which is what `HeadVersion` names — and `RecordCount` is the other half of the same omission, since Certificate Transparency's signed tree head is a root *and a size* and this family shipped only the root. A reader that receives a `dataCommitment` **without** them can use it against a witnessed anchor, where the epoch pins the state, and **MUST NOT** compare it against another root.
93
95
  *
94
96
  * **The construction is normative**, because two hosts that compute different roots over the same room make every comparison meaningless:
95
97
  * 1. Take every record the room holds — including tombstones, which are records — and order them by `key` using unsigned byte order.
@@ -155,6 +157,22 @@ export type ExpectedVersion_VtaV0_1 = number;
155
157
  * A colour **name**, resolved by each consumer against its own palette — never a hex value or any other literal. Two reasons, and both are about the consumer rather than the holder. A literal cannot be legible in a terminal, in a light theme and in a dark one at once, so a stored `#8B0000` is a colour that is wrong somewhere and the holder has no way to know where. And a consumer that reserves colours to mean something — an error, a warning, an irreversible act — must be able to keep a holder's decorative choice out of that channel; it cannot do that with an arbitrary value, and it can do it trivially with a closed set it maps itself. The eight members are chosen to be distinguishable from one another and deliberately carry no status connotation: none is named for success, warning or danger.
156
158
  */
157
159
  export type FacetColour = "slate" | "indigo" | "teal" | "moss" | "sand" | "clay" | "rose" | "plum";
160
+ /**
161
+ * The highest version among the records `DataCommitment` covers. `0` for a room that holds none.
162
+ *
163
+ * **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.
164
+ *
165
+ * 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.
166
+ *
167
+ * **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.
168
+ *
169
+ * A version is assigned by exactly the mutations that change the tree — every put, curate and retraction takes the next one — so the highest of them names the **state** the root describes. Two roots carrying the same `headVersion` and differing is a host caught: there is no write to attribute the difference to. Two roots carrying different ones are simply two moments, and a reader should draw nothing from them.
170
+ *
171
+ * A host can lie about this number too, and it is then lying about the counter it also uses for optimistic concurrency (`expectedVersion`) and for incremental sync (`sinceVersion`) — so a member holding a signed acknowledgement of a write at version `V` contradicts any head below `V` directly.
172
+ *
173
+ * **Not a timestamp.** A time is host-asserted, unverifiable and useless for this: two roots a second apart are not evidence of anything, while two roots at one version are.
174
+ */
175
+ export type HeadVersion = number;
158
176
  /**
159
177
  * `issued` is outstanding and revocable; `consumed` and `expired` are terminal.
160
178
  */
@@ -276,6 +294,16 @@ export type Provenance =
276
294
  * A device's platform push channel — the body the device registers with its push GATEWAY (push wake-up binding, https://trusttasks.org/binding/push/0.1; modeled on Aries RFC 0699/0734). The gateway holds this token and returns an opaque WakeHandle in exchange; the token is held by the gateway ONLY, never by the mediator or the maintainer/VTA. The gateway uses it to send a contentless wake-up when an authorized trigger asks — the push payload never carries Trust Task content. Tagged union over the discriminator `platform`.
277
295
  */
278
296
  export type PushRegistration = Apns | Fcm | WebPush;
297
+ /**
298
+ * 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.
299
+ *
300
+ * **Why a root needs this.** Certificate Transparency's signed tree head is a root *and a tree size*; this family shipped the root alone, and the half that was dropped is the half that makes a listing checkable. A reader holding a **complete, unfiltered** listing cannot recompute the root — a leaf commits to a whole record and a listing returns a projection without the body — but it can count. A host that omits a record from a listing while committing to a tree that holds it now contradicts itself in the same response, with no second party and no anchor involved.
301
+ *
302
+ * A host can of course understate both together. That is the point rather than a hole: the omission stops being silence and becomes a **specific claim about how many records the room holds**, which any other member's view, or any writer's signed put acknowledgement, contradicts. Making an omission attributable is the whole of what this machinery buys; it never claimed to make one impossible.
303
+ *
304
+ * **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.
305
+ */
306
+ export type RecordCount = number;
279
307
  /**
280
308
  * 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.
281
309
  *
@@ -2671,6 +2699,52 @@ export interface QueueLimits {
2671
2699
  */
2672
2700
  receiveQueueLimit?: number;
2673
2701
  }
2702
+ /**
2703
+ * What the agent checked on the member's behalf, and what it found.
2704
+ *
2705
+ * **A verdict, never an error.** None of these values fails the task, including the ones that report a host caught out. A member's own agent refusing to hand over a record because the *host* misbehaved punishes the member for somebody else's act — and locks them out of the room holding the records that would show what happened, at the moment they most need them. The consequence belongs on the **write** path, where continuing to hand material to a party you have caught is what compounds the damage.
2706
+ *
2707
+ * So a consumer **MUST NOT** treat any value here as a failed read, and **MUST** surface an adverse one rather than logging it. What that costs is words: a member shown a bare warning icon dismisses it, and a member later refused a write with no explanation blames their own agent. A detection the member attributes to the wrong party is worse than no detection.
2708
+ *
2709
+ * Members are **absent where the task cannot produce them** rather than carrying a not-applicable value — a listing has no `trace` because there is no single record to trace, and a single read has no `count` because a count is only checkable against a listing read to its end.
2710
+ */
2711
+ export interface ReadVerification {
2712
+ /**
2713
+ * Whether the record's `RecordTrace` reached the `dataCommitment` served beside it.
2714
+ *
2715
+ * `verified` says the record is under the root the host asserted — and **nothing about whether that root is the room's**, which is what `priorRoots` and an anchor are for. `notOffered` is a host that maintains no tree, which is legal and informative. `failed` is arithmetic that does not close: the host served a path that does not reach its own root, which is either a defect or a fabrication and is not distinguishable from here.
2716
+ */
2717
+ trace?: "verified" | "failed" | "notOffered";
2718
+ /**
2719
+ * Whether this root matches what the agent has seen from this host for this room **at this `headVersion`**.
2720
+ *
2721
+ * This is the comparison a member cannot make for themselves. A tab does not outlive itself and a CLI holds nothing; the agent is the only party on the member's side of the boundary that saw both reads.
2722
+ *
2723
+ * - `agree` — seen at this head before, same root.
2724
+ * - `conflict` — seen at this head before, **different root**. A host caught: there is no write to attribute the difference to, because a write would have moved the head.
2725
+ * - `noneHeld` — first read at this head. Not evidence of anything; a memory of one is not a comparison.
2726
+ * - `notChecked` — this agent keeps no root history. An honest answer for an agent that cannot make the comparison, and **not** a synonym for `noneHeld`: one says nothing was found, the other says nothing was looked for.
2727
+ *
2728
+ * REQUIRED, so that an agent which does not check has to say so rather than omit the question.
2729
+ */
2730
+ priorRoots: "agree" | "conflict" | "noneHeld" | "notChecked";
2731
+ /**
2732
+ * Whether the number of records returned matches the `recordCount` the host committed to.
2733
+ *
2734
+ * Only ever comparable against a listing with **no** `prefix`, **no** `sinceVersion` and read to its end — anything else legitimately holds fewer, and comparing it is a discrepancy the reader manufactured. `notComparable` is that case, and it is the common one.
2735
+ *
2736
+ * `short` is a host contradicting itself inside one exchange: it committed to a tree of N records and served fewer, with no filter to explain the difference. That is the omission the commitment exists to make detectable, caught without a second party and without an anchor.
2737
+ */
2738
+ count?: "agrees" | "short" | "notComparable" | "notOffered";
2739
+ /**
2740
+ * What the host asserted about the room, passed through unaltered so the member can compare it somewhere this agent cannot reach — with another member, or against a witnessed anchor. All three or none: a root without the state it describes is not comparable to another root, which is the whole of `HeadVersion`.
2741
+ */
2742
+ head?: {
2743
+ dataCommitment: DataCommitment;
2744
+ recordCount: RecordCount;
2745
+ headVersion: HeadVersion;
2746
+ };
2747
+ }
2674
2748
  /**
2675
2749
  * 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.
2676
2750
  */
package/src/index.ts CHANGED
@@ -237,6 +237,7 @@ export * as RoomsCreate_v0_1 from "./rooms/create/0.1/payload.js";
237
237
  export * as RoomsEpochChain_v0_1 from "./rooms/epoch/chain/0.1/payload.js";
238
238
  export * as RoomsEpochMint_v0_1 from "./rooms/epoch/mint/0.1/payload.js";
239
239
  export * as RoomsKeysBackfill_v0_1 from "./rooms/keys/backfill/0.1/payload.js";
240
+ export * as RoomsKeysBrowse_v0_1 from "./rooms/keys/browse/0.1/payload.js";
240
241
  export * as RoomsKeysChain_v0_1 from "./rooms/keys/chain/0.1/payload.js";
241
242
  export * as RoomsKeysCommit_v0_1 from "./rooms/keys/commit/0.1/payload.js";
242
243
  export * as RoomsKeysKeyPackage_v0_1 from "./rooms/keys/key-package/0.1/payload.js";
@@ -244,6 +245,7 @@ export * as RoomsKeysList_v0_1 from "./rooms/keys/list/0.1/payload.js";
244
245
  export * as RoomsKeysOpen_v0_1 from "./rooms/keys/open/0.1/payload.js";
245
246
  export * as RoomsKeysPresent_v0_1 from "./rooms/keys/present/0.1/payload.js";
246
247
  export * as RoomsKeysPresent_v0_2 from "./rooms/keys/present/0.2/payload.js";
248
+ export * as RoomsKeysRead_v0_1 from "./rooms/keys/read/0.1/payload.js";
247
249
  export * as RoomsKeysSeal_v0_1 from "./rooms/keys/seal/0.1/payload.js";
248
250
  export * as RoomsKeysWelcome_v0_1 from "./rooms/keys/welcome/0.1/payload.js";
249
251
  export * as RoomsOwnerClaim_v0_1 from "./rooms/owner/claim/0.1/payload.js";
@@ -14,4 +14,4 @@ export interface RoomsSharedTypes {
14
14
  * The definitions this shared schema publishes, hoisted to one declaration each.
15
15
  * See "../../../_shared/components.js".
16
16
  */
17
- export type { AuthorityPresentation, DataCommitment, EpochLink, RecordMetadata, RecordTrace, RetentionPolicy, SealedRecord, Visibility } from "../../../_shared/components.js";
17
+ export type { AuthorityPresentation, DataCommitment, EpochLink, HeadVersion, ReadVerification, RecordCount, RecordMetadata, RecordTrace, RetentionPolicy, SealedRecord, Visibility } from "../../../_shared/components.js";