Skip to content
Agentmart
Submit a tool

tdd-parallel

Full-auto PRD pipeline.

Skill by ZunoSmartLabs

IndexedMIT★ 2
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/zunosmartlabs-tdd-parallel

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

Full-auto PRD pipeline. Fans out the unblocked [AFK] sub-tasks of a parent PRD into parallel /tdd sub-agents, integrates them onto the PRD branch, auto-chains /verify-coverage to prove every user story has a passing non-vacuous test, auto-fixes any gaps (loop), then opens a single integration PR. Runs partially when an open [HITL] slice exists — fans out every slice whose blocker closure is HITL-free, defers the rest, and opens a [partial] PR that leaves the PRD open. Refuses only if no slice is runnable or an in-scope user story isn't expressible as an automatable test. PR-style repos only.

Use cases: backend, testing, data

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
Runs as
Shell scripts

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/tdd-parallel

What's inside

Skill name
tdd-parallel
Description
Full-auto PRD pipeline. Fans out the unblocked [AFK] sub-tasks of a parent PRD into parallel /tdd sub-agents, integrates them onto the PRD branch, auto-chains /verify-coverage to prove every user story has a passing non-vacuous test, auto-fixes any gaps (loop), then opens a single integration PR. Runs partially when an open [HITL] slice exists — fans out every slice whose blocker closure is HITL-free, defers the rest, and opens a [partial] PR that leaves the PRD open. Refuses only if no slice is runnable or an in-scope user story isn't expressible as an automatable test. PR-style repos only.
License
MIT
Instructions
562 lines in SKILL.md · view on GitHub

Before installing

  • Ships executable scripts

Agent Skills spec issues

  • body: 562 lines (spec recommends under 500)

Files (3)

  • SKILL.md
  • test_preflight.sh · scripts/tests/
  • zsl-preflight.sh · scripts/

SKILL.md (first lines)

# Parallel TDD

Full-auto pipeline from a PRD to a pushed integration PR: fanout → integrate → review → verify → fix → push, with no mid-run human gates in the happy path. Each `/tdd` sub-agent runs `/tdd <num> --no-ship` in its own worktree, committing locally but never pushing. The orchestrator merges every slice branch onto the parent's PRD branch (which doubles as the integration branch) in wave order with `--no-ff`, runs an integration code review, then chains `/verify-coverage --auto` and loops on any gaps it files before opening one consolidated PR.

`[HITL]` slices don't block the whole run — they're *deferred*. The pre-flight runs every slice whose transitive `Blocked by` closure is HITL-free and defers each open `[HITL]` slice plus everything transitively downstream of it. When anything is deferred, the run is **partial**: it ships the runnable slices in a `[partial]` PR that leaves the parent PRD *open*, with a re-entry recipe for landing the remainder after the gate clears via `/human-itl`. A PRD with no open `[HITL]` slices behaves exactly as a full run — closes the parent, no `[partial]` marker. The pre-flight still refuses any PRD whose *in-scope* user stories lack an `AC<n>:` acceptance criterion (per `/to-prd`'s story format), and refuses outright only when no slice is runnable at all. Once `/tdd-parallel` starts, it runs through to PR-push or a circuit-breaker halt.

PR-style repos only — direct-push fanouts merge straight to `main` without consolidation.

## Why partial runs are safe

The old blanket pre-flight refusal — *no open `[HITL]` sub-issues anywhere* — is stronger than the invariant it protects. The real invariant is **no human gate fires *after* invocation**: once the auto-loop starts, nothing should stop to wait on a human. That invariant is preserved by a weaker, graph-aware rule:

> Run only slices whose transitive `Blocked by` closure contains no open `[HITL]` slice. Defer every open `[HITL]` slice and everything transitively downstream of it.

Because every selected slice's *entire* blocker closure is HITL-free, no selected slice can become human-gated mid-run — the invariant holds just as firmly as under the blanket refusal, but without throwing away the work that doesn't depend on the gate. The deferred slices simply wait for a later run, after the gate clears via `/human-itl`. This carve is always on: there is no flag, and a PRD with zero open `[HITL]` slices is byte-for-byte the old behaviour (full fanout, closes the parent).

## Why one PR

Each push to a feature branch triggers CI workflows. With N sub-issues = N PRs you'd pay N × M CI runs over the life of a fanout. Staging slice work locally and pushing one consolidated branch costs one CI run. Trade-offs: one PR is a single review surface (no per-slice review granularity), and merge conflicts surface during local integration rather than during PR review. Both are acceptable when the wave model from `/to-issues` asserts same-wave slices are disjoint.

## Usage

```
/tdd-parallel <parent-issue> [--max N] [--max-coverage-rounds R] [--on-review-failure halt|continue]
```

- `<parent-issue>` — the parent (PRD) issue whose unblocked AFK sub-tasks should be fanned out.
- `--max N` — concurrency cap *within a wave*. Default 2.
- `--max-coverage-rounds R` — circuit breaker on the coverage auto-fix loop (step 4b). Default 3. On exhaustion, halts with the residual matrix; the user takes over.
- `--on-review-failure halt|continue` — what to do when step 4a's `/code-review --auto` applies findings but lint/tests fail and the review commit gets reverted. Default `halt` (preserves the interactive contract). `continue` proceeds to step 4c with the pre-review tip — all slices are still green individually, the integration polish just didn't land — and adds a `## ⚠️ Integration review failed` section to the PR body listing the attempted findings. Use `continue` from unattended paths (`/afk-worker`, the overnight per-PRD remote executor); the morning reviewer runs `/code-review` against the PR locally before merge.

Partial runs are **automatic and unconditional — there is no flag.** When the parent has open `[HITL]` slices (or slices still in triage), `/tdd-parallel` fans out everything not gated behind them and opens a `[partial]` PR, deferring the rest. A parent with no open `[HITL]` slices runs fully and closes the parent, exactly as before.

## AFK contract

Sub-agents spawned by this skill operate AFK. They make reasonable decisions and finish — they do **not** return mid-flight to ask routine questions. They escalate (return early with a question) only when they hit:

- A destructive operation that needs confirmation per auto mode rules.
- A missing access or credential they can't proceed without.
- A genuine architectural ambiguity that would change a public contract.

When an agent escalates, the orchestrator relays the question to the user and resumes the agent via `SendMessage` with the user's answer. Anything that routinely needs a manual human action mid-flight isn't AFK and shouldn't be in the fanout — it belongs as an `[HITL]` slice, cleared via `/human-itl`. (Routine *decisions* don't belong as `[HITL]` slices either — they're resolved upstream in `/grill-with-docs` + an ADR so the slice stays AFK.)

## Progress visibility

Sub-agents emit a one-line JSON heartbeat to `.tdd-progress.jsonl` in their worktree at each TDD phase. The orchestrator runs one `Monitor` per wave (with `tail -n +1 -F` over the wave's progress files) and renders a live wave board, so the user sees progress mid-flight rather than waiting for completion. `Monitor`'s stdout-line-per-notification model maps directly to one heartbeat record per notification.

Schema and phase list: see `engineering/tdd/SKILL.md` § Progress heartbeat. The contract is one direction only — agents emit, the orchestrator reads. Heartbeats are **not** an escalation channel: escalations still go through agent return + `SendMessage`. They are advisory; never gate merge logic on them.

## Process

### 1. Pre-flight

Four phases. 1a refuses on failure; 1b cleans up silently and continues; 1c either creates or adopts the PRD branch; 1d validates the parent PRD is auto-loop-eligible.

#### 1a. Environment validation

**Deterministic gate.** The mechanical parts of 1a + 1c (clean tree, HEAD not detached, the three required files exist, `.worktrees/` is gitignored) are scripted — each has one correct boolean answer. Resolve and run the validator; a `FAIL:` line means refuse with that message. It also covers 1c's clean-tree/not-detached checks, so 1c need not re-run them.

```bash
SP=$({ ls "$PWD"/skills/*/tdd-parallel/scripts/zsl-preflight.sh 2>/dev/null
       ls "$HOME/.claude/skills/tdd-parallel/scripts/zsl-preflight.sh" 2>/dev/null
       ls -d "$HOME"/.claude/plugins/cache/zsl-superpowers/zsl/*/skills/*/tdd-parallel/scripts/zsl-preflight.sh 2>/dev/null | sort -Vr; } | head -1)
if [ -n "$SP" ]; then
  bash "$SP" --clean-tree --not-detached \
    --require-file docs/agents/ship-style.md \
    --require-file docs/agents/issue-tracker.md \
    --require-file docs/agents/triage-labels.md \
    --ensure-gitignore-line '.worktrees/'
else
  echo "zsl-gate: zsl-preflight.sh unresolved — run the checks below by hand (Fallback)"
fi
```

Then the **one check the script can't make** — `docs/agents/ship-style.md` must *say PR-style*. That's a read of free-form prose, not a clean boolean, so it stays your call: open the file and refuse if it configures direct-push. Direct-push fanouts are unsupported — they'd land slices on `main` directly without consolidation, defeating the point.

**Fallback** (if `$SP` is empty — the gate didn't resolve): refuse with a clear error message if any of these fail, exactly as the script would:

- `docs/agents/ship-style.md` exists **and** says PR-style.
- `docs/agents/issue-tracker.md` exists.
- `docs/agents/triage-labels.md` exists.
- Working tree is clean (`git status --porcelain` empty) and HEAD is not detached.

Append `.worktrees/` to the repo root `.gitignore` if not already present (the exact line `.worktrees/`, only if absent).

#### 1b. Auto-clean stale slice worktrees and branches

Scan `.worktrees/*`. For each entry whose name matches the configured naming pattern (`<num>-<slug>` for GitHub/GitLab, `<feat>-<slice>-<slug>` for local-markdown — see 3c):

1. Parse the slice identifier from the directory name. GitHub/GitLab: `<num>` is the issue number. Local-markdown: `<feat>` is the feature dir number, `<slice>` is the per-feature slice file number; together they resolve to `.scratch/<feat>-*/issues/<slice>-*.md`.
2. Query the issue tracker for the slice's state.
3. **Skip** if the slice is OPEN — not ours to remove.
4. **Skip** if `git -C .worktrees/<dir> status --porcelain` is non-empty — uncommitted changes; the user should investigate.
5. Otherwise:
   - `git worktree remove .worktrees/<dir>` (no `--force`)
   - `git branch -d tdd/<dir>` (no `-D`) — branch name mirrors the worktree dir name
6. If `git branch -d` refuses because the branch isn't fully merged, **skip and log** — never `-D` automatically.

Print a one-block summary: `cleaned`, `skipped — open`, `skipped — uncommitted`, `skipped — unmerged branch`. Do not refuse on any skip.

#### 1c. Determine the PRD branch

The PRD branch doubles as the integration branch — sub-task branches will be merged onto it, and it gets pushed once at the end as the integration PR's source.

- Run `git fetch origin`.
- The dirty-tree / detached-HEAD refusal is already enforced by 1a's deterministic gate (`--clean-tree --not-detached`); `git fetch` doesn't touch the working tree, so it still holds here. (Fallback, if the gate didn't resolve: refuse if `git status --porcelain` is non-empty or HEAD is detached.)
- **If the orchestrator is on `main`**: create the PRD branch and switch to it.
  - Branch name: `feature/<parent-num>-<slug>`. Slug is kebab-case of the parent issue title, max 40 chars.
  - `git checkout -b feature/<parent-num>-<slug>` from `main`'s tip.
- **If the orchestrator is on a non-`main` branch**: treat it as the PRD branch. Do not switch, do not auto-rebase against `main` — the user owns its relationship to `main`.

After 1c the orchestrator is on the PRD branch with a clean working tree.

#### 1d. Parent PRD readiness

Fetch the parent issue and its sub-issues per `docs/agents/issue-tracker.md`. Refuse with a clear message if this fails:

- **Parent has a `## User Stories` section** — otherwise it isn't a PRD and this skill doesn't apply.

From ZunoSmartLabs/zsl-superpowers, MIT.

More from ZunoSmartLabs/zsl-superpowers

Signals

Stars
2
Forks
0
Open issues
0
Last commit (this folder)
Jun 19, 2026 (4 months ago)
Last release
Sep 18, 2026 (1 month ago)

From GitHub (fetched Oct 24, 2026).

Details

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

More from ZunoSmartLabs

Cite this page

tdd-parallel skill. Agent Mart. https://agentmart.dev/skills/zunosmartlabs-tdd-parallel (last updated 2026-10-24)