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.3.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"
easa-erules versions cs-vla --verify
easa-erules versions cs-vla --remote
easa-erules outline cs-vla --version amendment-1 --json

# 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" --material certification_specification --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.1",
  "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
integrity_error 8 Cached bytes do not match the stored SHA-256
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
    versions/<slug>/
      source.xml
      meta.yaml                # sha256, download_url, retrieved_at, …
      search.sqlite            # schema v2; isolated per amendment
      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
versions Local/remote amendments, integrity/freshness, safe deletion
outline Lightweight ordered navigation tree for a pinned version
inspect Structure stats, warnings, unknown elements
convert Markdown / JSON / HTML (--split, --format)
extract Single rule (JSON preferred for agents)
query Paginated/filterable FTS5 search and filter-only browse
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

EASA — sources/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 — experimental — sources/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)
  • MCP — easa-erules-mcp, exposing the catalog/version inventory, outline, filtered search, rule context, assets and legacy operations

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.

Release files for easa-erules 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for easa-erules 0.3.0
File Size Uploaded
easa_erules-0.3.0.tar.gz 164.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for easa-erules 0.3.0
File Interpreter ABI Platform
easa_erules-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 299.9 kB

Release files / easa_erules-0.3.0.tar.gz

Download URL easa_erules-0.3.0.tar.gz
Size 164.7 kB
Tags Source
SHA-256 checksum
How to use checksums
2aeb749c8940f0808819c3771aa2c43c33d7762f95ad86fd4c34a2a6c92ec557
BLAKE2b-256 checksum
How to use checksums
2ce95f3f75a2a5b131a28968bf40cec94c23fa9e832ab8464b09dcecb1f6ee76
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 11, 2026.

Transparency log

Release files / easa_erules-0.3.0-py3-none-any.whl

Download URL easa_erules-0.3.0-py3-none-any.whl
Size 135.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
87f05e917b9185b21edd7a39995377bc49945046740ee61eaf8065a2137700ee
BLAKE2b-256 checksum
How to use checksums
ea626659358dd5e058248b47358b533a4e0e4fbf6bfb62b30056220f34a2a77d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.1

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page