6.6 KiB
Executing unit: u14
[Claude #N] Stage 3 code-edit Round #N -- unit u14
unit_executed
u14 -- pytest coverage for phase_z2_failure_router cascade (u2/u3/u7 surface). Four deterministic cases per Stage 2 contract: donor_slack_insufficient → cross_zone_redistribute IMPLEMENTED, no_donor_candidates → cross_zone_redistribute IMPLEMENTED, three new salvage failure types route to expected next actions (cross_zone_insufficient→glue, glue→font, font→layout_adjust), rerender_still_fails → frame_reselect preserved.
files_changed
- tests/phase_z2/test_phase_z2_failure_router_cascade.py (new file, untracked -- single file scope, test-only)
diff_summary
-
New test module exercises four Stage 2 cases against
src.phase_z2_failure_router.classify_retry_failure,route_retry_failure,enrich_retry_trace_with_failure_classification,NEXT_ACTION_BY_FAILURE,NEXT_ACTION_IMPLEMENTATION_STATUS:-
test_donor_slack_insufficient_routes_to_cross_zone_redistribute_implemented-- Stage 1 root cause. retry_trace withplan.feasible=False+ failure_reason containingprimary donor 'bottom' slack 15px ... < target_added_px 70pxmatches the substring contract atsrc/phase_z2_failure_router.py:206-217. Assertsfailure_type=="donor_slack_insufficient",route_retry_failure(...).next_proposed_action=="cross_zone_redistribute"andnext_action_implementation_status=="IMPLEMENTED"(u7 lock atsrc/phase_z2_failure_router.py:142-149). Also exercises the enrichment wrapper end-to-end:enrich_retry_trace_with_failure_classification(trace)mutates trace adding bothfailure_classificationandnext_action_proposalfields. -
test_no_donor_candidates_routes_to_cross_zone_redistribute_implemented-- second cascade entry. retry_trace withplan.feasible=False+ failure_reason"no donor candidates"matchessrc/phase_z2_failure_router.py:220-227. Assertsfailure_type=="no_donor_candidates"andnext_proposed_action=="cross_zone_redistribute"withIMPLEMENTEDstatus. Confirms bothdonor_slack_insufficientandno_donor_candidatesshare the same cascade entry point (Stage 2 design — both signal "exhausted within current frame, try cross-zone"). -
test_three_new_salvage_failure_types_route_to_expected_cascade_actions-- u2/u3/u7 lock. Verifies the lockedNEXT_ACTION_BY_FAILUREtable directly (3 assertions:cross_zone_redistribute_insufficient→glue_compression,glue_absorption_insufficient→font_step_compression,font_step_insufficient→layout_adjust) AND theNEXT_ACTION_IMPLEMENTATION_STATUSlock (glue_compression/font_step_compression=IMPLEMENTED,layout_adjust=MISSING -- since IMP-12 stops short of layout_adjust per Stage 1 scope_lock). Then iterates the three classifier paths viasalvage_steps[-1]: for each(action, expected_ftype, expected_next)triple, constructs a retry_trace withsalvage_steps=[{action, passed:False, failure_reason}]and asserts the classifier surfacesexpected_ftype(perSALVAGE_FAILURE_TYPE_BY_ACTIONatsrc/phase_z2_failure_router.py:85-89) and the router emitsexpected_next. End-to-end classify→route round-trip. -
test_rerender_still_fails_preserved_routes_to_frame_reselect-- pre-cascade behavior preserved. retry_trace withplan.feasible=True+rerender_attempted=True+retry_passed=Falsehitscase 3atsrc/phase_z2_failure_router.py:240-246. Assertsfailure_type=="rerender_still_fails"andnext_proposed_action=="frame_reselect"-- u3 cascade rewire did NOT clobber the pre-existing visual-fail path. Important regression guard since u3 added 3 new entries toNEXT_ACTION_BY_FAILUREwithout rewriting the rerender row.
-
-
No source edits -- test-only unit; observes existing u2/u3/u7 contract on
src/phase_z2_failure_router.py. -
File metrics: 119 total lines (test module incl. docstring + 4 tests). Net diff = 119 added / 0 removed.
-
Helper-free design (function-arg API takes simple dicts). No shared fixtures introduced (single-test-file scope per Stage 2 scope_lock).
verification
python -m pytest -q tests/phase_z2/test_phase_z2_failure_router_cascade.py-> 4 passed in 0.02s.- Cross-checked classifier paths against
src/phase_z2_failure_router.py:- case 0.7 (salvage_steps last failed) at lines 170-187 -- handles the 3 new types via
SALVAGE_FAILURE_TYPE_BY_ACTION. - case 2 donor patterns at lines 199-237 -- donor substring + no-donor-candidates substring.
- case 3 rerender at lines 239-246 -- preserved.
- case 0.7 (salvage_steps last failed) at lines 170-187 -- handles the 3 new types via
- Confirmed u7 status lock at
src/phase_z2_failure_router.py:142-149:cross_zone_redistribute/glue_compression/font_step_compression==IMPLEMENTED;layout_adjust==MISSING. - Scope-lock per
feedback_phase_z_spacing_direction: not applicable -- this unit is router classifier only, no CSS emission. - Verified the planned cascade test module
test_phase_z2_failure_router_cascade.pyis present intests/phase_z2/; onlytest_phase_z2_step17_salvage_chain.py(u15) remains.
diff_summary (numeric)
wc -l tests/phase_z2/test_phase_z2_failure_router_cascade.py-> 119git status --shortshows the file as?? tests/phase_z2/test_phase_z2_failure_router_cascade.py(untracked, scope-lock holds).
remaining_units
- u15 (end-to-end Step 17 _attempt_salvage_chain test with 3 cascade fixtures: (a) zone_ratio fail + cross_zone pass; (b) cross_zone fail + glue pass; (c) all 3 fail → (b)-revert preserved).
follow_up_issue_candidates
- None observed this round.
layout_adjuststatus remains MISSING inNEXT_ACTION_IMPLEMENTATION_STATUS-- that's the intended terminal state of the deterministic salvage cascade per Stage 1 scope_lock (out-of-scope for IMP-12). If/when implemented, it would belong to a separate axis (referenced in Stage 1 out_of_scope list).
=== EVIDENCE === Commands run:
python -m pytest -q tests/phase_z2/test_phase_z2_failure_router_cascade.py-> 4 passed in 0.02sgit status --short-> file untracked, src/ files unchangedwc -l tests/phase_z2/test_phase_z2_failure_router_cascade.py-> 119Read src/phase_z2_failure_router.py(full file, 318 lines)Read src/phase_z2_router.py(full file, 188 lines -- confirmed u7 status lock)
Files checked:
- src/phase_z2_failure_router.py:85-89 (SALVAGE_FAILURE_TYPE_BY_ACTION)
- src/phase_z2_failure_router.py:94-102 (NEXT_ACTION_BY_FAILURE locked table)
- src/phase_z2_failure_router.py:142-149 (NEXT_ACTION_IMPLEMENTATION_STATUS)
- src/phase_z2_failure_router.py:170-187 (case 0.7 salvage_steps classifier)
- src/phase_z2_failure_router.py:199-246 (case 2/3 plan/rerender classifier)
- src/phase_z2_failure_router.py:261-318 (route_retry_failure + enrich wrapper)
- tests/phase_z2/test_phase_z2_failure_router_cascade.py (new, 119 lines)
Remaining units: [u15]