IMP — 89-d B5 frame_slot_metrics marker expansion (split from #89, paired with #94) #96

Open
opened 2026-05-24 01:06:32 +09:00 by Kyeongmin · 4 comments
Owner

IMP — 89-d B5 frame_slot_metrics marker expansion (split from #89)

관련 step: Step 14 (visual check) + Step 21 (debug/trace)
source: #89 split — Stage 1 R1 의 4 sub-axis 중 89-d 분리 (2026-05-24)
roadmap axis: R1 (안정성) — Layer A first-class lock
wave: P2 (after #91 acceptance gate, after #94 89-b)
priority: 낮 — Selenium consumer 이미 partial-agnostic, marker 만 확대
dependency: #89 closed (89-a complete), #94 89-b 선결 (marker convention 통일), #91 acceptance gate 권장

scope

data-frame-slot-id attribute 를 marker-less partial 에 추가 (B5 measurement marker 확대).

#89 Stage 1 R1 evidence:

  • src/phase_z2_pipeline.py:2734-2761 Selenium scan = 이미 generic (slide.querySelectorAll('[data-frame-slot-id]'))
  • F29 + F9 = 이미 marker 있음
  • 11 partial = marker 부재 → 본 이슈 scope
  • #94 89-b 의 data-region-id / data-content-unit-id marker convention 과 paired — 같은 partial 동시 작업 또는 #94

out of scope

  • Selenium scan 자체 변경 (이미 generic — JS 변경 X)
  • partial 의 시각 / 구조 변경
  • 19 contract-only template (no partial HTML)

guardrail / validation

  • data-frame-slot-id="<sub_zone.id>" 추가 (additive only)
  • frame_contracts.yamlsub_zones[i].idpartial_target_path selector 의 mapping 정합
  • mdx 01-05 의 frame_slot_metrics count 가 F29 외 다른 partial 에서도 측정 됨 확인
  • final.html SHA = byte-equivalent except for new data-* attrs
  • #94 89-b 의 marker convention 따라감 (cross-issue 통일 — patchwork 방지)

relevant feedback

  • feedback_workflow_atomicity_rules — 1 commit = 1 partial 권장
  • feedback_no_hardcoding — deterministic marker injection

🤖 Claude Opus 4.7 — #89 split (2026-05-24)

## IMP — 89-d B5 frame_slot_metrics marker expansion (split from #89) **관련 step**: Step 14 (visual check) + Step 21 (debug/trace) **source**: #89 split — Stage 1 R1 의 4 sub-axis 중 89-d 분리 (2026-05-24) **roadmap axis**: R1 (안정성) — Layer A first-class lock **wave**: P2 (after #91 acceptance gate, after #94 89-b) **priority**: 낮 — Selenium consumer 이미 partial-agnostic, marker 만 확대 **dependency**: #89 closed (89-a complete), **#94 89-b 선결** (marker convention 통일), #91 acceptance gate 권장 ### scope `data-frame-slot-id` attribute 를 marker-less partial 에 추가 (B5 measurement marker 확대). #89 Stage 1 R1 evidence: - `src/phase_z2_pipeline.py:2734-2761` Selenium scan = 이미 generic (`slide.querySelectorAll('[data-frame-slot-id]')`) - F29 + F9 = 이미 marker 있음 - 11 partial = marker 부재 → 본 이슈 scope - **#94 89-b 의 `data-region-id` / `data-content-unit-id` marker convention 과 paired** — 같은 partial 동시 작업 또는 #94 후 ### out of scope - Selenium scan 자체 변경 (이미 generic — JS 변경 X) - partial 의 시각 / 구조 변경 - 19 contract-only template (no partial HTML) ### guardrail / validation - `data-frame-slot-id="<sub_zone.id>"` 추가 (additive only) - `frame_contracts.yaml` 의 `sub_zones[i].id` 와 `partial_target_path` selector 의 mapping 정합 - mdx 01-05 의 `frame_slot_metrics` count 가 F29 외 다른 partial 에서도 측정 됨 확인 - final.html SHA = byte-equivalent except for new `data-*` attrs - #94 89-b 의 marker convention 따라감 (cross-issue 통일 — patchwork 방지) ### relevant feedback - `feedback_workflow_atomicity_rules` — 1 commit = 1 partial 권장 - `feedback_no_hardcoding` — deterministic marker injection 🤖 Claude Opus 4.7 — #89 split (2026-05-24)
Author
Owner

[Claude #1] Stage 1 problem-review — IMP-89-d B5 frame_slot_metrics marker expansion (#96)

=== EVIDENCE ===

HEAD: 97b7833 (main, working tree clean for tracked files relevant to #96 scope)

Selenium scan locus correction (issue body says src/phase_z2_pipeline.py:2734-2761, actual is 3864):

  • src/phase_z2_pipeline.py:3860-3887 — B5 v0 frame_slot_metrics builder. The actual scan = slide.querySelectorAll('[data-frame-slot-id]').forEach((cell) => { ... }) at L3864. This is a generic attribute-existence selector — partial-agnostic. Issue body's L2734-2761 reference is incorrect (that range is _build_grid_dynamic_2d override path); recorded for #96 Stage 2 follow-up.

Existing data-frame-slot-id carriers (2/13 partials):

  • templates/phase_z2/families/process_product_two_way.html (F29, frame_id 1171281210) — 6 inline carriers on .f29b__cell--left × 3 (data-frame-slot-id="process_column") and .f29b__cell--right × 3 (data-frame-slot-id="product_column"). Marker values match frame_contracts.yaml:111-119 sub_zones process_column / product_column.
  • templates/phase_z2/families/pre_construction_model_info_stacked.html (F9, frame_id 1171281180) — 1 inline carrier at L180 on .f9b__pill with data-frame-slot-id="pill_dynamic". NB: marker value pill_dynamic does NOT match frame_contracts.yaml:852-857 sub_zone.id pills (pre-existing convention divergence; out-of-scope per issue body "F29 + F9 = 이미 marker 있음").

Marker-less partials (11/13 — #96 scope):

  • templates/phase_z2/families/app_sw_package_vs_solution.html
  • templates/phase_z2/families/bim_current_problems_paired.html
  • templates/phase_z2/families/bim_dx_comparison_table.html
  • templates/phase_z2/families/bim_issues_quadrant_four.html
  • templates/phase_z2/families/construction_bim_three_usage.html
  • templates/phase_z2/families/construction_goals_three_circle_intersection.html
  • templates/phase_z2/families/dx_sw_necessity_three_perspectives.html
  • templates/phase_z2/families/info_management_what_how_when.html
  • templates/phase_z2/families/sw_reality_three_emphasis.html
  • templates/phase_z2/families/three_parallel_requirements.html
  • templates/phase_z2/families/three_persona_benefits.html

Verified with grep -L "data-frame-slot-id" templates/phase_z2/families/*.html (13 total .html files; 2 carriers; 11 absentees).

#94 paired axis confirmation:

  • src/region_marker_stamper.py:9-12, 80-137 — IMP-94 stamper is root-div-only (one stamp per zone on first data-template-id div). L92-93 explicit comment: frame_slot_id is "optional, ignored here — reserved for #96 (89-d)". L44 guardrail: "Disjoint from #96 (data-frame-slot-id is a separate axis / attr)".
  • .orchestrator/issues/94_stage_problem-review_exit.md:31 + 94_stage_simulation-plan_exit.md:11,16 — explicit out-of-scope hand-offs to #96, with F9/F29 frame-slot behavior preserved.
  • tests/test_phase_z2_imp94_marker_parity.py:585-606, 620-634, 1041-1068 — existing parity tests assert F29 process_column / product_column counts and F9 pill_dynamic count are unchanged by stamper, and that data-frame-slot-id axis is disjoint from data-region-id / data-content-unit-id. Adding markers to 11 new partials must NOT change F29/F9 baseline counts.

frame_contracts.yaml sub_zones[i].id ↔ partial_target_path mapping:

  • File has sub_zones with id: and partial_target_path: pairs across all 13 partials (32-frame catalog — 13 partial-backed + 19 contract-only). Per-cell CSS selectors (e.g., .f13b__cols > .f13b__col:nth-child(1), .f16b__quadrant--tl, .f29b__grid .f29b__cell--left) identify the DOM target for each sub_zone — these are the injection sites for data-frame-slot-id="<sub_zone.id>". (Selector-by-selector enumeration deferred to Stage 2.)

=== EXIT REPORT (English, binding contract) ===

root_cause: The B5 frame_slot_metrics Selenium scan at src/phase_z2_pipeline.py:3864 is already partial-agnostic (querySelectorAll('[data-frame-slot-id]')), but only 2/13 family partials emit data-frame-slot-id markers (F29 process_product_two_way × 6 cells, F9 pre_construction_model_info_stacked × 1 cell). The remaining 11 partials carry zero data-frame-slot-id attributes, so frame_slot_metrics returns empty entries for non-F29/F9 frames — Step 14 (visual check) and Step 21 (debug/trace) lose per-cell measurement coverage on those frames. This is a marker-emission gap, NOT a scan-side defect; the fix is per-cell marker injection on the 11 marker-less partials, sourced from frame_contracts.yaml sub_zones[i].id and targeted at partial_target_path selector locations.

key_files:

  • templates/phase_z2/families/*.html (11 marker-less partials — injection targets enumerated in EVIDENCE)
  • templates/phase_z2/catalog/frame_contracts.yaml (sub_zones[i].id + partial_target_path source of truth — 13 partial-backed contracts)
  • src/phase_z2_pipeline.py:3860-3887 (B5 v0 frame_slot_metrics consumer — generic scan, no change)
  • src/region_marker_stamper.py:9-12, 44, 92-93 (#94 axis boundary — data-frame-slot-id explicitly disjoint)
  • tests/test_phase_z2_imp94_marker_parity.py:585-606, 620-634, 1041-1068 (existing F29/F9 baseline counts + axis-disjoint asserts — must remain green)

scope_lock: Inject data-frame-slot-id="<sub_zones[i].id>" (additive HTML attribute) into the 11 marker-less family partials at the DOM target indicated by frame_contracts.yaml partial_target_path for each sub_zone. F29 + F9 are not modified. No change to Selenium scan, no change to frame_contracts.yaml, no change to frame_slot_metrics JS, no change to region_marker_stamper.py. Marker emission per-cell, mirroring F29's inline-template pattern (NOT extending the #94 root-div stamper, which is by-design root-only).

out_of_scope:

  • F29 / F9 existing marker values (process_column, product_column, pill_dynamic) — preserved as-is per issue body and .orchestrator/issues/94_stage_simulation-plan_exit.md:16.
  • F9 marker convention reconciliation (pill_dynamic ≠ sub_zone.id pills) — pre-existing divergence, separate issue.
  • 19 contract-only frames (no partial HTML) — no DOM exists to mark.
  • Selenium scan / frame_slot_metrics JS — already generic at src/phase_z2_pipeline.py:3864.
  • data-region-id / data-content-unit-id markers — #94 axis, root-div only, disjoint.
  • frame_contracts.yaml schema or sub_zones[i].id renames.
  • region_marker_stamper.py extension to per-cell — stays root-only.
  • MDX mutation, AI call, layout change, visual change, B4 frame_selection evidence integration.

guardrails:

  • Additive only — append data-frame-slot-id="..." as a new attribute; never modify existing attributes / classes / content.
  • Marker value = frame_contracts.yaml sub_zones[i].id verbatim (process fix, not artifact fix — feedback_no_hardcoding).
  • F29 / F9 untouched — tests/test_phase_z2_imp94_marker_parity.py:585-606, 620-634 must remain green; F29 6 carriers + F9 1 carrier counts preserved.
  • Axis disjoint — data-frame-slot-id MUST NOT collide with data-region-id / data-content-unit-id (per region_marker_stamper.py:44 and parity test L1041-1068).
  • final.html byte-equivalent except for new data-frame-slot-id attrs (per issue body validation criterion).
  • 1 commit = 1 partial (feedback_workflow_atomicity_rules) — 11 partials → 11 implementation units.
  • AI=0 (PZ-1) — deterministic marker injection, no LLM call.
  • MDX 무손실 (no content mutation through marker injection).
  • Per-cell target identified by partial_target_path CSS selector — when a sub_zone's selector matches N elements (e.g., F29's .f29b__grid .f29b__cell--left matches 3 cells), all N elements receive the same data-frame-slot-id="<sub_zone.id>" (mirroring F29 precedent).

unresolved_questions:

  • Q1 (injection mechanism): inline-template edit per partial (mirror F29 pattern, deterministic, 1-commit-per-partial) vs. selector-aware post-render stamper extension (single point of plumbing, more abstract)? Lock in Stage 2. Stage 1 evidence favors template edits because (a) F29 already does this, (b) region_marker_stamper.py:44 declares disjoint axis, (c) partial_target_path selectors are static per-partial — no runtime context needed.
  • Q2 (sub_zones with multiple-element selectors): when partial_target_path matches N>1 elements, place marker on each (F29 precedent) or wrap in container? Stage 2 must enumerate per-partial.
  • Q3 (validation strategy): per-partial parity test (mirror tests/test_phase_z2_imp94_marker_parity.py shape) vs. single combined test scanning all 11 partials for data-frame-slot-id="<expected sub_zone.id>" after render? Lock in Stage 2.
  • Q4 (MDX 01-05 coverage): which fresh-validation MDX → partial routing produces non-zero frame_slot_metrics count for each of the 11 newly-marked partials? Stage 2 must enumerate routing matrix to confirm frame_slot_metrics count > 0 for at least one MDX per partial (per issue body validation criterion).

evidence: see EVIDENCE block above. Fresh validation (HEAD 97b7833, branch main, 2026-05-27): grep -l "data-frame-slot-id" templates/phase_z2/families/*.html returns 2 files; inventory of 13 .html files in templates/phase_z2/families/ verified; Selenium scan at src/phase_z2_pipeline.py:3864 is generic; #94 axis disjoint per src/region_marker_stamper.py:44, 92-93 and tests/test_phase_z2_imp94_marker_parity.py:1041-1068; #94 Stage 1/2 exit reports both name #96 as the data-frame-slot-id axis out-of-scope hand-off.

source_comment_ids: [Claude #1] (this turn).

commit_sha: HEAD = 97b7833 (main; no commit for #96 yet).

[Claude #1] Stage 1 problem-review — IMP-89-d B5 frame_slot_metrics marker expansion (#96) === EVIDENCE === **HEAD**: `97b7833` (main, working tree clean for tracked files relevant to #96 scope) **Selenium scan locus correction (issue body says `src/phase_z2_pipeline.py:2734-2761`, actual is 3864)**: - `src/phase_z2_pipeline.py:3860-3887` — B5 v0 `frame_slot_metrics` builder. The actual scan = `slide.querySelectorAll('[data-frame-slot-id]').forEach((cell) => { ... })` at L3864. This is a generic attribute-existence selector — partial-agnostic. Issue body's L2734-2761 reference is incorrect (that range is `_build_grid_dynamic_2d` override path); recorded for #96 Stage 2 follow-up. **Existing `data-frame-slot-id` carriers (2/13 partials)**: - `templates/phase_z2/families/process_product_two_way.html` (F29, frame_id `1171281210`) — 6 inline carriers on `.f29b__cell--left` × 3 (`data-frame-slot-id="process_column"`) and `.f29b__cell--right` × 3 (`data-frame-slot-id="product_column"`). Marker values match `frame_contracts.yaml:111-119` sub_zones `process_column` / `product_column`. - `templates/phase_z2/families/pre_construction_model_info_stacked.html` (F9, frame_id `1171281180`) — 1 inline carrier at L180 on `.f9b__pill` with `data-frame-slot-id="pill_dynamic"`. NB: marker value `pill_dynamic` does NOT match `frame_contracts.yaml:852-857` sub_zone.id `pills` (pre-existing convention divergence; out-of-scope per issue body "F29 + F9 = 이미 marker 있음"). **Marker-less partials (11/13 — #96 scope)**: - `templates/phase_z2/families/app_sw_package_vs_solution.html` - `templates/phase_z2/families/bim_current_problems_paired.html` - `templates/phase_z2/families/bim_dx_comparison_table.html` - `templates/phase_z2/families/bim_issues_quadrant_four.html` - `templates/phase_z2/families/construction_bim_three_usage.html` - `templates/phase_z2/families/construction_goals_three_circle_intersection.html` - `templates/phase_z2/families/dx_sw_necessity_three_perspectives.html` - `templates/phase_z2/families/info_management_what_how_when.html` - `templates/phase_z2/families/sw_reality_three_emphasis.html` - `templates/phase_z2/families/three_parallel_requirements.html` - `templates/phase_z2/families/three_persona_benefits.html` Verified with `grep -L "data-frame-slot-id" templates/phase_z2/families/*.html` (13 total .html files; 2 carriers; 11 absentees). **#94 paired axis confirmation**: - `src/region_marker_stamper.py:9-12, 80-137` — IMP-94 stamper is root-div-only (one stamp per zone on first `data-template-id` div). L92-93 explicit comment: `frame_slot_id` is "optional, ignored here — reserved for #96 (89-d)". L44 guardrail: "Disjoint from #96 (`data-frame-slot-id` is a separate axis / attr)". - `.orchestrator/issues/94_stage_problem-review_exit.md:31` + `94_stage_simulation-plan_exit.md:11,16` — explicit out-of-scope hand-offs to #96, with F9/F29 frame-slot behavior preserved. - `tests/test_phase_z2_imp94_marker_parity.py:585-606, 620-634, 1041-1068` — existing parity tests assert F29 `process_column` / `product_column` counts and F9 `pill_dynamic` count are unchanged by stamper, and that `data-frame-slot-id` axis is disjoint from `data-region-id` / `data-content-unit-id`. Adding markers to 11 new partials must NOT change F29/F9 baseline counts. **`frame_contracts.yaml` sub_zones[i].id ↔ partial_target_path mapping**: - File has sub_zones with `id:` and `partial_target_path:` pairs across all 13 partials (32-frame catalog — 13 partial-backed + 19 contract-only). Per-cell CSS selectors (e.g., `.f13b__cols > .f13b__col:nth-child(1)`, `.f16b__quadrant--tl`, `.f29b__grid .f29b__cell--left`) identify the DOM target for each sub_zone — these are the injection sites for `data-frame-slot-id="<sub_zone.id>"`. (Selector-by-selector enumeration deferred to Stage 2.) === EXIT REPORT (English, binding contract) === **root_cause**: The B5 `frame_slot_metrics` Selenium scan at `src/phase_z2_pipeline.py:3864` is already partial-agnostic (`querySelectorAll('[data-frame-slot-id]')`), but only 2/13 family partials emit `data-frame-slot-id` markers (F29 `process_product_two_way` × 6 cells, F9 `pre_construction_model_info_stacked` × 1 cell). The remaining 11 partials carry zero `data-frame-slot-id` attributes, so `frame_slot_metrics` returns empty entries for non-F29/F9 frames — Step 14 (visual check) and Step 21 (debug/trace) lose per-cell measurement coverage on those frames. This is a marker-emission gap, NOT a scan-side defect; the fix is per-cell marker injection on the 11 marker-less partials, sourced from `frame_contracts.yaml` sub_zones[i].id and targeted at `partial_target_path` selector locations. **key_files**: - `templates/phase_z2/families/*.html` (11 marker-less partials — injection targets enumerated in EVIDENCE) - `templates/phase_z2/catalog/frame_contracts.yaml` (sub_zones[i].id + partial_target_path source of truth — 13 partial-backed contracts) - `src/phase_z2_pipeline.py:3860-3887` (B5 v0 `frame_slot_metrics` consumer — generic scan, no change) - `src/region_marker_stamper.py:9-12, 44, 92-93` (#94 axis boundary — `data-frame-slot-id` explicitly disjoint) - `tests/test_phase_z2_imp94_marker_parity.py:585-606, 620-634, 1041-1068` (existing F29/F9 baseline counts + axis-disjoint asserts — must remain green) **scope_lock**: Inject `data-frame-slot-id="<sub_zones[i].id>"` (additive HTML attribute) into the 11 marker-less family partials at the DOM target indicated by `frame_contracts.yaml` `partial_target_path` for each sub_zone. F29 + F9 are not modified. No change to Selenium scan, no change to `frame_contracts.yaml`, no change to `frame_slot_metrics` JS, no change to `region_marker_stamper.py`. Marker emission per-cell, mirroring F29's inline-template pattern (NOT extending the #94 root-div stamper, which is by-design root-only). **out_of_scope**: - F29 / F9 existing marker values (`process_column`, `product_column`, `pill_dynamic`) — preserved as-is per issue body and `.orchestrator/issues/94_stage_simulation-plan_exit.md:16`. - F9 marker convention reconciliation (`pill_dynamic` ≠ sub_zone.id `pills`) — pre-existing divergence, separate issue. - 19 contract-only frames (no partial HTML) — no DOM exists to mark. - Selenium scan / `frame_slot_metrics` JS — already generic at `src/phase_z2_pipeline.py:3864`. - `data-region-id` / `data-content-unit-id` markers — #94 axis, root-div only, disjoint. - `frame_contracts.yaml` schema or sub_zones[i].id renames. - `region_marker_stamper.py` extension to per-cell — stays root-only. - MDX mutation, AI call, layout change, visual change, B4 frame_selection evidence integration. **guardrails**: - Additive only — append `data-frame-slot-id="..."` as a new attribute; never modify existing attributes / classes / content. - Marker value = `frame_contracts.yaml` sub_zones[i].id verbatim (process fix, not artifact fix — `feedback_no_hardcoding`). - F29 / F9 untouched — `tests/test_phase_z2_imp94_marker_parity.py:585-606, 620-634` must remain green; F29 6 carriers + F9 1 carrier counts preserved. - Axis disjoint — `data-frame-slot-id` MUST NOT collide with `data-region-id` / `data-content-unit-id` (per `region_marker_stamper.py:44` and parity test L1041-1068). - final.html byte-equivalent except for new `data-frame-slot-id` attrs (per issue body validation criterion). - 1 commit = 1 partial (`feedback_workflow_atomicity_rules`) — 11 partials → 11 implementation units. - AI=0 (PZ-1) — deterministic marker injection, no LLM call. - MDX 무손실 (no content mutation through marker injection). - Per-cell target identified by `partial_target_path` CSS selector — when a sub_zone's selector matches N elements (e.g., F29's `.f29b__grid .f29b__cell--left` matches 3 cells), all N elements receive the same `data-frame-slot-id="<sub_zone.id>"` (mirroring F29 precedent). **unresolved_questions**: - Q1 (injection mechanism): inline-template edit per partial (mirror F29 pattern, deterministic, 1-commit-per-partial) vs. selector-aware post-render stamper extension (single point of plumbing, more abstract)? Lock in Stage 2. Stage 1 evidence favors template edits because (a) F29 already does this, (b) `region_marker_stamper.py:44` declares disjoint axis, (c) `partial_target_path` selectors are static per-partial — no runtime context needed. - Q2 (sub_zones with multiple-element selectors): when `partial_target_path` matches N>1 elements, place marker on each (F29 precedent) or wrap in container? Stage 2 must enumerate per-partial. - Q3 (validation strategy): per-partial parity test (mirror `tests/test_phase_z2_imp94_marker_parity.py` shape) vs. single combined test scanning all 11 partials for `data-frame-slot-id="<expected sub_zone.id>"` after render? Lock in Stage 2. - Q4 (MDX 01-05 coverage): which fresh-validation MDX → partial routing produces non-zero `frame_slot_metrics` count for each of the 11 newly-marked partials? Stage 2 must enumerate routing matrix to confirm `frame_slot_metrics count > 0` for at least one MDX per partial (per issue body validation criterion). **evidence**: see EVIDENCE block above. Fresh validation (HEAD `97b7833`, branch `main`, 2026-05-27): `grep -l "data-frame-slot-id" templates/phase_z2/families/*.html` returns 2 files; inventory of 13 .html files in `templates/phase_z2/families/` verified; Selenium scan at `src/phase_z2_pipeline.py:3864` is generic; #94 axis disjoint per `src/region_marker_stamper.py:44, 92-93` and `tests/test_phase_z2_imp94_marker_parity.py:1041-1068`; #94 Stage 1/2 exit reports both name #96 as the `data-frame-slot-id` axis out-of-scope hand-off. **source_comment_ids**: [Claude #1] (this turn). **commit_sha**: HEAD = `97b7833` (main; no commit for #96 yet).
Author
Owner

[Codex #1] Stage 1 problem-review - IMP-96

Verdict: root cause and scope are verified, with two path/location corrections that should be carried into Stage 2.

Root cause:

  • B5 frame_slot_metrics is built from a generic DOM selector, slide.querySelectorAll('[data-frame-slot-id]'), in src/phase_z2_pipeline.py:3864. The Selenium consumer is already partial-agnostic; missing metrics are caused by marker-less family partials, not by a consumer selector problem.
  • The issue body's src/phase_z2_pipeline.py:2734-2761 location is stale. That range is the _build_grid_dynamic_2d override path, not the B5 scan. The current scan locus is src/phase_z2_pipeline.py:3860-3887.
  • The contract file is templates/phase_z2/catalog/frame_contracts.yaml, not root-level frame_contracts.yaml. A root-level lookup fails; Stage 2 should use the catalog path.

Scope lock:

  • The implementation scope should be additive data-frame-slot-id="<sub_zones[i].id>" injection into the 11 marker-less partials only.
  • Do not change the Selenium scan in src/phase_z2_pipeline.py; it already consumes any element carrying data-frame-slot-id.
  • Do not merge this with #94 marker stamping. src/region_marker_stamper.py is explicitly root-div-only for data-region-id / data-content-unit-id, ignores frame_slot_id, and documents data-frame-slot-id as the separate #96 axis.
  • Preserve existing F29 and F9 behavior unless a later stage explicitly plans a compatibility migration. F29 is already aligned to contract sub-zone ids; F9 has a pre-existing divergence (pill_dynamic in HTML vs pills in the contract), which the issue body treats as existing marker behavior rather than the 11-partial expansion target.

Verified marker state:

  • There are 13 family partials under templates/phase_z2/families.
  • Existing carriers are 2/13 partials:
    • templates/phase_z2/families/process_product_two_way.html: six carriers, three process_column and three product_column; these match templates/phase_z2/catalog/frame_contracts.yaml sub-zone ids for F29.
    • templates/phase_z2/families/pre_construction_model_info_stacked.html: one carrier, pill_dynamic; the contract sub-zone id is pills.
  • Marker-less partials are 11/13 and match the issue scope:
    • templates/phase_z2/families/app_sw_package_vs_solution.html
    • templates/phase_z2/families/bim_current_problems_paired.html
    • templates/phase_z2/families/bim_dx_comparison_table.html
    • templates/phase_z2/families/bim_issues_quadrant_four.html
    • templates/phase_z2/families/construction_bim_three_usage.html
    • templates/phase_z2/families/construction_goals_three_circle_intersection.html
    • templates/phase_z2/families/dx_sw_necessity_three_perspectives.html
    • templates/phase_z2/families/info_management_what_how_when.html
    • templates/phase_z2/families/sw_reality_three_emphasis.html
    • templates/phase_z2/families/three_parallel_requirements.html
    • templates/phase_z2/families/three_persona_benefits.html

Stage 2 implications:

  • Plan against templates/phase_z2/catalog/frame_contracts.yaml sub-zone id plus partial_target_path mappings.
  • Use deterministic partial edits or a deterministic marker-injection helper; no MDX 03/04/05 hardcoding.
  • Validation should confirm the new markers increase frame_slot_metrics coverage for non-F29 partials while leaving rendered content structure byte-equivalent except for additive data-* attributes.

=== EVIDENCE ===
Commands run:

  • git status --short; git rev-parse --short HEAD
  • rg -n "data-frame-slot-id|querySelectorAll\('\[data-frame-slot-id\]'\)|frame_slot_metrics" src/phase_z2_pipeline.py templates/phase_z2/families frame_contracts.yaml
  • rg -n "frame_slot_id|data-frame-slot-id|reserved for #96|Disjoint from #96|IMP-94" src/region_marker_stamper.py .orchestrator/issues tests/test_phase_z2_imp94_marker_parity.py
  • rg --files -g 'frame_contracts.yaml' -g '*contracts*.yaml'
  • Get-ChildItem -LiteralPath 'templates\phase_z2\families' -Filter '*.html' | Select-Object -ExpandProperty Name | Sort-Object
  • Get-ChildItem -LiteralPath 'templates\phase_z2\families' -Filter '*.html' | Where-Object { -not (Select-String -LiteralPath $_.FullName -Pattern 'data-frame-slot-id' -Quiet) } | ForEach-Object { $_.FullName }
  • Get-ChildItem -LiteralPath 'templates\phase_z2\families' -Filter '*.html' | Select-String -Pattern 'data-frame-slot-id'
  • Get-Content -LiteralPath 'src\phase_z2_pipeline.py' | Select-Object -Index (2733..2761)
  • Get-Content -LiteralPath 'src\phase_z2_pipeline.py' | Select-Object -Index (3859..3887)
  • Get-Content -LiteralPath 'templates\phase_z2\catalog\frame_contracts.yaml' | Select-Object -Index (20..70)
  • Get-Content -LiteralPath 'templates\phase_z2\catalog\frame_contracts.yaml' | Select-Object -Index (80..125)
  • Get-Content -LiteralPath 'templates\phase_z2\catalog\frame_contracts.yaml' | Select-Object -Index (830..860)
  • Get-Content -LiteralPath 'src\region_marker_stamper.py' | Select-Object -Index (0..15), (40..45), (78..137)
  • Select-String -LiteralPath '.orchestrator\issues\94_stage_problem-review_exit.md','.orchestrator\issues\94_stage_simulation-plan_exit.md' -Pattern '#96|data-frame-slot-id|frame-slot|frame_slot'
  • Select-String -LiteralPath 'tests\test_phase_z2_imp94_marker_parity.py' -Pattern 'data-frame-slot-id|#96 axis|baseline_frame_slot_id_count|REGION_ID_ATTR|CONTENT_UNIT_ID_ATTR'

Files checked:

  • src/phase_z2_pipeline.py
  • src/region_marker_stamper.py
  • templates/phase_z2/catalog/frame_contracts.yaml
  • templates/phase_z2/families/*.html via per-file Get-ChildItem / Select-String
  • .orchestrator/issues/94_stage_problem-review_exit.md
  • .orchestrator/issues/94_stage_simulation-plan_exit.md
  • tests/test_phase_z2_imp94_marker_parity.py

Test results:

  • Not run. Current Stage 1 instruction is grep/find scope verification and explicitly says NO pytest.

Verified facts:

  • HEAD is 97b7833.
  • Working tree is dirty with unrelated tracked/untracked files; no files were modified for implementation in this Stage 1 review.
  • Root-level frame_contracts.yaml is missing; the live contract file is templates/phase_z2/catalog/frame_contracts.yaml.
  • B5 scan uses the generic selector [data-frame-slot-id] at src/phase_z2_pipeline.py:3864.
  • src/phase_z2_pipeline.py:2734-2761 is not the B5 scan; it is layout override logic.
  • Family partial count is 13 total, 2 with data-frame-slot-id, 11 without.
  • F29 existing marker values match contract sub-zone ids process_column and product_column.
  • F9 existing marker value pill_dynamic does not match contract sub-zone id pills; this is pre-existing and should be treated as compatibility-sensitive.
  • #94 artifacts explicitly reserve data-frame-slot-id for #96 and preserve F9/F29 frame-slot behavior.

FINAL_CONSENSUS: YES

[Codex #1] Stage 1 problem-review - IMP-96 Verdict: root cause and scope are verified, with two path/location corrections that should be carried into Stage 2. Root cause: - B5 `frame_slot_metrics` is built from a generic DOM selector, `slide.querySelectorAll('[data-frame-slot-id]')`, in `src/phase_z2_pipeline.py:3864`. The Selenium consumer is already partial-agnostic; missing metrics are caused by marker-less family partials, not by a consumer selector problem. - The issue body's `src/phase_z2_pipeline.py:2734-2761` location is stale. That range is the `_build_grid_dynamic_2d` override path, not the B5 scan. The current scan locus is `src/phase_z2_pipeline.py:3860-3887`. - The contract file is `templates/phase_z2/catalog/frame_contracts.yaml`, not root-level `frame_contracts.yaml`. A root-level lookup fails; Stage 2 should use the catalog path. Scope lock: - The implementation scope should be additive `data-frame-slot-id="<sub_zones[i].id>"` injection into the 11 marker-less partials only. - Do not change the Selenium scan in `src/phase_z2_pipeline.py`; it already consumes any element carrying `data-frame-slot-id`. - Do not merge this with #94 marker stamping. `src/region_marker_stamper.py` is explicitly root-div-only for `data-region-id` / `data-content-unit-id`, ignores `frame_slot_id`, and documents `data-frame-slot-id` as the separate #96 axis. - Preserve existing F29 and F9 behavior unless a later stage explicitly plans a compatibility migration. F29 is already aligned to contract sub-zone ids; F9 has a pre-existing divergence (`pill_dynamic` in HTML vs `pills` in the contract), which the issue body treats as existing marker behavior rather than the 11-partial expansion target. Verified marker state: - There are 13 family partials under `templates/phase_z2/families`. - Existing carriers are 2/13 partials: - `templates/phase_z2/families/process_product_two_way.html`: six carriers, three `process_column` and three `product_column`; these match `templates/phase_z2/catalog/frame_contracts.yaml` sub-zone ids for F29. - `templates/phase_z2/families/pre_construction_model_info_stacked.html`: one carrier, `pill_dynamic`; the contract sub-zone id is `pills`. - Marker-less partials are 11/13 and match the issue scope: - `templates/phase_z2/families/app_sw_package_vs_solution.html` - `templates/phase_z2/families/bim_current_problems_paired.html` - `templates/phase_z2/families/bim_dx_comparison_table.html` - `templates/phase_z2/families/bim_issues_quadrant_four.html` - `templates/phase_z2/families/construction_bim_three_usage.html` - `templates/phase_z2/families/construction_goals_three_circle_intersection.html` - `templates/phase_z2/families/dx_sw_necessity_three_perspectives.html` - `templates/phase_z2/families/info_management_what_how_when.html` - `templates/phase_z2/families/sw_reality_three_emphasis.html` - `templates/phase_z2/families/three_parallel_requirements.html` - `templates/phase_z2/families/three_persona_benefits.html` Stage 2 implications: - Plan against `templates/phase_z2/catalog/frame_contracts.yaml` sub-zone `id` plus `partial_target_path` mappings. - Use deterministic partial edits or a deterministic marker-injection helper; no MDX 03/04/05 hardcoding. - Validation should confirm the new markers increase `frame_slot_metrics` coverage for non-F29 partials while leaving rendered content structure byte-equivalent except for additive `data-*` attributes. === EVIDENCE === Commands run: - `git status --short; git rev-parse --short HEAD` - `rg -n "data-frame-slot-id|querySelectorAll\('\[data-frame-slot-id\]'\)|frame_slot_metrics" src/phase_z2_pipeline.py templates/phase_z2/families frame_contracts.yaml` - `rg -n "frame_slot_id|data-frame-slot-id|reserved for #96|Disjoint from #96|IMP-94" src/region_marker_stamper.py .orchestrator/issues tests/test_phase_z2_imp94_marker_parity.py` - `rg --files -g 'frame_contracts.yaml' -g '*contracts*.yaml'` - `Get-ChildItem -LiteralPath 'templates\phase_z2\families' -Filter '*.html' | Select-Object -ExpandProperty Name | Sort-Object` - `Get-ChildItem -LiteralPath 'templates\phase_z2\families' -Filter '*.html' | Where-Object { -not (Select-String -LiteralPath $_.FullName -Pattern 'data-frame-slot-id' -Quiet) } | ForEach-Object { $_.FullName }` - `Get-ChildItem -LiteralPath 'templates\phase_z2\families' -Filter '*.html' | Select-String -Pattern 'data-frame-slot-id'` - `Get-Content -LiteralPath 'src\phase_z2_pipeline.py' | Select-Object -Index (2733..2761)` - `Get-Content -LiteralPath 'src\phase_z2_pipeline.py' | Select-Object -Index (3859..3887)` - `Get-Content -LiteralPath 'templates\phase_z2\catalog\frame_contracts.yaml' | Select-Object -Index (20..70)` - `Get-Content -LiteralPath 'templates\phase_z2\catalog\frame_contracts.yaml' | Select-Object -Index (80..125)` - `Get-Content -LiteralPath 'templates\phase_z2\catalog\frame_contracts.yaml' | Select-Object -Index (830..860)` - `Get-Content -LiteralPath 'src\region_marker_stamper.py' | Select-Object -Index (0..15), (40..45), (78..137)` - `Select-String -LiteralPath '.orchestrator\issues\94_stage_problem-review_exit.md','.orchestrator\issues\94_stage_simulation-plan_exit.md' -Pattern '#96|data-frame-slot-id|frame-slot|frame_slot'` - `Select-String -LiteralPath 'tests\test_phase_z2_imp94_marker_parity.py' -Pattern 'data-frame-slot-id|#96 axis|baseline_frame_slot_id_count|REGION_ID_ATTR|CONTENT_UNIT_ID_ATTR'` Files checked: - `src/phase_z2_pipeline.py` - `src/region_marker_stamper.py` - `templates/phase_z2/catalog/frame_contracts.yaml` - `templates/phase_z2/families/*.html` via per-file `Get-ChildItem` / `Select-String` - `.orchestrator/issues/94_stage_problem-review_exit.md` - `.orchestrator/issues/94_stage_simulation-plan_exit.md` - `tests/test_phase_z2_imp94_marker_parity.py` Test results: - Not run. Current Stage 1 instruction is grep/find scope verification and explicitly says NO pytest. Verified facts: - HEAD is `97b7833`. - Working tree is dirty with unrelated tracked/untracked files; no files were modified for implementation in this Stage 1 review. - Root-level `frame_contracts.yaml` is missing; the live contract file is `templates/phase_z2/catalog/frame_contracts.yaml`. - B5 scan uses the generic selector `[data-frame-slot-id]` at `src/phase_z2_pipeline.py:3864`. - `src/phase_z2_pipeline.py:2734-2761` is not the B5 scan; it is layout override logic. - Family partial count is 13 total, 2 with `data-frame-slot-id`, 11 without. - F29 existing marker values match contract sub-zone ids `process_column` and `product_column`. - F9 existing marker value `pill_dynamic` does not match contract sub-zone id `pills`; this is pre-existing and should be treated as compatibility-sensitive. - #94 artifacts explicitly reserve `data-frame-slot-id` for #96 and preserve F9/F29 frame-slot behavior. FINAL_CONSENSUS: YES
Author
Owner

[Claude #2] Stage 2 simulation-plan — IMP-89-d B5 marker expansion (#96)

Axis — 11 marker-less partials (templates/phase_z2/families/)

ids verbatim from templates/phase_z2/catalog/frame_contracts.yaml.

Partial Frame sub_zone.id (catalog) Carriers
construction_bim_three_usage.html F11 category_1/2/3 3
three_parallel_requirements.html F13 3 col sub_zones 3
three_persona_benefits.html F14 3 col sub_zones 3
info_management_what_how_when.html F8 3 col sub_zones 3
dx_sw_necessity_three_perspectives.html F20 3 col sub_zones 3
sw_reality_three_emphasis.html F28 3 col sub_zones 3
app_sw_package_vs_solution.html F23 col_a / col_b 2
construction_goals_three_circle_intersection.html F12 3 circles + intersection 4
bim_issues_quadrant_four.html F16 quadrant tl/tr/bl/br 4
bim_current_problems_paired.html F17 4 rows × 2 sides 8
bim_dx_comparison_table.html F18 col_a_header / col_b_header / rows 3

Action: add data-frame-slot-id="<sub_zone.id>" to every DOM element matching catalog partial_target_path. Multi-element matches (descendant combinator) emit multiple identical markers on the same id. Additive only — no DOM/class/text/layout change. Convention: process_product_two_way.html:220-284.

=== IMPLEMENTATION_UNITS ===

- id: u1
  summary: F11/F13/F14 — 3 col/row carrier markers per partial
  files:
    - templates/phase_z2/families/construction_bim_three_usage.html
    - templates/phase_z2/families/three_parallel_requirements.html
    - templates/phase_z2/families/three_persona_benefits.html
  tests: []
  estimate_lines: 12
- id: u2
  summary: F8/F20/F28 — 3 col carrier markers per partial
  files:
    - templates/phase_z2/families/info_management_what_how_when.html
    - templates/phase_z2/families/dx_sw_necessity_three_perspectives.html
    - templates/phase_z2/families/sw_reality_three_emphasis.html
  tests: []
  estimate_lines: 12
- id: u3
  summary: F23 (col_a/col_b) + F12 (3 circles + intersection) markers
  files:
    - templates/phase_z2/families/app_sw_package_vs_solution.html
    - templates/phase_z2/families/construction_goals_three_circle_intersection.html
  tests: []
  estimate_lines: 8
- id: u4
  summary: F16 quadrant tl/tr/bl/br markers
  files:
    - templates/phase_z2/families/bim_issues_quadrant_four.html
  tests: []
  estimate_lines: 6
- id: u5
  summary: F17 paired 8-cell markers (4 rows × 2 sides)
  files:
    - templates/phase_z2/families/bim_current_problems_paired.html
  tests: []
  estimate_lines: 10
- id: u6
  summary: F18 table — col_a_header / col_b_header / rows markers
  files:
    - templates/phase_z2/families/bim_dx_comparison_table.html
  tests: []
  estimate_lines: 6
- id: u7
  summary: Regression — per-partial marker presence + sub_zone.id parity vs catalog (catalog-driven, no hardcoded ids)
  files:
    - tests/phase_z2/test_frame_slot_marker_presence.py
  tests:
    - tests/phase_z2/test_frame_slot_marker_presence.py
  estimate_lines: 50
- id: u8
  summary: B5 coverage parity — MDX 01-05 frame_slot_metrics expands beyond F29/F9 baseline (no Selenium edits)
  files:
    - tests/phase_z2/test_b5_marker_coverage.py
  tests:
    - tests/phase_z2/test_b5_marker_coverage.py
  estimate_lines: 45

Rationale

  • u1/u2 — uniform 3-col/3-row partials batched 3-per-unit; identical injection pattern = one decision unit.
  • u3 — F23 (2) + F12 (4) under 50-line cap, ≤3 files.
  • u4/u5/u6 — distinct carrier topology each → single-partial unit.
  • u7 — loads catalog, renders each partial with minimal fixture, asserts every sub_zone.id appears as data-frame-slot-id.
  • u8 — runs phase_z2 on MDX 01-05, captures B5 frame_slot_metrics, asserts non-F29/F9 frames contribute keys.

Out-of-scope (Stage 1 scope_lock carried)

src/phase_z2_pipeline.py B5 selector; src/region_marker_stamper.py and #94 region/content axis; F29 + F9 existing carriers; F9 pill_dynamic vs catalog pills divergence; B4 frame_selection evidence; Layer A render-path activation; 19 contract-only templates.

Rollback

Per-unit isolated commits → git revert <sha>. Additive data-* only; no schema/consumer/fixture impact. u7/u8 catch future removal.

=== EVIDENCE ===

  • HEAD 97b7833 (main; tracked tree clean for #96-scope).
  • ls templates/phase_z2/families/*.html → 13 partials.
  • grep -l data-frame-slot-id templates/phase_z2/families/*.html → 2 marker-bearing (process_product_two_way, pre_construction_model_info_stacked).
  • 11 marker-less prefixes via grep -oE 'f[0-9]+b__' → F8/F11/F12/F13/F14/F16/F17/F18/F20/F23/F28.
  • F29 precedent: process_product_two_way.html:220-284.
  • F11 sub_zones: frame_contracts.yaml:381-396. F18: :451-466. F23: :803-813.
  • 144 partial_target_path entries in catalog (catalog-driven u7 feasible via existing YAML loader).

FINAL_CONSENSUS: YES

[Claude #2] Stage 2 simulation-plan — IMP-89-d B5 marker expansion (#96) ## Axis — 11 marker-less partials (`templates/phase_z2/families/`) ids verbatim from `templates/phase_z2/catalog/frame_contracts.yaml`. | Partial | Frame | sub_zone.id (catalog) | Carriers | |---|---|---|---| | construction_bim_three_usage.html | F11 | category_1/2/3 | 3 | | three_parallel_requirements.html | F13 | 3 col sub_zones | 3 | | three_persona_benefits.html | F14 | 3 col sub_zones | 3 | | info_management_what_how_when.html | F8 | 3 col sub_zones | 3 | | dx_sw_necessity_three_perspectives.html | F20 | 3 col sub_zones | 3 | | sw_reality_three_emphasis.html | F28 | 3 col sub_zones | 3 | | app_sw_package_vs_solution.html | F23 | col_a / col_b | 2 | | construction_goals_three_circle_intersection.html | F12 | 3 circles + intersection | 4 | | bim_issues_quadrant_four.html | F16 | quadrant tl/tr/bl/br | 4 | | bim_current_problems_paired.html | F17 | 4 rows × 2 sides | 8 | | bim_dx_comparison_table.html | F18 | col_a_header / col_b_header / rows | 3 | Action: add `data-frame-slot-id="<sub_zone.id>"` to every DOM element matching catalog `partial_target_path`. Multi-element matches (descendant combinator) emit multiple identical markers on the same id. Additive only — no DOM/class/text/layout change. Convention: `process_product_two_way.html:220-284`. ## === IMPLEMENTATION_UNITS === ```yaml - id: u1 summary: F11/F13/F14 — 3 col/row carrier markers per partial files: - templates/phase_z2/families/construction_bim_three_usage.html - templates/phase_z2/families/three_parallel_requirements.html - templates/phase_z2/families/three_persona_benefits.html tests: [] estimate_lines: 12 - id: u2 summary: F8/F20/F28 — 3 col carrier markers per partial files: - templates/phase_z2/families/info_management_what_how_when.html - templates/phase_z2/families/dx_sw_necessity_three_perspectives.html - templates/phase_z2/families/sw_reality_three_emphasis.html tests: [] estimate_lines: 12 - id: u3 summary: F23 (col_a/col_b) + F12 (3 circles + intersection) markers files: - templates/phase_z2/families/app_sw_package_vs_solution.html - templates/phase_z2/families/construction_goals_three_circle_intersection.html tests: [] estimate_lines: 8 - id: u4 summary: F16 quadrant tl/tr/bl/br markers files: - templates/phase_z2/families/bim_issues_quadrant_four.html tests: [] estimate_lines: 6 - id: u5 summary: F17 paired 8-cell markers (4 rows × 2 sides) files: - templates/phase_z2/families/bim_current_problems_paired.html tests: [] estimate_lines: 10 - id: u6 summary: F18 table — col_a_header / col_b_header / rows markers files: - templates/phase_z2/families/bim_dx_comparison_table.html tests: [] estimate_lines: 6 - id: u7 summary: Regression — per-partial marker presence + sub_zone.id parity vs catalog (catalog-driven, no hardcoded ids) files: - tests/phase_z2/test_frame_slot_marker_presence.py tests: - tests/phase_z2/test_frame_slot_marker_presence.py estimate_lines: 50 - id: u8 summary: B5 coverage parity — MDX 01-05 frame_slot_metrics expands beyond F29/F9 baseline (no Selenium edits) files: - tests/phase_z2/test_b5_marker_coverage.py tests: - tests/phase_z2/test_b5_marker_coverage.py estimate_lines: 45 ``` ### Rationale - u1/u2 — uniform 3-col/3-row partials batched 3-per-unit; identical injection pattern = one decision unit. - u3 — F23 (2) + F12 (4) under 50-line cap, ≤3 files. - u4/u5/u6 — distinct carrier topology each → single-partial unit. - u7 — loads catalog, renders each partial with minimal fixture, asserts every `sub_zone.id` appears as `data-frame-slot-id`. - u8 — runs phase_z2 on MDX 01-05, captures B5 `frame_slot_metrics`, asserts non-F29/F9 frames contribute keys. ### Out-of-scope (Stage 1 scope_lock carried) `src/phase_z2_pipeline.py` B5 selector; `src/region_marker_stamper.py` and #94 region/content axis; F29 + F9 existing carriers; F9 `pill_dynamic` vs catalog `pills` divergence; B4 frame_selection evidence; Layer A render-path activation; 19 contract-only templates. ### Rollback Per-unit isolated commits → `git revert <sha>`. Additive `data-*` only; no schema/consumer/fixture impact. u7/u8 catch future removal. ### === EVIDENCE === - HEAD `97b7833` (main; tracked tree clean for #96-scope). - `ls templates/phase_z2/families/*.html` → 13 partials. - `grep -l data-frame-slot-id templates/phase_z2/families/*.html` → 2 marker-bearing (process_product_two_way, pre_construction_model_info_stacked). - 11 marker-less prefixes via `grep -oE 'f[0-9]+b__'` → F8/F11/F12/F13/F14/F16/F17/F18/F20/F23/F28. - F29 precedent: `process_product_two_way.html:220-284`. - F11 sub_zones: `frame_contracts.yaml:381-396`. F18: `:451-466`. F23: `:803-813`. - 144 `partial_target_path` entries in catalog (catalog-driven u7 feasible via existing YAML loader). FINAL_CONSENSUS: YES
Author
Owner

[Codex #1] Stage 2 simulation-plan review - IMP-89-d B5 marker expansion (#96)

=== IMPLEMENTATION_UNITS ===
reviewed_units:

  • id: u1
    summary: F11/F13/F14 3-slot carrier markers
    files:
    • templates/phase_z2/families/construction_bim_three_usage.html
    • templates/phase_z2/families/three_parallel_requirements.html
    • templates/phase_z2/families/three_persona_benefits.html
      tests: []
      estimate_lines: 12
  • id: u2
    summary: F8/F20/F28 3-slot carrier markers
    files:
    • templates/phase_z2/families/info_management_what_how_when.html
    • templates/phase_z2/families/dx_sw_necessity_three_perspectives.html
    • templates/phase_z2/families/sw_reality_three_emphasis.html
      tests: []
      estimate_lines: 12
  • id: u3
    summary: F23 col_a/col_b plus F12 circle/intersection markers
    files:
    • templates/phase_z2/families/app_sw_package_vs_solution.html
    • templates/phase_z2/families/construction_goals_three_circle_intersection.html
      tests: []
      estimate_lines: 8
  • id: u4
    summary: F16 quadrant markers
    files:
    • templates/phase_z2/families/bim_issues_quadrant_four.html
      tests: []
      estimate_lines: 6
  • id: u5
    summary: F17 paired 8-cell markers
    files:
    • templates/phase_z2/families/bim_current_problems_paired.html
      tests: []
      estimate_lines: 10
  • id: u6
    summary: F18 table header/rows markers
    files:
    • templates/phase_z2/families/bim_dx_comparison_table.html
      tests: []
      estimate_lines: 6
  • id: u7
    summary: Regression marker presence and catalog parity
    files:
    • tests/phase_z2/test_frame_slot_marker_presence.py
      tests: null
      estimate_lines: null
      verdict:
      completeness: no
      unit_constraints: u1-u6 pass file-count and line-estimate limits; u7 is not verifiable because tests and estimate_lines are absent in the visible plan body.
      missing_plan_details:
    • F13/F14/F17 are loop-rendered source templates; the plan must specify loop-aware marker emission that resolves to exact catalog ids, not only nth-child DOM selectors.
    • F23 catalog selectors .f23b__col-a-body and .f23b__col-b-body do not exist in the current source partial, so the plan cannot be implemented by matching partial_target_path as stated.
    • F17 source has one loop body for rows 1..4; the plan must state deterministic row_{{r}}_left/right mapping against row_1_left through row_4_right.
    • u7 must define exact assertions: all 11 in-scope partials gain data-frame-slot-id values equal to catalog sub_zones ids; F29/F9 remain untouched; no src/phase_z2_pipeline.py or src/region_marker_stamper.py edits.

u1 rationale: F11 selector mapping is source-visible, but F13/F14 require loop-index id mapping because only one source carrier is present before Jinja render.
u2 rationale: F8/F20/F28 selectors all resolve once in source and fit additive attribute-only edits.
u3 rationale: F12 selectors resolve, but F23 needs a repaired carrier plan because the catalog body selectors are absent from the current partial.
u4 rationale: F16 quadrant selectors resolve one-to-one and remain a small isolated unit.
u5 rationale: F17 is the riskiest unit because eight runtime cells are produced from one loop body; Stage 2 must pin the dynamic id expression before edit.
u6 rationale: F18 selectors resolve one-to-one for the two headers and rows container.
u7 rationale: Regression belongs in scope, but the plan body must complete the test command/assertion list and line estimate before Stage 3.

Out-of-scope notes: Keep Selenium B5 scan in src/phase_z2_pipeline.py read-only; keep src/region_marker_stamper.py and #94 region/content marker behavior untouched; do not reconcile F9 pill_dynamic vs catalog pills; do not change F29 existing carriers.

Rollback strategy: Revert only the 11 partial edits plus tests/phase_z2/test_frame_slot_marker_presence.py if Stage 3 fails; no pipeline or stamper rollback should be needed because they are out of scope.

=== EVIDENCE ===
Commands run:

  • git status --short
  • rg --files templates/phase_z2 | rg "(frame_contracts.yaml|families/)"
  • rg -n "data-frame-slot-id|partial_target_path|sub_zones|frame_id|family" templates/phase_z2/catalog/frame_contracts.yaml templates/phase_z2/families
  • python catalog/partial marker inventory using PyYAML
  • pytest -q tests
  • python BeautifulSoup selector cross-check for the 11 in-scope partials
  • rg -n "querySelectorAll('\[data-frame-slot-id\]')|frame_slot_metrics|region_marker_stamper|data-region-id|data-content-unit-id" src/phase_z2_pipeline.py src/region_marker_stamper.py templates/phase_z2/families/process_product_two_way.html templates/phase_z2/families/pre_construction_model_info_stacked.html
  • git rev-parse --short HEAD
    Files checked:
  • templates/phase_z2/catalog/frame_contracts.yaml
  • templates/phase_z2/families/*.html
  • src/phase_z2_pipeline.py
  • src/region_marker_stamper.py
  • tests/phase_z2/test_frame_slot_marker_presence.py
    Test results:
  • pytest -q tests failed pre-edit after 466.3s. First observed failure: tests/integration/test_multi_mdx_regression.py::test_pipeline_run_produces_step20_status[03] because phase_z2_pipeline.py raised ValueError for unknown override ZONE_ID(s) ['left', 'right'] on layout horizontal-2. Other snapshot failures were also observed.
    Verified facts:
  • HEAD is 97b7833.
  • There are 13 family partial HTML files on disk; 11 are marker-less and in scope, while process_product_two_way.html and pre_construction_model_info_stacked.html already carry data-frame-slot-id markers.
  • B5 still uses slide.querySelectorAll('[data-frame-slot-id]') at src/phase_z2_pipeline.py:3864; no Stage 2 plan should modify it.
  • src/region_marker_stamper.py owns data-region-id/data-content-unit-id only; it remains out of scope for data-frame-slot-id.
  • Selector cross-check misses: three_parallel_requirements pillar_2/pillar_3, three_persona_benefits persona_2/persona_3, app_sw_package_vs_solution col_a/col_b, and bim_current_problems_paired row_2_left through row_4_right in source-template form.
    rewind_target: stage_2_plan
    FINAL_CONSENSUS: NO
[Codex #1] Stage 2 simulation-plan review - IMP-89-d B5 marker expansion (#96) === IMPLEMENTATION_UNITS === reviewed_units: - id: u1 summary: F11/F13/F14 3-slot carrier markers files: - templates/phase_z2/families/construction_bim_three_usage.html - templates/phase_z2/families/three_parallel_requirements.html - templates/phase_z2/families/three_persona_benefits.html tests: [] estimate_lines: 12 - id: u2 summary: F8/F20/F28 3-slot carrier markers files: - templates/phase_z2/families/info_management_what_how_when.html - templates/phase_z2/families/dx_sw_necessity_three_perspectives.html - templates/phase_z2/families/sw_reality_three_emphasis.html tests: [] estimate_lines: 12 - id: u3 summary: F23 col_a/col_b plus F12 circle/intersection markers files: - templates/phase_z2/families/app_sw_package_vs_solution.html - templates/phase_z2/families/construction_goals_three_circle_intersection.html tests: [] estimate_lines: 8 - id: u4 summary: F16 quadrant markers files: - templates/phase_z2/families/bim_issues_quadrant_four.html tests: [] estimate_lines: 6 - id: u5 summary: F17 paired 8-cell markers files: - templates/phase_z2/families/bim_current_problems_paired.html tests: [] estimate_lines: 10 - id: u6 summary: F18 table header/rows markers files: - templates/phase_z2/families/bim_dx_comparison_table.html tests: [] estimate_lines: 6 - id: u7 summary: Regression marker presence and catalog parity files: - tests/phase_z2/test_frame_slot_marker_presence.py tests: null estimate_lines: null verdict: completeness: no unit_constraints: u1-u6 pass file-count and line-estimate limits; u7 is not verifiable because tests and estimate_lines are absent in the visible plan body. missing_plan_details: - F13/F14/F17 are loop-rendered source templates; the plan must specify loop-aware marker emission that resolves to exact catalog ids, not only nth-child DOM selectors. - F23 catalog selectors .f23b__col-a-body and .f23b__col-b-body do not exist in the current source partial, so the plan cannot be implemented by matching partial_target_path as stated. - F17 source has one loop body for rows 1..4; the plan must state deterministic row_{{r}}_left/right mapping against row_1_left through row_4_right. - u7 must define exact assertions: all 11 in-scope partials gain data-frame-slot-id values equal to catalog sub_zones ids; F29/F9 remain untouched; no src/phase_z2_pipeline.py or src/region_marker_stamper.py edits. u1 rationale: F11 selector mapping is source-visible, but F13/F14 require loop-index id mapping because only one source carrier is present before Jinja render. u2 rationale: F8/F20/F28 selectors all resolve once in source and fit additive attribute-only edits. u3 rationale: F12 selectors resolve, but F23 needs a repaired carrier plan because the catalog body selectors are absent from the current partial. u4 rationale: F16 quadrant selectors resolve one-to-one and remain a small isolated unit. u5 rationale: F17 is the riskiest unit because eight runtime cells are produced from one loop body; Stage 2 must pin the dynamic id expression before edit. u6 rationale: F18 selectors resolve one-to-one for the two headers and rows container. u7 rationale: Regression belongs in scope, but the plan body must complete the test command/assertion list and line estimate before Stage 3. Out-of-scope notes: Keep Selenium B5 scan in src/phase_z2_pipeline.py read-only; keep src/region_marker_stamper.py and #94 region/content marker behavior untouched; do not reconcile F9 pill_dynamic vs catalog pills; do not change F29 existing carriers. Rollback strategy: Revert only the 11 partial edits plus tests/phase_z2/test_frame_slot_marker_presence.py if Stage 3 fails; no pipeline or stamper rollback should be needed because they are out of scope. === EVIDENCE === Commands run: - git status --short - rg --files templates/phase_z2 | rg "(frame_contracts.yaml|families/)" - rg -n "data-frame-slot-id|partial_target_path|sub_zones|frame_id|family" templates/phase_z2/catalog/frame_contracts.yaml templates/phase_z2/families - python catalog/partial marker inventory using PyYAML - pytest -q tests - python BeautifulSoup selector cross-check for the 11 in-scope partials - rg -n "querySelectorAll('\\[data-frame-slot-id\\]')|frame_slot_metrics|region_marker_stamper|data-region-id|data-content-unit-id" src/phase_z2_pipeline.py src/region_marker_stamper.py templates/phase_z2/families/process_product_two_way.html templates/phase_z2/families/pre_construction_model_info_stacked.html - git rev-parse --short HEAD Files checked: - templates/phase_z2/catalog/frame_contracts.yaml - templates/phase_z2/families/*.html - src/phase_z2_pipeline.py - src/region_marker_stamper.py - tests/phase_z2/test_frame_slot_marker_presence.py Test results: - pytest -q tests failed pre-edit after 466.3s. First observed failure: tests/integration/test_multi_mdx_regression.py::test_pipeline_run_produces_step20_status[03] because phase_z2_pipeline.py raised ValueError for unknown override ZONE_ID(s) ['left', 'right'] on layout horizontal-2. Other snapshot failures were also observed. Verified facts: - HEAD is 97b7833. - There are 13 family partial HTML files on disk; 11 are marker-less and in scope, while process_product_two_way.html and pre_construction_model_info_stacked.html already carry data-frame-slot-id markers. - B5 still uses slide.querySelectorAll('[data-frame-slot-id]') at src/phase_z2_pipeline.py:3864; no Stage 2 plan should modify it. - src/region_marker_stamper.py owns data-region-id/data-content-unit-id only; it remains out of scope for data-frame-slot-id. - Selector cross-check misses: three_parallel_requirements pillar_2/pillar_3, three_persona_benefits persona_2/persona_3, app_sw_package_vs_solution col_a/col_b, and bim_current_problems_paired row_2_left through row_4_right in source-template form. rewind_target: stage_2_plan FINAL_CONSENSUS: NO
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Kyeongmin/C.E.L_Slide_test2#96