plugins/clade/skills/verify/SKILL.md
Verify project behavior anchors — compilation, tests, and interaction checks after autonomous runs. NOT the Codex built-in /verify (which runs the app to observe a single change working) — this one walks the AGENTS.md "Features (Behavior Anchors)" list.
npx skillsauth add shenxingy/claude-code-kit verifyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This workflow runs directly in Codex. Do not launch the claude CLI or
delegate the workflow to Clade's MCP bridge.
Codex compatibility rules:
AGENTS.md files for repository instructions. If a project
has only CLAUDE.md, treat it as legacy project guidance and read it too..clade/ (or ~/.clade/ for personal
state). Existing legacy Claude state may be read for migration, but do not
create new vendor-specific state./skill-name reference means the corresponding Codex $skill-name skill,
or the same workflow invoked naturally when explicit skill invocation is not
available.<plugin-root>/... are relative to the installed Clade plugin
containing this SKILL.md; resolve that root before invoking a helper.You are the Verify skill. You check that a project's key behaviors still work after code changes.
Read AGENTS.md and look for ## Project Type section. Extract:
If ## Project Type is missing, auto-detect by scanning the repo:
package.json with next/react → web-fullstackrequirements.txt with fastapi/flask → api-onlysetup.py/pyproject.toml with CLI entrypoints → cliCargo.toml / go.mod → check for main packageRead AGENTS.md and look for ## Features (Behavior Anchors) section. Each line is a feature to verify:
- [feature-name]: [what should happen when user does X]
If no anchors found, note this gap and proceed with what's available.
Execute checks based on project type. Run all applicable strategies:
If a test command is specified in ## Project Type:
timeout 120 {test_command}
Record: pass/fail + count of passing/failing tests.
Context hygiene: if ~/.clade/scripts/quiet-run.sh is installed, wrap the command:
timeout 130 bash ~/.clade/scripts/quiet-run.sh {test_command}
Full output lands in .clade/logs/quiet-*.log, each line timestamped [HH:MM:SS];
only the verdict line + failure tail enters the transcript. The exit code is
mirrored, so pass/fail detection is unchanged. Remember the printed full log:
path — if the UI Interaction strategy runs later in this same /verify pass, its
browser console output gets appended to this SAME file (see below), so a test
failure and a JS console error land in one chronologically-ordered artifact.
If no test command but common test patterns exist:
timeout 120 pytest / timeout 120 python -m pytest (Python)timeout 120 npm test / timeout 120 npx jest (Node)timeout 120 cargo test (Rust)timeout 120 go test ./... (Go)Try the likely command. If it works, report results. If not, skip. If timeout fires: mark as ⚠ (test suite timed out — may have hanging test), do NOT retry.
python -m py_compile {main_files} or mypy if configurednpx tsc --noEmitcargo checkgo build ./...If a verify command is specified in ## Project Type, run it.
For each anchor in ## Features:
--help or sample input; API anchor → check the route exists; script → check it's executable and runs without error)Anchor test examples:
install.sh: copies files to ~/.clade/ → bash install.sh --dry-run or check the script is syntactically valid: bash -n install.shslt: cycles statusline mode → bash slt --help or verify the script exists and is executable/commit: analyzes changes → verify the skill prompt file exists: test -f ~/.clade/skills/commit/prompt.md{tool} --help should exit 0Conditions — ALL must be true:
web-fullstack (from AGENTS.md ## Project Type)mcp__playwright__browser_navigate (Playwright MCP tools carry the mcp__playwright__ prefix). If absent, the browser MCP is not wired in — skip.If conditions are not met, set INTERACTION_RESULT: skipped and move on.
Enable browser verification once per project with
configs/scripts/setup-browser-verify.sh <project_dir>— it adds the Playwright MCP to.clade/mcp.json(which both worker spawns and/verifyalready load) and installs the Chromium binary. Below,browser_navigate/browser_snapshot/etc. are shorthand for themcp__playwright__-prefixed tools.
Flow:
Run configs/scripts/ensure-dev-server.sh (no args needed — it reads AGENTS.md's Frontend: ... port NNNN line itself, defaulting to 3000). It is idempotent and flock-guarded (Thorsten Ball: shared discovery state, .clade/dev-server.json) — safe to call even when a concurrent worktree worker is also verifying, since only one of you will actually start it; the rest reuse the same server. Read its one-line output: PORT=<port> STATUS=reused|started|unreachable [PID=<pid>].
If STATUS=unreachable (exit code 1) → set INTERACTION_RESULT: partial, write "App unreachable at localhost:{port}" to .clade/playwright-issues.md, and move on. Do NOT block the verify. Do NOT retry startup yourself — the script already tried for 30s.
Otherwise (reused or started), connect to http://localhost:{port} via browser_navigate — the server is confirmed reachable at this point.
Take a browser_snapshot of the home page to get the accessibility tree.
Walk up to 5 pages (home + up to 4 linked pages):
browser_snapshot → identify interactive elements (buttons, forms, links, inputs)[BUG]Call browser_console_messages once (after the page walk, not per-page — this
is a summary read, not a live stream). If it returns any error/warning
entries AND you remembered a quiet-run log path from the Test-suite strategy
above, append them to that SAME file (Thorsten Ball: merged, time-correlatable
log) — one line per message, timestamped and tagged so it sorts naturally
alongside the test-run output.
Never substitute message text directly into a shell command — a console
message can originate from the page under test (including a malicious PR's own
code), so it may contain $(...), backticks, or other shell metacharacters
that would execute if pasted into a quoted command string. Instead, for each
message: write it verbatim to a scratch file with the file-editing tools (not
shell-interpreted, so no escaping is needed), then append using only paths/
fixed text in the shell command, never the message content itself:
printf '[%s] [browser] ' "$(date +%H:%M:%S)" >> <remembered log path>
cat <scratch file path> >> <remembered log path>
printf '\n' >> <remembered log path>
If no quiet-run log path exists (no test command / quiet-run not used), skip the
append — the console findings still feed into .clade/playwright-issues.md below.
Evaluate:
Write findings to .clade/playwright-issues.md (overwrite, do not append):
[BUG] tag for broken functionality (crashes, errors, broken flows, missing data)[UX] tag for usability issues (confusing layout, missing feedback, accessibility gaps)Set result:
INTERACTION_RESULT: pass — all flows work, no bugs foundINTERACTION_RESULT: partial — some flows unverifiable (app didn't start, pages unreachable)INTERACTION_RESULT: fail — broken UI or unexpected errors found ([BUG] items exist)Bounds: Max 2 minutes of interaction time. Max 5 pages. If time runs out, report what you found so far.
Only if project has linting configured (.eslintrc, ruff.toml, etc.):
{lint_command}
Report warnings but don't count as failures.
If VERIFY.md exists in the project root, read it and report coverage status.
This is a read-only step — do NOT fix anything here. /verify reports; /review fixes.
Impact on VERIFY_RESULT:
fail (confirmed regression)partial at most (gaps, not regressions)If VERIFY.md does not exist: skip this step silently. Output VERIFY_COVERAGE: none in footer.
Write a human-readable summary, then the machine-parseable footer.
## Verify Report — {project_name}
### Test Suite
{pass/fail/skip details}
### Compile Check
{pass/fail details}
### Behavior Anchors
- [anchor-name]: PASS / FAIL (reason) / UNVERIFIABLE (reason)
- ...
### UI Interaction (frontend only)
{pass/partial/fail/skipped + details if applicable}
### VERIFY.md Coverage
{N ✅ N ❌ N ⚠ N ⬜ — or "not present"}
{list any ❌ checkpoint IDs and descriptions}
### Notes
{any observations, warnings, suggestions}
.clade/verify-issues.md)After producing the summary above, if ANY issues were found (failed anchors, test failures, compile errors, UI bugs, lint warnings), ALSO write a structured checklist to .clade/verify-issues.md.
Rules:
- [ ] checkbox per issue, one line eachFormat:
## Failed Anchors
- [ ] anchor-name: brief description of failure
## Test Failures
- [ ] test_module::test_name: assertion error / brief reason
## Compile Errors
- [ ] file:line: error description
## UI Issues
- [ ] [BUG] page/element: what's broken
- [ ] [UX] page/element: usability concern
## Lint Warnings
- [ ] file:line: warning code + message
Copying from playwright-issues.md: If .clade/playwright-issues.md exists and has [BUG] or [UX] items, copy them into the UI Issues section above.
Annotation convention (for human reviewers): Users can annotate each checkbox to control what happens next:
[fix] → auto-creates a fix task on next run[skip] → moved to .clade/skipped.md (won't be raised again)[wontfix] → moved to .clade/skipped.md with wontfix reasonExample: - [ ] [fix] slt: cycles to wrong mode after "off"
Unannotated items remain in the file for next review.
VERIFY_RESULT: pass|partial|fail
FAILED_ANCHORS: anchor-name-1, anchor-name-2
UNVERIFIABLE: N
INTERACTION_RESULT: pass|partial|fail|skipped
VERIFY_COVERAGE: N_pass/N_total|none
Decision rules for VERIFY_RESULT:
FAILED_ANCHORS: comma-separated list of anchor names that FAIL (not unverifiable — only actual regressions). Use none if no failures. NEVER leave blank — blank line breaks grep in start.sh.
UNVERIFIABLE: count of anchors that could not be tested (integer). 0 if all anchors were testable.
VERIFY_COVERAGE: N_pass/N_total where N_pass = ✅ count, N_total = all checkpoints in VERIFY.md. Use none if VERIFY.md does not exist.
INTERACTION_RESULT: UI interaction test outcome.
pass — all flows work, no bugs foundpartial — some flows unverifiable (app didn't start, page unreachable)fail — broken UI or unexpected errors found (.clade/playwright-issues.md has details)skipped — not a frontend project or no Playwright MCP availablethe configured Codex permission policy context (the caller handles this)timeout N: test suites timeout 120, curl/DB queries timeout 30, compile checks timeout 60. If timeout fires → mark ⚠, do NOT retry.clade/blockers.md3-strike rule: If the same approach fails 3 times, switch to BLOCKED — do not retry indefinitely.
Post-iteration verification used by start.sh to check that behavior anchors still pass after autonomous work. Not user-invocable — called internally by the autonomous loop.
development
Orchestrate a fleet of parallel `codex exec` workers with you (Claude Code) as the supervisor — spawn one per isolated git worktree, dispatch headless, verify each INDEPENDENTLY, PR/merge. The manual "codex-ultracode" pattern for fanning out real implementation, research, or review work onto Codex. Bakes in the hard gotchas (stdin blocking, background tracking, don't-trust-self-reports, writer isolation). Triggers on — orchestrate codex, codex workers, codex fleet, spawn codex, delegate to codex in parallel, manual ultracode, 开 codex 小弟, 派 codex worker — NOT for a single cross-vendor opinion (use the `second-opinion-codex` agent), NOT for web-UI worker decomposition (use `/orchestrate`).
development
Create and manage git worktrees for parallel Codex sessions
documentation
End-of-session documentation sync — updates TODO.md and PROGRESS.md only (run /commit after to commit everything)
development
Clade coverage-driven project review — walks every VERIFY.md checkpoint, fixes failures in-session, converges when all checkpoints pass. NOT the Codex built-in /review (which reviews a single pull request diff) — if the user wants a PR review, route to /review-pr (Clade's PR reviewer) or the CC built-in.