@deftai/directive-content 0.55.1 → 0.56.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 (220) hide show
  1. package/.githooks/pre-commit +143 -0
  2. package/.githooks/pre-push +121 -0
  3. package/QUICK-START.md +13 -3
  4. package/Taskfile.yml +934 -0
  5. package/UPGRADING.md +82 -11
  6. package/events/README.md +3 -3
  7. package/package.json +5 -4
  8. package/packs/skills/skills-pack-0.1.json +22 -22
  9. package/scripts/_agents_md.py +494 -0
  10. package/scripts/_cache_fetch.py +635 -0
  11. package/scripts/_cache_quota.py +529 -0
  12. package/scripts/_cache_refresh.py +163 -0
  13. package/scripts/_cache_validate.py +209 -0
  14. package/scripts/_content_root.py +42 -0
  15. package/scripts/_doctor_state.py +277 -0
  16. package/scripts/_event_detect.py +305 -0
  17. package/scripts/_events.py +514 -0
  18. package/scripts/_lifecycle_hygiene.py +568 -0
  19. package/scripts/_pathspec.py +91 -0
  20. package/scripts/_policy_show_cli.py +266 -0
  21. package/scripts/_precutover.py +92 -0
  22. package/scripts/_project_context.py +224 -0
  23. package/scripts/_project_definition_io.py +164 -0
  24. package/scripts/_relocate_snapshot.py +209 -0
  25. package/scripts/_relocate_states.py +343 -0
  26. package/scripts/_resolve_preflight_path.py +152 -0
  27. package/scripts/_safe_subprocess.py +167 -0
  28. package/scripts/_session_start_hook.py +205 -0
  29. package/scripts/_sor_gate_diff.py +365 -0
  30. package/scripts/_stdio_utf8.py +59 -0
  31. package/scripts/_triage_bootstrap_gitignore.py +904 -0
  32. package/scripts/_triage_classify_cli.py +122 -0
  33. package/scripts/_triage_queue_cli.py +625 -0
  34. package/scripts/_triage_scope_cli.py +343 -0
  35. package/scripts/_triage_scope_drift_cli.py +121 -0
  36. package/scripts/_triage_scope_ignores.py +286 -0
  37. package/scripts/_triage_scope_milestone.py +432 -0
  38. package/scripts/_triage_scope_mutations.py +337 -0
  39. package/scripts/_triage_scope_renderers.py +207 -0
  40. package/scripts/_triage_smoketest_stages.py +674 -0
  41. package/scripts/_triage_subscribe_cli.py +140 -0
  42. package/scripts/_triage_welcome_cli.py +421 -0
  43. package/scripts/_vbrief_build.py +239 -0
  44. package/scripts/_vbrief_fidelity.py +479 -0
  45. package/scripts/_vbrief_legacy.py +589 -0
  46. package/scripts/_vbrief_reconciliation.py +883 -0
  47. package/scripts/_vbrief_routing.py +277 -0
  48. package/scripts/_vbrief_safety.py +778 -0
  49. package/scripts/_vbrief_sources.py +312 -0
  50. package/scripts/_vbrief_speckit.py +262 -0
  51. package/scripts/_vbrief_story_quality.py +353 -0
  52. package/scripts/_vbrief_validation.py +299 -0
  53. package/scripts/build_dist.py +412 -0
  54. package/scripts/cache.py +1078 -0
  55. package/scripts/cache_scanner.py +745 -0
  56. package/scripts/candidates_log.py +432 -0
  57. package/scripts/capacity_backfill.py +680 -0
  58. package/scripts/capacity_show.py +653 -0
  59. package/scripts/ci_local.py +689 -0
  60. package/scripts/code_structure_validate.py +765 -0
  61. package/scripts/codebase_default_extractor.py +495 -0
  62. package/scripts/codebase_map.py +304 -0
  63. package/scripts/codebase_map_fresh.py +104 -0
  64. package/scripts/codebase_projection_registry.py +94 -0
  65. package/scripts/codebase_provider.py +582 -0
  66. package/scripts/doctor.py +2257 -0
  67. package/scripts/framework_commands.py +505 -0
  68. package/scripts/gh_rest.py +882 -0
  69. package/scripts/github_auth_modes.py +437 -0
  70. package/scripts/github_body.py +292 -0
  71. package/scripts/ip_risk.py +531 -0
  72. package/scripts/issue_emit.py +670 -0
  73. package/scripts/issue_ingest.py +1064 -0
  74. package/scripts/migrate_preflight.py +418 -0
  75. package/scripts/migrate_vbrief.py +2677 -0
  76. package/scripts/monitor_pr.py +401 -0
  77. package/scripts/pack_migrate_lessons.py +336 -0
  78. package/scripts/pack_migrate_patterns.py +254 -0
  79. package/scripts/pack_migrate_rules.py +350 -0
  80. package/scripts/pack_migrate_skills.py +423 -0
  81. package/scripts/pack_migrate_strategies.py +311 -0
  82. package/scripts/pack_migrate_swarm_spec.py +250 -0
  83. package/scripts/pack_render.py +434 -0
  84. package/scripts/packs_slice.py +712 -0
  85. package/scripts/platform_capabilities.py +336 -0
  86. package/scripts/policy.py +2826 -0
  87. package/scripts/policy_set.py +324 -0
  88. package/scripts/pr_check_closing_keywords.py +524 -0
  89. package/scripts/pr_check_protected_issues.py +267 -0
  90. package/scripts/pr_merge_readiness.py +1004 -0
  91. package/scripts/pr_wait_mergeable.py +669 -0
  92. package/scripts/prd_render.py +159 -0
  93. package/scripts/preflight_architecture_sor.py +974 -0
  94. package/scripts/preflight_branch.py +289 -0
  95. package/scripts/preflight_cache.py +974 -0
  96. package/scripts/preflight_gh.py +721 -0
  97. package/scripts/preflight_implementation.py +272 -0
  98. package/scripts/preflight_story_start.py +838 -0
  99. package/scripts/preflight_wip_cap.py +149 -0
  100. package/scripts/probe_session.py +545 -0
  101. package/scripts/project_render.py +293 -0
  102. package/scripts/quarantine_ext.py +237 -0
  103. package/scripts/reconcile_issues.py +1442 -0
  104. package/scripts/refresh-path.ps1 +107 -0
  105. package/scripts/release.py +2030 -0
  106. package/scripts/release_e2e.py +1011 -0
  107. package/scripts/release_publish.py +486 -0
  108. package/scripts/release_rollback.py +980 -0
  109. package/scripts/relocate.py +1034 -0
  110. package/scripts/resolve_changelog_unreleased.py +667 -0
  111. package/scripts/resolve_version.py +490 -0
  112. package/scripts/resume_conditions.py +706 -0
  113. package/scripts/ritual_sentinel.py +609 -0
  114. package/scripts/roadmap_render.py +635 -0
  115. package/scripts/rule_ownership_lint.py +325 -0
  116. package/scripts/scm.py +591 -0
  117. package/scripts/scope_audit_log.py +387 -0
  118. package/scripts/scope_decompose.py +654 -0
  119. package/scripts/scope_demote.py +509 -0
  120. package/scripts/scope_lifecycle.py +1126 -0
  121. package/scripts/scope_undo.py +772 -0
  122. package/scripts/session_start.py +406 -0
  123. package/scripts/setup_ghx.py +339 -0
  124. package/scripts/setup_windows.ps1 +220 -0
  125. package/scripts/slice_audit.py +585 -0
  126. package/scripts/slice_record.py +530 -0
  127. package/scripts/slice_record_existing.py +692 -0
  128. package/scripts/slug_normalize.py +178 -0
  129. package/scripts/spec_render.py +477 -0
  130. package/scripts/spec_validate.py +238 -0
  131. package/scripts/subagent_monitor.py +658 -0
  132. package/scripts/swarm_complete_cohort.py +644 -0
  133. package/scripts/swarm_launch.py +1206 -0
  134. package/scripts/swarm_readiness.py +554 -0
  135. package/scripts/swarm_verify_review_clean.py +438 -0
  136. package/scripts/swarm_worktrees.py +497 -0
  137. package/scripts/toolchain-check.py +52 -0
  138. package/scripts/triage_actions.py +871 -0
  139. package/scripts/triage_bootstrap.py +1153 -0
  140. package/scripts/triage_bulk.py +630 -0
  141. package/scripts/triage_classify.py +932 -0
  142. package/scripts/triage_help.py +1685 -0
  143. package/scripts/triage_queue.py +1944 -0
  144. package/scripts/triage_reconcile.py +581 -0
  145. package/scripts/triage_refresh.py +643 -0
  146. package/scripts/triage_scope.py +999 -0
  147. package/scripts/triage_scope_drift.py +575 -0
  148. package/scripts/triage_smoketest.py +396 -0
  149. package/scripts/triage_subscribe.py +399 -0
  150. package/scripts/triage_summary.py +1011 -0
  151. package/scripts/triage_welcome.py +1178 -0
  152. package/scripts/ts_check_lane.py +86 -0
  153. package/scripts/validate-links.py +64 -0
  154. package/scripts/validate_strategy_output.py +212 -0
  155. package/scripts/vbrief_activate.py +228 -0
  156. package/scripts/vbrief_migrate_conformance.py +368 -0
  157. package/scripts/vbrief_reconcile_graph.py +306 -0
  158. package/scripts/vbrief_reconcile_labels.py +460 -0
  159. package/scripts/vbrief_reconcile_umbrellas.py +741 -0
  160. package/scripts/vbrief_validate.py +1195 -0
  161. package/scripts/verify-stubs.py +61 -0
  162. package/scripts/verify_capacity.py +160 -0
  163. package/scripts/verify_encoding.py +699 -0
  164. package/scripts/verify_hooks_installed.py +206 -0
  165. package/scripts/verify_investigation.py +360 -0
  166. package/scripts/verify_judgment_gates.py +827 -0
  167. package/scripts/verify_no_task_runtime.py +171 -0
  168. package/scripts/verify_scm_boundary.py +509 -0
  169. package/scripts/verify_session_ritual.py +389 -0
  170. package/scripts/verify_tools.py +426 -0
  171. package/scripts/verify_vbrief_conformance.py +478 -0
  172. package/skills/deft-directive-swarm/SKILL.md +7 -26
  173. package/skills/deft-directive-sync/SKILL.md +1 -1
  174. package/tasks/architecture.yml +13 -0
  175. package/tasks/cache.yml +69 -0
  176. package/tasks/capacity.yml +38 -0
  177. package/tasks/change.yml +46 -0
  178. package/tasks/changelog.yml +24 -0
  179. package/tasks/ci.yml +49 -0
  180. package/tasks/codebase.yml +47 -0
  181. package/tasks/commit.yml +30 -0
  182. package/tasks/core.yml +126 -0
  183. package/tasks/deployments.yml +54 -0
  184. package/tasks/framework.yml +74 -0
  185. package/tasks/install.yml +60 -0
  186. package/tasks/issue.yml +50 -0
  187. package/tasks/migrate.yml +73 -0
  188. package/tasks/packs.yml +92 -0
  189. package/tasks/policy.yml +75 -0
  190. package/tasks/pr.yml +89 -0
  191. package/tasks/prd.yml +39 -0
  192. package/tasks/project.yml +27 -0
  193. package/tasks/reconcile.yml +32 -0
  194. package/tasks/relocate.yml +56 -0
  195. package/tasks/roadmap.yml +28 -0
  196. package/tasks/scm.yml +126 -0
  197. package/tasks/scope-undo.yml +36 -0
  198. package/tasks/scope.yml +141 -0
  199. package/tasks/session.yml +19 -0
  200. package/tasks/setup.yml +37 -0
  201. package/tasks/slice.yml +69 -0
  202. package/tasks/spec.yml +41 -0
  203. package/tasks/swarm.yml +85 -0
  204. package/tasks/toolchain.yml +13 -0
  205. package/tasks/triage-actions.yml +94 -0
  206. package/tasks/triage-bootstrap.yml +43 -0
  207. package/tasks/triage-bulk.yml +75 -0
  208. package/tasks/triage-classify.yml +30 -0
  209. package/tasks/triage-queue.yml +50 -0
  210. package/tasks/triage-reconcile.yml +29 -0
  211. package/tasks/triage-scope-drift.yml +29 -0
  212. package/tasks/triage-scope.yml +31 -0
  213. package/tasks/triage-smoketest.yml +33 -0
  214. package/tasks/triage-subscribe.yml +36 -0
  215. package/tasks/triage-summary.yml +29 -0
  216. package/tasks/triage-welcome.yml +32 -0
  217. package/tasks/ts.yml +328 -0
  218. package/tasks/vbrief.yml +206 -0
  219. package/tasks/verify.yml +292 -0
  220. package/templates/agents-entry.md +2 -2
@@ -0,0 +1,206 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ tasks:
7
+ _ts-build:
8
+ internal: true
9
+ desc: "Build @deftai/cli dist/ before TS-backed gates run (#1828 s2)."
10
+ dir: '{{.DEFT_ROOT}}'
11
+ cmds:
12
+ - pnpm run build
13
+
14
+ validate:
15
+ desc: Validate vBRIEF lifecycle folder structure and cross-file consistency
16
+ dir: '{{.USER_WORKING_DIR}}'
17
+ deps:
18
+ - _ts-build
19
+ cmds:
20
+ # Oracle/fallback (parity): scripts/vbrief_validate.py (#1828 Wave 8).
21
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" vbrief:validate --vbrief-dir "{{.USER_WORKING_DIR}}/vbrief"
22
+
23
+ preflight:
24
+ # Implementation-intent preflight wrapper (#810 / PR #812 fixup;
25
+ # #1046 PR-C / #1047 fail-closed resolver). Skill files
26
+ # (skills/deft-directive-build/SKILL.md Step 0,
27
+ # skills/deft-directive-swarm/SKILL.md Phase 0 Step 1) and the
28
+ # AGENTS.md template (templates/agents-entry.md Implementation Intent
29
+ # Gate block) reference THIS task rather than the underlying Python
30
+ # script directly so the skills are path-prefix-agnostic across the
31
+ # three supported install layouts:
32
+ #
33
+ # 1. ``.deft/core/scripts/...`` (v0.27+ canonical install per #992)
34
+ # 2. ``deft/scripts/...`` (legacy v0.20-v0.26 install)
35
+ # 3. ``scripts/...`` (in-repo case: deft framework itself)
36
+ #
37
+ # The wrapped ``preflight_implementation.py`` script is located
38
+ # via ``scripts/_resolve_preflight_path.py`` (#1046 PR-C / #1047),
39
+ # which probes the three candidate locations under
40
+ # ``{{.USER_WORKING_DIR}}`` in priority order and exits 2 with a
41
+ # structured ``gate misconfigured`` error pointing at
42
+ # ``task framework:doctor`` (#1046 PR-B / #1057) when no candidate
43
+ # resolves. The two-step invocation (resolve, then run) makes the
44
+ # fail-closed semantic explicit: if the resolver returns non-zero
45
+ # the inline ``sh:`` block exits with the same code BEFORE the
46
+ # downstream ``uv run python <script>`` ever fires, so the gate
47
+ # never silently fails open on a misconfigured install (the safety
48
+ # regression #1047 described).
49
+ #
50
+ # The resolver script ITSELF is dispatched via ``{{.DEFT_ROOT}}``
51
+ # (the Taskfile-relative install root) so it lives wherever the
52
+ # framework lives -- the resolver then probes the consumer's
53
+ # project root via ``{{.USER_WORKING_DIR}}``.
54
+ #
55
+ # The task bakes ``--vbrief-path`` so callers pass only the vBRIEF
56
+ # path: ``task vbrief:preflight -- <path>``.
57
+ #
58
+ # CLI_ARGS forwarding (#577): bare ``{{.CLI_ARGS}}`` -- DO NOT wrap
59
+ # in Taskfile-level double quotes. go-task already shell-escapes
60
+ # CLI_ARGS with single quotes, so wrapping in double quotes yields
61
+ # ``"'path'"`` at dispatch time on Windows (pwsh/cmd preserve nested
62
+ # quotes verbatim) and Python's argv receives a literal
63
+ # single-quote-prefixed filename that fails to open. This matches
64
+ # the convention enforced by tests/content/test_taskfile_cli_args.py
65
+ # and used in tasks/scope.yml / migrate.yml / prd.yml / etc.
66
+ # (Greptile P2 suggestion to quote was a false-positive against this
67
+ # project's established convention.)
68
+ #
69
+ # NOTE: NO ``sources:`` / ``generates:`` per ``conventions/task-caching.md``
70
+ # because the vBRIEF path is a user-facing argument forwarded via
71
+ # {{.CLI_ARGS}} and a cached cmds skip would silently swallow it.
72
+ desc: "Preflight an implementation-intent gate (#810): exits 0 only when vBRIEF is in vbrief/active/ AND plan.status == 'running'. Fails closed (#1046 PR-C / #1047) if the wrapped script cannot be resolved."
73
+ dir: '{{.USER_WORKING_DIR}}'
74
+ deps:
75
+ - _ts-build
76
+ cmds:
77
+ # Oracle/fallback (parity): scripts/preflight_implementation.py (#1828 Wave 8).
78
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" vbrief:preflight --vbrief-path {{.CLI_ARGS}}
79
+
80
+ reconcile:graph:
81
+ # Cascade-unblock walker (#1287). Walks vbrief/proposed/, resolves each
82
+ # candidate's plan.metadata.swarm.depends_on[] against current lifecycle
83
+ # state, and promotes (proposed/ -> pending/ via scope_lifecycle) every
84
+ # candidate whose dependencies ALL resolve to a brief in completed/ or
85
+ # cancelled/. Pure-vBRIEF / forge-agnostic: reuses the swarm_readiness.py
86
+ # dep-graph + cycle machinery and the scope_lifecycle promote surface.
87
+ # WIP-cap aware, cycle-safe (exit 1 on a detected cycle), and idempotent
88
+ # (a second run is a no-op). Pass-through flags: --force (override the WIP
89
+ # cap, audited), --dry-run (report without moving), --json (machine
90
+ # summary).
91
+ #
92
+ # CLI_ARGS forwarding (#577): bare ``{{.CLI_ARGS}}`` -- DO NOT wrap in
93
+ # Taskfile-level double quotes. go-task already shell-escapes CLI_ARGS
94
+ # with single quotes; double-wrapping breaks Windows argv. See the
95
+ # preflight task below for the full rationale.
96
+ #
97
+ # NOTE: NO ``sources:`` / ``generates:`` per ``conventions/task-caching.md``
98
+ # because the walk reads/writes lifecycle folders that go-task does not
99
+ # track, so a cached skip would silently swallow real promotions.
100
+ desc: "Reconcile dep graph: promote proposed/ vBRIEFs whose swarm.depends_on[] all resolve to completed/ or cancelled/ (#1287). Flags: --force --dry-run --json."
101
+ dir: '{{.USER_WORKING_DIR}}'
102
+ deps:
103
+ - _ts-build
104
+ cmds:
105
+ # Oracle/fallback (parity): scripts/vbrief_reconcile_graph.py (#1828 Wave 8).
106
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" vbrief-reconcile graph --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
107
+
108
+ reconcile:labels:
109
+ # SCM label reconciliation (#1288). Walks vbrief/proposed/ + pending/ +
110
+ # active/, resolves each brief's linked GitHub issue from its
111
+ # x-vbrief/github-issue reference, and applies/removes a fixed set of
112
+ # managed labels so the forge surface mirrors canonical vBRIEF state:
113
+ # status=blocked or an unresolved swarm.depends_on[] -> status:blocked;
114
+ # kind=epic -> epic + status:tracker; kind=research -> rfc. Mirror (not
115
+ # accumulate): managed labels that no longer apply are removed; labels
116
+ # outside the managed set are never touched. Every forge call routes
117
+ # through scripts/scm.py (#1145) so task verify:scm-boundary stays green,
118
+ # and the verb is idempotent (a second run mutates nothing). Pass-through
119
+ # flags: --repo OWNER/NAME (fallback when a reference URI lacks owner/
120
+ # repo), --dry-run (report without mutating), --json (machine summary).
121
+ #
122
+ # CLI_ARGS forwarding (#577): bare ``{{.CLI_ARGS}}`` -- DO NOT wrap in
123
+ # Taskfile-level double quotes. go-task already shell-escapes CLI_ARGS
124
+ # with single quotes; double-wrapping breaks Windows argv. See the
125
+ # preflight task above for the full rationale.
126
+ #
127
+ # NOTE: NO ``sources:`` / ``generates:`` per ``conventions/task-caching.md``
128
+ # because the walk reads the lifecycle folders and mutates remote forge
129
+ # state that go-task does not track, so a cached skip would silently
130
+ # swallow real label changes.
131
+ desc: "Reconcile SCM labels to mirror vBRIEF state: status:blocked / epic+status:tracker / rfc (#1288). Routes through scripts/scm.py. Flags: --repo --dry-run --json."
132
+ dir: '{{.USER_WORKING_DIR}}'
133
+ deps:
134
+ - _ts-build
135
+ cmds:
136
+ # Oracle/fallback (parity): scripts/vbrief_reconcile_labels.py (#1828 Wave 8).
137
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" vbrief-reconcile labels --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
138
+
139
+ reconcile:umbrellas:
140
+ # Umbrella current-shape auto-update (#1289). Walks every kind=epic
141
+ # vBRIEF, resolves its children from its x-vbrief/plan references,
142
+ # computes the wave structure from the children's swarm.depends_on[]
143
+ # edges, builds the canonical AGENTS.md section-1152 current-shape body
144
+ # (Last updated / Last pass type / Child count / Child-count history /
145
+ # Open children / Closed children / Wave order / Open questions /
146
+ # Reading order), and edits the linked SCM umbrella's current-shape
147
+ # comment IN PLACE so the permalink is preserved and the amendment
148
+ # trail is never touched. When no current-shape comment exists yet, one
149
+ # is created at pass-1. Every forge call routes through scripts/scm.py
150
+ # (#1145) so task verify:scm-boundary stays green, and the verb is
151
+ # idempotent (a second run with unchanged epic state mutates nothing --
152
+ # the pass number is only bumped when the rendered body differs).
153
+ # Pass-through flags: --repo OWNER/NAME (fallback when a reference URI
154
+ # lacks owner/repo), --dry-run (report without mutating), --json
155
+ # (machine summary).
156
+ #
157
+ # CLI_ARGS forwarding (#577): bare ``{{.CLI_ARGS}}`` -- DO NOT wrap in
158
+ # Taskfile-level double quotes. go-task already shell-escapes CLI_ARGS
159
+ # with single quotes; double-wrapping breaks Windows argv. See the
160
+ # preflight task below for the full rationale.
161
+ #
162
+ # NOTE: NO ``sources:`` / ``generates:`` per ``conventions/task-caching.md``
163
+ # because the walk reads the lifecycle folders and mutates remote forge
164
+ # state that go-task does not track, so a cached skip would silently
165
+ # swallow real comment updates.
166
+ desc: "Reconcile epic umbrella current-shape comments to vBRIEF state per AGENTS.md #1152: edit in place (preserve permalink). Routes through scripts/scm.py. Flags: --repo --dry-run --json."
167
+ dir: '{{.USER_WORKING_DIR}}'
168
+ deps:
169
+ - _ts-build
170
+ cmds:
171
+ # Oracle/fallback (parity): scripts/vbrief_reconcile_umbrellas.py (#1828 Wave 8).
172
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" vbrief-reconcile umbrellas --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
173
+
174
+ activate:
175
+ # Implementation-intent activation gate companion (#810). Idempotent:
176
+ # already-active vBRIEFs print a no-op message and exit 0; pending/
177
+ # vBRIEFs flip plan.status pending|approved -> running, stamp
178
+ # vBRIEFInfo.updated to current ISO8601 UTC, and atomically move to
179
+ # vbrief/active/. Any other source folder is rejected with an
180
+ # actionable message. Pairs with `scripts/preflight_implementation.py`
181
+ # (also reachable via `task vbrief:preflight`): this task is the ONLY
182
+ # supported way to satisfy that gate.
183
+ #
184
+ # Dispatched via `{{.DEFT_ROOT}}/scripts/vbrief_activate.py` mirroring
185
+ # the `tasks/scope.yml` pattern (scope_lifecycle.py) so the JSON edit
186
+ # + atomic move logic is testable. The companion test lives at
187
+ # `tests/cli/test_vbrief_activate.py` to satisfy the forward-coverage
188
+ # rule from main.md.
189
+ #
190
+ # CLI_ARGS forwarding (#577): bare ``{{.CLI_ARGS}}`` -- DO NOT wrap
191
+ # in Taskfile-level double quotes. See the preflight task above for
192
+ # the full rationale; the short version is that go-task already
193
+ # shell-escapes CLI_ARGS with single quotes, and double-wrapping it
194
+ # breaks Windows argv. Spaces in paths survive correctly through
195
+ # bare interpolation.
196
+ #
197
+ # NOTE: NO ``sources:`` / ``generates:`` per ``conventions/task-caching.md``
198
+ # because the vBRIEF path is a user-facing argument forwarded via
199
+ # {{.CLI_ARGS}} and a cached cmds skip would silently swallow it.
200
+ desc: "Activate a vBRIEF: pending/ -> active/ (status: running). Idempotent. (#810)"
201
+ dir: '{{.USER_WORKING_DIR}}'
202
+ deps:
203
+ - _ts-build
204
+ cmds:
205
+ # Oracle/fallback (parity): scripts/vbrief_activate.py (#1828 Wave 8).
206
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" vbrief:activate {{.CLI_ARGS}}
@@ -0,0 +1,292 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ tasks:
7
+ _ts-build:
8
+ internal: true
9
+ desc: "Build @deftai/cli dist/ before TS-backed gates run (#1828 s2)."
10
+ dir: '{{.DEFT_ROOT}}'
11
+ cmds:
12
+ - pnpm run build
13
+
14
+ stubs:
15
+ desc: Scan source files for stub patterns (TODO, FIXME, HACK, return null, bare pass)
16
+ deps:
17
+ - _ts-build
18
+ cmds:
19
+ # Oracle/fallback (parity): scripts/verify-stubs.py (#1828 Wave 8 / #1854 s3).
20
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify-stubs
21
+
22
+ links:
23
+ desc: Validate internal links in markdown files
24
+ deps:
25
+ - _ts-build
26
+ cmds:
27
+ # Oracle/fallback (parity): scripts/validate-links.py (#1828 Wave 8 / #1854 s3).
28
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" validate-links
29
+
30
+ rule-ownership:
31
+ desc: "Verify the Rule Ownership Map (conventions/rule-ownership.json) is in sync with its owner files (#635)"
32
+ deps:
33
+ - _ts-build
34
+ cmds:
35
+ # Oracle/fallback (parity): scripts/rule_ownership_lint.py (#1828 Wave 8 / #1854 s3).
36
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" rule-ownership-lint --root "{{.DEFT_ROOT}}"
37
+
38
+ content-manifest:
39
+ desc: "Verify the Content Manifest (conventions/content-manifest.json) classifies every git-tracked top-level entry (#1821). Fails on an unclassified entry, a stale classified path, an invalid bucket, or a duplicate path. Wave-1 shippability audit for the engine/content split (#1669)."
40
+ deps:
41
+ - _ts-build
42
+ # Framework-source-only gate: it classifies THIS repo's top-level tree, so it
43
+ # targets DEFT_ROOT (not USER_WORKING_DIR) -- a consumer install has no
44
+ # content/ + engine/ top-level split to audit. Mirrors verify:rule-ownership.
45
+ cmds:
46
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify-content-manifest --project-root "{{.DEFT_ROOT}}"
47
+
48
+ go-freeze:
49
+ desc: "Tier-1 freeze gate for the legacy Go-installer bridge (#1912). Advisory while the Tier-0 SoT (lastGoInstaller) is null; once the operator pins it, fails when cmd/deft-install is bumped above the frozen tag. Three-state exit (0 ok / 1 violation / 2 config error). Emergency bypass: DEFT_ALLOW_GO_INSTALLER_BUMP=1."
50
+ deps:
51
+ - _ts-build
52
+ # Framework-source-only gate: it inspects THIS repo's cmd/deft-install
53
+ # version constant + the Tier-0 SoT, so it targets DEFT_ROOT (not
54
+ # USER_WORKING_DIR) -- a consumer install has no Go-installer source to
55
+ # freeze. Mirrors verify:content-manifest.
56
+ cmds:
57
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify-go-freeze --project-root "{{.DEFT_ROOT}}"
58
+
59
+ bridge-drift:
60
+ desc: "Tier-1 cross-surface drift gate for the legacy Go-installer bridge (#1912). Asserts no surface marked with the bridge sentinel hardcodes a Go-installer version instead of reading the Tier-0 SoT (lastGoInstaller). Three-state exit (0 clean / 1 drift / 2 config error). Passes whether or not the UPGRADING/doctor surfaces exist yet."
61
+ deps:
62
+ - _ts-build
63
+ # Framework-source-only gate: it scans THIS repo's bridge-version surfaces
64
+ # against the Tier-0 SoT, so it targets DEFT_ROOT. Mirrors
65
+ # verify:content-manifest / verify:scm-boundary.
66
+ cmds:
67
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify-bridge-drift --project-root "{{.DEFT_ROOT}}"
68
+
69
+ branch:
70
+ desc: "Detection-bound branch-protection gate (#747). Reads plan.policy.allowDirectCommitsToMaster from PROJECT-DEFINITION."
71
+ dir: '{{.USER_WORKING_DIR}}'
72
+ deps:
73
+ - _ts-build
74
+ cmds:
75
+ # Oracle/fallback (parity): scripts/preflight_branch.py (#1828 Wave 8).
76
+ # `--allow-missing-project-definition` keeps the framework's own check
77
+ # green for fresh checkouts that have not yet run `task setup` (the
78
+ # bootstrap fallback path documented in #746 acceptance criterion E).
79
+ # Production projects with PROJECT-DEFINITION present will still get
80
+ # the full enforcement -- the flag is a no-op when the file exists.
81
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify:branch --project-root "{{.USER_WORKING_DIR}}" --allow-missing-project-definition
82
+
83
+ routing:
84
+ desc: "Operator coding sub-agent model routing gate (#1739). Pre-dispatch (default): fails when a dispatched worker role has no decision in .deft/routing.local.json. Pass --advise for the non-blocking session-start disclosure; --roles a,b to widen the gated set; --provider to override the runtime."
85
+ dir: '{{.USER_WORKING_DIR}}'
86
+ deps:
87
+ - _ts-build
88
+ cmds:
89
+ # Bare CLI_ARGS per the verify:encoding convention -- go-task shell-escapes pass-through args.
90
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" swarm-routing-verify --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
91
+
92
+ hooks-installed:
93
+ desc: "Assert the deft git hooks are installed AND functional -- core.hooksPath set, hooks dir + pre-commit/pre-push present, and the gate scripts resolve in this layout (own-repo or vendored). Fails loud on the #1463 false-green (wired but non-functional). Run `task setup` / re-run the installer if this fails (#747, #1463)."
94
+ dir: '{{.USER_WORKING_DIR}}'
95
+ deps:
96
+ - _ts-build
97
+ # No sources:/generates: -- a cached cmds skip would mask a hooks dir /
98
+ # gate-script that was deleted after the last run.
99
+ cmds:
100
+ # Oracle/fallback (parity): scripts/verify_hooks_installed.py (#1828 Wave 8).
101
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify:hooks-installed --project-root "{{.USER_WORKING_DIR}}"
102
+
103
+ encoding:
104
+ desc: "Detect PS 5.1 non-ASCII round-trip corruption (#798). Scans tracked text files for U+FFFD, CP1252/CP437-as-UTF-8 mojibake, and unexpected BOM. Defaults to --all; pass --staged for the pre-commit invocation."
105
+ dir: '{{.USER_WORKING_DIR}}'
106
+ deps:
107
+ - _ts-build
108
+ # Per `conventions/task-caching.md`: NO `sources:` / `generates:` because
109
+ # user-facing flags (--staged / --all / --allow-list <path>) MUST NOT be
110
+ # silently swallowed by go-task's incremental-build cache. The same
111
+ # rationale that gated `task release` (#74) and `task pr:check-protected-issues`
112
+ # (#702) applies here -- the gate accepts recovery flags that the cache
113
+ # layer would otherwise discard.
114
+ cmds:
115
+ # Oracle/fallback (parity): scripts/verify_encoding.py (#1828 Wave 8).
116
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify:encoding --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
117
+
118
+ vbrief-conformance:
119
+ desc: "Detect bare non-conformant vBRIEF keys (#1620). Scans tracked vbrief/**/*.vbrief.json and flags any document/plan/item key that is not 0.6 spec-core, x-directive/-namespaced, or x-vbrief/-namespaced. plan.policy + plan.completedNote carry a TEMPORARY allow-list pending vBRIEF #12. Defaults to --all; pass --staged for the pre-commit invocation."
120
+ dir: '{{.USER_WORKING_DIR}}'
121
+ deps:
122
+ - _ts-build
123
+ # Per `conventions/task-caching.md`: NO `sources:` / `generates:` because
124
+ # user-facing flags (--staged / --all / --allow-list <path>) MUST NOT be
125
+ # silently swallowed by go-task's incremental-build cache (same rationale
126
+ # as verify:encoding above).
127
+ cmds:
128
+ # Oracle/fallback (parity): scripts/verify_vbrief_conformance.py (#1828 Wave 8).
129
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" vbrief-validate conformance --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
130
+
131
+ destructive-gh-verbs:
132
+ desc: "Detection-bound gate for destructive gh verbs (#1019). Runs preflight-gh --self-test so the fixture-vs-classifier contract fails CI on drift. Override via DEFT_ALLOW_DESTRUCTIVE_GH_VERBS=1 (per-shell emergency bypass)."
133
+ dir: '{{.USER_WORKING_DIR}}'
134
+ deps:
135
+ - _ts-build
136
+ # No sources:/generates: -- the self-test fixture table is the
137
+ # invariant under test; we want the gate to re-run on every
138
+ # `task check` invocation regardless of whether the classifier file
139
+ # mtime moved. Caching here would silently mask a regression.
140
+ cmds:
141
+ # Oracle/fallback (parity): scripts/preflight_gh.py --self-test (#1854 s5).
142
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" preflight-gh --self-test {{.CLI_ARGS}}
143
+
144
+ cache-fresh:
145
+ desc: "Pre-`start_agent` cache-freshness gate (#1127). Refuses implementation dispatch when the triage cache is stale, missing, or the target issue's latest decision is not `accept`. Subscription-aware via plan.policy.triageScope[] (D12 / #1131). Flags: --for-issue N / --max-age-hours N / --allow-stale / --repo OWNER/NAME / --allow-missing-bootstrap (consumed by the framework's own `task check` so a fresh checkout passes -- consumers leave it OFF)."
146
+ dir: '{{.USER_WORKING_DIR}}'
147
+ deps:
148
+ - _ts-build
149
+ # Per `conventions/task-caching.md` (#574): NO `sources:` / `generates:`
150
+ # because the gate forwards user-facing flags via {{.CLI_ARGS}}
151
+ # (--for-issue / --max-age-hours / --allow-stale / --repo) that
152
+ # go-task's incremental-build cache would silently swallow. The
153
+ # `--allow-missing-bootstrap` flag below keeps the framework's own
154
+ # `task check` green on a fresh checkout that has not yet run
155
+ # `task triage:bootstrap`; consumer projects leave it off so a
156
+ # missing cache fails their `task check` loudly.
157
+ cmds:
158
+ # Oracle/fallback (parity): scripts/preflight_cache.py --allow-missing-bootstrap (#1854 s5).
159
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" preflight-cache --project-root "{{.USER_WORKING_DIR}}" --allow-missing-bootstrap {{.CLI_ARGS}}
160
+
161
+ codebase-map-fresh:
162
+ desc: "Drift gate for the generated .planning/codebase/MAP.md projection (#1595 PR4)."
163
+ dir: '{{.USER_WORKING_DIR}}'
164
+ deps:
165
+ - _ts-build
166
+ # Per conventions/task-caching.md: no sources/generates because this gate
167
+ # forwards output/artifact overrides through CLI_ARGS.
168
+ cmds:
169
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" codebase-map-fresh --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
170
+
171
+ session-ritual:
172
+ desc: "Fail-closed session ritual verifier (#1348). Flags: --tier quick|gated / --json. Set DEFT_SESSION_RITUAL_SKIP=1 for headless workers and CI."
173
+ dir: '{{.USER_WORKING_DIR}}'
174
+ deps:
175
+ - _ts-build
176
+ # No sources/generates: this gate is time-, HEAD-, and worktree-sensitive.
177
+ cmds:
178
+ # Oracle/fallback (parity): scripts/verify_session_ritual.py (#1828 Wave 8 / #1854 s3).
179
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify-session-ritual --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
180
+
181
+ tools:
182
+ desc: "Detect required Deft host tools and print install or manual guidance (#1187). Flags: --install / --yes / --json"
183
+ dir: '{{.USER_WORKING_DIR}}'
184
+ deps:
185
+ - _ts-build
186
+ cmds:
187
+ # Oracle/fallback (parity): scripts/verify_tools.py (#1828 Wave 8).
188
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify:tools {{.CLI_ARGS}}
189
+
190
+ scm-boundary:
191
+ desc: "Detection-bound gate against raw `gh` / `ghx` subprocess calls outside `scripts/scm.py` (#1145 / N5). Scans verb-layer Python files (`scripts/triage_*.py`, `scripts/scope_*.py`, `scripts/slice_*.py`, `scripts/_triage_*.py`, `scripts/_scope_*.py`, `scripts/resume_conditions.py`, `scripts/issue_ingest.py`) and fails loud when any of them invoke `gh` directly instead of going through `scm.call(source, verb, args)`. Three-state exit (0 clean / 1 violations / 2 config error). Document an exception via `--allow-list <path>` (file with newline-separated glob patterns)."
192
+ dir: '{{.USER_WORKING_DIR}}'
193
+ deps:
194
+ - _ts-build
195
+ # Per `conventions/task-caching.md` (#574): NO `sources:` / `generates:`
196
+ # because the gate forwards user-facing flags via {{.CLI_ARGS}}
197
+ # (`--allow-list <path>` / `--quiet`) that go-task's incremental-build
198
+ # cache would silently swallow.
199
+ cmds:
200
+ # Oracle/fallback (parity): scripts/verify_scm_boundary.py (#1828 Wave 8 / #1854 s3).
201
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify-scm-boundary --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
202
+
203
+ story-ready:
204
+ desc: "Deterministic story-start Gate 0 (#1378 Story C). Inspects working-tree cleanliness, the target vBRIEF lifecycle (active/ + plan.status==running), and the dispatch envelope's `## Allocation context` consent token (Story A schema). Three-state exit (0 ready / 1 not ready / 2 config error). -- task verify:story-ready -- --vbrief-path <active-story-path> [--allocation-context <dispatch-envelope-file>] [--allow-dirty] [--json]"
205
+ dir: '{{.USER_WORKING_DIR}}'
206
+ deps:
207
+ - _ts-build
208
+ # Per `conventions/task-caching.md` (#574): NO `sources:` / `generates:`
209
+ # because the gate forwards user-facing flags via {{.CLI_ARGS}}
210
+ # (--vbrief-path / --allocation-context / --allow-dirty / --json) that
211
+ # go-task's incremental-build cache would silently swallow. Intentionally
212
+ # NOT wired into the `task check` aggregate: Gate 0 is a pre-`start_agent`
213
+ # dispatch gate that requires a concrete --vbrief-path, which a generic
214
+ # `task check` run has no way to supply.
215
+ cmds:
216
+ # Oracle/fallback (parity): scripts/preflight_story_start.py (#1828 Wave 8).
217
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify:story-ready --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
218
+
219
+ investigation:
220
+ desc: "Validate a forensic investigation ledger (#1621). Promotes the forensic-research validator into a deterministic gate: the close check before Wave 5 / any causal chat. Three-state exit (0 close-ready / 1 hard failures / 2 config error). Intentionally NOT in the `task check` aggregate -- it requires a concrete --ledger path. -- task verify:investigation -- --ledger .tmp/investigations/<id>/investigation.vbrief.json [--json]"
221
+ dir: '{{.USER_WORKING_DIR}}'
222
+ deps:
223
+ - _ts-build
224
+ # Per `conventions/task-caching.md` (#574): NO `sources:` / `generates:`
225
+ # because the gate forwards user-facing flags via {{.CLI_ARGS}}
226
+ # (--ledger / --json) that go-task's incremental-build cache would
227
+ # silently swallow.
228
+ cmds:
229
+ # Oracle/fallback (parity): scripts/verify_investigation.py (#1828 Wave 8).
230
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify:investigation --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
231
+
232
+ architecture-sor:
233
+ desc: "Diff-time system-of-record architecture gate. Scans stateful persistence signals and requires a matching architecture.systemOfRecord record. Example: task verify:architecture-sor -- --base-ref origin/main [--story-path <path>]"
234
+ dir: '{{.USER_WORKING_DIR}}'
235
+ deps:
236
+ - _ts-build
237
+ # Per conventions/task-caching.md: no sources/generates because this gate
238
+ # forwards --base-ref, --story-path, and --json through CLI_ARGS.
239
+ cmds:
240
+ # Oracle/fallback (parity): scripts/preflight_architecture_sor.py (#1854 s5).
241
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" architecture-preflight-sor --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
242
+
243
+ capacity:
244
+ desc: "Three-state ADVISORY capacity gate (#1419 Slice 4). Reports trailing-window target-vs-actual bucket mix from plan.policy.capacityAllocation; exits 0 in the default advise posture (and on insufficient sample / unconfigured policy), 1 only under an explicit enforce posture with a sampled deficit, 2 on config error. DELIBERATELY NOT in the `task check` aggregate -- capacity must never fail-closed on the framework tree."
245
+ dir: '{{.USER_WORKING_DIR}}'
246
+ deps:
247
+ - _ts-build
248
+ # Per `conventions/task-caching.md` (#574): NO `sources:` / `generates:`
249
+ # because the gate forwards user-facing flags via {{.CLI_ARGS}}
250
+ # (--project-root / --quiet) that go-task's incremental-build cache would
251
+ # silently swallow. Advisory-only: this target is intentionally absent
252
+ # from the `task check` deps so a capacity deficit cannot wedge the
253
+ # framework's own self-check (advise-mode discipline, #1419).
254
+ cmds:
255
+ # Oracle/fallback (parity): scripts/verify_capacity.py (#1828 Wave 8 / #1854 s3).
256
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify-capacity --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
257
+
258
+ judgment-gates:
259
+ desc: "Three-state ADVISORY judgment-gate engine (#1419 Slice 3). Evaluates a candidate change (diff paths / labels / body) against plan.policy.judgmentGates + four default-on universal safety gates (secrets / infra / AGENTS.md+skills / installer). Advisory by default (always exits 0); opt-in --enforce fails closed (exit 1) when a mechanical block-tier gate fires without a recorded clearance; exit 2 on config error. -- task verify:judgment-gates [-- --base-ref <ref>] [--path P] [--label L] [--enforce] [--json]. DELIBERATELY NOT in the `task check` aggregate -- judgment gates must never fail-closed on the framework tree (advise -> observe -> block rollout, #1419)."
260
+ dir: '{{.USER_WORKING_DIR}}'
261
+ deps:
262
+ - _ts-build
263
+ # Per `conventions/task-caching.md` (#574): NO `sources:` / `generates:`
264
+ # because the gate forwards user-facing flags via {{.CLI_ARGS}}
265
+ # (--base-ref / --path / --label / --body / --state / --enforce / --json /
266
+ # --quiet) that go-task's incremental-build cache would silently swallow.
267
+ # Advisory-only: this target is intentionally absent from the `task check`
268
+ # deps so a gate finding cannot wedge the framework's own self-check. The
269
+ # directive-side invocation never passes --enforce, so the gate stays
270
+ # advisory on the framework's own tree (advise-mode discipline, #1419).
271
+ cmds:
272
+ # Oracle/fallback (parity): scripts/verify_judgment_gates.py (#1828 Wave 8).
273
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify:judgment-gates --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
274
+
275
+ wip-cap:
276
+ desc: "Pre-merge re-validation that pending/+active/ count is within plan.policy.wipCap (#1124 / D4 of #1119). Catches stale-branch merges + --force overrides. Default cap is 10 per umbrella #1119 Current Shape v3. The framework's own task check passes --allow-over-cap during landing-day overage; consumer projects MUST NOT pass that flag."
277
+ dir: '{{.USER_WORKING_DIR}}'
278
+ deps:
279
+ - _ts-build
280
+ # Per `conventions/task-caching.md` (#574): NO `sources:` /
281
+ # `generates:` because the gate forwards user-facing flags via
282
+ # {{.CLI_ARGS}} (--allow-over-cap / --quiet) that go-task's
283
+ # incremental-build cache would silently swallow. The framework's
284
+ # own `task check` invocation in Taskfile.yml passes
285
+ # `--allow-over-cap` so deft's landing-day overage (pending/+active/
286
+ # >> 10; resolved via D1 scope:demote --batch per umbrella v3) does
287
+ # not break framework self-check; consumer projects leave the flag
288
+ # OFF so a stale-branch / --force-merge over-cap state fails their
289
+ # `task check` loudly.
290
+ cmds:
291
+ # Oracle/fallback (parity): scripts/preflight_wip_cap.py (#1828 Wave 8).
292
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" verify:wip-cap --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
@@ -62,9 +62,9 @@ Check what exists before doing anything else:
62
62
 
63
63
  ⊗ Self-report the session-start ritual as complete without a fresh `deft session:start` state, or bypass `deft verify:session-ritual` before implementation dispatch. Headless workers and CI MAY set `DEFT_SESSION_RITUAL_SKIP=1`; the verifier exits 0 but warns when the bypass hides a failure.
64
64
 
65
- `deft doctor` remains the install-integrity + toolchain + AGENTS.md managed-section freshness probe (#1308). When the managed-section is stale, the doctor points the operator at `deft agents:refresh` to regenerate AGENTS.md from `templates/agents-entry.md`. The canonical `scripts/doctor.py` (single owner post #1335/#1336) also detects payload staleness from the `<install>/VERSION` manifest and, when behind, emits the canonical headless upgrade command `deft-install --yes --upgrade --repo-root . --json` (#1339 / #1409). The installer itself calls `scripts/doctor.py --session --json` at the end of every run for the unified handoff.
65
+ `deft doctor` remains the install-integrity + toolchain + AGENTS.md managed-section freshness probe (#1308). When the managed-section is stale, the doctor points the operator at `deft agents:refresh` to regenerate AGENTS.md from `templates/agents-entry.md`. The canonical `scripts/doctor.py` (single owner post #1335/#1336) also detects payload staleness from the `<install>/VERSION` manifest and, when behind, emits the canonical upgrade command `npm i -g @deftai/directive@latest` (#1339 / #1409 / #1912).
66
66
 
67
- **Canonical bootstrap / update path (#1339 #1340 #1409 Epic-5/6):** Use the published platform installer binary (from GitHub Releases) as the single deterministic entrypoint. For an existing install, the canonical headless refresh is `deft-install --yes --upgrade --repo-root . --json` (drop `--json` for human-readable output) -- it replaces the payload + manifest + AGENTS.md in one shot. Legacy `deft upgrade` / `run upgrade` are metadata-only acknowledgment (they do NOT replace the payload) and `deft relocate -- --confirm` is back-compat only; git-clone / submodule / legacy doctor surfaces are de-emphasized in UPGRADING.md / README / skills. Agent example: after running the installer command, start your session; the doctor output (or `deft doctor`) tells you the exact state and whether a re-install is needed for freshness.
67
+ **Canonical bootstrap / update path:** Install and upgrade via npm: `npm i -g @deftai/directive` (install) or `npm i -g @deftai/directive@latest` (upgrade). Node 20 is required to run Deft (the live gates run on the TypeScript engine). On a machine without Node, install Node first, then use npm the frozen legacy Go installer (GitHub Releases) is only a legacy/offline + layout-migration bridge (#1912), not a Node-free path. Legacy `deft upgrade` / `run upgrade` are metadata-only acknowledgment and `deft relocate -- --confirm` is back-compat only; git-clone / submodule / legacy doctor surfaces are de-emphasized in UPGRADING.md / README / skills. Agent example: after installing, start your session; `deft doctor` tells you the exact state.
68
68
  `deft triage:welcome` emits the triage one-liner and, when state is incomplete, nudges the operator at `deft triage:welcome --onboard` (#1143). Default mode is non-interactive; the `--onboard` flag runs the 6-phase interactive ritual.
69
69
 
70
70
  ## Resume nudge (conditional, #1269)