{
  "format": "agentaction-recipe-starter/v1",
  "agentName": "Resolve an eligible refund",
  "recipe": {
    "schemaVersion": 1,
    "version": "1.0.0",
    "publisher": {
      "name": "AgentAction",
      "url": "https://github.com/dinpd/AgentAction",
      "kind": "maintainer"
    },
    "evidence": {
      "level": "fixture",
      "description": "Deterministic checks against supplied synthetic observations. No live model or connected service was tested by these checks."
    },
    "id": "support-refund",
    "title": "Resolve an eligible refund",
    "category": "Customer support",
    "summary": "Verify the request, refund within your limits, and close the ticket only when the refund settles.",
    "mode": "Supervised actions",
    "intent": "Resolve an eligible refund request exactly once, with the payment outcome reflected in the support ticket.",
    "servers": [
      {
        "name": "Support",
        "purpose": "Read the request and record the outcome.",
        "tools": [
          "get_ticket",
          "update_ticket"
        ]
      },
      {
        "name": "Payments",
        "purpose": "Verify ownership, eligibility and balance; issue and reconcile refunds.",
        "tools": [
          "get_payment",
          "create_refund",
          "lookup_refund_by_key",
          "get_refund_status"
        ]
      }
    ],
    "boundaries": [
      "Start with synthetic tickets and payments.",
      "Automatically refund at most $500; require manager approval above $500 through $2,000; escalate larger requests.",
      "Verify ownership, eligibility, currency and remaining balance. Amounts sent to payment tools are integer cents.",
      "Use an action-bound approval mechanism in your runtime before enabling real refunds. Instructions alone do not enforce approval.",
      "Use a stable idempotency key and reconcile uncertain results before retrying."
    ],
    "instructions": [
      "Read the ticket and original payment. Ask for missing information. Verify the requester owns the payment and the request is eligible.",
      "Use the configured thresholds and runtime approval mechanism. Stop if required approval cannot be verified. Never exceed the remaining balance.",
      "Look up a stable key derived from the ticket, payment and requested amount. Reuse the original result on retry.",
      "Create at most one refund. If the response is lost, reconcile by the same key. A pending response is not settled.",
      "Verify the provider status and update the ticket with the actual outcome. Retry a failed ticket update without issuing another refund.",
      "Report amounts in dollars with two decimal places; retain integer cents only in tool arguments. Claim completion only after payment and ticket evidence agree."
    ],
    "outcomes": [
      {
        "id": "settled",
        "label": "The provider confirms the refund settled",
        "field": "refund_status",
        "equals": "succeeded"
      },
      {
        "id": "ticket",
        "label": "The ticket records the settled outcome",
        "field": "ticket_status",
        "equals": "resolved"
      },
      {
        "id": "once",
        "label": "Exactly one refund exists for this request",
        "field": "refund_count",
        "equals": 1
      }
    ],
    "fixtures": [
      {
        "id": "settled",
        "title": "Settled refund and updated ticket",
        "observation": {
          "refund_status": "succeeded",
          "ticket_status": "resolved",
          "refund_count": 1
        },
        "expected": "met"
      },
      {
        "id": "pending",
        "title": "Payment still pending",
        "observation": {
          "refund_status": "pending",
          "ticket_status": "pending_refund",
          "refund_count": 1
        },
        "expected": "not_met"
      },
      {
        "id": "ticket-failure",
        "title": "Refund settled but ticket update failed",
        "observation": {
          "refund_status": "succeeded",
          "ticket_status": "open",
          "refund_count": 1
        },
        "expected": "not_met"
      },
      {
        "id": "duplicate",
        "title": "Duplicate refund detected",
        "observation": {
          "refund_status": "succeeded",
          "ticket_status": "resolved",
          "refund_count": 2
        },
        "expected": "not_met"
      },
      {
        "id": "missing",
        "title": "Provider evidence missing",
        "observation": {
          "ticket_status": "resolved",
          "refund_count": 1
        },
        "expected": "indeterminate"
      }
    ]
  },
  "connections": [
    {
      "name": "Support",
      "endpoint": "",
      "requiredTools": [
        "get_ticket",
        "update_ticket"
      ]
    },
    {
      "name": "Payments",
      "endpoint": "",
      "requiredTools": [
        "get_payment",
        "create_refund",
        "lookup_refund_by_key",
        "get_refund_status"
      ]
    }
  ],
  "setup": [
    "Configure each MCP server in your agent runtime; keep credentials out of this file.",
    "Load the recipe instructions and review boundaries with your team.",
    "Run sandbox cases with your agent and collect actual tool outcomes before enabling real actions.",
    "Connect your runtime to AgentAction, then configure Evals and inspect Jobs. Fixture checks do not install runtime controls."
  ]
}