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,145 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5
+ # shellcheck source=/dev/null
6
+ source "$ROOT_DIR/scripts/dev/env.sh"
7
+
8
+ for bin in curl jq; do
9
+ if ! command -v "$bin" >/dev/null 2>&1; then
10
+ echo "Missing required tool: $bin"
11
+ exit 1
12
+ fi
13
+ done
14
+
15
+ if ! curl -fsS "$SETTLD_BASE_URL/healthz" >/dev/null 2>&1; then
16
+ cat <<EOF
17
+ API is not reachable at $SETTLD_BASE_URL.
18
+ Start it in another shell:
19
+ npm run dev:start
20
+ EOF
21
+ exit 1
22
+ fi
23
+
24
+ if [[ -z "${SETTLD_API_KEY:-}" ]]; then
25
+ SETTLD_API_KEY="$(bash "$ROOT_DIR/scripts/dev/new-sdk-key.sh" --print-only)"
26
+ export SETTLD_API_KEY
27
+ fi
28
+
29
+ API_AUTH_HEADER="authorization: Bearer $SETTLD_API_KEY"
30
+ PERIOD="$(date -u +%Y-%m)"
31
+
32
+ api_post_json() {
33
+ local path="$1"
34
+ local payload="$2"
35
+ local response
36
+ local body
37
+ local status
38
+
39
+ response="$(curl -sS -X POST "$SETTLD_BASE_URL$path" \
40
+ -H "$API_AUTH_HEADER" \
41
+ -H "x-proxy-tenant-id: $SETTLD_TENANT_ID" \
42
+ -H "content-type: application/json" \
43
+ -d "$payload" \
44
+ -w $'\n%{http_code}')"
45
+ body="$(printf "%s" "$response" | sed '$d')"
46
+ status="$(printf "%s" "$response" | tail -n1)"
47
+ if [[ ! "$status" =~ ^2 ]]; then
48
+ echo "Request failed: POST $path (HTTP $status)"
49
+ echo "$body" | jq . 2>/dev/null || echo "$body"
50
+ exit 1
51
+ fi
52
+ printf "%s" "$body"
53
+ }
54
+
55
+ echo "[1/5] Running first verified settlement..."
56
+ RUN_JSON="$(cd "$ROOT_DIR" && SETTLD_SDK_DISPUTE_WINDOW_DAYS=3 npm run -s sdk:first-run)"
57
+ echo "$RUN_JSON" | jq .
58
+
59
+ RUN_ID="$(echo "$RUN_JSON" | jq -r '.runId')"
60
+ PAYER_AGENT_ID="$(echo "$RUN_JSON" | jq -r '.payerAgentId')"
61
+ if [[ -z "$RUN_ID" || "$RUN_ID" == "null" ]]; then
62
+ echo "Could not parse runId from sdk:first-run output."
63
+ exit 1
64
+ fi
65
+ if [[ -z "$PAYER_AGENT_ID" || "$PAYER_AGENT_ID" == "null" ]]; then
66
+ echo "Could not parse payerAgentId from sdk:first-run output."
67
+ exit 1
68
+ fi
69
+
70
+ SUFFIX="$(date +%s%N | cut -c1-16)"
71
+ DISPUTE_ID="dispute_doctor_${SUFFIX}"
72
+ CASE_ID="arb_case_doctor_${SUFFIX}"
73
+
74
+ echo "[2/5] Opening dispute..."
75
+ DISPUTE_JSON="$(api_post_json "/runs/$RUN_ID/dispute/open" "{\"disputeId\":\"$DISPUTE_ID\",\"reason\":\"billing doctor validation\",\"openedByAgentId\":\"$PAYER_AGENT_ID\"}")"
76
+ echo "$DISPUTE_JSON" | jq .
77
+
78
+ echo "[3/5] Opening arbitration case..."
79
+ ARBITRATION_JSON="$(api_post_json "/runs/$RUN_ID/arbitration/open" "{\"caseId\":\"$CASE_ID\",\"disputeId\":\"$DISPUTE_ID\",\"arbiterAgentId\":\"$PAYER_AGENT_ID\"}")"
80
+ echo "$ARBITRATION_JSON" | jq .
81
+
82
+ echo "[4/5] Reading billable events..."
83
+ EVENTS_JSON="$(curl -sS "$SETTLD_BASE_URL/ops/finance/billable-events?period=$PERIOD" \
84
+ -H "authorization: Bearer $PROXY_OPS_TOKEN" \
85
+ -H "x-proxy-tenant-id: $SETTLD_TENANT_ID")"
86
+
87
+ SCOPED_EVENTS_JSON="$(echo "$EVENTS_JSON" | jq --arg runId "$RUN_ID" --arg caseId "$CASE_ID" '
88
+ [.events[] | select((.runId == $runId) or (.arbitrationCaseId == $caseId))]
89
+ ')"
90
+ echo "$SCOPED_EVENTS_JSON" | jq --arg tenantId "$SETTLD_TENANT_ID" --arg runId "$RUN_ID" --arg caseId "$CASE_ID" --arg period "$PERIOD" '
91
+ {
92
+ tenantId: $tenantId,
93
+ period: $period,
94
+ runId: $runId,
95
+ arbitrationCaseId: $caseId,
96
+ count: length,
97
+ eventTypeCounts: (reduce .[] as $event ({verified_run: 0, settled_volume: 0, arbitration_usage: 0};
98
+ if ($event.eventType == "verified_run") then .verified_run += 1
99
+ elif ($event.eventType == "settled_volume") then .settled_volume += 1
100
+ elif ($event.eventType == "arbitration_usage") then .arbitration_usage += 1
101
+ else .
102
+ end)),
103
+ events: .
104
+ }'
105
+
106
+ RUN_VERIFIED_EVENTS="$(echo "$SCOPED_EVENTS_JSON" | jq --arg runId "$RUN_ID" '[.[] | select(.eventType=="verified_run" and .runId==$runId)] | length')"
107
+ RUN_SETTLED_EVENTS="$(echo "$SCOPED_EVENTS_JSON" | jq --arg runId "$RUN_ID" '[.[] | select(.eventType=="settled_volume" and .runId==$runId)] | length')"
108
+ ARBITRATION_EVENTS_FOR_CASE="$(echo "$SCOPED_EVENTS_JSON" | jq --arg caseId "$CASE_ID" '[.[] | select(.eventType=="arbitration_usage" and .arbitrationCaseId==$caseId)] | length')"
109
+
110
+ if [[ "$RUN_VERIFIED_EVENTS" -lt 1 ]]; then
111
+ echo "Expected at least one verified_run event for run $RUN_ID, found $RUN_VERIFIED_EVENTS."
112
+ exit 1
113
+ fi
114
+ if [[ "$RUN_SETTLED_EVENTS" -lt 1 ]]; then
115
+ echo "Expected at least one settled_volume event for run $RUN_ID, found $RUN_SETTLED_EVENTS."
116
+ exit 1
117
+ fi
118
+ if [[ "$ARBITRATION_EVENTS_FOR_CASE" -lt 1 ]]; then
119
+ echo "Expected at least one arbitration_usage event for case $CASE_ID, found $ARBITRATION_EVENTS_FOR_CASE."
120
+ exit 1
121
+ fi
122
+
123
+ echo "[5/5] Reading billing summary..."
124
+ SUMMARY_JSON="$(curl -sS "$SETTLD_BASE_URL/ops/finance/billing/summary?period=$PERIOD" \
125
+ -H "authorization: Bearer $PROXY_OPS_TOKEN" \
126
+ -H "x-proxy-tenant-id: $SETTLD_TENANT_ID")"
127
+ echo "$SUMMARY_JSON" | jq '{
128
+ tenantId,
129
+ period,
130
+ plan: { planId: .plan.planId },
131
+ usage: .usage,
132
+ enforcement: .enforcement
133
+ }'
134
+
135
+ ARBITRATION_CASES="$(echo "$SUMMARY_JSON" | jq -r '.usage.arbitrationCases // 0')"
136
+ if [[ "$ARBITRATION_CASES" -lt 1 ]]; then
137
+ echo "Expected arbitrationCases >= 1 in billing summary, got $ARBITRATION_CASES."
138
+ exit 1
139
+ fi
140
+
141
+ echo
142
+ echo "Billing doctor passed."
143
+ echo "Run: $RUN_ID"
144
+ echo "Dispute: $DISPUTE_ID"
145
+ echo "Arbitration case: $CASE_ID"
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Load local env defaults automatically (same behavior as other dev scripts).
5
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
6
+ if [[ -f "$ROOT_DIR/scripts/dev/env.sh" ]]; then
7
+ # shellcheck source=/dev/null
8
+ source "$ROOT_DIR/scripts/dev/env.sh"
9
+ fi
10
+
11
+ for bin in curl jq; do
12
+ if ! command -v "$bin" >/dev/null 2>&1; then
13
+ echo "Missing required tool: $bin"
14
+ exit 1
15
+ fi
16
+ done
17
+
18
+ : "${SETTLD_BASE_URL:?SETTLD_BASE_URL is required (example: https://<your-api-domain>)}"
19
+ : "${PROXY_OPS_TOKEN:?PROXY_OPS_TOKEN is required}"
20
+
21
+ # Default to an isolated smoke tenant to avoid stale billing/subscription state
22
+ # in long-lived tenants (for example tenant_default).
23
+ if [[ -z "${SETTLD_TENANT_ID:-}" || "${SETTLD_TENANT_ID}" == "tenant_default" ]]; then
24
+ SETTLD_TENANT_ID="tenant_smoke_$(date +%s)"
25
+ fi
26
+ export SETTLD_TENANT_ID
27
+
28
+ if [[ "$SETTLD_BASE_URL" == "http://127.0.0.1:3000" || "$SETTLD_BASE_URL" == "http://localhost:3000" ]]; then
29
+ cat <<EOF
30
+ This is the production smoke script, but SETTLD_BASE_URL is still local ($SETTLD_BASE_URL).
31
+ Set your deployed API URL once:
32
+ echo 'SETTLD_BASE_URL=https://api.settld.work' >> .env.dev.runtime
33
+ EOF
34
+ exit 1
35
+ fi
36
+
37
+ if [[ "$PROXY_OPS_TOKEN" == "dev_ops_token" ]]; then
38
+ cat <<EOF
39
+ PROXY_OPS_TOKEN is still the local default (dev_ops_token), which will fail in production.
40
+ Set your real prod token once:
41
+ echo 'PROXY_OPS_TOKEN=<your_prod_ops_token>' >> .env.dev.runtime
42
+ EOF
43
+ exit 1
44
+ fi
45
+
46
+ api_get() {
47
+ local path="$1"
48
+ local response body status
49
+ response="$(curl -sS "$SETTLD_BASE_URL$path" \
50
+ -H "x-proxy-ops-token: $PROXY_OPS_TOKEN" \
51
+ -H "x-proxy-tenant-id: $SETTLD_TENANT_ID" \
52
+ -w $'\n%{http_code}')"
53
+ body="$(printf "%s" "$response" | sed '$d')"
54
+ status="$(printf "%s" "$response" | tail -n1)"
55
+ if [[ ! "$status" =~ ^2 ]]; then
56
+ echo "GET $path failed (HTTP $status)" >&2
57
+ echo "$body" | jq . 2>/dev/null >&2 || echo "$body" >&2
58
+ exit 1
59
+ fi
60
+ printf "%s" "$body"
61
+ }
62
+
63
+ api_post_json() {
64
+ local path="$1"
65
+ local payload="$2"
66
+ local response body status
67
+ response="$(curl -sS -X POST "$SETTLD_BASE_URL$path" \
68
+ -H "x-proxy-ops-token: $PROXY_OPS_TOKEN" \
69
+ -H "x-proxy-tenant-id: $SETTLD_TENANT_ID" \
70
+ -H "content-type: application/json" \
71
+ -d "$payload" \
72
+ -w $'\n%{http_code}')"
73
+ body="$(printf "%s" "$response" | sed '$d')"
74
+ status="$(printf "%s" "$response" | tail -n1)"
75
+ if [[ ! "$status" =~ ^2 ]]; then
76
+ echo "POST $path failed (HTTP $status)" >&2
77
+ echo "$body" | jq . 2>/dev/null >&2 || echo "$body" >&2
78
+ exit 1
79
+ fi
80
+ printf "%s" "$body"
81
+ }
82
+
83
+ api_post_json_with_status() {
84
+ local path="$1"
85
+ local payload="$2"
86
+ local response body status
87
+ response="$(curl -sS -X POST "$SETTLD_BASE_URL$path" \
88
+ -H "x-proxy-ops-token: $PROXY_OPS_TOKEN" \
89
+ -H "x-proxy-tenant-id: $SETTLD_TENANT_ID" \
90
+ -H "content-type: application/json" \
91
+ -d "$payload" \
92
+ -w $'\n%{http_code}')"
93
+ body="$(printf "%s" "$response" | sed '$d')"
94
+ status="$(printf "%s" "$response" | tail -n1)"
95
+ printf "%s\n%s" "$status" "$body"
96
+ }
97
+
98
+ echo "[1/5] Health check..."
99
+ HEALTH_RAW="$(curl -sS "$SETTLD_BASE_URL/healthz" || true)"
100
+ if ! echo "$HEALTH_RAW" | jq -e . >/dev/null 2>&1; then
101
+ echo "Health endpoint did not return JSON."
102
+ echo "This usually means SETTLD_BASE_URL points to the frontend (for example Vercel) instead of the API service."
103
+ echo
104
+ echo "First 240 chars returned:"
105
+ echo "$HEALTH_RAW" | head -c 240
106
+ echo
107
+ echo
108
+ echo "Expected something like: {\"ok\":true,\"dbOk\":true,...}"
109
+ exit 1
110
+ fi
111
+ HEALTH_JSON="$HEALTH_RAW"
112
+ echo "$HEALTH_JSON" | jq '{ok,dbOk,dbLatencyMs}'
113
+ if [[ "$(echo "$HEALTH_JSON" | jq -r '.ok // false')" != "true" ]]; then
114
+ echo "Health check failed."
115
+ exit 1
116
+ fi
117
+
118
+ STRIPE_CUSTOMER_ID=""
119
+ if [[ -n "${PROXY_BILLING_STRIPE_SECRET_KEY:-}" ]]; then
120
+ STRIPE_CUSTOMER_ID="$(
121
+ curl -sS https://api.stripe.com/v1/customers \
122
+ -u "$PROXY_BILLING_STRIPE_SECRET_KEY:" \
123
+ -d "name=Settld Smoke Customer $(date +%s)" | jq -r '.id'
124
+ )"
125
+ if [[ -z "$STRIPE_CUSTOMER_ID" || "$STRIPE_CUSTOMER_ID" == "null" ]]; then
126
+ echo "Failed to create Stripe customer for smoke run." >&2
127
+ exit 1
128
+ fi
129
+ fi
130
+
131
+ echo "[2/5] Billing checkout session..."
132
+ CHECKOUT_PAYLOAD="$(jq -n \
133
+ --arg plan "builder" \
134
+ --arg customerId "$STRIPE_CUSTOMER_ID" \
135
+ --arg successUrl "${SETTLD_BASE_URL%/}/billing/success" \
136
+ --arg cancelUrl "${SETTLD_BASE_URL%/}/billing/cancel" \
137
+ '{
138
+ plan: $plan,
139
+ successUrl: $successUrl,
140
+ cancelUrl: $cancelUrl
141
+ } + (if ($customerId | length) > 0 then { customerId: $customerId } else {} end)'
142
+ )"
143
+ CHECKOUT_JSON="$(api_post_json "/ops/finance/billing/providers/stripe/checkout" "$CHECKOUT_PAYLOAD")"
144
+ echo "$CHECKOUT_JSON" | jq '{tenantId, mode: .checkoutSession.mode, plan: .checkoutSession.plan, sessionId: .checkoutSession.sessionId, sessionUrl: .checkoutSession.sessionUrl}'
145
+ CHECKOUT_MODE="$(echo "$CHECKOUT_JSON" | jq -r '.checkoutSession.mode // ""')"
146
+ if [[ "$CHECKOUT_MODE" != "live" && "$CHECKOUT_MODE" != "stub" ]]; then
147
+ echo "Unexpected checkout mode: $CHECKOUT_MODE"
148
+ exit 1
149
+ fi
150
+
151
+ echo "[3/5] Billing customer portal session..."
152
+ CUSTOMER_ID="$STRIPE_CUSTOMER_ID"
153
+ if [[ -z "$CUSTOMER_ID" || "$CUSTOMER_ID" == "null" ]]; then
154
+ CUSTOMER_ID="cus_smoke_$(date +%s)"
155
+ fi
156
+
157
+ PORTAL_RESPONSE="$(api_post_json_with_status "/ops/finance/billing/providers/stripe/portal" "{\"customerId\":\"$CUSTOMER_ID\"}")"
158
+ PORTAL_STATUS="$(printf "%s" "$PORTAL_RESPONSE" | head -n1)"
159
+ PORTAL_JSON="$(printf "%s" "$PORTAL_RESPONSE" | sed '1d')"
160
+ if [[ "$PORTAL_STATUS" =~ ^2 ]] && [[ "$(echo "$PORTAL_JSON" | jq -r '.portalSession.sessionUrl // ""')" != "" ]]; then
161
+ echo "$PORTAL_JSON" | jq '{tenantId, mode: .portalSession.mode, customerId: .portalSession.customerId, sessionId: .portalSession.sessionId, sessionUrl: .portalSession.sessionUrl}'
162
+ else
163
+ # In live mode with a synthetic customer id, Stripe returns upstream "No such customer".
164
+ echo "$PORTAL_JSON" | jq '{tenantId,error,code,details}' 2>/dev/null || echo "$PORTAL_JSON"
165
+ if [[ "$PORTAL_STATUS" != "502" || "$(echo "$PORTAL_JSON" | jq -r '.code // ""' 2>/dev/null)" != "BILLING_PROVIDER_UPSTREAM_ERROR" ]]; then
166
+ echo "Unexpected portal response (HTTP $PORTAL_STATUS)."
167
+ exit 1
168
+ fi
169
+ fi
170
+
171
+ echo "[4/5] Provider reconcile subscription mapping..."
172
+ TS="$(date +%s)"
173
+ GROWTH_PRICE_ID="${PROXY_BILLING_STRIPE_PRICE_ID_GROWTH:-}"
174
+ if [[ -z "$GROWTH_PRICE_ID" ]]; then
175
+ GROWTH_CHECKOUT_JSON="$(api_post_json "/ops/finance/billing/providers/stripe/checkout" '{"plan":"growth"}')"
176
+ GROWTH_PRICE_ID="$(echo "$GROWTH_CHECKOUT_JSON" | jq -r '.checkoutSession.priceId // ""')"
177
+ fi
178
+ if [[ -z "$GROWTH_PRICE_ID" ]]; then
179
+ # In stub mode we still need a deterministic value in event payloads; plan mapping
180
+ # is derived from metadata and does not require a live provider price id.
181
+ GROWTH_PRICE_ID="price_stub_growth"
182
+ fi
183
+
184
+ RECON_PAYLOAD="$(jq -n \
185
+ --arg eventId "evt_smoke_price_map_${TS}" \
186
+ --arg subId "sub_smoke_price_map_${TS}" \
187
+ --arg customerId "$CUSTOMER_ID" \
188
+ --arg price "$GROWTH_PRICE_ID" \
189
+ --arg plan "growth" \
190
+ --argjson created "$TS" \
191
+ '{events:[{id:$eventId,type:"customer.subscription.updated",created:$created,data:{object:{id:$subId,customer:$customerId,status:"active",items:{data:[{price:{id:$price,metadata:{settldPlan:$plan}}}]},metadata:{settldPlan:$plan}}}}]}'
192
+ )"
193
+ RECON_JSON="$(api_post_json "/ops/finance/billing/providers/stripe/reconcile" "$RECON_PAYLOAD")"
194
+ echo "$RECON_JSON" | jq '{tenantId,summary}'
195
+ if [[ "$(echo "$RECON_JSON" | jq -r '.summary.applied // 0')" -lt 1 ]]; then
196
+ echo "Reconcile did not apply events."
197
+ exit 1
198
+ fi
199
+
200
+ PLAN_JSON="$(api_get "/ops/finance/billing/plan")"
201
+ echo "$PLAN_JSON" | jq '{tenantId,billing,resolvedPlan}'
202
+ if [[ "$(echo "$PLAN_JSON" | jq -r '.billing.plan // ""')" != "growth" ]]; then
203
+ echo "Expected billing.plan=growth after reconcile mapping."
204
+ exit 1
205
+ fi
206
+
207
+ echo "[5/5] Billing summary..."
208
+ PERIOD="$(date -u +%Y-%m)"
209
+ SUMMARY_JSON="$(api_get "/ops/finance/billing/summary?period=$PERIOD")"
210
+ echo "$SUMMARY_JSON" | jq '{tenantId,period,usage,enforcement}'
211
+ if [[ "$(echo "$SUMMARY_JSON" | jq -r '.usage.eventCount // 0')" -lt 0 ]]; then
212
+ echo "Unexpected summary payload."
213
+ exit 1
214
+ fi
215
+
216
+ echo
217
+ echo "Production billing smoke passed."
218
+ echo "Base URL: $SETTLD_BASE_URL"
219
+ echo "Tenant: $SETTLD_TENANT_ID"
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5
+ if [[ -f "$ROOT_DIR/scripts/dev/env.sh" ]]; then
6
+ # shellcheck source=/dev/null
7
+ source "$ROOT_DIR/scripts/dev/env.sh"
8
+ fi
9
+
10
+ for bin in curl jq; do
11
+ if ! command -v "$bin" >/dev/null 2>&1; then
12
+ echo "Missing required tool: $bin" >&2
13
+ exit 1
14
+ fi
15
+ done
16
+
17
+ : "${SETTLD_BASE_URL:?SETTLD_BASE_URL is required}"
18
+ : "${PROXY_OPS_TOKEN:?PROXY_OPS_TOKEN is required}"
19
+ : "${SETTLD_TENANT_ID:?SETTLD_TENANT_ID is required}"
20
+
21
+ LIMIT="${LIMIT:-200}"
22
+ OFFSET="${OFFSET:-0}"
23
+ REASON="${REASON:-}"
24
+ EVENT_TYPE="${EVENT_TYPE:-}"
25
+ AUDIT_IDS="${AUDIT_IDS:-}"
26
+ DRY_RUN="${DRY_RUN:-1}"
27
+
28
+ if [[ "$DRY_RUN" == "1" || "${DRY_RUN,,}" == "true" ]]; then
29
+ DRY_RUN_JSON="true"
30
+ else
31
+ DRY_RUN_JSON="false"
32
+ fi
33
+
34
+ urlencode() {
35
+ local input="${1:-}"
36
+ jq -rn --arg v "$input" '$v|@uri'
37
+ }
38
+
39
+ api_get() {
40
+ local path="$1"
41
+ local response body status
42
+ response="$(curl -sS "$SETTLD_BASE_URL$path" \
43
+ -H "x-proxy-ops-token: $PROXY_OPS_TOKEN" \
44
+ -H "x-proxy-tenant-id: $SETTLD_TENANT_ID" \
45
+ -w $'\n%{http_code}')"
46
+ body="$(printf "%s" "$response" | sed '$d')"
47
+ status="$(printf "%s" "$response" | tail -n1)"
48
+ if [[ ! "$status" =~ ^2 ]]; then
49
+ echo "GET $path failed (HTTP $status)" >&2
50
+ echo "$body" | jq . 2>/dev/null >&2 || echo "$body" >&2
51
+ exit 1
52
+ fi
53
+ printf "%s" "$body"
54
+ }
55
+
56
+ api_post_json() {
57
+ local path="$1"
58
+ local payload="$2"
59
+ local response body status
60
+ response="$(curl -sS -X POST "$SETTLD_BASE_URL$path" \
61
+ -H "x-proxy-ops-token: $PROXY_OPS_TOKEN" \
62
+ -H "x-proxy-tenant-id: $SETTLD_TENANT_ID" \
63
+ -H "content-type: application/json" \
64
+ -d "$payload" \
65
+ -w $'\n%{http_code}')"
66
+ body="$(printf "%s" "$response" | sed '$d')"
67
+ status="$(printf "%s" "$response" | tail -n1)"
68
+ if [[ ! "$status" =~ ^2 ]]; then
69
+ echo "POST $path failed (HTTP $status)" >&2
70
+ echo "$body" | jq . 2>/dev/null >&2 || echo "$body" >&2
71
+ exit 1
72
+ fi
73
+ printf "%s" "$body"
74
+ }
75
+
76
+ echo "[1/4] Stripe reconcile report snapshot"
77
+ REPORT_JSON="$(api_get "/ops/finance/billing/providers/stripe/reconcile/report?limit=${LIMIT}&offset=${OFFSET}")"
78
+ echo "$REPORT_JSON" | jq '{
79
+ tenantId,
80
+ provider,
81
+ counts,
82
+ ingestBreakdown,
83
+ rejectedReasonCounts,
84
+ replayableRejectedCount
85
+ }'
86
+
87
+ echo "[2/4] Dead-letter candidate snapshot"
88
+ DEAD_LETTER_PATH="/ops/finance/billing/providers/stripe/dead-letter?limit=${LIMIT}&offset=${OFFSET}"
89
+ if [[ -n "$REASON" ]]; then
90
+ DEAD_LETTER_PATH="${DEAD_LETTER_PATH}&reason=$(urlencode "$REASON")"
91
+ fi
92
+ if [[ -n "$EVENT_TYPE" ]]; then
93
+ DEAD_LETTER_PATH="${DEAD_LETTER_PATH}&eventType=$(urlencode "$EVENT_TYPE")"
94
+ fi
95
+
96
+ DEAD_JSON="$(api_get "$DEAD_LETTER_PATH")"
97
+ echo "$DEAD_JSON" | jq '{
98
+ tenantId,
99
+ provider,
100
+ count,
101
+ limit,
102
+ offset,
103
+ sample: (.events[:5] | map({auditId, eventId, eventType, reason, source, replayable}))
104
+ }'
105
+
106
+ if [[ "$(echo "$DEAD_JSON" | jq -r '.count // 0')" == "0" ]]; then
107
+ echo "No replayable dead-letter events found."
108
+ exit 0
109
+ fi
110
+
111
+ echo "[3/4] Replay request"
112
+ AUDIT_IDS_JSON="[]"
113
+ if [[ -n "$AUDIT_IDS" ]]; then
114
+ AUDIT_IDS_JSON="$(printf "%s" "$AUDIT_IDS" | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | jq -Rn '[inputs | select(length>0) | tonumber]')"
115
+ fi
116
+
117
+ REPLAY_PAYLOAD="$(
118
+ jq -n \
119
+ --argjson dryRun "$DRY_RUN_JSON" \
120
+ --arg reason "$REASON" \
121
+ --arg eventType "$EVENT_TYPE" \
122
+ --argjson limit "$LIMIT" \
123
+ --argjson offset "$OFFSET" \
124
+ --argjson auditIds "$AUDIT_IDS_JSON" \
125
+ '{
126
+ dryRun: $dryRun,
127
+ limit: $limit,
128
+ offset: $offset
129
+ }
130
+ + (if ($reason|length)>0 then {reason:$reason} else {} end)
131
+ + (if ($eventType|length)>0 then {eventType:$eventType} else {} end)
132
+ + (if ($auditIds|length)>0 then {auditIds:$auditIds} else {} end)'
133
+ )"
134
+
135
+ REPLAY_JSON="$(api_post_json "/ops/finance/billing/providers/stripe/dead-letter/replay" "$REPLAY_PAYLOAD")"
136
+ echo "$REPLAY_JSON" | jq '{
137
+ tenantId,
138
+ provider,
139
+ dryRun,
140
+ summary,
141
+ sample: (.results[:10])
142
+ }'
143
+
144
+ echo "[4/4] Post-replay report snapshot"
145
+ POST_REPORT_JSON="$(api_get "/ops/finance/billing/providers/stripe/reconcile/report?limit=${LIMIT}&offset=${OFFSET}")"
146
+ echo "$POST_REPORT_JSON" | jq '{
147
+ tenantId,
148
+ provider,
149
+ counts,
150
+ ingestBreakdown,
151
+ rejectedReasonCounts,
152
+ replayableRejectedCount
153
+ }'
154
+
155
+ FAILED_COUNT="$(echo "$REPLAY_JSON" | jq -r '.summary.failed // 0')"
156
+ if [[ "$DRY_RUN_JSON" == "false" && "$FAILED_COUNT" != "0" ]]; then
157
+ echo "Replay completed with failed events: $FAILED_COUNT" >&2
158
+ exit 2
159
+ fi
160
+
161
+ echo "Billing webhook replay guardrail flow completed."
@@ -0,0 +1,29 @@
1
+ # Copy to .env.dev at repo root:
2
+ # cp scripts/dev/env.dev.example .env.dev
3
+
4
+ # Core dev URLs
5
+ SETTLD_BASE_URL=http://127.0.0.1:3000
6
+ SETTLD_TENANT_ID=tenant_default
7
+ PROXY_OPS_TOKEN=dev_ops_token
8
+
9
+ # PG runtime
10
+ STORE=pg
11
+ PROXY_PG_SCHEMA=public
12
+ PROXY_MIGRATE_ON_STARTUP=1
13
+ DATABASE_URL=postgresql://neondb_owner:replace_me@host/neondb?sslmode=verify-full&channel_binding=require
14
+
15
+ # Stripe billing (test mode first)
16
+ # Free-first growth default: keep billing usage metering on but disable hard-limit blocking.
17
+ # Set to 1 when you intentionally want billing-plan hard limits to enforce 402 blocks.
18
+ PROXY_BILLING_PLAN_ENFORCEMENT_ENABLED=0
19
+
20
+ # Backend uses secret key + price IDs.
21
+ # Publishable key is for frontend Stripe.js usage and is optional for backend-only local flows.
22
+ STRIPE_PUBLISHABLE_KEY=pk_test_replace_me
23
+ PROXY_BILLING_STRIPE_SECRET_KEY=sk_test_replace_me
24
+ PROXY_BILLING_STRIPE_PRICE_ID_BUILDER=price_replace_me_builder
25
+ PROXY_BILLING_STRIPE_PRICE_ID_GROWTH=price_replace_me_growth
26
+ PROXY_BILLING_STRIPE_PRICE_ID_ENTERPRISE=price_replace_me_enterprise
27
+ PROXY_BILLING_STRIPE_CHECKOUT_SUCCESS_URL=http://127.0.0.1:3000/billing/success
28
+ PROXY_BILLING_STRIPE_CHECKOUT_CANCEL_URL=http://127.0.0.1:3000/billing/cancel
29
+ PROXY_BILLING_STRIPE_PORTAL_RETURN_URL=http://127.0.0.1:3000/settings/billing
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
5
+ echo "source scripts/dev/env.sh"
6
+ echo "This file must be sourced so exports are applied to your shell."
7
+ exit 1
8
+ fi
9
+
10
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
11
+ ENV_FILE="${SETTLD_ENV_FILE:-$ROOT_DIR/.env.dev}"
12
+ RUNTIME_ENV_FILE="${SETTLD_RUNTIME_ENV_FILE:-$ROOT_DIR/.env.dev.runtime}"
13
+
14
+ if [[ -f "$ENV_FILE" ]]; then
15
+ set -a
16
+ # shellcheck source=/dev/null
17
+ . "$ENV_FILE"
18
+ set +a
19
+ fi
20
+
21
+ if [[ -f "$RUNTIME_ENV_FILE" ]]; then
22
+ set -a
23
+ # shellcheck source=/dev/null
24
+ . "$RUNTIME_ENV_FILE"
25
+ set +a
26
+ fi
27
+
28
+ : "${SETTLD_BASE_URL:=http://127.0.0.1:3000}"
29
+ : "${SETTLD_TENANT_ID:=tenant_default}"
30
+ : "${PROXY_OPS_TOKEN:=dev_ops_token}"
31
+
32
+ export SETTLD_BASE_URL
33
+ export SETTLD_TENANT_ID
34
+ export PROXY_OPS_TOKEN
35
+ export SETTLD_ENV_FILE="$ENV_FILE"
36
+ export SETTLD_RUNTIME_ENV_FILE="$RUNTIME_ENV_FILE"
37
+
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5
+ # shellcheck source=/dev/null
6
+ source "$ROOT_DIR/scripts/dev/env.sh"
7
+
8
+ PRINT_ONLY=0
9
+ OPS_TOKEN_OVERRIDE=""
10
+ if [[ "${1:-}" == "--help" ]]; then
11
+ cat <<'EOF'
12
+ Usage:
13
+ bash scripts/dev/new-sdk-key.sh
14
+ bash scripts/dev/new-sdk-key.sh --print-only
15
+ bash scripts/dev/new-sdk-key.sh --ops-token <tok> [--print-only]
16
+
17
+ Behavior:
18
+ - mints a new API key via /ops/api-keys
19
+ - writes SETTLD_API_KEY into .env.dev.runtime
20
+ - prints export command for current shell
21
+ EOF
22
+ exit 0
23
+ fi
24
+
25
+ # Parse flags (source'd env files may override shell exports; we support explicit override).
26
+ while [[ $# -gt 0 ]]; do
27
+ case "$1" in
28
+ --print-only)
29
+ PRINT_ONLY=1
30
+ shift
31
+ ;;
32
+ --ops-token)
33
+ OPS_TOKEN_OVERRIDE="${2:-}"
34
+ if [[ -z "${OPS_TOKEN_OVERRIDE:-}" ]]; then
35
+ echo "--ops-token requires a value" >&2
36
+ exit 2
37
+ fi
38
+ shift 2
39
+ ;;
40
+ *)
41
+ echo "Unknown arg: $1" >&2
42
+ exit 2
43
+ ;;
44
+ esac
45
+ done
46
+
47
+ if [[ -n "${OPS_TOKEN_OVERRIDE:-}" ]]; then
48
+ export PROXY_OPS_TOKEN="$OPS_TOKEN_OVERRIDE"
49
+ fi
50
+
51
+ # Prefer x-proxy-ops-token for hosted deployments that may not forward Authorization.
52
+ RESPONSE="$(
53
+ curl -sS -X POST "$SETTLD_BASE_URL/ops/api-keys" \
54
+ -H "x-proxy-ops-token: $PROXY_OPS_TOKEN" \
55
+ -H "authorization: Bearer $PROXY_OPS_TOKEN" \
56
+ -H "x-proxy-tenant-id: $SETTLD_TENANT_ID" \
57
+ -H "content-type: application/json" \
58
+ -d '{"scopes":["ops_read","ops_write","finance_read","finance_write","audit_read"],"description":"sdk quickstart"}'
59
+ )"
60
+
61
+ KEY_ID="$(echo "$RESPONSE" | jq -r '.keyId // empty')"
62
+ SECRET="$(echo "$RESPONSE" | jq -r '.secret // empty')"
63
+
64
+ if [[ -z "$KEY_ID" || -z "$SECRET" ]]; then
65
+ echo "Failed to mint SDK key."
66
+ echo "$RESPONSE" | jq .
67
+ exit 1
68
+ fi
69
+
70
+ SETTLD_API_KEY_VALUE="${KEY_ID}.${SECRET}"
71
+
72
+ if [[ "$PRINT_ONLY" == "1" ]]; then
73
+ echo "$SETTLD_API_KEY_VALUE"
74
+ exit 0
75
+ fi
76
+
77
+ printf "SETTLD_API_KEY=%s\n" "$SETTLD_API_KEY_VALUE" >"$SETTLD_RUNTIME_ENV_FILE"
78
+ chmod 600 "$SETTLD_RUNTIME_ENV_FILE" || true
79
+
80
+ echo "Wrote $SETTLD_RUNTIME_ENV_FILE"
81
+ echo "export SETTLD_API_KEY='$SETTLD_API_KEY_VALUE'"