@openvtc/trust-tasks 0.19.17 → 0.19.18

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 (79) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/_runtime/consume.d.ts +1 -1
  3. package/dist/_runtime/consume.js +2 -2
  4. package/dist/_shared/components.d.ts +8 -0
  5. package/dist/_shared/components.d.ts.map +1 -1
  6. package/dist/index.d.ts +5 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +5 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/persona/attribute/promote/1.0/payload.d.ts +506 -0
  11. package/dist/persona/attribute/promote/1.0/payload.d.ts.map +1 -0
  12. package/dist/persona/attribute/promote/1.0/payload.js +263 -0
  13. package/dist/persona/attribute/promote/1.0/payload.js.map +1 -0
  14. package/dist/persona/binding/get/1.0/payload.d.ts +24 -0
  15. package/dist/persona/binding/get/1.0/payload.d.ts.map +1 -1
  16. package/dist/persona/binding/get/1.0/payload.js +10 -0
  17. package/dist/persona/binding/get/1.0/payload.js.map +1 -1
  18. package/dist/persona/binding/list/1.0/payload.d.ts +24 -0
  19. package/dist/persona/binding/list/1.0/payload.d.ts.map +1 -1
  20. package/dist/persona/binding/list/1.0/payload.js +10 -0
  21. package/dist/persona/binding/list/1.0/payload.js.map +1 -1
  22. package/dist/persona/binding/set/1.0/payload.d.ts +38 -0
  23. package/dist/persona/binding/set/1.0/payload.d.ts.map +1 -1
  24. package/dist/persona/binding/set/1.0/payload.js +15 -0
  25. package/dist/persona/binding/set/1.0/payload.js.map +1 -1
  26. package/dist/persona/local/binding/set/1.0/payload.d.ts +14 -0
  27. package/dist/persona/local/binding/set/1.0/payload.d.ts.map +1 -1
  28. package/dist/persona/local/binding/set/1.0/payload.js +5 -0
  29. package/dist/persona/local/binding/set/1.0/payload.js.map +1 -1
  30. package/dist/persona/profile/compose/1.0/payload.d.ts +951 -0
  31. package/dist/persona/profile/compose/1.0/payload.d.ts.map +1 -0
  32. package/dist/persona/profile/compose/1.0/payload.js +526 -0
  33. package/dist/persona/profile/compose/1.0/payload.js.map +1 -0
  34. package/dist/persona/profile/delete/1.0/payload.d.ts +71 -0
  35. package/dist/persona/profile/delete/1.0/payload.d.ts.map +1 -1
  36. package/dist/persona/profile/delete/1.0/payload.js +38 -0
  37. package/dist/persona/profile/delete/1.0/payload.js.map +1 -1
  38. package/dist/persona/profile/get/1.0/payload.d.ts +115 -0
  39. package/dist/persona/profile/get/1.0/payload.d.ts.map +1 -1
  40. package/dist/persona/profile/get/1.0/payload.js +66 -0
  41. package/dist/persona/profile/get/1.0/payload.js.map +1 -1
  42. package/dist/persona/profile/list/1.0/payload.d.ts +58 -0
  43. package/dist/persona/profile/list/1.0/payload.d.ts.map +1 -1
  44. package/dist/persona/profile/list/1.0/payload.js +33 -0
  45. package/dist/persona/profile/list/1.0/payload.js.map +1 -1
  46. package/dist/persona/profile/reinstate/1.0/payload.d.ts +325 -0
  47. package/dist/persona/profile/reinstate/1.0/payload.d.ts.map +1 -0
  48. package/dist/persona/profile/reinstate/1.0/payload.js +181 -0
  49. package/dist/persona/profile/reinstate/1.0/payload.js.map +1 -0
  50. package/dist/persona/profile/retire/1.0/payload.d.ts +436 -0
  51. package/dist/persona/profile/retire/1.0/payload.d.ts.map +1 -0
  52. package/dist/persona/profile/retire/1.0/payload.js +238 -0
  53. package/dist/persona/profile/retire/1.0/payload.js.map +1 -0
  54. package/dist/trust-task-control/0.1/payload.d.ts +19 -19
  55. package/dist/trust-task-control/0.1/payload.js +7 -7
  56. package/dist/trust-task-discovery/0.1/payload.d.ts +3 -3
  57. package/dist/trust-task-discovery/0.1/payload.js +1 -1
  58. package/dist/trust-task-discovery/0.2/payload.d.ts +368 -0
  59. package/dist/trust-task-discovery/0.2/payload.d.ts.map +1 -0
  60. package/dist/trust-task-discovery/0.2/payload.js +186 -0
  61. package/dist/trust-task-discovery/0.2/payload.js.map +1 -0
  62. package/package.json +1 -1
  63. package/src/_runtime/consume.ts +2 -2
  64. package/src/_shared/components.ts +8 -0
  65. package/src/index.ts +5 -0
  66. package/src/persona/attribute/promote/1.0/payload.ts +344 -0
  67. package/src/persona/binding/get/1.0/payload.ts +14 -0
  68. package/src/persona/binding/list/1.0/payload.ts +14 -0
  69. package/src/persona/binding/set/1.0/payload.ts +23 -0
  70. package/src/persona/local/binding/set/1.0/payload.ts +9 -0
  71. package/src/persona/profile/compose/1.0/payload.ts +641 -0
  72. package/src/persona/profile/delete/1.0/payload.ts +45 -0
  73. package/src/persona/profile/get/1.0/payload.ts +73 -0
  74. package/src/persona/profile/list/1.0/payload.ts +37 -0
  75. package/src/persona/profile/reinstate/1.0/payload.ts +219 -0
  76. package/src/persona/profile/retire/1.0/payload.ts +289 -0
  77. package/src/trust-task-control/0.1/payload.ts +12 -12
  78. package/src/trust-task-discovery/0.1/payload.ts +2 -2
  79. package/src/trust-task-discovery/0.2/payload.ts +286 -0
@@ -27,6 +27,13 @@ export interface PersonaProfileDeleteResponsePayload {
27
27
  * False when no live profile was present. A repeat delete returns false and deliberately takes no new version, so watchers never observe a change that did not happen.
28
28
  */
29
29
  existed: boolean;
30
+ /**
31
+ * How many distinct parties this face has disclosed to, across how many contexts, from the holder's disclosure history. Counts, not identifiers; persona/disclosure/history names them. Returned on the delete because the delete does not un-tell anyone: the history, and what those parties hold, remain.
32
+ */
33
+ disclosedTo?: {
34
+ partyCount: number;
35
+ contextCount: number;
36
+ };
30
37
  /**
31
38
  * Persona DIDs whose bindings were cleared. Present only when `unbind` was true and something was cleared — a holder is owed the list of which personas their one action left presenting nothing.
32
39
  *
@@ -105,6 +112,25 @@ export const PAYLOAD_SCHEMA = {
105
112
  "type": "boolean",
106
113
  "description": "False when no live profile was present. A repeat delete returns false and deliberately takes no new version, so watchers never observe a change that did not happen."
107
114
  },
115
+ "disclosedTo": {
116
+ "type": "object",
117
+ "additionalProperties": false,
118
+ "required": [
119
+ "partyCount",
120
+ "contextCount"
121
+ ],
122
+ "description": "How many distinct parties this face has disclosed to, across how many contexts, from the holder's disclosure history. Counts, not identifiers; persona/disclosure/history names them. Returned on the delete because the delete does not un-tell anyone: the history, and what those parties hold, remain.",
123
+ "properties": {
124
+ "partyCount": {
125
+ "type": "integer",
126
+ "minimum": 0
127
+ },
128
+ "contextCount": {
129
+ "type": "integer",
130
+ "minimum": 0
131
+ }
132
+ }
133
+ },
108
134
  "unboundPersonas": {
109
135
  "type": "array",
110
136
  "maxItems": 256,
@@ -167,6 +193,25 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
167
193
  "type": "boolean",
168
194
  "description": "False when no live profile was present. A repeat delete returns false and deliberately takes no new version, so watchers never observe a change that did not happen."
169
195
  },
196
+ "disclosedTo": {
197
+ "type": "object",
198
+ "additionalProperties": false,
199
+ "required": [
200
+ "partyCount",
201
+ "contextCount"
202
+ ],
203
+ "description": "How many distinct parties this face has disclosed to, across how many contexts, from the holder's disclosure history. Counts, not identifiers; persona/disclosure/history names them. Returned on the delete because the delete does not un-tell anyone: the history, and what those parties hold, remain.",
204
+ "properties": {
205
+ "partyCount": {
206
+ "type": "integer",
207
+ "minimum": 0
208
+ },
209
+ "contextCount": {
210
+ "type": "integer",
211
+ "minimum": 0
212
+ }
213
+ }
214
+ },
170
215
  "unboundPersonas": {
171
216
  "type": "array",
172
217
  "maxItems": 256,
@@ -22,6 +22,13 @@ export interface PersonaProfileGetPayload {
22
22
  */
23
23
  export interface PersonaProfileGetResponsePayload {
24
24
  profile: Profile;
25
+ /**
26
+ * How many distinct parties this face has disclosed to, across how many contexts, from the holder's disclosure history. Counts, not identifiers; persona/disclosure/history names them. A producer shows this before a delete: deleting a face does not un-tell anyone what it told them.
27
+ */
28
+ disclosedTo?: {
29
+ partyCount: number;
30
+ contextCount: number;
31
+ };
25
32
  /**
26
33
  * Present only when `resolve` was true: the claims this profile would present, in entry order, with overrides applied and pinned versions honoured. A credential-backed claim whose backing could not be re-derived appears carrying `stale`, because a holder inspecting a profile needs to see that it has stopped being fully presentable.
27
34
  *
@@ -94,6 +101,25 @@ export const PAYLOAD_SCHEMA = {
94
101
  "profile": {
95
102
  "$ref": "#/$defs/Profile"
96
103
  },
104
+ "disclosedTo": {
105
+ "type": "object",
106
+ "additionalProperties": false,
107
+ "required": [
108
+ "partyCount",
109
+ "contextCount"
110
+ ],
111
+ "description": "How many distinct parties this face has disclosed to, across how many contexts, from the holder's disclosure history. Counts, not identifiers; persona/disclosure/history names them. A producer shows this before a delete: deleting a face does not un-tell anyone what it told them.",
112
+ "properties": {
113
+ "partyCount": {
114
+ "type": "integer",
115
+ "minimum": 0
116
+ },
117
+ "contextCount": {
118
+ "type": "integer",
119
+ "minimum": 0
120
+ }
121
+ }
122
+ },
97
123
  "resolved": {
98
124
  "type": "array",
99
125
  "maxItems": 256,
@@ -333,6 +359,20 @@ export const PAYLOAD_SCHEMA = {
333
359
  "$ref": "#/$defs/ProfileEntry"
334
360
  }
335
361
  },
362
+ "status": {
363
+ "type": "string",
364
+ "enum": [
365
+ "active",
366
+ "retired"
367
+ ],
368
+ "default": "active",
369
+ "description": "`retired`: the face is worn nowhere, is left out of pickers and default listings, and cannot be worn until reinstated (persona/profile/retire, persona/profile/reinstate). Its disclosure history and every value it carries are kept — retiring is 'stop being this', not 'forget this'. Absent reads as `active`."
370
+ },
371
+ "retiredAt": {
372
+ "type": "string",
373
+ "format": "date-time",
374
+ "description": "When the face was retired. Present exactly when `status` is `retired`."
375
+ },
336
376
  "credentialRefs": {
337
377
  "type": "array",
338
378
  "maxItems": 256,
@@ -482,6 +522,25 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
482
522
  "profile": {
483
523
  "$ref": "#/$defs/Profile"
484
524
  },
525
+ "disclosedTo": {
526
+ "type": "object",
527
+ "additionalProperties": false,
528
+ "required": [
529
+ "partyCount",
530
+ "contextCount"
531
+ ],
532
+ "description": "How many distinct parties this face has disclosed to, across how many contexts, from the holder's disclosure history. Counts, not identifiers; persona/disclosure/history names them. A producer shows this before a delete: deleting a face does not un-tell anyone what it told them.",
533
+ "properties": {
534
+ "partyCount": {
535
+ "type": "integer",
536
+ "minimum": 0
537
+ },
538
+ "contextCount": {
539
+ "type": "integer",
540
+ "minimum": 0
541
+ }
542
+ }
543
+ },
485
544
  "resolved": {
486
545
  "type": "array",
487
546
  "maxItems": 256,
@@ -721,6 +780,20 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
721
780
  "$ref": "#/$defs/ProfileEntry"
722
781
  }
723
782
  },
783
+ "status": {
784
+ "type": "string",
785
+ "enum": [
786
+ "active",
787
+ "retired"
788
+ ],
789
+ "default": "active",
790
+ "description": "`retired`: the face is worn nowhere, is left out of pickers and default listings, and cannot be worn until reinstated (persona/profile/retire, persona/profile/reinstate). Its disclosure history and every value it carries are kept — retiring is 'stop being this', not 'forget this'. Absent reads as `active`."
791
+ },
792
+ "retiredAt": {
793
+ "type": "string",
794
+ "format": "date-time",
795
+ "description": "When the face was retired. Present exactly when `status` is `retired`."
796
+ },
724
797
  "credentialRefs": {
725
798
  "type": "array",
726
799
  "maxItems": 256,
@@ -15,6 +15,10 @@ export interface PersonaProfileListPayload {
15
15
  */
16
16
  cursor?: string;
17
17
  limit?: number;
18
+ /**
19
+ * Include retired faces. Off by default: a retired face is one the holder has stopped being, and a picker that offered it back would undo the decision by accident.
20
+ */
21
+ includeRetired?: boolean;
18
22
  ext?: Ext;
19
23
  }
20
24
  /**
@@ -75,6 +79,11 @@ export const PAYLOAD_SCHEMA = {
75
79
  "maximum": 500,
76
80
  "default": 100
77
81
  },
82
+ "includeRetired": {
83
+ "type": "boolean",
84
+ "default": false,
85
+ "description": "Include retired faces. Off by default: a retired face is one the holder has stopped being, and a picker that offered it back would undo the decision by accident."
86
+ },
78
87
  "ext": {
79
88
  "$ref": "#/$defs/Ext"
80
89
  }
@@ -146,6 +155,20 @@ export const PAYLOAD_SCHEMA = {
146
155
  "$ref": "#/$defs/ProfileEntry"
147
156
  }
148
157
  },
158
+ "status": {
159
+ "type": "string",
160
+ "enum": [
161
+ "active",
162
+ "retired"
163
+ ],
164
+ "default": "active",
165
+ "description": "`retired`: the face is worn nowhere, is left out of pickers and default listings, and cannot be worn until reinstated (persona/profile/retire, persona/profile/reinstate). Its disclosure history and every value it carries are kept — retiring is 'stop being this', not 'forget this'. Absent reads as `active`."
166
+ },
167
+ "retiredAt": {
168
+ "type": "string",
169
+ "format": "date-time",
170
+ "description": "When the face was retired. Present exactly when `status` is `retired`."
171
+ },
149
172
  "credentialRefs": {
150
173
  "type": "array",
151
174
  "maxItems": 256,
@@ -473,6 +496,20 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
473
496
  "$ref": "#/$defs/ProfileEntry"
474
497
  }
475
498
  },
499
+ "status": {
500
+ "type": "string",
501
+ "enum": [
502
+ "active",
503
+ "retired"
504
+ ],
505
+ "default": "active",
506
+ "description": "`retired`: the face is worn nowhere, is left out of pickers and default listings, and cannot be worn until reinstated (persona/profile/retire, persona/profile/reinstate). Its disclosure history and every value it carries are kept — retiring is 'stop being this', not 'forget this'. Absent reads as `active`."
507
+ },
508
+ "retiredAt": {
509
+ "type": "string",
510
+ "format": "date-time",
511
+ "description": "When the face was retired. Present exactly when `status` is `retired`."
512
+ },
476
513
  "credentialRefs": {
477
514
  "type": "array",
478
515
  "maxItems": 256,
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Generated by scripts/build-ts-bindings.mjs — DO NOT EDIT BY HAND.
3
+ * Source: specs/persona/profile/reinstate/1.0/payload.schema.json
4
+ */
5
+
6
+ import type { ExpectedVersion_PersonaV0_1 as ExpectedVersion, Ext, Ulid, Version_PersonaV0_1 as Version } from "../../../../_shared/components.js";
7
+
8
+
9
+ /**
10
+ * Make a retired face wearable again. It is worn nowhere afterwards: the bindings retiring cleared are not restored, because wearing a face in a context is a decision about that context, taken when it is taken.
11
+ */
12
+ export interface PersonaProfileReinstatePayload {
13
+ profileId: Ulid;
14
+ /**
15
+ * The context a context-local face lives in. Omit for a pool face.
16
+ */
17
+ contextId?: string;
18
+ expectedVersion?: ExpectedVersion;
19
+ ext?: Ext;
20
+ }
21
+ /**
22
+ * Success response to persona/profile/reinstate. Type https://trusttasks.org/spec/persona/profile/reinstate/1.0#response. Reinstating an active face is a success that changes nothing and takes no new version.
23
+ */
24
+ export interface PersonaProfileReinstateResponsePayload {
25
+ profileId: Ulid;
26
+ version: Version;
27
+ ext?: Ext;
28
+ }
29
+
30
+ /** Shared definitions this specification references, re-exported under the names it used to declare them with. */
31
+ export type { ExpectedVersion, Ext, Ulid, Version };
32
+
33
+ /** Trust Task type URI. */
34
+ export const TYPE_URI = "https://trusttasks.org/spec/persona/profile/reinstate/1.0" as const;
35
+
36
+ /** Stable alias for this specification's request payload shape. */
37
+ export type Payload = PersonaProfileReinstatePayload;
38
+
39
+ /** Trust Task response type URI (request type URI + "#response"). */
40
+ export const RESPONSE_TYPE_URI = "https://trusttasks.org/spec/persona/profile/reinstate/1.0#response" as const;
41
+
42
+ /** Stable alias for this specification's success-response payload shape. */
43
+ export type Response = PersonaProfileReinstateResponsePayload;
44
+
45
+ /**
46
+ * This specification's payload schema, as a value.
47
+ *
48
+ * SPEC.md §7.2 item 2 is performed against this. It is shipped as data
49
+ * rather than only as a `.json` file because TypeScript types are erased
50
+ * at runtime: without a schema a consumer has nothing to validate, and
51
+ * every REQUIRED payload member is optional in practice. Cross-file
52
+ * `$ref`s are already inlined, so it needs no resolver.
53
+ */
54
+ export const PAYLOAD_SCHEMA = {
55
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
56
+ "$id": "https://trusttasks.org/spec/persona/profile/reinstate/1.0",
57
+ "title": "Persona Profile Reinstate — payload",
58
+ "description": "Make a retired face wearable again. It is worn nowhere afterwards: the bindings retiring cleared are not restored, because wearing a face in a context is a decision about that context, taken when it is taken.",
59
+ "type": "object",
60
+ "additionalProperties": false,
61
+ "required": [
62
+ "profileId"
63
+ ],
64
+ "properties": {
65
+ "profileId": {
66
+ "$ref": "#/$defs/Ulid"
67
+ },
68
+ "contextId": {
69
+ "type": "string",
70
+ "minLength": 1,
71
+ "description": "The context a context-local face lives in. Omit for a pool face."
72
+ },
73
+ "expectedVersion": {
74
+ "$ref": "#/$defs/ExpectedVersion"
75
+ },
76
+ "ext": {
77
+ "$ref": "#/$defs/Ext"
78
+ }
79
+ },
80
+ "$defs": {
81
+ "Response": {
82
+ "$anchor": "response",
83
+ "title": "Persona Profile Reinstate — response payload",
84
+ "description": "Success response to persona/profile/reinstate. Type https://trusttasks.org/spec/persona/profile/reinstate/1.0#response. Reinstating an active face is a success that changes nothing and takes no new version.",
85
+ "type": "object",
86
+ "additionalProperties": false,
87
+ "required": [
88
+ "profileId",
89
+ "version"
90
+ ],
91
+ "properties": {
92
+ "profileId": {
93
+ "$ref": "#/$defs/Ulid"
94
+ },
95
+ "version": {
96
+ "$ref": "#/$defs/Version"
97
+ },
98
+ "ext": {
99
+ "$ref": "#/$defs/Ext"
100
+ }
101
+ }
102
+ },
103
+ "Ext": {
104
+ "title": "Ext",
105
+ "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.",
106
+ "type": "object",
107
+ "minProperties": 1,
108
+ "additionalProperties": true,
109
+ "propertyNames": {
110
+ "pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
111
+ }
112
+ },
113
+ "Version": {
114
+ "title": "Version",
115
+ "description": "A value of the store's monotonic write counter. Server-assigned; a producer never chooses one.",
116
+ "type": "integer",
117
+ "minimum": 1
118
+ },
119
+ "Ulid": {
120
+ "title": "Ulid",
121
+ "description": "A ULID in Crockford base32, uppercase. Used for `attributeId` and `profileId`. Chosen over a UUID because the leading 48 bits are a timestamp, so a key-ordered scan of the store is also creation-ordered and a `list` needs no secondary sort. Server-assigned on create; a producer MAY supply one to make a create idempotent, and a maintainer MUST reject a supplied value that already exists rather than silently overwriting.",
122
+ "type": "string",
123
+ "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
124
+ },
125
+ "ExpectedVersion": {
126
+ "title": "ExpectedVersion",
127
+ "description": "Optimistic-concurrency precondition. A positive value requires the record's current `version` to equal it exactly; zero means create-only and applies only when no live record exists at the address.",
128
+ "type": "integer",
129
+ "minimum": 0
130
+ }
131
+ }
132
+ } as const;
133
+
134
+ /** As {@link PAYLOAD_SCHEMA}, for the success-response variant. */
135
+ export const RESPONSE_PAYLOAD_SCHEMA = {
136
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
137
+ "$ref": "#/$defs/Response",
138
+ "$defs": {
139
+ "Response": {
140
+ "$anchor": "response",
141
+ "title": "Persona Profile Reinstate — response payload",
142
+ "description": "Success response to persona/profile/reinstate. Type https://trusttasks.org/spec/persona/profile/reinstate/1.0#response. Reinstating an active face is a success that changes nothing and takes no new version.",
143
+ "type": "object",
144
+ "additionalProperties": false,
145
+ "required": [
146
+ "profileId",
147
+ "version"
148
+ ],
149
+ "properties": {
150
+ "profileId": {
151
+ "$ref": "#/$defs/Ulid"
152
+ },
153
+ "version": {
154
+ "$ref": "#/$defs/Version"
155
+ },
156
+ "ext": {
157
+ "$ref": "#/$defs/Ext"
158
+ }
159
+ }
160
+ },
161
+ "Ext": {
162
+ "title": "Ext",
163
+ "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.",
164
+ "type": "object",
165
+ "minProperties": 1,
166
+ "additionalProperties": true,
167
+ "propertyNames": {
168
+ "pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
169
+ }
170
+ },
171
+ "Version": {
172
+ "title": "Version",
173
+ "description": "A value of the store's monotonic write counter. Server-assigned; a producer never chooses one.",
174
+ "type": "integer",
175
+ "minimum": 1
176
+ },
177
+ "Ulid": {
178
+ "title": "Ulid",
179
+ "description": "A ULID in Crockford base32, uppercase. Used for `attributeId` and `profileId`. Chosen over a UUID because the leading 48 bits are a timestamp, so a key-ordered scan of the store is also creation-ordered and a `list` needs no secondary sort. Server-assigned on create; a producer MAY supply one to make a create idempotent, and a maintainer MUST reject a supplied value that already exists rather than silently overwriting.",
180
+ "type": "string",
181
+ "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
182
+ },
183
+ "ExpectedVersion": {
184
+ "title": "ExpectedVersion",
185
+ "description": "Optimistic-concurrency precondition. A positive value requires the record's current `version` to equal it exactly; zero means create-only and applies only when no live record exists at the address.",
186
+ "type": "integer",
187
+ "minimum": 0
188
+ }
189
+ }
190
+ } as const;
191
+
192
+ /**
193
+ * SPEC.md §7.2 policy for the request variant, from this specification's
194
+ * front matter. Pass to `consumeInbound` — items 5b, 7 and 8 are
195
+ * per-specification and cannot be derived from the document alone, and
196
+ * item 2 needs the schema this carries.
197
+ */
198
+ export const SPEC = {
199
+ typeUri: TYPE_URI,
200
+ isBearer: false,
201
+ isProofRequired: true,
202
+ isRecipientRequired: true,
203
+ isIssuedAtRequired: true,
204
+ payloadSchema: PAYLOAD_SCHEMA,
205
+ } as const;
206
+
207
+ /**
208
+ * SPEC.md §7.2 policy for the success-response variant. `isRecipientRequired`
209
+ * tracks the *issuer* party's requirement because a response swaps the
210
+ * parties (§7.3 item 5).
211
+ */
212
+ export const RESPONSE_SPEC = {
213
+ typeUri: RESPONSE_TYPE_URI,
214
+ isBearer: false,
215
+ isProofRequired: true,
216
+ isRecipientRequired: true,
217
+ isIssuedAtRequired: true,
218
+ payloadSchema: RESPONSE_PAYLOAD_SCHEMA,
219
+ } as const;