4.0 KiB
4.0 KiB
Executing unit: u1
[Claude #3] Stage 3 code-edit Round #1 — unit u1
unit_executed
- id: u1
- summary: Extend
plan_zone_ratio_retryfrom single-primary-donor to multi-donor greedy aggregation; adddonors_used+aggregate_slack_usedto plan dict.
files_changed
src/phase_z2_retry.py(33 insertions, 13 deletions; net +20 lines, within u1 estimate ≤35)
diff_summary
Replaced single-donor feasibility branch in plan_zone_ratio_retry with multi-donor greedy aggregation along slack-desc donor order (already sorted):
- Feasibility check — compare
target_added_pxagainstaggregate_slack_available = sum(d.slack for d in donor_candidates)instead ofprimary_donor.slack. - Greedy allocation — when feasible, walk donor_candidates in slack-desc order, taking
min(donor.slack, remaining)from each untilremaining == 0. Each donor contributes only what is needed; later donors with sufficient remaining slack are untouched. - New plan fields —
donors_used: list[dict]with{position, reduced_px, slack_before, slack_after}per donor;aggregate_slack_used: int;aggregate_slack_available: int. - Backward-compat surface preserved —
donor_zone_position(primary donor),donor_reduced_px(primary donor's take, not total),donor_max_slack(primary donor's slack on failure path). Pipeline log line atphase_z2_pipeline.py:1886continues to render without change (u9 will update for multi-donor telemetry). - Failure-reason classifier preservation — failure_reason text retains
primary donor ... slack ... target_added_pxsubstrings (feedback_phase_z2_failure_router.py:126-130matches), so existingdonor_slack_insufficientclassification still fires on aggregate-insufficient case. u2/u3 will rewire routing.
evidence
python -c "from src.phase_z2_retry import plan_zone_ratio_retry; print('OK')"→OKpython -m pytest -q tests/phase_z2→ 62 passed in 0.13s (regression-free; u10 will add the multi-donor unit tests)git diff --stat src/phase_z2_retry.py→1 file changed, 33 insertions(+), 13 deletions(-)- Scope: 1 file modified (matches u1
files: [src/phase_z2_retry.py]); no other source file touched.
scope_lock_compliance
- ✅ deterministic (no AI call added) —
feedback_ai_isolation_contract - ✅ no global spacing shrink (planner only manipulates donor zone heights within
min_height_pxfloor) —feedback_phase_z_spacing_direction - ✅ no
ACTION_BY_CATEGORYchange —Stage 1 scope_lock - ✅ files ≤3 and estimate_lines ≤50 — actual: 1 file, +33/-13
- ✅ retry_budget=1 preserved (no orchestrator change in this unit)
- ✅ failure_reason substring stability preserves u2/u3 classifier surface
remaining_units
- u2 — failure_router classifier extension (3 new salvage failure types)
- u3 —
NEXT_ACTION_BY_FAILURErewire (donor_slack_insufficient → cross_zone_redistribute) - u4 —
plan_cross_zone_redistribute+ scoped role-height CSS - u5 —
plan_glue_compression+ frame-scoped CSS - u6 —
plan_font_step_compression+ zone-scoped CSS - u7 —
ACTION_IMPLEMENTATION_STATUSregistration for 3 new salvage actions - u8 —
_attempt_salvage_chainorchestrator (Step 17 pipeline) - u9 — pipeline wiring + Step 17 telemetry (
salvage_steps,salvage_passed) - u10 — multi-donor plan tests
- u11 —
plan_cross_zone_redistributetests - u12 —
plan_glue_compressiontests - u13 —
plan_font_step_compressiontests - u14 — failure_router cascade tests
- u15 — end-to-end
_attempt_salvage_chaintests
follow_up_issue_candidates
None. All observed deviations are addressed by remaining units (u9 will update the pipeline log line; u2 will replace substring-matching classifier with explicit feasibility-branch signal).
next
u2 — extend phase_z2_failure_router classifier to surface 3 new salvage failure types (cross_zone_redistribute_insufficient, glue_absorption_insufficient, font_step_insufficient).
rewind_target: continue_same FINAL_CONSENSUS: NO