settld 0.1.2 → 0.1.5
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 +61 -3
- package/SETTLD_VERSION +1 -1
- package/bin/settld-mcp +2 -0
- package/bin/settld.js +13 -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 +140 -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 +337 -0
- package/docs/QUICKSTART_MCP_HOSTS.md +143 -0
- package/docs/QUICKSTART_PRODUCE.md +61 -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 +15 -0
- package/docs/RELEASE_CHECKLIST.md +156 -0
- package/docs/RELEASING.md +81 -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 +70 -0
- package/docs/SUMMARY.md +16 -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 +52 -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 +104 -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 +14 -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/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/GO_LIVE_GATE_S13.md +27 -0
- package/docs/ops/HOSTED_BASELINE_R2.md +129 -0
- package/docs/ops/KERNEL_V0_SHIP_GATE.md +67 -0
- package/docs/ops/LIGHTHOUSE_PRODUCTION_CLOSE.md +51 -0
- package/docs/ops/MCP_COMPATIBILITY_MATRIX.md +28 -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 +103 -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 +47 -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/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/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/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/PRODUCER_ERRORS.md +42 -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 +104 -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 +51 -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/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 +148 -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 +21 -0
- package/docs/templates/buyer-email.txt +18 -0
- package/docs/templates/buyer-one-pager.md +24 -0
- package/package.json +40 -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 +148 -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 +246 -0
- package/scripts/ci/run-10x-throughput-incident-rehearsal.mjs +325 -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-smoke.mjs +275 -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/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 +1201 -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/hosted-baseline-evidence.mjs +681 -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/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/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/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/slo/check.mjs +178 -0
- package/scripts/smoke/k8s-smoke.mjs +214 -0
- package/scripts/spec/generate-protocol-vectors.mjs +931 -0
- package/scripts/test/check-no-generated-artifacts.sh +12 -0
- package/scripts/test/run.sh +45 -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 +947 -0
- package/src/api/app.js +32517 -16877
- package/src/api/maintenance.js +70 -0
- package/src/api/openapi.js +1130 -17
- package/src/api/persistence.js +272 -0
- package/src/api/server.js +81 -5
- package/src/api/store.js +1248 -6
- 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 +97 -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/maintenance-locks.js +1 -0
- package/src/core/paid-tool-manifest.js +318 -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 +213 -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/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 +838 -72
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`
|
|
@@ -117,6 +157,18 @@ Run conformance (kernel control plane, disputes + holdback):
|
|
|
117
157
|
./bin/settld.js conformance kernel --ops-token tok_ops
|
|
118
158
|
```
|
|
119
159
|
|
|
160
|
+
No-clone registry flow:
|
|
161
|
+
|
|
162
|
+
```sh
|
|
163
|
+
npx settld conformance kernel --ops-token tok_ops
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
No-clone release artifact flow (download `settld-<version>.tgz` from GitHub Releases):
|
|
167
|
+
|
|
168
|
+
```sh
|
|
169
|
+
npx --yes --package ./settld-<version>.tgz settld conformance kernel --ops-token tok_ops
|
|
170
|
+
```
|
|
171
|
+
|
|
120
172
|
Ops workspaces (HTML):
|
|
121
173
|
|
|
122
174
|
- Kernel Explorer: `GET /ops/kernel/workspace` (requires ops token)
|
|
@@ -142,9 +194,15 @@ Ops workspaces (HTML):
|
|
|
142
194
|
- `docs/QUICKSTART_PRODUCE.md`
|
|
143
195
|
- `docs/QUICKSTART_SDK.md`
|
|
144
196
|
- `docs/QUICKSTART_SDK_PYTHON.md`
|
|
197
|
+
- `docs/QUICKSTART_MCP.md`
|
|
198
|
+
- `docs/QUICKSTART_MCP_HOSTS.md`
|
|
145
199
|
- `docs/ADOPTION_CHECKLIST.md`
|
|
146
200
|
- `docs/SUPPORT.md`
|
|
147
201
|
- `docs/OPERATIONS_SIGNING.md`
|
|
202
|
+
- `docs/KERNEL_V0.md`
|
|
203
|
+
- `docs/KERNEL_COMPATIBLE.md`
|
|
204
|
+
- `docs/ops/PAYMENTS_ALPHA_R5.md`
|
|
205
|
+
- `docs/ops/X402_PILOT_WEEKLY_METRICS.md`
|
|
148
206
|
- `docs/ops/ARTIFACT_VERIFICATION_STATUS.md`
|
|
149
207
|
- `docs/ops/TRUST_CONFIG_WIZARD.md`
|
|
150
208
|
- `docs/integrations/README.md`
|
package/SETTLD_VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.5
|
package/bin/settld-mcp
ADDED
package/bin/settld.js
CHANGED
|
@@ -14,6 +14,7 @@ function usage() {
|
|
|
14
14
|
console.error(" settld conformance kernel:list");
|
|
15
15
|
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
16
|
console.error(" settld closepack verify <path.zip> [--json-out <path.json>]");
|
|
17
|
+
console.error(" settld x402 receipt verify <receipt.json|-> [--strict] [--format json|text] [--json-out <path>]");
|
|
17
18
|
console.error(" settld dev up [--no-build] [--foreground]");
|
|
18
19
|
console.error(" settld dev down [--wipe]");
|
|
19
20
|
console.error(" settld dev ps");
|
|
@@ -203,6 +204,18 @@ function main() {
|
|
|
203
204
|
process.exit(1);
|
|
204
205
|
}
|
|
205
206
|
|
|
207
|
+
if (cmd === "x402") {
|
|
208
|
+
const sub = argv[1] ? String(argv[1]) : "";
|
|
209
|
+
const sub2 = argv[2] ? String(argv[2]) : "";
|
|
210
|
+
if (sub === "receipt" && sub2 === "verify") {
|
|
211
|
+
return runNodeScript("scripts/x402/receipt-verify.mjs", argv.slice(3));
|
|
212
|
+
}
|
|
213
|
+
usage();
|
|
214
|
+
// eslint-disable-next-line no-console
|
|
215
|
+
console.error(`unknown x402 subcommand: ${sub}${sub2 ? ` ${sub2}` : ""}`);
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
|
|
206
219
|
usage();
|
|
207
220
|
// eslint-disable-next-line no-console
|
|
208
221
|
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;
|
package/docs/ACCESS.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Access (v0.3)
|
|
2
|
+
|
|
3
|
+
Access is modeled as a first-class, **revocable**, **time-scoped** dependency of a job. Access secrets are never written to the event log; only references are.
|
|
4
|
+
|
|
5
|
+
## Principles
|
|
6
|
+
|
|
7
|
+
- **No secrets in logs**: the event stream stores `credentialRef` (e.g. `vault://...`), never door codes/passwords.
|
|
8
|
+
- **Scoped and revocable**: access plans are time-bounded and can be revoked instantly.
|
|
9
|
+
- **Execution is gated**: the system rejects execution start without an active access plan and access granted within the plan window.
|
|
10
|
+
- **Revocation forces safe exit**: access revocation transitions the job to a safe-exit mode and rejects further “work” events.
|
|
11
|
+
|
|
12
|
+
## Events
|
|
13
|
+
|
|
14
|
+
### `ACCESS_PLAN_ISSUED` (server-signed)
|
|
15
|
+
|
|
16
|
+
Payload shape (current prototype, strict):
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"jobId": "job_123",
|
|
21
|
+
"accessPlanId": "ap_456",
|
|
22
|
+
"method": "SMART_LOCK_CODE|BUILDING_CONCIERGE|ON_SITE_OWNER|DOCKED_IN_BUILDING",
|
|
23
|
+
"credentialRef": "vault://access/ap_456/v1",
|
|
24
|
+
"scope": { "areas": ["ENTRYWAY"], "noGo": ["BEDROOM_2"] },
|
|
25
|
+
"validFrom": "2026-01-26T18:00:00Z",
|
|
26
|
+
"validTo": "2026-01-26T22:00:00Z",
|
|
27
|
+
"revocable": true,
|
|
28
|
+
"requestedBy": "system|customer|ops"
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### `ACCESS_GRANTED` / `ACCESS_DENIED` (robot- or operator-signed)
|
|
33
|
+
|
|
34
|
+
Payload includes the plan reference (no secrets):
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{ "jobId": "job_123", "accessPlanId": "ap_456", "method": "BUILDING_CONCIERGE" }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### `ACCESS_REVOKED` / `ACCESS_EXPIRED` (server-signed in v0.3)
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{ "jobId": "job_123", "accessPlanId": "ap_456", "requestedBy": "customer", "reason": "..." }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Enforced invariants (v0.3)
|
|
47
|
+
|
|
48
|
+
- `ACCESS_GRANTED`/`ACCESS_DENIED` are rejected unless:
|
|
49
|
+
- an `ACCESS_PLAN_ISSUED` exists, and
|
|
50
|
+
- the `accessPlanId` matches the current plan, and
|
|
51
|
+
- the event timestamp is within `[validFrom, validTo]`.
|
|
52
|
+
- `EXECUTION_STARTED` is rejected unless:
|
|
53
|
+
- an access plan exists, and
|
|
54
|
+
- access is currently granted, and
|
|
55
|
+
- the event timestamp is within the plan window.
|
|
56
|
+
- After `ACCESS_REVOKED`, the job moves to `ABORTING_SAFE_EXIT`, and “work” events are rejected.
|
|
57
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Adoption checklist (design partner ready)
|
|
2
|
+
|
|
3
|
+
Use this as an operational checklist to adopt Settld verification in CI with audit-grade evidence retention.
|
|
4
|
+
|
|
5
|
+
## Verification posture
|
|
6
|
+
|
|
7
|
+
- Decide strict vs non-strict (`docs/spec/STRICTNESS.md`).
|
|
8
|
+
- Decide whether warnings gate builds (`--fail-on-warnings`, `docs/spec/WARNINGS.md`).
|
|
9
|
+
- Decide required verification outputs to archive:
|
|
10
|
+
- Recommended: archive `VerifyCliOutput.v1` JSON + the bundle itself.
|
|
11
|
+
|
|
12
|
+
## Trust anchors
|
|
13
|
+
|
|
14
|
+
- Define who owns governance root keys (generation, storage, rotation).
|
|
15
|
+
- Define how trust anchors are distributed to CI (secret store, repo file, env injection).
|
|
16
|
+
- Define update process and emergency rotation response.
|
|
17
|
+
|
|
18
|
+
See `docs/spec/TRUST_ANCHORS.md` and `docs/spec/TOOL_PROVENANCE.md`.
|
|
19
|
+
|
|
20
|
+
## Key management + governance operations
|
|
21
|
+
|
|
22
|
+
- Who is authorized to sign:
|
|
23
|
+
- bundle head attestations
|
|
24
|
+
- verification reports
|
|
25
|
+
- Rotation and revocation procedures (who triggers, how fast, how communicated).
|
|
26
|
+
- Decide whether timestamp proofs are required for historical acceptance.
|
|
27
|
+
|
|
28
|
+
See `docs/spec/GovernancePolicy.v2.md` and `docs/spec/RevocationList.v1.md`.
|
|
29
|
+
|
|
30
|
+
## Storage + retention
|
|
31
|
+
|
|
32
|
+
- Where bundles live (artifact store) and retention period.
|
|
33
|
+
- Whether verification happens on:
|
|
34
|
+
- the original produced bundle, or
|
|
35
|
+
- a downloaded bundle copy (must remain byte-identical).
|
|
36
|
+
- Who can access archived bundles and verification receipts.
|
|
37
|
+
|
|
38
|
+
## Release pinning + upgrades
|
|
39
|
+
|
|
40
|
+
- Pin verifier version (SemVer) for CI stability.
|
|
41
|
+
- Define upgrade cadence and rollback plan.
|
|
42
|
+
|
|
43
|
+
See `docs/spec/VERSIONING.md` and `docs/RELEASING.md`.
|
|
44
|
+
|