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.
- package/README.md +93 -3
- package/SETTLD_VERSION +1 -1
- package/bin/settld-mcp +2 -0
- package/bin/settld.js +71 -0
- package/conformance/kernel-v0/README.md +7 -0
- package/conformance/kernel-v0/run.mjs +292 -4
- package/docs/ACCESS.md +57 -0
- package/docs/ADOPTION_CHECKLIST.md +44 -0
- package/docs/ALERTS.md +198 -0
- package/docs/ARCHITECTURE.md +69 -0
- package/docs/ARCHITECTURE_FOUNDER_GUIDE.md +284 -0
- package/docs/ARTIFACTS.md +60 -0
- package/docs/CERTIFICATION_CHECKLIST.md +33 -0
- package/docs/CIRCLE_SANDBOX_E2E.md +152 -0
- package/docs/CONFIG.md +297 -0
- package/docs/CONTRACTS_APIS.md +23 -0
- package/docs/DEPRECATION.md +31 -0
- package/docs/DOMAIN_MODEL.md +92 -0
- package/docs/EVENT_ENVELOPE.md +53 -0
- package/docs/FINANCE_PACK_FORMAT.md +53 -0
- package/docs/INCIDENT_TAXONOMY.md +30 -0
- package/docs/JOB_STATE_MACHINE.md +66 -0
- package/docs/KERNEL_COMPATIBLE.md +60 -0
- package/docs/KERNEL_V0.md +40 -0
- package/docs/KEY_ROTATION.md +80 -0
- package/docs/LEDGER.md +82 -0
- package/docs/LIVENESS.md +76 -0
- package/docs/MVP_BUILD_ORDER.md +36 -0
- package/docs/ONCALL_PLAYBOOK.md +39 -0
- package/docs/OPERATIONS_SIGNING.md +20 -0
- package/docs/OVERVIEW.md +190 -0
- package/docs/PERF_BASELINE.md +85 -0
- package/docs/PRD.md +77 -0
- package/docs/QUICKSTART_KERNEL_V0.md +96 -0
- package/docs/QUICKSTART_MCP.md +377 -0
- package/docs/QUICKSTART_MCP_HOSTS.md +210 -0
- package/docs/QUICKSTART_POLICY_PACKS.md +65 -0
- package/docs/QUICKSTART_PRODUCE.md +61 -0
- package/docs/QUICKSTART_PROFILES.md +198 -0
- package/docs/QUICKSTART_RELEASE_VERIFY.md +39 -0
- package/docs/QUICKSTART_SDK.md +125 -0
- package/docs/QUICKSTART_SDK_PYTHON.md +111 -0
- package/docs/QUICKSTART_VERIFY.md +54 -0
- package/docs/QUICKSTART_X402_GATEWAY.md +317 -0
- package/docs/README.md +33 -0
- package/docs/RELEASE_CHECKLIST.md +182 -0
- package/docs/RELEASING.md +82 -0
- package/docs/REPO_SETTINGS.md +37 -0
- package/docs/RUNBOOK.md +86 -0
- package/docs/SKILLS.md +42 -0
- package/docs/SKILL_BUNDLE_FORMAT.md +48 -0
- package/docs/SLO.md +131 -0
- package/docs/SUMMARY.md +17 -0
- package/docs/SUPPORT.md +31 -0
- package/docs/THREAT_MODEL.md +36 -0
- package/docs/TRUST.md +59 -0
- package/docs/WORKFLOW.md +35 -0
- package/docs/X402_BATCH_SETTLEMENT.md +126 -0
- package/docs/blog/2026-02-14-your-ai-agent-just-spent-500-where-is-the-receipt.md +73 -0
- package/docs/examples/x402-provider-payout-registry.example.json +14 -0
- package/docs/gitbook/README.md +64 -0
- package/docs/gitbook/SETUP.md +25 -0
- package/docs/gitbook/SUMMARY.md +15 -0
- package/docs/gitbook/api-reference.md +73 -0
- package/docs/gitbook/closepacks.md +55 -0
- package/docs/gitbook/conformance.md +59 -0
- package/docs/gitbook/core-primitives.md +85 -0
- package/docs/gitbook/dispute-lifecycle.md +33 -0
- package/docs/gitbook/faq.md +21 -0
- package/docs/gitbook/guides.md +49 -0
- package/docs/gitbook/operations-runbook.md +36 -0
- package/docs/gitbook/quickstart.md +103 -0
- package/docs/gitbook/replay-and-audit.md +30 -0
- package/docs/gitbook/sdk-reference.md +35 -0
- package/docs/gitbook/security-model.md +58 -0
- package/docs/integrations/README.md +15 -0
- package/docs/integrations/github-actions-verify.yml +31 -0
- package/docs/integrations/github-actions.md +34 -0
- package/docs/integrations/openclaw/CLAWHUB_PUBLISH_CHECKLIST.md +65 -0
- package/docs/integrations/openclaw/PUBLIC_QUICKSTART.md +95 -0
- package/docs/integrations/openclaw/settld-mcp-skill/SKILL.md +69 -0
- package/docs/integrations/openclaw/settld-mcp-skill/mcp-server.example.json +12 -0
- package/docs/kernel-compatible/capabilities.json +36 -0
- package/docs/marketing/agent-commerce-substrate.md +78 -0
- package/docs/marketing/hn-repost-2026-02-17.md +102 -0
- package/docs/marketing/show-hn-post.md +45 -0
- package/docs/ops/ARTIFACT_VERIFICATION_STATUS.md +43 -0
- package/docs/ops/BILLING_WEBHOOK_REPLAY.md +105 -0
- package/docs/ops/CI_FLAKE_BUDGET.md +31 -0
- package/docs/ops/DISPUTE_FINANCE_RECONCILIATION_PACKET.md +56 -0
- package/docs/ops/GO_LIVE_GATE_S13.md +27 -0
- package/docs/ops/HOSTED_BASELINE_R2.md +129 -0
- package/docs/ops/KERNEL_V0_SHIP_GATE.md +69 -0
- package/docs/ops/LIGHTHOUSE_PRODUCTION_CLOSE.md +51 -0
- package/docs/ops/MCP_COMPATIBILITY_MATRIX.md +30 -0
- package/docs/ops/MINIMUM_PRODUCTION_TOPOLOGY.md +89 -0
- package/docs/ops/P0_BACKEND_PROGRESS.md +150 -0
- package/docs/ops/PAYMENTS_ALPHA_R5.md +105 -0
- package/docs/ops/PILOT_ONBOARDING_RUNBOOK.md +112 -0
- package/docs/ops/PRODUCTION_DEPLOYMENT_CHECKLIST.md +140 -0
- package/docs/ops/R1_SLOS.md +66 -0
- package/docs/ops/RELEASE_SIGNING_INCIDENT.md +58 -0
- package/docs/ops/SELF_SERVE_LAUNCH_AUTOMATION.md +89 -0
- package/docs/ops/THROUGHPUT_DRILL_10X.md +48 -0
- package/docs/ops/TRUST_CONFIG_WIZARD.md +60 -0
- package/docs/ops/X402_PILOT_WEEKLY_METRICS.md +76 -0
- package/docs/ops/tool-call-disputes-holdback.md +52 -0
- package/docs/pilot-kit/PILOT_PACKAGE_SCORECARD_X402.md +46 -0
- package/docs/pilot-kit/README.md +29 -0
- package/docs/pilot-kit/architecture-one-pager.md +48 -0
- package/docs/pilot-kit/buyer-email.txt +19 -0
- package/docs/pilot-kit/buyer-one-pager.md +31 -0
- package/docs/pilot-kit/gtm-pilot-playbook.md +182 -0
- package/docs/pilot-kit/offline-verify.md +33 -0
- package/docs/pilot-kit/procurement-one-pager.md +50 -0
- package/docs/pilot-kit/rfp-clause.md +46 -0
- package/docs/pilot-kit/roi-calculator-template.csv +2 -0
- package/docs/pilot-kit/security-qa.md +153 -0
- package/docs/pilot-kit/security-summary.md +35 -0
- package/docs/plans/2026-02-13-mcp-spike-design.md +113 -0
- package/docs/plans/2026-02-20-trust-os-v1-jira-backlog.md +348 -0
- package/docs/plans/2026-02-21-agent-economic-actor-operating-model.md +169 -0
- package/docs/plans/2026-02-21-trust-os-v1-strategy.md +241 -0
- package/docs/research/2026-02-21-agent-spend-host-landscape.md +57 -0
- package/docs/spec/AcceptanceCriteria.v1.md +17 -0
- package/docs/spec/AcceptanceEvaluation.v1.md +10 -0
- package/docs/spec/AgentEvent.v1.md +47 -0
- package/docs/spec/AgentIdentity.v1.md +62 -0
- package/docs/spec/AgentPassport.v1.md +95 -0
- package/docs/spec/AgentReputation.v1.md +59 -0
- package/docs/spec/AgentReputation.v2.md +52 -0
- package/docs/spec/AgentRun.v1.md +47 -0
- package/docs/spec/AgentRunSettlement.v1.md +52 -0
- package/docs/spec/AgentWallet.v1.md +43 -0
- package/docs/spec/AgreementDelegation.v1.md +109 -0
- package/docs/spec/ArbitrationCase.v1.md +67 -0
- package/docs/spec/ArbitrationOutcomeMapping.v1.md +62 -0
- package/docs/spec/ArbitrationVerdict.v1.md +60 -0
- package/docs/spec/BundleHeadAttestation.v1.md +32 -0
- package/docs/spec/CANONICAL_JSON.md +31 -0
- package/docs/spec/CRYPTOGRAPHY.md +61 -0
- package/docs/spec/ClosePack.v1.md +49 -0
- package/docs/spec/ClosePackManifest.v1.md +24 -0
- package/docs/spec/DelegationGrant.v1.md +90 -0
- package/docs/spec/DisputeCaseLifecycle.v1.md +51 -0
- package/docs/spec/DisputeOpenEnvelope.v1.md +43 -0
- package/docs/spec/ERRORS.md +76 -0
- package/docs/spec/ESCROW_NETTING_INVARIANTS.md +71 -0
- package/docs/spec/EvidenceIndex.v1.md +20 -0
- package/docs/spec/ExecutionIntent.v1.md +90 -0
- package/docs/spec/FinancePackBundleManifest.v1.md +24 -0
- package/docs/spec/FundingHold.v1.md +60 -0
- package/docs/spec/GovernancePolicy.v1.md +34 -0
- package/docs/spec/GovernancePolicy.v2.md +30 -0
- package/docs/spec/INVARIANTS.md +389 -0
- package/docs/spec/InteractionDirectionMatrix.v1.md +30 -0
- package/docs/spec/InvoiceBundleManifest.v1.md +24 -0
- package/docs/spec/InvoiceClaim.v1.md +11 -0
- package/docs/spec/MONEY_RAIL_STATE_MACHINE.md +58 -0
- package/docs/spec/MarketplaceAcceptance.v2.md +46 -0
- package/docs/spec/MarketplaceOffer.v2.md +54 -0
- package/docs/spec/MeteringReport.v1.md +18 -0
- package/docs/spec/OperatorAction.v1.md +90 -0
- package/docs/spec/PRODUCER_ERRORS.md +42 -0
- package/docs/spec/PolicyDecision.v1.md +83 -0
- package/docs/spec/PricingMatrix.v1.md +20 -0
- package/docs/spec/PricingMatrixSignatures.v1.md +30 -0
- package/docs/spec/PricingMatrixSignatures.v2.md +29 -0
- package/docs/spec/ProduceCliOutput.v1.md +46 -0
- package/docs/spec/ProofBundleManifest.v1.md +24 -0
- package/docs/spec/README.md +109 -0
- package/docs/spec/REFERENCE_IMPLEMENTATIONS.md +29 -0
- package/docs/spec/REFERENCE_VERIFIER_BEHAVIOR.md +68 -0
- package/docs/spec/REMOTE_SIGNER.md +66 -0
- package/docs/spec/ReleaseIndex.v1.md +32 -0
- package/docs/spec/ReleaseIndexSignatures.v1.md +17 -0
- package/docs/spec/ReleaseTrust.v1.md +13 -0
- package/docs/spec/ReleaseTrust.v2.md +26 -0
- package/docs/spec/RemoteSignerRequest.v1.md +21 -0
- package/docs/spec/RemoteSignerResponse.v1.md +16 -0
- package/docs/spec/ReputationEvent.v1.md +63 -0
- package/docs/spec/RevocationList.v1.md +28 -0
- package/docs/spec/SIGNER_PROVIDER_PLUGIN.md +32 -0
- package/docs/spec/STRICTNESS.md +68 -0
- package/docs/spec/SUPPLY_CHAIN.md +33 -0
- package/docs/spec/SettlementAdjustment.v1.md +45 -0
- package/docs/spec/SettlementDecisionRecord.v1.md +48 -0
- package/docs/spec/SettlementDecisionRecord.v2.md +53 -0
- package/docs/spec/SettlementDecisionReport.v1.md +44 -0
- package/docs/spec/SettlementKernel.v1.md +59 -0
- package/docs/spec/SettlementReceipt.v1.md +63 -0
- package/docs/spec/SlaDefinition.v1.md +24 -0
- package/docs/spec/SlaEvaluation.v1.md +12 -0
- package/docs/spec/THREAT_MODEL.md +113 -0
- package/docs/spec/TOOL_PROVENANCE.md +30 -0
- package/docs/spec/TRUST_ANCHORS.md +84 -0
- package/docs/spec/TenantSettings.v1.md +90 -0
- package/docs/spec/TenantSettings.v2.md +99 -0
- package/docs/spec/TimestampProof.v1.md +25 -0
- package/docs/spec/ToolCallAgreement.v1.md +34 -0
- package/docs/spec/ToolCallEvidence.v1.md +47 -0
- package/docs/spec/ToolManifest.v1.md +47 -0
- package/docs/spec/VERIFIER_ENVIRONMENT.md +38 -0
- package/docs/spec/VERSIONING.md +107 -0
- package/docs/spec/VerificationReport.v1.md +50 -0
- package/docs/spec/VerifyAboutOutput.v1.md +10 -0
- package/docs/spec/VerifyCliOutput.v1.md +28 -0
- package/docs/spec/WARNINGS.md +83 -0
- package/docs/spec/error-codes.v1.txt +285 -0
- package/docs/spec/examples/agreement_delegation_v1.example.json +21 -0
- package/docs/spec/examples/arbitration_case_v1.example.json +26 -0
- package/docs/spec/examples/arbitration_verdict_v1.example.json +32 -0
- package/docs/spec/examples/dispute_open_envelope_v1.example.json +18 -0
- package/docs/spec/examples/produce_cli_output_v1.example.json +32 -0
- package/docs/spec/examples/release_index_signature_v1.example.json +9 -0
- package/docs/spec/examples/release_index_signatures_v1.example.json +14 -0
- package/docs/spec/examples/release_index_v1.example.json +15 -0
- package/docs/spec/examples/release_trust_v1.example.json +7 -0
- package/docs/spec/examples/release_trust_v2.example.json +22 -0
- package/docs/spec/examples/remote_signer_request_v1.example.json +18 -0
- package/docs/spec/examples/remote_signer_response_v1.example.json +8 -0
- package/docs/spec/examples/reputation_event_v1.example.json +29 -0
- package/docs/spec/examples/verification_report_v1.example.json +24 -0
- package/docs/spec/examples/verify_about_output_v1.example.json +29 -0
- package/docs/spec/examples/verify_cli_output_v1.example.json +13 -0
- package/docs/spec/legacy/MarketplaceAcceptance.v1.md +48 -0
- package/docs/spec/legacy/MarketplaceOffer.v1.md +56 -0
- package/docs/spec/legacy/schemas/MarketplaceAcceptance.v1.schema.json +53 -0
- package/docs/spec/legacy/schemas/MarketplaceOffer.v1.schema.json +61 -0
- package/docs/spec/producer-error-codes.v1.txt +14 -0
- package/docs/spec/schemas/AcceptanceCriteria.v1.schema.json +24 -0
- package/docs/spec/schemas/AcceptanceEvaluation.v1.schema.json +26 -0
- package/docs/spec/schemas/AgentEvent.v1.schema.json +49 -0
- package/docs/spec/schemas/AgentIdentity.v1.schema.json +129 -0
- package/docs/spec/schemas/AgentPassport.v1.schema.json +112 -0
- package/docs/spec/schemas/AgentReputation.v1.schema.json +151 -0
- package/docs/spec/schemas/AgentReputation.v2.schema.json +120 -0
- package/docs/spec/schemas/AgentRun.v1.schema.json +71 -0
- package/docs/spec/schemas/AgentRunSettlement.v1.schema.json +75 -0
- package/docs/spec/schemas/AgentWallet.v1.schema.json +54 -0
- package/docs/spec/schemas/AgreementDelegation.v1.schema.json +50 -0
- package/docs/spec/schemas/ArbitrationCase.v1.schema.json +133 -0
- package/docs/spec/schemas/ArbitrationVerdict.v1.schema.json +149 -0
- package/docs/spec/schemas/BundleHeadAttestation.v1.schema.json +21 -0
- package/docs/spec/schemas/ClosePackManifest.v1.schema.json +38 -0
- package/docs/spec/schemas/DelegationGrant.v1.schema.json +102 -0
- package/docs/spec/schemas/DisputeOpenEnvelope.v1.schema.json +78 -0
- package/docs/spec/schemas/EvidenceIndex.v1.schema.json +41 -0
- package/docs/spec/schemas/ExecutionIntent.v1.schema.json +85 -0
- package/docs/spec/schemas/FinancePackBundleManifest.v1.schema.json +38 -0
- package/docs/spec/schemas/FundingHold.v1.schema.json +46 -0
- package/docs/spec/schemas/GovernancePolicy.v1.schema.json +45 -0
- package/docs/spec/schemas/GovernancePolicy.v2.schema.json +70 -0
- package/docs/spec/schemas/InteractionDirectionMatrix.v1.schema.json +43 -0
- package/docs/spec/schemas/InvoiceBundleManifest.v1.schema.json +38 -0
- package/docs/spec/schemas/InvoiceClaim.v1.schema.json +39 -0
- package/docs/spec/schemas/MarketplaceAcceptance.v2.schema.json +53 -0
- package/docs/spec/schemas/MarketplaceOffer.v2.schema.json +61 -0
- package/docs/spec/schemas/MeteringReport.v1.schema.json +45 -0
- package/docs/spec/schemas/OperatorAction.v1.schema.json +113 -0
- package/docs/spec/schemas/PolicyDecision.v1.schema.json +74 -0
- package/docs/spec/schemas/PricingMatrix.v1.schema.json +24 -0
- package/docs/spec/schemas/PricingMatrixSignatures.v1.schema.json +24 -0
- package/docs/spec/schemas/PricingMatrixSignatures.v2.schema.json +24 -0
- package/docs/spec/schemas/ProduceCliOutput.v1.schema.json +107 -0
- package/docs/spec/schemas/ProofBundleManifest.v1.schema.json +37 -0
- package/docs/spec/schemas/PublicKeys.v1.schema.json +33 -0
- package/docs/spec/schemas/ReleaseIndex.v1.schema.json +45 -0
- package/docs/spec/schemas/ReleaseIndexSignature.v1.schema.json +16 -0
- package/docs/spec/schemas/ReleaseIndexSignatures.v1.schema.json +16 -0
- package/docs/spec/schemas/ReleaseTrust.v1.schema.json +15 -0
- package/docs/spec/schemas/ReleaseTrust.v2.schema.json +37 -0
- package/docs/spec/schemas/RemoteSignerPublicKeyResponse.v1.schema.json +14 -0
- package/docs/spec/schemas/RemoteSignerRequest.v1.schema.json +24 -0
- package/docs/spec/schemas/RemoteSignerResponse.v1.schema.json +10 -0
- package/docs/spec/schemas/RemoteSignerSignRequest.v1.schema.json +27 -0
- package/docs/spec/schemas/RemoteSignerSignResponse.v1.schema.json +16 -0
- package/docs/spec/schemas/ReputationEvent.v1.schema.json +164 -0
- package/docs/spec/schemas/RevocationList.v1.schema.json +51 -0
- package/docs/spec/schemas/SettlementAdjustment.v1.schema.json +44 -0
- package/docs/spec/schemas/SettlementDecisionRecord.v1.schema.json +66 -0
- package/docs/spec/schemas/SettlementDecisionRecord.v2.schema.json +149 -0
- package/docs/spec/schemas/SettlementDecisionReport.v1.schema.json +61 -0
- package/docs/spec/schemas/SettlementReceipt.v1.schema.json +135 -0
- package/docs/spec/schemas/SlaDefinition.v1.schema.json +33 -0
- package/docs/spec/schemas/SlaEvaluation.v1.schema.json +26 -0
- package/docs/spec/schemas/TenantSettings.v1.schema.json +90 -0
- package/docs/spec/schemas/TenantSettings.v2.schema.json +161 -0
- package/docs/spec/schemas/TimestampProof.v1.schema.json +17 -0
- package/docs/spec/schemas/ToolCallAgreement.v1.schema.json +34 -0
- package/docs/spec/schemas/ToolCallEvidence.v1.schema.json +45 -0
- package/docs/spec/schemas/ToolManifest.v1.schema.json +54 -0
- package/docs/spec/schemas/VerificationReport.v1.schema.json +83 -0
- package/docs/spec/schemas/VerifyAboutOutput.v1.schema.json +54 -0
- package/docs/spec/schemas/VerifyCliOutput.v1.schema.json +75 -0
- package/docs/spec/schemas/VerifyReleaseOutput.v1.schema.json +47 -0
- package/docs/spec/x402-error-codes.v1.txt +35 -0
- package/docs/templates/buyer-email.txt +18 -0
- package/docs/templates/buyer-one-pager.md +24 -0
- package/package.json +53 -6
- package/scripts/acceptance/full-stack.mjs +734 -0
- package/scripts/acceptance/full-stack.sh +99 -0
- package/scripts/audit/build-audit-packet.mjs +242 -0
- package/scripts/backup-pg.sh +45 -0
- package/scripts/backup-restore/README.md +18 -0
- package/scripts/backup-restore/capture-state.mjs +130 -0
- package/scripts/backup-restore/client.mjs +97 -0
- package/scripts/backup-restore/seed-workload.mjs +235 -0
- package/scripts/backup-restore/verify-state.mjs +139 -0
- package/scripts/backup-restore-test.sh +217 -0
- package/scripts/chaos.js +221 -0
- package/scripts/ci/build-launch-cutover-packet.mjs +304 -0
- package/scripts/ci/build-self-serve-benchmark-report.mjs +122 -0
- package/scripts/ci/changelog-guard.mjs +145 -0
- package/scripts/ci/check-kernel-v0-launch-gate.mjs +233 -0
- package/scripts/ci/check-secret-hygiene.mjs +78 -0
- package/scripts/ci/check-version-consistency.mjs +42 -0
- package/scripts/ci/cli-pack-smoke.mjs +160 -0
- package/scripts/ci/flake-budget-guard.mjs +68 -0
- package/scripts/ci/generate-error-codes.mjs +54 -0
- package/scripts/ci/lib/lighthouse-tracker.mjs +90 -0
- package/scripts/ci/lib/self-serve-launch-gate.mjs +89 -0
- package/scripts/ci/npm-pack-smoke.mjs +454 -0
- package/scripts/ci/run-10x-throughput-drill.mjs +318 -0
- package/scripts/ci/run-10x-throughput-incident-rehearsal.mjs +368 -0
- package/scripts/ci/run-arbitration-workspace-browser-e2e.sh +22 -0
- package/scripts/ci/run-circle-sandbox-smoke.mjs +237 -0
- package/scripts/ci/run-go-live-gate.mjs +150 -0
- package/scripts/ci/run-kernel-v0-ship-gate.mjs +97 -0
- package/scripts/ci/run-mcp-host-cert-matrix.mjs +201 -0
- package/scripts/ci/run-mcp-host-smoke.mjs +473 -0
- package/scripts/ci/run-offline-verification-parity-gate.mjs +762 -0
- package/scripts/ci/run-onboarding-host-success-gate.mjs +516 -0
- package/scripts/ci/run-onboarding-policy-slo-gate.mjs +537 -0
- package/scripts/ci/run-production-cutover-gate.mjs +540 -0
- package/scripts/ci/run-public-openclaw-npx-smoke.mjs +148 -0
- package/scripts/ci/run-release-promotion-guard.mjs +756 -0
- package/scripts/ci/run-self-serve-launch-gate.mjs +56 -0
- package/scripts/ci/runtime-import-smoke.mjs +58 -0
- package/scripts/ci/update-lighthouse-tracker.mjs +112 -0
- package/scripts/closepack/lib.mjs +286 -0
- package/scripts/collect-debug.sh +263 -0
- package/scripts/demo/compositional-settlement-3hop.mjs +237 -0
- package/scripts/demo/delivery-robot/export-ui-fixture.mjs +188 -0
- package/scripts/demo/delivery-robot/generate.mjs +377 -0
- package/scripts/demo/kernel-agent-goes-shopping.mjs +202 -0
- package/scripts/demo/magic-link-first-green.mjs +118 -0
- package/scripts/demo/magic-link-kind-smoke.mjs +577 -0
- package/scripts/demo/mcp-paid-exa.mjs +1110 -0
- package/scripts/dev/billing-doctor.sh +145 -0
- package/scripts/dev/billing-smoke-prod.sh +219 -0
- package/scripts/dev/billing-webhook-replay.sh +161 -0
- package/scripts/dev/env.dev.example +29 -0
- package/scripts/dev/env.sh +37 -0
- package/scripts/dev/new-sdk-key.sh +81 -0
- package/scripts/dev/sdk-first-run.sh +21 -0
- package/scripts/dev/smoke-x402-gateway.sh +115 -0
- package/scripts/dev/start-api.sh +24 -0
- package/scripts/doctor/mcp-host.mjs +120 -0
- package/scripts/examples/produce-and-verify-jobproof.mjs +191 -0
- package/scripts/examples/sdk-first-paid-rfq.py +105 -0
- package/scripts/examples/sdk-first-verified-run.mjs +85 -0
- package/scripts/examples/sdk-first-verified-run.py +99 -0
- package/scripts/examples/sdk-tenant-analytics.mjs +103 -0
- package/scripts/examples/sdk-tenant-analytics.py +118 -0
- package/scripts/finance-pack/bundle.mjs +284 -0
- package/scripts/fixtures/generate-bundle-fixtures.mjs +877 -0
- package/scripts/governance/export.mjs +169 -0
- package/scripts/load/delivery-stress.k6.js +183 -0
- package/scripts/load/ingest-burst.k6.js +236 -0
- package/scripts/load/run-delivery-load.js +66 -0
- package/scripts/load/webhook-receiver.js +131 -0
- package/scripts/magic-link/migrate-run-records-to-db.mjs +35 -0
- package/scripts/mcp/probe.mjs +238 -0
- package/scripts/mcp/settld-mcp-http-gateway.mjs +178 -0
- package/scripts/mcp/settld-mcp-server.mjs +1511 -0
- package/scripts/openapi/write.mjs +13 -0
- package/scripts/ops/bootstrap-tenant-conformance.mjs +185 -0
- package/scripts/ops/build-x402-pilot-reliability-report.mjs +489 -0
- package/scripts/ops/check-x402-receipt-sample.mjs +181 -0
- package/scripts/ops/design-partner-run-packet.mjs +466 -0
- package/scripts/ops/dispute-finance-reconciliation-packet.mjs +313 -0
- package/scripts/ops/hosted-baseline-evidence.mjs +890 -0
- package/scripts/ops/money-rails-chargeback-evidence.mjs +509 -0
- package/scripts/ops/money-rails-reconcile-evidence.mjs +180 -0
- package/scripts/ops/p0-seed-money-rail-operation.mjs +432 -0
- package/scripts/ops/run-x402-hitl-smoke.mjs +607 -0
- package/scripts/pilot/finance-pack.mjs +495 -0
- package/scripts/pilot/fixtures/robot-keypair.json +4 -0
- package/scripts/pilot/fixtures/server-signer.json +4 -0
- package/scripts/policy/cli.mjs +600 -0
- package/scripts/profile/cli.mjs +1324 -0
- package/scripts/proof-bundle/job.mjs +109 -0
- package/scripts/proof-bundle/lib.mjs +92 -0
- package/scripts/proof-bundle/month.mjs +103 -0
- package/scripts/provider/conformance-run.mjs +159 -0
- package/scripts/provider/keys-generate.mjs +135 -0
- package/scripts/provider/publish.mjs +420 -0
- package/scripts/quickstart/x402.mjs +334 -0
- package/scripts/register-entity-secret.mjs +102 -0
- package/scripts/release/build-artifacts.mjs +181 -0
- package/scripts/release/generate-release-index.mjs +112 -0
- package/scripts/release/release-index-lib.mjs +232 -0
- package/scripts/release/sign-release-index.mjs +85 -0
- package/scripts/release/validate-release-assets.mjs +170 -0
- package/scripts/release/verify-release.mjs +261 -0
- package/scripts/restore-pg.sh +34 -0
- package/scripts/scaffold/create-settld-paid-tool.mjs +19 -0
- package/scripts/sdk/smoke-python.py +30 -0
- package/scripts/sdk/smoke.mjs +16 -0
- package/scripts/settlement/x402-batch-worker.mjs +1091 -0
- package/scripts/setup/circle-bootstrap.mjs +310 -0
- package/scripts/setup/host-config.mjs +617 -0
- package/scripts/setup/onboard.mjs +1337 -0
- package/scripts/setup/openclaw-onboard.mjs +423 -0
- package/scripts/setup/wizard.mjs +986 -0
- package/scripts/slo/check.mjs +239 -0
- package/scripts/smoke/k8s-smoke.mjs +214 -0
- package/scripts/spec/generate-protocol-vectors.mjs +1019 -0
- package/scripts/test/check-no-generated-artifacts.sh +12 -0
- package/scripts/test/run.sh +59 -0
- package/scripts/trust/validate-trust-file.mjs +57 -0
- package/scripts/trust-config/rotate-settld-pay.mjs +277 -0
- package/scripts/trust-config/wizard.mjs +161 -0
- package/scripts/vendor-contract-test-lib.mjs +182 -0
- package/scripts/vendor-contract-test.mjs +55 -0
- package/scripts/vercel/build-mkdocs.sh +9 -0
- package/scripts/vercel/ignore-mkdocs.sh +25 -0
- package/scripts/vercel/install-mkdocs.sh +6 -0
- package/scripts/verify-pg.js +217 -0
- package/scripts/x402/receipt-verify.mjs +289 -0
- package/services/finance-sink/src/dedupe-store.js +29 -6
- package/services/receiver/src/dedupe-store.js +29 -5
- package/services/x402-gateway/Dockerfile +13 -0
- package/services/x402-gateway/README.md +58 -0
- package/services/x402-gateway/examples/upstream-mock.js +337 -0
- package/services/x402-gateway/src/server.js +1058 -0
- package/src/api/app.js +34658 -16940
- package/src/api/maintenance.js +70 -0
- package/src/api/middleware/trust-kernel.js +114 -0
- package/src/api/openapi.js +1778 -70
- package/src/api/persistence.js +456 -0
- package/src/api/server.js +81 -5
- package/src/api/store.js +1581 -62
- package/src/api/workers/deliveries.js +99 -4
- package/src/api/workers/insolvency-sweep.js +159 -0
- package/src/core/agent-card.js +69 -0
- package/src/core/agent-wallets.js +231 -0
- package/src/core/agreement-delegation.js +549 -0
- package/src/core/billing-plans.js +40 -6
- package/src/core/circle-reserve-adapter.js +845 -0
- package/src/core/event-policy.js +21 -2
- package/src/core/maintenance-locks.js +1 -0
- package/src/core/operator-action.js +303 -0
- package/src/core/paid-tool-manifest.js +318 -0
- package/src/core/policy-decision.js +322 -0
- package/src/core/policy-packs.js +207 -0
- package/src/core/profile-fingerprint.js +27 -0
- package/src/core/profile-simulation-reasons.js +84 -0
- package/src/core/profile-templates.js +242 -0
- package/src/core/provider-publish-conformance.js +525 -0
- package/src/core/provider-publish-proof.js +396 -0
- package/src/core/provider-quote-signature.js +170 -0
- package/src/core/settld-keys.js +112 -0
- package/src/core/settld-pay-token.js +344 -0
- package/src/core/settlement-kernel.js +239 -2
- package/src/core/settlement-verifier.js +335 -0
- package/src/core/tool-call-agreement.js +112 -0
- package/src/core/tool-call-evidence.js +144 -0
- package/src/core/tool-provider-signature.js +98 -0
- package/src/core/wallet-assignment-resolver.js +129 -0
- package/src/core/wallet-provider-bootstrap.js +365 -0
- package/src/core/x402-escalation-override.js +258 -0
- package/src/core/x402-gate.js +118 -0
- package/src/core/x402-provider-refund-decision.js +220 -0
- package/src/core/x402-receipt-verifier.js +708 -0
- package/src/core/x402-reversal-command.js +251 -0
- package/src/core/x402-wallet-issuer-decision.js +252 -0
- package/src/core/zk-verifier.js +300 -0
- package/src/db/migrations/029_reputation_event_index.sql +54 -0
- package/src/db/migrations/030_artifacts_source_event_unique_job_only.sql +15 -0
- package/src/db/pg.js +18 -7
- package/src/db/store-pg.js +1508 -111
package/README.md
CHANGED
|
@@ -1,6 +1,45 @@
|
|
|
1
1
|
# Settld
|
|
2
2
|
|
|
3
|
-
Settld is
|
|
3
|
+
Settld is verify-before-release receipts for delegated autonomous work: **verify what happened**, retain **audit-ready evidence**, and **settle** outcomes deterministically.
|
|
4
|
+
|
|
5
|
+
Wedge (current): an x402-style gateway that turns `HTTP 402` into `hold -> verify -> release/refund`, with deterministic receipts. Default posture is strict: **hold 100% until PASS**; **refund on FAIL**. Optionally require an **Ed25519 provider signature** over the upstream response hash.
|
|
6
|
+
|
|
7
|
+
What you get in this repo:
|
|
8
|
+
|
|
9
|
+
- `settld` CLI for bundle verification + a conformance pack (CI / audit evidence)
|
|
10
|
+
- Runnable Node.js prototype (API + agent simulator)
|
|
11
|
+
- Protocol + product docs (schemas/specs, trust anchors, warning codes, etc.)
|
|
12
|
+
- Positioning and go-to-market narrative: `docs/marketing/agent-commerce-substrate.md`
|
|
13
|
+
|
|
14
|
+
## 10-minute Demo: Verified Receipt (x402 Verify-Before-Release)
|
|
15
|
+
|
|
16
|
+
Prereqs: Node.js 20+.
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm ci && npm run quickstart:x402
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
By default the script keeps services running until you press Ctrl+C.
|
|
23
|
+
|
|
24
|
+
If you already ran `npm ci` in this repo, you can skip it:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
npm run quickstart:x402
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
To run once and exit (CI-friendly):
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
npm ci && SETTLD_QUICKSTART_KEEP_ALIVE=0 npm run quickstart:x402
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Success: prints `OK`, a `gateId=...`, and a `gateStateUrl=...`.
|
|
37
|
+
|
|
38
|
+
Next: `docs/QUICKSTART_X402_GATEWAY.md`
|
|
39
|
+
|
|
40
|
+
If you tried and failed:
|
|
41
|
+
|
|
42
|
+
- Run `./scripts/collect-debug.sh` and open a GitHub issue using the "Quickstart failure" template: https://github.com/aidenlippert/settld/issues/new?template=quickstart-failure.yml
|
|
4
43
|
|
|
5
44
|
The core mental model in this repo:
|
|
6
45
|
|
|
@@ -9,16 +48,17 @@ The core mental model in this repo:
|
|
|
9
48
|
- **Trust is a black box**: telemetry/evidence are append-only, hash-chained, and (optionally) signed.
|
|
10
49
|
- **Money is a ledger**: every settlement is double-entry and must always balance.
|
|
11
50
|
|
|
12
|
-
This repository is a runnable Node.js prototype (API + agent simulator) and a set of product/architecture docs.
|
|
13
|
-
|
|
14
51
|
## Bundle verification (CI / audit evidence)
|
|
15
52
|
|
|
16
53
|
- Overview: `docs/OVERVIEW.md`
|
|
17
54
|
- Quickstart: `docs/QUICKSTART_VERIFY.md`
|
|
18
55
|
- Kernel v0 quickstart (local dev stack + conformance + explorer): `docs/QUICKSTART_KERNEL_V0.md`
|
|
56
|
+
- Kernel v0 product surface (enforced vs not enforced): `docs/KERNEL_V0.md`
|
|
57
|
+
- Kernel Compatible policy + listing format: `docs/KERNEL_COMPATIBLE.md`
|
|
19
58
|
- Producer bootstrap: `docs/QUICKSTART_PRODUCE.md` (trust → produce → strict verify)
|
|
20
59
|
- SDK quickstart (first verified run): `docs/QUICKSTART_SDK.md`
|
|
21
60
|
- SDK quickstart (Python): `docs/QUICKSTART_SDK_PYTHON.md`
|
|
61
|
+
- x402 gateway quickstart (verify-before-release wedge): `docs/QUICKSTART_X402_GATEWAY.md`
|
|
22
62
|
- Integrations (GitHub Actions templates): `docs/integrations/README.md`
|
|
23
63
|
- Protocol contract (schemas/specs): `docs/spec/README.md`
|
|
24
64
|
- Conformance pack (portable oracle): `conformance/v1/README.md`
|
|
@@ -27,6 +67,31 @@ This repository is a runnable Node.js prototype (API + agent simulator) and a se
|
|
|
27
67
|
|
|
28
68
|
## Quick start
|
|
29
69
|
|
|
70
|
+
Agent host onboarding (Codex / Claude / Cursor / OpenClaw), with guided wallet + policy setup:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
npx -y settld setup
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Preflight-only check (no host config write), with JSON report:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
npx -y settld setup --preflight-only --report-path ./.tmp/setup-preflight.json
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If you prefer global install:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
npm install -g settld
|
|
86
|
+
settld setup
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Legacy setup wizard (advanced / old flags):
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
settld setup legacy
|
|
93
|
+
```
|
|
94
|
+
|
|
30
95
|
Start the API:
|
|
31
96
|
|
|
32
97
|
```sh
|
|
@@ -117,6 +182,24 @@ Run conformance (kernel control plane, disputes + holdback):
|
|
|
117
182
|
./bin/settld.js conformance kernel --ops-token tok_ops
|
|
118
183
|
```
|
|
119
184
|
|
|
185
|
+
Run local MCP host compatibility checks:
|
|
186
|
+
|
|
187
|
+
```sh
|
|
188
|
+
./bin/settld.js doctor
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
No-clone registry flow:
|
|
192
|
+
|
|
193
|
+
```sh
|
|
194
|
+
npx settld conformance kernel --ops-token tok_ops
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
No-clone release artifact flow (download `settld-<version>.tgz` from GitHub Releases):
|
|
198
|
+
|
|
199
|
+
```sh
|
|
200
|
+
npx --yes --package ./settld-<version>.tgz settld conformance kernel --ops-token tok_ops
|
|
201
|
+
```
|
|
202
|
+
|
|
120
203
|
Ops workspaces (HTML):
|
|
121
204
|
|
|
122
205
|
- Kernel Explorer: `GET /ops/kernel/workspace` (requires ops token)
|
|
@@ -142,9 +225,16 @@ Ops workspaces (HTML):
|
|
|
142
225
|
- `docs/QUICKSTART_PRODUCE.md`
|
|
143
226
|
- `docs/QUICKSTART_SDK.md`
|
|
144
227
|
- `docs/QUICKSTART_SDK_PYTHON.md`
|
|
228
|
+
- `docs/QUICKSTART_POLICY_PACKS.md`
|
|
229
|
+
- `docs/QUICKSTART_MCP.md`
|
|
230
|
+
- `docs/QUICKSTART_MCP_HOSTS.md`
|
|
145
231
|
- `docs/ADOPTION_CHECKLIST.md`
|
|
146
232
|
- `docs/SUPPORT.md`
|
|
147
233
|
- `docs/OPERATIONS_SIGNING.md`
|
|
234
|
+
- `docs/KERNEL_V0.md`
|
|
235
|
+
- `docs/KERNEL_COMPATIBLE.md`
|
|
236
|
+
- `docs/ops/PAYMENTS_ALPHA_R5.md`
|
|
237
|
+
- `docs/ops/X402_PILOT_WEEKLY_METRICS.md`
|
|
148
238
|
- `docs/ops/ARTIFACT_VERIFICATION_STATUS.md`
|
|
149
239
|
- `docs/ops/TRUST_CONFIG_WIZARD.md`
|
|
150
240
|
- `docs/integrations/README.md`
|
package/SETTLD_VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.2.0
|
package/bin/settld-mcp
ADDED
package/bin/settld.js
CHANGED
|
@@ -8,18 +8,47 @@ function usage() {
|
|
|
8
8
|
// eslint-disable-next-line no-console
|
|
9
9
|
console.error("usage:");
|
|
10
10
|
console.error(" settld --version");
|
|
11
|
+
console.error(" settld onboard [--help]");
|
|
12
|
+
console.error(" settld setup [--help]");
|
|
13
|
+
console.error(" settld setup legacy [--help]");
|
|
14
|
+
console.error(" settld setup circle [--help]");
|
|
15
|
+
console.error(" settld setup openclaw [--help]");
|
|
16
|
+
console.error(" settld doctor [--help] [--report <path>]");
|
|
11
17
|
console.error(" settld conformance test [--case <id>] [--bin settld-verify] [--node-bin <path/to/settld-verify.js>] [--keep-temp]");
|
|
12
18
|
console.error(" settld conformance list");
|
|
13
19
|
console.error(" settld conformance kernel --ops-token <tok_opsw> [--base-url http://127.0.0.1:3000] [--tenant-id tenant_default] [--protocol 1.0] [--case <id>]");
|
|
14
20
|
console.error(" settld conformance kernel:list");
|
|
15
21
|
console.error(" settld closepack export --agreement-hash <sha256> --out <path.zip> [--ops-token tok_ops] [--base-url http://127.0.0.1:3000] [--tenant-id tenant_default] [--protocol 1.0]");
|
|
16
22
|
console.error(" settld closepack verify <path.zip> [--json-out <path.json>]");
|
|
23
|
+
console.error(" settld x402 receipt verify <receipt.json|-> [--strict] [--format json|text] [--json-out <path>]");
|
|
24
|
+
console.error(" settld profile list [--format json|text] [--json-out <path>]");
|
|
25
|
+
console.error(" settld profile init <profile-id> [--out <path>] [--force] [--format json|text] [--json-out <path>]");
|
|
26
|
+
console.error(
|
|
27
|
+
" settld profile wizard [--template <profile-id>] [--non-interactive] [--profile-id <id>] [--name <text>] [--vertical <text>] [--description <text>] [--currency <code>] [--per-request-usd-cents <int>] [--monthly-usd-cents <int>] [--providers <csv>] [--tools <csv>] [--out <path>] [--force] [--format json|text] [--json-out <path>]"
|
|
28
|
+
);
|
|
29
|
+
console.error(" settld profile validate <profile.json|-> [--format json|text] [--json-out <path>]");
|
|
30
|
+
console.error(
|
|
31
|
+
" settld profile simulate <profile.json|-> [--scenario <scenario.json|->|--scenario-json <json>] [--format json|text] [--json-out <path>]"
|
|
32
|
+
);
|
|
33
|
+
console.error(" settld policy init <pack-id> [--out <path>] [--force] [--format json|text] [--json-out <path>]");
|
|
34
|
+
console.error(
|
|
35
|
+
" settld policy simulate <policy-pack.json|-> [--scenario <scenario.json|->|--scenario-json <json>] [--format json|text] [--json-out <path>]"
|
|
36
|
+
);
|
|
37
|
+
console.error(
|
|
38
|
+
" settld policy publish <policy-pack.json|-> [--out <path>] [--force] [--channel <name>] [--owner <id>] [--format json|text] [--json-out <path>]"
|
|
39
|
+
);
|
|
17
40
|
console.error(" settld dev up [--no-build] [--foreground]");
|
|
18
41
|
console.error(" settld dev down [--wipe]");
|
|
19
42
|
console.error(" settld dev ps");
|
|
20
43
|
console.error(" settld dev logs [--follow] [--service api]");
|
|
21
44
|
console.error(" settld dev info");
|
|
22
45
|
console.error(" settld init capability <name> [--out <dir>] [--force]");
|
|
46
|
+
console.error("");
|
|
47
|
+
console.error("onboarding:");
|
|
48
|
+
console.error(" settld onboard");
|
|
49
|
+
console.error(" settld setup");
|
|
50
|
+
console.error(" settld setup --help");
|
|
51
|
+
console.error(" settld dev up");
|
|
23
52
|
}
|
|
24
53
|
|
|
25
54
|
function repoRoot() {
|
|
@@ -91,6 +120,28 @@ function main() {
|
|
|
91
120
|
process.exit(0);
|
|
92
121
|
}
|
|
93
122
|
|
|
123
|
+
if (cmd === "setup") {
|
|
124
|
+
const setupSubcommand = String(argv[1] ?? "").trim();
|
|
125
|
+
if (setupSubcommand === "openclaw") {
|
|
126
|
+
return runNodeScript("scripts/setup/openclaw-onboard.mjs", argv.slice(2));
|
|
127
|
+
}
|
|
128
|
+
if (setupSubcommand === "circle") {
|
|
129
|
+
return runNodeScript("scripts/setup/circle-bootstrap.mjs", argv.slice(2));
|
|
130
|
+
}
|
|
131
|
+
if (setupSubcommand === "legacy") {
|
|
132
|
+
return runNodeScript("scripts/setup/wizard.mjs", argv.slice(2));
|
|
133
|
+
}
|
|
134
|
+
return runNodeScript("scripts/setup/onboard.mjs", argv.slice(1));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (cmd === "onboard") {
|
|
138
|
+
return runNodeScript("scripts/setup/onboard.mjs", argv.slice(1));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (cmd === "doctor") {
|
|
142
|
+
return runNodeScript("scripts/doctor/mcp-host.mjs", argv.slice(1));
|
|
143
|
+
}
|
|
144
|
+
|
|
94
145
|
if (cmd === "conformance") {
|
|
95
146
|
const sub = argv[1] ? String(argv[1]) : "test";
|
|
96
147
|
if (sub === "test") return runNodeScript("conformance/v1/run.mjs", argv.slice(2));
|
|
@@ -203,6 +254,26 @@ function main() {
|
|
|
203
254
|
process.exit(1);
|
|
204
255
|
}
|
|
205
256
|
|
|
257
|
+
if (cmd === "x402") {
|
|
258
|
+
const sub = argv[1] ? String(argv[1]) : "";
|
|
259
|
+
const sub2 = argv[2] ? String(argv[2]) : "";
|
|
260
|
+
if (sub === "receipt" && sub2 === "verify") {
|
|
261
|
+
return runNodeScript("scripts/x402/receipt-verify.mjs", argv.slice(3));
|
|
262
|
+
}
|
|
263
|
+
usage();
|
|
264
|
+
// eslint-disable-next-line no-console
|
|
265
|
+
console.error(`unknown x402 subcommand: ${sub}${sub2 ? ` ${sub2}` : ""}`);
|
|
266
|
+
process.exit(1);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (cmd === "profile") {
|
|
270
|
+
return runNodeScript("scripts/profile/cli.mjs", argv.slice(1));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (cmd === "policy") {
|
|
274
|
+
return runNodeScript("scripts/policy/cli.mjs", argv.slice(1));
|
|
275
|
+
}
|
|
276
|
+
|
|
206
277
|
usage();
|
|
207
278
|
// eslint-disable-next-line no-console
|
|
208
279
|
console.error(`unknown command: ${cmd}`);
|
|
@@ -30,6 +30,8 @@ Example (docker compose dev stack):
|
|
|
30
30
|
|
|
31
31
|
```sh
|
|
32
32
|
./bin/settld.js conformance kernel --ops-token tok_ops
|
|
33
|
+
# or, once published:
|
|
34
|
+
npx settld conformance kernel --ops-token tok_ops
|
|
33
35
|
```
|
|
34
36
|
|
|
35
37
|
Optional:
|
|
@@ -38,6 +40,7 @@ Optional:
|
|
|
38
40
|
node conformance/kernel-v0/run.mjs --ops-token tok_ops --case tool_call_holdback_release
|
|
39
41
|
node conformance/kernel-v0/run.mjs --ops-token tok_ops --case marketplace_run_replay_evaluate
|
|
40
42
|
node conformance/kernel-v0/run.mjs --ops-token tok_ops --list
|
|
43
|
+
node conformance/kernel-v0/run.mjs --ops-token tok_ops --closepack-out-dir /tmp/settld-closepacks
|
|
41
44
|
```
|
|
42
45
|
|
|
43
46
|
Write a machine-readable report:
|
|
@@ -58,3 +61,7 @@ The runner prints `INFO ...` lines with `agreementHash` / `runId` and direct lin
|
|
|
58
61
|
- `adjustmentId = sadj_agmt_${agreementHash}_holdback`
|
|
59
62
|
- `kind = holdback_release` (payee win) or `holdback_refund` (payer win)
|
|
60
63
|
- Applying the same verdict again is **idempotent** (returns the existing adjustment and reports `alreadyExisted=true`).
|
|
64
|
+
- Reputation facts remain stable under retries/tick reruns, and closepack verify enforces sourceRef hash resolution against the portable artifact graph.
|
|
65
|
+
- A kernel closepack can be exported from `agreementHash` and verified offline:
|
|
66
|
+
- `settld closepack export ...`
|
|
67
|
+
- `settld closepack verify ...`
|
|
@@ -12,6 +12,9 @@ import {
|
|
|
12
12
|
signHashHexEd25519,
|
|
13
13
|
verifyHashHexEd25519
|
|
14
14
|
} from "../../src/core/crypto.js";
|
|
15
|
+
import { buildDisputeOpenEnvelopeV1 } from "../../src/core/dispute-open-envelope.js";
|
|
16
|
+
import { exportToolCallClosepack, verifyToolCallClosepackZip } from "../../scripts/closepack/lib.mjs";
|
|
17
|
+
import { SETTLEMENT_VERIFIER_SOURCE } from "../../src/core/settlement-verifier.js";
|
|
15
18
|
|
|
16
19
|
function parseArgs(argv) {
|
|
17
20
|
const out = {
|
|
@@ -22,6 +25,7 @@ function parseArgs(argv) {
|
|
|
22
25
|
opsToken: null,
|
|
23
26
|
caseId: null,
|
|
24
27
|
jsonOut: null,
|
|
28
|
+
closepackOutDir: null,
|
|
25
29
|
list: false,
|
|
26
30
|
help: false
|
|
27
31
|
};
|
|
@@ -62,6 +66,11 @@ function parseArgs(argv) {
|
|
|
62
66
|
i += 1;
|
|
63
67
|
continue;
|
|
64
68
|
}
|
|
69
|
+
if (a === "--closepack-out-dir") {
|
|
70
|
+
out.closepackOutDir = String(argv[i + 1] ?? "");
|
|
71
|
+
i += 1;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
65
74
|
if (a === "--list") {
|
|
66
75
|
out.list = true;
|
|
67
76
|
continue;
|
|
@@ -79,7 +88,7 @@ function usage() {
|
|
|
79
88
|
// eslint-disable-next-line no-console
|
|
80
89
|
console.error("usage:");
|
|
81
90
|
console.error(
|
|
82
|
-
" node conformance/kernel-v0/run.mjs --ops-token <tok_opsw> [--base-url http://127.0.0.1:3000] [--tenant-id tenant_default] [--protocol 1.0] [--case <id>] [--json-out <path>] [--list]"
|
|
91
|
+
" node conformance/kernel-v0/run.mjs --ops-token <tok_opsw> [--base-url http://127.0.0.1:3000] [--tenant-id tenant_default] [--protocol 1.0] [--case <id>] [--json-out <path>] [--closepack-out-dir <dir>] [--list]"
|
|
83
92
|
);
|
|
84
93
|
console.error("");
|
|
85
94
|
console.error("notes:");
|
|
@@ -242,6 +251,65 @@ function assertArbitrationVerdictArtifact({ artifact, caseId, runId, disputeId,
|
|
|
242
251
|
assertArtifactHash(artifact);
|
|
243
252
|
}
|
|
244
253
|
|
|
254
|
+
function buildSignedDisputeOpenEnvelopeV1({
|
|
255
|
+
tenantId,
|
|
256
|
+
agreementHash,
|
|
257
|
+
receiptHash,
|
|
258
|
+
holdHash,
|
|
259
|
+
openedByAgentId,
|
|
260
|
+
signerKeyId,
|
|
261
|
+
signerPrivateKeyPem
|
|
262
|
+
}) {
|
|
263
|
+
const envelopeCoreWithPlaceholder = buildDisputeOpenEnvelopeV1({
|
|
264
|
+
envelopeId: `dopen_tc_${agreementHash}`,
|
|
265
|
+
caseId: `arb_case_tc_${agreementHash}`,
|
|
266
|
+
tenantId,
|
|
267
|
+
agreementHash,
|
|
268
|
+
receiptHash,
|
|
269
|
+
holdHash,
|
|
270
|
+
openedByAgentId,
|
|
271
|
+
openedAt: new Date().toISOString(),
|
|
272
|
+
reasonCode: "TOOL_CALL_DISPUTE",
|
|
273
|
+
nonce: `nonce_${sha256Hex(`${agreementHash}:${openedByAgentId}`).slice(0, 16)}`,
|
|
274
|
+
signerKeyId,
|
|
275
|
+
signature: "placeholder"
|
|
276
|
+
});
|
|
277
|
+
const signature = signHashHexEd25519(envelopeCoreWithPlaceholder.envelopeHash, signerPrivateKeyPem);
|
|
278
|
+
return { ...envelopeCoreWithPlaceholder, signature };
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function assertDisputeOpenEnvelopeArtifact({
|
|
282
|
+
artifact,
|
|
283
|
+
agreementHash,
|
|
284
|
+
receiptHash,
|
|
285
|
+
holdHash,
|
|
286
|
+
caseId,
|
|
287
|
+
openedByAgentId,
|
|
288
|
+
signerKeyId,
|
|
289
|
+
signerPublicKeyPem
|
|
290
|
+
}) {
|
|
291
|
+
assert(artifact && typeof artifact === "object" && !Array.isArray(artifact), "dispute-open artifact must be an object");
|
|
292
|
+
assert(String(artifact.schemaVersion ?? "") === "DisputeOpenEnvelope.v1", "dispute-open artifact schemaVersion mismatch");
|
|
293
|
+
assert(String(artifact.artifactType ?? "") === "DisputeOpenEnvelope.v1", "dispute-open artifact artifactType mismatch");
|
|
294
|
+
assert(String(artifact.caseId ?? "") === String(caseId), "dispute-open artifact caseId mismatch");
|
|
295
|
+
assert(String(artifact.agreementHash ?? "") === String(agreementHash), "dispute-open artifact agreementHash mismatch");
|
|
296
|
+
assert(String(artifact.receiptHash ?? "") === String(receiptHash), "dispute-open artifact receiptHash mismatch");
|
|
297
|
+
assert(String(artifact.holdHash ?? "") === String(holdHash), "dispute-open artifact holdHash mismatch");
|
|
298
|
+
assert(String(artifact.openedByAgentId ?? "") === String(openedByAgentId), "dispute-open artifact openedByAgentId mismatch");
|
|
299
|
+
assert(String(artifact.signerKeyId ?? "") === String(signerKeyId), "dispute-open artifact signerKeyId mismatch");
|
|
300
|
+
assert(isSha256Hex(String(artifact.envelopeHash ?? "")), "dispute-open artifact envelopeHash must be sha256 hex");
|
|
301
|
+
assert(typeof artifact.signature === "string" && artifact.signature.trim() !== "", "dispute-open artifact signature missing");
|
|
302
|
+
assert(
|
|
303
|
+
verifyHashHexEd25519({
|
|
304
|
+
hashHex: String(artifact.envelopeHash),
|
|
305
|
+
signatureBase64: String(artifact.signature),
|
|
306
|
+
publicKeyPem: signerPublicKeyPem
|
|
307
|
+
}) === true,
|
|
308
|
+
"dispute-open signature verification failed"
|
|
309
|
+
);
|
|
310
|
+
assertArtifactHash(artifact);
|
|
311
|
+
}
|
|
312
|
+
|
|
245
313
|
function buildSignedArbitrationVerdictV1({
|
|
246
314
|
tenantId,
|
|
247
315
|
runId,
|
|
@@ -291,6 +359,8 @@ async function runToolCallHoldbackDisputeCase({ opts, verdict }) {
|
|
|
291
359
|
const arbiterKeys = createEd25519Keypair();
|
|
292
360
|
|
|
293
361
|
const arbiterKeyId = keyIdFromPublicKeyPem(arbiterKeys.publicKeyPem);
|
|
362
|
+
const payerKeyId = keyIdFromPublicKeyPem(payerKeys.publicKeyPem);
|
|
363
|
+
const payeeKeyId = keyIdFromPublicKeyPem(payeeKeys.publicKeyPem);
|
|
294
364
|
|
|
295
365
|
await requestJson({
|
|
296
366
|
...opts,
|
|
@@ -381,6 +451,15 @@ async function runToolCallHoldbackDisputeCase({ opts, verdict }) {
|
|
|
381
451
|
receiptHash,
|
|
382
452
|
holdHash,
|
|
383
453
|
openedByAgentId: verdict === "payer" ? payerAgentId : payeeAgentId,
|
|
454
|
+
disputeOpenEnvelope: buildSignedDisputeOpenEnvelopeV1({
|
|
455
|
+
tenantId: opts.tenantId,
|
|
456
|
+
agreementHash,
|
|
457
|
+
receiptHash,
|
|
458
|
+
holdHash,
|
|
459
|
+
openedByAgentId: verdict === "payer" ? payerAgentId : payeeAgentId,
|
|
460
|
+
signerKeyId: verdict === "payer" ? payerKeyId : payeeKeyId,
|
|
461
|
+
signerPrivateKeyPem: verdict === "payer" ? payerKeys.privateKeyPem : payeeKeys.privateKeyPem
|
|
462
|
+
}),
|
|
384
463
|
arbiterAgentId,
|
|
385
464
|
summary: "Conformance dispute",
|
|
386
465
|
evidenceRefs: []
|
|
@@ -397,12 +476,40 @@ async function runToolCallHoldbackDisputeCase({ opts, verdict }) {
|
|
|
397
476
|
assert(settlementId, "arbitrationCase.settlementId missing");
|
|
398
477
|
assert(runId, "arbitrationCase.runId missing");
|
|
399
478
|
|
|
479
|
+
let duplicateOpenErr = null;
|
|
480
|
+
try {
|
|
481
|
+
await requestJson({
|
|
482
|
+
...opts,
|
|
483
|
+
method: "POST",
|
|
484
|
+
pathname: "/tool-calls/arbitration/open",
|
|
485
|
+
idempotencyKey: `conf_${suffix}_open_duplicate`,
|
|
486
|
+
body: {
|
|
487
|
+
agreementHash,
|
|
488
|
+
receiptHash,
|
|
489
|
+
holdHash,
|
|
490
|
+
openedByAgentId: verdict === "payer" ? payerAgentId : payeeAgentId,
|
|
491
|
+
arbiterAgentId,
|
|
492
|
+
summary: "Conformance dispute duplicate open",
|
|
493
|
+
evidenceRefs: []
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
} catch (err) {
|
|
497
|
+
duplicateOpenErr = err;
|
|
498
|
+
}
|
|
499
|
+
assert(duplicateOpenErr && Number(duplicateOpenErr.status) === 409, "duplicate dispute open must return 409");
|
|
500
|
+
assert(
|
|
501
|
+
String(duplicateOpenErr?.body?.code ?? "") === "DISPUTE_ALREADY_OPEN",
|
|
502
|
+
"duplicate dispute open must fail with DISPUTE_ALREADY_OPEN"
|
|
503
|
+
);
|
|
504
|
+
|
|
400
505
|
// Ensure the case artifact is vendored.
|
|
401
506
|
const caseArtifactId = `arbitration_case_${caseId}`;
|
|
402
507
|
assert(
|
|
403
508
|
open?.arbitrationCaseArtifact && typeof open.arbitrationCaseArtifact === "object" && String(open.arbitrationCaseArtifact.artifactId ?? "") === caseArtifactId,
|
|
404
509
|
"open response missing arbitrationCaseArtifact.artifactId"
|
|
405
510
|
);
|
|
511
|
+
const disputeOpenEnvelopeArtifactId = String(open?.disputeOpenEnvelopeArtifact?.artifactId ?? "");
|
|
512
|
+
assert(disputeOpenEnvelopeArtifactId === `dopen_tc_${agreementHash}`, "open response missing disputeOpenEnvelopeArtifact.artifactId");
|
|
406
513
|
await requestJson({
|
|
407
514
|
...opts,
|
|
408
515
|
method: "GET",
|
|
@@ -420,6 +527,17 @@ async function runToolCallHoldbackDisputeCase({ opts, verdict }) {
|
|
|
420
527
|
expectedVerdictId: null,
|
|
421
528
|
expectedVerdictHash: null
|
|
422
529
|
});
|
|
530
|
+
const disputeOpenEnvelopeArtifact = await fetchArtifact({ opts, artifactId: disputeOpenEnvelopeArtifactId });
|
|
531
|
+
assertDisputeOpenEnvelopeArtifact({
|
|
532
|
+
artifact: disputeOpenEnvelopeArtifact,
|
|
533
|
+
agreementHash,
|
|
534
|
+
receiptHash,
|
|
535
|
+
holdHash,
|
|
536
|
+
caseId,
|
|
537
|
+
openedByAgentId: verdict === "payer" ? payerAgentId : payeeAgentId,
|
|
538
|
+
signerKeyId: verdict === "payer" ? payerKeyId : payeeKeyId,
|
|
539
|
+
signerPublicKeyPem: verdict === "payer" ? payerKeys.publicKeyPem : payeeKeys.publicKeyPem
|
|
540
|
+
});
|
|
423
541
|
|
|
424
542
|
// Force the maintenance tick into the "window elapsed" branch, but ensure it blocks on the open arbitration case.
|
|
425
543
|
await sleep(challengeWindowMs + 25);
|
|
@@ -558,6 +676,153 @@ async function runToolCallHoldbackDisputeCase({ opts, verdict }) {
|
|
|
558
676
|
"second verdict submission should include arbitrationVerdictArtifact.artifactId"
|
|
559
677
|
);
|
|
560
678
|
|
|
679
|
+
const replayEvaluate = await requestJson({
|
|
680
|
+
...opts,
|
|
681
|
+
method: "GET",
|
|
682
|
+
pathname: `/ops/tool-calls/replay-evaluate?agreementHash=${encodeURIComponent(agreementHash)}`
|
|
683
|
+
});
|
|
684
|
+
assert(replayEvaluate && typeof replayEvaluate === "object", "tool-call replay-evaluate response missing");
|
|
685
|
+
assert(replayEvaluate?.comparisons?.chainConsistent === true, "tool-call replay-evaluate chainConsistent must be true");
|
|
686
|
+
assert(
|
|
687
|
+
String(replayEvaluate?.replay?.expected?.adjustmentKind ?? "") ===
|
|
688
|
+
(verdict === "payer" ? "holdback_refund" : "holdback_release"),
|
|
689
|
+
"tool-call replay-evaluate expected.adjustmentKind mismatch"
|
|
690
|
+
);
|
|
691
|
+
|
|
692
|
+
const reputationFacts = await requestJson({
|
|
693
|
+
...opts,
|
|
694
|
+
method: "GET",
|
|
695
|
+
pathname: `/ops/reputation/facts?agentId=${encodeURIComponent(payeeAgentId)}&toolId=tool_call&window=allTime&includeEvents=1`
|
|
696
|
+
});
|
|
697
|
+
assert(reputationFacts && typeof reputationFacts === "object", "reputation facts response missing");
|
|
698
|
+
assert(Number(reputationFacts?.facts?.totals?.disputes?.opened ?? 0) >= 1, "reputation facts disputes.opened must be >= 1");
|
|
699
|
+
if (verdict === "payer") {
|
|
700
|
+
assert(Number(reputationFacts?.facts?.totals?.disputes?.payerWin ?? 0) >= 1, "reputation facts disputes.payerWin must be >= 1");
|
|
701
|
+
} else {
|
|
702
|
+
assert(Number(reputationFacts?.facts?.totals?.disputes?.payeeWin ?? 0) >= 1, "reputation facts disputes.payeeWin must be >= 1");
|
|
703
|
+
}
|
|
704
|
+
assert(
|
|
705
|
+
Number(reputationFacts?.facts?.totals?.economics?.adjustmentAppliedCents ?? 0) >= Number(settlementAdjustment?.amountCents ?? 0),
|
|
706
|
+
"reputation facts economics.adjustmentAppliedCents must include adjustment amount"
|
|
707
|
+
);
|
|
708
|
+
const reputationEvents = Array.isArray(reputationFacts?.events) ? reputationFacts.events : [];
|
|
709
|
+
const reputationEventIds = reputationEvents.map((row) => String(row?.eventId ?? "")).filter(Boolean);
|
|
710
|
+
assert(new Set(reputationEventIds).size === reputationEventIds.length, "reputation events must not contain duplicate eventId values");
|
|
711
|
+
const reputationAggregateBeforeRetry = normalizeForCanonicalJson(reputationFacts?.facts ?? {}, { path: "$" });
|
|
712
|
+
const pinnedAsOf = String(reputationFacts?.asOf ?? "");
|
|
713
|
+
assert(Number.isFinite(Date.parse(pinnedAsOf)), "reputation facts must include a valid asOf timestamp");
|
|
714
|
+
const disputeEventId = `rep_dsp_${agreementHash}`;
|
|
715
|
+
const verdictEventId = `rep_vrd_${String(verdictRes?.arbitrationVerdict?.verdictHash ?? "").toLowerCase()}`;
|
|
716
|
+
const adjustmentId = `sadj_agmt_${agreementHash}_holdback`;
|
|
717
|
+
const adjustmentEventId = `rep_adj_${adjustmentId}`;
|
|
718
|
+
|
|
719
|
+
const disputeEvent = reputationEvents.find((row) => String(row?.eventId ?? "") === disputeEventId);
|
|
720
|
+
assert(disputeEvent && typeof disputeEvent === "object", "reputation events must include dispute_opened event");
|
|
721
|
+
assert(String(disputeEvent?.sourceRef?.artifactId ?? "") === caseArtifactId, "dispute_opened sourceRef.artifactId mismatch");
|
|
722
|
+
assert(isSha256Hex(String(disputeEvent?.sourceRef?.hash ?? "")), "dispute_opened sourceRef.hash must be sha256");
|
|
723
|
+
const disputeStatus = await requestJson({
|
|
724
|
+
...opts,
|
|
725
|
+
method: "GET",
|
|
726
|
+
pathname: `/artifacts/${encodeURIComponent(caseArtifactId)}/status`
|
|
727
|
+
});
|
|
728
|
+
assert(
|
|
729
|
+
String(disputeStatus?.artifactHash ?? "") === String(disputeEvent?.sourceRef?.hash ?? ""),
|
|
730
|
+
"dispute_opened sourceRef.hash must resolve to arbitration case artifact hash"
|
|
731
|
+
);
|
|
732
|
+
|
|
733
|
+
const verdictEvent = reputationEvents.find((row) => String(row?.eventId ?? "") === verdictEventId);
|
|
734
|
+
assert(verdictEvent && typeof verdictEvent === "object", "reputation events must include verdict_issued event");
|
|
735
|
+
assert(String(verdictEvent?.sourceRef?.artifactId ?? "") === verdictArtifactId, "verdict_issued sourceRef.artifactId mismatch");
|
|
736
|
+
assert(isSha256Hex(String(verdictEvent?.sourceRef?.hash ?? "")), "verdict_issued sourceRef.hash must be sha256");
|
|
737
|
+
const verdictStatus = await requestJson({
|
|
738
|
+
...opts,
|
|
739
|
+
method: "GET",
|
|
740
|
+
pathname: `/artifacts/${encodeURIComponent(verdictArtifactId)}/status`
|
|
741
|
+
});
|
|
742
|
+
assert(
|
|
743
|
+
String(verdictStatus?.artifactHash ?? "") === String(verdictEvent?.sourceRef?.hash ?? ""),
|
|
744
|
+
"verdict_issued sourceRef.hash must resolve to arbitration verdict artifact hash"
|
|
745
|
+
);
|
|
746
|
+
|
|
747
|
+
const adjustmentEvent = reputationEvents.find((row) => String(row?.eventId ?? "") === adjustmentEventId);
|
|
748
|
+
assert(adjustmentEvent && typeof adjustmentEvent === "object", "reputation events must include adjustment_applied event");
|
|
749
|
+
assert(String(adjustmentEvent?.sourceRef?.sourceId ?? "") === adjustmentId, "adjustment_applied sourceRef.sourceId mismatch");
|
|
750
|
+
assert(isSha256Hex(String(adjustmentEvent?.sourceRef?.hash ?? "")), "adjustment_applied sourceRef.hash must be sha256");
|
|
751
|
+
const adjustmentStatus = await requestJson({
|
|
752
|
+
...opts,
|
|
753
|
+
method: "GET",
|
|
754
|
+
pathname: `/ops/settlement-adjustments/${encodeURIComponent(adjustmentId)}`
|
|
755
|
+
});
|
|
756
|
+
assert(
|
|
757
|
+
String(adjustmentStatus?.adjustment?.adjustmentHash ?? "") === String(adjustmentEvent?.sourceRef?.hash ?? ""),
|
|
758
|
+
"adjustment_applied sourceRef.hash must resolve to settlement adjustment hash"
|
|
759
|
+
);
|
|
760
|
+
const reputationEventCountBeforeRetry = Number(reputationFacts?.facts?.totals?.eventCount ?? reputationEvents.length);
|
|
761
|
+
|
|
762
|
+
const tickAgain = await requestJson({
|
|
763
|
+
...opts,
|
|
764
|
+
method: "POST",
|
|
765
|
+
pathname: "/ops/maintenance/tool-call-holdback/run",
|
|
766
|
+
idempotencyKey: `conf_${suffix}_tick_again`,
|
|
767
|
+
body: { dryRun: false, limit: 250 }
|
|
768
|
+
});
|
|
769
|
+
assert(tickAgain && typeof tickAgain === "object", "maintenance retry response missing");
|
|
770
|
+
|
|
771
|
+
const reputationFactsAfterRetry = await requestJson({
|
|
772
|
+
...opts,
|
|
773
|
+
method: "GET",
|
|
774
|
+
pathname: `/ops/reputation/facts?agentId=${encodeURIComponent(payeeAgentId)}&toolId=tool_call&window=allTime&includeEvents=1`
|
|
775
|
+
});
|
|
776
|
+
const reputationFactsPinnedAsOf = await requestJson({
|
|
777
|
+
...opts,
|
|
778
|
+
method: "GET",
|
|
779
|
+
pathname: `/ops/reputation/facts?agentId=${encodeURIComponent(payeeAgentId)}&toolId=tool_call&window=allTime&includeEvents=1&asOf=${encodeURIComponent(
|
|
780
|
+
pinnedAsOf
|
|
781
|
+
)}`
|
|
782
|
+
});
|
|
783
|
+
const reputationAggregateAfterRetry = normalizeForCanonicalJson(reputationFactsAfterRetry?.facts ?? {}, { path: "$" });
|
|
784
|
+
const reputationAggregatePinnedAsOf = normalizeForCanonicalJson(reputationFactsPinnedAsOf?.facts ?? {}, { path: "$" });
|
|
785
|
+
const reputationEventsAfterRetry = Array.isArray(reputationFactsAfterRetry?.events) ? reputationFactsAfterRetry.events : [];
|
|
786
|
+
const eventCountAfterRetry = Number(reputationFactsAfterRetry?.facts?.totals?.eventCount ?? reputationEventsAfterRetry.length);
|
|
787
|
+
assert(
|
|
788
|
+
eventCountAfterRetry === reputationEventCountBeforeRetry,
|
|
789
|
+
"reputation eventCount must remain stable across retry/tick reruns"
|
|
790
|
+
);
|
|
791
|
+
const retryEventIds = reputationEventsAfterRetry.map((row) => String(row?.eventId ?? "")).filter(Boolean);
|
|
792
|
+
assert(new Set(retryEventIds).size === retryEventIds.length, "reputation events must remain deduplicated after retries");
|
|
793
|
+
assert(
|
|
794
|
+
canonicalJsonStringify(reputationAggregateAfterRetry) === canonicalJsonStringify(reputationAggregateBeforeRetry),
|
|
795
|
+
"reputation aggregates must remain stable across retry/tick reruns"
|
|
796
|
+
);
|
|
797
|
+
assert(
|
|
798
|
+
canonicalJsonStringify(reputationAggregatePinnedAsOf) === canonicalJsonStringify(reputationAggregateBeforeRetry),
|
|
799
|
+
"reputation aggregates must remain stable for a pinned asOf window"
|
|
800
|
+
);
|
|
801
|
+
|
|
802
|
+
const closepackOutDir =
|
|
803
|
+
typeof opts.closepackOutDir === "string" && opts.closepackOutDir.trim() !== ""
|
|
804
|
+
? path.resolve(process.cwd(), opts.closepackOutDir.trim())
|
|
805
|
+
: path.resolve("/tmp", "settld-kernel-closepacks");
|
|
806
|
+
const closepackZipPath = path.join(closepackOutDir, `${agreementHash}.zip`);
|
|
807
|
+
|
|
808
|
+
const closepackExport = await exportToolCallClosepack({
|
|
809
|
+
baseUrl: opts.baseUrl,
|
|
810
|
+
tenantId: opts.tenantId,
|
|
811
|
+
protocol: opts.protocol,
|
|
812
|
+
apiKey: opts.apiKey,
|
|
813
|
+
opsToken: opts.opsToken,
|
|
814
|
+
agreementHash,
|
|
815
|
+
outPath: closepackZipPath
|
|
816
|
+
});
|
|
817
|
+
assert(closepackExport?.ok === true, "closepack export must return ok=true");
|
|
818
|
+
assert(typeof closepackExport?.outPath === "string" && closepackExport.outPath.trim() !== "", "closepack export must return outPath");
|
|
819
|
+
assert(typeof closepackExport?.zipSha256 === "string" && /^[0-9a-f]{64}$/.test(closepackExport.zipSha256), "closepack export zipSha256 must be sha256 hex");
|
|
820
|
+
|
|
821
|
+
const closepackVerify = await verifyToolCallClosepackZip({ zipPath: closepackZipPath });
|
|
822
|
+
assert(closepackVerify?.ok === true, "closepack verify must return ok=true");
|
|
823
|
+
assert(closepackVerify?.replayMatch === true, "closepack verify must return replayMatch=true");
|
|
824
|
+
assert(closepackVerify?.sourceRefResolution?.ok === true, "closepack verify sourceRefResolution.ok must be true");
|
|
825
|
+
|
|
561
826
|
return {
|
|
562
827
|
agreementHash,
|
|
563
828
|
receiptHash,
|
|
@@ -566,7 +831,13 @@ async function runToolCallHoldbackDisputeCase({ opts, verdict }) {
|
|
|
566
831
|
disputeId,
|
|
567
832
|
settlementId,
|
|
568
833
|
runId,
|
|
569
|
-
adjustmentId
|
|
834
|
+
adjustmentId,
|
|
835
|
+
replayEvaluate,
|
|
836
|
+
closepack: {
|
|
837
|
+
path: closepackZipPath,
|
|
838
|
+
zipSha256: closepackExport.zipSha256,
|
|
839
|
+
verify: closepackVerify
|
|
840
|
+
}
|
|
570
841
|
};
|
|
571
842
|
}
|
|
572
843
|
|
|
@@ -641,7 +912,11 @@ async function runMarketplaceRunReplayEvaluateCase({ opts }) {
|
|
|
641
912
|
amountCents: 10_000,
|
|
642
913
|
currency: "USD",
|
|
643
914
|
etaSeconds: 60,
|
|
644
|
-
note: "conformance bid"
|
|
915
|
+
note: "conformance bid",
|
|
916
|
+
verificationMethod: {
|
|
917
|
+
mode: "deterministic",
|
|
918
|
+
source: SETTLEMENT_VERIFIER_SOURCE.DETERMINISTIC_LATENCY_THRESHOLD_V1
|
|
919
|
+
}
|
|
645
920
|
}
|
|
646
921
|
});
|
|
647
922
|
|
|
@@ -707,6 +982,17 @@ async function runMarketplaceRunReplayEvaluateCase({ opts }) {
|
|
|
707
982
|
pathname: `/runs/${encodeURIComponent(runId)}/settlement`
|
|
708
983
|
});
|
|
709
984
|
assert(settlement && typeof settlement === "object", "run settlement missing");
|
|
985
|
+
const decisionRecord = settlement?.decisionRecord ?? settlement?.settlement?.decisionTrace?.decisionRecord ?? null;
|
|
986
|
+
assert(decisionRecord && typeof decisionRecord === "object", "run settlement decisionRecord missing");
|
|
987
|
+
assert(
|
|
988
|
+
String(decisionRecord?.verifierRef?.modality ?? "").toLowerCase() === "deterministic",
|
|
989
|
+
"run settlement decisionRecord.verifierRef.modality must be deterministic"
|
|
990
|
+
);
|
|
991
|
+
assert(
|
|
992
|
+
String(decisionRecord?.verifierRef?.verifierId ?? "") === "settld.deterministic.latency-threshold",
|
|
993
|
+
"run settlement decisionRecord.verifierRef.verifierId mismatch"
|
|
994
|
+
);
|
|
995
|
+
assert(isSha256Hex(String(decisionRecord?.verifierRef?.verifierHash ?? "")), "run settlement decisionRecord.verifierRef.verifierHash must be sha256");
|
|
710
996
|
|
|
711
997
|
const replayEvaluate = await requestJson({
|
|
712
998
|
...opts,
|
|
@@ -720,6 +1006,7 @@ async function runMarketplaceRunReplayEvaluateCase({ opts }) {
|
|
|
720
1006
|
replayEvaluate?.comparisons?.decisionRecordReplayCriticalMatchesStored === true,
|
|
721
1007
|
"replay-evaluate decisionRecordReplayCriticalMatchesStored must be true"
|
|
722
1008
|
);
|
|
1009
|
+
assert(replayEvaluate?.comparisons?.verifierRefMatchesStored === true, "replay-evaluate verifierRefMatchesStored must be true");
|
|
723
1010
|
|
|
724
1011
|
return {
|
|
725
1012
|
rfqId,
|
|
@@ -758,7 +1045,8 @@ async function main() {
|
|
|
758
1045
|
tenantId: opts.tenantId,
|
|
759
1046
|
protocol: opts.protocol,
|
|
760
1047
|
apiKey: opts.apiKey,
|
|
761
|
-
opsToken: opts.opsToken
|
|
1048
|
+
opsToken: opts.opsToken,
|
|
1049
|
+
closepackOutDir: opts.closepackOutDir
|
|
762
1050
|
};
|
|
763
1051
|
|
|
764
1052
|
let pass = 0;
|