SpecKit Autonomous Build
SkillDocs & knowledgeAutonomous build phase, generates tasks, implements, tests, commits, pushes, merges, and produces release notes. Runs without user interaction.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the SpecKit Autonomous Build skill
What this skill tells your AI
The instructions your AI receives, as published by attckdigital/smith in skills/smith-build/SKILL.md and read by ahel’s review.
Executes the full build pipeline from answered questions through to merged PR and release notes. This command runs entirely without user interaction, using subagents to manage context.
Arguments: $ARGUMENTS
Vault Logging
Throughout this action, log significant events to the vault session log. Read the session log path from .smith/vault/.current-session. If the file is missing or the vault is not initialized, skip all logging silently.
Marker before first append: the workflow-gate denies markerless Bash redirection, so cat >> "$SESSION" appends are blocked until the active-workflow marker exists. Create the marker (Phase 0 step 0 helper) FIRST, then write the invocation entry immediately after — do not log before the marker.
Append entries using this format:
### [HH:MM:SS] /smith-build <event>
**User Request:**
> <verbatim user message that triggered this action — if invoked via /smith-new, reference the original request logged there. If invoked manually for recovery, capture the recovery command.>
**Synthesized Input:** <brief summary of what's being built>
**Outcome:** <what happened>
**Artifacts:** <files created/modified>
**Systems affected:** <system IDs>
Log at these points:
- On invocation — which feature is being built, fresh run or recovery, reference to original user request
- After each phase completes — phase name, tasks completed count, key artifacts produced
- After system spec updates — which system specs were updated and what changed
- After PR created — PR number, title
- After merge — success/failure, branch cleanup status
- On completion — brief release notes summary, total files created/modified, services rebuilt
Subagent Invocation Logging
Immediately before every Agent tool call in this workflow (including each phase subagent, testing subagent, and spec-update subagent), append a block to the session log. The Agent tool's return value does not expose subagent_type or model to the parent, so this is the only place that information can be captured.
### [HH:MM:SS] Subagent invoked: <description>
**Type:** <subagent_type or "general">
**Model:** <model override passed to Agent, or "inherited" if none>
After the Agent tool returns, the subagent-vault-writeback.sh hook automatically appends a matching "Subagent completed" block with metrics read from the sidechain transcript — do not duplicate that logging in the skill.
This command can be invoked in two ways:
- Automatically by
/smith-newafter questions are answered (normal flow) - Manually by the user via
/smith-buildfor recovery if a previous build failed partway
Phase 0: Context Discovery
-
Activate workflow tracking — invoke the shipped helper to create the per-branch marker. The workflow-gate hook (PR #20) exempts this exact helper by basename so the bootstrap runs even when no marker exists yet (per spec/31-workflow-gate-bootstrap). The helper also stamps the current session log with a
workflow-startline soworkflow-summary.sh --totals-onlycan attribute tokens correctly:BRANCH=$(git rev-parse --abbrev-ref HEAD) # Derive a slug from the branch (drop number prefix if numbered): SLUG=$(echo "$BRANCH" | sed 's/^[0-9]*-//') ~/.smith/scripts/create-active-workflow.sh \ --branch "$BRANCH" \ --workflow smith-build \ --slug "$SLUG" \ --worktree "$(pwd)"(Falls back to
scripts/create-active-workflow.shin repo-dev layouts.) Clear this marker at the end of Phase 7 (after release notes) or on unrecoverable failure. Use the shipped helper so this works even on projects that denyBash(rm:*):.specify/scripts/bash/clear-active-workflow.sh "$BRANCH" -
Detect worktree context:
COMMON_DIR=$(git rev-parse --git-common-dir) GIT_DIR=$(git rev-parse --git-dir)- If
COMMON_DIR≠GIT_DIR: we are in a worktree. SetWORKTREE_MODE=trueandWORKTREE_PATH=$(pwd). - Detect the primary repo path:
PRIMARY_REPO=$(git rev-parse --git-common-dir | sed 's|/\.git$||') - Log worktree status to vault session log.
- If
-
Run prerequisites check:
.specify/scripts/bash/check-prerequisites.sh --json --paths-onlyParse JSON for
FEATURE_DIRandAVAILABLE_DOCS.If the script fails (e.g., not on a feature branch), check:
- Is there a feature branch that matches
$ARGUMENTS? - Are there incomplete tasks in any
specs/*/tasks.md? - If recovery is possible, switch to the correct branch and retry.
- If not, ERROR with guidance.
- Is there a feature branch that matches
-
Load feature context from FEATURE_DIR:
spec.md(REQUIRED)plan.md(REQUIRED)questions.md(REQUIRED — verify Status is "ANSWERED")tasks.md(OPTIONAL — may not exist yet if this is first run)data-model.md(IF EXISTS)contracts/(IF EXISTS)research.md(IF EXISTS)quickstart.md(IF EXISTS)
Ledger Context (Optional)
If .smith/vault/ledger/ exists and contains non-empty files, load relevant Ledger sections to inform this workflow. If the directory is missing, empty, or unreadable, skip silently — the Ledger is purely additive and never required.
-
Check:
ls .smith/vault/ledger/*.md 2>/dev/null -
If files exist, read the following sections (higher-confidence entries first, truncate at ~2000 tokens per file):
.smith/vault/ledger/patterns.md.smith/vault/ledger/antipatterns.md.smith/vault/ledger/tool-preferences.md.smith/vault/ledger/edge-cases.md.smith/vault/ledger/project-quirks.md
-
Use loaded patterns as additional context — not as hard rules. The Ledger informs judgment, it does not override spec/plan/constitution.
-
Budget violation tracking: If any Ledger file was truncated (entries were dropped to fit within the ~2000 token budget per file), increment
context_budget_violationsin.smith/vault/ledger/.meta.jsonby 1. If.meta.jsondoes not exist, create it from the default template first. This signal tells the reconciliation system that the Ledger is too large for the configured budget. -
Determine build state (for recovery):
- If
tasks.mdexists, check for completed tasks[X]vs incomplete[ ] - If some tasks are complete, this is a recovery run — skip to Phase 2 (implementation)
- If no tasks.md exists, this is a fresh run — start from Phase 1
- If
Phase 1: Task Generation (Subagent)
Launch a subagent to generate the task breakdown.
The subagent should:
- Read artifacts: spec.md, plan.md, data-model.md, contracts/, research.md, quickstart.md
- Generate
tasks.mdfollowing the strict format:- [ ] [TaskID] [P?] [Story?] Description with file path- Phase 1: Setup (project initialization)
- Phase 2: Foundational (blocking prerequisites)
- Phase 3+: User Stories in priority order
- Final Phase: Polish & Cross-Cutting Concerns
- Run consistency analysis (
smith-analyzelogic):- Check spec ↔ plan ↔ tasks alignment
- Check for missing coverage, contradictions
- If CRITICAL issues found: fix them in-place (do not halt)
- Log any issues found for the release notes
Ledger-Informed Auto-Retry
If the build execution fails, check config for auto-retry:
- Read
.smith/config.json— checkledger.auto_retryandledger.max_retries - If
auto_retryisfalse(default) or config is missing, do NOT retry — fail normally - If
auto_retryistrue: a. Re-read.smith/vault/ledger/antipatterns.mdto get the latest failure patterns b. Analyze the failure against known antipatterns to adjust the approach c. Retry the execution with the adjusted approach d. Repeat up tomax_retriestimes (default: 2), re-reading antipatterns before each attempt e. If all retries exhausted, fail with a summary of all attempts - Each retry attempt is logged to the session log with attempt number and adjusted approach
Note: Auto-retry applies to the Phase 2 implementation loop. If a phase's subagent fails after 3 internal attempts AND auto-retry is enabled, the entire phase is retried with updated Ledger context.
Phase 2: Implementation (Subagent per Phase)
Execute tasks phase-by-phase, each phase in its own subagent to manage context.
Pre-implementation checks:
-
Verify/create ignore files based on plan.md tech stack:
.gitignore,.dockerignore,.eslintignore,.prettierignoreas applicable- Only append missing patterns to existing files
-
Parse tasks.md to extract phases and their tasks.
Execute each phase:
For each phase in tasks.md:
-
Launch a subagent with:
- The phase's tasks (incomplete ones only)
- Relevant context: plan.md tech stack, data-model.md, contracts/
- File paths from task descriptions
- Instructions to mark each task
[X]in tasks.md upon completion
-
Phase execution rules:
- Sequential tasks: execute in order
- Parallel tasks [P]: can run together (but subagent decides based on file conflicts)
- If a task fails: attempt fix up to 3 times, then log error and continue with remaining tasks
- After each task completion, update tasks.md with
[X]marker
-
Phase completion check:
- Verify all tasks in the phase are marked
[X] - If any failed permanently, log them for the summary
- Proceed to next phase
- Verify all tasks in the phase are marked
Implementation rules:
- Follow the plan.md architecture and file structure
- Respect data-model.md entity definitions
- Match contracts/ API specifications
- Use existing project patterns (read surrounding code before writing)
- Follow constitution.md principles
- Clean-code architecture — apply this checklist directly (it implements
the constitution's Clean Architecture Policy and mirrors the
/smith-clean-codeskill; do NOT rely on being able to load that skill, as build subagents may not have skill access):- Small, single-responsibility functions and files; one clear reason to change.
- Intention-revealing names (avoid
data,temp,handler,utilwhen a meaningful name exists). - Guard clauses over deep nesting; keep control flow shallow.
- Separation of concerns — keep I/O, business rules, and persistence in distinct units.
- No dead code, commented-out blocks, or duplicated logic.
- Honor the file structure
plan.mdprescribed; do not collapse it back into large monolithic files.
- Reuse over duplication: before writing new code, check for an existing
component that already does it — extend or import it rather than recreating
it. Use the reuse list in
plan.md(and/smith-navigate/.smith/index/when available) to locate existing modules, services, and utilities. Do not copy-paste near-identical logic; factor shared logic into a common helper. - Keep files small: follow the constitution File Size Policy (300-line soft target, 500-line decomposition threshold). When a file you are editing approaches the threshold, split it proactively during the build rather than leaving it for the post-hoc File Size Warnings flag in the PR body (§5.3).
- After any code changes to a Docker service: run
docker compose up -d --build <service>immediately
Phase 3: Testing (Subagent)
Launch a testing subagent after all implementation is complete.
3.1 Unit Tests
- If frontend code changed:
cd services/command-center && pnpm test - If Python service changed:
cd services/<service> && poetry run pytest - Run existing test suites — do NOT skip tests
3.2 Playwright E2E Tests (MANDATORY for UI changes)
- Check if any frontend files were modified in this feature:
- Files matching
services/command-center/src/components/** - Files matching
services/command-center/src/pages/** - Files matching
services/command-center/src/hooks/** - Files matching
services/command-center/src/App.tsx
- Files matching
- If YES:
- Run existing Playwright suite for regression:
cd services/command-center && pnpm exec playwright test - Write NEW Playwright tests for the changed/added UI flows
- Run the new tests
- Run existing Playwright suite for regression:
- If NO frontend changes: Skip Playwright
3.3 Test Failure Handling
- If tests fail: fix the code and re-run (up to 3 attempts per failure)
- If a test is flaky (passes on retry without code changes): note in release notes
- If tests cannot be fixed after 3 attempts: log the failure and continue
- The release notes will flag this as requiring manual attention
Phase 3.5: Clean Code Review Pass
Launch exactly ONE subagent (Task tool) to evaluate the full branch diff vs
$BASE_BRANCH against smith-clean-code's rubric, strictly after Phase 3
has reached a passing state and strictly before Phase 4 begins. This is an
ordering precondition only — flag-never-block still governs the PR outcome
(§5.4), never this pass's own invocation.
Invocation. Thread the same WORKTREE_PATH/BASE_BRANCH context
Phase 4/Phase 5 already use:
BASE_BRANCH=$(.specify/scripts/bash/get-base-branch.sh)
Diff against $BASE_BRANCH only — never a hardcoded or inferred ref. Pin
the subagent to model: sonnet (not Haiku — this pass makes
auto-fix judgment calls, not narrow classification/lookup).
Rubric delivery. The subagent Reads skills/smith-clean-code/SKILL.md
(worktree copy first), falling back to ~/.claude/skills/smith-clean-code/SKILL.md
(installed copy) only when the worktree copy is unavailable. It locates the
## Review Process, ## Decision Rules, and ## What You Should Avoid
sections by HEADING — e.g. grep -n '^## Review Process', then Read from
that line to the next ^## heading — never by hardcoded line number,
since that file is edited independently of this feature and any cited
range would drift out of date.
Findings contract. Each finding carries exactly one severity
(Critical/High/Medium/Low) plus: Location (path:line), Tenet violated
(short label — e.g. "Deep nesting", "Duplicated logic", "God
function/file", "Unclear naming", "Mixed responsibilities"),
Behavior-preserving fix available (true/false), Fix-safety
(clear/unclear), Auto-fix eligible (derived, see below), Fix applied
(true/false — set only once the edit is actually made), and a 1-2
sentence Rationale. A finding missing any field defaults to Fix-safety:
unclear (flag, never fix).
Auto-fix eligibility. A finding is auto-fix eligible if and only if it is behavior-preserving AND its fix-safety is clear. Not behavior-preserving, or fix-safety unclear → always FLAG, never auto-fix. State explicitly: a Critical finding whose only available fix would change program behavior is NEVER auto-fixed, always flagged, regardless of configuration — no override may relax this.
.meta coverage. This pass does NOT add its own proactive
.meta-write step. For builds launched via smith-new, that workflow's
existing per-edit .meta instruction already covers every edit the build
subagent makes, auto-fix edits included. For standalone smith-build
runs, auto-fix edits fall back to the existing passive §5.3.1 Description
Coverage Warnings scan, exactly like ordinary Phase 2 implementation
edits already do.
No tasks.md coupling. Auto-fix edits from this pass are polish, not
tracked tasks — they require no corresponding tasks.md change.
Bounded re-test. If one or more auto-fixes were applied (any count), run exactly one full re-run of Phase 3 in its entirety (3.1 → 3.2 → 3.3). If zero auto-fixes were applied, Phase 3 MUST NOT be re-run. A failing re-run resolves entirely via Phase 3.3's own existing bounded-attempts behavior — this pass adds no second retry loop, no second fix batch, and does NOT re-review the diff, regardless of the re-run's outcome. The bound is exactly: one review → at most one fix-application batch → at most one Phase 3 re-run. No step repeats.
Unresolved findings → scratch file. Findings where Fix applied: false are written by the review subagent itself (its own output — there
is no deterministic scan block to write here, unlike §5.3/§5.3.1, since
judging "is this a god function" is not something a script can do) to
/tmp/smith-build-clean-code-findings.txt:
- **[<Severity>]** `<path>:<line>` — <one-line description> (tenet: <Tenet violated>)
Medium, High, and Critical findings each get one line. Low-severity
findings are never listed individually — if any remain unfixed, append
exactly one trailing + N low-severity notes line instead (omitted when
N=0). An auto-fixed finding contributes nothing to this file.
Phase 3.6: Security Review Pass
Runs exactly once per build, strictly after Phase 3.5 completes (an ordering precondition only, independent of its outcome) and strictly before Phase 4 begins (FR-2). Never re-entered.
Invocation.
BASE_BRANCH=$(.specify/scripts/bash/get-base-branch.sh)
Diff against $BASE_BRANCH only.
Step 1 — presence-detect. Resolve detect-scanners.sh (installed-path-preferred,
repo-dev fallback — the convention scripts/install.sh stages this script family
under) and run it once, before any layer:
for cand in "$HOME/.smith/scripts/security/detect-scanners.sh" scripts/security/detect-scanners.sh; do
[ -f "$cand" ] && DETECT_SCANNERS="$cand" && break
done
SCANNERS=$(bash "$DETECT_SCANNERS") # gitleaks/semgrep/bandit=present|absent, one line each
Write /tmp/smith-build-security-layers-ran.txt (this feature's data-model.md §4)
unconditionally, derived from $SCANNERS: layer1_builtin=ran,
layer1_gitleaks=ran|skipped_absent, layer2_sast=ran:<tool-name>|skipped_absent,
layer3_llm=ran.
Step 2 — Layer 1, unconditional (FR-8). Resolve secret-scan.sh the same way and
invoke it, adding --with-gitleaks only if gitleaks=present:
for cand in "$HOME/.smith/scripts/security/secret-scan.sh" scripts/security/secret-scan.sh; do
[ -f "$cand" ] && SECRET_SCAN="$cand" && break
done
echo "$SCANNERS" | grep -q '^gitleaks=present$' && GL="--with-gitleaks" || GL=""
bash "$SECRET_SCAN" --diff-base "$BASE_BRANCH" $GL
Exit 0 clean, 1 findings on stdout (parse, not a failure), 2 internal error
(log, treat this layer as skipped — not fatal). This is the only guaranteed-coverage
deterministic layer; must work correctly with zero external scanners installed
(FR-8).
Step 3 — Layer 2, conditional. If Step 1 reported semgrep=present and/or
bandit=present, run each against the same git diff "$BASE_BRANCH" --name-only
file list, normalized into this feature's data-model.md §2 five-field format
(pattern-id = semgrep:<rule-id> / bandit:<check-id>). Silently skip entirely if
neither is present (FR-9) — no error, no install attempt; neither tool is ever added
as an installed dependency of Smith or the project.
Step 4 — Layer 3, unconditional. Launch exactly ONE subagent (Task tool) to
review the full git diff "$BASE_BRANCH" against this rubric, stated verbatim:
injection (SQL/command/template), authentication/authorization flaws,
secrets/credential handling, unsafe deserialization or eval-family use, path
traversal, SSRF and unvalidated redirects, cryptographic misuse, sensitive-data
logging or exposure, dependency-adjacent code smells (not CVE/SCA scanning), and race
conditions/TOCTOU in security-relevant paths. Do NOT invoke Smith's built-in
/security-review capability — this rubric is the sole methodology. Pin model: opus; read .smith/config.json's security_review.review_model
(haiku|sonnet|opus|fable) to override, using the same file-exists-and-parses validity
gate as every other config read in this pipeline — missing/malformed config or key
defaults to opus.
Findings contract. Every finding carries exactly one Severity
(Critical/High/Medium/Low), path:line Location, Category, a 1-2 sentence Rationale,
and the originating Layer (1/2/3) — this feature's data-model.md §3.
No auto-fix, ever (FR-13). This phase makes ZERO Write/Edit calls to the working tree, for any finding, any layer, any configuration — unlike Phase 3.5, there is no eligibility test, because none exists.
Step 5 — merge + decide. Merge all layers' findings; evaluate this feature's
data-model.md §5 tier × severity × layer decision table against
.smith/config.json's security_review.enforcement_tier (default flag if
absent/malformed, same defensive read as review_model above). One row applies in
every build regardless of tier: any Critical Layer 1 (secret) finding ALWAYS
terminates — non-bypassable, independent of enforcement_tier. The per-line
# smith-secret-scan: allow marker (applied before the scan runs) is the sole
false-positive remedy — no runtime-confirmation escape hatch, unlike the
browser-production confirm-gate (this is the system's second non-bypassable denial).
Terminate branch. Other layers may still finish evaluating so the eventual record
lists everything found, but nothing from this run reaches the flag-only scratch file
— the outcome is terminated, not a partial flag+terminate mix (NFR-6). Phase 4 never
begins, so Phase 5.1 (Commit)/5.2 (Push) never execute. Write a hard-stop marker to
the vault session log using this file's own ### [HH:MM:SS] /smith-build <event>
format, **Outcome:** naming the terminating finding(s) (severity, path:line,
category, layer — excerpt REDACTED per this feature's data-model.md §2, no
internal-only exception), plus an explicit **Hard-stop:** Security Review Pass (Phase 3.6) terminated this build before Phase 4. line. Surface the stop via Phase
7.5's Display Summary mechanism ("build terminated at Phase 3.6" instead of a PR
link). Preserve the worktree exactly like Phase 7.3's "on failure" convention; leave
the active-workflow marker uncleared. NEVER a prompt — this is a log entry, not a
pause (NFR-1).
Flag branch. If nothing resolves to "terminate," write every non-terminating
finding to /tmp/smith-build-security-findings.txt per this feature's
data-model.md §4 line format (Medium/High/Critical listed individually, Low folded
into one trailing + N low-severity notes line, omitted when N=0) and proceed to
Phase 4 exactly like Phase 3.5 does today.
Phase 4: Spec Updates (Subagent)
Launch a subagent to update related system spec files.
-
Identify modified files from git diff against the configured base branch:
BASE_BRANCH=$(.specify/scripts/bash/get-base-branch.sh) git diff "$BASE_BRANCH" --name-only -
Map modified files to system specs:
services/command-center/→specs/system-15-command-center/spec.mdservices/email-pipeline/→specs/system-03-email-archive-contact-graph/spec.mdservices/sentiment-engine/→specs/sentiment-engine/spec.mdservices/communication-triage/→specs/system-05-communication-triage/spec.mdservices/voice-training/→specs/system-04-personal-voice/spec.mddocker-compose.yml→specs/system-01-core-infrastructure/spec.md- Other mappings as discovered from
specs/*/spec.mdcontent
-
For each affected spec.md:
- Read the current spec
- Add an "Implementation History" section (or append to existing)
- Add a dated entry describing changes relevant to that system
- Keep entries concise and factual
-
Update STATUS.md at project root with current progress.
4.5 System Spec Updates via .specify/systems/
After updating the legacy specs/system-*/spec.md files above, also update the canonical system specs in .specify/systems/:
- Read the feature spec frontmatter — extract
primary_systemandalso_affectsfields. If the feature spec has no frontmatter (legacy spec inspecs/), fall back to the file-path mapping in step 2 above.
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 52
- Forks
- 8
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
smith-build- Source
- github.com/attckdigital/smith