src/quartet_concordance.cpp:20-27,43-51 — max_state tracks only the maximum non-NA state seen (to decide whether to grow n0/n1), but nothing rejects a negative state value before it's used to index n0[state]/n1[state] at :43,47,50. Currently safe only because the R caller (characters <- PhyDatToMatrix(dataset) → levelToInt[match(...)], always >= 1 or NA) never passes a negative code — the C++ function itself has no defence if that invariant changes.
Verified via direct code read (orchestrator, since the haiku batch omitted this item on its first pass).
Fix: reject or clamp negative state values at function entry, don't rely solely on the R-side contract.
Filed by /red-team area 14 (opus finder, 2026-08-05).
src/quartet_concordance.cpp:20-27,43-51—max_statetracks only the maximum non-NA state seen (to decide whether to grown0/n1), but nothing rejects a negativestatevalue before it's used to indexn0[state]/n1[state]at :43,47,50. Currently safe only because the R caller (characters <- PhyDatToMatrix(dataset)→levelToInt[match(...)], always>= 1orNA) never passes a negative code — the C++ function itself has no defence if that invariant changes.Verified via direct code read (orchestrator, since the haiku batch omitted this item on its first pass).
Fix: reject or clamp negative
statevalues at function entry, don't rely solely on the R-side contract.Filed by /red-team area 14 (opus finder, 2026-08-05).