Refs #6
Stage 4 split per Codex #10 acceptance: this commit lands the schema +
trace refinements required before the render-path rewiring. The actual
units/zones_data/Step 9/Step 20 plan-driven materialization remains in
Stage 4 part 2 (follow-up commit) so each commit is reviewable on its
own and regression-safe.
- _build_position_assignment_plan: add replaced_auto_unit field. Populated
only when the explicitly overridden position already held an auto unit
AND that auto unit had different source_section_ids than the override.
Documents a same-position override replacement as a distinct audit fact,
separate from skipped_collided_auto_units which captures cross-position
whole-skips per the locked collision policy.
- Backfill replaced_auto_unit = None on the empty/collision/auto branches
for schema-stable consumers.
- Update the override-application comment near the helper invocation so it
no longer claims the helper "reorders units"; Stage 4 part 2 will be the
commit that wires the plan into the actual render path.
- Helper unit tests: assert replaced_auto_unit shape in the collision
scenario and add a dedicated case that distinguishes same-sections
(template swap via --override-frame -> None) from different-sections
same-position replacement (populated, reason="same_position_override_replacement").
No AI, no calculate_fit, no full planner rerun, no frontend, no sample
hardcoding. plan_composition() signature preserved. helper remains pure.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>