@openvtc/trust-tasks 0.19.8 → 0.19.10

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 (60) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/_shared/components.d.ts +147 -17
  3. package/dist/_shared/components.d.ts.map +1 -1
  4. package/dist/index.d.ts +5 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +5 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/vta/_shared/0.1/did-template.d.ts +1 -1
  9. package/dist/vta/_shared/0.1/did-template.d.ts.map +1 -1
  10. package/dist/vta/_shared/0.2/did-template.d.ts +16 -0
  11. package/dist/vta/_shared/0.2/did-template.d.ts.map +1 -0
  12. package/dist/vta/_shared/0.2/did-template.js +6 -0
  13. package/dist/vta/_shared/0.2/did-template.js.map +1 -0
  14. package/dist/vta/contexts/delete/1.0/payload.d.ts +32 -0
  15. package/dist/vta/contexts/delete/1.0/payload.d.ts.map +1 -1
  16. package/dist/vta/contexts/delete/1.0/payload.js +14 -0
  17. package/dist/vta/contexts/delete/1.0/payload.js.map +1 -1
  18. package/dist/vta/contexts/preview-delete/1.0/payload.d.ts +32 -0
  19. package/dist/vta/contexts/preview-delete/1.0/payload.d.ts.map +1 -1
  20. package/dist/vta/contexts/preview-delete/1.0/payload.js +14 -0
  21. package/dist/vta/contexts/preview-delete/1.0/payload.js.map +1 -1
  22. package/dist/vta/did-templates/create/2.0/payload.d.ts +1 -1
  23. package/dist/vta/did-templates/create/2.0/payload.d.ts.map +1 -1
  24. package/dist/vta/did-templates/create/3.0/payload.d.ts +1092 -0
  25. package/dist/vta/did-templates/create/3.0/payload.d.ts.map +1 -0
  26. package/dist/vta/did-templates/create/3.0/payload.js +682 -0
  27. package/dist/vta/did-templates/create/3.0/payload.js.map +1 -0
  28. package/dist/vta/did-templates/get/2.0/payload.d.ts +1 -1
  29. package/dist/vta/did-templates/get/2.0/payload.d.ts.map +1 -1
  30. package/dist/vta/did-templates/get/3.0/payload.d.ts +742 -0
  31. package/dist/vta/did-templates/get/3.0/payload.d.ts.map +1 -0
  32. package/dist/vta/did-templates/get/3.0/payload.js +461 -0
  33. package/dist/vta/did-templates/get/3.0/payload.js.map +1 -0
  34. package/dist/vta/did-templates/list/2.0/payload.d.ts +1 -1
  35. package/dist/vta/did-templates/list/2.0/payload.d.ts.map +1 -1
  36. package/dist/vta/did-templates/list/3.0/payload.d.ts +799 -0
  37. package/dist/vta/did-templates/list/3.0/payload.d.ts.map +1 -0
  38. package/dist/vta/did-templates/list/3.0/payload.js +487 -0
  39. package/dist/vta/did-templates/list/3.0/payload.js.map +1 -0
  40. package/dist/vta/did-templates/update/2.0/payload.d.ts +1 -1
  41. package/dist/vta/did-templates/update/2.0/payload.d.ts.map +1 -1
  42. package/dist/vta/did-templates/update/3.0/payload.d.ts +1106 -0
  43. package/dist/vta/did-templates/update/3.0/payload.d.ts.map +1 -0
  44. package/dist/vta/did-templates/update/3.0/payload.js +688 -0
  45. package/dist/vta/did-templates/update/3.0/payload.js.map +1 -0
  46. package/package.json +1 -1
  47. package/src/_shared/components.ts +152 -18
  48. package/src/index.ts +5 -0
  49. package/src/vta/_shared/0.1/did-template.ts +1 -1
  50. package/src/vta/_shared/0.2/did-template.ts +17 -0
  51. package/src/vta/contexts/delete/1.0/payload.ts +18 -0
  52. package/src/vta/contexts/preview-delete/1.0/payload.ts +18 -0
  53. package/src/vta/did-templates/create/2.0/payload.ts +1 -1
  54. package/src/vta/did-templates/create/3.0/payload.ts +717 -0
  55. package/src/vta/did-templates/get/2.0/payload.ts +1 -1
  56. package/src/vta/did-templates/get/3.0/payload.ts +496 -0
  57. package/src/vta/did-templates/list/2.0/payload.ts +1 -1
  58. package/src/vta/did-templates/list/3.0/payload.ts +531 -0
  59. package/src/vta/did-templates/update/2.0/payload.ts +1 -1
  60. package/src/vta/did-templates/update/3.0/payload.ts +727 -0
@@ -0,0 +1,717 @@
1
+ /**
2
+ * Generated by scripts/build-ts-bindings.mjs — DO NOT EDIT BY HAND.
3
+ * Source: specs/vta/did-templates/create/3.0/payload.schema.json
4
+ */
5
+
6
+ import type { Builtin_VtaV0_1 as Builtin, Context_VtaV0_1 as Context, DidTemplate_VtaV0_2 as DidTemplate, DidTemplateRecord_VtaV0_2 as DidTemplateRecord, Ext, Global_VtaV0_1 as Global, Scope_VtaV0_1 as Scope } from "../../../../_shared/components.js";
7
+
8
+
9
+ /**
10
+ * Create a new DID template on a VTA. Omit `contextId` to create in the global scope (super-admin gated); set it to create a template scoped to that context (gated on the context's admin, or a super-admin). The template's own `name` is the resource id within the selected scope; the VTA refuses duplicates (use update to replace). The success response is the persisted DidTemplateRecord.
11
+ */
12
+ export interface VTADIDTemplateCreatePayload {
13
+ /**
14
+ * Scope selector. Absent: the global scope, gated on a super-administrator. Present: the context the template is scoped to, gated on that context's administrator (or a super-administrator).
15
+ */
16
+ contextId?: string;
17
+ /**
18
+ * Full template document to store. Validated against the v1 template schema before persistence; an invalid shape is rejected with the framework's `malformedRequest`.
19
+ */
20
+ template: DidTemplate;
21
+ /**
22
+ * Ecosystem-defined extension members per SPEC.md §4.5.1.
23
+ */
24
+ ext?: Ext;
25
+ }
26
+
27
+ /** Shared definitions this specification references, re-exported under the names it used to declare them with. */
28
+ export type { Builtin, Context, DidTemplate, DidTemplateRecord, Ext, Global, Scope };
29
+
30
+ /** Trust Task type URI. */
31
+ export const TYPE_URI = "https://trusttasks.org/spec/vta/did-templates/create/3.0" as const;
32
+
33
+ /** Stable alias for this specification's request payload shape. */
34
+ export type Payload = VTADIDTemplateCreatePayload;
35
+
36
+ /** Trust Task response type URI (request type URI + "#response"). */
37
+ export const RESPONSE_TYPE_URI = "https://trusttasks.org/spec/vta/did-templates/create/3.0#response" as const;
38
+
39
+ /** Stable alias for this specification's success-response payload shape. */
40
+ export type Response = DidTemplateRecord;
41
+
42
+ /**
43
+ * This specification's payload schema, as a value.
44
+ *
45
+ * SPEC.md §7.2 item 2 is performed against this. It is shipped as data
46
+ * rather than only as a `.json` file because TypeScript types are erased
47
+ * at runtime: without a schema a consumer has nothing to validate, and
48
+ * every REQUIRED payload member is optional in practice. Cross-file
49
+ * `$ref`s are already inlined, so it needs no resolver.
50
+ */
51
+ export const PAYLOAD_SCHEMA = {
52
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
53
+ "$id": "https://trusttasks.org/spec/vta/did-templates/create/3.0",
54
+ "title": "VTA DID-Template Create — payload",
55
+ "description": "Create a new DID template on a VTA. Omit `contextId` to create in the global scope (super-admin gated); set it to create a template scoped to that context (gated on the context's admin, or a super-admin). The template's own `name` is the resource id within the selected scope; the VTA refuses duplicates (use update to replace). The success response is the persisted DidTemplateRecord.",
56
+ "type": "object",
57
+ "additionalProperties": false,
58
+ "required": [
59
+ "template"
60
+ ],
61
+ "properties": {
62
+ "contextId": {
63
+ "type": "string",
64
+ "minLength": 1,
65
+ "description": "Scope selector. Absent: the global scope, gated on a super-administrator. Present: the context the template is scoped to, gated on that context's administrator (or a super-administrator)."
66
+ },
67
+ "template": {
68
+ "$ref": "#/$defs/DidTemplate",
69
+ "description": "Full template document to store. Validated against the v1 template schema before persistence; an invalid shape is rejected with the framework's `malformedRequest`."
70
+ },
71
+ "ext": {
72
+ "$ref": "#/$defs/Ext",
73
+ "description": "Ecosystem-defined extension members per SPEC.md §4.5.1."
74
+ }
75
+ },
76
+ "$defs": {
77
+ "Response": {
78
+ "$anchor": "response",
79
+ "title": "VTA DID-Template Create — response payload",
80
+ "description": "The persisted DidTemplateRecord. The DidTemplate fields are flattened at the top level alongside the resolved scope and provenance metadata. Same shape returned by get/update.",
81
+ "$ref": "#/$defs/DidTemplateRecord"
82
+ },
83
+ "DidTemplateRecord": {
84
+ "title": "DidTemplateRecord",
85
+ "description": "A persisted template. The DidTemplate fields are flattened at the top level alongside the resolved scope and provenance metadata. Same shape returned by get/create/update and carried per-item by list.",
86
+ "type": "object",
87
+ "additionalProperties": false,
88
+ "required": [
89
+ "schemaVersion",
90
+ "name",
91
+ "kind",
92
+ "document",
93
+ "scope",
94
+ "createdAt",
95
+ "updatedAt",
96
+ "createdBy"
97
+ ],
98
+ "properties": {
99
+ "schemaVersion": {
100
+ "type": "integer",
101
+ "enum": [
102
+ 1,
103
+ 2
104
+ ],
105
+ "description": "Template schema version. 1 is the historical shape, whose keys are implicitly an Ed25519 signing key and an X25519 key-agreement key. 2 adds the `keys` block, which makes those explicit and allows others."
106
+ },
107
+ "name": {
108
+ "type": "string",
109
+ "minLength": 1,
110
+ "maxLength": 64,
111
+ "pattern": "^[a-z0-9-]+$"
112
+ },
113
+ "kind": {
114
+ "type": "string",
115
+ "minLength": 1
116
+ },
117
+ "description": {
118
+ "type": [
119
+ "string",
120
+ "null"
121
+ ],
122
+ "maxLength": 1024
123
+ },
124
+ "methods": {
125
+ "type": "array",
126
+ "items": {
127
+ "type": "string"
128
+ }
129
+ },
130
+ "requiredVars": {
131
+ "type": "array",
132
+ "items": {
133
+ "type": "string"
134
+ }
135
+ },
136
+ "optionalVars": {
137
+ "type": "object",
138
+ "additionalProperties": true
139
+ },
140
+ "defaults": {
141
+ "type": "object",
142
+ "additionalProperties": true
143
+ },
144
+ "keys": {
145
+ "type": "object",
146
+ "minProperties": 1,
147
+ "additionalProperties": {
148
+ "type": "object",
149
+ "additionalProperties": false,
150
+ "required": [
151
+ "purpose",
152
+ "algorithms"
153
+ ],
154
+ "properties": {
155
+ "purpose": {
156
+ "type": "string",
157
+ "enum": [
158
+ "signing",
159
+ "keyAgreement"
160
+ ],
161
+ "description": "What the key is for. Deliberately coarser than DID Core's five verification relationships: the template says what the key is, and the `document` body says where it appears. Encoding the relationship here as well would let the two disagree."
162
+ },
163
+ "algorithms": {
164
+ "type": "array",
165
+ "minItems": 1,
166
+ "items": {
167
+ "type": "string",
168
+ "enum": [
169
+ "ed25519",
170
+ "x25519",
171
+ "p256",
172
+ "mldsa44",
173
+ "mldsa65"
174
+ ]
175
+ },
176
+ "description": "Acceptable algorithms, MOST PREFERRED FIRST. A list rather than a single value because a fleet does not migrate atomically: `[\"mldsa44\", \"ed25519\"]` means mint ML-DSA-44 where the implementation can and Ed25519 otherwise, so one template serves a VTA with post-quantum support and one without. An implementation MUST NOT substitute an algorithm absent from this list; running out of candidates is an error, never a silent downgrade — a deployment intended to be post-quantum would otherwise ship classical keys with nothing reporting it. `minItems: 1` for the same reason: an empty list would express no preference and inherit whatever the implementation defaulted to."
177
+ }
178
+ }
179
+ },
180
+ "propertyNames": {
181
+ "pattern": "^[a-z0-9-]+$"
182
+ },
183
+ "description": "The keys this template needs, by slot name. REQUIRES `schemaVersion` 2.\n\nA slot's name becomes a document placeholder by an explicit rule — uppercase, `-` to `_`, suffix `_KEY_MB` — so slot `signing` is rendered into `{SIGNING_KEY_MB}` and slot `ka` into `{KA_KEY_MB}`. Those are the two names a `schemaVersion` 1 template already uses, which is deliberate: a v1 template is exactly a v2 template whose `keys` block is `{signing: [ed25519], ka: [x25519]}`, so an implementation can read both through one path and raising the version cannot change how a v1 template renders.\n\nAn implementation MUST refuse a template that declares a slot whose placeholder never appears in `document` — the key would be minted and never published, so verifiers would continue to see only the keys that are, while the operator believes the template migrated. It MUST likewise refuse a slot placeholder in `document` that no slot declares, which would render as an unsubstituted literal."
184
+ },
185
+ "document": {
186
+ "type": "object"
187
+ },
188
+ "scope": {
189
+ "$ref": "#/$defs/Scope",
190
+ "description": "Resolved scope of the stored template."
191
+ },
192
+ "createdAt": {
193
+ "type": "integer",
194
+ "description": "UTC unix-epoch seconds the template was first stored."
195
+ },
196
+ "updatedAt": {
197
+ "type": "integer",
198
+ "description": "UTC unix-epoch seconds of the last write."
199
+ },
200
+ "createdBy": {
201
+ "type": "string",
202
+ "description": "DID of the admin who last wrote the template."
203
+ }
204
+ }
205
+ },
206
+ "Scope": {
207
+ "title": "Scope",
208
+ "description": "Where a stored template lives. Tagged by `type`.",
209
+ "type": "object",
210
+ "oneOf": [
211
+ {
212
+ "title": "Builtin",
213
+ "type": "object",
214
+ "additionalProperties": false,
215
+ "required": [
216
+ "type"
217
+ ],
218
+ "properties": {
219
+ "type": {
220
+ "const": "builtin"
221
+ }
222
+ }
223
+ },
224
+ {
225
+ "title": "Global",
226
+ "type": "object",
227
+ "additionalProperties": false,
228
+ "required": [
229
+ "type"
230
+ ],
231
+ "properties": {
232
+ "type": {
233
+ "const": "global"
234
+ }
235
+ }
236
+ },
237
+ {
238
+ "title": "Context",
239
+ "type": "object",
240
+ "additionalProperties": false,
241
+ "required": [
242
+ "type",
243
+ "contextId"
244
+ ],
245
+ "properties": {
246
+ "type": {
247
+ "const": "context"
248
+ },
249
+ "contextId": {
250
+ "type": "string",
251
+ "minLength": 1
252
+ }
253
+ }
254
+ }
255
+ ]
256
+ },
257
+ "Ext": {
258
+ "title": "Ext",
259
+ "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.",
260
+ "type": "object",
261
+ "minProperties": 1,
262
+ "additionalProperties": true,
263
+ "propertyNames": {
264
+ "pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
265
+ }
266
+ },
267
+ "DidTemplate": {
268
+ "title": "DidTemplate",
269
+ "description": "Authored template shape: a DID document with `{TOKEN}` placeholders plus the variable contract the VTA's renderer enforces.",
270
+ "type": "object",
271
+ "additionalProperties": false,
272
+ "required": [
273
+ "schemaVersion",
274
+ "name",
275
+ "kind",
276
+ "document"
277
+ ],
278
+ "properties": {
279
+ "schemaVersion": {
280
+ "type": "integer",
281
+ "description": "Template schema version. 1 is the historical shape, whose keys are implicitly an Ed25519 signing key and an X25519 key-agreement key. 2 adds the `keys` block, which makes those explicit and allows others.",
282
+ "enum": [
283
+ 1,
284
+ 2
285
+ ]
286
+ },
287
+ "name": {
288
+ "type": "string",
289
+ "minLength": 1,
290
+ "maxLength": 64,
291
+ "pattern": "^[a-z0-9-]+$",
292
+ "description": "Template id within its scope. Lowercase alphanumeric and hyphen only."
293
+ },
294
+ "kind": {
295
+ "type": "string",
296
+ "minLength": 1,
297
+ "description": "Classification hint, e.g. `mediator`, `did-host-http`, `app`. Drives downstream provisioning behaviour."
298
+ },
299
+ "description": {
300
+ "type": [
301
+ "string",
302
+ "null"
303
+ ],
304
+ "maxLength": 1024,
305
+ "description": "Human-readable description of what the template provisions."
306
+ },
307
+ "methods": {
308
+ "type": "array",
309
+ "items": {
310
+ "type": "string"
311
+ },
312
+ "description": "DID methods this template targets, e.g. [\"webvh\", \"web\"] for a hosted DID or [\"key\"] for a did:key."
313
+ },
314
+ "requiredVars": {
315
+ "type": "array",
316
+ "items": {
317
+ "type": "string"
318
+ },
319
+ "description": "Variables the caller MUST supply at render time. MUST NOT include reserved ambient names (DID, SIGNING_KEY_MB, KA_KEY_MB, VTA_DID, VTA_URL, CONTEXT_ID, CONTEXT_DID, NOW)."
320
+ },
321
+ "optionalVars": {
322
+ "type": "object",
323
+ "description": "Variables with default values, keyed by variable name.",
324
+ "additionalProperties": true
325
+ },
326
+ "defaults": {
327
+ "type": "object",
328
+ "description": "Hints for CLI / setup wizards (e.g. preRotationCount, portable, addMediatorService).",
329
+ "additionalProperties": true
330
+ },
331
+ "keys": {
332
+ "type": "object",
333
+ "minProperties": 1,
334
+ "additionalProperties": {
335
+ "type": "object",
336
+ "additionalProperties": false,
337
+ "required": [
338
+ "purpose",
339
+ "algorithms"
340
+ ],
341
+ "properties": {
342
+ "purpose": {
343
+ "type": "string",
344
+ "enum": [
345
+ "signing",
346
+ "keyAgreement"
347
+ ],
348
+ "description": "What the key is for. Deliberately coarser than DID Core's five verification relationships: the template says what the key is, and the `document` body says where it appears. Encoding the relationship here as well would let the two disagree."
349
+ },
350
+ "algorithms": {
351
+ "type": "array",
352
+ "minItems": 1,
353
+ "items": {
354
+ "type": "string",
355
+ "enum": [
356
+ "ed25519",
357
+ "x25519",
358
+ "p256",
359
+ "mldsa44",
360
+ "mldsa65"
361
+ ]
362
+ },
363
+ "description": "Acceptable algorithms, MOST PREFERRED FIRST. A list rather than a single value because a fleet does not migrate atomically: `[\"mldsa44\", \"ed25519\"]` means mint ML-DSA-44 where the implementation can and Ed25519 otherwise, so one template serves a VTA with post-quantum support and one without. An implementation MUST NOT substitute an algorithm absent from this list; running out of candidates is an error, never a silent downgrade — a deployment intended to be post-quantum would otherwise ship classical keys with nothing reporting it. `minItems: 1` for the same reason: an empty list would express no preference and inherit whatever the implementation defaulted to."
364
+ }
365
+ }
366
+ },
367
+ "propertyNames": {
368
+ "pattern": "^[a-z0-9-]+$"
369
+ },
370
+ "description": "The keys this template needs, by slot name. REQUIRES `schemaVersion` 2.\n\nA slot's name becomes a document placeholder by an explicit rule — uppercase, `-` to `_`, suffix `_KEY_MB` — so slot `signing` is rendered into `{SIGNING_KEY_MB}` and slot `ka` into `{KA_KEY_MB}`. Those are the two names a `schemaVersion` 1 template already uses, which is deliberate: a v1 template is exactly a v2 template whose `keys` block is `{signing: [ed25519], ka: [x25519]}`, so an implementation can read both through one path and raising the version cannot change how a v1 template renders.\n\nAn implementation MUST refuse a template that declares a slot whose placeholder never appears in `document` — the key would be minted and never published, so verifiers would continue to see only the keys that are, while the operator believes the template migrated. It MUST likewise refuse a slot placeholder in `document` that no slot declares, which would render as an unsubstituted literal."
371
+ },
372
+ "document": {
373
+ "type": "object",
374
+ "description": "The DID document body with `{TOKEN}` placeholders. `document.id` MUST contain the `{DID}` placeholder. Every `{TOKEN}` MUST be declared in requiredVars/optionalVars or be a reserved ambient name."
375
+ }
376
+ }
377
+ }
378
+ }
379
+ } as const;
380
+
381
+ /** As {@link PAYLOAD_SCHEMA}, for the success-response variant. */
382
+ export const RESPONSE_PAYLOAD_SCHEMA = {
383
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
384
+ "$ref": "#/$defs/Response",
385
+ "$defs": {
386
+ "Response": {
387
+ "$anchor": "response",
388
+ "title": "VTA DID-Template Create — response payload",
389
+ "description": "The persisted DidTemplateRecord. The DidTemplate fields are flattened at the top level alongside the resolved scope and provenance metadata. Same shape returned by get/update.",
390
+ "$ref": "#/$defs/DidTemplateRecord"
391
+ },
392
+ "DidTemplateRecord": {
393
+ "title": "DidTemplateRecord",
394
+ "description": "A persisted template. The DidTemplate fields are flattened at the top level alongside the resolved scope and provenance metadata. Same shape returned by get/create/update and carried per-item by list.",
395
+ "type": "object",
396
+ "additionalProperties": false,
397
+ "required": [
398
+ "schemaVersion",
399
+ "name",
400
+ "kind",
401
+ "document",
402
+ "scope",
403
+ "createdAt",
404
+ "updatedAt",
405
+ "createdBy"
406
+ ],
407
+ "properties": {
408
+ "schemaVersion": {
409
+ "type": "integer",
410
+ "enum": [
411
+ 1,
412
+ 2
413
+ ],
414
+ "description": "Template schema version. 1 is the historical shape, whose keys are implicitly an Ed25519 signing key and an X25519 key-agreement key. 2 adds the `keys` block, which makes those explicit and allows others."
415
+ },
416
+ "name": {
417
+ "type": "string",
418
+ "minLength": 1,
419
+ "maxLength": 64,
420
+ "pattern": "^[a-z0-9-]+$"
421
+ },
422
+ "kind": {
423
+ "type": "string",
424
+ "minLength": 1
425
+ },
426
+ "description": {
427
+ "type": [
428
+ "string",
429
+ "null"
430
+ ],
431
+ "maxLength": 1024
432
+ },
433
+ "methods": {
434
+ "type": "array",
435
+ "items": {
436
+ "type": "string"
437
+ }
438
+ },
439
+ "requiredVars": {
440
+ "type": "array",
441
+ "items": {
442
+ "type": "string"
443
+ }
444
+ },
445
+ "optionalVars": {
446
+ "type": "object",
447
+ "additionalProperties": true
448
+ },
449
+ "defaults": {
450
+ "type": "object",
451
+ "additionalProperties": true
452
+ },
453
+ "keys": {
454
+ "type": "object",
455
+ "minProperties": 1,
456
+ "additionalProperties": {
457
+ "type": "object",
458
+ "additionalProperties": false,
459
+ "required": [
460
+ "purpose",
461
+ "algorithms"
462
+ ],
463
+ "properties": {
464
+ "purpose": {
465
+ "type": "string",
466
+ "enum": [
467
+ "signing",
468
+ "keyAgreement"
469
+ ],
470
+ "description": "What the key is for. Deliberately coarser than DID Core's five verification relationships: the template says what the key is, and the `document` body says where it appears. Encoding the relationship here as well would let the two disagree."
471
+ },
472
+ "algorithms": {
473
+ "type": "array",
474
+ "minItems": 1,
475
+ "items": {
476
+ "type": "string",
477
+ "enum": [
478
+ "ed25519",
479
+ "x25519",
480
+ "p256",
481
+ "mldsa44",
482
+ "mldsa65"
483
+ ]
484
+ },
485
+ "description": "Acceptable algorithms, MOST PREFERRED FIRST. A list rather than a single value because a fleet does not migrate atomically: `[\"mldsa44\", \"ed25519\"]` means mint ML-DSA-44 where the implementation can and Ed25519 otherwise, so one template serves a VTA with post-quantum support and one without. An implementation MUST NOT substitute an algorithm absent from this list; running out of candidates is an error, never a silent downgrade — a deployment intended to be post-quantum would otherwise ship classical keys with nothing reporting it. `minItems: 1` for the same reason: an empty list would express no preference and inherit whatever the implementation defaulted to."
486
+ }
487
+ }
488
+ },
489
+ "propertyNames": {
490
+ "pattern": "^[a-z0-9-]+$"
491
+ },
492
+ "description": "The keys this template needs, by slot name. REQUIRES `schemaVersion` 2.\n\nA slot's name becomes a document placeholder by an explicit rule — uppercase, `-` to `_`, suffix `_KEY_MB` — so slot `signing` is rendered into `{SIGNING_KEY_MB}` and slot `ka` into `{KA_KEY_MB}`. Those are the two names a `schemaVersion` 1 template already uses, which is deliberate: a v1 template is exactly a v2 template whose `keys` block is `{signing: [ed25519], ka: [x25519]}`, so an implementation can read both through one path and raising the version cannot change how a v1 template renders.\n\nAn implementation MUST refuse a template that declares a slot whose placeholder never appears in `document` — the key would be minted and never published, so verifiers would continue to see only the keys that are, while the operator believes the template migrated. It MUST likewise refuse a slot placeholder in `document` that no slot declares, which would render as an unsubstituted literal."
493
+ },
494
+ "document": {
495
+ "type": "object"
496
+ },
497
+ "scope": {
498
+ "$ref": "#/$defs/Scope",
499
+ "description": "Resolved scope of the stored template."
500
+ },
501
+ "createdAt": {
502
+ "type": "integer",
503
+ "description": "UTC unix-epoch seconds the template was first stored."
504
+ },
505
+ "updatedAt": {
506
+ "type": "integer",
507
+ "description": "UTC unix-epoch seconds of the last write."
508
+ },
509
+ "createdBy": {
510
+ "type": "string",
511
+ "description": "DID of the admin who last wrote the template."
512
+ }
513
+ }
514
+ },
515
+ "Scope": {
516
+ "title": "Scope",
517
+ "description": "Where a stored template lives. Tagged by `type`.",
518
+ "type": "object",
519
+ "oneOf": [
520
+ {
521
+ "title": "Builtin",
522
+ "type": "object",
523
+ "additionalProperties": false,
524
+ "required": [
525
+ "type"
526
+ ],
527
+ "properties": {
528
+ "type": {
529
+ "const": "builtin"
530
+ }
531
+ }
532
+ },
533
+ {
534
+ "title": "Global",
535
+ "type": "object",
536
+ "additionalProperties": false,
537
+ "required": [
538
+ "type"
539
+ ],
540
+ "properties": {
541
+ "type": {
542
+ "const": "global"
543
+ }
544
+ }
545
+ },
546
+ {
547
+ "title": "Context",
548
+ "type": "object",
549
+ "additionalProperties": false,
550
+ "required": [
551
+ "type",
552
+ "contextId"
553
+ ],
554
+ "properties": {
555
+ "type": {
556
+ "const": "context"
557
+ },
558
+ "contextId": {
559
+ "type": "string",
560
+ "minLength": 1
561
+ }
562
+ }
563
+ }
564
+ ]
565
+ },
566
+ "Ext": {
567
+ "title": "Ext",
568
+ "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.",
569
+ "type": "object",
570
+ "minProperties": 1,
571
+ "additionalProperties": true,
572
+ "propertyNames": {
573
+ "pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
574
+ }
575
+ },
576
+ "DidTemplate": {
577
+ "title": "DidTemplate",
578
+ "description": "Authored template shape: a DID document with `{TOKEN}` placeholders plus the variable contract the VTA's renderer enforces.",
579
+ "type": "object",
580
+ "additionalProperties": false,
581
+ "required": [
582
+ "schemaVersion",
583
+ "name",
584
+ "kind",
585
+ "document"
586
+ ],
587
+ "properties": {
588
+ "schemaVersion": {
589
+ "type": "integer",
590
+ "description": "Template schema version. 1 is the historical shape, whose keys are implicitly an Ed25519 signing key and an X25519 key-agreement key. 2 adds the `keys` block, which makes those explicit and allows others.",
591
+ "enum": [
592
+ 1,
593
+ 2
594
+ ]
595
+ },
596
+ "name": {
597
+ "type": "string",
598
+ "minLength": 1,
599
+ "maxLength": 64,
600
+ "pattern": "^[a-z0-9-]+$",
601
+ "description": "Template id within its scope. Lowercase alphanumeric and hyphen only."
602
+ },
603
+ "kind": {
604
+ "type": "string",
605
+ "minLength": 1,
606
+ "description": "Classification hint, e.g. `mediator`, `did-host-http`, `app`. Drives downstream provisioning behaviour."
607
+ },
608
+ "description": {
609
+ "type": [
610
+ "string",
611
+ "null"
612
+ ],
613
+ "maxLength": 1024,
614
+ "description": "Human-readable description of what the template provisions."
615
+ },
616
+ "methods": {
617
+ "type": "array",
618
+ "items": {
619
+ "type": "string"
620
+ },
621
+ "description": "DID methods this template targets, e.g. [\"webvh\", \"web\"] for a hosted DID or [\"key\"] for a did:key."
622
+ },
623
+ "requiredVars": {
624
+ "type": "array",
625
+ "items": {
626
+ "type": "string"
627
+ },
628
+ "description": "Variables the caller MUST supply at render time. MUST NOT include reserved ambient names (DID, SIGNING_KEY_MB, KA_KEY_MB, VTA_DID, VTA_URL, CONTEXT_ID, CONTEXT_DID, NOW)."
629
+ },
630
+ "optionalVars": {
631
+ "type": "object",
632
+ "description": "Variables with default values, keyed by variable name.",
633
+ "additionalProperties": true
634
+ },
635
+ "defaults": {
636
+ "type": "object",
637
+ "description": "Hints for CLI / setup wizards (e.g. preRotationCount, portable, addMediatorService).",
638
+ "additionalProperties": true
639
+ },
640
+ "keys": {
641
+ "type": "object",
642
+ "minProperties": 1,
643
+ "additionalProperties": {
644
+ "type": "object",
645
+ "additionalProperties": false,
646
+ "required": [
647
+ "purpose",
648
+ "algorithms"
649
+ ],
650
+ "properties": {
651
+ "purpose": {
652
+ "type": "string",
653
+ "enum": [
654
+ "signing",
655
+ "keyAgreement"
656
+ ],
657
+ "description": "What the key is for. Deliberately coarser than DID Core's five verification relationships: the template says what the key is, and the `document` body says where it appears. Encoding the relationship here as well would let the two disagree."
658
+ },
659
+ "algorithms": {
660
+ "type": "array",
661
+ "minItems": 1,
662
+ "items": {
663
+ "type": "string",
664
+ "enum": [
665
+ "ed25519",
666
+ "x25519",
667
+ "p256",
668
+ "mldsa44",
669
+ "mldsa65"
670
+ ]
671
+ },
672
+ "description": "Acceptable algorithms, MOST PREFERRED FIRST. A list rather than a single value because a fleet does not migrate atomically: `[\"mldsa44\", \"ed25519\"]` means mint ML-DSA-44 where the implementation can and Ed25519 otherwise, so one template serves a VTA with post-quantum support and one without. An implementation MUST NOT substitute an algorithm absent from this list; running out of candidates is an error, never a silent downgrade — a deployment intended to be post-quantum would otherwise ship classical keys with nothing reporting it. `minItems: 1` for the same reason: an empty list would express no preference and inherit whatever the implementation defaulted to."
673
+ }
674
+ }
675
+ },
676
+ "propertyNames": {
677
+ "pattern": "^[a-z0-9-]+$"
678
+ },
679
+ "description": "The keys this template needs, by slot name. REQUIRES `schemaVersion` 2.\n\nA slot's name becomes a document placeholder by an explicit rule — uppercase, `-` to `_`, suffix `_KEY_MB` — so slot `signing` is rendered into `{SIGNING_KEY_MB}` and slot `ka` into `{KA_KEY_MB}`. Those are the two names a `schemaVersion` 1 template already uses, which is deliberate: a v1 template is exactly a v2 template whose `keys` block is `{signing: [ed25519], ka: [x25519]}`, so an implementation can read both through one path and raising the version cannot change how a v1 template renders.\n\nAn implementation MUST refuse a template that declares a slot whose placeholder never appears in `document` — the key would be minted and never published, so verifiers would continue to see only the keys that are, while the operator believes the template migrated. It MUST likewise refuse a slot placeholder in `document` that no slot declares, which would render as an unsubstituted literal."
680
+ },
681
+ "document": {
682
+ "type": "object",
683
+ "description": "The DID document body with `{TOKEN}` placeholders. `document.id` MUST contain the `{DID}` placeholder. Every `{TOKEN}` MUST be declared in requiredVars/optionalVars or be a reserved ambient name."
684
+ }
685
+ }
686
+ }
687
+ }
688
+ } as const;
689
+
690
+ /**
691
+ * SPEC.md §7.2 policy for the request variant, from this specification's
692
+ * front matter. Pass to `consumeInbound` — items 5b, 7 and 8 are
693
+ * per-specification and cannot be derived from the document alone, and
694
+ * item 2 needs the schema this carries.
695
+ */
696
+ export const SPEC = {
697
+ typeUri: TYPE_URI,
698
+ isBearer: false,
699
+ isProofRequired: true,
700
+ isRecipientRequired: true,
701
+ isIssuedAtRequired: true,
702
+ payloadSchema: PAYLOAD_SCHEMA,
703
+ } as const;
704
+
705
+ /**
706
+ * SPEC.md §7.2 policy for the success-response variant. `isRecipientRequired`
707
+ * tracks the *issuer* party's requirement because a response swaps the
708
+ * parties (§7.3 item 5).
709
+ */
710
+ export const RESPONSE_SPEC = {
711
+ typeUri: RESPONSE_TYPE_URI,
712
+ isBearer: false,
713
+ isProofRequired: true,
714
+ isRecipientRequired: true,
715
+ isIssuedAtRequired: true,
716
+ payloadSchema: RESPONSE_PAYLOAD_SCHEMA,
717
+ } as const;