@oxyhq/crowdsource-contracts 0.1.0
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/README.md +129 -0
- package/dist/case-envelope.d.ts +1130 -0
- package/dist/case-envelope.d.ts.map +1 -0
- package/dist/case-envelope.js +383 -0
- package/dist/case-envelope.js.map +1 -0
- package/dist/decisions.d.ts +353 -0
- package/dist/decisions.d.ts.map +1 -0
- package/dist/decisions.js +198 -0
- package/dist/decisions.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/json-schema.d.ts +43 -0
- package/dist/json-schema.d.ts.map +1 -0
- package/dist/json-schema.js +83 -0
- package/dist/json-schema.js.map +1 -0
- package/dist/policies.d.ts +286 -0
- package/dist/policies.d.ts.map +1 -0
- package/dist/policies.js +178 -0
- package/dist/policies.js.map +1 -0
- package/dist/primitives.d.ts +185 -0
- package/dist/primitives.d.ts.map +1 -0
- package/dist/primitives.js +231 -0
- package/dist/primitives.js.map +1 -0
- package/dist/reputation-events.d.ts +349 -0
- package/dist/reputation-events.d.ts.map +1 -0
- package/dist/reputation-events.js +128 -0
- package/dist/reputation-events.js.map +1 -0
- package/dist/resources.d.ts +484 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +436 -0
- package/dist/resources.js.map +1 -0
- package/dist/reviews.d.ts +276 -0
- package/dist/reviews.d.ts.map +1 -0
- package/dist/reviews.js +144 -0
- package/dist/reviews.js.map +1 -0
- package/dist/taxonomy.d.ts +266 -0
- package/dist/taxonomy.d.ts.map +1 -0
- package/dist/taxonomy.js +282 -0
- package/dist/taxonomy.js.map +1 -0
- package/dist/webhooks.d.ts +604 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +192 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +56 -0
- package/src/case-envelope.ts +433 -0
- package/src/decisions.ts +216 -0
- package/src/index.ts +45 -0
- package/src/json-schema.ts +89 -0
- package/src/policies.ts +203 -0
- package/src/primitives.ts +283 -0
- package/src/reputation-events.ts +144 -0
- package/src/resources.ts +489 -0
- package/src/reviews.ts +159 -0
- package/src/taxonomy.ts +313 -0
- package/src/webhooks.ts +215 -0
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The internal reputation event (§11.5, §11.6, §11.7).
|
|
3
|
+
*
|
|
4
|
+
* This is the only thing CrowdSource ever sends toward Oxy Trust, and it is a
|
|
5
|
+
* statement, not an instruction. "CrowdSource does not write to reputation
|
|
6
|
+
* collections. It publishes an authenticated internal event" (§11.5), and Oxy
|
|
7
|
+
* Trust's own consequence engine decides what, if anything, follows. Nothing in
|
|
8
|
+
* this payload names points, a tier, a strike or a standing: an application —
|
|
9
|
+
* and CrowdSource on its behalf — never chooses an Oxy reputation figure.
|
|
10
|
+
*
|
|
11
|
+
* Three of §11.7's eight pre-effect validations are structural, and all three
|
|
12
|
+
* are moved into the type rather than left to a runtime check that a future
|
|
13
|
+
* refactor can drop:
|
|
14
|
+
*
|
|
15
|
+
* * §11.7.4 — `subject.bindingProofId` is required. "No binding proof, no Oxy
|
|
16
|
+
* Trust effect" becomes an event that cannot be constructed.
|
|
17
|
+
* * §11.7.5 — a finding's scope must be `oxy_network` or `identity_integrity`.
|
|
18
|
+
* `application_local` cannot appear here at all, which is §6.5's rule that
|
|
19
|
+
* a local restriction does not become a global sanction, enforced at the
|
|
20
|
+
* wire rather than by the receiver's diligence.
|
|
21
|
+
* * §11.7.8 — the decision may not be superseded or corrected, so the status
|
|
22
|
+
* enum has only the two values that may carry an effect (§11.7.3).
|
|
23
|
+
*
|
|
24
|
+
* The remaining five are stateful — who signed it, whether this event was seen
|
|
25
|
+
* before, whether the incident already produced an equivalent effect — and stay
|
|
26
|
+
* with the bridge.
|
|
27
|
+
*
|
|
28
|
+
* This is the one payload in the package that is `.strict()` in the OUTBOUND
|
|
29
|
+
* direction. §10.11's rule about unknown fields has an explicit exception for
|
|
30
|
+
* "where the schema forbids them for safety", and this is that case twice over:
|
|
31
|
+
* a finding here deliberately carries no `resourceIds` and no free text, so
|
|
32
|
+
* that nothing about the reviewed material reaches a reputation ledger or a
|
|
33
|
+
* signed attestation, and an unrecognised field is exactly how that would
|
|
34
|
+
* happen. Forward compatibility is handled by the `.v1` in the event type.
|
|
35
|
+
*/
|
|
36
|
+
import { z } from 'zod';
|
|
37
|
+
/**
|
|
38
|
+
* §11.6 names one event type. §11.5 names four bridge operations — apply,
|
|
39
|
+
* finalize, reverse, reconcile — so siblings are expected, but the plan does
|
|
40
|
+
* not write them and they are not invented here. Adding one is additive: a new
|
|
41
|
+
* literal and a new variant, with the `.v1` suffix carrying the version.
|
|
42
|
+
*/
|
|
43
|
+
export declare const MODERATION_DECISION_FINALIZED_EVENT_TYPE = "moderation.decision.finalized.v1";
|
|
44
|
+
/**
|
|
45
|
+
* §11.7.3 and §11.7.8 together: an effect may follow a final decision or,
|
|
46
|
+
* where policy allows, a provisional one — and never a superseded or corrected
|
|
47
|
+
* one. Those two states are absent from this enum rather than rejected by a
|
|
48
|
+
* refinement, so the impossibility is visible in the type.
|
|
49
|
+
*/
|
|
50
|
+
export declare const REPUTATION_EVENT_DECISION_STATUSES: readonly ["provisional", "final"];
|
|
51
|
+
export declare const ReputationEventDecisionStatusSchema: z.ZodEnum<{
|
|
52
|
+
provisional: "provisional";
|
|
53
|
+
final: "final";
|
|
54
|
+
}>;
|
|
55
|
+
export type ReputationEventDecisionStatus = z.infer<typeof ReputationEventDecisionStatusSchema>;
|
|
56
|
+
/**
|
|
57
|
+
* Who the effect would land on (§11.6 `subject`).
|
|
58
|
+
*
|
|
59
|
+
* `bindingProofId` is required, unconditionally — see §11.7.4 above. The
|
|
60
|
+
* envelope's `principalBindings` make the same proof optional for non-Oxy
|
|
61
|
+
* principal types, because those can never reach this event; here there is
|
|
62
|
+
* nothing to be lenient about.
|
|
63
|
+
*/
|
|
64
|
+
export declare const ReputationEventSubjectSchema: z.ZodObject<{
|
|
65
|
+
principalType: z.ZodEnum<{
|
|
66
|
+
oxy_user: "oxy_user";
|
|
67
|
+
local_user: "local_user";
|
|
68
|
+
organization: "organization";
|
|
69
|
+
bot: "bot";
|
|
70
|
+
federated_actor: "federated_actor";
|
|
71
|
+
}>;
|
|
72
|
+
principalId: z.ZodString;
|
|
73
|
+
bindingProofId: z.ZodString;
|
|
74
|
+
}, z.core.$strict>;
|
|
75
|
+
export type ReputationEventSubject = z.infer<typeof ReputationEventSubjectSchema>;
|
|
76
|
+
/**
|
|
77
|
+
* A finding as Oxy Trust sees it (§11.6).
|
|
78
|
+
*
|
|
79
|
+
* Deliberately narrower than a `DecisionFinding`: no `resourceIds`, no policy
|
|
80
|
+
* rule ids, no text. Oxy Trust needs to know what was confirmed, how serious it
|
|
81
|
+
* was, how far it reaches and whose conduct it was — it does not need to know
|
|
82
|
+
* which piece of content it happened on, and §13.5's minimisation plus the
|
|
83
|
+
* invariant that sensitive content never appears in logs or public attestations
|
|
84
|
+
* mean it must not be told.
|
|
85
|
+
*
|
|
86
|
+
* `attribution` is required here where it is optional on a decision finding: an
|
|
87
|
+
* effect must land on somebody, and a finding that attributes nothing has
|
|
88
|
+
* nothing to contribute to this event.
|
|
89
|
+
*/
|
|
90
|
+
export declare const ReputationEventFindingSchema: z.ZodObject<{
|
|
91
|
+
code: z.ZodEnum<{
|
|
92
|
+
"integrity.spam": "integrity.spam";
|
|
93
|
+
"integrity.scam": "integrity.scam";
|
|
94
|
+
"integrity.fraud": "integrity.fraud";
|
|
95
|
+
"integrity.impersonation": "integrity.impersonation";
|
|
96
|
+
"integrity.coordinated_manipulation": "integrity.coordinated_manipulation";
|
|
97
|
+
"harassment.insult": "harassment.insult";
|
|
98
|
+
"harassment.targeted_abuse": "harassment.targeted_abuse";
|
|
99
|
+
"harassment.sexual_harassment": "harassment.sexual_harassment";
|
|
100
|
+
"harassment.doxxing": "harassment.doxxing";
|
|
101
|
+
"harassment.credible_threat": "harassment.credible_threat";
|
|
102
|
+
"hate.dehumanization": "hate.dehumanization";
|
|
103
|
+
"hate.slur": "hate.slur";
|
|
104
|
+
"hate.incitement": "hate.incitement";
|
|
105
|
+
"hate.protected_targeting": "hate.protected_targeting";
|
|
106
|
+
"violence.graphic": "violence.graphic";
|
|
107
|
+
"violence.threat": "violence.threat";
|
|
108
|
+
"violence.instruction": "violence.instruction";
|
|
109
|
+
"violence.celebration": "violence.celebration";
|
|
110
|
+
"sexual_content.nudity": "sexual_content.nudity";
|
|
111
|
+
"sexual_content.explicit_activity": "sexual_content.explicit_activity";
|
|
112
|
+
"sexual_content.non_consensual": "sexual_content.non_consensual";
|
|
113
|
+
"sexual_content.exploitation": "sexual_content.exploitation";
|
|
114
|
+
"child_safety.sexualization": "child_safety.sexualization";
|
|
115
|
+
"child_safety.grooming": "child_safety.grooming";
|
|
116
|
+
"child_safety.exploitation": "child_safety.exploitation";
|
|
117
|
+
"self_harm.promotion": "self_harm.promotion";
|
|
118
|
+
"self_harm.instruction": "self_harm.instruction";
|
|
119
|
+
"self_harm.imminent_risk": "self_harm.imminent_risk";
|
|
120
|
+
"privacy.personal_information": "privacy.personal_information";
|
|
121
|
+
"privacy.intimate_media": "privacy.intimate_media";
|
|
122
|
+
"privacy.location_exposure": "privacy.location_exposure";
|
|
123
|
+
"commerce.prohibited_item": "commerce.prohibited_item";
|
|
124
|
+
"commerce.counterfeit": "commerce.counterfeit";
|
|
125
|
+
"commerce.misleading_listing": "commerce.misleading_listing";
|
|
126
|
+
"commerce.unsafe_product": "commerce.unsafe_product";
|
|
127
|
+
"platform_abuse.ban_evasion": "platform_abuse.ban_evasion";
|
|
128
|
+
"platform_abuse.report_abuse": "platform_abuse.report_abuse";
|
|
129
|
+
"platform_abuse.automation_abuse": "platform_abuse.automation_abuse";
|
|
130
|
+
"other.policy_specific": "other.policy_specific";
|
|
131
|
+
"other.unclassifiable": "other.unclassifiable";
|
|
132
|
+
}>;
|
|
133
|
+
severity: z.ZodEnum<{
|
|
134
|
+
low: "low";
|
|
135
|
+
medium: "medium";
|
|
136
|
+
high: "high";
|
|
137
|
+
critical: "critical";
|
|
138
|
+
}>;
|
|
139
|
+
scope: z.ZodEnum<{
|
|
140
|
+
oxy_network: "oxy_network";
|
|
141
|
+
identity_integrity: "identity_integrity";
|
|
142
|
+
}>;
|
|
143
|
+
attribution: z.ZodEnum<{
|
|
144
|
+
author: "author";
|
|
145
|
+
reporter: "reporter";
|
|
146
|
+
reviewer: "reviewer";
|
|
147
|
+
}>;
|
|
148
|
+
}, z.core.$strict>;
|
|
149
|
+
export type ReputationEventFinding = z.infer<typeof ReputationEventFindingSchema>;
|
|
150
|
+
/**
|
|
151
|
+
* `moderation.decision.finalized.v1` (§11.6).
|
|
152
|
+
*
|
|
153
|
+
* `incidentId` is what makes "one penalty per incident" enforceable: it is the
|
|
154
|
+
* first component of the effect's idempotency key (Appendix D:
|
|
155
|
+
* `incidentId + principalId + effectType + decisionRevision`), so the same
|
|
156
|
+
* incident reaching the bridge twice — from a replay, from a redelivery, from
|
|
157
|
+
* two cases that were merged — produces one effect.
|
|
158
|
+
*
|
|
159
|
+
* `proofHash` binds the event to the decision it reports, so an effect can be
|
|
160
|
+
* explained and, if the decision is later corrected, reversed against the exact
|
|
161
|
+
* revision that caused it.
|
|
162
|
+
*/
|
|
163
|
+
export declare const ModerationDecisionFinalizedEventSchema: z.ZodObject<{
|
|
164
|
+
eventId: z.ZodString;
|
|
165
|
+
type: z.ZodLiteral<"moderation.decision.finalized.v1">;
|
|
166
|
+
caseId: z.ZodString;
|
|
167
|
+
incidentId: z.ZodString;
|
|
168
|
+
decisionId: z.ZodString;
|
|
169
|
+
decisionRevision: z.ZodNumber;
|
|
170
|
+
applicationId: z.ZodString;
|
|
171
|
+
subject: z.ZodObject<{
|
|
172
|
+
principalType: z.ZodEnum<{
|
|
173
|
+
oxy_user: "oxy_user";
|
|
174
|
+
local_user: "local_user";
|
|
175
|
+
organization: "organization";
|
|
176
|
+
bot: "bot";
|
|
177
|
+
federated_actor: "federated_actor";
|
|
178
|
+
}>;
|
|
179
|
+
principalId: z.ZodString;
|
|
180
|
+
bindingProofId: z.ZodString;
|
|
181
|
+
}, z.core.$strict>;
|
|
182
|
+
findings: z.ZodArray<z.ZodObject<{
|
|
183
|
+
code: z.ZodEnum<{
|
|
184
|
+
"integrity.spam": "integrity.spam";
|
|
185
|
+
"integrity.scam": "integrity.scam";
|
|
186
|
+
"integrity.fraud": "integrity.fraud";
|
|
187
|
+
"integrity.impersonation": "integrity.impersonation";
|
|
188
|
+
"integrity.coordinated_manipulation": "integrity.coordinated_manipulation";
|
|
189
|
+
"harassment.insult": "harassment.insult";
|
|
190
|
+
"harassment.targeted_abuse": "harassment.targeted_abuse";
|
|
191
|
+
"harassment.sexual_harassment": "harassment.sexual_harassment";
|
|
192
|
+
"harassment.doxxing": "harassment.doxxing";
|
|
193
|
+
"harassment.credible_threat": "harassment.credible_threat";
|
|
194
|
+
"hate.dehumanization": "hate.dehumanization";
|
|
195
|
+
"hate.slur": "hate.slur";
|
|
196
|
+
"hate.incitement": "hate.incitement";
|
|
197
|
+
"hate.protected_targeting": "hate.protected_targeting";
|
|
198
|
+
"violence.graphic": "violence.graphic";
|
|
199
|
+
"violence.threat": "violence.threat";
|
|
200
|
+
"violence.instruction": "violence.instruction";
|
|
201
|
+
"violence.celebration": "violence.celebration";
|
|
202
|
+
"sexual_content.nudity": "sexual_content.nudity";
|
|
203
|
+
"sexual_content.explicit_activity": "sexual_content.explicit_activity";
|
|
204
|
+
"sexual_content.non_consensual": "sexual_content.non_consensual";
|
|
205
|
+
"sexual_content.exploitation": "sexual_content.exploitation";
|
|
206
|
+
"child_safety.sexualization": "child_safety.sexualization";
|
|
207
|
+
"child_safety.grooming": "child_safety.grooming";
|
|
208
|
+
"child_safety.exploitation": "child_safety.exploitation";
|
|
209
|
+
"self_harm.promotion": "self_harm.promotion";
|
|
210
|
+
"self_harm.instruction": "self_harm.instruction";
|
|
211
|
+
"self_harm.imminent_risk": "self_harm.imminent_risk";
|
|
212
|
+
"privacy.personal_information": "privacy.personal_information";
|
|
213
|
+
"privacy.intimate_media": "privacy.intimate_media";
|
|
214
|
+
"privacy.location_exposure": "privacy.location_exposure";
|
|
215
|
+
"commerce.prohibited_item": "commerce.prohibited_item";
|
|
216
|
+
"commerce.counterfeit": "commerce.counterfeit";
|
|
217
|
+
"commerce.misleading_listing": "commerce.misleading_listing";
|
|
218
|
+
"commerce.unsafe_product": "commerce.unsafe_product";
|
|
219
|
+
"platform_abuse.ban_evasion": "platform_abuse.ban_evasion";
|
|
220
|
+
"platform_abuse.report_abuse": "platform_abuse.report_abuse";
|
|
221
|
+
"platform_abuse.automation_abuse": "platform_abuse.automation_abuse";
|
|
222
|
+
"other.policy_specific": "other.policy_specific";
|
|
223
|
+
"other.unclassifiable": "other.unclassifiable";
|
|
224
|
+
}>;
|
|
225
|
+
severity: z.ZodEnum<{
|
|
226
|
+
low: "low";
|
|
227
|
+
medium: "medium";
|
|
228
|
+
high: "high";
|
|
229
|
+
critical: "critical";
|
|
230
|
+
}>;
|
|
231
|
+
scope: z.ZodEnum<{
|
|
232
|
+
oxy_network: "oxy_network";
|
|
233
|
+
identity_integrity: "identity_integrity";
|
|
234
|
+
}>;
|
|
235
|
+
attribution: z.ZodEnum<{
|
|
236
|
+
author: "author";
|
|
237
|
+
reporter: "reporter";
|
|
238
|
+
reviewer: "reviewer";
|
|
239
|
+
}>;
|
|
240
|
+
}, z.core.$strict>>;
|
|
241
|
+
decisionStatus: z.ZodEnum<{
|
|
242
|
+
provisional: "provisional";
|
|
243
|
+
final: "final";
|
|
244
|
+
}>;
|
|
245
|
+
policyVersions: z.ZodObject<{
|
|
246
|
+
universal: z.ZodString;
|
|
247
|
+
application: z.ZodString;
|
|
248
|
+
oxyConduct: z.ZodString;
|
|
249
|
+
}, z.core.$strict>;
|
|
250
|
+
proofHash: z.ZodString;
|
|
251
|
+
}, z.core.$strict>;
|
|
252
|
+
export type ModerationDecisionFinalizedEvent = z.infer<typeof ModerationDecisionFinalizedEventSchema>;
|
|
253
|
+
/**
|
|
254
|
+
* Every reputation event CrowdSource emits.
|
|
255
|
+
*
|
|
256
|
+
* A union of one today. It exists so consumers switch on `type` from the start
|
|
257
|
+
* and adding §11.5's remaining operations does not change how they are written.
|
|
258
|
+
*/
|
|
259
|
+
export declare const ReputationEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
260
|
+
eventId: z.ZodString;
|
|
261
|
+
type: z.ZodLiteral<"moderation.decision.finalized.v1">;
|
|
262
|
+
caseId: z.ZodString;
|
|
263
|
+
incidentId: z.ZodString;
|
|
264
|
+
decisionId: z.ZodString;
|
|
265
|
+
decisionRevision: z.ZodNumber;
|
|
266
|
+
applicationId: z.ZodString;
|
|
267
|
+
subject: z.ZodObject<{
|
|
268
|
+
principalType: z.ZodEnum<{
|
|
269
|
+
oxy_user: "oxy_user";
|
|
270
|
+
local_user: "local_user";
|
|
271
|
+
organization: "organization";
|
|
272
|
+
bot: "bot";
|
|
273
|
+
federated_actor: "federated_actor";
|
|
274
|
+
}>;
|
|
275
|
+
principalId: z.ZodString;
|
|
276
|
+
bindingProofId: z.ZodString;
|
|
277
|
+
}, z.core.$strict>;
|
|
278
|
+
findings: z.ZodArray<z.ZodObject<{
|
|
279
|
+
code: z.ZodEnum<{
|
|
280
|
+
"integrity.spam": "integrity.spam";
|
|
281
|
+
"integrity.scam": "integrity.scam";
|
|
282
|
+
"integrity.fraud": "integrity.fraud";
|
|
283
|
+
"integrity.impersonation": "integrity.impersonation";
|
|
284
|
+
"integrity.coordinated_manipulation": "integrity.coordinated_manipulation";
|
|
285
|
+
"harassment.insult": "harassment.insult";
|
|
286
|
+
"harassment.targeted_abuse": "harassment.targeted_abuse";
|
|
287
|
+
"harassment.sexual_harassment": "harassment.sexual_harassment";
|
|
288
|
+
"harassment.doxxing": "harassment.doxxing";
|
|
289
|
+
"harassment.credible_threat": "harassment.credible_threat";
|
|
290
|
+
"hate.dehumanization": "hate.dehumanization";
|
|
291
|
+
"hate.slur": "hate.slur";
|
|
292
|
+
"hate.incitement": "hate.incitement";
|
|
293
|
+
"hate.protected_targeting": "hate.protected_targeting";
|
|
294
|
+
"violence.graphic": "violence.graphic";
|
|
295
|
+
"violence.threat": "violence.threat";
|
|
296
|
+
"violence.instruction": "violence.instruction";
|
|
297
|
+
"violence.celebration": "violence.celebration";
|
|
298
|
+
"sexual_content.nudity": "sexual_content.nudity";
|
|
299
|
+
"sexual_content.explicit_activity": "sexual_content.explicit_activity";
|
|
300
|
+
"sexual_content.non_consensual": "sexual_content.non_consensual";
|
|
301
|
+
"sexual_content.exploitation": "sexual_content.exploitation";
|
|
302
|
+
"child_safety.sexualization": "child_safety.sexualization";
|
|
303
|
+
"child_safety.grooming": "child_safety.grooming";
|
|
304
|
+
"child_safety.exploitation": "child_safety.exploitation";
|
|
305
|
+
"self_harm.promotion": "self_harm.promotion";
|
|
306
|
+
"self_harm.instruction": "self_harm.instruction";
|
|
307
|
+
"self_harm.imminent_risk": "self_harm.imminent_risk";
|
|
308
|
+
"privacy.personal_information": "privacy.personal_information";
|
|
309
|
+
"privacy.intimate_media": "privacy.intimate_media";
|
|
310
|
+
"privacy.location_exposure": "privacy.location_exposure";
|
|
311
|
+
"commerce.prohibited_item": "commerce.prohibited_item";
|
|
312
|
+
"commerce.counterfeit": "commerce.counterfeit";
|
|
313
|
+
"commerce.misleading_listing": "commerce.misleading_listing";
|
|
314
|
+
"commerce.unsafe_product": "commerce.unsafe_product";
|
|
315
|
+
"platform_abuse.ban_evasion": "platform_abuse.ban_evasion";
|
|
316
|
+
"platform_abuse.report_abuse": "platform_abuse.report_abuse";
|
|
317
|
+
"platform_abuse.automation_abuse": "platform_abuse.automation_abuse";
|
|
318
|
+
"other.policy_specific": "other.policy_specific";
|
|
319
|
+
"other.unclassifiable": "other.unclassifiable";
|
|
320
|
+
}>;
|
|
321
|
+
severity: z.ZodEnum<{
|
|
322
|
+
low: "low";
|
|
323
|
+
medium: "medium";
|
|
324
|
+
high: "high";
|
|
325
|
+
critical: "critical";
|
|
326
|
+
}>;
|
|
327
|
+
scope: z.ZodEnum<{
|
|
328
|
+
oxy_network: "oxy_network";
|
|
329
|
+
identity_integrity: "identity_integrity";
|
|
330
|
+
}>;
|
|
331
|
+
attribution: z.ZodEnum<{
|
|
332
|
+
author: "author";
|
|
333
|
+
reporter: "reporter";
|
|
334
|
+
reviewer: "reviewer";
|
|
335
|
+
}>;
|
|
336
|
+
}, z.core.$strict>>;
|
|
337
|
+
decisionStatus: z.ZodEnum<{
|
|
338
|
+
provisional: "provisional";
|
|
339
|
+
final: "final";
|
|
340
|
+
}>;
|
|
341
|
+
policyVersions: z.ZodObject<{
|
|
342
|
+
universal: z.ZodString;
|
|
343
|
+
application: z.ZodString;
|
|
344
|
+
oxyConduct: z.ZodString;
|
|
345
|
+
}, z.core.$strict>;
|
|
346
|
+
proofHash: z.ZodString;
|
|
347
|
+
}, z.core.$strict>], "type">;
|
|
348
|
+
export type ReputationEvent = z.infer<typeof ReputationEventSchema>;
|
|
349
|
+
//# sourceMappingURL=reputation-events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reputation-events.d.ts","sourceRoot":"","sources":["../src/reputation-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB;;;;;GAKG;AACH,eAAO,MAAM,wCAAwC,qCAAqC,CAAC;AAE3F;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,mCAAoC,CAAC;AACpF,eAAO,MAAM,mCAAmC;;;EAA6C,CAAC;AAC9F,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAEhG;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B;;;;;;;;;;kBAIvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAKvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAajD,CAAC;AACH,MAAM,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CACpD,OAAO,sCAAsC,CAC9C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAEhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The internal reputation event (§11.5, §11.6, §11.7).
|
|
4
|
+
*
|
|
5
|
+
* This is the only thing CrowdSource ever sends toward Oxy Trust, and it is a
|
|
6
|
+
* statement, not an instruction. "CrowdSource does not write to reputation
|
|
7
|
+
* collections. It publishes an authenticated internal event" (§11.5), and Oxy
|
|
8
|
+
* Trust's own consequence engine decides what, if anything, follows. Nothing in
|
|
9
|
+
* this payload names points, a tier, a strike or a standing: an application —
|
|
10
|
+
* and CrowdSource on its behalf — never chooses an Oxy reputation figure.
|
|
11
|
+
*
|
|
12
|
+
* Three of §11.7's eight pre-effect validations are structural, and all three
|
|
13
|
+
* are moved into the type rather than left to a runtime check that a future
|
|
14
|
+
* refactor can drop:
|
|
15
|
+
*
|
|
16
|
+
* * §11.7.4 — `subject.bindingProofId` is required. "No binding proof, no Oxy
|
|
17
|
+
* Trust effect" becomes an event that cannot be constructed.
|
|
18
|
+
* * §11.7.5 — a finding's scope must be `oxy_network` or `identity_integrity`.
|
|
19
|
+
* `application_local` cannot appear here at all, which is §6.5's rule that
|
|
20
|
+
* a local restriction does not become a global sanction, enforced at the
|
|
21
|
+
* wire rather than by the receiver's diligence.
|
|
22
|
+
* * §11.7.8 — the decision may not be superseded or corrected, so the status
|
|
23
|
+
* enum has only the two values that may carry an effect (§11.7.3).
|
|
24
|
+
*
|
|
25
|
+
* The remaining five are stateful — who signed it, whether this event was seen
|
|
26
|
+
* before, whether the incident already produced an equivalent effect — and stay
|
|
27
|
+
* with the bridge.
|
|
28
|
+
*
|
|
29
|
+
* This is the one payload in the package that is `.strict()` in the OUTBOUND
|
|
30
|
+
* direction. §10.11's rule about unknown fields has an explicit exception for
|
|
31
|
+
* "where the schema forbids them for safety", and this is that case twice over:
|
|
32
|
+
* a finding here deliberately carries no `resourceIds` and no free text, so
|
|
33
|
+
* that nothing about the reviewed material reaches a reputation ledger or a
|
|
34
|
+
* signed attestation, and an unrecognised field is exactly how that would
|
|
35
|
+
* happen. Forward compatibility is handled by the `.v1` in the event type.
|
|
36
|
+
*/
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.ReputationEventSchema = exports.ModerationDecisionFinalizedEventSchema = exports.ReputationEventFindingSchema = exports.ReputationEventSubjectSchema = exports.ReputationEventDecisionStatusSchema = exports.REPUTATION_EVENT_DECISION_STATUSES = exports.MODERATION_DECISION_FINALIZED_EVENT_TYPE = void 0;
|
|
39
|
+
const zod_1 = require("zod");
|
|
40
|
+
const primitives_1 = require("./primitives");
|
|
41
|
+
const case_envelope_1 = require("./case-envelope");
|
|
42
|
+
const policies_1 = require("./policies");
|
|
43
|
+
const taxonomy_1 = require("./taxonomy");
|
|
44
|
+
/**
|
|
45
|
+
* §11.6 names one event type. §11.5 names four bridge operations — apply,
|
|
46
|
+
* finalize, reverse, reconcile — so siblings are expected, but the plan does
|
|
47
|
+
* not write them and they are not invented here. Adding one is additive: a new
|
|
48
|
+
* literal and a new variant, with the `.v1` suffix carrying the version.
|
|
49
|
+
*/
|
|
50
|
+
exports.MODERATION_DECISION_FINALIZED_EVENT_TYPE = 'moderation.decision.finalized.v1';
|
|
51
|
+
/**
|
|
52
|
+
* §11.7.3 and §11.7.8 together: an effect may follow a final decision or,
|
|
53
|
+
* where policy allows, a provisional one — and never a superseded or corrected
|
|
54
|
+
* one. Those two states are absent from this enum rather than rejected by a
|
|
55
|
+
* refinement, so the impossibility is visible in the type.
|
|
56
|
+
*/
|
|
57
|
+
exports.REPUTATION_EVENT_DECISION_STATUSES = ['provisional', 'final'];
|
|
58
|
+
exports.ReputationEventDecisionStatusSchema = zod_1.z.enum(exports.REPUTATION_EVENT_DECISION_STATUSES);
|
|
59
|
+
/**
|
|
60
|
+
* Who the effect would land on (§11.6 `subject`).
|
|
61
|
+
*
|
|
62
|
+
* `bindingProofId` is required, unconditionally — see §11.7.4 above. The
|
|
63
|
+
* envelope's `principalBindings` make the same proof optional for non-Oxy
|
|
64
|
+
* principal types, because those can never reach this event; here there is
|
|
65
|
+
* nothing to be lenient about.
|
|
66
|
+
*/
|
|
67
|
+
exports.ReputationEventSubjectSchema = zod_1.z.strictObject({
|
|
68
|
+
principalType: case_envelope_1.PrincipalTypeSchema,
|
|
69
|
+
principalId: primitives_1.IdentifierSchema,
|
|
70
|
+
bindingProofId: primitives_1.IdentifierSchema,
|
|
71
|
+
});
|
|
72
|
+
/**
|
|
73
|
+
* A finding as Oxy Trust sees it (§11.6).
|
|
74
|
+
*
|
|
75
|
+
* Deliberately narrower than a `DecisionFinding`: no `resourceIds`, no policy
|
|
76
|
+
* rule ids, no text. Oxy Trust needs to know what was confirmed, how serious it
|
|
77
|
+
* was, how far it reaches and whose conduct it was — it does not need to know
|
|
78
|
+
* which piece of content it happened on, and §13.5's minimisation plus the
|
|
79
|
+
* invariant that sensitive content never appears in logs or public attestations
|
|
80
|
+
* mean it must not be told.
|
|
81
|
+
*
|
|
82
|
+
* `attribution` is required here where it is optional on a decision finding: an
|
|
83
|
+
* effect must land on somebody, and a finding that attributes nothing has
|
|
84
|
+
* nothing to contribute to this event.
|
|
85
|
+
*/
|
|
86
|
+
exports.ReputationEventFindingSchema = zod_1.z.strictObject({
|
|
87
|
+
code: taxonomy_1.TaxonomyCodeSchema,
|
|
88
|
+
severity: taxonomy_1.SeveritySchema,
|
|
89
|
+
scope: taxonomy_1.ReputationEligibleFindingScopeSchema,
|
|
90
|
+
attribution: taxonomy_1.FindingAttributionSchema,
|
|
91
|
+
});
|
|
92
|
+
/**
|
|
93
|
+
* `moderation.decision.finalized.v1` (§11.6).
|
|
94
|
+
*
|
|
95
|
+
* `incidentId` is what makes "one penalty per incident" enforceable: it is the
|
|
96
|
+
* first component of the effect's idempotency key (Appendix D:
|
|
97
|
+
* `incidentId + principalId + effectType + decisionRevision`), so the same
|
|
98
|
+
* incident reaching the bridge twice — from a replay, from a redelivery, from
|
|
99
|
+
* two cases that were merged — produces one effect.
|
|
100
|
+
*
|
|
101
|
+
* `proofHash` binds the event to the decision it reports, so an effect can be
|
|
102
|
+
* explained and, if the decision is later corrected, reversed against the exact
|
|
103
|
+
* revision that caused it.
|
|
104
|
+
*/
|
|
105
|
+
exports.ModerationDecisionFinalizedEventSchema = zod_1.z.strictObject({
|
|
106
|
+
eventId: primitives_1.IdentifierSchema,
|
|
107
|
+
type: zod_1.z.literal(exports.MODERATION_DECISION_FINALIZED_EVENT_TYPE),
|
|
108
|
+
caseId: primitives_1.IdentifierSchema,
|
|
109
|
+
incidentId: primitives_1.IdentifierSchema,
|
|
110
|
+
decisionId: primitives_1.IdentifierSchema,
|
|
111
|
+
decisionRevision: zod_1.z.number().int().positive(),
|
|
112
|
+
applicationId: primitives_1.IdentifierSchema,
|
|
113
|
+
subject: exports.ReputationEventSubjectSchema,
|
|
114
|
+
findings: zod_1.z.array(exports.ReputationEventFindingSchema).min(1).max(primitives_1.CONTRACT_LIMITS.FINDINGS_MAX),
|
|
115
|
+
decisionStatus: exports.ReputationEventDecisionStatusSchema,
|
|
116
|
+
policyVersions: policies_1.ReputationPolicyVersionsSchema,
|
|
117
|
+
proofHash: primitives_1.Sha256DigestSchema,
|
|
118
|
+
});
|
|
119
|
+
/**
|
|
120
|
+
* Every reputation event CrowdSource emits.
|
|
121
|
+
*
|
|
122
|
+
* A union of one today. It exists so consumers switch on `type` from the start
|
|
123
|
+
* and adding §11.5's remaining operations does not change how they are written.
|
|
124
|
+
*/
|
|
125
|
+
exports.ReputationEventSchema = zod_1.z.discriminatedUnion('type', [
|
|
126
|
+
exports.ModerationDecisionFinalizedEventSchema,
|
|
127
|
+
]);
|
|
128
|
+
//# sourceMappingURL=reputation-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reputation-events.js","sourceRoot":"","sources":["../src/reputation-events.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;;;AAEH,6BAAwB;AAExB,6CAAqF;AACrF,mDAAsD;AACtD,yCAA4D;AAC5D,yCAKoB;AAEpB;;;;;GAKG;AACU,QAAA,wCAAwC,GAAG,kCAAkC,CAAC;AAE3F;;;;;GAKG;AACU,QAAA,kCAAkC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAU,CAAC;AACvE,QAAA,mCAAmC,GAAG,OAAC,CAAC,IAAI,CAAC,0CAAkC,CAAC,CAAC;AAG9F;;;;;;;GAOG;AACU,QAAA,4BAA4B,GAAG,OAAC,CAAC,YAAY,CAAC;IACzD,aAAa,EAAE,mCAAmB;IAClC,WAAW,EAAE,6BAAgB;IAC7B,cAAc,EAAE,6BAAgB;CACjC,CAAC,CAAC;AAGH;;;;;;;;;;;;;GAaG;AACU,QAAA,4BAA4B,GAAG,OAAC,CAAC,YAAY,CAAC;IACzD,IAAI,EAAE,6BAAkB;IACxB,QAAQ,EAAE,yBAAc;IACxB,KAAK,EAAE,+CAAoC;IAC3C,WAAW,EAAE,mCAAwB;CACtC,CAAC,CAAC;AAGH;;;;;;;;;;;;GAYG;AACU,QAAA,sCAAsC,GAAG,OAAC,CAAC,YAAY,CAAC;IACnE,OAAO,EAAE,6BAAgB;IACzB,IAAI,EAAE,OAAC,CAAC,OAAO,CAAC,gDAAwC,CAAC;IACzD,MAAM,EAAE,6BAAgB;IACxB,UAAU,EAAE,6BAAgB;IAC5B,UAAU,EAAE,6BAAgB;IAC5B,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC7C,aAAa,EAAE,6BAAgB;IAC/B,OAAO,EAAE,oCAA4B;IACrC,QAAQ,EAAE,OAAC,CAAC,KAAK,CAAC,oCAA4B,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,4BAAe,CAAC,YAAY,CAAC;IACxF,cAAc,EAAE,2CAAmC;IACnD,cAAc,EAAE,yCAA8B;IAC9C,SAAS,EAAE,+BAAkB;CAC9B,CAAC,CAAC;AAKH;;;;;GAKG;AACU,QAAA,qBAAqB,GAAG,OAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAChE,8CAAsC;CACvC,CAAC,CAAC"}
|