zerodds-ast v1.0 — coverage
Source: docs/specs/zerodds-ast-1.0.md
Implementation: crates/ast-core, crates/ast, crates/ast-layout
Test run: cargo test -p zerodds-ast-core -p zerodds-ast -p zerodds-ast-layout — 321 passed, 0 failed.
Fuzz: snapshot_reader 9,664,902 runs clean; model_snapshot 4,520,036 runs clean against the full format after two out-of-memory fixes.
Each row names the carrier — core node, facet, or layout — with the code path and the test that exercises it. A feature with no carrier is marked open with its reason.
§1 Storage and identity
Spec: Per-kind generational arenas; a stale handle must fail rather than address the node that later occupied the slot. NodeId is stable across snapshots and processes, allocated deterministically.
Repo: ast-core/src/arena.rs, ast-core/src/id.rs. Carrier: core.
Tests: arena::tests::handle_from_before_removal_is_stale_not_reused, arena::tests::removed_handles_never_read_back (proptest over arbitrary interleavings), id::tests::allocation_is_deterministic_for_the_same_sequence, two_fresh_models_agree_on_every_builtin_identity.
Status: done
§2 References and resolution state
Spec: Three-valued Resolved | Pending | Broken, never Option. A failed attempt records its cause and is not retried implicitly.
Repo: ast-core/src/reference.rs, ast/src/resolve.rs. Carrier: core.
Tests: an_unresolvable_name_lands_in_broken_with_not_found, an_ambiguous_name_reports_every_candidate, a_broken_reference_is_not_retried_by_a_later_pass, a_type_arriving_later_resolves_every_waiter_in_one_step.
Status: done
§3.1 Modules
Spec: Reopening a module across translation units merges into one node.
Repo: ast/src/node/module.rs, Ast::ensure_module. Carrier: core.
Tests: reopening_a_module_merges_into_the_same_node, nested_modules_are_addressable_by_path.
Status: done
§3.2 Types
Spec: The TypeKind table, row for row, including float128, fixed, bitset, valuetype, value box, native, object reference and annotation type. A forward declaration is a completeness state, not a kind.
Repo: ast/src/node/type_.rs. Carrier: core.
Tests: every_primitive_of_the_spec_table_is_representable (asserts the set is exactly fifteen), a_forward_declared_type_completes_without_invalidating_handles, every_valuetype_modifier_is_representable.
Status: done
§3.3 Members and aggregate parts
Spec: Members, cases, enumerators, bit values, bitfields. An explicit @value or @position stays distinguishable from a positional one.
Repo: ast/src/node/member.rs. Carrier: core.
Tests: a_positional_enumerator_and_an_explicit_value_are_distinguishable, a_positional_bit_and_an_explicit_position_are_distinguishable, a_default_case_is_recorded_on_the_union_as_well_as_in_the_case_list, an_anonymous_bitfield_carries_no_name.
Status: done
§3.4 Interfaces and operations
Spec: Seven interface forms, operations with directions and raises, attributes, exceptions. CCM roles ride in the CORBA facet.
Repo: ast/src/node/interface.rs, ast/src/node/exception.rs, ast/src/facet/corba.rs. Carrier: core + facet.
Tests: all_seven_interface_kinds_are_representable, an_operation_records_its_parameters_in_order_with_directions, interface_inheritance_records_every_base_in_order.
Status: done
§3.5 Constants
Spec: Expression trees retained, not folded. Evaluation is a query with checked arithmetic that fails loudly on an unresolved name.
Repo: ast/src/node/constant.rs, Ast::eval_integral. Carrier: core.
Tests: an_expression_tree_survives_as_a_tree, evaluation_yields_the_folded_value_without_mutating_the_tree, division_by_zero_is_an_error_not_a_panic, overflow_is_an_error_not_a_wrap, evaluating_through_an_unresolved_name_fails_loudly, float_literals_retain_their_written_form.
Status: done
§3.6 Annotations
Spec: Thirty built-ins as ordinary declarations in a builtin module, identical across models.
Repo: ast/src/node/annotation.rs, Ast::populate_builtins. Carrier: core.
Tests: every_builtin_annotation_of_the_spec_list_is_present, builtin_identities_come_from_the_builtin_space, two_fresh_models_agree_on_every_builtin_identity.
Status: done
§3.7 Deployment
Spec: Domains, topics, QoS profiles with typed policy values, participants, endpoints, libraries. An unwritten policy field stays distinguishable from a defaulted one.
Repo: ast/src/node/deployment.rs. Carrier: core.
Tests: all_twenty_four_qos_policies_are_representable, an_unwritten_policy_field_stays_distinguishable_from_a_default_one, a_profile_may_inherit_from_another_profile.
Status: done
§4 Facets
Spec: XTypes, CORBA, ROS 2, DDS-XML, FlatData, vendor and source, each a struct. Vendor directives are not normalised into core constructs.
Repo: ast/src/facet/. Carrier: facet.
Tests: facets_from_different_sources_coexist_on_one_node, vendor_directives_are_not_normalised_into_core_constructs, an_absent_facet_is_none_not_a_default_populated_struct, the_effective_member_id_and_its_origin_are_both_retained.
Status: done
§5 Transactions and events
Spec: One mutation path; a rejected commit restores the model exactly; observers see only committed state.
Repo: ast/src/edit.rs, ast-core/src/txn.rs, ast-core/src/observer.rs. Carrier: core.
Tests: a_rejected_commit_restores_the_model_and_notifies_nobody, a_transaction_dropped_unfinished_rolls_back, observers_never_see_an_intermediate_state, deleting_a_referenced_type_breaks_incoming_references_rather_than_dangling.
Status: done
§6 Traversal and indices
Spec: Cycle-safe walking; four indices maintained from the changeset.
Repo: ast-core/src/walk.rs, ast-core/src/index.rs, ast/src/query.rs. Carrier: core.
Tests: a_mutual_cycle_terminates_and_visits_each_node_once, a_deep_chain_does_not_depend_on_stack_depth (100k nodes), deleting_a_type_removes_it_from_the_index_in_the_same_commit, descendants_of_a_recursive_type_terminate_with_the_type_appearing_once.
Status: done
§7 Layout view
Spec: Plans per encoding, endianness and purpose; offsets endianness-invariant; every wire rule in one place.
Repo: ast-layout/src/xcdr.rs, ast-layout/src/cache.rs, ast-layout/src/keyhash.rs. Carrier: layout.
Tests: offsets_are_shared_between_little_and_big_endian, a_change_evicts_the_type_and_its_dependents_and_nothing_else, an_unresolved_member_type_fails_loudly_rather_than_guessing_a_size, plus V-1…V-12 in tests/wire_vectors.rs.
Status: done — XCDR2 against the OMG vectors V-1…V-12 in tests/wire_vectors.rs; XCDR1 PL_CDR1 against the rules in crates/cdr/src/xcdr1.rs in tests/xcdr1_gate.rs, which caught the missing length > 0xFFFF extended-header condition and the absent PID_LIST_END sentinel. Length codes cross-checked against what Fast DDS and Cyclone emit.
§7.1 Length-code policy
Spec: Both framings XTypes 1.3 §7.4.3.4.2 permits are configurable; the default is the one the other implementations emit, and an unrecognised setting is rejected rather than silently defaulted.
Repo: ast-layout/src/key.rs — LengthCodePolicy, LayoutKey::with_length_codes. Carrier: layout.
Decision: Compact (LC5/LC6/LC7) is the default. Verified in the reference sources on the Linux test host: Fast DDS joins the NEXTINT with the member’s length word (Fast-CDR v2.3.5, include/fastcdr/CdrSizeCalculator.hpp::get_serialized_member_size), Cyclone returns LENGTH_CODE_ALSO_NEXTINT for strings (Cyclone DDS 11.0.1, src/core/cdr/src/dds_cdrstream.c::get_length_code). RTI keeps its selection in the binaries and is evidence in neither direction. UniversalNextInt (LC4 throughout) stays reachable as a flag, because the pre-rebuild emitters produced it and OMG wire vector V-10 is pinned in that shape.
Tests: the_default_policy_is_the_one_the_other_implementations_emit, the_policy_parses_from_a_configuration_value_and_rejects_a_typo, the_two_policies_produce_different_framing_for_the_same_type, plus the V-10 pair in tests/wire_vectors.rs covering both forms.
Status: done
§8.1 Structural invariants
Spec: Checked on every commit, all violations reported, pending and broken references not violations.
Repo: ast/src/invariant.rs. Carrier: core.
Tests: duplicate_member_ids_are_rejected_with_both_offenders_named, a_pending_reference_is_not_an_invariant_violation, the_same_label_is_accepted_while_the_discriminator_is_still_pending, every_violation_is_reported_rather_than_only_the_first.
Status: done
§8.2 Profile validation
Spec: Per-specification rules with paragraph references; the same model may pass one profile and fail another.
Repo: ast/src/profile/mod.rs, ast/src/profile/verdict.rs. Carrier: core.
Tests: a_map_is_valid_under_xtypes_and_invalid_under_corba_33, a_violation_names_its_rule_and_its_specification_paragraph, ros_2_rejects_a_union_and_a_wide_string, a_plain_flatdata_type_may_not_reach_a_string.
Status: done — profile/verdict.rs rules on every construct (21) and every facet property (14) in every profile (7) with no catch-all arm, so an unruled pair is a compile error. tests/profile_table.rs builds one instance of each construct and asserts validate() reports exactly what the table rejects.
§9 Snapshot
Spec: Round-trip preserves every NodeId; re-serialisation is byte-identical; malformed input is a typed error.
Repo: ast-core/src/snapshot.rs, ast/src/snapshot.rs. Carrier: core.
Tests: a_populated_model_round_trips_preserving_every_node_id, re_serialising_a_loaded_model_is_byte_identical, two_independently_built_identical_models_snapshot_identically, a_snapshot_declaring_more_elements_than_the_buffer_holds_is_rejected, a_snapshot_naming_a_slot_beyond_its_capacity_is_rejected.
Status: done — every one of the 22 node kinds round-trips, with the full facet payload. tests/snapshot_sections.rs covers each section on its own so a break names its section (a_module_round_trips, a_type_round_trips, a_struct_member_round_trips, an_interface_with_an_operation_round_trips, the_deployment_layer_round_trips, facets_survive); every_xtypes_field_survives_the_round_trip, every_corba_field_survives_the_round_trip and every_ros2_and_xml_field_survives_the_round_trip assert beforehand that the fixture really holds every facet field. A Pending reference comes back on its key and resolves after the load (a_pending_reference_comes_back_pending_on_the_same_key), a Broken one with its cause (a_broken_reference_keeps_its_cause), and a constant keeps its type (a_constant_round_trips).
§10 Error model
Spec: No panic on any reachable path; typed errors carrying the offending node.
Repo: ast/src/error.rs, ast-core/src/snapshot.rs, ast-layout/src/plan.rs; the workspace lints deny unwrap_used, expect_used, panic, todo, unimplemented, unreachable. Carrier: all three.
Tests: snapshot::tests::a_truncated_stream_is_an_error_not_a_partial_value, snapshot::tests::a_length_prefix_beyond_the_buffer_is_rejected, snapshot::tests::the_header_round_trips_and_a_wrong_magic_is_rejected, snapshot::tests::an_unknown_version_is_rejected, arena::tests::double_remove_is_an_error_not_a_second_value, an_unresolved_member_type_fails_loudly_rather_than_guessing_a_size — each case yields a typed error rather than a panic. Plus the lint barrier cargo clippy --all-targets -- -D warnings across the three crates and both fuzz targets.
Status: done
§11 Coverage obligation
Spec: §11 — completeness of the superset MUST be demonstrated in docs/spec-coverage/zerodds-ast-1.0.md as a bilingual pair; each row names one specification feature with its paragraph reference, its carrier (core node, facet or layout view), the implementing code path and the test that exercises it. An empty cell is an open break and is reported as one.
Repo: docs/spec-coverage/zerodds-ast-1.0.md + docs/spec-coverage/zerodds-ast-1.0.en.md. Carrier: all three — the obligation sits on the document, not on a crate.
Tests: tools/traceability/tests/ast_coverage_obligation.rs::the_pair_carries_the_same_rows_in_the_same_order (bilingual pair, same rows, same status), tools/traceability/tests/ast_coverage_obligation.rs::no_done_row_leaves_a_cell_empty (no empty cell under done), tools/traceability/tests/ast_coverage_obligation.rs::every_cited_test_name_exists_in_the_three_crates (every cited test name is defined in ast-core/ast/ast-layout), tools/traceability/tests/ast_coverage_obligation.rs::every_row_names_its_carrier, tools/traceability/tests/ast_coverage_obligation.rs::the_audit_aggregate_matches_the_rows.
Status: done
Audit status
19 done / 0 partial / 0 open / 0 blocked / 0 n/a (informative).
Test run: cargo test -p zerodds-ast-core -p zerodds-ast -p zerodds-ast-layout — 321 passed, 0 failed.
§11 obligation checked mechanically: cargo test -p zerodds-traceability --test ast_coverage_obligation — 5 passed, 0 failed.
Open items: none.
zerodds-ast v1.0 — Coverage
Quelle: docs/specs/zerodds-ast-1.0.md
Implementation: crates/ast-core, crates/ast, crates/ast-layout
Test-Lauf: cargo test -p zerodds-ast-core -p zerodds-ast -p zerodds-ast-layout — 321 bestanden, 0 fehlgeschlagen.
Fuzz: snapshot_reader 9.664.902 Läufe ohne Fund; model_snapshot 4.520.036 Läufe ohne Fund gegen das volle Format nach zwei Out-of-Memory-Fixes.
Jede Zeile nennt den Träger — Kern-Knoten, Facette oder Layout — mit Code-Pfad und dem Test, der ihn prüft. Ein Feature ohne Träger steht als offen mit seinem Grund.
§1 Speicher und Identität
Spec: Generationsbehaftete Arenen pro Knotenart; ein veraltetes Handle muss fehlschlagen, statt den Knoten anzusprechen, der den Slot später belegt. NodeId ist über Snapshots und Prozesse stabil und wird deterministisch vergeben.
Repo: ast-core/src/arena.rs, ast-core/src/id.rs. Träger: Kern.
Tests: arena::tests::handle_from_before_removal_is_stale_not_reused, arena::tests::removed_handles_never_read_back (proptest über beliebige Verschränkungen), id::tests::allocation_is_deterministic_for_the_same_sequence, two_fresh_models_agree_on_every_builtin_identity.
Status: done
§2 Referenzen und Auflösungszustand
Spec: Dreiwertig Resolved | Pending | Broken, nie Option. Ein gescheiterter Versuch hält seine Ursache fest und wird nicht implizit wiederholt.
Repo: ast-core/src/reference.rs, ast/src/resolve.rs. Träger: Kern.
Tests: an_unresolvable_name_lands_in_broken_with_not_found, an_ambiguous_name_reports_every_candidate, a_broken_reference_is_not_retried_by_a_later_pass, a_type_arriving_later_resolves_every_waiter_in_one_step.
Status: done
§3.1 Module
Spec: Ein über Übersetzungseinheiten hinweg wiedergeöffnetes Modul verschmilzt zu einem Knoten.
Repo: ast/src/node/module.rs, Ast::ensure_module. Träger: Kern.
Tests: reopening_a_module_merges_into_the_same_node, nested_modules_are_addressable_by_path.
Status: done
§3.2 Typen
Spec: Die TypeKind-Tabelle Zeile für Zeile, inklusive float128, fixed, Bitset, Valuetype, Value-Box, Native, Object-Reference und Annotation-Typ. Eine Forward-Deklaration ist ein Vollständigkeitszustand, keine eigene Art.
Repo: ast/src/node/type_.rs. Träger: Kern.
Tests: every_primitive_of_the_spec_table_is_representable (prüft, dass die Menge genau fünfzehn Einträge hat), a_forward_declared_type_completes_without_invalidating_handles, every_valuetype_modifier_is_representable.
Status: done
§3.3 Member und Aggregat-Teile
Spec: Member, Cases, Enumeratoren, Bit-Werte, Bitfields. Ein explizites @value oder @position bleibt von einem positionellen unterscheidbar.
Repo: ast/src/node/member.rs. Träger: Kern.
Tests: a_positional_enumerator_and_an_explicit_value_are_distinguishable, a_positional_bit_and_an_explicit_position_are_distinguishable, a_default_case_is_recorded_on_the_union_as_well_as_in_the_case_list, an_anonymous_bitfield_carries_no_name.
Status: done
§3.4 Interfaces und Operationen
Spec: Sieben Interface-Formen, Operationen mit Richtungen und raises, Attribute, Exceptions. CCM-Rollen sitzen in der CORBA-Facette.
Repo: ast/src/node/interface.rs, ast/src/node/exception.rs, ast/src/facet/corba.rs. Träger: Kern + Facette.
Tests: all_seven_interface_kinds_are_representable, an_operation_records_its_parameters_in_order_with_directions, interface_inheritance_records_every_base_in_order.
Status: done
§3.5 Konstanten
Spec: Ausdrucksbäume bleiben erhalten, werden nicht gefaltet. Auswertung ist eine Query mit geprüfter Arithmetik, die bei einem unaufgelösten Namen laut fehlschlägt.
Repo: ast/src/node/constant.rs, Ast::eval_integral. Träger: Kern.
Tests: an_expression_tree_survives_as_a_tree, evaluation_yields_the_folded_value_without_mutating_the_tree, division_by_zero_is_an_error_not_a_panic, overflow_is_an_error_not_a_wrap, evaluating_through_an_unresolved_name_fails_loudly, float_literals_retain_their_written_form.
Status: done
§3.6 Annotationen
Spec: Dreißig Builtins als gewöhnliche Deklarationen in einem Builtin-Modul, über Modelle hinweg identisch.
Repo: ast/src/node/annotation.rs, Ast::populate_builtins. Träger: Kern.
Tests: every_builtin_annotation_of_the_spec_list_is_present, builtin_identities_come_from_the_builtin_space, two_fresh_models_agree_on_every_builtin_identity.
Status: done
§3.7 Deployment
Spec: Domains, Topics, QoS-Profile mit typisierten Policy-Werten, Participants, Endpoints, Libraries. Ein nicht geschriebenes Policy-Feld bleibt von einem auf Default gesetzten unterscheidbar.
Repo: ast/src/node/deployment.rs. Träger: Kern.
Tests: all_twenty_four_qos_policies_are_representable, an_unwritten_policy_field_stays_distinguishable_from_a_default_one, a_profile_may_inherit_from_another_profile.
Status: done
§4 Facetten
Spec: XTypes, CORBA, ROS 2, DDS-XML, FlatData, Vendor und Source, jede ein struct. Vendor-Direktiven werden nicht in Kern-Konstrukte normalisiert.
Repo: ast/src/facet/. Träger: Facette.
Tests: facets_from_different_sources_coexist_on_one_node, vendor_directives_are_not_normalised_into_core_constructs, an_absent_facet_is_none_not_a_default_populated_struct, the_effective_member_id_and_its_origin_are_both_retained.
Status: done
§5 Transaktionen und Events
Spec: Ein Mutationspfad; ein abgelehnter Commit stellt das Modell exakt wieder her; Observer sehen nur committeten Zustand.
Repo: ast/src/edit.rs, ast-core/src/txn.rs, ast-core/src/observer.rs. Träger: Kern.
Tests: a_rejected_commit_restores_the_model_and_notifies_nobody, a_transaction_dropped_unfinished_rolls_back, observers_never_see_an_intermediate_state, deleting_a_referenced_type_breaks_incoming_references_rather_than_dangling.
Status: done
§6 Traversierung und Indizes
Spec: Zyklensicheres Walking; vier Indizes, aus dem Changeset gepflegt.
Repo: ast-core/src/walk.rs, ast-core/src/index.rs, ast/src/query.rs. Träger: Kern.
Tests: a_mutual_cycle_terminates_and_visits_each_node_once, a_deep_chain_does_not_depend_on_stack_depth (100k Knoten), deleting_a_type_removes_it_from_the_index_in_the_same_commit, descendants_of_a_recursive_type_terminate_with_the_type_appearing_once.
Status: done
§7 Layout-View
Spec: Pläne pro Encoding, Endianness und Zweck; Offsets endianness-invariant; jede Wire-Regel an genau einer Stelle.
Repo: ast-layout/src/xcdr.rs, ast-layout/src/cache.rs, ast-layout/src/keyhash.rs. Träger: Layout.
Tests: offsets_are_shared_between_little_and_big_endian, a_change_evicts_the_type_and_its_dependents_and_nothing_else, an_unresolved_member_type_fails_loudly_rather_than_guessing_a_size, dazu V-1…V-12 in tests/wire_vectors.rs.
Status: done — XCDR2 gegen die OMG-Vektoren V-1…V-12 in tests/wire_vectors.rs; XCDR1-PL_CDR1 gegen die Regeln in crates/cdr/src/xcdr1.rs in tests/xcdr1_gate.rs, was die fehlende length > 0xFFFF-Bedingung für den extended Header und den fehlenden PID_LIST_END-Sentinel aufdeckte. Length-Codes gegen das abgeglichen, was Fast DDS und Cyclone emittieren.
§7.1 Length-Code-Policy
Spec: Beide Rahmungen, die XTypes 1.3 §7.4.3.4.2 erlaubt, sind konfigurierbar; der Default ist die Form, die die anderen Implementierungen emittieren, und ein unbekannter Wert wird abgelehnt statt still auf den Default zu fallen.
Repo: ast-layout/src/key.rs — LengthCodePolicy, LayoutKey::with_length_codes. Träger: Layout.
Entscheidung: Compact (LC5/LC6/LC7) ist der Default. In den Referenz-Quellen auf dem Linux-Testhost verifiziert: Fast DDS legt den NEXTINT mit dem Längenwort des Members zusammen (Fast-CDR v2.3.5, include/fastcdr/CdrSizeCalculator.hpp::get_serialized_member_size), Cyclone liefert LENGTH_CODE_ALSO_NEXTINT für Strings (Cyclone DDS 11.0.1, src/core/cdr/src/dds_cdrstream.c::get_length_code). RTI hält seine Auswahl in den Binaries und ist damit kein Beleg in beide Richtungen. UniversalNextInt (durchgehend LC4) bleibt als Flag erreichbar, weil die Emitter vor dem Rebuild das erzeugten und der OMG-Wire-Vektor V-10 in dieser Form fixiert ist.
Tests: the_default_policy_is_the_one_the_other_implementations_emit, the_policy_parses_from_a_configuration_value_and_rejects_a_typo, the_two_policies_produce_different_framing_for_the_same_type, dazu das V-10-Paar in tests/wire_vectors.rs, das beide Formen abdeckt.
Status: done
§8.1 Strukturelle Invarianten
Spec: Bei jedem Commit geprüft, alle Verletzungen gemeldet, Pending und Broken sind keine Verletzungen.
Repo: ast/src/invariant.rs. Träger: Kern.
Tests: duplicate_member_ids_are_rejected_with_both_offenders_named, a_pending_reference_is_not_an_invariant_violation, the_same_label_is_accepted_while_the_discriminator_is_still_pending, every_violation_is_reported_rather_than_only_the_first.
Status: done
§8.2 Profil-Validierung
Spec: Regeln pro Spezifikation mit Paragrafen-Referenz; dasselbe Modell kann ein Profil bestehen und ein anderes nicht.
Repo: ast/src/profile/mod.rs, ast/src/profile/verdict.rs. Träger: Kern.
Tests: a_map_is_valid_under_xtypes_and_invalid_under_corba_33, a_violation_names_its_rule_and_its_specification_paragraph, ros_2_rejects_a_union_and_a_wide_string, a_plain_flatdata_type_may_not_reach_a_string.
Status: done — profile/verdict.rs urteilt über jedes Konstrukt (21) und jede Facetten-Eigenschaft (14) in jedem Profil (7), ohne Catch-all-Arm; eine nicht beurteilte Paarung ist ein Compile-Fehler. tests/profile_table.rs baut je eine Instanz jedes Konstrukts und prüft, dass validate() genau meldet, was die Tabelle ablehnt.
§9 Snapshot
Spec: Round-Trip erhält jede NodeId; Re-Serialisierung ist byte-identisch; fehlerhafte Eingabe ist ein typisierter Fehler.
Repo: ast-core/src/snapshot.rs, ast/src/snapshot.rs. Träger: Kern.
Tests: a_populated_model_round_trips_preserving_every_node_id, re_serialising_a_loaded_model_is_byte_identical, two_independently_built_identical_models_snapshot_identically, a_snapshot_declaring_more_elements_than_the_buffer_holds_is_rejected, a_snapshot_naming_a_slot_beyond_its_capacity_is_rejected.
Status: done — alle 22 Knotenarten laufen durch den Roundtrip, samt voller Facetten-Nutzlast. tests/snapshot_sections.rs deckt jede Sektion einzeln ab, damit ein Bruch seine Sektion benennt (a_module_round_trips, a_type_round_trips, a_struct_member_round_trips, an_interface_with_an_operation_round_trips, the_deployment_layer_round_trips, facets_survive); every_xtypes_field_survives_the_round_trip, every_corba_field_survives_the_round_trip und every_ros2_and_xml_field_survives_the_round_trip prüfen vorher, dass das Fixture wirklich jedes Facetten-Feld hält. Eine Pending-Referenz kommt mit ihrem Schlüssel zurück und löst sich nach dem Laden auf (a_pending_reference_comes_back_pending_on_the_same_key), eine Broken-Referenz mit ihrer Ursache (a_broken_reference_keeps_its_cause), und eine Konstante behält ihren Typ (a_constant_round_trips).
§10 Fehlermodell
Spec: Kein Panic auf erreichbarem Pfad; typisierte Fehler mit dem betroffenen Knoten.
Repo: ast/src/error.rs, ast-core/src/snapshot.rs, ast-layout/src/plan.rs; die Workspace-Lints setzen unwrap_used, expect_used, panic, todo, unimplemented, unreachable auf deny. Träger: alle drei.
Tests: snapshot::tests::a_truncated_stream_is_an_error_not_a_partial_value, snapshot::tests::a_length_prefix_beyond_the_buffer_is_rejected, snapshot::tests::the_header_round_trips_and_a_wrong_magic_is_rejected, snapshot::tests::an_unknown_version_is_rejected, arena::tests::double_remove_is_an_error_not_a_second_value, an_unresolved_member_type_fails_loudly_rather_than_guessing_a_size — jeder Fall liefert einen typisierten Fehler statt eines Panics. Dazu die Lint-Schranke cargo clippy --all-targets -- -D warnings über die drei Crates und beide Fuzz-Targets.
Status: done
§11 Coverage-Pflicht
Spec: §11 — die Vollständigkeit des Supersets MUSS in docs/spec-coverage/zerodds-ast-1.0.md als zweisprachiges Paar nachgewiesen werden; jede Zeile nennt ein Spec-Feature mit Paragrafen-Referenz, ihren Träger (Kern-Knoten, Facette oder Layout-View), den Code-Pfad und den Test, der ihn prüft. Eine leere Zelle ist ein offener Bruch und wird als solcher gemeldet.
Repo: docs/spec-coverage/zerodds-ast-1.0.md + docs/spec-coverage/zerodds-ast-1.0.en.md. Träger: alle drei — die Pflicht liegt auf dem Dokument, nicht auf einer Crate.
Tests: tools/traceability/tests/ast_coverage_obligation.rs::the_pair_carries_the_same_rows_in_the_same_order (zweisprachiges Paar, gleiche Zeilen, gleicher Status), tools/traceability/tests/ast_coverage_obligation.rs::no_done_row_leaves_a_cell_empty (keine leere Zelle unter done), tools/traceability/tests/ast_coverage_obligation.rs::every_cited_test_name_exists_in_the_three_crates (jeder zitierte Testname ist in ast-core/ast/ast-layout definiert), tools/traceability/tests/ast_coverage_obligation.rs::every_row_names_its_carrier, tools/traceability/tests/ast_coverage_obligation.rs::the_audit_aggregate_matches_the_rows.
Status: done
Audit-Status
19 done / 0 partial / 0 open / 0 blocked / 0 n/a (informative).
Test-Lauf: cargo test -p zerodds-ast-core -p zerodds-ast -p zerodds-ast-layout — 321 bestanden, 0 fehlgeschlagen.
§11-Pflicht mechanisch geprüft: cargo test -p zerodds-traceability --test ast_coverage_obligation — 5 bestanden, 0 fehlgeschlagen.
Offene Punkte: keine.