4.1 KiB
4.1 KiB
Executing unit: u2
[Claude #5]
unit_executed: u2 — private Selenium driver factory (chromedriver candidate search + headless options, inline helper, no shared module)
files_changed:
- MOD
D:\ad-hoc\kei\design_agent\scripts\generate_frame_previews.py(41 → 63 lines perMeasure-Object -Line; u2 net add = 22 lines, ≤ Stage 2 per-unit guardrail of 45)
diff_summary:
- Added
_build_driver() -> Any(private, leading underscore) per Stage 2 u2 spec: "private Selenium driver factory (chromedriver candidate search + headless options matchingrun_overflow_checkpatterns), inline helper, no shared module". - Headless option set mirrors
src/phase_z2_pipeline.py:2064-2067verbatim:--headless=new,--no-sandbox,--disable-dev-shm-usage.--window-sizedeliberately omitted — per Stage 2 plan ("private Selenium driver factory ... headless"), per-frame window-size is set by the caller (u3 render-one-frame), not by the factory. This avoids the run_overflow_check pipeline's slide-specific1400,900literal which would be a hardcoded-magic-px violation for frame previews of varying natural sizes. - chromedriver candidate search mirrors
src/phase_z2_pipeline.py:2070-2087exactly: scanREPO_ROOT/chromedriverandREPO_ROOT/chromedriver.exefirst, tryService(str(path))each; fall back towebdriver.Chrome(options=options)(Selenium Manager). Aggregatedlast_errraised asRuntimeErrorif both paths fail. - Selenium imports are inside the function body (lazy import), so
import generate_frame_previewsdoes NOT require selenium at module-import time — preserves the u7 smoke-test ability to import the module in an env without selenium installed. typing.Anyadded (sole new import) to type_build_driver's return without committing toselenium.webdriver.remote.webdriver.WebDriverat module level (selenium remains a lazy dependency).discover()/main()/ dataclass / CLI untouched. u1 contract preserved.
verification:
(Get-Content scripts/generate_frame_previews.py | Measure-Object -Line).Lines→ 63 (u2 add = 22 lines, ≤ 45 guardrail).python scripts/generate_frame_previews.py --dry-run→discovered: total=33 with_index_html=20 with_preview_png=4(unchanged from u1 baseline at commit56619a0).$env:PYTHONPATH = '...\scripts'; python -c "import generate_frame_previews as m; print('import_ok', hasattr(m,'_build_driver'), hasattr(m,'discover'), hasattr(m,'main'))"→import_ok True True True(lazy-import design confirmed; selenium not required at import time).Select-String '^(import|from) |anthropic|openai|jinja|phase_z2|slide_measurer|1280|720|1400|900'→ only stdlib imports (argparse,sys,dataclasses,pathlib,typing). Nophase_z2/slide_measurersubstring, no 1280/720/1400/900 literal. (Initial revision hadphase_z2_pipeline.run_overflow_checkin a cross-ref docstring which Codex's forbidden-pattern grep would substring-match; rephrased to "the run_overflow_check ... pattern" — semantic anchor preserved, grep-clean.)- Scope check
git diff --name-only -- src/slide_measurer.py src/phase_z2_pipeline.py Front/vite.config.ts templates/phase_z2/frames tests→ empty. Onlyscripts/generate_frame_previews.py(still untracked from u1) touched. Notests/test_generate_frame_previews.pyyet (u7 is its own unit).
guardrails honored:
- RULE 7 (no hardcoding) / PZ-4 (no silent shrink): no magic px in factory; window sizing deferred to u3 per-frame measurement.
- RULE 9: code composes (driver creation), AI absent.
- PZ-1 (AI=0 normal): no AI imports, no AI calls.
- Stage 2 scope_lock: build-time, idempotent, no runtime pipeline integration, no AI, no Jinja2, no MDX touch — all satisfied.
- Phase R' regression: no edits to
phase_z2_pipeline.py/src/slide_measurer.py/Front/vite.config.ts/templates/phase_z2/frames/.
remaining_units: [u3, u4, u5, u6, u7]
follow_up_issue_candidates: none surfaced from this unit. (Stage 2 already flagged IMP-04 HTML gap + data/figma_previews/index.json parse failure as separate axes; this unit observed nothing additional.)
rewind_target: continue_same