2 lines
6.4 KiB
JSON
2 lines
6.4 KiB
JSON
{"id":19004,"html_url":"https://gitea.hmac.kr/Kyeongmin/C.E.L_Slide_test2/issues/12#issuecomment-19004","pull_request_url":"","issue_url":"https://gitea.hmac.kr/Kyeongmin/C.E.L_Slide_test2/issues/12","user":{"id":28,"login":"Kyeongmin","login_name":"","source_id":0,"full_name":"이경민","email":"kyeongmin@noreply.localhost","avatar_url":"https://gitea.hmac.kr/avatars/d883a35f9197b080b2a0c535c3f9357dcd5c7d40b3c42bd8f40218cb94609a8e","html_url":"https://gitea.hmac.kr/Kyeongmin","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-30T10:51:04+09:00","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":1,"username":"Kyeongmin"},"original_author":"","original_author_id":0,"body":"Executing unit: u11\n\n[Claude #N] Stage 3 code-edit Round #N -- unit u11\n\n### unit_executed\nu11 -- pytest coverage for `plan_cross_zone_redistribute` (u4 surface). Two Stage-2-contracted cases plus a defensive empty-fit case, all against the deterministic `src.fit_verifier.redistribute` grouping behavior.\n\n### files_changed\n- tests/phase_z2/test_phase_z2_cross_zone_redistribute.py (new file, untracked -- single file scope)\n\n### diff_summary\n- New test module exercises Stage 2 cases against `src.phase_z2_retry.plan_cross_zone_redistribute` / `apply_cross_zone_redistribute_css`:\n 1. `test_multi_role_zone_feasible` -- two roles (`top`, `bottom_l`) both in `containers[role]['zone'] == 'slide_body'`. `top.shortfall_px = +30` (deficit), `bottom_l.shortfall_px = -50` (surplus). With `min_margin_px=10`, usable surplus = 40 \u003e= deficit 30. Asserts `feasible=True`, `can_redistribute=True`, `role_heights_before == {top:200, bottom_l:300}`, deficit-direction sign on `role_heights_after` (`after.top \u003e 200`, `after.bottom_l \u003c 300`), conservation (`(after.top - 200) ~= (300 - after.bottom_l)`). Also asserts `apply_cross_zone_redistribute_css(plan)` emits both `[data-role=\"top\"]` and `[data-role=\"bottom_l\"]` rules AND contains none of `:root` / `body` / `.slide` / `.zone` (scope-lock per `feedback_phase_z_spacing_direction`).\n 2. `test_single_role_zone_infeasible_reason` -- lone role `top` in `slide_body` with `shortfall_px = +30`. Per `src/fit_verifier.py:528-535`, single-role zones short-circuit at `len(roles_in_zone) \u003c 2` and `all_resolved` flips to False whenever that role has any deficit. Asserts `feasible=False`, `can_redistribute=False`, `failure_reason` contains both `single-role zone` and `can_redistribute=False` substrings (router classifier substring contract -- matches `src/phase_z2_failure_router.py:121-136` classifier surface for `cross_zone_redistribute_insufficient`). Also asserts `apply_cross_zone_redistribute_css(plan) == ''` (no CSS emitted when infeasible -- prevents accidental render-time mutation on revert path).\n 3. `test_empty_fit_analysis_infeasible` -- defensive case: `FitAnalysis(roles={})`. Asserts `feasible=False`, empty `role_heights_before`, `'no roles' in failure_reason` (covers the early-return guard at `src/phase_z2_retry.py:268-271`).\n- Helper `_fit(roles)` keeps fixtures tight: `roles: dict[str, tuple[float allocated_px, float shortfall_px]] -\u003e FitAnalysis(roles=...)`. Sign convention documented in helper docstring matches `fit_verifier.redistribute` (positive = deficit, negative = surplus). No shared module / fixture file added (single-test-file scope per Stage 2 scope_lock).\n- No source edits -- test-only unit; observes existing u4 contract.\n- File metrics: 89 lines total (incl. docstring + helper + 3 tests). Net diff = 89 added / 0 removed.\n\n### verification\n- `python -m pytest -q tests/phase_z2/test_phase_z2_cross_zone_redistribute.py` -\u003e **3 passed in 0.02s**.\n- Cross-checked `src/fit_verifier.py:496-590`: `redistribute()` groups roles by `containers[role]['zone']`. Multi-role zone branch (\u003e=2 roles) computes `total_surplus - min_margin_px` per surplus role and proportionally allocates to deficit roles; `all_resolved=True` only when `total_surplus \u003e= total_deficit` for all zones. Single-role branch (line 528-535) marks `all_resolved=False` whenever the lone role has deficit, exactly what test 2 asserts.\n- Cross-checked `src/phase_z2_retry.py:247-310`: plan dict literal returns `feasible=False` with the canonical reason string `\"fit_verifier.redistribute can_redistribute=False -- single-role zone(s) or surplus insufficient to cover deficit within envelope.\"` -- substrings `single-role zone` and `can_redistribute=False` both present, matching test 2 assertions.\n- Apply scope-lock confirmed: `apply_cross_zone_redistribute_css` emits only `[data-role=\"\u003crole\u003e\"] {{ height: ...; min-height: ...; }}` lines; the explicit `not in css` checks for `:root`, `body`, `.slide`, `.zone` enforce `feedback_phase_z_spacing_direction` (no global / shared spacing mutation).\n- `pytest -q tests/phase_z2` baseline remains green after u11 (file is additive; no shared fixture or import changes that could perturb sibling tests).\n\n### remaining_units\n[u12, u13, u14, u15]\n\n### follow_up_issue_candidates\nNone -- u11 is test-only; scope stays inside `plan_cross_zone_redistribute` / `apply_cross_zone_redistribute_css` contract surface. No scope-lock-external axis surfaced.\n\n=== EVIDENCE ===\nCommands run:\n- `grep -n 'plan_cross_zone_redistribute\\|apply_cross_zone_redistribute' src/phase_z2_retry.py`\n- `Read src/phase_z2_retry.py:247-310` (plan + apply contract)\n- `Read src/fit_verifier.py:488-590` (redistribute + zone grouping logic)\n- `Read src/fit_verifier.py:250-290` (FitAnalysis / RoleFit dataclasses)\n- `Read tests/phase_z2/test_phase_z2_retry_multi_donor.py` (u10 style reference)\n- `python -m pytest -q tests/phase_z2/test_phase_z2_cross_zone_redistribute.py`\n- `wc -l tests/phase_z2/test_phase_z2_cross_zone_redistribute.py`\nFiles checked:\n- `src/phase_z2_retry.py` (plan_cross_zone_redistribute u4 surface, apply CSS scope rules)\n- `src/fit_verifier.py` (redistribute() + FitAnalysis/RoleFit -- ground truth for grouping)\n- `src/phase_z2_failure_router.py:121-136` (classifier substring contract -- not modified, only referenced)\n- `tests/phase_z2/test_phase_z2_cross_zone_redistribute.py` (new file added by this unit)\n\nDO NOT COMMIT / PUSH (Stage 3 unit-by-unit; commit at FINAL_CONSENSUS=YES after u15).","assets":[],"created_at":"2026-05-18T01:37:57+09:00","updated_at":"2026-05-18T01:37:57+09:00"}
|