| name | build |
| description | Execute ONE executable leaf workstream with TDD, guard enforcement, and ws-verdict output |
| cli | sdp guard activate |
| llm | Spawn subagents for TDD cycle |
| version | 8.2.0 |
| changes | [{"8.2.0":"Add @go-modern guidance for Go implementation and review"},"Evidence + checkpoint commit step after sdp-orchestrate --advance (step 3b)","Post-build bd close for each bead in WS frontmatter; batch syntax /build 00-053-16..25","Remove auto-continue rules; @build does ONE WS then STOPS","Strip evidence boilerplate to orchestrator/CLI","Single subagent strategy (no Option A/B ambiguity)"] |
build
CLI: sdp guard activate <workstream-id> (scope enforcement)
LLM: Execute one executable leaf workstream following TDD discipline
Execute this ONE executable leaf workstream. After commit, STOP.
Continuation is the orchestrator's job (@oneshot / sdp orchestrate).
Batch syntax: /build 00-053-16..25 (or /build 00-053-16 00-053-17 … 00-053-25) — run leaf workstreams sequentially. Stop on first failure. Report: N done, M failed.
CRITICAL RULES
- CHECK EXISTING CODE FIRST — Run
@reality --quick or grep before starting new features. Output existing_work_summary in ws-verdict — required. Short summary: files/functions/risks found before implementation.
- ONE EXECUTABLE LEAF — Execute this workstream only if it is a leaf. If the target is an aggregate/container workstream, STOP and hand control back to
@oneshot or target a child leaf explicitly. After commit, STOP. Do not start the next WS.
- USE SPAWN OR DO IT YOURSELF — If spawn available, use it. If not, implement manually.
- POST-COMPACTION RECOVERY — After context compaction, run
bd ready to find your task. Never drift to side tasks.
- MODERN GO FOR GO CODE — When touched files are Go, load
@go-modern and prefer safe stdlib modernizations before inventing helpers.
Git Safety
CLI: sdp guard activate <ws-id> runs branch validation before build. Use it in setup (step 1). If guard reports wrong branch, STOP.
Manual check (when guard unavailable):
pwd
git branch --show-current
FEATURE_ID=$(grep "^feature_id:" docs/workstreams/backlog/${WS_ID}.md 2>/dev/null | awk '{print $2}')
EXPECTED=$(jq -r .branch .sdp/checkpoints/${FEATURE_ID}.json 2>/dev/null)
CURRENT=$(git branch --show-current)
if [ -n "$EXPECTED" ] && [ "$CURRENT" != "$EXPECTED" ]; then
echo "ERROR: Wrong branch. Expected $EXPECTED, got $CURRENT."
exit 1
fi
NOTE: Features MUST be implemented in feature branches. @oneshot creates the branch; @build only verifies.
Write Plan (F101)
Before the TDD cycle (step 2 of EXECUTE THIS NOW), emit a write plan:
- Enumerate — List every file the skill will CREATE / MODIFY / DELETE with a one-line reason. During the TDD cycle (step 2), enumerate source files, test files, and ws-verdict output.
- Flags:
--dry-run — Emit write plan only. Do NOT create, modify, or delete any file.
--yes — Skip confirmation prompt. Execute immediately. Intended for CI/non-interactive.
- Confirm — Present the plan to the user and wait for explicit approval (unless
--yes).
- Log — Append write plan event to
.sdp/log/events.jsonl (sanitize file paths before logging: strip newlines, ensure valid JSON escaping):
{"spec_version":"v1.0","event_id":"<uuid>","timestamp":"<ISO-8601>","source":{"system":"sdp-lab","component":"build"},"event_type":"decision.made","payload":{"decision_type":"write_plan","plan":[{"path":"...","action":"CREATE|MODIFY|DELETE","reason":"..."}]},"context":{"feature_id":"<F-id>","workstream_id":"<ws-id>"}}
Note: Phase 1 uses prompt-level write boundaries (CLI out of scope). Aligns with sdp/schema/contracts/orchestration-event.schema.json via event_type: "decision.made". Phase 2 CLI will emit natively.
Output format:
WRITE PLAN for @build <ws-id>:
CREATE: path/to/new/file — <reason>
MODIFY: path/to/existing/file — <reason>
DELETE: path/to/removed/file — <reason>
Proceed? [y/n]
Modes:
- No flag: Show plan → Confirm → Execute
--dry-run: Show plan → STOP
--yes: Show plan → Execute immediately (no prompt)
EXECUTE THIS NOW
When user invokes @build 00-067-01:
- Setup:
sdp guard activate 00-067-01
Read the workstream frontmatter before doing real work. If ws_kind exists and
is not leaf, STOP with a clear error: aggregate/container workstreams are not
direct execution targets.
-
TDD cycle (spawn subagents if available, else do yourself):
- Implementer: RED → GREEN → REFACTOR per AC. Orchestrator contract: Emit phase markers so orchestrator can parse:
TDD:RED (writing failing test), TDD:GREEN (test passes), TDD:REFACTOR (cleanup). One marker per phase.
- Spec Reviewer: Verify each AC with evidence
- Quality Reviewer: Coverage >= 80%, LOC <= 200, lint pass
-
Commit and STOP:
sdp guard deactivate
git add .
git commit -m "feat(<feature-id>): <ws-id> - {title}"
3b. Evidence and checkpoint (after sdp-orchestrate --advance when running as part of @oneshot):
git add .sdp/evidence/ .sdp/checkpoints/
git commit --amend --no-edit || git commit -m "<feature-id>: evidence"
- Write ws-verdict (required):
mkdir -p .sdp/ws-verdicts
Required fields: existing_work_summary — one line summary of pre-existing code/tests found before implementation. Output must validate against schema/ws-verdict.schema.json (ws-verdict.schema.json).
Evidence lifecycle (create/patch .sdp/evidence/*.json) is orchestrator or post-build CLI responsibility.
Subagent Tasks (if spawning)
Implementer: TDD per AC. Output verdict + evidence.
Spec Reviewer: Verify code matches spec. Output ac_evidence per ws-verdict.schema.json: {"ac":"AC text","met": true|false,"evidence":"file:line or test name"}.
Quality Reviewer: Coverage >= 80%, LOC <= 200, lint. For Go code, also check modern stdlib usage via @go-modern. Output verdict.
Quality Gates
| Gate | Threshold |
|---|
| Tests | 100% pass |
| Coverage | >= 80% |
| Lint | 0 errors |
| File Size | <= 200 LOC |
Beads Integration
- Before:
bd update {beads_id} --status in_progress
- Leaf-only dispatch: only executable leaf workstreams may carry an open
primary Beads issue.
- Success: Run
bd close {beads_id} --reason "WS completed" for each bound leaf issue in WS frontmatter (for example ## Beads with primary: and finding: roles). Resolve beads from .beads-sdp-mapping.jsonl by sdp_id, or from the WS body.
- Failure:
bd update {beads_id} --status blocked
Few-Shot Examples
Good ws-verdict (all gates green):
{
"ws_id": "<ws-id>",
"feature_id": "<feature-id>",
"verdict": "PASS",
"commit": "a1b2c3d",
"quality_gates": {"tests_pass": true, "lint_clean": true, "coverage_pct": 85.2, "coverage_threshold": 80, "max_file_loc": 142, "build_ok": true, "vet_ok": true},
"ac_evidence": [
{"ac": "User can reset password via email", "met": true, "evidence": "TestResetPassword in internal/auth/reset_test.go:42"},
{"ac": "Rate limit 5/min per email", "met": true, "evidence": "TestRateLimit in internal/auth/reset_test.go:89"}
],
"existing_work_summary": "Found ResetToken in pkg/auth; extended with email flow."
}
Bad — missing existing_work_summary:
{"ws_id": "<ws-id>", "feature_id": "<feature-id>", "verdict": "PASS", "ac_evidence": [...]}
Reason: existing_work_summary is required. Add one-line summary of pre-existing code/tests found before implementation.
Bad — ac_evidence without evidence field:
{"ac": "User can reset password", "met": true}
Reason: Each ac_evidence entry must include evidence (file:line or test name).
Schema: schema/ws-verdict.schema.json (from sdp root; project: sdp/schema/)
Batch Execution
When user invokes /build 00-053-16..25 (or multiple WS IDs):
- Expand range:
00-053-16..25 → 00-053-16, 00-053-17, …, 00-053-25
- Sequential: Execute each WS one at a time. Do not parallelize.
- Stop on first failure: If any WS fails (commit, test, or gate), STOP. Do not continue to the next.
- Report: At end, output
N done, M failed (e.g. 3 done, 1 failed if 00-053-18 failed after 00-053-16, 17 succeeded).
See Also
@oneshot — Orchestrator that invokes @build per WS
@tdd — TDD pattern
@go-modern — Modern Go style and cleanup rules