deft-directive-setup · diff
git:20261005.3c1ce6d to git:20261005.283bfab
6 added, 3 removed. Audit A to A.
---
name: deft-directive-setup
description: >-
Set up a new project with Deft Directive framework standards. Use when the
user wants to bootstrap user preferences, configure a project, or generate a
project specification. Walks through setup conversationally — no separate
CLI needed.
---
<!-- AUTO-GENERATED by task packs:render -- DO NOT EDIT MANUALLY -->
<!-- Purpose: rendered skill -->
<!-- Source of truth: packs/skills/skills-pack-0.1.json -->
<!-- Regenerate with: task packs:render -->
<!-- Edit the source, not this file. Slice instead of loading every SKILL.md: task packs:slice skills by-trigger --trigger <kw> (or list) -->
# Deft Directive Setup
Agent-driven alternative to `directive init` plus setup Phases 1-3 (`task project:render` / spec interview).
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
## When to Use
- User says "set up deft", "configure deft", or "bootstrap my project"
- User asks to create USER.md, PROJECT-DEFINITION.xbrief.json, or a specification
- User clones a deft-enabled repo for the first time with no config
- User says "revisit experimental rules", "toggle experimental meta", "enable SOUL", "disable morals", or wants to change Experimental Rules after bootstrap (#46)
## Opt-out flag (`.no-deft-directive`) (#2926)
! Before Pre-Cutover Detection Guard, Phase 1, or any install/setup step, check the **project root** for `.no-deft-directive` (exact lowercase name; presence = flag; empty or short `#` comment OK).
| Condition | Action |
|-----------|--------|
| Flag **present** | Stop. Tell the human: "Directive disabled via `.no-deft-directive`". ⊗ Offer install, session ritual, or setup interview. |
| Flag **absent**, no Directive deposit (`.deft/core`) | ? Ask whether to use Directive. On **no** → create root `.no-deft-directive` (optional one-line rationale) and stop. On **yes** → continue setup and ⊗ create the flag. |
| Operator says **stop using DD** | Create `.no-deft-directive`. ⊗ Auto-delete `.deft/` (explicit cleanup only). |
| Operator says **start using DD** | Remove `.no-deft-directive` and ensure install (`directive init` / deposit). |
! Flag is **root-only** (workspace root opened). Nested monorepo package roots are out of scope for v1.
! Flag **wins locally** over trusted-org / product-signal force-on (v1).
! Flag + deposit = inconsistent: warn loudly; doctor diagnoses; do not silently refresh. See `content/docs/no-deft-directive.md`.
## Consumer-first default (#1813)
! Assume the operator is **using Deft in their project** (consumer path). Proceed directly to the Pre-Cutover Detection Guard and Phase 1 — do NOT open with a contributor-vs-consumer fork.
~ The overwhelming majority of setup sessions are consumer installs; contributor onboarding is a separate, opt-in path (see below).
## Contributor / framework-maintainer path (secondary)
? Only enter this branch when the user **explicitly** says they are working on Deft itself (framework source checkout, `deftai/directive` clone, or maintainer tooling).
When that happens:
1. ! Tell the user: "Contributor setup lives in [`CONTRIBUTING.md`](../../../CONTRIBUTING.md) and this repo's root [`AGENTS.md`](../../../AGENTS.md). Use the maintainer installer: `deft-install --yes --upgrade --maintainer --repo-root . --json`."
2. ⊗ Continue the consumer USER.md / PROJECT-DEFINITION interview — the maintainer path does not use the first-session consumer flow.
3. **Stop here** unless the user explicitly asks to continue with consumer setup anyway.
## Pre-Cutover Detection Guard
! Before proceeding with any setup phase, detect whether the project uses the pre-v0.20 document model and redirect to migration if so.
### Detection Criteria
A project is **pre-cutover** if ANY of the following are true. When in doubt, run `task verify:pre-cutover` (the deterministic helper).
1. `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: xbrief/specification.xbrief.json -->`, and `xbrief/specification.xbrief.json` plus all five lifecycle folders exist.
2. `PROJECT.md` exists and contains neither the legacy `<!-- deft:deprecated-redirect -->` sentinel NOR the current `Purpose: deprecation redirect` canonical-banner marker (same one-release-cycle grace window).
3. `xbrief/specification.xbrief.json` exists but the lifecycle folders (`xbrief/proposed/`, `xbrief/pending/`, `xbrief/active/`, `xbrief/completed/`, `xbrief/cancelled/`) do NOT exist
### Action on Detection
! If pre-cutover state is detected, **stop immediately** and display an actionable message pointing at the frozen-release migration path (#2068):
> "This project uses the pre-v0.20 document model. Current npm releases no longer ship in-product `task migrate:vbrief`. Follow UPGRADING.md § Frozen pre-v0.20 document-model migration: pin framework v0.59.0 (frozen Go installer or git tag), install Python 3.11+ and uv, run `task migrate:vbrief` once from that payload, then upgrade to current npm."
! Include specific details about what was detected:
- Missing lifecycle folders: "Create lifecycle folders via the frozen-release migrator on v0.59.0, or manually add `xbrief/{proposed,pending,active,completed,cancelled}/` after migrating narratives"
- `SPECIFICATION.md` with real content: "SPECIFICATION.md contains non-redirect content — migrate on pinned v0.59.0 before upgrading to current npm"
- `PROJECT.md` with real content: "PROJECT.md contains non-redirect content — migrate on pinned v0.59.0 before upgrading to current npm"
- Missing `PROJECT-DEFINITION.xbrief.json`: "Run `task project:render` after document-model migration completes"
### Preflight (optional diagnostic)
~ Run `task migrate:preflight` to confirm pre-cutover state and print the frozen-release guidance. It does **not** run migration.
⊗ Offer to run `task migrate:vbrief` from the current npm deposit — the migrator is not bundled on current releases (#2068).
⊗ Proceed with setup phases when pre-cutover artifacts are detected — always redirect to the frozen migration path first.
⊗ Silently ignore pre-cutover artifacts — the user must be informed with an actionable command to fix the state.
### Greenfield Projects (No Migration Needed)
! For new projects (no existing `SPECIFICATION.md`, `PROJECT.md`, or `xbrief/specification.xbrief.json`), the guard passes silently and setup proceeds normally.
! Greenfield setup creates the full xBRIEF-centric structure from scratch:
1. `./xbrief/` directory with all 5 lifecycle subdirectories: `proposed/`, `pending/`, `active/`, `completed/`, `cancelled/`
2. `./xbrief/PROJECT-DEFINITION.xbrief.json` generated from Phase 2 interview results
3. First scope xBRIEF created in `proposed/` or `pending/` depending on Phase 3 interview outcome
~ This is already handled by Phase 2 Output Path (creates `./xbrief/` and lifecycle subfolders) and Phase 3 Output (creates scope xBRIEFs in lifecycle folders). The guard ensures migrating projects are redirected before reaching these phases.
### Migration safety flags (frozen v0.59.0 release only)
When guiding an operator through migration on the pinned release, mention the migrator safety affordances (#497, #506 D7):
- **`task migrate:vbrief -- --dry-run` (preview)** on v0.59.0
- **Dirty-tree guard** — migrator refuses when the working tree is dirty unless `--force`
- **`task migrate:vbrief -- --rollback`** on v0.59.0 to restore `.premigrate.*` backups
⊗ Offer in-product migration from a current npm deposit — use the frozen path (#2068).
## Deterministic Questions Contract
! Every numbered-menu prompt rendered in this skill (Phase 1 depth question, Phase 2 project type / deployment / language / strategy / branching gates, Phase 3 onboarding question, end-of-phase transition prompts, post-interview confirmation gate) MUST follow [`../../contracts/deterministic-questions.md`](../../contracts/deterministic-questions.md): render the canonical numbered menu in chat unless the host UI visibly preserves numeric option labels and returns numeric selections or exact displayed option text. The final two numbered options MUST be `Discuss` and `Back`, in that order. The Discuss-pause semantic is documented verbatim there -- on `Discuss` selection the agent MUST halt the in-progress sequence immediately, prompt `What would you like to discuss?`, and resume only on an explicit user signal (re-asks original question, says `resume`/`continue`, or re-issues prior selection). Implicit resumption is forbidden. Fallback chat replies MUST map only to the displayed number or exact displayed option text; do not infer from alphabetic host affordances.
## 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
- ! Create parent directories as needed when writing USER.md
- ~ `$DEFT_PROJECT_PATH` overrides the default project config path (`./xbrief/PROJECT-DEFINITION.xbrief.json`) if set
- ! Resolve `<policy-project-root>` to the user's working directory at skill entry. When `$DEFT_PROJECT_PATH` is set, resolve it relative to that root and preserve the environment variable for every Phase 2 command; the public policy writer, inspector, lock, and conformance gate honor the configured file even when it is outside the canonical `xbrief/` path.
- ! Pass `--project-root <policy-project-root>` to every Phase 2 policy inspector, writer, and conformance command. Do not unset or rewrite `$DEFT_PROJECT_PATH`, and do not let those commands fall back to a different working directory.
## Agent Behavior
**Flow:**
- ! Start asking immediately — everything you need is in THIS file
- ⊗ Explore the codebase, read framework files, or gather context before asking — except the Phase 1 freshness live-reader install-manifest / VERSION lookup (#4987)
- ? Read `deft/main.md` or language files LATER when generating output
**Interaction:**
- ~ Use structured question tools only when their visible option labels preserve the canonical numbers (for example, `1. Yes`) and their return value is the numeric selection or exact displayed option text.
- ! Fall back to the numbered chat menu when the host UI may replace numbers with alphabetic affordances, unlabeled buttons, or any other non-canonical choice labels.
- ⊗ Infer deterministic answers from host-added letters or shortcuts unless those letters were actually displayed in the canonical menu labels.
**Defaults:**
- ! Communicate that deft ships with best-in-class standards for 20+ languages
- ! Frame setup as "tell me your overrides" — not "configure everything"
- ~ "Deft has solid opinions on how code should be written and tested — I just need a few things about you and your project."
**Adapt to Technical Level:**
- ! First question gauges whether user is technical or non-technical
- ! Technical user: ask about languages, strategy, coverage directly — they'll have opinions
- ! Non-technical user: skip jargon, use sensible defaults, ask about what they're building not how
- ⊗ Ask non-technical users about coverage thresholds, strategies, or framework choices
## Available Languages
C, C++, C#, Dart, Delphi, Elixir, Go, Java, JavaScript, Julia, Kotlin,
Office.js (Excel JavaScript API), Python, R, Rust, SQL, Swift, TypeScript,
VBA (Excel macros), VHDL, Visual Basic (.NET), Zig, 6502-DASM
- ? Read `deft/languages/{name}.md` when generating output — not before asking
## Available Strategies
~ When presenting strategies to the user, always use this numbered list format (not a plain table).
~ Always include the chaining note below the list.
! Always show the FULL strategy list at every chaining gate — never remove a strategy because it was previously run.
~ If a strategy has been run already, indicate it with a note e.g. `(run 1x)` but keep it selectable.
1. **interview** ★ (recommended) — Structured interview with sizing gate: Light or Full path
2. **yolo** — Auto-pilot interview — Johnbot picks all recommended options
3. **map** — Analyze existing codebase conventions before adding features
4. **discuss** — Front-load decisions and alignment before planning
5. **probe** — Adversarially stress-test the plan; surface assumptions, edge cases, and risks before spec
6. **research** — Investigate the domain before planning
7. **speckit** — Five-phase spec-driven workflow for large/complex projects
> 💡 Strategies can be chained — after one completes, you'll be asked if you want to run another.
---
## Phase 1 — User Preferences (USER.md)
**Goal:** Personal preferences file with two sections:
- **Personal** — always wins over everything (name, custom rules)
- **Defaults** — fallback values that PROJECT-DEFINITION.xbrief.json can override (strategy, coverage)
- ~ Skip if USER.md exists at the platform-appropriate path (see Platform Detection) and user doesn't want to overwrite
- ⊗ Scan filesystem beyond checking that one USER.md path — except the install-manifest / VERSION live-reader used by USER.md freshness (#4987)
### USER.md Freshness Detection
! When an existing USER.md is found (returning user), check its `deft_version` field before skipping Phase 1.
! **Live reader (#4987 / #2294):** Resolve the installed framework version with `locateManifest` → read the VERSION file → `parseInstallManifest` → `manifestReportableVersion` (`packages/core/src/doctor/manifest.ts` / `@deftai/directive-core` doctor surface). Compare and stamp only when `reportable.version` is a non-null stampable semver. ⊗ Invent a generated version file for this purpose. ⊗ Use `resolveProbeCurrentVersion` or `resolveVersion`'s `"dev"` fallback for USER.md freshness or first-write stamps.
! **Freshness manifest exception (#4987):** That live-reader lookup is an explicit exception to the "do not scan past USER.md / read framework files before the first question" rules. When an existing USER.md is found, perform the install-manifest / VERSION read during freshness before deciding whether to skip Phase 1. ⊗ Use the exception to explore the codebase or read unrelated framework files.
1. ! If `deft_version` is **missing**: the USER.md predates versioning -- treat as stale
2. ! If `reportable.version` is null (missing manifest, `source: "sha"`, or `source: "none"`): ask nothing new for freshness and do **not** rewrite the stamp; on first write omit `deft_version` rather than writing a placeholder
3. ! If `deft_version` is present but **differs from `reportable.version`**: check whether any expected fields are missing from the USER.md
4. ! If fields are missing: query the user for each missing field individually -- do NOT re-run the full Phase 1 interview
5. ! After completing any field queries (even if none were needed), when `reportable.version` is non-null, write that version as `deft_version` to USER.md (install at X stamps X; a second run on the same install leaves it X; upgrade X→Y restamps Y once after missing-field questions)
6. ~ If `deft_version` matches `reportable.version` and all expected fields are present: USER.md is fresh — do **not** re-run Phase 1. ! Still offer the **Returning-user re-entry** menu below so the operator can revisit Experimental Rules or continue to Phase 2 without a full re-interview (#46).
Expected USER.md fields: **Name**, **Custom Rules**, **Default Strategy**, and optionally **Coverage** and **Experimental Rules**.
⊗ Re-run the full Phase 1 interview when only individual fields are missing from a stale USER.md -- query missing fields individually instead.
### Returning-user re-entry (#46)
! When USER.md already exists (fresh or after individual missing-field fill), present a deterministic numbered menu before assuming Phase 1 is "done and silent":
> "USER.md is in place. What next?"
> 1. Continue to Phase 2 (project configuration) ★ (recommended when project config is still missing)
> 2. **Revisit experimental rules** — enable/disable SOUL / morals / code-field without hand-editing schema
> 3. Not now (exit setup)
> 4. Discuss
> 5. Back
- ! Final two numbered options MUST be `Discuss` and `Back` per [`../../contracts/deterministic-questions.md`](../../contracts/deterministic-questions.md)
- ! On option 2, enter **Revisit experimental rules** (next section) — not a full Phase 1 re-interview
- ⊗ Silently skip past a complete USER.md with no re-entry offer when the operator entered setup (or asked to configure preferences)
- ⊗ Invent a `deft config` / `task config:*` verb family for this slice — setup skill re-entry is the product surface (#46)
### Interview Rules
! This phase follows the deterministic interview loop defined in `skills/deft-directive-interview/SKILL.md`. The core rules (one question per turn, numbered options with stated default, explicit "other" escape, depth gate, default acceptance, confirmation gate, structured handoff) apply here. Key points repeated for emphasis:
! **Each message you send MUST contain exactly ONE question.** This is the most
important rule in this file. After the user answers, send the NEXT question in
a new message. Repeat until all questions for their track are answered.
- ⊗ Include two or more questions in the same message under any circumstances
- ⊗ List upcoming questions — only show the current one
- ~ Provide numbered answer options with an "other" choice where appropriate
- ! Mark which option is RECOMMENDED when showing choices
- ~ Use structured question tools only when visible option labels preserve the canonical numbers and returns map to numeric selections or exact displayed option text.
! **Progress checkpoints (#5353):** Emit concise Rule 2 status-only progress checkpoints (current phase, remaining material decision areas / inventory labels, accepted deferrals, reasons for runtime additions) at closed triggers only: phase entry/exit, after a runtime decision-area addition-with-reason (not ordinary field-fill), after an accepted deferral, before the confirmation gate, and on operator how-much-is-left. Prefer a separate status message before the next question; if shared-turn, status prose stays ABOVE the structured-tool call (outside the tool `question` field) with exactly one question. Remaining-scope text MAY name inventory labels; it MUST NOT list concrete upcoming question text. On how-much-is-left: status grounded in the session inventory, then re-render the same pending question (do not advance; do not open Discuss unless the operator chose Discuss). Keep one-question / Discuss/Back / Rule 8 confirmation; do not remove Rule 8 or switch to yolo for orientation. Progress status is not a second question.
### Question Sequence
**Step 0 — Opening (all users):**
Ask: "How deep do you want to go?"
1. I'm technical — ask me everything
2. I have some opinions but keep it simple
3. Just pick good defaults — I care about the product, not the tools
Wait for answer. Then follow the track below.
! That answer is `1`, `2`, or `3`. When Phase 1 runs, persist it on the USER.md write in the Personal section as one line, `**Depth**: {n}`. Phase 2 in that first session uses this selection and does not ask the depth question again.
**Track 1 (technical) — 7 steps:**
- Step 1: Ask their name
- Step 2: Ask strategy preference (show Available Strategies numbered list from the Available Strategies section, with descriptions and recommended marker; fallback — projects can override)
- Step 3: Ask coverage threshold (default 85%; fallback — projects can override)
- Step 4: Ask for custom rules — if user has rules, collect them one per line (empty line to finish); if none, skip
- Step 5a: Present SOUL.md and ask whether to include it (default: yes):
> **SOUL.md** — Results-first agent persona (inspired by Winston Wolf). Enforces assess-before-acting,
> finish-what-you-start, right-tool-for-the-job, and play-the-long-game. Keeps the AI decisive and
> concise. Includes a named persona ('Vinston') — drop if you prefer to define your own agent personality.
> Include SOUL.md? (Y/n)
- Step 5b: Present morals.md and ask whether to include it (default: yes):
> **morals.md** — Epistemic honesty rules. No presenting speculation as fact, label unverified claims,
> self-correct when wrong. Foundational trust rules for any AI agent. Strongly recommended.
> Include morals.md? (Y/n)
- Step 5c: Present code-field.md and ask whether to include it (default: yes):
> **code-field.md** — Pre-code assumption protocol. Requires stating assumptions and naming failure modes
> before writing a single line. Fights the 'it compiles, ship it' instinct. Based on NeoVertex1 context-field.
> Include code-field.md? (Y/n)
**Track 2 (middle ground) — 2 steps:**
- Step 1: Ask their name
- Step 2: Ask for custom rules — if user has rules, collect them one per line (empty line to finish); if none, skip
- Set defaults without asking: strategy = "interview", coverage = 85%, all meta-guidelines included
**Track 3 (non-technical) — 2 steps:**
- Step 1: Ask their name
- Step 2: Ask what they're building (brief description — used for PROJECT-DEFINITION.xbrief.json later)
- Set defaults: strategy = "interview", coverage = 85%, all meta-guidelines included
### Output Path
Resolve using Platform Detection above. Write to the platform-appropriate path
(or `$DEFT_USER_PATH` if set). Create parent directories as needed.
! Phase 1 persist is that USER.md write (#4660). It is not the project-identity write.
### Template
```markdown
# User Preferences
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
{If reportable.version is non-null: `**deft_version**: {reportable.version}`; otherwise omit the deft_version line}
## Personal (always wins)
Settings in this section have HIGHEST precedence — override all other deft rules,
including PROJECT-DEFINITION.xbrief.json.
**Name**: Address the user as: **{name}**
**Depth**: {n}
**Custom Rules**:
{custom rules or "No custom rules defined yet."}
**Forge outage retry** (optional): `forgeOutageRetryMinutes: 30` — integer minutes, minimum 5. Default 30. Personal wins over `plan.policy.forgeOutageRetryMinutes`. Omit to use project policy or the framework default. Inspect: `task policy:show --field=forgeOutageRetryMinutes`.
## Defaults (fallback)
Settings in this section are fallback defaults. PROJECT-DEFINITION.xbrief.json overrides these
for project-scoped settings (strategy, coverage).
**Default Strategy**: [{strategy name}](../strategies/{strategy-file}.md)
{If coverage != 85: "**Coverage**: ! ≥{N}% test coverage"}
{If any experimental rules selected:
"## Experimental Rules
{one line per selected rule, e.g.:
- ! Use meta/SOUL.md for strategic context and purpose-driven guidance
- ! Use meta/morals.md for ethical AI development principles
- ~ Use meta/code-field.md for advanced architecture patterns}"}
---
**Note**: Edit this file anytime to update your preferences.
**See**: [../../main.md](../../../main.md) for framework defaults.
```
### Then
- ! Emit a structured-tool question asking whether to continue to Phase 2 (project configuration) only when the host preserves numeric labels; otherwise emit the deterministic numbered menu in chat. Options: `1. Yes (continue)`, `2. Not now (exit setup)`, `3. Discuss`, `4. Back (revisit previous phase)`. The numeric labels MUST remain visible and be returned as numeric selections or exact displayed option text.
- ⊗ Ask the phase-transition question as unnumbered conversational prose or through a structured UI that hides the canonical numeric labels -- it is a deterministic menu and MUST preserve visible numbers (#478, #1563).
---
## Revisit experimental rules (#46)
**Goal:** Guided enable/disable of USER.md **Experimental Rules** entries that *reference* framework deposit meta files (`meta/SOUL.md`, `meta/morals.md`, `meta/code-field.md`). This is a post-bootstrap return path — not Phase 1 bootstrap, not a general preferences UI, and not an editor for framework meta file bodies.
### When to enter
- Returning-user re-entry option **Revisit experimental rules**
- Direct user ask: "revisit experimental rules", "toggle experimental meta", "turn on SOUL", "disable code-field", etc.
- USER.md exists and is complete enough to edit (Name present); missing non-meta fields still use Freshness Detection individual queries first
### Out of scope
- ⊗ General preferences UI / rewriting Personal or Defaults sections as part of this path
- ⊗ Editing framework `meta/*.md` content (deposit owns SOUL / morals / code-field bodies; `directive update` refreshes deposit)
- ⊗ Deposit layout changes
- ⊗ Inventing a full `deft config` mega-surface or new `task config:*` verb family for this slice
- ⊗ Re-building USER.md bootstrap / non-overwrite semantics
- ⊗ Treating Experimental Rules lines as project-local copies of meta files — they are **references** only
### Flow
! **Each message MUST contain exactly ONE question** (same interview rule as Phase 1).
1. ! Resolve USER.md via Platform Detection (`$DEFT_USER_PATH` → platform path). Read the file as **UTF-8**.
2. ! Parse current Experimental Rules state (on/off) for the three paths:
- `meta/SOUL.md`
- `meta/morals.md`
- `meta/code-field.md`
- Detection: any line containing that path counts as **on** (custom wording still counts).
3. ! Show a **current state** summary (table or short list), for example:
| Entry | State | Role |
|-------|-------|------|
| SOUL.md | on/off | Results-first agent persona |
| morals.md | on/off | Epistemic honesty |
| code-field.md | on/off | Pre-code assumption protocol |
4. ! Ask which entry to change with a deterministic numbered menu (one question). Options MUST include each of the three entries as toggle targets, plus **Done (save)** / **Done (discard)**, and final two options `Discuss` and `Back`:
> "Toggle which experimental meta entry? (current state shown above)"
> 1. SOUL.md — currently {on|off}
> 2. morals.md — currently {on|off}
> 3. code-field.md — currently {on|off}
> 4. Done — save changes
> 5. Done — discard changes
> 6. Discuss
> 7. Back
5. ! When the user picks an entry (1–3), optionally show the short Phase 1 explainer (steps **5a–5c** copy below), then confirm the new on/off value with a Y/n or numbered keep/flip menu. Update the **in-memory** desired state; do not write yet. Return to the toggle menu (step 4) until Done.
6. ! On **Done — save**: show a confirmation summary of the three final on/off values and require explicit affirmative (`yes` / `confirmed` / `approve`) before write — same Post-Interview Confirmation Gate strictness.
7. ! On **Done — discard** or **Back** without save: leave USER.md unchanged and return to the Returning-user re-entry menu (or exit if invoked directly).
### Explainers (reuse Phase 1 steps 5a–5c)
- **SOUL.md** — Results-first agent persona (inspired by Winston Wolf). Enforces assess-before-acting, finish-what-you-start, right-tool-for-the-job, and play-the-long-game. Keeps the AI decisive and concise. Includes a named persona ('Vinston') — drop if you prefer to define your own agent personality.
- **morals.md** — Epistemic honesty rules. No presenting speculation as fact, label unverified claims, self-correct when wrong. Foundational trust rules for any AI agent. Strongly recommended.
- **code-field.md** — Pre-code assumption protocol. Requires stating assumptions and naming failure modes before writing a single line. Fights the 'it compiles, ship it' instinct. Based on NeoVertex1 context-field.
### Safe write rules (non-clobber)
! When persisting toggles to USER.md:
1. ! Write **UTF-8** (no BOM). Create parent directories only if the resolved path's parent is missing — never relocate USER.md.
2. ! Change **only** the `## Experimental Rules` section (add the section if enabling when absent; remove the section when all three are off and no custom bullets remain).
3. ! Canonical enable lines (match Phase 1 template):
- `- ! Use meta/SOUL.md for strategic context and purpose-driven guidance`
- `- ! Use meta/morals.md for ethical AI development principles`
- `- ~ Use meta/code-field.md for advanced architecture patterns`
4. ! Disable = remove lines that mention that path. Preserve any **custom** non-meta bullets under Experimental Rules.
5. ! **Personal** and **Defaults** section bodies MUST remain byte-identical to the pre-write file (non-clobber).
6. ~ Prefer the pure helper `applyExperimentalRulesState` / `setExperimentalRule` from `@deftai/directive-core` `userConfig` (`packages/core/src/user-config/experimental-rules.ts`) when the package is importable (framework checkout, tests, or a thin local script). When editing by hand as an agent, apply the same rules: section-only edit, UTF-8, path-based match, canonical enable lines.
7. ! After write, re-read USER.md and show the final on/off state to the user.
⊗ Rewrite the whole USER.md from the Phase 1 template when only Experimental Rules changed
⊗ Clobber or reformat **Personal** / **Defaults** content while toggling experimental meta
⊗ Hand-edit framework `meta/SOUL.md`, `meta/morals.md`, or `meta/code-field.md` bodies as part of this path
⊗ Invent `deft config` / `task config:experimental-*` for this product slice when setup re-entry suffices
### Then
- ! After a successful save (or discard), re-offer the Returning-user re-entry menu (Continue to Phase 2 / Revisit again / Exit / Discuss / Back) unless the user asked only for the toggle and is done.
- ~ If Phase 2 is already complete, prefer Exit over Continue unless the user wants project reconfiguration.
## Phase 2 — Project Configuration (PROJECT-DEFINITION.xbrief.json)
**Goal:** Project-specific configuration — tech stack, type, quality standards — written as a xBRIEF file at `./xbrief/PROJECT-DEFINITION.xbrief.json`.
! **Path Resolution Anchor**: Resolve ALL paths relative to the user's working directory (pwd) at skill entry -- never relative to the skill file location, AGENTS.md location, or any framework directory (e.g. `./deft/`). When deft is cloned as a subdirectory, the skill file lives inside the clone but all project artifacts (`./xbrief/PROJECT-DEFINITION.xbrief.json`, build files, etc.) must be resolved from the user's pwd.
- ~ Skip if `./xbrief/PROJECT-DEFINITION.xbrief.json` exists (or `$DEFT_PROJECT_PATH` if set) and user doesn't want to replace
- ! That existing file, including empty narrative strings, is not a missing-answers detector (#4668). Read it on a return visit. Do not ask for a previous setup summary.
- ⊗ Count `./deft/PROJECT-DEFINITION.xbrief.json` or `./deft/core/project.md` as the user's project config — those are framework-internal
### Re-entry shadow guard (#3609)
! Before any Phase 2 confirmation or file mutation when PROJECT-DEFINITION already exists, run `deft policy:show --field=plan.policy.allowDirectCommitsToMaster --project-root <policy-project-root>` and inspect **stderr as well as the exit code**. The inspector intentionally exits 0 when it can still read the namespaced value, so a warning that bare `plan.policy` coexists with `plan["x-directive/policy"]` is a hard stop even when the command succeeds.
! On that warning, do not regenerate, overwrite, or run a policy writer. Inventory the keys in both blocks; fold every bare-only key into `plan["x-directive/policy"]`; resolve every collision explicitly; delete bare `plan.policy`; then rerun the inspector. Preserve all unrelated PROJECT-DEFINITION content. Resume only when exactly one policy block remains.
⊗ Treat matching `allowDirectCommitsToMaster` values as safe while other keys may still be stranded in the shadowed block
⊗ Copy arbitrary policy values into a diagnostic or silently choose one side of a collision
### Inference
- ! Before asking, infer from codebase — look for `package.json`, `go.mod`, `requirements.txt`, `Cargo.toml`, `pyproject.toml`, `*.csproj`
- ! Use inferences to pre-fill answers and confirm — don't ask blind
- ⊗ Look inside `./deft/` for build files (`go.mod`, `package.json`, `pyproject.toml`, `Cargo.toml`, `*.csproj`, etc.) — those are framework-internal. Only inspect files at the project root and its non-`deft` subdirectories.
- ⊗ Run git commands inside `./deft/` to determine project identity — that directory is the framework repo, not the user's project.
- ~ If no build files are found at the project root, default the project name to the current directory name and ask for confirmation.
### Track Detection (#4668)
! Before any Phase 2 question, read Depth only inside the USER.md Personal section. The section starts at the `## Personal` heading and ends at the next line that begins with `## `. That is the same section bound the other USER.md field parsers use (Name, forge-outage retry). A `**Depth**:` line outside Personal is not the track.
! A Personal Depth line is optional leading `- `, then `**Depth**:` or `Depth:`, then a value. Strip bold markers and surrounding space. Only `1`, `2`, and `3` are valid. `1` is Track 1 (technical), `2` is Track 2 (middle ground), `3` is Track 3 (non-technical).
! Exactly one Personal line with a valid value is the track. When `**Depth**:` is `1`, `2`, or `3`, do not ask the depth question. Follow that track in the Question Sequence below. Skipping this question is not skipping Phase 2.
! When Phase 1 ran in this session, its selection is already the track. The Phase 1 USER.md write persisted it as one Personal line, `**Depth**: {n}`. Phase 2 does not ask the depth question again in that first session.
! When `**Depth**:` is absent from Personal, ask the depth question before any other Phase 2 question. A preferences file with no Depth field is asked once. A return visit whose Personal section has no Depth field is that case. A line outside Personal does not fill the absence.
! Duplicate lines are two or more `**Depth**:` lines inside Personal, whether or not the values match. Do not pick one. Do not treat any of them as the track. Ask the depth question once, then replace every Personal Depth line with one `**Depth**: {n}` line.
! An invalid value is one Personal Depth line whose value is not exactly `1`, `2`, or `3`. Do not treat that line as the track. Ask the depth question once, then replace it with `**Depth**: {n}`. Do not keep the invalid value. Two or more Personal Depth lines are duplicate lines, not an invalid value, even when one of them is `1`, `2`, or `3`.
> "How deep do you want to go?"
> 1. I'm technical — ask me everything
> 2. I have some opinions but keep it simple
> 3. Just pick good defaults — I care about the product, not the tools
! After the operator answers `1`, `2`, or `3`, write that number to USER.md before any other Phase 2 question. Insert or replace one Personal-section line, `**Depth**: {n}`. Write UTF-8 with no BOM. Leave every other USER.md line unchanged. On duplicate lines, the replacement leaves exactly one Personal Depth line. This field write is the exception to the end-of-phase confirmation gate. It is not the Phase 2 narrative write and it does not set policy keys. The next setup entry finds the field and does not ask again.
! Depth is not an expected freshness field. A missing Depth field does not re-run Phase 1. When Phase 1 runs, it stores the opening answer in Personal. The Phase 2 store is the return visit that still has no Personal Depth field, and the replacement of duplicate lines or an invalid value.
⊗ Infer the track from strategy, coverage, or any other USER.md field.
⊗ Assume Track 1 (technical) because USER.md exists or contains strategy or coverage fields.
⊗ Ask the depth question again when `**Depth**:` is already `1`, `2`, or `3`.
⊗ Treat a `**Depth**:` line outside Personal as the track.
### Existing project definition (#4668)
! An existing `./xbrief/PROJECT-DEFINITION.xbrief.json` (or `$DEFT_PROJECT_PATH`), including a seed whose narrative strings are empty, is a file that exists. Read it. It is not a missing-answers detector.
! Project identity strings are `deft project:write-narratives` (#4663). A return visit reads that file. Do not reimplement that writer. Do not set policy keys from the depth question or from empty narratives.
⊗ Ask the operator to re-provide a previous setup summary because narratives are empty.
⊗ Treat empty Overview, TechStack, Strategy, Quality, ProjectRules, or Branching as missing interview answers.
### Defaults in Agentic Mode
! When a question has a USER.md default, phrase it as:
> "{Field}: **{value}** from USER.md — keep this, or enter a different value?"
! Accept any affirmative response ("keep", "yes", "same", "default", ✓) as confirmation to use the default.
⊗ Phrase defaults as "press Enter to keep" — there is no Enter in conversational mode.
### Interview Rules (same as Phase 1)
! **Each message MUST contain exactly ONE question.** The Phase 1 interview rules
apply here too. Do not combine questions. See `skills/deft-directive-interview/SKILL.md` for the canonical deterministic interview loop.
- ⊗ Include two or more questions in the same message under any circumstances
- ⊗ List upcoming questions — only show the current one
! **Progress checkpoints (#5353):** Emit concise Rule 2 status-only progress checkpoints (current phase, remaining material decision areas / inventory labels, accepted deferrals, reasons for runtime additions) at closed triggers only: phase entry/exit, after a runtime decision-area addition-with-reason (not ordinary field-fill), after an accepted deferral, before the confirmation gate, and on operator how-much-is-left. Prefer a separate status message before the next question; if shared-turn, status prose stays ABOVE the structured-tool call (outside the tool `question` field) with exactly one question. Remaining-scope text MAY name inventory labels; it MUST NOT list concrete upcoming question text. On how-much-is-left: status grounded in the session inventory, then re-render the same pending question (do not advance; do not open Discuss unless the operator chose Discuss). Keep one-question / Discuss/Back / Rule 8 confirmation; do not remove Rule 8 or switch to yolo for orientation. Progress status is not a second question.
### Question Sequence
**Track 1 (technical) — 8 steps:**
- Step 1: Ask project name (infer from build files or directory name, confirm)
- Step 2: Ask project type (CLI, TUI, Desktop App, REST API, Web App, Library, other)
- Step 3: Ask deployment platform:
1. Cross-platform (Linux / macOS / Windows)
2. Windows-native
3. macOS-native
4. Linux / Unix
5. Embedded / low-resource
6. Web / Cloud
7. Mobile (iOS / Android)
8. Other / not sure
- Step 4: Ask languages — show a filtered shortlist (3–4 recommendations) based on project type + platform. If codebase markers exist (`go.mod`, `pyproject.toml`, etc.), skip and confirm: "Detected {lang} — correct?"
- If user selects "Other": show remaining plausible languages for the type+platform context (Tier 2)
- If still not found: free text input (Tier 3)
- If entered language has no deft `languages/{lang}.md` standards file, warn: "deft doesn't have a standards file for {lang} yet — general defaults will be used. Continue?"
- Step 5: Ask tech stack (frameworks, libraries)
- Step 6: Ask strategy (default to USER.md Defaults; ask if this project needs different — show Available Strategies numbered list with descriptions and recommended marker)
- Step 7: Ask coverage (default to USER.md Defaults; ask if this project needs different)
- Step 8: Ask for project-specific rules (optional, same one-per-line format as Phase 1 custom rules)
- Step 9: Ask branching preference (typed `plan.policy.allowDirectCommitsToMaster` flag per #746):
! Render this as a deterministic numbered menu. Default `1. Branch-based`. Final two options MUST be `Discuss` and `Back` per [`../../contracts/deterministic-questions.md`](../../contracts/deterministic-questions.md):
> "Do you prefer branch-based workflow (create a feature branch for every change) or
> trunk-based (commit directly to master)? Branch-based is the default and recommended
> for teams; trunk-based is common for solo projects."
> 1. Branch-based ★ (recommended -- default; enforces feature branches via the deft branch-protection policy)
> 2. Trunk-based (direct commits to master) -- see capability-cost disclosure below
> 3. Discuss
> 4. Back
! **Capability-cost disclosure (#746):** When the user picks option 2 (trunk-based), the agent MUST present the capability-cost disclosure verbatim BEFORE writing the typed flag, then re-prompt for explicit confirmation:
> "Capability-cost disclosure -- enabling direct commits to the default branch turns OFF the deft branch-protection policy. The pre-commit + pre-push hooks will no longer block default-branch commits, `deft verify:branch` / `task deft:verify:branch` will pass on the default branch, and the skill-level guards in deft-directive-{swarm,review-cycle,pre-pr,release} will not halt for default-branch work. The change is reversible (`task policy:enforce-branches`) and is recorded to meta/policy-changes.log for auditability. The CI sanity check (head_ref != base_ref) remains independent and will continue to flag master->master PRs. Are you sure?"
> 1. Yes, opt out -- persist `allowDirectCommitsToMaster=true` through the policy writer
> 2. No, keep branch-protection enforced -- persist `allowDirectCommitsToMaster=false` through the policy writer
> 3. Discuss
> 4. Back
! Default to option 2 (enforce). Explicit affirmative on option 1 is required to opt out -- a broad `proceed` does NOT satisfy this gate. The same affirmative-only rule applies as in `/deft:change` (`yes`, `confirmed`, `approve`).
! Record the answer as the logical field `plan.policy.allowDirectCommitsToMaster`, but do not hand-write either policy block. The common Output Path gate below invokes the only writer and stores the boolean under `plan["x-directive/policy"].allowDirectCommitsToMaster`. Default `false` (enforce branches) when the user picks option 2 OR omits the question entirely. Agents MUST NOT write bare `plan.policy` or the legacy free-form `Allow direct commits to master:` narrative key.
! **Re-running the interview detects the existing flag (#746 part G2):** After the Re-entry shadow guard passes, surface the resolved current value (e.g. "Current setting: `allowDirectCommitsToMaster=false` (branch-protection ON)") and ask whether to keep it or change it before re-prompting. A keep choice still runs the selected writer so legacy-only storage is migrated; an already-namespaced match is a no-op with no audit append. On Track 2 or 3, preserve an existing resolved boolean by default without asking a new branching question. Never replace an existing `true` with the greenfield `false` default unless the operator explicitly chooses the Track 1 change flow.
! **Consumer command alternatives (#746 part G2):** Once the project is set up, use the public CLI directly:
- `deft policy:show --field=plan.policy.allowDirectCommitsToMaster --project-root <policy-project-root>` -- display the current resolved policy and source
- `deft policy:enforce-branches --actor agent:deft-directive-setup --project-root <policy-project-root>` -- set `allowDirectCommitsToMaster=false`
- `deft policy:allow-direct-commits --confirm --actor agent:deft-directive-setup --project-root <policy-project-root>` -- set `allowDirectCommitsToMaster=true`
Each transition is recorded to `meta/policy-changes.log` for auditability.
**Track 2 (middle ground) — 4 steps:**
- Step 1: Ask project name (infer from build files or directory name, confirm)
- Step 2: Ask project type (CLI, TUI, Desktop App, REST API, Web App, Library, other)
- Step 3: Ask languages (show detected, confirm or adjust; if none detected, infer from type and ask)
- Step 4: Ask strategy (default to USER.md Defaults; ask if this project needs different — show Available Strategies numbered list with descriptions and recommended marker)
- Default coverage to USER.md Defaults without asking
- ! Do not ask a branching question. For greenfield or absent policy, the common Output Path gate persists `allowDirectCommitsToMaster=false`. On re-entry it preserves the resolved existing boolean, including `true`; change it only through the Track 1 disclosure gate.
**Track 3 (non-technical) — 1 step:**
- Step 1: Present summary of inferences: "Based on your project: {name} ({type}), built with {stack}. Look right?"
- ⊗ Ask about strategy or coverage — use Phase 1 defaults
- ! Do not ask a branching question. For greenfield or absent policy, the common Output Path gate persists `allowDirectCommitsToMaster=false`. On re-entry it preserves the resolved existing boolean, including `true`; change it only through the Track 1 disclosure gate.
### Output Path
`./xbrief/PROJECT-DEFINITION.xbrief.json` (or the resolved `$DEFT_PROJECT_PATH` if set). Create `<policy-project-root>/xbrief/` and its lifecycle subfolders (`proposed/`, `pending/`, `active/`, `completed/`, `cancelled/`) if they don't exist. A configured PROJECT-DEFINITION may live elsewhere; the lifecycle root remains under `<policy-project-root>`.
### Branch-policy persistence gate (#3609)
! This gate applies to **every track**, including default/greenfield and keep/re-entry paths. For greenfield setup, first store the confirmed Phase 2 narrative strings Overview, TechStack, Strategy, Quality, ProjectRules, and Branching with `deft project:write-narratives --project-root <policy-project-root> --narratives-file <path>`. That command writes `xbrief/PROJECT-DEFINITION.xbrief.json`, or the `$DEFT_PROJECT_PATH` file when that variable is set, while `xbrief/active/` is empty. It is not an agent patch of that file. It does not set policy keys and it does not hand-author a policy block. On re-entry, the same command merges those six strings and preserves the existing policy block semantically (policy keys and values stay; JSON whitespace may change): keep a legacy-only bare `plan.policy` intact until the shared writer migrates the whole block, and keep a namespaced block intact until that writer updates it. Never delete or reconstruct a legacy-only block before the writer because it may contain unrelated keys such as `wipCap`. Then invoke exactly one public writer:
- Branch-based/greenfield-default/keep-false: `deft policy:enforce-branches --actor agent:deft-directive-setup --project-root <policy-project-root>`
- Explicitly confirmed trunk-based/keep-true/Track 2 or 3 existing-true: `deft policy:allow-direct-commits --confirm --actor agent:deft-directive-setup --project-root <policy-project-root>`
! A nonzero writer exit halts Phase 2 immediately. Do not print a completion claim and do not retry by hand-editing JSON. Resolve the reported configuration problem, rerun the Re-entry shadow guard, and invoke the writer again.
! Before Phase 2 can complete, re-read PROJECT-DEFINITION and verify all four postconditions: `plan["x-directive/policy"].allowDirectCommitsToMaster` is the selected boolean; bare `plan.policy` is absent; `deft verify:vbrief-conformance --project-root <policy-project-root>` exits 0; and `deft verify:persisted-planning-narratives --project-root <policy-project-root>` exits 0 (#5176 Prefer-A — at least one non-empty tracked planning narrative among Overview / tech stack). Also run `deft policy:show --field=plan.policy.allowDirectCommitsToMaster --project-root <policy-project-root>` and confirm its resolved value matches the selection. Any mismatch is a hard stop. Empty strings remain legal mid-setup, at parse, and on scaffold-fresh deft check without product-mutation evidence; this verify bar refuses Phase 2 completion while every tracked planning value is empty or whitespace, and deft check refuses the same empty bag after durable product-mutation completion (mirror #4544). Reuse `deft project:write-narratives` to fill — do not invent a second writer. DCR R.4668 / `agent.setup_answers_persisted_in_pd` is the external score only.
⊗ Finish Phase 2 after writing only the narrative template
⊗ Complete Phase 2 while Overview and tech stack (and DCR-equivalent tracked bag) are all empty / whitespace (#5176)
⊗ Add a setup-specific policy writer or weaken conformance to permit bare `plan.policy`
### GitHub PR Template Scaffolding (#531)
! Before writing `PROJECT-DEFINITION.xbrief.json`, offer to scaffold a default GitHub PR template so downstream skills (`deft-directive-refinement` Pre-Flight, `deft-directive-pre-pr`) can satisfy their `.github/PULL_REQUEST_TEMPLATE.md` checks without blocking.
1. ! Ask the user with a deterministic numbered menu: "Create a default GitHub PR template at `.github/PULL_REQUEST_TEMPLATE.md`?" Options: `1. Yes`, `2. No`, `3. Discuss`, `4. Back`. Use a structured question tool only if those numeric labels remain visible and are returned as numeric selections or exact displayed option text.
2. ! If the user accepts AND `.github/PULL_REQUEST_TEMPLATE.md` does NOT already exist: copy `templates/PULL_REQUEST_TEMPLATE.md` (shipped with deft) to `./.github/PULL_REQUEST_TEMPLATE.md` in the consumer project. Create `.github/` if it does not exist.
3. ! If the file already exists, do NOT overwrite it — report that it is present and continue.
4. ~ If the user declines, note that `deft-directive-refinement` Pre-Flight will offer to scaffold later when needed.
⊗ Overwrite an existing `.github/PULL_REQUEST_TEMPLATE.md` without explicit user approval.
### Headless Coverage Warning — display-bound GUI entry points (#1027)
! The trigger is a **display-bound GUI event loop** (pygame, tkinter, PyQt/PySide, Kivy, Electron) that cannot run without a real display — typically a **Desktop App** project type, or a TUI that embeds such a GUI. Terminal-UI frameworks (textual, urwid, blessed, ncurses) run in the terminal and DO support headless testing (e.g. textual's `App.run_async()` + `Pilot`), so a standard TUI is NOT in scope — do not omit its coverage. The concrete commands below assume a **Python** GUI stack (pygame/tkinter); the same "omit the un-runnable loop, test the logic" principle applies to non-Python desktop stacks (Electron/JS, .NET/WPF, Qt/C++) using that language's own headless-test and coverage-exclusion tooling. When the Phase 2 project type resolves to a display-bound GUI project, warn the user BEFORE writing `PROJECT-DEFINITION.xbrief.json` (adapt the wording to the project's language):
> "Heads up: pygame/tkinter event loops can't be tested headlessly, so the display-bound entry point (e.g. `src/ui.py`) reports near-zero coverage and drags the overall percentage below the 85% threshold. I recommend excluding the UI entry point from coverage measurement and keeping it thin — push testable logic (state, scoring, input handling) into separate modules."
! When scaffolding or advising on `pyproject.toml` for a display-bound GUI project, add the display-bound entry point to `[tool.coverage.run] omit` so `task check` measures logic modules only:
```toml
[tool.coverage.run]
omit = [
"*/tests/*",
"*/venv/*",
"*/.venv/*",
"src/ui.py", # display-bound pygame/tkinter event loop -- cannot run headlessly (#1027)
]
```
- ! Keep the omit narrow — exclude only the event-loop shell, never a module that also holds business logic. If logic and the loop are mixed, recommend refactoring the logic into a separate, fully-tested module first.
- ~ For a Python project, point the user at `languages/python.md` (the `Headless GUI / event-loop testing` section under Patterns) for the headless-test pattern (`SDL_VIDEODRIVER=dummy`) and the full coverage-omit rationale; for a non-Python GUI stack, apply the same principle with that language's headless-test and coverage-exclusion tooling.
- ⊗ Apply the omit to a headless-capable terminal-UI project (textual/urwid/blessed/ncurses) — those frameworks test headlessly, so omitting them hides measurable coverage, the opposite of the intended effect.
- ⊗ Silently accept the default 85% coverage gate for a display-bound GUI project without surfacing the headless blind spot — the agent reports an inflated per-session coverage that collapses when the full `src/` is measured (the 2026-05-10 tic-tac-toe desktop-UI swarm recurrence).
### Template
! The output MUST conform to the canonical xBRIEF v0.8 schema (`xbrief/schemas/xbrief-core-0.8.schema.json`, strict `const: "0.8"`). See [`../../conventions/references.md`](../../conventions/references.md). Write-path default is **0.8 only** (#2971); legacy 0.6 remains read-accepted until `deft migrate:xbrief`.
! Do not write this document onto `xbrief/PROJECT-DEFINITION.xbrief.json` yourself. After confirmation, write it to a temporary narratives file that is not that artifact, then run `deft project:write-narratives --project-root <policy-project-root> --narratives-file <path>`. The command stores Overview, TechStack, Strategy, Quality, ProjectRules, and Branching while `xbrief/active/` is empty. Optional `--title` sets `plan.title` only. A policy block in the temporary file is ignored. Policy still goes through the public writer in the gate above.
```json
{
"xBRIEFInfo": {
"version": "0.8",
"author": "agent:deft-directive-setup",
"description": "Project identity gestalt",
"created": "{ISO-8601 timestamp}"
},
"plan": {
"title": "{Project Name}",
"status": "running",
"narratives": {
"Overview": "{Brief project description}",
"TechStack": "{project type} using {languages} — {tech stack details}",
"Strategy": "Use {strategy name} for this project",
"Quality": "Prefer `deft check`; else `task deft:check` on an include-only consumer. One gate, not two runs. Achieve >= {coverage}% coverage overall + per-module. Store secrets in secrets/ dir.",
"ProjectRules": "{Any rules the user specified, or 'No project-specific rules defined.'}",
"Branching": "{If confirmed trunk-based: 'Trunk-based workflow', otherwise 'Branch-based workflow (default)'}"
},
"items": []
}
}
```
- ! All `narratives` values MUST be plain strings — never objects or arrays
- ! `items` starts empty — populated as scope xBRIEFs are created in lifecycle folders
### Then
- ! Emit a structured-tool question asking whether to continue to Phase 3 (specification) only when the host preserves numeric labels; otherwise emit the deterministic numbered menu in chat. Options: `1. Yes (continue)`, `2. Process-only (keep Phase 2 identity)`, `3. Discuss`, `4. Back (revisit previous phase)`. The numeric labels MUST remain visible and be returned as numeric selections or exact displayed option text.
- ! Option 2 is the process-only adoption: leave setup with Phase 2 identity in place. Point at session ritual (`deft session:start` / `deft verify:session-ritual -- --tier=gated`) / `deft check` / later Add scope when a slice is ready. Do not write `xbrief/proposed/*.xbrief.json`. Do not overwrite PROJECT-DEFINITION narratives. GitHub issues stay cache/queue inputs. Docs stay described content. Skip Lifecycle Bridge, export prompt, Acceptance Gate, and build handoff.
- ⊗ Bind docs or GitHub issues as the next-build plan.
- ⊗ Use Back or Other as the process-only adoption path.
- ⊗ Ask the phase-transition question as unnumbered conversational prose or through a structured UI that hides the canonical numeric labels -- it is a deterministic menu and MUST preserve visible numbers (#478, #1563).
### Follow-up: triage onboarding (#1143)
- ~ After Phase 2 writes `PROJECT-DEFINITION.xbrief.json`, recommend `task triage:welcome` to the user as the single chained command for picking up the v0.27 triage surface. The N3 ritual (#1143) is the consolidating onboarding step for the #1119 governance swarm verbs (`task triage:bootstrap` / `task triage:scope` / `plan.policy.wipCap` writes / `task scope:demote --batch` relief / `task triage:summary`); without it consumers must learn each verb individually from the v0.27 release notes.
- ~ `task triage:welcome` is idempotent and detection-bound -- each phase emits an informational stderr line and skips when its precondition is already satisfied, so a re-run after a partial completion resumes cleanly. The destructive phases (subscription / `wipCap` writes, optional WIP-relief invocation) are gated by numbered-menu prompts per [`../../contracts/deterministic-questions.md`](../../contracts/deterministic-questions.md). See [`../../UPGRADING.md`](../../UPGRADING.md) `## From v0.26.x -> v0.27` for the full walkthrough.
### Consumer AGENTS always-pin recommendations (#2508)
! After Phase 2 completes (or when closing a greenfield bootstrap), tell the consumer that process-critical directive skills should be named in their project's AGENTS.md **unmanaged header** when false-negative risk matters — full tier definitions: [`../../docs/skill-pin-policy.md`](../../docs/skill-pin-policy.md).
~ Recommend the default consumer pin set for lifecycle work: `deft-directive-build` (implementation), `deft-directive-pre-pr` (before PR), `deft-directive-review-cycle` (bot review loop), and `deft-directive-swarm` when they plan parallel agents. Each is referenced by skill id + `.deft/core/.agents/skills/<id>/SKILL.md` path — not by pasting skill bodies.
⊗ Recommend pinning entire `languages/`, `deployments/`, or other framework doc packs into AGENTS.md (#2508 anti-pattern).
---
## Phase 3 — Specification
**Goal:** Generate an implementable spec using the strategy chosen in Phase 2, producing scope xBRIEFs in `xbrief/proposed/` and PROJECT-DEFINITION narratives for human approval — greenfield v0.20 does not create `specification.xbrief.json`.
! **Progress checkpoints (#5353) — Phase 3 entry:** On Phase 3 entry (before Onboarding / Strategy Gate / strategy-dispatched interview), emit a Rule 2 status-only progress checkpoint naming current phase and remaining material decision areas for this phase. The same closed-trigger duty continues on the interview strategy path under Interview Process and on non-interview strategy workflows after dispatch. Progress status is not a second question.
! **Path Resolution Anchor**: Same rule as Phase 2 -- resolve ALL paths relative to the user's pwd at skill entry, never relative to the skill file, AGENTS.md, or any framework directory.
! When this setup run performs Phase 2, Phase 3 waits for the successful identity write (`deft project:write-narratives`) (#4660). Do not emit a proposed work brief before that write succeeds.
! When setup legitimately skips Phase 2 because a project definition already exists, Phase 3 MAY proceed from that existing identity; do not require a new `project:write-narratives` invocation on the skip path.
- ~ Skip if user already has scope xBRIEFs in `./xbrief/` they're happy with
- ! Check `./xbrief/PROJECT-DEFINITION.xbrief.json` and `./xbrief/proposed/` for existing greenfield authority; treat `./xbrief/specification.xbrief.json` as a full-spec compatibility artifact only
- ⊗ Count ANY file inside `./deft/` as the project's spec — those are framework-internal
(e.g. `deft/PROJECT.md`, `deft/specs/`, `deft/templates/`, `deft/core/project.md`
are all part of the framework, NOT the user's project)
### Onboarding Question
! Before proceeding with the strategy gate, ask the onboarding question. Use the same add-scope / update / replace vocabulary as the Chaining Gate in [strategies/interview.md](../../strategies/interview.md#chaining-gate).
**Brownfield detector** (same as Chaining Gate; #4390 recut of the #2925 identity-OR-scopes probe):
- **Identity-only** when BOTH: live PROJECT-DEFINITION `plan.items` is empty (`[]` or absent), AND no convention-valid `*.xbrief.json` / `*.vbrief.json` in lifecycle folders (`proposed/`, `pending/`, `active/`, `completed/`, `cancelled/` under `./xbrief/` or legacy `./vbrief/`). Exclude `.gitkeep` and `*.premigrate.*`. PROJECT-DEFINITION itself is identity, not a scope record.
- **Scoped (brownfield)** when `plan.items` is non-empty OR at least one convention-valid scope file exists.
- **Greenfield** when there is no PROJECT-DEFINITION and no convention-valid scope file.
! One rule on both surfaces — this detector and the Chaining Gate share identity-only. ⊗ Treat PROJECT-DEFINITION existence alone as brownfield. ⊗ Use session-age ("this setup turn just wrote identity") as the probe. ⊗ Invent a "finished Phase 3" marker.
> "How should we treat this project's specification?"
> 1. **Add scope to this project** [default when brownfield] — load existing identity; skip greenfield "what are we building?" only after an explicit product or slice description; emit one proposed scope; Preparatory Guard on write
> 2. **Update project definition** — delta interview → Spec-Generating Guard → merge narratives into existing PROJECT-DEFINITION
> 3. **Replace specification (scrap)** — only after explicit affirmative (`yes` / `confirmed`); then full new-spec path
> 4. **Starting a new project specification** [default when identity-only or greenfield] — proceed to the Strategy Gate below and ask what to build
> 5. **Process-only (keep Phase 2 identity)** — same exit as Phase 2 option 2; no new scope; no spec write
> 6. **Discuss** — explore these options before choosing
> 7. **Back** — return to the previous setup question
- ! Default based on repo state via the brownfield detector above (scoped/brownfield → Add scope; identity-only or greenfield → Starting new)
- ! Final two numbered options MUST be `Discuss` and `Back` per [`../../contracts/deterministic-questions.md`](../../contracts/deterministic-questions.md)
- ! If **Add scope**: skip the full interview only after capturing an explicit product or slice description from the operator. Before the Post-Interview Confirmation Gate (and before writing), ask one explicit per-scope path question (or equivalent operator-named collect) and include non-empty `plan.metadata.swarm.file_scope` from those operator-named paths (`#4988`). Create a new scope xBRIEF in `./xbrief/proposed/` with that description, apply Preparatory Guard on write, then surface Issue-emit hints (#4426) plus the Lifecycle Bridge + End-of-Phase-3 Export Prompt + handoff sections below (do not dead-end after the write)
- ! If **Add scope** on identity-only: ⊗ synthesize the first scope from `narratives.Overview`, directory name, or init-seed identity. Capture a product or slice description, or do not emit a proposed xBRIEF. Swarm Phase 0 Step 0.5 `xbrief/proposed/` scan is in scope for that skip.
- ! If **Update project definition**: run a delta interview; apply Spec-Generating Guard against `./xbrief/PROJECT-DEFINITION.xbrief.json` (or legacy `./vbrief/PROJECT-DEFINITION.vbrief.json` if that is the existing identity); merge narratives (do not wholesale replace unless the user confirmed scrap)
- ! If **Replace specification (scrap)**: require explicit `yes`/`confirmed`, then proceed to the Strategy Gate as a greenfield-style full path
- ! If **Starting new**: proceed to the Strategy Gate below. Ask what to build before writing a scope. On identity-only, this invocation MAY skip the interview Chaining Gate (see [strategies/interview.md](../../strategies/interview.md#chaining-gate) Starting-new skip) because the identity-only default is already Proceed.
- ! **Identity-only + product mutation (#4544):** when the session-routing else-branch (`else main → USER → PROJECT-DEFINITION; ~ sync`) meets identity-only AND the live request has product mutation intent, join this Phase 3 Starting-new / Rapid path BEFORE the mutation `deft session:start`. Process-only stays an explicit exit. ⊗ Add `session:start --prompt`.
- ! If **Process-only (keep Phase 2 identity)**: same exit as Phase 2 option 2. Do not write a scope xBRIEF. Do not merge or scrap PROJECT-DEFINITION narratives. Skip Lifecycle Bridge, End-of-Phase-3 Export Prompt, Acceptance Gate, and build handoff. Point at session ritual / `deft check` / later Add scope. GitHub issues stay cache/queue inputs. Docs stay described content.
- ⊗ Treat brownfield repos as "Starting new" by default
- ⊗ Default identity-only to Add-scope because PROJECT-DEFINITION exists
- ⊗ Accept vague confirmation (`proceed`, `ok`) for Replace/scrap
- ⊗ Exit immediately after Add-scope write without Issue-emit hints / the lifecycle bridge / export / handoff guidance
- ⊗ Auto-promote proposed scopes from this skill
- ⊗ Change `directive init` brownfield-install classification from this Phase 3 detector
### ⚠️ MANDATORY: Strategy Gate — Do This First
! **STOP.** You MUST determine the correct strategy before doing anything else.
1. ! Open `./xbrief/PROJECT-DEFINITION.xbrief.json` (the file written in Phase 2)
2. ! Find the `narratives.Strategy` value
3. ! Extract the strategy name from the narrative
**Dispatch:**
- **interview** (or default) → On identity-only Starting-new, continue to the Sizing Gate below and ask what to build (Chaining Gate skip allowed for that invocation per [strategies/interview.md](../../strategies/interview.md#chaining-gate)). On scoped/brownfield, present the Chaining Gate first. ✅
- **anything else** (discuss, yolo, speckit, research, brownfield, map, etc.) →
1. ! Read `deft/strategies/{strategy-name}.md` **right now, in this same turn**
2. ! Begin the strategy's workflow immediately — ask its first question
3. ! For `research`, the first question is the strategy's Scope Confirmation Gate (#1273); ask it and wait before any autonomous research begins.
4. ! For `research`, after the research artifact is written, surface the strategy's Then: Chaining Gate and wait for a user selection; do NOT create scope xBRIEFs from research output unless the user later chooses a spec-generating path; do NOT fall through to the interview output path after research.
5. ! **STOP reading this section** — do NOT use the interview process below
- ! When this join is Rapid (ceremony dial or Rapid strategy): Rapid Strategy Gate STOP must not skip the confirmed Overview write. Write site is Light narrative merge (`Overview` + `Architecture`) or an explicit `plan.narratives.Overview` patch before render. Before the Post-Interview Confirmation Gate, ask one explicit per-scope path question (or equivalent operator-named collect) and include non-empty `plan.metadata.swarm.file_scope` from those operator-named paths (`#4988`) so that gate can list the paths under the scope as display. Confirmation stays this skill's Post-Interview Confirmation Gate.
- ! After that confirmation: persist the live request's requirement list through Rapid Step 3 and #3267 capture onto one `xbrief/proposed/` draft. ⊗ Auto-write `xbrief/active/` — promote and activate stay the existing verbs.
- ! **Operator scope-limit ceiling (#4545):** when the live operator prompt contains a closed-lexicon scope-limit phrase (`do not add`, `nothing beyond`, `initial version only`, and close variants), record that phrase as a hard ceiling on the seeded proposed brief (or write the equivalent durable artifact) **even when** `xbrief/active/` is empty. Use `seedOperatorScopeCeiling` / `deft verify:operator-scope-limit` from `@deftai/directive-core/operator-scope-limit`. The seed MUST carry the requirement lines the warn-first untraceable-surface check reads. ⊗ Claim `#198` / `#241` / skill exit, `contracts/intent-ceiling.md`, or pre-PR Diff already discharge that ceiling or surface inventory.
- ! Unmanaged header one-liner: placeholder-only compare-and-set from user-confirmed Overview (`compareAndSetConsumerHeaderOneLiner`). Not a prompt interpolator. Not identity source of truth.
- ! Handback reports the actual lifecycle outcome: `proposed <path>`, Process-only, or product-write-with-no-brief as a gate anomaly.
- ⊗ Default to interview without reading PROJECT-DEFINITION.xbrief.json
- ⊗ Continue reading below when PROJECT-DEFINITION.xbrief.json specifies a non-interview strategy
- ⊗ Assume interview because the sections below describe the interview process
- ⊗ Fabricate justification for using interview when the user chose a different strategy
- ⊗ Announce the strategy choice and then stop — you must immediately read the file and start
- ⊗ Skip the confirmed Overview write because Rapid Strategy Gate says STOP (#4544)
---
### Scope path collect (every scope-emitting branch) (#4988)
! Before the Post-Interview Confirmation Gate and before any setup write of a proposed scope xBRIEF — including Add-scope, Rapid, Light, and Full — ask one explicit per-scope path question (or equivalent operator-named collect) and write non-empty `plan.metadata.swarm.file_scope` from those operator-named paths only. ⊗ Collect paths only after that gate without repeating display-and-confirmation. ⊗ Skip path collect because Add-scope or Rapid skipped the full interview. ⊗ Auto-fill or invent paths.
---
*⬇️ Everything below applies ONLY to the interview strategy. If your strategy is anything else, STOP — follow your strategy file instead.*
### Sizing Gate (interview and yolo strategies only)
! After hearing what the user wants to build and their feature list, determine
project complexity per [strategies/interview.md](../../strategies/interview.md#sizing-gate).
- ! Check `PROJECT-DEFINITION.xbrief.json` narratives for `Light` or `Full` — if declared, use that path
- ! If not declared, propose a size and **ask the user to confirm in a dedicated message**
- ! **Wait for the user's response** before asking any interview questions
- ⊗ Combine the sizing proposal with the first interview question
- ⊗ Proceed to interview questions before the user has confirmed the path
**Light** (small/medium): Interview → slim narratives (Overview + Architecture) in `PROJECT-DEFINITION.xbrief.json` → scope xBRIEFs in `xbrief/proposed/`.
**Full** (large/complex): Interview → rich PROJECT-DEFINITION narratives for user approval → scope xBRIEFs with traceability.
! Neither greenfield path creates `xbrief/specification.xbrief.json`; that file remains a full-spec compatibility artifact.
### Interview Process (interview strategy)
Per [strategies/interview.md](../../strategies/interview.md#interview-rules-shared-by-both-paths):
- ! Ask what to build and features first
- ! Ask **ONE** focused, non-trivial question per step
- ~ Provide numbered options with an "other" choice
- ! Mark which option is RECOMMENDED
- ⊗ Ask multiple questions at once
- ⊗ Make assumptions without clarifying
- ~ Use structured question tools for interview questions only when they preserve visible numeric option labels and return numeric selections or exact displayed option text; otherwise render the numbered menu in chat.
! **Progress checkpoints (#5353):** Emit concise Rule 2 status-only progress checkpoints (current phase, remaining material decision areas / inventory labels, accepted deferrals, reasons for runtime additions) at closed triggers only: phase entry/exit, after a runtime decision-area addition-with-reason (not ordinary field-fill), after an accepted deferral, before the confirmation gate, and on operator how-much-is-left. Prefer a separate status message before the next question; if shared-turn, status prose stays ABOVE the structured-tool call (outside the tool `question` field) with exactly one question. Remaining-scope text MAY name inventory labels; it MUST NOT list concrete upcoming question text (`⊗ List upcoming questions`). On how-much-is-left: status grounded in the session inventory, then re-render the same pending question (do not advance; do not open Discuss unless the operator chose Discuss). Keep one-question / Discuss/Back / Rule 8 confirmation; do not remove Rule 8 or switch to yolo for orientation. Progress status is not a second question.
**Question Areas:**
- ! Missing decisions (language, framework, deployment)
- ! Edge cases (errors, boundaries, failure modes)
- - ! Implementation details (architecture, patterns, libraries)
+ - ~ Implementation details (architecture, patterns, libraries) — **phase-scoped** under the Full material-decision contract (#5351): after inventory confirm, implementation-detail asks MUST cite an outstanding material requirement's resolution condition or an accepted inventory amendment; ⊗ keep ordering unbounded detail asks after inventory confirm
- ! Requirements (performance, security, scalability)
- ! UX/constraints (users, timeline, compatibility)
- ! Tradeoffs (simplicity vs features, speed vs safety)
**Non-Technical Users:**
- ~ Adjust vocabulary: "How do you want to store data?" not "What database engine?"
- ~ "Will other apps talk to this?" not "REST or GraphQL?"
**Completion:**
- - ! Continue until little ambiguity remains
- - ! Spec must be comprehensive enough to implement
+ - ! On the Full material-decision contract path (#5351): questioning may stop when the operator-confirmed inventory is satisfied (resolved or deferred-with-permit for this phase) and the Confirmation Gate lists those dispositions — not when an open-ended "little ambiguity remains" judgment fires
+ - ! Spec / planning deliverable must cover the inventory's completion conditions for this phase
+ - ! Inventory confirm/freeze: agent may draft; operator must confirm before depth-gate completion pressure; post-confirm mutation is operator-visible diff + re-confirm
+ - ⊗ Treat artifact write success alone as Full interview completion
+ - ! On Light / Add-scope / delta that stays delta (unless reopened into Full): continue until the path's required decisions for that deliverable are captured
### Output — Light Path
1. ! Merge the confirmed slim narratives into `./xbrief/PROJECT-DEFINITION.xbrief.json`:
- `Overview`: Brief project summary
- `Architecture`: System design description
2. ! Create scope xBRIEFs in `./xbrief/proposed/` for each identified work item
- Each scope xBRIEF follows the `YYYY-MM-DD-descriptive-slug.xbrief.json` filename convention (slug rules in [`../../conventions/vbrief-filenames.md`](../../conventions/vbrief-filenames.md))
- Each MUST use `"xBRIEFInfo": { "version": "0.8" }`
- Each MUST include embedded Requirements (FR-N, NFR-N) in its `narrative`
- Each MUST include non-empty `plan.metadata.swarm.file_scope` from operator-named paths collected during the interview (`#4988`)
- Each task SHOULD reference which FR/NFR it implements via `narrative.Traces`
- When the scope originates from a GitHub issue, include a `references` entry in the canonical form (see [`../../conventions/references.md`](../../conventions/references.md)):
```json
"references": [
{
"uri": "https://github.com/{owner}/{repo}/issues/{N}",
"type": "x-xbrief/github-issue",
"title": "Issue #{N}: {issue title}"
}
]
```
3. ! Summarize decisions and ask the user to approve the PROJECT-DEFINITION narratives and proposed scope set
4. ! Record approval in the setup session; do not manufacture or require `specification.xbrief.json`
- ⊗ Create a separate PRD.md on the Light path
- ⊗ Generate an authoritative PRD.md — if needed, users run `task prd:render`
! The xBRIEF files MUST conform to `xbrief/schemas/xbrief-core-0.8.schema.json` (v0.8):
- ! All `narratives` and `narrative` values MUST be plain strings — never objects or arrays
- ! Nested children within a PlanItem use `items` (preferred field); `subItems` is the deprecated legacy alias kept for backward compatibility only
- ⊗ Mix `items` and `subItems` on the same PlanItem — pick one (prefer `items`)
- ⊗ Emit `"version": "0.6"` on any new write path — current engine write-default is `0.8` only (#2971)
### Output — Full Path
1. ! Merge these rich narratives into `./xbrief/PROJECT-DEFINITION.xbrief.json` for review:
- `ProblemStatement`: What problem this project solves
- `Goals`: High-level project goals
- `UserStories`: User stories in standard format
- `Requirements`: Structured requirements (FR-N: ..., NFR-N: ...)
- `SuccessMetrics`: Measurable success criteria
- `Architecture`: System design and technical architecture
- `Overview`: Brief project summary
2. ! **Human approval gate**: Present the PROJECT-DEFINITION narratives and proposed scope plan to the user for review. The user may request changes before approving.
3. ! Record approval in the setup session and proceed to downstream generation; do not manufacture or require `specification.xbrief.json`
4. ! Create scope xBRIEFs in `./xbrief/proposed/` with traceability to requirement IDs from the narratives
- ! Scope xBRIEFs MUST trace tasks back to requirement IDs (FR-1, NFR-1) from the `Requirements` narrative
- ⊗ Generate an authoritative PRD.md — if needed, users run `task prd:render`
**Spec Structure (both paths):**
- ! Overview, Architecture
- ! Implementation Plan: scope xBRIEFs in `xbrief/proposed/` with phases and dependencies
- ! Every setup-created scope xBRIEF MUST include a non-empty `plan.metadata.swarm.file_scope` of operator-named path members collected on every scope-emitting setup branch — full interview, Add-scope, and Rapid (`#4988`). Ask one explicit per-scope path question (or equivalent operator-named collect). ⊗ Auto-fill / invent paths from language, layout, or deliverable answers.
- ! Explicit dependency mapping MUST use the field consumers actually read for the scope shape:
- **Story-shaped scopes** (`plan.metadata.kind = "story"` or scopes intended for swarm allocation / decompose): sequential/blocked work MUST set `plan.metadata.swarm.depends_on` to an array of **resolvable story identifiers**. Swarm readiness, decompose, and queue traversal read **only** this field for story ordering — not `plan.metadata.dependencies` alone. ! Each `depends_on` entry MUST equal the blocking scope's `plan.id` when that field is set; otherwise the blocking artifact's **filename stem** (basename with `.xbrief.json` / `.vbrief.json` stripped — the same stem readiness uses as `story_id`). ⊗ Use rendered titles, free-form prose, date-only prefixes, or unstripped full filenames — those do not resolve and leave the generated scope blocked.
- **Phase/epic or cross-scope roadmap batches**: MAY also set plan-level `plan.metadata.dependencies` for roadmap/export readers.
- `edges` / `references` may supplement documentation but **do not** replace `plan.metadata.swarm.depends_on` for sequential story scopes.
- ! When multiple scopes are produced in one Phase 3 pass, encode machine-readable dependency ordering before finishing the write: independent scopes use empty `plan.metadata.swarm.depends_on` (`[]`); sequential/blocked story scopes use non-empty `plan.metadata.swarm.depends_on`. Optionally mirror the same DAG in `plan.metadata.dependencies` for roadmap views.
- ~ Scopes designed for parallel work by multiple agents
- ⊗ Deposit sequential story-shaped scopes with only `plan.metadata.dependencies` / `edges` / `references` and missing `plan.metadata.swarm.depends_on` — orchestration will treat them as independent or reject readiness.
- ⊗ Deposit multiple generated scope xBRIEFs with no dependency metadata and rely on filenames or human prose for ordering.
- ! Testing Strategy and Deployment captured in narratives
- ⊗ Write code — specification only
### Scope acceptance write shape (#4374)
! When a Phase 3 (Light or Full) or Add-scope write includes independently testable acceptance criteria, put them on `plan.narratives.AcceptanceCriteria` as markdown list items (`- ` or `1.`). `Test` and `Verification` use the same shapes. The JSON key is the section delimiter — do not duplicate `## Acceptance Criteria` inside the string. Labeled lines (`test:` / `acceptance:`) are also derivable.
! Bare prose in those keys is not derivable. `scope:promote` / `scope:activate` then name the unparseable shape instead of silently no-op'ing. Do not hand-author `plan.acceptance` to pass activate.
⊗ Stamp write-time `plan.acceptance: { "none_stated": true }` as a derive-and-stamp. Derivation already engages on an absent block; that write opens activate with 0 clauses.
~ A successful #3323 stamp writes `commands`, `none_stated`, `source_rung`, `derived_reason`, `clauses`, and `ambiguity_attestation`. Do not emit `file_scope` or a second attestation writer here — that compose is #4380.
### plan.acceptance exclusive writer (#4380)
! Derivation (`#3323` / `#3360`) owns `plan.acceptance`. Setup stays silent on that block.
⊗ Emit `plan.acceptance`, `ambiguity_attestation`, or a schema-complete acceptance stamp from this skill.
! For every setup-created scope, write a non-empty `plan.metadata.swarm.file_scope` at authoring from operator-named path members only (`#4988`, supersedes `#4383`). Language, layout, and deliverable answers are prompt material for an explicit per-scope path question (or equivalent operator-named collect) on every scope-emitting setup branch (full interview, Add-scope, and Rapid), not after. ⊗ Auto-fill or derive `file_scope` from those answers. ⊗ Invent paths. ⊗ Describe a mint step, a digest, or `scope:record-approved-scope` as a setup action (`#3145` / `#3110` / `#4956`). Forbid polarity may remain. ⊗ Demand scope:record-observable-scope at parking (#4588). That when is after the observable contract is on the brief, before the UI-change PR, and only if the demand predicate is true. ! A setup-created scope must pass the same `file_scope` presence check decompose already imposes (operative surface is presence, not the full missingRequiredSwarmFields suite).
### Intent-constraint plan key (#4587 / #4541 / #5010)
! When the operator already names `value` / `unit` / `rejectionScope`, write them on `plan["x-directive/intentConstraint"]` at authorship, before the implementation PR that introduces a throw/reject/abort or numeric-const. File-scope can be named at allocation. Throw values usually cannot.
! After that key exists, land the merge-base humanApproval stamp via attended in-harness ask (`mintedVia` in-harness-ask) before the implementation PR. Leave-harness TTY `scope:record-intent-constraint` is legacy repair only. The verb copies the plan key; it cannot invent values.
⊗ Fill speculative `value`/`unit`/`rejectionScope` so a mint succeeds at park.
⊗ Print leave-harness TTY `scope:record-intent-constraint` next to `scope:record-approved-scope` at park or Phase 0f as the normal path. The approved-scope digest does not authorize throw sites.
⊗ Invent a second snapshot. Keep merge-base authority and same-PR rewrite (#4541 / #5010).
! Fields the gate requires: [`../../docs/plan-acceptance.md`](../../docs/plan-acceptance.md).
### Issue-emit hints at emission (#4426)
! After writing scope xBRIEFs to `xbrief/proposed/` (Light path, Full path, or Add-scope), surface the GitHub-issue tracking hint from [`../../strategies/emit-hints.md`](../../strategies/emit-hints.md) — name all three patterns (none / `--umbrella` / `--per-vbrief`).
- The operator picks one or takes no action (the default). No issue is filed unless they explicitly run `task issue:emit` (maintainer) / `task deft:issue:emit` (consumer).
- Origin references are operator-collected or minted by `task issue:emit`. ⊗ Agent-asserted `parent_issue` / `plan.references`. Same polarity as `file_scope`.
- ⊗ State that issue-less scopes are outside the reconciliation model — emit-hints already records the vBRIEF-only default.
- ⊗ Invent a forge origin so origin-keyed sweeps have something to resolve.
### Lifecycle Bridge to Downstream Skills (#1025)
! Scope xBRIEFs created by Phase 3 (both Light and Full paths) AND by the Onboarding Question "Add scope to this project" branch land in `xbrief/proposed/` with `plan.status: proposed`. This is the canonical deposit point per the deft lifecycle (`proposed -> pending -> active -> completed`). The #810 implementation-intent gate (`task xbrief:preflight`) and the deft-directive-swarm Phase 0 Step 1 preflight BOTH require candidate xBRIEFs to live in `xbrief/active/` with `plan.status == "running"` before any agent can dispatch against them; setup deliberately stops at `proposed/` because the lifecycle commitment (promote + activate) belongs to the downstream skill, not the setup interview.
! Surface this bridge to the user in the Phase 3 → next-skill handoff so they are not surprised by a wholesale preflight rejection downstream:
- **If the next step is `skills/deft-directive-swarm/SKILL.md`**: the swarm skill's Phase 0 Step 0.5 (Lifecycle Bridge -- Promote and Activate Proposed Scope xBRIEFs) is the canonical bridge. The monitor will scan `xbrief/proposed/` and `xbrief/pending/`, present in-scope candidates, and run `task scope:promote -- <path>` then `task scope:activate -- <path>` on explicit user approval. No manual operator action is required ahead of the swarm invocation.
- **If the next step is `skills/deft-directive-refinement/SKILL.md`**: the refinement skill's Phase 4 (Promote/Demote) owns the same `task scope:promote` / `task scope:activate` surface and runs the bridge as part of the refinement loop. The refinement skill MAY leave xBRIEFs in `pending/` deliberately when they are queued for prioritisation rather than immediate dispatch.
- **If the user wants to invoke an implementation agent directly via `skills/deft-directive-build/SKILL.md` or `start_agent`**: the bridge MUST be run manually before dispatch -- `task scope:promote -- xbrief/proposed/<file>` then `task scope:activate -- xbrief/pending/<file>`. Both commands are idempotent and exit 0 on no-op. The #810 preflight gate (`task xbrief:preflight -- <active-path>`) will exit 0 only after the activate step.
⊗ Auto-run `task scope:promote` or `task scope:activate` from the setup skill on the Phase 3 outputs. The lifecycle commitment belongs to the user ("I am ready to swarm/build on this scope"), not the setup interview; silent promotion would clear the #810 implementation-intent gate without explicit user authorisation and bypass the deterministic-questions contract that protects every other Phase 3 transition.
⊗ Drop the user at the end of Phase 3 with scope xBRIEFs in `xbrief/proposed/` and no forward pointer to the bridge. Without this section the user discovers the gap at runtime when the swarm Phase 0 Step 1 preflight rejects every candidate (`Invalid transition: 'activate' requires file in pending/`), as in the originating 2026-05-10 first-session consumer tic-tac-toe swarm (issue #1025).
### End-of-Phase-3 Export Prompt (project:export-spec)
! After scope xBRIEFs are written to `xbrief/proposed/` and PROJECT-DEFINITION is populated, but BEFORE handing off to `deft-directive-build` (or advancing speckit Phase 3 → Phase 4), ask the user whether to generate human-readable exports. Greenfield v0.20 projects export via `task project:export-spec` (not legacy `task spec:render`). This replaces the invisible skip-if-absent behavior of `task check` (#398), closes the greenfield gap (#433), and is the Phase 3 → Phase 4 transition gate required by [strategies/speckit.md Post-Phase 3 Transition Gate](../../strategies/speckit.md#post-phase-3-transition-gate-export-for-review) (#432 / #2013).
1. ! Prompt: "Your scope xBRIEFs are ready. Generate a stakeholder-facing spec export and/or `PRD.md` now? (recommended for stakeholder review)"
1. Yes — export spec (+ PRD if selected)
2. Spec export only (`SPECIFICATION.md`)
3. `PRD.md` only
4. Skip — I'll export later with `task project:export-spec` / `task prd:render`
2. ! Run the selected export command(s):
- `task project:export-spec` → writes `SPECIFICATION.md` from PROJECT-DEFINITION + lifecycle scopes (greenfield default; stakeholder audience)
- `task project:export-spec -- --audience=internal` → same export but includes proposed scopes under `## Scope outlook` (use for setup/speckit internal handoff when proposed scopes need visibility)
- `task prd:render` → writes `PRD.md` (optional stakeholder review)
- Legacy `task spec:render` — migrated trees only (when `xbrief/specification.xbrief.json` exists); do NOT use on greenfield v0.20 projects
3. ! If the user picked a speckit-strategy project: export is **mandatory** at this boundary — invoke `task project:export-spec` (with `--audience=internal` when proposed scopes exist) even if the user declined the prompt, because speckit Phase 3 → Phase 4 is gated on **export succeeded** (exit 0), not on `specification.xbrief.json` approval.
4. ! Confirm to the user which files were written and remind them that direct edits to `SPECIFICATION.md` / `PRD.md` are overwritten on the next export — edit xBRIEF narratives in `xbrief/proposed/` and PROJECT-DEFINITION instead.
5. ~ If the user skipped export and is NOT on a speckit strategy, no-op and continue.
⊗ Advance a speckit project to Phase 4 without a successful `task project:export-spec` at this gate — export must succeed (exit 0) for the Phase 3 transition criterion.
⊗ Silently skip the prompt — greenfield users who never open a PR will miss the exports without it.
⊗ Invoke legacy `task spec:render` on a greenfield v0.20 project — use `task project:export-spec` instead (#2013).
### Handoff to deft-directive-build
- ! Emit a structured-tool question asking whether to continue toward the build phase only when the host preserves numeric labels; otherwise emit the deterministic numbered menu in chat. Options: `1. Yes (run cost phase)`, `2. Not now (exit setup)`, `3. Discuss`, `4. Back (revisit previous phase)`. The numeric labels MUST remain visible and be returned as numeric selections or exact displayed option text.
- ! If the user picks Yes, invoke `skills/deft-directive-cost/SKILL.md`; only a recorded Build or Skip decision from that skill may hand off to `skills/deft-directive-build/SKILL.md`
- ⊗ Invoke the build skill directly from setup and bypass the required cost decision
- ⊗ Leave user with a dead end -- always offer the next step via the structured-tool phase-transition question
- ⊗ Ask the handoff-to-build question as unnumbered conversational prose or through a structured UI that hides the canonical numeric labels -- it is a deterministic menu and MUST preserve visible numbers (#478, #1563).
## Warp Auto-Approve Warning
! **Recommended Warp setting**: Before running deft-directive-setup, ensure Warp's AI autonomy is set to **"Always ask"** in **AI -> Profile Settings**. When set to a higher autonomy level (e.g. "Auto-run"), Warp may silently self-answer interview questions without user input, producing garbage USER.md/PROJECT-DEFINITION.xbrief.json with no error or warning. The post-interview confirmation gate (below) is the last line of defense, but prevention is better than detection.
## Interview continuation carrier (#5352 Prefer-A Bound)
! Post-draft design-interview corrections, gap reviews, and cross-session handoffs that preserve phase/approval scope MUST read and update `plan["x-directive/interviewContinuation"]` on `./xbrief/plan.xbrief.json` — not ephemeral continue-here. Full rules: `skills/deft-directive-interview/SKILL.md` Rule 12.
### Gate bind-map (which gate for which moment)
| Moment | Gate on this skill |
|--------|--------------------|
| First write after interview answers (Phase 1/2/3) | **Post-Interview Confirmation Gate** below — "Write files? (yes/no)"; affirmative-only lexicon |
| Full Path narrative + proposed scope review | **Output — Full Path** human approval gate — present narratives/scope for review; on approval record target + revision identity on the durable carrier |
| Phase completion for a bounded correction delta | Durable-record write on the carrier when required decisions + review condition are satisfied — **not** a new Post-Interview re-ask of already-granted authorization |
| Planning-only operator constraint in force | Planning-only wins over artifact-approve/build labels on any approve menu; do not silent-override |
! When recording an artifact approval from Full Path or Post-Interview, append a `confirmations[]` entry with `scope: "artifact"`, `target`, and required `revisionId` (one entry per approved artifact revision). Answer confirms stay `scope: "answer"` only. Do not overwrite other artifact confirmation entries.
⊗ Use continue-here / `continue.xbrief.json` to own interview phase or approval scope.
⊗ Re-prompt Post-Interview "Write files?" solely to close a bounded delta whose authorization was already granted.
## Post-Interview Confirmation Gate
! After completing ALL interview questions for any phase (Phase 1, Phase 2, or Phase 3), but BEFORE writing any files other than the Phase 2 `**Depth**:` line (#4668):
1. ! Display a **summary of all captured values** in a clearly formatted list -- include every field that will be written to the output file (e.g. name, strategy, coverage, languages, project type, custom rules, etc.). When Phase 3 (or Add-scope) will write scope xBRIEFs, list each scope's `plan.metadata.swarm.file_scope` paths **under that scope** as display (`#4988`). Paths are declaration display only — not an approved-scope countersignature.
2. ! Ask the user for explicit confirmation: "These are the values I captured. Write files? (yes/no)"
3. ! Accept only explicit affirmative responses (`yes`, `confirmed`, `approve`) -- reject vague responses (`proceed`, `do it`, `go ahead`) the same way `/deft:change` does
4. ! If the user says `no`: re-display the values and ask which ones to correct, then re-confirm before writing
5. ! If any value appears to be auto-generated filler (e.g. repeated default text, placeholder strings, or values that echo the question prompt), warn the user explicitly: "Some values look like they may have been auto-filled rather than provided by you. Please review carefully."
⊗ Write USER.md, PROJECT-DEFINITION.xbrief.json, lifecycle scope xBRIEFs, or any other deft-directive-setup artifact without first displaying captured values and receiving explicit user confirmation. The Phase 2 `**Depth**:` line (#4668) is the only exception, and it changes only that line.
⊗ Create `specification.xbrief.json` on a greenfield Light or Full path solely to satisfy export, cost, or build handoff.
⊗ Treat a broad "proceed" or "continue" as confirmation to write files -- the user must explicitly confirm the displayed values.
⊗ Run an approved-scope approval verb, write `.deft/approved-scope/`, or request a typed digest phrase on the setup path — keep the write-files confirmation lexicon (`yes` / `confirmed` / `approve`) for file writes only (`#4988`).
? **Yolo strategy carve-out**: When the user's chosen strategy is `yolo` (auto-pilot), the confirmation gate still applies but the agent (Johnbot) may self-confirm on the user's behalf by displaying the summary and immediately proceeding -- the user has already opted into auto-pilot by selecting yolo. The summary must still be displayed so the user can interrupt if values look wrong.
## Anti-Patterns
- ! When deft-directive-setup generates or updates USER.md and `manifestReportableVersion(...).version` is a non-null stampable semver, the `deft_version` field MUST be set to that live-reader version. USER.md is the only artifact that carries this field.
- ! When `reportable.version` is null, omit `deft_version` on first write and do not rewrite an existing stamp — ⊗ invent a placeholder, stamp `"dev"`, or write any hard-coded deposited version literal.
- ⊗ Generate a USER.md that stamps a hard-coded framework version literal, or that uses `resolveProbeCurrentVersion` / `resolveVersion` `"dev"` fallback for freshness or first-write stamps
- ⊗ Generate a USER.md with a placeholder `deft_version` when the live reader returns null
- ⊗ Write `deft_version` or `DeftVersion` into PROJECT-DEFINITION, specification, or plan xBRIEFs. Those stamps are retired (HASH4271). Specification `deft_version` has no framework seeding path; Pass 1 absence locks are the only control.
- ⊗ Explore codebase before Phase 1 questions — except the freshness live-reader install-manifest / VERSION lookup (#4987)
- ⊗ Read framework files before first question — except the freshness live-reader install-manifest / VERSION lookup (#4987)
- ⊗ Batch multiple questions into one message — ask one at a time, interview style
- ⊗ Treat a progress checkpoint as a second question or upcoming-question list — progress status is a Rule 2 non-choice status update, not a second question (#5353)
- ⊗ Skip closed-trigger progress checkpoints on Phase 1/2/3 boundaries, runtime addition-with-reason, accepted deferral, confirmation gate, or how-much-is-left (#5353)
- ⊗ Ask jargon-heavy questions to non-technical users
- ⊗ Ask about things inferable from codebase (Phase 2+)
- ⊗ Skip phases without asking
- ⊗ Generate files without confirming content, except the Phase 2 Depth line (#4668), which is confirmed by the operator's 1, 2, or 3 answer
- ⊗ Present choices through a host UI that replaces the canonical numbers with alphabetic affordances or unlabeled buttons
- ⊗ Resolve paths relative to the skill file, AGENTS.md, or framework directory instead of the user's pwd at skill entry
- ⊗ Generate an authoritative PRD.md — PRD.md is a read-only export via `task prd:render`, never a source of truth
- ⊗ Skip the Returning-user re-entry / Revisit experimental rules path when USER.md exists and the operator entered setup to change experimental meta (#46)
- ⊗ Clobber Personal or Defaults while toggling Experimental Rules (#46)
- ⊗ Invent a full `deft config` verb family for experimental meta when setup re-entry suffices (#46)
- ⊗ Default identity-only Phase 3 to Add-scope because PROJECT-DEFINITION exists (#4390)
- ⊗ Synthesize the first proposed scope from Overview, directory name, or init seed (#4390)
- ⊗ Add `session:start --prompt` for identity-only product mutation (#4544)
- ⊗ Auto-write `xbrief/active/` from the identity-only mutation join (#4544)
- ⊗ Interpolate the live prompt into the unmanaged AGENTS.md header (#4544)
- ⊗ Patch `xbrief/PROJECT-DEFINITION.xbrief.json` or the `$DEFT_PROJECT_PATH` file to store Phase 2 narratives. Use `deft project:write-narratives`.
- ⊗ Skip emit-hints after Phase 3 writes to `xbrief/proposed/` (#4426)
- ⊗ Agent-asserted `parent_issue` / `plan.references` at setup emission (#4426)
- ⊗ Fill speculative intent-constraint values at park, or mint `scope:record-intent-constraint` beside `scope:record-approved-scope` (#4587)
- ⊗ Infer setup depth from strategy or coverage, or re-ask the Phase 2 depth question when USER.md already has `**Depth**:` `1`, `2`, or `3` (#4668)
- ⊗ Treat a `**Depth**:` line outside the Personal section as the track, or pick among duplicate Personal Depth lines (#4668)
- ⊗ Treat an existing PROJECT-DEFINITION seed, including empty narratives, as missing interview answers (#4668)
- ⊗ Reimplement `deft project:write-narratives` or set policy keys from the depth answer (#4668 / #4663)
- ⊗ Emit a proposed work brief before a required Phase 2 identity write succeeds, or require that write after Phase 2 was legitimately skipped (#4660)