{
  "markdown": "# decide.fyi Decision API\n\n> Deterministic Decision API engine powering workflow applications, stable MCP notary remotes, decision memo packets, and execution gates\n\n[![Version](https://img.shields.io/badge/version-1.3.1-blue.svg)](https://decide.fyi)\n[![MCP](https://img.shields.io/badge/MCP-compatible-green.svg)](https://modelcontextprotocol.io)\n[![Vendors](https://img.shields.io/badge/vendors-100-orange.svg)](https://decide.fyi)\n\n**Positioning:** Decide is the API engine and compatibility surface. Krafthaus workflow apps, Policy MCP Notaries, decision memo packets, and execution gates are application surfaces that reuse the same verdict, request ID, and evidence contract.\n\n## Gate agent tool calls before execution\n\nUse Decide to evaluate an agent-proposed action against a deterministic rulebook\nbefore the tool receives authority to change state. The caller gets a replayable\nDecision Record and routes `yes`, `no`, or `review` while retaining control of\ncredentials and execution.\n\n[See the AI agent action gate guide](https://www.decide.fyi/use-cases/ai-agent-action-gate?source=github_readme)\n\n## Production Determinism Boundary\n\nBinding production verdicts should use a versioned declarative rulebook:\n\nRuntime architecture: see [`docs/RULEBOOK_RUNTIME_ARCHITECTURE.md`](docs/RULEBOOK_RUNTIME_ARCHITECTURE.md).\nMachine-readable schema: [`https://api.decide.fyi/schemas/rulebook-v1.schema.json`](https://api.decide.fyi/schemas/rulebook-v1.schema.json).\nActive runtime manifest: [`https://api.decide.fyi/manifests/rulebook-runtime-v1.json`](https://api.decide.fyi/manifests/rulebook-runtime-v1.json).\nDownstream application binding: [`decide_application_binding_v1`](docs/APPLICATION_BINDING_V1.md).\n\nThe production core is `hybrid_declarative_rulebook_with_trusted_adapters`:\ndirect declarative rulebooks are supported, registered first-party trusted\nadapters may supply bounded facts, and customer executable rulebooks are\nrejected. In both supported binding modes, Rulebook v1 remains the only binding\nverdict selector.\n\n```json\n{\n  \"mode\": \"rulebook\",\n  \"rulebook\": {\n    \"schema_version\": \"rulebook_v1\",\n    \"rulebook_id\": \"pricing_exception\",\n    \"version\": \"2026-06-11\",\n    \"input_schema\": {\n      \"required\": [\"discount_percent\"],\n      \"properties\": {\n        \"discount_percent\": { \"type\": \"number\" }\n      }\n    },\n    \"rules\": [\n      {\n        \"rule_id\": \"approve_standard_discount\",\n        \"priority\": 50,\n        \"condition\": {\n          \"field\": \"discount_percent\",\n          \"operator\": \"lte\",\n          \"value\": 15\n        },\n        \"outcome\": {\n          \"decision\": \"yes\",\n          \"verdict\": \"APPROVE\",\n          \"action\": \"approve_discount\",\n          \"reason_code\": \"WITHIN_STANDARD_LIMIT\"\n        }\n      }\n    ],\n    \"default_outcome\": {\n      \"decision\": \"review\",\n      \"verdict\": \"REVIEW\",\n      \"action\": \"route_to_owner\",\n      \"reason_code\": \"NO_RULE_MATCHED\"\n    }\n  },\n  \"context\": {\n    \"inputs\": {\n      \"discount_percent\": 10\n    }\n  }\n}\n```\n\n`mode: \"rulebook\"` does not call an LLM. It validates the request rulebook\nagainst the published JSON Schema, hashes the rulebook, evaluates bounded\nconditions, and returns `yes`, `no`, or `review` alongside the application\nverdict, action, reason code, matched rule, and `evaluator_version`. Responses\nalso include `rulebook_contract` with the enforced schema URL/hash,\n`runtime_binding` with the direct or trusted-adapter binding mode, `input_hash`,\na SHA-256 hash of the canonical inputs or adapter facts consumed by the\ndeclarative evaluator, plus a `rulebook_attestation_v1` bundle hash over the\ndeterministic execution tuple.\nProduction deployments can sign that bundle hash with a\n`rulebook_attestation_signature_v1` Ed25519 envelope; verification keys are\npublished at `/.well-known/rulebook-attestation-keys.json`. Set\n`DECIDE_RULEBOOK_ATTESTATION_SIGNATURE_REQUIRED=true` in production to fail\nclosed instead of returning unsigned Rulebook decisions. Publish retired public\nverification keys with `DECIDE_RULEBOOK_ATTESTATION_KEY_HISTORY_JSON` so older\nDecision Records remain verifiable after rotation.\n\nRulebook requests cannot preload Decide-generated Decision Record material.\nFields such as `runtime_binding`, `trusted_adapter`, `adapter_facts`,\n`rulebook_attestation`, `application_verdict`, and `action` are response-only at\nthe request body, `context.inputs`, and adapter-facts boundaries; attempts return\n`RULEBOOK_OUTPUT_MATERIAL_FORBIDDEN`.\n\nLegacy `single`, `multi`, and `runtime` requests remain available for\nAI-assisted exploration, but they are not binding production verdicts. Those\nresponses include `decision_contract` with `authority: \"advisory_only\"` and\n`production_verdict: false`, plus `production_binding_required: true` and the\nsupported production binding modes; callers that need deterministic execution\nmust use `mode: \"rulebook\"` and capture `rulebook_contract`, `runtime_binding`,\nand the Rulebook attestation material.\n\nAt the public Decision Record boundary, successful evaluations are registered\nas immutable tenant-scoped snapshots. Historical replay restores the original\ncanonical input and stored rulebook snapshot rather than trusting a caller\noverride or the current application deployment.\n\nRulebook v1 also supports registered first-party trusted adapters for bounded\nfact normalization. Adapter requests pin an exact semantic version and manifest\nhash; responses attest the bundled implementation source hash plus canonical\ninput/output hashes and the enforced execution contract. Each invocation runs\nonce in an empty-environment worker with hard time/resource limits and denied\ncommon ambient capabilities. The declarative rulebook remains the only binding\nverdict selector. See [`docs/TRUSTED_ADAPTERS_V1.md`](docs/TRUSTED_ADAPTERS_V1.md).\n\nThe current reference applications prove both production patterns: Solana\nExecution Gate, Decision Memo Readiness Gate, and Krafthaus Workflow Readiness Binding\nuse trusted adapters before Rulebook v1, while the Refund, Trial, Cancel, and\nReturn Policy MCP notaries supply normalized facts directly to Rulebook v1 and\nexpose the signed rulebook result through their stable REST and MCP surfaces.\n\nBefore evaluator, adapter, or rulebook changes ship, run the local historical\nreplay gate:\n\n```bash\nnpm run rulebook:migration-dry-run -- --json\n```\n\nUse `--candidate-rulebook`, `--candidate-adapter`, and\n`--candidate-evaluator-version` to compare proposed migrations against the\ngolden replay corpus before production routing changes.\n\nFor release gates, prefer a `rulebook_migration_v1` manifest so candidate\nartifacts, expected drift, and approval status are reviewed together:\n\n```bash\nnpm run rulebook:migration-dry-run -- --migration path/to/migration.json --json\n```\n\nThe manifest schema is published at\n`https://api.decide.fyi/schemas/rulebook-migration-v1.schema.json`, and the dry\nrun validates manifests against that closed schema before replay.\n\nAfter production routing or runtime-contract changes ship, run the production\nruntime smoke:\n\n```bash\nnpm run smoke:rulebook-runtime\n```\n\nThis hits `https://api.decide.fyi` from outside the runtime and always verifies\nthe published `hybrid_declarative_rulebook_with_trusted_adapters` manifest,\nclosed Rulebook v1 schema, attestation key endpoint, and protected Decision API\nedge. Supply `DECIDE_RULEBOOK_RUNTIME_SMOKE_API_KEY` to also exercise live\ndeclarative evaluation, rejection behavior, and advisory-only legacy metadata.\nGitHub Actions runs the public boundary checks as the scheduled/manual\n**Rulebook Runtime Production Smoke** workflow and runs the authenticated checks\nwhen its optional smoke credential is configured.\n\nThe legacy `single`, `multi`, and `runtime` modes are AI-assisted surfaces.\nThey are not the production determinism boundary for loosely defined business\njudgment.\n\nArchitecture:\n\n- [Ecosystem constitution](docs/ECOSYSTEM_CONSTITUTION.md)\n- [Application binding contract](docs/APPLICATION_BINDING_V1.md)\n- [Rulebook v1 contract](docs/RULEBOOK_V1.md)\n- [Rulebook compatibility policy](docs/RULEBOOK_COMPATIBILITY_POLICY.md)\n- [Rulebook migration examples](docs/RULEBOOK_MIGRATION_EXAMPLES.md)\n- [Rulebook migration manifest](docs/RULEBOOK_MIGRATION_MANIFEST_V1.md)\n\n## JavaScript SDK and CLI\n\nThe public [`@decide-fyi/sdk`](https://www.npmjs.com/package/@decide-fyi/sdk)\nclient covers Decision API calls, Decision Record and Decision Packet\nverification, Rulebook conformance, replay, execution receipts, and outcome\nreporting.\n\n```sh\nnpm install @decide-fyi/sdk\n```\n\nThe canonical package source is [`sdk/`](sdk/), licensed under Apache-2.0.\nPackage release requirements and source mapping are documented in\n[`sdk/SOURCE_PROVENANCE.md`](sdk/SOURCE_PROVENANCE.md).\n\n## One-Click Install\n\n[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.png)](cursor://anysphere.cursor-deeplink/mcp/install?name=decide-policy-notaries&config=eyJ1cmwiOiJodHRwczovL3BvbGljeS5kZWNpZGUuZnlpL2FwaS9tY3AifQ==) [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_Server-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=decide-policy-notaries&config=%7B%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fpolicy.decide.fyi%2Fapi%2Fmcp%22%7D) [![Add to Claude](https://fastmcp.me/badges/claude_dark.svg)](#connect-via-mcp-claude-desktop--windsurf--other-clients) [![Add to ChatGPT](https://fastmcp.me/badges/chatgpt_dark.svg)](#connect-via-mcp-claude-desktop--windsurf--other-clients) [![Add to Codex](https://fastmcp.me/badges/codex_dark.svg)](#connect-via-mcp-claude-desktop--windsurf--other-clients) [![Add to Gemini](https://fastmcp.me/badges/gemini_dark.svg)](#connect-via-mcp-claude-desktop--windsurf--other-clients)\n\n> Buttons install the canonical four-tool **Decide Policy Notaries** server. Existing specialist endpoints remain supported for compatibility.\n\n## Stable MCP Remotes\n\n| Server | Domain | Tool | Verdicts |\n|--------|--------|------|----------|\n| **Policy Notaries** | [policy.decide.fyi](https://policy.decide.fyi) | All 4 tools below | Policy-specific verdicts |\n| **Refund Notary** | [refund.decide.fyi](https://refund.decide.fyi) | `refund_eligibility` | ALLOWED / DENIED / UNKNOWN |\n| **Cancel Notary** | [cancel.decide.fyi](https://cancel.decide.fyi) | `cancellation_penalty` | FREE_CANCEL / PENALTY / LOCKED / UNKNOWN |\n| **Return Notary** | [return.decide.fyi](https://return.decide.fyi) | `return_eligibility` | RETURNABLE / EXPIRED / NON_RETURNABLE / UNKNOWN |\n| **Trial Notary** | [trial.decide.fyi](https://trial.decide.fyi) | `trial_terms` | TRIAL_AVAILABLE / NO_TRIAL / UNKNOWN |\n\nAll servers: 100 vendor identifiers, US region, individual plans, stateless, no auth, 100 req/min. Results fail closed to `UNKNOWN` when the available facts cannot support an automated verdict.\n\n## Quick Start\n\n### Connect via MCP (Claude Desktop / Windsurf / other clients)\n\n```json\n{\n  \"mcpServers\": {\n    \"decide-policy-notaries\": { \"url\": \"https://policy.decide.fyi/api/mcp\" }\n  }\n}\n```\n\n#### Specialist compatibility configuration\n\nExisting installations can keep using the specialist remotes. They expose the\nsame tool names and response contracts as the canonical suite:\n\n```json\n{\n  \"mcpServers\": {\n    \"refund-decide\": { \"url\": \"https://refund.decide.fyi/api/mcp\" },\n    \"cancel-decide\": { \"url\": \"https://cancel.decide.fyi/api/mcp\" },\n    \"return-decide\": { \"url\": \"https://return.decide.fyi/api/mcp\" },\n    \"trial-decide\": { \"url\": \"https://trial.decide.fyi/api/mcp\" }\n  }\n}\n```\n\n### REST API\n\n```bash\n# Refund eligibility\ncurl -X POST https://refund.decide.fyi/api/v1/refund/eligibility \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"vendor\":\"adobe\",\"days_since_purchase\":12,\"region\":\"US\",\"plan\":\"individual\",\"qualifying_conditions_met\":true}'\n\n# Cancellation penalty\ncurl -X POST https://cancel.decide.fyi/api/v1/cancel/penalty \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"vendor\":\"adobe\",\"region\":\"US\",\"plan\":\"individual\",\"billing_cadence\":\"annual\"}'\n\n# Return eligibility\ncurl -X POST https://return.decide.fyi/api/v1/return/eligibility \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"vendor\":\"adobe\",\"days_since_purchase\":12,\"region\":\"US\",\"plan\":\"individual\",\"qualifying_conditions_met\":true}'\n\n# Trial terms\ncurl -X POST https://trial.decide.fyi/api/v1/trial/terms \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"vendor\":\"adobe\",\"region\":\"US\",\"plan\":\"individual\",\"offer_confirmed\":true,\"observed_trial_days\":7,\"observed_card_required\":true,\"observed_auto_converts\":true}'\n```\n\nOnly set evidence fields from facts you have actually verified. A time window alone is not proof that source-specific conditions are satisfied. Approval-dependent policies stay `UNKNOWN` even when a caller sets `qualifying_conditions_met`; trial results require a live offer observation.\n\n### Local Dev Checks\n\nStart local dev server:\n\n```bash\nnpx vercel dev\n```\n\nIn a separate terminal:\n\n```bash\n# Handler-level smoke checks (no running server required)\nnpm run smoke\n\n# MCP endpoint checks (requires a running server)\nnpm run mcp:check\n\n# Self-contained local MCP check; starts/stops vercel dev on localhost:3000\nnpm run mcp:check:local\n\n# End-to-end workflow fixture (example -> result)\nnpm run workflow:test\n\n# Production customer-key verification after provisioning a key\nDECIDE_SMOKE_API_KEY='<customer-key>' npm run smoke:customer-key\n```\n\n---\n\n## Protected Zendesk Reference Workflow\n\nThe Zendesk routes are protected reference adapters. They return an advisory\nclassification, a policy result, and a recommended Zendesk action shape, but\nthey do **not** write to Zendesk, authorize execution, or create a binding\nproduction Decision Record. Every response sets\n`workflow_contract.execution_allowed: false`.\n\nFor the production architecture, including the Rulebook v1 action boundary and\nDecision Record that must precede a downstream side effect, see\n[`docs/POLICY_MCP_SUPPORT_WORKFLOW.md`](docs/POLICY_MCP_SUPPORT_WORKFLOW.md).\n\n**Endpoints**\n\n- `POST https://refund.decide.fyi/api/v1/workflows/zendesk/refund`\n- `POST https://cancel.decide.fyi/api/v1/workflows/zendesk/cancel`\n- `POST https://return.decide.fyi/api/v1/workflows/zendesk/return`\n- `POST https://trial.decide.fyi/api/v1/workflows/zendesk/trial`\n\n### Request\n\n```json\n{\n  \"ticket_id\": \"ZD-9001\",\n  \"workflow_type\": \"refund\",\n  \"question\": \"Should this Adobe annual plan refund request proceed under policy?\",\n  \"vendor\": \"adobe\",\n  \"region\": \"US\",\n  \"plan\": \"individual\",\n  \"days_since_purchase\": 5,\n  \"qualifying_conditions_met\": true\n}\n```\n\nProduction workflow requests require a server-to-server Bearer token:\n\n```bash\ncurl -sS -X POST https://refund.decide.fyi/api/v1/workflows/zendesk/refund \\\n  -H \"Authorization: Bearer $WORKFLOW_API_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d @workflow-request.json\n```\n\nFor `refund` and `return`, include `days_since_purchase` and source-specific condition evidence when requested. Cancellation may require `billing_cadence`. Trial automation requires `offer_confirmed` plus the observed duration, card requirement, and auto-conversion status. The workflow escalates instead of approving when required context is absent.\n\n### Test-only fixture mode\n\n`decision_override` exists only for explicit local and CI tests with both\n`NODE_ENV=test` and `WORKFLOW_TEST_MODE=1`. It is rejected by deployed routes\nand must never be used as an integration mechanism.\n\n```json\n{\n  \"decision_override\": \"yes\"\n}\n```\n\n### Response (example)\n\n```json\n{\n  \"ok\": true,\n  \"flow\": \"zendesk_refund_v1\",\n  \"ticket_id\": \"ZD-9001\",\n  \"decision\": { \"c\": \"yes\", \"request_id\": \"req_123\" },\n  \"policy\": { \"verdict\": \"ALLOWED\", \"code\": \"WITHIN_WINDOW\" },\n  \"workflow_contract\": { \"production_verdict\": false, \"execution_allowed\": false },\n  \"action\": {\n    \"type\": \"approve_refund\",\n    \"execution_allowed\": false,\n    \"zendesk_tags\": [\"decide\", \"decide_yes\", \"refund_allowed\"]\n  }\n}\n```\n\n---\n\n## Refund Notary\n\n**Endpoint:** `POST https://refund.decide.fyi/api/v1/refund/eligibility`\n**MCP Tool:** `refund_eligibility`\n\nEvaluates a refund only when the versioned rule and supplied source-specific facts support automation.\n\n**Input:** `vendor`, `days_since_purchase`, `region`, `plan`, and conditionally `qualifying_conditions_met`\n\n```json\n{\"refundable\":true,\"verdict\":\"ALLOWED\",\"code\":\"WITHIN_WINDOW\",\"message\":\"Refund is allowed. Purchase is 12 day(s) old, within 14 day window.\",\"vendor\":\"adobe\",\"window_days\":14,\"qualifying_conditions_met\":true,\"automation_safe\":true}\n```\n\n**Codes:** `WITHIN_WINDOW`, `OUTSIDE_WINDOW`, `NO_REFUNDS`, `MISSING_REQUIRED_CONTEXT`, `UNSUPPORTED_VENDOR`\n\n## Cancel Notary\n\n**Endpoint:** `POST https://cancel.decide.fyi/api/v1/cancel/penalty`\n**MCP Tool:** `cancellation_penalty`\n\nChecks cancellation penalties — early termination fees, contract locks, or free cancellation.\n\n**Input:** `vendor`, `region`, `plan`, and conditionally `billing_cadence`\n\n```json\n{\"verdict\":\"PENALTY\",\"code\":\"EARLY_TERMINATION_FEE\",\"message\":\"adobe charges an early termination fee: 50% of remaining months on annual plan.\",\"vendor\":\"adobe\",\"policy\":\"etf\",\"billing_cadence\":\"annual\",\"automation_safe\":true}\n```\n\n**Codes:** `NO_PENALTY`, `EARLY_TERMINATION_FEE`, `CONTRACT_LOCKED`, `MISSING_REQUIRED_CONTEXT`, `UNSUPPORTED_VENDOR`\n\n## Return Notary\n\n**Endpoint:** `POST https://return.decide.fyi/api/v1/return/eligibility`\n**MCP Tool:** `return_eligibility`\n\nEvaluates whether a subscription purchase can be reversed when the versioned rule and supplied source-specific facts support automation.\n\n**Input:** `vendor`, `days_since_purchase`, `region`, `plan`, and conditionally `qualifying_conditions_met`\n\n```json\n{\"returnable\":true,\"verdict\":\"RETURNABLE\",\"code\":\"FULL_RETURN\",\"message\":\"Return is available. Purchase is 5 day(s) old, within 14-day window.\",\"vendor\":\"adobe\",\"return_type\":\"full_refund\",\"method\":\"self_service\",\"qualifying_conditions_met\":true,\"automation_safe\":true}\n```\n\n**Codes:** `FULL_RETURN`, `PRORATED_RETURN`, `CREDIT_RETURN`, `OUTSIDE_WINDOW`, `NO_RETURNS`, `MISSING_REQUIRED_CONTEXT`, `UNSUPPORTED_VENDOR`\n\n## Trial Notary\n\n**Endpoint:** `POST https://trial.decide.fyi/api/v1/trial/terms`\n**MCP Tool:** `trial_terms`\n\nEvaluates availability and terms from a live offer observation. It does not publish static trial availability.\n\n**Input:** `vendor`, `region`, `plan`, `offer_confirmed`; when confirmed, also `observed_trial_days`, `observed_card_required`, `observed_auto_converts`\n\n```json\n{\"verdict\":\"TRIAL_AVAILABLE\",\"code\":\"AUTO_CONVERTS\",\"message\":\"A live 7-day adobe trial offer was confirmed. Credit card required. Auto-converts to paid plan.\",\"vendor\":\"adobe\",\"trial_days\":7,\"card_required\":true,\"auto_converts\":true,\"offer_confirmed\":true,\"automation_safe\":true}\n```\n\n**Codes:** `AUTO_CONVERTS`, `NO_AUTO_CONVERT`, `TRIAL_NOT_AVAILABLE`, `MISSING_REQUIRED_CONTEXT`, `UNSUPPORTED_VENDOR`\n\n---\n\n## Supported Vendor Registry (100)\n\nThe versioned JSON registries are the canonical vendor catalog. A compact Markdown\ntable is intentionally not duplicated here because policy windows, channels, and\napproval branches can change independently. Contract tests require the same 100\nidentifiers in every rule and source registry.\n\n| Family | Rules | Official-source registry | Automation classification |\n|--------|-------|--------------------------|---------------------------|\n| Refund | [`v1_us_individual.json`](rules/v1_us_individual.json) | [`policy-sources.json`](rules/policy-sources.json) | `deterministic`, `conditional`, `review_only` |\n| Cancellation | [`v1_us_individual_cancel.json`](rules/v1_us_individual_cancel.json) | [`cancel-policy-sources.json`](rules/cancel-policy-sources.json) | `deterministic`, `conditional`, `review_only` |\n| Return/reversal | [`v1_us_individual_return.json`](rules/v1_us_individual_return.json) | [`return-policy-sources.json`](rules/return-policy-sources.json) | `deterministic`, `conditional`, `review_only` |\n| Trial | [`v1_us_individual_trial.json`](rules/v1_us_individual_trial.json) | [`trial-policy-sources.json`](rules/trial-policy-sources.json) | `observed` live-offer mode |\n\n- `deterministic`: the standard policy is categorical for the supported US individual-plan scope.\n- `conditional`: automation requires an explicit caller assertion that the source-specific conditions were verified.\n- `review_only`: the policy depends on approval, channel, commitment, exceptions, or source language that is not categorical enough to automate.\n- `observed`: the current account or promotion must expose a live offer before trial terms can be returned.\n\n**Scope:** US region, individual plans only.\n\n## Data Freshness\n\nEach policy family has versioned rules and source metadata for 100 vendor identifiers.\nThe source tracker monitors official vendor documentation and terms of service;\nit does not automatically promote page text into a verdict.\n\n- **Six-hour source checks** — The `Daily Policy Check` workflow runs every six hours across refund, cancellation, return, and trial sources. Material signals enter a human review queue.\n- **Human-verification freshness** — `npm run audit:policy-freshness` reports the age of the last reviewed source set independently from tracker uptime.\n- **Policy source URLs tracked** — Each policy family has its own sources file in `rules/` linking to official policy pages.\n- **Compliance export** — `GET /api/compliance-export` returns a CSV snapshot of tracked sources, hashes, and pending candidate changes (`?format=json` for machine-readable output).\n- **Versioned rules** — Each rules file includes a `rules_version` field for staleness detection.\n\n## Architecture\n\n- **Stateless verdict runtime** — Policy calls do not create sessions or mutate policy rules\n- **Deterministic** — Same input always produces same output\n- **Versioned Rules** — Rules files include version for tracking changes\n- **Scheduled Monitoring** — GitHub Action checks all vendor policy pages every six hours\n- **Serverless** — Runs on Vercel serverless functions\n- **Zero Dependencies** — Core compute logic has no external dependencies\n- **Hostname Routing** — Vercel middleware routes subdomains to correct MCP endpoints\n\n## Limitations\n\n- **US Only** — Currently only supports US region\n- **Individual Plans Only** — Business/enterprise plans not yet supported\n- **Calendar Days** — Windows are based on calendar days, not business days\n- **Fail-closed branches** — Approval-dependent, channel-dependent, ambiguous, or incomplete cases return `UNKNOWN` for review\n- **Live trial evidence** — Trial availability and terms must be observed for the account or promotion being evaluated\n\n## Changelog\n\n### v1.3.1 (2026-07-16)\n\n**Changed:**\n- Policy Notaries now use explicit `deterministic`, `conditional`, `review_only`, and live-offer modes; incomplete or approval-dependent requests fail closed.\n- Monitoring timestamps no longer mutate policy lineage hashes, and golden replay generation rejects incomplete decisions.\n- Canonical MCP metadata now describes the fail-closed contract and observed trial evidence fields.\n\n### v1.3.0 (2026-07-15)\n\n**Added:**\n- Canonical `policy.decide.fyi/api/mcp` server exposing all four Policy Notary tools through one connection.\n- Generated Official Registry metadata and Smithery server-card metadata sourced from the live tool definitions.\n\n**Changed:**\n- One-click install links now install the four-tool Policy Notaries server.\n- Specialist Refund, Cancel, Return, and Trial MCP URLs remain stable compatibility surfaces.\n\n### Unreleased\n\n**Added:**\n- `GET /api/compliance-export` endpoint for policy monitoring evidence export (CSV default, JSON via `?format=json`).\n- Smoke test coverage for compliance export JSON and CSV paths.\n- Private `report:mcp-adoption` operator report that separates remote-server discovery, probes, and completed Policy Notaries evaluations.\n- Token-gated Console adoption snapshot with declared MCP client attribution, conservative follow-on inference, and aggregate-only output.\n- Service-only Policy Notaries guide funnel that keeps connection intent, public REST proof, MCP evaluation, and Krafthaus workflow handoff metrics distinct.\n\n**Changed:**\n- Landing pages now position Decide as the Decision API engine and frame Policy MCP Notaries as one reference application.\n- Zendesk reference routes require server-to-server authentication in production, fail closed when unconfigured, and mark all returned action shapes as non-executing.\n\n### v1.2.1 (2026-02-08)\n\n**Changed:**\n- Subdomain homepage now shows the relevant notary card (refund/cancel/return/trial).\n- Version metadata is consistent across `server.json`, MCP `initialize`, and `/.well-known/*`.\n\n### v1.2.0 (2026-02-02)\n\n**Added:**\n- Cancel Notary MCP (cancel.decide.fyi) — cancellation penalty checker\n- Return Notary MCP (return.decide.fyi) — return eligibility checker\n- Trial Notary MCP (trial.decide.fyi) — free trial terms checker\n- Hostname-based middleware routing for all subdomains\n- Policy source files and daily checking for cancel, return, and trial policies\n- Systems/Agents mode framing on landing page\n- MCP catalog with cards for all 4 servers\n\n**Fixed:**\n- Daily policy checker: added `contents:write` permission and fixed shell logic\n- Removed dead Cloudflare email-decode scripts causing 404s\n\n### v1.1.0 (2026-02-01)\n\n**Added:**\n- Expanded from 64 to 100 supported vendors\n- Daily policy-check GitHub Action (cron at 08:00 UTC)\n- Policy source URLs tracked in `rules/policy-sources.json`\n- MCP vendor `enum` in inputSchema for agent discoverability\n\n**Fixed:**\n- `ERR_IMPORT_ATTRIBUTE_MISSING` crash on Vercel (Node 22 import attributes)\n\n### v1.0.0 (2026-01-15)\n\n**Added:**\n- Initial release with REST API and MCP server\n- Support for 9 vendors\n\n## Public Policy APIs And Protected Decision API\n\nAll 4 policy servers are free to use. No authentication. No API keys.\n\n`/api/decide` requires a trusted proxy or API credential in production. Local and preview deployments can opt into the same boundary with `DECIDE_API_AUTH_REQUIRED=1`; configuring `DECIDE_API_KEY` or `DECIDE_PROXY_SHARED_TOKEN` also enables it.\n\nIf you run `decide` behind the `decidesite` proxy with dynamic customer keys, also set:\n\n- `DECIDE_PROXY_SHARED_TOKEN`: shared secret required in `x-decide-proxy-token` header for trusted proxy calls.\n- `DECIDE_API_KEY`: optional direct backend credential for trusted server-side callers.\n- `DECIDE_GEMINI_MODE`: defaults to `disabled`. In this hard-zero state, legacy advisory `single`, `multi`, and `runtime` requests return `DECIDE_AI_DISABLED_ZERO_COST` without reading an API key or making a provider request. Rulebook v1 remains available and never uses Gemini.\n- `DECIDE_GEMINI_MODE=paid`: explicit nonzero-cost opt-in for advisory modes. This mode also requires a restricted server-side `GEMINI_API_KEY`. `DECIDE_GEMINI_MODEL` may only be `gemini-3.1-flash-lite`; changing models requires a reviewed code release rather than an environment-only switch.\n- `DECIDE_GEMINI_BUDGET_KV_REST_API_URL` and `DECIDE_GEMINI_BUDGET_KV_REST_API_TOKEN`: dedicated Redis-compatible REST store for the atomic provider-attempt guard. Paid advisory fails closed before Gemini if this store is absent or unavailable. The legacy `DECIDE_KV_REST_API_*`/`KV_REST_API_*` names are compatibility fallbacks; dedicated credentials are preferred.\n- Compiled provider-attempt ceilings are 10/day, 100/month, 500 lifetime, and one concurrent request. `DECIDE_GEMINI_DAILY_CALL_CAP`, `DECIDE_GEMINI_MONTHLY_CALL_CAP`, and `DECIDE_GEMINI_LIFETIME_CALL_CAP` may only lower those ceilings.\n- `DECIDE_GEMINI_TIMEOUT_MS`: the single paid-mode provider deadline (defaults to and cannot exceed 8 seconds).\n- `DECIDE_GEMINI_MAX_PROMPT_CHARS`: the pre-fetch advisory prompt cap (defaults to and cannot exceed 4,096 characters; it may be lowered to 256).\n\nPaid mode makes exactly one provider attempt and never falls back to another model. Gemini 3.1 Flash-Lite uses the provider's one-candidate default, lowest supported `minimal` thinking level, and default temperature; output is capped at 8 tokens for `single`, 128 for `multi`, and 512 for `runtime`. Keep the Gemini Google Cloud project unlinked from billing for a provider-side zero-dollar boundary; the application counters limit calls but do not prove a currency amount.\n\nGeneral `/api/decide` rate limit: 20 requests/minute per IP per serverless instance. This is an abuse control, not the Gemini cost boundary; the durable provider-attempt guard applies even when a trusted proxy bypasses the general limiter.\n\nFor first-customer handoff and keyed production verification, see [`docs/FIRST_CUSTOMER_RUNBOOK.md`](docs/FIRST_CUSTOMER_RUNBOOK.md).\n\n### Policy Fetch Hook (for policy checker browser-hook lane)\n\nUse `POST /api/policy-fetch-hook` as a fetch adapter for the daily checker when direct fetches are blocked.\n\nRequest body:\n\n```json\n{\n  \"url\": \"https://example.com/policy\",\n  \"vendor\": \"example_vendor\",\n  \"policy_type\": \"refund\",\n  \"timeout_ms\": 18000\n}\n```\n\nAuth:\n- `Authorization: Bearer <POLICY_CHECK_BROWSER_HOOK_TOKEN>` or `x-hook-token: <token>`\n\nServer env:\n- `POLICY_CHECK_BROWSER_HOOK_TOKEN` (required for endpoint auth)\n- `POLICY_FETCH_CLOUDFLARE_ACCOUNT_ID` and `POLICY_FETCH_CLOUDFLARE_API_TOKEN` (optional; enables Cloudflare Browser Run first, using a token limited to Browser Rendering Write)\n- `POLICY_FETCH_CLOUDFLARE_CACHE_TTL_SECONDS` (optional; defaults to 21600 seconds to reuse renders across policy types)\n- `POLICY_FETCH_BROWSERLESS_TOKEN` (optional secondary browser provider)\n- `POLICY_FETCH_BROWSERLESS_CONTENT_URL` (optional override; default `https://production-sfo.browserless.io/content`)\n- `POLICY_FETCH_ALLOWED_HOSTS` (optional comma-separated host allowlist)\n\nChecker (GitHub Actions, repo `decide`):\n- Secret `POLICY_CHECK_BROWSER_HOOK_URL` = deployed endpoint URL (canonical: `https://api.decide.fyi/api/policy-fetch-hook`)\n- Secret `POLICY_CHECK_BROWSER_HOOK_TOKEN` = same token as runtime env\n- Variable `POLICY_CHECK_FETCH_LANES_DEFAULT` = `direct,zendesk_api,mirror,browser_hook`\n- Optional variable `POLICY_CHECK_BROWSER_HOOK_MIN_INTERVAL_MS` controls spacing between browser-hook requests (default `10500`, suitable for Cloudflare Browser Rendering Free limits).\n\nQuestions? [support@decide.fyi](mailto:support@decide.fyi) or [@decidefyi on X](https://x.com/decidefyi)\n\n## Links\n\n- **Website:** [https://decide.fyi](https://decide.fyi)\n- **Policy alerts:** [https://www.decide.fyi/resources/policy-alerts](https://www.decide.fyi/resources/policy-alerts)\n- **Refund:** [https://refund.decide.fyi](https://refund.decide.fyi)\n- **Cancel:** [https://cancel.decide.fyi](https://cancel.decide.fyi)\n- **Return:** [https://return.decide.fyi](https://return.decide.fyi)\n- **Trial:** [https://trial.decide.fyi](https://trial.decide.fyi)\n- **X/Twitter:** [@decidefyi](https://x.com/decidefyi)\n- **MCP Spec:** [https://modelcontextprotocol.io](https://modelcontextprotocol.io)\n\n---\n\nDecide is the API engine. Applications prove the primitive.\n",
  "bytes": 31063,
  "sha": "6e7110f179506c61926fff214272f6efc458a93f1d4cb8c43c49f179e5239de3",
  "repo_slug": "ndkasndakn/decade",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_ndkasndakn_refund_decide_282babf1/readme"
}