Skip to content
Agentmart
Submit a tool

approve-spec

User-only gate from spec to TDD.

Skill by MarcinSufa

IndexedMIT★ 1
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/marcinsufa-approve-spec

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

User-only gate from spec to TDD. Uses AskUserQuestion interactive primitive (cannot be fabricated by agent) to capture explicit user approval, then writes `approvedAt` + `approvedBy` to the claim file and flips sub-status to `implementing`. The PreToolUse hook (`enforce-spec-gate.sh`) then unblocks Write/Edit outside `specs/`. Use when - "approve the spec", "give green light to TDD", "spec is good, proceed".

Use cases: testing, writing, 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/approve-spec

What's inside

Skill name
approve-spec
Description
User-only gate from spec to TDD. Uses AskUserQuestion interactive primitive (cannot be fabricated by agent) to capture explicit user approval, then writes `approvedAt` + `approvedBy` to the claim file and flips sub-status to `implementing`. The PreToolUse hook (`enforce-spec-gate.sh`) then unblocks Write/Edit outside `specs/`. Use when - "approve the spec", "give green light to TDD", "spec is good, proceed".
License
MIT
Instructions
92 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

# /pr-autopilot:approve-spec

The hard gate between spec lifecycle and code lifecycle. **Must be invoked by user**, not autonomously by agent. The approval fields (`approvedAt`, `approvedBy`, `approvalContext`) are written only by `${CLAUDE_SKILL_DIR}/scripts/approve-claim.sh`, which the **user runs in their own terminal** (it reads a typed confirmation from `/dev/tty`; the agent's Bash tool has no terminal). The PreToolUse hook `enforce-spec-gate.sh` denies agent Write/Edit/Bash calls that change those fields or run that script. It is NOT cryptographic — see the hook header for what remains bypassable.

Full algorithm + gate strength analysis: `docs/superpowers/specs/2026-05-28-pr-autopilot-v0.5-pre-pr-lifecycle-design.md` (v2.2 §`/approve-spec` + §`enforce-spec-gate.sh`).

## Pre-flight

- Inside a worktree with `.claude/assignment-claims/<id>.json` present.
- `subStatus == spec_review_complete` (P0-6 fix — must have reviewed first; EVAL 44 covers attempting approve without review).

## Steps

1. **Read claim file.** Verify `subStatus == spec_review_complete`. Reject otherwise:
   - If `spec_drafting` or `spec_review_requested` → "Spec hasn't completed review. Run `/pr-autopilot:review-spec` first."
   - If `spec_revising` → "Spec has open P0 findings. Address them, re-run `/review-spec`, then come back."
   - If `implementing` or later → "Already approved. Nothing to do."

2. **AskUserQuestion (MANDATORY — lets the user choose approve / show / reject):**

   Generate the question with:
   - **Question:** `"Approve spec for assignment '<id>'? This unlocks Write/Edit across the entire codebase for this branch."`
   - **Header:** `"Approve spec"`
   - **Options (single-select):**
     - `"✅ Approve — unlock TDD"` with description listing aggregated review summary: `"Reviewers: <list>. Findings: 0 P0, <M> P1, <K> P2. Spec: <path>"`
     - `"🔵 Show full spec first"` with description: `"Print the spec content to chat for review, then re-run /approve-spec."`
     - `"❌ Reject — back to spec_revising"` with description: `"Sub-status flips to spec_revising. Agent will need to address concerns and re-run /review-spec."`

3. **Branch on user response:**

   **If user picked "Show full spec":** print spec file content to chat, exit (do NOT mutate state). User re-runs `/approve-spec` when ready.

   **If user picked "Reject":** update the claim file `subStatus: spec_revising` with the Edit tool (the spec gate denies Bash writes into `.claude/assignment-claims/`), then commit:
   ```bash
   git add .claude/assignment-claims/<id>.json
   git commit -m "chore(pr-autopilot): user rejected spec for <id> — back to spec_revising"
   ```
   Echo: "Spec rejected by user. Address concerns and re-run `/pr-autopilot:review-spec` then `/approve-spec`."

   **If user picked "Approve":** do NOT edit the claim file yourself (the hook will deny it). Print this for the user and stop until they confirm it ran:
   ```
   Run this in your own terminal, inside the worktree (it asks you to type the id):
     bash "${CLAUDE_SKILL_DIR}/scripts/approve-claim.sh" <id>
   ```
   The script checks `subStatus == spec_review_complete`, asks for the id on `/dev/tty`, then writes and commits:
   ```json
   {
     "subStatus": "implementing",
     "approvedAt": "<iso>",
     "approvedBy": "<git config user.email, else $USER>",
     "approvalContext": {
       "findings": { "p0": 0, "p1": <M>, "p2": <K> },
       "specFile": "<path>",
       "iterationAtApproval": <reviewIteration>
     }
   }
   ```
   Commit message: `chore(pr-autopilot): approve spec for <id> by <user-id>`.
   When the user says it ran, re-read the claim file and confirm `approvedAt` is set before continuing.

4. **Mirror to ExoVault**: `mcp__exo-vault__update_task(taskId, status='in_progress')` (status doesn't change; description markdown gets new approval entry).

5. **Echo to agent:**
   ```
   ✅ Spec APPROVED by <user-id> at <iso> (read back from the claim file).

   Sub-status: implementing
   Hard gate: LIFTED — PreToolUse hook will allow Write/Edit outside specs/.

   Next steps:
   1. TDD red → green → refactor (follow the project's own CLAUDE.md / contributing rules)
   2. When PR opens via `gh pr create`, run `/pr-autopilot:pr-opened <PR#>` to hand off to v0.4 step loop
   3. After PR merges, run `/pr-autopilot:finish <id>` to close the lifecycle
   ```

## Why this is the gate

Three layers of defense (per spec §"Gate strength"):

1. **User-only invocation**: `disable-model-invocation: true` keeps the model from starting this skill, and the approval write happens in `approve-claim.sh`, which needs a real terminal and a typed confirmation.
2. **Claim file integrity**: the hook denies agent changes to `approvedAt` / `approvedBy` / `approvalContext`, denies flipping `subStatus` to a coding state without `approvedAt`, and blocks all writes if a claim says `implementing` with `approvedAt: null`.
3. **Audit trail**: every transition is a git commit on the worktree branch. Any tampering is permanently logged.

This is **strong**, not bulletproof: an agent determined to bypass it can still write files through an interpreter, delete the claim file, or create the pause sentinel (full list in `hooks/enforce-spec-gate.sh`). Bulletproof would require cryptographic signing (overkill for v0.5).

## Idempotency

Re-running after approval (`subStatus: implementing` already set):
- Print current approval metadata (who, when).
- No-op. Do not re-trigger AskUserQuestion (would be confusing).

From MarcinSufa/claude-pr-autopilot, MIT.

Signals

Stars
1
Forks
0
Open issues
0
Last commit (this folder)
May 28, 2026 (5 months ago)
Last release
May 28, 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 MarcinSufa

Cite this page

approve-spec skill. Agent Mart. https://agentmart.dev/skills/marcinsufa-approve-spec (last updated 2026-10-24)