§1 — Problem (fully defined)

The thermal-fusion neutron-rate StandardName family is internally inconsistent. All members carry unit Hz (a count rate, s⁻¹), but they disagree on physical_base and the structural tree is broken. Current live/superseded members:

Two defects: (a) the two per-reaction children use base=flux, but "flux" denotes an areal density (m⁻²·s⁻¹); a total count rate in Hz is a source_rate, as the canonical name correctly uses. (b) Their structural parent neutron_flux_due_to_thermal_fusion is superseded, so two live derived names hang off a dead parent — an orphaned derivation the structural fixpoints cannot re-anchor.

CANONICAL (accepted, dd) total_neutron_source_rate_due_to_thermal_fusion — base=source_rate parent — SUPERSEDED (dead) neutron_flux_due_to_thermal_fusion — base=flux deuterium_deuterium_neutron_flux_due_to_thermal_fusion tritium_tritium_neutron_flux_due_to_thermal_fusion live children, base=flux [Hz] — wrong base, dead parent Target: align children to base=source_rate under a LIVE parent (the canonical total, or a re-derived neutron_source_rate parent).

§2 — Why it matters (motivation)

Mixed physical_base for one physical concept (a neutron count rate) means the same quantity is named two different ways depending on whether it is the total or a per-reaction channel — the catalog reads as if "flux" and "source_rate" are different physics when they are the same dimension. The dead structural parent is a latent ledger/graph inconsistency: a live derived name whose HAS_PARENT target is superseded cannot be regenerated or validated cleanly, and breaks the "derived child ⇒ live parent" expectation. It is small (2 live names) but a clear correctness/consistency fix. Surfaced by sn-pedestal-source-recovery (f-psr-006) while retiring the redundant manual flux_due_to_thermal_fusion.

✓ landed 2026-07-10

§3 — Executed

Both per-reaction children renamed flux→source_rate via the cascade (0 conflicts); the structural fixpoint re-derived a LIVE neutron_source_rate_due_to_thermal_fusion parent (structurally accepted), with total_neutron_source_rate_due_to_thermal_fusion correctly its child (total_ is an aggregation prefix — decision locked: rederive-parent); grammar segments realigned (physical_base=source_rate on all four); 0 orphans / 0 desyncs. The superseded flux names stay retired.

§3 — The decision + approach (reference)

The concept and correct base already exist (source_rate, on the canonical total). The fix aligns the per-reaction children to it and restores a live parent:

Mechanism: the deterministic rename cascade (sn run --rename OLD:NEW --include-accepted, --dry-run first), never a --focus recompose. Verify 0 orphans / 0 desyncs and that the live children point at a live parent.

§ Decisions

After renaming the per-reaction children to base=source_rate, what is their live structural parent?

derive_edges derives structural parents from the grammar: the renamed children strip their reaction-channel qualifier to neutron_source_rate_due_to_thermal_fusion, and total_ is itself an aggregation prefix — so the canonical total is a SIBLING-level derived child of the same parent, not a valid group parent. The structural fixpoint re-derived the parent automatically and it was structurally accepted.

§ Followups

Rename the fusion neutron-flux children to source_rate and restore a live parent

Align the two accepted per-reaction children (D-D, T-T) from base=flux to base=source_rate to match the canonical total_neutron_source_rate_due_to_thermal_fusion, and ensure they hang off a live parent (their current parent neutron_flux_due_to_thermal_fusion is superseded). Use the rename cascade; validate grammar round-trip. Spun out of sn-pedestal-source-recovery f-psr-006.
Project: imas-standard-names (grammar) + imas-codex (standard_names) + imas graph
Plan: sn-fusion-neutron-rate-naming (http://localhost:8765/imas-standard-names/sn-fusion-neutron-rate-naming.html)
Section: rename flux children to source_rate + restore live parent
Tier: sonnet

Context
  total_neutron_source_rate_due_to_thermal_fusion (base=source_rate, dd, accepted) is canonical. Two
  accepted DERIVED children — deuterium_deuterium_neutron_flux_due_to_thermal_fusion and
  tritium_tritium_neutron_flux_due_to_thermal_fusion — still use base=flux [Hz] and hang off the
  SUPERSEDED parent neutron_flux_due_to_thermal_fusion. Honour the fusion-child-parent decision shown
  live above before acting.

State to read (CODE / FILES / DATA)
  imas-codex graph_ops.py: _execute_rename_cascade, HAS_PARENT/HAS_SUCCESSOR, structural rederive
  (seed_parent_sources / rederive_structural_edges). CLI: sn run --rename OLD:NEW --include-accepted
  (--dry-run first). ISN grammar: parse_standard_name / render.compose must accept + round-trip the
  targets (verified: deuterium_deuterium_neutron_rate_due_to_thermal_fusion parses, base=rate). Graph:
    MATCH (n:StandardName) WHERE n.id CONTAINS 'due_to_thermal_fusion'
    OPTIONAL MATCH (n)-[:HAS_PARENT]->(p) RETURN n.id,n.physical_base,n.unit,n.name_stage,p.id

Scope locks / constraints (non-decision)
  - Rename cascade only, NEVER --focus recompose. Every target ISN-grammar-valid + round-tripping.
  - Preserve provenance (derived sources) and content; keep 0 orphans / 0 desyncs.
  - Do not resurrect the superseded flux_due_to_thermal_fusion / neutron_flux_due_to_thermal_fusion;
    the children must end up under a LIVE source_rate parent.
  - Note: 'source_rate' is the valid base; 'rate' also parses — pick the base consistent with the
    canonical total_neutron_source_rate_due_to_thermal_fusion.

Done-when
  1. The two per-reaction children carry base=source_rate (name aligned to the canonical), grammar-valid.
  2. They hang off a LIVE structural parent (per the decision).
  3. 0 orphans / 0 desyncs; provenance preserved.
  4. This followup resolved.

Landed — both children renamed flux→source_rate via the cascade (0 conflicts); structural fixpoint re-derived a LIVE neutron_source_rate_due_to_thermal_fusion parent (accepted); total_neutron_source_rate_due_to_thermal_fusion now correctly its child; grammar segments realigned (physical_base=source_rate on all 4); 0 orphans/desyncs. Superseded flux names left retired.