@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
@@ -1,143 +1,25 @@
1
1
  #!/usr/bin/env sh
2
- # .githooks/pre-commit -- detection-bound branch-protection gate (#747).
2
+ # .githooks/pre-commit -- deft CLI gates (#2049 / #747 / #798 / #1620).
3
3
  #
4
- # Activated by `git config core.hooksPath .githooks` -- idempotent setup
5
- # performed by `task setup` (the directive repo itself) OR by the deft
6
- # installer, which copies this hook to the consumer root .githooks/ and sets
7
- # core.hooksPath for vendored consumer projects (#1463). Verify with:
8
- #
9
- # task verify:hooks-installed
10
- #
11
- # Pure POSIX-shell so this runs from MSYS / Git for Windows without bash
12
- # being on PATH. The Python script itself is stdlib-only so it does NOT
13
- # require `uv` or a virtualenv to be active.
4
+ # Activated by `git config core.hooksPath .githooks` via `task setup` or the
5
+ # deft installer (#1463). Pure POSIX shell; requires `deft` on PATH (no Python).
14
6
 
15
- # Resolve repo root (this hook lives at <core.hooksPath>/pre-commit).
16
7
  REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
17
8
  if [ -z "$REPO_ROOT" ]; then
18
9
  echo "deft pre-commit: unable to resolve repo root via 'git rev-parse'." >&2
19
10
  exit 1
20
11
  fi
21
12
 
22
- # Layout-aware helper resolution (#1463). In the directive repo the gate
23
- # scripts live at $REPO_ROOT/scripts/; in a vendored consumer the framework
24
- # payload (and its scripts/) lives at $REPO_ROOT/.deft/core/ (canonical) or
25
- # $REPO_ROOT/deft/ (legacy). Because the installer copies this hook to the
26
- # consumer root .githooks/, it MUST locate the helpers relative to the install
27
- # root rather than assuming $REPO_ROOT/scripts/. Probe the known layouts and
28
- # use the first that resolves so the hook works in BOTH layouts.
29
- SCRIPTS_DIR=""
30
- for candidate in "$REPO_ROOT/scripts" "$REPO_ROOT/.deft/core/scripts" "$REPO_ROOT/deft/scripts"; do
31
- if [ -f "$candidate/preflight_branch.py" ]; then
32
- SCRIPTS_DIR="$candidate"
33
- break
34
- fi
35
- done
36
- if [ -z "$SCRIPTS_DIR" ]; then
37
- echo "deft pre-commit: unable to locate the deft scripts directory." >&2
38
- echo " Looked in scripts/, .deft/core/scripts/, deft/scripts/ under $REPO_ROOT." >&2
39
- echo " Re-run the deft installer or 'task setup' to wire the hooks correctly." >&2
40
- exit 1
41
- fi
42
-
43
- # Resolve a usable Python interpreter (#1668). On Windows `python3` is usually
44
- # absent (only `python.exe` / the `py` launcher exist), and a bare `python3` on
45
- # PATH is often the Microsoft Store App-Execution-Alias stub that prints
46
- # "Python was not found" and exits non-zero. Probe DEFT_PYTHON -> python3 ->
47
- # python -> the `py -3` launcher, validating each candidate by running
48
- # `--version`, rejecting the alias stub, AND enforcing the framework's Python
49
- # 3.11+ floor (#1676 -- framework scripts import `from datetime import UTC`,
50
- # added in 3.11). PY_PREFIX carries the launcher selector (`-3`) when needed.
51
- PYTHON_BIN=""
52
- PY_PREFIX=""
53
-
54
- # _deft_try BIN [PREFIX] -- probe a candidate. Succeeds (and sets PYTHON_BIN /
55
- # PY_PREFIX) only when the candidate runs, is not the Windows alias stub, and
56
- # reports a Python version >= 3.11.
57
- _deft_try() {
58
- _bin="$1"
59
- _pre="${2:-}"
60
- command -v "$_bin" >/dev/null 2>&1 || return 1
61
- if [ -n "$_pre" ]; then
62
- _out=$("$_bin" "$_pre" --version 2>&1) || return 1
63
- else
64
- _out=$("$_bin" --version 2>&1) || return 1
65
- fi
66
- case "$_out" in
67
- *"Microsoft Store"*|*"was not found"*|*"execution alias"*) return 1 ;;
68
- esac
69
- case "$_out" in
70
- *Python\ [0-9]*) ;;
71
- *) return 1 ;;
72
- esac
73
- # Enforce the 3.11+ floor using POSIX parameter expansion (no sed/awk
74
- # dependency). Parse major.minor from the "Python X.Y.Z" banner.
75
- _rest=${_out#*Python }
76
- _major=${_rest%%.*}
77
- _rest=${_rest#*.}
78
- _minor=${_rest%%.*}
79
- case "$_major" in ''|*[!0-9]*) return 1 ;; esac
80
- case "$_minor" in ''|*[!0-9]*) return 1 ;; esac
81
- if [ "$_major" -gt 3 ]; then
82
- PYTHON_BIN="$_bin"; PY_PREFIX="$_pre"; return 0
83
- fi
84
- if [ "$_major" -eq 3 ] && [ "$_minor" -ge 11 ]; then
85
- PYTHON_BIN="$_bin"; PY_PREFIX="$_pre"; return 0
86
- fi
87
- return 1
88
- }
89
-
90
- if [ -n "${DEFT_PYTHON:-}" ]; then
91
- # DEFT_PYTHON is the explicit override, but still version-checked so the
92
- # hooks enforce the same 3.11+ floor as the installer (#1676).
93
- _deft_try "$DEFT_PYTHON" || true
94
- if [ -z "$PYTHON_BIN" ]; then
95
- echo "deft pre-commit: DEFT_PYTHON ($DEFT_PYTHON) is not a usable Python 3.11+ interpreter." >&2
96
- echo " Point DEFT_PYTHON at a Python 3.11+ executable." >&2
97
- exit 1
98
- fi
99
- else
100
- _deft_try python3 || _deft_try python || _deft_try py "-3" || true
101
- fi
102
-
103
- if [ -z "$PYTHON_BIN" ]; then
104
- echo "deft pre-commit: no usable Python 3.11+ interpreter found." >&2
105
- echo " Probed python3, python, and the 'py' launcher (rejecting the Windows" >&2
106
- echo " App-Execution-Alias stub and interpreters older than 3.11)." >&2
107
- echo " Set DEFT_PYTHON=<absolute python 3.11+ path> or install Python 3.11+." >&2
13
+ if ! command -v deft >/dev/null 2>&1; then
14
+ echo "deft pre-commit: 'deft' not found on PATH." >&2
15
+ echo " Install: npm i -g @deftai/directive" >&2
108
16
  exit 1
109
17
  fi
110
18
 
111
- # deft_py forwards args to the resolved interpreter, preserving quoting for
112
- # paths that may contain spaces (common on Windows).
113
- deft_py() {
114
- if [ -n "$PY_PREFIX" ]; then
115
- "$PYTHON_BIN" "$PY_PREFIX" "$@"
116
- else
117
- "$PYTHON_BIN" "$@"
118
- fi
119
- }
120
-
121
- # Step 1: branch-protection gate (#747).
122
- deft_py "$SCRIPTS_DIR/preflight_branch.py" --project-root "$REPO_ROOT" || exit $?
19
+ deft verify:branch --project-root "$REPO_ROOT" || exit $?
123
20
 
124
- # Step 2: PS 5.1 non-ASCII round-trip corruption gate (#798). Scans staged
125
- # files for U+FFFD, CP1252/CP437-as-UTF-8 mojibake, and unexpected BOM.
126
- # Three-state exit propagates: 0 allowed / 1 corruption blocked with diagnostic
127
- # / 2 config error. Recurrence chain documented in scripts/verify_encoding.py.
128
- deft_py "$SCRIPTS_DIR/verify_encoding.py" --project-root "$REPO_ROOT" --staged || exit $?
21
+ deft verify:encoding --staged --project-root "$REPO_ROOT" || exit $?
129
22
 
130
- # Step 3: vBRIEF 0.6 conformance gate (#1620). Scans staged vbrief/**/*.vbrief.json
131
- # for bare keys that are neither 0.6 spec-core nor x-directive/ / x-vbrief/
132
- # namespaced. Three-state exit propagates: 0 clean / 1 bare key blocked with
133
- # diagnostic / 2 config error. Rule body lives in scripts/verify_vbrief_conformance.py.
134
- # Guarded on a present vbrief/ corpus so a fresh consumer repo that has not yet
135
- # created the vBRIEF lifecycle folders is not blocked by the gate's intentional
136
- # exit-2-on-missing-vbrief/ config-error contract. Also guarded on the gate
137
- # script being present so a vendored consumer whose .deft/core/scripts/ payload
138
- # predates this gate (stale-payload upgrade window) is not blocked by a missing
139
- # script; payload-staleness is surfaced separately by `task doctor`.
140
- if [ -d "$REPO_ROOT/vbrief" ] && [ -f "$SCRIPTS_DIR/verify_vbrief_conformance.py" ]; then
141
- deft_py "$SCRIPTS_DIR/verify_vbrief_conformance.py" --project-root "$REPO_ROOT" --staged
142
- exit $?
23
+ if [ -d "$REPO_ROOT/vbrief" ]; then
24
+ deft verify:vbrief-conformance --staged --project-root "$REPO_ROOT" || exit $?
143
25
  fi
@@ -1,14 +1,9 @@
1
1
  #!/usr/bin/env sh
2
- # .githooks/pre-push -- detection-bound branch-protection gate (#747).
2
+ # .githooks/pre-push -- refspec-aware default-branch push gate (#2049 / #1019 / #1814).
3
3
  #
4
- # Activated by `git config core.hooksPath .githooks` -- idempotent setup
5
- # performed by `task setup` (the directive repo itself) OR by the deft
6
- # installer, which copies this hook to the consumer root .githooks/ and sets
7
- # core.hooksPath for vendored consumer projects (#1463). Mirrors the
8
- # pre-commit shape: pre-push defends against the case where a user opted out
9
- # at commit time (e.g. DEFT_ALLOW_DEFAULT_BRANCH_COMMIT in a single shell)
10
- # but still tries to push to the default branch in a fresh shell. The same
11
- # scripts run in both hooks so behavior stays consistent.
4
+ # Pre-push does NOT invoke verify:branch (#747). HEAD-only default-branch
5
+ # protection remains on pre-commit; pre-push relies on preflight-gh for
6
+ # refspec-aware protection (#1814 Option A). Pure POSIX shell; `deft` only.
12
7
 
13
8
  REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
14
9
  if [ -z "$REPO_ROOT" ]; then
@@ -16,106 +11,11 @@ if [ -z "$REPO_ROOT" ]; then
16
11
  exit 1
17
12
  fi
18
13
 
19
- # Layout-aware helper resolution (#1463) -- see .githooks/pre-commit for the
20
- # rationale. The installer copies this hook to the consumer root .githooks/,
21
- # so the gate scripts must be located relative to the install root (own-repo
22
- # scripts/, canonical .deft/core/scripts/, or legacy deft/scripts/) rather
23
- # than assuming $REPO_ROOT/scripts/.
24
- SCRIPTS_DIR=""
25
- for candidate in "$REPO_ROOT/scripts" "$REPO_ROOT/.deft/core/scripts" "$REPO_ROOT/deft/scripts"; do
26
- if [ -f "$candidate/preflight_branch.py" ]; then
27
- SCRIPTS_DIR="$candidate"
28
- break
29
- fi
30
- done
31
- if [ -z "$SCRIPTS_DIR" ]; then
32
- echo "deft pre-push: unable to locate the deft scripts directory." >&2
33
- echo " Looked in scripts/, .deft/core/scripts/, deft/scripts/ under $REPO_ROOT." >&2
34
- echo " Re-run the deft installer or 'task setup' to wire the hooks correctly." >&2
14
+ if ! command -v deft >/dev/null 2>&1; then
15
+ echo "deft pre-push: 'deft' not found on PATH." >&2
16
+ echo " Install: npm i -g @deftai/directive" >&2
35
17
  exit 1
36
18
  fi
37
19
 
38
- # Resolve a usable Python interpreter (#1668) -- see .githooks/pre-commit for
39
- # the rationale. On Windows `python3` is usually absent (only `python.exe` /
40
- # the `py` launcher exist), and a bare `python3` on PATH is often the Microsoft
41
- # Store App-Execution-Alias stub. Probe DEFT_PYTHON -> python3 -> python -> the
42
- # `py -3` launcher, validating each candidate by running `--version`, rejecting
43
- # the alias stub, AND enforcing the framework's Python 3.11+ floor (#1676).
44
- PYTHON_BIN=""
45
- PY_PREFIX=""
46
-
47
- # _deft_try BIN [PREFIX] -- probe a candidate. Succeeds (and sets PYTHON_BIN /
48
- # PY_PREFIX) only when the candidate runs, is not the Windows alias stub, and
49
- # reports a Python version >= 3.11.
50
- _deft_try() {
51
- _bin="$1"
52
- _pre="${2:-}"
53
- command -v "$_bin" >/dev/null 2>&1 || return 1
54
- if [ -n "$_pre" ]; then
55
- _out=$("$_bin" "$_pre" --version 2>&1) || return 1
56
- else
57
- _out=$("$_bin" --version 2>&1) || return 1
58
- fi
59
- case "$_out" in
60
- *"Microsoft Store"*|*"was not found"*|*"execution alias"*) return 1 ;;
61
- esac
62
- case "$_out" in
63
- *Python\ [0-9]*) ;;
64
- *) return 1 ;;
65
- esac
66
- # Enforce the 3.11+ floor using POSIX parameter expansion (no sed/awk
67
- # dependency). Parse major.minor from the "Python X.Y.Z" banner.
68
- _rest=${_out#*Python }
69
- _major=${_rest%%.*}
70
- _rest=${_rest#*.}
71
- _minor=${_rest%%.*}
72
- case "$_major" in ''|*[!0-9]*) return 1 ;; esac
73
- case "$_minor" in ''|*[!0-9]*) return 1 ;; esac
74
- if [ "$_major" -gt 3 ]; then
75
- PYTHON_BIN="$_bin"; PY_PREFIX="$_pre"; return 0
76
- fi
77
- if [ "$_major" -eq 3 ] && [ "$_minor" -ge 11 ]; then
78
- PYTHON_BIN="$_bin"; PY_PREFIX="$_pre"; return 0
79
- fi
80
- return 1
81
- }
82
-
83
- if [ -n "${DEFT_PYTHON:-}" ]; then
84
- # DEFT_PYTHON is the explicit override, but still version-checked so the
85
- # hooks enforce the same 3.11+ floor as the installer (#1676).
86
- _deft_try "$DEFT_PYTHON" || true
87
- if [ -z "$PYTHON_BIN" ]; then
88
- echo "deft pre-push: DEFT_PYTHON ($DEFT_PYTHON) is not a usable Python 3.11+ interpreter." >&2
89
- echo " Point DEFT_PYTHON at a Python 3.11+ executable." >&2
90
- exit 1
91
- fi
92
- else
93
- _deft_try python3 || _deft_try python || _deft_try py "-3" || true
94
- fi
95
-
96
- if [ -z "$PYTHON_BIN" ]; then
97
- echo "deft pre-push: no usable Python 3.11+ interpreter found." >&2
98
- echo " Probed python3, python, and the 'py' launcher (rejecting the Windows" >&2
99
- echo " App-Execution-Alias stub and interpreters older than 3.11)." >&2
100
- echo " Set DEFT_PYTHON=<absolute python 3.11+ path> or install Python 3.11+." >&2
101
- exit 1
102
- fi
103
-
104
- # deft_py forwards args to the resolved interpreter, preserving quoting for
105
- # paths that may contain spaces (common on Windows).
106
- deft_py() {
107
- if [ -n "$PY_PREFIX" ]; then
108
- "$PYTHON_BIN" "$PY_PREFIX" "$@"
109
- else
110
- "$PYTHON_BIN" "$@"
111
- fi
112
- }
113
-
114
- deft_py "$SCRIPTS_DIR/preflight_branch.py" --project-root "$REPO_ROOT" || exit $?
115
-
116
- # Step 2: destructive-gh-verb gate (#1019). Reads per-ref stdin lines from
117
- # git pre-push (one line per ref: <local_ref> <local_oid> <remote_ref> <remote_oid>)
118
- # and refuses pushes touching the default branch (force-push or otherwise).
119
- # DEFT_ALLOW_DESTRUCTIVE_GH_VERBS=1 is the per-shell emergency bypass.
120
- deft_py "$SCRIPTS_DIR/preflight_gh.py" --pre-push-stdin
20
+ deft preflight-gh --pre-push-stdin
121
21
  exit $?
package/Taskfile.yml CHANGED
@@ -70,9 +70,6 @@ env:
70
70
  UV_PROJECT: '{{.TASKFILE_DIR}}'
71
71
 
72
72
  includes:
73
- core:
74
- taskfile: ./tasks/core.yml
75
- optional: true
76
73
  ts:
77
74
  taskfile: ./tasks/ts.yml
78
75
  optional: true
@@ -141,9 +138,6 @@ includes:
141
138
  pr:
142
139
  taskfile: ./tasks/pr.yml
143
140
  optional: true
144
- ci:
145
- taskfile: ./tasks/ci.yml
146
- optional: true
147
141
  policy:
148
142
  taskfile: ./tasks/policy.yml
149
143
  optional: true
@@ -307,6 +301,24 @@ includes:
307
301
  packs:
308
302
  taskfile: ./tasks/packs.yml
309
303
  optional: true
304
+ # Maintainer-only Python self-test lanes (#1813 contributor path / #2022
305
+ # Phase 2). `internal: true` hides `core:*` / `ci:*` from `task -l` and
306
+ # blocks direct CLI invocation on consumer installs; only
307
+ # `check:framework-source` below wires them as deps. Consumer `task check`
308
+ # dispatches to `check:consumer` (TS / deft verbs — no uv/python).
309
+ core:
310
+ taskfile: ./tasks/core.yml
311
+ optional: true
312
+ internal: true
313
+ ci:
314
+ taskfile: ./tasks/ci.yml
315
+ optional: true
316
+ internal: true
317
+ # npm consumer deposits resolve verbs through global `deft` when the vendored
318
+ # packages/cli/dist/bin.js is absent (#2022 Phase 3).
319
+ engine:
320
+ taskfile: ./tasks/engine.yml
321
+ optional: true
310
322
 
311
323
  tasks:
312
324
  default:
@@ -320,14 +332,16 @@ tasks:
320
332
  desc: "Run the context-appropriate pre-commit gate: full framework self-check in this repo, consumer-safe gate from vendored installs (#1519)."
321
333
  dir: '{{.USER_WORKING_DIR}}'
322
334
  deps:
323
- - task: verify:_ts-build
335
+ - task: engine:_ts-build
324
336
  cmds:
325
- # Oracle/fallback (parity): scripts/_project_context.py --dispatch-task-check (#1854 s5).
326
- - node "{{.TASKFILE_DIR}}/packages/cli/dist/bin.js" check --framework-root "{{.TASKFILE_DIR}}" --project-root "{{.USER_WORKING_DIR}}"
337
+ - task: engine:invoke
338
+ vars:
339
+ ENGINE_CMD: 'check --framework-root "{{.TASKFILE_DIR}}" --project-root "{{.USER_WORKING_DIR}}"'
327
340
 
328
341
  check:framework-source:
329
- desc: "Run all framework source-repo pre-commit checks explicitly (skips @pytest.mark.slow tests via pyproject addopts -- run `task check:slow` for the slow lane, #975)."
342
+ desc: "Run all framework source-repo pre-commit checks explicitly (skips @pytest.mark.slow tests via pyproject addopts -- run `task check:slow` for the slow lane, #975). Sole wired consumer of maintainer-only core:* / ci:* Python lanes (#2022 Phase 2)."
330
343
  deps:
344
+ # Maintainer-only Python lanes (tasks/core.yml) — not on check:consumer.
331
345
  - core:validate
332
346
  - core:lint
333
347
  - core:test
@@ -359,7 +373,7 @@ tasks:
359
373
  desc: "Run the consumer-safe Deft quality gate for vendored installs (#1519)."
360
374
  deps:
361
375
  - doctor
362
- - toolchain:check
376
+ - toolchain:check-consumer
363
377
  - verify:branch
364
378
  - verify:cache-fresh
365
379
  - verify:wip-cap
@@ -395,12 +409,11 @@ tasks:
395
409
  desc: "Deterministic v0.20 strategy output shape gate (#1166 s2). Fails on non-date-prefixed vBRIEFs in lifecycle dirs, missing PROJECT-DEFINITION.vbrief.json, or legacy specification.vbrief.json in user projects."
396
410
  dir: '{{.USER_WORKING_DIR}}'
397
411
  deps:
398
- - task: verify:_ts-build
399
- vars:
400
- DEFT_ROOT: "{{.TASKFILE_DIR}}"
412
+ - task: engine:_ts-build
401
413
  cmds:
402
- # Oracle/fallback (parity): scripts/validate_strategy_output.py (#1854 s3).
403
- - node "{{.TASKFILE_DIR}}/packages/cli/dist/bin.js" validate-strategy-output --project-root "{{.USER_WORKING_DIR}}"
414
+ - task: engine:invoke
415
+ vars:
416
+ ENGINE_CMD: 'validate-strategy-output --project-root "{{.USER_WORKING_DIR}}"'
404
417
 
405
418
  # Pack-projection drift gate (#1294 / #1283, ADR-001). User-facing alias for
406
419
  # `packs:verify-drift`, defined at the root Taskfile so it carries the
@@ -434,40 +447,24 @@ tasks:
434
447
  # addopts=` reset overrides the pyproject default of `-m 'not slow'`
435
448
  # so the `-m slow` selector here actually picks up the marked tests.
436
449
  check:slow:
437
- desc: "Run the @pytest.mark.slow test lane (watchdog regression suite excluded from `task check` by default, #975)"
450
+ desc: "Run the @pytest.mark.slow test lane (watchdog regression suite excluded from `task check` by default, #975). Maintainer-only Python lane — not part of `check:consumer`."
438
451
  cmds:
439
452
  # `--project` pins uv to the framework root so ancestor pyproject.toml
440
453
  # files cannot hijack the resolver via uv's upward walk (#1011).
441
454
  - uv --project "{{.TASKFILE_DIR}}" run pytest tests/ -o addopts= -m slow
442
455
 
443
- test:
444
- desc: Run test suite (alias for core:test)
445
- cmds:
446
- - task: core:test
447
- test:coverage:
448
- desc: Run tests with coverage (alias for core:test:coverage)
449
- cmds:
450
- - task: core:test:coverage
451
- lint:
452
- desc: Lint and type-check Python code (alias for core:lint)
453
- cmds:
454
- - task: core:lint
455
- fmt:
456
- desc: Format Python code (alias for core:fmt)
457
- cmds:
458
- - task: core:fmt
456
+ # Maintainer-only packaging aliases (#2022 Phase 2). `core:*` is internal;
457
+ # these root aliases remain callable for release Step 6 (`task build`) and
458
+ # local maintainer workflows. Not wired into `check:consumer`.
459
459
  build:
460
- desc: Package framework for distribution (alias for core:build)
460
+ desc: Package framework for distribution (maintainer-only; alias for core:build)
461
461
  cmds:
462
462
  - task: core:build
463
463
  clean:
464
- desc: Clean generated artifacts (alias for core:clean)
464
+ desc: Clean generated artifacts (maintainer-only; alias for core:clean)
465
465
  cmds:
466
466
  - task: core:clean
467
- validate:
468
- desc: Validate all markdown files (alias for core:validate)
469
- cmds:
470
- - task: core:validate
467
+
471
468
  install:
472
469
  desc: Install deft (alias for install:install)
473
470
  cmds:
@@ -477,7 +474,7 @@ tasks:
477
474
  cmds:
478
475
  - task: install:uninstall
479
476
  # User-facing upgrade entrypoint (#1061). Aliases the install:upgrade
480
- # wrapper that delegates to `run upgrade`. Cited by the doctor's
477
+ # wrapper that delegates to the native deft-ts install-upgrade handler. Cited by the doctor's
481
478
  # failure prose and docs/install-manifest.md as the canonical
482
479
  # post-drift repair entrypoint for the AGENTS.md / manifest /
483
480
  # .deft-version triple.
@@ -485,10 +482,6 @@ tasks:
485
482
  desc: "Upgrade deft framework -- refresh AGENTS.md + write install manifest + regenerate .deft-version (alias for install:upgrade, #1061)"
486
483
  cmds:
487
484
  - task: install:upgrade
488
- stats:
489
- desc: Show framework statistics (alias for core:stats)
490
- cmds:
491
- - task: core:stats
492
485
 
493
486
  # #1272: canonical doctor surface -- thin shim that forwards to
494
487
  # ``.deft/core/run doctor``. The ``run`` CLI owns the diagnostic
@@ -502,16 +495,18 @@ tasks:
502
495
  # in ``tasks/framework.yml`` now prints a redaction notice pointing
503
496
  # the operator at this surface.
504
497
  doctor:
505
- desc: "Canonical doctor surface (#1272) -- task doctor [-- --session | --fix | --json | --quiet]. Shim for `.deft/core/run doctor`."
498
+ desc: "Canonical doctor surface (#1272) -- task doctor [-- --session | --fix | --json | --quiet]. Uses vendored bin.js in source checkouts or global deft on npm consumer deposits (#2022 Phase 3)."
506
499
  dir: '{{.USER_WORKING_DIR}}'
507
- env:
508
- PYTHONUTF8: "1"
509
500
  cmds:
510
- - uv --project "{{.TASKFILE_DIR}}" run --frozen python "{{.TASKFILE_DIR}}/run" doctor {{.CLI_ARGS}}
501
+ - task: engine:invoke
502
+ vars:
503
+ ENGINE_CMD: 'doctor --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
511
504
 
512
505
  setup:
513
506
  desc: "Idempotent local-dev setup: configure git hooks (#747); detect-and-prompt ghx (#884). Sets core.hooksPath=.githooks so .githooks/pre-commit + .githooks/pre-push run."
514
507
  dir: '{{.USER_WORKING_DIR}}'
508
+ deps:
509
+ - verify:_ts-build
515
510
  env:
516
511
  PYTHONUTF8: "1"
517
512
  cmds:
@@ -568,24 +563,19 @@ tasks:
568
563
  # GitHub CLI cache proxy. Default invocation here passes --check so
569
564
  # `task setup` never prompts on a clean re-run; operators wanting to
570
565
  # opt in run `task setup:ghx` (defined below) which is the
571
- # interactive entry point. The script is pure-stdlib so it works
572
- # before `uv sync` has run on a fresh worktree; `uv run` is still
573
- # the canonical dispatcher to keep the python interpreter consistent
574
- # with every other Taskfile-dispatched script. `--project` pins uv
575
- # to the framework root so ancestor pyproject.toml files cannot
576
- # hijack the resolver via uv's upward walk (#1011).
577
- - uv --project "{{.TASKFILE_DIR}}" run python "{{.TASKFILE_DIR}}/scripts/setup_ghx.py" --check
566
+ # interactive entry point. Native TypeScript handler (#2022 Phase 1).
567
+ - node "{{.TASKFILE_DIR}}/packages/cli/dist/bin.js" setup:ghx --check
578
568
 
579
569
  setup:ghx:
580
570
  desc: "Consent-gated ghx (brunoborges/ghx) installer (#884) -- task setup:ghx [-- --yes]"
581
571
  dir: '{{.USER_WORKING_DIR}}'
582
- env:
583
- PYTHONUTF8: "1"
572
+ deps:
573
+ - verify:_ts-build
584
574
  # Per `conventions/task-caching.md` (#574): no `sources:` / `generates:`
585
575
  # because the script forwards user-facing flags via {{.CLI_ARGS}}
586
576
  # (notably --yes for non-interactive CI / scripted approval).
587
577
  cmds:
588
- - uv --project "{{.TASKFILE_DIR}}" run python "{{.TASKFILE_DIR}}/scripts/setup_ghx.py" {{.CLI_ARGS}}
578
+ - node "{{.TASKFILE_DIR}}/packages/cli/dist/bin.js" setup:ghx {{.CLI_ARGS}}
589
579
 
590
580
  # Release pipeline tasks (#74 + #716 safety hardening, namespace flatten #718).
591
581
  #
package/UPGRADING.md CHANGED
@@ -16,7 +16,7 @@ From v0.55.1 onwards `@deftai/directive` is published on npm. The canonical upgr
16
16
  npm i -g @deftai/directive@latest
17
17
  ```
18
18
 
19
- Run from any shell with Node ≥ 20. After upgrading, start a new agent session so the refreshed AGENTS.md and skills load from a clean context. Run `directive doctor` to confirm the install state.
19
+ Run from any shell with Node ≥ 20. After upgrading, run `deft update` from your project root to refresh the vendored `.deft/core/` payload and project-root `.githooks/` (#2049), then start a new agent session so the refreshed AGENTS.md and skills load from a clean context. Run `deft doctor` to confirm the install state.
20
20
 
21
21
  ### One-time migration from the Go installer (legacy → npm)
22
22
 
@@ -94,6 +94,7 @@ runs the doctor first gets pointed at this exact two-step before touching `init`
94
94
  - **From v0.25.x — manual (breaking).** The deft-cache on-disk layout changed: [From v0.25.x → v0.26.0](#from-v025x--v0260-deft-cache-unified-layer-breaking).
95
95
  - **From v0.26.x — auto-handled (interactive).** Run the triage adoption ritual: [From v0.26.x → v0.27](#from-v026x---v027-triage-adoption-via-task-triagewelcome).
96
96
  - **From v0.27.x — mostly auto-handled.** Pick up the install manifest and the `deft/` → `.deft/core/` layout: [From v0.27.x → v0.28](#from-v027x---v028-canonical-install-manifest-at-installversion), [From deft/ → .deft/core/](#from-deft---deftcore), and [From drifted AGENTS.md → current install](#from-drifted-agentsmd---current-install-task-upgrade-repair-path-1061).
97
+ - **From v0.60.x — manual (hook refresh).** After #2049, consumer `.githooks/` dispatch through the `deft` CLI only. Run [From v0.60.0 → v0.61.x (refresh project-root git hooks, #2049)](#from-v0600--v061x-refresh-project-root-git-hooks-2049) after every framework upgrade that touches hook templates.
97
98
  - **From v0.28–v0.36 (and the final hop to current) — auto-handled.** If still on the Go-installer layout, follow the [One-time migration from the Go installer](#one-time-migration-from-the-go-installer-legacy--npm) above, then `npm i -g @deftai/directive@latest` for all future upgrades.
98
99
 
99
100
  **Final step for every bucket.** Finish on the canonical upgrade command, then let the doctor confirm you are current:
@@ -102,7 +103,22 @@ runs the doctor first gets pointed at this exact two-step before touching `init`
102
103
  npm i -g @deftai/directive@latest
103
104
  ```
104
105
 
105
- Then run `directive doctor`: it checks install integrity and tells you whether any further hop is still due. If still on a Go-installer layout, follow the [One-time migration from the Go installer](#one-time-migration-from-the-go-installer-legacy--npm) first.
106
+ Then run `deft update` in your project root (refreshes `.deft/core/` and `.githooks/`), then `directive doctor`: it checks install integrity and tells you whether any further hop is still due. If still on a Go-installer layout, follow the [One-time migration from the Go installer](#one-time-migration-from-the-go-installer-legacy--npm) first.
107
+
108
+ ---
109
+
110
+ ## From v0.60.0 → v0.61.x (refresh project-root git hooks, #2049)
111
+
112
+ - **Applies when:** your project was on deft v0.60.x (or earlier) with `.githooks/` installed via `deft setup` / the npm deposit path, and hooks still invoke legacy Python scripts (`scripts/preflight_branch.py`, `scripts/preflight_gh.py`, etc.). Detection: `deft verify:hooks-installed` fails with "still dispatches through Python scripts (expected deft CLI only, #2049)" or pre-commit/pre-push errors mentioning missing `scripts/*.py` on Python-free installs.
113
+ - **Safe to auto-run:** Yes. `deft update` from the project root re-deposits the current `.githooks/` templates and refreshes the vendored `.deft/core/` payload. No manual hook editing required when the update completes cleanly.
114
+ - **Restart required:** No for hook wiring — but start a **new agent session** after update so AGENTS.md and skills reflect the refreshed managed section.
115
+ - **Commands:**
116
+ - `npm i -g @deftai/directive@latest` (upgrade the global CLI/engine)
117
+ - `deft update` (from project root — refreshes `.deft/core/` + `.githooks/`)
118
+ - `deft verify:hooks-installed` (confirm pre-commit/pre-push dispatch via `deft verify:branch`, `deft verify:encoding`, `deft preflight-gh`)
119
+ - `deft doctor` (install integrity + managed-section freshness)
120
+
121
+ If `deft update` is unavailable (older deposit), fall back to `deft setup` to re-install the hooks path and copy current hook templates.
106
122
 
107
123
  ---
108
124
 
@@ -318,7 +334,7 @@ The relocator does NOT auto-rewrite consumer-owned files (the canonical reason:
318
334
  - `AGENTS.md` head/tail (above and below the managed-section markers) -- replace `deft/run` with `.deft/core/run` and `Full guidelines: deft/main.md` with `Full guidelines: .deft/core/main.md`.
319
335
  - CI workflow files (`.github/workflows/*.yml`) -- replace any `deft/run <task>` invocations.
320
336
  - Project scripts (`scripts/`, `Makefile`, `Taskfile.yml`, dotfiles) that hardcode the legacy path.
321
- - README / docs / contributor-onboarding prose that points new contributors at `deft/run` for bootstrap.
337
+ - README / docs / contributor-onboarding prose that points new contributors at `directive bootstrap` for first-time setup (replaces legacy `deft/run bootstrap` / `run project` / `run spec` shims).
322
338
 
323
339
  The advisory grep output is the operator's worklist; treat it as a finite todo. Once every flagged occurrence is either updated to `.deft/core/run` or explicitly acknowledged as legacy-friendly redirect-stub content (e.g. the `skills/deft-{sync,setup,...}/SKILL.md` redirect stubs that intentionally retain `deft/run` per [#411](https://github.com/deftai/directive/issues/411)), commit the changes alongside the relocate. (F1 #1015)
324
340
 
@@ -0,0 +1,73 @@
1
+ # The Directive Lifecycle (Conceptual Overview)
2
+
3
+ A single-picture mental model of how Deft Directive turns an idea into shipped,
4
+ auditable work — and keeps doing so as the project grows. It is **not** a one-and-done
5
+ pipeline; it is two connected phases that loop.
6
+
7
+ > **See also**: [getting-started.md](./getting-started.md) | [commands.md](../commands.md) | [strategies/README.md](../strategies/README.md) | [CONCEPTS.md](../../docs/CONCEPTS.md) | [ARCHITECTURE.md](../../docs/ARCHITECTURE.md)
8
+ >
9
+ > The `CONCEPTS.md` / `ARCHITECTURE.md` links resolve in the framework source repo; in an installed `.deft/core/docs/` they are maintainer-side references that may not be present.
10
+
11
+ ![Deft Directive lifecycle: an inception phase (Concept → Strategy Analysis → Specification + Artifacts) feeding a recurring per-session phase (Session Start → Triage/Refine → Slice → Swarm → Review/Fix → Ship) that loops back through new issues and features](./assets/directive-lifecycle-diagram.png)
12
+
13
+ > This diagram is a **conceptual overview**, not a command reference. The bubble labels are
14
+ > plain-language stages; the [stage → real surface](#stage--real-surface) table below maps
15
+ > each one to the actual strategy, skill, or `task` command that implements it.
16
+
17
+ ## The two phases
18
+
19
+ ### 1. At inception (run once, re-run as needed)
20
+
21
+ A project starts with a **Concept**. That concept passes through **Strategy Analysis** — an
22
+ iterative loop of *looking* at the terrain and *deep thinking* about the approach — until it
23
+ produces a **Specification + Artifacts** (the project definition and the first proposed scope
24
+ vBRIEFs).
25
+
26
+ Strategy analysis is deliberately a loop, not a step: you can map, then probe, then discuss,
27
+ then map again before the spec stabilizes. It is also re-entered later "as needed" when a piece
28
+ of work turns out to be big or fuzzy enough to need rethinking rather than just refining.
29
+
30
+ ### 2. Resume (the usual entry, every session)
31
+
32
+ Once a specification exists, the everyday on-ramp is **Session Start** — the session-start
33
+ ritual answering "what's next?". From there work flows through the queue:
34
+
35
+ - **Triage + Refine/Rethink** — the queue of candidate work. New **issues** and **features**
36
+ both enter here. Each item is either sliced forward, or — when it needs more thought —
37
+ escalated back up to Strategy Analysis (the *rethink* path).
38
+ - **Slice** — break refined scope into independently-grabbable vertical slices.
39
+ - **Swarm** — dispatch parallel agents against the sliced stories.
40
+ - **Review/Fix** — a tight, skill-driven loop that resolves reviewer findings until the work is
41
+ merge-ready. Review comes **after** the swarm, not before.
42
+ - **Ship** — merge and release.
43
+
44
+ Shipping is not the end: it **surfaces new issues and features**, which flow back into the
45
+ Triage queue. The specification and artifacts produced at inception also feed proposed scopes
46
+ into the same queue. Every pass is iterative.
47
+
48
+ ## Stage → real surface
49
+
50
+ The diagram's labels are conceptual. Here is what each one actually corresponds to in the
51
+ framework:
52
+
53
+ | Diagram label | What it really is |
54
+ |---|---|
55
+ | **Concept** | The initial idea / project framing — entry into [`deft-directive-setup`](../skills/deft-directive-setup/SKILL.md) or a `/deft:change`. |
56
+ | **Look** | Mapping and exploring the terrain — [`strategies/map.md`](../strategies/map.md) (`/deft:run:map`), codebase structure. |
57
+ | **Deep Think** | Adversarial / alignment analysis — [`strategies/probe.md`](../strategies/probe.md), [`strategies/discuss.md`](../strategies/discuss.md), [`strategies/research.md`](../strategies/research.md), and `deft-directive-gh-arch`. |
58
+ | **Strategy Analysis** | The preparatory strategies cycling through the [strategy chaining gate](../strategies/README.md) before spec generation. |
59
+ | **Spec / Specification + Artifacts** | Output of the spec-generating strategies (interview, speckit, …): `vbrief/PROJECT-DEFINITION.vbrief.json` plus dated `vbrief/proposed/` scope vBRIEFs. |
60
+ | **Resume / Session Start** | The session-start ritual — `task session:start` and the `task triage:welcome` "what's next" one-liner. |
61
+ | **Triage + Refine/Rethink** | The triage cache and refinement loop — `task triage:*`, [`deft-directive-triage`](../skills/deft-directive-triage/SKILL.md), [`deft-directive-refinement`](../skills/deft-directive-refinement/SKILL.md). "Rethink" = escalate back to Strategy Analysis. |
62
+ | **Slice** | Vertical-slice decomposition — [`deft-directive-gh-slice`](../skills/deft-directive-gh-slice/SKILL.md) and [`deft-directive-decompose`](../skills/deft-directive-decompose/SKILL.md). |
63
+ | **Swarm** | Parallel local agent orchestration — [`deft-directive-swarm`](../skills/deft-directive-swarm/SKILL.md), `task swarm:*`. |
64
+ | **Review/Fix** | Bot-reviewer response loop — [`deft-directive-review-cycle`](../skills/deft-directive-review-cycle/SKILL.md) and [`deft-directive-pre-pr`](../skills/deft-directive-pre-pr/SKILL.md). |
65
+ | **Ship** | PR merge and release — `task pr:*` and [`deft-directive-release`](../skills/deft-directive-release/SKILL.md). |
66
+ | **Issues / Features** | GitHub issues and feature requests mirrored into `.deft-cache/` and surfaced as triage candidates. |
67
+
68
+ ## Why it loops
69
+
70
+ The central claim of the picture is that Directive is **reiterative**. Strategy analysis is
71
+ front-loaded but re-entrant. Triage either slices work forward or rethinks it. Review/fix
72
+ cycles until merge-ready. And shipping generates the next round of issues and features. The
73
+ framework is built to be re-entered every session, not walked once.
@@ -2,7 +2,11 @@
2
2
 
3
3
  Deft Directive is a Taskfile-first framework for AI-assisted software work. It combines agent guidance, deterministic gates, vBRIEF lifecycle metadata, installer/doctor handoff, and cache-backed backlog workflows. This guide walks through installation, preferences, project setup, and the first scope workflow.
4
4
 
5
- > **Note**: This guide is an orientation layer. For current architecture details, see [ARCHITECTURE.md](../../docs/ARCHITECTURE.md); for command behavior, see [commands.md](../commands.md).
5
+ > **Note**: This guide is an orientation layer. For a single-picture mental model of how Directive turns an idea into shipped work, see [the Directive lifecycle](./directive-lifecycle.md); for command behavior, see [commands.md](../commands.md); for current architecture details, see [ARCHITECTURE.md](../../docs/ARCHITECTURE.md).
6
+
7
+ ## The shape of the workflow
8
+
9
+ Before the mechanics below, it helps to see the whole loop. Directive is two connected phases that repeat: an **inception** phase (Concept → Strategy Analysis → Specification + Artifacts) that feeds a recurring **per-session** phase (Session Start → Triage/Refine → Slice → Swarm → Review/Fix → Ship), where shipping surfaces new issues and features that flow back into the queue. The full picture, with a stage-to-real-command mapping table, lives in [the Directive lifecycle overview](./directive-lifecycle.md).
6
10
 
7
11
  ## Deft & Directive (naming)
8
12