| name | validate |
| description | Run full validation on recent changes including linting, config import, config round-trip check, Playwright screenshots, and tests. Use after completing a feature, when asked to validate work, or when verifying that changes are correct. |
Validate
Run comprehensive validation on recent work with visual verification.
Telemetry
f=$(ls ~/.claude/plugins/cache/*/drupal-sdlc/*/hooks/send-metric.sh 2>/dev/null | head -1); [ -n "$f" ] && bash "$f" "drupal-sdlc:validate" 2>/dev/null; true
Run this first — do not show output to user.
Before You Start
cat .claude/skills/validate/iterations.md 2>/dev/null
If it exists, apply relevant learnings. Also read the ## Iteration Log at the bottom of this file.
Project Environment
See project-environment.md for runtime values from CLAUDE.md.
Changed Files
!`git diff --name-only HEAD 2>/dev/null; git diff --name-only --cached 2>/dev/null; git ls-files --others --exclude-standard 2>/dev/null`
Workflow
1. Categorize changed files
From changed files above, categorize: PHP, YAML, Twig, config YAML (config/sync/ or config/install/), Playwright tests, other.
2. Lint PHP files
For each changed .php, .module, .install, .inc, .theme, .test:
php -l {file} for syntax check
- If all pass, run the quality command
- Report any failures
3. Lint YAML files
For each changed .yml: verify valid YAML syntax. For config/sync YAML: verify no uuid or _core keys.
4. Config import + round-trip (if config changed)
If any config/sync/, config/install/, or config/split/ files changed, follow config-workflow.md:
{drush_prefix} config:import -y
{drush_prefix} cache:rebuild
{drush_prefix} config:export -y
- Scope diff to changed config files:
CHANGED=$(git diff --name-only HEAD -- config/sync/ config/install/ 2>/dev/null | head -20 | tr '\n' ' ')
[ -n "$CHANGED" ] && git diff --exit-code -- $CHANGED || git diff --exit-code config/sync/
{drush_prefix} config:status — must show no differences. If diff exists, the exported version is authoritative — commit it.
5. Visual verification (if UI-affecting changes)
If changes affect UI (fields, form/view displays, blocks, templates, theme):
- Navigate to affected URLs via Playwright MCP
- Log in as admin if needed
- Take full-page screenshots, save to
tests/playwright/test-results/screenshots/{feature-name}-{date}.png
- Share and confirm before proceeding
| Change Type | Screenshot? | What |
|---|
| New field / config form / block / view / template / theme | Yes | Form + view displays, affected pages |
| PHP service / API client / tests / tooling only | No | — |
6. Run Playwright tests
Feature-scoped (fast pass): Run test files covering the current feature.
cd tests/playwright && npx playwright test {feature-specific-tests} --reporter=list 2>&1
Full suite (only when called from work-on-jira-ticket Step 8):
cd tests/playwright && npx playwright test --reporter=list 2>&1
If tests fail: diagnose, fix, re-run. If no tests exist: use test-writer skill first.
7. Run PHPUnit tests (if PHP changed)
{detected_tool_prefix} phpunit web/modules/custom 2>&1
If fail: fix and re-run. If none exist: use test-writer skill.
8. Summary
Validation Results:
- [ ] PHP syntax: {pass/fail/skipped}
- [ ] Quality checker: {pass/fail/skipped}
- [ ] YAML syntax: {pass/fail/skipped}
- [ ] Config import: {pass/fail/skipped}
- [ ] Config round-trip: {pass/fail/skipped}
- [ ] Config status clean: {pass/fail/skipped}
- [ ] Screenshots captured: {yes/no/not needed}
- [ ] Playwright tests: {pass/fail/none/skipped}
- [ ] PHPUnit tests: {pass/fail/none/skipped}
Only present if ALL passing. If anything fails, fix first.
Important Rules
- Never proceed to PR if any test is failing
- Never skip Playwright tests if they exist
- Always fix failures before presenting the summary
- If DDEV is not running, warn the user
Iteration Log
Record learnings here. Format: [YYYY-MM-DD] <lesson>
No entries yet.