| name | deft-directive-build |
| description | Build a project from scope vBRIEFs following Deft Directive framework standards. Use after deft-directive-setup has generated the project definition, or when the user has story vBRIEFs in vbrief/active/ ready to implement. Handles scaffolding, implementation, testing, and quality checks phase by phase.
|
Deft Directive Build
Implements a project from its scope vBRIEFs following Deft Directive standards.
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
When to Use
- After
deft-directive-setup completes and generates PROJECT-DEFINITION.vbrief.json
- User says "build this", "implement the spec", or "start building"
- Resuming a partially-built project that has story vBRIEFs in
vbrief/active/
Step 0 -- Implementation Preflight (#810)
- ! Before starting any new implementation story or switching from one story to another, MUST run
git status --short --branch.
- ! If the working tree is dirty, MUST stop and summarize the current branch, modified/untracked files, and whether the changes appear related to the target story. Ask the operator to choose one path: commit existing work, stash existing work, include existing work in the current story, or stop.
- ⊗ Begin a new story while unrelated dirty work is present without explicit operator approval.
- ! Resolve exactly one target story vBRIEF path by default. One story is the default implementation unit for this skill; if the user asks for a phase/epic, decompose or ask which story to start.
- ! Batching multiple stories in one branch/PR requires explicit operator approval and a short rationale recorded in the handoff.
- ! Swarm-cohort dispatch carve-out: when this skill is invoked as part of a swarm cohort allocated by
skills/deft-directive-swarm/SKILL.md, the approved Phase 5 allocation plan satisfies the "explicit operator approval and short rationale recorded in the handoff" requirement above -- the dispatched vBRIEF paths and allocation rationale ARE the consent token. Process each assigned story sequentially under the checkpoint-commit + task scope:complete discipline below. Do NOT re-prompt the parent for batching approval mid-cohort -- the all-or-nothing dispatch envelope rule (AGENTS.md ## Multi-agent orchestration discipline (#954)) forbids mid-scope user-approval gates.
- ! Structured consent-token recognition (#1378): the canonical recognition path for the carve-out above is the structured
## Allocation context section of the dispatch envelope (the frozen schema in templates/agent-prompt-preamble.md, Story A of #1378). When that section reports dispatch_kind: swarm-cohort with a non-null allocation_plan_id AND a non-null batching_rationale, the consent token is satisfied mechanically -- read cohort_vbriefs as the authoritative file boundary and process each entry sequentially under the checkpoint-commit + task scope:complete discipline below, without re-prompting the parent for batching approval mid-cohort. When the ## Allocation context section is ABSENT (pre-#1378 dispatches, solo-interactive sessions), fall back to the #1371 prose carve-out immediately above -- the prose carve-out remains the recognition path of record for un-elevated envelopes.
- ! Within a cohort, between stories: the working tree MUST be clean after each story's checkpoint commit +
task scope:complete. If git status --short shows uncommitted state between stories (e.g. a missed task scope:complete move, an unstaged file from the prior story), checkpoint-commit it and proceed -- do NOT pause to ask the operator. The dirty-tree "ask the operator" branch above applies only at the FIRST story-start of a fresh branch, where uncommitted operator work might legitimately exist.
- ! If the target story is in
vbrief/proposed/, run task scope:promote -- <path> first; if it is in vbrief/pending/, run task scope:activate -- <path>. After activation, update the path to the active-file location before preflight.
- ! Before any code-writing tool call -- the first scaffold edit, the first
task invocation that mutates files, or any start_agent dispatch that will implement scope -- MUST run task vbrief:preflight -- <active-story-path> (the structural intent gate; wraps scripts/preflight_implementation.py so the same invocation works whether deft is the project root or installed as a deft/ subdirectory).
The gate exits 0 only when the candidate vBRIEF lives in vbrief/active/ AND plan.status == "running". Any other state (pending/, proposed/, completed/, active/-with-non-running-status, malformed JSON, missing keys) exits 1 with an actionable redirect to task vbrief:activate <path>.
- ! A non-zero exit MUST halt the skill. Surface the helper's stderr message verbatim to the user; do NOT proceed to USER.md Gate, File Reading, or any later phase.
- ! Use canonical lifecycle tasks to satisfy this gate:
task scope:promote -- <path> for proposed stories, task scope:activate -- <path> for pending stories, and the helper's idempotent companion task vbrief:activate <path> only when following the preflight redirect directly. Manual lifecycle moves bypass the activation contract -- use the task.
- ⊗ Infer implementation intent from lifecycle vocabulary ("do the full PR process", "start the work", "poller agents"), branching language, or workflow shape. Workflow-shape vocabulary is NOT authorization to spawn an implementation agent (#810 surfacing event).
- ⊗ Skip this preflight because the user said "yes", "go", or "proceed" -- affirmative continuation phrases are NOT implementation authorization unless the prior turn explicitly proposed implementation. When intent is ambiguous, ask one targeted question before invoking the gate.
Platform Detection
! Before resolving any config paths, detect the host OS from your environment context:
| Platform | USER.md default path |
|---|
| Windows | %APPDATA%\deft\USER.md (e.g. C:\Users\{user}\AppData\Roaming\deft\USER.md) |
| Unix (macOS/Linux) | ~/.config/deft/USER.md |
- ! If
$DEFT_USER_PATH is set, it takes precedence on any platform
Pre-Cutover Detection Guard
! Before proceeding with any build step, detect whether the project uses the pre-v0.20 document model or was generated by a strategy that emitted non-conformant v0.20 output shape (the root cause of most "build fails immediately after spec" complaints in #1166). Redirect or block with the precise remediation.
Detection Criteria
A project is pre-cutover if ANY of the following are true. This prose mirrors the executable helper in scripts/_precutover.py; when in doubt, the helper is canonical.
SPECIFICATION.md exists and is neither a deprecation redirect nor a current generated spec export. A current generated spec export contains <!-- Purpose: rendered specification --> and <!-- Source of truth: vbrief/specification.vbrief.json -->, and vbrief/specification.vbrief.json plus all five lifecycle folders exist.
PROJECT.md exists and contains neither the legacy <!-- deft:deprecated-redirect --> sentinel NOR the current Purpose: deprecation redirect canonical-banner marker (real content, not a deprecation redirect)
vbrief/specification.vbrief.json exists but the lifecycle folders (vbrief/proposed/, vbrief/pending/, vbrief/active/, vbrief/completed/, vbrief/cancelled/) do NOT exist
- Strategy output shape violations (run
task verify-strategy-output -- the canonical gate -- or the direct form python .deft/core/scripts/validate_strategy_output.py --project-root <path> after deft install):
- Any scope vBRIEF under
vbrief/proposed/ (or other lifecycle dirs) lacks the required YYYY-MM-DD- date prefix in its filename (e.g. bare scaffold.vbrief.json).
vbrief/PROJECT-DEFINITION.vbrief.json is missing.
vbrief/specification.vbrief.json exists as a legacy dual-write in a user-generated project. This is tolerated only for the framework source tree or a complete post-cutover full-spec consumer where all lifecycle folders exist and SPECIFICATION.md is rendered from vbrief/specification.vbrief.json.
Action on Detection
! If pre-cutover or strategy-nonconformant state is detected, stop immediately and display an actionable message that cites the exact validator:
"This project was generated with pre-v0.20 or non-conformant strategy output. Run the deterministic validator and follow its remediation: task verify-strategy-output (works in source and after deft package install) or python .deft/core/scripts/validate_strategy_output.py --project-root . . Then task migrate:vbrief / task project:render / strategy re-run as indicated."
! Include specific details about what was detected (the validator output is authoritative):
- Legacy specification.vbrief.json or missing lifecycle folders: "Run
task migrate:vbrief to create the lifecycle folder structure and remove legacy dual-writes"
- Non-date-prefixed vBRIEFs: "Re-run the emitting strategy after the v0.20 migrations (#1166 s1+s2+...) or manually rename files to
YYYY-MM-DD-<slug>.vbrief.json and task scope:promote"
- Missing
PROJECT-DEFINITION.vbrief.json: "Run task project:render to generate the project definition"
SPECIFICATION.md / PROJECT.md without sentinel: the classic pre-cutover messages
- Scope vBRIEF in wrong folder: "Status is '{status}' but file is in {folder}/ -- run
task scope:activate <file> to fix"
! After the validator reports clean, re-run this guard before continuing.
⊗ Proceed with build when pre-cutover or strategy-nonconformant artifacts are detected -- always redirect to migration first (or run the validator) and surface the exact remediation.
⊗ Silently ignore these artifacts or guess at fixes -- the validator (wired into task check and this guard) is the deterministic gate.
USER.md Gate
! Before proceeding, verify USER.md exists at the platform-appropriate path
(resolved via Platform Detection above, or $DEFT_USER_PATH if set).
- ! If USER.md is not found: inform the user and redirect to
deft-directive-setup
Phase 1 before continuing -- do not proceed without user preferences
- ! Once USER.md exists, continue with the Cost Phase Gate below
Cost Phase Gate (#739)
! Before proceeding to File Reading, verify the project has gone through the
pre-build cost & budget transparency phase from skills/deft-directive-cost/SKILL.md.
This closes the adoption-blocker surfaced by issue #739 (refs #151 umbrella) where
users finished the spec flow and stopped at build because deft offered no cost
signal.
Detection
- ! Check for
COST-ESTIMATE.md in the project root.
- ! Check that the file contains a recorded decision (the Decision recorded
block populated with one of:
build, rescope, no-build, skip).
- ! For
skip, rescope, or no-build decisions: the Reason field MUST be
populated (one or two sentences in plain language). A skip with no reason
recorded is treated the same as no decision.
Action
-
! If COST-ESTIMATE.md is missing OR the Decision recorded block is
unpopulated OR a skip/rescope/no-build decision has no reason recorded:
stop immediately and redirect the user:
"This project has not gone through the pre-build cost & budget transparency
phase. Run skills/deft-directive-cost/SKILL.md to produce a plain-English
COST-ESTIMATE.md, then re-run the build skill once the user has chosen
build / rescope / no-build / skip(+reason)."
-
! On a build or skip decision: continue with File Reading below.
-
! On a rescope decision: stop and redirect the user back to spec edits
(chain to skills/deft-directive-refinement/SKILL.md to pull spec scope
back, or the interview), then re-run skills/deft-directive-cost/SKILL.md
before re-attempting build.
-
! On a no-build decision: stop and exit; do NOT proceed to File Reading.
The user has explicitly stopped the project at the cost phase.
-
⊗ Proceed to File Reading or any subsequent phase when COST-ESTIMATE.md is
missing, when the decision is unpopulated, or when a skip / rescope / no-build
decision has no reason recorded.
-
⊗ Treat a rescope or no-build decision as if it were a build -- the
build skill MUST honor the recorded decision.
File Reading
- ! Read in order, lazy load:
./vbrief/active/ -- scope vBRIEFs for work items to build (required)
./vbrief/PROJECT-DEFINITION.vbrief.json -- project identity, tech stack, architecture
- USER.md at the platform-appropriate path (see Platform Detection) -- Personal section is highest precedence; Defaults are fallback
deft/main.md -- framework guidelines
deft/coding/coding.md -- coding standards
deft/coding/testing.md -- testing requirements
deft/coding/toolchain.md -- toolchain validation rules
deft/languages/{language}.md -- only for languages this project uses
- ⊗ Read all language/interface/tool files upfront
Rule Precedence
USER.md Personal <- HIGHEST (name, custom rules -- always wins)
PROJECT-DEFINITION.vbrief.json <- Project-specific (tech stack, architecture, config)
USER.md Defaults <- Fallback defaults (used when PROJECT-DEFINITION doesn't specify)
{language}.md <- Language standards
coding.md <- General coding
main.md <- Framework defaults
Scope vBRIEFs <- LOWEST
- ! USER.md Personal section always wins over any other file
- ! For project-scoped settings, PROJECT-DEFINITION.vbrief.json overrides USER.md Defaults
Change Lifecycle Gate
! Before any implementation that touches 3+ files, verify that a /deft:change <name> proposal exists and has been confirmed by the user:
- ! Check
history/changes/ for an active proposal.vbrief.json matching this work
- ! If no proposal exists: propose
/deft:change <name> and present the change name for explicit confirmation (e.g. "Confirm? yes/no")
- ! The user must reply with an affirmative (
yes, confirmed, approve) — a general 'proceed', 'do it', or 'go ahead' does NOT satisfy this gate
- ? For solo projects: this gate is RECOMMENDED but not mandatory for changes fully covered by
task check; it remains mandatory for cross-cutting, architectural, or high-risk changes
- ⊗ Skip this gate because the user has already said "proceed" or "go ahead"
Build Process
All vBRIEFs (including those read from vbrief/active/ and any new vBRIEFs this skill emits) MUST use "vBRIEFInfo": { "version": "0.6" }. The validator rejects any other version (see ../../conventions/references.md).
Step 1: Understand the Scope
- ! Read story vBRIEFs from
vbrief/active/ and PROJECT-DEFINITION.vbrief.json
- ! Identify phases, dependencies, starting point from scope vBRIEF acceptance criteria
- ! When scanning the existing codebase during scope understanding, MUST surface any contradicting patterns (two error-handling shapes, two state-management approaches, two naming conventions, etc.) before implementation begins -- apply
coding/hygiene.md ## Surface Conflicts: Pick One, Explain, Flag the Other (#1005) and choose ONE pattern (more recent OR more tested), explain the choice in the scope summary, and flag the other for cleanup
- ⊗ Begin implementation against an averaged blend of two contradicting patterns -- "average code that satisfies both rules is the worst code" (#1005)
- ! Present brief summary to user:
"Here's what I see: {N} story vBRIEFs in active/. I'll start with {name}. Ready?"
Step 2: Verify Toolchain
- ! Before any implementation, verify all tools required by this project are installed and functional — see
deft/coding/toolchain.md for full rules
- ! At minimum: confirm task runner (
task --version), language compiler/runtime, and platform SDK (if applicable) are available
- ! If any required tool is missing, stop and report — do not proceed to Step 3
- ⊗ Assume tools are available because the spec references them
Step 3: Build Phase by Phase
For each phase:
- ! Scaffold — file structure, dependencies, config
- ! Test first — write tests before implementation (TDD)
- ! Implement — make tests pass, following deft coding standards
- ! Verify — run
task check, fix any issues
- ! Checkpoint — tell user what's done, what's next
- ⊗ Move to next phase until current phase passes all checks
Step 4: Quality Gates
After EVERY phase:
task check
task test:coverage
- ! Phase is NOT done until
task check passes
- ⊗ Skip quality gates or claim they passed without running
Coding Standards (Summary)
Read full files when you need detail:
- ! TDD: write tests first — implementation incomplete without passing tests
- ! Coverage: ≥85% lines, functions, branches, statements
- ~ Files: <300 lines ideal, <500 recommended, ! <1000 max
- ~ Naming: hyphens for filenames unless language idiom dictates otherwise
- ! Contracts first: define interfaces/types before implementation
- ! Secrets: in
secrets/ dir with .example templates; ⊗ secrets in code
- ! Commits: Conventional Commits format; ! run
task check before every commit
See deft/coding/coding.md and deft/coding/testing.md for full rules.
Pre-Commit File Review
! Before every commit, re-read ALL modified files and explicitly check for:
- ! Encoding errors -- em-dashes corrupted to replacement characters, BOM artifacts, mojibake from round-trip read/write
- ! Unintended duplication -- accidental double entries in CHANGELOG.md, scope vBRIEF files, or structured data files
- ! Structural issues -- malformed CHANGELOG entries, broken table rows, mismatched index entries, invalid JSON/YAML
- ! Semantic accuracy -- verify that counts, claims, and summaries in CHANGELOG entries and ROADMAP changelog lines match the actual data in the commit (e.g. "triaged 4 issues" must match the number actually triaged, issue numbers cited must match the issues actually added)
- ! Semantic contradictions -- when adding a
! or ⊗ rule that prohibits a specific command, pattern, or behavior, search the same file for any ~, ≉, or prose that recommends or permits the same command/pattern -- resolve all contradictions in the same commit before pushing
- ! Strength duplicates -- when strengthening a rule (e.g. upgrading
~ to !), grep for the term in the full file and verify no weaker-strength duplicate remains
- ! Forward test coverage -- for each new source file in this PR (
scripts/, src/, cmd/, *.py, *.go), verify a corresponding test file exists in the same PR; running existing tests is not sufficient for new code
⊗ Commit without re-reading all modified files first.
Commit Strategy
- ! Default to one story per branch/PR. Batching multiple stories in one branch requires explicit operator approval and a short rationale.
- ! Create a checkpoint commit after each completed story before beginning another story.
- ! Run
task check before committing
- ⊗ Claim checks passed without running them
feat(phase-1): scaffold project structure
feat(phase-1): implement core data models with tests
feat(phase-2): add REST API endpoints with integration tests
Error Recovery
- ! Tests fail → fix them; ⊗ skip or weaken assertions
- ! Coverage drops → write more tests; ⊗ exclude files
- ! Lint/type errors → fix them; ≉ add ignore comments without documented reason
- ! Scope vBRIEF ambiguous -> ask user; ⊗ guess
- ! Scope needs changes -> propose, get approval, update the scope vBRIEF first
Completion
- ! When all phases pass and
task check is green, complete each implemented story via task scope:complete -- <active-story-path> before final PR handoff.
"The project is built and all quality checks pass. Describe any new features you'd like to add — I'll follow the deft standards we've set up."
Anti-Patterns
- ⊗ Skip tests or write them after implementation
- ⊗ Ignore
task check failures
- ⊗ Implement things not in scope vBRIEF without asking
- ⊗ Read every deft file upfront
- ⊗ Move to next phase before current passes checks
- ⊗ Make commits without running
task check
- ⊗ Proceed without USER.md -- always run the USER.md Gate first
- ⊗ Spawn an implementation agent or invoke a code-writing tool against a vBRIEF that has not passed
task vbrief:preflight (which wraps scripts/preflight_implementation.py) -- always run the Step 0 Implementation Preflight (#810) first; satisfy via task vbrief:activate <path>
- ⊗ Proceed without
COST-ESTIMATE.md and a recorded build / rescope / no-build / skip(+reason) decision -- always run the Cost Phase Gate (#739) first
- ⊗ Proceed with implementation when the build or test toolchain is unavailable -- always run the Toolchain Gate (Step 2) first
- ⊗ Proceed to next task or phase without tests passing -- testing is a hard gate, not a cleanup step
- ⊗ Skip the Change Lifecycle Gate because the user said "proceed" -- broad approval does not satisfy the confirmation gate
- ⊗ Commit or push directly to the default branch -- always create a feature branch first. Exception: user explicitly instructs a direct commit, or
PROJECT-DEFINITION.vbrief.json narratives contain Allow direct commits to master: true
- ⊗ Add a prohibition (
! or ⊗) without scanning the same file for conflicting softer-strength rules (~, ≉) that reference the same term