@deftai/directive-content 0.59.0 → 0.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/.githooks/pre-commit +10 -128
  2. package/.githooks/pre-push +8 -108
  3. package/Taskfile.yml +48 -58
  4. package/UPGRADING.md +19 -3
  5. package/docs/assets/directive-lifecycle-diagram.png +0 -0
  6. package/docs/directive-lifecycle.md +73 -0
  7. package/docs/getting-started.md +5 -1
  8. package/package.json +3 -3
  9. package/packs/skills/skills-pack-0.1.json +1 -1
  10. package/packs/strategies/strategies-pack-0.1.json +19 -19
  11. package/scm/github.md +37 -6
  12. package/skills/deft-directive-setup/SKILL.md +24 -15
  13. package/strategies/speckit.md +14 -14
  14. package/strategies/v0-20-contract.md +12 -1
  15. package/tasks/change.yml +16 -31
  16. package/tasks/ci.yml +8 -0
  17. package/tasks/commit.yml +12 -19
  18. package/tasks/core.yml +10 -0
  19. package/tasks/engine.yml +42 -0
  20. package/tasks/framework.yml +3 -0
  21. package/tasks/install.yml +20 -19
  22. package/tasks/migrate.yml +26 -15
  23. package/tasks/project.yml +26 -0
  24. package/tasks/toolchain.yml +15 -5
  25. package/tasks/vbrief.yml +4 -3
  26. package/tasks/verify.yml +12 -14
  27. package/templates/agents-entry.md +1 -1
  28. package/scripts/_agents_md.py +0 -494
  29. package/scripts/_cache_fetch.py +0 -635
  30. package/scripts/_cache_quota.py +0 -529
  31. package/scripts/_cache_refresh.py +0 -163
  32. package/scripts/_cache_validate.py +0 -209
  33. package/scripts/_content_root.py +0 -42
  34. package/scripts/_doctor_state.py +0 -277
  35. package/scripts/_event_detect.py +0 -305
  36. package/scripts/_events.py +0 -514
  37. package/scripts/_lifecycle_hygiene.py +0 -568
  38. package/scripts/_pathspec.py +0 -91
  39. package/scripts/_policy_show_cli.py +0 -266
  40. package/scripts/_precutover.py +0 -92
  41. package/scripts/_project_context.py +0 -224
  42. package/scripts/_project_definition_io.py +0 -164
  43. package/scripts/_relocate_snapshot.py +0 -209
  44. package/scripts/_relocate_states.py +0 -343
  45. package/scripts/_resolve_preflight_path.py +0 -152
  46. package/scripts/_safe_subprocess.py +0 -167
  47. package/scripts/_session_start_hook.py +0 -205
  48. package/scripts/_sor_gate_diff.py +0 -365
  49. package/scripts/_stdio_utf8.py +0 -59
  50. package/scripts/_triage_bootstrap_gitignore.py +0 -904
  51. package/scripts/_triage_classify_cli.py +0 -122
  52. package/scripts/_triage_queue_cli.py +0 -625
  53. package/scripts/_triage_scope_cli.py +0 -343
  54. package/scripts/_triage_scope_drift_cli.py +0 -121
  55. package/scripts/_triage_scope_ignores.py +0 -286
  56. package/scripts/_triage_scope_milestone.py +0 -432
  57. package/scripts/_triage_scope_mutations.py +0 -337
  58. package/scripts/_triage_scope_renderers.py +0 -207
  59. package/scripts/_triage_smoketest_stages.py +0 -674
  60. package/scripts/_triage_subscribe_cli.py +0 -140
  61. package/scripts/_triage_welcome_cli.py +0 -421
  62. package/scripts/_vbrief_build.py +0 -239
  63. package/scripts/_vbrief_fidelity.py +0 -479
  64. package/scripts/_vbrief_legacy.py +0 -589
  65. package/scripts/_vbrief_reconciliation.py +0 -883
  66. package/scripts/_vbrief_routing.py +0 -277
  67. package/scripts/_vbrief_safety.py +0 -778
  68. package/scripts/_vbrief_sources.py +0 -312
  69. package/scripts/_vbrief_speckit.py +0 -262
  70. package/scripts/_vbrief_story_quality.py +0 -353
  71. package/scripts/_vbrief_validation.py +0 -299
  72. package/scripts/build_dist.py +0 -412
  73. package/scripts/cache.py +0 -1078
  74. package/scripts/cache_scanner.py +0 -745
  75. package/scripts/candidates_log.py +0 -432
  76. package/scripts/capacity_backfill.py +0 -680
  77. package/scripts/capacity_show.py +0 -653
  78. package/scripts/ci_local.py +0 -689
  79. package/scripts/code_structure_validate.py +0 -765
  80. package/scripts/codebase_default_extractor.py +0 -495
  81. package/scripts/codebase_map.py +0 -304
  82. package/scripts/codebase_map_fresh.py +0 -104
  83. package/scripts/codebase_projection_registry.py +0 -94
  84. package/scripts/codebase_provider.py +0 -582
  85. package/scripts/doctor.py +0 -2552
  86. package/scripts/framework_commands.py +0 -505
  87. package/scripts/gh_rest.py +0 -882
  88. package/scripts/github_auth_modes.py +0 -437
  89. package/scripts/github_body.py +0 -292
  90. package/scripts/ip_risk.py +0 -531
  91. package/scripts/issue_emit.py +0 -670
  92. package/scripts/issue_ingest.py +0 -1064
  93. package/scripts/migrate_preflight.py +0 -418
  94. package/scripts/migrate_vbrief.py +0 -2677
  95. package/scripts/monitor_pr.py +0 -401
  96. package/scripts/pack_migrate_lessons.py +0 -336
  97. package/scripts/pack_migrate_patterns.py +0 -254
  98. package/scripts/pack_migrate_rules.py +0 -350
  99. package/scripts/pack_migrate_skills.py +0 -423
  100. package/scripts/pack_migrate_strategies.py +0 -311
  101. package/scripts/pack_migrate_swarm_spec.py +0 -250
  102. package/scripts/pack_render.py +0 -434
  103. package/scripts/packs_slice.py +0 -712
  104. package/scripts/platform_capabilities.py +0 -336
  105. package/scripts/policy.py +0 -2826
  106. package/scripts/policy_set.py +0 -324
  107. package/scripts/pr_check_closing_keywords.py +0 -524
  108. package/scripts/pr_check_protected_issues.py +0 -267
  109. package/scripts/pr_merge_readiness.py +0 -1004
  110. package/scripts/pr_wait_mergeable.py +0 -669
  111. package/scripts/prd_render.py +0 -159
  112. package/scripts/preflight_architecture_sor.py +0 -974
  113. package/scripts/preflight_branch.py +0 -289
  114. package/scripts/preflight_cache.py +0 -974
  115. package/scripts/preflight_gh.py +0 -721
  116. package/scripts/preflight_implementation.py +0 -272
  117. package/scripts/preflight_story_start.py +0 -838
  118. package/scripts/preflight_wip_cap.py +0 -149
  119. package/scripts/probe_session.py +0 -545
  120. package/scripts/project_render.py +0 -293
  121. package/scripts/quarantine_ext.py +0 -237
  122. package/scripts/reconcile_issues.py +0 -1442
  123. package/scripts/refresh-path.ps1 +0 -107
  124. package/scripts/release.py +0 -2030
  125. package/scripts/release_e2e.py +0 -1011
  126. package/scripts/release_publish.py +0 -486
  127. package/scripts/release_rollback.py +0 -980
  128. package/scripts/relocate.py +0 -1034
  129. package/scripts/resolve_changelog_unreleased.py +0 -667
  130. package/scripts/resolve_version.py +0 -490
  131. package/scripts/resume_conditions.py +0 -706
  132. package/scripts/ritual_sentinel.py +0 -609
  133. package/scripts/roadmap_render.py +0 -635
  134. package/scripts/rule_ownership_lint.py +0 -325
  135. package/scripts/scm.py +0 -591
  136. package/scripts/scope_audit_log.py +0 -387
  137. package/scripts/scope_decompose.py +0 -654
  138. package/scripts/scope_demote.py +0 -509
  139. package/scripts/scope_lifecycle.py +0 -1126
  140. package/scripts/scope_undo.py +0 -772
  141. package/scripts/session_start.py +0 -406
  142. package/scripts/setup_ghx.py +0 -339
  143. package/scripts/setup_windows.ps1 +0 -220
  144. package/scripts/slice_audit.py +0 -585
  145. package/scripts/slice_record.py +0 -530
  146. package/scripts/slice_record_existing.py +0 -692
  147. package/scripts/slug_normalize.py +0 -178
  148. package/scripts/spec_render.py +0 -477
  149. package/scripts/spec_validate.py +0 -238
  150. package/scripts/subagent_monitor.py +0 -658
  151. package/scripts/swarm_complete_cohort.py +0 -644
  152. package/scripts/swarm_launch.py +0 -1206
  153. package/scripts/swarm_readiness.py +0 -554
  154. package/scripts/swarm_verify_review_clean.py +0 -438
  155. package/scripts/swarm_worktrees.py +0 -497
  156. package/scripts/toolchain-check.py +0 -52
  157. package/scripts/triage_actions.py +0 -871
  158. package/scripts/triage_bootstrap.py +0 -1153
  159. package/scripts/triage_bulk.py +0 -630
  160. package/scripts/triage_classify.py +0 -932
  161. package/scripts/triage_help.py +0 -1685
  162. package/scripts/triage_queue.py +0 -1944
  163. package/scripts/triage_reconcile.py +0 -581
  164. package/scripts/triage_refresh.py +0 -643
  165. package/scripts/triage_scope.py +0 -999
  166. package/scripts/triage_scope_drift.py +0 -575
  167. package/scripts/triage_smoketest.py +0 -396
  168. package/scripts/triage_subscribe.py +0 -399
  169. package/scripts/triage_summary.py +0 -1011
  170. package/scripts/triage_welcome.py +0 -1178
  171. package/scripts/ts_check_lane.py +0 -86
  172. package/scripts/validate-links.py +0 -64
  173. package/scripts/validate_strategy_output.py +0 -212
  174. package/scripts/vbrief_activate.py +0 -228
  175. package/scripts/vbrief_migrate_conformance.py +0 -368
  176. package/scripts/vbrief_reconcile_graph.py +0 -306
  177. package/scripts/vbrief_reconcile_labels.py +0 -460
  178. package/scripts/vbrief_reconcile_umbrellas.py +0 -741
  179. package/scripts/vbrief_validate.py +0 -1144
  180. package/scripts/verify-stubs.py +0 -61
  181. package/scripts/verify_capacity.py +0 -160
  182. package/scripts/verify_encoding.py +0 -699
  183. package/scripts/verify_hooks_installed.py +0 -206
  184. package/scripts/verify_investigation.py +0 -360
  185. package/scripts/verify_judgment_gates.py +0 -827
  186. package/scripts/verify_no_task_runtime.py +0 -171
  187. package/scripts/verify_scm_boundary.py +0 -509
  188. package/scripts/verify_session_ritual.py +0 -389
  189. package/scripts/verify_tools.py +0 -426
  190. package/scripts/verify_vbrief_conformance.py +0 -478
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deftai/directive-content",
3
- "version": "0.59.0",
4
- "description": "Shippable Directive framework content in the consumer .deft/core/ layout (C1 flatten), plus the engine surfaces (.githooks/, Taskfile.yml, tasks/, scripts/) the deposit wires. Refs #11, #1669, #1967.",
3
+ "version": "0.61.0",
4
+ "description": "Shippable Directive framework content in the consumer .deft/core/ layout (C1 flatten), plus the engine surfaces (.githooks/, Taskfile.yml, tasks/) the deposit wires. Python-free per #2022 Phase 3. Refs #11, #1669, #1967.",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "**/*",
@@ -17,7 +17,7 @@
17
17
  "provenance": true
18
18
  },
19
19
  "scripts": {
20
- "prepack": "node --input-type=module -e \"import{cpSync,existsSync,readdirSync,rmSync}from'node:fs';import{dirname,join}from'node:path';import{fileURLToPath}from'node:url';const pkg=dirname(fileURLToPath(import.meta.url));const root=join(pkg,'..','..');const keep=(s)=>!s.includes('__pycache__')&&!s.endsWith('.pyc');const src=join(root,'content');for(const name of readdirSync(src)){const from=join(src,name);const to=join(pkg,name);if(existsSync(to))rmSync(to,{recursive:true,force:true});cpSync(from,to,{recursive:true,filter:keep});}for(const name of ['.githooks','Taskfile.yml','tasks','scripts']){const from=join(root,name);if(!existsSync(from))continue;const to=join(pkg,name);if(existsSync(to))rmSync(to,{recursive:true,force:true});cpSync(from,to,{recursive:true,filter:keep});}\"",
20
+ "prepack": "node --input-type=module -e \"import{cpSync,existsSync,readdirSync,rmSync}from'node:fs';import{dirname,join}from'node:path';import{fileURLToPath}from'node:url';const pkg=dirname(fileURLToPath(import.meta.url));const root=join(pkg,'..','..');const keep=(s)=>!s.includes('__pycache__')&&!s.endsWith('.pyc')&&!s.endsWith('.py');const src=join(root,'content');for(const name of readdirSync(src)){const from=join(src,name);const to=join(pkg,name);if(existsSync(to))rmSync(to,{recursive:true,force:true});cpSync(from,to,{recursive:true,filter:keep});}for(const name of ['.githooks','Taskfile.yml','tasks']){const from=join(root,name);if(!existsSync(from))continue;const to=join(pkg,name);if(existsSync(to))rmSync(to,{recursive:true,force:true});cpSync(from,to,{recursive:true,filter:keep});}\"",
21
21
  "postpack": "node --input-type=module -e \"import{readdirSync,rmSync}from'node:fs';import{dirname,join}from'node:path';import{fileURLToPath}from'node:url';const pkg=dirname(fileURLToPath(import.meta.url));for(const name of readdirSync(pkg)){if(name==='package.json')continue;rmSync(join(pkg,name),{recursive:true,force:true});}\""
22
22
  }
23
23
  }
@@ -203,7 +203,7 @@
203
203
  ],
204
204
  "path": "skills/deft-directive-setup/SKILL.md",
205
205
  "version": "0.1",
206
- "body": "# Deft Directive Setup\n\nAgent-driven alternative to `.deft/core/run bootstrap && .deft/core/run project && .deft/core/run spec`.\n\nLegend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.\n\n## When to Use\n\n- User says \"set up deft\", \"configure deft\", or \"bootstrap my project\"\n- User asks to create USER.md, PROJECT-DEFINITION.vbrief.json, or a specification\n- User clones a deft-enabled repo for the first time with no config\n\n## Pre-Cutover Detection Guard\n\n! Before proceeding with any setup phase, detect whether the project uses the pre-v0.20 document model and redirect to migration if so.\n\n### Detection Criteria\n\nA project is **pre-cutover** if ANY of the following are true. This prose mirrors the executable helper in `scripts/_precutover.py`; when in doubt, the helper is canonical.\n\n1. `SPECIFICATION.md` exists and is neither a deprecation redirect nor a current generated spec export. A current generated spec export contains `<!-- Purpose: rendered specification -->` and `<!-- Source of truth: vbrief/specification.vbrief.json -->`, and `vbrief/specification.vbrief.json` plus all five lifecycle folders exist.\n2. `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).\n3. `vbrief/specification.vbrief.json` exists but the lifecycle folders (`vbrief/proposed/`, `vbrief/pending/`, `vbrief/active/`, `vbrief/completed/`, `vbrief/cancelled/`) do NOT exist\n\n### Action on Detection\n\n! If pre-cutover state is detected, **stop immediately** and display an actionable message:\n\n> \"This project uses the pre-v0.20 document model. Run `task migrate:vbrief` to upgrade to the vBRIEF-centric model.\"\n\n! Include specific details about what was detected:\n\n- Missing lifecycle folders: \"Run `task migrate:vbrief` to create the lifecycle folder structure\"\n- `SPECIFICATION.md` with real content: \"SPECIFICATION.md contains non-redirect content -- this file is deprecated; use scope vBRIEFs in `vbrief/` instead\"\n- `PROJECT.md` with real content: \"PROJECT.md contains non-redirect content -- this file is deprecated; use `PROJECT-DEFINITION.vbrief.json` instead\"\n- Missing `PROJECT-DEFINITION.vbrief.json`: \"Run `task project:render` to generate the project definition\"\n\n### Environment Preflight (before asking to run migration)\n\n! Before asking the user \"Would you like me to run `task migrate:vbrief` now?\", run an environment preflight and report the results to the user. Do NOT ask the yes/no prompt until preflight results have been reported. Each failing check must be surfaced with a specific fix pointer so the user (or agent) can resolve the blocker before approving the run.\n\nRun these four checks, in order:\n\n1. **Document-model confirmation** -- re-apply the Detection Criteria above (the executable source is `scripts/_precutover.py`). If `SPECIFICATION.md` is a current generated spec export from `vbrief/specification.vbrief.json` and all lifecycle folders exist, stop: migration is NOT needed and MUST NOT be run.\n2. **Task resolvability** -- check whether `task migrate:vbrief` is dispatchable from the project root:\n - Run `task --list` (or platform-equivalent) and grep the output for a line containing `migrate:vbrief`.\n - If present: the primary command works from the project root -- canonical invocation is `task migrate:vbrief`.\n - If absent: the consumer `Taskfile.yml` does not include `deft/Taskfile.yml`. Fall back to the explicit-taskfile invocation `task -t ./deft/Taskfile.yml migrate:vbrief` and tell the user: \"`task migrate:vbrief` is not resolvable from the project root. I will use the fallback invocation `task -t ./deft/Taskfile.yml migrate:vbrief`, which reads the task directly from the framework Taskfile. To make the primary command work in future, add an include for `deft/Taskfile.yml` to your project `Taskfile.yml` — see `deft/main.md` § Publishing deft tasks in your project root.\"\n3. **`uv` on PATH** -- the migrator runs `uv run python scripts/migrate_vbrief.py`. Check `uv --version` (or equivalent): if it fails, point the user at the uv install docs (`https://docs.astral.sh/uv/`) and stop; migration cannot run without `uv`.\n4. **Migration script present** -- check `deft/scripts/migrate_vbrief.py` exists on disk. If absent, the `deft/` checkout is incomplete or came from a pre-v0.20 framework version; point the user at `deft/QUICK-START.md` (framework refresh guidance) and stop.\n\n! Report each preflight check's result to the user (e.g. \"✓ task migrate:vbrief resolvable\", \"✗ uv not on PATH — install from https://docs.astral.sh/uv/\") BEFORE prompting for yes/no approval. If any check fails, do NOT offer to run migration until it is resolved.\n\n⊗ Skip preflight and immediately ask \"Would you like me to run `task migrate:vbrief` now?\" -- preflight catches preventable errors (unresolvable task, missing `uv`, missing script) before the user commits to running migration.\n⊗ Propose an install-step mutation that writes `migrate:vbrief` content into the consumer Taskfile. The supported publish mechanism is the `includes: deft: deft/Taskfile.yml` pattern documented in `deft/main.md` § Publishing deft tasks in your project root; inline Taskfile mutation is explicitly out of scope (per #506 D6).\n\n### Prompt and Run\n\n! After preflight results are reported (and all checks pass), ask the user: \"Would you like me to run `task migrate:vbrief` now?\"\n- If yes: run the migration command (use the fallback invocation `task -t ./deft/Taskfile.yml migrate:vbrief` if the preflight resolvability check found the primary task unresolvable). Then re-run the pre-cutover detection guard to verify clean state before proceeding.\n- If no: stop and let the user handle migration manually.\n\n⊗ Proceed with setup phases when pre-cutover artifacts are detected -- always redirect to migration first.\n⊗ Silently ignore pre-cutover artifacts -- the user must be informed with an actionable command to fix the state.\n⊗ Display the migration diagnostic without offering to run it -- always ask the user if they want the agent to handle it (after preflight has passed).\n\n### Greenfield Projects (No Migration Needed)\n\n! For new projects (no existing `SPECIFICATION.md`, `PROJECT.md`, or `vbrief/specification.vbrief.json`), the guard passes silently and setup proceeds normally.\n\n! Greenfield setup creates the full vBRIEF-centric structure from scratch:\n\n1. `./vbrief/` directory with all 5 lifecycle subdirectories: `proposed/`, `pending/`, `active/`, `completed/`, `cancelled/`\n2. `./vbrief/PROJECT-DEFINITION.vbrief.json` generated from Phase 2 interview results\n3. First scope vBRIEF created in `proposed/` or `pending/` depending on Phase 3 interview outcome\n\n~ This is already handled by Phase 2 Output Path (creates `./vbrief/` and lifecycle subfolders) and Phase 3 Output (creates scope vBRIEFs in lifecycle folders). The guard ensures migrating projects are redirected before reaching these phases.\n\n### Migration safety flags\n\n`task migrate:vbrief` is destructive by default (it replaces `SPECIFICATION.md` and `PROJECT.md` with redirect stubs and rewrites `vbrief/`), but it carries four always-on / on-demand safety affordances so operators can preview, recover, and undo (#497, #506 D7). Agents offering to run migration MUST mention these and pick the right one for the operator's situation.\n\n- ! **Automatic `.premigrate.*` backups (always-on, no flag)**: before any destructive write the migrator copies every pre-cutover input to its `.premigrate` sibling -- `SPECIFICATION.md` -> `SPECIFICATION.premigrate.md`, `PROJECT.md` -> `PROJECT.premigrate.md`, `ROADMAP.md` -> `ROADMAP.premigrate.md`, `PRD.md` -> `PRD.premigrate.md` (only if present), and `vbrief/specification.vbrief.json` -> `vbrief/specification.premigrate.vbrief.json`. Each backup emits a `BACKUP <src> -> <dst> (<N> bytes)` line in the migration output. These files are `.gitignore`d by default so they do not leak into commits; operators who want them versioned can remove the patterns.\n- ! **`task migrate:vbrief -- --dry-run` (preview)**: prints the complete migration plan (every proposed backup, lifecycle folder, narrative ingestion, scope vBRIEF, and deprecation-redirect replacement) prefixed `DRYRUN` without writing any file. Exits 0 on success. Use this before running migration for the first time on an unfamiliar project.\n- ! **Dirty-tree guard (always-on)**: if `git status --porcelain` is non-empty the migrator refuses to run and points the operator at `--force`. Keeps migration output separable from in-progress edits. Bypass with `task migrate:vbrief -- --force` only after confirming the operator has accepted the risk.\n- ! **`task migrate:vbrief -- --rollback`**: restores every pre-cutover input from its `.premigrate.*` backup and removes the scope vBRIEFs and migration-report files a prior run created. Reads `vbrief/migration/safety-manifest.json` (written by the migrator). Refuses if any redirect stub has been edited since migration -- re-run with `--force` to overwrite those edits on purpose, or commit them before rolling back. Prompts for a yes/no confirmation unless `--force` is passed.\n\n! When a user declines an in-flight migration or reports an incorrect result, offer `task migrate:vbrief -- --rollback` before asking them to edit files by hand.\n\n⊗ Offer `task migrate:vbrief` without also telling the user about `--dry-run` when they sound hesitant -- previewing is free and catches reconciliation surprises that would otherwise land in a commit.\n⊗ Suggest `git reset --hard` or manual file deletion as a recovery path when `--rollback` would do the right thing more safely.\n\n## Deterministic Questions Contract\n\n! 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.\n\n## Platform Detection\n\n! Before resolving any config paths, detect the host OS from your environment context:\n\n| Platform | USER.md default path |\n|--------------------|-------------------------------------------------------------------|\n| Windows | `%APPDATA%\\deft\\USER.md` (e.g. `C:\\Users\\{user}\\AppData\\Roaming\\deft\\USER.md`) |\n| Unix (macOS/Linux) | `~/.config/deft/USER.md` |\n\n- ! If `$DEFT_USER_PATH` is set, it takes precedence on any platform\n- ! Create parent directories as needed when writing USER.md\n- ~ `$DEFT_PROJECT_PATH` overrides the default project config path (`./vbrief/PROJECT-DEFINITION.vbrief.json`) if set\n\n## Agent Behavior\n\n**Flow:**\n- ! Start asking immediately — everything you need is in THIS file\n- ⊗ Explore the codebase, read framework files, or gather context before asking\n- ? Read `deft/main.md` or language files LATER when generating output\n\n**Interaction:**\n- ~ 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.\n- ! 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.\n- ⊗ Infer deterministic answers from host-added letters or shortcuts unless those letters were actually displayed in the canonical menu labels.\n\n**Defaults:**\n- ! Communicate that deft ships with best-in-class standards for 20+ languages\n- ! Frame setup as \"tell me your overrides\" — not \"configure everything\"\n- ~ \"Deft has solid opinions on how code should be written and tested — I just need a few things about you and your project.\"\n\n**Adapt to Technical Level:**\n- ! First question gauges whether user is technical or non-technical\n- ! Technical user: ask about languages, strategy, coverage directly — they'll have opinions\n- ! Non-technical user: skip jargon, use sensible defaults, ask about what they're building not how\n- ⊗ Ask non-technical users about coverage thresholds, strategies, or framework choices\n\n## Available Languages\n\nC, C++, C#, Dart, Delphi, Elixir, Go, Java, JavaScript, Julia, Kotlin,\nOffice.js (Excel JavaScript API), Python, R, Rust, SQL, Swift, TypeScript,\nVBA (Excel macros), VHDL, Visual Basic (.NET), Zig, 6502-DASM\n\n- ? Read `deft/languages/{name}.md` when generating output — not before asking\n\n## Available Strategies\n\n~ When presenting strategies to the user, always use this numbered list format (not a plain table).\n~ Always include the chaining note below the list.\n! Always show the FULL strategy list at every chaining gate — never remove a strategy because it was previously run.\n~ If a strategy has been run already, indicate it with a note e.g. `(run 1x)` but keep it selectable.\n\n1. **interview** ★ (recommended) — Structured interview with sizing gate: Light or Full path\n2. **yolo** — Auto-pilot interview — Johnbot picks all recommended options\n3. **map** — Analyze existing codebase conventions before adding features\n4. **discuss** — Front-load decisions and alignment before planning\n5. **probe** — Adversarially stress-test the plan; surface assumptions, edge cases, and risks before spec\n6. **research** — Investigate the domain before planning\n7. **speckit** — Five-phase spec-driven workflow for large/complex projects\n\n> 💡 Strategies can be chained — after one completes, you'll be asked if you want to run another.\n\n---\n\n## Phase 1 — User Preferences (USER.md)\n\n**Goal:** Personal preferences file with two sections:\n- **Personal** — always wins over everything (name, custom rules)\n- **Defaults** — fallback values that PROJECT-DEFINITION.vbrief.json can override (strategy, coverage)\n\n- ~ Skip if USER.md exists at the platform-appropriate path (see Platform Detection) and user doesn't want to overwrite\n- ⊗ Scan filesystem beyond checking that one path\n\n### USER.md Freshness Detection\n\n! When an existing USER.md is found (returning user), check its `deft_version` field before skipping Phase 1:\n\n1. ! If `deft_version` is **missing**: the USER.md predates versioning -- treat as stale\n2. ! If `deft_version` is present but **differs from the current framework version** (0.20.0): check whether any expected fields are missing from the USER.md\n3. ! If fields are missing: query the user for each missing field individually -- do NOT re-run the full Phase 1 interview\n4. ! After completing any field queries (even if none were needed), write the current `deft_version` (0.20.0) to USER.md\n5. ~ If `deft_version` matches the current version and all expected fields are present: no action needed (USER.md is fresh)\n\nExpected USER.md fields: **Name**, **Custom Rules**, **Default Strategy**, and optionally **Coverage** and **Experimental Rules**.\n\n⊗ Re-run the full Phase 1 interview when only individual fields are missing from a stale USER.md -- query missing fields individually instead.\n\n### Interview Rules\n\n! 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:\n\n! **Each message you send MUST contain exactly ONE question.** This is the most\nimportant rule in this file. After the user answers, send the NEXT question in\na new message. Repeat until all questions for their track are answered.\n\n- ⊗ Include two or more questions in the same message under any circumstances\n- ⊗ List upcoming questions — only show the current one\n- ~ Provide numbered answer options with an \"other\" choice where appropriate\n- ! Mark which option is RECOMMENDED when showing choices\n- ~ Use structured question tools only when visible option labels preserve the canonical numbers and returns map to numeric selections or exact displayed option text.\n\n### Question Sequence\n\n**Step 0 — Opening (all users):**\nAsk: \"How deep do you want to go?\"\n 1. I'm technical — ask me everything\n 2. I have some opinions but keep it simple\n 3. Just pick good defaults — I care about the product, not the tools\n\nWait for answer. Then follow the track below.\n\n**Track 1 (technical) — 7 steps:**\n- Step 1: Ask their name\n- Step 2: Ask strategy preference (show Available Strategies numbered list from the Available Strategies section, with descriptions and recommended marker; fallback — projects can override)\n- Step 3: Ask coverage threshold (default 85%; fallback — projects can override)\n- Step 4: Ask for custom rules — if user has rules, collect them one per line (empty line to finish); if none, skip\n- Step 5a: Present SOUL.md and ask whether to include it (default: yes):\n > **SOUL.md** — Results-first agent persona (inspired by Winston Wolf). Enforces assess-before-acting,\n > finish-what-you-start, right-tool-for-the-job, and play-the-long-game. Keeps the AI decisive and\n > concise. Includes a named persona ('Vinston') — drop if you prefer to define your own agent personality.\n > Include SOUL.md? (Y/n)\n- Step 5b: Present morals.md and ask whether to include it (default: yes):\n > **morals.md** — Epistemic honesty rules. No presenting speculation as fact, label unverified claims,\n > self-correct when wrong. Foundational trust rules for any AI agent. Strongly recommended.\n > Include morals.md? (Y/n)\n- Step 5c: Present code-field.md and ask whether to include it (default: yes):\n > **code-field.md** — Pre-code assumption protocol. Requires stating assumptions and naming failure modes\n > before writing a single line. Fights the 'it compiles, ship it' instinct. Based on NeoVertex1 context-field.\n > Include code-field.md? (Y/n)\n\n**Track 2 (middle ground) — 2 steps:**\n- Step 1: Ask their name\n- Step 2: Ask for custom rules — if user has rules, collect them one per line (empty line to finish); if none, skip\n- Set defaults without asking: strategy = \"interview\", coverage = 85%, all meta-guidelines included\n\n**Track 3 (non-technical) — 2 steps:**\n- Step 1: Ask their name\n- Step 2: Ask what they're building (brief description — used for PROJECT-DEFINITION.vbrief.json later)\n- Set defaults: strategy = \"interview\", coverage = 85%, all meta-guidelines included\n\n### Output Path\n\nResolve using Platform Detection above. Write to the platform-appropriate path\n(or `$DEFT_USER_PATH` if set). Create parent directories as needed.\n\n### Template\n\n```markdown\n# User Preferences\n\nLegend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.\n\n**deft_version**: 0.20.0\n\n## Personal (always wins)\n\nSettings in this section have HIGHEST precedence — override all other deft rules,\nincluding PROJECT-DEFINITION.vbrief.json.\n\n**Name**: Address the user as: **{name}**\n\n**Custom Rules**:\n{custom rules or \"No custom rules defined yet.\"}\n\n## Defaults (fallback)\n\nSettings in this section are fallback defaults. PROJECT-DEFINITION.vbrief.json overrides these\nfor project-scoped settings (strategy, coverage).\n\n**Default Strategy**: [{strategy name}](../strategies/{strategy-file}.md)\n\n{If coverage != 85: \"**Coverage**: ! ≥{N}% test coverage\"}\n\n{If any experimental rules selected:\n\"## Experimental Rules\n\n{one line per selected rule, e.g.:\n- ! Use meta/SOUL.md for strategic context and purpose-driven guidance\n- ! Use meta/morals.md for ethical AI development principles\n- ~ Use meta/code-field.md for advanced architecture patterns}\"}\n\n---\n\n**Note**: Edit this file anytime to update your preferences.\n**See**: [../../main.md](../../../main.md) for framework defaults.\n```\n\n### Then\n\n- ! 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.\n- ⊗ 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).\n\n---\n\n## Phase 2 — Project Configuration (PROJECT-DEFINITION.vbrief.json)\n\n**Goal:** Project-specific configuration — tech stack, type, quality standards — written as a vBRIEF file at `./vbrief/PROJECT-DEFINITION.vbrief.json`.\n\n! **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 (`./vbrief/PROJECT-DEFINITION.vbrief.json`, build files, etc.) must be resolved from the user's pwd.\n\n- ~ Skip if `./vbrief/PROJECT-DEFINITION.vbrief.json` exists (or `$DEFT_PROJECT_PATH` if set) and user doesn't want to replace\n- ⊗ Count `./deft/PROJECT-DEFINITION.vbrief.json` or `./deft/core/project.md` as the user's project config — those are framework-internal\n\n### Inference\n\n- ! Before asking, infer from codebase — look for `package.json`, `go.mod`, `requirements.txt`, `Cargo.toml`, `pyproject.toml`, `*.csproj`\n- ! Use inferences to pre-fill answers and confirm — don't ask blind\n- ⊗ 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.\n- ⊗ Run git commands inside `./deft/` to determine project identity — that directory is the framework repo, not the user's project.\n- ~ If no build files are found at the project root, default the project name to the current directory name and ask for confirmation.\n\n### Track Detection\n\n! If Phase 1 was skipped (USER.md already existed), the user's track is unknown.\nBefore asking any Phase 2 questions, ask the depth question:\n\n> \"How deep do you want to go?\"\n> 1. I'm technical — ask me everything\n> 2. I have some opinions but keep it simple\n> 3. Just pick good defaults — I care about the product, not the tools\n\nWait for answer. Then follow the corresponding track in the Question Sequence below.\n\n⊗ Assume Track 1 (technical) because USER.md exists or contains strategy/coverage fields.\n⊗ Infer the track from USER.md content — always ask.\n\n### Defaults in Agentic Mode\n\n! When a question has a USER.md default, phrase it as:\n> \"{Field}: **{value}** from USER.md — keep this, or enter a different value?\"\n\n! Accept any affirmative response (\"keep\", \"yes\", \"same\", \"default\", ✓) as confirmation to use the default.\n⊗ Phrase defaults as \"press Enter to keep\" — there is no Enter in conversational mode.\n\n### Interview Rules (same as Phase 1)\n\n! **Each message MUST contain exactly ONE question.** The Phase 1 interview rules\napply here too. Do not combine questions. See `skills/deft-directive-interview/SKILL.md` for the canonical deterministic interview loop.\n\n### Question Sequence\n\n**Track 1 (technical) — 8 steps:**\n- Step 1: Ask project name (infer from build files or directory name, confirm)\n- Step 2: Ask project type (CLI, TUI, Desktop App, REST API, Web App, Library, other)\n- Step 3: Ask deployment platform:\n 1. Cross-platform (Linux / macOS / Windows)\n 2. Windows-native\n 3. macOS-native\n 4. Linux / Unix\n 5. Embedded / low-resource\n 6. Web / Cloud\n 7. Mobile (iOS / Android)\n 8. Other / not sure\n- 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?\"\n - If user selects \"Other\": show remaining plausible languages for the type+platform context (Tier 2)\n - If still not found: free text input (Tier 3)\n - 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?\"\n- Step 5: Ask tech stack (frameworks, libraries)\n- 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)\n- Step 7: Ask coverage (default to USER.md Defaults; ask if this project needs different)\n- Step 8: Ask for project-specific rules (optional, same one-per-line format as Phase 1 custom rules)\n- Step 9: Ask branching preference (typed `plan.policy.allowDirectCommitsToMaster` flag per #746):\n\n ! 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):\n\n > \"Do you prefer branch-based workflow (create a feature branch for every change) or\n > trunk-based (commit directly to master)? Branch-based is the default and recommended\n > for teams; trunk-based is common for solo projects.\"\n > 1. Branch-based ★ (recommended -- default; enforces feature branches via the deft branch-protection policy)\n > 2. Trunk-based (direct commits to master) -- see capability-cost disclosure below\n > 3. Discuss\n > 4. Back\n\n ! **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:\n\n > \"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, `task 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?\"\n > 1. Yes, opt out -- write `plan.policy.allowDirectCommitsToMaster = true`\n > 2. No, keep branch-protection enforced -- write `plan.policy.allowDirectCommitsToMaster = false`\n > 3. Discuss\n > 4. Back\n\n ! 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`).\n\n ! Write the answer to `plan.policy.allowDirectCommitsToMaster` (typed boolean) on the PROJECT-DEFINITION vBRIEF. Default `false` (enforce branches) when the user picks option 2 OR omits the question entirely. Writing this typed surface is what the framework reads going forward; agents MUST NOT write the legacy free-form `Allow direct commits to master:` narrative key (#746 part A migrates the legacy narrative away).\n\n ! **Re-running the interview detects the existing flag (#746 part G2):** If `vbrief/PROJECT-DEFINITION.vbrief.json` already exists and has `plan.policy.allowDirectCommitsToMaster` set, the interview MUST surface the current value (e.g. \"Current setting: `allowDirectCommitsToMaster=false` (branch-protection ON)\") and ask whether to keep it or change it before re-prompting. Do not silently overwrite an existing typed value.\n\n ! **Slash-command alternatives (#746 part G2):** Once the project is set up, the typed flag can also be flipped via slash commands wrapping `task policy:*`:\n - `/deft:policy:show` -- display the current resolved policy and source\n - `/deft:policy:enforce-branches` -- set `allowDirectCommitsToMaster=false`\n - `/deft:policy:allow-direct-commits` -- set `allowDirectCommitsToMaster=true` (requires `--confirm` to apply)\n\n Each transition is recorded to `meta/policy-changes.log` for auditability.\n\n**Track 2 (middle ground) — 4 steps:**\n- Step 1: Ask project name (infer from build files or directory name, confirm)\n- Step 2: Ask project type (CLI, TUI, Desktop App, REST API, Web App, Library, other)\n- Step 3: Ask languages (show detected, confirm or adjust; if none detected, infer from type and ask)\n- 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)\n- Default coverage to USER.md Defaults without asking\n\n**Track 3 (non-technical) — 1 step:**\n- Step 1: Present summary of inferences: \"Based on your project: {name} ({type}), built with {stack}. Look right?\"\n- ⊗ Ask about strategy or coverage — use Phase 1 defaults\n\n### Output Path\n\n`./vbrief/PROJECT-DEFINITION.vbrief.json` (or `$DEFT_PROJECT_PATH` if set). Create `./vbrief/` directory and lifecycle subfolders (`proposed/`, `pending/`, `active/`, `completed/`, `cancelled/`) if they don't exist.\n\n### GitHub PR Template Scaffolding (#531)\n\n! Before writing `PROJECT-DEFINITION.vbrief.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.\n\n1. ! 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.\n2. ! 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.\n3. ! If the file already exists, do NOT overwrite it — report that it is present and continue.\n4. ~ If the user declines, note that `deft-directive-refinement` Pre-Flight will offer to scaffold later when needed.\n\n⊗ Overwrite an existing `.github/PULL_REQUEST_TEMPLATE.md` without explicit user approval.\n\n### Headless Coverage Warning — display-bound GUI entry points (#1027)\n\n! 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.vbrief.json` (adapt the wording to the project's language):\n\n> \"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.\"\n\n! 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:\n\n```toml\n[tool.coverage.run]\nomit = [\n \"*/tests/*\",\n \"*/venv/*\",\n \"*/.venv/*\",\n \"src/ui.py\", # display-bound pygame/tkinter event loop -- cannot run headlessly (#1027)\n]\n```\n\n- ! 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.\n- ~ 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.\n- ⊗ 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.\n- ⊗ 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).\n\n### Template\n\n! The output MUST conform to the canonical vBRIEF v0.6 schema (`vbrief/schemas/vbrief-core.schema.json`, strict `const: \"0.6\"`). See [`../../conventions/references.md`](../../conventions/references.md).\n\n```json\n{\n \"vBRIEFInfo\": {\n \"version\": \"0.6\",\n \"author\": \"agent:deft-directive-setup\",\n \"description\": \"Project identity gestalt\",\n \"created\": \"{ISO-8601 timestamp}\"\n },\n \"plan\": {\n \"title\": \"{Project Name}\",\n \"status\": \"running\",\n \"narratives\": {\n \"Overview\": \"{Brief project description}\",\n \"TechStack\": \"{project type} using {languages} — {tech stack details}\",\n \"Strategy\": \"Use {strategy name} for this project\",\n \"Quality\": \"Run task check before every commit. Achieve >= {coverage}% coverage overall + per-module. Store secrets in secrets/ dir.\",\n \"ProjectRules\": \"{Any rules the user specified, or 'No project-specific rules defined.'}\",\n \"Branching\": \"{If trunk-based: 'Allow direct commits to master: true', else omit or 'Branch-based workflow (default)'}\",\n \"DeftVersion\": \"0.20.0\"\n },\n \"items\": []\n }\n}\n```\n\n- ! All `narratives` values MUST be plain strings — never objects or arrays\n- ! `items` starts empty — populated as scope vBRIEFs are created in lifecycle folders\n\n### Then\n\n- ! 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. 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.\n- ⊗ 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).\n\n### Follow-up: triage onboarding (#1143)\n\n- ~ After Phase 2 writes `PROJECT-DEFINITION.vbrief.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.\n- ~ `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.\n- ? The recommendation is informational, not a hard gate -- consumers who plan to wire triage manually MAY skip the ritual and call the individual verbs in any order; the framework defaults stay fail-open per the umbrella `#1119 §12 framework-vs-consumer-config boundary`.\n\n---\n\n## Phase 3 — Specification\n\n**Goal:** Generate an implementable spec using the strategy chosen in Phase 2, producing a `specification.vbrief.json` draft for human approval before downstream generation.\n\n! **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.\n\n- ~ Skip if user already has scope vBRIEFs in `./vbrief/` they're happy with\n- ! Check `./vbrief/specification.vbrief.json` or `./vbrief/proposed/` for existing scope vBRIEFs\n- ⊗ Count ANY file inside `./deft/` as the project's spec — those are framework-internal\n (e.g. `deft/PROJECT.md`, `deft/specs/`, `deft/templates/`, `deft/core/project.md`\n are all part of the framework, NOT the user's project)\n\n### Onboarding Question\n\n! Before proceeding with the strategy gate, ask the onboarding question:\n\n> \"Are you adding a scope to this project or starting a new specification?\"\n> 1. Adding scope to existing project [default if `./vbrief/specification.vbrief.json` exists or scope vBRIEFs found in lifecycle folders]\n> 2. Starting a new project specification [default if no specification or scope vBRIEFs exist]\n\n- ! Default based on repo state: if specification.vbrief.json exists or any lifecycle folder has scope vBRIEFs, default to \"Adding scope\"; otherwise default to \"Starting new\"\n- ! If adding scope: skip the full interview, create a new scope vBRIEF in `./vbrief/proposed/` with the user's description, then exit\n- ! If starting new: proceed to the Strategy Gate below\n\n### ⚠️ MANDATORY: Strategy Gate — Do This First\n\n! **STOP.** You MUST determine the correct strategy before doing anything else.\n\n1. ! Open `./vbrief/PROJECT-DEFINITION.vbrief.json` (the file written in Phase 2)\n2. ! Find the `narratives.Strategy` value\n3. ! Extract the strategy name from the narrative\n\n**Dispatch:**\n\n- **interview** (or default) → Continue to the Sizing Gate below ✅\n- **anything else** (discuss, yolo, speckit, research, brownfield, map, etc.) →\n 1. ! Read `deft/strategies/{strategy-name}.md` **right now, in this same turn**\n 2. ! Begin the strategy's workflow immediately — ask its first question\n 3. ! **STOP reading this section** — do NOT use the interview process below\n\n- ⊗ Default to interview without reading PROJECT-DEFINITION.vbrief.json\n- ⊗ Continue reading below when PROJECT-DEFINITION.vbrief.json specifies a non-interview strategy\n- ⊗ Assume interview because the sections below describe the interview process\n- ⊗ Fabricate justification for using interview when the user chose a different strategy\n- ⊗ Announce the strategy choice and then stop — you must immediately read the file and start\n\n---\n\n*⬇️ Everything below applies ONLY to the interview strategy. If your strategy is anything else, STOP — follow your strategy file instead.*\n\n### Sizing Gate (interview and yolo strategies only)\n\n! After hearing what the user wants to build and their feature list, determine\nproject complexity per [strategies/interview.md](../../strategies/interview.md#sizing-gate).\n\n- ! Check `PROJECT-DEFINITION.vbrief.json` narratives for `Light` or `Full` — if declared, use that path\n- ! If not declared, propose a size and **ask the user to confirm in a dedicated message**\n- ! **Wait for the user's response** before asking any interview questions\n- ⊗ Combine the sizing proposal with the first interview question\n- ⊗ Proceed to interview questions before the user has confirmed the path\n\n**Light** (small/medium): Interview → `specification.vbrief.json` with slim narratives (Overview + Architecture) → scope vBRIEFs in `vbrief/proposed/`.\n**Full** (large/complex): Interview → rich narratives in `specification.vbrief.json` (user approval) → scope vBRIEFs with traceability.\n\n### Interview Process (interview strategy)\n\nPer [strategies/interview.md](../../strategies/interview.md#interview-rules-shared-by-both-paths):\n\n- ! Ask what to build and features first\n- ! Ask **ONE** focused, non-trivial question per step\n- ~ Provide numbered options with an \"other\" choice\n- ! Mark which option is RECOMMENDED\n- ⊗ Ask multiple questions at once\n- ⊗ Make assumptions without clarifying\n- ~ 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.\n\n**Question Areas:**\n- ! Missing decisions (language, framework, deployment)\n- ! Edge cases (errors, boundaries, failure modes)\n- ! Implementation details (architecture, patterns, libraries)\n- ! Requirements (performance, security, scalability)\n- ! UX/constraints (users, timeline, compatibility)\n- ! Tradeoffs (simplicity vs features, speed vs safety)\n\n**Non-Technical Users:**\n- ~ Adjust vocabulary: \"How do you want to store data?\" not \"What database engine?\"\n- ~ \"Will other apps talk to this?\" not \"REST or GraphQL?\"\n\n**Completion:**\n- ! Continue until little ambiguity remains\n- ! Spec must be comprehensive enough to implement\n\n### Output — Light Path\n\n1. ! Write `./vbrief/specification.vbrief.json` with `\"vBRIEFInfo\": { \"version\": \"0.6\" }`, `status: draft`, and slim narratives:\n - `Overview`: Brief project summary\n - `Architecture`: System design description\n2. ! Create scope vBRIEFs in `./vbrief/proposed/` for each identified work item\n - Each scope vBRIEF follows the `YYYY-MM-DD-descriptive-slug.vbrief.json` filename convention (slug rules in [`../../conventions/vbrief-filenames.md`](../../conventions/vbrief-filenames.md))\n - Each MUST use `\"vBRIEFInfo\": { \"version\": \"0.6\" }`\n - Each MUST include embedded Requirements (FR-N, NFR-N) in its `narrative`\n - Each task SHOULD reference which FR/NFR it implements via `narrative.Traces`\n - When the scope originates from a GitHub issue, include a `references` entry in the canonical form (see [`../../conventions/references.md`](../../conventions/references.md)):\n ```json\n \"references\": [\n {\n \"uri\": \"https://github.com/{owner}/{repo}/issues/{N}\",\n \"type\": \"x-vbrief/github-issue\",\n \"title\": \"Issue #{N}: {issue title}\"\n }\n ]\n ```\n3. ! Summarize decisions, ask user to review the vBRIEF narratives\n4. ! On approval, update `specification.vbrief.json` status to `approved`\n- ⊗ Create a separate PRD.md on the Light path\n- ⊗ Generate an authoritative PRD.md — if needed, users run `task prd:render`\n\n! The vBRIEF files MUST conform to `vbrief/schemas/vbrief-core.schema.json` (v0.6):\n\n- ! All `narratives` and `narrative` values MUST be plain strings — never objects or arrays\n- ! Nested children within a PlanItem use `items` (v0.6 preferred field); `subItems` is the deprecated legacy alias kept for backward compatibility only\n- ⊗ Mix `items` and `subItems` on the same PlanItem — pick one (prefer `items`)\n\n### Output — Full Path\n\n1. ! Write rich narratives to `./vbrief/specification.vbrief.json` with `\"vBRIEFInfo\": { \"version\": \"0.6\" }`, `plan.status: draft`, and these narrative keys:\n - `ProblemStatement`: What problem this project solves\n - `Goals`: High-level project goals\n - `UserStories`: User stories in standard format\n - `Requirements`: Structured requirements (FR-N: ..., NFR-N: ...)\n - `SuccessMetrics`: Measurable success criteria\n - `Architecture`: System design and technical architecture\n - `Overview`: Brief project summary\n2. ! **Human approval gate**: Present the vBRIEF draft narratives to the user for review — reviewing the `specification.vbrief.json` narratives IS the approval step (replaces the former PRD.md review). The user may request changes before approving.\n3. ! On approval, update `status` to `approved` and proceed to downstream generation\n4. ! Create scope vBRIEFs in `./vbrief/proposed/` with traceability to requirement IDs from the narratives\n- ! Scope vBRIEFs MUST trace tasks back to requirement IDs (FR-1, NFR-1) from the `Requirements` narrative\n- ⊗ Generate an authoritative PRD.md — if needed, users run `task prd:render`\n\n**Spec Structure (both paths):**\n- ! Overview, Architecture\n- ! Implementation Plan: scope vBRIEFs in `vbrief/proposed/` with phases and dependencies\n- ! Explicit dependency mapping between scopes (via vBRIEF `edges` or `references`)\n- ~ Scopes designed for parallel work by multiple agents\n- ! Testing Strategy and Deployment captured in narratives\n- ⊗ Write code — specification only\n\n### Lifecycle Bridge to Downstream Skills (#1025)\n\n! Scope vBRIEFs created by Phase 3 (both Light and Full paths) AND by the Onboarding Question \"Adding scope to existing project\" branch land in `vbrief/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 vbrief:preflight`) and the deft-directive-swarm Phase 0 Step 1 preflight BOTH require candidate vBRIEFs to live in `vbrief/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.\n\n! Surface this bridge to the user in the Phase 3 → next-skill handoff so they are not surprised by a wholesale preflight rejection downstream:\n\n - **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 vBRIEFs) is the canonical bridge. The monitor will scan `vbrief/proposed/` and `vbrief/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.\n - **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 vBRIEFs in `pending/` deliberately when they are queued for prioritisation rather than immediate dispatch.\n - **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 -- vbrief/proposed/<file>` then `task scope:activate -- vbrief/pending/<file>`. Both commands are idempotent and exit 0 on no-op (see `scripts/scope_lifecycle.py`). The #810 preflight gate (`task vbrief:preflight -- <active-path>`) will exit 0 only after the activate step.\n\n⊗ 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.\n\n⊗ Drop the user at the end of Phase 3 with scope vBRIEFs in `vbrief/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).\n\n### End-of-Phase-3 Export Prompt and Render Gate\n\n! After the human approval gate on `specification.vbrief.json` narratives but BEFORE handing off to `deft-directive-build` (or advancing speckit Phase 3 → Phase 4), ask the user whether to generate human-readable exports. This replaces the invisible skip-if-absent behavior of `task check` (#398) and closes the greenfield gap (#433). This is also 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-render-for-review) (#432).\n\n1. ! Prompt: \"Your `specification.vbrief.json` is approved. Generate `SPECIFICATION.md` and/or `PRD.md` now? (recommended for stakeholder review)\"\n 1. Yes — render both\n 2. `SPECIFICATION.md` only\n 3. `PRD.md` only\n 4. Skip — I’ll render later with `task spec:render` / `task prd:render`\n2. ! Run the selected render command(s):\n - `task spec:render` → writes `SPECIFICATION.md`\n - `task prd:render` → writes `PRD.md`\n3. ! If the user picked a speckit-strategy project: `task spec:render` is **mandatory** at this boundary — invoke it even if the user declined the prompt, because speckit Phase 3 → Phase 4 is gated on `SPECIFICATION.md` existing and matching the current vBRIEF hash.\n4. ! Confirm to the user which files were written and remind them that direct edits to `SPECIFICATION.md` / `PRD.md` are overwritten on the next render — edit `specification.vbrief.json` instead.\n5. ~ If the user skipped rendering and is NOT on a speckit strategy, no-op and continue.\n\n⊗ Advance a speckit project to Phase 4 without running `task spec:render` at this gate — `SPECIFICATION.md` is required for the Phase 3 transition criterion.\n⊗ Silently skip the prompt — greenfield users who never open a PR will miss the exports without it.\n\n### Handoff to deft-directive-build\n\n- ! Emit a structured-tool question asking whether to continue to the build phase 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.\n- ~ If platform supports skill invocation and the user picks Yes, invoke `skills/deft-directive-build/SKILL.md`\n- ⊗ Leave user with a dead end -- always offer the next step via the structured-tool phase-transition question\n- ⊗ 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).\n\n## Warp Auto-Approve Warning\n\n! **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.vbrief.json with no error or warning. The post-interview confirmation gate (below) is the last line of defense, but prevention is better than detection.\n\n## Post-Interview Confirmation Gate\n\n! After completing ALL interview questions for any phase (Phase 1, Phase 2, or Phase 3), but BEFORE writing any files:\n\n1. ! 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.)\n2. ! Ask the user for explicit confirmation: \"These are the values I captured. Write files? (yes/no)\"\n3. ! Accept only explicit affirmative responses (`yes`, `confirmed`, `approve`) -- reject vague responses (`proceed`, `do it`, `go ahead`) the same way `/deft:change` does\n4. ! If the user says `no`: re-display the values and ask which ones to correct, then re-confirm before writing\n5. ! 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.\"\n\n⊗ Write USER.md, PROJECT-DEFINITION.vbrief.json, specification.vbrief.json, or any other deft-directive-setup artifact without first displaying captured values and receiving explicit user confirmation.\n⊗ Treat a broad \"proceed\" or \"continue\" as confirmation to write files -- the user must explicitly confirm the displayed values.\n\n? **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.\n\n## Anti-Patterns\n\n- ! When deft-directive-setup generates or updates USER.md or PROJECT-DEFINITION.vbrief.json, the `deft_version` field MUST be set to the current framework version\n- ⊗ Generate a USER.md or PROJECT-DEFINITION.vbrief.json without including the `deft_version` field\n- ⊗ Explore codebase before Phase 1 questions\n- ⊗ Read framework files before first question\n- ⊗ Batch multiple questions into one message — ask one at a time, interview style\n- ⊗ Ask jargon-heavy questions to non-technical users\n- ⊗ Ask about things inferable from codebase (Phase 2+)\n- ⊗ Skip phases without asking\n- ⊗ Generate files without confirming content\n- ⊗ Present choices through a host UI that replaces the canonical numbers with alphabetic affordances or unlabeled buttons\n- ⊗ Resolve paths relative to the skill file, AGENTS.md, or framework directory instead of the user's pwd at skill entry\n- ⊗ Generate an authoritative PRD.md — PRD.md is a read-only export via `task prd:render`, never a source of truth\n",
206
+ "body": "<!-- AUTO-GENERATED by task packs:render -- DO NOT EDIT MANUALLY -->\n<!-- Purpose: rendered skill -->\n<!-- Source of truth: packs/skills/skills-pack-0.1.json -->\n<!-- Regenerate with: task packs:render -->\n<!-- Edit the source, not this file. Slice instead of loading every SKILL.md: task packs:slice skills by-trigger --trigger <kw> (or list) -->\n\n# Deft Directive Setup\n\nAgent-driven alternative to `.deft/core/run bootstrap && .deft/core/run project && .deft/core/run spec`.\n\nLegend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.\n\n## When to Use\n\n- User says \"set up deft\", \"configure deft\", or \"bootstrap my project\"\n- User asks to create USER.md, PROJECT-DEFINITION.vbrief.json, or a specification\n- User clones a deft-enabled repo for the first time with no config\n\n## Pre-Cutover Detection Guard\n\n! Before proceeding with any setup phase, detect whether the project uses the pre-v0.20 document model and redirect to migration if so.\n\n### Detection Criteria\n\nA project is **pre-cutover** if ANY of the following are true. This prose mirrors the executable helper in `scripts/_precutover.py`; when in doubt, the helper is canonical.\n\n1. `SPECIFICATION.md` exists and is neither a deprecation redirect nor a current generated spec export. A current generated spec export contains `<!-- Purpose: rendered specification -->` and `<!-- Source of truth: vbrief/specification.vbrief.json -->`, and `vbrief/specification.vbrief.json` plus all five lifecycle folders exist.\n2. `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).\n3. `vbrief/specification.vbrief.json` exists but the lifecycle folders (`vbrief/proposed/`, `vbrief/pending/`, `vbrief/active/`, `vbrief/completed/`, `vbrief/cancelled/`) do NOT exist\n\n### Action on Detection\n\n! If pre-cutover state is detected, **stop immediately** and display an actionable message:\n\n> \"This project uses the pre-v0.20 document model. Run `task migrate:vbrief` to upgrade to the vBRIEF-centric model.\"\n\n! Include specific details about what was detected:\n\n- Missing lifecycle folders: \"Run `task migrate:vbrief` to create the lifecycle folder structure\"\n- `SPECIFICATION.md` with real content: \"SPECIFICATION.md contains non-redirect content -- this file is deprecated; use scope vBRIEFs in `vbrief/` instead\"\n- `PROJECT.md` with real content: \"PROJECT.md contains non-redirect content -- this file is deprecated; use `PROJECT-DEFINITION.vbrief.json` instead\"\n- Missing `PROJECT-DEFINITION.vbrief.json`: \"Run `task project:render` to generate the project definition\"\n\n### Environment Preflight (before asking to run migration)\n\n! Before asking the user \"Would you like me to run `task migrate:vbrief` now?\", run an environment preflight and report the results to the user. Do NOT ask the yes/no prompt until preflight results have been reported. Each failing check must be surfaced with a specific fix pointer so the user (or agent) can resolve the blocker before approving the run.\n\nRun these four checks, in order:\n\n1. **Document-model confirmation** -- re-apply the Detection Criteria above (the executable source is `scripts/_precutover.py`). If `SPECIFICATION.md` is a current generated spec export from `vbrief/specification.vbrief.json` and all lifecycle folders exist, stop: migration is NOT needed and MUST NOT be run.\n2. **Task resolvability** -- check whether `task migrate:vbrief` is dispatchable from the project root:\n - Run `task --list` (or platform-equivalent) and grep the output for a line containing `migrate:vbrief`.\n - If present: the primary command works from the project root -- canonical invocation is `task migrate:vbrief`.\n - If absent: the consumer `Taskfile.yml` does not include `deft/Taskfile.yml`. Fall back to the explicit-taskfile invocation `task -t ./deft/Taskfile.yml migrate:vbrief` and tell the user: \"`task migrate:vbrief` is not resolvable from the project root. I will use the fallback invocation `task -t ./deft/Taskfile.yml migrate:vbrief`, which reads the task directly from the framework Taskfile. To make the primary command work in future, add an include for `deft/Taskfile.yml` to your project `Taskfile.yml` — see `deft/main.md` § Publishing deft tasks in your project root.\"\n3. **`uv` on PATH** -- the migrator runs `uv run python scripts/migrate_vbrief.py`. Check `uv --version` (or equivalent): if it fails, point the user at the uv install docs (`https://docs.astral.sh/uv/`) and stop; migration cannot run without `uv`.\n4. **Migration script present** -- check `deft/scripts/migrate_vbrief.py` exists on disk. If absent, the `deft/` checkout is incomplete or came from a pre-v0.20 framework version; point the user at `deft/QUICK-START.md` (framework refresh guidance) and stop.\n\n! Report each preflight check's result to the user (e.g. \"✓ task migrate:vbrief resolvable\", \"✗ uv not on PATH — install from https://docs.astral.sh/uv/\") BEFORE prompting for yes/no approval. If any check fails, do NOT offer to run migration until it is resolved.\n\n⊗ Skip preflight and immediately ask \"Would you like me to run `task migrate:vbrief` now?\" -- preflight catches preventable errors (unresolvable task, missing `uv`, missing script) before the user commits to running migration.\n⊗ Propose an install-step mutation that writes `migrate:vbrief` content into the consumer Taskfile. The supported publish mechanism is the `includes: deft: deft/Taskfile.yml` pattern documented in `deft/main.md` § Publishing deft tasks in your project root; inline Taskfile mutation is explicitly out of scope (per #506 D6).\n\n### Prompt and Run\n\n! After preflight results are reported (and all checks pass), ask the user: \"Would you like me to run `task migrate:vbrief` now?\"\n- If yes: run the migration command (use the fallback invocation `task -t ./deft/Taskfile.yml migrate:vbrief` if the preflight resolvability check found the primary task unresolvable). Then re-run the pre-cutover detection guard to verify clean state before proceeding.\n- If no: stop and let the user handle migration manually.\n\n⊗ Proceed with setup phases when pre-cutover artifacts are detected -- always redirect to migration first.\n⊗ Silently ignore pre-cutover artifacts -- the user must be informed with an actionable command to fix the state.\n⊗ Display the migration diagnostic without offering to run it -- always ask the user if they want the agent to handle it (after preflight has passed).\n\n### Greenfield Projects (No Migration Needed)\n\n! For new projects (no existing `SPECIFICATION.md`, `PROJECT.md`, or `vbrief/specification.vbrief.json`), the guard passes silently and setup proceeds normally.\n\n! Greenfield setup creates the full vBRIEF-centric structure from scratch:\n\n1. `./vbrief/` directory with all 5 lifecycle subdirectories: `proposed/`, `pending/`, `active/`, `completed/`, `cancelled/`\n2. `./vbrief/PROJECT-DEFINITION.vbrief.json` generated from Phase 2 interview results\n3. First scope vBRIEF created in `proposed/` or `pending/` depending on Phase 3 interview outcome\n\n~ This is already handled by Phase 2 Output Path (creates `./vbrief/` and lifecycle subfolders) and Phase 3 Output (creates scope vBRIEFs in lifecycle folders). The guard ensures migrating projects are redirected before reaching these phases.\n\n### Migration safety flags\n\n`task migrate:vbrief` is destructive by default (it replaces `SPECIFICATION.md` and `PROJECT.md` with redirect stubs and rewrites `vbrief/`), but it carries four always-on / on-demand safety affordances so operators can preview, recover, and undo (#497, #506 D7). Agents offering to run migration MUST mention these and pick the right one for the operator's situation.\n\n- ! **Automatic `.premigrate.*` backups (always-on, no flag)**: before any destructive write the migrator copies every pre-cutover input to its `.premigrate` sibling -- `SPECIFICATION.md` -> `SPECIFICATION.premigrate.md`, `PROJECT.md` -> `PROJECT.premigrate.md`, `ROADMAP.md` -> `ROADMAP.premigrate.md`, `PRD.md` -> `PRD.premigrate.md` (only if present), and `vbrief/specification.vbrief.json` -> `vbrief/specification.premigrate.vbrief.json`. Each backup emits a `BACKUP <src> -> <dst> (<N> bytes)` line in the migration output. These files are `.gitignore`d by default so they do not leak into commits; operators who want them versioned can remove the patterns.\n- ! **`task migrate:vbrief -- --dry-run` (preview)**: prints the complete migration plan (every proposed backup, lifecycle folder, narrative ingestion, scope vBRIEF, and deprecation-redirect replacement) prefixed `DRYRUN` without writing any file. Exits 0 on success. Use this before running migration for the first time on an unfamiliar project.\n- ! **Dirty-tree guard (always-on)**: if `git status --porcelain` is non-empty the migrator refuses to run and points the operator at `--force`. Keeps migration output separable from in-progress edits. Bypass with `task migrate:vbrief -- --force` only after confirming the operator has accepted the risk.\n- ! **`task migrate:vbrief -- --rollback`**: restores every pre-cutover input from its `.premigrate.*` backup and removes the scope vBRIEFs and migration-report files a prior run created. Reads `vbrief/migration/safety-manifest.json` (written by the migrator). Refuses if any redirect stub has been edited since migration -- re-run with `--force` to overwrite those edits on purpose, or commit them before rolling back. Prompts for a yes/no confirmation unless `--force` is passed.\n\n! When a user declines an in-flight migration or reports an incorrect result, offer `task migrate:vbrief -- --rollback` before asking them to edit files by hand.\n\n⊗ Offer `task migrate:vbrief` without also telling the user about `--dry-run` when they sound hesitant -- previewing is free and catches reconciliation surprises that would otherwise land in a commit.\n⊗ Suggest `git reset --hard` or manual file deletion as a recovery path when `--rollback` would do the right thing more safely.\n\n## Deterministic Questions Contract\n\n! 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.\n\n## Platform Detection\n\n! Before resolving any config paths, detect the host OS from your environment context:\n\n| Platform | USER.md default path |\n|--------------------|-------------------------------------------------------------------|\n| Windows | `%APPDATA%\\deft\\USER.md` (e.g. `C:\\Users\\{user}\\AppData\\Roaming\\deft\\USER.md`) |\n| Unix (macOS/Linux) | `~/.config/deft/USER.md` |\n\n- ! If `$DEFT_USER_PATH` is set, it takes precedence on any platform\n- ! Create parent directories as needed when writing USER.md\n- ~ `$DEFT_PROJECT_PATH` overrides the default project config path (`./vbrief/PROJECT-DEFINITION.vbrief.json`) if set\n\n## Agent Behavior\n\n**Flow:**\n- ! Start asking immediately — everything you need is in THIS file\n- ⊗ Explore the codebase, read framework files, or gather context before asking\n- ? Read `deft/main.md` or language files LATER when generating output\n\n**Interaction:**\n- ~ 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.\n- ! 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.\n- ⊗ Infer deterministic answers from host-added letters or shortcuts unless those letters were actually displayed in the canonical menu labels.\n\n**Defaults:**\n- ! Communicate that deft ships with best-in-class standards for 20+ languages\n- ! Frame setup as \"tell me your overrides\" — not \"configure everything\"\n- ~ \"Deft has solid opinions on how code should be written and tested — I just need a few things about you and your project.\"\n\n**Adapt to Technical Level:**\n- ! First question gauges whether user is technical or non-technical\n- ! Technical user: ask about languages, strategy, coverage directly — they'll have opinions\n- ! Non-technical user: skip jargon, use sensible defaults, ask about what they're building not how\n- ⊗ Ask non-technical users about coverage thresholds, strategies, or framework choices\n\n## Available Languages\n\nC, C++, C#, Dart, Delphi, Elixir, Go, Java, JavaScript, Julia, Kotlin,\nOffice.js (Excel JavaScript API), Python, R, Rust, SQL, Swift, TypeScript,\nVBA (Excel macros), VHDL, Visual Basic (.NET), Zig, 6502-DASM\n\n- ? Read `deft/languages/{name}.md` when generating output — not before asking\n\n## Available Strategies\n\n~ When presenting strategies to the user, always use this numbered list format (not a plain table).\n~ Always include the chaining note below the list.\n! Always show the FULL strategy list at every chaining gate — never remove a strategy because it was previously run.\n~ If a strategy has been run already, indicate it with a note e.g. `(run 1x)` but keep it selectable.\n\n1. **interview** ★ (recommended) — Structured interview with sizing gate: Light or Full path\n2. **yolo** — Auto-pilot interview — Johnbot picks all recommended options\n3. **map** — Analyze existing codebase conventions before adding features\n4. **discuss** — Front-load decisions and alignment before planning\n5. **probe** — Adversarially stress-test the plan; surface assumptions, edge cases, and risks before spec\n6. **research** — Investigate the domain before planning\n7. **speckit** — Five-phase spec-driven workflow for large/complex projects\n\n> 💡 Strategies can be chained — after one completes, you'll be asked if you want to run another.\n\n---\n\n## Phase 1 — User Preferences (USER.md)\n\n**Goal:** Personal preferences file with two sections:\n- **Personal** — always wins over everything (name, custom rules)\n- **Defaults** — fallback values that PROJECT-DEFINITION.vbrief.json can override (strategy, coverage)\n\n- ~ Skip if USER.md exists at the platform-appropriate path (see Platform Detection) and user doesn't want to overwrite\n- ⊗ Scan filesystem beyond checking that one path\n\n### USER.md Freshness Detection\n\n! When an existing USER.md is found (returning user), check its `deft_version` field before skipping Phase 1:\n\n1. ! If `deft_version` is **missing**: the USER.md predates versioning -- treat as stale\n2. ! If `deft_version` is present but **differs from the current framework version** (0.20.0): check whether any expected fields are missing from the USER.md\n3. ! If fields are missing: query the user for each missing field individually -- do NOT re-run the full Phase 1 interview\n4. ! After completing any field queries (even if none were needed), write the current `deft_version` (0.20.0) to USER.md\n5. ~ If `deft_version` matches the current version and all expected fields are present: no action needed (USER.md is fresh)\n\nExpected USER.md fields: **Name**, **Custom Rules**, **Default Strategy**, and optionally **Coverage** and **Experimental Rules**.\n\n⊗ Re-run the full Phase 1 interview when only individual fields are missing from a stale USER.md -- query missing fields individually instead.\n\n### Interview Rules\n\n! 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:\n\n! **Each message you send MUST contain exactly ONE question.** This is the most\nimportant rule in this file. After the user answers, send the NEXT question in\na new message. Repeat until all questions for their track are answered.\n\n- ⊗ Include two or more questions in the same message under any circumstances\n- ⊗ List upcoming questions — only show the current one\n- ~ Provide numbered answer options with an \"other\" choice where appropriate\n- ! Mark which option is RECOMMENDED when showing choices\n- ~ Use structured question tools only when visible option labels preserve the canonical numbers and returns map to numeric selections or exact displayed option text.\n\n### Question Sequence\n\n**Step 0 — Opening (all users):**\nAsk: \"How deep do you want to go?\"\n 1. I'm technical — ask me everything\n 2. I have some opinions but keep it simple\n 3. Just pick good defaults — I care about the product, not the tools\n\nWait for answer. Then follow the track below.\n\n**Track 1 (technical) — 7 steps:**\n- Step 1: Ask their name\n- Step 2: Ask strategy preference (show Available Strategies numbered list from the Available Strategies section, with descriptions and recommended marker; fallback — projects can override)\n- Step 3: Ask coverage threshold (default 85%; fallback — projects can override)\n- Step 4: Ask for custom rules — if user has rules, collect them one per line (empty line to finish); if none, skip\n- Step 5a: Present SOUL.md and ask whether to include it (default: yes):\n > **SOUL.md** — Results-first agent persona (inspired by Winston Wolf). Enforces assess-before-acting,\n > finish-what-you-start, right-tool-for-the-job, and play-the-long-game. Keeps the AI decisive and\n > concise. Includes a named persona ('Vinston') — drop if you prefer to define your own agent personality.\n > Include SOUL.md? (Y/n)\n- Step 5b: Present morals.md and ask whether to include it (default: yes):\n > **morals.md** — Epistemic honesty rules. No presenting speculation as fact, label unverified claims,\n > self-correct when wrong. Foundational trust rules for any AI agent. Strongly recommended.\n > Include morals.md? (Y/n)\n- Step 5c: Present code-field.md and ask whether to include it (default: yes):\n > **code-field.md** — Pre-code assumption protocol. Requires stating assumptions and naming failure modes\n > before writing a single line. Fights the 'it compiles, ship it' instinct. Based on NeoVertex1 context-field.\n > Include code-field.md? (Y/n)\n\n**Track 2 (middle ground) — 2 steps:**\n- Step 1: Ask their name\n- Step 2: Ask for custom rules — if user has rules, collect them one per line (empty line to finish); if none, skip\n- Set defaults without asking: strategy = \"interview\", coverage = 85%, all meta-guidelines included\n\n**Track 3 (non-technical) — 2 steps:**\n- Step 1: Ask their name\n- Step 2: Ask what they're building (brief description — used for PROJECT-DEFINITION.vbrief.json later)\n- Set defaults: strategy = \"interview\", coverage = 85%, all meta-guidelines included\n\n### Output Path\n\nResolve using Platform Detection above. Write to the platform-appropriate path\n(or `$DEFT_USER_PATH` if set). Create parent directories as needed.\n\n### Template\n\n```markdown\n# User Preferences\n\nLegend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.\n\n**deft_version**: 0.20.0\n\n## Personal (always wins)\n\nSettings in this section have HIGHEST precedence — override all other deft rules,\nincluding PROJECT-DEFINITION.vbrief.json.\n\n**Name**: Address the user as: **{name}**\n\n**Custom Rules**:\n{custom rules or \"No custom rules defined yet.\"}\n\n## Defaults (fallback)\n\nSettings in this section are fallback defaults. PROJECT-DEFINITION.vbrief.json overrides these\nfor project-scoped settings (strategy, coverage).\n\n**Default Strategy**: [{strategy name}](../strategies/{strategy-file}.md)\n\n{If coverage != 85: \"**Coverage**: ! ≥{N}% test coverage\"}\n\n{If any experimental rules selected:\n\"## Experimental Rules\n\n{one line per selected rule, e.g.:\n- ! Use meta/SOUL.md for strategic context and purpose-driven guidance\n- ! Use meta/morals.md for ethical AI development principles\n- ~ Use meta/code-field.md for advanced architecture patterns}\"}\n\n---\n\n**Note**: Edit this file anytime to update your preferences.\n**See**: [../../main.md](../../../main.md) for framework defaults.\n```\n\n### Then\n\n- ! 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.\n- ⊗ 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).\n\n---\n\n## Phase 2 — Project Configuration (PROJECT-DEFINITION.vbrief.json)\n\n**Goal:** Project-specific configuration — tech stack, type, quality standards — written as a vBRIEF file at `./vbrief/PROJECT-DEFINITION.vbrief.json`.\n\n! **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 (`./vbrief/PROJECT-DEFINITION.vbrief.json`, build files, etc.) must be resolved from the user's pwd.\n\n- ~ Skip if `./vbrief/PROJECT-DEFINITION.vbrief.json` exists (or `$DEFT_PROJECT_PATH` if set) and user doesn't want to replace\n- ⊗ Count `./deft/PROJECT-DEFINITION.vbrief.json` or `./deft/core/project.md` as the user's project config — those are framework-internal\n\n### Inference\n\n- ! Before asking, infer from codebase — look for `package.json`, `go.mod`, `requirements.txt`, `Cargo.toml`, `pyproject.toml`, `*.csproj`\n- ! Use inferences to pre-fill answers and confirm — don't ask blind\n- ⊗ 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.\n- ⊗ Run git commands inside `./deft/` to determine project identity — that directory is the framework repo, not the user's project.\n- ~ If no build files are found at the project root, default the project name to the current directory name and ask for confirmation.\n\n### Track Detection\n\n! If Phase 1 was skipped (USER.md already existed), the user's track is unknown.\nBefore asking any Phase 2 questions, ask the depth question:\n\n> \"How deep do you want to go?\"\n> 1. I'm technical — ask me everything\n> 2. I have some opinions but keep it simple\n> 3. Just pick good defaults — I care about the product, not the tools\n\nWait for answer. Then follow the corresponding track in the Question Sequence below.\n\n⊗ Assume Track 1 (technical) because USER.md exists or contains strategy/coverage fields.\n⊗ Infer the track from USER.md content — always ask.\n\n### Defaults in Agentic Mode\n\n! When a question has a USER.md default, phrase it as:\n> \"{Field}: **{value}** from USER.md — keep this, or enter a different value?\"\n\n! Accept any affirmative response (\"keep\", \"yes\", \"same\", \"default\", ✓) as confirmation to use the default.\n⊗ Phrase defaults as \"press Enter to keep\" — there is no Enter in conversational mode.\n\n### Interview Rules (same as Phase 1)\n\n! **Each message MUST contain exactly ONE question.** The Phase 1 interview rules\napply here too. Do not combine questions. See `skills/deft-directive-interview/SKILL.md` for the canonical deterministic interview loop.\n\n### Question Sequence\n\n**Track 1 (technical) — 8 steps:**\n- Step 1: Ask project name (infer from build files or directory name, confirm)\n- Step 2: Ask project type (CLI, TUI, Desktop App, REST API, Web App, Library, other)\n- Step 3: Ask deployment platform:\n 1. Cross-platform (Linux / macOS / Windows)\n 2. Windows-native\n 3. macOS-native\n 4. Linux / Unix\n 5. Embedded / low-resource\n 6. Web / Cloud\n 7. Mobile (iOS / Android)\n 8. Other / not sure\n- 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?\"\n - If user selects \"Other\": show remaining plausible languages for the type+platform context (Tier 2)\n - If still not found: free text input (Tier 3)\n - 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?\"\n- Step 5: Ask tech stack (frameworks, libraries)\n- 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)\n- Step 7: Ask coverage (default to USER.md Defaults; ask if this project needs different)\n- Step 8: Ask for project-specific rules (optional, same one-per-line format as Phase 1 custom rules)\n- Step 9: Ask branching preference (typed `plan.policy.allowDirectCommitsToMaster` flag per #746):\n\n ! 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):\n\n > \"Do you prefer branch-based workflow (create a feature branch for every change) or\n > trunk-based (commit directly to master)? Branch-based is the default and recommended\n > for teams; trunk-based is common for solo projects.\"\n > 1. Branch-based ★ (recommended -- default; enforces feature branches via the deft branch-protection policy)\n > 2. Trunk-based (direct commits to master) -- see capability-cost disclosure below\n > 3. Discuss\n > 4. Back\n\n ! **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:\n\n > \"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, `task 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?\"\n > 1. Yes, opt out -- write `plan.policy.allowDirectCommitsToMaster = true`\n > 2. No, keep branch-protection enforced -- write `plan.policy.allowDirectCommitsToMaster = false`\n > 3. Discuss\n > 4. Back\n\n ! 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`).\n\n ! Write the answer to `plan.policy.allowDirectCommitsToMaster` (typed boolean) on the PROJECT-DEFINITION vBRIEF. Default `false` (enforce branches) when the user picks option 2 OR omits the question entirely. Writing this typed surface is what the framework reads going forward; agents MUST NOT write the legacy free-form `Allow direct commits to master:` narrative key (#746 part A migrates the legacy narrative away).\n\n ! **Re-running the interview detects the existing flag (#746 part G2):** If `vbrief/PROJECT-DEFINITION.vbrief.json` already exists and has `plan.policy.allowDirectCommitsToMaster` set, the interview MUST surface the current value (e.g. \"Current setting: `allowDirectCommitsToMaster=false` (branch-protection ON)\") and ask whether to keep it or change it before re-prompting. Do not silently overwrite an existing typed value.\n\n ! **Slash-command alternatives (#746 part G2):** Once the project is set up, the typed flag can also be flipped via slash commands wrapping `task policy:*`:\n - `/deft:policy:show` -- display the current resolved policy and source\n - `/deft:policy:enforce-branches` -- set `allowDirectCommitsToMaster=false`\n - `/deft:policy:allow-direct-commits` -- set `allowDirectCommitsToMaster=true` (requires `--confirm` to apply)\n\n Each transition is recorded to `meta/policy-changes.log` for auditability.\n\n**Track 2 (middle ground) — 4 steps:**\n- Step 1: Ask project name (infer from build files or directory name, confirm)\n- Step 2: Ask project type (CLI, TUI, Desktop App, REST API, Web App, Library, other)\n- Step 3: Ask languages (show detected, confirm or adjust; if none detected, infer from type and ask)\n- 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)\n- Default coverage to USER.md Defaults without asking\n\n**Track 3 (non-technical) — 1 step:**\n- Step 1: Present summary of inferences: \"Based on your project: {name} ({type}), built with {stack}. Look right?\"\n- ⊗ Ask about strategy or coverage — use Phase 1 defaults\n\n### Output Path\n\n`./vbrief/PROJECT-DEFINITION.vbrief.json` (or `$DEFT_PROJECT_PATH` if set). Create `./vbrief/` directory and lifecycle subfolders (`proposed/`, `pending/`, `active/`, `completed/`, `cancelled/`) if they don't exist.\n\n### GitHub PR Template Scaffolding (#531)\n\n! Before writing `PROJECT-DEFINITION.vbrief.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.\n\n1. ! 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.\n2. ! 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.\n3. ! If the file already exists, do NOT overwrite it — report that it is present and continue.\n4. ~ If the user declines, note that `deft-directive-refinement` Pre-Flight will offer to scaffold later when needed.\n\n⊗ Overwrite an existing `.github/PULL_REQUEST_TEMPLATE.md` without explicit user approval.\n\n### Headless Coverage Warning — display-bound GUI entry points (#1027)\n\n! 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.vbrief.json` (adapt the wording to the project's language):\n\n> \"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.\"\n\n! 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:\n\n```toml\n[tool.coverage.run]\nomit = [\n \"*/tests/*\",\n \"*/venv/*\",\n \"*/.venv/*\",\n \"src/ui.py\", # display-bound pygame/tkinter event loop -- cannot run headlessly (#1027)\n]\n```\n\n- ! 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.\n- ~ 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.\n- ⊗ 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.\n- ⊗ 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).\n\n### Template\n\n! The output MUST conform to the canonical vBRIEF v0.6 schema (`vbrief/schemas/vbrief-core.schema.json`, strict `const: \"0.6\"`). See [`../../conventions/references.md`](../../conventions/references.md).\n\n```json\n{\n \"vBRIEFInfo\": {\n \"version\": \"0.6\",\n \"author\": \"agent:deft-directive-setup\",\n \"description\": \"Project identity gestalt\",\n \"created\": \"{ISO-8601 timestamp}\"\n },\n \"plan\": {\n \"title\": \"{Project Name}\",\n \"status\": \"running\",\n \"narratives\": {\n \"Overview\": \"{Brief project description}\",\n \"TechStack\": \"{project type} using {languages} — {tech stack details}\",\n \"Strategy\": \"Use {strategy name} for this project\",\n \"Quality\": \"Run task check before every commit. Achieve >= {coverage}% coverage overall + per-module. Store secrets in secrets/ dir.\",\n \"ProjectRules\": \"{Any rules the user specified, or 'No project-specific rules defined.'}\",\n \"Branching\": \"{If trunk-based: 'Allow direct commits to master: true', else omit or 'Branch-based workflow (default)'}\",\n \"DeftVersion\": \"0.20.0\"\n },\n \"items\": []\n }\n}\n```\n\n- ! All `narratives` values MUST be plain strings — never objects or arrays\n- ! `items` starts empty — populated as scope vBRIEFs are created in lifecycle folders\n\n### Then\n\n- ! 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. 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.\n- ⊗ 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).\n\n### Follow-up: triage onboarding (#1143)\n\n- ~ After Phase 2 writes `PROJECT-DEFINITION.vbrief.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.\n- ~ `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.\n- ? The recommendation is informational, not a hard gate -- consumers who plan to wire triage manually MAY skip the ritual and call the individual verbs in any order; the framework defaults stay fail-open per the umbrella `#1119 §12 framework-vs-consumer-config boundary`.\n\n---\n\n## Phase 3 — Specification\n\n**Goal:** Generate an implementable spec using the strategy chosen in Phase 2, producing scope vBRIEFs in `vbrief/proposed/` and PROJECT-DEFINITION narratives for human approval — greenfield v0.20 does not create `specification.vbrief.json`.\n\n! **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.\n\n- ~ Skip if user already has scope vBRIEFs in `./vbrief/` they're happy with\n- ! Check `./vbrief/specification.vbrief.json` or `./vbrief/proposed/` for existing scope vBRIEFs\n- ⊗ Count ANY file inside `./deft/` as the project's spec — those are framework-internal\n (e.g. `deft/PROJECT.md`, `deft/specs/`, `deft/templates/`, `deft/core/project.md`\n are all part of the framework, NOT the user's project)\n\n### Onboarding Question\n\n! Before proceeding with the strategy gate, ask the onboarding question:\n\n> \"Are you adding a scope to this project or starting a new specification?\"\n> 1. Adding scope to existing project [default if `./vbrief/specification.vbrief.json` exists or scope vBRIEFs found in lifecycle folders]\n> 2. Starting a new project specification [default if no specification or scope vBRIEFs exist]\n\n- ! Default based on repo state: if specification.vbrief.json exists or any lifecycle folder has scope vBRIEFs, default to \"Adding scope\"; otherwise default to \"Starting new\"\n- ! If adding scope: skip the full interview, create a new scope vBRIEF in `./vbrief/proposed/` with the user's description, then exit\n- ! If starting new: proceed to the Strategy Gate below\n\n### ⚠️ MANDATORY: Strategy Gate — Do This First\n\n! **STOP.** You MUST determine the correct strategy before doing anything else.\n\n1. ! Open `./vbrief/PROJECT-DEFINITION.vbrief.json` (the file written in Phase 2)\n2. ! Find the `narratives.Strategy` value\n3. ! Extract the strategy name from the narrative\n\n**Dispatch:**\n\n- **interview** (or default) → Continue to the Sizing Gate below ✅\n- **anything else** (discuss, yolo, speckit, research, brownfield, map, etc.) →\n 1. ! Read `deft/strategies/{strategy-name}.md` **right now, in this same turn**\n 2. ! Begin the strategy's workflow immediately — ask its first question\n 3. ! **STOP reading this section** — do NOT use the interview process below\n\n- ⊗ Default to interview without reading PROJECT-DEFINITION.vbrief.json\n- ⊗ Continue reading below when PROJECT-DEFINITION.vbrief.json specifies a non-interview strategy\n- ⊗ Assume interview because the sections below describe the interview process\n- ⊗ Fabricate justification for using interview when the user chose a different strategy\n- ⊗ Announce the strategy choice and then stop — you must immediately read the file and start\n\n---\n\n*⬇️ Everything below applies ONLY to the interview strategy. If your strategy is anything else, STOP — follow your strategy file instead.*\n\n### Sizing Gate (interview and yolo strategies only)\n\n! After hearing what the user wants to build and their feature list, determine\nproject complexity per [strategies/interview.md](../../strategies/interview.md#sizing-gate).\n\n- ! Check `PROJECT-DEFINITION.vbrief.json` narratives for `Light` or `Full` — if declared, use that path\n- ! If not declared, propose a size and **ask the user to confirm in a dedicated message**\n- ! **Wait for the user's response** before asking any interview questions\n- ⊗ Combine the sizing proposal with the first interview question\n- ⊗ Proceed to interview questions before the user has confirmed the path\n\n**Light** (small/medium): Interview → `specification.vbrief.json` with slim narratives (Overview + Architecture) → scope vBRIEFs in `vbrief/proposed/`.\n**Full** (large/complex): Interview → rich narratives in `specification.vbrief.json` (user approval) → scope vBRIEFs with traceability.\n\n### Interview Process (interview strategy)\n\nPer [strategies/interview.md](../../strategies/interview.md#interview-rules-shared-by-both-paths):\n\n- ! Ask what to build and features first\n- ! Ask **ONE** focused, non-trivial question per step\n- ~ Provide numbered options with an \"other\" choice\n- ! Mark which option is RECOMMENDED\n- ⊗ Ask multiple questions at once\n- ⊗ Make assumptions without clarifying\n- ~ 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.\n\n**Question Areas:**\n- ! Missing decisions (language, framework, deployment)\n- ! Edge cases (errors, boundaries, failure modes)\n- ! Implementation details (architecture, patterns, libraries)\n- ! Requirements (performance, security, scalability)\n- ! UX/constraints (users, timeline, compatibility)\n- ! Tradeoffs (simplicity vs features, speed vs safety)\n\n**Non-Technical Users:**\n- ~ Adjust vocabulary: \"How do you want to store data?\" not \"What database engine?\"\n- ~ \"Will other apps talk to this?\" not \"REST or GraphQL?\"\n\n**Completion:**\n- ! Continue until little ambiguity remains\n- ! Spec must be comprehensive enough to implement\n\n### Output — Light Path\n\n1. ! Write `./vbrief/specification.vbrief.json` with `\"vBRIEFInfo\": { \"version\": \"0.6\" }`, `status: draft`, and slim narratives:\n - `Overview`: Brief project summary\n - `Architecture`: System design description\n2. ! Create scope vBRIEFs in `./vbrief/proposed/` for each identified work item\n - Each scope vBRIEF follows the `YYYY-MM-DD-descriptive-slug.vbrief.json` filename convention (slug rules in [`../../conventions/vbrief-filenames.md`](../../conventions/vbrief-filenames.md))\n - Each MUST use `\"vBRIEFInfo\": { \"version\": \"0.6\" }`\n - Each MUST include embedded Requirements (FR-N, NFR-N) in its `narrative`\n - Each task SHOULD reference which FR/NFR it implements via `narrative.Traces`\n - When the scope originates from a GitHub issue, include a `references` entry in the canonical form (see [`../../conventions/references.md`](../../conventions/references.md)):\n ```json\n \"references\": [\n {\n \"uri\": \"https://github.com/{owner}/{repo}/issues/{N}\",\n \"type\": \"x-vbrief/github-issue\",\n \"title\": \"Issue #{N}: {issue title}\"\n }\n ]\n ```\n3. ! Summarize decisions, ask user to review the vBRIEF narratives\n4. ! On approval, update `specification.vbrief.json` status to `approved`\n- ⊗ Create a separate PRD.md on the Light path\n- ⊗ Generate an authoritative PRD.md — if needed, users run `task prd:render`\n\n! The vBRIEF files MUST conform to `vbrief/schemas/vbrief-core.schema.json` (v0.6):\n\n- ! All `narratives` and `narrative` values MUST be plain strings — never objects or arrays\n- ! Nested children within a PlanItem use `items` (v0.6 preferred field); `subItems` is the deprecated legacy alias kept for backward compatibility only\n- ⊗ Mix `items` and `subItems` on the same PlanItem — pick one (prefer `items`)\n\n### Output — Full Path\n\n1. ! Write rich narratives to `./vbrief/specification.vbrief.json` with `\"vBRIEFInfo\": { \"version\": \"0.6\" }`, `plan.status: draft`, and these narrative keys:\n - `ProblemStatement`: What problem this project solves\n - `Goals`: High-level project goals\n - `UserStories`: User stories in standard format\n - `Requirements`: Structured requirements (FR-N: ..., NFR-N: ...)\n - `SuccessMetrics`: Measurable success criteria\n - `Architecture`: System design and technical architecture\n - `Overview`: Brief project summary\n2. ! **Human approval gate**: Present the vBRIEF draft narratives to the user for review — reviewing the `specification.vbrief.json` narratives IS the approval step (replaces the former PRD.md review). The user may request changes before approving.\n3. ! On approval, update `status` to `approved` and proceed to downstream generation\n4. ! Create scope vBRIEFs in `./vbrief/proposed/` with traceability to requirement IDs from the narratives\n- ! Scope vBRIEFs MUST trace tasks back to requirement IDs (FR-1, NFR-1) from the `Requirements` narrative\n- ⊗ Generate an authoritative PRD.md — if needed, users run `task prd:render`\n\n**Spec Structure (both paths):**\n- ! Overview, Architecture\n- ! Implementation Plan: scope vBRIEFs in `vbrief/proposed/` with phases and dependencies\n- ! Explicit dependency mapping between scopes (via vBRIEF `edges` or `references`)\n- ~ Scopes designed for parallel work by multiple agents\n- ! Testing Strategy and Deployment captured in narratives\n- ⊗ Write code — specification only\n\n### Lifecycle Bridge to Downstream Skills (#1025)\n\n! Scope vBRIEFs created by Phase 3 (both Light and Full paths) AND by the Onboarding Question \"Adding scope to existing project\" branch land in `vbrief/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 vbrief:preflight`) and the deft-directive-swarm Phase 0 Step 1 preflight BOTH require candidate vBRIEFs to live in `vbrief/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.\n\n! Surface this bridge to the user in the Phase 3 → next-skill handoff so they are not surprised by a wholesale preflight rejection downstream:\n\n - **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 vBRIEFs) is the canonical bridge. The monitor will scan `vbrief/proposed/` and `vbrief/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.\n - **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 vBRIEFs in `pending/` deliberately when they are queued for prioritisation rather than immediate dispatch.\n - **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 -- vbrief/proposed/<file>` then `task scope:activate -- vbrief/pending/<file>`. Both commands are idempotent and exit 0 on no-op (see `scripts/scope_lifecycle.py`). The #810 preflight gate (`task vbrief:preflight -- <active-path>`) will exit 0 only after the activate step.\n\n⊗ 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.\n\n⊗ Drop the user at the end of Phase 3 with scope vBRIEFs in `vbrief/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).\n\n### End-of-Phase-3 Export Prompt (project:export-spec)\n\n! After scope vBRIEFs are written to `vbrief/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).\n\n1. ! Prompt: \"Your scope vBRIEFs are ready. Generate a stakeholder-facing spec export and/or `PRD.md` now? (recommended for stakeholder review)\"\n 1. Yes — export spec (+ PRD if selected)\n 2. Spec export only (`SPECIFICATION.md`)\n 3. `PRD.md` only\n 4. Skip — I'll export later with `task project:export-spec` / `task prd:render`\n2. ! Run the selected export command(s):\n - `task project:export-spec` → writes `SPECIFICATION.md` from PROJECT-DEFINITION + lifecycle scopes (greenfield default; stakeholder audience)\n - `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)\n - `task prd:render` → writes `PRD.md` (optional stakeholder review)\n - Legacy `task spec:render` — migrated trees only (when `vbrief/specification.vbrief.json` exists); do NOT use on greenfield v0.20 projects\n3. ! 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.vbrief.json` approval.\n4. ! 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 vBRIEF narratives in `vbrief/proposed/` and PROJECT-DEFINITION instead.\n5. ~ If the user skipped export and is NOT on a speckit strategy, no-op and continue.\n\n⊗ 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.\n⊗ Silently skip the prompt — greenfield users who never open a PR will miss the exports without it.\n⊗ Invoke legacy `task spec:render` on a greenfield v0.20 project — use `task project:export-spec` instead (#2013).\n\n### Handoff to deft-directive-build\n\n- ! Emit a structured-tool question asking whether to continue to the build phase 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.\n- ~ If platform supports skill invocation and the user picks Yes, invoke `skills/deft-directive-build/SKILL.md`\n- ⊗ Leave user with a dead end -- always offer the next step via the structured-tool phase-transition question\n- ⊗ 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).\n\n## Warp Auto-Approve Warning\n\n! **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.vbrief.json with no error or warning. The post-interview confirmation gate (below) is the last line of defense, but prevention is better than detection.\n\n## Post-Interview Confirmation Gate\n\n! After completing ALL interview questions for any phase (Phase 1, Phase 2, or Phase 3), but BEFORE writing any files:\n\n1. ! 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.)\n2. ! Ask the user for explicit confirmation: \"These are the values I captured. Write files? (yes/no)\"\n3. ! Accept only explicit affirmative responses (`yes`, `confirmed`, `approve`) -- reject vague responses (`proceed`, `do it`, `go ahead`) the same way `/deft:change` does\n4. ! If the user says `no`: re-display the values and ask which ones to correct, then re-confirm before writing\n5. ! 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.\"\n\n⊗ Write USER.md, PROJECT-DEFINITION.vbrief.json, specification.vbrief.json, or any other deft-directive-setup artifact without first displaying captured values and receiving explicit user confirmation.\n⊗ Treat a broad \"proceed\" or \"continue\" as confirmation to write files -- the user must explicitly confirm the displayed values.\n\n? **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.\n\n## Anti-Patterns\n\n- ! When deft-directive-setup generates or updates USER.md or PROJECT-DEFINITION.vbrief.json, the `deft_version` field MUST be set to the current framework version\n- ⊗ Generate a USER.md or PROJECT-DEFINITION.vbrief.json without including the `deft_version` field\n- ⊗ Explore codebase before Phase 1 questions\n- ⊗ Read framework files before first question\n- ⊗ Batch multiple questions into one message — ask one at a time, interview style\n- ⊗ Ask jargon-heavy questions to non-technical users\n- ⊗ Ask about things inferable from codebase (Phase 2+)\n- ⊗ Skip phases without asking\n- ⊗ Generate files without confirming content\n- ⊗ Present choices through a host UI that replaces the canonical numbers with alphabetic affordances or unlabeled buttons\n- ⊗ Resolve paths relative to the skill file, AGENTS.md, or framework directory instead of the user's pwd at skill entry\n- ⊗ Generate an authoritative PRD.md — PRD.md is a read-only export via `task prd:render`, never a source of truth\n",
207
207
  "frontmatter_extra": null
208
208
  },
209
209
  {