IMP-04 F17 schema correction — paired_rows_4x2 + pill alternation + source-faithful theme
source = 8 atomic issues (4 paired rows × 2 cells per texts.md), 이전 strict-4
가 source 의 절반 누락. round 55~73 review-loop 의 calibration frame.
- contract : source_shape=top_bullets / layout_variant=paired_rows_4x2_alternating_pills
/ strict 8 (no pad/truncate) / role_order row_{1..4}_{left,right} / visual_hints
pill_positions + row_gap_after / builder paired_rows_4x2_slots
- builder : new _build_paired_rows_4x2_slots — 2-axis (row × side) deterministic
index mapping, strict 8 raises before render, quadrant_item parser 재사용
- partial : 4-row × 2-cell flex, pill alternation (row 1/3 top, row 2/4 bottom
via column-reverse), row 2-3 visual gap, source-faithful color (rgb(204,82,0)
→rgb(136,55,0) title + #60A451 row border + rgba(250,237,203,0.15) bg + #0c271e
body + 2px dashed #60A451 cell 분할선), pill = CSS approximation (asset crop
variant single-pass 비용 高 → fallback per Codex round 62/68 scope cap, pill
shape + alternation + green/cream/brown theme 보존), no row headers (source
부재, inference 금지)
- fixture : flat 8 top-bullet (texts.md 8 issues 그대로)
- smoke + R3 : PASS (11/11 self-check, 5535 chars partial, 8 units rendered,
pill alternation 정합, row 2-3 gap, no invented row headers)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -577,12 +577,73 @@ def _build_compare_table_2col(section, units, contract) -> dict:
|
||||
return payload
|
||||
|
||||
|
||||
def _build_paired_rows_4x2_slots(section, units, contract) -> dict:
|
||||
"""F17-style — paired_rows_4x2_alternating_pills. top_bullets 8 units → 2-axis keyed slots.
|
||||
|
||||
1-axis (quadrant_flat_slots = TL/TR/BL/BR) vs 2-axis (row × side) :
|
||||
- quadrant : index 1..4 → quadrant_N_{label,body}
|
||||
- paired_rows_4x2 : index 1..8 → row_R_SIDE_{label,body} where R = ceil(i/2), SIDE = left|right
|
||||
|
||||
deterministic index mapping per Codex round 60 §Q3 answer + round 70 §1 :
|
||||
unit 1 → row_1_left unit 2 → row_1_right
|
||||
unit 3 → row_2_left unit 4 → row_2_right
|
||||
unit 5 → row_3_left unit 6 → row_3_right
|
||||
unit 7 → row_4_left unit 8 → row_4_right
|
||||
|
||||
strict 8 : under/over → FitError before render (Codex round 60 §3, round 62 acceptance
|
||||
criterion "no pad_to/truncate_at fallback hides cardinality mismatch").
|
||||
parser = quadrant_item (label + body heading-less) — F17 atomic issue = single label + single body.
|
||||
|
||||
builder_options :
|
||||
item_parser : ITEM_PARSERS key (default = "quadrant_item")
|
||||
label_key_pattern : "row_{r}_{side}_label"
|
||||
body_key_pattern : "row_{r}_{side}_body"
|
||||
rows : 4
|
||||
sides : ["left", "right"]
|
||||
"""
|
||||
options = contract["payload"]["builder_options"]
|
||||
parser_name = options["item_parser"]
|
||||
parser = ITEM_PARSERS.get(parser_name)
|
||||
if parser is None:
|
||||
raise ValueError(
|
||||
f"Contract '{contract['template_id']}' references item_parser='{parser_name}' "
|
||||
f"but ITEM_PARSERS has no such entry."
|
||||
)
|
||||
|
||||
label_key = options.get("label_key_pattern", "row_{r}_{side}_label")
|
||||
body_key = options.get("body_key_pattern", "row_{r}_{side}_body")
|
||||
rows = options.get("rows", 4)
|
||||
sides = options.get("sides", ["left", "right"])
|
||||
expected = rows * len(sides)
|
||||
|
||||
if len(units) != expected:
|
||||
raise ValueError(
|
||||
f"Contract '{contract['template_id']}' requires strict {expected} units "
|
||||
f"(rows={rows} × sides={len(sides)}), got {len(units)}. "
|
||||
f"silent pad/truncate is disabled for paired_rows_4x2_slots."
|
||||
)
|
||||
|
||||
payload: dict = {}
|
||||
payload.update(_resolve_title(section, contract["payload"], contract))
|
||||
|
||||
parsed = [parser(u) for u in units]
|
||||
idx = 0
|
||||
for r in range(1, rows + 1):
|
||||
for side in sides:
|
||||
payload[label_key.format(r=r, side=side)] = parsed[idx]["label"]
|
||||
payload[body_key.format(r=r, side=side)] = parsed[idx]["body"]
|
||||
idx += 1
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
PAYLOAD_BUILDERS: dict[str, Callable] = {
|
||||
"items_with_role": _build_items_with_role,
|
||||
"process_product_pair": _build_process_product_pair,
|
||||
"quadrant_flat_slots": _build_quadrant_flat_slots,
|
||||
"cycle_intersect_3": _build_cycle_intersect_3,
|
||||
"compare_table_2col": _build_compare_table_2col,
|
||||
"paired_rows_4x2_slots": _build_paired_rows_4x2_slots,
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user