Skip to content

Build-time consistency audit: parameter registry vs Fortran derived types #1573

Description

@sbryngelson

Motivation

The single largest bug class found during the 2026-06 refactoring series (#1550-#1572) was mirror drift: a parameter or type member added or removed on one side of a manual mirror without its counterpart. The starkest instance was #1562 — fourteen parameters registered in the toolchain whose Fortran type members had been removed a year earlier; setting any of them in a case file passed validation and then crashed the namelist read with a misleading datatype error.

The registry (toolchain/mfc/params/definitions.py) and the derived types (src/common/m_derived_types.fpp) are maintained by hand on both sides, with nothing checking they agree. #1553 fixed the current instances; nothing prevents recurrence.

Proposal

A build-time audit, run by the same ninja-tracked custom command that already generates the parameter includes (so it costs nothing extra to wire), that:

  1. Parses the struct-member declarations from m_derived_types.fpp for every type backing an indexed parameter family (fluid_pp, patch_icpp, bub_pp, lag_params, chem_params, ...).
  2. Asserts every registered member name + Fortran type class (REAL/INT/LOG/STR) exists in the corresponding derived type, and that every namelist-bound member of those types is registered.
  3. Fails the build with a named, two-sided diff on any mismatch ("registered but not in type: ...", "namelist-bound member not registered: ...").

Execution sketch

  • A new toolchain/mfc/params/generators/type_audit.py (~150 lines): a line-level Fortran declaration parser scoped to the known type blocks (the codebase's declaration style is uniform enough; the broadcast generator already does similar member-walking).
  • Wire into cmake_gen.py after generation; unit tests in params_tests/ with deliberately broken fixtures (member removed, member added, kind mismatch).
  • Validation: mutate one member locally and confirm the build fails with the named diff; then run the audit against current master to confirm it passes clean (it should, post-Fix three pre-existing multi-rank broadcast defects; deregister dead parameters #1553).
  • Effort: small (one toolchain file + tests). Risk: low — it only ever fails builds that would mis-run anyway.

Part of the structural theme proven by the series: make invariants structural, not disciplinary. Companion proposals: the registry-driven defaults and the validator/checker unification.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions