Observed while burning down #352, and it is the second time this has bitten — #351's review caught the same thing.
The effect
audit-graphs reports a node as UNREACHABLE_FROM_TRAIT when its island has no undirected path to a TRAIT node. So the count falls for two quite different reasons:
- the graph actually became more connected, or
- a node inside an existing island was retyped to
TRAIT, making the island self-anchoring while remaining exactly as disconnected as before.
Only the first is progress. The second is measured as progress.
Measured on #352's burn-down
Retyping four genuinely-mistyped disposition nodes to TRAIT:
UNREACHABLE_FROM_TRAIT 1303 -> 1296 (-7)
FRAGMENTED_GRAPH 218 -> 218 ( 0)
Every one of the seven is accounted for by case 2 or by a node being deleted. In oxygen_preference.yaml, detoxifying_enzyme_expression, superoxide_dismutase and reactive_oxygen_species_stress stopped being reported because oxygen_tolerance — sitting in their island — became a TRAIT. The island is still an island: that file's FRAGMENTED_GRAPH finding is unchanged.
The retypes were correct and each is grounded to a real, non-colliding METPO term. The problem is not the change; it is that the metric moved in a way a reader will misread as connectivity.
Why the existing guard doesn't cover it
#352's third bullet warns that an ungrounded new TRAIT node becomes a free anchor. That framing suggests requiring a grounding fixes it. It does not — these four are grounded, and the anchor effect is identical. Grounding prevents a fabricated anchor; it does not stop a legitimate one from moving the number.
Options
- Report them together. Never print
UNREACHABLE_FROM_TRAIT without FRAGMENTED_GRAPH alongside, so a fall in one against a flat other is visible rather than needing to be remembered.
- Count components, not nodes.
FRAGMENTED_GRAPH already does this and is the honest connectivity metric; UNREACHABLE_FROM_TRAIT's value is in naming which nodes, not in its total.
- Flag anchor churn. If the set of
TRAIT nodes in a graph changed between baseline and run, say so in the output, so a drop that coincides with a new anchor is labelled.
Not urgent — nothing is mis-detected, and the per-node findings are all correct. What is wrong is that the headline number invites a claim the data doesn't support, and it has now invited it twice.
Observed while burning down #352, and it is the second time this has bitten — #351's review caught the same thing.
The effect
audit-graphsreports a node asUNREACHABLE_FROM_TRAITwhen its island has no undirected path to aTRAITnode. So the count falls for two quite different reasons:TRAIT, making the island self-anchoring while remaining exactly as disconnected as before.Only the first is progress. The second is measured as progress.
Measured on #352's burn-down
Retyping four genuinely-mistyped disposition nodes to
TRAIT:Every one of the seven is accounted for by case 2 or by a node being deleted. In
oxygen_preference.yaml,detoxifying_enzyme_expression,superoxide_dismutaseandreactive_oxygen_species_stressstopped being reported becauseoxygen_tolerance— sitting in their island — became aTRAIT. The island is still an island: that file'sFRAGMENTED_GRAPHfinding is unchanged.The retypes were correct and each is grounded to a real, non-colliding METPO term. The problem is not the change; it is that the metric moved in a way a reader will misread as connectivity.
Why the existing guard doesn't cover it
#352's third bullet warns that an ungrounded new TRAIT node becomes a free anchor. That framing suggests requiring a grounding fixes it. It does not — these four are grounded, and the anchor effect is identical. Grounding prevents a fabricated anchor; it does not stop a legitimate one from moving the number.
Options
UNREACHABLE_FROM_TRAITwithoutFRAGMENTED_GRAPHalongside, so a fall in one against a flat other is visible rather than needing to be remembered.FRAGMENTED_GRAPHalready does this and is the honest connectivity metric;UNREACHABLE_FROM_TRAIT's value is in naming which nodes, not in its total.TRAITnodes in a graph changed between baseline and run, say so in the output, so a drop that coincides with a new anchor is labelled.Not urgent — nothing is mis-detected, and the per-node findings are all correct. What is wrong is that the headline number invites a claim the data doesn't support, and it has now invited it twice.