Files
C.E.L_Slide_test2/.orchestrator/tmp/61_r3_post.json
T

1 line
6.6 KiB
JSON

{"body": "[Claude #7] Stage 3 code-edit — IMP-33 #61 (R3 u3)\n\nExecuting unit: u3\n\n■ unit_executed\n- id: u3\n- summary: AI fallback prompt builder (`src/phase_z2_ai_fallback/prompts.py`). System prompt pins MDX READ-ONLY + u2 whitelist + forbidden kinds + frame_id-swap lock + Internal Region containment. User payload carries the 6 declared inputs. Fallback-route guard raises `ValueError` when V4 route ≠ `ai_adaptation_required`.\n\n■ files_changed\n- src/phase_z2_ai_fallback/prompts.py (NEW, 80 lines)\n- tests/phase_z2_ai_fallback/test_prompts.py (NEW, 100 lines, 11 tests)\n\n■ diff_summary\n- `src/phase_z2_ai_fallback/prompts.py`:\n - module-level constant `V4_ROUTE_AI_ADAPTATION = \"ai_adaptation_required\"` (mirrors `src/phase_z2_pipeline.py:575` `_IMP05_ROUTE_HINTS[\"restructure\"]`).\n - `SYSTEM_PROMPT` (module constant) — composes:\n - Rule 1: MDX in user payload is **READ-ONLY**; no rewrite / compress / paraphrase (`feedback_ai_isolation_contract`).\n - Rule 2: output MUST be a single JSON object conforming to `AiFallbackProposal` (u2).\n - Rule 3: enumerates the u2 whitelist `{builder_options_patch, partial_overrides, slot_mapping_proposal}` from `ProposalKind` (no hardcoded duplicate; sourced from u2 module).\n - Rule 4: enumerates the u2 forbidden kinds `{mdx_text, frame_id_change, raw_html, raw_css}` from `FORBIDDEN_KINDS` (single source of truth).\n - Rule 5: forbids `frame_id` change (V4 rank-1 protected, `feedback_phase_z_spacing_direction`).\n - Rule 6: keep declared frame slots (text/table/image/details) populated (Stage 2 dropped-slot guard preview; u5 enforces).\n - Rule 7: respect Internal Region containment.\n - `build_ai_fallback_prompt(*, v4_result, frame_contract, frame_visual_html, figma_partial_json, internal_region, mdx_text) -> dict[str, str]`:\n - Fallback-route guard: reads `v4_result.route` (or alias `imp05_route_hint`); raises `ValueError` mentioning `V4_ROUTE_AI_ADAPTATION` if not equal. This is the prompt-layer enforcement of PZ-1 (AI=0 normal path).\n - Returns `{\"system\": SYSTEM_PROMPT, \"user\": json.dumps(payload, ensure_ascii=False)}`.\n - User payload structure: `{\"v4\": {route, cardinality, label, frame_id, rank}, \"frame_contract\", \"frame_visual_html\", \"figma_partial_json\", \"internal_region\", \"mdx_text_READ_ONLY\"}` — MDX key suffix is the on-wire READ-ONLY signal (paired with system-prompt rule 1).\n - Cardinality alias support: reads `cardinality` or `cardinality_signature` (V4 caller compatibility).\n - No Anthropic import, no `messages.create()` call, no filesystem I/O (caller supplies loaded artifacts) — u4 owns client wiring.\n- `tests/phase_z2_ai_fallback/test_prompts.py` — 11 tests:\n - SYSTEM_PROMPT declares \"READ-ONLY\".\n - SYSTEM_PROMPT enumerates all 3 whitelisted `ProposalKind` values.\n - SYSTEM_PROMPT enumerates all 4 forbidden kinds from `FORBIDDEN_KINDS`.\n - SYSTEM_PROMPT mentions `frame_id` (swap lock).\n - `build_ai_fallback_prompt` returns exactly the `{system, user}` shape and `system == SYSTEM_PROMPT`.\n - User payload contains all 6 declared inputs, the V4 sub-shape, and the MDX key suffixed `_READ_ONLY` (asserts `\"mdx_text\" not in payload` to confirm there is no writable MDX alias).\n - Parametrized: `direct_render`, `deterministic_minor_adjustment`, `design_reference_only`, missing-route — all raise `ValueError` matching `V4_ROUTE_AI_ADAPTATION`.\n - `cardinality_signature` alias is read when `cardinality` is absent.\n\n■ verification (this unit only, scope-qualified)\n- `python -m pytest tests/phase_z2_ai_fallback/test_prompts.py -q` → 11 passed in 0.02s.\n- `python -m pytest tests/phase_z2_ai_fallback/ -q` → 20 passed in 0.03s (schema 9 + prompts 11).\n- Baseline + u1 + u2 + u3 combined: `python -m pytest tests/test_family_contract_baseline.py tests/test_phase_z2_ai_fallback_config.py tests/phase_z2_ai_fallback/ -q` → 28 passed in 0.62s. No regression in baseline.\n- `grep -rn \"Anthropic|messages\\.create\" src/phase_z2_ai_fallback/ tests/phase_z2_ai_fallback/` → only a docstring reference to \"the Anthropic client (u4)\"; no import, no API call.\n- No edits to `src/phase_z2_pipeline*.py`; normal-path AI call count unchanged.\n\n■ guardrail_checks\n- PZ-1 (AI=0 normal path): preserved — prompts builder is module-scoped, callable only when V4 route equals `ai_adaptation_required`; raises before constructing prompt otherwise. No call-site introduced yet (u7 wires).\n- `feedback_ai_isolation_contract`: preserved — MDX text is explicitly suffixed `_READ_ONLY` and the system prompt declares MDX is read-only.\n- `feedback_phase_z_spacing_direction`: preserved — system prompt forbids `frame_id` change; u5 will reinforce at the validator.\n- RULE 7 (no hardcoding): the whitelist + forbidden kind lists are derived from `ProposalKind` and `FORBIDDEN_KINDS` (single source of truth in u2). No sample-specific MDX/frame literal in this module.\n- RULE 9 (LLM classifies, code composes): u3 hands the LLM a *classification/proposal* task only; payload composition (and HTML/CSS structure) remain code-owned downstream.\n- `feedback_one_step_per_turn`: only u3 executed; stopping here. u4 NOT touched.\n\n■ remaining_units\n- u4 (client.py — Anthropic wiring; timeout/retry/backoff/budget/circuit via u1 Settings; transient-retry classes; NO inline literals)\n- u5 (validate.py — schema + builder whitelist + dropped-slot + frame-swap + Internal Region containment)\n- u6 (cache.py — IMP-46 gate; storage NotImplementedError)\n- u7 (router.py — flag-off + route-gated + cache-read composition)\n- u8 (Step 12 wiring after IMP-30 provisional payload; reject remains design_reference_only)\n- u9 (Step 17 blocked behind IMP-34/35; cascade order enforced)\n- u10 (AST import isolation guard — no Phase Q/Kei/pipeline runtime imports from fallback package)\n- u11 (docs sync — runtime state, module path, Step 12/17 state, cascade order, IMP-46 gate)\n\n■ follow_up_issue_candidates\n- none. No scope-lock-外 axis surfaced during u3. (Note: u3 deliberately does NOT load HTML/JSON from disk — that becomes the u7 router's responsibility; not a new axis, planned in Stage 2.)\n\n■ next_action_proposal (informational only; not executed this turn)\n- Next turn = u4 (client). Module path = `src/phase_z2_ai_fallback/client.py` per Stage 1 audit-binding. All policy values (timeout=60s, max_retries=3, backoff base/cap/jitter=1.0/8.0/0.3, budget=10, circuit=5, model=`claude-opus-4-6-20250415`) MUST source from u1 `Settings` (no inline literals; u4 test asserts this). No commit / push performed this turn (Stage 3 contract).\n\nrewind_target: continue_same\n"}