@openvtc/trust-tasks 0.19.3 → 0.19.5
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 +209 -0
- package/dist/_shared/components.d.ts +298 -0
- package/dist/_shared/components.d.ts.map +1 -1
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/vetting/_shared/0.1/identity-vetting.d.ts +11 -0
- package/dist/vetting/_shared/0.1/identity-vetting.d.ts.map +1 -0
- package/dist/vetting/_shared/0.1/identity-vetting.js +6 -0
- package/dist/vetting/_shared/0.1/identity-vetting.js.map +1 -0
- package/dist/vetting/_shared/0.1/vetting-card.d.ts +16 -0
- package/dist/vetting/_shared/0.1/vetting-card.d.ts.map +1 -0
- package/dist/vetting/_shared/0.1/vetting-card.js +6 -0
- package/dist/vetting/_shared/0.1/vetting-card.js.map +1 -0
- package/dist/vetting/_shared/0.1/vetting.d.ts +16 -0
- package/dist/vetting/_shared/0.1/vetting.d.ts.map +1 -0
- package/dist/vetting/_shared/0.1/vetting.js +6 -0
- package/dist/vetting/_shared/0.1/vetting.js.map +1 -0
- package/dist/vetting/decline/0.1/payload.d.ts +138 -0
- package/dist/vetting/decline/0.1/payload.d.ts.map +1 -0
- package/dist/vetting/decline/0.1/payload.js +81 -0
- package/dist/vetting/decline/0.1/payload.js.map +1 -0
- package/dist/vetting/request/0.1/payload.d.ts +1188 -0
- package/dist/vetting/request/0.1/payload.d.ts.map +1 -0
- package/dist/vetting/request/0.1/payload.js +596 -0
- package/dist/vetting/request/0.1/payload.js.map +1 -0
- package/dist/vetting/session/0.1/payload.d.ts +978 -0
- package/dist/vetting/session/0.1/payload.d.ts.map +1 -0
- package/dist/vetting/session/0.1/payload.js +570 -0
- package/dist/vetting/session/0.1/payload.js.map +1 -0
- package/dist/vta/webvh/dids/realign-keys/1.0/payload.d.ts +484 -0
- package/dist/vta/webvh/dids/realign-keys/1.0/payload.d.ts.map +1 -0
- package/dist/vta/webvh/dids/realign-keys/1.0/payload.js +259 -0
- package/dist/vta/webvh/dids/realign-keys/1.0/payload.js.map +1 -0
- package/dist/vtc/_shared/0.1/vetter-profile.d.ts +16 -0
- package/dist/vtc/_shared/0.1/vetter-profile.d.ts.map +1 -0
- package/dist/vtc/_shared/0.1/vetter-profile.js +6 -0
- package/dist/vtc/_shared/0.1/vetter-profile.js.map +1 -0
- package/dist/vtc/join-requests/manifest/0.2/payload.d.ts +1294 -0
- package/dist/vtc/join-requests/manifest/0.2/payload.d.ts.map +1 -0
- package/dist/vtc/join-requests/manifest/0.2/payload.js +667 -0
- package/dist/vtc/join-requests/manifest/0.2/payload.js.map +1 -0
- package/dist/vtc/vetting/revoke-statement/0.1/payload.d.ts +299 -0
- package/dist/vtc/vetting/revoke-statement/0.1/payload.d.ts.map +1 -0
- package/dist/vtc/vetting/revoke-statement/0.1/payload.js +172 -0
- package/dist/vtc/vetting/revoke-statement/0.1/payload.js.map +1 -0
- package/dist/vtc/vetting/vetters/grant/0.1/payload.d.ts +337 -0
- package/dist/vtc/vetting/vetters/grant/0.1/payload.d.ts.map +1 -0
- package/dist/vtc/vetting/vetters/grant/0.1/payload.js +183 -0
- package/dist/vtc/vetting/vetters/grant/0.1/payload.js.map +1 -0
- package/dist/vtc/vetting/vetters/list/0.1/payload.d.ts +1257 -0
- package/dist/vtc/vetting/vetters/list/0.1/payload.d.ts.map +1 -0
- package/dist/vtc/vetting/vetters/list/0.1/payload.js +597 -0
- package/dist/vtc/vetting/vetters/list/0.1/payload.js.map +1 -0
- package/dist/vtc/vetting/vetters/profile/0.1/payload.d.ts +970 -0
- package/dist/vtc/vetting/vetters/profile/0.1/payload.d.ts.map +1 -0
- package/dist/vtc/vetting/vetters/profile/0.1/payload.js +463 -0
- package/dist/vtc/vetting/vetters/profile/0.1/payload.js.map +1 -0
- package/dist/vtc/vetting/vetters/resend/0.1/payload.d.ts +240 -0
- package/dist/vtc/vetting/vetters/resend/0.1/payload.d.ts.map +1 -0
- package/dist/vtc/vetting/vetters/resend/0.1/payload.js +137 -0
- package/dist/vtc/vetting/vetters/resend/0.1/payload.js.map +1 -0
- package/package.json +1 -1
- package/src/_shared/components.ts +318 -0
- package/src/index.ts +14 -0
- package/src/vetting/_shared/0.1/identity-vetting.ts +11 -0
- package/src/vetting/_shared/0.1/vetting-card.ts +17 -0
- package/src/vetting/_shared/0.1/vetting.ts +17 -0
- package/src/vetting/decline/0.1/payload.ts +111 -0
- package/src/vetting/request/0.1/payload.ts +799 -0
- package/src/vetting/session/0.1/payload.ts +629 -0
- package/src/vta/webvh/dids/realign-keys/1.0/payload.ts +332 -0
- package/src/vtc/_shared/0.1/vetter-profile.ts +17 -0
- package/src/vtc/join-requests/manifest/0.2/payload.ts +815 -0
- package/src/vtc/vetting/revoke-statement/0.1/payload.ts +218 -0
- package/src/vtc/vetting/vetters/grant/0.1/payload.ts +237 -0
- package/src/vtc/vetting/vetters/list/0.1/payload.ts +816 -0
- package/src/vtc/vetting/vetters/profile/0.1/payload.ts +647 -0
- package/src/vtc/vetting/vetters/resend/0.1/payload.ts +174 -0
|
@@ -0,0 +1,815 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated by scripts/build-ts-bindings.mjs — DO NOT EDIT BY HAND.
|
|
3
|
+
* Source: specs/vtc/join-requests/manifest/0.2/payload.schema.json
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ClaimType, DigestMultibase, Ext, VettingDocumentation, VettingMethod } from "../../../../_shared/components.js";
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* An ISO 8601 duration in weeks, days, hours, minutes and seconds only (e.g. `P120D`, `P2W`, `P1DT12H`, `PT15M`). Years and months are refused: their length depends on the calendar, and an age limit that means different things on different days is not a limit.
|
|
11
|
+
*/
|
|
12
|
+
export type Duration = string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Discover a community's join criteria before applying. The request carries nothing. Version 0.2 adds, per criterion, an optional `vetting` requirements object — how many identity-vetting statements a community needs, by which methods, from whom — and a `requirementsDigest` that names the exact version of the criterion an applicant started under. The response may also carry `branding`, how the community asks to be shown.
|
|
16
|
+
*/
|
|
17
|
+
export interface VTCJoinRequestsManifestPayload {
|
|
18
|
+
ext?: Ext;
|
|
19
|
+
}
|
|
20
|
+
export interface VTCJoinRequestsManifestResponsePayload {
|
|
21
|
+
communityDid: string;
|
|
22
|
+
criteria: Criterion[];
|
|
23
|
+
branding?: CommunityBranding;
|
|
24
|
+
ext?: Ext;
|
|
25
|
+
}
|
|
26
|
+
export interface Criterion {
|
|
27
|
+
id: string;
|
|
28
|
+
/**
|
|
29
|
+
* Plain-language summary of the criterion, authored by the community and shown to prospective applicants. Informative: where it and `vetting` disagree, `vetting` governs.
|
|
30
|
+
*/
|
|
31
|
+
description?: string;
|
|
32
|
+
/**
|
|
33
|
+
* The presentation-definition an applicant must satisfy for this criterion (opaque here).
|
|
34
|
+
*/
|
|
35
|
+
presentationDefinition: {};
|
|
36
|
+
vetting?: VettingRequirements;
|
|
37
|
+
/**
|
|
38
|
+
* Digest over the RFC 8785 (JCS) canonicalization of this criterion object with the `requirementsDigest` member removed, as a multibase-encoded multihash (SHA-256 and base58btc RECOMMENDED). Names one version of the criterion: an applicant records it when starting an application and echoes it to vetters and at submission. REQUIRED when `vetting` is present.
|
|
39
|
+
*/
|
|
40
|
+
requirementsDigest?: DigestMultibase;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* What identity-vetting evidence a criterion needs, beyond what a presentation-definition can express: distinct eligible vetters, per-method floors, independence caps. Every number is the community's own policy. This schema supplies no defaults — an absent optional member means the community imposes no constraint of that kind, never that some protocol value applies. Deliberately open: a consumer MUST ignore members it does not recognise, so a community publishing a newer shape does not make an older client unable to read the rest. Durations: `maxStatementAge` — a statement older than this at decision time does not count (absent: no limit beyond the statement's own validity); `decisionSla` — how long after submission the community undertakes to decide, including on a referred application; `requirementsGrace` — how long an application started under an earlier `requirementsDigest` is still evaluated under that version.
|
|
44
|
+
*/
|
|
45
|
+
export interface VettingRequirements {
|
|
46
|
+
/**
|
|
47
|
+
* Version of this requirements object's shape. `0.1` for the members defined here.
|
|
48
|
+
*/
|
|
49
|
+
version: string;
|
|
50
|
+
/**
|
|
51
|
+
* The endorsement type URI a counted vetting statement carries as `credentialSubject.endorsement.type`, as registered with the community via vtc/endorsement-types/register.
|
|
52
|
+
*/
|
|
53
|
+
statementType: string;
|
|
54
|
+
/**
|
|
55
|
+
* How many counted statements are needed, counting each vetter once however many DIDs they hold.
|
|
56
|
+
*/
|
|
57
|
+
minStatements: number;
|
|
58
|
+
/**
|
|
59
|
+
* Per-method floors within `minStatements` — e.g. `{ "inPerson": 1 }`. Every method named MUST also be in `acceptedMethods`. Absent: no method floor.
|
|
60
|
+
*/
|
|
61
|
+
minByMethod?: {
|
|
62
|
+
[k: string]: number | undefined;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Methods whose statements count at all.
|
|
66
|
+
*
|
|
67
|
+
* @minItems 1
|
|
68
|
+
*/
|
|
69
|
+
acceptedMethods: [VettingMethod, ...VettingMethod[]];
|
|
70
|
+
/**
|
|
71
|
+
* Documentation a statement must have relied on in order to count. Absent — the expected case — means each vetter decides what documentation they accept, including none for prior acquaintance, and the community counts what they attest.
|
|
72
|
+
*
|
|
73
|
+
* @minItems 1
|
|
74
|
+
*/
|
|
75
|
+
acceptedDocumentClasses?: [VettingDocumentation, ...VettingDocumentation[]];
|
|
76
|
+
/**
|
|
77
|
+
* Claim types the applicant's Vetting Card must carry, which the identity commitment is computed over, and which a counted statement must list as verified. Absent: none.
|
|
78
|
+
*/
|
|
79
|
+
requiredClaims?: ClaimType[];
|
|
80
|
+
/**
|
|
81
|
+
* Claim types an applicant MAY add to the card and a vetter MAY verify. They never affect whether a statement counts.
|
|
82
|
+
*/
|
|
83
|
+
optionalClaims?: ClaimType[];
|
|
84
|
+
maxStatementAge?: Duration;
|
|
85
|
+
/**
|
|
86
|
+
* How a vetter's eligibility is established.
|
|
87
|
+
*/
|
|
88
|
+
eligibleVetters: {
|
|
89
|
+
/**
|
|
90
|
+
* The role named in a community-issued `CommunityRole` endorsement credential (see `vtc/vetting/vetters/grant/0.1`). A statement counts only if its issuer holds that credential.
|
|
91
|
+
*/
|
|
92
|
+
role: string;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Caps on how much evidence may come from people close to the applicant. Absent: no caps.
|
|
96
|
+
*/
|
|
97
|
+
independence?: {
|
|
98
|
+
/**
|
|
99
|
+
* The most counted statements that may come from vetters declaring each relationship — e.g. `{ "family": 0 }`.
|
|
100
|
+
*/
|
|
101
|
+
maxByDeclaredRelationship?: {
|
|
102
|
+
[k: string]: number | undefined;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* When true, every counted statement must carry the same identity commitment — all vetters verified the same claimed identity. Absent: false.
|
|
106
|
+
*/
|
|
107
|
+
requireConsistentIdentityCommitment?: boolean;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Whether an invitation credential must accompany the statements at submission (`required`), may (`optional`), or plays no part (`none`). Absent: the presentation-definition alone governs.
|
|
111
|
+
*/
|
|
112
|
+
invitation?: "required" | "optional" | "none";
|
|
113
|
+
decisionSla?: Duration;
|
|
114
|
+
requirementsGrace?: Duration;
|
|
115
|
+
/**
|
|
116
|
+
* Where the community's vetting governance — including the attestation text vetters sign — is published.
|
|
117
|
+
*/
|
|
118
|
+
governanceFrameworkUrl?: string;
|
|
119
|
+
[k: string]: unknown | undefined;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* OPTIONAL. How the community asks to be shown to a prospective applicant: a name, an accent colour and a logo. Presentation only, self-asserted and unverified — `communityDid` identifies the community, never `branding`. Not part of any criterion, so not covered by a `requirementsDigest`. Every member is optional.
|
|
123
|
+
*/
|
|
124
|
+
export interface CommunityBranding {
|
|
125
|
+
/**
|
|
126
|
+
* The community's name as it asks to be shown.
|
|
127
|
+
*/
|
|
128
|
+
displayName?: string;
|
|
129
|
+
/**
|
|
130
|
+
* An sRGB colour as `#rrggbb`, compared case-insensitively. A community SHOULD write it in lower case.
|
|
131
|
+
*/
|
|
132
|
+
accentColor?: string;
|
|
133
|
+
/**
|
|
134
|
+
* An https URL of the community's logo. Fetched by the client, so an untrusted image from wherever it points.
|
|
135
|
+
*/
|
|
136
|
+
logoUrl?: string;
|
|
137
|
+
ext?: Ext;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Shared definitions this specification references, re-exported under the names it used to declare them with. */
|
|
141
|
+
export type { ClaimType, DigestMultibase, Ext, VettingDocumentation, VettingMethod };
|
|
142
|
+
|
|
143
|
+
/** Trust Task type URI. */
|
|
144
|
+
export const TYPE_URI = "https://trusttasks.org/spec/vtc/join-requests/manifest/0.2" as const;
|
|
145
|
+
|
|
146
|
+
/** Stable alias for this specification's request payload shape. */
|
|
147
|
+
export type Payload = VTCJoinRequestsManifestPayload;
|
|
148
|
+
|
|
149
|
+
/** Trust Task response type URI (request type URI + "#response"). */
|
|
150
|
+
export const RESPONSE_TYPE_URI = "https://trusttasks.org/spec/vtc/join-requests/manifest/0.2#response" as const;
|
|
151
|
+
|
|
152
|
+
/** Stable alias for this specification's success-response payload shape. */
|
|
153
|
+
export type Response = VTCJoinRequestsManifestResponsePayload;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* This specification's payload schema, as a value.
|
|
157
|
+
*
|
|
158
|
+
* SPEC.md §7.2 item 2 is performed against this. It is shipped as data
|
|
159
|
+
* rather than only as a `.json` file because TypeScript types are erased
|
|
160
|
+
* at runtime: without a schema a consumer has nothing to validate, and
|
|
161
|
+
* every REQUIRED payload member is optional in practice. Cross-file
|
|
162
|
+
* `$ref`s are already inlined, so it needs no resolver.
|
|
163
|
+
*/
|
|
164
|
+
export const PAYLOAD_SCHEMA = {
|
|
165
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
166
|
+
"$id": "https://trusttasks.org/spec/vtc/join-requests/manifest/0.2",
|
|
167
|
+
"title": "VTC Join-Requests Manifest — payload",
|
|
168
|
+
"description": "Discover a community's join criteria before applying. The request carries nothing. Version 0.2 adds, per criterion, an optional `vetting` requirements object — how many identity-vetting statements a community needs, by which methods, from whom — and a `requirementsDigest` that names the exact version of the criterion an applicant started under. The response may also carry `branding`, how the community asks to be shown.",
|
|
169
|
+
"type": "object",
|
|
170
|
+
"additionalProperties": false,
|
|
171
|
+
"properties": {
|
|
172
|
+
"ext": {
|
|
173
|
+
"$ref": "#/$defs/Ext"
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
"$defs": {
|
|
177
|
+
"Duration": {
|
|
178
|
+
"title": "Duration",
|
|
179
|
+
"type": "string",
|
|
180
|
+
"maxLength": 32,
|
|
181
|
+
"pattern": "^P(([0-9]+W)?([0-9]+D)?T([0-9]+H([0-9]+M)?([0-9]+S)?|[0-9]+M([0-9]+S)?|[0-9]+S)|[0-9]+W([0-9]+D)?|[0-9]+D)$",
|
|
182
|
+
"description": "An ISO 8601 duration in weeks, days, hours, minutes and seconds only (e.g. `P120D`, `P2W`, `P1DT12H`, `PT15M`). Years and months are refused: their length depends on the calendar, and an age limit that means different things on different days is not a limit."
|
|
183
|
+
},
|
|
184
|
+
"Criterion": {
|
|
185
|
+
"title": "Criterion",
|
|
186
|
+
"type": "object",
|
|
187
|
+
"additionalProperties": false,
|
|
188
|
+
"required": [
|
|
189
|
+
"id",
|
|
190
|
+
"presentationDefinition"
|
|
191
|
+
],
|
|
192
|
+
"dependentRequired": {
|
|
193
|
+
"vetting": [
|
|
194
|
+
"requirementsDigest"
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
"properties": {
|
|
198
|
+
"id": {
|
|
199
|
+
"type": "string",
|
|
200
|
+
"minLength": 1,
|
|
201
|
+
"maxLength": 128
|
|
202
|
+
},
|
|
203
|
+
"description": {
|
|
204
|
+
"type": "string",
|
|
205
|
+
"maxLength": 1024,
|
|
206
|
+
"description": "Plain-language summary of the criterion, authored by the community and shown to prospective applicants. Informative: where it and `vetting` disagree, `vetting` governs."
|
|
207
|
+
},
|
|
208
|
+
"presentationDefinition": {
|
|
209
|
+
"type": "object",
|
|
210
|
+
"description": "The presentation-definition an applicant must satisfy for this criterion (opaque here)."
|
|
211
|
+
},
|
|
212
|
+
"vetting": {
|
|
213
|
+
"$ref": "#/$defs/VettingRequirements"
|
|
214
|
+
},
|
|
215
|
+
"requirementsDigest": {
|
|
216
|
+
"$ref": "#/$defs/DigestMultibase",
|
|
217
|
+
"description": "Digest over the RFC 8785 (JCS) canonicalization of this criterion object with the `requirementsDigest` member removed, as a multibase-encoded multihash (SHA-256 and base58btc RECOMMENDED). Names one version of the criterion: an applicant records it when starting an application and echoes it to vetters and at submission. REQUIRED when `vetting` is present."
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
"VettingRequirements": {
|
|
222
|
+
"title": "VettingRequirements",
|
|
223
|
+
"type": "object",
|
|
224
|
+
"additionalProperties": true,
|
|
225
|
+
"required": [
|
|
226
|
+
"version",
|
|
227
|
+
"statementType",
|
|
228
|
+
"minStatements",
|
|
229
|
+
"acceptedMethods",
|
|
230
|
+
"eligibleVetters"
|
|
231
|
+
],
|
|
232
|
+
"description": "What identity-vetting evidence a criterion needs, beyond what a presentation-definition can express: distinct eligible vetters, per-method floors, independence caps. Every number is the community's own policy. This schema supplies no defaults — an absent optional member means the community imposes no constraint of that kind, never that some protocol value applies. Deliberately open: a consumer MUST ignore members it does not recognise, so a community publishing a newer shape does not make an older client unable to read the rest. Durations: `maxStatementAge` — a statement older than this at decision time does not count (absent: no limit beyond the statement's own validity); `decisionSla` — how long after submission the community undertakes to decide, including on a referred application; `requirementsGrace` — how long an application started under an earlier `requirementsDigest` is still evaluated under that version.",
|
|
233
|
+
"properties": {
|
|
234
|
+
"version": {
|
|
235
|
+
"type": "string",
|
|
236
|
+
"pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$",
|
|
237
|
+
"description": "Version of this requirements object's shape. `0.1` for the members defined here."
|
|
238
|
+
},
|
|
239
|
+
"statementType": {
|
|
240
|
+
"type": "string",
|
|
241
|
+
"format": "uri",
|
|
242
|
+
"minLength": 1,
|
|
243
|
+
"maxLength": 512,
|
|
244
|
+
"description": "The endorsement type URI a counted vetting statement carries as `credentialSubject.endorsement.type`, as registered with the community via vtc/endorsement-types/register."
|
|
245
|
+
},
|
|
246
|
+
"minStatements": {
|
|
247
|
+
"type": "integer",
|
|
248
|
+
"minimum": 1,
|
|
249
|
+
"description": "How many counted statements are needed, counting each vetter once however many DIDs they hold."
|
|
250
|
+
},
|
|
251
|
+
"minByMethod": {
|
|
252
|
+
"type": "object",
|
|
253
|
+
"propertyNames": {
|
|
254
|
+
"$ref": "#/$defs/VettingMethod"
|
|
255
|
+
},
|
|
256
|
+
"additionalProperties": {
|
|
257
|
+
"type": "integer",
|
|
258
|
+
"minimum": 0
|
|
259
|
+
},
|
|
260
|
+
"description": "Per-method floors within `minStatements` — e.g. `{ \"inPerson\": 1 }`. Every method named MUST also be in `acceptedMethods`. Absent: no method floor."
|
|
261
|
+
},
|
|
262
|
+
"acceptedMethods": {
|
|
263
|
+
"type": "array",
|
|
264
|
+
"minItems": 1,
|
|
265
|
+
"uniqueItems": true,
|
|
266
|
+
"items": {
|
|
267
|
+
"$ref": "#/$defs/VettingMethod"
|
|
268
|
+
},
|
|
269
|
+
"description": "Methods whose statements count at all."
|
|
270
|
+
},
|
|
271
|
+
"acceptedDocumentClasses": {
|
|
272
|
+
"type": "array",
|
|
273
|
+
"minItems": 1,
|
|
274
|
+
"uniqueItems": true,
|
|
275
|
+
"items": {
|
|
276
|
+
"$ref": "#/$defs/VettingDocumentation"
|
|
277
|
+
},
|
|
278
|
+
"description": "Documentation a statement must have relied on in order to count. Absent — the expected case — means each vetter decides what documentation they accept, including none for prior acquaintance, and the community counts what they attest."
|
|
279
|
+
},
|
|
280
|
+
"requiredClaims": {
|
|
281
|
+
"type": "array",
|
|
282
|
+
"uniqueItems": true,
|
|
283
|
+
"items": {
|
|
284
|
+
"$ref": "#/$defs/ClaimType"
|
|
285
|
+
},
|
|
286
|
+
"description": "Claim types the applicant's Vetting Card must carry, which the identity commitment is computed over, and which a counted statement must list as verified. Absent: none."
|
|
287
|
+
},
|
|
288
|
+
"optionalClaims": {
|
|
289
|
+
"type": "array",
|
|
290
|
+
"uniqueItems": true,
|
|
291
|
+
"items": {
|
|
292
|
+
"$ref": "#/$defs/ClaimType"
|
|
293
|
+
},
|
|
294
|
+
"description": "Claim types an applicant MAY add to the card and a vetter MAY verify. They never affect whether a statement counts."
|
|
295
|
+
},
|
|
296
|
+
"maxStatementAge": {
|
|
297
|
+
"$ref": "#/$defs/Duration"
|
|
298
|
+
},
|
|
299
|
+
"eligibleVetters": {
|
|
300
|
+
"type": "object",
|
|
301
|
+
"additionalProperties": false,
|
|
302
|
+
"required": [
|
|
303
|
+
"role"
|
|
304
|
+
],
|
|
305
|
+
"properties": {
|
|
306
|
+
"role": {
|
|
307
|
+
"type": "string",
|
|
308
|
+
"minLength": 1,
|
|
309
|
+
"maxLength": 128,
|
|
310
|
+
"pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$",
|
|
311
|
+
"description": "The role named in a community-issued `CommunityRole` endorsement credential (see `vtc/vetting/vetters/grant/0.1`). A statement counts only if its issuer holds that credential."
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
"description": "How a vetter's eligibility is established."
|
|
315
|
+
},
|
|
316
|
+
"independence": {
|
|
317
|
+
"type": "object",
|
|
318
|
+
"additionalProperties": false,
|
|
319
|
+
"properties": {
|
|
320
|
+
"maxByDeclaredRelationship": {
|
|
321
|
+
"type": "object",
|
|
322
|
+
"propertyNames": {
|
|
323
|
+
"$ref": "#/$defs/VettingRelationship"
|
|
324
|
+
},
|
|
325
|
+
"additionalProperties": {
|
|
326
|
+
"type": "integer",
|
|
327
|
+
"minimum": 0
|
|
328
|
+
},
|
|
329
|
+
"description": "The most counted statements that may come from vetters declaring each relationship — e.g. `{ \"family\": 0 }`."
|
|
330
|
+
},
|
|
331
|
+
"requireConsistentIdentityCommitment": {
|
|
332
|
+
"type": "boolean",
|
|
333
|
+
"description": "When true, every counted statement must carry the same identity commitment — all vetters verified the same claimed identity. Absent: false."
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
"description": "Caps on how much evidence may come from people close to the applicant. Absent: no caps."
|
|
337
|
+
},
|
|
338
|
+
"invitation": {
|
|
339
|
+
"type": "string",
|
|
340
|
+
"enum": [
|
|
341
|
+
"required",
|
|
342
|
+
"optional",
|
|
343
|
+
"none"
|
|
344
|
+
],
|
|
345
|
+
"description": "Whether an invitation credential must accompany the statements at submission (`required`), may (`optional`), or plays no part (`none`). Absent: the presentation-definition alone governs."
|
|
346
|
+
},
|
|
347
|
+
"decisionSla": {
|
|
348
|
+
"$ref": "#/$defs/Duration"
|
|
349
|
+
},
|
|
350
|
+
"requirementsGrace": {
|
|
351
|
+
"$ref": "#/$defs/Duration"
|
|
352
|
+
},
|
|
353
|
+
"governanceFrameworkUrl": {
|
|
354
|
+
"type": "string",
|
|
355
|
+
"format": "uri",
|
|
356
|
+
"pattern": "^https://",
|
|
357
|
+
"maxLength": 2048,
|
|
358
|
+
"description": "Where the community's vetting governance — including the attestation text vetters sign — is published."
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
"CommunityBranding": {
|
|
363
|
+
"title": "CommunityBranding",
|
|
364
|
+
"type": "object",
|
|
365
|
+
"additionalProperties": false,
|
|
366
|
+
"description": "OPTIONAL. How the community asks to be shown to a prospective applicant: a name, an accent colour and a logo. Presentation only, self-asserted and unverified — `communityDid` identifies the community, never `branding`. Not part of any criterion, so not covered by a `requirementsDigest`. Every member is optional.",
|
|
367
|
+
"properties": {
|
|
368
|
+
"displayName": {
|
|
369
|
+
"type": "string",
|
|
370
|
+
"minLength": 1,
|
|
371
|
+
"maxLength": 128,
|
|
372
|
+
"description": "The community's name as it asks to be shown."
|
|
373
|
+
},
|
|
374
|
+
"accentColor": {
|
|
375
|
+
"type": "string",
|
|
376
|
+
"pattern": "^#[0-9a-fA-F]{6}$",
|
|
377
|
+
"description": "An sRGB colour as `#rrggbb`, compared case-insensitively. A community SHOULD write it in lower case."
|
|
378
|
+
},
|
|
379
|
+
"logoUrl": {
|
|
380
|
+
"type": "string",
|
|
381
|
+
"format": "uri",
|
|
382
|
+
"pattern": "^https://",
|
|
383
|
+
"maxLength": 2048,
|
|
384
|
+
"description": "An https URL of the community's logo. Fetched by the client, so an untrusted image from wherever it points."
|
|
385
|
+
},
|
|
386
|
+
"ext": {
|
|
387
|
+
"$ref": "#/$defs/Ext"
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
"Response": {
|
|
392
|
+
"$anchor": "response",
|
|
393
|
+
"title": "VTC Join-Requests Manifest — response payload",
|
|
394
|
+
"type": "object",
|
|
395
|
+
"additionalProperties": false,
|
|
396
|
+
"required": [
|
|
397
|
+
"communityDid",
|
|
398
|
+
"criteria"
|
|
399
|
+
],
|
|
400
|
+
"properties": {
|
|
401
|
+
"communityDid": {
|
|
402
|
+
"type": "string",
|
|
403
|
+
"pattern": "^did:"
|
|
404
|
+
},
|
|
405
|
+
"criteria": {
|
|
406
|
+
"type": "array",
|
|
407
|
+
"items": {
|
|
408
|
+
"$ref": "#/$defs/Criterion"
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
"branding": {
|
|
412
|
+
"$ref": "#/$defs/CommunityBranding"
|
|
413
|
+
},
|
|
414
|
+
"ext": {
|
|
415
|
+
"$ref": "#/$defs/Ext"
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
"Ext": {
|
|
420
|
+
"title": "Ext",
|
|
421
|
+
"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.",
|
|
422
|
+
"type": "object",
|
|
423
|
+
"minProperties": 1,
|
|
424
|
+
"additionalProperties": true,
|
|
425
|
+
"propertyNames": {
|
|
426
|
+
"pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
|
|
427
|
+
}
|
|
428
|
+
},
|
|
429
|
+
"VettingRelationship": {
|
|
430
|
+
"title": "VettingRelationship",
|
|
431
|
+
"type": "string",
|
|
432
|
+
"enum": [
|
|
433
|
+
"none",
|
|
434
|
+
"communityColleague",
|
|
435
|
+
"sameEmployer",
|
|
436
|
+
"family",
|
|
437
|
+
"otherPersonal"
|
|
438
|
+
],
|
|
439
|
+
"description": "The vetter's own declaration of how they relate to the applicant. Declared, not verified: it exists so community policy can cap how much evidence comes from people close to the applicant, and a false declaration is the vetter's attributable act."
|
|
440
|
+
},
|
|
441
|
+
"ClaimType": {
|
|
442
|
+
"title": "ClaimType",
|
|
443
|
+
"description": "The vocabulary token naming what a value IS — `name.legal`, `phone.mobile`, `address.postal`, `person.birthDate`. Dotted, most-general segment first, so that a consumer with no knowledge of the specific token can still group by its prefix.\n\nThe token is the maintainer's own; no external vocabulary is primary. External vocabularies (vCard/jCard, OIDC standard claims, schema.org) are mappings applied at PRESENTATION by a renderer, not at rest, so that a query written in any of them can be matched without the store having to live inside any one of them.\n\nThe `x:` prefix is an open extension namespace and is not decoration. The closest prior art — Windows CardSpace's self-issued card — supported exactly fifteen predefined claim types with no extensibility, and that is the specific way it failed the requirement a holder actually has. An `x:` attribute stores, composes, binds and discloses exactly like a known one; it renders generically and matches only an explicit query.",
|
|
444
|
+
"type": "string",
|
|
445
|
+
"minLength": 1,
|
|
446
|
+
"maxLength": 128,
|
|
447
|
+
"pattern": "^(x:)?[a-z][a-zA-Z0-9]*(\\.[a-z][a-zA-Z0-9]*)*$"
|
|
448
|
+
},
|
|
449
|
+
"VettingDocumentation": {
|
|
450
|
+
"title": "VettingDocumentation",
|
|
451
|
+
"type": "string",
|
|
452
|
+
"minLength": 1,
|
|
453
|
+
"maxLength": 64,
|
|
454
|
+
"pattern": "^[a-z][a-zA-Z0-9]*$",
|
|
455
|
+
"description": "A class of documentation, named in lowerCamelCase. Open rather than enumerated, because what documentation a vetter accepts is each vetter's own choice. Well-known values: `passport`, `nationalId`, `driverLicence`, and `none` — the vetter will attest without a document, which is the `priorAcquaintance` case. Only the class ever travels — never a document number, an image, an issuing authority or an expiry date. `none` states a policy (what a vetter accepts); a record of what was relied on expresses 'no document' as an empty list instead."
|
|
456
|
+
},
|
|
457
|
+
"VettingMethod": {
|
|
458
|
+
"title": "VettingMethod",
|
|
459
|
+
"type": "string",
|
|
460
|
+
"enum": [
|
|
461
|
+
"inPerson",
|
|
462
|
+
"video",
|
|
463
|
+
"priorAcquaintance"
|
|
464
|
+
],
|
|
465
|
+
"description": "How the vetter established that the person they checked is the person controlling the applicant's DID. `inPerson` — both people were physically together. `video` — a live, two-way video call. `priorAcquaintance` — the vetter has known or worked with this person over a period, and attests from that knowledge rather than from a document. A method is a description of what happened, not an assurance level: which methods count, and how many of each, is community policy."
|
|
466
|
+
},
|
|
467
|
+
"DigestMultibase": {
|
|
468
|
+
"title": "DigestMultibase",
|
|
469
|
+
"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`.",
|
|
470
|
+
"type": "string",
|
|
471
|
+
"minLength": 16,
|
|
472
|
+
"pattern": "^(z[1-9A-HJ-NP-Za-km-z]+|u[A-Za-z0-9_-]+)$",
|
|
473
|
+
"examples": [
|
|
474
|
+
"zQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR"
|
|
475
|
+
]
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
} as const;
|
|
479
|
+
|
|
480
|
+
/** As {@link PAYLOAD_SCHEMA}, for the success-response variant. */
|
|
481
|
+
export const RESPONSE_PAYLOAD_SCHEMA = {
|
|
482
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
483
|
+
"$ref": "#/$defs/Response",
|
|
484
|
+
"$defs": {
|
|
485
|
+
"Duration": {
|
|
486
|
+
"title": "Duration",
|
|
487
|
+
"type": "string",
|
|
488
|
+
"maxLength": 32,
|
|
489
|
+
"pattern": "^P(([0-9]+W)?([0-9]+D)?T([0-9]+H([0-9]+M)?([0-9]+S)?|[0-9]+M([0-9]+S)?|[0-9]+S)|[0-9]+W([0-9]+D)?|[0-9]+D)$",
|
|
490
|
+
"description": "An ISO 8601 duration in weeks, days, hours, minutes and seconds only (e.g. `P120D`, `P2W`, `P1DT12H`, `PT15M`). Years and months are refused: their length depends on the calendar, and an age limit that means different things on different days is not a limit."
|
|
491
|
+
},
|
|
492
|
+
"Criterion": {
|
|
493
|
+
"title": "Criterion",
|
|
494
|
+
"type": "object",
|
|
495
|
+
"additionalProperties": false,
|
|
496
|
+
"required": [
|
|
497
|
+
"id",
|
|
498
|
+
"presentationDefinition"
|
|
499
|
+
],
|
|
500
|
+
"dependentRequired": {
|
|
501
|
+
"vetting": [
|
|
502
|
+
"requirementsDigest"
|
|
503
|
+
]
|
|
504
|
+
},
|
|
505
|
+
"properties": {
|
|
506
|
+
"id": {
|
|
507
|
+
"type": "string",
|
|
508
|
+
"minLength": 1,
|
|
509
|
+
"maxLength": 128
|
|
510
|
+
},
|
|
511
|
+
"description": {
|
|
512
|
+
"type": "string",
|
|
513
|
+
"maxLength": 1024,
|
|
514
|
+
"description": "Plain-language summary of the criterion, authored by the community and shown to prospective applicants. Informative: where it and `vetting` disagree, `vetting` governs."
|
|
515
|
+
},
|
|
516
|
+
"presentationDefinition": {
|
|
517
|
+
"type": "object",
|
|
518
|
+
"description": "The presentation-definition an applicant must satisfy for this criterion (opaque here)."
|
|
519
|
+
},
|
|
520
|
+
"vetting": {
|
|
521
|
+
"$ref": "#/$defs/VettingRequirements"
|
|
522
|
+
},
|
|
523
|
+
"requirementsDigest": {
|
|
524
|
+
"$ref": "#/$defs/DigestMultibase",
|
|
525
|
+
"description": "Digest over the RFC 8785 (JCS) canonicalization of this criterion object with the `requirementsDigest` member removed, as a multibase-encoded multihash (SHA-256 and base58btc RECOMMENDED). Names one version of the criterion: an applicant records it when starting an application and echoes it to vetters and at submission. REQUIRED when `vetting` is present."
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
},
|
|
529
|
+
"VettingRequirements": {
|
|
530
|
+
"title": "VettingRequirements",
|
|
531
|
+
"type": "object",
|
|
532
|
+
"additionalProperties": true,
|
|
533
|
+
"required": [
|
|
534
|
+
"version",
|
|
535
|
+
"statementType",
|
|
536
|
+
"minStatements",
|
|
537
|
+
"acceptedMethods",
|
|
538
|
+
"eligibleVetters"
|
|
539
|
+
],
|
|
540
|
+
"description": "What identity-vetting evidence a criterion needs, beyond what a presentation-definition can express: distinct eligible vetters, per-method floors, independence caps. Every number is the community's own policy. This schema supplies no defaults — an absent optional member means the community imposes no constraint of that kind, never that some protocol value applies. Deliberately open: a consumer MUST ignore members it does not recognise, so a community publishing a newer shape does not make an older client unable to read the rest. Durations: `maxStatementAge` — a statement older than this at decision time does not count (absent: no limit beyond the statement's own validity); `decisionSla` — how long after submission the community undertakes to decide, including on a referred application; `requirementsGrace` — how long an application started under an earlier `requirementsDigest` is still evaluated under that version.",
|
|
541
|
+
"properties": {
|
|
542
|
+
"version": {
|
|
543
|
+
"type": "string",
|
|
544
|
+
"pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$",
|
|
545
|
+
"description": "Version of this requirements object's shape. `0.1` for the members defined here."
|
|
546
|
+
},
|
|
547
|
+
"statementType": {
|
|
548
|
+
"type": "string",
|
|
549
|
+
"format": "uri",
|
|
550
|
+
"minLength": 1,
|
|
551
|
+
"maxLength": 512,
|
|
552
|
+
"description": "The endorsement type URI a counted vetting statement carries as `credentialSubject.endorsement.type`, as registered with the community via vtc/endorsement-types/register."
|
|
553
|
+
},
|
|
554
|
+
"minStatements": {
|
|
555
|
+
"type": "integer",
|
|
556
|
+
"minimum": 1,
|
|
557
|
+
"description": "How many counted statements are needed, counting each vetter once however many DIDs they hold."
|
|
558
|
+
},
|
|
559
|
+
"minByMethod": {
|
|
560
|
+
"type": "object",
|
|
561
|
+
"propertyNames": {
|
|
562
|
+
"$ref": "#/$defs/VettingMethod"
|
|
563
|
+
},
|
|
564
|
+
"additionalProperties": {
|
|
565
|
+
"type": "integer",
|
|
566
|
+
"minimum": 0
|
|
567
|
+
},
|
|
568
|
+
"description": "Per-method floors within `minStatements` — e.g. `{ \"inPerson\": 1 }`. Every method named MUST also be in `acceptedMethods`. Absent: no method floor."
|
|
569
|
+
},
|
|
570
|
+
"acceptedMethods": {
|
|
571
|
+
"type": "array",
|
|
572
|
+
"minItems": 1,
|
|
573
|
+
"uniqueItems": true,
|
|
574
|
+
"items": {
|
|
575
|
+
"$ref": "#/$defs/VettingMethod"
|
|
576
|
+
},
|
|
577
|
+
"description": "Methods whose statements count at all."
|
|
578
|
+
},
|
|
579
|
+
"acceptedDocumentClasses": {
|
|
580
|
+
"type": "array",
|
|
581
|
+
"minItems": 1,
|
|
582
|
+
"uniqueItems": true,
|
|
583
|
+
"items": {
|
|
584
|
+
"$ref": "#/$defs/VettingDocumentation"
|
|
585
|
+
},
|
|
586
|
+
"description": "Documentation a statement must have relied on in order to count. Absent — the expected case — means each vetter decides what documentation they accept, including none for prior acquaintance, and the community counts what they attest."
|
|
587
|
+
},
|
|
588
|
+
"requiredClaims": {
|
|
589
|
+
"type": "array",
|
|
590
|
+
"uniqueItems": true,
|
|
591
|
+
"items": {
|
|
592
|
+
"$ref": "#/$defs/ClaimType"
|
|
593
|
+
},
|
|
594
|
+
"description": "Claim types the applicant's Vetting Card must carry, which the identity commitment is computed over, and which a counted statement must list as verified. Absent: none."
|
|
595
|
+
},
|
|
596
|
+
"optionalClaims": {
|
|
597
|
+
"type": "array",
|
|
598
|
+
"uniqueItems": true,
|
|
599
|
+
"items": {
|
|
600
|
+
"$ref": "#/$defs/ClaimType"
|
|
601
|
+
},
|
|
602
|
+
"description": "Claim types an applicant MAY add to the card and a vetter MAY verify. They never affect whether a statement counts."
|
|
603
|
+
},
|
|
604
|
+
"maxStatementAge": {
|
|
605
|
+
"$ref": "#/$defs/Duration"
|
|
606
|
+
},
|
|
607
|
+
"eligibleVetters": {
|
|
608
|
+
"type": "object",
|
|
609
|
+
"additionalProperties": false,
|
|
610
|
+
"required": [
|
|
611
|
+
"role"
|
|
612
|
+
],
|
|
613
|
+
"properties": {
|
|
614
|
+
"role": {
|
|
615
|
+
"type": "string",
|
|
616
|
+
"minLength": 1,
|
|
617
|
+
"maxLength": 128,
|
|
618
|
+
"pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$",
|
|
619
|
+
"description": "The role named in a community-issued `CommunityRole` endorsement credential (see `vtc/vetting/vetters/grant/0.1`). A statement counts only if its issuer holds that credential."
|
|
620
|
+
}
|
|
621
|
+
},
|
|
622
|
+
"description": "How a vetter's eligibility is established."
|
|
623
|
+
},
|
|
624
|
+
"independence": {
|
|
625
|
+
"type": "object",
|
|
626
|
+
"additionalProperties": false,
|
|
627
|
+
"properties": {
|
|
628
|
+
"maxByDeclaredRelationship": {
|
|
629
|
+
"type": "object",
|
|
630
|
+
"propertyNames": {
|
|
631
|
+
"$ref": "#/$defs/VettingRelationship"
|
|
632
|
+
},
|
|
633
|
+
"additionalProperties": {
|
|
634
|
+
"type": "integer",
|
|
635
|
+
"minimum": 0
|
|
636
|
+
},
|
|
637
|
+
"description": "The most counted statements that may come from vetters declaring each relationship — e.g. `{ \"family\": 0 }`."
|
|
638
|
+
},
|
|
639
|
+
"requireConsistentIdentityCommitment": {
|
|
640
|
+
"type": "boolean",
|
|
641
|
+
"description": "When true, every counted statement must carry the same identity commitment — all vetters verified the same claimed identity. Absent: false."
|
|
642
|
+
}
|
|
643
|
+
},
|
|
644
|
+
"description": "Caps on how much evidence may come from people close to the applicant. Absent: no caps."
|
|
645
|
+
},
|
|
646
|
+
"invitation": {
|
|
647
|
+
"type": "string",
|
|
648
|
+
"enum": [
|
|
649
|
+
"required",
|
|
650
|
+
"optional",
|
|
651
|
+
"none"
|
|
652
|
+
],
|
|
653
|
+
"description": "Whether an invitation credential must accompany the statements at submission (`required`), may (`optional`), or plays no part (`none`). Absent: the presentation-definition alone governs."
|
|
654
|
+
},
|
|
655
|
+
"decisionSla": {
|
|
656
|
+
"$ref": "#/$defs/Duration"
|
|
657
|
+
},
|
|
658
|
+
"requirementsGrace": {
|
|
659
|
+
"$ref": "#/$defs/Duration"
|
|
660
|
+
},
|
|
661
|
+
"governanceFrameworkUrl": {
|
|
662
|
+
"type": "string",
|
|
663
|
+
"format": "uri",
|
|
664
|
+
"pattern": "^https://",
|
|
665
|
+
"maxLength": 2048,
|
|
666
|
+
"description": "Where the community's vetting governance — including the attestation text vetters sign — is published."
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
},
|
|
670
|
+
"CommunityBranding": {
|
|
671
|
+
"title": "CommunityBranding",
|
|
672
|
+
"type": "object",
|
|
673
|
+
"additionalProperties": false,
|
|
674
|
+
"description": "OPTIONAL. How the community asks to be shown to a prospective applicant: a name, an accent colour and a logo. Presentation only, self-asserted and unverified — `communityDid` identifies the community, never `branding`. Not part of any criterion, so not covered by a `requirementsDigest`. Every member is optional.",
|
|
675
|
+
"properties": {
|
|
676
|
+
"displayName": {
|
|
677
|
+
"type": "string",
|
|
678
|
+
"minLength": 1,
|
|
679
|
+
"maxLength": 128,
|
|
680
|
+
"description": "The community's name as it asks to be shown."
|
|
681
|
+
},
|
|
682
|
+
"accentColor": {
|
|
683
|
+
"type": "string",
|
|
684
|
+
"pattern": "^#[0-9a-fA-F]{6}$",
|
|
685
|
+
"description": "An sRGB colour as `#rrggbb`, compared case-insensitively. A community SHOULD write it in lower case."
|
|
686
|
+
},
|
|
687
|
+
"logoUrl": {
|
|
688
|
+
"type": "string",
|
|
689
|
+
"format": "uri",
|
|
690
|
+
"pattern": "^https://",
|
|
691
|
+
"maxLength": 2048,
|
|
692
|
+
"description": "An https URL of the community's logo. Fetched by the client, so an untrusted image from wherever it points."
|
|
693
|
+
},
|
|
694
|
+
"ext": {
|
|
695
|
+
"$ref": "#/$defs/Ext"
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
},
|
|
699
|
+
"Response": {
|
|
700
|
+
"$anchor": "response",
|
|
701
|
+
"title": "VTC Join-Requests Manifest — response payload",
|
|
702
|
+
"type": "object",
|
|
703
|
+
"additionalProperties": false,
|
|
704
|
+
"required": [
|
|
705
|
+
"communityDid",
|
|
706
|
+
"criteria"
|
|
707
|
+
],
|
|
708
|
+
"properties": {
|
|
709
|
+
"communityDid": {
|
|
710
|
+
"type": "string",
|
|
711
|
+
"pattern": "^did:"
|
|
712
|
+
},
|
|
713
|
+
"criteria": {
|
|
714
|
+
"type": "array",
|
|
715
|
+
"items": {
|
|
716
|
+
"$ref": "#/$defs/Criterion"
|
|
717
|
+
}
|
|
718
|
+
},
|
|
719
|
+
"branding": {
|
|
720
|
+
"$ref": "#/$defs/CommunityBranding"
|
|
721
|
+
},
|
|
722
|
+
"ext": {
|
|
723
|
+
"$ref": "#/$defs/Ext"
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
},
|
|
727
|
+
"Ext": {
|
|
728
|
+
"title": "Ext",
|
|
729
|
+
"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.",
|
|
730
|
+
"type": "object",
|
|
731
|
+
"minProperties": 1,
|
|
732
|
+
"additionalProperties": true,
|
|
733
|
+
"propertyNames": {
|
|
734
|
+
"pattern": "^[a-z][a-z0-9-]*(\\.[a-z0-9-]+)+$"
|
|
735
|
+
}
|
|
736
|
+
},
|
|
737
|
+
"VettingRelationship": {
|
|
738
|
+
"title": "VettingRelationship",
|
|
739
|
+
"type": "string",
|
|
740
|
+
"enum": [
|
|
741
|
+
"none",
|
|
742
|
+
"communityColleague",
|
|
743
|
+
"sameEmployer",
|
|
744
|
+
"family",
|
|
745
|
+
"otherPersonal"
|
|
746
|
+
],
|
|
747
|
+
"description": "The vetter's own declaration of how they relate to the applicant. Declared, not verified: it exists so community policy can cap how much evidence comes from people close to the applicant, and a false declaration is the vetter's attributable act."
|
|
748
|
+
},
|
|
749
|
+
"ClaimType": {
|
|
750
|
+
"title": "ClaimType",
|
|
751
|
+
"description": "The vocabulary token naming what a value IS — `name.legal`, `phone.mobile`, `address.postal`, `person.birthDate`. Dotted, most-general segment first, so that a consumer with no knowledge of the specific token can still group by its prefix.\n\nThe token is the maintainer's own; no external vocabulary is primary. External vocabularies (vCard/jCard, OIDC standard claims, schema.org) are mappings applied at PRESENTATION by a renderer, not at rest, so that a query written in any of them can be matched without the store having to live inside any one of them.\n\nThe `x:` prefix is an open extension namespace and is not decoration. The closest prior art — Windows CardSpace's self-issued card — supported exactly fifteen predefined claim types with no extensibility, and that is the specific way it failed the requirement a holder actually has. An `x:` attribute stores, composes, binds and discloses exactly like a known one; it renders generically and matches only an explicit query.",
|
|
752
|
+
"type": "string",
|
|
753
|
+
"minLength": 1,
|
|
754
|
+
"maxLength": 128,
|
|
755
|
+
"pattern": "^(x:)?[a-z][a-zA-Z0-9]*(\\.[a-z][a-zA-Z0-9]*)*$"
|
|
756
|
+
},
|
|
757
|
+
"VettingDocumentation": {
|
|
758
|
+
"title": "VettingDocumentation",
|
|
759
|
+
"type": "string",
|
|
760
|
+
"minLength": 1,
|
|
761
|
+
"maxLength": 64,
|
|
762
|
+
"pattern": "^[a-z][a-zA-Z0-9]*$",
|
|
763
|
+
"description": "A class of documentation, named in lowerCamelCase. Open rather than enumerated, because what documentation a vetter accepts is each vetter's own choice. Well-known values: `passport`, `nationalId`, `driverLicence`, and `none` — the vetter will attest without a document, which is the `priorAcquaintance` case. Only the class ever travels — never a document number, an image, an issuing authority or an expiry date. `none` states a policy (what a vetter accepts); a record of what was relied on expresses 'no document' as an empty list instead."
|
|
764
|
+
},
|
|
765
|
+
"VettingMethod": {
|
|
766
|
+
"title": "VettingMethod",
|
|
767
|
+
"type": "string",
|
|
768
|
+
"enum": [
|
|
769
|
+
"inPerson",
|
|
770
|
+
"video",
|
|
771
|
+
"priorAcquaintance"
|
|
772
|
+
],
|
|
773
|
+
"description": "How the vetter established that the person they checked is the person controlling the applicant's DID. `inPerson` — both people were physically together. `video` — a live, two-way video call. `priorAcquaintance` — the vetter has known or worked with this person over a period, and attests from that knowledge rather than from a document. A method is a description of what happened, not an assurance level: which methods count, and how many of each, is community policy."
|
|
774
|
+
},
|
|
775
|
+
"DigestMultibase": {
|
|
776
|
+
"title": "DigestMultibase",
|
|
777
|
+
"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`.",
|
|
778
|
+
"type": "string",
|
|
779
|
+
"minLength": 16,
|
|
780
|
+
"pattern": "^(z[1-9A-HJ-NP-Za-km-z]+|u[A-Za-z0-9_-]+)$",
|
|
781
|
+
"examples": [
|
|
782
|
+
"zQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR"
|
|
783
|
+
]
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
} as const;
|
|
787
|
+
|
|
788
|
+
/**
|
|
789
|
+
* SPEC.md §7.2 policy for the request variant, from this specification's
|
|
790
|
+
* front matter. Pass to `consumeInbound` — items 5b, 7 and 8 are
|
|
791
|
+
* per-specification and cannot be derived from the document alone, and
|
|
792
|
+
* item 2 needs the schema this carries.
|
|
793
|
+
*/
|
|
794
|
+
export const SPEC = {
|
|
795
|
+
typeUri: TYPE_URI,
|
|
796
|
+
isBearer: false,
|
|
797
|
+
isProofRequired: false,
|
|
798
|
+
isRecipientRequired: true,
|
|
799
|
+
isIssuedAtRequired: false,
|
|
800
|
+
payloadSchema: PAYLOAD_SCHEMA,
|
|
801
|
+
} as const;
|
|
802
|
+
|
|
803
|
+
/**
|
|
804
|
+
* SPEC.md §7.2 policy for the success-response variant. `isRecipientRequired`
|
|
805
|
+
* tracks the *issuer* party's requirement because a response swaps the
|
|
806
|
+
* parties (§7.3 item 5).
|
|
807
|
+
*/
|
|
808
|
+
export const RESPONSE_SPEC = {
|
|
809
|
+
typeUri: RESPONSE_TYPE_URI,
|
|
810
|
+
isBearer: false,
|
|
811
|
+
isProofRequired: false,
|
|
812
|
+
isRecipientRequired: true,
|
|
813
|
+
isIssuedAtRequired: false,
|
|
814
|
+
payloadSchema: RESPONSE_PAYLOAD_SCHEMA,
|
|
815
|
+
} as const;
|