settld 0.1.1 → 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
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Trust anchors (out-of-band)
|
|
2
|
+
|
|
3
|
+
Strict verification requires **trusted root keys** that are *not* bundled inside artifacts.
|
|
4
|
+
|
|
5
|
+
This is intentional: bundling trust anchors inside the thing being verified would create a trust-loop.
|
|
6
|
+
|
|
7
|
+
## Release authenticity trust (separate domain)
|
|
8
|
+
|
|
9
|
+
Settld release authenticity (verifying the tool distribution artifacts themselves) uses a **separate trust domain** from bundle verification.
|
|
10
|
+
|
|
11
|
+
- Release trust roots live in `trust/release-trust.json` (see `ReleaseTrust.v2.md`).
|
|
12
|
+
- Release verification CLI: `settld-release verify --dir <release-assets-dir> --trust-file trust/release-trust.json --format json`
|
|
13
|
+
|
|
14
|
+
Do not mix release signing keys with bundle/governance signing keys (different purpose, different blast radius).
|
|
15
|
+
|
|
16
|
+
## Governance roots (required for strict)
|
|
17
|
+
|
|
18
|
+
`GovernancePolicy.v2` and `RevocationList.v1` are signed by governance root keys that must be trusted out-of-band.
|
|
19
|
+
|
|
20
|
+
Verifier input mechanism:
|
|
21
|
+
|
|
22
|
+
- `SETTLD_TRUSTED_GOVERNANCE_ROOT_KEYS_JSON`
|
|
23
|
+
- JSON object mapping `keyId -> publicKeyPem`
|
|
24
|
+
- required for strict verification
|
|
25
|
+
|
|
26
|
+
Recommended operational posture:
|
|
27
|
+
|
|
28
|
+
- Store the trust roots JSON (or a `trust.json` file that contains it) in version control.
|
|
29
|
+
- Distribute updates via PR + review (treat as a security-sensitive change).
|
|
30
|
+
- Pin tool versions in CI (see `docs/spec/VERSIONING.md`) so a verification receipt can be mapped to a stable tool build.
|
|
31
|
+
- For regulated workflows: run strict mode and gate on warnings (`--fail-on-warnings`) when policy requires it (see `STRICTNESS.md` and `WARNINGS.md`).
|
|
32
|
+
|
|
33
|
+
## Buyer pricing signer keys (required for strict InvoiceBundle pricing terms)
|
|
34
|
+
|
|
35
|
+
Invoice bundles may include buyer-approved pricing terms via `pricing/pricing_matrix_signatures.json` (`PricingMatrixSignatures.*`).
|
|
36
|
+
|
|
37
|
+
Verifier input mechanism:
|
|
38
|
+
|
|
39
|
+
- `SETTLD_TRUSTED_PRICING_SIGNER_KEYS_JSON`
|
|
40
|
+
- JSON object mapping `keyId -> publicKeyPem`
|
|
41
|
+
- required to validate buyer pricing signatures in strict mode
|
|
42
|
+
|
|
43
|
+
Optional restriction:
|
|
44
|
+
|
|
45
|
+
- `SETTLD_TRUSTED_PRICING_SIGNER_KEY_IDS_JSON`
|
|
46
|
+
- JSON array of allowed `keyId` strings
|
|
47
|
+
- when set and non-empty, only signatures by these key IDs are treated as trusted (even if additional keys are present in `SETTLD_TRUSTED_PRICING_SIGNER_KEYS_JSON`)
|
|
48
|
+
|
|
49
|
+
Do not overload governance roots: pricing signer trust is a separate trust set with a distinct purpose and blast radius.
|
|
50
|
+
|
|
51
|
+
## Buyer decision signer keys (required to verify SettlementDecisionReport)
|
|
52
|
+
|
|
53
|
+
Buyer approval/hold receipts (`SettlementDecisionReport.v1`) are signed and must be verified under a buyer-controlled trust set.
|
|
54
|
+
|
|
55
|
+
Verifier input mechanism:
|
|
56
|
+
|
|
57
|
+
- `SETTLD_TRUSTED_SETTLEMENT_DECISION_SIGNER_KEYS_JSON`
|
|
58
|
+
- JSON object mapping `keyId -> publicKeyPem`
|
|
59
|
+
- required to validate settlement decision report signatures
|
|
60
|
+
|
|
61
|
+
## Time authorities (required only when needed)
|
|
62
|
+
|
|
63
|
+
Bundles may include `timestampProof` objects that require a verifier-trusted time authority key.
|
|
64
|
+
|
|
65
|
+
Verifier input mechanism:
|
|
66
|
+
|
|
67
|
+
- `SETTLD_TRUSTED_TIME_AUTHORITY_KEYS_JSON`
|
|
68
|
+
- JSON object mapping `keyId -> publicKeyPem`
|
|
69
|
+
- required only when verifying a timestamp proof that must be trusted in strict mode
|
|
70
|
+
|
|
71
|
+
## Fixture corpus convention
|
|
72
|
+
|
|
73
|
+
The committed end-to-end fixtures under `test/fixtures/bundles/v1/**` include a `trust.json` file that contains the trusted keys used by tests.
|
|
74
|
+
|
|
75
|
+
The CLI fixture harness reads that file and injects the corresponding env vars when running `settld-verify` against fixtures.
|
|
76
|
+
|
|
77
|
+
## Rotation workflow (example)
|
|
78
|
+
|
|
79
|
+
1. Add the new root key to your trust file (do not remove the old one yet).
|
|
80
|
+
2. Roll out the trust file change to CI/verifier environments.
|
|
81
|
+
3. Begin signing new governance policy streams with the new root key.
|
|
82
|
+
4. Once all verifiers are updated and the old root is no longer needed, remove the old root key from the trust file.
|
|
83
|
+
|
|
84
|
+
If you remove a trust root key too early, strict verification will fail with trust-related errors (see `ERRORS.md`).
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# TenantSettings.v1
|
|
2
|
+
|
|
3
|
+
`TenantSettings.v1` is the **tenant-scoped configuration contract** for Settld Verify Cloud / Magic Link.
|
|
4
|
+
|
|
5
|
+
This version is legacy and is superseded by `TenantSettings.v2` (which adds artifact storage controls and archival export sinks).
|
|
6
|
+
|
|
7
|
+
It controls:
|
|
8
|
+
|
|
9
|
+
- default verification posture (`auto|strict|compat`)
|
|
10
|
+
- tenant-specific governance trust roots (for strict verification without deploy-time env config)
|
|
11
|
+
- tenant-specific pricing signer keys (for strict verification of buyer-approved pricing terms)
|
|
12
|
+
- retention and quota limits
|
|
13
|
+
- buyer policy controls for vendor submissions
|
|
14
|
+
- buyer portal authentication + RBAC (service-level)
|
|
15
|
+
- buyer decision authentication controls (service-level)
|
|
16
|
+
- buyer decision signing configuration (service-level)
|
|
17
|
+
- webhook configuration
|
|
18
|
+
|
|
19
|
+
## Schema
|
|
20
|
+
|
|
21
|
+
See `schemas/TenantSettings.v1.schema.json`.
|
|
22
|
+
|
|
23
|
+
## Vendor / contract policy controls (service-level)
|
|
24
|
+
|
|
25
|
+
`vendorPolicies` and `contractPolicies` are **service-level** enforcement knobs for Verify Cloud. They do **not** change `InvoiceBundle.v1`.
|
|
26
|
+
|
|
27
|
+
Policy selection precedence:
|
|
28
|
+
|
|
29
|
+
1. `contractPolicies[contractId]` (if `contractId` is present on the run)
|
|
30
|
+
2. `vendorPolicies[vendorId]` (if `vendorId` is present on the run)
|
|
31
|
+
3. no policy
|
|
32
|
+
|
|
33
|
+
Policy fields:
|
|
34
|
+
|
|
35
|
+
- `requiredMode`: `auto|strict|compat` override for how the hosted verifier runs (independent of uploader requested mode).
|
|
36
|
+
- `failOnWarnings`: if true, hosted output is failed when any warnings are present (same as CLI `--fail-on-warnings` posture).
|
|
37
|
+
- `allowAmberApprovals`: if false, buyers cannot record **Approve** decisions when status is Amber.
|
|
38
|
+
- `requireProducerReceiptPresent`: if true, hosted output fails if `verify/verification_report.json` is missing (even in compat mode).
|
|
39
|
+
- `requiredPricingMatrixSignerKeyIds`: when set, hosted verification fails unless `pricing/pricing_matrix_signatures.json` includes at least one trusted signature whose `signerKeyId` is allowlisted by this policy.
|
|
40
|
+
- `retentionDays`: optional per-policy retention override for runs matching that vendor/contract.
|
|
41
|
+
|
|
42
|
+
## Decision authentication (service-level)
|
|
43
|
+
|
|
44
|
+
`decisionAuthEmailDomains` configures optional **email OTP gating** for buyer decision actions (`Approve`/`Hold`) on Magic Links.
|
|
45
|
+
|
|
46
|
+
- If empty (default): decision capture is unauthenticated and relies on typed actor name+email.
|
|
47
|
+
- If non-empty: decision capture requires an email OTP, and the email domain MUST match one of the configured domains.
|
|
48
|
+
|
|
49
|
+
This is a service control plane feature (not part of the frozen `InvoiceBundle.v1` protocol).
|
|
50
|
+
|
|
51
|
+
## Buyer portal authentication + RBAC (service-level)
|
|
52
|
+
|
|
53
|
+
Verify Cloud supports **buyer portal** access without sharing the tenant API key.
|
|
54
|
+
|
|
55
|
+
This is a service control plane feature (not part of the frozen `InvoiceBundle.v1` protocol).
|
|
56
|
+
|
|
57
|
+
### Authentication
|
|
58
|
+
|
|
59
|
+
`buyerAuthEmailDomains` configures **email OTP login** for buyer users.
|
|
60
|
+
|
|
61
|
+
- If empty (default): buyer portal OTP login is disabled.
|
|
62
|
+
- If non-empty: buyers can request an OTP and establish a session if their email domain matches one of the configured domains.
|
|
63
|
+
|
|
64
|
+
### Roles
|
|
65
|
+
|
|
66
|
+
`buyerUserRoles` is an optional mapping from **buyer email → role**:
|
|
67
|
+
|
|
68
|
+
- `admin`: manage settings, ingest keys, policies, exports, billing
|
|
69
|
+
- `approver`: view inbox, export audit packet/CSV, approve/hold (via signed `SettlementDecisionReport.v1`)
|
|
70
|
+
- `viewer`: view inbox only
|
|
71
|
+
|
|
72
|
+
If an email is not listed in `buyerUserRoles`, it is treated as `viewer`.
|
|
73
|
+
|
|
74
|
+
## Pricing signer trust (service-level)
|
|
75
|
+
|
|
76
|
+
`pricingSignerKeysJson` is an optional tenant-scoped trust set for **buyer pricing signer keys**.
|
|
77
|
+
|
|
78
|
+
It is used to populate `SETTLD_TRUSTED_PRICING_SIGNER_KEYS_JSON` for hosted verification runs so that
|
|
79
|
+
`pricing/pricing_matrix_signatures.json` can be validated in strict mode.
|
|
80
|
+
|
|
81
|
+
`trustedPricingSignerKeyIds` is an optional allowlist of key IDs. When set and non-empty, Verify Cloud MUST treat only those key IDs as trusted pricing signers (even if additional keys exist in `pricingSignerKeysJson`).
|
|
82
|
+
|
|
83
|
+
## Settlement decision signing (service-level)
|
|
84
|
+
|
|
85
|
+
`settlementDecisionSigner` configures how Verify Cloud signs buyer approval/hold receipts (`SettlementDecisionReport.v1`).
|
|
86
|
+
|
|
87
|
+
Supported modes:
|
|
88
|
+
|
|
89
|
+
- local PEM private key (pilot posture)
|
|
90
|
+
- delegated remote signer (hardened key custody)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# TenantSettings.v2
|
|
2
|
+
|
|
3
|
+
`TenantSettings.v2` is the **tenant-scoped configuration contract** for Settld Verify Cloud / Magic Link.
|
|
4
|
+
|
|
5
|
+
It is a backwards-compatible evolution of `TenantSettings.v1` that adds:
|
|
6
|
+
|
|
7
|
+
- per-tenant artifact storage cost controls (`artifactStorage`)
|
|
8
|
+
- tenant-configurable archival export sink (`archiveExportSink`)
|
|
9
|
+
- buyer notification delivery config (`buyerNotifications`)
|
|
10
|
+
- automatic settlement decision policy controls (`autoDecision`)
|
|
11
|
+
- payment trigger delivery controls (`paymentTriggers`)
|
|
12
|
+
- tenant-scoped request rate limits (`rateLimits`)
|
|
13
|
+
|
|
14
|
+
## Schema
|
|
15
|
+
|
|
16
|
+
See `schemas/TenantSettings.v2.schema.json`.
|
|
17
|
+
|
|
18
|
+
## Vendor / contract policy controls (service-level)
|
|
19
|
+
|
|
20
|
+
Unchanged from `TenantSettings.v1`:
|
|
21
|
+
|
|
22
|
+
- `vendorPolicies` and `contractPolicies` are Verify Cloud enforcement knobs and do **not** change `InvoiceBundle.v1`.
|
|
23
|
+
|
|
24
|
+
## Artifact storage controls (service-level)
|
|
25
|
+
|
|
26
|
+
`artifactStorage` controls what Verify Cloud persists under `MAGIC_LINK_DATA_DIR`.
|
|
27
|
+
|
|
28
|
+
Fields:
|
|
29
|
+
|
|
30
|
+
- `storeBundleZip` (default `true`): persist `zips/<token>.zip` so a buyer can download the exact bytes that were verified.
|
|
31
|
+
- `storePdf` (default `true`): persist `pdf/<token>.pdf` when an invoice claim is present.
|
|
32
|
+
- `precomputeMonthlyAuditPackets` (default `false`): allow the service to cache monthly audit packet zips for export sinks (still safe to generate on-demand).
|
|
33
|
+
|
|
34
|
+
These are service controls (not part of the frozen `InvoiceBundle.v1` protocol).
|
|
35
|
+
|
|
36
|
+
## Archival export sink (service-level)
|
|
37
|
+
|
|
38
|
+
`archiveExportSink` configures an optional monthly archival push of:
|
|
39
|
+
|
|
40
|
+
- monthly audit packet ZIP (`/v1/tenants/:tenant/audit-packet?month=…`)
|
|
41
|
+
- monthly CSV export (`/v1/tenants/:tenant/export.csv?month=…`)
|
|
42
|
+
|
|
43
|
+
Supported sink types:
|
|
44
|
+
|
|
45
|
+
- `s3`: S3-compatible object storage.
|
|
46
|
+
|
|
47
|
+
Secrets (e.g. `secretAccessKey`) are encrypted at rest when `MAGIC_LINK_SETTINGS_KEY_HEX` is configured.
|
|
48
|
+
|
|
49
|
+
## Buyer notifications (service-level)
|
|
50
|
+
|
|
51
|
+
`buyerNotifications` configures post-verification delivery of buyer links.
|
|
52
|
+
|
|
53
|
+
Fields:
|
|
54
|
+
|
|
55
|
+
- `emails`: recipient list (normalized lowercase emails).
|
|
56
|
+
- `deliveryMode`: `smtp|webhook|record`.
|
|
57
|
+
- `webhookUrl`: required when `deliveryMode=webhook`.
|
|
58
|
+
- `webhookSecret`: optional HMAC secret for webhook delivery (encrypted at rest when settings key is configured).
|
|
59
|
+
|
|
60
|
+
Notification delivery is idempotent per run token.
|
|
61
|
+
|
|
62
|
+
## Auto-decision policy (service-level)
|
|
63
|
+
|
|
64
|
+
`autoDecision` configures optional automatic buyer decisions immediately after verification completes.
|
|
65
|
+
|
|
66
|
+
Fields:
|
|
67
|
+
|
|
68
|
+
- `enabled`: turn policy automation on/off.
|
|
69
|
+
- `approveOnGreen`: auto-approve `green` runs.
|
|
70
|
+
- `approveOnAmber`: auto-approve `amber` runs.
|
|
71
|
+
- `holdOnRed`: auto-hold `red` runs.
|
|
72
|
+
- `templateIds`: optional template allowlist. When set, auto-decision only applies to listed SLA template IDs.
|
|
73
|
+
- `actorName` / `actorEmail`: actor identity stamped into `SettlementDecisionReport.v1` for automated decisions.
|
|
74
|
+
|
|
75
|
+
Automated decisions are best-effort and respect idempotency/lockout (`DECISION_ALREADY_RECORDED`).
|
|
76
|
+
|
|
77
|
+
## Payment triggers (service-level)
|
|
78
|
+
|
|
79
|
+
`paymentTriggers` configures optional outbound delivery when an artifact is approved.
|
|
80
|
+
|
|
81
|
+
Fields:
|
|
82
|
+
|
|
83
|
+
- `enabled`: enable/disable payment trigger delivery.
|
|
84
|
+
- `deliveryMode`: `record|webhook`.
|
|
85
|
+
- `webhookUrl`: required when `enabled=true` and `deliveryMode=webhook`.
|
|
86
|
+
- `webhookSecret`: optional HMAC signing secret (encrypted at rest when settings key is configured).
|
|
87
|
+
|
|
88
|
+
Delivery is idempotent per approved decision report hash.
|
|
89
|
+
|
|
90
|
+
## Tenant rate limits (service-level)
|
|
91
|
+
|
|
92
|
+
`rateLimits` configures tenant + IP window limits:
|
|
93
|
+
|
|
94
|
+
- `uploadsPerHour` (default `100`)
|
|
95
|
+
- `verificationViewsPerHour` (default `1000`)
|
|
96
|
+
- `decisionsPerHour` (default `300`)
|
|
97
|
+
- `otpRequestsPerHour` (default `300`)
|
|
98
|
+
|
|
99
|
+
Exceeded limits return `429` with a `Retry-After` header.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# TimestampProof.v1
|
|
2
|
+
|
|
3
|
+
This document defines a **trustworthy signing time** proof that can be embedded inside signed protocol documents (e.g. `BundleHeadAttestation.v1` and `VerificationReport.v1`).
|
|
4
|
+
|
|
5
|
+
## Semantics
|
|
6
|
+
|
|
7
|
+
`TimestampProof.v1` is an **independent attestation of time** over a specific message hash. It exists so strict verification can support “historical acceptance” under prospective revocation rules without trusting a signer-controlled timestamp field.
|
|
8
|
+
|
|
9
|
+
v1 supports one proof kind:
|
|
10
|
+
|
|
11
|
+
- `kind = "ed25519_time_authority"` — an Ed25519 signature by a trusted time authority key.
|
|
12
|
+
|
|
13
|
+
Fields:
|
|
14
|
+
|
|
15
|
+
- `timestamp`: the asserted timestamp (RFC3339 / ISO string).
|
|
16
|
+
- `messageHash`: `sha256` hex of the canonical JSON bytes of the signed document’s **core payload**, computed **without** the `timestampProof` field.
|
|
17
|
+
- `signerKeyId` / `signature`: the time authority signature.
|
|
18
|
+
|
|
19
|
+
## Trust model (strict verification)
|
|
20
|
+
|
|
21
|
+
Strict verification MUST treat the time as trustworthy only if:
|
|
22
|
+
|
|
23
|
+
- the proof verifies cryptographically, and
|
|
24
|
+
- the proof’s signer key is trusted out-of-band by the verifier (a “time authority” trust anchor).
|
|
25
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# ToolCallAgreement.v1
|
|
2
|
+
|
|
3
|
+
`ToolCallAgreement.v1` binds a payable tool invocation to deterministic settlement terms.
|
|
4
|
+
|
|
5
|
+
The output is a hash-addressable agreement (`agreementHash`) that can be referenced by downstream holds, disputes, and receipts without trusting an online service.
|
|
6
|
+
|
|
7
|
+
## Fields
|
|
8
|
+
|
|
9
|
+
Required:
|
|
10
|
+
|
|
11
|
+
- `schemaVersion` (const: `ToolCallAgreement.v1`)
|
|
12
|
+
- `toolId` (string)
|
|
13
|
+
- `manifestHash` (sha256 hex; hash of the referenced `ToolManifest.v1`)
|
|
14
|
+
- `callId` (string; tool-call correlation id)
|
|
15
|
+
- `inputHash` (sha256 hex; hash of canonical JSON of the tool-call input payload)
|
|
16
|
+
- `acceptanceCriteria` (object or `null`)
|
|
17
|
+
- `settlementTerms` (object or `null`)
|
|
18
|
+
- `payerAgentId` (string or `null`)
|
|
19
|
+
- `payeeAgentId` (string or `null`)
|
|
20
|
+
- `createdAt` (ISO 8601 date-time)
|
|
21
|
+
- `agreementHash` (sha256 hex)
|
|
22
|
+
|
|
23
|
+
## Canonicalization + hashing
|
|
24
|
+
|
|
25
|
+
1. Canonicalize using RFC 8785 (JCS).
|
|
26
|
+
2. The `agreementHash` is `sha256` over UTF-8 bytes of canonical JSON of the **agreement core**:
|
|
27
|
+
- the full `ToolCallAgreement.v1` object **excluding** the `agreementHash` field.
|
|
28
|
+
|
|
29
|
+
Implementations must treat the nullable fields (`acceptanceCriteria`, `settlementTerms`, `payerAgentId`, `payeeAgentId`) as present with explicit `null` when absent so `agreementHash` does not depend on “omitted vs null” representation.
|
|
30
|
+
|
|
31
|
+
## Schema
|
|
32
|
+
|
|
33
|
+
See `docs/spec/schemas/ToolCallAgreement.v1.schema.json`.
|
|
34
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# ToolCallEvidence.v1
|
|
2
|
+
|
|
3
|
+
`ToolCallEvidence.v1` records the outcome of a tool invocation (`outputHash`, optional references/metrics) and binds it to a `ToolCallAgreement.v1` via `agreementHash`.
|
|
4
|
+
|
|
5
|
+
The output is a hash-addressable evidence record (`evidenceHash`) that can be optionally signed by an agent key.
|
|
6
|
+
|
|
7
|
+
## Fields
|
|
8
|
+
|
|
9
|
+
Required:
|
|
10
|
+
|
|
11
|
+
- `schemaVersion` (const: `ToolCallEvidence.v1`)
|
|
12
|
+
- `agreementHash` (sha256 hex; points to `ToolCallAgreement.v1`)
|
|
13
|
+
- `callId` (string; must match the agreement `callId`)
|
|
14
|
+
- `inputHash` (sha256 hex; must match the agreement `inputHash`)
|
|
15
|
+
- `outputHash` (sha256 hex; hash of canonical JSON of the tool-call output payload)
|
|
16
|
+
- `outputRef` (string or `null`; optional pointer to stored output)
|
|
17
|
+
- `metrics` (object or `null`; optional timing/quality metrics)
|
|
18
|
+
- `startedAt` (ISO 8601 date-time)
|
|
19
|
+
- `completedAt` (ISO 8601 date-time)
|
|
20
|
+
- `createdAt` (ISO 8601 date-time)
|
|
21
|
+
- `evidenceHash` (sha256 hex)
|
|
22
|
+
|
|
23
|
+
Optional:
|
|
24
|
+
|
|
25
|
+
- `signature` (object): Ed25519 signature over `evidenceHash`
|
|
26
|
+
- `algorithm` (const: `ed25519`)
|
|
27
|
+
- `signerKeyId` (string)
|
|
28
|
+
- `evidenceHash` (sha256 hex; must equal the parent `evidenceHash`)
|
|
29
|
+
- `signature` (base64)
|
|
30
|
+
|
|
31
|
+
## Canonicalization + hashing
|
|
32
|
+
|
|
33
|
+
1. Canonicalize using RFC 8785 (JCS).
|
|
34
|
+
2. The `evidenceHash` is `sha256` over UTF-8 bytes of canonical JSON of the **evidence core**:
|
|
35
|
+
- the full `ToolCallEvidence.v1` object excluding `evidenceHash` and `signature`.
|
|
36
|
+
|
|
37
|
+
Implementations must treat the nullable fields (`outputRef`, `metrics`) as present with explicit `null` when absent so `evidenceHash` does not depend on “omitted vs null” representation.
|
|
38
|
+
|
|
39
|
+
## Signing
|
|
40
|
+
|
|
41
|
+
- When present, `signature.signature` is an Ed25519 signature over the **bytes** of `evidenceHash` (hex), base64-encoded.
|
|
42
|
+
- Verifiers should ensure `signature.evidenceHash` matches the enclosing `evidenceHash` before verifying the signature.
|
|
43
|
+
|
|
44
|
+
## Schema
|
|
45
|
+
|
|
46
|
+
See `docs/spec/schemas/ToolCallEvidence.v1.schema.json`.
|
|
47
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# ToolManifest.v1
|
|
2
|
+
|
|
3
|
+
`ToolManifest.v1` describes a payable capability (a tool) as a signed, portable contract that can be pinned by hash.
|
|
4
|
+
|
|
5
|
+
This object is intentionally small: it exists to make third-party discovery and replay possible without “server configuration context”.
|
|
6
|
+
|
|
7
|
+
## Fields
|
|
8
|
+
|
|
9
|
+
Required:
|
|
10
|
+
|
|
11
|
+
- `schemaVersion` (const: `ToolManifest.v1`)
|
|
12
|
+
- `toolId` (string; stable identifier)
|
|
13
|
+
- `toolVersion` (string; SemVer)
|
|
14
|
+
- `endpoints[]` (non-empty array)
|
|
15
|
+
- `kind` (const: `http`)
|
|
16
|
+
- `baseUrl` (string)
|
|
17
|
+
- `callPath` (string)
|
|
18
|
+
- `manifestPath` (string)
|
|
19
|
+
- `inputSchemaHash` (sha256 hex; hash of the canonical JSON input schema)
|
|
20
|
+
- `outputSchemaHash` (sha256 hex; hash of the canonical JSON output schema)
|
|
21
|
+
- `createdAt` (ISO 8601)
|
|
22
|
+
- `signature` (required)
|
|
23
|
+
- `algorithm` (const: `ed25519`)
|
|
24
|
+
- `signerKeyId` (string)
|
|
25
|
+
- `manifestHash` (sha256 hex)
|
|
26
|
+
- `signature` (base64)
|
|
27
|
+
- `signerPublicKeyPem` (optional; PEM string)
|
|
28
|
+
|
|
29
|
+
Optional:
|
|
30
|
+
|
|
31
|
+
- `verifierHints` (object or `null`): non-binding hints for consumers about how to evaluate/verify outputs (e.g. deterministic verifier).
|
|
32
|
+
|
|
33
|
+
## Canonicalization + hashing
|
|
34
|
+
|
|
35
|
+
1. Canonicalize using RFC 8785 (JCS).
|
|
36
|
+
2. The `manifestHash` is `sha256` over UTF-8 bytes of canonical JSON of the **manifest core**:
|
|
37
|
+
- the full `ToolManifest.v1` object **excluding** the `signature` field.
|
|
38
|
+
|
|
39
|
+
## Signing
|
|
40
|
+
|
|
41
|
+
- The `signature.signature` value is an Ed25519 signature over `manifestHash` (the hex hash string), using the private key corresponding to `signerKeyId`.
|
|
42
|
+
- Consumers may verify using `signature.signerPublicKeyPem` when present, or via an external key registry for `signerKeyId`.
|
|
43
|
+
|
|
44
|
+
## Schema
|
|
45
|
+
|
|
46
|
+
See `docs/spec/schemas/ToolManifest.v1.schema.json`.
|
|
47
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Verifier Environment Assumptions + Hardening (v1)
|
|
2
|
+
|
|
3
|
+
This document describes operational assumptions and recommended hardening when deploying `settld-verify`.
|
|
4
|
+
|
|
5
|
+
## Filesystem assumptions
|
|
6
|
+
|
|
7
|
+
- The bundle is verified from a local directory (or an extracted zip) whose contents are stable during verification.
|
|
8
|
+
- The verifier treats manifest paths as portable `/`-separated bundle-relative paths.
|
|
9
|
+
- The verifier refuses symlinks for manifest-listed files and rejects path traversal attempts.
|
|
10
|
+
- Spec: `REFERENCE_VERIFIER_BEHAVIOR.md`
|
|
11
|
+
|
|
12
|
+
## CI / production recommendations
|
|
13
|
+
|
|
14
|
+
- **Regulated workflows**: run **strict mode** by default.
|
|
15
|
+
- CLI: `settld-verify --strict --format json …`
|
|
16
|
+
- Spec: `STRICTNESS.md`
|
|
17
|
+
- **Warnings policy**:
|
|
18
|
+
- If warnings represent “unknown provenance / incomplete guarantees” in your environment, enable `--fail-on-warnings`.
|
|
19
|
+
- CLI: `settld-verify --fail-on-warnings …`
|
|
20
|
+
- Spec: `WARNINGS.md`
|
|
21
|
+
- **Pin tool versions**:
|
|
22
|
+
- Prefer installing a pinned version of `settld-verify` and recording `VerifyCliOutput.v1.tool.{version,commit}` as evidence.
|
|
23
|
+
- Spec: `TOOL_PROVENANCE.md`, `VERSIONING.md`
|
|
24
|
+
|
|
25
|
+
## Trust anchor distribution (do / don’t)
|
|
26
|
+
|
|
27
|
+
- DO distribute governance-root public keys out-of-band and pin them (e.g., repo file, immutable artifact, or configuration management).
|
|
28
|
+
- DO treat trust anchors as high-integrity inputs (tampering undermines authorization checks).
|
|
29
|
+
- DON’T fetch trust roots over unauthenticated channels at verification time.
|
|
30
|
+
- Spec: `TRUST_ANCHORS.md`
|
|
31
|
+
|
|
32
|
+
## Volatility and determinism
|
|
33
|
+
|
|
34
|
+
- CLI output ordering of `errors[]` and `warnings[]` is deterministic (sorted) to support CI and archival.
|
|
35
|
+
- If you need stronger determinism guarantees, archive both:
|
|
36
|
+
- `verify/verification_report.json` inside the bundle (receipt), and
|
|
37
|
+
- `settld-verify --format json` output (what your CI observed).
|
|
38
|
+
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Versioning (tools vs protocol)
|
|
2
|
+
|
|
3
|
+
Settld has **two coupled version surfaces**:
|
|
4
|
+
|
|
5
|
+
1. **Tool versions** (SemVer): the software you install/run (`settld-verify`, bundlers, services).
|
|
6
|
+
2. **Protocol versions** (object `*.v1`, `*.v2`, …): on-disk/wire-format contracts (schemas + semantics).
|
|
7
|
+
|
|
8
|
+
This document defines when to bump **tool SemVer**, when to introduce **new protocol object versions**, and how to avoid accidental drift.
|
|
9
|
+
|
|
10
|
+
## Tool SemVer policy
|
|
11
|
+
|
|
12
|
+
Tools follow Semantic Versioning:
|
|
13
|
+
|
|
14
|
+
- **MAJOR**: any breaking change to a public surface (CLI flags/output, verification semantics in strict mode, required protocol surfaces, bundle layout requirements, removal of documented warnings, etc.).
|
|
15
|
+
- **MINOR**: backwards-compatible additions (new CLI flags, new optional output fields, new warning codes, new non-strict compatibility paths).
|
|
16
|
+
- **PATCH**: bug fixes and perf improvements that do not change documented behavior (same pass/fail, same codes, same hashes/signatures).
|
|
17
|
+
|
|
18
|
+
### Concrete examples (tool SemVer)
|
|
19
|
+
|
|
20
|
+
- Add a new CLI flag (e.g. `--hash-concurrency`) that does not change verification semantics → **MINOR**.
|
|
21
|
+
- Fix a bug where strict mode accepted an invalid signature and now fails it → **MAJOR** (strict semantics changed).
|
|
22
|
+
- Stream file hashing (perf) while keeping hashes, codes, and strict/non-strict semantics identical → **PATCH**.
|
|
23
|
+
- Add a new warning code and surface it in `VerifyCliOutput.v1` → **MINOR**.
|
|
24
|
+
- Change sorting of `errors[]` / `warnings[]` in CLI JSON output → **MAJOR** (downstream parsers/snapshots can break).
|
|
25
|
+
|
|
26
|
+
## Protocol surface policy
|
|
27
|
+
|
|
28
|
+
The protocol is treated like an API:
|
|
29
|
+
|
|
30
|
+
- Specs: `docs/spec/*`
|
|
31
|
+
- Schemas: `docs/spec/schemas/*`
|
|
32
|
+
- Vectors: `test/fixtures/protocol-vectors/v1.json`
|
|
33
|
+
- End-to-end fixtures: `test/fixtures/bundles/v1/*`
|
|
34
|
+
|
|
35
|
+
## v1 freeze (protocol becomes a stable contract)
|
|
36
|
+
|
|
37
|
+
Protocol `v1` is a **frozen contract**: customers, auditors, and independent implementers must be able to pin a tool version and rely on the v1 meaning indefinitely.
|
|
38
|
+
|
|
39
|
+
### Allowed changes (v1)
|
|
40
|
+
|
|
41
|
+
- Documentation clarifications and additional examples that do **not** change acceptance criteria.
|
|
42
|
+
- Performance improvements that do **not** change:
|
|
43
|
+
- pass/fail outcomes,
|
|
44
|
+
- error/warning codes,
|
|
45
|
+
- hashes/signatures (canonicalization inputs and bytes),
|
|
46
|
+
- strict/non-strict downgrade behavior.
|
|
47
|
+
- New tests, fixtures, and conformance cases that increase coverage without changing behavior.
|
|
48
|
+
|
|
49
|
+
### Not allowed changes (v1)
|
|
50
|
+
|
|
51
|
+
- Any change to `docs/spec/schemas/*v1*.json` that would alter the schema contract.
|
|
52
|
+
- Any change to `test/fixtures/protocol-vectors/v1.json` that changes canonical meaning.
|
|
53
|
+
- Any change to canonicalization rules (RFC 8785 / JCS) or hashing inputs.
|
|
54
|
+
- Any change to strictness semantics in `STRICTNESS.md`.
|
|
55
|
+
- Any change to warning code meanings in `WARNINGS.md`.
|
|
56
|
+
|
|
57
|
+
### Enforcement (CI + local)
|
|
58
|
+
|
|
59
|
+
Changes to v1 schemas/vectors must be **deliberate**:
|
|
60
|
+
|
|
61
|
+
- CI fails if v1 schemas or `test/fixtures/protocol-vectors/v1.json` change unless:
|
|
62
|
+
- `CHANGELOG.md` is updated, **and**
|
|
63
|
+
- the PR includes an explicit marker `protocol-change` (PR body or commit message).
|
|
64
|
+
- A local freeze test (`test/protocol-v1-freeze.test.js`) asserts v1 schema/vector file hashes are unchanged unless `ALLOW_PROTOCOL_V1_MUTATION=1` is set (intended only for deliberate rotations).
|
|
65
|
+
|
|
66
|
+
### What is a breaking protocol change?
|
|
67
|
+
|
|
68
|
+
Any change that alters what an independent verifier would accept/reject, or what it would compute as hashes/signatures, including:
|
|
69
|
+
|
|
70
|
+
- JSON Schema breaking changes for existing `*.v1` objects.
|
|
71
|
+
- Canonicalization changes (RFC 8785 / JCS rules).
|
|
72
|
+
- Hashing changes (algorithm, input bytes, file inclusion/exclusion rules).
|
|
73
|
+
- Strictness contract changes (required surfaces, required validations, downgrade behavior).
|
|
74
|
+
- Bundle layout changes that affect required files or meaning.
|
|
75
|
+
|
|
76
|
+
### When to introduce `v2` objects vs mutate `v1`
|
|
77
|
+
|
|
78
|
+
Do **not** mutate the meaning of `*.v1` objects in a way that would cause previously valid instances to become invalid (or vice versa) in strict mode.
|
|
79
|
+
|
|
80
|
+
Introduce a `v2` when:
|
|
81
|
+
|
|
82
|
+
- A required field changes shape/type/meaning.
|
|
83
|
+
- A new required field is introduced.
|
|
84
|
+
- The canonicalization/hashing/signing inputs change.
|
|
85
|
+
- You need to remove/rename fields or change invariants.
|
|
86
|
+
|
|
87
|
+
You may evolve `v1` only via **compatible additions**:
|
|
88
|
+
|
|
89
|
+
- Add new **optional** fields that are omitted when absent (not `null`).
|
|
90
|
+
- Clarify docs without changing semantics.
|
|
91
|
+
- Add new warning codes (closed set remains documented).
|
|
92
|
+
|
|
93
|
+
### How vectors and fixtures relate to compatibility
|
|
94
|
+
|
|
95
|
+
- **Protocol vectors** lock canonical examples and edge cases. Any intentional protocol change requires a deliberate vector update (and review).
|
|
96
|
+
- **Bundle fixtures** are a conformance corpus. Changes to strict/non-strict behavior should be expressed as:
|
|
97
|
+
- a new fixture directory (single fault), and
|
|
98
|
+
- an expectation row in `test/fixtures/bundles/v1/fixtures.json`.
|
|
99
|
+
|
|
100
|
+
## Compatibility matrix (within a major tool version)
|
|
101
|
+
|
|
102
|
+
Within a given tool **MAJOR**:
|
|
103
|
+
|
|
104
|
+
- Verifier `X.Y.Z` must verify bundles produced by bundler `X.*.*` (same major), subject to documented strict/non-strict behavior and governance trust anchors.
|
|
105
|
+
- Bundlers may emit new **optional** protocol fields in `v1` objects; verifiers in the same major should ignore unknown optional fields unless strict rules say otherwise.
|
|
106
|
+
|
|
107
|
+
If a change requires a new protocol object version (`*.v2`), that is a **MAJOR** tool bump unless explicitly documented as “dual read” compatibility.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# VerificationReport.v1
|
|
2
|
+
|
|
3
|
+
`VerificationReport.v1` is a canonical JSON object emitted into `verify/verification_report.json`.
|
|
4
|
+
|
|
5
|
+
In strict mode, it is **required** and **must be signed**.
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
- Provide a machine-ingestible record of verification results.
|
|
10
|
+
- Bind verification statements to a specific bundle by referencing:
|
|
11
|
+
- `subject.manifestHash`
|
|
12
|
+
- `bundleHeadAttestation.attestationHash` (binding to the head commitment)
|
|
13
|
+
|
|
14
|
+
## Core fields
|
|
15
|
+
|
|
16
|
+
- `schemaVersion = "VerificationReport.v1"`
|
|
17
|
+
- `profile = "strict"`
|
|
18
|
+
- `tool`: `{ name: "settld", version: string | null, commit?: string }`
|
|
19
|
+
- `warnings`: array of warning objects (see `WARNINGS.md`)
|
|
20
|
+
- `subject`:
|
|
21
|
+
- `type`: bundle kind/type (e.g. `JobProofBundle.v1`, `MonthProofBundle.v1`, `FinancePackBundle.v1`)
|
|
22
|
+
- `manifestHash`: the bundle manifest hash
|
|
23
|
+
- `bundleHeadAttestation` (strict-required for bundles that support head attestations):
|
|
24
|
+
- `attestationHash`: must match `attestation/bundle_head_attestation.json` computed hash
|
|
25
|
+
|
|
26
|
+
## Report hash + signature
|
|
27
|
+
|
|
28
|
+
- `reportHash` is computed over the canonical JSON object with `reportHash` and `signature` removed.
|
|
29
|
+
- If the report is signed, it includes:
|
|
30
|
+
- `signature` (base64)
|
|
31
|
+
- `signerKeyId`
|
|
32
|
+
- `signedAt`
|
|
33
|
+
|
|
34
|
+
## Timestamp proof (optional)
|
|
35
|
+
|
|
36
|
+
`timestampProof` (when present) provides a verifier-trusted signing time for revocation/rotation historical acceptance checks. It is computed over the report core **without** `timestampProof` so it can bind to the report payload.
|
|
37
|
+
|
|
38
|
+
## No circular hashing
|
|
39
|
+
|
|
40
|
+
`verify/**` is excluded from bundle manifests. The report binds to the bundle by:
|
|
41
|
+
|
|
42
|
+
- including `subject.manifestHash`
|
|
43
|
+
- including `bundleHeadAttestation.attestationHash`
|
|
44
|
+
- being signed by a governed server key (in strict mode)
|
|
45
|
+
|
|
46
|
+
## Tool identity completeness
|
|
47
|
+
|
|
48
|
+
`tool.commit` is a best-effort build identifier (typically a git commit SHA) intended to answer “what build produced this receipt”.
|
|
49
|
+
|
|
50
|
+
- If the tool commit cannot be determined, the report MUST include warning code `TOOL_COMMIT_UNKNOWN`.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# VerifyAboutOutput.v1
|
|
2
|
+
|
|
3
|
+
`VerifyAboutOutput.v1` is the machine-readable JSON output emitted by `settld-verify --about --format json`.
|
|
4
|
+
|
|
5
|
+
This is a **tool metadata contract** intended for CI and operational introspection.
|
|
6
|
+
|
|
7
|
+
## Schema
|
|
8
|
+
|
|
9
|
+
See `schemas/VerifyAboutOutput.v1.schema.json`.
|
|
10
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# VerifyCliOutput.v1
|
|
2
|
+
|
|
3
|
+
`VerifyCliOutput.v1` is the machine-readable JSON output emitted by `settld-verify --format json`.
|
|
4
|
+
|
|
5
|
+
This is a **tool contract** intended for CI gating and automated ingestion. It is versioned and treated as a stable surface.
|
|
6
|
+
|
|
7
|
+
## Schema
|
|
8
|
+
|
|
9
|
+
See `schemas/VerifyCliOutput.v1.schema.json`.
|
|
10
|
+
|
|
11
|
+
## Semantics
|
|
12
|
+
|
|
13
|
+
- `ok` is the CLI’s overall verdict, including policy flags like `--fail-on-warnings`.
|
|
14
|
+
- `verificationOk` reflects the underlying verifier result (`true` only when the bundle verification succeeded).
|
|
15
|
+
- When available, `errors[].code` is promoted from the verifier’s structured error (`result.detail.error`) to prefer stable, code-like identifiers; `errors[].message` may contain a human summary (`result.error`).
|
|
16
|
+
- `errors` and `warnings` are sorted deterministically by `(path, code)`.
|
|
17
|
+
- The CLI supports `--hash-concurrency <n>` to bound parallel hashing work; it does not change verification semantics.
|
|
18
|
+
- `tool.commit` is a best-effort build identifier for the verifier tool (typically a git commit SHA or build revision).
|
|
19
|
+
|
|
20
|
+
## `--explain` (deterministic stderr)
|
|
21
|
+
|
|
22
|
+
`settld-verify --explain` prints a deterministic diagnostic summary to **stderr** (while `--format json` continues to print machine output to stdout).
|
|
23
|
+
|
|
24
|
+
Contract:
|
|
25
|
+
|
|
26
|
+
- Output is deterministic for the same inputs/environment.
|
|
27
|
+
- Output MUST NOT include secrets.
|
|
28
|
+
- Output ends with **exactly one** trailing newline.
|