Skip to main content

easa-erules

CI PyPI version Python versions License: MIT GitHub release

Deterministic, local toolkit for EASA Easy Access Rules — built for LLM agents.

Turns the official EAR XML exports (CS-*, AMC, GM) into structured data an agent can quote from. An experimental FAA branch serves 14 CFR through the public eCFR API using the same interface.

  • fetch a regulation, or a pinned version, into a local cache
  • parse into a canonical Regulation AST (Flat OPC / OOXML, or eCFR XML)
  • export Markdown, JSON and HTML
  • extract one rule, query with SQLite FTS5, walk cross-references
  • validate conversions so nothing is dropped silently

Regulatory text is never rewritten by an LLM during conversion. Conversion is deterministic; models reason on tool output, not on recall.

Every machine-readable result states which publication and amendment it came from, and distinguishes "searched, found nothing" from "never looked" — the usual way an agent pipeline goes quietly wrong.


Install

Requires Python ≥ 3.11.

# PyPI (recommended for users)
pip install easa-erules

# or with uv
uv pip install easa-erules

From source / development:

git clone https://github.com/mrSpringpeace/easa-erules.git
cd easa-erules
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
# or: pip install -e ".[dev]"

Pinned git tag (if PyPI is unavailable):

pip install "git+https://github.com/mrSpringpeace/easa-erules.git@v0.2.0"

Optional MCP server (for agent hosts that speak MCP rather than shell):

pip install "easa-erules[mcp]"

Entry points: easa-erules, easa-erules-mcp.

Disclaimer: Unofficial toolkit, not endorsed by EASA or the FAA. Always verify critical interpretations against the official publication. The MIT licence covers this software only — see NOTICE for the attribution and licensing of regulatory text.


Quick start

# Catalog
easa-erules list
easa-erules info vla

# Download latest XML into the cache
easa-erules fetch cs-vla
easa-erules fetch cs-vla --version "Amendment 1"

# Inspect / convert / extract / search / refs
easa-erules inspect cs-vla
easa-erules convert cs-vla -o ./out --split
easa-erules convert ./local.xml -o ./out --format html
easa-erules extract cs-vla CS-VLA.303 --format json
easa-erules query cs-vla "factor of safety" --json
easa-erules refs cs-vla CS-VLA.303 --json
easa-erules validate ./out

# FAA parts work the same way (experimental)
easa-erules fetch far-23
easa-erules extract far-23 "14 CFR 23.2005" --format json

Local path or registry id/alias is accepted for most commands. Use --fetch on convert/extract/query when the id is not cached yet.

Output contract

Every --json result carries the same envelope, so an agent can branch on it without guessing:

{
  "schema_version": "1.0",
  "status": "ok",
  "source": {"regulation_id": "cs-vla", "amendment": "Amendment 1", "sha256": "…"},
  "warnings": [],
  "rule": { "…": "…" }
}
status exit Meaning
ok 0 Succeeded, results present
no_match 0 Searched, nothing matched
not_cached 3 Not downloaded — run fetch or pass --fetch
index_missing 4 Search index damaged — retry with --rebuild
fetch_failed 5 Download failed
source_drift 6 Landing page no longer matches the catalog entry
parse_error 7 Source could not be parsed
error 1 Unknown id, bad path, everything else

no_match is not evidence that a requirement does not exist. Amendment and issue are never silently null: when they cannot be established the field reads unknown and a warning says so.

Cache layout

~/.cache/easa-erules/          # override: EASA_ERULES_CACHE
  cs-vla/
    source.xml                 # latest convenience copy
    meta.yaml
    search.sqlite              # FTS index (built on first query)
    versions/<slug>/
      source.xml
      meta.yaml                # sha256, download_url, retrieved_at, …
      original.zip

Split convert output

out/
├── index.md
├── metadata.yaml
├── document.json
├── conversion-report.json
├── rules/
│   └── cs-vla-303.md
└── assets/
    └── cs-vla-303-fig-01.png

CLI reference

Command Purpose
list Built-in regulation catalog
info Metadata + cache presence for an id/alias
fetch Resolve landing page → download XML → cache + integrity
inspect Structure stats, warnings, unknown elements
convert Markdown / JSON / HTML (--split, --format)
extract Single rule (JSON preferred for agents)
query Local FTS5 search (--json, --rebuild)
refs Outgoing / incoming cross-reference graph
validate Check a conversion output directory

Design principles, adapters and the full output contract: docs/MANUAL.md.


Architecture

EASA landing page ──fetch──► cache (XML + meta + sha256)
eCFR API          ──fetch──►      │
                                  │
Local XML/DOCX ───────────────────┤
                                  ▼
                     OpcPackage / eCFR XML
                              ▼
              EasaDocumentParser | FaaEcfrAdapter
                              ▼
                     Regulation AST ──normalize──►
                              ▼
              ┌───────────────┼───────────────┐
              ▼               ▼               ▼
          Markdown          JSON            HTML
              │
              ├── SQLite FTS5 (query)
              ├── Reference graph (refs)
              └── Validation / conversion-report.json

Built-in sources

EASAsources/easa.yaml, keyed on stable landing pages rather than fragile direct URLs:

cs-vla, cs-lsa, cs-22, cs-23, cs-25, cs-27, cs-29, cs-e, part-21, uas-rules

cs-p and cs-etso are catalogued but PDF-only — EASA publishes no XML export for them, so commands fail with an explanation instead of a confusing parse error.

FAA — experimentalsources/faa.yaml, served by the public eCFR API:

far-21, far-23, far-25, far-27, far-43, far-91

This branch is a prototype: it mirrors regulation text only, its shape may change, and it is not a source for the FAA certification basis. EASA is where this project is maintained.

A weekly workflow resolves, downloads and parses every entry, and reports drift without failing the build:

python scripts/catalog_health.py --deep

For LLM agents

Two integration routes, same results:

  • Shell — the thin skills under skills/ (generic / Codex / Claude Code / OpenCode)
  • MCPeasa-erules-mcp, exposing list_regulations, regulation_info, extract_rule, query_regulation, rule_references, fetch_regulation

Cookbook: examples/agent-cookbook.md
Full manual: docs/MANUAL.md

Rules of engagement:

  1. Prefer query / extract / refs with --json over stuffing full regulations into context.
  2. Never hand-write or "fix" regulatory text from model memory.
  3. After bulk convert, run validate.
  4. Ground answers only on tool output, and cite the designation + amendment from the source block.
  5. This is an EASA source. It is not a source for the FAA certification basis — the FAA branch mirrors eCFR text only, with no Advisory Circulars or policy material.

Development

pytest                                        # offline; real-sample tests skip
python tests/real_samples/fetch_samples.py    # pull the pinned publications
pytest -m real_sample -v
EASA_ERULES_LIVE=1 pytest -k live -v          # network smokes

ruff check src tests scripts
  • Unit fixtures: tests/fixtures/
  • Golden renders: tests/golden/
  • Real documents: pinned, not committed — see tests/real_samples/README.md and docs/LEGAL-REVIEW.md

Development state: docs/STATUS.md


Design principles

  • Deterministic conversion — same source + parser version → same AST/ids/exports
  • No silent content loss — unknown elements and failed structures are reported
  • AST in the middle — no direct XML → Markdown hacks
  • Agent-first CLI — versioned, self-describing JSON for extract/query/refs
  • Explicit over empty — a result never leaves an agent guessing why it is empty

License

MIT for the software — see LICENSE.

The MIT grant does not extend to regulatory text retrieved through this tool. EASA Easy Access Rules are reproduced with acknowledgement per EASA's copyright policy; 14 CFR is US Government work in the public domain. See NOTICE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

easa_erules-0.2.1.tar.gz (141.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

easa_erules-0.2.1-py3-none-any.whl (117.3 kB view details)

Uploaded Python 3

File details

Details for the file easa_erules-0.2.1.tar.gz.

File metadata

  • Download URL: easa_erules-0.2.1.tar.gz
  • Upload date:
  • Size: 141.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for easa_erules-0.2.1.tar.gz
Algorithm Hash digest
SHA256 ae9c5ecb9d63dacd772ded7d776f7043532b0072a0a2fd6633f878a1777b36d0
MD5 96f6fd32189c26f55f410839acd8b331
BLAKE2b-256 59ccf4e3af36710003b7ce0e1f7ecaa6ff1a343e2c812516cedd30b5062e495b

See more details on using hashes here.

Provenance

The following attestation bundles were made for easa_erules-0.2.1.tar.gz:

Publisher: publish.yml on mrSpringpeace/easa-erules

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file easa_erules-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: easa_erules-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 117.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for easa_erules-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8ce6ff09e287420f23608271f4984bfe28b7ef90d26c991a10e1d59b79561037
MD5 998945dce97f212c08eb5ab1a5b4a1ac
BLAKE2b-256 501a0c2cee5d7ab408750fb78c0ee340f3e84c3531bac74e438c5c6aebdab3ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for easa_erules-0.2.1-py3-none-any.whl:

Publisher: publish.yml on mrSpringpeace/easa-erules

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page