@oxy.so/contracts 1.0.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/LICENSE +202 -0
- package/NOTICE +16 -0
- package/dist/cjs/.tsbuildinfo +1 -0
- package/dist/cjs/accountGraph.js +489 -0
- package/dist/cjs/agency.js +439 -0
- package/dist/cjs/browserHub.js +215 -0
- package/dist/cjs/civic.js +163 -0
- package/dist/cjs/commonsSignIn.js +59 -0
- package/dist/cjs/deviceBoot.js +50 -0
- package/dist/cjs/deviceDirectory.js +189 -0
- package/dist/cjs/devicePairing.js +138 -0
- package/dist/cjs/deviceSession.js +164 -0
- package/dist/cjs/emailAgentContext.js +32 -0
- package/dist/cjs/followGraph.js +28 -0
- package/dist/cjs/identity.js +258 -0
- package/dist/cjs/inboxPush.js +24 -0
- package/dist/cjs/index.js +618 -0
- package/dist/cjs/inference/accountBilling.js +334 -0
- package/dist/cjs/inference/aliaModelRelease.js +262 -0
- package/dist/cjs/inference/attribution.js +106 -0
- package/dist/cjs/inference/catalogue.js +487 -0
- package/dist/cjs/inference/entitlement.js +217 -0
- package/dist/cjs/inference/errors.js +309 -0
- package/dist/cjs/inference/identifiers.js +224 -0
- package/dist/cjs/inference/inbox.js +105 -0
- package/dist/cjs/inference/modelDocumentation.js +433 -0
- package/dist/cjs/inference/money.js +188 -0
- package/dist/cjs/inference/priceVersion.js +110 -0
- package/dist/cjs/inference/providerConnection.js +455 -0
- package/dist/cjs/inference/request.js +477 -0
- package/dist/cjs/inference/routingPolicy.js +318 -0
- package/dist/cjs/inference/streamEvents.js +258 -0
- package/dist/cjs/inference/usage.js +329 -0
- package/dist/cjs/inference/version.js +105 -0
- package/dist/cjs/keyRecovery.js +91 -0
- package/dist/cjs/keyRotation.js +75 -0
- package/dist/cjs/links.js +68 -0
- package/dist/cjs/moderationReputation.js +298 -0
- package/dist/cjs/oauth.js +66 -0
- package/dist/cjs/oxyRecordTypes.js +71 -0
- package/dist/cjs/protocol.js +53 -0
- package/dist/cjs/recommendations.js +168 -0
- package/dist/cjs/reputation.js +297 -0
- package/dist/cjs/sessionStatus.js +121 -0
- package/dist/cjs/transparency.js +89 -0
- package/dist/cjs/updates.js +252 -0
- package/dist/cjs/userInvalidation.js +89 -0
- package/dist/cjs/userResponse.js +245 -0
- package/dist/cjs/username.js +290 -0
- package/dist/cjs/webauthn.js +71 -0
- package/dist/esm/.tsbuildinfo +1 -0
- package/dist/esm/accountGraph.js +480 -0
- package/dist/esm/agency.js +436 -0
- package/dist/esm/browserHub.js +212 -0
- package/dist/esm/civic.js +160 -0
- package/dist/esm/commonsSignIn.js +56 -0
- package/dist/esm/deviceBoot.js +47 -0
- package/dist/esm/deviceDirectory.js +186 -0
- package/dist/esm/devicePairing.js +135 -0
- package/dist/esm/deviceSession.js +161 -0
- package/dist/esm/emailAgentContext.js +29 -0
- package/dist/esm/followGraph.js +27 -0
- package/dist/esm/identity.js +255 -0
- package/dist/esm/inboxPush.js +21 -0
- package/dist/esm/index.js +172 -0
- package/dist/esm/inference/accountBilling.js +331 -0
- package/dist/esm/inference/aliaModelRelease.js +259 -0
- package/dist/esm/inference/attribution.js +103 -0
- package/dist/esm/inference/catalogue.js +484 -0
- package/dist/esm/inference/entitlement.js +214 -0
- package/dist/esm/inference/errors.js +306 -0
- package/dist/esm/inference/identifiers.js +221 -0
- package/dist/esm/inference/inbox.js +102 -0
- package/dist/esm/inference/modelDocumentation.js +430 -0
- package/dist/esm/inference/money.js +185 -0
- package/dist/esm/inference/priceVersion.js +107 -0
- package/dist/esm/inference/providerConnection.js +452 -0
- package/dist/esm/inference/request.js +474 -0
- package/dist/esm/inference/routingPolicy.js +315 -0
- package/dist/esm/inference/streamEvents.js +255 -0
- package/dist/esm/inference/usage.js +326 -0
- package/dist/esm/inference/version.js +102 -0
- package/dist/esm/keyRecovery.js +88 -0
- package/dist/esm/keyRotation.js +72 -0
- package/dist/esm/links.js +65 -0
- package/dist/esm/moderationReputation.js +295 -0
- package/dist/esm/oauth.js +63 -0
- package/dist/esm/oxyRecordTypes.js +68 -0
- package/dist/esm/protocol.js +50 -0
- package/dist/esm/recommendations.js +165 -0
- package/dist/esm/reputation.js +293 -0
- package/dist/esm/sessionStatus.js +118 -0
- package/dist/esm/transparency.js +86 -0
- package/dist/esm/updates.js +249 -0
- package/dist/esm/userInvalidation.js +85 -0
- package/dist/esm/userResponse.js +240 -0
- package/dist/esm/username.js +283 -0
- package/dist/esm/webauthn.js +68 -0
- package/dist/types/.tsbuildinfo +1 -0
- package/dist/types/accountGraph.d.ts +378 -0
- package/dist/types/agency.d.ts +2162 -0
- package/dist/types/browserHub.d.ts +856 -0
- package/dist/types/civic.d.ts +338 -0
- package/dist/types/commonsSignIn.d.ts +58 -0
- package/dist/types/deviceBoot.d.ts +74 -0
- package/dist/types/deviceDirectory.d.ts +1317 -0
- package/dist/types/devicePairing.d.ts +130 -0
- package/dist/types/deviceSession.d.ts +411 -0
- package/dist/types/emailAgentContext.d.ts +248 -0
- package/dist/types/followGraph.d.ts +150 -0
- package/dist/types/identity.d.ts +402 -0
- package/dist/types/inboxPush.d.ts +30 -0
- package/dist/types/index.d.ts +100 -0
- package/dist/types/inference/accountBilling.d.ts +738 -0
- package/dist/types/inference/aliaModelRelease.d.ts +609 -0
- package/dist/types/inference/attribution.d.ts +176 -0
- package/dist/types/inference/catalogue.d.ts +1618 -0
- package/dist/types/inference/entitlement.d.ts +519 -0
- package/dist/types/inference/errors.d.ts +242 -0
- package/dist/types/inference/identifiers.d.ts +182 -0
- package/dist/types/inference/inbox.d.ts +374 -0
- package/dist/types/inference/modelDocumentation.d.ts +1603 -0
- package/dist/types/inference/money.d.ts +185 -0
- package/dist/types/inference/priceVersion.d.ts +182 -0
- package/dist/types/inference/providerConnection.d.ts +968 -0
- package/dist/types/inference/request.d.ts +2800 -0
- package/dist/types/inference/routingPolicy.d.ts +616 -0
- package/dist/types/inference/streamEvents.d.ts +950 -0
- package/dist/types/inference/usage.d.ts +1164 -0
- package/dist/types/inference/version.d.ts +102 -0
- package/dist/types/keyRecovery.d.ts +138 -0
- package/dist/types/keyRotation.d.ts +103 -0
- package/dist/types/links.d.ts +96 -0
- package/dist/types/moderationReputation.d.ts +487 -0
- package/dist/types/oauth.d.ts +86 -0
- package/dist/types/oxyRecordTypes.d.ts +62 -0
- package/dist/types/protocol.d.ts +86 -0
- package/dist/types/recommendations.d.ts +542 -0
- package/dist/types/reputation.d.ts +457 -0
- package/dist/types/sessionStatus.d.ts +231 -0
- package/dist/types/transparency.d.ts +392 -0
- package/dist/types/updates.d.ts +545 -0
- package/dist/types/userInvalidation.d.ts +94 -0
- package/dist/types/userResponse.d.ts +1706 -0
- package/dist/types/username.d.ts +265 -0
- package/dist/types/webauthn.d.ts +77 -0
- package/package.json +87 -0
|
@@ -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>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The two `/auth/oauth/*` responses the browser hub's edge layer reads.
|
|
4
|
+
*
|
|
5
|
+
* They existed on the wire long before this file — `GET /auth/oauth/consent`
|
|
6
|
+
* and `POST /auth/oauth/authorize` are the surface `auth.oxy.so` has always
|
|
7
|
+
* driven with a bearer. What is new (issue #937 Phase 5) is a SECOND consumer
|
|
8
|
+
* that is not the SPA: the IdP's edge layer runs both calls server-side so the
|
|
9
|
+
* device-wide bearer never enters the browser's script context. A shape read by
|
|
10
|
+
* two independently deployed consumers is a contract, so it is written down
|
|
11
|
+
* once here and validated on both sides rather than transcribed into the edge.
|
|
12
|
+
*
|
|
13
|
+
* These are NOT the RFC 6749 token/userinfo responses. Those two speak flat
|
|
14
|
+
* OAuth/OIDC on the wire and are the one place in the API that does not use the
|
|
15
|
+
* `{ data }` envelope; these two are ordinary internal API responses that happen
|
|
16
|
+
* to be about OAuth.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Server-authoritative answer to "must this user be shown a consent screen".
|
|
20
|
+
*
|
|
21
|
+
* Discriminated on `consentRequired` so the two arms cannot be confused by a
|
|
22
|
+
* consumer that reads `reason` first: `trusted`/`granted` are reasons NOT to
|
|
23
|
+
* ask, `new`/`scope_changed` are reasons to ask, and a flat object would let a
|
|
24
|
+
* typo in one produce a plausible value of the other.
|
|
25
|
+
*
|
|
26
|
+
* - `trusted` — the application is first-party/internal/system/official
|
|
27
|
+
* by the REGISTRY's verdict (`isTrustedApplication`), and
|
|
28
|
+
* the request names no scope over the user's own follow
|
|
29
|
+
* graph. Never inferred from a hostname.
|
|
30
|
+
* - `granted` — a prior `AppGrant` already covers every requested scope.
|
|
31
|
+
* - `scope_changed` — a prior grant exists and is missing one.
|
|
32
|
+
* - `new` — no prior grant.
|
|
33
|
+
*
|
|
34
|
+
* `userConsentScopes` names the scopes that FORCED the screen, so the consent UI
|
|
35
|
+
* can say which one it is asking about. Present only on the `true` arm, and only
|
|
36
|
+
* when such a scope exists — a trusted app asked for one is still asked.
|
|
37
|
+
*/
|
|
38
|
+
export declare const oauthConsentDecisionSchema: z.ZodDiscriminatedUnion<"consentRequired", [z.ZodObject<{
|
|
39
|
+
consentRequired: z.ZodLiteral<false>;
|
|
40
|
+
reason: z.ZodEnum<["trusted", "granted"]>;
|
|
41
|
+
}, "strip", z.ZodTypeAny, {
|
|
42
|
+
reason: "trusted" | "granted";
|
|
43
|
+
consentRequired: false;
|
|
44
|
+
}, {
|
|
45
|
+
reason: "trusted" | "granted";
|
|
46
|
+
consentRequired: false;
|
|
47
|
+
}>, z.ZodObject<{
|
|
48
|
+
consentRequired: z.ZodLiteral<true>;
|
|
49
|
+
reason: z.ZodEnum<["new", "scope_changed"]>;
|
|
50
|
+
userConsentScopes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
51
|
+
}, "strip", z.ZodTypeAny, {
|
|
52
|
+
reason: "new" | "scope_changed";
|
|
53
|
+
consentRequired: true;
|
|
54
|
+
userConsentScopes?: string[] | undefined;
|
|
55
|
+
}, {
|
|
56
|
+
reason: "new" | "scope_changed";
|
|
57
|
+
consentRequired: true;
|
|
58
|
+
userConsentScopes?: string[] | undefined;
|
|
59
|
+
}>]>;
|
|
60
|
+
/**
|
|
61
|
+
* A minted authorization code.
|
|
62
|
+
*
|
|
63
|
+
* `state` is echoed back as the caller sent it and is `null` when they sent
|
|
64
|
+
* none — never omitted, so a consumer cannot read "the server dropped my state"
|
|
65
|
+
* as "I sent none". `redirectUri` is echoed for the same reason the code is
|
|
66
|
+
* bound to it server-side: the caller must be able to see that the value the
|
|
67
|
+
* code was issued against is the one it registered.
|
|
68
|
+
*/
|
|
69
|
+
export declare const oauthAuthorizeCodeResponseSchema: z.ZodObject<{
|
|
70
|
+
code: z.ZodString;
|
|
71
|
+
state: z.ZodNullable<z.ZodString>;
|
|
72
|
+
redirectUri: z.ZodString;
|
|
73
|
+
expiresIn: z.ZodNumber;
|
|
74
|
+
}, "strip", z.ZodTypeAny, {
|
|
75
|
+
code: string;
|
|
76
|
+
state: string | null;
|
|
77
|
+
redirectUri: string;
|
|
78
|
+
expiresIn: number;
|
|
79
|
+
}, {
|
|
80
|
+
code: string;
|
|
81
|
+
state: string | null;
|
|
82
|
+
redirectUri: string;
|
|
83
|
+
expiresIn: number;
|
|
84
|
+
}>;
|
|
85
|
+
export type OauthConsentDecision = z.infer<typeof oauthConsentDecisionSchema>;
|
|
86
|
+
export type OauthAuthorizeCodeResponse = z.infer<typeof oauthAuthorizeCodeResponseSchema>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Oxy-scoped signed-record types.
|
|
3
|
+
*
|
|
4
|
+
* The base `signedRecordEnvelopeSchema` (`./identity`) treats `type` as an OPEN,
|
|
5
|
+
* non-empty string so ANY Oxy app may sign on the shared envelope grammar. The
|
|
6
|
+
* Oxy STORE re-narrows it to the closed set in this module — a `type` outside it
|
|
7
|
+
* is rejected as `invalid_envelope`.
|
|
8
|
+
*
|
|
9
|
+
* `oxySignedRecordTypeSchema` is that runtime gate (the API's `verifyEnvelope`
|
|
10
|
+
* re-narrows with it; the Mongoose `SignedRecord.type` enum and the Postgres
|
|
11
|
+
* CHECK on `signed_records.type` are both derived from `.options`);
|
|
12
|
+
* `OxySignedRecordType` is the matching compile-time union the SDK
|
|
13
|
+
* identity/civic mixins type against.
|
|
14
|
+
*
|
|
15
|
+
* The signing input INCLUDES `type`, so this set is part of the signed bytes —
|
|
16
|
+
* a record cannot have its category swapped after signing, and a value once
|
|
17
|
+
* signed can never be renamed.
|
|
18
|
+
*
|
|
19
|
+
* v1 only ever carried `identity` / `profile` (already in production); v2 added
|
|
20
|
+
* the civic record types (reputation attestations, real-life / peer validations,
|
|
21
|
+
* personhood vouches, verifiable credentials) and the user-node registration
|
|
22
|
+
* record.
|
|
23
|
+
*
|
|
24
|
+
* ## Why `app_record` is here, when it deliberately was not
|
|
25
|
+
*
|
|
26
|
+
* This set used to hold Oxy's own categories only, and said so: an app's `type`
|
|
27
|
+
* was "intentionally NOT in this set". The reason given was that the store
|
|
28
|
+
* accepts only what it knows how to **verify and materialize**. Verification
|
|
29
|
+
* turned out not to argue for the exclusion — the engine verifies a signature
|
|
30
|
+
* against the subject's keys whatever the category says — and materialization
|
|
31
|
+
* is the app's job, not the store's: an app projects its own feed tables from
|
|
32
|
+
* records it reads back.
|
|
33
|
+
*
|
|
34
|
+
* What changed is the decision the exclusion blocked. One chain per PERSON, held
|
|
35
|
+
* by Oxy, is the ecosystem substrate: apps append their records to the subject's
|
|
36
|
+
* one chain instead of each keeping a private chain for the same person. A
|
|
37
|
+
* closed set that admits no app category makes that unrepresentable.
|
|
38
|
+
*
|
|
39
|
+
* `app_record` is ONE value rather than an open lane, and the lexicon lives in
|
|
40
|
+
* the envelope's `collection` (`app.mention.feed.post`, `app.syra.*`), which the
|
|
41
|
+
* store denormalizes to `signed_records.nsid` and indexes. So a new app needs no
|
|
42
|
+
* change here — it picks its own collection namespace and signs `app_record`,
|
|
43
|
+
* exactly as Mention already does in production. Keeping the set closed is what
|
|
44
|
+
* keeps the CHECK a real constraint.
|
|
45
|
+
*
|
|
46
|
+
* **Admitting the category is not the whole of that decision.** Two gates sit
|
|
47
|
+
* beside it and are unchanged: an app record must arrive as a v2 (chained)
|
|
48
|
+
* envelope, and `oxyVerificationResolver` accepts exactly one custodial issuer
|
|
49
|
+
* (`OXY_DID`). So a record a user signs themselves verifies here today, while
|
|
50
|
+
* one an app signs custodially under its OWN issuer DID does not — that needs a
|
|
51
|
+
* separate, deliberate answer about which issuers may write to a person's chain.
|
|
52
|
+
*
|
|
53
|
+
* Platform-agnostic — zod only, no react/react-native/expo, ESM-safe.
|
|
54
|
+
*/
|
|
55
|
+
import { z } from 'zod';
|
|
56
|
+
export declare const oxySignedRecordTypeSchema: z.ZodEnum<["identity", "profile", "reputation_attestation", "real_life_attestation", "validation_verdict", "personhood_vouch", "credential", "node", "app_record"]>;
|
|
57
|
+
/**
|
|
58
|
+
* The closed set of record categories the Oxy identity/civic/node store accepts.
|
|
59
|
+
* The base envelope `type` is an open string; this is what the Oxy store
|
|
60
|
+
* re-narrows it to.
|
|
61
|
+
*/
|
|
62
|
+
export type OxySignedRecordType = z.infer<typeof oxySignedRecordTypeSchema>;
|