@voltro/plugin-sanctions 0.0.0-stage → 0.87.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.
@@ -0,0 +1,585 @@
1
+ import { ColumnBuilder } from '@voltro/database';
2
+ import { Context } from 'effect';
3
+ import { DataStore } from '@voltro/database';
4
+ import { Effect } from 'effect';
5
+ import { FieldDefinitions } from '@voltro/database';
6
+ import { PluginPrivacyTarget } from '@voltro/protocol';
7
+ import { PreparedSqlMutation } from '@voltro/database/sql';
8
+ import { RateLimitStore } from '@voltro/plugin-ratelimit';
9
+ import { RedisStoreOptions } from '@voltro/plugin-ratelimit';
10
+ import { Schema } from 'effect';
11
+ import { Subject } from '@voltro/protocol';
12
+ import { Table } from '@voltro/database';
13
+ import { VoltroPlugin } from '@voltro/protocol';
14
+ import { YieldableError } from 'effect/Cause';
15
+
16
+ declare const ACTION_KINDS: readonly ["warn", "mute", "chatBan", "matchmakingBan", "rankedBan", "tradeBan", "ban", "shadowBan", "nameReset", "rollback"];
17
+
18
+ declare const ACTIONS_TABLE = "_voltro_sanc_actions";
19
+
20
+ declare const ADMISSIONS_TABLE = "_voltro_sanc_admissions";
21
+
22
+ declare const APPEALS_TABLE = "_voltro_sanc_appeals";
23
+
24
+ declare const AppealSchema: Schema.Struct<{
25
+ readonly id: Schema.String;
26
+ readonly actionId: Schema.String;
27
+ readonly text: Schema.String;
28
+ readonly state: Schema.Literals<readonly ["pending", "reviewed"]>;
29
+ readonly outcome: Schema.NullOr<Schema.Literals<readonly ["upheld", "revoked"]>>;
30
+ readonly createdAt: Schema.Number;
31
+ readonly decidedAt: Schema.NullOr<Schema.Number>;
32
+ }>;
33
+
34
+ declare namespace C {
35
+ export {
36
+ REPORTS_TABLE,
37
+ CASES_TABLE,
38
+ ACTIONS_TABLE,
39
+ APPEALS_TABLE,
40
+ STRIKES_TABLE,
41
+ DEVICE_HINTS_TABLE,
42
+ ADMISSIONS_TABLE,
43
+ ACTION_KINDS,
44
+ CATEGORIES,
45
+ POINTS,
46
+ SanctionKind,
47
+ SanctionCategory,
48
+ SanctionPoint,
49
+ SanctionScopeSchema,
50
+ ReportContextSchema,
51
+ ReportContext,
52
+ SanctionSchema,
53
+ ReportSchema,
54
+ AppealSchema,
55
+ CaseSchema,
56
+ DecisionSchema,
57
+ Sanction,
58
+ SanctionReport,
59
+ SanctionAppeal,
60
+ SanctionCase,
61
+ SanctionDecision,
62
+ SanctionScope,
63
+ ReportInput,
64
+ IssueSanctionInput,
65
+ SanctionCheckContext,
66
+ TrustedSanctionSignal
67
+ }
68
+ }
69
+
70
+ declare const CASES_TABLE = "_voltro_sanc_cases";
71
+
72
+ declare const CaseSchema: Schema.Struct<{
73
+ readonly id: Schema.String;
74
+ readonly targetId: Schema.NullOr<Schema.String>;
75
+ readonly reports: Schema.Number;
76
+ readonly evidence: Schema.$Array<Schema.$Record<Schema.String, Schema.Unknown>>;
77
+ readonly trustScore: Schema.Number;
78
+ readonly state: Schema.Literals<readonly ["open", "reviewing", "actioned", "dismissed"]>;
79
+ readonly decidedBy: Schema.NullOr<Schema.String>;
80
+ readonly decidedAt: Schema.NullOr<Schema.Number>;
81
+ readonly version: Schema.Number;
82
+ }>;
83
+
84
+ declare const CATEGORIES: readonly ["cheating", "abuse", "name", "spam", "griefing", "rmt"];
85
+
86
+ export declare const dataStoreSanctions: (store: DataStore, options: ResolvedSanctionsOptions, limiter: RateLimitStore) => {
87
+ api: SanctionsApi;
88
+ port: SanctionsService;
89
+ admission: SanctionsSqlAdmissionService;
90
+ operator: SanctionsOperatorService;
91
+ recordDeviceHint: (subject: Subject, input: {
92
+ readonly tenantId: string;
93
+ readonly subjectId: string;
94
+ readonly deviceId: string;
95
+ }, salt: Uint8Array) => Effect.Effect<void, SanctionsError, never>;
96
+ exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, SanctionsError, never>;
97
+ eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, SanctionsError, never>;
98
+ };
99
+
100
+ declare const DecisionSchema: Schema.Struct<{
101
+ readonly allowed: Schema.Boolean;
102
+ readonly actionIds: Schema.$Array<Schema.String>;
103
+ readonly shadow: Schema.Boolean;
104
+ }>;
105
+
106
+ export declare const defaultSanctionsStrategies: Readonly<{
107
+ escalationLadder: (input: EscalationInput) => EscalationStep | null;
108
+ trustScore: (input: TrustScoreInput) => number;
109
+ evidenceCollector: (_input: EvidenceCollectorInput) => Effect.Effect<ReadonlyArray<Readonly<Record<string, unknown>>>, SanctionsError>;
110
+ enforcementPoints: ({ action, point, context }: EnforcementInput) => {
111
+ readonly denied: boolean;
112
+ readonly shadow: boolean;
113
+ };
114
+ }>;
115
+
116
+ declare const DEVICE_HINTS_TABLE = "_voltro_sanc_device_hints";
117
+
118
+ export declare interface EnforcementInput {
119
+ readonly action: Sanction;
120
+ readonly point: SanctionPoint;
121
+ readonly context: SanctionCheckContext;
122
+ }
123
+
124
+ export declare interface EscalationInput {
125
+ readonly category: SanctionCategory;
126
+ readonly count: number;
127
+ readonly confidence: number;
128
+ readonly minimumConfidence: number;
129
+ }
130
+
131
+ export declare interface EscalationStep {
132
+ readonly kind: SanctionKind;
133
+ readonly durationMs: number | null;
134
+ }
135
+
136
+ export declare interface EvidenceCollectorInput {
137
+ readonly subject: Subject;
138
+ readonly targetId: string;
139
+ readonly context: ReportContext;
140
+ }
141
+
142
+ export declare interface IssueSanctionInput {
143
+ readonly requestId: string;
144
+ readonly targetId: string;
145
+ readonly kind: SanctionKind;
146
+ readonly scope?: SanctionScope;
147
+ readonly durationMs?: number | null;
148
+ readonly reason: string;
149
+ readonly publicReason: string;
150
+ readonly evidenceCaseId?: string;
151
+ readonly appealable?: boolean;
152
+ }
153
+
154
+ declare const POINTS: readonly ["chat", "matchmaking", "trade", "ranked", "login"];
155
+
156
+ export declare type ReportContext = typeof ReportContextSchema.Type;
157
+
158
+ declare const ReportContextSchema: Schema.Struct<{
159
+ readonly channelId: Schema.optional<Schema.String>;
160
+ readonly messageIds: Schema.optional<Schema.$Array<Schema.String>>;
161
+ readonly roomId: Schema.optional<Schema.String>;
162
+ readonly matchId: Schema.optional<Schema.String>;
163
+ readonly replayRef: Schema.optional<Schema.String>;
164
+ }>;
165
+
166
+ export declare interface ReportInput {
167
+ readonly requestId: string;
168
+ readonly targetId: string;
169
+ readonly category: SanctionCategory;
170
+ readonly context?: ReportContext;
171
+ readonly note?: string;
172
+ }
173
+
174
+ declare const REPORTS_TABLE = "_voltro_sanc_reports";
175
+
176
+ declare const ReportSchema: Schema.Struct<{
177
+ readonly id: Schema.String;
178
+ readonly targetId: Schema.String;
179
+ readonly category: Schema.Literals<readonly ["cheating", "abuse", "name", "spam", "griefing", "rmt"]>;
180
+ readonly state: Schema.Literals<readonly ["open", "reviewing", "actioned", "dismissed"]>;
181
+ readonly createdAt: Schema.Number;
182
+ readonly caseId: Schema.String;
183
+ }>;
184
+
185
+ declare type ResolvedSanctionsOptions = ReturnType<typeof resolveSanctionsOptions>;
186
+
187
+ export declare const resolveSanctionsOptions: (input?: SanctionsOptions) => Readonly<{
188
+ maxActiveActions: number;
189
+ maxReportsPerCase: number;
190
+ maxEvidenceRefs: number;
191
+ maxContextMessageIds: number;
192
+ maxTextLength: number;
193
+ pageSize: number;
194
+ maxExportRows: number;
195
+ reportLimit: number;
196
+ reportWindowMs: number;
197
+ strikeDecayMs: number;
198
+ minimumSignalConfidence: number;
199
+ strategies: Readonly<{
200
+ escalationLadder: (input: EscalationInput) => EscalationStep | null;
201
+ trustScore: (input: TrustScoreInput) => number;
202
+ evidenceCollector: (_input: EvidenceCollectorInput) => Effect.Effect<ReadonlyArray<Readonly<Record<string, unknown>>>, SanctionsError>;
203
+ enforcementPoints: ({ action, point, context }: EnforcementInput) => {
204
+ readonly denied: boolean;
205
+ readonly shadow: boolean;
206
+ };
207
+ }>;
208
+ rateLimit: RedisStoreOptions | undefined;
209
+ now: () => number;
210
+ }>;
211
+
212
+ export declare type Sanction = typeof SanctionSchema.Type;
213
+
214
+ export declare const sanctionActionsTable: Table<"_voltro_sanc_actions", FieldDefinitions<{
215
+ readonly id: ColumnBuilder<string, "id", boolean>;
216
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
217
+ readonly targetId: ColumnBuilder<string | null, "text", boolean>;
218
+ readonly kind: ColumnBuilder<"warn" | "mute" | "chatBan" | "matchmakingBan" | "rankedBan" | "tradeBan" | "ban" | "shadowBan" | "nameReset" | "rollback", "text", boolean>;
219
+ readonly scope: ColumnBuilder<unknown, "json", boolean>;
220
+ readonly from: ColumnBuilder<Date, "timestamp", boolean>;
221
+ readonly until: ColumnBuilder<Date | null, "timestamp", boolean>;
222
+ readonly reason: ColumnBuilder<string, "text", boolean>;
223
+ readonly publicReason: ColumnBuilder<string, "text", boolean>;
224
+ readonly issuedBy: ColumnBuilder<string | null, "text", boolean>;
225
+ readonly evidenceCaseId: ColumnBuilder<string | null, "text", boolean>;
226
+ readonly appealable: ColumnBuilder<boolean, "boolean", boolean>;
227
+ readonly revokedAt: ColumnBuilder<Date | null, "timestamp", boolean>;
228
+ readonly requestKey: ColumnBuilder<string, "text", boolean>;
229
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
230
+ }>, true, never>;
231
+
232
+ export declare const sanctionAdmissionsTable: Table<"_voltro_sanc_admissions", FieldDefinitions<{
233
+ readonly id: ColumnBuilder<string, "id", boolean>;
234
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
235
+ readonly subjectId: ColumnBuilder<string | null, "text", boolean>;
236
+ readonly admission: ColumnBuilder<number, "integer", boolean>;
237
+ readonly erased: ColumnBuilder<boolean, "boolean", boolean>;
238
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
239
+ }>, true, never>;
240
+
241
+ export declare type SanctionAppeal = typeof AppealSchema.Type;
242
+
243
+ export declare const sanctionAppealsTable: Table<"_voltro_sanc_appeals", FieldDefinitions<{
244
+ readonly id: ColumnBuilder<string, "id", boolean>;
245
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
246
+ readonly actionId: ColumnBuilder<string, "text", boolean>;
247
+ readonly subjectId: ColumnBuilder<string | null, "text", boolean>;
248
+ readonly text: ColumnBuilder<string, "text", boolean>;
249
+ readonly state: ColumnBuilder<"pending" | "reviewed", "text", boolean>;
250
+ readonly decidedBy: ColumnBuilder<string | null, "text", boolean>;
251
+ readonly decidedAt: ColumnBuilder<Date | null, "timestamp", boolean>;
252
+ readonly outcome: ColumnBuilder<"revoked" | "upheld" | null, "text", boolean>;
253
+ readonly createdAt: ColumnBuilder<Date, "timestamp", boolean>;
254
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
255
+ }>, true, never>;
256
+
257
+ export declare type SanctionCase = typeof CaseSchema.Type;
258
+
259
+ export declare const sanctionCasesTable: Table<"_voltro_sanc_cases", FieldDefinitions<{
260
+ readonly id: ColumnBuilder<string, "id", boolean>;
261
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
262
+ readonly targetId: ColumnBuilder<string | null, "text", boolean>;
263
+ readonly reports: ColumnBuilder<number, "integer", boolean>;
264
+ readonly evidence: ColumnBuilder<unknown, "json", boolean>;
265
+ readonly trustScore: ColumnBuilder<number, "integer", boolean>;
266
+ readonly state: ColumnBuilder<"open" | "reviewing" | "actioned" | "dismissed", "text", boolean>;
267
+ readonly decidedBy: ColumnBuilder<string | null, "text", boolean>;
268
+ readonly decidedAt: ColumnBuilder<Date | null, "timestamp", boolean>;
269
+ readonly version: ColumnBuilder<number, "integer", boolean>;
270
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
271
+ }>, true, never>;
272
+
273
+ export declare type SanctionCategory = typeof CATEGORIES[number];
274
+
275
+ export declare interface SanctionCheckContext {
276
+ readonly channelId?: string;
277
+ readonly queueId?: string;
278
+ }
279
+
280
+ export declare type SanctionDecision = typeof DecisionSchema.Type;
281
+
282
+ export declare const sanctionDeviceHintsTable: Table<"_voltro_sanc_device_hints", FieldDefinitions<{
283
+ readonly id: ColumnBuilder<string, "id", boolean>;
284
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
285
+ readonly subjectId: ColumnBuilder<string | null, "text", boolean>;
286
+ readonly deviceHash: ColumnBuilder<string, "text", boolean>;
287
+ readonly firstSeen: ColumnBuilder<Date, "timestamp", boolean>;
288
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
289
+ }>, true, never>;
290
+
291
+ export declare type SanctionKind = typeof ACTION_KINDS[number];
292
+
293
+ export declare type SanctionPoint = typeof POINTS[number];
294
+
295
+ export declare type SanctionReport = typeof ReportSchema.Type;
296
+
297
+ export declare const sanctionReportsTable: Table<"_voltro_sanc_reports", FieldDefinitions<{
298
+ readonly id: ColumnBuilder<string, "id", boolean>;
299
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
300
+ readonly reporterId: ColumnBuilder<string | null, "text", boolean>;
301
+ readonly targetId: ColumnBuilder<string | null, "text", boolean>;
302
+ readonly category: ColumnBuilder<"name" | "cheating" | "abuse" | "spam" | "griefing" | "rmt", "text", boolean>;
303
+ readonly context: ColumnBuilder<unknown, "json", boolean>;
304
+ readonly note: ColumnBuilder<string, "text", boolean>;
305
+ readonly state: ColumnBuilder<"open" | "reviewing" | "actioned" | "dismissed", "text", boolean>;
306
+ readonly assignee: ColumnBuilder<string | null, "text", boolean>;
307
+ readonly createdAt: ColumnBuilder<Date, "timestamp", boolean>;
308
+ readonly caseId: ColumnBuilder<string, "text", boolean>;
309
+ readonly requestKey: ColumnBuilder<string, "text", boolean>;
310
+ readonly source: ColumnBuilder<"system" | "human", "text", boolean>;
311
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
312
+ }>, true, never>;
313
+
314
+ declare interface SanctionsAdmissionBatch extends SanctionsAdmissionRead {
315
+ readonly tenantId: string;
316
+ readonly participants: readonly {
317
+ readonly ownerId: string;
318
+ readonly expected: SanctionsPermission;
319
+ }[];
320
+ }
321
+
322
+ declare interface SanctionsAdmissionPrepare extends SanctionsAdmissionRead {
323
+ readonly expected: SanctionsPermission;
324
+ }
325
+
326
+ declare interface SanctionsAdmissionRead {
327
+ readonly point: SanctionPoint;
328
+ readonly at: number;
329
+ readonly context?: SanctionCheckContext;
330
+ }
331
+
332
+ export declare interface SanctionsApi {
333
+ readonly report: (subject: Subject, input: C.ReportInput) => Effect.Effect<C.SanctionReport, SanctionsError>;
334
+ readonly reportsMine: (subject: Subject) => Effect.Effect<ReadonlyArray<C.SanctionReport>, SanctionsError>;
335
+ readonly mine: (subject: Subject) => Effect.Effect<ReadonlyArray<C.Sanction>, SanctionsError>;
336
+ readonly appeal: (subject: Subject, input: {
337
+ readonly actionId: string;
338
+ readonly text: string;
339
+ }) => Effect.Effect<C.SanctionAppeal, SanctionsError>;
340
+ readonly appealsMine: (subject: Subject) => Effect.Effect<ReadonlyArray<C.SanctionAppeal>, SanctionsError>;
341
+ readonly cases: (subject: Subject) => Effect.Effect<ReadonlyArray<C.SanctionCase>, SanctionsError>;
342
+ readonly reviewCase: (subject: Subject, input: {
343
+ readonly caseId: string;
344
+ readonly baseVersion: number;
345
+ readonly state: C.SanctionCase['state'];
346
+ }) => Effect.Effect<C.SanctionCase, SanctionsError>;
347
+ readonly issue: (subject: Subject, input: C.IssueSanctionInput) => Effect.Effect<C.Sanction, SanctionsError>;
348
+ readonly revoke: (subject: Subject, actionId: string) => Effect.Effect<void, SanctionsError>;
349
+ readonly appealsQueue: (subject: Subject) => Effect.Effect<ReadonlyArray<C.SanctionAppeal>, SanctionsError>;
350
+ readonly reviewAppeal: (subject: Subject, input: {
351
+ readonly appealId: string;
352
+ readonly outcome: 'upheld' | 'revoked';
353
+ }) => Effect.Effect<C.SanctionAppeal, SanctionsError>;
354
+ }
355
+
356
+ declare const SanctionSchema: Schema.Struct<{
357
+ readonly id: Schema.String;
358
+ readonly kind: Schema.Literals<readonly ["warn", "mute", "chatBan", "matchmakingBan", "rankedBan", "tradeBan", "ban", "shadowBan", "nameReset", "rollback"]>;
359
+ readonly scope: Schema.Struct<{
360
+ readonly channels: Schema.$Array<Schema.String>;
361
+ readonly queues: Schema.$Array<Schema.String>;
362
+ }>;
363
+ readonly from: Schema.Number;
364
+ readonly until: Schema.NullOr<Schema.Number>;
365
+ readonly publicReason: Schema.String;
366
+ readonly appealable: Schema.Boolean;
367
+ }>;
368
+
369
+ export declare type SanctionScope = typeof SanctionScopeSchema.Type;
370
+
371
+ declare const SanctionScopeSchema: Schema.Struct<{
372
+ readonly channels: Schema.$Array<Schema.String>;
373
+ readonly queues: Schema.$Array<Schema.String>;
374
+ }>;
375
+
376
+ export declare class SanctionsError extends SanctionsError_base {
377
+ }
378
+
379
+ declare const SanctionsError_base: Schema.Class<SanctionsError, Schema.TaggedStruct<"SanctionsError", {
380
+ readonly code: Schema.Literals<readonly ["identity_required", "invalid_input", "forbidden", "not_found", "conflict", "rate_limited", "sanctioned", "unavailable", "export_limit"]>;
381
+ }>, YieldableError>;
382
+
383
+ /** The tenant and human operator a trusted server caller (a GM console) acts as; recorded as the issuer. */
384
+ export declare interface SanctionsOperator {
385
+ readonly tenantId: string;
386
+ readonly operatorId: string;
387
+ }
388
+
389
+ /** Server-only issue/revoke for code that already admitted its operator. No request scope is read. */
390
+ export declare interface SanctionsOperatorService {
391
+ readonly issue: (operator: SanctionsOperator, input: C.IssueSanctionInput) => Effect.Effect<C.Sanction, SanctionsError>;
392
+ readonly revoke: (operator: SanctionsOperator, actionId: string) => Effect.Effect<void, SanctionsError>;
393
+ }
394
+
395
+ export declare interface SanctionsOptions {
396
+ readonly maxActiveActions?: number;
397
+ readonly maxReportsPerCase?: number;
398
+ readonly maxEvidenceRefs?: number;
399
+ readonly maxContextMessageIds?: number;
400
+ readonly maxTextLength?: number;
401
+ readonly pageSize?: number;
402
+ readonly maxExportRows?: number;
403
+ readonly reportLimit?: number;
404
+ readonly reportWindowMs?: number;
405
+ readonly strikeDecayMs?: number;
406
+ readonly minimumSignalConfidence?: number;
407
+ readonly strategies?: Partial<typeof defaultSanctionsStrategies>;
408
+ readonly rateLimit?: RedisStoreOptions;
409
+ readonly now?: () => number;
410
+ }
411
+
412
+ declare interface SanctionsPermission {
413
+ readonly allowed: boolean;
414
+ readonly trustScore: number;
415
+ }
416
+
417
+ export declare interface SanctionsPlugin extends VoltroPlugin {
418
+ readonly sanctions: {
419
+ readonly admission: () => SanctionsSqlAdmissionService;
420
+ /** Server-only operator issue/revoke for a caller that already admitted its staff actor (`@voltro/plugin-gm`). */
421
+ readonly operator: () => SanctionsOperatorService;
422
+ };
423
+ }
424
+
425
+ export declare const sanctionsPlugin: (input?: SanctionsOptions) => SanctionsPlugin;
426
+
427
+ /** Other systems consult this small port rather than sanction SQL or an app-local enforcement map. */
428
+ export declare class SanctionsPort extends SanctionsPort_base {
429
+ }
430
+
431
+ declare const SanctionsPort_base: Context.ServiceClass<SanctionsPort, "@voltro/SanctionsPort", SanctionsService>;
432
+
433
+ export declare interface SanctionsService {
434
+ readonly check: (subject: Subject, point: SanctionPoint, context?: SanctionCheckContext) => Effect.Effect<SanctionDecision, SanctionsError>;
435
+ readonly active: (subject: Subject) => Effect.Effect<ReadonlyArray<Sanction>, SanctionsError>;
436
+ readonly trust: (subject: Subject) => Effect.Effect<number, SanctionsError>;
437
+ readonly recordSignal: (subject: Subject, input: TrustedSanctionSignal) => Effect.Effect<void, SanctionsError>;
438
+ }
439
+
440
+ /** Server-only capability; the small ordinary SanctionsPort remains unchanged. */
441
+ declare interface SanctionsSqlAdmissionService {
442
+ readonly read: (subject: Subject, input: SanctionsAdmissionRead) => Effect.Effect<SanctionsPermission, SanctionsError>;
443
+ readonly prepare: (subject: Subject, input: SanctionsAdmissionPrepare) => Effect.Effect<PreparedSqlMutation<void>, SanctionsError>;
444
+ readonly prepareMany: (input: SanctionsAdmissionBatch) => Effect.Effect<PreparedSqlMutation<void>, SanctionsError>;
445
+ }
446
+
447
+ export declare const sanctionsSystemContract: {
448
+ readonly slots: {
449
+ readonly escalationLadder: {
450
+ readonly defaultExport: "abuseEscalationLadder";
451
+ readonly fixtureExport: "sanctionsEscalationFixture";
452
+ };
453
+ readonly trustScore: {
454
+ readonly defaultExport: "conservativeTrustScore";
455
+ readonly fixtureExport: "sanctionsTrustFixture";
456
+ };
457
+ readonly evidenceCollector: {
458
+ readonly defaultExport: "noCollectedSanctionEvidence";
459
+ readonly fixtureExport: "sanctionsEvidenceFixture";
460
+ };
461
+ readonly enforcementPoints: {
462
+ readonly defaultExport: "defaultSanctionEnforcement";
463
+ readonly fixtureExport: "sanctionsEnforcementFixture";
464
+ };
465
+ };
466
+ readonly ports: {
467
+ readonly sanctions: {
468
+ readonly tagExport: "SanctionsPort";
469
+ readonly fakeLayerExport: "sanctionsFakeLayer";
470
+ readonly fixtureExport: "sanctionsPortFixture";
471
+ };
472
+ };
473
+ readonly events: readonly ["sanctions.changed"];
474
+ };
475
+
476
+ export declare const sanctionStrikesTable: Table<"_voltro_sanc_strikes", FieldDefinitions<{
477
+ readonly id: ColumnBuilder<string, "id", boolean>;
478
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
479
+ readonly targetId: ColumnBuilder<string | null, "text", boolean>;
480
+ readonly category: ColumnBuilder<"name" | "cheating" | "abuse" | "spam" | "griefing" | "rmt", "text", boolean>;
481
+ readonly count: ColumnBuilder<number, "integer", boolean>;
482
+ readonly lastAt: ColumnBuilder<Date, "timestamp", boolean>;
483
+ readonly decayAt: ColumnBuilder<Date, "timestamp", boolean>;
484
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
485
+ }>, true, never>;
486
+
487
+ export declare const sanctionTables: ( Table<"_voltro_sanc_reports", FieldDefinitions<{
488
+ readonly id: ColumnBuilder<string, "id", boolean>;
489
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
490
+ readonly reporterId: ColumnBuilder<string | null, "text", boolean>;
491
+ readonly targetId: ColumnBuilder<string | null, "text", boolean>;
492
+ readonly category: ColumnBuilder<"name" | "cheating" | "abuse" | "spam" | "griefing" | "rmt", "text", boolean>;
493
+ readonly context: ColumnBuilder<unknown, "json", boolean>;
494
+ readonly note: ColumnBuilder<string, "text", boolean>;
495
+ readonly state: ColumnBuilder<"open" | "reviewing" | "actioned" | "dismissed", "text", boolean>;
496
+ readonly assignee: ColumnBuilder<string | null, "text", boolean>;
497
+ readonly createdAt: ColumnBuilder<Date, "timestamp", boolean>;
498
+ readonly caseId: ColumnBuilder<string, "text", boolean>;
499
+ readonly requestKey: ColumnBuilder<string, "text", boolean>;
500
+ readonly source: ColumnBuilder<"system" | "human", "text", boolean>;
501
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
502
+ }>, true, never> | Table<"_voltro_sanc_cases", FieldDefinitions<{
503
+ readonly id: ColumnBuilder<string, "id", boolean>;
504
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
505
+ readonly targetId: ColumnBuilder<string | null, "text", boolean>;
506
+ readonly reports: ColumnBuilder<number, "integer", boolean>;
507
+ readonly evidence: ColumnBuilder<unknown, "json", boolean>;
508
+ readonly trustScore: ColumnBuilder<number, "integer", boolean>;
509
+ readonly state: ColumnBuilder<"open" | "reviewing" | "actioned" | "dismissed", "text", boolean>;
510
+ readonly decidedBy: ColumnBuilder<string | null, "text", boolean>;
511
+ readonly decidedAt: ColumnBuilder<Date | null, "timestamp", boolean>;
512
+ readonly version: ColumnBuilder<number, "integer", boolean>;
513
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
514
+ }>, true, never> | Table<"_voltro_sanc_actions", FieldDefinitions<{
515
+ readonly id: ColumnBuilder<string, "id", boolean>;
516
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
517
+ readonly targetId: ColumnBuilder<string | null, "text", boolean>;
518
+ readonly kind: ColumnBuilder<"warn" | "mute" | "chatBan" | "matchmakingBan" | "rankedBan" | "tradeBan" | "ban" | "shadowBan" | "nameReset" | "rollback", "text", boolean>;
519
+ readonly scope: ColumnBuilder<unknown, "json", boolean>;
520
+ readonly from: ColumnBuilder<Date, "timestamp", boolean>;
521
+ readonly until: ColumnBuilder<Date | null, "timestamp", boolean>;
522
+ readonly reason: ColumnBuilder<string, "text", boolean>;
523
+ readonly publicReason: ColumnBuilder<string, "text", boolean>;
524
+ readonly issuedBy: ColumnBuilder<string | null, "text", boolean>;
525
+ readonly evidenceCaseId: ColumnBuilder<string | null, "text", boolean>;
526
+ readonly appealable: ColumnBuilder<boolean, "boolean", boolean>;
527
+ readonly revokedAt: ColumnBuilder<Date | null, "timestamp", boolean>;
528
+ readonly requestKey: ColumnBuilder<string, "text", boolean>;
529
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
530
+ }>, true, never> | Table<"_voltro_sanc_appeals", FieldDefinitions<{
531
+ readonly id: ColumnBuilder<string, "id", boolean>;
532
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
533
+ readonly actionId: ColumnBuilder<string, "text", boolean>;
534
+ readonly subjectId: ColumnBuilder<string | null, "text", boolean>;
535
+ readonly text: ColumnBuilder<string, "text", boolean>;
536
+ readonly state: ColumnBuilder<"pending" | "reviewed", "text", boolean>;
537
+ readonly decidedBy: ColumnBuilder<string | null, "text", boolean>;
538
+ readonly decidedAt: ColumnBuilder<Date | null, "timestamp", boolean>;
539
+ readonly outcome: ColumnBuilder<"revoked" | "upheld" | null, "text", boolean>;
540
+ readonly createdAt: ColumnBuilder<Date, "timestamp", boolean>;
541
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
542
+ }>, true, never> | Table<"_voltro_sanc_strikes", FieldDefinitions<{
543
+ readonly id: ColumnBuilder<string, "id", boolean>;
544
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
545
+ readonly targetId: ColumnBuilder<string | null, "text", boolean>;
546
+ readonly category: ColumnBuilder<"name" | "cheating" | "abuse" | "spam" | "griefing" | "rmt", "text", boolean>;
547
+ readonly count: ColumnBuilder<number, "integer", boolean>;
548
+ readonly lastAt: ColumnBuilder<Date, "timestamp", boolean>;
549
+ readonly decayAt: ColumnBuilder<Date, "timestamp", boolean>;
550
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
551
+ }>, true, never> | Table<"_voltro_sanc_device_hints", FieldDefinitions<{
552
+ readonly id: ColumnBuilder<string, "id", boolean>;
553
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
554
+ readonly subjectId: ColumnBuilder<string | null, "text", boolean>;
555
+ readonly deviceHash: ColumnBuilder<string, "text", boolean>;
556
+ readonly firstSeen: ColumnBuilder<Date, "timestamp", boolean>;
557
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
558
+ }>, true, never> | Table<"_voltro_sanc_admissions", FieldDefinitions<{
559
+ readonly id: ColumnBuilder<string, "id", boolean>;
560
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
561
+ readonly subjectId: ColumnBuilder<string | null, "text", boolean>;
562
+ readonly admission: ColumnBuilder<number, "integer", boolean>;
563
+ readonly erased: ColumnBuilder<boolean, "boolean", boolean>;
564
+ readonly metadata: ColumnBuilder<unknown, "json", boolean>;
565
+ }>, true, never>)[];
566
+
567
+ declare const STRIKES_TABLE = "_voltro_sanc_strikes";
568
+
569
+ export declare interface TrustedSanctionSignal {
570
+ readonly tenantId: string;
571
+ readonly targetId: string;
572
+ readonly requestId: string;
573
+ readonly category: SanctionCategory;
574
+ readonly confidence: number;
575
+ readonly context?: ReportContext;
576
+ }
577
+
578
+ export declare interface TrustScoreInput {
579
+ readonly strikes: number;
580
+ readonly verifiedAccountAgeMs: number | null;
581
+ readonly verifiedPlatform: boolean;
582
+ readonly verifiedPaymentCount: number;
583
+ }
584
+
585
+ export { }