settld 0.1.2 → 0.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 (483) hide show
  1. package/README.md +93 -3
  2. package/SETTLD_VERSION +1 -1
  3. package/bin/settld-mcp +2 -0
  4. package/bin/settld.js +71 -0
  5. package/conformance/kernel-v0/README.md +7 -0
  6. package/conformance/kernel-v0/run.mjs +292 -4
  7. package/docs/ACCESS.md +57 -0
  8. package/docs/ADOPTION_CHECKLIST.md +44 -0
  9. package/docs/ALERTS.md +198 -0
  10. package/docs/ARCHITECTURE.md +69 -0
  11. package/docs/ARCHITECTURE_FOUNDER_GUIDE.md +284 -0
  12. package/docs/ARTIFACTS.md +60 -0
  13. package/docs/CERTIFICATION_CHECKLIST.md +33 -0
  14. package/docs/CIRCLE_SANDBOX_E2E.md +152 -0
  15. package/docs/CONFIG.md +297 -0
  16. package/docs/CONTRACTS_APIS.md +23 -0
  17. package/docs/DEPRECATION.md +31 -0
  18. package/docs/DOMAIN_MODEL.md +92 -0
  19. package/docs/EVENT_ENVELOPE.md +53 -0
  20. package/docs/FINANCE_PACK_FORMAT.md +53 -0
  21. package/docs/INCIDENT_TAXONOMY.md +30 -0
  22. package/docs/JOB_STATE_MACHINE.md +66 -0
  23. package/docs/KERNEL_COMPATIBLE.md +60 -0
  24. package/docs/KERNEL_V0.md +40 -0
  25. package/docs/KEY_ROTATION.md +80 -0
  26. package/docs/LEDGER.md +82 -0
  27. package/docs/LIVENESS.md +76 -0
  28. package/docs/MVP_BUILD_ORDER.md +36 -0
  29. package/docs/ONCALL_PLAYBOOK.md +39 -0
  30. package/docs/OPERATIONS_SIGNING.md +20 -0
  31. package/docs/OVERVIEW.md +190 -0
  32. package/docs/PERF_BASELINE.md +85 -0
  33. package/docs/PRD.md +77 -0
  34. package/docs/QUICKSTART_KERNEL_V0.md +96 -0
  35. package/docs/QUICKSTART_MCP.md +377 -0
  36. package/docs/QUICKSTART_MCP_HOSTS.md +210 -0
  37. package/docs/QUICKSTART_POLICY_PACKS.md +65 -0
  38. package/docs/QUICKSTART_PRODUCE.md +61 -0
  39. package/docs/QUICKSTART_PROFILES.md +198 -0
  40. package/docs/QUICKSTART_RELEASE_VERIFY.md +39 -0
  41. package/docs/QUICKSTART_SDK.md +125 -0
  42. package/docs/QUICKSTART_SDK_PYTHON.md +111 -0
  43. package/docs/QUICKSTART_VERIFY.md +54 -0
  44. package/docs/QUICKSTART_X402_GATEWAY.md +317 -0
  45. package/docs/README.md +33 -0
  46. package/docs/RELEASE_CHECKLIST.md +182 -0
  47. package/docs/RELEASING.md +82 -0
  48. package/docs/REPO_SETTINGS.md +37 -0
  49. package/docs/RUNBOOK.md +86 -0
  50. package/docs/SKILLS.md +42 -0
  51. package/docs/SKILL_BUNDLE_FORMAT.md +48 -0
  52. package/docs/SLO.md +131 -0
  53. package/docs/SUMMARY.md +17 -0
  54. package/docs/SUPPORT.md +31 -0
  55. package/docs/THREAT_MODEL.md +36 -0
  56. package/docs/TRUST.md +59 -0
  57. package/docs/WORKFLOW.md +35 -0
  58. package/docs/X402_BATCH_SETTLEMENT.md +126 -0
  59. package/docs/blog/2026-02-14-your-ai-agent-just-spent-500-where-is-the-receipt.md +73 -0
  60. package/docs/examples/x402-provider-payout-registry.example.json +14 -0
  61. package/docs/gitbook/README.md +64 -0
  62. package/docs/gitbook/SETUP.md +25 -0
  63. package/docs/gitbook/SUMMARY.md +15 -0
  64. package/docs/gitbook/api-reference.md +73 -0
  65. package/docs/gitbook/closepacks.md +55 -0
  66. package/docs/gitbook/conformance.md +59 -0
  67. package/docs/gitbook/core-primitives.md +85 -0
  68. package/docs/gitbook/dispute-lifecycle.md +33 -0
  69. package/docs/gitbook/faq.md +21 -0
  70. package/docs/gitbook/guides.md +49 -0
  71. package/docs/gitbook/operations-runbook.md +36 -0
  72. package/docs/gitbook/quickstart.md +103 -0
  73. package/docs/gitbook/replay-and-audit.md +30 -0
  74. package/docs/gitbook/sdk-reference.md +35 -0
  75. package/docs/gitbook/security-model.md +58 -0
  76. package/docs/integrations/README.md +15 -0
  77. package/docs/integrations/github-actions-verify.yml +31 -0
  78. package/docs/integrations/github-actions.md +34 -0
  79. package/docs/integrations/openclaw/CLAWHUB_PUBLISH_CHECKLIST.md +65 -0
  80. package/docs/integrations/openclaw/PUBLIC_QUICKSTART.md +95 -0
  81. package/docs/integrations/openclaw/settld-mcp-skill/SKILL.md +69 -0
  82. package/docs/integrations/openclaw/settld-mcp-skill/mcp-server.example.json +12 -0
  83. package/docs/kernel-compatible/capabilities.json +36 -0
  84. package/docs/marketing/agent-commerce-substrate.md +78 -0
  85. package/docs/marketing/hn-repost-2026-02-17.md +102 -0
  86. package/docs/marketing/show-hn-post.md +45 -0
  87. package/docs/ops/ARTIFACT_VERIFICATION_STATUS.md +43 -0
  88. package/docs/ops/BILLING_WEBHOOK_REPLAY.md +105 -0
  89. package/docs/ops/CI_FLAKE_BUDGET.md +31 -0
  90. package/docs/ops/DISPUTE_FINANCE_RECONCILIATION_PACKET.md +56 -0
  91. package/docs/ops/GO_LIVE_GATE_S13.md +27 -0
  92. package/docs/ops/HOSTED_BASELINE_R2.md +129 -0
  93. package/docs/ops/KERNEL_V0_SHIP_GATE.md +69 -0
  94. package/docs/ops/LIGHTHOUSE_PRODUCTION_CLOSE.md +51 -0
  95. package/docs/ops/MCP_COMPATIBILITY_MATRIX.md +30 -0
  96. package/docs/ops/MINIMUM_PRODUCTION_TOPOLOGY.md +89 -0
  97. package/docs/ops/P0_BACKEND_PROGRESS.md +150 -0
  98. package/docs/ops/PAYMENTS_ALPHA_R5.md +105 -0
  99. package/docs/ops/PILOT_ONBOARDING_RUNBOOK.md +112 -0
  100. package/docs/ops/PRODUCTION_DEPLOYMENT_CHECKLIST.md +140 -0
  101. package/docs/ops/R1_SLOS.md +66 -0
  102. package/docs/ops/RELEASE_SIGNING_INCIDENT.md +58 -0
  103. package/docs/ops/SELF_SERVE_LAUNCH_AUTOMATION.md +89 -0
  104. package/docs/ops/THROUGHPUT_DRILL_10X.md +48 -0
  105. package/docs/ops/TRUST_CONFIG_WIZARD.md +60 -0
  106. package/docs/ops/X402_PILOT_WEEKLY_METRICS.md +76 -0
  107. package/docs/ops/tool-call-disputes-holdback.md +52 -0
  108. package/docs/pilot-kit/PILOT_PACKAGE_SCORECARD_X402.md +46 -0
  109. package/docs/pilot-kit/README.md +29 -0
  110. package/docs/pilot-kit/architecture-one-pager.md +48 -0
  111. package/docs/pilot-kit/buyer-email.txt +19 -0
  112. package/docs/pilot-kit/buyer-one-pager.md +31 -0
  113. package/docs/pilot-kit/gtm-pilot-playbook.md +182 -0
  114. package/docs/pilot-kit/offline-verify.md +33 -0
  115. package/docs/pilot-kit/procurement-one-pager.md +50 -0
  116. package/docs/pilot-kit/rfp-clause.md +46 -0
  117. package/docs/pilot-kit/roi-calculator-template.csv +2 -0
  118. package/docs/pilot-kit/security-qa.md +153 -0
  119. package/docs/pilot-kit/security-summary.md +35 -0
  120. package/docs/plans/2026-02-13-mcp-spike-design.md +113 -0
  121. package/docs/plans/2026-02-20-trust-os-v1-jira-backlog.md +348 -0
  122. package/docs/plans/2026-02-21-agent-economic-actor-operating-model.md +169 -0
  123. package/docs/plans/2026-02-21-trust-os-v1-strategy.md +241 -0
  124. package/docs/research/2026-02-21-agent-spend-host-landscape.md +57 -0
  125. package/docs/spec/AcceptanceCriteria.v1.md +17 -0
  126. package/docs/spec/AcceptanceEvaluation.v1.md +10 -0
  127. package/docs/spec/AgentEvent.v1.md +47 -0
  128. package/docs/spec/AgentIdentity.v1.md +62 -0
  129. package/docs/spec/AgentPassport.v1.md +95 -0
  130. package/docs/spec/AgentReputation.v1.md +59 -0
  131. package/docs/spec/AgentReputation.v2.md +52 -0
  132. package/docs/spec/AgentRun.v1.md +47 -0
  133. package/docs/spec/AgentRunSettlement.v1.md +52 -0
  134. package/docs/spec/AgentWallet.v1.md +43 -0
  135. package/docs/spec/AgreementDelegation.v1.md +109 -0
  136. package/docs/spec/ArbitrationCase.v1.md +67 -0
  137. package/docs/spec/ArbitrationOutcomeMapping.v1.md +62 -0
  138. package/docs/spec/ArbitrationVerdict.v1.md +60 -0
  139. package/docs/spec/BundleHeadAttestation.v1.md +32 -0
  140. package/docs/spec/CANONICAL_JSON.md +31 -0
  141. package/docs/spec/CRYPTOGRAPHY.md +61 -0
  142. package/docs/spec/ClosePack.v1.md +49 -0
  143. package/docs/spec/ClosePackManifest.v1.md +24 -0
  144. package/docs/spec/DelegationGrant.v1.md +90 -0
  145. package/docs/spec/DisputeCaseLifecycle.v1.md +51 -0
  146. package/docs/spec/DisputeOpenEnvelope.v1.md +43 -0
  147. package/docs/spec/ERRORS.md +76 -0
  148. package/docs/spec/ESCROW_NETTING_INVARIANTS.md +71 -0
  149. package/docs/spec/EvidenceIndex.v1.md +20 -0
  150. package/docs/spec/ExecutionIntent.v1.md +90 -0
  151. package/docs/spec/FinancePackBundleManifest.v1.md +24 -0
  152. package/docs/spec/FundingHold.v1.md +60 -0
  153. package/docs/spec/GovernancePolicy.v1.md +34 -0
  154. package/docs/spec/GovernancePolicy.v2.md +30 -0
  155. package/docs/spec/INVARIANTS.md +389 -0
  156. package/docs/spec/InteractionDirectionMatrix.v1.md +30 -0
  157. package/docs/spec/InvoiceBundleManifest.v1.md +24 -0
  158. package/docs/spec/InvoiceClaim.v1.md +11 -0
  159. package/docs/spec/MONEY_RAIL_STATE_MACHINE.md +58 -0
  160. package/docs/spec/MarketplaceAcceptance.v2.md +46 -0
  161. package/docs/spec/MarketplaceOffer.v2.md +54 -0
  162. package/docs/spec/MeteringReport.v1.md +18 -0
  163. package/docs/spec/OperatorAction.v1.md +90 -0
  164. package/docs/spec/PRODUCER_ERRORS.md +42 -0
  165. package/docs/spec/PolicyDecision.v1.md +83 -0
  166. package/docs/spec/PricingMatrix.v1.md +20 -0
  167. package/docs/spec/PricingMatrixSignatures.v1.md +30 -0
  168. package/docs/spec/PricingMatrixSignatures.v2.md +29 -0
  169. package/docs/spec/ProduceCliOutput.v1.md +46 -0
  170. package/docs/spec/ProofBundleManifest.v1.md +24 -0
  171. package/docs/spec/README.md +109 -0
  172. package/docs/spec/REFERENCE_IMPLEMENTATIONS.md +29 -0
  173. package/docs/spec/REFERENCE_VERIFIER_BEHAVIOR.md +68 -0
  174. package/docs/spec/REMOTE_SIGNER.md +66 -0
  175. package/docs/spec/ReleaseIndex.v1.md +32 -0
  176. package/docs/spec/ReleaseIndexSignatures.v1.md +17 -0
  177. package/docs/spec/ReleaseTrust.v1.md +13 -0
  178. package/docs/spec/ReleaseTrust.v2.md +26 -0
  179. package/docs/spec/RemoteSignerRequest.v1.md +21 -0
  180. package/docs/spec/RemoteSignerResponse.v1.md +16 -0
  181. package/docs/spec/ReputationEvent.v1.md +63 -0
  182. package/docs/spec/RevocationList.v1.md +28 -0
  183. package/docs/spec/SIGNER_PROVIDER_PLUGIN.md +32 -0
  184. package/docs/spec/STRICTNESS.md +68 -0
  185. package/docs/spec/SUPPLY_CHAIN.md +33 -0
  186. package/docs/spec/SettlementAdjustment.v1.md +45 -0
  187. package/docs/spec/SettlementDecisionRecord.v1.md +48 -0
  188. package/docs/spec/SettlementDecisionRecord.v2.md +53 -0
  189. package/docs/spec/SettlementDecisionReport.v1.md +44 -0
  190. package/docs/spec/SettlementKernel.v1.md +59 -0
  191. package/docs/spec/SettlementReceipt.v1.md +63 -0
  192. package/docs/spec/SlaDefinition.v1.md +24 -0
  193. package/docs/spec/SlaEvaluation.v1.md +12 -0
  194. package/docs/spec/THREAT_MODEL.md +113 -0
  195. package/docs/spec/TOOL_PROVENANCE.md +30 -0
  196. package/docs/spec/TRUST_ANCHORS.md +84 -0
  197. package/docs/spec/TenantSettings.v1.md +90 -0
  198. package/docs/spec/TenantSettings.v2.md +99 -0
  199. package/docs/spec/TimestampProof.v1.md +25 -0
  200. package/docs/spec/ToolCallAgreement.v1.md +34 -0
  201. package/docs/spec/ToolCallEvidence.v1.md +47 -0
  202. package/docs/spec/ToolManifest.v1.md +47 -0
  203. package/docs/spec/VERIFIER_ENVIRONMENT.md +38 -0
  204. package/docs/spec/VERSIONING.md +107 -0
  205. package/docs/spec/VerificationReport.v1.md +50 -0
  206. package/docs/spec/VerifyAboutOutput.v1.md +10 -0
  207. package/docs/spec/VerifyCliOutput.v1.md +28 -0
  208. package/docs/spec/WARNINGS.md +83 -0
  209. package/docs/spec/error-codes.v1.txt +285 -0
  210. package/docs/spec/examples/agreement_delegation_v1.example.json +21 -0
  211. package/docs/spec/examples/arbitration_case_v1.example.json +26 -0
  212. package/docs/spec/examples/arbitration_verdict_v1.example.json +32 -0
  213. package/docs/spec/examples/dispute_open_envelope_v1.example.json +18 -0
  214. package/docs/spec/examples/produce_cli_output_v1.example.json +32 -0
  215. package/docs/spec/examples/release_index_signature_v1.example.json +9 -0
  216. package/docs/spec/examples/release_index_signatures_v1.example.json +14 -0
  217. package/docs/spec/examples/release_index_v1.example.json +15 -0
  218. package/docs/spec/examples/release_trust_v1.example.json +7 -0
  219. package/docs/spec/examples/release_trust_v2.example.json +22 -0
  220. package/docs/spec/examples/remote_signer_request_v1.example.json +18 -0
  221. package/docs/spec/examples/remote_signer_response_v1.example.json +8 -0
  222. package/docs/spec/examples/reputation_event_v1.example.json +29 -0
  223. package/docs/spec/examples/verification_report_v1.example.json +24 -0
  224. package/docs/spec/examples/verify_about_output_v1.example.json +29 -0
  225. package/docs/spec/examples/verify_cli_output_v1.example.json +13 -0
  226. package/docs/spec/legacy/MarketplaceAcceptance.v1.md +48 -0
  227. package/docs/spec/legacy/MarketplaceOffer.v1.md +56 -0
  228. package/docs/spec/legacy/schemas/MarketplaceAcceptance.v1.schema.json +53 -0
  229. package/docs/spec/legacy/schemas/MarketplaceOffer.v1.schema.json +61 -0
  230. package/docs/spec/producer-error-codes.v1.txt +14 -0
  231. package/docs/spec/schemas/AcceptanceCriteria.v1.schema.json +24 -0
  232. package/docs/spec/schemas/AcceptanceEvaluation.v1.schema.json +26 -0
  233. package/docs/spec/schemas/AgentEvent.v1.schema.json +49 -0
  234. package/docs/spec/schemas/AgentIdentity.v1.schema.json +129 -0
  235. package/docs/spec/schemas/AgentPassport.v1.schema.json +112 -0
  236. package/docs/spec/schemas/AgentReputation.v1.schema.json +151 -0
  237. package/docs/spec/schemas/AgentReputation.v2.schema.json +120 -0
  238. package/docs/spec/schemas/AgentRun.v1.schema.json +71 -0
  239. package/docs/spec/schemas/AgentRunSettlement.v1.schema.json +75 -0
  240. package/docs/spec/schemas/AgentWallet.v1.schema.json +54 -0
  241. package/docs/spec/schemas/AgreementDelegation.v1.schema.json +50 -0
  242. package/docs/spec/schemas/ArbitrationCase.v1.schema.json +133 -0
  243. package/docs/spec/schemas/ArbitrationVerdict.v1.schema.json +149 -0
  244. package/docs/spec/schemas/BundleHeadAttestation.v1.schema.json +21 -0
  245. package/docs/spec/schemas/ClosePackManifest.v1.schema.json +38 -0
  246. package/docs/spec/schemas/DelegationGrant.v1.schema.json +102 -0
  247. package/docs/spec/schemas/DisputeOpenEnvelope.v1.schema.json +78 -0
  248. package/docs/spec/schemas/EvidenceIndex.v1.schema.json +41 -0
  249. package/docs/spec/schemas/ExecutionIntent.v1.schema.json +85 -0
  250. package/docs/spec/schemas/FinancePackBundleManifest.v1.schema.json +38 -0
  251. package/docs/spec/schemas/FundingHold.v1.schema.json +46 -0
  252. package/docs/spec/schemas/GovernancePolicy.v1.schema.json +45 -0
  253. package/docs/spec/schemas/GovernancePolicy.v2.schema.json +70 -0
  254. package/docs/spec/schemas/InteractionDirectionMatrix.v1.schema.json +43 -0
  255. package/docs/spec/schemas/InvoiceBundleManifest.v1.schema.json +38 -0
  256. package/docs/spec/schemas/InvoiceClaim.v1.schema.json +39 -0
  257. package/docs/spec/schemas/MarketplaceAcceptance.v2.schema.json +53 -0
  258. package/docs/spec/schemas/MarketplaceOffer.v2.schema.json +61 -0
  259. package/docs/spec/schemas/MeteringReport.v1.schema.json +45 -0
  260. package/docs/spec/schemas/OperatorAction.v1.schema.json +113 -0
  261. package/docs/spec/schemas/PolicyDecision.v1.schema.json +74 -0
  262. package/docs/spec/schemas/PricingMatrix.v1.schema.json +24 -0
  263. package/docs/spec/schemas/PricingMatrixSignatures.v1.schema.json +24 -0
  264. package/docs/spec/schemas/PricingMatrixSignatures.v2.schema.json +24 -0
  265. package/docs/spec/schemas/ProduceCliOutput.v1.schema.json +107 -0
  266. package/docs/spec/schemas/ProofBundleManifest.v1.schema.json +37 -0
  267. package/docs/spec/schemas/PublicKeys.v1.schema.json +33 -0
  268. package/docs/spec/schemas/ReleaseIndex.v1.schema.json +45 -0
  269. package/docs/spec/schemas/ReleaseIndexSignature.v1.schema.json +16 -0
  270. package/docs/spec/schemas/ReleaseIndexSignatures.v1.schema.json +16 -0
  271. package/docs/spec/schemas/ReleaseTrust.v1.schema.json +15 -0
  272. package/docs/spec/schemas/ReleaseTrust.v2.schema.json +37 -0
  273. package/docs/spec/schemas/RemoteSignerPublicKeyResponse.v1.schema.json +14 -0
  274. package/docs/spec/schemas/RemoteSignerRequest.v1.schema.json +24 -0
  275. package/docs/spec/schemas/RemoteSignerResponse.v1.schema.json +10 -0
  276. package/docs/spec/schemas/RemoteSignerSignRequest.v1.schema.json +27 -0
  277. package/docs/spec/schemas/RemoteSignerSignResponse.v1.schema.json +16 -0
  278. package/docs/spec/schemas/ReputationEvent.v1.schema.json +164 -0
  279. package/docs/spec/schemas/RevocationList.v1.schema.json +51 -0
  280. package/docs/spec/schemas/SettlementAdjustment.v1.schema.json +44 -0
  281. package/docs/spec/schemas/SettlementDecisionRecord.v1.schema.json +66 -0
  282. package/docs/spec/schemas/SettlementDecisionRecord.v2.schema.json +149 -0
  283. package/docs/spec/schemas/SettlementDecisionReport.v1.schema.json +61 -0
  284. package/docs/spec/schemas/SettlementReceipt.v1.schema.json +135 -0
  285. package/docs/spec/schemas/SlaDefinition.v1.schema.json +33 -0
  286. package/docs/spec/schemas/SlaEvaluation.v1.schema.json +26 -0
  287. package/docs/spec/schemas/TenantSettings.v1.schema.json +90 -0
  288. package/docs/spec/schemas/TenantSettings.v2.schema.json +161 -0
  289. package/docs/spec/schemas/TimestampProof.v1.schema.json +17 -0
  290. package/docs/spec/schemas/ToolCallAgreement.v1.schema.json +34 -0
  291. package/docs/spec/schemas/ToolCallEvidence.v1.schema.json +45 -0
  292. package/docs/spec/schemas/ToolManifest.v1.schema.json +54 -0
  293. package/docs/spec/schemas/VerificationReport.v1.schema.json +83 -0
  294. package/docs/spec/schemas/VerifyAboutOutput.v1.schema.json +54 -0
  295. package/docs/spec/schemas/VerifyCliOutput.v1.schema.json +75 -0
  296. package/docs/spec/schemas/VerifyReleaseOutput.v1.schema.json +47 -0
  297. package/docs/spec/x402-error-codes.v1.txt +35 -0
  298. package/docs/templates/buyer-email.txt +18 -0
  299. package/docs/templates/buyer-one-pager.md +24 -0
  300. package/package.json +53 -6
  301. package/scripts/acceptance/full-stack.mjs +734 -0
  302. package/scripts/acceptance/full-stack.sh +99 -0
  303. package/scripts/audit/build-audit-packet.mjs +242 -0
  304. package/scripts/backup-pg.sh +45 -0
  305. package/scripts/backup-restore/README.md +18 -0
  306. package/scripts/backup-restore/capture-state.mjs +130 -0
  307. package/scripts/backup-restore/client.mjs +97 -0
  308. package/scripts/backup-restore/seed-workload.mjs +235 -0
  309. package/scripts/backup-restore/verify-state.mjs +139 -0
  310. package/scripts/backup-restore-test.sh +217 -0
  311. package/scripts/chaos.js +221 -0
  312. package/scripts/ci/build-launch-cutover-packet.mjs +304 -0
  313. package/scripts/ci/build-self-serve-benchmark-report.mjs +122 -0
  314. package/scripts/ci/changelog-guard.mjs +145 -0
  315. package/scripts/ci/check-kernel-v0-launch-gate.mjs +233 -0
  316. package/scripts/ci/check-secret-hygiene.mjs +78 -0
  317. package/scripts/ci/check-version-consistency.mjs +42 -0
  318. package/scripts/ci/cli-pack-smoke.mjs +160 -0
  319. package/scripts/ci/flake-budget-guard.mjs +68 -0
  320. package/scripts/ci/generate-error-codes.mjs +54 -0
  321. package/scripts/ci/lib/lighthouse-tracker.mjs +90 -0
  322. package/scripts/ci/lib/self-serve-launch-gate.mjs +89 -0
  323. package/scripts/ci/npm-pack-smoke.mjs +454 -0
  324. package/scripts/ci/run-10x-throughput-drill.mjs +318 -0
  325. package/scripts/ci/run-10x-throughput-incident-rehearsal.mjs +368 -0
  326. package/scripts/ci/run-arbitration-workspace-browser-e2e.sh +22 -0
  327. package/scripts/ci/run-circle-sandbox-smoke.mjs +237 -0
  328. package/scripts/ci/run-go-live-gate.mjs +150 -0
  329. package/scripts/ci/run-kernel-v0-ship-gate.mjs +97 -0
  330. package/scripts/ci/run-mcp-host-cert-matrix.mjs +201 -0
  331. package/scripts/ci/run-mcp-host-smoke.mjs +473 -0
  332. package/scripts/ci/run-offline-verification-parity-gate.mjs +762 -0
  333. package/scripts/ci/run-onboarding-host-success-gate.mjs +516 -0
  334. package/scripts/ci/run-onboarding-policy-slo-gate.mjs +537 -0
  335. package/scripts/ci/run-production-cutover-gate.mjs +540 -0
  336. package/scripts/ci/run-public-openclaw-npx-smoke.mjs +148 -0
  337. package/scripts/ci/run-release-promotion-guard.mjs +756 -0
  338. package/scripts/ci/run-self-serve-launch-gate.mjs +56 -0
  339. package/scripts/ci/runtime-import-smoke.mjs +58 -0
  340. package/scripts/ci/update-lighthouse-tracker.mjs +112 -0
  341. package/scripts/closepack/lib.mjs +286 -0
  342. package/scripts/collect-debug.sh +263 -0
  343. package/scripts/demo/compositional-settlement-3hop.mjs +237 -0
  344. package/scripts/demo/delivery-robot/export-ui-fixture.mjs +188 -0
  345. package/scripts/demo/delivery-robot/generate.mjs +377 -0
  346. package/scripts/demo/kernel-agent-goes-shopping.mjs +202 -0
  347. package/scripts/demo/magic-link-first-green.mjs +118 -0
  348. package/scripts/demo/magic-link-kind-smoke.mjs +577 -0
  349. package/scripts/demo/mcp-paid-exa.mjs +1110 -0
  350. package/scripts/dev/billing-doctor.sh +145 -0
  351. package/scripts/dev/billing-smoke-prod.sh +219 -0
  352. package/scripts/dev/billing-webhook-replay.sh +161 -0
  353. package/scripts/dev/env.dev.example +29 -0
  354. package/scripts/dev/env.sh +37 -0
  355. package/scripts/dev/new-sdk-key.sh +81 -0
  356. package/scripts/dev/sdk-first-run.sh +21 -0
  357. package/scripts/dev/smoke-x402-gateway.sh +115 -0
  358. package/scripts/dev/start-api.sh +24 -0
  359. package/scripts/doctor/mcp-host.mjs +120 -0
  360. package/scripts/examples/produce-and-verify-jobproof.mjs +191 -0
  361. package/scripts/examples/sdk-first-paid-rfq.py +105 -0
  362. package/scripts/examples/sdk-first-verified-run.mjs +85 -0
  363. package/scripts/examples/sdk-first-verified-run.py +99 -0
  364. package/scripts/examples/sdk-tenant-analytics.mjs +103 -0
  365. package/scripts/examples/sdk-tenant-analytics.py +118 -0
  366. package/scripts/finance-pack/bundle.mjs +284 -0
  367. package/scripts/fixtures/generate-bundle-fixtures.mjs +877 -0
  368. package/scripts/governance/export.mjs +169 -0
  369. package/scripts/load/delivery-stress.k6.js +183 -0
  370. package/scripts/load/ingest-burst.k6.js +236 -0
  371. package/scripts/load/run-delivery-load.js +66 -0
  372. package/scripts/load/webhook-receiver.js +131 -0
  373. package/scripts/magic-link/migrate-run-records-to-db.mjs +35 -0
  374. package/scripts/mcp/probe.mjs +238 -0
  375. package/scripts/mcp/settld-mcp-http-gateway.mjs +178 -0
  376. package/scripts/mcp/settld-mcp-server.mjs +1511 -0
  377. package/scripts/openapi/write.mjs +13 -0
  378. package/scripts/ops/bootstrap-tenant-conformance.mjs +185 -0
  379. package/scripts/ops/build-x402-pilot-reliability-report.mjs +489 -0
  380. package/scripts/ops/check-x402-receipt-sample.mjs +181 -0
  381. package/scripts/ops/design-partner-run-packet.mjs +466 -0
  382. package/scripts/ops/dispute-finance-reconciliation-packet.mjs +313 -0
  383. package/scripts/ops/hosted-baseline-evidence.mjs +890 -0
  384. package/scripts/ops/money-rails-chargeback-evidence.mjs +509 -0
  385. package/scripts/ops/money-rails-reconcile-evidence.mjs +180 -0
  386. package/scripts/ops/p0-seed-money-rail-operation.mjs +432 -0
  387. package/scripts/ops/run-x402-hitl-smoke.mjs +607 -0
  388. package/scripts/pilot/finance-pack.mjs +495 -0
  389. package/scripts/pilot/fixtures/robot-keypair.json +4 -0
  390. package/scripts/pilot/fixtures/server-signer.json +4 -0
  391. package/scripts/policy/cli.mjs +600 -0
  392. package/scripts/profile/cli.mjs +1324 -0
  393. package/scripts/proof-bundle/job.mjs +109 -0
  394. package/scripts/proof-bundle/lib.mjs +92 -0
  395. package/scripts/proof-bundle/month.mjs +103 -0
  396. package/scripts/provider/conformance-run.mjs +159 -0
  397. package/scripts/provider/keys-generate.mjs +135 -0
  398. package/scripts/provider/publish.mjs +420 -0
  399. package/scripts/quickstart/x402.mjs +334 -0
  400. package/scripts/register-entity-secret.mjs +102 -0
  401. package/scripts/release/build-artifacts.mjs +181 -0
  402. package/scripts/release/generate-release-index.mjs +112 -0
  403. package/scripts/release/release-index-lib.mjs +232 -0
  404. package/scripts/release/sign-release-index.mjs +85 -0
  405. package/scripts/release/validate-release-assets.mjs +170 -0
  406. package/scripts/release/verify-release.mjs +261 -0
  407. package/scripts/restore-pg.sh +34 -0
  408. package/scripts/scaffold/create-settld-paid-tool.mjs +19 -0
  409. package/scripts/sdk/smoke-python.py +30 -0
  410. package/scripts/sdk/smoke.mjs +16 -0
  411. package/scripts/settlement/x402-batch-worker.mjs +1091 -0
  412. package/scripts/setup/circle-bootstrap.mjs +310 -0
  413. package/scripts/setup/host-config.mjs +617 -0
  414. package/scripts/setup/onboard.mjs +1337 -0
  415. package/scripts/setup/openclaw-onboard.mjs +423 -0
  416. package/scripts/setup/wizard.mjs +986 -0
  417. package/scripts/slo/check.mjs +239 -0
  418. package/scripts/smoke/k8s-smoke.mjs +214 -0
  419. package/scripts/spec/generate-protocol-vectors.mjs +1019 -0
  420. package/scripts/test/check-no-generated-artifacts.sh +12 -0
  421. package/scripts/test/run.sh +59 -0
  422. package/scripts/trust/validate-trust-file.mjs +57 -0
  423. package/scripts/trust-config/rotate-settld-pay.mjs +277 -0
  424. package/scripts/trust-config/wizard.mjs +161 -0
  425. package/scripts/vendor-contract-test-lib.mjs +182 -0
  426. package/scripts/vendor-contract-test.mjs +55 -0
  427. package/scripts/vercel/build-mkdocs.sh +9 -0
  428. package/scripts/vercel/ignore-mkdocs.sh +25 -0
  429. package/scripts/vercel/install-mkdocs.sh +6 -0
  430. package/scripts/verify-pg.js +217 -0
  431. package/scripts/x402/receipt-verify.mjs +289 -0
  432. package/services/finance-sink/src/dedupe-store.js +29 -6
  433. package/services/receiver/src/dedupe-store.js +29 -5
  434. package/services/x402-gateway/Dockerfile +13 -0
  435. package/services/x402-gateway/README.md +58 -0
  436. package/services/x402-gateway/examples/upstream-mock.js +337 -0
  437. package/services/x402-gateway/src/server.js +1058 -0
  438. package/src/api/app.js +34658 -16940
  439. package/src/api/maintenance.js +70 -0
  440. package/src/api/middleware/trust-kernel.js +114 -0
  441. package/src/api/openapi.js +1778 -70
  442. package/src/api/persistence.js +456 -0
  443. package/src/api/server.js +81 -5
  444. package/src/api/store.js +1581 -62
  445. package/src/api/workers/deliveries.js +99 -4
  446. package/src/api/workers/insolvency-sweep.js +159 -0
  447. package/src/core/agent-card.js +69 -0
  448. package/src/core/agent-wallets.js +231 -0
  449. package/src/core/agreement-delegation.js +549 -0
  450. package/src/core/billing-plans.js +40 -6
  451. package/src/core/circle-reserve-adapter.js +845 -0
  452. package/src/core/event-policy.js +21 -2
  453. package/src/core/maintenance-locks.js +1 -0
  454. package/src/core/operator-action.js +303 -0
  455. package/src/core/paid-tool-manifest.js +318 -0
  456. package/src/core/policy-decision.js +322 -0
  457. package/src/core/policy-packs.js +207 -0
  458. package/src/core/profile-fingerprint.js +27 -0
  459. package/src/core/profile-simulation-reasons.js +84 -0
  460. package/src/core/profile-templates.js +242 -0
  461. package/src/core/provider-publish-conformance.js +525 -0
  462. package/src/core/provider-publish-proof.js +396 -0
  463. package/src/core/provider-quote-signature.js +170 -0
  464. package/src/core/settld-keys.js +112 -0
  465. package/src/core/settld-pay-token.js +344 -0
  466. package/src/core/settlement-kernel.js +239 -2
  467. package/src/core/settlement-verifier.js +335 -0
  468. package/src/core/tool-call-agreement.js +112 -0
  469. package/src/core/tool-call-evidence.js +144 -0
  470. package/src/core/tool-provider-signature.js +98 -0
  471. package/src/core/wallet-assignment-resolver.js +129 -0
  472. package/src/core/wallet-provider-bootstrap.js +365 -0
  473. package/src/core/x402-escalation-override.js +258 -0
  474. package/src/core/x402-gate.js +118 -0
  475. package/src/core/x402-provider-refund-decision.js +220 -0
  476. package/src/core/x402-receipt-verifier.js +708 -0
  477. package/src/core/x402-reversal-command.js +251 -0
  478. package/src/core/x402-wallet-issuer-decision.js +252 -0
  479. package/src/core/zk-verifier.js +300 -0
  480. package/src/db/migrations/029_reputation_event_index.sql +54 -0
  481. package/src/db/migrations/030_artifacts_source_event_unique_job_only.sql +15 -0
  482. package/src/db/pg.js +18 -7
  483. package/src/db/store-pg.js +1508 -111
@@ -0,0 +1,300 @@
1
+ const SUPPORTED_X402_ZK_PROTOCOLS = new Set(["groth16", "plonk", "stark"]);
2
+ const CRYPTOGRAPHIC_ZK_PROTOCOLS = new Set(["groth16", "plonk"]);
3
+
4
+ let snarkJsPromise = null;
5
+
6
+ function normalizeOptionalSha256(value) {
7
+ if (value === null || value === undefined) return null;
8
+ if (typeof value !== "string") return null;
9
+ const normalized = value.trim().toLowerCase();
10
+ return /^[0-9a-f]{64}$/.test(normalized) ? normalized : null;
11
+ }
12
+
13
+ function normalizeOptionalRef(value) {
14
+ if (value === null || value === undefined) return null;
15
+ if (typeof value !== "string") return null;
16
+ const normalized = value.trim();
17
+ return normalized ? normalized : null;
18
+ }
19
+
20
+ async function loadSnarkJs() {
21
+ if (!snarkJsPromise) {
22
+ snarkJsPromise = import("snarkjs");
23
+ }
24
+ return await snarkJsPromise;
25
+ }
26
+
27
+ async function terminateSnarkCurves() {
28
+ const candidates = [globalThis?.curve_bn128, globalThis?.curve_bls12381];
29
+ for (const curve of candidates) {
30
+ if (curve && typeof curve.terminate === "function") {
31
+ try {
32
+ await curve.terminate();
33
+ } catch {
34
+ // Best-effort cleanup to prevent lingering worker MessagePorts.
35
+ }
36
+ }
37
+ }
38
+ }
39
+
40
+ export function listSupportedX402ZkProofProtocols() {
41
+ return Array.from(SUPPORTED_X402_ZK_PROTOCOLS.values());
42
+ }
43
+
44
+ export async function verifyX402ExecutionProofV1({
45
+ proof = null,
46
+ verificationKey = null,
47
+ expectedVerificationKeyRef = null,
48
+ requiredProtocol = null,
49
+ expectedBindings = null,
50
+ requireBindings = false,
51
+ protocolAdapters = null
52
+ } = {}) {
53
+ if (!proof || typeof proof !== "object" || Array.isArray(proof)) {
54
+ return {
55
+ present: false,
56
+ status: "not_provided",
57
+ verified: null,
58
+ code: null,
59
+ message: null
60
+ };
61
+ }
62
+
63
+ const protocol = typeof proof.protocol === "string" ? proof.protocol.trim().toLowerCase() : "";
64
+ if (!protocol || !SUPPORTED_X402_ZK_PROTOCOLS.has(protocol)) {
65
+ return {
66
+ present: true,
67
+ protocol: protocol || null,
68
+ status: "unsupported_protocol",
69
+ verified: false,
70
+ code: "X402_ZK_PROOF_PROTOCOL_UNSUPPORTED",
71
+ message: "proof.protocol is not supported"
72
+ };
73
+ }
74
+
75
+ const requiredProtocolNormalized = typeof requiredProtocol === "string" ? requiredProtocol.trim().toLowerCase() : null;
76
+ if (requiredProtocolNormalized && protocol !== requiredProtocolNormalized) {
77
+ return {
78
+ present: true,
79
+ protocol,
80
+ status: "protocol_mismatch",
81
+ verified: false,
82
+ code: "X402_ZK_PROOF_PROTOCOL_MISMATCH",
83
+ message: "proof protocol does not match required policy protocol",
84
+ details: {
85
+ requiredProtocol: requiredProtocolNormalized
86
+ }
87
+ };
88
+ }
89
+
90
+ if (!CRYPTOGRAPHIC_ZK_PROTOCOLS.has(protocol)) {
91
+ return {
92
+ present: true,
93
+ protocol,
94
+ status: "unsupported_protocol",
95
+ verified: false,
96
+ code: "X402_ZK_PROOF_PROTOCOL_UNSUPPORTED",
97
+ message: "proof protocol is not supported by verifier"
98
+ };
99
+ }
100
+
101
+ const proofVerificationKey =
102
+ proof.verificationKey && typeof proof.verificationKey === "object" && !Array.isArray(proof.verificationKey)
103
+ ? proof.verificationKey
104
+ : null;
105
+ const policyVerificationKey =
106
+ verificationKey && typeof verificationKey === "object" && !Array.isArray(verificationKey) ? verificationKey : null;
107
+ const effectiveVerificationKey = policyVerificationKey ?? proofVerificationKey;
108
+ if (!effectiveVerificationKey) {
109
+ return {
110
+ present: true,
111
+ protocol,
112
+ status: "verification_key_missing",
113
+ verified: false,
114
+ code: "X402_ZK_PROOF_VERIFICATION_KEY_MISSING",
115
+ message: "proof verification key is required"
116
+ };
117
+ }
118
+
119
+ const proofVerificationKeyRef = normalizeOptionalRef(proof.verificationKeyRef ?? null);
120
+ const expectedVerificationKeyRefNormalized = normalizeOptionalRef(expectedVerificationKeyRef);
121
+ if (
122
+ expectedVerificationKeyRefNormalized &&
123
+ proofVerificationKeyRef &&
124
+ proofVerificationKeyRef !== expectedVerificationKeyRefNormalized
125
+ ) {
126
+ return {
127
+ present: true,
128
+ protocol,
129
+ status: "verification_key_ref_mismatch",
130
+ verified: false,
131
+ code: "X402_ZK_PROOF_VERIFICATION_KEY_REF_MISMATCH",
132
+ message: "proof verification key ref does not match policy",
133
+ details: {
134
+ expectedVerificationKeyRef: expectedVerificationKeyRefNormalized,
135
+ verificationKeyRef: proofVerificationKeyRef
136
+ }
137
+ };
138
+ }
139
+ if (expectedVerificationKeyRefNormalized && !proofVerificationKeyRef && !proofVerificationKey) {
140
+ return {
141
+ present: true,
142
+ protocol,
143
+ status: "verification_key_ref_missing",
144
+ verified: false,
145
+ code: "X402_ZK_PROOF_VERIFICATION_KEY_REF_REQUIRED",
146
+ message: "proof verification key ref is required by policy",
147
+ details: {
148
+ expectedVerificationKeyRef: expectedVerificationKeyRefNormalized
149
+ }
150
+ };
151
+ }
152
+
153
+ const expected = expectedBindings && typeof expectedBindings === "object" && !Array.isArray(expectedBindings) ? expectedBindings : null;
154
+ if (expected) {
155
+ const checks = [
156
+ {
157
+ proofField: "statementHashSha256",
158
+ expectedField: "statementHashSha256",
159
+ mismatchCode: "X402_ZK_PROOF_STATEMENT_HASH_MISMATCH",
160
+ missingCode: "X402_ZK_PROOF_STATEMENT_HASH_REQUIRED"
161
+ },
162
+ {
163
+ proofField: "inputDigestSha256",
164
+ expectedField: "inputDigestSha256",
165
+ mismatchCode: "X402_ZK_PROOF_INPUT_DIGEST_MISMATCH",
166
+ missingCode: "X402_ZK_PROOF_INPUT_DIGEST_REQUIRED"
167
+ },
168
+ {
169
+ proofField: "outputDigestSha256",
170
+ expectedField: "outputDigestSha256",
171
+ mismatchCode: "X402_ZK_PROOF_OUTPUT_DIGEST_MISMATCH",
172
+ missingCode: "X402_ZK_PROOF_OUTPUT_DIGEST_REQUIRED"
173
+ }
174
+ ];
175
+ for (const check of checks) {
176
+ const expectedValue = normalizeOptionalSha256(expected[check.expectedField]);
177
+ if (!expectedValue) continue;
178
+ const proofValue = normalizeOptionalSha256(proof[check.proofField]);
179
+ if (!proofValue) {
180
+ if (requireBindings) {
181
+ return {
182
+ present: true,
183
+ protocol,
184
+ status: "binding_missing",
185
+ verified: false,
186
+ code: check.missingCode,
187
+ message: `${check.proofField} is required for binding`
188
+ };
189
+ }
190
+ continue;
191
+ }
192
+ if (proofValue !== expectedValue) {
193
+ return {
194
+ present: true,
195
+ protocol,
196
+ status: "binding_mismatch",
197
+ verified: false,
198
+ code: check.mismatchCode,
199
+ message: `${check.proofField} does not match expected binding`,
200
+ details: {
201
+ expectedField: check.expectedField
202
+ }
203
+ };
204
+ }
205
+ }
206
+ }
207
+
208
+ if (!Array.isArray(proof.publicSignals)) {
209
+ return {
210
+ present: true,
211
+ protocol,
212
+ status: "malformed",
213
+ verified: false,
214
+ code: "X402_ZK_PROOF_PUBLIC_SIGNALS_INVALID",
215
+ message: "proof.publicSignals must be an array"
216
+ };
217
+ }
218
+ if (!proof.proofData || typeof proof.proofData !== "object" || Array.isArray(proof.proofData)) {
219
+ return {
220
+ present: true,
221
+ protocol,
222
+ status: "malformed",
223
+ verified: false,
224
+ code: "X402_ZK_PROOF_DATA_INVALID",
225
+ message: "proof.proofData must be an object"
226
+ };
227
+ }
228
+
229
+ const adapterMap =
230
+ protocolAdapters && typeof protocolAdapters === "object" && !Array.isArray(protocolAdapters) ? protocolAdapters : null;
231
+ let verifierFn = adapterMap && typeof adapterMap[protocol] === "function" ? adapterMap[protocol] : null;
232
+ if (!verifierFn) {
233
+ let snarkjs;
234
+ try {
235
+ snarkjs = await loadSnarkJs();
236
+ } catch (err) {
237
+ return {
238
+ present: true,
239
+ protocol,
240
+ status: "verifier_unavailable",
241
+ verified: false,
242
+ code: "X402_ZK_VERIFIER_UNAVAILABLE",
243
+ message: "snarkjs verifier is unavailable",
244
+ details: {
245
+ error: err?.message ?? String(err ?? "")
246
+ }
247
+ };
248
+ }
249
+ if (protocol === "groth16") verifierFn = snarkjs?.groth16?.verify;
250
+ if (protocol === "plonk") verifierFn = snarkjs?.plonk?.verify;
251
+ }
252
+ if (typeof verifierFn !== "function") {
253
+ return {
254
+ present: true,
255
+ protocol,
256
+ status: "verifier_unavailable",
257
+ verified: false,
258
+ code: "X402_ZK_VERIFIER_UNAVAILABLE",
259
+ message: `no verifier is configured for protocol ${protocol}`
260
+ };
261
+ }
262
+
263
+ try {
264
+ const ok = await verifierFn(effectiveVerificationKey, proof.publicSignals, proof.proofData);
265
+ if (ok === true) {
266
+ return {
267
+ present: true,
268
+ protocol,
269
+ status: "verified",
270
+ verified: true,
271
+ code: null,
272
+ message: null
273
+ };
274
+ }
275
+ return {
276
+ present: true,
277
+ protocol,
278
+ status: "invalid",
279
+ verified: false,
280
+ code: "X402_ZK_PROOF_INVALID",
281
+ message: "proof verification failed"
282
+ };
283
+ } catch (err) {
284
+ return {
285
+ present: true,
286
+ protocol,
287
+ status: "invalid",
288
+ verified: false,
289
+ code: "X402_ZK_PROOF_INVALID",
290
+ message: "proof verification failed",
291
+ details: {
292
+ error: err?.message ?? String(err ?? "")
293
+ }
294
+ };
295
+ } finally {
296
+ if (!adapterMap) {
297
+ await terminateSnarkCurves();
298
+ }
299
+ }
300
+ }
@@ -0,0 +1,54 @@
1
+ -- ReputationEvent.v1 index table for fast `(tenant, agent, tool?, occurredAt)` queries.
2
+ -- Keeps immutable artifact payload in `artifacts`, while indexing query-critical keys.
3
+
4
+ CREATE TABLE IF NOT EXISTS reputation_event_index (
5
+ tenant_id TEXT NOT NULL,
6
+ artifact_id TEXT NOT NULL,
7
+ artifact_hash TEXT NOT NULL,
8
+ subject_agent_id TEXT NOT NULL,
9
+ subject_tool_id TEXT,
10
+ occurred_at TIMESTAMPTZ NOT NULL,
11
+ event_kind TEXT NOT NULL,
12
+ source_kind TEXT NOT NULL,
13
+ source_hash TEXT,
14
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
15
+ PRIMARY KEY (tenant_id, artifact_id),
16
+ FOREIGN KEY (tenant_id, artifact_id) REFERENCES artifacts (tenant_id, artifact_id) ON DELETE CASCADE
17
+ );
18
+
19
+ CREATE INDEX IF NOT EXISTS reputation_event_index_by_subject_tool_time
20
+ ON reputation_event_index (tenant_id, subject_agent_id, subject_tool_id, occurred_at DESC, artifact_id DESC);
21
+
22
+ CREATE INDEX IF NOT EXISTS reputation_event_index_by_subject_time
23
+ ON reputation_event_index (tenant_id, subject_agent_id, occurred_at DESC, artifact_id DESC);
24
+
25
+ CREATE INDEX IF NOT EXISTS reputation_event_index_by_tenant_time
26
+ ON reputation_event_index (tenant_id, occurred_at DESC, artifact_id DESC);
27
+
28
+ -- Backfill index rows from already-persisted ReputationEvent artifacts.
29
+ INSERT INTO reputation_event_index (
30
+ tenant_id,
31
+ artifact_id,
32
+ artifact_hash,
33
+ subject_agent_id,
34
+ subject_tool_id,
35
+ occurred_at,
36
+ event_kind,
37
+ source_kind,
38
+ source_hash
39
+ )
40
+ SELECT
41
+ a.tenant_id,
42
+ a.artifact_id,
43
+ a.artifact_hash,
44
+ a.artifact_json->'subject'->>'agentId' AS subject_agent_id,
45
+ NULLIF(a.artifact_json->'subject'->>'toolId', '') AS subject_tool_id,
46
+ a.created_at AS occurred_at,
47
+ lower(COALESCE(a.artifact_json->>'eventKind', 'unknown')) AS event_kind,
48
+ lower(COALESCE(a.artifact_json->'sourceRef'->>'kind', 'unknown')) AS source_kind,
49
+ NULLIF(lower(a.artifact_json->'sourceRef'->>'hash'), '') AS source_hash
50
+ FROM artifacts a
51
+ WHERE a.artifact_type = 'ReputationEvent.v1'
52
+ AND jsonb_typeof(a.artifact_json) = 'object'
53
+ AND COALESCE(a.artifact_json->'subject'->>'agentId', '') <> ''
54
+ ON CONFLICT (tenant_id, artifact_id) DO NOTHING;
@@ -0,0 +1,15 @@
1
+ -- v1.??: fix artifact uniqueness to apply only to job-scoped artifacts.
2
+ --
3
+ -- The original unique index enforced one artifact per (tenant_id, job_id, artifact_type, source_event_id) whenever
4
+ -- source_event_id <> ''. For non-job artifacts we persist with job_id = '' (for example PartyStatement.v1 and
5
+ -- PayoutInstruction.v1 during month-close), this incorrectly blocks multiple artifacts of the same type generated from
6
+ -- the same month-close event.
7
+ --
8
+ -- The invariant we actually want is: for job-scoped artifacts (job_id <> ''), prevent duplicates per source event.
9
+
10
+ DROP INDEX IF EXISTS artifacts_unique_by_job_type_source_event;
11
+
12
+ CREATE UNIQUE INDEX IF NOT EXISTS artifacts_unique_by_job_type_source_event
13
+ ON artifacts (tenant_id, job_id, artifact_type, source_event_id)
14
+ WHERE source_event_id <> '' AND job_id <> '';
15
+
package/src/db/pg.js CHANGED
@@ -93,13 +93,24 @@ export async function createPgPool({ databaseUrl, schema = "public" } = {}) {
93
93
  const pool = new Pool({ connectionString: databaseUrl });
94
94
 
95
95
  if (schema !== "public") {
96
- try {
97
- await pool.query(`CREATE SCHEMA ${quoteIdent(schema)}`);
98
- } catch (err) {
99
- const duplicateSchema = err?.code === "42P06" || err?.code === "23505";
100
- if (!duplicateSchema) throw err;
101
- const existsRes = await pool.query("SELECT 1 FROM pg_namespace WHERE nspname = $1 LIMIT 1", [schema]);
102
- if (!existsRes.rows.length) throw err;
96
+ const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
97
+ const createSchemaSql = `CREATE SCHEMA IF NOT EXISTS ${quoteIdent(schema)}`;
98
+ // Concurrency-safe: docker-compose may start multiple processes (api + maintenance)
99
+ // that race to initialize the same schema.
100
+ for (let attempt = 0; attempt < 6; attempt += 1) {
101
+ try {
102
+ await pool.query(createSchemaSql);
103
+ break;
104
+ } catch (err) {
105
+ // Postgres documents that IF NOT EXISTS can still raise errors under concurrent creation.
106
+ // In practice we can see 23505 (unique violation on pg_namespace) or 42P06 (duplicate schema).
107
+ const code = typeof err?.code === "string" ? err.code : "";
108
+ if (code !== "23505" && code !== "42P06") throw err;
109
+ const exists = await pool.query("SELECT 1 FROM pg_namespace WHERE nspname = $1 LIMIT 1", [schema]);
110
+ if (exists?.rowCount) break;
111
+ if (attempt === 5) throw err;
112
+ await wait(25 * (attempt + 1));
113
+ }
103
114
  }
104
115
  }
105
116