Pass 5 — the lattice pass

Vertical-sign detection improvement loop · AI3D-339 · 2026-08-03 · report 5 of N · previous: pass 4
TL;DR. Pass 5 turned the German delineator-spacing regulation into a shipped detector stage.
1 · Interchange audit
2 · Chains + null test
3 · Adversarial verdicts
4 · The recall number
5 · The shipped rule
6 · Negative results
7 · Research memo
8 · Pass-6 queue & stop status

1 · The A4_5 count contradiction is an interchange, not an FP pool

Pass 4 left a live suspicion: 114 accepted A4_5 delineators vs a rail-corrected expectation of 26–51. Half of the "excess" sits in segments 131/132/134 — which turn out to be a full interchange. The nearest-neighbour spacings there (7.1–7.7 m, plus 1.2–2 m gore-nose groups) match the HLB curve table for R≈70–80 m ramps, not mainline. All 12 sampled detections are unambiguous posts, bollards or gore devices in close-up; 4 spot checks were re-confirmed by the adversarial fleet (4/4 real). Side lesson: on_road_fraction=1.0 / dist_to_road=0 is unreliable at interchanges — never use it as an FP cue there.

2 · Fitting the lattice through the posts themselves

Road-centerline models failed on this corridor (junctions + dual carriageway), so rows are fitted directly through the candidates: every accepted delineator seeds chain growth over a gated pool of rejected clusters; each step predicts the next site at the tracked base spacing, snaps within 3 m, and tolerates up to 6 missing sites. A null test (same growth, pool positions randomized within each segment) determines which chain classes carry real signal:

null test

High-skip and 1–2-anchor chains appear as often in randomized pools — chance. The signal lives in anchor-rich, low-skip chains.

chain 0 overview

Chain 0 (segs 32–36): a textbook 25 m row along the carriageway edge. Orange rings = chain members; red rings = predicted-but-empty sites, later probed for raw occupancy.

3 · What the adversarial fleet said

verdicts

36 crops (+2 late A4_5 crops) judged by Opus and Grok independently, refute-framed, 28/36 agreement, Fable tiebreak on the rest. Outcomes: all 8 A1 admissions from the two 6-anchor chains are real; all 6 candidates from 1–2-anchor chains are vegetation (exactly as the null test predicted); 3 of the occupied predicted-empty sites hold real posts the detector never clustered.

admission example

Typical admission (s034 c207): slender ~1 m post with brighter head at the verge — sparse scanline sampling of a 12 cm HLB post. Rejected by the base detector as "unclassified"; phase-locked at 25 m in a 6-anchor chain.

4 · The first external recall number

recall waterfall missed post

A clean post with bright cap at a lattice-predicted site (~1 m prediction offset) — no cluster, no detection. Three of these are confirmed; they can only be recovered by detect-at-predicted-site (pass-6 queue #1).

Caveat (strategist): these stretches were selectable because they had 6 detected anchors — the measurement is recall's best case, an upper bound. Corridor-wide recall is still unknown; measuring it via the A4_5 road model + rail registry is pass-6 queue #3.

5 · The shipped rule and its validation

GateValueWhy
chain anchors≥ 4 accepted delineatorsnull test: 1–2-anchor chains are chance (their candidates judged 6/6 vegetation)
spacing residual< 15% of baselattice regularity (HLB: 50 m mainline, 3–50 m by curvature)
pool height0.8–1.4 mHLB post = 1.00 m above pavement edge
pool plate≤ 0.05 mpost is a plate, not a blob
pool bright seed fraction≥ 0.15a delineator has a retroreflector; the one judged-veg candidate inside a 6-anchor chain had 0.000

Implementation: lattice.py post-pass invoked at the end of detect.main() over the whole invocation (chains cross segment borders); idempotent; lattice_admission=False restores byte-identical outputs. New append-only CSV column z_ground lets the pass rebuild full detection dicts without reloading NPZ. 263 tests pass (11 new).

Full-rerun diff (p5_final vs p4_final): A1 +8 / −0 (exactly the judged-real set), A4_5 +2 / −0. No other change.
the FP admission

The one bad admission, on the record: s078 c59 (A4_5) — both judges say vegetation (a shrub in a row that happens to phase-lock at 49.5 m against 11 anchors). Its bright fraction (0.182) is a near-tie with the dimmest judged-real admission (0.177): no honest geometric threshold separates them, so it ships as a documented FP instead of a p-hacked cut. Judged admission precision: 9/10.

6 · Negative results (kept on purpose)

7 · Research memo (Codex) highlights

8 · Pass-6 queue and stop status

Stop-condition verdict (fresh-eyes strategist): not stopped. Recall ~50% measured on best-case stretches kills condition 4; raw occupancy proves the data still contains unexploited signal (kills 3); rule-level moves remain (kills 1); condition 2 is close but the machine path isn't exhausted.
  1. Detect-at-predicted-site: lower clustering thresholds only inside windows around lattice-predicted empty sites, then apply the existing HLB shape + retroreflectivity gates. The 3 confirmed never-clustered posts are the guaranteed yield.
  2. FP purge + guarded lattice fixpoint: remove the ~6 known accepted FPs from anchoring, then iterate admission with an original-anchor quorum and a per-iteration null test.
  3. Corridor-wide recall on A4_5 via road model + rail registry — turns the anecdote into a denominator. Holdout stays sealed until goal.
  4. RF refresh as soft verifier over #1's candidates, fed lattice/context features (cluster-internal features are capped at AUC ~0.73).
  5. Gates and trees: measure or explicitly de-scope — the goal names four classes and two are currently unreported.
Ask for Miro: install the web point-cloud viewer now (parallel, cheap lead time). Strongest use: one human calibration pass over ~20 hard judged cases (the 12 misses + 8 admissions) to bound LLM-judge error — the whole loop's precision/recall numbers currently rest on machine judges with no human calibration.

Artifacts