Commit Graph

7 Commits

Author SHA1 Message Date
f3ef4d917c feat(#64): IMP-35 details_popup_escalation u1~u10 + Stage 3 R7 anchor re-pin
Land the production + test surface for the Step 17 cascade POPUP terminal
(DETERMINISTIC -> POPUP -> AI_REPAIR -> USER_OVERRIDE) per Stage 2 plan R2.
u11 (baseline-red invariance gate) was already landed in 7c93031 ahead of
this commit; this commit completes u1~u10 plus the Stage 3 R7 follow-up
anchor re-pin for test_imp17_comment_anchor.py.

Implementation units (Stage 2 R2 contract):
  u1  frame_reselect_insufficient failure_type + post-frame remeasure (q4)
        - src/phase_z2_failure_router.py, src/phase_z2_pipeline.py
  u2  NEXT_ACTION_BY_FAILURE row + impl_status flip
        - src/phase_z2_failure_router.py
  u3  Router details_popup_escalation MISSING->IMPLEMENTED + executor stub
        - src/phase_z2_router.py
  u4  step17.py AI split-decision contract (POPUP cascade_stage +
      route_for_label + skip_reason); API gated
        - src/phase_z2_ai_fallback/step17.py
  u5  Step 17 POPUP gate executor; popup_escalation_plan + has_popup marker
        - src/phase_z2_pipeline.py, src/phase_z2_ai_fallback/step17.py
  u6  Composition popup binding -- yaml strategy -> zone payload
        - src/phase_z2_composition.py
  u7  Pipeline composer -> render_slide wiring
      (popup_html / preview_text / has_popup)
        - src/phase_z2_pipeline.py
  u8  slide_base.html <details>/<summary> popup wrapper
        - templates/phase_z2/slide_base.html
  u9  display_strategies.yaml inline_preview + popup metadata
        - templates/phase_z2/regions/display_strategies.yaml
  u10 MDX preservation invariant: popup=full source / body=summary or subset
        (asserted by tests/phase_z2/test_popup_mdx_preservation.py)
  u11 (already in 7c93031) -- baseline-red invariance gate

Stage 3 R7 follow-up (anchor re-pin, test-only):
  - tests/orchestrator_unit/test_imp17_comment_anchor.py
    Pre-anchor additions in src/phase_z2_pipeline.py (u1 / u5 / u7) shifted
    the restructure/reject route-hint comments 578/579 -> 586/587. Re-pinned
    the two guard tests (and docstring re-pin lineage 564 -> 570 -> 578 ->
    586). Production code untouched.

Verification (Stage 4 R1):
  pytest -q tests/orchestrator_unit/test_imp17_comment_anchor.py
    -> 2 passed / 0.02s
  pytest -q <10 IMP-35 unit files in tests/phase_z2 + tests/phase_z2_ai_fallback>
    -> 136 passed / 15.94s
  Baseline-red invariance gate
    (tests/test_imp47b_step12_ai_wiring.py +
     tests/test_phase_z2_ai_fallback_config.py)
    -> 4 failed / 6 passed; FAILED set === IMP35_BASELINE_RED_NODE_IDS
    (frozen registry from 7c93031). Contract holds.
  Codex Stage 4 R1 = YES (independent verify).

Guardrails honored:
  - MDX content preservation: popup carries full source, body holds
    summary or subset only (CLAUDE.md 자세히보기 원칙;
    feedback_phase_z_spacing_direction -- capacity expanded, no margin shrink).
  - AI isolation contract: Step 17 POPUP gate is deterministic; AI hook
    surface is split-decision contract only, API call gated.
  - No hardcoding: escalation thresholds derived from existing overflow
    detector outputs; preview_chars deterministic from container px.
  - 1 commit = 1 decision unit: u1~u10 land together as the planned
    production surface; u11 was deliberately split into 7c93031 as Stage 3
    R7 carve-out, and the R7 anchor re-pin rides with this commit because
    it is the direct shift consequence of the u1/u5/u7 pre-anchor additions.
  - Scope-locked: .claude/settings.json explicitly excluded
    (Stage 4 exit report contract).

Out of scope (per Stage 1 + Stage 2):
  - AI_REPAIR API activation (post IMP-35 axis).
  - IMP-34 zone resize, IMP-36 responsive fit (chain partners,
    separate issues).
  - Print-time auto-expand JavaScript for <details>.
  - Popup escalation in stages other than Step 17.
  - Baseline-red body repair (4 frozen failures) -- separate follow-up
    issue; u11 only guards the count.
  - frame_reselect algorithm changes (entry point only).
  - templates/phase_z2/slide_base.html path rename.

source_comment_ids:
  Stage 1: claude_stage1_problem_review_imp35, codex_stage1_verification_imp35_yes
  Stage 2: Claude #4 R2 plan, Codex #5 R2 YES
  Stage 3: Claude #86 (R7 anchor re-pin), Codex #87 YES
  Stage 4: Claude #88 R1, Codex #89 R1 YES

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 07:36:57 +09:00
ee97f4fc78 feat(#77): IMP-48 composition planner re-split on all-reject (u1~u9)
Add resplit_all_reject_merges() helper in phase_z2_composition.py that
detects parent_merged / parent_merged_inferred units with label=reject
and rebuilds them as per-section single units using each section's own
rank-1 V4 evidence (no frame swap, MDX raw_content preserved).

Pipeline hook fires once after Step 6 settling chain (u12/u4/empty-shell)
and section_assignment_plan resolution, before Step 6 artifact write.
Guards: beneficial-split rule (>=1 non-reject), coverage equality, layout
cap (>4 abort), max_retry=1, section_assignment_override short-circuit.

Audit: comp_debug["imp48_resplit"] additive payload (applied, split_units,
skipped_units, post_split_unit_count, post_split_layout_preset);
selection_path="resplit_from_merge" telemetry on rebuilt singles;
layout_preset re-derived via select_layout_preset(new_units).

Tests: 39/39 PASS (composition u1~u6: 14 cases; pipeline u7~u9: 25 cases).
Scoped regression 720/6 with 6 failures isolated as pre-existing on
baseline 79f9ea5 (independent of IMP-48). mdx03 golden lock preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 05:00:07 +09:00
1efbf672bd feat(#39): IMP-30 first-render invariant + abort bypass (2 paths)
Restore first-render invariant: final.html + Step 20 slide_status MUST be
written for every input where Step 0~5 succeed. Two abort paths replaced
with provisional/empty-shell synthesis; MDX content preserved, AI-free.

- u1 V4Match.provisional + lookup_v4_match_with_fallback(allow_provisional)
  chain_exhausted -> synthesize rank-1 provisional (opt-in, default-off)
- u2 CompositionUnit.provisional propagation (single / parent_merged /
  parent_merged_inferred constructors)
- u3 select_composition_units(allow_provisional_fill=True) last-resort
  fill + _candidate_state="selected_provisional"
- u4 pipeline.py path-(a) abort guard replaced with provisional retry +
  terminal __empty__ shell (no sys.exit(1))
- u5 zones_data.provisional -> slide_base.html zone--provisional class +
  data-provisional + needs-adaptation badge (template-only)
- u6 compute_slide_status additive provisional_first_render_count/_units
  (overall enum unchanged per IMP-05 Codex #10 D4)
- u7 regression: tests/test_phase_z2_imp30_first_render.py (28 tests) +
  tests/test_phase_z2_v4_fallback.py (+5 cases)

Guardrails verified: MVP1_ALLOWED_STATUSES unchanged, no calculate_fit,
no LLM in fallback path, no MDX 03/04/05 hardcoding.

Anchor sync (Rule 13): tests/orchestrator_unit/test_imp17_comment_anchor.py
re-pinned 564/565 -> 570/571 to track V4Match.provisional shift at
src/phase_z2_pipeline.py:179-184.

Cross-ref: IMP-05 (#5) §5 defer + Codex #2 first-render invariant.
2026-05-21 00:40:58 +09:00
a422d72c0b feat(IMP-08): U1 — schema helper + V4 alias resolver (4 lookup sites)
Adds sub-section schema fields (heading_number / v4_alias_keys /
sub_sections) to MdxSection with defaults so existing 4-positional
constructions remain valid. Introduces _resolve_v4_section_key helper
that resolves a V4 mdx_sections key in exact > alias > None order with
no parent/sibling promotion (axis 7 hybrid lock).

Rewires four runtime V4 lookup sites (lookup_v4_match,
lookup_v4_match_with_fallback, lookup_v4_all_judgments,
lookup_v4_candidates) to accept an optional alias_keys kwarg and go
through the resolver. U1 callers pass empty alias lists so behaviour
is byte-identical to the previous exact-match path; U2 will populate
aliases from MDX heading_number metadata.

Closure callers in run_phase_z2 build section_alias_by_id from
MdxSection.v4_alias_keys and forward into lookup_fn /
candidates_lookup_fn / lookup_v4_all_judgments (Step 7-A trace) and
into _select_template_for_overrides single-section selector.

Step 9 candidate report (post-decision diagnostic) is marked with an
inline English exemption comment per N-R6 — runtime selection goes
through _resolve_v4_section_key, the report path stays a direct
dict-shape lookup to avoid debug_zones schema plumbing.

derive_parent_id now recognises canonical ordinal ids
("03-1-sub-2" -> "03-1") first and keeps the legacy decimal fallback
("04-2.1" -> "04-2") for V4 alias compatibility.

Tests : 8 synthetic cases in tests/test_phase_z2_subsection_schema.py
covering derive_parent_id ordinal/decimal/none and the resolver
exact/alias/no-promote/miss cases. 30/30 PASS combined with the 14
override + 8 fallback baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 22:28:59 +09:00
15c5b9ae00 IMP-05 deterministic V4 candidate bridge — pre-render rank-2/3 fallback + trace schema + dedup invariant test
round 55~73 review-loop lock per Codex #11 final + Claude #13 6-axis L1~L9.

Scope (deterministic only) :
- pre-render rank-2/3 fallback via lookup_v4_match_with_fallback (selector only,
  no calculate_fit migration, no AI, no full planner rerun, no layout topology change,
  no abort behavior change)
- Step 9 informative candidate_evidence schema (additive) — v4_label / phase_z_status
  / catalog_registered / filtered_for_direct_execution / route_hint / decision / reason
- Step 20 qualifier fields (additive) — fallback_used / fallback_selection_count
  / selection_paths[] — top-level enum unchanged
- restructure / reject candidates preserved as non-direct evidence with route hints
  (design_reference_only / ai_adaptation_required) — deferred actual handlers IMP-29/IMP-31
- catalog 1:1 invariant test (separate file tests/test_catalog_invariant.py) —
  fails fast if template_id/frame_id 1:1 mapping ever breaks
- 6 behavior tests fully synthetic with MOCK_ prefix (no real catalog IDs,
  no v4_full32_result.yaml dependency) — monkeypatch get_contract +
  compute_capacity_fit (selector has no DI, function signature unchanged)

Deferred to follow-up issues :
- IMP-30 first-render invariant + abort bypass (zero-unit + section status filter)
- IMP-29 frontend zone-level override (deterministic only)
- IMP-31 AI-assisted frame-aware adaptation

Guardrails locked : no calculate_fit / no AI / no frontend / no full rerun /
no layout topology / no abort behavior change / no 1-2 sample hardcoding.

Tests : 8/8 pass (6 selector behavior + 2 catalog invariant).
Smoke regression : 11/11 partials pass (IMP-04 F17 calibration intact).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 23:06:39 +09:00
ec83405770 phase z pipeline: Step 5 / 6-A / 7-conn / 8-conn / Step 9 v0 axis 박힘
사용자 lock 2026-05-08 — Step 5/6/9 boundary reframe.
V4 가 frame 선택, Step 6 은 V4 rank-1 default 전사, Step 9 는 application_plan
번역. compat 매트릭스 안 폐기.

src/phase_z2_pipeline.py 변경 :
- lookup_v4_candidates(v4, section_id, max_n=6) 추가 — V4 non-reject max-6
  후보 list. raw 32 entry 는 v4_full32_result.yaml 영속, step05 = 정제 list.
  lookup_v4_match() (rank-1) 유지 — Step 6 backward compat. (Step 5 보완)
- step05_v4_evidence.json schema 확장 — evidence_per_section[i] =
  {section_id, v4_candidates: [...], candidate_status: "ok" |
  "no_non_reject_v4_candidate"}. (Step 5 보완)
- candidates_lookup_fn 정의 + plan_composition() 에 주입.
  V4 raw dict 는 composition module 안 봄 — fn injection. (Step 6-A)
- Step 6 artifact 의 selected_units[i] 에 v4_candidates 필드 추가. (Step 6-A)
- step07_layout.json data 에 unit_count + layout_candidates 필드 추가
  (Step 7-B 의 select_layout_candidates 결과). step07_selected_layout.html
  에 Layout Candidates 섹션 추가 (default / alternative / selected badge).
  (Step 7-conn)
- step08_zone_region_ratios.json 의 per_zone_plan[i] 에 region_layout_candidates
  + display_strategy_candidates 필드 추가 (Step 8-B-1/2 후보 함수 호출).
  step8_conn_placeholder_signals 명시 — Step 3/4 부재 종속 placeholder
  (region_count=1, content_type="text_block"). step08 HTML 에 candidates pill +
  placeholder caveat. (Step 8-conn)
- APPLICATION_MODE_BY_V4_LABEL 상수 추가 — V4 label → application_mode 변환.
- Step 9 v0 artifact block 신설 (~180 줄) — step09_application_plan.json +
  .html. unit 별 layout_candidates / region_layout_candidates /
  display_strategy_candidates / v4_candidates / candidate_status /
  application_status / current_default_candidate / application_candidates 박힘.
  invariant 5 가지 자연 만족 (status.md §4). (Step 9 v0)

src/phase_z2_composition.py 변경 :
- CompositionUnit 에 v4_candidates: list field 추가 (additive, logic 무변).
  duck typed (V4Match-shape) — circular import 회피. (Step 6-A)
- collect_candidates() 에 v4_candidates_lookup_fn 인자 추가. 3 분기
  (single / parent_merged / parent_merged_inferred) 에서 v4_candidates 채움.
  (Step 6-A)
- plan_composition() 도 v4_candidates_lookup_fn pass-through. (Step 6-A)
- stale "pipeline 호출처 X" 주석 정정 (3 곳: select_layout_candidates /
  select_region_layout_candidates / select_display_strategy_candidates +
  catalog header 2 곳). Step 7-conn / 8-conn 으로 호출처 박혀 *호출처 X* 사실
  위배. (cleanup-1)

axis 닫힘 : Step 5 보완 + 6-A + 7-conn + 8-conn + Step 9 v0 + cleanup-1.
폐기 : 6-B (frame ownership transfer — misframed axis. PHASE-Z-CHANGE-LOG.md
2026-05-08 #2 entry 참조).

regression 0 : MDX03 fresh run 검증 — final.html / step10/12/13/20 byte-동일.
schema 확장만 (step05/06/07/08/09).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:47:11 +09:00
e7848b602d Add Phase Z runtime foundation
- add visual fit classifier, router, retry, and failure routing modules
- add composition planner and catalog-driven mapper
- add Phase Z pipeline orchestration and architecture docs
2026-05-04 08:21:28 +09:00