Files
C.E.L_Slide_test2/.orchestrator/tmp/claude4_u2_body.md
T

5.0 KiB
Raw Blame History

Executing unit: u2

[Claude #4] Stage 3 Round #2 — IMP-09 PR 2 u2

unit_executed

  • id: u2
  • summary: Add _aggregate_axis_zone helper (combine zones in same row/col track into synthetic zone for PR 1 solvers)

files_changed

  • src/phase_z2_pipeline.py (+44 / -0)

diff_summary

  • Inserted directly after the _TWO_D_TOPOLOGIES = frozenset(...) line that u1 added, and before the existing # Layout preset → zone position 순서 ... comment (HEAD line 1152 → working-tree line 1196). u1 surface and PR 1 helpers untouched.
  • Helper signature: _aggregate_axis_zone(positions: list[str], zones_data: list[dict]) -> dict.
  • Aggregation rules (verified against PR 1 solver contracts):
    • content_weight.score = SUM of member scores (more content in a track = larger share of available space — matches the proportional distribution in both compute_zone_layout row solver and compute_zone_layout_cols col solver).
    • min_height_px = MAX across members (row track must accommodate the tallest side-by-side member min; the cols solver does not consume this field but the value is harmless on that path).
    • position / template_id = "+".join(...) of member ids — surfaces composite ("bottom-left+bottom-right", "tB+tC") in Step 8 trace raw_zone_layout for explainability.
  • Missing-position guard: raises ValueError listing the absent positions and the actual position keys present in zones_data — composition planning must declare every zone referenced by TOPOLOGY_AXIS_MAP[topology][axis].
  • Default fallback: members without min_height_px use DEFAULT_ZONE_MIN_HEIGHT_PX (module constant at line 120 — same fallback compute_zone_layout itself uses at line 791).
  • No dispatch wiring added. build_layout_css normal path still routes only topology in {"rows","cols"} to dynamic sinks; all 2-D topologies still fall through to _build_fr_default (computation == "fr_default_from_preset", dynamic_rows == False, dynamic_cols == False). u3 will add _build_2d_dynamic (the consumer) and u6 will wire dispatch.

evidence

  • git log -1 --format=%H201099e53b0048f3040e17ee9b0394ba9ad6e940 (Stage 2 baseline preserved; no commit/push this turn per Stage 3 contract).
  • git diff --stat src/phase_z2_pipeline.py1 file changed, 80 insertions(+) (cumulative across u1 + u2; u2-only delta = 80 36 = 44 lines ≤ 50-line gate ✓).
  • git diff --numstat80 0 src/phase_z2_pipeline.py (single file ≤ 3-file gate ✓; 0 deletions = pure insertion).
  • git diff --check src/phase_z2_pipeline.py → no whitespace errors.
  • git diff --name-only HEAD -- src/space_allocator.py → empty (Kei legacy invariant preserved ✓).
  • python -c "import ast; ast.parse(...)"PARSE OK.
  • Behavior smoke (import-load with module on sys.path):
    • single-position track _aggregate_axis_zone(['top'], zones){'position': 'top', 'template_id': 'tA', 'content_weight': {'score': 4.0}, 'min_height_px': 200} ✓ (verbatim passthrough of member zone shape).
    • multi-position track _aggregate_axis_zone(['bottom-left','bottom-right'], zones){'position': 'bottom-left+bottom-right', 'template_id': 'tB+tC', 'content_weight': {'score': 5.0}, 'min_height_px': 250} ✓ (sum=2+3=5; max=max(150,250)=250).
    • default min_height fallback when member lacks min_height_px → returns DEFAULT_ZONE_MIN_HEIGHT_PX (100) when member-with-min < default ✓.
    • missing-position guard _aggregate_axis_zone(['nope'], zones)ValueError: _aggregate_axis_zone: positions ['nope'] absent from zones_data (have ...) ✓.
  • PR 1 solver compatibility (T topology with TOPOLOGY_AXIS_MAP["T"] from u1):
    • row synthesis: [_aggregate_axis_zone(g, zones) for g in TOPOLOGY_AXIS_MAP["T"]["rows"]]compute_zone_layout(...)heights_px = [254, 317], sum = 571 == SLIDE_BODY_HEIGHT - GRID_GAP (585 - 14 = 571) ✓.
    • col synthesis: [_aggregate_axis_zone(g, zones) for g in TOPOLOGY_AXIS_MAP["T"]["cols"]]compute_zone_layout_cols(...)widths_px = [466, 700], sum = 1166 == SLIDE_BODY_WIDTH - GRID_GAP (1180 - 14 = 1166) ✓.
  • Scope-lock no-creep check:
    • hasattr(p, '_build_2d_dynamic')False (u3) ✓
    • hasattr(p, '_derive_axis_tracks_from_override')False (u4) ✓
    • hasattr(p, '_override_to_grid_tracks')False (u5) ✓
    • build_layout_css('top-1-bottom-2', ...)["computation"]'fr_default_from_preset' (dispatch still falls through; u6 will route) ✓.

remaining_units

u3, u4, u5, u6, u7, u8, u9, u10, u11, u12, u13, u14, u15, u16, u17, u18, u19, u20, u21, u22, u23, u24, u25, u26

follow_up_issue_candidates

None this turn. No new axis surfaced — _aggregate_axis_zone matches the Stage 2 plan and reuses existing PR 1 solver contracts (no min_width_px needed; compute_zone_layout_cols is weight-only). Composite position keys for synthetic zones ("top-left+top-right" style) flow into raw_zone_layout trace explainability; Step 8 computation label change to "2d_dynamic_aggregated" is scheduled for u3 (sink) — not introduced here.