{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://zinvyl.com/marketplace/agent-purchase-lifecycle.json",
  "version": "1.2.0",
  "title": "Zinvyl Agent Purchase Lifecycle, Control Layers, and Stop Taxonomy",
  "seller_of_record": "G.B. Industry LLC d/b/a Zinvyl",
  "purpose": "One canonical map of the separate qualification, authority, purchase-intent, payment, and fulfillment controls. A stop is classified where it occurs; not every stop is a failed purchase, and not every stop is side-effect free.",
  "commercial_flow": ["discovered_or_matched", "authority_terms_scope_and_identity_validated", "routed", "payment_pending", "funded", "awaiting_inputs", "inputs_complete", "in_progress", "delivered", "accepted"],
  "canonical_public_flow": ["discovered", "funded", "delivered", "accepted"],
  "non_states": ["CONFIRMED", "PENDING_FUNDS"],
  "surface_roles": {
    "mcp_purchase_ingress": {
      "endpoint": "POST https://zinvyl.com/marketplace/agent-mcp",
      "tools": ["buy_matching_service", "buy_service"],
      "role": "The live production purchase ingress. The MCP tool result may contain an intent and payment route, or a structured stop."
    },
    "a2a_qualification": {
      "endpoints": ["POST https://zinvyl.com/marketplace/a2a", "POST https://zinvyl.com/marketplace/a2a/message:send"],
      "role": "Qualification, matching, durable task status, and the create_zinvyl_purchase_route action. When every identity, authority, scope, terms, capacity, tax, and payment-readiness gate passes, that action reuses the same governed payment-route handler to create a bounded live purchase intent, quote, and adaptive Stripe route. A2A does not mark payment; only signed Stripe reconciliation can establish funding."
    },
    "agent_machine_payment": {
      "endpoint": "POST https://zinvyl.com/marketplace/api/agent-machine-payment",
      "role": "Returns and verifies the Stripe MPP signed 402 route for an already-routed intent."
    },
    "agent_delegated_payment": {
      "endpoint": "POST https://zinvyl.com/marketplace/api/agent-delegated-payment",
      "setup_endpoint": "POST https://zinvyl.com/marketplace/api/account/delegated-payment-method/setup",
      "role": "Uses a Stripe-hosted, owner-enrolled organization payment method for an already-routed intent whose buyer credential and signed single-transaction mandate match exactly. The endpoint remains feature-gated until production setup is complete."
    },
    "stripe_webhook": {
      "endpoint": "POST https://zinvyl.com/marketplace/stripe/webhook",
      "role": "Verifies the raw Stripe event signature and reconciles the authoritative order/payment ledger."
    }
  },
  "execution_layers": {
    "cloudflare_network_edge": "Terminates and routes public traffic. No Cloudflare WAF, card-testing, or TCP-drop rule is claimed as deployed by this contract without separate account-level evidence.",
    "marketplace_worker_gateway": "Parses schemas, rejects sensitive public input, enforces application throttles, validates declared authority, buyer-agent credentials, mandates, offer limits, terms, scope, idempotency, and capacity.",
    "d1_commercial_ledgers": "Stores bounded intents, quotes, payment/order reconciliation, fulfillment, and operational telemetry. Each ledger has separate authority.",
    "stripe_payment_rail": "Hosts checkout, completes the MPP payment route, or stores and charges an owner-enrolled organization payment method. A setup, route, session, challenge, API response, or processor authorization is not Zinvyl funding until signed-webhook ledger reconciliation passes.",
    "fulfillment_runtime": "Admits work only for a verified live paid order with complete sanitized inputs and the required offer execution contract."
  },
  "ledgers": {
    "public_commercial": { "states": ["discovered", "funded", "delivered", "accepted"], "authoritative_for": "The externally published commercial lifecycle." },
    "purchase_intent": { "states": ["routed", "payment_pending", "funded"], "authoritative_for": "A bounded transaction identity, quote, capacity reservation, and payment route." },
    "payment": { "states": ["pending", "paid", "failed", "needs_reconciliation", "partially_refunded", "refunded", "disputed", "dispute_closed_review_required"], "authoritative_for": "Whether independently verified cleared payment authorizes fulfillment." },
    "fulfillment": { "states": ["awaiting_inputs", "inputs_received", "inputs_complete", "in_progress", "quality_review", "revision_requested", "delivered", "accepted", "cancelled"], "authoritative_for": "Post-funding input readiness, execution, quality review, delivery, revision, and acceptance." }
  },
  "side_effect_boundaries": {
    "zero_commercial_side_effect": "Pre-intent routing exits and authority blocks create no purchase intent, quote, checkout session, order, charge, capacity lock, or funding claim. Privacy-minimized security, traffic, funnel, or journey telemetry may still be recorded.",
    "bounded_prefunding_state": "A purchase-route block or payment exception may occur after an intent, quote, reservation, checkout session, payment attempt, or non-funded order record exists. It must never be described as zero side effect or funded.",
    "verified_postfunding_state": "Funded-input holds, delivery exceptions, refunds, and disputes occur after verified payment or after a previously paid state. They are not pre-purchase blockers."
  },
  "outcome_classes": {
    "pre_intent_routing_exit": {
      "codes": ["catalog_gap", "scope_reduction_required", "sensitive_input"],
      "purchase_attempted": false,
      "intent_created": false,
      "commercial_side_effect": "none",
      "operational_telemetry_possible": true
    },
    "authority_block": {
      "codes": ["authority_missing", "offer_not_delegated", "spend_limit_mismatch", "safe_scope_unconfirmed", "terms_unaccepted", "buyer_credential_required", "buyer_credential_invalid", "mandate_required", "mandate_signing_unavailable", "mandate_invalid", "mandate_expired", "mandate_principal_mismatch", "mandate_limit_mismatch", "mandate_scope_mismatch", "mandate_revoked_or_unknown", "mandate_already_used", "mandate_unavailable", "transaction_binding_mismatch"],
      "purchase_attempted": true,
      "intent_created": false,
      "commercial_side_effect": "none",
      "operational_telemetry_possible": true
    },
    "purchase_route_block": {
      "codes": ["capacity_exhausted", "availability_unavailable", "purchase_ledger_unavailable", "payment_route_not_configured", "dynamic_checkout_unavailable", "payment_method_enrollment_required", "delegated_card_payments_disabled", "stripe_mode_mismatch", "tax_validation_required", "mandate_total_exceeded", "invalid_purchase_schema", "idempotency_or_binding_conflict", "reservation_expired", "quote_binding_mismatch"],
      "purchase_attempted": true,
      "funded": false,
      "commercial_side_effect": "intent, quote, reservation, or checkout session may already exist depending on the failing gate"
    },
    "payment_exception": {
      "codes": ["payment_declined", "payment_failed", "authentication_required", "invalid_webhook_signature", "webhook_timestamp_outside_tolerance", "duplicate_payment_event", "payment_reference_missing", "payment_reference_mismatch", "amount_mismatch", "currency_mismatch", "offer_mismatch", "terms_mismatch", "livemode_mismatch", "needs_reconciliation"],
      "funded": false,
      "commercial_side_effect": "payment route, payment attempt, processor object, or non-funded order record may exist"
    },
    "funded_input_hold": {
      "codes": ["awaiting_inputs", "inputs_incomplete", "prohibited_sensitive_input", "input_validation_failed", "input_manifest_missing", "input_digest_mismatch"],
      "funded": true,
      "purchase_failed": false
    },
    "delivery_exception": {
      "codes": ["execution_admission_blocked", "execution_failed", "execution_timeout", "quality_gate_blocked", "revision_requested", "delivery_late", "acceptance_test_failed", "buyer_input_missing"],
      "funded": true,
      "purchase_failed": false
    },
    "post_payment_financial_exception": {
      "codes": ["partially_refunded", "refunded", "disputed", "dispute_closed_review_required"],
      "funded_or_previously_funded": true
    }
  },
  "authority": {
    "live_autonomous_purchase": "Delegated-card purchases require an authenticated buyer-agent credential with an owner-set offer allowlist, USD per-purchase ceiling, current terms and safe scope, plus an active organization payment method. A principal-signed single-transaction HMAC mandate is an optional narrower restriction for this route and remains required for autonomous routes without standing settlement consent.",
    "human_fallback": "When exact delegated authority is absent or insufficient, no autonomous intent is created; the exact human approval handoff is returned.",
    "assertion_boundary": "A caller assertion alone is not independent proof of identity or authority.",
    "http_and_tool_status_boundary": "There is no universal 401/403 authorization_required response. MCP returns a structured tool result for declared-authority and allowlist failures; credential and signed-mandate enforcement inside the payment-route handler uses 401, 403, or 409 with the exact blocker code."
  },
  "idempotency": {
    "mcp_purchase": "Use buyer.request_id in the MCP JSON body as the stable buyer-scoped idempotency key. The A2A qualification surface does not use buyer.request_id as its task identity.",
    "unchanged_retry": "Returns the same bounded intent and reservation.",
    "changed_retry": "A changed request_id is a different transaction identity, not a retry. In live autonomous mode the single-use mandate, organization capacity cap, and transaction binding prevent silent rebinding or duplicate funding; callers must recover the original intent instead.",
    "work_request_api": "The separate private work-request API uses the Idempotency-Key HTTP header."
  },
  "timing": {
    "mandate_signature": "Zinvyl buyer mandates use HMAC-SHA256, not EIP-712.",
    "mandate_clock_rule": "The Worker rejects an invalid issued_at, an issued_at more than 300 seconds in the future, or an expired expires_at. Zinvyl server time is authoritative.",
    "payment_settlement": "A payment remains pending until a valid Stripe event reconciles the ledger. No fixed 1–3 second webhook delivery time is promised."
  },
  "data_boundary": {
    "accepted": ["Buying organization", "Authorized business contact", "One sanitized bounded business outcome", "Offer, budget, turnaround, and broad industry when voluntarily supplied"],
    "prohibited_public_input": ["Passwords", "API keys", "Tokens", "Private keys", "Raw payment-card or banking data", "Production credentials", "Unredacted sensitive or regulated personal data", "Raw confidential files", "Trade-secret substance"],
    "rejection_behavior": "The application rejects secret-like or prohibited public input with a structured error. A funded order remains funded and held for safe, complete replacement inputs; the payment is not erased or relabeled failed."
  },
  "operational_friction": {
    "request_identity": "Changing buyer.request_id during a retry prevents idempotent recovery and invokes live mandate, binding, and capacity controls; it does not safely attach to the original transaction.",
    "mandate_time": "A future-dated mandate beyond the five-minute tolerance or an expired mandate is rejected. This is an HMAC timestamp check, not EIP-712 verification.",
    "webhook_delivery": "Processor delivery or retry latency can leave the order pending until a valid event reconciles; no fixed latency is guaranteed.",
    "external_buyer_readiness": "A live delegated-card purchase requires an organization-issued agent credential and an owner-enrolled organization payment method. Auto selects that delegated settlement route first and does not add a per-purchase owner click when the offer and amount stay within policy; otherwise it returns hosted checkout. Compatible clients may explicitly choose Stripe MPP. Only signed-webhook ledger reconciliation proves funding."
  },
  "verified_controls": ["Application-level request throttling", "Stable buyer-scoped MCP idempotency", "Standing buyer-agent offer allowlist and per-purchase ceiling", "Optional single-use HMAC-signed mandate narrowing", "Bounded capacity reservations", "Stripe webhook HMAC-SHA256 verification with a 300-second timestamp tolerance", "Duplicate payment-event handling", "Machine-payment replay rejection", "No-unfunded-delivery gate"],
  "not_claimed_without_separate_evidence": ["Cloudflare WAF, card-testing, TCP-drop, or account-level rate-limiting rules are not represented here as deployed controls.", "A catalog view, match, purchase intent, approval, checkout URL, processor object, 402 challenge, or browser redirect is not payment.", "An incomplete funded intake is a fulfillment hold, not proof that the purchase failed.", "A pending payment is a normal pre-funding state, not automatically a payment failure."]
}
