@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 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/outbox/enforcement/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { Decision } from '@crowdsource.you/contracts';
2
+ import type { ModerationEnforcementConfig, PlannedEnforcementAction } from '../types.js';
3
+ /**
4
+ * What the application will do about this decision.
5
+ *
6
+ * Never empty: a decision that produces no action produces an explicit
7
+ * `noneAction`, because a row saying "we decided to do nothing, and why" is
8
+ * evidence and an absent row is a question.
9
+ */
10
+ /**
11
+ * Raised when `restoreAction` names actions that are being UNDONE rather than
12
+ * actions that DO the undoing.
13
+ *
14
+ * A doc line is not enough for this one. An inverted `restoreAction` type-checks
15
+ * — both directions are `TAction[]` — and it does not fail at runtime either: it
16
+ * plans, it claims, and it applies a restriction and a label on an accepted
17
+ * appeal. It succeeds at the opposite thing, on the one path whose whole purpose
18
+ * is to give something back.
19
+ *
20
+ * The signal is unambiguous when it exists. `reverses` maps each undoing action
21
+ * to what it undoes, so its VALUES are targets and its KEYS are actors. An
22
+ * action that appears only as a target has been declared as a restore by
23
+ * someone reading the targets, which is exactly the mistake this catches.
24
+ *
25
+ * Deliberately narrow: an action absent from `reverses` entirely is fine (it may
26
+ * undo something needing no previous state), and one that is both a key and a
27
+ * value is fine (it undoes and is undone). Only "a target, and never an actor"
28
+ * is reported, so a correct configuration cannot trip it.
29
+ */
30
+ export declare class ModerationRestoreDirectionError extends Error {
31
+ constructor(inverted: readonly string[]);
32
+ }
33
+ /**
34
+ * Refuse an inverted `restoreAction` at construction rather than at the first
35
+ * correction, which may be weeks later and reads as a moderation decision
36
+ * rather than a configuration error.
37
+ */
38
+ export declare function assertRestoreDirection<TAction extends string>(config: ModerationEnforcementConfig<TAction>): void;
39
+ export declare function planEnforcement<TAction extends string>(decision: Decision, config: ModerationEnforcementConfig<TAction>): PlannedEnforcementAction<TAction>[];
40
+ /**
41
+ * The one action worth recording on the report.
42
+ *
43
+ * One field, several planned actions, so it has to be the one that answers "what
44
+ * happened to this object". The application's `precedence` decides, strongest
45
+ * first — and `reviewAction` should sit near the end but ABOVE `noneAction`,
46
+ * because a reporter told "nothing happened" when a human is about to look is
47
+ * being told something untrue.
48
+ */
49
+ export declare function primaryAction<TAction extends string>(actions: readonly TAction[], precedence: readonly TAction[]): TAction | undefined;
50
+ //# sourceMappingURL=planner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../../../src/outbox/enforcement/planner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAA+B,MAAM,4BAA4B,CAAC;AACxF,OAAO,KAAK,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAiLzF;;;;;;GAMG;AACH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,+BAAgC,SAAQ,KAAK;gBAC5C,QAAQ,EAAE,SAAS,MAAM,EAAE;CAUxC;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,SAAS,MAAM,EAC3D,MAAM,EAAE,2BAA2B,CAAC,OAAO,CAAC,GAC3C,IAAI,CAmBN;AAED,wBAAgB,eAAe,CAAC,OAAO,SAAS,MAAM,EACpD,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,2BAA2B,CAAC,OAAO,CAAC,GAC3C,wBAAwB,CAAC,OAAO,CAAC,EAAE,CA4GrC;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,SAAS,MAAM,EAClD,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,UAAU,EAAE,SAAS,OAAO,EAAE,GAC7B,OAAO,GAAG,SAAS,CAKrB"}
@@ -0,0 +1,333 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ModerationRestoreDirectionError = void 0;
4
+ exports.assertRestoreDirection = assertRestoreDirection;
5
+ exports.planEnforcement = planEnforcement;
6
+ exports.primaryAction = primaryAction;
7
+ /**
8
+ * Deciding what an application will do about a decision — and nothing else.
9
+ *
10
+ * Pure: no database, no clock, no configuration. A decision in, a plan out. That
11
+ * is what makes the mapping testable as a table rather than as an integration
12
+ * scenario, and it is why `observe` mode is a real audit rather than a comment —
13
+ * the plan is computed identically in every mode and only its EXECUTION is
14
+ * gated.
15
+ *
16
+ * ## The application maps recommendations, not findings
17
+ *
18
+ * `decision.recommendedActions` is what this reads, falling back to severity
19
+ * only when a violation arrives with no recommendation at all.
20
+ *
21
+ * The reason is a division of labour: the jury classified the material and the
22
+ * consensus engine turned that into a recommendation under a versioned policy.
23
+ * An application that re-derived its action from raw severity would be quietly
24
+ * re-deciding the case with a second, unversioned policy of its own — and the
25
+ * two would diverge the first time CrowdSource's policy was updated. The
26
+ * fallback exists because a `violation` the application did nothing about would
27
+ * be worse than a mapped one.
28
+ *
29
+ * ## Why this ALGORITHM is shared and only the TABLES are per-application
30
+ *
31
+ * Every application has different actions, so the tables have to be its own. The
32
+ * algorithm must not be, because it carries a correctness property that is
33
+ * invisible by construction — see {@link withRestoreForNoViolation}. An
34
+ * application writing its own planner is a chance to ship that bug silently, and
35
+ * no test written against the application's own mapping would catch it.
36
+ */
37
+ const SEVERITY_ORDER = ['low', 'medium', 'high', 'critical'];
38
+ /**
39
+ * Recommendations that ask for NO effect.
40
+ *
41
+ * An unmapped recommendation goes to `reviewAction`, because a recommendation
42
+ * this application has no action for is a decision a human should see. These
43
+ * three are the exception, and the distinction is not cosmetic: they are
44
+ * CrowdSource saying "take no action", so routing them to review would put a
45
+ * human in front of every cleared case and bury the ones that need looking at.
46
+ *
47
+ * An application's own table still wins — it may genuinely want `allow` to mean
48
+ * something — but the default for an application that maps nothing has to be
49
+ * "do nothing" rather than "wake somebody".
50
+ */
51
+ const NO_EFFECT_RECOMMENDATIONS = new Set([
52
+ 'allow',
53
+ 'no_action',
54
+ 'no_global_effect',
55
+ ]);
56
+ function actionForRecommendation(recommended, config) {
57
+ const mapped = config.recommendationToAction?.[recommended];
58
+ if (mapped !== undefined)
59
+ return mapped;
60
+ return NO_EFFECT_RECOMMENDATIONS.has(recommended)
61
+ ? config.noneAction
62
+ : config.reviewAction;
63
+ }
64
+ function highestSeverity(decision) {
65
+ let highest;
66
+ for (const finding of decision.findings) {
67
+ if (highest === undefined ||
68
+ SEVERITY_ORDER.indexOf(finding.severity) > SEVERITY_ORDER.indexOf(highest)) {
69
+ highest = finding.severity;
70
+ }
71
+ }
72
+ return highest;
73
+ }
74
+ /**
75
+ * `no_violation` always carries a restore, whatever it recommended.
76
+ *
77
+ * This exists because of a failure that is very easy to ship and very hard to
78
+ * see. A correction is a new revision whose outcome is `no_violation`, and its
79
+ * recommendation is frequently `no_action` — which is CrowdSource saying "take
80
+ * no NEW action", not "leave what you already did in place". Mapping that
81
+ * straight through plans nothing, and the object an earlier revision removed
82
+ * stays removed forever: the appeal succeeded, the case says the content was
83
+ * fine, and nothing in the application ever puts it back. No error, no log line,
84
+ * no failing test anywhere else.
85
+ *
86
+ * `allow`, `restore` and `no_action` are listed together as an application's
87
+ * options for `no_violation` precisely because choosing between them needs
88
+ * knowledge only the application has — whether it did something earlier. So the
89
+ * plan always includes the restore, and the executor records "there was nothing
90
+ * restricted" when that is the case, which is evidence rather than a silent
91
+ * no-op.
92
+ */
93
+ function restoreActions(declared) {
94
+ if (declared === null)
95
+ return [];
96
+ return typeof declared === 'string' ? [declared] : declared;
97
+ }
98
+ function withRestoreForNoViolation(decision, planned, declared) {
99
+ /**
100
+ * `null` is a decision the application made, not an omission — the type
101
+ * requires it to be written down. An application with no sanction primitive
102
+ * has nothing an earlier revision could have removed, so there is nothing for
103
+ * a correction to put back.
104
+ */
105
+ if (decision.outcome !== 'no_violation')
106
+ return planned;
107
+ /**
108
+ * EVERY declared restore, not just the first. An application whose levers are
109
+ * "hide it" and "label it" has two things a correction must undo, and planning
110
+ * one leaves the other stuck forever — the object is un-hidden and stays
111
+ * labelled, with no error and nothing failing. That is the same failure this
112
+ * function exists to prevent, applied to the second reversible action instead
113
+ * of the first.
114
+ *
115
+ * A restore with nothing to undo is not waste: the executor records
116
+ * `changed: false` with its reason, which is evidence that it was checked.
117
+ */
118
+ const missing = restoreActions(declared).filter((action) => !planned.some((entry) => entry.action === action));
119
+ if (missing.length === 0)
120
+ return planned;
121
+ return [
122
+ ...planned,
123
+ ...missing.map((action) => ({
124
+ action,
125
+ reason: 'No violation: undo any earlier restriction',
126
+ })),
127
+ ];
128
+ }
129
+ /**
130
+ * Collapse a plan to the actions that can coexist.
131
+ *
132
+ * A decision may recommend both removal and a label; a removed object does not
133
+ * need one, and recording both would claim two effects where one happened. So an
134
+ * action absorbs whatever the application declared it absorbs, and the explicit
135
+ * "nothing" never survives alongside anything else.
136
+ *
137
+ * `reviewAction` always survives — it is a note for a human, and dropping it
138
+ * because something else was also done is how a `suspend_user` recommendation
139
+ * gets lost.
140
+ */
141
+ function collapse(actions, config) {
142
+ const byAction = new Map();
143
+ for (const planned of actions) {
144
+ if (!byAction.has(planned.action))
145
+ byAction.set(planned.action, planned);
146
+ }
147
+ for (const [action, absorbed] of Object.entries(config.absorb ?? {})) {
148
+ if (!byAction.has(action))
149
+ continue;
150
+ for (const loser of absorbed ?? []) {
151
+ if (loser === config.reviewAction)
152
+ continue;
153
+ byAction.delete(loser);
154
+ }
155
+ }
156
+ if (byAction.size > 1)
157
+ byAction.delete(config.noneAction);
158
+ return Array.from(byAction.values());
159
+ }
160
+ /**
161
+ * What the application will do about this decision.
162
+ *
163
+ * Never empty: a decision that produces no action produces an explicit
164
+ * `noneAction`, because a row saying "we decided to do nothing, and why" is
165
+ * evidence and an absent row is a question.
166
+ */
167
+ /**
168
+ * Raised when `restoreAction` names actions that are being UNDONE rather than
169
+ * actions that DO the undoing.
170
+ *
171
+ * A doc line is not enough for this one. An inverted `restoreAction` type-checks
172
+ * — both directions are `TAction[]` — and it does not fail at runtime either: it
173
+ * plans, it claims, and it applies a restriction and a label on an accepted
174
+ * appeal. It succeeds at the opposite thing, on the one path whose whole purpose
175
+ * is to give something back.
176
+ *
177
+ * The signal is unambiguous when it exists. `reverses` maps each undoing action
178
+ * to what it undoes, so its VALUES are targets and its KEYS are actors. An
179
+ * action that appears only as a target has been declared as a restore by
180
+ * someone reading the targets, which is exactly the mistake this catches.
181
+ *
182
+ * Deliberately narrow: an action absent from `reverses` entirely is fine (it may
183
+ * undo something needing no previous state), and one that is both a key and a
184
+ * value is fine (it undoes and is undone). Only "a target, and never an actor"
185
+ * is reported, so a correct configuration cannot trip it.
186
+ */
187
+ class ModerationRestoreDirectionError extends Error {
188
+ constructor(inverted) {
189
+ super(`restoreAction names [${inverted.join(', ')}], which 'reverses' lists as actions ` +
190
+ 'being UNDONE rather than actions that do the undoing. restoreAction holds what ' +
191
+ "the planner emits on 'no_violation' — the restoring actions, e.g. " +
192
+ "['restore', 'unlabel_sensitive'] — not the restrictions being lifted. As written, " +
193
+ 'an accepted appeal would apply the punishment it was correcting.');
194
+ this.name = 'ModerationRestoreDirectionError';
195
+ }
196
+ }
197
+ exports.ModerationRestoreDirectionError = ModerationRestoreDirectionError;
198
+ /**
199
+ * Refuse an inverted `restoreAction` at construction rather than at the first
200
+ * correction, which may be weeks later and reads as a moderation decision
201
+ * rather than a configuration error.
202
+ */
203
+ function assertRestoreDirection(config) {
204
+ const reverses = config.reverses ?? {};
205
+ const entries = Object.entries(reverses);
206
+ const actors = new Set(entries.map(([actor]) => actor));
207
+ const targets = new Set();
208
+ for (const [, undone] of entries) {
209
+ if (undone === undefined)
210
+ continue;
211
+ for (const action of typeof undone === 'string' ? [undone] : undone) {
212
+ targets.add(action);
213
+ }
214
+ }
215
+ const inverted = restoreActions(config.restoreAction).filter((action) => targets.has(action) && !actors.has(action));
216
+ if (inverted.length > 0)
217
+ throw new ModerationRestoreDirectionError(inverted);
218
+ }
219
+ function planEnforcement(decision, config) {
220
+ const fromRecommendations = decision.recommendedActions.map((recommended) => ({
221
+ action: actionForRecommendation(recommended.action, config),
222
+ reason: `CrowdSource recommended ${recommended.action}`,
223
+ recommendedAction: recommended.action,
224
+ }));
225
+ if (fromRecommendations.length > 0) {
226
+ const collapsed = collapse(withRestoreForNoViolation(decision, fromRecommendations, config.restoreAction), config);
227
+ return collapsed.length > 0
228
+ ? collapsed
229
+ : [
230
+ {
231
+ action: config.noneAction,
232
+ reason: 'No recommended action maps to an effect this application has',
233
+ },
234
+ ];
235
+ }
236
+ switch (decision.outcome) {
237
+ case 'violation': {
238
+ const severity = highestSeverity(decision);
239
+ /**
240
+ * A `violation` with no findings cannot happen — the contract refuses it —
241
+ * so an absent severity here means a newer CrowdSource sent something this
242
+ * code has not seen. A human looks at it rather than a default removing an
243
+ * object.
244
+ */
245
+ if (severity === undefined) {
246
+ return [
247
+ {
248
+ action: config.reviewAction,
249
+ reason: 'Violation carried no finding severity this version understands',
250
+ },
251
+ ];
252
+ }
253
+ return [
254
+ {
255
+ action: config.severityFallback?.[severity] ?? config.reviewAction,
256
+ reason: `Violation with no recommended action, highest severity ${severity}`,
257
+ },
258
+ ];
259
+ }
260
+ case 'no_violation':
261
+ /**
262
+ * A restore, always planned — even when nothing was restricted. The
263
+ * executor records it as not applied with the reason, which is how "we
264
+ * checked and there was nothing to undo" is distinguishable from "we never
265
+ * looked".
266
+ */
267
+ {
268
+ const declared = restoreActions(config.restoreAction);
269
+ return declared.length === 0
270
+ ? [
271
+ {
272
+ action: config.noneAction,
273
+ reason: 'No violation, and this application has nothing to restore',
274
+ },
275
+ ]
276
+ : declared.map((action) => ({
277
+ action,
278
+ reason: 'No violation: undo any earlier restriction',
279
+ }));
280
+ }
281
+ case 'insufficient_context':
282
+ case 'inconclusive':
283
+ case 'escalated':
284
+ /**
285
+ * None of these is "remove", and none is "it was fine": absence of
286
+ * consensus is neither guilt nor innocence, so the application changes
287
+ * nothing on its own and asks a human.
288
+ */
289
+ return [
290
+ {
291
+ action: config.reviewAction,
292
+ reason: `Outcome ${decision.outcome}: no automatic action, internal review`,
293
+ },
294
+ ];
295
+ case 'content_unavailable':
296
+ case 'duplicate':
297
+ return [
298
+ {
299
+ action: config.noneAction,
300
+ reason: `Outcome ${decision.outcome}: nothing to enforce`,
301
+ },
302
+ ];
303
+ default:
304
+ /**
305
+ * An outcome the contract does not currently define. A newer server must
306
+ * not break an older client, and the safe reading of an unknown outcome is
307
+ * a human, never a default effect.
308
+ */
309
+ return [
310
+ {
311
+ action: config.reviewAction,
312
+ reason: 'Decision outcome not recognised by this version of the application',
313
+ },
314
+ ];
315
+ }
316
+ }
317
+ /**
318
+ * The one action worth recording on the report.
319
+ *
320
+ * One field, several planned actions, so it has to be the one that answers "what
321
+ * happened to this object". The application's `precedence` decides, strongest
322
+ * first — and `reviewAction` should sit near the end but ABOVE `noneAction`,
323
+ * because a reporter told "nothing happened" when a human is about to look is
324
+ * being told something untrue.
325
+ */
326
+ function primaryAction(actions, precedence) {
327
+ for (const candidate of precedence) {
328
+ if (actions.includes(candidate))
329
+ return candidate;
330
+ }
331
+ return actions[0];
332
+ }
333
+ //# sourceMappingURL=planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner.js","sourceRoot":"","sources":["../../../src/outbox/enforcement/planner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ import type { ReportInput } from '../index.js';
2
+ import type { ModerationReportFields, ModerationSubjectProvider, ModerationSubjectSnapshot, ModerationTaxonomy } from './types.js';
3
+ /**
4
+ * Turning a stored report into the thing the SDK delivers.
5
+ *
6
+ * This is NOT a case-envelope builder, and the difference matters enough to
7
+ * name: `@crowdsource.you/core` builds the Case Envelope, and it deliberately does
8
+ * not export the function that does it. What this module produces is the SDK's
9
+ * `ReportInput` — a description of the material — and the SDK derives the
10
+ * envelope from it: resource ids, relations, digests, pseudonymous principal
11
+ * refs, the identity binding proof, the pinned policy version, the privacy terms
12
+ * and the idempotency key.
13
+ *
14
+ * That is not a technicality. Those derived values are exactly what the case
15
+ * dedup key is computed over, so an application that composed its own envelope
16
+ * would be the reason two reporters about one object opened two cases — and "one
17
+ * penalty per incident" would fail in production with nothing failing in a test.
18
+ * Building the description and letting the SDK build the document is what keeps
19
+ * that property true for every application at once.
20
+ *
21
+ * So this module does three things and no more: ask the registry for a snapshot
22
+ * of the reported object, translate the reporter's categories into allegations,
23
+ * and assemble both with the report's own identity.
24
+ */
25
+ /**
26
+ * The material could not be described, because nothing can describe it.
27
+ *
28
+ * This is a DEFECT, not a state, and it should be unreachable. A report whose
29
+ * type has no subject provider never gets a delivery event in the first place —
30
+ * intake decides that from the same registry this module reads — so an event
31
+ * that arrives here has been created by something that bypassed intake, or by a
32
+ * deployment where a provider was removed while its reports were still in
33
+ * flight.
34
+ *
35
+ * `retryable: false` therefore dead-letters the outbox event, so the
36
+ * reconciliation sweep counts it and a human looks. The alternative — writing a
37
+ * local state — would file a genuine defect in the one place that looks
38
+ * identical to the deliberate local-only reports, and nothing would ever alert
39
+ * on it.
40
+ *
41
+ * Separate from "the object is gone": a deleted object is a fact about the world
42
+ * and closes the report normally.
43
+ */
44
+ export declare class ModerationSubjectUnsupportedError extends Error {
45
+ readonly retryable = false;
46
+ constructor(reportedType: string);
47
+ }
48
+ /**
49
+ * The application's taxonomy produced no allegation for a report.
50
+ *
51
+ * Not retryable and never silently defaulted. A report with no allegation is not
52
+ * a report, and substituting `other.unclassifiable` here would put a claim in
53
+ * front of a jury that no reporter made and that no version of the mapping
54
+ * records — the taxonomy is the application's to fix, and dead-lettering is what
55
+ * makes somebody fix it.
56
+ */
57
+ export declare class ModerationTaxonomyError extends Error {
58
+ readonly retryable = false;
59
+ constructor(categories: readonly string[]);
60
+ }
61
+ /**
62
+ * SHA-256 of the snapshot, stored on the report.
63
+ *
64
+ * Taken over the described MATERIAL, not over the whole `ReportInput`: the
65
+ * report id, the reporter and the allegations are properties of the report, and
66
+ * including them would mean two people reporting identical content produced
67
+ * different hashes — which is the opposite of what this hash is for. Key order
68
+ * is fixed by the literal below rather than by `Object.keys`, so the digest is
69
+ * stable across Node versions and across a refactor that reorders a field.
70
+ */
71
+ export declare function snapshotHash(snapshot: ModerationSubjectSnapshot): string;
72
+ /** The subject providers, indexed by the application's own reported type. */
73
+ export interface SubjectRegistry {
74
+ /**
75
+ * The provider for a reported type, or `undefined` when it is not deliverable.
76
+ *
77
+ * The single authority on whether a report leaves this deployment. Intake asks
78
+ * before queueing a delivery, and this module asks again when it builds one; a
79
+ * type this returns `undefined` for is stored and never enqueued.
80
+ */
81
+ providerFor(reportedType: string): ModerationSubjectProvider | undefined;
82
+ /**
83
+ * The reported types wired to CrowdSource, as the registry itself sees them.
84
+ *
85
+ * Exists so an application can pin the set in a test. That is not ceremony:
86
+ * the difference between a delivered type and a local-only one is invisible in
87
+ * a 201, so registering a provider — or forgetting to — is a change no
88
+ * response body would reveal.
89
+ */
90
+ deliverableTypes(): string[];
91
+ }
92
+ export declare function createSubjectRegistry(providers: readonly ModerationSubjectProvider[]): SubjectRegistry;
93
+ export interface ModerationReportInput {
94
+ /** What the SDK delivers. */
95
+ readonly reportInput: ReportInput;
96
+ /** The digest to store on the local report. */
97
+ readonly snapshotHash: string;
98
+ }
99
+ /**
100
+ * Describe a stored report for delivery, or report why it cannot be described.
101
+ *
102
+ * Returns `null` when the reported object no longer exists. That is not an error
103
+ * either: content deleted between the report and its delivery is ordinary, and
104
+ * evidence stays available through retention on CrowdSource's side — but an
105
+ * object the application never got to snapshot has no evidence to keep.
106
+ */
107
+ export declare function buildModerationReportInput(input: {
108
+ report: Pick<ModerationReportFields, 'reportedType' | 'reportedId' | 'reporter' | 'categories' | 'details' | 'createdAt'> & {
109
+ id: string;
110
+ };
111
+ registry: SubjectRegistry;
112
+ taxonomy: ModerationTaxonomy;
113
+ }): Promise<ModerationReportInput | null>;
114
+ //# sourceMappingURL=evidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../src/outbox/evidence.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EACV,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,iCAAkC,SAAQ,KAAK;IAC1D,QAAQ,CAAC,SAAS,SAAS;gBAEf,YAAY,EAAE,MAAM;CAIjC;AAED;;;;;;;;GAQG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,SAAS,SAAS;gBAEf,UAAU,EAAE,SAAS,MAAM,EAAE;CAO1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,CAYxE;AAED,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,yBAAyB,GAAG,SAAS,CAAC;IACzE;;;;;;;OAOG;IACH,gBAAgB,IAAI,MAAM,EAAE,CAAC;CAC9B;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,SAAS,yBAAyB,EAAE,GAC9C,eAAe,CAsBjB;AAED,MAAM,WAAW,qBAAqB;IACpC,6BAA6B;IAC7B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,+CAA+C;IAC/C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAAC,KAAK,EAAE;IACtD,MAAM,EAAE,IAAI,CACV,sBAAsB,EACtB,cAAc,GAAG,YAAY,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,WAAW,CACpF,GAAG;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACnB,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;CAC9B,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAwDxC"}