feat(#39): IMP-30 first-render invariant + abort bypass (2 paths)
Restore first-render invariant: final.html + Step 20 slide_status MUST be written for every input where Step 0~5 succeed. Two abort paths replaced with provisional/empty-shell synthesis; MDX content preserved, AI-free. - u1 V4Match.provisional + lookup_v4_match_with_fallback(allow_provisional) chain_exhausted -> synthesize rank-1 provisional (opt-in, default-off) - u2 CompositionUnit.provisional propagation (single / parent_merged / parent_merged_inferred constructors) - u3 select_composition_units(allow_provisional_fill=True) last-resort fill + _candidate_state="selected_provisional" - u4 pipeline.py path-(a) abort guard replaced with provisional retry + terminal __empty__ shell (no sys.exit(1)) - u5 zones_data.provisional -> slide_base.html zone--provisional class + data-provisional + needs-adaptation badge (template-only) - u6 compute_slide_status additive provisional_first_render_count/_units (overall enum unchanged per IMP-05 Codex #10 D4) - u7 regression: tests/test_phase_z2_imp30_first_render.py (28 tests) + tests/test_phase_z2_v4_fallback.py (+5 cases) Guardrails verified: MVP1_ALLOWED_STATUSES unchanged, no calculate_fit, no LLM in fallback path, no MDX 03/04/05 hardcoding. Anchor sync (Rule 13): tests/orchestrator_unit/test_imp17_comment_anchor.py re-pinned 564/565 -> 570/571 to track V4Match.provisional shift at src/phase_z2_pipeline.py:179-184. Cross-ref: IMP-05 (#5) §5 defer + Codex #2 first-render invariant.
This commit is contained in:
1557
tests/test_phase_z2_imp30_first_render.py
Normal file
1557
tests/test_phase_z2_imp30_first_render.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user