Files
C.E.L_Slide_test2/.orchestrator/tmp/39_payload.json
T

1 line
9.7 KiB
JSON

{"body": "[Claude #1] Stage 1 problem-review \u2014 IMP-30 first-render invariant + abort bypass\n\n=== ROOT_CAUSE ===\n\nTwo abort paths described in the issue are real. Issue line numbers are stale; verified actual locations:\n\n| issue ref | actual location | what it does |\n|---|---|---|\n| path (a) `if not units or layout_preset is None` @ `:1762~` | `src/phase_z2_pipeline.py:3156` | writes `error.json`, then `sys.exit(1)` |\n| path (b) `if status not in MVP1_ALLOWED_STATUSES` @ `:489` | `src/phase_z2_pipeline.py:657` (inside `_choose_match_from_judgments`) | per-rank candidate filter; cascades to `selection_path=\"chain_exhausted\"` \u2192 `lookup_v4_match()` returns `None` \u2192 composition planner emits no candidate for that section |\n\n**Cascade:** When every aligned section produces only `restructure`/`reject` V4 labels (or has no V4 entry at all), path (b) filters all rank-1/2/3 candidates inside `_choose_match_from_judgments`, the section ends up with no `CompositionUnit` in `collect_candidates`, `plan_composition` returns `units=[]` + `preset=None`, and path (a) hard-aborts before any artifact tree (`final.html`, `step20_slide_status.json`, candidate_evidence, \u2026) is written.\n\n**Downstream blast radius:** IMP-29 (#38, shipped `b4872ba`) frontend zone-level evidence bridge has nothing to read because `data/runs/<run-id>/` never gets populated. IMP-31 (AI adaptation) cannot be triggered because it expects a first-render trace as input. The pipeline survivability invariant (\"first render always produced, even when degraded\") is violated.\n\n=== SCOPE_LOCK ===\n\n**IN scope (IMP-30):**\n\n1. **Composition layer placeholder synthesis** \u2014 `src/phase_z2_composition.py`:\n - For each aligned section uncovered by any auto-selectable `CompositionUnit` (no V4 match, all restructure/reject, or `chain_exhausted`), synthesize a **placeholder `CompositionUnit`** with:\n - `frame_template_id = \"__placeholder_needs_adaptation__\"` (sentinel \u2014 parallel to existing `__empty__` pattern at `:3536`)\n - `phase_z_status = \"placeholder_needs_adaptation\"` (informational only; **NOT** added to `MVP1_ALLOWED_STATUSES`)\n - `placeholder = True`, `adaptation_reason \u2208 {no_v4_entry, restructure_only, reject_only, chain_exhausted}`\n - `raw_content = section.raw_content` (MDX byte-preserved, no rewrite)\n - `v4_candidates` populated from full-32 (including reject) so IMP-31 has seed evidence\n - placeholders DO NOT pass through `select_composition_units` filter (which gates on `auto_selectable + allowed_statuses`); they are union-appended at `plan_composition` exit to cover sections the auto pass missed.\n\n2. **Abort path (a) loosen** \u2014 `src/phase_z2_pipeline.py:3156`:\n - Trigger `sys.exit(1)` only when `len(sections) == 0` (truly empty MDX input).\n - When `len(sections) > 0` but auto units are 0, placeholders cover the gap; `layout_preset` is computed from `len(auto_units \u222a placeholder_units)`.\n\n3. **Renderer placeholder partial** \u2014 minimal partial under `templates/phase_z2/placeholders/needs_adaptation.html`:\n - emits a visible adaptation banner (\"needs user/AI adaptation\") + section title + MDX preview (truncated, full text in `<details>` if long).\n - zone-loop `:2059` short-circuit gains a sibling branch: `template_id == \"__placeholder_needs_adaptation__\"` \u2192 render the placeholder partial instead of the empty string.\n\n4. **Telemetry / artifacts**:\n - Step 6 `composition_plan` artifact: new `placeholder_units` list (one entry per placeholder, with `section_id`, `adaptation_reason`, `v4_candidates_count`).\n - Step 20 `slide_status`: new informational fields `placeholder_zone_count` + `placeholder_section_ids` + `adaptation_pending_count`. **Top-level `overall` enum unchanged** (PASS / RENDERED_WITH_VISUAL_REGRESSION / PARTIAL_COVERAGE / \u2026).\n - `candidate_evidence` per-zone (IMP-05 L2 schema) for placeholder zones records `placeholder=True` + `adaptation_reason` + full V4 evidence (including reject candidates).\n\n5. **`full_mdx_coverage` semantics** \u2014 placeholder-covered sections count as `covered` (placeholder still provides zone identity + MDX preservation on the slide). `adaptation_pending_count` separately surfaces how many of those covered zones need adaptation. Rationale: matches issue intent \"abort \ud68c\ud53c + provisional first result\" \u2014 every section reaches the slide visibly, deferred work is tracked separately.\n\n**OUT of scope:**\n\n- AI-assisted adaptation for restructure/reject zones \u2192 **IMP-31**\n- Frontend interactive override on placeholder zones \u2192 **IMP-29** (bridge already shipped `b4872ba`)\n- Post-render `frame_reselect` execution \u2192 IMP-29 \ub610\ub294 \ubcc4 axis\n- Composition planner promoting rank-2/3 with `restructure`/`reject` labels \u2192 would require changing `MVP1_ALLOWED_STATUSES` baseline = \ubcc4 axis\n\n=== GUARDRAILS ===\n\n| guardrail | how satisfied |\n|---|---|\n| top-level slide status enum \ubcc0\uacbd X (IMP-05 Codex #10 D4) | new fields are additive (`placeholder_*`, `adaptation_pending_*`); `overall` enum untouched |\n| `MVP1_ALLOWED_STATUSES` baseline \ubcc0\uacbd X | new `phase_z_status=\"placeholder_needs_adaptation\"` is informational only, never added to the set; auto-select filter unchanged |\n| no `calculate_fit` | placeholder synthesis is metadata-only; no capacity / fit calculation invoked |\n| no AI in IMP-30 itself | placeholders are static metadata + MDX preservation; AI adaptation deferred to IMP-31 |\n| no hardcoding (Rule 7) | sentinel template_id parallels existing `__empty__` pattern; placeholder generated parametrically from `derive_parent_id` + V4 evidence absence; no MDX/frame/section literal |\n| MDX content preserved no rewrite | `raw_content = section.raw_content` byte-identical |\n| auto pipeline (no review_required) | placeholder is an auto outcome of \"no auto unit found\"; classified as `placeholder_needs_adaptation` + clear failure-trace; no human-gate inserted |\n\n=== OPEN_QUESTIONS ===\n\n1. **Q1 \u2014 `lookup_v4_candidates` vs `lookup_v4_all_judgments` for placeholder seed**: current `lookup_v4_candidates` (`:721`) filters reject. Placeholder synthesis for \"reject_only\" sections needs full-32 (`lookup_v4_all_judgments` `:698`) so IMP-31 has the reject evidence to start from. Stage 2 needs to decide: does the composition planner accept a second lookup fn for placeholder evidence, or does the placeholder path call `lookup_v4_all_judgments` directly from the pipeline layer before injecting into the planner result? Recommendation: pipeline-layer injection \u2014 keeps composition planner contract narrower (lookup_fn signatures already at 2; adding a 3rd is creep).\n\n2. **Q2 \u2014 placeholder layout preset rules**: when 0 auto units + N placeholders, `select_layout_preset` is called with N. Current `select_layout_preset` requires `1 \u2264 n \u2264 4` and `ValueError`s on N>4. For IMP-30 first-render, do we want to clamp N\u22644 (first 4 sections get placeholders, rest get a \"more_sections_truncated\" marker) or extend the layout vocabulary for placeholder-only slides? Recommendation: keep `n \u2264 4` constraint, place first 4 placeholders, surface remaining as a Step 6 informational warning. Larger axis (multi-slide split) is out of scope.\n\n3. **Q3 \u2014 placeholder partial template visual**: minimal banner + MDX preview is the safest first cut. Does the user want a specific visual language (color / label text)? Stage 2 will propose concrete partial markup; flag now in case user has a preference.\n\n4. **Q4 \u2014 issue line number `:489`**: confirmed stale; the status filter the issue refers to is at `:657` (per-rank inside `_choose_match_from_judgments`). Line `:489` is part of `align_sections_to_v4_granularity` alias_keys generation, unrelated. If the issue author meant a different filter site, clarification needed before Stage 2; otherwise proceeding with `:657` as the intended target.\n\n=== EVIDENCE ===\n\nFiles read:\n- `src/phase_z2_pipeline.py` ranges `:85-96` (`MVP1_ALLOWED_STATUSES`), `:620-695` (`_choose_match_from_judgments`), `:698-757` (`lookup_v4_all_judgments` + `lookup_v4_candidates`), `:2057-2061` (`__empty__` zone short-circuit), `:2426-2555` (`compute_slide_status`), `:2980-3175` (`plan_composition` call + abort), `:3520-3565` (`__empty__` zone record emit).\n- `src/phase_z2_composition.py` full (843 lines) \u2014 confirmed `plan_composition` signature, `select_layout_preset` constraints, `CompositionUnit` dataclass, no current placeholder concept.\n\nCommands run:\n- `Grep MVP1_ALLOWED_STATUSES src/phase_z2_pipeline.py` \u2192 7 hits (definition + 6 references including comp_debug exports).\n- `Grep \"layout_preset is None|not units\" src/phase_z2_pipeline.py` \u2192 1 hit (`:3156` \u2014 confirmed sole abort site for path (a)).\n- `Grep __empty__ src/phase_z2_pipeline.py` \u2192 7 hits (existing sentinel pattern verified at `:2059`, `:3044`, `:3536`, `:3551`, `:3562`).\n- `Grep \"PARTIAL_COVERAGE|slide_status|top.?level.*status\" src/phase_z2_pipeline.py` \u2192 confirms top-level `overall` enum lives in `compute_slide_status` (`:2542-2549`), additive-only schema per IMP-05 L3 lock.\n\nCross-ref confirmed:\n- IMP-05 (#5) \u00a75 defer note (\"L7 first-render invariant deferred\") matches this issue's source.\n- IMP-29 (#38) commit `b4872ba` already provides the frontend zone-level evidence bridge \u2014 once placeholders emit `candidate_evidence`, IMP-29 consumes them with no extra work.\n\nStage 2 will produce: `IMPLEMENTATION_UNITS` table (composition module placeholder synthesis / pipeline abort loosen / renderer partial / artifact telemetry / tests), file-by-file edit plan, test plan (placeholder for all-restructure section, placeholder for no-V4 section, mixed auto+placeholder coverage, abort still fires on empty sections).\n"}