paybondpaybond
Sign in

Completion preset catalog

Shared archetype presets for strong completion rules — Harbor templates, evidence schemas, and sample payloads.

Paybond ships a completion preset catalog as the single source of truth for strong, generic completion archetypes. Harbor managed templates, the policy registry console, Kit CLI scaffolding, and docs all consume the same preset IDs and field names.

Canonical file: completion preset catalog (catalog.json)
JSON Schema: completion preset catalog schema (catalog.schema.json)

Why presets exist

Spend guardrails (gateway authorize) and completion predicates (Harbor release) are separate layers. Presets tie them together with:

  • A stable preset ID for docs and CLI (api_response_ok, not vendor-specific names in v1)
  • A Harbor template ID that materializes parameters into validated predicate_dsl
  • Evidence schema and sample pass/fail payloads for preview and test
  • Optional spend hints for documentation (not auto-enforced in v1)

Predicate evaluation stays in Harbor. Your integration collects HTTP responses, webhooks, or artifact hashes and places structured fields in signed evidence — the VM never calls external APIs.

Agent middleware policy files reference preset IDs via evidence_preset in paybond.policy.yaml. Validate preset alignment with paybond policy validate-tools --file paybond.policy.yaml.

Funding vs completion

Paybond enforces a two-layer model. Funding webhooks and authorization payloads move an intent to funded and issue a capability_token. Completion evidence proves the paid tool ran and predicates evaluate that payload only — rail-agnostic, separate from settlement state.

flowchart LR
  subgraph funding [Funding layer - Harbor internal]
    create[Intent create]
    fund[Fund / webhooks / x402 auth]
    funded[state=funded + capability_token]
  end
  subgraph completion [Completion layer - payee evidence]
    tool[Execute paid tool]
    evidence[Submit evidence JSON]
    predicate[Predicate eval]
    settle[Capture / transfer / void]
  end
  create --> fund --> funded --> tool --> evidence --> predicate --> settle
RailFunding signal (NOT evidence)Tool completion evidence (catalog)
stripe_connectCard PaymentIntent succeeded / captureapi_response_ok, vendor_webhook_confirmed, artifact_attested
stripe_ach_debitpayment_intent.succeededfunded (Harbor internal)Same archetypes; never submit PI/charge/mandate ids as payee evidence
x402_usdc_baseauthorization_succeeded via /fund + Coinbase webhooksSame archetypes; never submit payment_session_id / authorization_id / auth tx hashes as payee evidence

Harbor stores rail fields in settlement provider state; predicates evaluate rail-agnostic evidence.payload only. Completion presets do not replace funding webhooks — use the ACH integration checklist and x402 integration checklist below for settlement triage.

ACH integration checklist (stripe_ach_debit)

  1. Fund gate — Wait for Harbor funded after Stripe confirms bank debit (payment_intent.succeeded is funding only).
  2. Capability — Read capability_token from the funded intent; pass it to your spend guard before tool calls.
  3. Tool proof — Call the vendor API or receive an async vendor webhook after the tool completes.
  4. Evidence — Submit tool-completion fields via ach_paid_api_ok, ach_travel_booking, or ach_vendor_webhook (not Stripe funding payloads).
  5. Transfer / refund — On predicate pass, Harbor settles via Connect transfer; on failure, use the canonical refund path.
sequenceDiagram
  participant Agent
  participant Harbor
  participant Stripe
  participant VendorTool

  Agent->>Harbor: fund until capability_token
  Note over Harbor,Stripe: payment_intent.succeeded = FUNDING only
  Agent->>VendorTool: paid API call with capability
  VendorTool-->>Agent: HTTP 200 + confirmation_number
  Agent->>Harbor: evidence via ach_paid_api_ok or ach_travel_booking
  Harbor->>Harbor: predicate pass
  Harbor->>Stripe: Connect transfer on release

x402 integration checklist (x402_usdc_base)

  1. Fund until capability_token — Complete /fund (402PAYMENT-SIGNATURE retry) until Harbor reports authorization_succeeded.
  2. Tool proof — Call the paid tool with the capability; optionally collect an x402 Signed Offer & Receipt on the response.
  3. Evidence — Submit via x402_paid_api_ok, x402_delivery_receipt, or x402_cost_and_completion (not Coinbase session ids).
  4. Capture / void — On predicate pass, Harbor captures USDC; on failure, void the authorization.
sequenceDiagram
  participant Agent
  participant Harbor
  participant Coinbase
  participant VendorTool

  Agent->>Harbor: fund until authorization_succeeded
  Note over Harbor,Coinbase: authorization = FUNDING only
  Agent->>VendorTool: paid call with capability_token
  VendorTool-->>Agent: result + optional x402 signed receipt
  Agent->>Harbor: evidence via x402_delivery_receipt or x402_paid_api_ok
  Harbor->>Coinbase: capture on predicate pass

v1 archetypes

Preset IDHarbor templateMinimum evidence fieldsPredicate intent
api_response_okapi_response_v1http_status, vendor_ref_id, response_digestHTTP status equals expected value; required string fields match schema
webhook_confirmedwebhook_confirmation_v1webhook_event_id, event_type, payload_digestEvent type matches; webhook id and digest present
artifact_attestedartifact_hash_v1artifact_blake3_hex, operation, vendor_ref_idNon-empty hash array; operation matches; vendor ref present
cost_and_completioncompletion_budget_v1status, cost_centsStatus completed; cost within intent amount_cents
sandbox_permissivetrue_v1optional smoke fieldsAlways pass (explicit opt-in for sandbox)

Using presets in the console

  1. Open Configuration → Policies in the admin console.
  2. Select a template such as api_response_v1.
  3. Use the Recommended archetype picker — rail hints and anti-patterns appear for vendor packs.
  4. Use the pre-filled Parameters, Evidence, and Evidence schema in the sandbox panel (defaults match this catalog).
  5. Run Preview to see materialized DSL, then Test evaluate with sample evidence.

Add template IDs to your tenant allowed_policy_templates guardrail list before publishing in enforce mode. New tenants provisioned after the completion archetype rollout receive these template IDs in their default allow-list automatically (observe mode until you switch to enforce).

After you choose a settlement rail (stripe_connect, stripe_ach_debit, or x402_usdc_base), pick a matching vendor pack from the catalog — see the TypeScript quickstart.

Tenant defaults

Signup provisioning seeds allowed_policy_templates with every Harbor template id from this catalog so archetypes can be published without manual allowlist editing. Only tenants with no guardrail policy row receive these defaults when the gateway schema bootstrap runs (paybond-gateway-bootstrap after schema.sql) or at signup. An empty allowed_policy_templates list on an existing policy is intentional and is not overwritten — operators who want archetype templates must add them explicitly or publish a new guardrail policy version.

The sql migration 20260625_completion_archetype_guardrail_defaults is a one-time snapshot for environments that apply migrations manually; it seeds the same template list for tenants with no policy row. When the catalog gains new Harbor templates, update the migration array or rely on bootstrap/signup seeding (guarded by TestDefaultAllowedPolicyTemplateIDs_matchCatalog in Go).

Schema validation vs predicate release

When a completion preset is bound at intent create, Harbor validates canonical and optional vendor evidence against the frozen schemas pinned on the intent row. This is signal-only in v1: validation failures appear in schema_validation and Signal COMPLETION_* fraud signals, but evidence submission still succeeds and the predicate may still pass release. A passing predicate does not guarantee vendor schema conformance — alert on passed_with_drift and pack_stale in production workflows.

Catalog entry shape

Each preset in catalog.json includes:

FieldPurpose
preset_idStable archetype name for CLI and docs
harbor_template_idManaged template passed to Harbor policy APIs
parametersDefault tenant parameters for materialization
evidence_schemaJSON Schema-style object for intent evidence_schema
sample_evidencePayload that should pass policy test
sample_failing_evidencePayload that should fail (except sandbox_permissive)
human_summaryOperator-facing one-liner
spend_hintsOptional recommended gateway spend caps (documentation only in v1)
scopetool_completion or sandbox_smoke — explicit lifecycle scope
rail_hintsSettlement rails this pack is documented for (filter/docs only)
forbidden_evidence_fieldsRail-owned ids that must not appear in payee evidence
anti_patternsHuman-readable warnings surfaced in docs and console

Vendor packs add kind: "vendor_pack", archetype_preset_id, evidence_field_map, and optional vendor_evidence_schema / vendor_sample_evidence.

Example: API response OK

Parameters (from catalog):

{
  "http_status_path": ["http_status"],
  "expected_http_status": 200
}

Sample passing evidence:

{
  "http_status": 200,
  "vendor_ref_id": "ch_3NxExample",
  "response_digest": "blake3:7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069"
}

Materialized predicate (via POST /harbor/policy/v1/preview):

{
  "version": 1,
  "root": {
    "op": "and",
    "clauses": [
      { "op": "eq", "path": ["http_status"], "value": 200 },
      { "op": "schema_field", "field": "vendor_ref_id" },
      { "op": "schema_field", "field": "response_digest" }
    ]
  }
}

Example: Artifact attested

Materialized predicate for artifact_hash_v1:

{
  "version": 1,
  "root": {
    "op": "and",
    "clauses": [
      { "op": "schema_field", "field": "artifact_blake3_hex" },
      { "op": "array_nonempty", "field": "artifact_blake3_hex" },
      { "op": "completion", "path": ["operation"], "value": "attested" },
      { "op": "schema_field", "field": "vendor_ref_id" }
    ]
  }
}

An empty artifact_blake3_hex array fails at the array_nonempty clause even when operation and vendor_ref_id are present.

Anti-patterns

  • Funding webhooks in evidence — Stripe payment_intent.succeeded, Coinbase authorization_succeeded, and x402 payment-session payloads are funding signals. Harbor consumes them internally; do not submit them as tool-completion evidence.
  • x402 session ids in evidencepayment_session_id, authorization_id, and on-chain auth transaction hashes belong in settlement provider state, not payee evidence.
  • HTTP 200 alone — pair status checks with vendor_ref_id and a content digest so evidence is bound to a specific response body.
  • Raw predicate DSL in production — prefer publishing a managed template head and binding with policy_binding (signing v7).
  • Mismatched field names — align init scaffolds and evidence builders with catalog canonical names (cost_cents, not ad-hoc aliases).
  • Deprecated stripe_webhook_payment — use vendor_webhook_confirmed for vendor SaaS job/order webhooks; never Stripe funding event types.

Vendor packs and receipt import

Vendor packs

Named vendor packs are thin wrappers over archetypes. They reuse the same Harbor template and predicate materialization while exposing vendor-friendly evidence field names via evidence_field_map. rail_hints are documentation and console filter hints only — predicates stay rail-agnostic.

Vendor packArchetypePinned api_versionRail hintsField mapping
stripe_chargeapi_response_ok2024-10-28.acaciastripe_connectcharge_idvendor_ref_id
vendor_webhook_confirmedwebhook_confirmedvendor_webhook_v1webhook_event_id, neutral job.completed default
stripe_webhook_paymentwebhook_confirmedstripe_webhook_legacy_v1stripe_connectDeprecated — use vendor_webhook_confirmed
ach_paid_api_okapi_response_okach_paid_api_v1stripe_ach_debitconfirmation_numbervendor_ref_id
ach_travel_bookingcost_and_completionach_travel_booking_v1stripe_ach_debitconfirmation_number, total_cents, fare_class
ach_vendor_webhookwebhook_confirmedach_vendor_webhook_v1stripe_ach_debitvendor_event_idwebhook_event_id, booking.confirmed
x402_paid_api_okapi_response_okx402_api_v1x402_usdc_basestandard HTTP completion fields
x402_delivery_receiptartifact_attestedx402_receipt_v1x402_usdc_basereceipt_digestartifact_blake3_hex[0], resource_urlvendor_ref_id
x402_cost_and_completioncost_and_completionx402_metered_v1x402_usdc_basestandard status / cost_cents

Scaffold with paybond init completion --preset ach_paid_api_ok (or any preset id). The generated helper maps vendor fields to canonical names before evidence submit.

Evidence example (ach_travel_booking):

{
  "confirmation_number": "AA-8JZ3QK",
  "total_cents": 19750,
  "fare_class": "economy",
  "status": "completed"
}

Evidence example (x402_delivery_receipt canonical):

{
  "artifact_blake3_hex": ["<digest of signed x402 receipt>"],
  "operation": "attested",
  "vendor_ref_id": "https://api.vendor.example/job/123"
}

MCP SEP-2828 receipt import

Pair a cryptographically signed decision record (pre-side-effect) with a signed outcome record (post-execution). The CLI verifies signatures before mapping into artifact_attested evidence:

paybond policy import-mcp-receipt \
  --decision-file decision.json \
  --outcome-file outcome.json \
  --write-evidence-file evidence.json

Signature requirements (both records):

  • Each record must carry an Ed25519 signature over SHA-256 of JCS-canonical JSON with signature fields stripped.
  • Signatures live in issuerAsserted (decision) or receiptAsserted (outcome), or at the record root, as ed25519_signature_hex + signing_public_key_ed25519_hex.
  • Pairing checks: backLink.attestationDigest must match on both records; outcomeDerived.decisionDigest must equal the signed decision record digest.
  • Unsigned or tampered records are rejected — bare field mapping without verification is not supported.

Mapped evidence fields:

  • artifact_blake3_hex from outcomeDerived.decisionDigest and resultCommitment
  • operation to attested when outcomeDerived.status is executed
  • vendor_ref_id from backLink.attestationDigest

Minimal signed decision shape (outcome mirrors with receiptAsserted and outcomeDerived):

{
  "backLink": {
    "attestationDigest": "sha256:deadbeef",
    "attestationNonce": "nonce-1"
  },
  "decisionDerived": { "decision": "allow" },
  "issuerAsserted": {
    "iss": "did:example:mcp-server",
    "signing_public_key_ed25519_hex": "<32-byte hex>",
    "ed25519_signature_hex": "<64-byte hex>"
  }
}

x402 Signed Receipt import

Import a signed x402 offer-receipt artifact (tool delivery proof, not funding). The CLI verifies the signature before mapping:

paybond policy import-x402-receipt \
  --receipt-file receipt.json \
  --write-evidence-file evidence.json

Signature requirements:

  • Input must include format and signature on a signed offer-receipt envelope — typically under extensions.offer-receipt.info.receipt, or at the top level as { "format", "payload", "signature" }.
  • JWS (format: "jws"): compact serialization (header.payload.signature) with Ed25519 (EdDSA) or ES256; header must embed the verifying jwk.
  • EIP-712 (format: "eip712"): typed-data digest over the receipt payload fields with a secp256k1 signature (0x-prefixed 65-byte hex).
  • Raw unsigned receipt JSON is rejected.

Example JWS envelope (payload fields vary by vendor):

{
  "extensions": {
    "offer-receipt": {
      "info": {
        "receipt": {
          "format": "jws",
          "signature": "<header>.<payload>.<sig>"
        }
      }
    }
  }
}

Do not import Coinbase authorization_succeeded webhooks as evidence — those are funding, not completion.

Doctor alignment checks

paybond doctor warns (non-blocking) when:

  • Local completion scaffold evidence_schema diverges from the catalog preset
  • Published tenant policy head parameters diverge from catalog defaults
  • Scaffold properties intersect preset forbidden_evidence_fields
  • webhook_confirmed parameters use Stripe funding event types (payment_intent.succeeded, charge.succeeded)
  • Scaffold uses deprecated stripe_webhook_payment
  • Vendor pack scaffold contract pins (VENDOR_CONTRACT_API_VERSION, schema digests) lag the catalog (completion_pack_stale)
  • Vendor pack scaffold is missing VENDOR_QUALITY_FIELDS exports (completion_quality_fields)

Contract pinning and drift

Vendor packs declare a frozen vendor_contract block in the catalog (api_version, schema digests, quality_fields). Harbor snapshots those fields on intent create and validates optional vendor_payload at evidence submit (signal-only — evidence is still accepted; drift surfaces in schema_validation and Signal).

WorkflowCommand / surface
Pre-validate locallypaybond policy validate-evidence --preset <id> --vendor-file vendor.json
Sandbox submitScaffolds pass vendorPayload alongside canonical payload via submitSandboxEvidence
Operator triagePolicy registry shows pinned vendor_contract; Signal emits COMPLETION_* drift codes
Integrator hygienepaybond doctor warns when scaffold pins lag catalog

paybond policy validate-evidence mirrors Harbor schema checks locally and additionally enforces preset forbidden_evidence_fields (rail-owned ids that must not appear in payee evidence). The JSON report includes:

FieldMeaning
vendor_schema_ok / canonical_schema_okJSON Schema conformance against frozen or live catalog schemas
quality_fields_missingVendor-pack quality fields absent from the payload
forbidden_fields_presentRail-owned field names found in vendor or canonical evidence
pack_staleFrozen contract pins lag the live catalog
drift_kindsMachine-readable drift codes, including forbidden_field_present

When forbidden_fields_present is non-empty, vendor_schema_ok and/or canonical_schema_ok are set to false and drift_kinds includes forbidden_field_present. Harbor submit still accepts evidence in v1 (signal-only); use this command in CI before agents submit.

Re-scaffold with paybond init completion --preset <id> --force after catalog api_version bumps. In-flight intents keep their frozen contract for audit.

Predicate VM scope is unchanged — archetypes compose existing ops only; array paths and regex are deferred until a template truly needs them.