1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//! Member-side membership-credential exchange (`members/*`).
//!
//! Membership between a persona DID and a VTC is a **pair of VMCs**: the VTC
//! issues a `MembershipCredential` to the member at admission
//! (community → member), and the member issues one back to the VTC
//! (member → community), so each side holds a credential asserting the other's
//! membership edge. This family carries the **full reciprocal VMC** and lets
//! it be (re)exchanged at any point — at join time with
//! [`MemberVmcBody::request_id`] set (which also closes the approved join
//! request; the retired `join-requests/accept` semantics), or unprompted /
//! on request later:
//!
//! - [`MEMBER_REQUEST_VMC_TYPE`] — VTC → member: "please issue + send your VMC".
//! Admin-triggered from the VTC; delivered over DIDComm to the member's agent.
//! - [`MEMBER_VMC_TYPE`] — member → VTC: the member-issued VMC (a Data-Integrity
//! VC whose `issuer` is the member and whose `credentialSubject.id` is the
//! community DID). The VTC verifies the proof + binding and stores it.
//! - [`MEMBER_VMC_RESPONSE_TYPE`] — VTC → member: a receipt acknowledging the
//! stored VMC.
use ;
use Value;
/// The `type` array tag a member-issued membership credential must carry
/// (alongside `VerifiableCredential`). Same credential type the VTC issues for
/// its half of the pair — the direction is given by `issuer` /
/// `credentialSubject.id`, not the type.
///
/// The canonical DTG tag, exactly as `dtg-credentials` emits it
/// (`DTGCredentialType::Membership`) and as the VTC's own issuance stamps it.
///
/// The name previously carried a `VERIFIABLE_` prefix that the *value* never
/// had. That gap is not cosmetic: it is how
/// `"VerifiableEndorsementCredential"` came to be hand-rolled into the
/// recognition path, where it matched nothing any VTC issues and silently
/// broke cross-community recognition for every real presentation
/// (OpenVTC/verifiable-trust-infrastructure#1062). A constant whose name
/// disagrees with its value invites exactly that.
pub const MEMBERSHIP_CREDENTIAL_TYPE: &str = "MembershipCredential";
/// Wire `type` tag of a VEC, per DTG Credentials §VEC.
///
/// Sibling of [`MEMBERSHIP_CREDENTIAL_TYPE`], and here for the same reason:
/// the recognition path had this one as a bare literal, spelled wrongly, with
/// nothing to compare it against.
pub const ENDORSEMENT_CREDENTIAL_TYPE: &str = "EndorsementCredential";
/// VTC → member: request that the member issue and send their reciprocal VMC.
pub const MEMBER_REQUEST_VMC_TYPE: &str = "https://trusttasks.org/spec/vtc/members/request-vmc/0.1";
/// Member → VTC: a member-issued [`MEMBERSHIP_CREDENTIAL_TYPE`] VMC,
/// the member → community half of the membership pair.
pub const MEMBER_VMC_TYPE: &str = "https://trusttasks.org/spec/vtc/members/vmc/0.1";
/// VTC → member: receipt acknowledging a stored member VMC. The `#response`
/// variant of [`MEMBER_VMC_TYPE`].
pub const MEMBER_VMC_RESPONSE_TYPE: &str =
"https://trusttasks.org/spec/vtc/members/vmc/0.1#response";
/// VTC → member: **unsolicited** notice that the community removed them.
///
/// Distinct from the self-remove receipt
/// ([`crate::protocols::join_requests::MEMBER_SELF_REMOVE_RECEIPT_TYPE`]) in the
/// way that matters: a receipt answers a request the member made and is
/// correlated to it, so the member is already waiting for it. This answers
/// nothing — the member did not ask, is not waiting, and may be offline. Sending
/// one for a member-initiated departure would tell somebody who chose to leave
/// that they were removed.
pub const MEMBER_REMOVAL_NOTICE_TYPE: &str =
"https://trusttasks.org/spec/vtc/members/removal-notice/0.1";
/// Which removal happened, as carried in [`RemovalNoticeBody::code`].
///
/// Two variants rather than one `removed` flag because they differ in what
/// recourse the member has: an administrator's removal ran the community's
/// removal policy, a super-administrator's purge deliberately skipped it.
/// Body of a [`MEMBER_REMOVAL_NOTICE_TYPE`] notice.
///
/// Every field except `reason` is required, because a notice that omits any of
/// them fails to answer one of the questions a removed member has: what
/// happened, to what, when, and on whose say-so.
/// Body of a [`MEMBER_REQUEST_VMC_TYPE`] request. The member should issue a VMC
/// whose `credentialSubject.id` is `community_did` and send it back as a
/// [`MEMBER_VMC_TYPE`] message.
/// Body of a [`MEMBER_VMC_TYPE`] submission: the member-issued VMC verbatim.
/// `vc.issuer` is the member DID (the authcrypt sender / DI-proof signer) and
/// `vc.credentialSubject.id` is the community DID.
/// Body of a [`MEMBER_VMC_RESPONSE_TYPE`] receipt.