Handoff: guardrail rail-vs-support split (options 1+2)

2026-08-14 · implementation agent · generated by Claude Fable 5

Summary

Goal: in the LaneFinder guardrails repo, implement the two low-cost tiers of the rail-vs-support decomposition decided on 2026-08-14: (1) a per-run post-cadence attribute (spacing, count, confidence, gap list) and (2) a per-point sub-mask guardrail_rail / guardrail_support / ambiguous in point_masks.npz. Do NOT add a second exported feature class — exports (XML/OKSTRA-style) stay single-class guardrail; the split is internal enrichment only.

Repo: /mnt/data/dev/3dai.iolabs.pointcloud.guardrails (work happened in worktree /home/miro/.t3/worktrees/3dai.iolabs.pointcloud.guardrails/t3code-66d41c12), branch t3code/separate-v-profile-support-classes, tip 0c471fb (v0.3.1). Jira context: AI3D-351 line of work.

Current state (nothing implemented yet)

Key facts the design relies on

Design decisions (already made — do not relitigate)

Next steps (ordered)

  1. Read README.md, guardrails/config.py, guardrails/geometry.py (select_candidate_cells), guardrails/instances.py, guardrails/detect.py (~:517 and :576), guardrails/outputs.py to confirm the line references above still hold on the current tip.
  2. New module (e.g. guardrails/posts.py): corridor-scoped low-band evidence pass + along-station histogram + autocorrelation cadence estimator. Stream via the existing chunked reader (iolabs.common.segment_points_io.iter_points_chunks) — respect the memory budget machinery (memory_budget_gb, record_chunk_points, config.py:181-196).
  3. New config block (+ mirror in guardrails.default.json): low band [0.10, 0.35], bin 0.10 m, catalog spacings [1.33, 2.00, 4.00], snap tolerance, min confidence, feature flag enable_post_cadence (default on) and enable_component_masks.
  4. Wire cadence attributes into _enrich_instances; pass through to JSON/XML instance attributes.
  5. Implement the per-point sub-labeler using the cadence estimate; write the extra channel into point_masks.npz (keep backward-compatible: additive keys only, existing consumers must not break — check the lane-zone replay path lane_xml.py and dev/probe.py which touch masks/records).
  6. Unit tests: synthetic guardrail generator (rail band at 0.5–0.75 m + posts at exact cadence + noise) → assert recovered spacing, count, gap detection, and sub-mask precision on the synthetic truth. Test cadence robustness with 30% of posts randomly deleted (scan-phase simulation) — spacing must still snap correctly, missing posts must land in post_gap_spans.
  7. Run the module on a curated real segment (see azure-cli skill for cached ACC LAS data) and eyeball a rendered mask overlay before calling it done.
  8. Version bump + wrap-up per repo convention (/wrap-up skill: Nexus publish, AI3D-351 Jira-tagged commit) — only when Miro asks.

Verification contract

Risks and open questions