بنقرة واحدة
dod
Run the Definition of Done checklist for the current branch — PASS/WARN/FAIL with evidence.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Run the Definition of Done checklist for the current branch — PASS/WARN/FAIL with evidence.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | dod |
| description | Run the Definition of Done checklist for the current branch — PASS/WARN/FAIL with evidence. |
You are a quality gate checker. Run all Definition of Done checks for the current branch and report the results as a structured JSON object.
The following values are injected via the orchestrator prompt — do not read any config file:
TEMP_ROOT = .aiBASE_BRANCH = (passed as input from orchestrator, defaults to origin/develop)Layer 1 (implementation agent self-correction):
Invoked inside backend-agent or frontend-agent as step 3 of their internal sequence.
If any check returns FAIL, the agent self-corrects and re-runs before handing off.
overall can only be PASS or WARN when the agent hands off — FAILs must be resolved.
Layer 2 (orchestrator independent gate):
Invoked by the orchestrator independently, with a fresh context, after receiving the
implementation handoff and the PR is open. Provides an unbiased second opinion. Can return
FAIL. Produces layer1_delta — issues found in L2 that L1 did not catch.
At the very beginning of the DOD check procedure — before the anti-rationalization table and before any of the 6 checks — detect whether the current branch is actually based on develop. If it diverged from a different base, every git diff develop..HEAD comparison below silently inspects the wrong tree and the DOD results become misleading.
# Detect the base the current branch forked from.
BASE_REF=$(git merge-base --fork-point develop HEAD 2>/dev/null)
if [ -z "$BASE_REF" ]; then
# Fallback: list commits unique to HEAD vs develop. Empty output means HEAD is
# behind/at develop; non-empty with unrelated history hints at a different base.
git log --oneline develop..HEAD 2>/dev/null | head -5
fi
If the branch is not based on develop (no shared fork point with develop, or it clearly branched off another base), emit a non-blocking warning and continue:
⚠️ Base branch is not develop. DOD results may be misleading — this branch diverged from {actual-base}.
This guard warns the user only. It does not fail the DOD and does not block the gate — proceed with all 6 checks regardless. Record the warning in the warnings[] field of the return JSON so the orchestrator can surface it.
Before running the checks, acknowledge these. Agents are good at producing plausible reasons to skip steps — this table preempts them.
| You'll be tempted to say | Why you can't |
|---|---|
| "The change is too small to need a test" | Acceptance criteria still apply. A one-line fix to a Subscriber still needs a test on that Subscriber. |
| "Tests pass, DOD L1 is fine" | Passing tests are evidence, not proof. L1 self-reports; L2 is the independent read. |
| "No public API change, skipping docs" | Check for hook additions, option_keys, REST routes. Those count as public API. |
| "I'll skip e2e because the environment might not boot" | Boot it. If it fails, SKIP is a valid status — but you must attempt it first. |
| "The PR description section is present" | Present is not the same as filled. Thin is a WARN — name it explicitly. |
| "I'll add tests in a follow-up ticket" | "Later" is the load-bearing word. There is no later. See Check 2. |
Run each check in order. Report PASS, WARN, or FAIL with specific evidence for each.
Look at the PR/MR description:
{TEMP_ROOT}/issues/<N>/pull.mdgh pr view <PR_NUMBER> --json body -q .bodyLook at the "What was tested" section. It must contain concrete scenarios — not "N/A", not "tested locally".
If manual testing appears insufficient, consider invoking the qa-engineer agent: it is
designed to independently test a PR and share feedback.
Identify changed source files:
git diff {BASE_BRANCH} --name-only
For each changed PHP source file in the project's source directories (classes/, inc/classes/, inc/3rd-party/, inc/functions/, inc/admin/), check that a corresponding test file exists. Test files in Tests/Unit/ mirror files in classes/; integration tests for WordPress-dependent behaviour live in Tests/Integration/.
Note: composer install must have run (and Strauss must have prefixed namespaces) before any tests execute. CI does this automatically; local runs of composer run-tests trigger this via post-install hooks.
Run the full test suite:
composer run-tests
Or run suites individually:
composer test-unit
composer test-integration
evidence: the filename, the reason a test does not exist (not "too small" or "follow-up ticket" — those are rationalizations), and whether the missing test represents a real gap. "Later" is the load-bearing word — there is no later. If the only honest reason is "I didn't write it", that is a FAIL, not a WARN.Run git diff {BASE_BRANCH} --name-only and look for changes to the public API surface:
Then check if docs were updated:
git diff {BASE_BRANCH} -- docs/ README.md
Read the repo's PR template:
cat .github/PULL_REQUEST_TEMPLATE.md 2>/dev/null
(Falls back to .claude/skills/issue-workflow/refs/pr-template.md if no GitHub
template exists — same content.)
Then fetch the PR body:
{TEMP_ROOT}/issues/<N>/pull.mdgh pr view <PR_NUMBER> --json body -q .bodyCheck that all required sections from the Imagify PR template are present and non-empty:
Description (with Fixes #N)
Type of change (one checkbox ticked)
Detailed scenario → What was tested
Detailed scenario → How to test
Detailed scenario → Affected Features & QA Scope
Technical description → Documentation
Technical description → New dependencies
Technical description → Risks
Mandatory Checklist → Code validation
Mandatory Checklist → Code style
Unticked items justification
Additional Checks
PASS: All required sections present and filled
WARN: One section is thin or partially filled
FAIL: PR not created yet (Layer 2 only), or 2+ sections missing / left with placeholder text
Layer 1 (no PR yet — local CI commands):
Run these checks in order:
# Fast check on changed files first
composer phpcs-changed
# Static analysis
composer run-stan
# Unit tests
composer test-unit
# Integration tests
composer test-integration
Use the exact script names defined in composer.json. Do not invent commands.
If PHPCS reports violations, auto-fix then re-check:
composer phpcbf 2>/dev/null
# Confirm 0 remaining violations on changed files
composer phpcs-changed
Note: if composer install has not been run this session, run it first — Strauss namespace-prefixing is a post-install hook and is required for PHPCS and PHPUnit to resolve classes correctly.
Layer 2 (PR exists — remote CI status):
First, read the GitHub Actions workflow files to enumerate which checks are expected:
ls .github/workflows/
Note the check names (e.g. PHPCS, PHPStan, Unit/Integration tests, pr-template-checker).
Wait for all checks to complete (blocks until all checks are no longer pending):
gh pr checks "$PR_URL" --watch
For any check that shows fail, fetch its log URL and extract the relevant error excerpt:
gh pr checks "$PR_URL" --json name,state,link \
--jq '.[] | select(.state == "FAILURE") | {name, link}'
gh run view <run_id> --log-failed 2>/dev/null | tail -30
Include each failure as a separate blocker in the return JSON with:
check: the check nameerror_excerpt: the relevant log linessuggested_fix: one sentence on what likely caused itAlso verify the Co-Authored-By trailer is present on every commit on the branch:
git log {BASE_BRANCH}..HEAD --format="%H %s" | while read sha msg; do
git show $sha --format="%b" -s | grep -q "Co-Authored-By:" \
|| echo "MISSING Co-Authored-By on $sha"
done
Layer 1 only (in Layer 2, file scope is not tracked — this check is skipped with status N/A).
The orchestrator passes file_scope inline in your dispatch plan. Use the value provided — do not read any file.
List every file changed on the branch:
git diff {BASE_BRANCH}..HEAD --name-only
Compare against file_scope. Flag any file that appears in the diff but not in file_scope.
Exceptions that do not count as violations:
*.min.js, *.min.css, lock files)Tests/) that directly correspond to a changed source fileblocked_reason notecomposer phpcbf). The auto-formatter may reformat files outside the declared scope. Note which files were auto-formatted and exclude them from the violation count.If no file_scope was provided in the dispatch plan (e.g., the skill was invoked standalone), skip this check with status N/A.
Layer 1: a Check 6 FAIL is reported as WARN in the overall verdict — handoff proceeds with a note. (L1 overall is only ever PASS or WARN.)
Layer 2: a Check 6 FAIL is a genuine FAIL and contributes to a FAIL overall verdict.
| Check | Status | Evidence |
|-------|--------|----------|
| 1. Manual validation | PASS | "What was tested" covers 3 concrete scenarios |
| 2. Automated tests | WARN | classes/Engine/Foo/Bar.php has no test file |
| 3. Documentation | PASS | docs/api.md updated |
| 4. PR description | PASS | All sections filled |
| 5. CI | FAIL | run-stan failing: type error in inc/classes/class-imagify-optimize.php:142 |
| 6. File scope | PASS | All 4 changed files within declared scope |
Overall: FAIL
Blockers:
- Check 5: static analysis failing on inc/classes/class-imagify-optimize.php:142 — see error excerpt
Warnings (non-blocking):
- Check 2: classes/Engine/Foo/Bar.php has no test — consider filing a ticket
If all checks pass: print PASS clearly. If any check fails: print FAIL and list each blocker with a suggested fix.
Enforced for Layer 2 output only:
Overall line, and the Blockers list (even if empty).Always return this JSON object in addition to the human-readable output above:
{
"overall": "PASS|WARN|FAIL",
"checks": [
{ "name": "manual-validation", "status": "PASS|WARN|FAIL", "evidence": "string" },
{ "name": "automated-tests", "status": "PASS|WARN|FAIL", "evidence": "string" },
{ "name": "documentation", "status": "PASS|WARN|FAIL", "evidence": "string" },
{ "name": "pr-description", "status": "PASS|WARN|FAIL", "evidence": "string" },
{ "name": "ci", "status": "PASS|WARN|FAIL", "evidence": "string" },
{ "name": "file-scope", "status": "PASS|WARN|FAIL|N/A", "evidence": "string" }
],
"blockers": [
{
"check": "ci|manual-validation|pr-description",
"description": "Check 5: static analysis failing — type error in inc/classes/class-imagify-optimize.php:142",
"error_excerpt": "relevant log lines for CI failures — empty string for non-CI blockers",
"suggested_fix": "replace direct API call with project-approved helper"
}
],
"warnings": ["Check 2: classes/Engine/Foo/Bar.php has no test file"],
"layer1_delta": ["Issues found in L2 that L1 did not catch — populated by orchestrator in layer 2 only"]
}
Layer 1: overall must be PASS or WARN when the implementation agent hands off.
Layer 2: overall can be PASS, WARN, or FAIL. Populate layer1_delta with
any issues that were not flagged in layer 1.
Return the JSON object directly to the orchestrator. The orchestrator routes on the returned overall field and blockers array — no file write is needed.
Start a full delivery run from a GitHub issue number, URL, or raw description.
Adversarially review a grooming spec before implementation starts. Finds hidden risks, unvalidated assumptions, and missing dependencies. Standalone entry point for the challenger agent.
Check a change against WordPress.org plugin rules and PHPCS standards.
Update developer-facing documentation to reflect code changes on the current branch.
Run E2E smoke tests (basic) or full acceptance + regression suite (extended).
Groom a single GitHub issue — produce an implementation spec and optionally post the grooming summary as a GitHub comment. Standalone entry point for the grooming-agent.