* docs: round-6 deep project review (graded B+, ▲ from B−)
Sixth deep project review of the entire tracked repo — 6 cold facet
auditors (Python, PHP/security, schema/data, tests/CI, ops, docs) +
synthesizer hand-re-verification, judging two bands: (A) did round-5's
fixes durably stick, and (B) what did #93–#98 + migrations 0069–0071 +
the two direct-to-main commits introduce.
The recursive integrity check passes cleanly for the first time in the
series: every round-5 fix (R1.1/R1.2/R1.3/R1.5/R2.1/R3.x/R4.x) landed as
a committed PR and is still present at HEAD, and every mechanized guard
is proven non-vacuous by break-it experiment. New code is clean — no
CRIT/HIGH: #93 USACE kcfs→cfs (correct, per-series), migrations
0069/0070/0071 (idempotent, FK-clean, Bridgeport DROP cascade
residue-free), #96/#97 multi-state pickers, #95/#98 gradient JS.
Two MED findings, both recurrences of round-5 classes closed by
documentation not mechanization: (1) two direct-to-main commits, one of
which broke CI on main (the {}-is-a-dict bug); (2) a nightly snapshot
overrode migration 0067's sort_name for gauge 217 with no migration.
Root cause is shared — main accepts un-CI-gated direct pushes from both
humans and the snapshot bot. Lever: route everything through a CI gate
(branch protection + a self-gating/auto-merging snapshot), a
snapshot-column drift guard, and teach seed_gauge_display to preserve
migration-pinned sort_names.
Two facet over-claims dissolved on hand-re-verification (the USACE
temperature-docstring drop is a correct fix; check_reaches DOES
range-check vertices via validate_lat_lon).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs: fold external-review corrections into the round-6 review (#99)
The PR #99 external verification pass re-confirmed every finding,
severity, and the B+ grade against db34ae0 (recommendation: merge), and
flagged one inaccurate evidence line plus three off-by-one citations.
Corrected:
- MED #1: drop the `git branch --contains` "reachable only from main"
claim — feature branches later cut from main now contain 9b428bb /
6007c21, so containment no longer distinguishes them. The direct-to-
main conclusion stands on the durable evidence (linear f3ed673..HEAD,
no merge commit, missing (#NN) suffix).
- citations: ci.yml:114→115, SourceUrlTest.php:83-84→84-85,
check_reaches.py:212→213.
Added an External-review note recording the pass + the one below-LOW item
it surfaced (the 0069/0070 header comments' now-stale PENDING_RECONCILIATION
wording).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fast-follow to #96 (review flagged this sibling issue).
Why
#96 makes border gauges (
gauge.state = 'OR,WA'— the whole Columbia mainstem) selectable in the gauge picker. Their destination,custom_gauges.php?ids=…, carried the same exact-match state handling the picker had, so a selected border gauge landed on a page that couldn't filter it:_compute_custom_gauges_filters()—isset(CUSTOM_GAUGES_STATE_ABBREVS['OR,WA'])is false → no state pill.CUSTOM_GAUGES_STATE_ABBREVS['OR,WA'] ?? ''→ empty$state, so theif ($state !== '' && $huc8 !== '')guard emitted nodata-state/data-huc8→ the row escaped both the state and watershed filters.data-split="csv", so even a commadata-statewouldn't have matched a pill.Milder than the picker bug (the gauge still rendered its flow/gage), but it dropped its pills and ignored the filters.
Fix — same three-spot mirror of the static build (
web/build/gauges.py,levels.py:469)gauge.stateon the comma so each state contributes a pill.data-state="Oregon,Washington".data-split="csv"sofilters.jssplits the row value to match each pill.No schema or data change — purely how the page reads the existing
statecolumn.Tests
CustomGaugesIntegrationTestgains anOR,WAseed gauge and asserts a single border gauge surfaces both Oregon and Washington pills, the State group isdata-split="csv", and the row renders as a filterable row (data-state="Oregon,Washington" data-huc8="17080003").Local gate (green)
Independent of #96 (different files); merges in any order.
🤖 Generated with Claude Code