---
name: audit-dev-tests
description: Audit acceptance-test coverage of BA Acceptance Criteria (DEV-TEST-001..003, BLOCKING) plus advisory test-convention anti-patterns (DEV-TEST-004..007, warn). Deterministic, runs after /ba-develop Phase 4 (Acceptance Tests).
group: D
phase: devTests
kind: audit
audit_only: true
section_label: 'AUDIT-DEV-TESTS (rules to apply against generated AC tests vs the BA use-case.md ACs)'
allowed-tools: [Read, Glob, Grep, Bash]  # Bash: CLI invocation
---

# audit-dev-tests — Acceptance Tests Coverage Audit

## Context

You are auditing the output of **Phase 4 of `/ba-develop`** (Acceptance Tests).
Compare the BA-declared Acceptance Criteria (`<UC-code>#AC-NN` pairs in every
`<section>/use-case.md`) against the generated xUnit tests (`[Trait("AC","…")]`
on each `[Fact]`), and ensure:

1. Every BA AC has a generated `[Fact]`.
2. No generated `[Fact]` references a stale (non-existent) BA AC.
3. No `// TODO[AC-` marker remains in the generated test bodies (Phase 4 must
   have filled them all).

This is the **dev-readiness gate for vibecoded code** — it makes the BA
acceptance criteria into a deterministic, executable contract.

## Rules

### DEV-TEST-001 — Every BA AC has a generated [Fact]
For every `<UC-code>#AC-NN` declared in any `<moduleDir>/<section>/use-case.md`
(under the UC's `**Acceptance Criteria**` field), the generated test code
under `<projectPath>/Tests/**/*.cs` contains a `[Fact]` carrying
`[Trait("AC", "<UC-code>#AC-NN")]`. A missing trait means an AC has no test —
the BA contract is not enforceable.

- **Severity**: **err** (BLOCKING).
- **Fix**: re-run `/ba-develop` Phase 4, or invoke
  `scaffold-tests-from-ac --spec '{"moduleDir":...,"projectPath":...,"appCode":...,"module":...}'`
  manually, then commit.

### DEV-TEST-002 — No `// TODO[AC-` marker remains
Every generated AC test file MUST have its body filled — no
`// TODO[AC-NN]:` marker may remain. The presence of even one means Phase 4's
TODO-filling pass was incomplete or skipped, leaving an `Assert.Fail(...)`
sentinel that does NOT actually assert the AC.

- **Severity**: **err** (BLOCKING).
- **Fix**: re-run Phase 4's TODO-filling subagent for the listed files, or
  edit the offending test bodies by hand using the AC text in the file comment.

### DEV-TEST-003 — Every test [Trait("AC",…)] resolves to a real BA AC
The reverse direction of DEV-TEST-001: every `[Trait("AC", "<ref>")]` in
generated code MUST point at a `<UC-code>#AC-NN` pair that still exists in
the BA. Catches stale tests left over after an AC was deleted upstream.

- **Severity**: **warn**.
- **Fix**: delete the orphan `[Fact]` or restore the BA AC (re-run
  `/ba-create-use-case`).

### DEV-TEST-004..007 — Test-convention anti-patterns (advisory)

Distilled from the SmartStack.app `test-conventions` corpus. These are **`warn`
only — they never block the gate** (consistent with keeping the vibecoding flow
unobstructed); the generators are already corrected so freshly-scaffolded tests
never trip them. They catch hand-written drift across `Tests/**/*.cs` and
`tests/**/*.test.{ts,tsx}`.

| Rule | Flags | Use instead |
|------|-------|-------------|
| **DEV-TEST-004** | `Assert.True(true)` / `expect(true).toBe(true)` (stub) | A real assertion that exercises the behaviour. |
| **DEV-TEST-005** | a DateTime compared with `BeGreaterThan` / `BeLessThan` | `BeOnOrAfter` / `BeBefore` / `BeCloseTo(…, TimeSpan.FromSeconds(n))`. |
| **DEV-TEST-006** | a hardcoded GUID literal (`new Guid("…")` / `Guid.Parse("…")`) | `Guid.NewGuid()` (anti-enumeration; no cross-test coupling). |
| **DEV-TEST-007** | `CancellationToken.None` in a test | `TestContext.Current.CancellationToken` (xUnit v3). |

- **Severity**: **warn** (advisory — does not affect exit code).
- **Fix**: edit the listed files per the “use instead” column.

## Invocation

```bash
npx --prefer-offline tsx skills/development/audit-dev-tests/cli/audit-dev-tests/index.ts \
  --spec '{"moduleDir":".smartstack/ba/CRM/PIPELINE","projectPath":"./generated/crm"}' \
  --json
```

The CLI returns an `AuditReport` with `findings[]` (severity + rule code + the
offending IDs + fix suggestion). Exit code is non-zero on `err`.

## Notes

- Parser reuse: this skill imports `parseAcFromUseCaseMd` from
  `templates/skills/development/testing/cli/scaffold-tests-from-ac/parse-ac.ts`
  (same canonical AC grammar — see `business-analyse/_workflow/doc-templates.md`).
- Globs `Tests/**/*.cs` (not only `Tests/**/Acceptance/*.cs`) to also flag tests
  written manually under other folders that carry `[Trait("AC",...)]`.
- This audit is **read-only** — no `Edit`, no `Write`, no test re-generation.
  Findings route back to `/ba-develop` Phase 4 (or `scaffold-tests-from-ac`
  directly) for remediation.
