@openvtc/trust-tasks 0.23.0 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/_shared/components.d.ts +94 -1
- package/dist/_shared/components.d.ts.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/vtc/admin/actions/_shared/0.1/action.d.ts +1 -1
- package/dist/vtc/admin/actions/_shared/0.1/action.d.ts.map +1 -1
- package/dist/vtc/admin/actions/_shared/0.2/action.d.ts +26 -0
- package/dist/vtc/admin/actions/_shared/0.2/action.d.ts.map +1 -0
- package/dist/vtc/admin/actions/_shared/0.2/action.js +6 -0
- package/dist/vtc/admin/actions/_shared/0.2/action.js.map +1 -0
- package/dist/vtc/admin/actions/acknowledge/0.1/payload.d.ts +1 -1
- package/dist/vtc/admin/actions/acknowledge/0.1/payload.d.ts.map +1 -1
- package/dist/vtc/admin/actions/acknowledge/0.2/payload.d.ts +1052 -0
- package/dist/vtc/admin/actions/acknowledge/0.2/payload.d.ts.map +1 -0
- package/dist/vtc/admin/actions/acknowledge/0.2/payload.js +666 -0
- package/dist/vtc/admin/actions/acknowledge/0.2/payload.js.map +1 -0
- package/dist/vtc/admin/actions/cancel/0.1/payload.d.ts +1 -1
- package/dist/vtc/admin/actions/cancel/0.1/payload.d.ts.map +1 -1
- package/dist/vtc/admin/actions/cancel/0.2/payload.d.ts +1066 -0
- package/dist/vtc/admin/actions/cancel/0.2/payload.d.ts.map +1 -0
- package/dist/vtc/admin/actions/cancel/0.2/payload.js +671 -0
- package/dist/vtc/admin/actions/cancel/0.2/payload.js.map +1 -0
- package/dist/vtc/admin/actions/list/0.1/payload.d.ts +1 -1
- package/dist/vtc/admin/actions/list/0.1/payload.d.ts.map +1 -1
- package/dist/vtc/admin/actions/list/0.2/payload.d.ts +1240 -0
- package/dist/vtc/admin/actions/list/0.2/payload.d.ts.map +1 -0
- package/dist/vtc/admin/actions/list/0.2/payload.js +756 -0
- package/dist/vtc/admin/actions/list/0.2/payload.js.map +1 -0
- package/dist/vtc/admin/actions/show/0.1/payload.d.ts +1 -1
- package/dist/vtc/admin/actions/show/0.1/payload.d.ts.map +1 -1
- package/dist/vtc/admin/actions/show/0.2/payload.d.ts +1052 -0
- package/dist/vtc/admin/actions/show/0.2/payload.d.ts.map +1 -0
- package/dist/vtc/admin/actions/show/0.2/payload.js +666 -0
- package/dist/vtc/admin/actions/show/0.2/payload.js.map +1 -0
- package/dist/vtc/members/authority-reduction-pending-notice/0.1/payload.d.ts +236 -0
- package/dist/vtc/members/authority-reduction-pending-notice/0.1/payload.d.ts.map +1 -0
- package/dist/vtc/members/authority-reduction-pending-notice/0.1/payload.js +122 -0
- package/dist/vtc/members/authority-reduction-pending-notice/0.1/payload.js.map +1 -0
- package/dist/vtc/operator/offline-write/0.1/payload.d.ts +167 -0
- package/dist/vtc/operator/offline-write/0.1/payload.d.ts.map +1 -0
- package/dist/vtc/operator/offline-write/0.1/payload.js +96 -0
- package/dist/vtc/operator/offline-write/0.1/payload.js.map +1 -0
- package/package.json +1 -1
- package/src/_shared/components.ts +102 -1
- package/src/index.ts +7 -0
- package/src/vtc/admin/actions/_shared/0.1/action.ts +1 -1
- package/src/vtc/admin/actions/_shared/0.2/action.ts +27 -0
- package/src/vtc/admin/actions/acknowledge/0.1/payload.ts +1 -1
- package/src/vtc/admin/actions/acknowledge/0.2/payload.ts +701 -0
- package/src/vtc/admin/actions/cancel/0.1/payload.ts +1 -1
- package/src/vtc/admin/actions/cancel/0.2/payload.ts +710 -0
- package/src/vtc/admin/actions/list/0.1/payload.ts +1 -1
- package/src/vtc/admin/actions/list/0.2/payload.ts +825 -0
- package/src/vtc/admin/actions/show/0.1/payload.ts +1 -1
- package/src/vtc/admin/actions/show/0.2/payload.ts +701 -0
- package/src/vtc/members/authority-reduction-pending-notice/0.1/payload.ts +176 -0
- package/src/vtc/operator/offline-write/0.1/payload.ts +133 -0
|
@@ -0,0 +1,825 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated by scripts/build-ts-bindings.mjs — DO NOT EDIT BY HAND.
|
|
3
|
+
* Source: specs/vtc/admin/actions/list/0.2/payload.schema.json
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Action_VtcAdminActionsV0_2 as Action, ActionId, DigestMultibase, Ext, Field, Summary } from "../../../../../_shared/components.js";
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Enumerate the administrative actions a Verifiable Trust Community holds that the caller is entitled to see, one page at a time, from one of four views. The single-record sibling is vtc/admin/actions/show/0.2. The outer document members (id, type, issuer, recipient, issuedAt, expiresAt, proof) are owned by the framework — SPEC §6.3.
|
|
11
|
+
*/
|
|
12
|
+
export interface VTCAdminActionsListPayload {
|
|
13
|
+
/**
|
|
14
|
+
* `waitingForMe` — open actions on which the caller is an eligible approver or acknowledger and has not yet decided. `requestedByMe` — open actions the caller requested, including `coolingOff` actions that will land unless the caller cancels them. `history` — closed actions the caller requested, decided, or was the subject of, or (with the audit-read capability) any closed action, newest first. `all` — every action the caller may see, open and closed, including a `coolingOff` action that acts on the caller (`callerRole: subject`). A `coolingOff` action is never in `waitingForMe`: nobody decides it.
|
|
15
|
+
*/
|
|
16
|
+
view: "waitingForMe" | "requestedByMe" | "history" | "all";
|
|
17
|
+
/**
|
|
18
|
+
* Only with `view: history`: return actions closed at or after this instant. Supplied with any other view it is refused with `invalidFilter` rather than ignored, so a caller never reads a silently unfiltered page as a filtered one.
|
|
19
|
+
*/
|
|
20
|
+
since?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Maximum number of actions in the page. The community MAY return fewer.
|
|
23
|
+
*/
|
|
24
|
+
limit?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Opaque continuation token from a previous page's `nextCursor`, valid only with the same `view` and `since` it was issued for.
|
|
27
|
+
*/
|
|
28
|
+
cursor?: string;
|
|
29
|
+
ext?: Ext;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* One page of actions and the caller's badge counts. Failures use trust-task-error, not this shape.
|
|
33
|
+
*/
|
|
34
|
+
export interface VTCAdminActionsListResponsePayload {
|
|
35
|
+
/**
|
|
36
|
+
* The page, in the view's order: open views by deadline soonest first — `expiresAt`, or `landsAt` for `coolingOff` — (actions with neither last, then by `createdAt`), `history` by `closedAt` newest first, `all` open-before-closed in those orders. An empty array is a successful answer: nothing in this view.
|
|
37
|
+
*
|
|
38
|
+
* @maxItems 100
|
|
39
|
+
*/
|
|
40
|
+
actions: Action[];
|
|
41
|
+
/**
|
|
42
|
+
* Present when more actions follow. Pass it back as `cursor` with the same `view` and `since`.
|
|
43
|
+
*/
|
|
44
|
+
nextCursor?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Totals across the whole collection, not the page — what a console badge shows. Computed for the caller regardless of which `view` was requested.
|
|
47
|
+
*/
|
|
48
|
+
counts: {
|
|
49
|
+
/**
|
|
50
|
+
* Open actions awaiting the caller's decision or acknowledgement.
|
|
51
|
+
*/
|
|
52
|
+
waitingForMe: number;
|
|
53
|
+
/**
|
|
54
|
+
* Open actions the caller requested.
|
|
55
|
+
*/
|
|
56
|
+
requestedByMe: number;
|
|
57
|
+
};
|
|
58
|
+
ext?: Ext;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Shared definitions this specification references, re-exported under the names it used to declare them with. */
|
|
62
|
+
export type { Action, ActionId, DigestMultibase, Ext, Field, Summary };
|
|
63
|
+
|
|
64
|
+
/** Trust Task type URI. */
|
|
65
|
+
export const TYPE_URI = "https://trusttasks.org/spec/vtc/admin/actions/list/0.2" as const;
|
|
66
|
+
|
|
67
|
+
/** Stable alias for this specification's request payload shape. */
|
|
68
|
+
export type Payload = VTCAdminActionsListPayload;
|
|
69
|
+
|
|
70
|
+
/** Trust Task response type URI (request type URI + "#response"). */
|
|
71
|
+
export const RESPONSE_TYPE_URI = "https://trusttasks.org/spec/vtc/admin/actions/list/0.2#response" as const;
|
|
72
|
+
|
|
73
|
+
/** Stable alias for this specification's success-response payload shape. */
|
|
74
|
+
export type Response = VTCAdminActionsListResponsePayload;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* This specification's payload schema, as a value.
|
|
78
|
+
*
|
|
79
|
+
* SPEC.md §7.2 item 2 is performed against this. It is shipped as data
|
|
80
|
+
* rather than only as a `.json` file because TypeScript types are erased
|
|
81
|
+
* at runtime: without a schema a consumer has nothing to validate, and
|
|
82
|
+
* every REQUIRED payload member is optional in practice. Cross-file
|
|
83
|
+
* `$ref`s are already inlined, so it needs no resolver.
|
|
84
|
+
*/
|
|
85
|
+
export const PAYLOAD_SCHEMA = {
|
|
86
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
87
|
+
"$id": "https://trusttasks.org/spec/vtc/admin/actions/list/0.2",
|
|
88
|
+
"title": "VTC Admin Actions — List — payload",
|
|
89
|
+
"description": "Enumerate the administrative actions a Verifiable Trust Community holds that the caller is entitled to see, one page at a time, from one of four views. The single-record sibling is vtc/admin/actions/show/0.2. The outer document members (id, type, issuer, recipient, issuedAt, expiresAt, proof) are owned by the framework — SPEC §6.3.",
|
|
90
|
+
"type": "object",
|
|
91
|
+
"additionalProperties": false,
|
|
92
|
+
"required": [
|
|
93
|
+
"view"
|
|
94
|
+
],
|
|
95
|
+
"properties": {
|
|
96
|
+
"view": {
|
|
97
|
+
"type": "string",
|
|
98
|
+
"enum": [
|
|
99
|
+
"waitingForMe",
|
|
100
|
+
"requestedByMe",
|
|
101
|
+
"history",
|
|
102
|
+
"all"
|
|
103
|
+
],
|
|
104
|
+
"description": "`waitingForMe` — open actions on which the caller is an eligible approver or acknowledger and has not yet decided. `requestedByMe` — open actions the caller requested, including `coolingOff` actions that will land unless the caller cancels them. `history` — closed actions the caller requested, decided, or was the subject of, or (with the audit-read capability) any closed action, newest first. `all` — every action the caller may see, open and closed, including a `coolingOff` action that acts on the caller (`callerRole: subject`). A `coolingOff` action is never in `waitingForMe`: nobody decides it."
|
|
105
|
+
},
|
|
106
|
+
"since": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"format": "date-time",
|
|
109
|
+
"description": "Only with `view: history`: return actions closed at or after this instant. Supplied with any other view it is refused with `invalidFilter` rather than ignored, so a caller never reads a silently unfiltered page as a filtered one."
|
|
110
|
+
},
|
|
111
|
+
"limit": {
|
|
112
|
+
"type": "integer",
|
|
113
|
+
"minimum": 1,
|
|
114
|
+
"maximum": 100,
|
|
115
|
+
"default": 25,
|
|
116
|
+
"description": "Maximum number of actions in the page. The community MAY return fewer."
|
|
117
|
+
},
|
|
118
|
+
"cursor": {
|
|
119
|
+
"type": "string",
|
|
120
|
+
"minLength": 1,
|
|
121
|
+
"maxLength": 1024,
|
|
122
|
+
"description": "Opaque continuation token from a previous page's `nextCursor`, valid only with the same `view` and `since` it was issued for."
|
|
123
|
+
},
|
|
124
|
+
"ext": {
|
|
125
|
+
"$ref": "#/$defs/Ext"
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"$defs": {
|
|
129
|
+
"Response": {
|
|
130
|
+
"$anchor": "response",
|
|
131
|
+
"title": "VTC Admin Actions — List — response payload",
|
|
132
|
+
"description": "One page of actions and the caller's badge counts. Failures use trust-task-error, not this shape.",
|
|
133
|
+
"type": "object",
|
|
134
|
+
"additionalProperties": false,
|
|
135
|
+
"required": [
|
|
136
|
+
"actions",
|
|
137
|
+
"counts"
|
|
138
|
+
],
|
|
139
|
+
"properties": {
|
|
140
|
+
"actions": {
|
|
141
|
+
"type": "array",
|
|
142
|
+
"maxItems": 100,
|
|
143
|
+
"items": {
|
|
144
|
+
"$ref": "#/$defs/Action"
|
|
145
|
+
},
|
|
146
|
+
"description": "The page, in the view's order: open views by deadline soonest first — `expiresAt`, or `landsAt` for `coolingOff` — (actions with neither last, then by `createdAt`), `history` by `closedAt` newest first, `all` open-before-closed in those orders. An empty array is a successful answer: nothing in this view."
|
|
147
|
+
},
|
|
148
|
+
"nextCursor": {
|
|
149
|
+
"type": "string",
|
|
150
|
+
"minLength": 1,
|
|
151
|
+
"maxLength": 1024,
|
|
152
|
+
"description": "Present when more actions follow. Pass it back as `cursor` with the same `view` and `since`."
|
|
153
|
+
},
|
|
154
|
+
"counts": {
|
|
155
|
+
"type": "object",
|
|
156
|
+
"additionalProperties": false,
|
|
157
|
+
"required": [
|
|
158
|
+
"waitingForMe",
|
|
159
|
+
"requestedByMe"
|
|
160
|
+
],
|
|
161
|
+
"description": "Totals across the whole collection, not the page — what a console badge shows. Computed for the caller regardless of which `view` was requested.",
|
|
162
|
+
"properties": {
|
|
163
|
+
"waitingForMe": {
|
|
164
|
+
"type": "integer",
|
|
165
|
+
"minimum": 0,
|
|
166
|
+
"description": "Open actions awaiting the caller's decision or acknowledgement."
|
|
167
|
+
},
|
|
168
|
+
"requestedByMe": {
|
|
169
|
+
"type": "integer",
|
|
170
|
+
"minimum": 0,
|
|
171
|
+
"description": "Open actions the caller requested."
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
"ext": {
|
|
176
|
+
"$ref": "#/$defs/Ext"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
"Ext": {
|
|
181
|
+
"title": "Ext",
|
|
182
|
+
"description": "Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.",
|
|
183
|
+
"type": "object",
|
|
184
|
+
"minProperties": 1,
|
|
185
|
+
"additionalProperties": true,
|
|
186
|
+
"propertyNames": {
|
|
187
|
+
"pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
"Action": {
|
|
191
|
+
"title": "Action",
|
|
192
|
+
"description": "One parked administrative operation, as the caller is entitled to see it. The same action reads differently to different callers only in `challenge` and `callerRole`, which are per-caller.",
|
|
193
|
+
"type": "object",
|
|
194
|
+
"additionalProperties": false,
|
|
195
|
+
"required": [
|
|
196
|
+
"actionId",
|
|
197
|
+
"category",
|
|
198
|
+
"kind",
|
|
199
|
+
"typeUri",
|
|
200
|
+
"requester",
|
|
201
|
+
"status",
|
|
202
|
+
"createdAt",
|
|
203
|
+
"approvals",
|
|
204
|
+
"summary",
|
|
205
|
+
"payload",
|
|
206
|
+
"payloadDigest",
|
|
207
|
+
"callerRole"
|
|
208
|
+
],
|
|
209
|
+
"properties": {
|
|
210
|
+
"actionId": {
|
|
211
|
+
"$ref": "#/$defs/ActionId"
|
|
212
|
+
},
|
|
213
|
+
"category": {
|
|
214
|
+
"type": "string",
|
|
215
|
+
"enum": [
|
|
216
|
+
"approval",
|
|
217
|
+
"acknowledge",
|
|
218
|
+
"queue",
|
|
219
|
+
"coolingOff"
|
|
220
|
+
],
|
|
221
|
+
"description": "`approval` — eligible approvers approve or decline, N-of-M; the operation executes when the threshold is met. `acknowledge` — an operation that already happened (an operator's offline or break-glass write) which every remaining administrator must acknowledge; there is nothing to approve or decline. `queue` — an existing human decision (for example a join review) surfaced in the same list, with a threshold of one. `coolingOff` — an operation with no eligible third party to consent, which lands by itself at `landsAt` unless its requester cancels it first; nobody approves, declines or acknowledges it."
|
|
222
|
+
},
|
|
223
|
+
"kind": {
|
|
224
|
+
"type": "string",
|
|
225
|
+
"minLength": 1,
|
|
226
|
+
"maxLength": 128,
|
|
227
|
+
"pattern": "^[a-z][a-zA-Z0-9.]*$",
|
|
228
|
+
"description": "The community's name for what kind of operation is parked, dotted and lowerCamelCase (`acl.grant.authority`, `member.join.review`). Selects the summary template. The set is OPEN: a renderer that does not recognise a kind still renders `summary` from its fields."
|
|
229
|
+
},
|
|
230
|
+
"typeUri": {
|
|
231
|
+
"type": "string",
|
|
232
|
+
"format": "uri",
|
|
233
|
+
"minLength": 1,
|
|
234
|
+
"description": "The Type URI of the parked operation — the Trust Task the community will execute when the action completes (for `coolingOff`, when it lands). Together with `payload` it is exactly what will run. For `acknowledge`, the Type URI of the operation that already took effect; an operator's offline write, which is a command on the community's host and has no Trust Task of its own, is named by the record type `https://trusttasks.org/spec/vtc/operator/offline-write/0.1`, and `payload` is then that record."
|
|
235
|
+
},
|
|
236
|
+
"requester": {
|
|
237
|
+
"type": "string",
|
|
238
|
+
"minLength": 1,
|
|
239
|
+
"maxLength": 2048,
|
|
240
|
+
"description": "VID of the party whose operation was parked. For `acknowledge`, the operator whose offline write is being acknowledged, where the community can attribute one. For `coolingOff`, the administrator whose operation will land — the only party who may cancel it."
|
|
241
|
+
},
|
|
242
|
+
"status": {
|
|
243
|
+
"type": "string",
|
|
244
|
+
"enum": [
|
|
245
|
+
"open",
|
|
246
|
+
"completed",
|
|
247
|
+
"declined",
|
|
248
|
+
"expired",
|
|
249
|
+
"cancelled",
|
|
250
|
+
"failed"
|
|
251
|
+
],
|
|
252
|
+
"description": "`open` — awaiting decisions, or for `coolingOff` awaiting `landsAt`. `completed` — the threshold was met and the operation executed, a `coolingOff` operation landed, or, for `acknowledge`, every administrator acknowledged. `declined` — an eligible approver denied it. `expired` — it lapsed at `expiresAt`. `cancelled` — the requester withdrew it, or the community invalidated it (see `closedReason`). `failed` — the threshold was met or `landsAt` reached but the re-check at execution refused it, or execution itself failed; the operation did not take effect."
|
|
253
|
+
},
|
|
254
|
+
"createdAt": {
|
|
255
|
+
"type": "string",
|
|
256
|
+
"format": "date-time",
|
|
257
|
+
"description": "When the operation was parked."
|
|
258
|
+
},
|
|
259
|
+
"expiresAt": {
|
|
260
|
+
"type": "string",
|
|
261
|
+
"format": "date-time",
|
|
262
|
+
"description": "When an open action lapses. ALWAYS present for `approval`, whose open life is bounded (72 hours by default; the community configures it between 15 minutes and 14 days). Absent for an `acknowledge` or `queue` action that does not expire, and ALWAYS absent for `coolingOff`, which does not lapse but lands — see `landsAt`."
|
|
263
|
+
},
|
|
264
|
+
"landsAt": {
|
|
265
|
+
"type": "string",
|
|
266
|
+
"format": "date-time",
|
|
267
|
+
"description": "When a `coolingOff` action lands: the instant from which the community executes the parked operation, after its execution-time re-check, unless the requester cancelled first. Present exactly when `category` is `coolingOff`. It is a deadline for the requester's cancellation, not for anyone's approval, and it is fixed when the action is parked: neither the requester nor the subject can move it."
|
|
268
|
+
},
|
|
269
|
+
"cancellableBy": {
|
|
270
|
+
"type": "string",
|
|
271
|
+
"enum": [
|
|
272
|
+
"requester"
|
|
273
|
+
],
|
|
274
|
+
"description": "Who may withdraw the action with `vtc/admin/actions/cancel` while it is `open`. Present on every open `coolingOff` action, where it is `requester`: the operation lands unless its requester stops it, and nobody else — the subject included — can. A closed set so that a console can offer a cancel control without inferring it; future values would widen who may cancel and need a new version."
|
|
275
|
+
},
|
|
276
|
+
"closedAt": {
|
|
277
|
+
"type": "string",
|
|
278
|
+
"format": "date-time",
|
|
279
|
+
"description": "When the action left `open`. Present exactly when `status` is not `open`."
|
|
280
|
+
},
|
|
281
|
+
"closedReason": {
|
|
282
|
+
"type": "string",
|
|
283
|
+
"enum": [
|
|
284
|
+
"thresholdMet",
|
|
285
|
+
"declined",
|
|
286
|
+
"expired",
|
|
287
|
+
"cancelledByRequester",
|
|
288
|
+
"invalidated",
|
|
289
|
+
"failedRecheck",
|
|
290
|
+
"acknowledged",
|
|
291
|
+
"landedAfterCoolingOff"
|
|
292
|
+
],
|
|
293
|
+
"description": "Why the action closed. Present exactly when `status` is not `open`. `invalidated` — the community closed it because something it depended on stopped holding before the threshold or `landsAt` (an approver or the requester lost standing, the target state moved); `failedRecheck` — the threshold was met or `landsAt` reached but the execution-time re-check refused; `landedAfterCoolingOff` — a `coolingOff` action reached `landsAt` uncancelled and its operation executed (`status: completed`)."
|
|
294
|
+
},
|
|
295
|
+
"threshold": {
|
|
296
|
+
"type": "integer",
|
|
297
|
+
"minimum": 1,
|
|
298
|
+
"description": "The number of distinct approvals the operation needs. Present for `approval`; absent otherwise (a `queue` decision is one decision by construction, `acknowledge` needs every remaining administrator, and `coolingOff` needs no approval at all)."
|
|
299
|
+
},
|
|
300
|
+
"approvals": {
|
|
301
|
+
"type": "array",
|
|
302
|
+
"description": "The decisions in favour recorded so far — approvals for `approval` and `queue`, acknowledgements for `acknowledge` — one entry per distinct subject, in the order recorded. Empty while none has landed, and always empty for `coolingOff`, which takes no decisions.",
|
|
303
|
+
"items": {
|
|
304
|
+
"type": "object",
|
|
305
|
+
"additionalProperties": false,
|
|
306
|
+
"required": [
|
|
307
|
+
"subject",
|
|
308
|
+
"at"
|
|
309
|
+
],
|
|
310
|
+
"properties": {
|
|
311
|
+
"subject": {
|
|
312
|
+
"type": "string",
|
|
313
|
+
"minLength": 1,
|
|
314
|
+
"maxLength": 2048,
|
|
315
|
+
"description": "VID of the approver or acknowledger, as proven by the decision's own proof."
|
|
316
|
+
},
|
|
317
|
+
"at": {
|
|
318
|
+
"type": "string",
|
|
319
|
+
"format": "date-time",
|
|
320
|
+
"description": "When the decision was recorded."
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
"approversRemaining": {
|
|
326
|
+
"type": "integer",
|
|
327
|
+
"minimum": 0,
|
|
328
|
+
"description": "How many further distinct decisions the action needs while `open` — approvals for `approval`, acknowledgements for `acknowledge`. Lets a console say 'one more' without disclosing the eligible set. Absent for `coolingOff`, which waits on time, not on decisions."
|
|
329
|
+
},
|
|
330
|
+
"summary": {
|
|
331
|
+
"$ref": "#/$defs/Summary"
|
|
332
|
+
},
|
|
333
|
+
"payload": {
|
|
334
|
+
"type": "object",
|
|
335
|
+
"description": "The exact payload of the parked operation — the object `payloadDigest` is computed over and the one the community will execute. Carried so an approver can recompute the digest and re-derive every summary field from it rather than trusting the rendering (VTI-APV-013). Deliberately an open object: its shape is governed by the specification `typeUri` names, and a digest is checked over members exactly as received."
|
|
336
|
+
},
|
|
337
|
+
"payloadDigest": {
|
|
338
|
+
"$ref": "#/$defs/DigestMultibase",
|
|
339
|
+
"description": "Digest of `payload`, taken over its RFC 8785 (JCS) canonicalization. The community re-derives it from the payload it is about to execute and refuses on mismatch. The digest an approver signs over is the challenge-salted one of `task-consent/decision`, not this value; this one lets the approver check that `payload` is what was parked."
|
|
340
|
+
},
|
|
341
|
+
"challenge": {
|
|
342
|
+
"type": "string",
|
|
343
|
+
"minLength": 16,
|
|
344
|
+
"maxLength": 256,
|
|
345
|
+
"description": "Present ONLY on an action the CALLER may decide now — an `approval` or `queue` action on which the caller is an eligible approver who has not yet decided. Never present on `acknowledge` or `coolingOff`. Per-approver: two approvers are shown different challenges for the same action. Echoed verbatim in `task-consent/decision`'s `challenge`, which binds that decision to this approver and this action. Absent for everyone else, including the requester."
|
|
346
|
+
},
|
|
347
|
+
"callerRole": {
|
|
348
|
+
"type": "string",
|
|
349
|
+
"enum": [
|
|
350
|
+
"approver",
|
|
351
|
+
"requester",
|
|
352
|
+
"acknowledger",
|
|
353
|
+
"subject",
|
|
354
|
+
"observer"
|
|
355
|
+
],
|
|
356
|
+
"description": "The caller's relation to this action. `approver` — an eligible approver (whether or not already decided). `requester` — the party whose operation was parked. `acknowledger` — an administrator expected to acknowledge it. `subject` — the party a `coolingOff` operation acts on, shown it so that they learn of it before it lands; a subject can neither decide nor cancel it. `observer` — none of these; seen only through the audit-read capability on a `history` or `all` view."
|
|
357
|
+
},
|
|
358
|
+
"requesterOpenActions": {
|
|
359
|
+
"type": "integer",
|
|
360
|
+
"minimum": 0,
|
|
361
|
+
"description": "How many open actions the requester currently has at the community, this one included. For consent-fatigue display: an approver shown the twentieth request from one requester today should be able to see that it is the twentieth."
|
|
362
|
+
},
|
|
363
|
+
"ext": {
|
|
364
|
+
"$ref": "#/$defs/Ext"
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
},
|
|
368
|
+
"Summary": {
|
|
369
|
+
"title": "Summary",
|
|
370
|
+
"description": "What an approver is shown, rendered from the summary template for the action's `kind`. Title and effect are the template's prose; the fields are the payload values that prose is about, each located by pointer so a renderer can verify it.",
|
|
371
|
+
"type": "object",
|
|
372
|
+
"additionalProperties": false,
|
|
373
|
+
"required": [
|
|
374
|
+
"title",
|
|
375
|
+
"fields",
|
|
376
|
+
"templateDigest"
|
|
377
|
+
],
|
|
378
|
+
"properties": {
|
|
379
|
+
"title": {
|
|
380
|
+
"type": "string",
|
|
381
|
+
"minLength": 1,
|
|
382
|
+
"maxLength": 256,
|
|
383
|
+
"description": "One-line heading from the template. Prose only: a renderer MUST NOT present the action from this text without the fields."
|
|
384
|
+
},
|
|
385
|
+
"effect": {
|
|
386
|
+
"type": "string",
|
|
387
|
+
"maxLength": 1024,
|
|
388
|
+
"description": "One or two sentences from the template saying what executing the operation will do."
|
|
389
|
+
},
|
|
390
|
+
"fields": {
|
|
391
|
+
"type": "object",
|
|
392
|
+
"description": "Named values the template displays, keyed by a lowerCamelCase field name. Each locates its value in `payload` by JSON Pointer.",
|
|
393
|
+
"propertyNames": {
|
|
394
|
+
"pattern": "^[a-z][a-zA-Z0-9]*$",
|
|
395
|
+
"maxLength": 64
|
|
396
|
+
},
|
|
397
|
+
"additionalProperties": {
|
|
398
|
+
"$ref": "#/$defs/Field"
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
|
+
"templateDigest": {
|
|
402
|
+
"$ref": "#/$defs/DigestMultibase",
|
|
403
|
+
"description": "Digest of the summary template this summary was rendered from, over its RFC 8785 (JCS) canonicalization. Pinned per `kind`: a renderer that holds the template for a kind refuses a summary naming a different digest, so the community cannot change what approvers are shown for a kind without that change being visible."
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
"Field": {
|
|
408
|
+
"title": "Field",
|
|
409
|
+
"description": "One displayed value, with where it comes from and how to render it.",
|
|
410
|
+
"type": "object",
|
|
411
|
+
"additionalProperties": false,
|
|
412
|
+
"required": [
|
|
413
|
+
"pointer",
|
|
414
|
+
"format",
|
|
415
|
+
"value"
|
|
416
|
+
],
|
|
417
|
+
"properties": {
|
|
418
|
+
"pointer": {
|
|
419
|
+
"type": "string",
|
|
420
|
+
"maxLength": 512,
|
|
421
|
+
"pattern": "^(/([^~/]|~[01])*)*$",
|
|
422
|
+
"description": "RFC 6901 JSON Pointer into the action's `payload`. The empty string addresses the whole payload."
|
|
423
|
+
},
|
|
424
|
+
"format": {
|
|
425
|
+
"type": "string",
|
|
426
|
+
"enum": [
|
|
427
|
+
"did",
|
|
428
|
+
"capabilityList",
|
|
429
|
+
"duration",
|
|
430
|
+
"datetime",
|
|
431
|
+
"text"
|
|
432
|
+
],
|
|
433
|
+
"description": "How to render the value. `did` — a DID, shown in full or with a verified display name, never truncated to a prefix that two DIDs share. `capabilityList` — an array of capability names. `duration` — an ISO 8601 duration. `datetime` — an RFC 3339 date-time. `text` — anything else, rendered as literal text."
|
|
434
|
+
},
|
|
435
|
+
"value": {
|
|
436
|
+
"description": "The value found at `pointer` when the community rendered the summary. A renderer re-derives it from `payload` and refuses to render the action on any mismatch; it is carried so that a mismatch is detectable, not so that it can be trusted."
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
"DigestMultibase": {
|
|
441
|
+
"title": "DigestMultibase",
|
|
442
|
+
"description": "A cryptographic digest as a multibase-encoded multihash — the encoding the W3C Verifiable Credentials Data Model 2.0 defines for `digestMultibase`, and the one `did:webvh` uses for its SCID and entry hashes.\n\nMultihash carries the hash algorithm in-band, so the value is self-describing and the wire format survives an algorithm change without a schema revision; multibase does the same for the base encoding, so a verifier never infers base58 from base64url by context. A bare hex string or a `sha-256:`-style prefix hard-codes one algorithm into the wire contract and is non-conforming here.\n\nThis definition constrains the *encoding only*. What the digest is computed over is stated by each referencing field, because it differs legitimately: a digest over a JSON document is taken over its RFC 8785 (JCS) canonicalization, while a digest over an opaque artifact is taken over its bytes. A field whose input is a JSON document and which does not name a canonicalization is not reproducible.\n\nRestricted to the two multibase headers W3C Controlled Identifiers 1.0 §2.4 normatively requires — `z` (base58btc) and `u` (base64url-no-pad). CID permits others but states that \"interoperability is not guaranteed between implementations using such values\", and a registry whose purpose is interoperability should not mint digests a conforming verifier may be unable to read. The alphabets are enforced rather than assumed: base58btc excludes 0, O, I and l, and an earlier permissive pattern let three published examples carry digests that were not valid base58 at all. base58btc is RECOMMENDED, for consistency with `did:key` and `did:webvh`.",
|
|
443
|
+
"type": "string",
|
|
444
|
+
"minLength": 16,
|
|
445
|
+
"pattern": "^(z[1-9A-HJ-NP-Za-km-z]+|u[A-Za-z0-9_-]+)$",
|
|
446
|
+
"examples": [
|
|
447
|
+
"zQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR"
|
|
448
|
+
]
|
|
449
|
+
},
|
|
450
|
+
"ActionId": {
|
|
451
|
+
"title": "ActionId",
|
|
452
|
+
"description": "Opaque, community-minted identifier of one action. A consumer MUST NOT parse or order it; it is compared for equality only. Long enough to be unguessable, because a show of an id the caller may not see is answered `notFound` and an enumerable id would turn that answer into an oracle.",
|
|
453
|
+
"type": "string",
|
|
454
|
+
"minLength": 16,
|
|
455
|
+
"maxLength": 128,
|
|
456
|
+
"pattern": "^[A-Za-z0-9._~:-]+$"
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
} as const;
|
|
460
|
+
|
|
461
|
+
/** As {@link PAYLOAD_SCHEMA}, for the success-response variant. */
|
|
462
|
+
export const RESPONSE_PAYLOAD_SCHEMA = {
|
|
463
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
464
|
+
"$ref": "#/$defs/Response",
|
|
465
|
+
"$defs": {
|
|
466
|
+
"Response": {
|
|
467
|
+
"$anchor": "response",
|
|
468
|
+
"title": "VTC Admin Actions — List — response payload",
|
|
469
|
+
"description": "One page of actions and the caller's badge counts. Failures use trust-task-error, not this shape.",
|
|
470
|
+
"type": "object",
|
|
471
|
+
"additionalProperties": false,
|
|
472
|
+
"required": [
|
|
473
|
+
"actions",
|
|
474
|
+
"counts"
|
|
475
|
+
],
|
|
476
|
+
"properties": {
|
|
477
|
+
"actions": {
|
|
478
|
+
"type": "array",
|
|
479
|
+
"maxItems": 100,
|
|
480
|
+
"items": {
|
|
481
|
+
"$ref": "#/$defs/Action"
|
|
482
|
+
},
|
|
483
|
+
"description": "The page, in the view's order: open views by deadline soonest first — `expiresAt`, or `landsAt` for `coolingOff` — (actions with neither last, then by `createdAt`), `history` by `closedAt` newest first, `all` open-before-closed in those orders. An empty array is a successful answer: nothing in this view."
|
|
484
|
+
},
|
|
485
|
+
"nextCursor": {
|
|
486
|
+
"type": "string",
|
|
487
|
+
"minLength": 1,
|
|
488
|
+
"maxLength": 1024,
|
|
489
|
+
"description": "Present when more actions follow. Pass it back as `cursor` with the same `view` and `since`."
|
|
490
|
+
},
|
|
491
|
+
"counts": {
|
|
492
|
+
"type": "object",
|
|
493
|
+
"additionalProperties": false,
|
|
494
|
+
"required": [
|
|
495
|
+
"waitingForMe",
|
|
496
|
+
"requestedByMe"
|
|
497
|
+
],
|
|
498
|
+
"description": "Totals across the whole collection, not the page — what a console badge shows. Computed for the caller regardless of which `view` was requested.",
|
|
499
|
+
"properties": {
|
|
500
|
+
"waitingForMe": {
|
|
501
|
+
"type": "integer",
|
|
502
|
+
"minimum": 0,
|
|
503
|
+
"description": "Open actions awaiting the caller's decision or acknowledgement."
|
|
504
|
+
},
|
|
505
|
+
"requestedByMe": {
|
|
506
|
+
"type": "integer",
|
|
507
|
+
"minimum": 0,
|
|
508
|
+
"description": "Open actions the caller requested."
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
"ext": {
|
|
513
|
+
"$ref": "#/$defs/Ext"
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
"Ext": {
|
|
518
|
+
"title": "Ext",
|
|
519
|
+
"description": "Vendor-namespaced extension object per SPEC.md §4.5.1. Each immediate key MUST be a reverse-DNS namespace; structure under each namespace is opaque to the framework.",
|
|
520
|
+
"type": "object",
|
|
521
|
+
"minProperties": 1,
|
|
522
|
+
"additionalProperties": true,
|
|
523
|
+
"propertyNames": {
|
|
524
|
+
"pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
|
|
525
|
+
}
|
|
526
|
+
},
|
|
527
|
+
"Action": {
|
|
528
|
+
"title": "Action",
|
|
529
|
+
"description": "One parked administrative operation, as the caller is entitled to see it. The same action reads differently to different callers only in `challenge` and `callerRole`, which are per-caller.",
|
|
530
|
+
"type": "object",
|
|
531
|
+
"additionalProperties": false,
|
|
532
|
+
"required": [
|
|
533
|
+
"actionId",
|
|
534
|
+
"category",
|
|
535
|
+
"kind",
|
|
536
|
+
"typeUri",
|
|
537
|
+
"requester",
|
|
538
|
+
"status",
|
|
539
|
+
"createdAt",
|
|
540
|
+
"approvals",
|
|
541
|
+
"summary",
|
|
542
|
+
"payload",
|
|
543
|
+
"payloadDigest",
|
|
544
|
+
"callerRole"
|
|
545
|
+
],
|
|
546
|
+
"properties": {
|
|
547
|
+
"actionId": {
|
|
548
|
+
"$ref": "#/$defs/ActionId"
|
|
549
|
+
},
|
|
550
|
+
"category": {
|
|
551
|
+
"type": "string",
|
|
552
|
+
"enum": [
|
|
553
|
+
"approval",
|
|
554
|
+
"acknowledge",
|
|
555
|
+
"queue",
|
|
556
|
+
"coolingOff"
|
|
557
|
+
],
|
|
558
|
+
"description": "`approval` — eligible approvers approve or decline, N-of-M; the operation executes when the threshold is met. `acknowledge` — an operation that already happened (an operator's offline or break-glass write) which every remaining administrator must acknowledge; there is nothing to approve or decline. `queue` — an existing human decision (for example a join review) surfaced in the same list, with a threshold of one. `coolingOff` — an operation with no eligible third party to consent, which lands by itself at `landsAt` unless its requester cancels it first; nobody approves, declines or acknowledges it."
|
|
559
|
+
},
|
|
560
|
+
"kind": {
|
|
561
|
+
"type": "string",
|
|
562
|
+
"minLength": 1,
|
|
563
|
+
"maxLength": 128,
|
|
564
|
+
"pattern": "^[a-z][a-zA-Z0-9.]*$",
|
|
565
|
+
"description": "The community's name for what kind of operation is parked, dotted and lowerCamelCase (`acl.grant.authority`, `member.join.review`). Selects the summary template. The set is OPEN: a renderer that does not recognise a kind still renders `summary` from its fields."
|
|
566
|
+
},
|
|
567
|
+
"typeUri": {
|
|
568
|
+
"type": "string",
|
|
569
|
+
"format": "uri",
|
|
570
|
+
"minLength": 1,
|
|
571
|
+
"description": "The Type URI of the parked operation — the Trust Task the community will execute when the action completes (for `coolingOff`, when it lands). Together with `payload` it is exactly what will run. For `acknowledge`, the Type URI of the operation that already took effect; an operator's offline write, which is a command on the community's host and has no Trust Task of its own, is named by the record type `https://trusttasks.org/spec/vtc/operator/offline-write/0.1`, and `payload` is then that record."
|
|
572
|
+
},
|
|
573
|
+
"requester": {
|
|
574
|
+
"type": "string",
|
|
575
|
+
"minLength": 1,
|
|
576
|
+
"maxLength": 2048,
|
|
577
|
+
"description": "VID of the party whose operation was parked. For `acknowledge`, the operator whose offline write is being acknowledged, where the community can attribute one. For `coolingOff`, the administrator whose operation will land — the only party who may cancel it."
|
|
578
|
+
},
|
|
579
|
+
"status": {
|
|
580
|
+
"type": "string",
|
|
581
|
+
"enum": [
|
|
582
|
+
"open",
|
|
583
|
+
"completed",
|
|
584
|
+
"declined",
|
|
585
|
+
"expired",
|
|
586
|
+
"cancelled",
|
|
587
|
+
"failed"
|
|
588
|
+
],
|
|
589
|
+
"description": "`open` — awaiting decisions, or for `coolingOff` awaiting `landsAt`. `completed` — the threshold was met and the operation executed, a `coolingOff` operation landed, or, for `acknowledge`, every administrator acknowledged. `declined` — an eligible approver denied it. `expired` — it lapsed at `expiresAt`. `cancelled` — the requester withdrew it, or the community invalidated it (see `closedReason`). `failed` — the threshold was met or `landsAt` reached but the re-check at execution refused it, or execution itself failed; the operation did not take effect."
|
|
590
|
+
},
|
|
591
|
+
"createdAt": {
|
|
592
|
+
"type": "string",
|
|
593
|
+
"format": "date-time",
|
|
594
|
+
"description": "When the operation was parked."
|
|
595
|
+
},
|
|
596
|
+
"expiresAt": {
|
|
597
|
+
"type": "string",
|
|
598
|
+
"format": "date-time",
|
|
599
|
+
"description": "When an open action lapses. ALWAYS present for `approval`, whose open life is bounded (72 hours by default; the community configures it between 15 minutes and 14 days). Absent for an `acknowledge` or `queue` action that does not expire, and ALWAYS absent for `coolingOff`, which does not lapse but lands — see `landsAt`."
|
|
600
|
+
},
|
|
601
|
+
"landsAt": {
|
|
602
|
+
"type": "string",
|
|
603
|
+
"format": "date-time",
|
|
604
|
+
"description": "When a `coolingOff` action lands: the instant from which the community executes the parked operation, after its execution-time re-check, unless the requester cancelled first. Present exactly when `category` is `coolingOff`. It is a deadline for the requester's cancellation, not for anyone's approval, and it is fixed when the action is parked: neither the requester nor the subject can move it."
|
|
605
|
+
},
|
|
606
|
+
"cancellableBy": {
|
|
607
|
+
"type": "string",
|
|
608
|
+
"enum": [
|
|
609
|
+
"requester"
|
|
610
|
+
],
|
|
611
|
+
"description": "Who may withdraw the action with `vtc/admin/actions/cancel` while it is `open`. Present on every open `coolingOff` action, where it is `requester`: the operation lands unless its requester stops it, and nobody else — the subject included — can. A closed set so that a console can offer a cancel control without inferring it; future values would widen who may cancel and need a new version."
|
|
612
|
+
},
|
|
613
|
+
"closedAt": {
|
|
614
|
+
"type": "string",
|
|
615
|
+
"format": "date-time",
|
|
616
|
+
"description": "When the action left `open`. Present exactly when `status` is not `open`."
|
|
617
|
+
},
|
|
618
|
+
"closedReason": {
|
|
619
|
+
"type": "string",
|
|
620
|
+
"enum": [
|
|
621
|
+
"thresholdMet",
|
|
622
|
+
"declined",
|
|
623
|
+
"expired",
|
|
624
|
+
"cancelledByRequester",
|
|
625
|
+
"invalidated",
|
|
626
|
+
"failedRecheck",
|
|
627
|
+
"acknowledged",
|
|
628
|
+
"landedAfterCoolingOff"
|
|
629
|
+
],
|
|
630
|
+
"description": "Why the action closed. Present exactly when `status` is not `open`. `invalidated` — the community closed it because something it depended on stopped holding before the threshold or `landsAt` (an approver or the requester lost standing, the target state moved); `failedRecheck` — the threshold was met or `landsAt` reached but the execution-time re-check refused; `landedAfterCoolingOff` — a `coolingOff` action reached `landsAt` uncancelled and its operation executed (`status: completed`)."
|
|
631
|
+
},
|
|
632
|
+
"threshold": {
|
|
633
|
+
"type": "integer",
|
|
634
|
+
"minimum": 1,
|
|
635
|
+
"description": "The number of distinct approvals the operation needs. Present for `approval`; absent otherwise (a `queue` decision is one decision by construction, `acknowledge` needs every remaining administrator, and `coolingOff` needs no approval at all)."
|
|
636
|
+
},
|
|
637
|
+
"approvals": {
|
|
638
|
+
"type": "array",
|
|
639
|
+
"description": "The decisions in favour recorded so far — approvals for `approval` and `queue`, acknowledgements for `acknowledge` — one entry per distinct subject, in the order recorded. Empty while none has landed, and always empty for `coolingOff`, which takes no decisions.",
|
|
640
|
+
"items": {
|
|
641
|
+
"type": "object",
|
|
642
|
+
"additionalProperties": false,
|
|
643
|
+
"required": [
|
|
644
|
+
"subject",
|
|
645
|
+
"at"
|
|
646
|
+
],
|
|
647
|
+
"properties": {
|
|
648
|
+
"subject": {
|
|
649
|
+
"type": "string",
|
|
650
|
+
"minLength": 1,
|
|
651
|
+
"maxLength": 2048,
|
|
652
|
+
"description": "VID of the approver or acknowledger, as proven by the decision's own proof."
|
|
653
|
+
},
|
|
654
|
+
"at": {
|
|
655
|
+
"type": "string",
|
|
656
|
+
"format": "date-time",
|
|
657
|
+
"description": "When the decision was recorded."
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
"approversRemaining": {
|
|
663
|
+
"type": "integer",
|
|
664
|
+
"minimum": 0,
|
|
665
|
+
"description": "How many further distinct decisions the action needs while `open` — approvals for `approval`, acknowledgements for `acknowledge`. Lets a console say 'one more' without disclosing the eligible set. Absent for `coolingOff`, which waits on time, not on decisions."
|
|
666
|
+
},
|
|
667
|
+
"summary": {
|
|
668
|
+
"$ref": "#/$defs/Summary"
|
|
669
|
+
},
|
|
670
|
+
"payload": {
|
|
671
|
+
"type": "object",
|
|
672
|
+
"description": "The exact payload of the parked operation — the object `payloadDigest` is computed over and the one the community will execute. Carried so an approver can recompute the digest and re-derive every summary field from it rather than trusting the rendering (VTI-APV-013). Deliberately an open object: its shape is governed by the specification `typeUri` names, and a digest is checked over members exactly as received."
|
|
673
|
+
},
|
|
674
|
+
"payloadDigest": {
|
|
675
|
+
"$ref": "#/$defs/DigestMultibase",
|
|
676
|
+
"description": "Digest of `payload`, taken over its RFC 8785 (JCS) canonicalization. The community re-derives it from the payload it is about to execute and refuses on mismatch. The digest an approver signs over is the challenge-salted one of `task-consent/decision`, not this value; this one lets the approver check that `payload` is what was parked."
|
|
677
|
+
},
|
|
678
|
+
"challenge": {
|
|
679
|
+
"type": "string",
|
|
680
|
+
"minLength": 16,
|
|
681
|
+
"maxLength": 256,
|
|
682
|
+
"description": "Present ONLY on an action the CALLER may decide now — an `approval` or `queue` action on which the caller is an eligible approver who has not yet decided. Never present on `acknowledge` or `coolingOff`. Per-approver: two approvers are shown different challenges for the same action. Echoed verbatim in `task-consent/decision`'s `challenge`, which binds that decision to this approver and this action. Absent for everyone else, including the requester."
|
|
683
|
+
},
|
|
684
|
+
"callerRole": {
|
|
685
|
+
"type": "string",
|
|
686
|
+
"enum": [
|
|
687
|
+
"approver",
|
|
688
|
+
"requester",
|
|
689
|
+
"acknowledger",
|
|
690
|
+
"subject",
|
|
691
|
+
"observer"
|
|
692
|
+
],
|
|
693
|
+
"description": "The caller's relation to this action. `approver` — an eligible approver (whether or not already decided). `requester` — the party whose operation was parked. `acknowledger` — an administrator expected to acknowledge it. `subject` — the party a `coolingOff` operation acts on, shown it so that they learn of it before it lands; a subject can neither decide nor cancel it. `observer` — none of these; seen only through the audit-read capability on a `history` or `all` view."
|
|
694
|
+
},
|
|
695
|
+
"requesterOpenActions": {
|
|
696
|
+
"type": "integer",
|
|
697
|
+
"minimum": 0,
|
|
698
|
+
"description": "How many open actions the requester currently has at the community, this one included. For consent-fatigue display: an approver shown the twentieth request from one requester today should be able to see that it is the twentieth."
|
|
699
|
+
},
|
|
700
|
+
"ext": {
|
|
701
|
+
"$ref": "#/$defs/Ext"
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
},
|
|
705
|
+
"Summary": {
|
|
706
|
+
"title": "Summary",
|
|
707
|
+
"description": "What an approver is shown, rendered from the summary template for the action's `kind`. Title and effect are the template's prose; the fields are the payload values that prose is about, each located by pointer so a renderer can verify it.",
|
|
708
|
+
"type": "object",
|
|
709
|
+
"additionalProperties": false,
|
|
710
|
+
"required": [
|
|
711
|
+
"title",
|
|
712
|
+
"fields",
|
|
713
|
+
"templateDigest"
|
|
714
|
+
],
|
|
715
|
+
"properties": {
|
|
716
|
+
"title": {
|
|
717
|
+
"type": "string",
|
|
718
|
+
"minLength": 1,
|
|
719
|
+
"maxLength": 256,
|
|
720
|
+
"description": "One-line heading from the template. Prose only: a renderer MUST NOT present the action from this text without the fields."
|
|
721
|
+
},
|
|
722
|
+
"effect": {
|
|
723
|
+
"type": "string",
|
|
724
|
+
"maxLength": 1024,
|
|
725
|
+
"description": "One or two sentences from the template saying what executing the operation will do."
|
|
726
|
+
},
|
|
727
|
+
"fields": {
|
|
728
|
+
"type": "object",
|
|
729
|
+
"description": "Named values the template displays, keyed by a lowerCamelCase field name. Each locates its value in `payload` by JSON Pointer.",
|
|
730
|
+
"propertyNames": {
|
|
731
|
+
"pattern": "^[a-z][a-zA-Z0-9]*$",
|
|
732
|
+
"maxLength": 64
|
|
733
|
+
},
|
|
734
|
+
"additionalProperties": {
|
|
735
|
+
"$ref": "#/$defs/Field"
|
|
736
|
+
}
|
|
737
|
+
},
|
|
738
|
+
"templateDigest": {
|
|
739
|
+
"$ref": "#/$defs/DigestMultibase",
|
|
740
|
+
"description": "Digest of the summary template this summary was rendered from, over its RFC 8785 (JCS) canonicalization. Pinned per `kind`: a renderer that holds the template for a kind refuses a summary naming a different digest, so the community cannot change what approvers are shown for a kind without that change being visible."
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
},
|
|
744
|
+
"Field": {
|
|
745
|
+
"title": "Field",
|
|
746
|
+
"description": "One displayed value, with where it comes from and how to render it.",
|
|
747
|
+
"type": "object",
|
|
748
|
+
"additionalProperties": false,
|
|
749
|
+
"required": [
|
|
750
|
+
"pointer",
|
|
751
|
+
"format",
|
|
752
|
+
"value"
|
|
753
|
+
],
|
|
754
|
+
"properties": {
|
|
755
|
+
"pointer": {
|
|
756
|
+
"type": "string",
|
|
757
|
+
"maxLength": 512,
|
|
758
|
+
"pattern": "^(/([^~/]|~[01])*)*$",
|
|
759
|
+
"description": "RFC 6901 JSON Pointer into the action's `payload`. The empty string addresses the whole payload."
|
|
760
|
+
},
|
|
761
|
+
"format": {
|
|
762
|
+
"type": "string",
|
|
763
|
+
"enum": [
|
|
764
|
+
"did",
|
|
765
|
+
"capabilityList",
|
|
766
|
+
"duration",
|
|
767
|
+
"datetime",
|
|
768
|
+
"text"
|
|
769
|
+
],
|
|
770
|
+
"description": "How to render the value. `did` — a DID, shown in full or with a verified display name, never truncated to a prefix that two DIDs share. `capabilityList` — an array of capability names. `duration` — an ISO 8601 duration. `datetime` — an RFC 3339 date-time. `text` — anything else, rendered as literal text."
|
|
771
|
+
},
|
|
772
|
+
"value": {
|
|
773
|
+
"description": "The value found at `pointer` when the community rendered the summary. A renderer re-derives it from `payload` and refuses to render the action on any mismatch; it is carried so that a mismatch is detectable, not so that it can be trusted."
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
},
|
|
777
|
+
"DigestMultibase": {
|
|
778
|
+
"title": "DigestMultibase",
|
|
779
|
+
"description": "A cryptographic digest as a multibase-encoded multihash — the encoding the W3C Verifiable Credentials Data Model 2.0 defines for `digestMultibase`, and the one `did:webvh` uses for its SCID and entry hashes.\n\nMultihash carries the hash algorithm in-band, so the value is self-describing and the wire format survives an algorithm change without a schema revision; multibase does the same for the base encoding, so a verifier never infers base58 from base64url by context. A bare hex string or a `sha-256:`-style prefix hard-codes one algorithm into the wire contract and is non-conforming here.\n\nThis definition constrains the *encoding only*. What the digest is computed over is stated by each referencing field, because it differs legitimately: a digest over a JSON document is taken over its RFC 8785 (JCS) canonicalization, while a digest over an opaque artifact is taken over its bytes. A field whose input is a JSON document and which does not name a canonicalization is not reproducible.\n\nRestricted to the two multibase headers W3C Controlled Identifiers 1.0 §2.4 normatively requires — `z` (base58btc) and `u` (base64url-no-pad). CID permits others but states that \"interoperability is not guaranteed between implementations using such values\", and a registry whose purpose is interoperability should not mint digests a conforming verifier may be unable to read. The alphabets are enforced rather than assumed: base58btc excludes 0, O, I and l, and an earlier permissive pattern let three published examples carry digests that were not valid base58 at all. base58btc is RECOMMENDED, for consistency with `did:key` and `did:webvh`.",
|
|
780
|
+
"type": "string",
|
|
781
|
+
"minLength": 16,
|
|
782
|
+
"pattern": "^(z[1-9A-HJ-NP-Za-km-z]+|u[A-Za-z0-9_-]+)$",
|
|
783
|
+
"examples": [
|
|
784
|
+
"zQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR"
|
|
785
|
+
]
|
|
786
|
+
},
|
|
787
|
+
"ActionId": {
|
|
788
|
+
"title": "ActionId",
|
|
789
|
+
"description": "Opaque, community-minted identifier of one action. A consumer MUST NOT parse or order it; it is compared for equality only. Long enough to be unguessable, because a show of an id the caller may not see is answered `notFound` and an enumerable id would turn that answer into an oracle.",
|
|
790
|
+
"type": "string",
|
|
791
|
+
"minLength": 16,
|
|
792
|
+
"maxLength": 128,
|
|
793
|
+
"pattern": "^[A-Za-z0-9._~:-]+$"
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
} as const;
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* SPEC.md §7.2 policy for the request variant, from this specification's
|
|
800
|
+
* front matter. Pass to `consumeInbound` — items 5b, 7 and 8 are
|
|
801
|
+
* per-specification and cannot be derived from the document alone, and
|
|
802
|
+
* item 2 needs the schema this carries.
|
|
803
|
+
*/
|
|
804
|
+
export const SPEC = {
|
|
805
|
+
typeUri: TYPE_URI,
|
|
806
|
+
isBearer: false,
|
|
807
|
+
isProofRequired: true,
|
|
808
|
+
isRecipientRequired: true,
|
|
809
|
+
isIssuedAtRequired: false,
|
|
810
|
+
payloadSchema: PAYLOAD_SCHEMA,
|
|
811
|
+
} as const;
|
|
812
|
+
|
|
813
|
+
/**
|
|
814
|
+
* SPEC.md §7.2 policy for the success-response variant. `isRecipientRequired`
|
|
815
|
+
* tracks the *issuer* party's requirement because a response swaps the
|
|
816
|
+
* parties (§7.3 item 5).
|
|
817
|
+
*/
|
|
818
|
+
export const RESPONSE_SPEC = {
|
|
819
|
+
typeUri: RESPONSE_TYPE_URI,
|
|
820
|
+
isBearer: false,
|
|
821
|
+
isProofRequired: true,
|
|
822
|
+
isRecipientRequired: true,
|
|
823
|
+
isIssuedAtRequired: false,
|
|
824
|
+
payloadSchema: RESPONSE_PAYLOAD_SCHEMA,
|
|
825
|
+
} as const;
|