Type Certificate Data Sheet (systems-engineering-safety/continued-airworthiness/type-certificate-data-sheet)
Use when a type certificate data sheet style type design record must be
compiled, validated or revised: checking the required section set, the
weight block, the category airspeed limitations and the approved engine
and propeller configuration, then summarizing counts or diffing two
revisions for a type certificate amendment or an STC integration review.
This leaf implements the TCDS record checks in pure Python, stdlib only:
every check is a small deterministic function over a plain dict record.
It pairs with the certification-basis leaf in this family, which decides
the regulation set and approval route that the certification_basis
section of the record then quotes, and with the airworthiness-limitation
leaf in this pack, which reads type-certificate limitation data as an
input to maintenance-program checks.
Domain quick reference
- Record shape: a dict with a "category" key plus the required sections
REQUIRED_SECTIONS = (models, type_design, engine_models,
propeller_models, weights, certification_basis,
operating_limitations, noise_standards). The models, engine_models and
propeller_models sections are lists, weights is a dict holding
max_ramp, max_takeoff and max_landing, and operating_limitations is a
dict of named limits.
- Section presence: missing_sections returns the REQUIRED_SECTIONS keys
absent from the record. Content checks inside sections that exist are
separate: a missing section is reported once by missing_sections.
- Weight block rules: every weight is positive; max_ramp at or above
max_takeoff (ramp below takeoff is an error, the fuel for start and
taxi is not yet burned); max_landing at or below max_takeoff (landing
weight is limited to the takeoff certified value).
- Category airspeed rules (CATEGORY_AIRSPEED_KEYS): transport requires
VMO or MMO, any one key present and positive satisfies the rule;
normal, utility and acrobatic categories require VNE. These follow the
Part 25 transport limit philosophy (VMO/MMO envelope) versus the
legacy Part 23 category rule set (VNE placard), handled here as data.
- Approved configuration: a TCDS lists the approved engine and
propeller models, so engine_models and propeller_models must be
non-empty; operating_limitations may carry an optional "engines" list
of engine model references and each reference must appear in
engine_models.
- Revision diff: tcds_revision_diff maps each section key to unchanged,
added, removed or modified, reports the per-model change of the models
section as models_added and models_removed, and the weight changes as
"_delta" floats such as max_takeoff_delta.
- Units: weights in the worked examples are kg and airspeeds are labeled
in the record (ktas for VMO, Mach for MMO); limits keep the units the
record declares, values are compared as numbers.
- Regulatory frame: FAR 25 is named only as the transport certification
standard the sheet records, with the legacy Part 23 category rules and
the FAR 36 noise standards treated as data entries.
Workflow
- Assemble the draft type design record as a dict with a "category" key
and the section keys of the sheet being compiled.
- Check section presence with missing_sections(record) and fill any
REQUIRED_SECTIONS key that is absent.
- Validate the weight block with weight_errors(record) and correct any
missing, non-positive or inconsistent weight entries.
- Validate the category airspeed limitations with
airspeed_errors(record): transport needs VMO or MMO, the smaller
categories need VNE.
- Check the approved configuration with approved_config_errors(record):
non-empty engine and propeller model lists and, when present, engine
references in operating_limitations that all appear in engine_models.
- Run the aggregate check validate_tcds(record) and read the
missing_sections, weight_errors, airspeed_errors, config_errors lists
and the valid flag; valid is True exactly when all four lists are
empty.
- Summarize the record with tcds_summary(record) for the model counts,
the max takeoff weight and the sorted airspeed limit list.
- For a type certificate amendment or STC integration review, diff the
old and new revisions with tcds_revision_diff(old, new) and read the
per-section statuses, the added and removed models, and the weight
deltas.
- Confirm the deterministic checks with the contract test
scripts/test_type-certificate-data-sheet.py.
Worked example
Record A: category "transport", models ["T-100"], type_design "T-100
basic", engine_models ["E-1", "E-2"], propeller_models ["P-1"], weights
{max_ramp 80000, max_takeoff 79000, max_landing 70000} (kg),
certification_basis ["far-25"], operating_limitations {vmo 340 (ktas),
mmo 0.84}, noise_standards ["far-36"].
- missing_sections(A) == [], weight_errors(A) == [],
airspeed_errors(A) == [] (transport satisfied by vmo 340),
approved_config_errors(A) == [].
- validate_tcds(A) valid True with all four error lists empty.
- tcds_summary(A): models 1, engine_models 2, propeller_models 1,
max_takeoff_weight 79000.0, airspeed_limits ["mmo=0.84", "vmo=340"].
- Record B: category "normal" with weights {max_ramp 75000,
max_takeoff 79000, max_landing 70000} and operating_limitations {}:
weight_errors(B) = ["max_ramp below max_takeoff"] and
airspeed_errors(B) = ["missing vne for category normal"], so
validate_tcds(B) valid False.
- Revision A2 adds model "T-101" and changes max_takeoff to 79400:
tcds_revision_diff(A, A2) reports sections models "modified" and
weights "modified", models_added ["T-101"], models_removed [], and
weight_deltas {"max_takeoff_delta": 400.0}.
- Configuration spot check: operating_limitations with an "engines"
list ["E-9"] gives the error "engine reference E-9 not in approved
engine models".
Verification
- Confirm missing_sections on a record without propeller_models and
noise_standards returns exactly those two, in section order.
- Confirm the weight rules: ramp below takeoff flagged, landing above
takeoff flagged, non-positive and zero weights flagged, and a record
with no weights section returns no weight errors (section absence is
reported by missing_sections).
- Confirm the airspeed truth table across all four categories and that
an unknown category is flagged.
- Confirm validate_tcds(A) valid True and validate_tcds(B) valid False
with the two content errors of the worked example.
- Confirm the identities: valid equals all four error lists empty,
summary counts equal their list lengths, a diff of a record with
itself is all "unchanged", and models_added and models_removed are
disjoint.
- Confirm ValueError rejection of non-physical inputs: a record without
a "category" key, a weights section that is not a dict, an
operating_limitations section that is not a dict, and non-numeric
weight or airspeed values.
- Confirm the module is deterministic: the same record gives the same
validation dict on every run.
- Run the contract test offline: python3
scripts/test_type-certificate-data-sheet.py (35 tests,
deterministic).
Related leaves
- systems-engineering-safety/certification/certification-basis: decides
the regulation set and approval route that the certification_basis
section of the record then quotes.
- systems-engineering-safety/continued-airworthiness/
ica-cmr-ali-classification: downstream in this pack, consumes the
type-certificate limitation data when a maintenance program is checked
against the airworthiness limitations of the type.
- systems-engineering-safety/continued-airworthiness/
in-service-safety-assessment: the field review that reacts to events
on the certified type after it enters service.
- systems-engineering-safety/arp4754a/configuration-management: change
control over the type design record when the sheet is amended.
Pitfalls
- Confusing section presence with section content: missing_sections
reports only absent REQUIRED_SECTIONS keys, so a record with a weights
section whose keys are wrong gets no missing-section entry but does
get "missing weight key ..." entries from weight_errors; read both
lists from validate_tcds.
- Treating a present but empty section as complete: operating_limitations
{} is present, so it never appears in missing_sections, yet the
category airspeed rule still fails for it (Record B shows exactly
this: no missing sections, but "missing vne for category normal").
- Requiring every airspeed key: the category rule needs any one listed
key present and positive, so a transport record with VMO alone is
valid without MMO, and MMO alone satisfies it too.
- Checking engine references against an empty approved list: when
engine_models is empty the config check reports "no approved engine
models listed" and skips the reference comparison, so an "engines"
entry does not cascade into duplicate reference errors.
- Ignoring the units declared in the record: the worked example mixes
ktas (VMO 340) and Mach (MMO 0.84) inside one operating_limitations
dict, and weights in kg; values are compared as numbers with the units
treated as labels, so compare like for like.
- Reading a revision diff as a full history: tcds_revision_diff gives
the state change between exactly two revisions, not the amendment
trail, and a reordering of models inside the list counts as
"modified" with empty added and removed lists.
Behavior contract (gate 3)
Run the deterministic contract test (stdlib unittest, offline):
python3 scripts/test_type-certificate-data-sheet.py
The test covers the worked example (record A valid, record B invalid
with "max_ramp below max_takeoff" and "missing vne for category
normal"), the missing-section lists on partial records, the weight rule
truth table (ramp below takeoff, landing above takeoff, non-positive
and missing weight keys), the category airspeed truth table across all
four categories with the unknown-category flag, the approved
configuration checks including engine references, the summary counts
and sorted airspeed limits, the revision diff (added and removed
models, weight deltas, self-diff all unchanged, disjoint added and
removed), the identity valid == all error lists empty, determinism, and
ValueError rejection of records without a category, non-dict weights or
operating_limitations sections, and non-numeric values.
Compliance
- Standards referenced, not reproduced: FAR 25 frames the transport
certification basis that the sheet records and FAR 36 the noise
standards entry, while the legacy Part 23 category airspeed rule is
carried as data; all are named as context only and the rules above
are summary-only per standards-map.yaml.
- compliance: STANDARDS-REF, gated: false.
1---2name: type-certificate-data-sheet3description: Use when you must compile and validate a type certificate data sheet: check that every required section is present (models, type design, approved engines and propellers, weights, certification basis, operating limitations, noise standards), validate the weight block consistency (max ramp at or above max takeoff, max landing at or below max takeoff, all positive), validate the category airspeed limitations (transport requires VMO or MMO; normal, utility and acrobatic categories require VNE), check the approved configuration consistency, and diff two revisions of the record into a per-section change summary for type certificate amendment or STC integration review. Produces the missing-section list, the validation error list, the summary counts, and the revision change report. Trigger: type certificate data sheet, TCDS record, type design record, approved engine models, weight block, category airspeed limits, VMO, MMO, VNE, TCDS revision diff.4license: Apache-2.05---67# Type Certificate Data Sheet (systems-engineering-safety/continued-airworthiness/type-certificate-data-sheet)89Use when a type certificate data sheet style type design record must be10compiled, validated or revised: checking the required section set, the11weight block, the category airspeed limitations and the approved engine12and propeller configuration, then summarizing counts or diffing two13revisions for a type certificate amendment or an STC integration review.14This leaf implements the TCDS record checks in pure Python, stdlib only:15every check is a small deterministic function over a plain dict record.16It pairs with the certification-basis leaf in this family, which decides17the regulation set and approval route that the certification_basis18section of the record then quotes, and with the airworthiness-limitation19leaf in this pack, which reads type-certificate limitation data as an20input to maintenance-program checks.2122## Domain quick reference2324- Record shape: a dict with a "category" key plus the required sections25 REQUIRED_SECTIONS = (models, type_design, engine_models,26 propeller_models, weights, certification_basis,27 operating_limitations, noise_standards). The models, engine_models and28 propeller_models sections are lists, weights is a dict holding29 max_ramp, max_takeoff and max_landing, and operating_limitations is a30 dict of named limits.31- Section presence: missing_sections returns the REQUIRED_SECTIONS keys32 absent from the record. Content checks inside sections that exist are33 separate: a missing section is reported once by missing_sections.34- Weight block rules: every weight is positive; max_ramp at or above35 max_takeoff (ramp below takeoff is an error, the fuel for start and36 taxi is not yet burned); max_landing at or below max_takeoff (landing37 weight is limited to the takeoff certified value).38- Category airspeed rules (CATEGORY_AIRSPEED_KEYS): transport requires39 VMO or MMO, any one key present and positive satisfies the rule;40 normal, utility and acrobatic categories require VNE. These follow the41 Part 25 transport limit philosophy (VMO/MMO envelope) versus the42 legacy Part 23 category rule set (VNE placard), handled here as data.43- Approved configuration: a TCDS lists the approved engine and44 propeller models, so engine_models and propeller_models must be45 non-empty; operating_limitations may carry an optional "engines" list46 of engine model references and each reference must appear in47 engine_models.48- Revision diff: tcds_revision_diff maps each section key to unchanged,49 added, removed or modified, reports the per-model change of the models50 section as models_added and models_removed, and the weight changes as51 "<key>_delta" floats such as max_takeoff_delta.52- Units: weights in the worked examples are kg and airspeeds are labeled53 in the record (ktas for VMO, Mach for MMO); limits keep the units the54 record declares, values are compared as numbers.55- Regulatory frame: FAR 25 is named only as the transport certification56 standard the sheet records, with the legacy Part 23 category rules and57 the FAR 36 noise standards treated as data entries.5859## Workflow60611. Assemble the draft type design record as a dict with a "category" key62 and the section keys of the sheet being compiled.632. Check section presence with missing_sections(record) and fill any64 REQUIRED_SECTIONS key that is absent.653. Validate the weight block with weight_errors(record) and correct any66 missing, non-positive or inconsistent weight entries.674. Validate the category airspeed limitations with68 airspeed_errors(record): transport needs VMO or MMO, the smaller69 categories need VNE.705. Check the approved configuration with approved_config_errors(record):71 non-empty engine and propeller model lists and, when present, engine72 references in operating_limitations that all appear in engine_models.736. Run the aggregate check validate_tcds(record) and read the74 missing_sections, weight_errors, airspeed_errors, config_errors lists75 and the valid flag; valid is True exactly when all four lists are76 empty.777. Summarize the record with tcds_summary(record) for the model counts,78 the max takeoff weight and the sorted airspeed limit list.798. For a type certificate amendment or STC integration review, diff the80 old and new revisions with tcds_revision_diff(old, new) and read the81 per-section statuses, the added and removed models, and the weight82 deltas.839. Confirm the deterministic checks with the contract test84 scripts/test_type-certificate-data-sheet.py.8586## Worked example8788Record A: category "transport", models ["T-100"], type_design "T-10089basic", engine_models ["E-1", "E-2"], propeller_models ["P-1"], weights90{max_ramp 80000, max_takeoff 79000, max_landing 70000} (kg),91certification_basis ["far-25"], operating_limitations {vmo 340 (ktas),92mmo 0.84}, noise_standards ["far-36"].9394- missing_sections(A) == [], weight_errors(A) == [],95 airspeed_errors(A) == [] (transport satisfied by vmo 340),96 approved_config_errors(A) == [].97- validate_tcds(A) valid True with all four error lists empty.98- tcds_summary(A): models 1, engine_models 2, propeller_models 1,99 max_takeoff_weight 79000.0, airspeed_limits ["mmo=0.84", "vmo=340"].100- Record B: category "normal" with weights {max_ramp 75000,101 max_takeoff 79000, max_landing 70000} and operating_limitations {}:102 weight_errors(B) = ["max_ramp below max_takeoff"] and103 airspeed_errors(B) = ["missing vne for category normal"], so104 validate_tcds(B) valid False.105- Revision A2 adds model "T-101" and changes max_takeoff to 79400:106 tcds_revision_diff(A, A2) reports sections models "modified" and107 weights "modified", models_added ["T-101"], models_removed [], and108 weight_deltas {"max_takeoff_delta": 400.0}.109- Configuration spot check: operating_limitations with an "engines"110 list ["E-9"] gives the error "engine reference E-9 not in approved111 engine models".112113## Verification114115- Confirm missing_sections on a record without propeller_models and116 noise_standards returns exactly those two, in section order.117- Confirm the weight rules: ramp below takeoff flagged, landing above118 takeoff flagged, non-positive and zero weights flagged, and a record119 with no weights section returns no weight errors (section absence is120 reported by missing_sections).121- Confirm the airspeed truth table across all four categories and that122 an unknown category is flagged.123- Confirm validate_tcds(A) valid True and validate_tcds(B) valid False124 with the two content errors of the worked example.125- Confirm the identities: valid equals all four error lists empty,126 summary counts equal their list lengths, a diff of a record with127 itself is all "unchanged", and models_added and models_removed are128 disjoint.129- Confirm ValueError rejection of non-physical inputs: a record without130 a "category" key, a weights section that is not a dict, an131 operating_limitations section that is not a dict, and non-numeric132 weight or airspeed values.133- Confirm the module is deterministic: the same record gives the same134 validation dict on every run.135- Run the contract test offline: python3136 scripts/test_type-certificate-data-sheet.py (35 tests,137 deterministic).138139## Related leaves140141- systems-engineering-safety/certification/certification-basis: decides142 the regulation set and approval route that the certification_basis143 section of the record then quotes.144- systems-engineering-safety/continued-airworthiness/145 ica-cmr-ali-classification: downstream in this pack, consumes the146 type-certificate limitation data when a maintenance program is checked147 against the airworthiness limitations of the type.148- systems-engineering-safety/continued-airworthiness/149 in-service-safety-assessment: the field review that reacts to events150 on the certified type after it enters service.151- systems-engineering-safety/arp4754a/configuration-management: change152 control over the type design record when the sheet is amended.153154## Pitfalls155156- Confusing section presence with section content: missing_sections157 reports only absent REQUIRED_SECTIONS keys, so a record with a weights158 section whose keys are wrong gets no missing-section entry but does159 get "missing weight key ..." entries from weight_errors; read both160 lists from validate_tcds.161- Treating a present but empty section as complete: operating_limitations162 {} is present, so it never appears in missing_sections, yet the163 category airspeed rule still fails for it (Record B shows exactly164 this: no missing sections, but "missing vne for category normal").165- Requiring every airspeed key: the category rule needs any one listed166 key present and positive, so a transport record with VMO alone is167 valid without MMO, and MMO alone satisfies it too.168- Checking engine references against an empty approved list: when169 engine_models is empty the config check reports "no approved engine170 models listed" and skips the reference comparison, so an "engines"171 entry does not cascade into duplicate reference errors.172- Ignoring the units declared in the record: the worked example mixes173 ktas (VMO 340) and Mach (MMO 0.84) inside one operating_limitations174 dict, and weights in kg; values are compared as numbers with the units175 treated as labels, so compare like for like.176- Reading a revision diff as a full history: tcds_revision_diff gives177 the state change between exactly two revisions, not the amendment178 trail, and a reordering of models inside the list counts as179 "modified" with empty added and removed lists.180181## Behavior contract (gate 3)182183Run the deterministic contract test (stdlib unittest, offline):184185 python3 scripts/test_type-certificate-data-sheet.py186187The test covers the worked example (record A valid, record B invalid188with "max_ramp below max_takeoff" and "missing vne for category189normal"), the missing-section lists on partial records, the weight rule190truth table (ramp below takeoff, landing above takeoff, non-positive191and missing weight keys), the category airspeed truth table across all192four categories with the unknown-category flag, the approved193configuration checks including engine references, the summary counts194and sorted airspeed limits, the revision diff (added and removed195models, weight deltas, self-diff all unchanged, disjoint added and196removed), the identity valid == all error lists empty, determinism, and197ValueError rejection of records without a category, non-dict weights or198operating_limitations sections, and non-numeric values.199200## Compliance201202- Standards referenced, not reproduced: FAR 25 frames the transport203 certification basis that the sheet records and FAR 36 the noise204 standards entry, while the legacy Part 23 category airspeed rule is205 carried as data; all are named as context only and the rules above206 are summary-only per standards-map.yaml.207- compliance: STANDARDS-REF, gated: false.