@openvtc/trust-tasks 0.12.7 → 0.12.8

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 (31) hide show
  1. package/dist/vtc/endorsement-types/list/0.1/payload.d.ts +20 -0
  2. package/dist/vtc/endorsement-types/list/0.1/payload.d.ts.map +1 -1
  3. package/dist/vtc/endorsement-types/list/0.1/payload.js +8 -0
  4. package/dist/vtc/endorsement-types/list/0.1/payload.js.map +1 -1
  5. package/dist/vtc/endorsement-types/register/0.1/payload.d.ts +20 -0
  6. package/dist/vtc/endorsement-types/register/0.1/payload.d.ts.map +1 -1
  7. package/dist/vtc/endorsement-types/register/0.1/payload.js +8 -0
  8. package/dist/vtc/endorsement-types/register/0.1/payload.js.map +1 -1
  9. package/dist/vtc/join-requests/decide/0.1/payload.d.ts +42 -0
  10. package/dist/vtc/join-requests/decide/0.1/payload.d.ts.map +1 -1
  11. package/dist/vtc/join-requests/decide/0.1/payload.js +28 -0
  12. package/dist/vtc/join-requests/decide/0.1/payload.js.map +1 -1
  13. package/dist/vtc/members/list/0.1/payload.d.ts +108 -0
  14. package/dist/vtc/members/list/0.1/payload.d.ts.map +1 -1
  15. package/dist/vtc/members/list/0.1/payload.js +62 -0
  16. package/dist/vtc/members/list/0.1/payload.js.map +1 -1
  17. package/dist/vtc/members/show/0.1/payload.d.ts +108 -0
  18. package/dist/vtc/members/show/0.1/payload.d.ts.map +1 -1
  19. package/dist/vtc/members/show/0.1/payload.js +62 -0
  20. package/dist/vtc/members/show/0.1/payload.js.map +1 -1
  21. package/dist/vtc/members/update/0.1/payload.d.ts +120 -0
  22. package/dist/vtc/members/update/0.1/payload.d.ts.map +1 -1
  23. package/dist/vtc/members/update/0.1/payload.js +69 -0
  24. package/dist/vtc/members/update/0.1/payload.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/vtc/endorsement-types/list/0.1/payload.ts +12 -0
  27. package/src/vtc/endorsement-types/register/0.1/payload.ts +12 -0
  28. package/src/vtc/join-requests/decide/0.1/payload.ts +38 -0
  29. package/src/vtc/members/list/0.1/payload.ts +82 -0
  30. package/src/vtc/members/show/0.1/payload.ts +82 -0
  31. package/src/vtc/members/update/0.1/payload.ts +93 -0
@@ -30,6 +30,10 @@ export interface EndorsementType {
30
30
  */
31
31
  claimSchema?: {};
32
32
  createdAt?: string;
33
+ /**
34
+ * The member who registered this endorsement type. An endorsement vocabulary is community-defined and shapes what every later endorsement can claim, so who introduced a type is audit-relevant in a way its creation time alone is not.
35
+ */
36
+ createdByDid?: string;
33
37
  }
34
38
 
35
39
  /** Trust Task type URI. */
@@ -135,6 +139,10 @@ export const PAYLOAD_SCHEMA = {
135
139
  "createdAt": {
136
140
  "type": "string",
137
141
  "format": "date-time"
142
+ },
143
+ "createdByDid": {
144
+ "type": "string",
145
+ "description": "The member who registered this endorsement type. An endorsement vocabulary is community-defined and shapes what every later endorsement can claim, so who introduced a type is audit-relevant in a way its creation time alone is not."
138
146
  }
139
147
  }
140
148
  }
@@ -208,6 +216,10 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
208
216
  "createdAt": {
209
217
  "type": "string",
210
218
  "format": "date-time"
219
+ },
220
+ "createdByDid": {
221
+ "type": "string",
222
+ "description": "The member who registered this endorsement type. An endorsement vocabulary is community-defined and shapes what every later endorsement can claim, so who introduced a type is audit-relevant in a way its creation time alone is not."
211
223
  }
212
224
  }
213
225
  }
@@ -33,6 +33,10 @@ export interface EndorsementType {
33
33
  */
34
34
  claimSchema?: {};
35
35
  createdAt?: string;
36
+ /**
37
+ * The member who registered this endorsement type. An endorsement vocabulary is community-defined and shapes what every later endorsement can claim, so who introduced a type is audit-relevant in a way its creation time alone is not.
38
+ */
39
+ createdByDid?: string;
36
40
  }
37
41
 
38
42
  /** Trust Task type URI. */
@@ -137,6 +141,10 @@ export const PAYLOAD_SCHEMA = {
137
141
  "createdAt": {
138
142
  "type": "string",
139
143
  "format": "date-time"
144
+ },
145
+ "createdByDid": {
146
+ "type": "string",
147
+ "description": "The member who registered this endorsement type. An endorsement vocabulary is community-defined and shapes what every later endorsement can claim, so who introduced a type is audit-relevant in a way its creation time alone is not."
140
148
  }
141
149
  }
142
150
  }
@@ -201,6 +209,10 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
201
209
  "createdAt": {
202
210
  "type": "string",
203
211
  "format": "date-time"
212
+ },
213
+ "createdByDid": {
214
+ "type": "string",
215
+ "description": "The member who registered this endorsement type. An endorsement vocabulary is community-defined and shapes what every later endorsement can claim, so who introduced a type is audit-relevant in a way its creation time alone is not."
204
216
  }
205
217
  }
206
218
  }
@@ -33,6 +33,16 @@ export interface VTCJoinRequestsDecideResponsePayload {
33
33
  * The request's post-decision state; echoes the decision.
34
34
  */
35
35
  status: "approved" | "rejected";
36
+ /**
37
+ * The membership credential issued by this decision, delivered inline. Present only where the decision admitted the applicant.
38
+ *
39
+ * Inline because the alternative is worse: the applicant would poll for a status, learn they were admitted, and then fetch the credential separately — a second round trip whose only purpose is to collect something the community already had in hand when it decided.
40
+ */
41
+ vmc?: {} | null;
42
+ /**
43
+ * The endorsement credential carrying the role this decision granted, delivered inline alongside `vmc` and on the same reasoning. Present only where the decision admitted the applicant and granted a role.
44
+ */
45
+ roleVec?: {} | null;
36
46
  ext?: Ext;
37
47
  }
38
48
 
@@ -114,6 +124,20 @@ export const PAYLOAD_SCHEMA = {
114
124
  ],
115
125
  "description": "The request's post-decision state; echoes the decision."
116
126
  },
127
+ "vmc": {
128
+ "type": [
129
+ "object",
130
+ "null"
131
+ ],
132
+ "description": "The membership credential issued by this decision, delivered inline. Present only where the decision admitted the applicant.\n\nInline because the alternative is worse: the applicant would poll for a status, learn they were admitted, and then fetch the credential separately — a second round trip whose only purpose is to collect something the community already had in hand when it decided."
133
+ },
134
+ "roleVec": {
135
+ "type": [
136
+ "object",
137
+ "null"
138
+ ],
139
+ "description": "The endorsement credential carrying the role this decision granted, delivered inline alongside `vmc` and on the same reasoning. Present only where the decision admitted the applicant and granted a role."
140
+ },
117
141
  "ext": {
118
142
  "$ref": "#/$defs/Ext"
119
143
  }
@@ -160,6 +184,20 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
160
184
  ],
161
185
  "description": "The request's post-decision state; echoes the decision."
162
186
  },
187
+ "vmc": {
188
+ "type": [
189
+ "object",
190
+ "null"
191
+ ],
192
+ "description": "The membership credential issued by this decision, delivered inline. Present only where the decision admitted the applicant.\n\nInline because the alternative is worse: the applicant would poll for a status, learn they were admitted, and then fetch the credential separately — a second round trip whose only purpose is to collect something the community already had in hand when it decided."
193
+ },
194
+ "roleVec": {
195
+ "type": [
196
+ "object",
197
+ "null"
198
+ ],
199
+ "description": "The endorsement credential carrying the role this decision granted, delivered inline alongside `vmc` and on the same reasoning. Present only where the decision admitted the applicant and granted a role."
200
+ },
163
201
  "ext": {
164
202
  "$ref": "#/$defs/Ext"
165
203
  }
@@ -73,6 +73,26 @@ export interface MemberResponse {
73
73
  * Id of the member's current role Verifiable Endorsement Credential, if issued.
74
74
  */
75
75
  currentRoleVecId?: string | null;
76
+ /**
77
+ * Whether the community has asserted that this member is a distinct real person. Read-only here: it is set and cleared by the personhood verbs, and cleared by a renewal-policy downgrade. Load-bearing rather than informational — a community that recognises members of another community may gate on it, so a consumer that cannot read it cannot make that decision.
78
+ */
79
+ personhood?: boolean;
80
+ /**
81
+ * When personhood was most recently asserted. Absent where it never has been. Operator-facing: it belongs on admin-gated reads, and a member's own view of themselves need carry only the flag.
82
+ */
83
+ personhoodAssertedAt?: string | null;
84
+ /**
85
+ * Whether this member joined by presenting an invitation credential rather than by an admin's decision on an open request. The two routes to membership carry different evidence, and an operator reviewing a roster can otherwise not tell them apart.
86
+ */
87
+ joinedViaInvitation?: boolean;
88
+ /**
89
+ * `id` of the member-issued reciprocal membership credential — the member half of the pair — once the member has sent it. Absent until then, which is the useful signal: it distinguishes a membership the community has asserted from one the member has acknowledged. The credential body is not echoed here.
90
+ */
91
+ memberVmcId?: string | null;
92
+ /**
93
+ * When that reciprocal credential was received. Paired with `memberVmcId`.
94
+ */
95
+ memberVmcReceivedAt?: string | null;
76
96
  /**
77
97
  * Opaque community-defined extension bag. Keys are maintainer-defined; the maintainer caps its size (16 KiB in the reference implementation).
78
98
  */
@@ -242,6 +262,37 @@ export const PAYLOAD_SCHEMA = {
242
262
  ],
243
263
  "description": "Id of the member's current role Verifiable Endorsement Credential, if issued."
244
264
  },
265
+ "personhood": {
266
+ "type": "boolean",
267
+ "description": "Whether the community has asserted that this member is a distinct real person. Read-only here: it is set and cleared by the personhood verbs, and cleared by a renewal-policy downgrade. Load-bearing rather than informational — a community that recognises members of another community may gate on it, so a consumer that cannot read it cannot make that decision."
268
+ },
269
+ "personhoodAssertedAt": {
270
+ "type": [
271
+ "string",
272
+ "null"
273
+ ],
274
+ "format": "date-time",
275
+ "description": "When personhood was most recently asserted. Absent where it never has been. Operator-facing: it belongs on admin-gated reads, and a member's own view of themselves need carry only the flag."
276
+ },
277
+ "joinedViaInvitation": {
278
+ "type": "boolean",
279
+ "description": "Whether this member joined by presenting an invitation credential rather than by an admin's decision on an open request. The two routes to membership carry different evidence, and an operator reviewing a roster can otherwise not tell them apart."
280
+ },
281
+ "memberVmcId": {
282
+ "type": [
283
+ "string",
284
+ "null"
285
+ ],
286
+ "description": "`id` of the member-issued reciprocal membership credential — the member half of the pair — once the member has sent it. Absent until then, which is the useful signal: it distinguishes a membership the community has asserted from one the member has acknowledged. The credential body is not echoed here."
287
+ },
288
+ "memberVmcReceivedAt": {
289
+ "type": [
290
+ "string",
291
+ "null"
292
+ ],
293
+ "format": "date-time",
294
+ "description": "When that reciprocal credential was received. Paired with `memberVmcId`."
295
+ },
245
296
  "extensions": {
246
297
  "type": "object",
247
298
  "description": "Opaque community-defined extension bag. Keys are maintainer-defined; the maintainer caps its size (16 KiB in the reference implementation)."
@@ -371,6 +422,37 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
371
422
  ],
372
423
  "description": "Id of the member's current role Verifiable Endorsement Credential, if issued."
373
424
  },
425
+ "personhood": {
426
+ "type": "boolean",
427
+ "description": "Whether the community has asserted that this member is a distinct real person. Read-only here: it is set and cleared by the personhood verbs, and cleared by a renewal-policy downgrade. Load-bearing rather than informational — a community that recognises members of another community may gate on it, so a consumer that cannot read it cannot make that decision."
428
+ },
429
+ "personhoodAssertedAt": {
430
+ "type": [
431
+ "string",
432
+ "null"
433
+ ],
434
+ "format": "date-time",
435
+ "description": "When personhood was most recently asserted. Absent where it never has been. Operator-facing: it belongs on admin-gated reads, and a member's own view of themselves need carry only the flag."
436
+ },
437
+ "joinedViaInvitation": {
438
+ "type": "boolean",
439
+ "description": "Whether this member joined by presenting an invitation credential rather than by an admin's decision on an open request. The two routes to membership carry different evidence, and an operator reviewing a roster can otherwise not tell them apart."
440
+ },
441
+ "memberVmcId": {
442
+ "type": [
443
+ "string",
444
+ "null"
445
+ ],
446
+ "description": "`id` of the member-issued reciprocal membership credential — the member half of the pair — once the member has sent it. Absent until then, which is the useful signal: it distinguishes a membership the community has asserted from one the member has acknowledged. The credential body is not echoed here."
447
+ },
448
+ "memberVmcReceivedAt": {
449
+ "type": [
450
+ "string",
451
+ "null"
452
+ ],
453
+ "format": "date-time",
454
+ "description": "When that reciprocal credential was received. Paired with `memberVmcId`."
455
+ },
374
456
  "extensions": {
375
457
  "type": "object",
376
458
  "description": "Opaque community-defined extension bag. Keys are maintainer-defined; the maintainer caps its size (16 KiB in the reference implementation)."
@@ -57,6 +57,26 @@ export interface MemberResponse {
57
57
  * Id of the member's current role Verifiable Endorsement Credential, if issued.
58
58
  */
59
59
  currentRoleVecId?: string | null;
60
+ /**
61
+ * Whether the community has asserted that this member is a distinct real person. Read-only here: it is set and cleared by the personhood verbs, and cleared by a renewal-policy downgrade. Load-bearing rather than informational — a community that recognises members of another community may gate on it, so a consumer that cannot read it cannot make that decision.
62
+ */
63
+ personhood?: boolean;
64
+ /**
65
+ * When personhood was most recently asserted. Absent where it never has been. Operator-facing: it belongs on admin-gated reads, and a member's own view of themselves need carry only the flag.
66
+ */
67
+ personhoodAssertedAt?: string | null;
68
+ /**
69
+ * Whether this member joined by presenting an invitation credential rather than by an admin's decision on an open request. The two routes to membership carry different evidence, and an operator reviewing a roster can otherwise not tell them apart.
70
+ */
71
+ joinedViaInvitation?: boolean;
72
+ /**
73
+ * `id` of the member-issued reciprocal membership credential — the member half of the pair — once the member has sent it. Absent until then, which is the useful signal: it distinguishes a membership the community has asserted from one the member has acknowledged. The credential body is not echoed here.
74
+ */
75
+ memberVmcId?: string | null;
76
+ /**
77
+ * When that reciprocal credential was received. Paired with `memberVmcId`.
78
+ */
79
+ memberVmcReceivedAt?: string | null;
60
80
  /**
61
81
  * Opaque community-defined extension bag. Keys are maintainer-defined; the maintainer caps its size (16 KiB in the reference implementation).
62
82
  */
@@ -202,6 +222,37 @@ export const PAYLOAD_SCHEMA = {
202
222
  ],
203
223
  "description": "Id of the member's current role Verifiable Endorsement Credential, if issued."
204
224
  },
225
+ "personhood": {
226
+ "type": "boolean",
227
+ "description": "Whether the community has asserted that this member is a distinct real person. Read-only here: it is set and cleared by the personhood verbs, and cleared by a renewal-policy downgrade. Load-bearing rather than informational — a community that recognises members of another community may gate on it, so a consumer that cannot read it cannot make that decision."
228
+ },
229
+ "personhoodAssertedAt": {
230
+ "type": [
231
+ "string",
232
+ "null"
233
+ ],
234
+ "format": "date-time",
235
+ "description": "When personhood was most recently asserted. Absent where it never has been. Operator-facing: it belongs on admin-gated reads, and a member's own view of themselves need carry only the flag."
236
+ },
237
+ "joinedViaInvitation": {
238
+ "type": "boolean",
239
+ "description": "Whether this member joined by presenting an invitation credential rather than by an admin's decision on an open request. The two routes to membership carry different evidence, and an operator reviewing a roster can otherwise not tell them apart."
240
+ },
241
+ "memberVmcId": {
242
+ "type": [
243
+ "string",
244
+ "null"
245
+ ],
246
+ "description": "`id` of the member-issued reciprocal membership credential — the member half of the pair — once the member has sent it. Absent until then, which is the useful signal: it distinguishes a membership the community has asserted from one the member has acknowledged. The credential body is not echoed here."
247
+ },
248
+ "memberVmcReceivedAt": {
249
+ "type": [
250
+ "string",
251
+ "null"
252
+ ],
253
+ "format": "date-time",
254
+ "description": "When that reciprocal credential was received. Paired with `memberVmcId`."
255
+ },
205
256
  "extensions": {
206
257
  "type": "object",
207
258
  "description": "Opaque community-defined extension bag. Keys are maintainer-defined; the maintainer caps its size (16 KiB in the reference implementation)."
@@ -314,6 +365,37 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
314
365
  ],
315
366
  "description": "Id of the member's current role Verifiable Endorsement Credential, if issued."
316
367
  },
368
+ "personhood": {
369
+ "type": "boolean",
370
+ "description": "Whether the community has asserted that this member is a distinct real person. Read-only here: it is set and cleared by the personhood verbs, and cleared by a renewal-policy downgrade. Load-bearing rather than informational — a community that recognises members of another community may gate on it, so a consumer that cannot read it cannot make that decision."
371
+ },
372
+ "personhoodAssertedAt": {
373
+ "type": [
374
+ "string",
375
+ "null"
376
+ ],
377
+ "format": "date-time",
378
+ "description": "When personhood was most recently asserted. Absent where it never has been. Operator-facing: it belongs on admin-gated reads, and a member's own view of themselves need carry only the flag."
379
+ },
380
+ "joinedViaInvitation": {
381
+ "type": "boolean",
382
+ "description": "Whether this member joined by presenting an invitation credential rather than by an admin's decision on an open request. The two routes to membership carry different evidence, and an operator reviewing a roster can otherwise not tell them apart."
383
+ },
384
+ "memberVmcId": {
385
+ "type": [
386
+ "string",
387
+ "null"
388
+ ],
389
+ "description": "`id` of the member-issued reciprocal membership credential — the member half of the pair — once the member has sent it. Absent until then, which is the useful signal: it distinguishes a membership the community has asserted from one the member has acknowledged. The credential body is not echoed here."
390
+ },
391
+ "memberVmcReceivedAt": {
392
+ "type": [
393
+ "string",
394
+ "null"
395
+ ],
396
+ "format": "date-time",
397
+ "description": "When that reciprocal credential was received. Paired with `memberVmcId`."
398
+ },
317
399
  "extensions": {
318
400
  "type": "object",
319
401
  "description": "Opaque community-defined extension bag. Keys are maintainer-defined; the maintainer caps its size (16 KiB in the reference implementation)."
@@ -12,6 +12,10 @@ export interface VTCMembersUpdatePayload {
12
12
  * New role (wire form). MUST NOT be `admin` — promotion to admin is a separate, gated flow, not a metadata patch.
13
13
  */
14
14
  role?: string;
15
+ /**
16
+ * Operator-facing display label for this member. Editable, unlike the DID it labels — which is the point: an operator needs a name they can read on a roster of identifiers they cannot. `null` clears it; omit to leave it unchanged.
17
+ */
18
+ label?: string | null;
15
19
  /**
16
20
  * New directory-publish consent.
17
21
  */
@@ -70,6 +74,26 @@ export interface MemberResponse {
70
74
  * Id of the member's current role Verifiable Endorsement Credential, if issued.
71
75
  */
72
76
  currentRoleVecId?: string | null;
77
+ /**
78
+ * Whether the community has asserted that this member is a distinct real person. Read-only here: it is set and cleared by the personhood verbs, and cleared by a renewal-policy downgrade. Load-bearing rather than informational — a community that recognises members of another community may gate on it, so a consumer that cannot read it cannot make that decision.
79
+ */
80
+ personhood?: boolean;
81
+ /**
82
+ * When personhood was most recently asserted. Absent where it never has been. Operator-facing: it belongs on admin-gated reads, and a member's own view of themselves need carry only the flag.
83
+ */
84
+ personhoodAssertedAt?: string | null;
85
+ /**
86
+ * Whether this member joined by presenting an invitation credential rather than by an admin's decision on an open request. The two routes to membership carry different evidence, and an operator reviewing a roster can otherwise not tell them apart.
87
+ */
88
+ joinedViaInvitation?: boolean;
89
+ /**
90
+ * `id` of the member-issued reciprocal membership credential — the member half of the pair — once the member has sent it. Absent until then, which is the useful signal: it distinguishes a membership the community has asserted from one the member has acknowledged. The credential body is not echoed here.
91
+ */
92
+ memberVmcId?: string | null;
93
+ /**
94
+ * When that reciprocal credential was received. Paired with `memberVmcId`.
95
+ */
96
+ memberVmcReceivedAt?: string | null;
73
97
  /**
74
98
  * Opaque community-defined extension bag. Keys are maintainer-defined; the maintainer caps its size (16 KiB in the reference implementation).
75
99
  */
@@ -117,6 +141,13 @@ export const PAYLOAD_SCHEMA = {
117
141
  "minLength": 1,
118
142
  "description": "New role (wire form). MUST NOT be `admin` — promotion to admin is a separate, gated flow, not a metadata patch."
119
143
  },
144
+ "label": {
145
+ "type": [
146
+ "string",
147
+ "null"
148
+ ],
149
+ "description": "Operator-facing display label for this member. Editable, unlike the DID it labels — which is the point: an operator needs a name they can read on a roster of identifiers they cannot. `null` clears it; omit to leave it unchanged."
150
+ },
120
151
  "publishConsent": {
121
152
  "type": "boolean",
122
153
  "description": "New directory-publish consent."
@@ -237,6 +268,37 @@ export const PAYLOAD_SCHEMA = {
237
268
  ],
238
269
  "description": "Id of the member's current role Verifiable Endorsement Credential, if issued."
239
270
  },
271
+ "personhood": {
272
+ "type": "boolean",
273
+ "description": "Whether the community has asserted that this member is a distinct real person. Read-only here: it is set and cleared by the personhood verbs, and cleared by a renewal-policy downgrade. Load-bearing rather than informational — a community that recognises members of another community may gate on it, so a consumer that cannot read it cannot make that decision."
274
+ },
275
+ "personhoodAssertedAt": {
276
+ "type": [
277
+ "string",
278
+ "null"
279
+ ],
280
+ "format": "date-time",
281
+ "description": "When personhood was most recently asserted. Absent where it never has been. Operator-facing: it belongs on admin-gated reads, and a member's own view of themselves need carry only the flag."
282
+ },
283
+ "joinedViaInvitation": {
284
+ "type": "boolean",
285
+ "description": "Whether this member joined by presenting an invitation credential rather than by an admin's decision on an open request. The two routes to membership carry different evidence, and an operator reviewing a roster can otherwise not tell them apart."
286
+ },
287
+ "memberVmcId": {
288
+ "type": [
289
+ "string",
290
+ "null"
291
+ ],
292
+ "description": "`id` of the member-issued reciprocal membership credential — the member half of the pair — once the member has sent it. Absent until then, which is the useful signal: it distinguishes a membership the community has asserted from one the member has acknowledged. The credential body is not echoed here."
293
+ },
294
+ "memberVmcReceivedAt": {
295
+ "type": [
296
+ "string",
297
+ "null"
298
+ ],
299
+ "format": "date-time",
300
+ "description": "When that reciprocal credential was received. Paired with `memberVmcId`."
301
+ },
240
302
  "extensions": {
241
303
  "type": "object",
242
304
  "description": "Opaque community-defined extension bag. Keys are maintainer-defined; the maintainer caps its size (16 KiB in the reference implementation)."
@@ -349,6 +411,37 @@ export const RESPONSE_PAYLOAD_SCHEMA = {
349
411
  ],
350
412
  "description": "Id of the member's current role Verifiable Endorsement Credential, if issued."
351
413
  },
414
+ "personhood": {
415
+ "type": "boolean",
416
+ "description": "Whether the community has asserted that this member is a distinct real person. Read-only here: it is set and cleared by the personhood verbs, and cleared by a renewal-policy downgrade. Load-bearing rather than informational — a community that recognises members of another community may gate on it, so a consumer that cannot read it cannot make that decision."
417
+ },
418
+ "personhoodAssertedAt": {
419
+ "type": [
420
+ "string",
421
+ "null"
422
+ ],
423
+ "format": "date-time",
424
+ "description": "When personhood was most recently asserted. Absent where it never has been. Operator-facing: it belongs on admin-gated reads, and a member's own view of themselves need carry only the flag."
425
+ },
426
+ "joinedViaInvitation": {
427
+ "type": "boolean",
428
+ "description": "Whether this member joined by presenting an invitation credential rather than by an admin's decision on an open request. The two routes to membership carry different evidence, and an operator reviewing a roster can otherwise not tell them apart."
429
+ },
430
+ "memberVmcId": {
431
+ "type": [
432
+ "string",
433
+ "null"
434
+ ],
435
+ "description": "`id` of the member-issued reciprocal membership credential — the member half of the pair — once the member has sent it. Absent until then, which is the useful signal: it distinguishes a membership the community has asserted from one the member has acknowledged. The credential body is not echoed here."
436
+ },
437
+ "memberVmcReceivedAt": {
438
+ "type": [
439
+ "string",
440
+ "null"
441
+ ],
442
+ "format": "date-time",
443
+ "description": "When that reciprocal credential was received. Paired with `memberVmcId`."
444
+ },
352
445
  "extensions": {
353
446
  "type": "object",
354
447
  "description": "Opaque community-defined extension bag. Keys are maintainer-defined; the maintainer caps its size (16 KiB in the reference implementation)."