> ## 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.

# Author your first ruleset

> A 15-minute follow-along tutorial using Claude Code, Aethis MCP, and a small file-based rules project.

In this tutorial, you will create a tiny ruleset from source files, review the fields and tests, add guidance, generate rules, publish, and run a decision.

Expected time: **15 minutes**. Generation usually takes **1-3 minutes** for a small example. More complex policies can take longer.

## What you will see

By the end, you will have seen the full authoring loop:

* A real project directory with `sources/`, `tests/`, and `guidance/`
* Claude Code using Aethis MCP to create and generate a ruleset
* Field discovery before generation, with a human review checkpoint
* Test cases drafted by Claude and reviewed by you
* Guidance hints stored as files and sent to the API
* A generate/test loop until all tests pass
* A published ruleset that returns deterministic decisions

You can paste rules into the conversation, drop files into `sources/`, or ask Claude Code to fetch source material from the web and save it there. This tutorial uses two small local files so every step is easy to inspect.

<Warning>
  If Claude fetches source material from the web, review the saved files before authoring. Web pages can contain summaries, navigation text, or stale content. The rules should compile from the source text you approve.
</Warning>

## Before you start

You need:

* `aethis-cli` installed
* Aethis MCP installed in Claude Code
* An Aethis API key with authoring access

Install MCP if you have not already:

```bash theme={null}
aethis mcp install --target claude-code
```

Restart Claude Code after installing MCP.

## 1. Create the project directory

Use the CLI to create a file-based authoring project:

```bash theme={null}
aethis init free-school-meals-child-demo
cd free-school-meals-child-demo
```

The CLI creates this structure:

```text theme={null}
free-school-meals-child-demo/
  aethis.yaml
  sources/
  tests/
    scenarios.yaml
  guidance/
    hints.yaml
  .aethis/
```

The directories matter:

* `sources/` contains the rules or policy text
* `tests/scenarios.yaml` contains expected decisions
* `guidance/hints.yaml` contains subject-matter guidance for generation
* `.aethis/` stores local tool state such as project IDs

## 2. Add two source files

Create `sources/age-rule.md`:

```md theme={null}
# Age rule

A child is eligible under this tutorial rule only if the child is aged 4 to 15 inclusive at the start of the relevant school year.

A child aged 3 is too young. A child aged 16 or older is outside this tutorial rule.
```

Create `sources/school-type-rule.md`:

```md theme={null}
# School type rule

A child is eligible under this tutorial rule only if the child attends a state-funded school.

A child who attends an independent school is not eligible under this tutorial rule.

A child who is home educated is not eligible under this tutorial rule.

This tutorial covers only the child eligibility gate. It does not assess household income, benefits, universal infant entitlement, or sixth-form rules.
```

This shows the normal workflow: source material lives in files. Claude Code can read those files and call MCP tools from the conversation.

## 3. Add initial guidance

Open `guidance/hints.yaml` and replace the placeholder with:

```yaml theme={null}
hints:
  - text: >
      This project covers only the child eligibility gate. Do not include
      household income, benefits, universal infant entitlement, or sixth-form rules.
    process_type: rule_generation

  - text: >
      child.age is an integer age in whole years at the start of the school year.
      The age range is inclusive: age 4 passes and age 15 passes.
    process_type: field_extraction

  - text: >
      child.school_type is an enum with values state_funded, independent,
      home_educated. Only state_funded qualifies.
    process_type: field_extraction
```

Guidance hints are not a substitute for source text. Use them to clarify field names, scope, vocabulary, and known authoring conventions.

## 4. Ask Claude Code to inspect the project

In Claude Code, ask:

```text theme={null}
Use Aethis MCP to author the rules in this project directory.

Read all files in sources/ and guidance/hints.yaml.
First tell me the fields you expect, then draft tests and stop for my review.
Do not publish anything until I approve the tests and all tests pass.
```

Claude should identify two expected fields:

| Field               | Type    | Expected values                                |
| ------------------- | ------- | ---------------------------------------------- |
| `child.age`         | integer | Whole years at the start of the school year    |
| `child.school_type` | enum    | `state_funded`, `independent`, `home_educated` |

If Claude proposes different names or extra fields, correct them before generation.

## 5. Review the tests

Ask Claude to write the tests into `tests/scenarios.yaml`. The reviewed file should look like this:

```yaml theme={null}
tests:
  - name: "Age 4 at state-funded school - eligible"
    inputs:
      child.age: 4
      child.school_type: state_funded
    expect:
      outcome: eligible

  - name: "Age 15 at state-funded school - eligible"
    inputs:
      child.age: 15
      child.school_type: state_funded
    expect:
      outcome: eligible

  - name: "Age 3 at state-funded school - too young"
    inputs:
      child.age: 3
      child.school_type: state_funded
    expect:
      outcome: not_eligible

  - name: "Age 16 at state-funded school - too old"
    inputs:
      child.age: 16
      child.school_type: state_funded
    expect:
      outcome: not_eligible

  - name: "Age 10 at independent school - not eligible"
    inputs:
      child.age: 10
      child.school_type: independent
    expect:
      outcome: not_eligible

  - name: "Age 8 home educated - not eligible"
    inputs:
      child.age: 8
      child.school_type: home_educated
    expect:
      outcome: not_eligible
```

These tests cover the lower boundary, upper boundary, below-boundary case, above-boundary case, and both excluded school types.

<Warning>
  Tests are your review surface. Passing tests mean the generated rules match the reviewed test suite. They do not prove your source material is complete.
</Warning>

## 6. Create the MCP project and discover fields

After you approve the tests, ask Claude:

```text theme={null}
Create the Aethis project with aethis_create_ruleset using the source files,
the reviewed tests, and the guidance hints. Then run aethis_discover_fields
and stop so I can review the discovered fields before generation.
```

Claude should call MCP tools in this order:

```js theme={null}
aethis_create_ruleset({
  name: "Free School Meals child demo",
  section_id: "free_school_meals_child_demo",
  source_text: "<combined reviewed source files>",
  test_cases: ["<reviewed tests>"]
})

aethis_add_guidance({ project_id, guidance_text, process_type })

aethis_discover_fields({ project_id })
```

Review the discovered fields against the expected fields:

```text theme={null}
child.age          int
child.school_type  enum: state_funded, independent, home_educated
```

If discovery adds unrelated fields such as household income or benefits, tell Claude to add guidance narrowing the scope and run field discovery again.

## 7. Generate and test

When the field discovery looks right, ask:

```text theme={null}
Generate and test the ruleset. If any test fails, explain the failure before
adding more guidance.
```

Claude should call:

```js theme={null}
aethis_generate_and_test({ project_id })
```

For this tutorial, the expected result is:

```text theme={null}
6/6 tests passing
```

The generated criteria should be equivalent to:

```text theme={null}
age_range: child.age >= 4 AND child.age <= 15
school_type_state: child.school_type == "state_funded"
```

If a test fails, keep the feedback specific:

```text theme={null}
The age bounds are inclusive. Age 4 and age 15 should both pass.
Regenerate and run the tests again.
```

## 8. Publish

Only publish after the test gate is green:

```text theme={null}
Publish the ruleset with aethis_publish. Tell me the ruleset_id and test count.
```

Claude should call:

```js theme={null}
aethis_publish({ project_id })
```

Publishing runs the tests again as a server-side gate. If the tests do not pass, publishing is blocked unless you explicitly force it.

<Tip>
  If generation times out in the client, it may still finish server-side. Ask Claude to check the project status or run the tests again before assuming generation failed.
</Tip>

## 9. Run two decisions

Ask Claude:

```text theme={null}
Run a decision for a 10-year-old at a state-funded school. Include the trace.
```

Claude should call:

```js theme={null}
aethis_decide({
  ruleset_id: "<published_ruleset_id>",
  field_values: {
    "child.age": 10,
    "child.school_type": "state_funded"
  },
  include_trace: true
})
```

Expected decision:

```json theme={null}
{
  "decision": "eligible",
  "trace": {
    "age_check": "satisfied",
    "school_type_check": "satisfied"
  }
}
```

Then ask for a failing case:

```text theme={null}
Now test a 10-year-old at an independent school. Include the trace.
```

Expected decision: `not_eligible`, with `school_type_check` not satisfied.

## 10. Export guidance back to files

During a conversation, Claude may add guidance directly through MCP. Export active guidance back into the project so it remains reviewable and version-controlled:

```bash theme={null}
aethis guidance export --project-id <project_id> --output-file guidance/hints.yaml
```

You can also import local guidance into the API:

```bash theme={null}
aethis guidance import guidance/hints.yaml --project-id <project_id>
```

This is deliberate, not automatic. Treat `guidance/hints.yaml` as the human-reviewed record of the SME guidance that shaped generation.

## The pattern

For a first authoring session, keep the loop this small:

<Steps>
  <Step title="Put source text in files">
    Start with one small section. Do not begin with a whole Act, handbook, or policy manual.
  </Step>

  <Step title="Review fields and tests">
    Let Claude draft them, but approve them yourself. Boundary tests matter more than volume.
  </Step>

  <Step title="Review guidance">
    Keep guidance specific and scoped. Export MCP-added guidance back to `guidance/hints.yaml` before review.
  </Step>

  <Step title="Generate, publish, decide">
    Publish only after the test gate is green, then call `aethis_decide` against the published ruleset.
  </Step>
</Steps>

Once this flow is comfortable, move to [Author a rule from legislation](/recipes/author-a-rule) for section discovery, field vocabulary, and multi-section composition.
