feat(IMP-17): AI repair fallback infra carve-out — design-only boundary + 3-cond AND gate

u1 — src/phase_z2_pipeline.py:564 route hint comment corrected from
non-existent IMP-31 to IMP-17 (carve-out, AI fallback only, normal path 밖).
Line 565 IMP-29 frontend override reference untouched.

u2 — docs/architecture/IMP-17-CARVE-OUT.md (new) defines:
- allowed scope (Step 12 restructure proposal, Step 16/17 retry fallback)
- forbidden scope (normal-path AI calls, MDX compression, HTML structure)
- 3-condition AND activation gate (User GO ∧ B4 frame_selection evidence
  ∧ IMP-04 catalog + IMP-05 V4 fallback live)
- pattern shape reference (link-only): content_editor.py:21,318 +
  sse_utils.py:16-50 (Phase Q Archive Candidate, no port)
- AI 격리 contract + Kei persona 단절 (permanent)

u3 — PHASE-Z-IMPLEMENTATION-ISSUE-BACKLOG.md:68 IMP-17 row gains
carve-out doc link + 3-cond AND gate pointer.

u4 — PHASE-Q-INSIGHT-TO-22STEP-MAP.md AI repair fallback infra registry
row prefixed with IMP-17 + carve-out link; normal_path=no preserved.

Anchor test: tests/orchestrator_unit/test_imp17_comment_anchor.py asserts
line 564 IMP-17 wording AND line 565 IMP-29 preservation (2 tests pass).

Runtime behavior change: 0. Only delta in executable file is one comment
line. Normal-path AI invocation count remains 0.

Refs: gitea #17

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-19 08:12:43 +09:00
parent 23ba8b68cd
commit e10ec36617
5 changed files with 76 additions and 3 deletions

View File

@@ -0,0 +1,29 @@
"""IMP-17 u1 (2026-05-19) — comment anchor for src/phase_z2_pipeline.py route hint table.
Stage 1 finding: line 564 previously referenced a non-existent ID ("IMP-31").
The legitimate slot is IMP-17 (Gitea #17, carve-out — AI fallback only, normal path 밖).
Line 565 (IMP-29 frontend zone-level override) must remain untouched.
Run: pytest -q tests/orchestrator_unit/test_imp17_comment_anchor.py
"""
from pathlib import Path
ROOT = Path(__file__).parent.parent.parent
PIPELINE = ROOT / "src" / "phase_z2_pipeline.py"
def _lines() -> list[str]:
return PIPELINE.read_text(encoding="utf-8").splitlines()
def test_line_564_references_imp17_not_imp31():
line = _lines()[563] # 1-indexed line 564
assert "restructure" in line, f"line 564 anchor drifted: {line!r}"
assert "IMP-17" in line, f"line 564 must reference IMP-17 (carve-out): {line!r}"
assert "IMP-31" not in line, f"line 564 must not reference non-existent IMP-31: {line!r}"
def test_line_565_still_references_imp29():
line = _lines()[564] # 1-indexed line 565
assert "reject" in line, f"line 565 anchor drifted: {line!r}"
assert "IMP-29" in line, f"line 565 must still reference IMP-29 frontend override: {line!r}"