@oxyhq/crowdsource-contracts 0.2.0 → 0.4.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/appeals.d.ts +323 -0
- package/dist/appeals.d.ts.map +1 -0
- package/dist/appeals.js +203 -0
- package/dist/appeals.js.map +1 -0
- package/dist/case-envelope.d.ts +59 -59
- package/dist/case-envelope.d.ts.map +1 -1
- package/dist/case-envelope.js +32 -32
- package/dist/case-envelope.js.map +1 -1
- package/dist/decisions.d.ts +3 -3
- package/dist/decisions.d.ts.map +1 -1
- package/dist/decisions.js +28 -28
- package/dist/decisions.js.map +1 -1
- package/dist/esm/appeals.js +200 -0
- package/dist/esm/appeals.js.map +1 -0
- package/dist/esm/case-envelope.js +380 -0
- package/dist/esm/case-envelope.js.map +1 -0
- package/dist/esm/closed.js +32 -0
- package/dist/esm/closed.js.map +1 -0
- package/dist/esm/decisions.js +195 -0
- package/dist/esm/decisions.js.map +1 -0
- package/dist/esm/index.js +48 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/json-schema.js +84 -0
- package/dist/esm/json-schema.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/policies.js +175 -0
- package/dist/esm/policies.js.map +1 -0
- package/dist/esm/primitives.js +249 -0
- package/dist/esm/primitives.js.map +1 -0
- package/dist/esm/reputation-events.js +125 -0
- package/dist/esm/reputation-events.js.map +1 -0
- package/dist/esm/resources.js +455 -0
- package/dist/esm/resources.js.map +1 -0
- package/dist/esm/reviewer-surface.js +612 -0
- package/dist/esm/reviewer-surface.js.map +1 -0
- package/dist/esm/reviews.js +141 -0
- package/dist/esm/reviews.js.map +1 -0
- package/dist/esm/taxonomy.js +278 -0
- package/dist/esm/taxonomy.js.map +1 -0
- package/dist/esm/webhooks.js +188 -0
- package/dist/esm/webhooks.js.map +1 -0
- package/dist/index.d.ts +13 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -11
- package/dist/index.js.map +1 -1
- package/dist/json-schema.d.ts +2 -2
- package/dist/json-schema.d.ts.map +1 -1
- package/dist/json-schema.js +26 -21
- package/dist/json-schema.js.map +1 -1
- package/dist/policies.d.ts +1 -1
- package/dist/policies.d.ts.map +1 -1
- package/dist/policies.js +14 -14
- package/dist/policies.js.map +1 -1
- package/dist/primitives.d.ts +17 -0
- package/dist/primitives.d.ts.map +1 -1
- package/dist/primitives.js +22 -1
- package/dist/primitives.js.map +1 -1
- package/dist/reputation-events.js +19 -19
- package/dist/reputation-events.js.map +1 -1
- package/dist/resources.d.ts +116 -39
- package/dist/resources.d.ts.map +1 -1
- package/dist/resources.js +143 -121
- package/dist/resources.js.map +1 -1
- package/dist/reviewer-surface.d.ts +1956 -0
- package/dist/reviewer-surface.d.ts.map +1 -0
- package/dist/reviewer-surface.js +615 -0
- package/dist/reviewer-surface.js.map +1 -0
- package/dist/reviews.d.ts +2 -2
- package/dist/reviews.js +15 -15
- package/dist/reviews.js.map +1 -1
- package/dist/webhooks.d.ts +4 -4
- package/dist/webhooks.d.ts.map +1 -1
- package/dist/webhooks.js +18 -18
- package/dist/webhooks.js.map +1 -1
- package/package.json +4 -4
- package/src/appeals.ts +229 -0
- package/src/case-envelope.ts +5 -5
- package/src/decisions.ts +6 -6
- package/src/index.ts +13 -11
- package/src/json-schema.ts +13 -8
- package/src/policies.ts +3 -3
- package/src/primitives.ts +25 -0
- package/src/reputation-events.ts +4 -4
- package/src/resources.ts +136 -100
- package/src/reviewer-surface.ts +715 -0
- package/src/reviews.ts +4 -4
- package/src/webhooks.ts +4 -4
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The internal reputation event (§11.5, §11.6, §11.7).
|
|
3
|
+
*
|
|
4
|
+
* This is the only thing CrowdSource ever sends toward Oxy Trust, and it is a
|
|
5
|
+
* statement, not an instruction. "CrowdSource does not write to reputation
|
|
6
|
+
* collections. It publishes an authenticated internal event" (§11.5), and Oxy
|
|
7
|
+
* Trust's own consequence engine decides what, if anything, follows. Nothing in
|
|
8
|
+
* this payload names points, a tier, a strike or a standing: an application —
|
|
9
|
+
* and CrowdSource on its behalf — never chooses an Oxy reputation figure.
|
|
10
|
+
*
|
|
11
|
+
* Three of §11.7's eight pre-effect validations are structural, and all three
|
|
12
|
+
* are moved into the type rather than left to a runtime check that a future
|
|
13
|
+
* refactor can drop:
|
|
14
|
+
*
|
|
15
|
+
* * §11.7.4 — `subject.bindingProofId` is required. "No binding proof, no Oxy
|
|
16
|
+
* Trust effect" becomes an event that cannot be constructed.
|
|
17
|
+
* * §11.7.5 — a finding's scope must be `oxy_network` or `identity_integrity`.
|
|
18
|
+
* `application_local` cannot appear here at all, which is §6.5's rule that
|
|
19
|
+
* a local restriction does not become a global sanction, enforced at the
|
|
20
|
+
* wire rather than by the receiver's diligence.
|
|
21
|
+
* * §11.7.8 — the decision may not be superseded or corrected, so the status
|
|
22
|
+
* enum has only the two values that may carry an effect (§11.7.3).
|
|
23
|
+
*
|
|
24
|
+
* The remaining five are stateful — who signed it, whether this event was seen
|
|
25
|
+
* before, whether the incident already produced an equivalent effect — and stay
|
|
26
|
+
* with the bridge.
|
|
27
|
+
*
|
|
28
|
+
* This is the one payload in the package that is `.strict()` in the OUTBOUND
|
|
29
|
+
* direction. §10.11's rule about unknown fields has an explicit exception for
|
|
30
|
+
* "where the schema forbids them for safety", and this is that case twice over:
|
|
31
|
+
* a finding here deliberately carries no `resourceIds` and no free text, so
|
|
32
|
+
* that nothing about the reviewed material reaches a reputation ledger or a
|
|
33
|
+
* signed attestation, and an unrecognised field is exactly how that would
|
|
34
|
+
* happen. Forward compatibility is handled by the `.v1` in the event type.
|
|
35
|
+
*/
|
|
36
|
+
import { z } from 'zod';
|
|
37
|
+
import { CONTRACT_LIMITS, IdentifierSchema, Sha256DigestSchema } from './primitives.js';
|
|
38
|
+
import { PrincipalTypeSchema } from './case-envelope.js';
|
|
39
|
+
import { ReputationPolicyVersionsSchema } from './policies.js';
|
|
40
|
+
import { FindingAttributionSchema, ReputationEligibleFindingScopeSchema, SeveritySchema, TaxonomyCodeSchema, } from './taxonomy.js';
|
|
41
|
+
/**
|
|
42
|
+
* §11.6 names one event type. §11.5 names four bridge operations — apply,
|
|
43
|
+
* finalize, reverse, reconcile — so siblings are expected, but the plan does
|
|
44
|
+
* not write them and they are not invented here. Adding one is additive: a new
|
|
45
|
+
* literal and a new variant, with the `.v1` suffix carrying the version.
|
|
46
|
+
*/
|
|
47
|
+
export const MODERATION_DECISION_FINALIZED_EVENT_TYPE = 'moderation.decision.finalized.v1';
|
|
48
|
+
/**
|
|
49
|
+
* §11.7.3 and §11.7.8 together: an effect may follow a final decision or,
|
|
50
|
+
* where policy allows, a provisional one — and never a superseded or corrected
|
|
51
|
+
* one. Those two states are absent from this enum rather than rejected by a
|
|
52
|
+
* refinement, so the impossibility is visible in the type.
|
|
53
|
+
*/
|
|
54
|
+
export const REPUTATION_EVENT_DECISION_STATUSES = ['provisional', 'final'];
|
|
55
|
+
export const ReputationEventDecisionStatusSchema = z.enum(REPUTATION_EVENT_DECISION_STATUSES);
|
|
56
|
+
/**
|
|
57
|
+
* Who the effect would land on (§11.6 `subject`).
|
|
58
|
+
*
|
|
59
|
+
* `bindingProofId` is required, unconditionally — see §11.7.4 above. The
|
|
60
|
+
* envelope's `principalBindings` make the same proof optional for non-Oxy
|
|
61
|
+
* principal types, because those can never reach this event; here there is
|
|
62
|
+
* nothing to be lenient about.
|
|
63
|
+
*/
|
|
64
|
+
export const ReputationEventSubjectSchema = z.strictObject({
|
|
65
|
+
principalType: PrincipalTypeSchema,
|
|
66
|
+
principalId: IdentifierSchema,
|
|
67
|
+
bindingProofId: IdentifierSchema,
|
|
68
|
+
});
|
|
69
|
+
/**
|
|
70
|
+
* A finding as Oxy Trust sees it (§11.6).
|
|
71
|
+
*
|
|
72
|
+
* Deliberately narrower than a `DecisionFinding`: no `resourceIds`, no policy
|
|
73
|
+
* rule ids, no text. Oxy Trust needs to know what was confirmed, how serious it
|
|
74
|
+
* was, how far it reaches and whose conduct it was — it does not need to know
|
|
75
|
+
* which piece of content it happened on, and §13.5's minimisation plus the
|
|
76
|
+
* invariant that sensitive content never appears in logs or public attestations
|
|
77
|
+
* mean it must not be told.
|
|
78
|
+
*
|
|
79
|
+
* `attribution` is required here where it is optional on a decision finding: an
|
|
80
|
+
* effect must land on somebody, and a finding that attributes nothing has
|
|
81
|
+
* nothing to contribute to this event.
|
|
82
|
+
*/
|
|
83
|
+
export const ReputationEventFindingSchema = z.strictObject({
|
|
84
|
+
code: TaxonomyCodeSchema,
|
|
85
|
+
severity: SeveritySchema,
|
|
86
|
+
scope: ReputationEligibleFindingScopeSchema,
|
|
87
|
+
attribution: FindingAttributionSchema,
|
|
88
|
+
});
|
|
89
|
+
/**
|
|
90
|
+
* `moderation.decision.finalized.v1` (§11.6).
|
|
91
|
+
*
|
|
92
|
+
* `incidentId` is what makes "one penalty per incident" enforceable: it is the
|
|
93
|
+
* first component of the effect's idempotency key (Appendix D:
|
|
94
|
+
* `incidentId + principalId + effectType + decisionRevision`), so the same
|
|
95
|
+
* incident reaching the bridge twice — from a replay, from a redelivery, from
|
|
96
|
+
* two cases that were merged — produces one effect.
|
|
97
|
+
*
|
|
98
|
+
* `proofHash` binds the event to the decision it reports, so an effect can be
|
|
99
|
+
* explained and, if the decision is later corrected, reversed against the exact
|
|
100
|
+
* revision that caused it.
|
|
101
|
+
*/
|
|
102
|
+
export const ModerationDecisionFinalizedEventSchema = z.strictObject({
|
|
103
|
+
eventId: IdentifierSchema,
|
|
104
|
+
type: z.literal(MODERATION_DECISION_FINALIZED_EVENT_TYPE),
|
|
105
|
+
caseId: IdentifierSchema,
|
|
106
|
+
incidentId: IdentifierSchema,
|
|
107
|
+
decisionId: IdentifierSchema,
|
|
108
|
+
decisionRevision: z.number().int().positive(),
|
|
109
|
+
applicationId: IdentifierSchema,
|
|
110
|
+
subject: ReputationEventSubjectSchema,
|
|
111
|
+
findings: z.array(ReputationEventFindingSchema).min(1).max(CONTRACT_LIMITS.FINDINGS_MAX),
|
|
112
|
+
decisionStatus: ReputationEventDecisionStatusSchema,
|
|
113
|
+
policyVersions: ReputationPolicyVersionsSchema,
|
|
114
|
+
proofHash: Sha256DigestSchema,
|
|
115
|
+
});
|
|
116
|
+
/**
|
|
117
|
+
* Every reputation event CrowdSource emits.
|
|
118
|
+
*
|
|
119
|
+
* A union of one today. It exists so consumers switch on `type` from the start
|
|
120
|
+
* and adding §11.5's remaining operations does not change how they are written.
|
|
121
|
+
*/
|
|
122
|
+
export const ReputationEventSchema = z.discriminatedUnion('type', [
|
|
123
|
+
ModerationDecisionFinalizedEventSchema,
|
|
124
|
+
]);
|
|
125
|
+
//# sourceMappingURL=reputation-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reputation-events.js","sourceRoot":"","sources":["../../src/reputation-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACxF,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EACL,wBAAwB,EACxB,oCAAoC,EACpC,cAAc,EACd,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAEvB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wCAAwC,GAAG,kCAAkC,CAAC;AAE3F;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAU,CAAC;AACpF,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;AAG9F;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,YAAY,CAAC;IACzD,aAAa,EAAE,mBAAmB;IAClC,WAAW,EAAE,gBAAgB;IAC7B,cAAc,EAAE,gBAAgB;CACjC,CAAC,CAAC;AAGH;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,YAAY,CAAC;IACzD,IAAI,EAAE,kBAAkB;IACxB,QAAQ,EAAE,cAAc;IACxB,KAAK,EAAE,oCAAoC;IAC3C,WAAW,EAAE,wBAAwB;CACtC,CAAC,CAAC;AAGH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,sCAAsC,GAAG,CAAC,CAAC,YAAY,CAAC;IACnE,OAAO,EAAE,gBAAgB;IACzB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,wCAAwC,CAAC;IACzD,MAAM,EAAE,gBAAgB;IACxB,UAAU,EAAE,gBAAgB;IAC5B,UAAU,EAAE,gBAAgB;IAC5B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC7C,aAAa,EAAE,gBAAgB;IAC/B,OAAO,EAAE,4BAA4B;IACrC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC;IACxF,cAAc,EAAE,mCAAmC;IACnD,cAAc,EAAE,8BAA8B;IAC9C,SAAS,EAAE,kBAAkB;CAC9B,CAAC,CAAC;AAKH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAChE,sCAAsC;CACvC,CAAC,CAAC"}
|
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resources and relations — the universal content unit (§5.2–§5.7).
|
|
3
|
+
*
|
|
4
|
+
* "Applications send data, never executable code" (§5.2). Everything in this
|
|
5
|
+
* module follows from that one sentence:
|
|
6
|
+
*
|
|
7
|
+
* * The resource union is CLOSED and discriminated on `type`, and each
|
|
8
|
+
* variant declares exactly which fields it may carry. There is no free-form
|
|
9
|
+
* branch, so there is no place to put a rendering instruction.
|
|
10
|
+
* * Every object is `.strict()`. In the outbound direction an unknown field
|
|
11
|
+
* is harmless forward compatibility (§10.11); inbound it is not. A field
|
|
12
|
+
* that is silently dropped is context an application believes it sent and a
|
|
13
|
+
* jury never sees — which is how a case gets decided on incomplete material
|
|
14
|
+
* — and a field that is silently kept is a rendering input nobody reviewed.
|
|
15
|
+
* §10.11 makes exactly this exception: unknown fields must not break
|
|
16
|
+
* clients "except where the schema forbids them for safety".
|
|
17
|
+
* * A media type must agree with its resource type, so an `image` cannot
|
|
18
|
+
* declare `text/html` and be handed to something that trusts the label.
|
|
19
|
+
* * §5.7 custom payloads are bounded JSON with no `$`-prefixed keys, which
|
|
20
|
+
* removes every JSON Schema reference mechanism at once — `$ref` to a
|
|
21
|
+
* remote document IS the "remote component" §5.7 forbids, and resolving one
|
|
22
|
+
* is an SSRF against CrowdSource itself.
|
|
23
|
+
*
|
|
24
|
+
* What is deliberately NOT here: any filter on the CONTENT of text fields. The
|
|
25
|
+
* material under review is hostile by definition — a harassment report quotes
|
|
26
|
+
* the harassment, a phishing report quotes the phishing link. A lexical
|
|
27
|
+
* blocklist would reject the evidence and protect nothing, because the contract
|
|
28
|
+
* has no field whose value is ever interpreted as markup or code.
|
|
29
|
+
*/
|
|
30
|
+
import { z } from 'zod';
|
|
31
|
+
import { CONTRACT_LIMITS, CustomPayloadSchema, HttpUrlSchema, IdentifierSchema, LanguageTagSchema, MetadataBagSchema, MimeTypeSchema, OxyFileIdSchema, Sha256DigestSchema, TimestampSchema, } from './primitives.js';
|
|
32
|
+
import { PolicyVersionSchema } from './policies.js';
|
|
33
|
+
import { SensitivityHintSchema } from './taxonomy.js';
|
|
34
|
+
/** A resource id, unique within one envelope (§5.2 `id`). */
|
|
35
|
+
export const ResourceIdSchema = IdentifierSchema;
|
|
36
|
+
/**
|
|
37
|
+
* A pseudonymous reference to an actor, resolved within one envelope.
|
|
38
|
+
*
|
|
39
|
+
* Never a real identity: §13.5 requires a pseudonymous principal wherever one
|
|
40
|
+
* suffices. `principalBindings` is the only place a ref is tied to anything,
|
|
41
|
+
* and even there it is tied to a binding proof id, not to a name.
|
|
42
|
+
*/
|
|
43
|
+
export const PrincipalRefSchema = IdentifierSchema;
|
|
44
|
+
/** §5.2 `role`: why this resource is in the case. */
|
|
45
|
+
export const RESOURCE_ROLES = [
|
|
46
|
+
'subject',
|
|
47
|
+
'attachment',
|
|
48
|
+
'context',
|
|
49
|
+
'parent',
|
|
50
|
+
'quoted',
|
|
51
|
+
'evidence',
|
|
52
|
+
'metadata',
|
|
53
|
+
'policy_context',
|
|
54
|
+
];
|
|
55
|
+
export const ResourceRoleSchema = z.enum(RESOURCE_ROLES);
|
|
56
|
+
/** §5.3 standard resource types. */
|
|
57
|
+
export const RESOURCE_TYPES = [
|
|
58
|
+
'text',
|
|
59
|
+
'image',
|
|
60
|
+
'video',
|
|
61
|
+
'audio',
|
|
62
|
+
'document',
|
|
63
|
+
'link',
|
|
64
|
+
'profile',
|
|
65
|
+
'conversation',
|
|
66
|
+
'listing',
|
|
67
|
+
'location',
|
|
68
|
+
'metadata',
|
|
69
|
+
'custom',
|
|
70
|
+
];
|
|
71
|
+
export const ResourceTypeSchema = z.enum(RESOURCE_TYPES);
|
|
72
|
+
/** §5.3 text formatting. Never HTML: `markdown_subset` is a subset for a reason. */
|
|
73
|
+
export const TEXT_FORMATTINGS = ['plain', 'markdown_subset'];
|
|
74
|
+
export const TextFormattingSchema = z.enum(TEXT_FORMATTINGS);
|
|
75
|
+
/**
|
|
76
|
+
* A reference to bytes held outside the envelope (§5.2 `asset`).
|
|
77
|
+
*
|
|
78
|
+
* **`fileId` is where the bytes are. `url` is where they came from.** Those are
|
|
79
|
+
* not alternatives, and the earlier contract encoding them as "exactly one of
|
|
80
|
+
* `uploadId` or `url`" is what left an integrator with no safe way to attach an
|
|
81
|
+
* image at all: the `uploadId` branch needed a presigned upload route that was
|
|
82
|
+
* superseded by the Oxy media chokepoint before it was ever built, and the `url`
|
|
83
|
+
* branch put a URL on the reporting application's own host in front of a
|
|
84
|
+
* reviewer — breaking §9.1's branding rule and the chokepoint rule at once.
|
|
85
|
+
*
|
|
86
|
+
* So `fileId` is required and `url` is optional provenance:
|
|
87
|
+
*
|
|
88
|
+
* * **`fileId`** — a bare Oxy file id. The application uploads the bytes
|
|
89
|
+
* through the Oxy media chokepoint with its own Oxy credentials and passes
|
|
90
|
+
* the id. That is why CrowdSource serves no upload route of its own.
|
|
91
|
+
* * **`url`** — a PROVENANCE RECORD, and never a fetch target. A third-party
|
|
92
|
+
* URL is not wrong the way a first-party one is (a federated post's image
|
|
93
|
+
* genuinely lives elsewhere), but no reviewer client may dereference it:
|
|
94
|
+
* fetching it would tell that host exactly when its content is under review,
|
|
95
|
+
* which lets the reported party correlate reviewer accesses, and it would
|
|
96
|
+
* deliver bytes live rather than the pinned ones §5.6 requires.
|
|
97
|
+
*
|
|
98
|
+
* `sha256` stays required, and requiring `fileId` alongside it costs an
|
|
99
|
+
* integrator nothing new — an application able to compute that digest already
|
|
100
|
+
* holds the bytes. What changes is that it puts bytes it already has somewhere a
|
|
101
|
+
* reviewer can read safely, instead of pointing at its own host.
|
|
102
|
+
*/
|
|
103
|
+
export const AssetRefSchema = z.strictObject({
|
|
104
|
+
/** Bare Oxy file id. The only source of the bytes a jury sees. */
|
|
105
|
+
fileId: OxyFileIdSchema,
|
|
106
|
+
/** Where the material was found. Recorded, never fetched — see above. */
|
|
107
|
+
url: HttpUrlSchema.optional(),
|
|
108
|
+
mimeType: MimeTypeSchema,
|
|
109
|
+
sha256: Sha256DigestSchema,
|
|
110
|
+
sizeBytes: z.number().int().positive().optional(),
|
|
111
|
+
width: z.number().int().positive().optional(),
|
|
112
|
+
height: z.number().int().positive().optional(),
|
|
113
|
+
durationSeconds: z.number().positive().optional(),
|
|
114
|
+
});
|
|
115
|
+
const mediaTypeMismatch = (ctx, mimeType, allowedPrefixes) => {
|
|
116
|
+
if (!allowedPrefixes.some((prefix) => mimeType.startsWith(prefix))) {
|
|
117
|
+
ctx.addIssue({
|
|
118
|
+
code: 'custom',
|
|
119
|
+
path: ['asset', 'mimeType'],
|
|
120
|
+
message: `must be one of ${allowedPrefixes.join(', ')}* for this resource type`,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
const resourceBaseShape = {
|
|
125
|
+
id: ResourceIdSchema,
|
|
126
|
+
role: ResourceRoleSchema,
|
|
127
|
+
/** §5.2: BCP 47 "where applicable" — a text of unknown language is real. */
|
|
128
|
+
language: LanguageTagSchema.optional(),
|
|
129
|
+
/** §5.2: the moment of the ORIGINAL object, not of the report. */
|
|
130
|
+
createdAt: TimestampSchema.optional(),
|
|
131
|
+
authorPrincipalRef: PrincipalRefSchema.optional(),
|
|
132
|
+
/** §5.2: a prior classification of exposure, never shown as a verdict. */
|
|
133
|
+
sensitivity: SensitivityHintSchema.optional(),
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* `sha256` is required on every resource whose content travels inline, and
|
|
137
|
+
* optional on asset-backed ones where `asset.sha256` carries it instead.
|
|
138
|
+
*
|
|
139
|
+
* That split is not a preference; it is what both reference envelopes do.
|
|
140
|
+
* Appendix A's `res_post` and `res_parent` carry a top-level digest and its
|
|
141
|
+
* `res_image` carries the digest on the asset only. §5.6 asks for "SHA 256 of
|
|
142
|
+
* each resource", so one of the two is always present.
|
|
143
|
+
*/
|
|
144
|
+
const inlineResourceShape = { ...resourceBaseShape, sha256: Sha256DigestSchema };
|
|
145
|
+
const assetResourceShape = { ...resourceBaseShape, sha256: Sha256DigestSchema.optional() };
|
|
146
|
+
/**
|
|
147
|
+
* The `data` of each resource type, named.
|
|
148
|
+
*
|
|
149
|
+
* Extracted so the reviewer surface (`reviewer-surface.ts`) can build its own
|
|
150
|
+
* resource union — same content, no `sha256`, a media handle instead of an asset
|
|
151
|
+
* locator — out of THESE schemas rather than restating twelve content shapes.
|
|
152
|
+
* A second copy would drift, and the direction it would drift in is a jury shown
|
|
153
|
+
* less than the application sent.
|
|
154
|
+
*/
|
|
155
|
+
export const TextResourceDataSchema = z.strictObject({
|
|
156
|
+
text: z.string().min(1).max(CONTRACT_LIMITS.TEXT_RESOURCE_MAX_LENGTH),
|
|
157
|
+
formatting: TextFormattingSchema.optional(),
|
|
158
|
+
});
|
|
159
|
+
const TextResourceSchema = z.strictObject({
|
|
160
|
+
...inlineResourceShape,
|
|
161
|
+
type: z.literal('text'),
|
|
162
|
+
data: TextResourceDataSchema,
|
|
163
|
+
});
|
|
164
|
+
export const VideoResourceDataSchema = z.strictObject({
|
|
165
|
+
timeRange: z
|
|
166
|
+
.strictObject({
|
|
167
|
+
startSeconds: z.number().nonnegative(),
|
|
168
|
+
endSeconds: z.number().positive(),
|
|
169
|
+
})
|
|
170
|
+
.refine((range) => range.endSeconds > range.startSeconds, {
|
|
171
|
+
message: 'endSeconds must be greater than startSeconds',
|
|
172
|
+
path: ['endSeconds'],
|
|
173
|
+
})
|
|
174
|
+
.optional(),
|
|
175
|
+
});
|
|
176
|
+
export const AudioResourceDataSchema = z.strictObject({
|
|
177
|
+
transcript: z.string().max(CONTRACT_LIMITS.EXTRACTED_TEXT_MAX_LENGTH).optional(),
|
|
178
|
+
});
|
|
179
|
+
export const DocumentResourceDataSchema = z.strictObject({
|
|
180
|
+
title: z.string().min(1).max(CONTRACT_LIMITS.SHORT_TEXT_MAX_LENGTH),
|
|
181
|
+
extractedText: z.string().max(CONTRACT_LIMITS.EXTRACTED_TEXT_MAX_LENGTH).optional(),
|
|
182
|
+
});
|
|
183
|
+
const ImageResourceSchema = z
|
|
184
|
+
.strictObject({
|
|
185
|
+
...assetResourceShape,
|
|
186
|
+
type: z.literal('image'),
|
|
187
|
+
asset: AssetRefSchema,
|
|
188
|
+
})
|
|
189
|
+
.superRefine((resource, ctx) => mediaTypeMismatch(ctx, resource.asset.mimeType, ['image/']));
|
|
190
|
+
const VideoResourceSchema = z
|
|
191
|
+
.strictObject({
|
|
192
|
+
...assetResourceShape,
|
|
193
|
+
type: z.literal('video'),
|
|
194
|
+
asset: AssetRefSchema,
|
|
195
|
+
data: VideoResourceDataSchema.optional(),
|
|
196
|
+
})
|
|
197
|
+
.superRefine((resource, ctx) => {
|
|
198
|
+
mediaTypeMismatch(ctx, resource.asset.mimeType, ['video/']);
|
|
199
|
+
if (resource.asset.durationSeconds === undefined) {
|
|
200
|
+
ctx.addIssue({
|
|
201
|
+
code: 'custom',
|
|
202
|
+
path: ['asset', 'durationSeconds'],
|
|
203
|
+
message: 'a video asset must declare durationSeconds',
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
const AudioResourceSchema = z
|
|
208
|
+
.strictObject({
|
|
209
|
+
...assetResourceShape,
|
|
210
|
+
type: z.literal('audio'),
|
|
211
|
+
asset: AssetRefSchema,
|
|
212
|
+
data: AudioResourceDataSchema.optional(),
|
|
213
|
+
})
|
|
214
|
+
.superRefine((resource, ctx) => {
|
|
215
|
+
mediaTypeMismatch(ctx, resource.asset.mimeType, ['audio/']);
|
|
216
|
+
if (resource.asset.durationSeconds === undefined) {
|
|
217
|
+
ctx.addIssue({
|
|
218
|
+
code: 'custom',
|
|
219
|
+
path: ['asset', 'durationSeconds'],
|
|
220
|
+
message: 'an audio asset must declare durationSeconds',
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
const DocumentResourceSchema = z
|
|
225
|
+
.strictObject({
|
|
226
|
+
...assetResourceShape,
|
|
227
|
+
type: z.literal('document'),
|
|
228
|
+
asset: AssetRefSchema,
|
|
229
|
+
data: DocumentResourceDataSchema,
|
|
230
|
+
})
|
|
231
|
+
.superRefine((resource, ctx) => mediaTypeMismatch(ctx, resource.asset.mimeType, ['application/', 'text/']));
|
|
232
|
+
export const LinkResourceDataSchema = z.strictObject({
|
|
233
|
+
url: HttpUrlSchema,
|
|
234
|
+
title: z.string().max(CONTRACT_LIMITS.SHORT_TEXT_MAX_LENGTH).optional(),
|
|
235
|
+
resolvedHost: z
|
|
236
|
+
.string()
|
|
237
|
+
.max(253)
|
|
238
|
+
.regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/, 'must be a hostname')
|
|
239
|
+
.optional(),
|
|
240
|
+
snapshot: z.string().max(CONTRACT_LIMITS.EXTRACTED_TEXT_MAX_LENGTH).optional(),
|
|
241
|
+
});
|
|
242
|
+
const LinkResourceSchema = z.strictObject({
|
|
243
|
+
...inlineResourceShape,
|
|
244
|
+
type: z.literal('link'),
|
|
245
|
+
data: LinkResourceDataSchema,
|
|
246
|
+
});
|
|
247
|
+
export const ProfileResourceDataSchema = z.strictObject({
|
|
248
|
+
/**
|
|
249
|
+
* Every field is optional on purpose. A federated or unresolved actor
|
|
250
|
+
* routinely has no display name, and requiring one would push applications
|
|
251
|
+
* into synthesising a name — the opposite of what the profile-identity rule
|
|
252
|
+
* in the ecosystem instructions asks for.
|
|
253
|
+
*/
|
|
254
|
+
displayName: z.string().max(CONTRACT_LIMITS.SHORT_TEXT_MAX_LENGTH).optional(),
|
|
255
|
+
bio: z.string().max(CONTRACT_LIMITS.LONG_TEXT_MAX_LENGTH).optional(),
|
|
256
|
+
/** An `image` resource in the same envelope. */
|
|
257
|
+
avatarRef: ResourceIdSchema.optional(),
|
|
258
|
+
claims: MetadataBagSchema.optional(),
|
|
259
|
+
});
|
|
260
|
+
const ProfileResourceSchema = z.strictObject({
|
|
261
|
+
...inlineResourceShape,
|
|
262
|
+
type: z.literal('profile'),
|
|
263
|
+
data: ProfileResourceDataSchema,
|
|
264
|
+
});
|
|
265
|
+
export const ConversationResourceDataSchema = z.strictObject({
|
|
266
|
+
/**
|
|
267
|
+
* Ordered (§5.3). §13.5 asks for five messages around the incident rather
|
|
268
|
+
* than the whole thread, which is why this is a bounded list of ids the
|
|
269
|
+
* application chose, not a pointer to a conversation.
|
|
270
|
+
*/
|
|
271
|
+
messageResourceIds: z
|
|
272
|
+
.array(ResourceIdSchema)
|
|
273
|
+
.min(1)
|
|
274
|
+
.max(CONTRACT_LIMITS.CONVERSATION_MESSAGES_MAX),
|
|
275
|
+
});
|
|
276
|
+
const ConversationResourceSchema = z.strictObject({
|
|
277
|
+
...inlineResourceShape,
|
|
278
|
+
type: z.literal('conversation'),
|
|
279
|
+
data: ConversationResourceDataSchema,
|
|
280
|
+
});
|
|
281
|
+
export const ListingResourceDataSchema = z.strictObject({
|
|
282
|
+
title: z.string().min(1).max(CONTRACT_LIMITS.SHORT_TEXT_MAX_LENGTH),
|
|
283
|
+
description: z.string().max(CONTRACT_LIMITS.LONG_TEXT_MAX_LENGTH).optional(),
|
|
284
|
+
price: z.number().finite().nonnegative().optional(),
|
|
285
|
+
currency: z
|
|
286
|
+
.string()
|
|
287
|
+
.regex(/^[A-Z]{3}$/, 'must be an ISO 4217 alphabetic code')
|
|
288
|
+
.optional(),
|
|
289
|
+
sellerRef: PrincipalRefSchema.optional(),
|
|
290
|
+
mediaRefs: z.array(ResourceIdSchema).max(CONTRACT_LIMITS.LISTING_MEDIA_REFS_MAX).optional(),
|
|
291
|
+
});
|
|
292
|
+
const ListingResourceSchema = z
|
|
293
|
+
.strictObject({
|
|
294
|
+
...inlineResourceShape,
|
|
295
|
+
type: z.literal('listing'),
|
|
296
|
+
data: ListingResourceDataSchema,
|
|
297
|
+
})
|
|
298
|
+
.superRefine((resource, ctx) => {
|
|
299
|
+
const hasPrice = resource.data.price !== undefined;
|
|
300
|
+
const hasCurrency = resource.data.currency !== undefined;
|
|
301
|
+
if (hasPrice !== hasCurrency) {
|
|
302
|
+
ctx.addIssue({
|
|
303
|
+
code: 'custom',
|
|
304
|
+
path: ['data', hasPrice ? 'currency' : 'price'],
|
|
305
|
+
message: 'price and currency must travel together',
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
/** Two decimal places ≈ 1.1 km — coarse enough not to locate a person. */
|
|
310
|
+
const COARSE_COORDINATE_DECIMALS = 2;
|
|
311
|
+
const isCoarse = (value) => Number.isInteger(value * 10 ** COARSE_COORDINATE_DECIMALS);
|
|
312
|
+
export const LocationResourceDataSchema = z.strictObject({
|
|
313
|
+
label: z.string().max(CONTRACT_LIMITS.SHORT_TEXT_MAX_LENGTH).optional(),
|
|
314
|
+
latitude: z.number().min(-90).max(90).optional(),
|
|
315
|
+
longitude: z.number().min(-180).max(180).optional(),
|
|
316
|
+
});
|
|
317
|
+
const LocationResourceSchema = z
|
|
318
|
+
.strictObject({
|
|
319
|
+
...inlineResourceShape,
|
|
320
|
+
type: z.literal('location'),
|
|
321
|
+
data: LocationResourceDataSchema,
|
|
322
|
+
})
|
|
323
|
+
.superRefine((resource, ctx) => {
|
|
324
|
+
const { label, latitude, longitude } = resource.data;
|
|
325
|
+
if (label === undefined && latitude === undefined && longitude === undefined) {
|
|
326
|
+
ctx.addIssue({
|
|
327
|
+
code: 'custom',
|
|
328
|
+
path: ['data'],
|
|
329
|
+
message: 'a location must carry a label, coordinates, or both',
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
if ((latitude === undefined) !== (longitude === undefined)) {
|
|
333
|
+
ctx.addIssue({
|
|
334
|
+
code: 'custom',
|
|
335
|
+
path: ['data', latitude === undefined ? 'latitude' : 'longitude'],
|
|
336
|
+
message: 'latitude and longitude must travel together',
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* §5.3 says "coarse location or place label" and §13.5 requires precise
|
|
341
|
+
* location to be redacted before community review. Precision is a property
|
|
342
|
+
* of the number itself, so the contract can refuse the precise value rather
|
|
343
|
+
* than trusting every downstream renderer to round it.
|
|
344
|
+
*/
|
|
345
|
+
if (latitude !== undefined && !isCoarse(latitude)) {
|
|
346
|
+
ctx.addIssue({
|
|
347
|
+
code: 'custom',
|
|
348
|
+
path: ['data', 'latitude'],
|
|
349
|
+
message: `must be coarse: at most ${COARSE_COORDINATE_DECIMALS} decimal places`,
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
if (longitude !== undefined && !isCoarse(longitude)) {
|
|
353
|
+
ctx.addIssue({
|
|
354
|
+
code: 'custom',
|
|
355
|
+
path: ['data', 'longitude'],
|
|
356
|
+
message: `must be coarse: at most ${COARSE_COORDINATE_DECIMALS} decimal places`,
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
export const MetadataResourceDataSchema = MetadataBagSchema.refine((bag) => Object.keys(bag).length >= 1, { message: 'a metadata resource must carry at least one field' });
|
|
361
|
+
const MetadataResourceSchema = z.strictObject({
|
|
362
|
+
...inlineResourceShape,
|
|
363
|
+
type: z.literal('metadata'),
|
|
364
|
+
data: MetadataResourceDataSchema,
|
|
365
|
+
});
|
|
366
|
+
const CustomResourceSchema = z.strictObject({
|
|
367
|
+
...inlineResourceShape,
|
|
368
|
+
type: z.literal('custom'),
|
|
369
|
+
/** The schema the application registered for this shape (§5.7). */
|
|
370
|
+
schemaId: IdentifierSchema,
|
|
371
|
+
/**
|
|
372
|
+
* Validated twice: structurally here, then against the registered JSON Schema
|
|
373
|
+
* at ingress. The registered schema decides what the fields MEAN; this decides
|
|
374
|
+
* that they are fields at all.
|
|
375
|
+
*/
|
|
376
|
+
payload: CustomPayloadSchema,
|
|
377
|
+
});
|
|
378
|
+
/**
|
|
379
|
+
* One resource (§5.2).
|
|
380
|
+
*
|
|
381
|
+
* A discriminated union rather than one object with everything optional: the
|
|
382
|
+
* latter would accept an `image` with inline text and no asset, which is not a
|
|
383
|
+
* resource anybody can review.
|
|
384
|
+
*/
|
|
385
|
+
export const ResourceSchema = z.discriminatedUnion('type', [
|
|
386
|
+
TextResourceSchema,
|
|
387
|
+
ImageResourceSchema,
|
|
388
|
+
VideoResourceSchema,
|
|
389
|
+
AudioResourceSchema,
|
|
390
|
+
DocumentResourceSchema,
|
|
391
|
+
LinkResourceSchema,
|
|
392
|
+
ProfileResourceSchema,
|
|
393
|
+
ConversationResourceSchema,
|
|
394
|
+
ListingResourceSchema,
|
|
395
|
+
LocationResourceSchema,
|
|
396
|
+
MetadataResourceSchema,
|
|
397
|
+
CustomResourceSchema,
|
|
398
|
+
]);
|
|
399
|
+
/** §5.5 relation types. */
|
|
400
|
+
export const RELATION_TYPES = [
|
|
401
|
+
'has_attachment',
|
|
402
|
+
'replies_to',
|
|
403
|
+
'quotes',
|
|
404
|
+
'authored_by',
|
|
405
|
+
'contextualizes',
|
|
406
|
+
'previous_version',
|
|
407
|
+
'contains',
|
|
408
|
+
'refers_to',
|
|
409
|
+
];
|
|
410
|
+
export const RelationTypeSchema = z.enum(RELATION_TYPES);
|
|
411
|
+
/**
|
|
412
|
+
* Relation types whose `to` names a principal rather than a resource.
|
|
413
|
+
*
|
|
414
|
+
* §5.5 defines `authored_by` as "a resource was created by a principal", so its
|
|
415
|
+
* target is a `principalRef`. Every other relation in the table joins two
|
|
416
|
+
* resources. No example in the plan exercises `authored_by`, so this reading is
|
|
417
|
+
* recorded here rather than assumed: it is what makes §5.5's "the backend must
|
|
418
|
+
* validate that every referenced id exists in the envelope" checkable at all,
|
|
419
|
+
* since the two id spaces are separate.
|
|
420
|
+
*/
|
|
421
|
+
export const PRINCIPAL_TARGETED_RELATION_TYPES = ['authored_by'];
|
|
422
|
+
/**
|
|
423
|
+
* A relation (§5.5).
|
|
424
|
+
*
|
|
425
|
+
* `from` and `to` are only shape-checked here. Whether they RESOLVE is decided
|
|
426
|
+
* by `CaseEnvelopeSchema`, which is the smallest scope that can see both the
|
|
427
|
+
* resource list and the principal list.
|
|
428
|
+
*/
|
|
429
|
+
export const RelationSchema = z.strictObject({
|
|
430
|
+
from: ResourceIdSchema,
|
|
431
|
+
type: RelationTypeSchema,
|
|
432
|
+
to: IdentifierSchema,
|
|
433
|
+
});
|
|
434
|
+
/**
|
|
435
|
+
* A custom resource schema an application registers (§5.7).
|
|
436
|
+
*
|
|
437
|
+
* `jsonSchema` reuses the custom-payload grammar, which forbids `$`-prefixed
|
|
438
|
+
* keys. That single restriction removes `$ref`, `$dynamicRef`, `$recursiveRef`
|
|
439
|
+
* and `$id` in one move — every mechanism by which a registered schema could
|
|
440
|
+
* point at a document CrowdSource would then have to fetch. §5.7's "no remote
|
|
441
|
+
* components" is not a rendering rule alone; a remote `$ref` is also an SSRF
|
|
442
|
+
* with a tenant holding the pen.
|
|
443
|
+
*
|
|
444
|
+
* The cost is `$defs`, `$schema` and `$comment`, which flat custom-field
|
|
445
|
+
* schemas do not need. Recursive tenant schemas are not supported and are not
|
|
446
|
+
* meant to be.
|
|
447
|
+
*/
|
|
448
|
+
export const ResourceSchemaRegistrationSchema = z.strictObject({
|
|
449
|
+
schemaId: IdentifierSchema,
|
|
450
|
+
version: PolicyVersionSchema,
|
|
451
|
+
title: z.string().min(1).max(CONTRACT_LIMITS.SHORT_TEXT_MAX_LENGTH),
|
|
452
|
+
description: z.string().max(CONTRACT_LIMITS.LONG_TEXT_MAX_LENGTH).optional(),
|
|
453
|
+
jsonSchema: CustomPayloadSchema,
|
|
454
|
+
});
|
|
455
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/resources.ts"],"names":[],"mappings":"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"}
|