Mapping FAA Part-145 Obligations to Ingestion Pipeline Stages

Regulators do not audit code — they audit obligations. This page pins each FAA 14 CFR Part-145 recordkeeping duty to the concrete stage of Automated Log Ingestion & Parsing Workflows that actually discharges it, so an engineer can walk an inspector from a legal requirement to the exact component that satisfies it. The result is a coverage map: every clause has an owner, and every stage knows which clause it answers to.

Where this stage sits

This is a bridging stage. It consumes no maintenance data and produces no ledger records; instead it consumes the catalog of obligations documented in FAA Part-145 Recordkeeping Standards and binds each one to a downstream pipeline stage that emits a verifiable artifact. Upstream is the regulatory text. Downstream is a compliance matrix that quality assurance can hand to an auditor.

Because the mapping is declarative, it lives beside the pipeline as configuration, not inside any single processing stage. When a stage changes — a new OCR engine, a revised schema — the mapping is the fixture that proves the obligation is still covered.

Part-145 obligations mapped to stages

Part-145 obligations mapped to stages§145.219recordsIngest+ OCRExtract+ validateSign+ retainAuditevidence

Problem & regulatory driver

The core obligation is FAA 14 CFR § 145.219, which requires a certificated repair station to make a record for, and maintain records of, all maintenance and alteration work it performs, to retain those records, and to make them available to the Administrator on request. That single clause fans out into several concrete duties: the content of the record must be captured faithfully, it must survive for the required retention period, and it must be retrievable in a form that supports inspection. Section 145.219 also ties back to the content requirements of § 43.9 for the maintenance release itself.

The failure mode this page prevents is diffuse responsibility. When “we comply with § 145.219” is asserted by the pipeline as a whole rather than by named stages, an auditor finding on one clause forces a scramble to locate which component owns it. A stage-by-stage map removes that ambiguity: the ingest and OCR stage owns faithful content capture, the extraction stage owns field fidelity, the sign-and-retain stage owns retention and non-repudiation, and the audit stage owns retrieval.

Interface contract

The mapping’s inputs are obligation clauses — each identified by its CFR citation, a plain-language duty, and a severity. Its outputs are ObligationMapping records binding each clause to exactly one owning stage and to the evidence artifact that stage produces (a SHA-256 fingerprint, a validated schema version, a signed release block). A clause with no owning stage is a coverage gap and must fail the build; a stage claiming an obligation it produces no artifact for is an unbacked assertion and must also fail.

Design decisions

The mapping is one-to-one from clause to owning stage, deliberately. A clause owned by two stages diffuses accountability again, so shared duties are decomposed into distinct clauses until each has a single owner. Evidence is always an artifact a machine can check — a hash, a version tag, a boolean release flag — never prose. And the mapping is validated in CI so that deleting or renaming a stage that owns an obligation breaks the build rather than silently dropping coverage. The structural rejection that happens here complements the record-level checks performed in Schema Validation & Error Handling, which enforces field-level contracts on the data itself.

Production Python implementation

The following module models obligations and their stage bindings, then validates that coverage is complete. It uses Pydantic v2 with a model_validator to reject unbacked mappings and structured logging for the compliance report.

from __future__ import annotations

import logging
from enum import Enum
from typing import Dict, List

from pydantic import BaseModel, ConfigDict, Field, model_validator

logging.basicConfig(level=logging.INFO, format="%(asctime)s | %(levelname)s | %(message)s")
logger = logging.getLogger("mro.compliance.bridge")


class Stage(str, Enum):
    INGEST_OCR = "ingest_ocr"
    EXTRACT_VALIDATE = "extract_validate"
    SIGN_RETAIN = "sign_retain"
    AUDIT = "audit"


class ObligationMapping(BaseModel):
    """Binds one Part-145 clause to the stage that discharges it."""

    model_config = ConfigDict(frozen=True)

    # FAA 14 CFR § 145.219 requires a repair station to make, retain, and
    # make available to the Administrator records of the work it performs.
    cfr_citation: str = Field(pattern=r"^§ \d+\.\d+$|^§ \d+\.\d+$")
    duty: str = Field(min_length=8)
    owning_stage: Stage
    evidence_artifact: str = Field(min_length=1)

    @model_validator(mode="after")
    def require_evidence(self) -> "ObligationMapping":
        if not self.evidence_artifact.strip():
            raise ValueError(f"{self.cfr_citation} claims {self.owning_stage} with no evidence")
        return self


def build_matrix(mappings: List[ObligationMapping]) -> Dict[str, str]:
    coverage: Dict[str, str] = {}
    for m in mappings:
        if m.cfr_citation in coverage:
            raise ValueError(f"duplicate owner for {m.cfr_citation}")
        coverage[m.cfr_citation] = m.owning_stage.value
        logger.info("mapped %s -> %s via %s", m.cfr_citation, m.owning_stage.value,
                    m.evidence_artifact)
    return coverage


if __name__ == "__main__":
    matrix = build_matrix([
        ObligationMapping(cfr_citation="§ 145.219", duty="Retain records and make them "
                          "available to the Administrator", owning_stage=Stage.SIGN_RETAIN,
                          evidence_artifact="worm_store.sha256"),
        ObligationMapping(cfr_citation="§ 43.9", duty="Record content of maintenance release",
                          owning_stage=Stage.EXTRACT_VALIDATE,
                          evidence_artifact="schema_v2.release_block"),
        ObligationMapping(cfr_citation="§ 43.13", duty="Perform work per acceptable methods",
                          owning_stage=Stage.INGEST_OCR,
                          evidence_artifact="source.sha256"),
    ])
    print(matrix)

Validation & testing

The build gate is a set-difference assertion: the set of CFR citations owned by stages must equal the set of citations the standard enumerates. A missing citation is a gap; an extra citation is a stale mapping referencing a repealed or renumbered clause. Applied to a worked case — say the removal of P/N AS7710-04 from VH-OQA under ATA 52-11 (passenger door) — the matrix lets QA assert that § 145.219 retention is discharged by the WORM store artifact, not merely assumed. Snapshot tests over the generated matrix catch accidental owner changes during refactors.

Failure modes & troubleshooting

The subtle failure is drift between the mapping and the standard’s text. When a clause is renumbered, the mapping keeps pointing at the old citation and silently loses coverage; pin the standard version and diff citations on every regulatory update. A second failure is evidence that exists but is not actually checkable — a “retention policy document” listed as evidence proves nothing an auditor can verify. Insist that every evidence artifact resolves to a hash, a schema version, or a signed field. Maintained this way, the mapping becomes the single sheet an inspector needs: each Part-145 duty, the stage that owns it, and the machine-checkable artifact that proves it was done.