> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aethis.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction

> Compile source documents into deterministic eligibility rules. Decide in under 1ms, explain why, and guide users through the shortest path to a determination — no LLM at decision time.

Aethis turns legislation, policy, and contract clauses into formal constraint logic. At decision time there is no language model: every call is a deterministic, sub-millisecond evaluation against pre-compiled rules, with a cryptographic input hash and a clause-level audit trail on every response.

This page is built around three real, public rulesets you can hit right now without an API key.

<Note>
  Successful decision responses identify the serving build in `engine_version`.
  Read that field from your response rather than relying on a version copied into a tutorial.
  [What the deployed engine serves](/reference/deployed-contract).
</Note>

## Two tiers, and which one you are in

| | **Evaluate** | **Author and publish** |
| - | - | - |
| Access | Open. No signup, no Aethis key, no model-provider key. | **Invite-only private beta.** [Request access](https://aethis.ai/developer-access). |
| What you do | Decide against published public rulesets, read their schema, explain them, graph them, browse the catalogue. | Compile your own source documents into rules and publish them. |
| Start here | [**Your first decision**](/getting-started/first-decision) — one command, no install | [Author your first ruleset](/getting-started/author-first-ruleset) |

Everything below the "Author your own rules" heading on this page belongs to
the second tier. Full breakdown, including what a `401` or `403` is telling
you: [Capabilities and access](/reference/capabilities).

<Note>
  One wrinkle inside the open tier: decisions on a leaf **ruleset** (e.g.
  `aethis/uk-fsm/child-eligibility`) and the schema/list endpoints need no key,
  but decisions on a composed **rulebook** (e.g. `aethis/uk-fsm`, binding
  `A AND (B OR C)`) always require an `x-api-key` header. See
  [Nomenclature](/concepts/nomenclature#ruleset_id-vs-rulebook_id-on-decide).
</Note>

***

## 1. Decide — paste this curl

```bash theme={null}
curl -sS -X POST https://api.aethis.ai/api/v1/public/decide \
  -H "Content-Type: application/json" \
  -d '{
    "ruleset_id": "aethis/uk-fsm/child-eligibility",
    "field_values": {
      "child.age": 10,
      "child.school_type": "state_funded"
    }
  }'
```

Response:

```json theme={null}
{
  "decision": "eligible",
  "ruleset_id": "uk-fsm-child-eligibility:20260728-4be3c335",
  "slug": "aethis/uk-fsm/child-eligibility",
  "ruleset_version": "v4",
  "content_digest": "sha256:453502fd9dec1c84c7de6eb63f7133e5587809f608bff0b1ad4b1d1e35ec580f",
  "fields_evaluated": 2,
  "fields_provided": 2,
  "field_errors": null,
  "decision_id": "dec_546TGYZY5WmePQZd",
  "inputs_hash": "sha256:75c958f1a3d72335ccf67c7d5e32f58b57966e0873786843c353b09f787c5ec2",
  "decision_time": "2026-09-03T11:50:03.766344Z"
}
```

A production call against the UK Free School Meals child-eligibility section. `inputs_hash` is the canonical fingerprint of the input — same inputs, same hash, same decision, every time. `content_digest` fingerprints the *rules*, so a decision is replayable against exactly the published content that produced it.

<Note>
  That is the real response `api.aethis.ai` returned for this call on
  2026-09-03. `decision_id` and `decision_time` are per-invocation, so yours
  will differ; `ruleset_version` and `content_digest` move whenever the ruleset
  is republished. Every key shown is served today.
</Note>

<Note>
  **Public preview.** The decision API runs always-warm in europe-west1. The engine evaluates each decision in under 1ms; observed end-to-end round-trip from Europe is \~100–150ms hot, dominated by network and request handling. Multi-region warm pools and a published latency SLA ship with general availability.
</Note>

### Discover what's available

Don't know which rulesets exist? Enumerate them — every currently-live ruleset comes back with its slug, description, and rule count:

```bash theme={null}
curl https://api.aethis.ai/api/v1/public/rulesets
```

Then drill into any one of them with `/schema` to see its input contract before calling `/decide`:

```bash theme={null}
curl https://api.aethis.ai/api/v1/public/rulesets/aethis/uk-fsm/child-eligibility/schema
```

```json theme={null}
{
  "slug": "aethis/uk-fsm/child-eligibility",
  "fields": [
    {
      "field_id": "child.age",
      "field_type": "int",
      "description": "Child's age in whole years at the start of the relevant academic year (1 September)."
    },
    {
      "field_id": "child.school_type",
      "field_type": "enum",
      "enum_values": ["state_funded", "independent", "home_educated"]
    }
  ]
}
```

Every public ruleset exposes its full input contract this way — list, then schema, then decide.

***

## 2. Explain — show your working

Add `"include_trace": true` and the response carries the full reasoning chain. Try the spacecraft demo ruleset with a single field — `species: "Vogon"`:

```bash theme={null}
curl -sS -X POST https://api.aethis.ai/api/v1/public/decide \
  -H "Content-Type: application/json" \
  -d '{
    "ruleset_id": "aethis/spacecraft-crew-certification",
    "field_values": { "space.crew.species": "Vogon" },
    "include_trace": true
  }'
```

Real response (trimmed for clarity):

```json theme={null}
{
  "decision": "not_eligible",
  "fields_provided": 1,
  "fields_evaluated": 11,
  "trace": {
    "status": "ineligible",
    "failure_reasons": [
      ["species_not_vogon", [
        { "type": "answer", "field": "space.crew.species", "value": "vogon" },
        { "type": "condition",
          "expression": "Not(spacecraft-crew-certification:v1:space.crew.species == Vogon)" }
      ]]
    ],
    "answered": ["space.crew.species"],
    "group_statuses": {
      "species_eligibility": "not_satisfied",
      "flight_readiness": "pending",
      "medical_certification": "pending",
      "medical_cert_validity": "pending",
      "radiation_certification": "pending",
      "propulsion_compliance": "pending",
      "towel_compliance": "pending"
    }
  }
}
```

The ruleset has 11 fields across 7 rule groups. The engine reasoned over all of them, found a constraint violation in the species check, and short-circuited — `fields_provided: 1` because that's all it needed. The `failure_reasons` list points at the exact compiled SMT condition that failed, which traces back to a specific clause in the source Spacecraft Crew Certification Act 2049.

For natural-language reasoning, add `"include_explanation": true` instead of (or alongside) `include_trace`.

***

## 3. Guide — the shortest path to an answer

When the engine has enough fields to short-circuit, it does. When it doesn't, it tells you exactly which question to ask next. Send a partial input:

```bash theme={null}
curl -sS -X POST https://api.aethis.ai/api/v1/public/decide \
  -H "Content-Type: application/json" \
  -d '{
    "ruleset_id": "aethis/spacecraft-crew-certification",
    "field_values": {
      "space.crew.species": "Human",
      "space.crew.age": 35
    }
  }'
```

Real response (trimmed):

```json theme={null}
{
  "decision": "undetermined",
  "fields_provided": 2,
  "missing_fields": [
    "space.crew.flight_hours",
    "space.crew.has_pilot_license",
    "space.crew.has_gaa_exam",
    "space.crew.has_approved_provider_cert",
    "space.medical.cert_valid",
    "space.mission.type",
    "space.crew.has_radiation_cert",
    "space.vessel.propulsion_type",
    "space.crew.has_towel"
  ],
  "next_question": {
    "field_id": "space.mission.type",
    "question": "What is the mission type?",
    "weight": 1
  },
  "optimal_path": [
    { "field_id": "space.mission.type",                "question": "What is the mission type?" },
    { "field_id": "space.crew.flight_hours",           "question": "How many flight hours has the applicant accumulated?" },
    { "field_id": "space.crew.has_pilot_license",      "question": "Does the applicant hold a valid pilot licence?" },
    { "field_id": "space.crew.has_gaa_exam",           "question": "Has the applicant passed a GAA medical examination?" },
    { "field_id": "space.medical.cert_valid",          "question": "Is the medical certificate within 730 days of application?" },
    { "field_id": "space.crew.has_radiation_cert",     "question": "Does the applicant hold a radiation protection certificate?" },
    { "field_id": "space.vessel.propulsion_type",      "question": "What type of propulsion system does the vessel use?" },
    { "field_id": "space.crew.has_towel",              "question": "Does the applicant carry a towel?" }
  ]
}
```

`next_question` is the single field most likely to collapse the remaining decision space. `optimal_path` is the full ordered shortlist. This is not a fixed decision tree — the engine evaluates all eligibility paths simultaneously and picks the field that, given what's been answered, branches the fewest remaining possibilities. Build a wizard, a chatbot, or an intake form on top of this without writing routing logic.

***

## How it works

```mermaid theme={null}
%%{init: {"theme": "dark"}}%%
flowchart LR
    subgraph author["  ✦  Authoring — once  "]
        direction LR
        P(Source documents) --> R(Aethis rule authoring)
        R --> S(Logical sections)
        S --> B[(Versioned rule database)]
    end
    subgraph runtime["  ⚡  Decision time — every request  "]
        direction LR
        I(Input data) --> E("Eligibility engine · &lt;1ms · no LLM")
        E -->|decision| O("eligible / not_eligible / undetermined")
    end
    B --> E

    style author fill:#141218,stroke:#3b3654,stroke-width:1px
    style runtime fill:#0d1410,stroke:#26412e,stroke-width:1px
    style S fill:#141218,stroke:#3b3654,stroke-width:1px
    style B fill:#1e1409,stroke:#B8531C,stroke-width:1.5px
    style O fill:#0a1c12,stroke:#1e5c34,stroke-width:1px
```

A language model reads your source material **once**, at authoring time, and proposes constraint logic. The engine refines that logic against subject-matter-expert-authored tests until every test passes — **a ruleset with stored test cases cannot be published while any of them fails**. That gate is real but bounded, and it is worth knowing its edges: it re-runs the project's **stored** test cases server-side, so a project that has never had tests written against it has nothing to fail; and a publish may carry `force_unsafe: true` to proceed over failing cases, which is recorded as a `publish_force_bypass` audit event against the project, ruleset and key. The guarantee is therefore "we will not let a tested ruleset go out while its tests are red, and we keep a record when someone overrides that" — not "every published ruleset is correct". Correctness still comes from the tests a subject-matter expert chose to write.

The compiled, versioned ruleset is then stored. At decision time the engine queries the compiled form — no model in the path, no temperature, no retrieval, no drift. The same `inputs_hash` always produces the same `decision_id` shape with the same outcome.

<Note>
  **Determinism is repeatability; correctness comes from the test gate.** Rules compile from your source documents, not your tests. Tests validate the output, and the platform refuses to publish a ruleset with a failing test.
</Note>

***

## Pick your interface

All four call the same engine. Decision tools on leaf rulesets work with no signup, no key.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    # Isolated, no venv juggling:
    uv tool install aethis-cli

    aethis decide \
      -b aethis/uk-fsm/child-eligibility \
      -i '{"child.age": 10, "child.school_type": "state_funded"}'
    ```

    Add `--explain` for the trace. Inspect a ruleset's input fields with `aethis fields -b <ruleset_id>`. See [CLI reference](/interfaces/cli).
  </Tab>

  <Tab title="Python SDK">
    ```bash theme={null}
    uv add aethis-sdk
    ```

    ```python theme={null}
    from aethis_sdk import Aethis

    with Aethis() as client:  # api_key= for authoring; leaf decisions need none
        response = client.decide(
            ruleset_id="aethis/uk-fsm/child-eligibility",
            field_values={"child.age": 10, "child.school_type": "state_funded"},
        )
        print(response.decision)
    ```

    Typed sync and async clients with a stateful `DecisionSession` adapter for wizard / chatbot intake. Pick it when you're shipping a Python service. See [Python SDK reference](/interfaces/python-sdk).
  </Tab>

  <Tab title="curl">
    ```bash theme={null}
    curl -sS -X POST https://api.aethis.ai/api/v1/public/decide \
      -H "Content-Type: application/json" \
      -d '{ "ruleset_id": "aethis/uk-fsm/child-eligibility",
            "field_values": { "child.age": 10, "child.school_type": "state_funded" } }'
    ```

    Any HTTP client works. See [REST API reference](/interfaces/rest-api).
  </Tab>

  <Tab title="MCP">
    Wire the engine into your coding agent (Claude Code, Cursor, Windsurf, …) in one command:

    ```bash theme={null}
    claude mcp add aethis -- npx -y aethis-mcp
    ```

    Then ask in natural language:

    > *"Use Aethis to check whether a 10-year-old at a state-funded school qualifies for free school meals."*

    Your agent invokes `aethis_decide` for you. See [MCP server overview](/mcp-server/overview).
  </Tab>
</Tabs>

***

## Author your own rules

Three steps: paste source text, write tests, iterate until they pass. The same authoring pipeline is exposed via MCP tools and the CLI.

<Steps>
  <Step title="Create a project, drop in source + tests">
    <Tabs>
      <Tab title="CLI">
        ```bash theme={null}
        aethis init income-threshold
        cd income-threshold
        # Put source PDFs / text into sources/
        # Add test cases to tests/scenarios.yaml
        # Optional: hints in guidance/hints.yaml
        ```

        See `examples/spacecraft-crew-rules/` in [aethis-cli](https://github.com/Aethis-ai/aethis-cli) for a complete project layout you can copy.
      </Tab>

      <Tab title="MCP">
        Ask your coding agent in natural language:

        > *"Use Aethis to start a project called 'Income threshold check' with section\_id `income_eligibility`, source text: 'An applicant qualifies if their annual net income is below £30,000…', and two test cases: annual\_income 25000 → eligible, 35000 → not\_eligible."*

        Your agent invokes `aethis_create_ruleset` for you.
      </Tab>
    </Tabs>
  </Step>

  <Step title="Generate and test">
    <Tabs>
      <Tab title="CLI">
        ```bash theme={null}
        aethis generate --poll   # 60–120s, uploads sources + triggers generation
        aethis test              # runs your test cases against the new ruleset
        ```
      </Tab>

      <Tab title="MCP">
        Ask your coding agent in natural language:

        > *"Run aethis\_generate\_and\_test on the project. If anything fails, use aethis\_refine with guidance pointing at the specific clause that was missed."*
      </Tab>
    </Tabs>

    Any failure points at the clause that was missed so you can refine the source text, the test, or the guidance — not the generated rules. Rules compile from the source, not from the tests.
  </Step>

  <Step title="Publish">
    <Tabs>
      <Tab title="CLI">
        ```bash theme={null}
        aethis publish
        # → ruleset_id: income_eligibility:20260416-a1b2c3d4
        ```
      </Tab>

      <Tab title="MCP">
        Ask your coding agent:

        > *"Run aethis\_publish on the project and tell me the `ruleset_id`."*
      </Tab>
    </Tabs>

    Now anyone can call `/decide` with that `ruleset_id`. No model at decision time.
  </Step>
</Steps>

Rule authoring is **invite-only private beta** — approval required, and every call in this section needs an Aethis API key plus your own model-provider key. Decision tools work now with no signup. [Request authoring access →](https://aethis.ai/developer-access) · [What each tier includes](/reference/capabilities)

***

## When to use Aethis

| Requirement | Why Aethis |
| - | - |
| Same answer every time | Rules compile to formal logic — no temperature, no variance |
| Audit trail to source | Every decision traces to a specific clause in your source text |
| Fast at scale | Under 1ms per decision in the engine; thousands per second under parallel load |
| Regulated compliance | No LLM in the decision path — defensible in regulated contexts |
| Guided intake | `next_question` + `optimal_path` give you a wizard for free |

Not a good fit for: recommendations, probabilistic scoring, or decisions where "close enough" is acceptable.

***

## Choose your path

<CardGroup cols={2}>
  <Card title="More live rulesets to curl" icon="terminal" href="/getting-started/try-it">
    Spacecraft, construction insurance, consumer credit, the full UK Free School Meals rulebook (`A AND (B OR C)`). All currently active in production.
  </Card>

  <Card title="Single-section policy (invite-only)" icon="file-lines" href="/authoring/rule-generation">
    One set of criteria, one decision. Go straight to Rule generation.
  </Card>

  <Card title="Multi-section legislation (invite-only)" icon="sitemap" href="/authoring/section-discovery">
    Multiple entitlements or prerequisite gates. Start with Section discovery.
  </Card>

  <Card title="Worked example" icon="graduation-cap" href="/getting-started/examples">
    UK Free School Meals end-to-end — 3 sections, 3 source documents, 23 test cases.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.