@oxyhq/contracts 0.20.0 → 0.22.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/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/accountGraph.js +80 -3
- package/dist/cjs/index.js +69 -4
- package/dist/cjs/moderationReputation.js +298 -0
- package/dist/cjs/reputation.js +15 -3
- package/dist/cjs/userInvalidation.js +89 -0
- package/dist/cjs/userResponse.js +21 -1
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/accountGraph.js +77 -2
- package/dist/esm/index.js +13 -1
- package/dist/esm/moderationReputation.js +295 -0
- package/dist/esm/reputation.js +15 -3
- package/dist/esm/userInvalidation.js +85 -0
- package/dist/esm/userResponse.js +22 -2
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/accountGraph.d.ts +77 -6
- package/dist/types/index.d.ts +6 -2
- package/dist/types/moderationReputation.d.ts +487 -0
- package/dist/types/recommendations.d.ts +14 -14
- package/dist/types/reputation.d.ts +16 -0
- package/dist/types/userInvalidation.d.ts +94 -0
- package/dist/types/userResponse.d.ts +278 -28
- package/package.json +1 -1
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Oxy Trust — the moderation reputation bridge (CrowdSource → Oxy Trust).
|
|
3
|
+
*
|
|
4
|
+
* SINGLE SOURCE OF TRUTH for the wire shapes crossing the one-way boundary
|
|
5
|
+
* between a participatory-moderation service and the Oxy reputation ledger.
|
|
6
|
+
*
|
|
7
|
+
* The direction is not negotiable: a moderation service NEVER writes reputation.
|
|
8
|
+
* It emits an authenticated internal event describing a decision it published,
|
|
9
|
+
* and Oxy's own consequence engine validates that event and derives the effect.
|
|
10
|
+
* Everything in this module is therefore either (a) the event, (b) the receipt
|
|
11
|
+
* the engine returns, or (c) the derived state the engine publishes back to the
|
|
12
|
+
* subject.
|
|
13
|
+
*
|
|
14
|
+
* Design anchors, all load-bearing:
|
|
15
|
+
*
|
|
16
|
+
* - **Conduct is a separate axis from contribution.** A conduct penalty raises
|
|
17
|
+
* `activeRisk` and creates a strike; positive contribution points can never
|
|
18
|
+
* cancel a strike, because standing is derived from active risk and not from
|
|
19
|
+
* the point total. See {@link ReputationConduct}.
|
|
20
|
+
* - **The reporting axis carries only reporting signals.** `abuseScore` on the
|
|
21
|
+
* legacy reliability block conflated rejected reports with every negative
|
|
22
|
+
* transaction; {@link ReputationReporting} exists so a conduct penalty can
|
|
23
|
+
* never inflate a report-abuse figure.
|
|
24
|
+
* - **No binding proof, no effect.** {@link ModerationDecisionEventSubject}
|
|
25
|
+
* requires a `bindingProofId`, and the engine rejects an event whose binding
|
|
26
|
+
* does not resolve to the claimed principal at or before `occurredAt`. An
|
|
27
|
+
* application cannot move a reputation figure by naming a user id.
|
|
28
|
+
* - **One penalty per incident.** The idempotency key is
|
|
29
|
+
* `moderation:<incidentId>:<decisionRevision>:<effectType>`; a hundred
|
|
30
|
+
* reports about the same material produce one effect.
|
|
31
|
+
* - **Every effect carries the policy version it was decided under**, so a
|
|
32
|
+
* consequence can be recomputed under the original policy rather than under
|
|
33
|
+
* whatever the current tuning happens to be.
|
|
34
|
+
*
|
|
35
|
+
* Platform-agnostic — zod only. ESM-safe (no `require()`).
|
|
36
|
+
*/
|
|
37
|
+
import { z } from 'zod';
|
|
38
|
+
/**
|
|
39
|
+
* Severity band of a moderation finding, lowest → highest.
|
|
40
|
+
*
|
|
41
|
+
* The band — not the taxonomy code — is what the consequence engine consumes:
|
|
42
|
+
* points, active risk and expiry are all keyed by severity in the versioned
|
|
43
|
+
* conduct policy, so a new taxonomy code needs no engine change and no
|
|
44
|
+
* intimate category ever reaches the ledger.
|
|
45
|
+
*/
|
|
46
|
+
export declare const MODERATION_SEVERITIES: readonly ["low", "medium", "high", "critical"];
|
|
47
|
+
export type ModerationSeverity = (typeof MODERATION_SEVERITIES)[number];
|
|
48
|
+
export declare const moderationSeveritySchema: z.ZodEnum<["low", "medium", "high", "critical"]>;
|
|
49
|
+
/**
|
|
50
|
+
* How far a finding reaches.
|
|
51
|
+
*
|
|
52
|
+
* - `application_local` — the application enforces locally; Oxy Trust is NOT
|
|
53
|
+
* touched. Emitted for completeness; the engine rejects the effect.
|
|
54
|
+
* - `oxy_network` — conduct against the Oxy network as a whole.
|
|
55
|
+
* - `identity_integrity` — impersonation, sybil behaviour, credential abuse.
|
|
56
|
+
*
|
|
57
|
+
* Only `oxy_network` and `identity_integrity` can produce a global effect.
|
|
58
|
+
*/
|
|
59
|
+
export declare const MODERATION_FINDING_SCOPES: readonly ["application_local", "oxy_network", "identity_integrity"];
|
|
60
|
+
export type ModerationFindingScope = (typeof MODERATION_FINDING_SCOPES)[number];
|
|
61
|
+
export declare const moderationFindingScopeSchema: z.ZodEnum<["application_local", "oxy_network", "identity_integrity"]>;
|
|
62
|
+
/** Which participant in the reported material the finding attributes to. */
|
|
63
|
+
export declare const MODERATION_ATTRIBUTIONS: readonly ["author", "sharer", "reporter", "reviewer"];
|
|
64
|
+
export type ModerationAttribution = (typeof MODERATION_ATTRIBUTIONS)[number];
|
|
65
|
+
export declare const moderationAttributionSchema: z.ZodEnum<["author", "sharer", "reporter", "reviewer"]>;
|
|
66
|
+
/**
|
|
67
|
+
* Lifecycle of the decision the event describes.
|
|
68
|
+
*
|
|
69
|
+
* `inconclusive` is its own outcome and never collapses into "no violation";
|
|
70
|
+
* it simply produces no effect. `superseded` and `corrected` describe a
|
|
71
|
+
* revision that a later one replaced — an event in either state is rejected,
|
|
72
|
+
* because applying it would resurrect a consequence the appeal removed.
|
|
73
|
+
*/
|
|
74
|
+
export declare const MODERATION_DECISION_STATUSES: readonly ["provisional", "final", "inconclusive", "superseded", "corrected"];
|
|
75
|
+
export type ModerationDecisionStatus = (typeof MODERATION_DECISION_STATUSES)[number];
|
|
76
|
+
export declare const moderationDecisionStatusSchema: z.ZodEnum<["provisional", "final", "inconclusive", "superseded", "corrected"]>;
|
|
77
|
+
/**
|
|
78
|
+
* The kind of consequence an effect carries. Each is its own axis, and the
|
|
79
|
+
* idempotency key includes it — one incident may legitimately produce a conduct
|
|
80
|
+
* effect for the author AND a report-abuse effect for a malicious reporter.
|
|
81
|
+
*/
|
|
82
|
+
export declare const MODERATION_EFFECT_TYPES: readonly ["conduct_penalty", "report_abuse_penalty", "review_abuse_penalty"];
|
|
83
|
+
export type ModerationEffectType = (typeof MODERATION_EFFECT_TYPES)[number];
|
|
84
|
+
export declare const moderationEffectTypeSchema: z.ZodEnum<["conduct_penalty", "report_abuse_penalty", "review_abuse_penalty"]>;
|
|
85
|
+
/** Lifecycle of a stored effect. */
|
|
86
|
+
export declare const MODERATION_EFFECT_STATUSES: readonly ["applied", "reversed"];
|
|
87
|
+
export type ModerationEffectStatus = (typeof MODERATION_EFFECT_STATUSES)[number];
|
|
88
|
+
export declare const moderationEffectStatusSchema: z.ZodEnum<["applied", "reversed"]>;
|
|
89
|
+
/** Lifecycle of a conduct strike. Only `active` strikes carry active risk. */
|
|
90
|
+
export declare const CONDUCT_STRIKE_STATUSES: readonly ["active", "expired", "reversed"];
|
|
91
|
+
export type ConductStrikeStatus = (typeof CONDUCT_STRIKE_STATUSES)[number];
|
|
92
|
+
export declare const conductStrikeStatusSchema: z.ZodEnum<["active", "expired", "reversed"]>;
|
|
93
|
+
/**
|
|
94
|
+
* Conduct standing, derived from ACTIVE RISK and nothing else.
|
|
95
|
+
*
|
|
96
|
+
* Deliberately independent of the point total: a person may hold a high
|
|
97
|
+
* contribution tier and a `limited` standing at the same time, and earning
|
|
98
|
+
* points cannot move standing back toward `good`. Only expiry or reversal can.
|
|
99
|
+
*/
|
|
100
|
+
export declare const CONDUCT_STANDINGS: readonly ["good", "watch", "limited", "restricted"];
|
|
101
|
+
export type ConductStanding = (typeof CONDUCT_STANDINGS)[number];
|
|
102
|
+
export declare const conductStandingSchema: z.ZodEnum<["good", "watch", "limited", "restricted"]>;
|
|
103
|
+
/** Contribution tier, derived from contribution points only. */
|
|
104
|
+
export declare const CONTRIBUTION_TIERS: readonly ["new", "trusted", "high_trust"];
|
|
105
|
+
export type ContributionTier = (typeof CONTRIBUTION_TIERS)[number];
|
|
106
|
+
export declare const contributionTierSchema: z.ZodEnum<["new", "trusted", "high_trust"]>;
|
|
107
|
+
/** Personhood status. Being a real person proves neither conduct nor competence. */
|
|
108
|
+
export declare const PERSONHOOD_STATUSES: readonly ["unknown", "probable", "verified"];
|
|
109
|
+
export type PersonhoodStatusValue = (typeof PERSONHOOD_STATUSES)[number];
|
|
110
|
+
export declare const personhoodStatusSchema: z.ZodEnum<["unknown", "probable", "verified"]>;
|
|
111
|
+
/**
|
|
112
|
+
* How an Oxy identity was bound to the actor an application reported.
|
|
113
|
+
*
|
|
114
|
+
* - `oauth_grant` — the user authorized the application through Oxy's own
|
|
115
|
+
* OAuth flow. Oxy wrote the record; the application asserts nothing.
|
|
116
|
+
* - `session_proof` — the application presented the USER'S OWN Oxy access
|
|
117
|
+
* token alongside its service credential, proving the user was present in
|
|
118
|
+
* that application under a named local principal id.
|
|
119
|
+
* - `commons_signature` — a DID-verifiable signature over a server-issued nonce.
|
|
120
|
+
* - `federated_actor` — a resolvable, authorized federated actor link.
|
|
121
|
+
*/
|
|
122
|
+
export declare const IDENTITY_BINDING_TYPES: readonly ["oauth_grant", "session_proof", "commons_signature", "federated_actor"];
|
|
123
|
+
export type IdentityBindingType = (typeof IDENTITY_BINDING_TYPES)[number];
|
|
124
|
+
export declare const identityBindingTypeSchema: z.ZodEnum<["oauth_grant", "session_proof", "commons_signature", "federated_actor"]>;
|
|
125
|
+
/** Binding lifecycle. A revoked binding proves nothing about a later action. */
|
|
126
|
+
export declare const IDENTITY_BINDING_STATUSES: readonly ["active", "revoked"];
|
|
127
|
+
export type IdentityBindingStatus = (typeof IDENTITY_BINDING_STATUSES)[number];
|
|
128
|
+
export declare const identityBindingStatusSchema: z.ZodEnum<["active", "revoked"]>;
|
|
129
|
+
/**
|
|
130
|
+
* An application's own moderation standing. An external application can abuse
|
|
131
|
+
* the system too, so it carries standing exactly like a person does.
|
|
132
|
+
*
|
|
133
|
+
* `sandbox` applications moderate locally and produce NO global effect.
|
|
134
|
+
*/
|
|
135
|
+
export declare const APPLICATION_MODERATION_STANDINGS: readonly ["sandbox", "trusted", "restricted"];
|
|
136
|
+
export type ApplicationModerationStanding = (typeof APPLICATION_MODERATION_STANDINGS)[number];
|
|
137
|
+
export declare const applicationModerationStandingSchema: z.ZodEnum<["sandbox", "trusted", "restricted"]>;
|
|
138
|
+
/**
|
|
139
|
+
* Why the engine declined to apply an effect.
|
|
140
|
+
*
|
|
141
|
+
* Returned rather than thrown for the cases that are a legitimate outcome of a
|
|
142
|
+
* well-formed event (a sandboxed application, a local-only finding, an
|
|
143
|
+
* inconclusive decision): the emitter must be able to record "delivered, no
|
|
144
|
+
* effect" and stop retrying. Malformed or unauthorized events are HTTP errors,
|
|
145
|
+
* not skip reasons.
|
|
146
|
+
*/
|
|
147
|
+
export declare const MODERATION_EFFECT_SKIP_REASONS: readonly ["no_binding_proof", "binding_after_action", "binding_principal_mismatch", "binding_revoked", "decision_not_effective", "decision_superseded", "finding_scope_local", "finding_not_in_policy", "application_not_permitted", "no_effective_finding"];
|
|
148
|
+
export type ModerationEffectSkipReason = (typeof MODERATION_EFFECT_SKIP_REASONS)[number];
|
|
149
|
+
export declare const moderationEffectSkipReasonSchema: z.ZodEnum<["no_binding_proof", "binding_after_action", "binding_principal_mismatch", "binding_revoked", "decision_not_effective", "decision_superseded", "finding_scope_local", "finding_not_in_policy", "application_not_permitted", "no_effective_finding"]>;
|
|
150
|
+
/** One finding of a published decision. */
|
|
151
|
+
export interface ModerationFinding {
|
|
152
|
+
/** Taxonomy code, e.g. `harassment.targeted_abuse`. Never rendered publicly. */
|
|
153
|
+
code: string;
|
|
154
|
+
severity: ModerationSeverity;
|
|
155
|
+
scope: ModerationFindingScope;
|
|
156
|
+
attribution: ModerationAttribution;
|
|
157
|
+
/**
|
|
158
|
+
* Conduct family the code belongs to (e.g. `harassment`). Repetition is
|
|
159
|
+
* assessed per family and time window, so stacking taxonomy labels cannot
|
|
160
|
+
* manufacture a disproportionate sanction.
|
|
161
|
+
*/
|
|
162
|
+
family: string;
|
|
163
|
+
}
|
|
164
|
+
export declare const moderationFindingSchema: z.ZodType<ModerationFinding>;
|
|
165
|
+
/** The principal a decision is about, and the proof it is who the emitter says. */
|
|
166
|
+
export interface ModerationDecisionEventSubject {
|
|
167
|
+
/** Only `oxy_user` can carry a global reputation effect today. */
|
|
168
|
+
principalType: 'oxy_user';
|
|
169
|
+
/** The Oxy user id (or publicKey) the emitter claims the actor resolves to. */
|
|
170
|
+
principalId: string;
|
|
171
|
+
/**
|
|
172
|
+
* The identity binding that proves it. REQUIRED — an event without a
|
|
173
|
+
* resolvable binding produces no effect, by construction rather than by
|
|
174
|
+
* policy.
|
|
175
|
+
*/
|
|
176
|
+
bindingProofId: string;
|
|
177
|
+
}
|
|
178
|
+
export declare const moderationDecisionEventSubjectSchema: z.ZodType<ModerationDecisionEventSubject>;
|
|
179
|
+
/**
|
|
180
|
+
* The policy versions a decision was made under. All three are recorded on the
|
|
181
|
+
* effect so a consequence stays explainable after any of them moves on.
|
|
182
|
+
*/
|
|
183
|
+
export interface ModerationPolicyVersions {
|
|
184
|
+
/** The universal taxonomy version. */
|
|
185
|
+
universal: string;
|
|
186
|
+
/** The application's own policy version. */
|
|
187
|
+
application: string;
|
|
188
|
+
/** The Oxy conduct policy version the consequence engine must resolve. */
|
|
189
|
+
oxyConduct: string;
|
|
190
|
+
}
|
|
191
|
+
export declare const moderationPolicyVersionsSchema: z.ZodType<ModerationPolicyVersions>;
|
|
192
|
+
/**
|
|
193
|
+
* `POST /reputation/moderation/effects` — a decision a moderation service
|
|
194
|
+
* published, offered to Oxy Trust for consequence derivation.
|
|
195
|
+
*
|
|
196
|
+
* The emitter states a decision. It never states an effect: no points, no risk,
|
|
197
|
+
* no standing, no duration. Those are derived here from the policy version the
|
|
198
|
+
* decision names, which is what keeps the direction one-way.
|
|
199
|
+
*/
|
|
200
|
+
export interface ModerationDecisionEvent {
|
|
201
|
+
/** Emitter-unique event id. Replay of the same id is a no-op. */
|
|
202
|
+
eventId: string;
|
|
203
|
+
/**
|
|
204
|
+
* The application the reported action happened in — NOT the emitter.
|
|
205
|
+
*
|
|
206
|
+
* This is in the body, and the reason is worth stating because the sibling
|
|
207
|
+
* rule elsewhere is the opposite: at a moderation service's own ingress,
|
|
208
|
+
* `applicationId` must come from the credential, because a tenant choosing
|
|
209
|
+
* its own tenant id is an IDOR. Here the emitter is a privileged internal
|
|
210
|
+
* service reporting ON BEHALF OF an application, so it cannot be the
|
|
211
|
+
* credential's own id. What bounds it instead is that this field is checked
|
|
212
|
+
* against TWO independent gates the emitter does not control: the named
|
|
213
|
+
* application must itself be permitted to produce global effects, and the
|
|
214
|
+
* binding proof must be one the NAMED application holds for this person.
|
|
215
|
+
* Naming an application the subject never used therefore yields no effect.
|
|
216
|
+
*/
|
|
217
|
+
reportedApplicationId: string;
|
|
218
|
+
/** Event type + version, e.g. `moderation.decision.finalized.v1`. */
|
|
219
|
+
type: string;
|
|
220
|
+
caseId: string;
|
|
221
|
+
/**
|
|
222
|
+
* The cross-tenant incident the case belongs to. THE unit of consequence:
|
|
223
|
+
* one incident yields one effect per (principal, effect type, revision).
|
|
224
|
+
*/
|
|
225
|
+
incidentId: string;
|
|
226
|
+
decisionId: string;
|
|
227
|
+
/** 1-based revision. An appeal publishes revision 2, never edits revision 1. */
|
|
228
|
+
decisionRevision: number;
|
|
229
|
+
subject: ModerationDecisionEventSubject;
|
|
230
|
+
findings: ModerationFinding[];
|
|
231
|
+
decisionStatus: ModerationDecisionStatus;
|
|
232
|
+
policyVersions: ModerationPolicyVersions;
|
|
233
|
+
/**
|
|
234
|
+
* ISO 8601 time of the REPORTED ACTION (not of the decision). The binding
|
|
235
|
+
* must have existed at or before this instant, which is what makes the
|
|
236
|
+
* binding a proof of presence rather than an after-the-fact claim.
|
|
237
|
+
*/
|
|
238
|
+
occurredAt: string;
|
|
239
|
+
/**
|
|
240
|
+
* Hash of the private decision document. Recorded on the effect and in the
|
|
241
|
+
* attestation so provenance is verifiable without the decision's contents.
|
|
242
|
+
*/
|
|
243
|
+
proofHash: string;
|
|
244
|
+
}
|
|
245
|
+
export declare const moderationDecisionEventSchema: z.ZodType<ModerationDecisionEvent>;
|
|
246
|
+
/**
|
|
247
|
+
* Which decision revision an operation addresses. Deliberately the whole body of
|
|
248
|
+
* `POST /reputation/moderation/effects/finalize`: confirming that a consequence
|
|
249
|
+
* landed must not be able to carry a figure, or it would become a second write
|
|
250
|
+
* path into the ledger.
|
|
251
|
+
*/
|
|
252
|
+
export interface FinalizeModerationDecisionInput {
|
|
253
|
+
decisionId: string;
|
|
254
|
+
decisionRevision: number;
|
|
255
|
+
}
|
|
256
|
+
export declare const finalizeModerationDecisionSchema: z.ZodType<FinalizeModerationDecisionInput>;
|
|
257
|
+
/**
|
|
258
|
+
* `POST /reputation/moderation/effects/reverse` — an appeal overturned a
|
|
259
|
+
* decision revision, so the consequence it produced must be compensated.
|
|
260
|
+
*
|
|
261
|
+
* Names no figure either: the reversal is derived from the stored effect, so a
|
|
262
|
+
* caller cannot choose how much to give back.
|
|
263
|
+
*/
|
|
264
|
+
export interface ReverseModerationEffectInput extends FinalizeModerationDecisionInput {
|
|
265
|
+
/** Why the decision was overturned. Recorded on the reversal. */
|
|
266
|
+
reason: string;
|
|
267
|
+
}
|
|
268
|
+
export declare const reverseModerationEffectSchema: z.ZodType<ReverseModerationEffectInput>;
|
|
269
|
+
/**
|
|
270
|
+
* What the engine derived for one principal from one decision revision.
|
|
271
|
+
*
|
|
272
|
+
* `points` and `activeRisk` are already multiplied and capped; the multipliers
|
|
273
|
+
* are reported so the figure is explainable without re-running the engine.
|
|
274
|
+
*/
|
|
275
|
+
export interface ModerationEffect {
|
|
276
|
+
/** The effect's own id (its Mongo `_id` as a string). */
|
|
277
|
+
id: string;
|
|
278
|
+
incidentId: string;
|
|
279
|
+
caseId: string;
|
|
280
|
+
decisionId: string;
|
|
281
|
+
decisionRevision: number;
|
|
282
|
+
/** The Oxy user the effect landed on. */
|
|
283
|
+
principalId: string;
|
|
284
|
+
effectType: ModerationEffectType;
|
|
285
|
+
status: ModerationEffectStatus;
|
|
286
|
+
/** Signed point delta written to the ledger (negative for a penalty). */
|
|
287
|
+
points: number;
|
|
288
|
+
/** Active-risk delta added to conduct standing. */
|
|
289
|
+
activeRisk: number;
|
|
290
|
+
severity: ModerationSeverity;
|
|
291
|
+
/** Repetition multiplier applied (1.0 for a first similar incident). */
|
|
292
|
+
repetitionMultiplier: number;
|
|
293
|
+
/** Multi-finding multiplier applied, capped by the policy. */
|
|
294
|
+
multiFindingMultiplier: number;
|
|
295
|
+
/** The idempotency key the ledger transaction was written under. */
|
|
296
|
+
idempotencyKey: string;
|
|
297
|
+
/** The ledger transaction this effect created. */
|
|
298
|
+
transactionId: string;
|
|
299
|
+
/** The conduct strike this effect created, when the effect carries risk. */
|
|
300
|
+
strikeId?: string;
|
|
301
|
+
/** The compensating transaction, once reversed. */
|
|
302
|
+
reversalTransactionId?: string;
|
|
303
|
+
policyVersions: ModerationPolicyVersions;
|
|
304
|
+
/** ISO 8601 timestamp the effect was applied at. */
|
|
305
|
+
appliedAt: string;
|
|
306
|
+
/** ISO 8601 timestamp the effect was reversed at, if reversed. */
|
|
307
|
+
reversedAt?: string;
|
|
308
|
+
}
|
|
309
|
+
export declare const moderationEffectSchema: z.ZodType<ModerationEffect>;
|
|
310
|
+
/**
|
|
311
|
+
* The response to an event submission.
|
|
312
|
+
*
|
|
313
|
+
* `applied: false` with a `skipReason` is a SUCCESS: the event was accepted and
|
|
314
|
+
* durably recorded as producing no effect, so the emitter must not retry.
|
|
315
|
+
*/
|
|
316
|
+
export interface ApplyModerationDecisionResult {
|
|
317
|
+
/** Whether a consequence was derived. */
|
|
318
|
+
applied: boolean;
|
|
319
|
+
/** Present when `applied` is true. */
|
|
320
|
+
effect?: ModerationEffect;
|
|
321
|
+
/** Present when `applied` is false. */
|
|
322
|
+
skipReason?: ModerationEffectSkipReason;
|
|
323
|
+
/**
|
|
324
|
+
* True when this exact event (or an equivalent effect for the incident and
|
|
325
|
+
* revision) had already been processed, so nothing new was written.
|
|
326
|
+
*/
|
|
327
|
+
idempotent: boolean;
|
|
328
|
+
}
|
|
329
|
+
export declare const applyModerationDecisionResultSchema: z.ZodType<ApplyModerationDecisionResult>;
|
|
330
|
+
/** The response to a reversal. */
|
|
331
|
+
export interface ReverseModerationEffectResult {
|
|
332
|
+
/** Every effect the decision revision produced, now `reversed`. */
|
|
333
|
+
reversed: ModerationEffect[];
|
|
334
|
+
/** True when the effects were already reversed and nothing new was written. */
|
|
335
|
+
idempotent: boolean;
|
|
336
|
+
}
|
|
337
|
+
export declare const reverseModerationEffectResultSchema: z.ZodType<ReverseModerationEffectResult>;
|
|
338
|
+
/**
|
|
339
|
+
* `POST /reputation/moderation/bindings` — register the fact that an Oxy user
|
|
340
|
+
* was present in the calling application under a local principal id.
|
|
341
|
+
*
|
|
342
|
+
* The caller is a service credential AND must present the user's own Oxy access
|
|
343
|
+
* token in `userProofToken`: the binding is only as strong as the proof, and a
|
|
344
|
+
* body an application composes on its own is no proof at all. `applicationId`
|
|
345
|
+
* comes from the credential.
|
|
346
|
+
*/
|
|
347
|
+
export interface RegisterIdentityBindingInput {
|
|
348
|
+
/** The application's own id for this person. */
|
|
349
|
+
localPrincipalId: string;
|
|
350
|
+
/**
|
|
351
|
+
* The USER'S Oxy access token, proving they were signed in to the calling
|
|
352
|
+
* application. Verified server-side; its subject must be the bound user.
|
|
353
|
+
*/
|
|
354
|
+
userProofToken: string;
|
|
355
|
+
}
|
|
356
|
+
export declare const registerIdentityBindingSchema: z.ZodType<RegisterIdentityBindingInput>;
|
|
357
|
+
/**
|
|
358
|
+
* A registered binding, as returned to the application that registered it.
|
|
359
|
+
*
|
|
360
|
+
* Carries no proof material: the token is verified and discarded, never stored.
|
|
361
|
+
* `id` is what an event's `bindingProofId` references.
|
|
362
|
+
*/
|
|
363
|
+
export interface IdentityBinding {
|
|
364
|
+
id: string;
|
|
365
|
+
applicationId: string;
|
|
366
|
+
/** The bound Oxy user id. */
|
|
367
|
+
userId: string;
|
|
368
|
+
localPrincipalId: string;
|
|
369
|
+
bindingType: IdentityBindingType;
|
|
370
|
+
status: IdentityBindingStatus;
|
|
371
|
+
/** ISO 8601 timestamp the binding was verified at. */
|
|
372
|
+
verifiedAt: string;
|
|
373
|
+
/** ISO 8601 creation timestamp. */
|
|
374
|
+
createdAt: string;
|
|
375
|
+
}
|
|
376
|
+
export declare const identityBindingSchema: z.ZodType<IdentityBinding>;
|
|
377
|
+
/**
|
|
378
|
+
* Personhood: whether Oxy believes this is a real, distinct person.
|
|
379
|
+
*
|
|
380
|
+
* Deliberately NOT a trust tier. Being a real person proves neither good
|
|
381
|
+
* conduct nor moderation competence, so it is its own axis and confers nothing
|
|
382
|
+
* on the others.
|
|
383
|
+
*/
|
|
384
|
+
export interface ReputationPersonhood {
|
|
385
|
+
status: PersonhoodStatusValue;
|
|
386
|
+
/** 0..1 confidence in that status. */
|
|
387
|
+
score: number;
|
|
388
|
+
}
|
|
389
|
+
export declare const reputationPersonhoodSchema: z.ZodType<ReputationPersonhood>;
|
|
390
|
+
/**
|
|
391
|
+
* Contribution: what the person has built. Positive-only ladder.
|
|
392
|
+
*
|
|
393
|
+
* `points` EXCLUDES conduct penalties — they live on the conduct axis. Their
|
|
394
|
+
* ledger entries still count toward the legacy `total`, so the ledger stays
|
|
395
|
+
* honest, but they neither lower the contribution tier nor can be offset by it.
|
|
396
|
+
*/
|
|
397
|
+
export interface ReputationContribution {
|
|
398
|
+
points: number;
|
|
399
|
+
tier: ContributionTier;
|
|
400
|
+
}
|
|
401
|
+
export declare const reputationContributionSchema: z.ZodType<ReputationContribution>;
|
|
402
|
+
/**
|
|
403
|
+
* Conduct: the standing that moderation outcomes move.
|
|
404
|
+
*
|
|
405
|
+
* `activeRisk` is the sum of risk carried by ACTIVE strikes; it decays as
|
|
406
|
+
* strikes expire and drops immediately when one is reversed. `standing` is
|
|
407
|
+
* derived from `activeRisk` alone, which is precisely why contribution points
|
|
408
|
+
* cannot buy it back.
|
|
409
|
+
*/
|
|
410
|
+
export interface ReputationConduct {
|
|
411
|
+
standing: ConductStanding;
|
|
412
|
+
activeRisk: number;
|
|
413
|
+
activeStrikes: number;
|
|
414
|
+
/**
|
|
415
|
+
* ISO 8601 timestamp the earliest-expiring active strike lapses at. Absent
|
|
416
|
+
* when there is no active strike, or when every one of them requires manual
|
|
417
|
+
* recovery review (critical severity never expires automatically).
|
|
418
|
+
*/
|
|
419
|
+
nextExpiryAt?: string;
|
|
420
|
+
}
|
|
421
|
+
export declare const reputationConductSchema: z.ZodType<ReputationConduct>;
|
|
422
|
+
/**
|
|
423
|
+
* Reporting: how reliable this person's reports are.
|
|
424
|
+
*
|
|
425
|
+
* A Beta-posterior mean with a neutral prior, plus a confidence that grows with
|
|
426
|
+
* sample size — one accurate report does not make a perfect reporter, and a
|
|
427
|
+
* newcomer keeps a neutral prior. `malicious` counts CONFIRMED report abuse,
|
|
428
|
+
* and nothing else: a rejected report is not bad faith.
|
|
429
|
+
*/
|
|
430
|
+
export interface ReputationReporting {
|
|
431
|
+
/** Smoothed 0..1 accuracy estimate. */
|
|
432
|
+
reliability: number;
|
|
433
|
+
/** 0..1 confidence in that estimate, from effective sample size. */
|
|
434
|
+
confidence: number;
|
|
435
|
+
confirmed: number;
|
|
436
|
+
rejected: number;
|
|
437
|
+
/** Confirmed report-abuse findings. */
|
|
438
|
+
malicious: number;
|
|
439
|
+
}
|
|
440
|
+
export declare const reputationReportingSchema: z.ZodType<ReputationReporting>;
|
|
441
|
+
/**
|
|
442
|
+
* Reviewing: how reliable this person is AS A REVIEWER, per category and
|
|
443
|
+
* language rather than as one global number — competence in one category says
|
|
444
|
+
* little about another.
|
|
445
|
+
*/
|
|
446
|
+
export interface ReputationReviewing {
|
|
447
|
+
globalReliability: number;
|
|
448
|
+
categoryReliability: Record<string, number>;
|
|
449
|
+
languageReliability: Record<string, number>;
|
|
450
|
+
}
|
|
451
|
+
export declare const reputationReviewingSchema: z.ZodType<ReputationReviewing>;
|
|
452
|
+
/**
|
|
453
|
+
* The contextual influence weights the V2 model publishes.
|
|
454
|
+
*
|
|
455
|
+
* Separate from the legacy four-weight block: selection probability for a jury
|
|
456
|
+
* and the priority of a report are different questions, and neither is the
|
|
457
|
+
* weight of a vote. A vote is never weighted — one qualified person, one vote.
|
|
458
|
+
*/
|
|
459
|
+
export interface ReputationContextualInfluence {
|
|
460
|
+
reportPriorityWeight: number;
|
|
461
|
+
reviewSelectionWeight: number;
|
|
462
|
+
rankingWeight: number;
|
|
463
|
+
}
|
|
464
|
+
export declare const reputationContextualInfluenceSchema: z.ZodType<ReputationContextualInfluence>;
|
|
465
|
+
/**
|
|
466
|
+
* An application's own moderation standing. A new application moderates
|
|
467
|
+
* locally from `sandbox` and produces no global effect until it has passed
|
|
468
|
+
* technical review and a sufficient quality period.
|
|
469
|
+
*/
|
|
470
|
+
export interface ApplicationModerationTrust {
|
|
471
|
+
applicationId: string;
|
|
472
|
+
standing: ApplicationModerationStanding;
|
|
473
|
+
/** 0..1 — how well the application's evidence survives scrutiny. */
|
|
474
|
+
evidenceIntegrity: number;
|
|
475
|
+
/** 0..1 — how well its identity bindings hold up. */
|
|
476
|
+
identityBindingReliability: number;
|
|
477
|
+
/** 0..1 — share of its decisions overturned on appeal. */
|
|
478
|
+
decisionOverturnRate: number;
|
|
479
|
+
/** 0..1 — assessed quality of its own policy. */
|
|
480
|
+
policyQuality: number;
|
|
481
|
+
/**
|
|
482
|
+
* THE gate. False for every application until explicitly granted, so the
|
|
483
|
+
* default for a newly-integrated application is local enforcement only.
|
|
484
|
+
*/
|
|
485
|
+
globalReputationEffectsAllowed: boolean;
|
|
486
|
+
}
|
|
487
|
+
export declare const applicationModerationTrustSchema: z.ZodType<ApplicationModerationTrust>;
|
|
@@ -172,11 +172,11 @@ export declare const recommendationCountSchema: z.ZodObject<{
|
|
|
172
172
|
followers: z.ZodNumber;
|
|
173
173
|
following: z.ZodNumber;
|
|
174
174
|
}, "strip", z.ZodTypeAny, {
|
|
175
|
-
following: number;
|
|
176
175
|
followers: number;
|
|
177
|
-
}, {
|
|
178
176
|
following: number;
|
|
177
|
+
}, {
|
|
179
178
|
followers: number;
|
|
179
|
+
following: number;
|
|
180
180
|
}>;
|
|
181
181
|
export type RecommendationCount = z.infer<typeof recommendationCountSchema>;
|
|
182
182
|
/**
|
|
@@ -205,11 +205,11 @@ export declare const recommendationItemSchema: z.ZodObject<{
|
|
|
205
205
|
followers: z.ZodNumber;
|
|
206
206
|
following: z.ZodNumber;
|
|
207
207
|
}, "strip", z.ZodTypeAny, {
|
|
208
|
-
following: number;
|
|
209
208
|
followers: number;
|
|
210
|
-
}, {
|
|
211
209
|
following: number;
|
|
210
|
+
}, {
|
|
212
211
|
followers: number;
|
|
212
|
+
following: number;
|
|
213
213
|
}>;
|
|
214
214
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
215
215
|
id: z.ZodString;
|
|
@@ -230,11 +230,11 @@ export declare const recommendationItemSchema: z.ZodObject<{
|
|
|
230
230
|
followers: z.ZodNumber;
|
|
231
231
|
following: z.ZodNumber;
|
|
232
232
|
}, "strip", z.ZodTypeAny, {
|
|
233
|
-
following: number;
|
|
234
233
|
followers: number;
|
|
235
|
-
}, {
|
|
236
234
|
following: number;
|
|
235
|
+
}, {
|
|
237
236
|
followers: number;
|
|
237
|
+
following: number;
|
|
238
238
|
}>;
|
|
239
239
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
240
240
|
id: z.ZodString;
|
|
@@ -255,11 +255,11 @@ export declare const recommendationItemSchema: z.ZodObject<{
|
|
|
255
255
|
followers: z.ZodNumber;
|
|
256
256
|
following: z.ZodNumber;
|
|
257
257
|
}, "strip", z.ZodTypeAny, {
|
|
258
|
-
following: number;
|
|
259
258
|
followers: number;
|
|
260
|
-
}, {
|
|
261
259
|
following: number;
|
|
260
|
+
}, {
|
|
262
261
|
followers: number;
|
|
262
|
+
following: number;
|
|
263
263
|
}>;
|
|
264
264
|
}, z.ZodTypeAny, "passthrough">>;
|
|
265
265
|
export type RecommendationItem = z.infer<typeof recommendationItemSchema>;
|
|
@@ -283,11 +283,11 @@ export declare const recommendationResponseSchema: z.ZodArray<z.ZodObject<{
|
|
|
283
283
|
followers: z.ZodNumber;
|
|
284
284
|
following: z.ZodNumber;
|
|
285
285
|
}, "strip", z.ZodTypeAny, {
|
|
286
|
-
following: number;
|
|
287
286
|
followers: number;
|
|
288
|
-
}, {
|
|
289
287
|
following: number;
|
|
288
|
+
}, {
|
|
290
289
|
followers: number;
|
|
290
|
+
following: number;
|
|
291
291
|
}>;
|
|
292
292
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
293
293
|
id: z.ZodString;
|
|
@@ -308,11 +308,11 @@ export declare const recommendationResponseSchema: z.ZodArray<z.ZodObject<{
|
|
|
308
308
|
followers: z.ZodNumber;
|
|
309
309
|
following: z.ZodNumber;
|
|
310
310
|
}, "strip", z.ZodTypeAny, {
|
|
311
|
-
following: number;
|
|
312
311
|
followers: number;
|
|
313
|
-
}, {
|
|
314
312
|
following: number;
|
|
313
|
+
}, {
|
|
315
314
|
followers: number;
|
|
315
|
+
following: number;
|
|
316
316
|
}>;
|
|
317
317
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
318
318
|
id: z.ZodString;
|
|
@@ -333,11 +333,11 @@ export declare const recommendationResponseSchema: z.ZodArray<z.ZodObject<{
|
|
|
333
333
|
followers: z.ZodNumber;
|
|
334
334
|
following: z.ZodNumber;
|
|
335
335
|
}, "strip", z.ZodTypeAny, {
|
|
336
|
-
following: number;
|
|
337
336
|
followers: number;
|
|
338
|
-
}, {
|
|
339
337
|
following: number;
|
|
338
|
+
}, {
|
|
340
339
|
followers: number;
|
|
340
|
+
following: number;
|
|
341
341
|
}>;
|
|
342
342
|
}, z.ZodTypeAny, "passthrough">>, "many">;
|
|
343
343
|
export type RecommendationResponse = z.infer<typeof recommendationResponseSchema>;
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
*/
|
|
42
42
|
import { z } from 'zod';
|
|
43
43
|
import { type UserNameResponse } from './userResponse';
|
|
44
|
+
import { type ReputationConduct, type ReputationContextualInfluence, type ReputationContribution, type ReputationPersonhood, type ReputationReporting, type ReputationReviewing } from './moderationReputation';
|
|
44
45
|
/**
|
|
45
46
|
* Category bucket a reputation transaction falls into. Drives the per-category
|
|
46
47
|
* balance breakdown; every rule and transaction carries exactly one.
|
|
@@ -234,6 +235,21 @@ export interface ReputationBalance extends ReputationBalanceSummary {
|
|
|
234
235
|
recalculatedAt: string;
|
|
235
236
|
/** ISO 8601 last-update timestamp. */
|
|
236
237
|
updatedAt: string;
|
|
238
|
+
/** Whether Oxy believes this is a real, distinct person. Confers nothing else. */
|
|
239
|
+
personhood?: ReputationPersonhood;
|
|
240
|
+
/** What the person built. Excludes conduct penalties. */
|
|
241
|
+
contribution?: ReputationContribution;
|
|
242
|
+
/**
|
|
243
|
+
* The standing moderation outcomes move. Derived from ACTIVE RISK alone, so
|
|
244
|
+
* earning contribution points cannot cancel an active strike.
|
|
245
|
+
*/
|
|
246
|
+
conduct?: ReputationConduct;
|
|
247
|
+
/** Reporting accuracy, smoothed with a neutral prior plus a confidence. */
|
|
248
|
+
reporting?: ReputationReporting;
|
|
249
|
+
/** Reviewer reliability, per category and language rather than global. */
|
|
250
|
+
reviewing?: ReputationReviewing;
|
|
251
|
+
/** Contextual weights: report priority, jury selection, ranking. Never vote weight. */
|
|
252
|
+
contextualInfluence?: ReputationContextualInfluence;
|
|
237
253
|
}
|
|
238
254
|
export declare const reputationBalanceSchema: z.ZodType<ReputationBalance>;
|
|
239
255
|
/**
|