Chrome MCP mandatory for exploratory web browsing; Playwright reserved for scripted CI suites

AJ directive 2026-05-16: every actual web browsing task (open page, observe rendered output, click/type, screenshot proof) routes through Chrome MCP (mcp__Claude_in_Chrome__*). Playwright is NEVER the exploratory browser — reserved for scripted/regression suites only (.spec.ts files, scripts/smoke-tests/, CI workflows in .github/workflows/).

Enforcement: PreToolUse hook at /root/.claude/hooks/chrome-mcp-mandatory-guard.py BLOCKS Playwright invocation with exit-code 2 unless scripted-suite evidence present (file path detection / SCRIPTED_BROWSER=1 / PLAYWRIGHT_BYPASS=1). Wired into ~/.claude/settings.json PreToolUse with matcher Skill|Bash|mcp__.*. Hook unit-tested with 6 cases (allow Chrome MCP / block Playwright on known sites / allow .spec.ts scripted / allow novel-site browser-use / block known-site browser-use / allow env bypass).

Why: Chrome MCP uses AJ’s real Chrome session (real auth, real fonts, real extensions, real rendering). Playwright headless inside the VPS cannot reuse AJ’s session — authenticated exploratory browsing renders blank. The R-Dash dashboard demo proved this: Chrome MCP exposed the broken viz_config (KPIs showing ”—”, donut “undefined” labels) that headless Playwright would have missed.

Legitimate Playwright scope (zero overlap with Chrome MCP): GHA CI (no human, no extension), cross-browser (Firefox/WebKit), visual regression with stored baselines, trace files for post-mortem, parallel execution, isolated browser contexts. Live example: R-Dash .github/workflows/accessibility.yml (axe-core PRs) + nightly-smoke.yml (post-deploy.spec.ts at 03:00 IST).

References: feedback_chrome_mcp_over_playwright.md, feedback_proactive_utilization.md § 3, playwright-cli SKILL.md (canonical reference pattern), browser-use SKILL.md (scope-narrowed to <1% rare-tier fallback).