Found while re-scoring #135's Run A epoch curve after merging main into
analysis/run-b-power-135 (#138): the seam wrap from #140 changes three committed
YOLO baseline numbers, and scripts/model_comparison/yolo_baseline/benchmark_eval/
still holds the pre-fix values.
What moved
Measured over all three pano arms × all ten splits, wrap_x=False vs wrap_x=True,
same committed detections in benchmark/model_detections/ both times. Everything not
listed is identical at published precision.
| split |
arm |
metric |
committed (pre-#140) |
current scorer |
note |
manual_gold |
y26_pano |
precision |
0.739 |
0.740 |
tp/fp/fn 2895/1021/1024 → 2896/1020/1023 |
clovis |
y26_pano |
AP |
0.593 |
0.596 |
counts unchanged |
richmond |
y26_pano |
AP |
0.536 |
0.537 |
counts unchanged |
The manual_gold one is the clearest: one detection crossed the seam and became a
true positive instead of a false positive on one side plus a miss on the other. That
is exactly the defect #130/#140 set out to fix, so the new number is the right one —
it is only the committed artifact that is stale.
The F1 headline table in scripts/model_comparison/yolo_baseline/README.md is
entirely unaffected — every cell rounds the same. So does every y11l_pano and
y11x_pano_h200 cell, and RampNet's own numbers on every split.
docs/model_comparison.md:1310 also quotes richmond y26_pano AP as 0.536 in
prose, which is now 0.537.
The comparison is sound
Scored with wrap_x=False, the current code reproduces the committed
benchmark_eval/*.txt exactly — same tp/fp/fn, same P/R/F1/AP to three decimals,
on every row checked. So the delta is the matcher and nothing else: not a different
detection set, not a different threshold, not environment drift.
Why it slipped
#140 regenerated docs/model_comparison.md and added
tests/test_scoreboard.py::test_every_number_matches_model_comparison, which
re-derives that document's table cells on every CI run. But the YOLO pano arms are
listed there as "published, not in these tables"
(docs/model_comparison.md:57), so they sit outside that test's coverage.
benchmark_eval/ is a separate committed artifact with no equivalent guard, and
nothing failed when it went stale.
That is the generalisable part: the scoreboard test protects one document, and we
have committed numbers living in at least one other place.
Also worth correcting: the claim in score_pano's docstring
rampnet/detection_eval.py currently says:
Wrapping moves no RampNet or YOLO metric on any committed split — but it does move
the challengers.
That is not right, and it is the kind of claim someone will reasonably rely on when
deciding whether a re-score is needed. It is true for RampNet on every split and
true for every arm's F1 at the operating point, but three published YOLO cells do
move, and max-F1 — which is not in those tables but is the calibration-free column
#135 reads — moves considerably more: bend/y11x_pano_h200 by +0.0014 and
richmond/y26_pano by +0.0030.
Suggested fix
- Regenerate
benchmark_eval/ from the committed detections (no GPU needed — it is a
re-score of a cached detection set) and commit the three changed cells.
- Fix the
docs/model_comparison.md:1310 prose figure.
- Narrow the docstring claim to what was actually measured.
- Extend the scoreboard test, or add a sibling, so
benchmark_eval/ is re-derived in
CI too — otherwise the next scorer change does this again silently.
Not doing any of it in #138, which only needed the Run A epoch curve re-scored; that PR
records the measurement and points here.
🤖 Generated with Claude Code (claude-opus-5[1m])
Found while re-scoring #135's Run A epoch curve after merging main into
analysis/run-b-power-135(#138): the seam wrap from #140 changes three committedYOLO baseline numbers, and
scripts/model_comparison/yolo_baseline/benchmark_eval/still holds the pre-fix values.
What moved
Measured over all three pano arms × all ten splits,
wrap_x=Falsevswrap_x=True,same committed detections in
benchmark/model_detections/both times. Everything notlisted is identical at published precision.
manual_goldy26_pano2895/1021/1024→2896/1020/1023clovisy26_panorichmondy26_panoThe
manual_goldone is the clearest: one detection crossed the seam and became atrue positive instead of a false positive on one side plus a miss on the other. That
is exactly the defect #130/#140 set out to fix, so the new number is the right one —
it is only the committed artifact that is stale.
The F1 headline table in
scripts/model_comparison/yolo_baseline/README.mdisentirely unaffected — every cell rounds the same. So does every
y11l_panoandy11x_pano_h200cell, and RampNet's own numbers on every split.docs/model_comparison.md:1310also quotes richmondy26_panoAP as 0.536 inprose, which is now 0.537.
The comparison is sound
Scored with
wrap_x=False, the current code reproduces the committedbenchmark_eval/*.txtexactly — same tp/fp/fn, same P/R/F1/AP to three decimals,on every row checked. So the delta is the matcher and nothing else: not a different
detection set, not a different threshold, not environment drift.
Why it slipped
#140 regenerated
docs/model_comparison.mdand addedtests/test_scoreboard.py::test_every_number_matches_model_comparison, whichre-derives that document's table cells on every CI run. But the YOLO pano arms are
listed there as "published, not in these tables"
(
docs/model_comparison.md:57), so they sit outside that test's coverage.benchmark_eval/is a separate committed artifact with no equivalent guard, andnothing failed when it went stale.
That is the generalisable part: the scoreboard test protects one document, and we
have committed numbers living in at least one other place.
Also worth correcting: the claim in
score_pano's docstringrampnet/detection_eval.pycurrently says:That is not right, and it is the kind of claim someone will reasonably rely on when
deciding whether a re-score is needed. It is true for RampNet on every split and
true for every arm's F1 at the operating point, but three published YOLO cells do
move, and max-F1 — which is not in those tables but is the calibration-free column
#135 reads — moves considerably more:
bend/y11x_pano_h200by +0.0014 andrichmond/y26_panoby +0.0030.Suggested fix
benchmark_eval/from the committed detections (no GPU needed — it is are-score of a cached detection set) and commit the three changed cells.
docs/model_comparison.md:1310prose figure.benchmark_eval/is re-derived inCI too — otherwise the next scorer change does this again silently.
Not doing any of it in #138, which only needed the Run A epoch curve re-scored; that PR
records the measurement and points here.
🤖 Generated with Claude Code (claude-opus-5[1m])