The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Refund Decide listing page.
Deterministic Decision API engine powering workflow applications, stable MCP notary remotes, decision memo packets, and execution gates
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.
Use Decide to evaluate an agent-proposed action against a deterministic rulebook
before the tool receives authority to change state. The caller gets a replayable
Decision Record and routes yes, no, or review while retaining control of
credentials and execution.
See the AI agent action gate guide
Binding production verdicts should use a versioned declarative rulebook:
Runtime architecture: see docs/RULEBOOK_RUNTIME_ARCHITECTURE.md.
Machine-readable schema: https://api.decide.fyi/schemas/rulebook-v1.schema.json.
Active runtime manifest: https://api.decide.fyi/manifests/rulebook-runtime-v1.json.
Downstream application binding: decide_application_binding_v1.
The production core is hybrid_declarative_rulebook_with_trusted_adapters:
direct declarative rulebooks are supported, registered first-party trusted
adapters may supply bounded facts, and customer executable rulebooks are
rejected. In both supported binding modes, Rulebook v1 remains the only binding
verdict selector.
mode: "rulebook" does not call an LLM. It validates the request rulebook
against the published JSON Schema, hashes the rulebook, evaluates bounded
conditions, and returns yes, no, or review alongside the application
verdict, action, reason code, matched rule, and evaluator_version. Responses
also include rulebook_contract with the enforced schema URL/hash,
runtime_binding with the direct or trusted-adapter binding mode, input_hash,
a SHA-256 hash of the canonical inputs or adapter facts consumed by the
declarative evaluator, plus a rulebook_attestation_v1 bundle hash over the
deterministic execution tuple.
Production deployments can sign that bundle hash with a
rulebook_attestation_signature_v1 Ed25519 envelope; verification keys are
published at /.well-known/rulebook-attestation-keys.json. Set
DECIDE_RULEBOOK_ATTESTATION_SIGNATURE_REQUIRED=true in production to fail
closed instead of returning unsigned Rulebook decisions. Publish retired public
verification keys with DECIDE_RULEBOOK_ATTESTATION_KEY_HISTORY_JSON so older
Decision Records remain verifiable after rotation.
Rulebook requests cannot preload Decide-generated Decision Record material.
Fields such as runtime_binding, trusted_adapter, adapter_facts,
rulebook_attestation, application_verdict, and action are response-only at
the request body, context.inputs, and adapter-facts boundaries; attempts return
RULEBOOK_OUTPUT_MATERIAL_FORBIDDEN.
Legacy single, multi, and runtime requests remain available for
AI-assisted exploration, but they are not binding production verdicts. Those
responses include decision_contract with authority: "advisory_only" and
production_verdict: false, plus production_binding_required: true and the
supported production binding modes; callers that need deterministic execution
must use mode: "rulebook" and capture rulebook_contract, runtime_binding,
and the Rulebook attestation material.
At the public Decision Record boundary, successful evaluations are registered as immutable tenant-scoped snapshots. Historical replay restores the original canonical input and stored rulebook snapshot rather than trusting a caller override or the current application deployment.
Rulebook v1 also supports registered first-party trusted adapters for bounded
fact normalization. Adapter requests pin an exact semantic version and manifest
hash; responses attest the bundled implementation source hash plus canonical
input/output hashes and the enforced execution contract. Each invocation runs
once in an empty-environment worker with hard time/resource limits and denied
common ambient capabilities. The declarative rulebook remains the only binding
verdict selector. See docs/TRUSTED_ADAPTERS_V1.md.
The current reference applications prove both production patterns: Solana Execution Gate, Decision Memo Readiness Gate, and Krafthaus Workflow Readiness Binding use trusted adapters before Rulebook v1, while the Refund, Trial, Cancel, and Return Policy MCP notaries supply normalized facts directly to Rulebook v1 and expose the signed rulebook result through their stable REST and MCP surfaces.
Before evaluator, adapter, or rulebook changes ship, run the local historical replay gate:
Use --candidate-rulebook, --candidate-adapter, and
--candidate-evaluator-version to compare proposed migrations against the
golden replay corpus before production routing changes.
For release gates, prefer a rulebook_migration_v1 manifest so candidate
artifacts, expected drift, and approval status are reviewed together:
The manifest schema is published at
https://api.decide.fyi/schemas/rulebook-migration-v1.schema.json, and the dry
run validates manifests against that closed schema before replay.
After production routing or runtime-contract changes ship, run the production runtime smoke:
This hits https://api.decide.fyi from outside the runtime and always verifies
the published hybrid_declarative_rulebook_with_trusted_adapters manifest,
closed Rulebook v1 schema, attestation key endpoint, and protected Decision API
edge. Supply DECIDE_RULEBOOK_RUNTIME_SMOKE_API_KEY to also exercise live
declarative evaluation, rejection behavior, and advisory-only legacy metadata.
GitHub Actions runs the public boundary checks as the scheduled/manual
Rulebook Runtime Production Smoke workflow and runs the authenticated checks
when its optional smoke credential is configured.
The legacy single, multi, and runtime modes are AI-assisted surfaces.
They are not the production determinism boundary for loosely defined business
judgment.
Architecture:
The public @decide-fyi/sdk
client covers Decision API calls, Decision Record and Decision Packet
verification, Rulebook conformance, replay, execution receipts, and outcome
reporting.
The canonical package source is sdk/, licensed under Apache-2.0.
Package release requirements and source mapping are documented in
sdk/SOURCE_PROVENANCE.md.
Buttons install the canonical four-tool Decide Policy Notaries server. Existing specialist endpoints remain supported for compatibility.
| Server | Domain | Tool | Verdicts |
|---|---|---|---|
| Policy Notaries | policy.decide.fyi | All 4 tools below | Policy-specific verdicts |
| Refund Notary | refund.decide.fyi | refund_eligibility | ALLOWED / DENIED / UNKNOWN |
| Cancel Notary | cancel.decide.fyi | cancellation_penalty | FREE_CANCEL / CANCEL_AT_PERIOD_END / PENALTY / LOCKED / UNKNOWN |
| Return Notary | return.decide.fyi | return_eligibility | RETURNABLE / EXPIRED / NON_RETURNABLE / UNKNOWN |
| Trial Notary | trial.decide.fyi | trial_terms | TRIAL_AVAILABLE / NO_TRIAL / UNKNOWN |
Stateless, no auth, 100 req/min. Coverage is policy-specific: 100 existing US individual-plan vendors, plus scoped Typeform Basic cancellation only. Results fail closed to UNKNOWN when scope or current reviewed evidence is missing. See Typeform integration.
Existing installations can keep using the specialist remotes. They expose the same tool names and response contracts as the canonical suite:
Only 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.
Start local dev server:
In a separate terminal:
The Zendesk routes are protected reference adapters. They return an advisory
classification, a policy result, and a recommended Zendesk action shape, but
they do not write to Zendesk, authorize execution, or create a binding
production Decision Record. Every response sets
workflow_contract.execution_allowed: false.
For the production architecture, including the Rulebook v1 action boundary and
Decision Record that must precede a downstream side effect, see
docs/POLICY_MCP_SUPPORT_WORKFLOW.md.
Endpoints
POST https://refund.decide.fyi/api/v1/workflows/zendesk/refundPOST https://cancel.decide.fyi/api/v1/workflows/zendesk/cancelPOST https://return.decide.fyi/api/v1/workflows/zendesk/returnPOST https://trial.decide.fyi/api/v1/workflows/zendesk/trialProduction workflow requests require a server-to-server Bearer token:
For 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.
decision_override exists only for explicit local and CI tests with both
NODE_ENV=test and WORKFLOW_TEST_MODE=1. It is rejected by deployed routes
and must never be used as an integration mechanism.
Endpoint: POST https://refund.decide.fyi/api/v1/refund/eligibility
MCP Tool: refund_eligibility
Evaluates a refund only when the versioned rule and supplied source-specific facts support automation.
Input: vendor, days_since_purchase, region, plan, and conditionally qualifying_conditions_met
Codes: WITHIN_WINDOW, OUTSIDE_WINDOW, NO_REFUNDS, MISSING_REQUIRED_CONTEXT, UNSUPPORTED_VENDOR
Endpoint: POST https://cancel.decide.fyi/api/v1/cancel/penalty
MCP Tool: cancellation_penalty
Checks cancellation penalties — early termination fees, contract locks, or free cancellation.
Input: vendor, region, plan, and conditionally billing_cadence
Codes: NO_PENALTY, EARLY_TERMINATION_FEE, CONTRACT_LOCKED, MISSING_REQUIRED_CONTEXT, UNSUPPORTED_VENDOR
Endpoint: POST https://return.decide.fyi/api/v1/return/eligibility
MCP Tool: return_eligibility
Evaluates whether a subscription purchase can be reversed when the versioned rule and supplied source-specific facts support automation.
Input: vendor, days_since_purchase, region, plan, and conditionally qualifying_conditions_met
Codes: FULL_RETURN, PRORATED_RETURN, CREDIT_RETURN, OUTSIDE_WINDOW, NO_RETURNS, MISSING_REQUIRED_CONTEXT, UNSUPPORTED_VENDOR
Endpoint: POST https://trial.decide.fyi/api/v1/trial/terms
MCP Tool: trial_terms
Evaluates availability and terms from a live offer observation. It does not publish static trial availability.
Input: vendor, region, plan, offer_confirmed; when confirmed, also observed_trial_days, observed_card_required, observed_auto_converts
Codes: AUTO_CONVERTS, NO_AUTO_CONVERT, TRIAL_NOT_AVAILABLE, MISSING_REQUIRED_CONTEXT, UNSUPPORTED_VENDOR
The versioned JSON registries are the canonical vendor catalog. A compact Markdown table is intentionally not duplicated here because policy windows, channels, and approval branches can change independently. Contract tests require each policy's rules, sources and discovery to agree. Typeform is admitted for cancellation only, not refund, return or trial.
| Family | Rules | Official-source registry | Automation classification |
|---|---|---|---|
| Refund | v1_us_individual.json | policy-sources.json | deterministic, conditional, review_only |
| Cancellation | v1_us_individual_cancel.json | cancel-policy-sources.json | deterministic, conditional, review_only |
| Return/reversal | v1_us_individual_return.json | return-policy-sources.json | deterministic, conditional, review_only |
| Trial | v1_us_individual_trial.json | trial-policy-sources.json | observed live-offer mode |
deterministic: the standard policy is categorical for the supported US individual-plan scope.conditional: automation requires an explicit caller assertion that the source-specific conditions were verified.review_only: the policy depends on approval, channel, commitment, exceptions, or source language that is not categorical enough to automate.observed: the current account or promotion must expose a live offer before trial terms can be returned.Scope: US individual plans by default. Typeform cancellation has an explicit Basic, direct, self-serve platform-subscription override.
Each policy family has versioned rules and source metadata. Cancellation has 101 vendor identifiers; the other three families have 100 each. The source tracker monitors official vendor documentation and terms of service; it does not automatically promote page text into a verdict.
Daily Policy Check workflow runs every six hours across refund, cancellation, return, and trial sources. Material signals enter a human review queue.npm run audit:policy-freshness reports reviewed-source age independently from tracker uptime. New policy evaluations also require current, request-bound evidence; missing or stale evidence routes to review.rules/ linking to official policy pages.GET /api/compliance-export returns a CSV snapshot of tracked sources, hashes, and pending candidate changes (?format=json for machine-readable output).rules_version field for staleness detection.UNKNOWN for reviewChanged:
deterministic, conditional, review_only, and live-offer modes; incomplete or approval-dependent requests fail closed.Added:
policy.decide.fyi/api/mcp server exposing all four Policy Notary tools through one connection.Changed:
Added:
GET /api/compliance-export endpoint for policy monitoring evidence export (CSV default, JSON via ?format=json).report:mcp-adoption operator report that separates remote-server discovery, probes, and completed Policy Notaries evaluations.Changed:
Changed:
server.json, MCP initialize, and /.well-known/*.Added:
Fixed:
contents:write permission and fixed shell logicAdded:
rules/policy-sources.jsonenum in inputSchema for agent discoverabilityFixed:
ERR_IMPORT_ATTRIBUTE_MISSING crash on Vercel (Node 22 import attributes)Added:
All 4 policy servers are free to use. No authentication. No API keys.
/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.
If you run decide behind the decidesite proxy with dynamic customer keys, also set:
DECIDE_PROXY_SHARED_TOKEN: shared secret required in x-decide-proxy-token header for trusted proxy calls.DECIDE_API_KEY: optional direct backend credential for trusted server-side callers.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.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.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.DECIDE_GEMINI_DAILY_CALL_CAP, DECIDE_GEMINI_MONTHLY_CALL_CAP, and DECIDE_GEMINI_LIFETIME_CALL_CAP may only lower those ceilings.DECIDE_GEMINI_TIMEOUT_MS: the single paid-mode provider deadline (defaults to and cannot exceed 8 seconds).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).Paid 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.
General /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.
For first-customer handoff and keyed production verification, see docs/FIRST_CUSTOMER_RUNBOOK.md.
Use POST /api/policy-fetch-hook as a fetch adapter for the daily checker when direct fetches are blocked.
Request body:
Auth:
Authorization: Bearer <POLICY_CHECK_BROWSER_HOOK_TOKEN> or x-hook-token: <token>Server env:
POLICY_CHECK_BROWSER_HOOK_TOKEN (required for endpoint auth)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)POLICY_FETCH_CLOUDFLARE_CACHE_TTL_SECONDS (optional; defaults to 21600 seconds to reuse renders across policy types)POLICY_FETCH_BROWSERLESS_TOKEN (optional secondary browser provider)POLICY_FETCH_BROWSERLESS_CONTENT_URL (optional override; default https://production-sfo.browserless.io/content)POLICY_FETCH_ALLOWED_HOSTS (optional comma-separated host allowlist)Checker (GitHub Actions, repo decide):
POLICY_CHECK_BROWSER_HOOK_URL = deployed endpoint URL (canonical: https://api.decide.fyi/api/policy-fetch-hook)POLICY_CHECK_BROWSER_HOOK_TOKEN = same token as runtime envPOLICY_CHECK_FETCH_LANES_DEFAULT = direct,zendesk_api,mirror,browser_hookPOLICY_CHECK_BROWSER_HOOK_MIN_INTERVAL_MS controls spacing between browser-hook requests (default 10500, suitable for Cloudflare Browser Rendering Free limits).Questions? support@decide.fyi or @decidefyi on X
Decide is the API engine. Applications prove the primitive.