@crowdsource.you/core 1.2.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.
Files changed (339) hide show
  1. package/README.md +571 -0
  2. package/dist/cases.d.ts +66 -0
  3. package/dist/cases.d.ts.map +1 -0
  4. package/dist/cases.js +79 -0
  5. package/dist/cases.js.map +1 -0
  6. package/dist/client.d.ts +90 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +125 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/communityNotes.d.ts +49 -0
  11. package/dist/communityNotes.d.ts.map +1 -0
  12. package/dist/communityNotes.js +104 -0
  13. package/dist/communityNotes.js.map +1 -0
  14. package/dist/credential.d.ts +58 -0
  15. package/dist/credential.d.ts.map +1 -0
  16. package/dist/credential.js +71 -0
  17. package/dist/credential.js.map +1 -0
  18. package/dist/defaults.d.ts +61 -0
  19. package/dist/defaults.d.ts.map +1 -0
  20. package/dist/defaults.js +82 -0
  21. package/dist/defaults.js.map +1 -0
  22. package/dist/digest.d.ts +44 -0
  23. package/dist/digest.d.ts.map +1 -0
  24. package/dist/digest.js +79 -0
  25. package/dist/digest.js.map +1 -0
  26. package/dist/envelope.d.ts +143 -0
  27. package/dist/envelope.d.ts.map +1 -0
  28. package/dist/envelope.js +258 -0
  29. package/dist/envelope.js.map +1 -0
  30. package/dist/errors.d.ts +90 -0
  31. package/dist/errors.d.ts.map +1 -0
  32. package/dist/errors.js +151 -0
  33. package/dist/errors.js.map +1 -0
  34. package/dist/esm/cases.js +74 -0
  35. package/dist/esm/cases.js.map +1 -0
  36. package/dist/esm/client.js +121 -0
  37. package/dist/esm/client.js.map +1 -0
  38. package/dist/esm/communityNotes.js +100 -0
  39. package/dist/esm/communityNotes.js.map +1 -0
  40. package/dist/esm/credential.js +67 -0
  41. package/dist/esm/credential.js.map +1 -0
  42. package/dist/esm/defaults.js +77 -0
  43. package/dist/esm/defaults.js.map +1 -0
  44. package/dist/esm/digest.js +74 -0
  45. package/dist/esm/digest.js.map +1 -0
  46. package/dist/esm/envelope.js +252 -0
  47. package/dist/esm/envelope.js.map +1 -0
  48. package/dist/esm/errors.js +140 -0
  49. package/dist/esm/errors.js.map +1 -0
  50. package/dist/esm/express/index.js +29 -0
  51. package/dist/esm/express/index.js.map +1 -0
  52. package/dist/esm/express/middleware.js +293 -0
  53. package/dist/esm/express/middleware.js.map +1 -0
  54. package/dist/esm/express/store.js +69 -0
  55. package/dist/esm/express/store.js.map +1 -0
  56. package/dist/esm/express/verify.js +133 -0
  57. package/dist/esm/express/verify.js.map +1 -0
  58. package/dist/esm/index.js +57 -0
  59. package/dist/esm/index.js.map +1 -0
  60. package/dist/esm/outbox/client.js +43 -0
  61. package/dist/esm/outbox/client.js.map +1 -0
  62. package/dist/esm/outbox/decision.js +153 -0
  63. package/dist/esm/outbox/decision.js.map +1 -0
  64. package/dist/esm/outbox/delivery.js +129 -0
  65. package/dist/esm/outbox/delivery.js.map +1 -0
  66. package/dist/esm/outbox/enforcement/executor.js +219 -0
  67. package/dist/esm/outbox/enforcement/executor.js.map +1 -0
  68. package/dist/esm/outbox/enforcement/planner.js +326 -0
  69. package/dist/esm/outbox/enforcement/planner.js.map +1 -0
  70. package/dist/esm/outbox/evidence.js +173 -0
  71. package/dist/esm/outbox/evidence.js.map +1 -0
  72. package/dist/esm/outbox/inbound.js +87 -0
  73. package/dist/esm/outbox/inbound.js.map +1 -0
  74. package/dist/esm/outbox/index.js +71 -0
  75. package/dist/esm/outbox/index.js.map +1 -0
  76. package/dist/esm/outbox/intake.js +140 -0
  77. package/dist/esm/outbox/intake.js.map +1 -0
  78. package/dist/esm/outbox/integration.js +116 -0
  79. package/dist/esm/outbox/integration.js.map +1 -0
  80. package/dist/esm/outbox/outbox/dispatcher.js +114 -0
  81. package/dist/esm/outbox/outbox/dispatcher.js.map +1 -0
  82. package/dist/esm/outbox/outbox/service.js +271 -0
  83. package/dist/esm/outbox/outbox/service.js.map +1 -0
  84. package/dist/esm/outbox/postgres/index.js +41 -0
  85. package/dist/esm/outbox/postgres/index.js.map +1 -0
  86. package/dist/esm/outbox/postgres/registries.js +155 -0
  87. package/dist/esm/outbox/postgres/registries.js.map +1 -0
  88. package/dist/esm/outbox/postgres/reportColumns.js +191 -0
  89. package/dist/esm/outbox/postgres/reportColumns.js.map +1 -0
  90. package/dist/esm/outbox/postgres/store/enforcement.js +158 -0
  91. package/dist/esm/outbox/postgres/store/enforcement.js.map +1 -0
  92. package/dist/esm/outbox/postgres/store/events.js +101 -0
  93. package/dist/esm/outbox/postgres/store/events.js.map +1 -0
  94. package/dist/esm/outbox/postgres/store/index.js +59 -0
  95. package/dist/esm/outbox/postgres/store/index.js.map +1 -0
  96. package/dist/esm/outbox/postgres/store/outbox.js +207 -0
  97. package/dist/esm/outbox/postgres/store/outbox.js.map +1 -0
  98. package/dist/esm/outbox/postgres/store/reports.js +231 -0
  99. package/dist/esm/outbox/postgres/store/reports.js.map +1 -0
  100. package/dist/esm/outbox/postgres/store/transaction.js +29 -0
  101. package/dist/esm/outbox/postgres/store/transaction.js.map +1 -0
  102. package/dist/esm/outbox/postgres/tables.js +270 -0
  103. package/dist/esm/outbox/postgres/tables.js.map +1 -0
  104. package/dist/esm/outbox/reconciliation.js +157 -0
  105. package/dist/esm/outbox/reconciliation.js.map +1 -0
  106. package/dist/esm/outbox/reportStatus.js +22 -0
  107. package/dist/esm/outbox/reportStatus.js.map +1 -0
  108. package/dist/esm/outbox/retention.js +33 -0
  109. package/dist/esm/outbox/retention.js.map +1 -0
  110. package/dist/esm/outbox/store/types.js +30 -0
  111. package/dist/esm/outbox/store/types.js.map +1 -0
  112. package/dist/esm/outbox/types.js +23 -0
  113. package/dist/esm/outbox/types.js.map +1 -0
  114. package/dist/esm/outbox/webhook.js +145 -0
  115. package/dist/esm/outbox/webhook.js.map +1 -0
  116. package/dist/esm/package.json +1 -0
  117. package/dist/esm/reports.js +74 -0
  118. package/dist/esm/reports.js.map +1 -0
  119. package/dist/esm/testing/fixtures.js +132 -0
  120. package/dist/esm/testing/fixtures.js.map +1 -0
  121. package/dist/esm/testing/index.js +33 -0
  122. package/dist/esm/testing/index.js.map +1 -0
  123. package/dist/esm/testing/sandbox.js +337 -0
  124. package/dist/esm/testing/sandbox.js.map +1 -0
  125. package/dist/esm/testing/webhook-simulator.js +93 -0
  126. package/dist/esm/testing/webhook-simulator.js.map +1 -0
  127. package/dist/esm/transport.js +177 -0
  128. package/dist/esm/transport.js.map +1 -0
  129. package/dist/esm/webhookEndpoints.js +139 -0
  130. package/dist/esm/webhookEndpoints.js.map +1 -0
  131. package/dist/express/index.d.ts +32 -0
  132. package/dist/express/index.d.ts.map +1 -0
  133. package/dist/express/index.js +40 -0
  134. package/dist/express/index.js.map +1 -0
  135. package/dist/express/middleware.d.ts +97 -0
  136. package/dist/express/middleware.d.ts.map +1 -0
  137. package/dist/express/middleware.js +298 -0
  138. package/dist/express/middleware.js.map +1 -0
  139. package/dist/express/store.d.ts +45 -0
  140. package/dist/express/store.d.ts.map +1 -0
  141. package/dist/express/store.js +72 -0
  142. package/dist/express/store.js.map +1 -0
  143. package/dist/express/verify.d.ts +86 -0
  144. package/dist/express/verify.d.ts.map +1 -0
  145. package/dist/express/verify.js +138 -0
  146. package/dist/express/verify.js.map +1 -0
  147. package/dist/index.d.ts +67 -0
  148. package/dist/index.d.ts.map +1 -0
  149. package/dist/index.js +89 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/outbox/client.d.ts +35 -0
  152. package/dist/outbox/client.d.ts.map +1 -0
  153. package/dist/outbox/client.js +46 -0
  154. package/dist/outbox/client.js.map +1 -0
  155. package/dist/outbox/decision.d.ts +36 -0
  156. package/dist/outbox/decision.d.ts.map +1 -0
  157. package/dist/outbox/decision.js +159 -0
  158. package/dist/outbox/decision.js.map +1 -0
  159. package/dist/outbox/delivery.d.ts +50 -0
  160. package/dist/outbox/delivery.d.ts.map +1 -0
  161. package/dist/outbox/delivery.js +135 -0
  162. package/dist/outbox/delivery.js.map +1 -0
  163. package/dist/outbox/enforcement/executor.d.ts +26 -0
  164. package/dist/outbox/enforcement/executor.d.ts.map +1 -0
  165. package/dist/outbox/enforcement/executor.js +222 -0
  166. package/dist/outbox/enforcement/executor.js.map +1 -0
  167. package/dist/outbox/enforcement/planner.d.ts +50 -0
  168. package/dist/outbox/enforcement/planner.d.ts.map +1 -0
  169. package/dist/outbox/enforcement/planner.js +333 -0
  170. package/dist/outbox/enforcement/planner.js.map +1 -0
  171. package/dist/outbox/evidence.d.ts +114 -0
  172. package/dist/outbox/evidence.d.ts.map +1 -0
  173. package/dist/outbox/evidence.js +181 -0
  174. package/dist/outbox/evidence.js.map +1 -0
  175. package/dist/outbox/inbound.d.ts +78 -0
  176. package/dist/outbox/inbound.d.ts.map +1 -0
  177. package/dist/outbox/inbound.js +91 -0
  178. package/dist/outbox/inbound.js.map +1 -0
  179. package/dist/outbox/index.d.ts +79 -0
  180. package/dist/outbox/index.d.ts.map +1 -0
  181. package/dist/outbox/index.js +98 -0
  182. package/dist/outbox/index.js.map +1 -0
  183. package/dist/outbox/intake.d.ts +62 -0
  184. package/dist/outbox/intake.d.ts.map +1 -0
  185. package/dist/outbox/intake.js +145 -0
  186. package/dist/outbox/intake.js.map +1 -0
  187. package/dist/outbox/integration.d.ts +62 -0
  188. package/dist/outbox/integration.d.ts.map +1 -0
  189. package/dist/outbox/integration.js +119 -0
  190. package/dist/outbox/integration.js.map +1 -0
  191. package/dist/outbox/outbox/dispatcher.d.ts +26 -0
  192. package/dist/outbox/outbox/dispatcher.d.ts.map +1 -0
  193. package/dist/outbox/outbox/dispatcher.js +119 -0
  194. package/dist/outbox/outbox/dispatcher.js.map +1 -0
  195. package/dist/outbox/outbox/service.d.ts +124 -0
  196. package/dist/outbox/outbox/service.d.ts.map +1 -0
  197. package/dist/outbox/outbox/service.js +279 -0
  198. package/dist/outbox/outbox/service.js.map +1 -0
  199. package/dist/outbox/postgres/index.d.ts +44 -0
  200. package/dist/outbox/postgres/index.d.ts.map +1 -0
  201. package/dist/outbox/postgres/index.js +51 -0
  202. package/dist/outbox/postgres/index.js.map +1 -0
  203. package/dist/outbox/postgres/registries.d.ts +69 -0
  204. package/dist/outbox/postgres/registries.d.ts.map +1 -0
  205. package/dist/outbox/postgres/registries.js +159 -0
  206. package/dist/outbox/postgres/registries.js.map +1 -0
  207. package/dist/outbox/postgres/reportColumns.d.ts +154 -0
  208. package/dist/outbox/postgres/reportColumns.d.ts.map +1 -0
  209. package/dist/outbox/postgres/reportColumns.js +195 -0
  210. package/dist/outbox/postgres/reportColumns.js.map +1 -0
  211. package/dist/outbox/postgres/store/enforcement.d.ts +33 -0
  212. package/dist/outbox/postgres/store/enforcement.d.ts.map +1 -0
  213. package/dist/outbox/postgres/store/enforcement.js +161 -0
  214. package/dist/outbox/postgres/store/enforcement.js.map +1 -0
  215. package/dist/outbox/postgres/store/events.d.ts +46 -0
  216. package/dist/outbox/postgres/store/events.d.ts.map +1 -0
  217. package/dist/outbox/postgres/store/events.js +104 -0
  218. package/dist/outbox/postgres/store/events.js.map +1 -0
  219. package/dist/outbox/postgres/store/index.d.ts +27 -0
  220. package/dist/outbox/postgres/store/index.d.ts.map +1 -0
  221. package/dist/outbox/postgres/store/index.js +62 -0
  222. package/dist/outbox/postgres/store/index.js.map +1 -0
  223. package/dist/outbox/postgres/store/outbox.d.ts +8 -0
  224. package/dist/outbox/postgres/store/outbox.d.ts.map +1 -0
  225. package/dist/outbox/postgres/store/outbox.js +210 -0
  226. package/dist/outbox/postgres/store/outbox.js.map +1 -0
  227. package/dist/outbox/postgres/store/reports.d.ts +69 -0
  228. package/dist/outbox/postgres/store/reports.d.ts.map +1 -0
  229. package/dist/outbox/postgres/store/reports.js +234 -0
  230. package/dist/outbox/postgres/store/reports.js.map +1 -0
  231. package/dist/outbox/postgres/store/transaction.d.ts +49 -0
  232. package/dist/outbox/postgres/store/transaction.d.ts.map +1 -0
  233. package/dist/outbox/postgres/store/transaction.js +32 -0
  234. package/dist/outbox/postgres/store/transaction.js.map +1 -0
  235. package/dist/outbox/postgres/tables.d.ts +737 -0
  236. package/dist/outbox/postgres/tables.d.ts.map +1 -0
  237. package/dist/outbox/postgres/tables.js +273 -0
  238. package/dist/outbox/postgres/tables.js.map +1 -0
  239. package/dist/outbox/reconciliation.d.ts +49 -0
  240. package/dist/outbox/reconciliation.d.ts.map +1 -0
  241. package/dist/outbox/reconciliation.js +162 -0
  242. package/dist/outbox/reconciliation.js.map +1 -0
  243. package/dist/outbox/reportStatus.d.ts +12 -0
  244. package/dist/outbox/reportStatus.d.ts.map +1 -0
  245. package/dist/outbox/reportStatus.js +25 -0
  246. package/dist/outbox/reportStatus.js.map +1 -0
  247. package/dist/outbox/retention.d.ts +33 -0
  248. package/dist/outbox/retention.d.ts.map +1 -0
  249. package/dist/outbox/retention.js +36 -0
  250. package/dist/outbox/retention.js.map +1 -0
  251. package/dist/outbox/store/types.d.ts +466 -0
  252. package/dist/outbox/store/types.d.ts.map +1 -0
  253. package/dist/outbox/store/types.js +31 -0
  254. package/dist/outbox/store/types.js.map +1 -0
  255. package/dist/outbox/types.d.ts +660 -0
  256. package/dist/outbox/types.d.ts.map +1 -0
  257. package/dist/outbox/types.js +24 -0
  258. package/dist/outbox/types.js.map +1 -0
  259. package/dist/outbox/webhook.d.ts +15 -0
  260. package/dist/outbox/webhook.d.ts.map +1 -0
  261. package/dist/outbox/webhook.js +148 -0
  262. package/dist/outbox/webhook.js.map +1 -0
  263. package/dist/reports.d.ts +73 -0
  264. package/dist/reports.d.ts.map +1 -0
  265. package/dist/reports.js +78 -0
  266. package/dist/reports.js.map +1 -0
  267. package/dist/testing/fixtures.d.ts +62 -0
  268. package/dist/testing/fixtures.d.ts.map +1 -0
  269. package/dist/testing/fixtures.js +137 -0
  270. package/dist/testing/fixtures.js.map +1 -0
  271. package/dist/testing/index.d.ts +36 -0
  272. package/dist/testing/index.d.ts.map +1 -0
  273. package/dist/testing/index.js +43 -0
  274. package/dist/testing/index.js.map +1 -0
  275. package/dist/testing/sandbox.d.ts +109 -0
  276. package/dist/testing/sandbox.d.ts.map +1 -0
  277. package/dist/testing/sandbox.js +342 -0
  278. package/dist/testing/sandbox.js.map +1 -0
  279. package/dist/testing/webhook-simulator.d.ts +78 -0
  280. package/dist/testing/webhook-simulator.d.ts.map +1 -0
  281. package/dist/testing/webhook-simulator.js +98 -0
  282. package/dist/testing/webhook-simulator.js.map +1 -0
  283. package/dist/transport.d.ts +59 -0
  284. package/dist/transport.d.ts.map +1 -0
  285. package/dist/transport.js +181 -0
  286. package/dist/transport.js.map +1 -0
  287. package/dist/webhookEndpoints.d.ts +147 -0
  288. package/dist/webhookEndpoints.d.ts.map +1 -0
  289. package/dist/webhookEndpoints.js +143 -0
  290. package/dist/webhookEndpoints.js.map +1 -0
  291. package/package.json +127 -0
  292. package/src/cases.ts +119 -0
  293. package/src/client.ts +202 -0
  294. package/src/communityNotes.ts +194 -0
  295. package/src/credential.ts +100 -0
  296. package/src/defaults.ts +87 -0
  297. package/src/digest.ts +91 -0
  298. package/src/envelope.ts +432 -0
  299. package/src/errors.ts +165 -0
  300. package/src/express/index.ts +43 -0
  301. package/src/express/middleware.ts +387 -0
  302. package/src/express/store.ts +85 -0
  303. package/src/express/verify.ts +166 -0
  304. package/src/index.ts +107 -0
  305. package/src/outbox/client.ts +75 -0
  306. package/src/outbox/decision.ts +209 -0
  307. package/src/outbox/delivery.ts +163 -0
  308. package/src/outbox/enforcement/executor.ts +288 -0
  309. package/src/outbox/enforcement/planner.ts +377 -0
  310. package/src/outbox/evidence.ts +231 -0
  311. package/src/outbox/inbound.ts +140 -0
  312. package/src/outbox/index.ts +160 -0
  313. package/src/outbox/intake.ts +175 -0
  314. package/src/outbox/integration.ts +205 -0
  315. package/src/outbox/outbox/dispatcher.ts +131 -0
  316. package/src/outbox/outbox/service.ts +444 -0
  317. package/src/outbox/postgres/index.ts +59 -0
  318. package/src/outbox/postgres/registries.ts +177 -0
  319. package/src/outbox/postgres/reportColumns.ts +281 -0
  320. package/src/outbox/postgres/store/enforcement.ts +186 -0
  321. package/src/outbox/postgres/store/events.ts +112 -0
  322. package/src/outbox/postgres/store/index.ts +72 -0
  323. package/src/outbox/postgres/store/outbox.ts +273 -0
  324. package/src/outbox/postgres/store/reports.ts +349 -0
  325. package/src/outbox/postgres/store/transaction.ts +64 -0
  326. package/src/outbox/postgres/tables.ts +339 -0
  327. package/src/outbox/reconciliation.ts +199 -0
  328. package/src/outbox/reportStatus.ts +24 -0
  329. package/src/outbox/retention.ts +34 -0
  330. package/src/outbox/store/types.ts +528 -0
  331. package/src/outbox/types.ts +753 -0
  332. package/src/outbox/webhook.ts +165 -0
  333. package/src/reports.ts +138 -0
  334. package/src/testing/fixtures.ts +183 -0
  335. package/src/testing/index.ts +57 -0
  336. package/src/testing/sandbox.ts +469 -0
  337. package/src/testing/webhook-simulator.ts +166 -0
  338. package/src/transport.ts +250 -0
  339. package/src/webhookEndpoints.ts +256 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * What an integrator does not have to declare, and why each default is safe to
3
+ * apply without being asked.
4
+ *
5
+ * The product requirement is near-zero configuration: an application should be
6
+ * able to report a piece of content with a credential and the object itself. The
7
+ * plan's requirement pulling the other way is §6.4 — every decision records the
8
+ * policy version it was decided under, and a policy update must never silently
9
+ * change what a past decision meant.
10
+ *
11
+ * Both hold only if the default is a PINNED VERSION rather than "whatever is
12
+ * current". `DEFAULT_POLICY` below names a specific immutable published version.
13
+ * When CrowdSource publishes a newer baseline, this constant changes in a
14
+ * release of this package and integrators adopt it by upgrading — which is
15
+ * visible in a lockfile, reviewable in a diff, and dated. The alternative
16
+ * (resolving "latest" server-side) would move the policy version under an
17
+ * application that never changed a line, and would silently split
18
+ * `caseDedupKey` — §7.3 makes the policy version part of that key, so the day it
19
+ * moved, two reports about one post would open two cases.
20
+ */
21
+ import type { CasePolicyRef, CasePrivacy, TaxonomyCode } from '@crowdsource.you/contracts';
22
+ /** Where the service lives. One deployment; there is no sandbox host. */
23
+ export declare const DEFAULT_BASE_URL = "https://api.crowdsource.oxy.so";
24
+ /**
25
+ * The policy set a report is evaluated under when the application declares
26
+ * none: the baseline CrowdSource ships over its own universal taxonomy (§6.3).
27
+ *
28
+ * Must stay equal to `BASELINE_POLICY_SET_ID` / `BASELINE_POLICY_VERSION` in the
29
+ * backend's `modules/policy/policyBaseline.ts`, which is the registry that
30
+ * resolves it. A drift is not a type error and not a test failure anywhere else:
31
+ * it is a 422 on every zero-config report, in production, at the moment of
32
+ * upgrade. `__tests__/defaults.test.ts` reads that file and asserts the pair.
33
+ */
34
+ export declare const DEFAULT_POLICY: CasePolicyRef;
35
+ /**
36
+ * §13.6's default retention: 30 days after a final decision, configurable by
37
+ * policy.
38
+ */
39
+ export declare const DEFAULT_RETENTION_DAYS = 30;
40
+ /**
41
+ * Allegation codes that must never reach a community jury (§7.5).
42
+ *
43
+ * §7.5 routes child sexual abuse and potentially illegal material to a
44
+ * specialist team under legal protocol, and non-consensual intimate material to
45
+ * specialist review. An integrator who never read §7.5 still gets that: an
46
+ * envelope alleging one of these is composed with `allowCommunityReview: false`,
47
+ * and an application that explicitly asks for `true` alongside one of them is
48
+ * REFUSED rather than quietly corrected — the belief that this material can be
49
+ * community-reviewed is the defect, and silently fixing the field would leave
50
+ * the belief in place.
51
+ *
52
+ * This is a floor, never a ceiling. Triage may route a case away from the
53
+ * community for reasons this list cannot see; nothing here can route one
54
+ * towards it.
55
+ */
56
+ export declare const COMMUNITY_REVIEW_FORBIDDEN_ALLEGATIONS: readonly TaxonomyCode[];
57
+ /** The allegations in `codes` that §7.5 keeps away from a community jury. */
58
+ export declare function allegationsForbiddingCommunityReview(codes: readonly TaxonomyCode[]): readonly TaxonomyCode[];
59
+ /** The privacy terms of a report that declares none. */
60
+ export declare function defaultPrivacy(allegationCodes: readonly TaxonomyCode[]): CasePrivacy;
61
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE3F,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,mCAAmC,CAAC;AAEjE;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,EAAE,aAG3B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sCAAsC,EAAE,SAAS,YAAY,EAMxE,CAAC;AAIH,6EAA6E;AAC7E,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,SAAS,YAAY,EAAE,GAC7B,SAAS,YAAY,EAAE,CAEzB;AAED,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,eAAe,EAAE,SAAS,YAAY,EAAE,GAAG,WAAW,CAKpF"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ /**
3
+ * What an integrator does not have to declare, and why each default is safe to
4
+ * apply without being asked.
5
+ *
6
+ * The product requirement is near-zero configuration: an application should be
7
+ * able to report a piece of content with a credential and the object itself. The
8
+ * plan's requirement pulling the other way is §6.4 — every decision records the
9
+ * policy version it was decided under, and a policy update must never silently
10
+ * change what a past decision meant.
11
+ *
12
+ * Both hold only if the default is a PINNED VERSION rather than "whatever is
13
+ * current". `DEFAULT_POLICY` below names a specific immutable published version.
14
+ * When CrowdSource publishes a newer baseline, this constant changes in a
15
+ * release of this package and integrators adopt it by upgrading — which is
16
+ * visible in a lockfile, reviewable in a diff, and dated. The alternative
17
+ * (resolving "latest" server-side) would move the policy version under an
18
+ * application that never changed a line, and would silently split
19
+ * `caseDedupKey` — §7.3 makes the policy version part of that key, so the day it
20
+ * moved, two reports about one post would open two cases.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.COMMUNITY_REVIEW_FORBIDDEN_ALLEGATIONS = exports.DEFAULT_RETENTION_DAYS = exports.DEFAULT_POLICY = exports.DEFAULT_BASE_URL = void 0;
24
+ exports.allegationsForbiddingCommunityReview = allegationsForbiddingCommunityReview;
25
+ exports.defaultPrivacy = defaultPrivacy;
26
+ /** Where the service lives. One deployment; there is no sandbox host. */
27
+ exports.DEFAULT_BASE_URL = 'https://api.crowdsource.oxy.so';
28
+ /**
29
+ * The policy set a report is evaluated under when the application declares
30
+ * none: the baseline CrowdSource ships over its own universal taxonomy (§6.3).
31
+ *
32
+ * Must stay equal to `BASELINE_POLICY_SET_ID` / `BASELINE_POLICY_VERSION` in the
33
+ * backend's `modules/policy/policyBaseline.ts`, which is the registry that
34
+ * resolves it. A drift is not a type error and not a test failure anywhere else:
35
+ * it is a 422 on every zero-config report, in production, at the moment of
36
+ * upgrade. `__tests__/defaults.test.ts` reads that file and asserts the pair.
37
+ */
38
+ exports.DEFAULT_POLICY = Object.freeze({
39
+ policySetId: 'crowdsource.baseline',
40
+ version: '2026.07',
41
+ });
42
+ /**
43
+ * §13.6's default retention: 30 days after a final decision, configurable by
44
+ * policy.
45
+ */
46
+ exports.DEFAULT_RETENTION_DAYS = 30;
47
+ /**
48
+ * Allegation codes that must never reach a community jury (§7.5).
49
+ *
50
+ * §7.5 routes child sexual abuse and potentially illegal material to a
51
+ * specialist team under legal protocol, and non-consensual intimate material to
52
+ * specialist review. An integrator who never read §7.5 still gets that: an
53
+ * envelope alleging one of these is composed with `allowCommunityReview: false`,
54
+ * and an application that explicitly asks for `true` alongside one of them is
55
+ * REFUSED rather than quietly corrected — the belief that this material can be
56
+ * community-reviewed is the defect, and silently fixing the field would leave
57
+ * the belief in place.
58
+ *
59
+ * This is a floor, never a ceiling. Triage may route a case away from the
60
+ * community for reasons this list cannot see; nothing here can route one
61
+ * towards it.
62
+ */
63
+ exports.COMMUNITY_REVIEW_FORBIDDEN_ALLEGATIONS = Object.freeze([
64
+ 'child_safety.sexualization',
65
+ 'child_safety.grooming',
66
+ 'child_safety.exploitation',
67
+ 'sexual_content.non_consensual',
68
+ 'sexual_content.exploitation',
69
+ ]);
70
+ const FORBIDDEN_SET = new Set(exports.COMMUNITY_REVIEW_FORBIDDEN_ALLEGATIONS);
71
+ /** The allegations in `codes` that §7.5 keeps away from a community jury. */
72
+ function allegationsForbiddingCommunityReview(codes) {
73
+ return codes.filter((code) => FORBIDDEN_SET.has(code));
74
+ }
75
+ /** The privacy terms of a report that declares none. */
76
+ function defaultPrivacy(allegationCodes) {
77
+ return {
78
+ retentionDays: exports.DEFAULT_RETENTION_DAYS,
79
+ allowCommunityReview: allegationsForbiddingCommunityReview(allegationCodes).length === 0,
80
+ };
81
+ }
82
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;AAuDH,oFAIC;AAGD,wCAKC;AA/DD,yEAAyE;AAC5D,QAAA,gBAAgB,GAAG,gCAAgC,CAAC;AAEjE;;;;;;;;;GASG;AACU,QAAA,cAAc,GAAkB,MAAM,CAAC,MAAM,CAAC;IACzD,WAAW,EAAE,sBAAsB;IACnC,OAAO,EAAE,SAAS;CACnB,CAAC,CAAC;AAEH;;;GAGG;AACU,QAAA,sBAAsB,GAAG,EAAE,CAAC;AAEzC;;;;;;;;;;;;;;;GAeG;AACU,QAAA,sCAAsC,GAA4B,MAAM,CAAC,MAAM,CAAC;IAC3F,4BAA4B;IAC5B,uBAAuB;IACvB,2BAA2B;IAC3B,+BAA+B;IAC/B,6BAA6B;CAC9B,CAAC,CAAC;AAEH,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAC,8CAAsC,CAAC,CAAC;AAE3F,6EAA6E;AAC7E,SAAgB,oCAAoC,CAClD,KAA8B;IAE9B,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,wDAAwD;AACxD,SAAgB,cAAc,CAAC,eAAwC;IACrE,OAAO;QACL,aAAa,EAAE,8BAAsB;QACrC,oBAAoB,EAAE,oCAAoC,CAAC,eAAe,CAAC,CAAC,MAAM,KAAK,CAAC;KACzF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Resource digests (§5.2 `sha256`, §5.6 "SHA 256 of each resource").
3
+ *
4
+ * Every inline resource in an envelope must carry a digest of "the exact
5
+ * representation reviewed", and asking an integrator to compute one is asking
6
+ * them to get canonical serialisation right — which they will do differently
7
+ * from the next integrator, and differently again from themselves next quarter.
8
+ * So the client computes it, from one rule applied to every resource type:
9
+ *
10
+ * sha256:<hex of SHA-256 over canonicalJson({ type, data }) in UTF-8>
11
+ *
12
+ * `type` is inside the digest so a `text` resource and a `metadata` resource
13
+ * carrying identical fields do not produce the same digest. `custom` hashes its
14
+ * registered `schemaId` and `payload` for the same reason.
15
+ *
16
+ * Determinism is not a nicety here, it is the deduplication invariant. §7.3
17
+ * requires two people reporting the same version of the same post to land on ONE
18
+ * case, and the server's `caseDedupKey` is computed over a projection of the
19
+ * envelope that INCLUDES every resource verbatim, digest and all. A digest that
20
+ * varied with key order — or with which reporter sent it — would give the same
21
+ * post two cases, and "one penalty per incident" would be broken by a JSON
22
+ * serialiser.
23
+ *
24
+ * Asset-backed resources are the exception the contract already makes: their
25
+ * bytes live outside the envelope and `asset.sha256` is the digest of those
26
+ * bytes, so nothing here computes one for them.
27
+ */
28
+ /** A JSON value that can be canonicalised. */
29
+ export type CanonicalValue = string | number | boolean | null | readonly CanonicalValue[] | {
30
+ readonly [key: string]: CanonicalValue | undefined;
31
+ };
32
+ /**
33
+ * JSON with object keys in a fixed order and `undefined` members dropped.
34
+ *
35
+ * Array order is PRESERVED. In a conversation's `messageResourceIds` the order
36
+ * is the meaning, and the backend's own canonicaliser makes the same choice for
37
+ * the same reason.
38
+ */
39
+ export declare function canonicalJson(value: CanonicalValue): string;
40
+ /** `sha256:<64 lowercase hex>` — the only digest form the contract accepts. */
41
+ export declare function sha256Digest(bytes: Uint8Array | string): string;
42
+ /** The digest of an inline resource's reviewable representation. */
43
+ export declare function resourceDigest(reviewable: CanonicalValue): string;
44
+ //# sourceMappingURL=digest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,8CAA8C;AAC9C,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,cAAc,EAAE,GACzB;IAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAA;CAAE,CAAC;AAE3D;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAwB3D;AAYD,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAE/D;AAED,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,UAAU,EAAE,cAAc,GAAG,MAAM,CAEjE"}
package/dist/digest.js ADDED
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ /**
3
+ * Resource digests (§5.2 `sha256`, §5.6 "SHA 256 of each resource").
4
+ *
5
+ * Every inline resource in an envelope must carry a digest of "the exact
6
+ * representation reviewed", and asking an integrator to compute one is asking
7
+ * them to get canonical serialisation right — which they will do differently
8
+ * from the next integrator, and differently again from themselves next quarter.
9
+ * So the client computes it, from one rule applied to every resource type:
10
+ *
11
+ * sha256:<hex of SHA-256 over canonicalJson({ type, data }) in UTF-8>
12
+ *
13
+ * `type` is inside the digest so a `text` resource and a `metadata` resource
14
+ * carrying identical fields do not produce the same digest. `custom` hashes its
15
+ * registered `schemaId` and `payload` for the same reason.
16
+ *
17
+ * Determinism is not a nicety here, it is the deduplication invariant. §7.3
18
+ * requires two people reporting the same version of the same post to land on ONE
19
+ * case, and the server's `caseDedupKey` is computed over a projection of the
20
+ * envelope that INCLUDES every resource verbatim, digest and all. A digest that
21
+ * varied with key order — or with which reporter sent it — would give the same
22
+ * post two cases, and "one penalty per incident" would be broken by a JSON
23
+ * serialiser.
24
+ *
25
+ * Asset-backed resources are the exception the contract already makes: their
26
+ * bytes live outside the envelope and `asset.sha256` is the digest of those
27
+ * bytes, so nothing here computes one for them.
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.canonicalJson = canonicalJson;
31
+ exports.sha256Digest = sha256Digest;
32
+ exports.resourceDigest = resourceDigest;
33
+ const node_crypto_1 = require("node:crypto");
34
+ /**
35
+ * JSON with object keys in a fixed order and `undefined` members dropped.
36
+ *
37
+ * Array order is PRESERVED. In a conversation's `messageResourceIds` the order
38
+ * is the meaning, and the backend's own canonicaliser makes the same choice for
39
+ * the same reason.
40
+ */
41
+ function canonicalJson(value) {
42
+ if (value === null || typeof value === 'boolean' || typeof value === 'string') {
43
+ return JSON.stringify(value);
44
+ }
45
+ if (typeof value === 'number') {
46
+ if (!Number.isFinite(value)) {
47
+ throw new TypeError('A resource cannot carry a non-finite number: it has no JSON form.');
48
+ }
49
+ return JSON.stringify(value);
50
+ }
51
+ if (isCanonicalArray(value)) {
52
+ return `[${value.map((entry) => canonicalJson(entry)).join(',')}]`;
53
+ }
54
+ const members = Object.keys(value)
55
+ .sort()
56
+ .flatMap((key) => {
57
+ const member = value[key];
58
+ return member === undefined ? [] : [`${JSON.stringify(key)}:${canonicalJson(member)}`];
59
+ });
60
+ return `{${members.join(',')}}`;
61
+ }
62
+ /**
63
+ * A written-out predicate rather than a bare `Array.isArray`, because
64
+ * `Array.isArray` narrows `readonly T[]` in its TRUE branch only — the false
65
+ * branch keeps the array in the union and the object branch below stops
66
+ * type-checking.
67
+ */
68
+ function isCanonicalArray(value) {
69
+ return Array.isArray(value);
70
+ }
71
+ /** `sha256:<64 lowercase hex>` — the only digest form the contract accepts. */
72
+ function sha256Digest(bytes) {
73
+ return `sha256:${(0, node_crypto_1.createHash)('sha256').update(bytes).digest('hex')}`;
74
+ }
75
+ /** The digest of an inline resource's reviewable representation. */
76
+ function resourceDigest(reviewable) {
77
+ return sha256Digest(Buffer.from(canonicalJson(reviewable), 'utf8'));
78
+ }
79
+ //# sourceMappingURL=digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.js","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;AAoBH,sCAwBC;AAaD,oCAEC;AAGD,wCAEC;AA9DD,6CAAyC;AAWzC;;;;;;GAMG;AACH,SAAgB,aAAa,CAAC,KAAqB;IACjD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9E,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,SAAS,CAAC,mEAAmE,CAAC,CAAC;QAC3F,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACrE,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;SAC/B,IAAI,EAAE;SACN,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;IAEL,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAClC,CAAC;AAED;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,KAAqB;IAC7C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,+EAA+E;AAC/E,SAAgB,YAAY,CAAC,KAA0B;IACrD,OAAO,UAAU,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AACtE,CAAC;AAED,oEAAoE;AACpE,SAAgB,cAAc,CAAC,UAA0B;IACvD,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Composing a Case Envelope out of what an application already has.
3
+ *
4
+ * §5 is a rich document contract — resources with stable ids, relations between
5
+ * them, pseudonymous principal bindings, digests, a policy reference, privacy
6
+ * terms. Handing that to an integrator and asking them to fill it in is how a
7
+ * moderation integration becomes a two-week project, and it is how the parts
8
+ * that MATTER get filled in wrong: a random resource id or a per-report binding
9
+ * proof inside the hashed projection means two people reporting the same post
10
+ * open two cases, and "one penalty per incident" (Appendix F) fails in
11
+ * production with nothing failing in a test.
12
+ *
13
+ * So the integrator describes the object — its id, its author, its text, its
14
+ * attachments, what is alleged about it — and this module derives the rest:
15
+ *
16
+ * * **Resource ids are positional and stable** (`res_subject`,
17
+ * `res_attachment_1`, `res_context_1`). Two reporters describing the same
18
+ * post through this SDK produce byte-identical resource lists, which is what
19
+ * makes §7.3's dedup key match.
20
+ * * **Principal refs are derived from the identity**, never generated. Same
21
+ * reason: the content snapshot the server hashes includes every principal
22
+ * the material points at, so a random ref would fragment the case.
23
+ * * **Digests are computed** (see `digest.ts`).
24
+ * * **Relations are derived** from the role each resource was given.
25
+ * * **The binding proof is the Oxy `sub`.** §11.14 requires proof that a
26
+ * pseudonymous ref corresponds to a real identity before anything can touch
27
+ * Oxy Trust. Sign in with Oxy already produced exactly that: a subject
28
+ * issued for this `applicationId`. There is no separate binding step to
29
+ * implement, and this module does not invent one.
30
+ * * **`applicationId` comes from the credential** (see `credential.ts`). No
31
+ * input on this page can carry one.
32
+ */
33
+ import { type CaseEnvelope, type CasePolicyRef, type CasePrivacy, type CaseUrgency, type MetadataBag, type PrincipalType, type Resource, type SubjectType, type TaxonomyCode } from '@crowdsource.you/contracts';
34
+ import { CrowdSourceError } from './errors.js';
35
+ /** `Omit` that survives a discriminated union instead of collapsing it. */
36
+ type DistributiveOmit<T, K extends keyof never> = T extends unknown ? Omit<T, K> : never;
37
+ /**
38
+ * A resource as an integrator describes it: the material, without the envelope
39
+ * plumbing.
40
+ *
41
+ * Derived from the published `Resource` union rather than restated, so a
42
+ * resource type added to the contract is available here the moment the
43
+ * contracts dependency is bumped, and a field removed from it stops compiling
44
+ * on the next build instead of being silently ignored at ingress.
45
+ */
46
+ export type ResourceInput = DistributiveOmit<Resource, 'id' | 'role' | 'sha256' | 'authorPrincipalRef' | 'createdAt'> & {
47
+ /** The moment of the ORIGINAL object, not of the report (§5.2). */
48
+ readonly createdAt?: Date | string;
49
+ };
50
+ /** Why a context resource is attached to the subject (§5.5). */
51
+ export type ContextRole = 'parent' | 'quoted' | 'context' | 'evidence';
52
+ export type ContextInput = ResourceInput & {
53
+ readonly role: ContextRole;
54
+ };
55
+ /**
56
+ * A person or account, as the application knows them.
57
+ *
58
+ * `oxyUserId` is the OAuth `sub` from Sign in with Oxy. Supplying it is what
59
+ * makes an actor addressable by Oxy Trust at all — §11.14 admits no effect
60
+ * without a binding proof, and the `sub` issued for this application IS that
61
+ * proof. `id` is the application's own identifier for the same actor, for
62
+ * applications that keep their own user table; it is what a reviewer's
63
+ * pseudonymous ref is derived from and never shown to a jury.
64
+ */
65
+ export interface PrincipalInput {
66
+ readonly oxyUserId?: string;
67
+ readonly id?: string;
68
+ /** Defaults to `oxy_user` with an `oxyUserId`, `local_user` without one. */
69
+ readonly type?: PrincipalType;
70
+ }
71
+ /** What the reporter claims, not what is true (§6.2). */
72
+ export interface AllegationInput {
73
+ readonly code: TaxonomyCode;
74
+ /** The reporter's own words. Never shown as evidence of the claim. */
75
+ readonly details?: string;
76
+ }
77
+ export interface ReportSubjectInput {
78
+ /** The application's own id for the object being reported. */
79
+ readonly externalId: string;
80
+ /** §5.4, e.g. `social.post` or `custom.<organization>.<object_type>`. */
81
+ readonly type: SubjectType;
82
+ /** Where the application's own users see it. Never fetched by a jury. */
83
+ readonly permalink?: string;
84
+ readonly author?: PrincipalInput;
85
+ }
86
+ export interface ReportInput {
87
+ /** The application's own report id. Also the default idempotency key. */
88
+ readonly externalReportId: string;
89
+ readonly subject: ReportSubjectInput;
90
+ /** The reported material. A string is shorthand for a plain-text resource. */
91
+ readonly content: string | ResourceInput;
92
+ readonly attachments?: readonly ResourceInput[];
93
+ /** Replies, quotes, surrounding messages — context without extra exposure. */
94
+ readonly context?: readonly ContextInput[];
95
+ readonly allegations: readonly (TaxonomyCode | AllegationInput)[];
96
+ /** Who reported it. Omit for a report the application raised itself. */
97
+ readonly reportedBy?: PrincipalInput;
98
+ /** Defaults to the pinned baseline policy version — see `defaults.ts`. */
99
+ readonly policy?: CasePolicyRef;
100
+ readonly privacy?: Partial<CasePrivacy>;
101
+ readonly urgency?: CaseUrgency;
102
+ readonly metadata?: MetadataBag;
103
+ /**
104
+ * When the USER reported it (§5.1 `source.submittedAt`) — the timestamp on the
105
+ * application's own outbox row, not the moment of delivery.
106
+ *
107
+ * There is no default, and that is load-bearing rather than an omission. The
108
+ * ingress fingerprints the whole `{ externalReportId, envelope }` to detect
109
+ * §10.5's "external id reused with different content", so ANY value this
110
+ * client invented per attempt would make a legitimate retry from an outbox a
111
+ * permanent 409 — the failure would appear as moderation work silently
112
+ * stuck in a delivery queue, days after the integration was written. Omitted
113
+ * when absent: §5.1 makes `source` optional and §5.8 leaves it out.
114
+ */
115
+ readonly submittedAt?: Date | string;
116
+ /** Appendix D. Defaults to `report.<externalReportId>`. */
117
+ readonly idempotencyKey?: string;
118
+ }
119
+ /** Raised when an input cannot become a valid envelope. Never retryable. */
120
+ export declare class CrowdSourceReportInputError extends CrowdSourceError {
121
+ constructor(message: string);
122
+ }
123
+ /** How the application declares its own environment (§5.1 `source`). */
124
+ export type SourceEnvironment = 'production' | 'sandbox';
125
+ export interface EnvelopeComposition {
126
+ readonly applicationId: string;
127
+ readonly environment: SourceEnvironment;
128
+ }
129
+ /**
130
+ * Composes and VALIDATES a Case Envelope.
131
+ *
132
+ * The parse at the end is not belt-and-braces. Everything above assembles a
133
+ * document from caller data — a subject type, a text body, an asset digest —
134
+ * and the contract is where a bad one is caught. Catching it here means the
135
+ * integrator sees the field and the reason at the call site, in their own
136
+ * process, instead of reading a 422 out of a delivery worker's log an hour
137
+ * later.
138
+ */
139
+ export declare function composeCaseEnvelope(input: ReportInput, composition: EnvelopeComposition): CaseEnvelope;
140
+ /** Appendix D: the same report re-delivered must return the same `reportId`. */
141
+ export declare function defaultIdempotencyKey(externalReportId: string): string;
142
+ export {};
143
+ //# sourceMappingURL=envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"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"}