| name | sg-tdd |
| description | Use this when execute is complete and TDD verification is required โ invokes superpowers:test-driven-development and appends a tdd stage row to HANDOFF.md. |
| argument-hint | [phase] - optional. Defaults to STATE.md current phase |
Detect the user's input language and respond in that language throughout this skill's output.
- Korean input โ respond in Korean
- English input โ respond in English
- Mixed input โ match the dominant language
When tdd_mode is enabled, verify that the current phase implementation complies with TDD discipline by invoking the Superpowers test-driven-development skill, then record a tdd stage row in HANDOFF.md. Per the Non-invasive constraint (D-07), no Superpowers or GSD internal files are modified.
## Platform Constraints (Codex / Gemini CLI / Antigravity CLI)
- SubagentStop not supported: no automatic trigger on stage completion. Run $sg-review manually after completion.
- AskUserQuestion not supported: failure path is presented as a plain text numbered list. Read user reply and proceed accordingly.
- Use $sg-tdd / $sg-review / $sg-execute (agent-style commands). Claude Code slash-command format is not supported.
<execution_context>
This command is self-contained โ no external workflow files imported. Reads .planning/config.json, .planning/STATE.md, .planning/ROADMAP.md, .planning/HANDOFF.md.
</execution_context>
1. **tdd_mode ํ๋๊ทธ ํ์ธ (D-02, per D-03).**
config.json์์ tdd_mode๋ฅผ ์ฝ๋๋ค. macOS ํธํ, jq/python3 ๋ฏธ์ฌ์ฉ:
```bash
TDD_MODE=$(node -e "try{const c=require('./.planning/config.json');console.log(c.super_gsd&&c.super_gsd.tdd_mode?'true':'false')}catch(e){console.log('false')}" 2>/dev/null || echo "false")
if [ "$TDD_MODE" != "true" ]; then
echo "tdd_mode is not enabled. To activate: set super_gsd.tdd_mode: true in .planning/config.json. Recommended: re-run sg-execute first."
fi
```
tdd_mode๊ฐ "true"๊ฐ ์๋์ด๋ ๊ณ์ ์งํํ๋ค (๋ธ๋ก ์์, per D-02).
-
Phase resolve.
ARGUMENTS๊ฐ ๋น์ด์์ง ์์ผ๋ฉด PHASE_NUM=$ARGUMENTS. ์๋๋ฉด Read .planning/STATE.md์์ YAML frontmatter์ Phase: ๊ฐ์ ์ถ์ถํ์ฌ PHASE_NUM์ผ๋ก ์ค์ ํ๋ค.
if [ -n "$ARGUMENTS" ]; then
PHASE_NUM="$ARGUMENTS"
else
Read .planning/STATE.md, then extract the Phase: value from the YAML frontmatter. Set PHASE_NUM to the extracted value.
fi
if [ -z "$PHASE_NUM" ]; then
echo "Could not resolve current phase. Pass phase number explicitly: $sg-tdd <phase>"
exit 1
fi
-
Phase directory ํ์ธ.
PHASE_PAD=$(printf "%02d" "$PHASE_NUM" 2>/dev/null || echo "$PHASE_NUM")
PHASE_DIR=$(ls -d .planning/phases/${PHASE_PAD}-* 2>/dev/null | head -1)
if [ -z "$PHASE_DIR" ]; then
PHASE_DIR=$(ls -d .planning/phases/${PHASE_NUM}-* 2>/dev/null | head -1)
fi
if [ -z "$PHASE_DIR" ]; then
echo "No phase directory matches '${PHASE_NUM}' under .planning/phases/. Run $sg-plan first."
exit 1
fi
-
Phase meta ์ฝ๊ธฐ.
Read .planning/ROADMAP.md์์ ### Phase PHASE_NUM: ์น์
์ PHASE_NAME, GOAL, SC_TEXT๋ฅผ ์ถ์ถํ๋ค.
Read .planning/ROADMAP.md, then:
- Find the ### Phase <PHASE_NUM>: section header (try both unpadded and zero-padded two-digit PHASE_PAD forms); extract PHASE_NAME (text after "Phase N: " on that line).
- Extract the **Goal**: line value immediately following the header. Set GOAL.
- Extract numbered items under **Success Criteria** until the next ** section. Set SC_TEXT.
If no matching header is found, print: "No '### Phase <PHASE_NUM>:' header found in .planning/ROADMAP.md. Aborting." and exit.
-
HANDOFF.md ์๋ ์ด๊ธฐํ.
HANDOFF_FILE=".planning/HANDOFF.md"
if [ ! -f "$HANDOFF_FILE" ] || ! grep -q "Timestamp.*Phase.*From.*To.*Plan Hash" "$HANDOFF_FILE" 2>/dev/null; then
mkdir -p "$(dirname "$HANDOFF_FILE")"
printf '| Timestamp | Phase | From | To | Plan Hash | User |\n| --- | --- | --- | --- | --- | --- |\n' > "$HANDOFF_FILE"
fi
-
HANDOFF.md์ tdd ํ append (Skill() ํธ์ถ ์ ).
From ์ปฌ๋ผ์ HANDOFF.md ๋ง์ง๋ง ํ์ To ๊ฐ(์ด์ stage์ ๋ชฉ์ ์ง = ํ์ฌ ํ์ ์ถ๋ฐ์ง)์ ์ฝ์ด ์ค์ ํ๋ค (์ฌ์๋ ์ From=tdd ๋ฐฉ์ง).
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
PHASE_SLUG=$(basename "$PHASE_DIR")
GIT_USER=$(git config user.name 2>/dev/null || echo "-")
[ -z "$GIT_USER" ] && GIT_USER="-"
LAST_ROW=$(grep -E '^\| [0-9]{4}-' .planning/HANDOFF.md 2>/dev/null | tail -1)
if [ -n "$LAST_ROW" ]; then
FROM_STAGE=$(echo "$LAST_ROW" | awk -F'|' '{gsub(/ /,"",$5); print $5}')
fi
[ -z "$FROM_STAGE" ] && FROM_STAGE="execute"
echo "| $TS | $PHASE_SLUG | $FROM_STAGE | tdd | - | $GIT_USER |" >> .planning/HANDOFF.md
-
ํ๋กฌํํธ ๋น๋ + TDD ๊ฒ์ฆ ์๋ฃ ์ ํธ ์ถ๋ ฅ + Skill() ํธ์ถ (D-06, D-07).
Superpowers์ ์ ๋ฌํ ์ปจํ
์คํธ blob์ ์๋ ํ์์ผ๋ก ์กฐ๋ฆฝํ๋ค:
# TDD Verification โ Phase <N> (<PHASE_NAME>)
## Goal
<GOAL>
## Success Criteria
<SC_TEXT>
## Instruction
Verify TDD compliance for the implementation above using superpowers:test-driven-development.
Check that: (1) tests were written before or alongside implementation, (2) all tests pass, (3) no production code exists without a corresponding test.
If TDD verification finds issues, surface them and ask the user: proceed to $sg-review or retry.
์ปจํ
์คํธ blob ์ถ๋ ฅ ํ ๋ฐ๋์ ์๋ ์ ํํ ๋ฌธ์์ด์ ์ถ๋ ฅํ๋ค (D-06 transcript ์ ํธ):
echo "TDD verification complete"
๊ทธ ๋ค์ Skill() ํธ์ถ โ ์ดํ ์ด๋ค ์ฝ๋๋ ์คํํ์ง ์๋๋ค (Terminal Skill pattern):
Skill(skill="superpowers:test-driven-development", args="<the context blob above>")
TDD ๊ฒ์ฆ ์คํจ ์ฒ๋ฆฌ (D-01) โ Superpowers ์คํฌ์ด ์คํจ๋ฅผ ๋ณด๊ณ ํ ๋ sg-tdd ์คํฌ ๋ด๋ถ์์ ์ฒ๋ฆฌ:
Superpowers ์คํฌ ์๋ฃ ํ ์คํจ ์ ํธ๊ฐ ๊ฐ์ง๋๋ฉด plain text๋ก ๋ค์์ ์ถ๋ ฅํ๊ณ ์ฌ์ฉ์ ์๋ต์ ๊ธฐ๋ค๋ฆฐ๋ค:
TDD verification found issues. How do you want to proceed?
1. Proceed to $sg-review
2. Retry TDD verification
(Read user reply and proceed: "1" โ continue to $sg-review, "2" โ re-run verification)
<success_criteria>
- tdd_mode: false ๋๋ ๋ฏธ์ค์ ์ํ์์ ํธ์ถํ๋ฉด ๊ฒฝ๊ณ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๊ณ ๊ณ์ ์งํํ๋ค (๋ธ๋ก ์์).
- tdd_mode: true ์ํ์์ ํธ์ถํ๋ฉด Superpowers test-driven-development ์คํฌ์ ์ ํํ ํ ๋ฒ ํธ์ถํ๋ค.
- Skill() ํธ์ถ ์ ์ HANDOFF.md์ tdd stage ํ์ด ๊ธฐ๋ก๋๋ค (From=dynamic, To=tdd, Plan Hash=-).
- Skill() ํธ์ถ ์ง์ ์ "TDD verification complete" ๋ฌธ์์ด์ด ์ถ๋ ฅ๋๋ค.
- TDD ๊ฒ์ฆ ์คํจ ์ plain text numbered list๋ก ์ํํธ ๊ฒฝ๊ณ + proceed/retry ์ ํ์ง๋ฅผ ์ ๊ณตํ๋ค (AskUserQuestion ๋ฏธ์ฌ์ฉ).
</success_criteria>