easa-erules
Universal, deterministic toolkit for EASA Easy Access Rules / eRules XML publications.
This is not “XML → Markdown only”. It is a local CLI for humans and LLM agents:
- fetch a regulation (or a pinned version) from EASA,
- load Flat OPC / OOXML packages,
- parse into a canonical Regulation AST,
- export Markdown, JSON, and HTML,
- extract single rules, search with SQLite FTS5, explore cross-references,
- validate conversions without silently dropping content.
Regulatory text is never rewritten by an LLM during conversion. Conversion is deterministic; models should reason on tool output.
Project status
| Area | Status | Notes |
|---|---|---|
| Package reader (Flat OPC + ZIP/DOCX) | Done | OPC .rels paths, relative media targets |
| EASA parser → Regulation AST | Done | Fixtures (erules:topic) and real EAR Word SDT topics/headings |
| Deterministic IDs + normalize | Done | Stable ids; whitespace/heading/list/ref passes |
| Markdown / JSON / HTML export | Done | Split-by-rule MD; frontmatter; HTML document |
Registry + fetch + cache |
Done | YAML catalog; landing-page resolver; sha256 metadata |
extract / query / refs |
Done | Agent-oriented JSON; FTS5 index with invalidation |
| Validation + conversion report | Done | Topic count vs source; assets; duplicates; unresolved refs |
| Golden + unit tests | Done | Fixtures + frozen goldens |
| Real-document smokes | Done | Checked-in cs-vla.xml (~6 MB), cs-23.xml (~4 MB); topic counts align |
| LLM skills (thin adapters) | Done | skills/{generic,codex,claude-code,opencode}/ |
| Complex tables (colspan/rowspan) | Improved | HTML path emits merge attrs; nested tables; header-row fix |
| Broader catalog | Expanded | cs-25/27/29, cs-e/p/etso, part-21, uas-rules (+ original four) |
| Designation quality on real docs | Done | Export source-title + first-line extract; CS-VLA.1, AMC VLA 21(c), AMC1 CS-23.2000, … |
| Real-doc metadata | Done | erules-export customXml by sdt-id; core props; unique ERulesIds |
| Agent cookbook + manual | Done | examples/agent-cookbook.md, docs/MANUAL.md |
| CI + live CS-25 smoke | Done | .github/workflows/ci.yml + optional live-smoke.yml |
| FAA / ASTM adapters | Scaffold | src/easa_erules/adapters/ — EASA production; FAA/ASTM stubs |
| Vector/embeddings search | Out of scope | FTS5 only (by design for v1) |
Verdict: MVP complete for agent-local EAR workflows, with designation/metadata polish and docs in place. Next expansion is optional (more live packages, FAA/ASTM when needed).
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.1.2"
Entry point: easa-erules.
Disclaimer: Unofficial toolkit. Always verify critical interpretations against the official EASA Easy Access Rules publication. This software does not re-license 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
Local path or registry id/alias is accepted for most commands. Use --fetch on convert/extract/query when the id is not cached yet.
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 |
Architecture
EASA landing page ──fetch──► cache (XML + meta)
│
Local XML/DOCX ───────────────┤
▼
OpcPackage (Flat OPC / ZIP)
▼
EasaDocumentParser
▼
Regulation AST ──normalize──►
▼
┌───────────────┼───────────────┐
▼ ▼ ▼
Markdown JSON HTML
│
├── SQLite FTS5 (query)
├── Reference graph (refs)
└── Validation / conversion-report.json
Built-in sources
Defined in src/easa_erules/sources/easa.yaml (stable landing pages, not fragile direct URLs):
cs-vla, cs-lsa, cs-22, cs-23, cs-25, cs-27, cs-29, cs-e, cs-p, cs-etso, part-21, uas-rules
For LLM agents
Use the thin skills under skills/ (generic / Codex / Claude Code / OpenCode).
Cookbook: examples/agent-cookbook.md
Full manual: docs/MANUAL.md
Rules of engagement:
- Prefer
query/extract/refswith--jsonover stuffing full regulations into context. - Never hand-write or “fix” regulatory text from model memory.
- After bulk
convert, runvalidate. - Ground answers only on tool output.
Development
pytest
# real EAR smokes (checked-in samples):
pytest tests/test_real_samples.py -v
# optional live network re-fetch:
EASA_ERULES_LIVE=1 pytest tests/test_real_samples.py -v
ruff check src tests
- Unit fixtures:
tests/fixtures/ - Golden renders:
tests/golden/ - Real documents:
tests/real_samples/(see README there)
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 — stable JSON shapes for extract/query/refs
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file easa_erules-0.1.2.tar.gz.
File metadata
- Download URL: easa_erules-0.1.2.tar.gz
- Upload date:
- Size: 99.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9369ff13cf74e8c9a0fae5a848390530ec23e0db4020cbad96343a12855d8d5
|
|
| MD5 |
051c6d2deec5f747901165637de8000f
|
|
| BLAKE2b-256 |
f03c551326ef2381498ca720ee389e6916d2ac1a3b5aa6ab35938d60c30ba6a6
|
Provenance
The following attestation bundles were made for easa_erules-0.1.2.tar.gz:
Publisher:
publish.yml on mrSpringpeace/easa-erules
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
easa_erules-0.1.2.tar.gz -
Subject digest:
a9369ff13cf74e8c9a0fae5a848390530ec23e0db4020cbad96343a12855d8d5 - Sigstore transparency entry: 2392249705
- Sigstore integration time:
-
Permalink:
mrSpringpeace/easa-erules@77054b10c18db64e6a0d4402978bf3cdddff083e -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/mrSpringpeace
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@77054b10c18db64e6a0d4402978bf3cdddff083e -
Trigger Event:
release
-
Statement type:
File details
Details for the file easa_erules-0.1.2-py3-none-any.whl.
File metadata
- Download URL: easa_erules-0.1.2-py3-none-any.whl
- Upload date:
- Size: 95.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd0b92f8d55acb1a4bfc1b4855a9af807284b6a7d690db848e7716d6d3c63633
|
|
| MD5 |
557a08f9a7d58fdb83d756e9b2dc7d20
|
|
| BLAKE2b-256 |
5e106c8ed704f0e7a354a948a0ea9bb3d8c18827169f32541739eae192756795
|
Provenance
The following attestation bundles were made for easa_erules-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on mrSpringpeace/easa-erules
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
easa_erules-0.1.2-py3-none-any.whl -
Subject digest:
cd0b92f8d55acb1a4bfc1b4855a9af807284b6a7d690db848e7716d6d3c63633 - Sigstore transparency entry: 2392250301
- Sigstore integration time:
-
Permalink:
mrSpringpeace/easa-erules@77054b10c18db64e6a0d4402978bf3cdddff083e -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/mrSpringpeace
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@77054b10c18db64e6a0d4402978bf3cdddff083e -
Trigger Event:
release
-
Statement type: