verify-acceptance
Skill4 starsChanged 7 days agoMITView on GitHub
Review a completed bead's implementation against its acceptance_criteria, criterion-by-criterion, and emit a strict-mode `report.json`. Use after /review but before declaring STATUS COMPLETE. The bead-axis counterpart to code-axis review — answers "did we build what was asked for?" not "is the code well-structured?" Triggers on: verify acceptance, bead coverage check, check acceptance criteria, did the implementation match the bead.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- krzysztofsurdy/code-virtuosotheir own version, first seen Nov 1, 2026
- garthcodes/claude-skillstheir own version, first seen Oct 8, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- krzysztofsurdy/code-virtuoso★ 36same name
- garthcodes/claude-skills★ 2same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository14 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- ac-quality-reviewSkill
- beadsSkill
- consult-councilSkill
- create-beadSkill
- freshness-triageSkill
- playwright-cliSkill
- reaperSkill
- reviewSkill
- rubSkill
- wishSkill
- create-beadSkill
- wishSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
16 rules. About 0 are common, 2 are distinctive, and 14 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
14
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 10
Before anything else: run djinn skills check --here in the repo you are working in.
- Very specific: line 41
Use field name acceptance_criteria (NOT acceptance — that key is always null).
- Very specific: line 57
Read it end to end for small diffs.
- Distinctive: line 71
If no comment matches the current run and iteration:
- Very specific: line 76
When the current record IS present, its row count should match the criterion count from Step 2.
- Very specific: line 94
If Implementation names path/file.ts:42, open that file and read around line 42.
- Very specific: line 95
If Verification is a playwright-cli command, confirm it's a plausible way to exercise the criterion (not a placeholder).
- Very specific: line 96
If Evidence names a snapshot file, confirm it exists under .playwright-cli/ (list the directory).
- Very specific: line 97
If Evidence is "algorithmic analysis" for a criterion that named a specific empirical threshold (e.g., "< 100ms at 10k entries"), assign …
- Very specific: line 101
Every criterion is pass → complete: true, reason: null.
- Very specific: line 137
Add no top-level or per-criterion key outside this shape — no verdict shadow field.
- Very specific: line 139
When complete: false, fill reason with a non-null one-line summary naming which criteria gated rejection.
- Distinctive: line 159
Adding criteria the bead does not name: If the author did not write "keyboard shortcut to reset filters," the absence of that shortcut is …
- Very specific: line 160
Judging code quality: Leave style, readability, architecture to /review.
- Very specific: line 161
"Probably pass.": If you cannot validate the file:line claim by opening the file, the status is partial or fail — not pass with a caveat.
- Very specific: line 165
Empirical-vs-algorithmic laundering: If the criterion names a concrete threshold (latency, count, scale), evidence needs that concrete …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!-- djinn-compat-check: begin -->Before anything else: run djinn skills check --here in the repo you are working in. If it exits non-zero, stop: relay its output to the user verbatim — it names the fix — and run no other step of this skill. On exit 0, continue.
<!-- djinn-compat-check: end -->Verify Acceptance
Overview
Bead-axis review: judge every acceptance criterion against the diff plus the evidence artifact and emit a report.json that names each criterion's verdict, a non-empty note, and the diff files that satisfy it. This complements /review, which reviews code health.
Scope boundary — read this before anything else. Findings MUST be grounded in the literal text of bead.acceptance_criteria. Do NOT expand scope. If the implementation is missing a capability that seems useful but is not named in the criteria, that is a bead-authoring concern, not a /verify-acceptance finding. This skill answers exactly one question: does the diff implement every criterion the bead names?
Strict mode — read this twice. Mark complete: true only when every criterion has status: "pass". Acceptance has exactly two branches: all-pass → complete: true, or anything else → complete: false with a non-empty reason. On complete: false the Author fixes the gap (or files a separate bead for genuinely-out-of-scope work and reduces the parent's criteria) and re-runs. No code checks this rule for you: a partial or fail criterion means complete: false, however persuasive its note reads.
Inputs
The invoker must provide:
bead_id— e.g.phoenix-a4os- Diff base ref — the commit before this bead's work started. Under DJINN, use the harness
pre_sha(the fallback below names where to read it). OtherwiseHEAD~Nwhere N is this iteration's commit count. - Evidence — the bead's latest evidence comment, read with
bd comments <bead_id> --json(djinn-mr56i; there is no evidence file)
Only input 1 is guaranteed: a harness caller passes the bead id and nothing else, and there is no operator in the loop to supply the rest. If an input is missing, derive it from convention and continue — never stop, ask, or wait for a human: the diff base ref is the pre-implement SHA the harness records (pre_sha) — read it from the iteration's [run.N] <bead_id> child bead with bd show <run_bead_id> --json | jq -r '.[0].metadata.pre_sha' (written at run-open time by internal/djinn/session/iter_beads.go); when that bead or field is unreadable, fall back to git merge-base <default-branch> HEAD, and outside a harness run to HEAD~N for this iteration's commit count. The evidence is always the bead's own comment thread — no path to pass. In formula mode the harness records that comment in its commit-push step, which runs AFTER verification, so inside a harness run (DJINN_SESSION=1) the bead usually carries no evidence comment for this iteration yet: when none is present there, skip the row-count check in Step 4 and judge every criterion from the bead text and the diff alone; in that mode its absence is never a fail. Outside a harness run the evidence comment is the author's §6 obligation and is expected to exist: a missing one is a fail.
Process
Step 1. Read the bead
bd show {bead_id} --json | jq -r '.[0].acceptance_criteria'Use field name acceptance_criteria (NOT acceptance — that key is always null).
Step 2. Split criteria into segments
Acceptance criteria follow a line-per-criterion convention (see the project's bead-authoring rules): each non-blank line is one independently-verifiable criterion. Trim whitespace. Preserve order — index N in report.criteria corresponds to segment N (1-indexed).
Older beads written before the convention may use ; as a separator. For those, split on ; and best-effort. If you detect ambiguous splits (semicolons inside parenthetical clauses, e.g. tooltip shows (heartbeat × 3; story_so_far × 0)), record the issue under the affected criterion's note and continue with your best split.
Step 3. Read the diff
git diff <base>..HEAD
git diff <base>..HEAD --stat # for large diffs, then Read individual files
git diff <base>..HEAD --name-only # canonical diff-file set; criterion.diff_files MUST be a subsetRead it end to end for small diffs; use --stat to triage which files to open with Read for larger changes.
Step 4. Read the evidence comment
bd comments {bead_id} --json # the whole thread; select by run/iter, not by recencySelect the record by IDENTITY, never by recency. New evidence comments are JSON objects with schema: "djinn-evidence" and top-level run (string) and iter (integer) fields (contract §6). For legacy YAML comments, read the same identity from the first-line header # djinn evidence — run <run-id> · iter <n>.
Comments are append-only: they survive retries, fix iterations and reopened beads, so the newest evidence comment on a bead is frequently an EARLIER attempt's — and in formula mode it always is, because the harness records the current run's comment at commit-push, after this verification has already run. Judging an older record as if it were this one produces a false row-count fail the moment the criteria changed between attempts.
So: read the run/iter fields (or legacy header) of each evidence comment and pick the one whose run/iter match the run and iteration you are verifying. Treat every other evidence comment as history — do not judge against it, do not count its rows. A comment with neither the JSON schema marker nor the legacy header is not an evidence record; skip it.
If no comment matches the current run and iteration:
- Inside a harness run (formula mode,
DJINN_SESSION=1): the harness has not recorded it yet. Skip this step entirely and judge from the diff; do not report the absence as a finding — this is the documented skip, not a gap. - Outside a harness run: a missing evidence record is a
fail— the author owed it under §6.
When the current record IS present, its row count should match the criterion count from Step 2; a mismatch is a fail.
Each row carries the author's claim: Status, Implementation (file:line), Verification (command or test), Evidence (artifact). Use these as starting points — then validate.
Step 5. Judge each criterion
For each segment from Step 2, independently assign one of the three closed-enum statuses (pass | partial | fail):
pass — The diff implements the criterion, the evidence row's Implementation file:line points to code that actually does what the criterion describes (open the file and confirm), and Verification is a runnable command or real test path.
partial — The diff addresses the criterion — code in it does or starts part of what the criterion describes — but a sub-aspect the criterion names is not met. A named behaviour left as a stub or a TODO behind code the diff does add is partial. Examples: "remains readable with 500 ticks" but only tested at 87; "tooltip shows X, Y, Z" but tooltip shows X and Y only; criterion demands empirical test and evidence offers algorithmic reasoning only; "--since <date> prints only later entries" but the diff parses the date and leaves the filter a TODO.
The unmet sub-aspect must be one the criterion's text names. A concern the criterion does not name — a hard-coded literal that still says what the criterion asks, a detail it does not ask to be tested, an evidence file:line a few lines off the code you confirmed — goes in the note and never lowers pass. Pick one status per criterion and stand by it; a note that says the criterion is met carries pass.
fail — Nothing in the diff addresses the criterion: no file:line in the diff touches it, OR the claimed file:line does not exist, OR the claimed file:line exists but does no part of what the criterion describes. When the diff does part of the criterion, the status is partial, however large the missing part, and never fail.
For each criterion, validate the author's claim yourself:
- If Implementation names
path/file.ts:42, open that file and read around line 42. Confirm it implements what the criterion says. - If Verification is a
playwright-clicommand, confirm it's a plausible way to exercise the criterion (not a placeholder). You do not need to re-run it. - If Evidence names a snapshot file, confirm it exists under
.playwright-cli/(list the directory). - If Evidence is "algorithmic analysis" for a criterion that named a specific empirical threshold (e.g., "< 100ms at 10k entries"), assign
partialunless the empirical number is produced.
Step 6. Decide acceptance (strict mode)
- Every criterion is
pass→complete: true,reason: null. - Any criterion is
partialorfail→complete: false,reason: "<one-line summary naming which criteria gated rejection>".
There is no third branch. Acceptance carries no follow-up budget — a bead with one partial criterion is rejected. If the gap is genuinely out of scope, the remediation is to file a follow-up bead and update the parent's criteria, not to ship complete: true and promise to come back.
Step 7. Emit report.json
Output a single JSON object — no prose, no markdown, no code fences. A /verify-acceptance Skill-tool invocation emits it inline.
The object has this shape:
{
"complete": true,
"reason": null,
"criteria": [
{
"index": 1,
"status": "pass",
"note": "<non-empty evidence string: file:line + what it does>",
"diff_files": ["<path relative to repo root>", "..."]
}
]
}The accept-path shape above omits suggested_change because it has no remediation to record. The rejection example below shows it in use.
Shape rules:
completeMUST be present and a bool.criteriaMUST be present: an array with one entry per criterion from Step 2.reasonMUST be a string or null.- Each
statusMUST be present and one of"pass","partial"or"fail"— never any other value. - Each
noteMUST be non-empty. suggested_changeis optional; omit the key when not used.- Add no top-level or per-criterion key outside this shape — no
verdictshadow field. - Emit exactly one JSON value — no stray second object and no trailing token after the first JSON value.
- When
complete: false, fillreasonwith a non-null one-line summary naming which criteria gated rejection. - Each
diff_filesentry MUST appear ingit diff --name-only <base>..HEAD.
Example — rejection path
Any non-pass criterion forces complete: false:
{
"complete": false,
"reason": "criterion 12 partial: scalability untested at the named 500-tick threshold",
"criteria": [
{"index": 1, "status": "pass", "note": "tick-timeline-utils.ts:12 implements unique-tick mapping over the cell range", "diff_files": ["src/lib/tick-timeline-utils.ts"]},
{"index": 12, "status": "partial", "note": "Tested at ~87 ticks / 12 out-of-tick only. 500-tick fixture does not exist; virtualization not implemented.", "suggested_change": "Add testdata/500-ticks.json fixture and assert virtualization activation at >50 entries.", "diff_files": ["src/lib/tick-timeline-utils.ts", "src/components/TickTimelineStrip.svelte"]}
]
}Anti-Patterns
- Adding criteria the bead does not name. If the author did not write "keyboard shortcut to reset filters," the absence of that shortcut is not a finding.
- Judging code quality. Leave style, readability, architecture to
/review. This skill judges coverage of promises, not code health. - "Probably pass." If you cannot validate the
file:lineclaim by opening the file, the status ispartialorfail— notpasswith a caveat. - Marking
complete: truewith mixed-status criteria. This is the original 3-iteration halt incident's failure mode. Strict mode requires every criterion atpass; onepartialorfailmeanscomplete: false. - Inventing a fourth status. The enum is closed:
pass | partial | fail. Never write any other value. - Rubber-stamping the evidence comment. The evidence comment is the author's claim. Your job is to validate, not quote it back.
- Empirical-vs-algorithmic laundering. If the criterion names a concrete threshold (latency, count, scale), evidence needs that concrete number. Algorithmic reasoning is
partialat best. - Wrapping output in code fences or prose. The output is raw JSON, one object and nothing else. Markdown decoration makes it something other than the
report.jsonshape.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

