> ## 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 5ms, 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-5ms 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>
  Decisions on a leaf **ruleset** (e.g. `aethis/uk-fsm/child-eligibility`) and the schema/list endpoints are open — no key. Decisions on a composed **rulebook** (e.g. `aethis/uk-fsm`, binding `A AND (B OR C)`) and the authoring pipeline 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"
    }
  }'
```

Real response:

```json theme={null}
{
  "decision": "eligible",
  "slug": "aethis/uk-fsm/child-eligibility",
  "engine_version": "aethis-core@0.36.0",
  "fields_evaluated": 2,
  "fields_provided": 2,
  "decision_id": "dec_GjBMU4o8sNvNRmaR",
  "inputs_hash": "sha256:75c958f1a3d72335ccf67c7d5e32f58b57966e0873786843c353b09f787c5ec2",
  "decision_time": "2026-04-26T23:20:41Z"
}
```

That's a live production call against the UK Free School Meals child-eligibility section. The `inputs_hash` is the canonical fingerprint of the input — same inputs, same hash, same decision, every time.

<Note>
  **Public preview.** The decision API runs always-warm in europe-west1. The engine evaluates each decision in under 5ms; 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;5ms · 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 cannot be published with a failing test**. 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. Decision tools work now with no signup. [Request authoring access →](https://aethis.ai/developer-access)

***

## 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 5ms 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" icon="file-lines" href="/authoring/rule-generation">
    One set of criteria, one decision. Go straight to Rule generation.
  </Card>

  <Card title="Multi-section legislation" 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>
