Skip to content
Agentmart
Submit a tool

ac

Verify acceptance criteria for a task.

Skill by tbeack

IndexedMIT★ 8
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/tbeack-ac

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Verify acceptance criteria for a task. Reads the task's detail file, fans every unchecked AC out to an independent verifier subagent, adversarially refutes each PASS before marking it, and inserts a "All criteria verified" timestamp when all pass. Use when you want to run or re-run ACs independently of task execution — e.g. after implementation, in a follow-up session, or to get an honest mid-task progress check.

Use cases: productivity, agent-building

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/ac

What's inside

Skill name
ac
Description
Verify acceptance criteria for a task. Reads the task's detail file, fans every unchecked AC out to an independent verifier subagent, adversarially refutes each PASS before marking it, and inserts a "All criteria verified" timestamp when all pass. Use when you want to run or re-run ACs independently of task execution — e.g. after implementation, in a follow-up session, or to get an honest mid-task progress check.
License
MIT
Instructions
279 lines in SKILL.md · view on GitHub

Agent Skills spec issues

  • name: missing

Files (1)

  • SKILL.md

SKILL.md (first lines)

# fsad-harness:ac — acceptance criteria verifier

Fan every unchecked AC in a task file out to an independent verifier subagent, adversarially refute each claimed PASS before marking it, and let only the orchestrator edit the task file.

## Asking the user

This rule covers every question this skill asks the user: a confirmation, a choice, a missing value, a numbered decision list, or a stop-and-ask. It applies even where a later step says "ask the user" or "ask exactly once". The user may watch the decisions pane rather than the chat, so a question that only goes to chat can go unanswered.

- **When `mcp__decision-tracker__decision` is in your tool list** (loaded, or named as a deferred tool; load a deferred one with `ToolSearch` first), log each question before you ask it:
  1. Call it with `action: "open"`, the question (ending in `?`), and `options` when the answers are a closed set. Set `required: false` when the work can go on without an answer. A numbered list of questions opens one decision per item. Keep each returned `id`.
  2. Ask the question in chat as this skill says. The open call does not replace the chat question.
  3. When the user answers, in chat or as a `Decision Dn: <answer>` message from the plugin, call the tool with `action: "close"`, the `id` and the answer.
  4. When the change the answer asked for is in place, call it with `action: "implement"`, the `id` and a `path:line`.
- **When the tool is absent**, ask in chat only.
- An `AskUserQuestion` call is logged on its own. Do not open it again.
- This rule changes where a question is logged. It does not change when this skill asks, or how many times.

## Definitions used throughout

### `VERIFIER_TOOLS` — the read-only tool allowlist

```
VERIFIER_TOOLS = Read, Grep, Glob, Bash (read-only commands only)
```

- **Read-only `Bash`** means commands that inspect and never mutate: `grep`, `ls`, `cat`, `head`, `sed -n`, `wc`, `diff`, `cmp`, `git diff`, `git log`, `git show`, `git status`. Never `rm`, `git reset`, `git checkout`, `git stash`, `git clean`, package installs, or build/dist scripts.
- **Never granted:** `Edit`, `Write`, `MultiEdit`, `NotebookEdit`. No verifier or refuter subagent may receive these under any circumstances.
- **Enforcement is the Agent call, not the prompt.** Every verifier `Agent` call in Step 4 and every refuter `Agent` call in Step 5 must pass the allowlist explicitly — `tools: VERIFIER_TOOLS` (or, when the `Agent` tool takes a `subagent_type` instead of a `tools:` field, a read-only agent type such as `Explore` whose tool set is a subset of `VERIFIER_TOOLS`). A prompt sentence saying "read-only" is advisory; the allowlist is what prevents a verifier from editing the task file or reverting a build.

### `trivial` — the trivial-change predicate

```
trivial = (files_changed ≤ 1) AND (lines_changed ≤ 10) AND non-behavioural
```

- `files_changed` / `lines_changed`: from `git diff --stat` of the change under verification (the working tree or worktree branch against its base), scoped to the files the task file names. `lines_changed` = insertions + deletions.
- `non-behavioural`: the diff touches only a docstring, comment, label, or copy text — no code path, config value, data, or build output changes.
- If the diff cannot be determined, or any AC needs runtime/browser evidence, the change is **not** trivial.
- `fsad-harness:do-task` Step 5e (TBS-086) mirrors this predicate, and the `ENUM` block below, by name and thresholds; keep all three definitions identical.

### `ENUM` — the optional per-AC enumeration block

<!-- ENUM:begin -->
**`ENUM`** — the optional per-AC self-healing enumeration block. An AC may declare a deterministic, read-only enumeration command as an indented child bullet immediately beneath its `- [ ]` line:

```markdown
- [ ] <criterion text, unchanged>
  - enumerate: `<ENUM_CMD>`
```

Declaration syntax:
1. The child bullet is the very next non-blank line after the AC item, indented by at least two spaces, and begins `- enumerate:`. At most one per AC. Anything else beneath the item is ignored by the parser.
2. `ENUM_CMD` is one inline-code span on the line. Multi-line logic lives in a version-controlled script the command calls (e.g. `` `bash scripts/ac/no-cli-phrase.sh` ``).
3. `ENUM_CMD` runs from `$ROOT`, prints one line per violation on stdout (`path:line:text` recommended), and prints nothing when there are no violations, using grep exit-code semantics: `0`/`1` are normal, `≥2` is an error. The command is responsible for exiting `≥2` when its target does not exist; the canonical pattern is a leading guard, `test -d <dir> || exit 2;` (or `test -f <file> || exit 2;`), because `grep --include` on a missing directory exits `1` silently on macOS.
4. `ENUM_CMD` must be read-only in the `VERIFIER_TOOLS` sense — the orchestrator refuses to run a command matching a forbidden form (`rm`, `git reset`, `git checkout`, `git stash`, `git clean`, package installs, or redirection into the tree) and treats it as `enum.status = error` rather than running it.

The canonical runner. Bash tool shell state does not persist between separate tool calls, so a shell function declared in one call is gone in the next; the orchestrator therefore writes this runner once per run to a script file (e.g. `${TMPDIR:-/tmp}/enum_gate.sh`) via the `Write` tool before its first use, then invokes it by path in every call — never as an inline function re-declared per call:

```bash
#!/usr/bin/env bash
# enum_gate.sh — usage: bash enum_gate.sh '<ENUM_CMD>'
# invoked as: (cd "$ROOT" && bash "$SCRIPT_PATH" '<ENUM_CMD>')
out=$(bash -c "set -o pipefail; $1" 2>"${TMPDIR:-/tmp}/enum.err"); rc=$?
err=$(cat "${TMPDIR:-/tmp}/enum.err")
if [ "$rc" -ge 2 ]; then
  printf 'ENUM_ERROR rc=%s\n%s\n' "$rc" "$err"
  exit 2
fi
n=$(printf '%s\n' "$out" | grep -c .)
printf '%s\n' "$out"; printf 'ENUM_COUNT %s\n' "$n"
[ "$n" -eq 0 ]
```

`set -o pipefail` inside the inner `bash -c` subshell means a piped `ENUM_CMD` (e.g. `rg … | sort`) now surfaces an earlier stage's failure — a missing tool, `command not found` — as the subshell's own exit code, so the `rc -ge 2` guard catches it and reports `ENUM_ERROR` instead of silently scoring zero violations.

The gate predicate is `converged ⇔ enum_gate exits 0 ∧ survivors_after_spot_check = ∅`, where a "survivor" is a location the blind refuter (below) still stands behind after the orchestrator spot-checks its claim:

| `enum_gate` exit | blind refuter | outcome |
|---|---|---|
| 0 | no survivors | `PASS` (eligible for checkbox flip) |
| 0 | survivor(s) stand spot-check | `FAIL`, `root_cause = enumeration_undercovers` |
| 1 | anything | `FAIL` — the subagent's view is recorded but cannot change the verdict |
| 2 | not consulted | `UNCLEAR`, `enum.status = error`, stop-and-ask |

**Ownership.** A `- enumerate:` declaration is authored and edited by a human only — a verifier, refuter, or repair agent never authors or edits a declaration line; an agent that identifies a need for one proposes it in prose for a human to add.
<!-- ENUM:end -->
`$ROOT` is the working tree — the same tree `trivial`'s `git diff --stat` is computed against.

## Step 0 — Detect the project

1. Determine the current working directory.
2. Read `${CLAUDE_PLUGIN_ROOT}/skills/add-task/add-task-projects.yaml`.
3. Match cwd against each project's `match_paths` (expand `~`). Prefer the longest match if multiple match.
4. If a project matches, use its entry as `cfg` and resolve `project_root`. Proceed.
5. If **no project matches** in `add-task-projects.yaml`:
   - Tell the user: "This directory isn't registered. Run `/fsad-harness:add-task` from the project to register it."
   - Stop.

## Step 1 — Resolve the task identifier

Normalize `$ARGUMENTS` to canonical form `PREFIX-NNN`:

- Prefix: `cfg.prefix` (exact casing — e.g. `TBS`, `CBP`, `FSD_Train`).
- Number: zero-padded to `cfg.number_digits` digits.
- If `$ARGUMENTS` is empty, ask: "Which `[cfg.prefix]` task? (e.g. `[cfg.prefix]-001`)"

## Step 2 — Locate the task file

Resolve the path using the same rules as `do-task`:

- `{nnn}` = zero-padded number
- `{prefix_lower}` = `cfg.prefix_in_filename` if set, else `cfg.prefix` lowercased
- `{ID}` = canonical identifier

```
{project_root}/{cfg.task_dir}/{rendered cfg.task_filename_template}
```

- **File not found**: Tell the user the task file doesn't exist. Suggest running `/fsad-harness:do-task {ID}` to create it first. Stop.

From tbeack/fsad_playbook, MIT.

More from tbeack/fsad_playbook

Signals

Stars
8
Forks
4
Open issues
0
Last commit (this folder)
Oct 7, 2026 (21 days ago)
Last release
May 18, 2026 (5 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from tbeack

Cite this page

ac skill. Agent Mart. https://agentmart.dev/skills/tbeack-ac (last updated 2026-10-24)