@deftai/directive-content 0.55.2 → 0.56.1

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 (217) hide show
  1. package/.githooks/pre-commit +143 -0
  2. package/.githooks/pre-push +121 -0
  3. package/QUICK-START.md +2 -2
  4. package/Taskfile.yml +934 -0
  5. package/UPGRADING.md +47 -1
  6. package/events/README.md +3 -3
  7. package/package.json +5 -4
  8. package/scripts/_agents_md.py +494 -0
  9. package/scripts/_cache_fetch.py +635 -0
  10. package/scripts/_cache_quota.py +529 -0
  11. package/scripts/_cache_refresh.py +163 -0
  12. package/scripts/_cache_validate.py +209 -0
  13. package/scripts/_content_root.py +42 -0
  14. package/scripts/_doctor_state.py +277 -0
  15. package/scripts/_event_detect.py +305 -0
  16. package/scripts/_events.py +514 -0
  17. package/scripts/_lifecycle_hygiene.py +568 -0
  18. package/scripts/_pathspec.py +91 -0
  19. package/scripts/_policy_show_cli.py +266 -0
  20. package/scripts/_precutover.py +92 -0
  21. package/scripts/_project_context.py +224 -0
  22. package/scripts/_project_definition_io.py +164 -0
  23. package/scripts/_relocate_snapshot.py +209 -0
  24. package/scripts/_relocate_states.py +343 -0
  25. package/scripts/_resolve_preflight_path.py +152 -0
  26. package/scripts/_safe_subprocess.py +167 -0
  27. package/scripts/_session_start_hook.py +205 -0
  28. package/scripts/_sor_gate_diff.py +365 -0
  29. package/scripts/_stdio_utf8.py +59 -0
  30. package/scripts/_triage_bootstrap_gitignore.py +904 -0
  31. package/scripts/_triage_classify_cli.py +122 -0
  32. package/scripts/_triage_queue_cli.py +625 -0
  33. package/scripts/_triage_scope_cli.py +343 -0
  34. package/scripts/_triage_scope_drift_cli.py +121 -0
  35. package/scripts/_triage_scope_ignores.py +286 -0
  36. package/scripts/_triage_scope_milestone.py +432 -0
  37. package/scripts/_triage_scope_mutations.py +337 -0
  38. package/scripts/_triage_scope_renderers.py +207 -0
  39. package/scripts/_triage_smoketest_stages.py +674 -0
  40. package/scripts/_triage_subscribe_cli.py +140 -0
  41. package/scripts/_triage_welcome_cli.py +421 -0
  42. package/scripts/_vbrief_build.py +239 -0
  43. package/scripts/_vbrief_fidelity.py +479 -0
  44. package/scripts/_vbrief_legacy.py +589 -0
  45. package/scripts/_vbrief_reconciliation.py +883 -0
  46. package/scripts/_vbrief_routing.py +277 -0
  47. package/scripts/_vbrief_safety.py +778 -0
  48. package/scripts/_vbrief_sources.py +312 -0
  49. package/scripts/_vbrief_speckit.py +262 -0
  50. package/scripts/_vbrief_story_quality.py +353 -0
  51. package/scripts/_vbrief_validation.py +299 -0
  52. package/scripts/build_dist.py +412 -0
  53. package/scripts/cache.py +1078 -0
  54. package/scripts/cache_scanner.py +745 -0
  55. package/scripts/candidates_log.py +432 -0
  56. package/scripts/capacity_backfill.py +680 -0
  57. package/scripts/capacity_show.py +653 -0
  58. package/scripts/ci_local.py +689 -0
  59. package/scripts/code_structure_validate.py +765 -0
  60. package/scripts/codebase_default_extractor.py +495 -0
  61. package/scripts/codebase_map.py +304 -0
  62. package/scripts/codebase_map_fresh.py +104 -0
  63. package/scripts/codebase_projection_registry.py +94 -0
  64. package/scripts/codebase_provider.py +582 -0
  65. package/scripts/doctor.py +2257 -0
  66. package/scripts/framework_commands.py +505 -0
  67. package/scripts/gh_rest.py +882 -0
  68. package/scripts/github_auth_modes.py +437 -0
  69. package/scripts/github_body.py +292 -0
  70. package/scripts/ip_risk.py +531 -0
  71. package/scripts/issue_emit.py +670 -0
  72. package/scripts/issue_ingest.py +1064 -0
  73. package/scripts/migrate_preflight.py +418 -0
  74. package/scripts/migrate_vbrief.py +2677 -0
  75. package/scripts/monitor_pr.py +401 -0
  76. package/scripts/pack_migrate_lessons.py +336 -0
  77. package/scripts/pack_migrate_patterns.py +254 -0
  78. package/scripts/pack_migrate_rules.py +350 -0
  79. package/scripts/pack_migrate_skills.py +423 -0
  80. package/scripts/pack_migrate_strategies.py +311 -0
  81. package/scripts/pack_migrate_swarm_spec.py +250 -0
  82. package/scripts/pack_render.py +434 -0
  83. package/scripts/packs_slice.py +712 -0
  84. package/scripts/platform_capabilities.py +336 -0
  85. package/scripts/policy.py +2826 -0
  86. package/scripts/policy_set.py +324 -0
  87. package/scripts/pr_check_closing_keywords.py +524 -0
  88. package/scripts/pr_check_protected_issues.py +267 -0
  89. package/scripts/pr_merge_readiness.py +1004 -0
  90. package/scripts/pr_wait_mergeable.py +669 -0
  91. package/scripts/prd_render.py +159 -0
  92. package/scripts/preflight_architecture_sor.py +974 -0
  93. package/scripts/preflight_branch.py +289 -0
  94. package/scripts/preflight_cache.py +974 -0
  95. package/scripts/preflight_gh.py +721 -0
  96. package/scripts/preflight_implementation.py +272 -0
  97. package/scripts/preflight_story_start.py +838 -0
  98. package/scripts/preflight_wip_cap.py +149 -0
  99. package/scripts/probe_session.py +545 -0
  100. package/scripts/project_render.py +293 -0
  101. package/scripts/quarantine_ext.py +237 -0
  102. package/scripts/reconcile_issues.py +1442 -0
  103. package/scripts/refresh-path.ps1 +107 -0
  104. package/scripts/release.py +2030 -0
  105. package/scripts/release_e2e.py +1011 -0
  106. package/scripts/release_publish.py +486 -0
  107. package/scripts/release_rollback.py +980 -0
  108. package/scripts/relocate.py +1034 -0
  109. package/scripts/resolve_changelog_unreleased.py +667 -0
  110. package/scripts/resolve_version.py +490 -0
  111. package/scripts/resume_conditions.py +706 -0
  112. package/scripts/ritual_sentinel.py +609 -0
  113. package/scripts/roadmap_render.py +635 -0
  114. package/scripts/rule_ownership_lint.py +325 -0
  115. package/scripts/scm.py +591 -0
  116. package/scripts/scope_audit_log.py +387 -0
  117. package/scripts/scope_decompose.py +654 -0
  118. package/scripts/scope_demote.py +509 -0
  119. package/scripts/scope_lifecycle.py +1126 -0
  120. package/scripts/scope_undo.py +772 -0
  121. package/scripts/session_start.py +406 -0
  122. package/scripts/setup_ghx.py +339 -0
  123. package/scripts/setup_windows.ps1 +220 -0
  124. package/scripts/slice_audit.py +585 -0
  125. package/scripts/slice_record.py +530 -0
  126. package/scripts/slice_record_existing.py +692 -0
  127. package/scripts/slug_normalize.py +178 -0
  128. package/scripts/spec_render.py +477 -0
  129. package/scripts/spec_validate.py +238 -0
  130. package/scripts/subagent_monitor.py +658 -0
  131. package/scripts/swarm_complete_cohort.py +644 -0
  132. package/scripts/swarm_launch.py +1206 -0
  133. package/scripts/swarm_readiness.py +554 -0
  134. package/scripts/swarm_verify_review_clean.py +438 -0
  135. package/scripts/swarm_worktrees.py +497 -0
  136. package/scripts/toolchain-check.py +52 -0
  137. package/scripts/triage_actions.py +871 -0
  138. package/scripts/triage_bootstrap.py +1153 -0
  139. package/scripts/triage_bulk.py +630 -0
  140. package/scripts/triage_classify.py +932 -0
  141. package/scripts/triage_help.py +1685 -0
  142. package/scripts/triage_queue.py +1944 -0
  143. package/scripts/triage_reconcile.py +581 -0
  144. package/scripts/triage_refresh.py +643 -0
  145. package/scripts/triage_scope.py +999 -0
  146. package/scripts/triage_scope_drift.py +575 -0
  147. package/scripts/triage_smoketest.py +396 -0
  148. package/scripts/triage_subscribe.py +399 -0
  149. package/scripts/triage_summary.py +1011 -0
  150. package/scripts/triage_welcome.py +1178 -0
  151. package/scripts/ts_check_lane.py +86 -0
  152. package/scripts/validate-links.py +64 -0
  153. package/scripts/validate_strategy_output.py +212 -0
  154. package/scripts/vbrief_activate.py +228 -0
  155. package/scripts/vbrief_migrate_conformance.py +368 -0
  156. package/scripts/vbrief_reconcile_graph.py +306 -0
  157. package/scripts/vbrief_reconcile_labels.py +460 -0
  158. package/scripts/vbrief_reconcile_umbrellas.py +741 -0
  159. package/scripts/vbrief_validate.py +1195 -0
  160. package/scripts/verify-stubs.py +61 -0
  161. package/scripts/verify_capacity.py +160 -0
  162. package/scripts/verify_encoding.py +699 -0
  163. package/scripts/verify_hooks_installed.py +206 -0
  164. package/scripts/verify_investigation.py +360 -0
  165. package/scripts/verify_judgment_gates.py +827 -0
  166. package/scripts/verify_no_task_runtime.py +171 -0
  167. package/scripts/verify_scm_boundary.py +509 -0
  168. package/scripts/verify_session_ritual.py +389 -0
  169. package/scripts/verify_tools.py +426 -0
  170. package/scripts/verify_vbrief_conformance.py +478 -0
  171. package/tasks/architecture.yml +13 -0
  172. package/tasks/cache.yml +69 -0
  173. package/tasks/capacity.yml +38 -0
  174. package/tasks/change.yml +46 -0
  175. package/tasks/changelog.yml +24 -0
  176. package/tasks/ci.yml +49 -0
  177. package/tasks/codebase.yml +47 -0
  178. package/tasks/commit.yml +30 -0
  179. package/tasks/core.yml +126 -0
  180. package/tasks/deployments.yml +54 -0
  181. package/tasks/framework.yml +74 -0
  182. package/tasks/install.yml +60 -0
  183. package/tasks/issue.yml +50 -0
  184. package/tasks/migrate.yml +73 -0
  185. package/tasks/packs.yml +92 -0
  186. package/tasks/policy.yml +75 -0
  187. package/tasks/pr.yml +89 -0
  188. package/tasks/prd.yml +39 -0
  189. package/tasks/project.yml +27 -0
  190. package/tasks/reconcile.yml +32 -0
  191. package/tasks/relocate.yml +56 -0
  192. package/tasks/roadmap.yml +28 -0
  193. package/tasks/scm.yml +126 -0
  194. package/tasks/scope-undo.yml +36 -0
  195. package/tasks/scope.yml +141 -0
  196. package/tasks/session.yml +19 -0
  197. package/tasks/setup.yml +37 -0
  198. package/tasks/slice.yml +69 -0
  199. package/tasks/spec.yml +41 -0
  200. package/tasks/swarm.yml +85 -0
  201. package/tasks/toolchain.yml +13 -0
  202. package/tasks/triage-actions.yml +94 -0
  203. package/tasks/triage-bootstrap.yml +43 -0
  204. package/tasks/triage-bulk.yml +75 -0
  205. package/tasks/triage-classify.yml +30 -0
  206. package/tasks/triage-queue.yml +50 -0
  207. package/tasks/triage-reconcile.yml +29 -0
  208. package/tasks/triage-scope-drift.yml +29 -0
  209. package/tasks/triage-scope.yml +31 -0
  210. package/tasks/triage-smoketest.yml +33 -0
  211. package/tasks/triage-subscribe.yml +36 -0
  212. package/tasks/triage-summary.yml +29 -0
  213. package/tasks/triage-welcome.yml +32 -0
  214. package/tasks/ts.yml +328 -0
  215. package/tasks/vbrief.yml +206 -0
  216. package/tasks/verify.yml +292 -0
  217. package/templates/agents-entry.md +1 -1
@@ -0,0 +1,75 @@
1
+ version: '3'
2
+
3
+ # tasks/policy.yml -- reconfiguration surface for the typed branch policy
4
+ # (#746) and the detection-bound gate (#747). Per `conventions/task-caching.md`,
5
+ # tasks that accept user-facing recovery flags via `{{.CLI_ARGS}}` (here:
6
+ # `--confirm`, `--note "<text>"`) MUST NOT declare `sources:` / `generates:`
7
+ # -- the cached cmds: skip would silently discard the recovery flag.
8
+
9
+ vars:
10
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
11
+
12
+ tasks:
13
+ show:
14
+ # N8 (#1148) of #1119 Wave-2d-1: `task policy:show` is now the
15
+ # CONSOLIDATED typed-policy inspector. Walks every entry in
16
+ # `scripts.policy._REGISTERED_POLICIES` (allowDirectCommitsToMaster #746,
17
+ # wipCap #1124, triageScope #1131, triageScopeIgnores #1133/#1182,
18
+ # triageRankingLabels #1128, triageAutoClassify #1129, triageHoldMarkers
19
+ # #1129) and prints current / default / source per row. Flags forwarded
20
+ # via {{.CLI_ARGS}}:
21
+ # --format=text|json -- machine-stable scripting envelope
22
+ # --changed-only -- drop default-source rows
23
+ # --field=<name> -- single-field isolation
24
+ # The legacy `python -m scripts.policy show` CLI continues to work for
25
+ # any scripts that called it directly (back-compat for #746 consumers).
26
+ desc: "Inspect every registered typed-policy field on vbrief/PROJECT-DEFINITION.vbrief.json (#1148 / N8). -- task policy:show [-- --format=json] [--changed-only] [--field=<name>]"
27
+ dir: '{{.USER_WORKING_DIR}}'
28
+ deps:
29
+ - task: :ts:build
30
+ cmds:
31
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" policy show --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
32
+
33
+ enforce-branches:
34
+ desc: "Set plan.policy.allowDirectCommitsToMaster=false (enforce feature branches). Audits to meta/policy-changes.log. (#746)"
35
+ dir: '{{.USER_WORKING_DIR}}'
36
+ deps:
37
+ - task: :ts:build
38
+ cmds:
39
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" policy enforce-branches --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
40
+
41
+ allow-direct-commits:
42
+ desc: "Set plan.policy.allowDirectCommitsToMaster=true (capability-cost: branch-protection OFF). Requires --confirm to apply. (#746)"
43
+ dir: '{{.USER_WORKING_DIR}}'
44
+ deps:
45
+ - task: :ts:build
46
+ cmds:
47
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" policy allow-direct-commits --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
48
+
49
+ wip-cap:
50
+ desc: "Set plan.policy.wipCap=N (#1124 / D4 of #1119). Requires --set N --confirm. Default cap is 10 per umbrella #1119 Current Shape v3."
51
+ dir: '{{.USER_WORKING_DIR}}'
52
+ deps:
53
+ - task: :ts:build
54
+ cmds:
55
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" policy-set wip-cap {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
56
+
57
+ subagent-backend:
58
+ desc: "DEPRECATED (superseded by `task swarm:routing-set`, #1739). Was: Set plan.policy.swarmSubagentBackend (#1531a). -- task policy:subagent-backend -- --set composer|grok-build|cursor-cloud"
59
+ dir: '{{.USER_WORKING_DIR}}'
60
+ deps:
61
+ - task: :ts:build
62
+ cmds:
63
+ - cmd: echo "[deft deprecation] task policy:subagent-backend is superseded by 'task swarm:routing-set' (#1739). The swarmSubagentBackend enum is no longer the active routing surface." 1>&2
64
+ silent: true
65
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" policy-set subagent-backend {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
66
+
67
+ subagent-backends:
68
+ desc: "DEPRECATED (superseded by `task swarm:routing-set` / `task verify:routing`, #1739). Was: Probe sub-agent backend ids, role capabilities, and availability (#1531a). -- task policy:subagent-backends [-- --format=json]"
69
+ dir: '{{.USER_WORKING_DIR}}'
70
+ deps:
71
+ - task: :ts:build
72
+ cmds:
73
+ - cmd: echo "[deft deprecation] task policy:subagent-backends is superseded by 'task verify:routing -- --advise' and 'task swarm:routing-set' (#1739). The swarmSubagentBackend enum is no longer the active routing surface." 1>&2
74
+ silent: true
75
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" policy-set subagent-backends {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
package/tasks/pr.yml ADDED
@@ -0,0 +1,89 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ # pr:* tasks for PR-level merge-discipline checks.
7
+ #
8
+ # pr:check-protected-issues is the Taskfile-level encoding of the Layer 3
9
+ # pre-merge protected-issue link inspection from
10
+ # skills/deft-directive-swarm/SKILL.md Phase 6 Step 1 (#701). Per the Rule
11
+ # Authority [AXIOM] block in main.md, deterministic and Taskfile encodings
12
+ # rank above prose -- this target wraps the canonical
13
+ # gh pr view <N> --json closingIssuesReferences
14
+ # query so a swarm monitor (or any operator) can verify in one command that
15
+ # no protected (umbrella / staying-OPEN) issue is GitHub-side linked to the
16
+ # PR before squash-merging.
17
+ #
18
+ # Companion script: scripts/pr_check_protected_issues.py
19
+ # Companion test: tests/cli/test_pr_check_protected_issues.py
20
+
21
+ tasks:
22
+ check-protected-issues:
23
+ desc: "Verify NO protected (umbrella / staying-OPEN) issue is GitHub-side linked to a PR before squash merge (#701)"
24
+ deps: [":ts:build"]
25
+ dir: '{{.USER_WORKING_DIR}}'
26
+ cmds:
27
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" pr-protected-issues {{.CLI_ARGS}}
28
+
29
+ # pr:check-closing-keywords -- Layer 0 (prevention) closing-keyword
30
+ # negation-context lint introduced by #737. Refuses to push when the
31
+ # PR body or any commit message contains a closing-keyword token in a
32
+ # negation / quotation / example / code-block context. Pairs with the
33
+ # existing Layer 3 (recovery) ``pr:check-protected-issues`` (#701).
34
+ #
35
+ # Per ``conventions/task-caching.md`` (#574): NO ``sources:`` /
36
+ # ``generates:`` because user-facing recovery flags (``--pr``,
37
+ # ``--body-file``, ``--commits-file``, ``--allow-known-false-positives``)
38
+ # MUST NOT be silently swallowed by go-task's incremental-build cache.
39
+ check-closing-keywords:
40
+ desc: "Scan PR body + commit messages for closing-keyword substrings in negation/quotation/example contexts that would trigger Layer 0 false-positive auto-closes (#737)"
41
+ dir: '{{.USER_WORKING_DIR}}'
42
+ deps: [":ts:build"]
43
+ env:
44
+ PYTHONUTF8: "1"
45
+ cmds:
46
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" pr-closing-keywords {{.CLI_ARGS}}
47
+
48
+ # pr:merge-ready -- programmatic Greptile-body verdict gate. Closes the
49
+ # SUCCESS-with-findings blind spot in the Phase 5 -> 6 merge-readiness
50
+ # checklist. Parses the Greptile rolling-summary comment body (NOT the
51
+ # CheckRun status) for confidence, P0/P1 findings, errored sentinel
52
+ # (#526), and HEAD-SHA freshness. Companion to the swarm SKILL Phase 6
53
+ # Step 1 prose rule. PR #652 incident motivated this gap-closer.
54
+ #
55
+ # Companion script: scripts/pr_merge_readiness.py
56
+ # Companion test: tests/cli/test_pr_merge_readiness.py
57
+ merge-ready:
58
+ desc: "Verify a PR's Greptile review body satisfies the merge exit condition (confidence >3, no P0/P1, HEAD-SHA fresh, not errored)"
59
+ deps: [":ts:build"]
60
+ dir: '{{.USER_WORKING_DIR}}'
61
+ cmds:
62
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" pr-merge-readiness {{.CLI_ARGS}}
63
+
64
+ # pr:wait-mergeable-and-merge -- cascade automation surface (#1369).
65
+ # Wraps scripts/pr_wait_mergeable.py which composes the resilient
66
+ # wait-until-ready monitor (#1368) and the Layer-3 protected-issue
67
+ # link inspector (#701) into a single end-to-end primitive so a swarm
68
+ # monitor can request "wait until this PR is mergeable, then merge it"
69
+ # without hand-rolling the loop. The companion script invokes
70
+ # scripts/pr_check_protected_issues.py (Layer-3 #701) BEFORE the wait
71
+ # loop when --protected is supplied, so a persistent
72
+ # closingIssuesReferences link short-circuits the cascade with exit 1
73
+ # ahead of any gh pr merge call. Cascade automation on the Grok Build
74
+ # hybrid path MUST go through this surface per the AGENTS.md
75
+ # `## Cascade automation surface (#1369)` rule.
76
+ #
77
+ # Per `conventions/task-caching.md` (#574): NO `sources:` / `generates:`
78
+ # because user-facing flags (`--cap-minutes` / `--protected` / `--repo`
79
+ # / `--json`) MUST NOT be silently swallowed by go-task's incremental-
80
+ # build cache.
81
+ #
82
+ # Companion script: scripts/pr_wait_mergeable.py
83
+ # Companion test: tests/cli/test_pr_wait_mergeable.py
84
+ wait-mergeable-and-merge:
85
+ desc: "Wait until PR is mergeable (resilient cascade, #1368) and squash-merge with admin (#1369); Layer-3 protected-issue check (#701) chains before any merge call"
86
+ deps: [":ts:build"]
87
+ dir: '{{.USER_WORKING_DIR}}'
88
+ cmds:
89
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" pr-wait-mergeable {{.CLI_ARGS}}
package/tasks/prd.yml ADDED
@@ -0,0 +1,39 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ # prd:render task.
7
+ #
8
+ # IMPORTANT: explicit absolute paths are passed for BOTH the input spec and
9
+ # the output PRD.md so a stray ``dir:`` or ``CWD`` mis-resolution can never
10
+ # cause the framework's own ``deft/PRD.md`` to be silently overwritten from
11
+ # a consumer project (#539). Standardised on ``node .../bin.js prd-render`` --
12
+ # the prior ``python3`` invocation was inconsistent with every other task and
13
+ # caused sporadic PATH issues on Windows.
14
+
15
+ tasks:
16
+ _ts-build:
17
+ internal: true
18
+ desc: "Build @deftai/cli dist/ before TS-backed render gates run (#1854 s2)."
19
+ dir: '{{.USER_WORKING_DIR}}'
20
+ cmds:
21
+ - pnpm --dir "{{.DEFT_ROOT}}" run build
22
+
23
+ render:
24
+ # Caching: intentionally absent. `prd:render` runs in <30ms and its
25
+ # CLI_ARGS carry recovery flags (e.g. `--force` from the #539
26
+ # refuse-to-overwrite safety check). Declaring `sources:` / `generates:`
27
+ # would cause go-task to short-circuit before `cmds:` runs, dropping
28
+ # CLI_ARGS and silently breaking the #539 recovery path (#573, #574).
29
+ # See deft/conventions/task-caching.md for the full rule.
30
+ desc: Export plan.narratives from specification.vbrief.json to a read-only PRD.md
31
+ summary: |
32
+ Reads specification.vbrief.json and extracts plan.narratives into a
33
+ human-readable PRD.md for stakeholder export. PRD.md is never
34
+ authoritative -- the vBRIEF is the source of truth.
35
+ dir: '{{.USER_WORKING_DIR}}'
36
+ deps:
37
+ - _ts-build
38
+ cmds:
39
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" prd-render --spec "{{.USER_WORKING_DIR}}/vbrief/specification.vbrief.json" --output "{{.USER_WORKING_DIR}}/PRD.md" {{.CLI_ARGS}}
@@ -0,0 +1,27 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ # project:render task.
7
+ #
8
+ # Fixed #539: the task previously used ``{{.ROOT_DIR}}`` which is deft's
9
+ # own repo root when invoked via ``includes:`` -- consumers got their data
10
+ # scanned from ``deft/vbrief/``. Switched to ``{{.USER_WORKING_DIR}}`` to
11
+ # match the convention used by roadmap:render / spec:render / migrate:vbrief.
12
+
13
+ tasks:
14
+ _ts-build:
15
+ internal: true
16
+ desc: "Build @deftai/cli dist/ before TS-backed render gates run (#1854 s2)."
17
+ dir: '{{.USER_WORKING_DIR}}'
18
+ cmds:
19
+ - pnpm --dir "{{.DEFT_ROOT}}" run build
20
+
21
+ render:
22
+ desc: Regenerate PROJECT-DEFINITION.vbrief.json items registry from lifecycle folders
23
+ dir: '{{.USER_WORKING_DIR}}'
24
+ deps:
25
+ - _ts-build
26
+ cmds:
27
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" project-render "{{.USER_WORKING_DIR}}/vbrief"
@@ -0,0 +1,32 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ # reconcile issues task.
7
+ #
8
+ # IMPORTANT: runs from the consumer project root (``dir:
9
+ # '{{.USER_WORKING_DIR}}'``) so ``gh`` and ``git`` commands executed by
10
+ # ``scripts/reconcile_issues.py`` resolve against the CONSUMER's remote,
11
+ # not deftai/directive (#538). Script path dispatched via {{.DEFT_ROOT}}
12
+ # (defined locally in this file's `vars:` block via
13
+ # ``{{joinPath .TASKFILE_DIR ".."}}`` -- see ../Taskfile.yml for why
14
+ # root-level definition is avoided) to keep the path traversal-free and
15
+ # avoid the {{.TASKFILE_DIR}}/.. form that breaks on Windows under
16
+ # `uv --project "{{.DEFT_ROOT}}" run python` (#566).
17
+
18
+ tasks:
19
+ _ensure-ts:
20
+ internal: true
21
+ desc: "Build the TS engine before reconcile gates (#1828 s4)"
22
+ dir: '{{.USER_WORKING_DIR}}'
23
+ cmds:
24
+ - pnpm --dir "{{.DEFT_ROOT}}" run build
25
+
26
+ issues:
27
+ desc: "Reconcile GitHub issues against vBRIEF references -- report linked, unlinked, and resolved"
28
+ dir: '{{.USER_WORKING_DIR}}'
29
+ deps:
30
+ - _ensure-ts
31
+ cmds:
32
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" reconcile-issues --vbrief-dir "{{.USER_WORKING_DIR}}/vbrief" --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
@@ -0,0 +1,56 @@
1
+ version: '3'
2
+
3
+ # tasks/relocate.yml -- wipe-and-reinstall relocator surface (#992 PR2).
4
+ #
5
+ # Wires `task relocate` to scripts/relocate.py with full {{.CLI_ARGS}}
6
+ # pass-through so operators can compose flags as documented in the script
7
+ # docstring (--project-root / --framework-source / --force / --confirm /
8
+ # --no-confirm / --dry-run / --rollback / --snapshot / --no-snapshot /
9
+ # --json / --quiet).
10
+ #
11
+ # Per `conventions/task-caching.md` (#574): NO `sources:` / `generates:`
12
+ # declarations because user-facing recovery flags (`--force`, `--confirm`,
13
+ # `--rollback`, `--dry-run`) flow via {{.CLI_ARGS}} -- a go-task cache
14
+ # short-circuit would silently drop the recovery flag and leave the
15
+ # operator following the docs against an exit-0 no-op (the same hazard
16
+ # `task prd:render -- --force` hit at #574).
17
+ #
18
+ # Path resolution uses the same {{.TASKFILE_DIR}} / joinPath idiom every
19
+ # other fragment uses (#566) so the dispatch resolves correctly under
20
+ # Windows / macOS / Linux. The dispatched script lives at
21
+ # {{.DEFT_ROOT}}/scripts/relocate.py with helper modules at
22
+ # {{.DEFT_ROOT}}/scripts/_relocate_states.py and
23
+ # {{.DEFT_ROOT}}/scripts/_relocate_snapshot.py.
24
+ #
25
+ # Usage notes for operators:
26
+ #
27
+ # - Bare invocation against a project root that needs relocating prompts
28
+ # `[y/N]` on stdin (auto-prompt never auto-wipe per the active vBRIEF).
29
+ # - For scripted use, pass `--confirm` to skip the prompt (or
30
+ # `--no-snapshot` for hermetic test fixtures).
31
+ # - For consumer projects: the canonical entry point is the webinstaller
32
+ # bootstrap (`upgrade.sh` / `upgrade.ps1` in the separate `webinstaller`
33
+ # repo) which fetches a fresh framework copy to a temp dir and runs the
34
+ # relocator from THAT copy -- the in-place framework about to be wiped
35
+ # never executes its own wipe.
36
+ # - `task relocate -- --rollback` extracts the most recent snapshot back
37
+ # into project root.
38
+ #
39
+ # Companion script: scripts/relocate.py
40
+ # Companion tests: tests/relocate/test_state_matrix.py
41
+ # tests/relocate/test_preflight.py
42
+ # Refs: #992 (parent issue), #11 (.deft/core/ origin),
43
+ # #768 (managed-section v2 contract), #794 (_wrap_legacy_in_markers),
44
+ # #884 (consent-gate convention).
45
+
46
+ vars:
47
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
48
+
49
+ tasks:
50
+ relocate:
51
+ desc: "Wipe-and-reinstall relocator (#992 PR2) -- task relocate [-- --confirm | --dry-run | --force | --rollback | --json | --quiet]"
52
+ dir: '{{.USER_WORKING_DIR}}'
53
+ env:
54
+ PYTHONUTF8: "1"
55
+ cmds:
56
+ - uv --project "{{.DEFT_ROOT}}" run python "{{.DEFT_ROOT}}/scripts/relocate.py" {{.CLI_ARGS}}
@@ -0,0 +1,28 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ # roadmap tasks -- consumer-safe CWD + script resolution (#539, #540, #566).
7
+ # Scripts are dispatched via {{.DEFT_ROOT}} (defined locally in this file's
8
+ # `vars:` block via ``{{joinPath .TASKFILE_DIR ".."}}`` -- see
9
+ # ../Taskfile.yml for why root-level definition is avoided) to keep the
10
+ # path traversal-free and avoid the {{.TASKFILE_DIR}}/.. form that breaks
11
+ # on Windows under `uv --project "{{.DEFT_ROOT}}" run python` (#566).
12
+
13
+ tasks:
14
+ render:
15
+ desc: Render ROADMAP.md from vbrief/pending/ (Active) and vbrief/completed/ (Completed) lifecycle folders
16
+ dir: '{{.USER_WORKING_DIR}}'
17
+ deps:
18
+ - task: :ts:build
19
+ cmds:
20
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" roadmap-render "{{.USER_WORKING_DIR}}/vbrief/pending" "{{.USER_WORKING_DIR}}/ROADMAP.md"
21
+
22
+ check:
23
+ desc: Verify ROADMAP.md matches what roadmap:render would produce
24
+ dir: '{{.USER_WORKING_DIR}}'
25
+ deps:
26
+ - task: :ts:build
27
+ cmds:
28
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" roadmap-render "{{.USER_WORKING_DIR}}/vbrief/pending" "{{.USER_WORKING_DIR}}/ROADMAP.md" --check
package/tasks/scm.yml ADDED
@@ -0,0 +1,126 @@
1
+ version: '3'
2
+
3
+ # ---------------------------------------------------------------------------
4
+ # scm.yml -- STUB for #883 v1 cache layer (Story 1) + #976 REST opt-in + #1555 safe body posting.
5
+ #
6
+ # DO NOT EXTEND except for the narrow #1555 body-posting carve-out below.
7
+ #
8
+ # The full scm:* task namespace lives at #881; this file is replaced wholesale
9
+ # when #881 lands. The stub exposes the minimum surface the #883 v1 cache
10
+ # consumer (Story 2 cache:fetch-all) needs:
11
+ #
12
+ # - scm:issue:list (thin wrapper over `ghx|gh issue list`)
13
+ # - scm:issue:view (thin wrapper over `ghx|gh issue view`)
14
+ # - scm:issue:close (thin wrapper over `ghx|gh issue close`)
15
+ # - scm:issue:edit (thin wrapper over `ghx|gh issue edit`)
16
+ # - scm:body:* (#1555 safe Markdown body posting via github-body TS CLI)
17
+ #
18
+ # Each command is a thin pass-through to `ghx <verb>` (when ghx is on PATH)
19
+ # or `gh <verb>` (fallback). Output JSON via the consumer-supplied --json
20
+ # flag. The JSON-shape contract Story 2 depends on is pinned by the
21
+ # tests/test_scm_contract.py contract test against tests/fixtures/scm_issue_view.json.
22
+ #
23
+ # REST opt-in (#976): callers may pass `--rest` to scm:issue:view /
24
+ # scm:issue:list to route the read through scripts/gh_rest.py REST
25
+ # helpers (rest_issue_view / rest_issue_list) instead of forwarding to
26
+ # `ghx|gh issue view|list`. This sidesteps the GraphQL bucket entirely so
27
+ # a depleted graphql.remaining no longer fails read-only smoke / cache
28
+ # flows. The REST shape differs from the gh --json GraphQL shape (REST
29
+ # emits user/created_at/lowercase state vs GraphQL author/createdAt/
30
+ # uppercase state); only callers that opt in see the REST shape. Story 2
31
+ # cache:fetch-all keeps the legacy (GraphQL) path until #881. Mutations
32
+ # (close, edit) keep forwarding to gh -- they have non-trivial flag
33
+ # surfaces (--body-file, --add-label, --remove-label, ...) that this
34
+ # stub deliberately does not re-implement; #881 owns the full surface.
35
+ #
36
+ # Forward-compat marker: the ONLY scm:* surface in v1 is the four issue:*
37
+ # commands above plus the #1555 body-posting safety wrapper. PR commands
38
+ # (scm:pr:list/view/merge/close) and any additional scm:* surface are
39
+ # EXPLICITLY deferred to #881; do not add them here. See
40
+ # vbrief/active/2026-05-05-883-story-1-scm-stub.vbrief.json for the full
41
+ # Story 1 scope and vbrief/active/2026-05-05-883-deft-cache-quarantine-v1.vbrief.json
42
+ # for the epic chain context.
43
+ # ---------------------------------------------------------------------------
44
+
45
+ vars:
46
+ # Each included sub-taskfile defines its own DEFT_ROOT mirror so scripts
47
+ # can be dispatched via {{.DEFT_ROOT}}/scripts/<name>.py on every platform
48
+ # (#566). joinPath is evaluated eagerly by go-task templating and yields
49
+ # a native-separator absolute path that uv --project "{{.DEFT_ROOT}}" run python can open on Windows.
50
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
51
+
52
+ # Per `conventions/task-caching.md` (#574): tasks that accept user-facing
53
+ # CLI args via {{.CLI_ARGS}} MUST NOT declare `sources:` / `generates:` --
54
+ # the cached cmds skip would silently discard the recovery flag.
55
+ tasks:
56
+ issue:list:
57
+ desc: "[#883 stub] List issues -- task scm:issue:list -- [--rest] --repo OWNER/NAME --json number,title,state,updatedAt [--state ...] (#976 --rest routes via REST helpers; default forwards to ghx|gh)"
58
+ dir: '{{.USER_WORKING_DIR}}'
59
+ deps:
60
+ - task: :ts:build
61
+ cmds:
62
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scm issue list {{.CLI_ARGS}}
63
+
64
+ issue:view:
65
+ desc: "[#883 stub] View an issue -- task scm:issue:view -- [--rest] <N> --repo OWNER/NAME --json number,title,body,state,author,createdAt,updatedAt,labels,comments (#976 --rest routes via REST helpers and emits REST shape; default forwards to ghx|gh GraphQL shape)"
66
+ dir: '{{.USER_WORKING_DIR}}'
67
+ deps:
68
+ - task: :ts:build
69
+ cmds:
70
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scm issue view {{.CLI_ARGS}}
71
+
72
+ issue:close:
73
+ desc: "[#883 stub] Close an issue -- task scm:issue:close -- <N> --repo OWNER/NAME [--comment ...]"
74
+ dir: '{{.USER_WORKING_DIR}}'
75
+ deps:
76
+ - task: :ts:build
77
+ cmds:
78
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scm issue close {{.CLI_ARGS}}
79
+
80
+ issue:edit:
81
+ desc: "[#883 stub] Edit an issue -- task scm:issue:edit -- <N> --repo OWNER/NAME [--add-label ...] [--body ...]"
82
+ dir: '{{.USER_WORKING_DIR}}'
83
+ deps:
84
+ - task: :ts:build
85
+ cmds:
86
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scm issue edit {{.CLI_ARGS}}
87
+
88
+ body:issue:create:
89
+ desc: "[#1555] Safely create an issue body from --body-file without shell Markdown interpolation"
90
+ dir: '{{.USER_WORKING_DIR}}'
91
+ deps:
92
+ - task: :ts:build
93
+ cmds:
94
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" github-body issue-create {{.CLI_ARGS}}
95
+
96
+ body:issue:edit:
97
+ desc: "[#1555] Safely edit an issue body from --body-file and live gh read-back"
98
+ dir: '{{.USER_WORKING_DIR}}'
99
+ deps:
100
+ - task: :ts:build
101
+ cmds:
102
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" github-body issue-edit {{.CLI_ARGS}}
103
+
104
+ body:comment:create:
105
+ desc: "[#1555] Safely create an issue/PR comment body from --body-file and live gh read-back"
106
+ dir: '{{.USER_WORKING_DIR}}'
107
+ deps:
108
+ - task: :ts:build
109
+ cmds:
110
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" github-body comment-create {{.CLI_ARGS}}
111
+
112
+ body:comment:edit:
113
+ desc: "[#1555] Safely edit an issue comment body from --body-file and live gh read-back"
114
+ dir: '{{.USER_WORKING_DIR}}'
115
+ deps:
116
+ - task: :ts:build
117
+ cmds:
118
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" github-body comment-edit {{.CLI_ARGS}}
119
+
120
+ body:pr:edit:
121
+ desc: "[#1555] Safely edit a PR body from --body-file and live gh read-back"
122
+ dir: '{{.USER_WORKING_DIR}}'
123
+ deps:
124
+ - task: :ts:build
125
+ cmds:
126
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" github-body pr-edit {{.CLI_ARGS}}
@@ -0,0 +1,36 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ # scope:undo fragment (D15 / #1134).
7
+ #
8
+ # Standalone fragment per the post-D12 sub-task convention so the
9
+ # orchestrator's cross-child coordination contract does not collide
10
+ # with edits on tasks/scope.yml. The user-facing alias `task scope:undo`
11
+ # lives in the root Taskfile.yml below; this fragment exposes the inner
12
+ # task name `undo` under the include namespace key `scope-undo`, so the
13
+ # fragment-namespace form `task scope-undo:undo` is also reachable for
14
+ # debugging but is not the documented surface.
15
+ #
16
+ # CLI_ARGS forwarded bare (matches every other scope:* verb -- go-task's
17
+ # shell-escape pipeline misbehaves on Windows when CLI_ARGS is wrapped
18
+ # in double quotes, see #577).
19
+ #
20
+ # `dir: '{{.USER_WORKING_DIR}}'` keeps Python CWD at the consumer project
21
+ # root so `--project-root "{{.USER_WORKING_DIR}}"` resolves correctly
22
+ # (#535 path-resolution invariant).
23
+ #
24
+ # `env: PYTHONUTF8: "1"` is a belt-and-suspenders guard for Windows cp1252
25
+ # default (#540); root Taskfile.yml also sets this.
26
+ #
27
+ # Per `conventions/task-caching.md` (#574) no `sources:` / `generates:`
28
+ # because the verb forwards user-facing flags (`--dry-run` / `--batch-id` /
29
+ # `--decision-id`) via {{.CLI_ARGS}}.
30
+
31
+ tasks:
32
+ undo:
33
+ desc: "Reverse a scope-lifecycle audit entry (#1134). Single: `task scope:undo -- <decision_id>` / `task scope:undo -- --decision-id=<uuid>`. Batch: `task scope:undo -- --batch-id=<uuid>`. Optional `--dry-run`."
34
+ dir: '{{.USER_WORKING_DIR}}'
35
+ cmds:
36
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scope-undo {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
@@ -0,0 +1,141 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ # scope lifecycle tasks.
7
+ #
8
+ # IMPORTANT: every task sets ``dir: '{{.USER_WORKING_DIR}}'`` so the Python
9
+ # script's CWD is the consumer project root, NOT ``deft/``. The script path
10
+ # is resolved via ``{{.DEFT_ROOT}}/scripts/`` (DEFT_ROOT is defined locally
11
+ # in this file's `vars:` block via ``{{joinPath .TASKFILE_DIR ".."}}`` --
12
+ # see ../Taskfile.yml for why root-level definition is avoided) so it
13
+ # still points at ``deft/scripts/scope_lifecycle.py`` after the dir switch.
14
+ # The previous ``{{.TASKFILE_DIR}}/../scripts/`` form broke on Windows
15
+ # under `uv --project "{{.DEFT_ROOT}}" run python` (#566) because mixed-separator traversal
16
+ # normalizes incorrectly and drops the deft/ prefix.
17
+ #
18
+ # CLI_ARGS: passed to the script raw / unquoted. go-task shell-escapes
19
+ # CLI_ARGS with single quotes on its own, so wrapping the interpolation
20
+ # in Taskfile-level double quotes produces ``"'path'"`` at dispatch time
21
+ # on Windows (pwsh/cmd preserve nested quotes verbatim), and Python's
22
+ # argv receives a literal single-quote-prefixed filename that fails to
23
+ # open (#577). All seven scope:* commands therefore forward
24
+ # ``{{.CLI_ARGS}}`` bare -- matching migrate.yml / prd.yml / issue.yml /
25
+ # reconcile.yml. ``scope_lifecycle.py`` handles both absolute and
26
+ # relative values via ``_resolve_file_path`` + ``resolve_project_root``
27
+ # -- the script owns path resolution, the task just forwards
28
+ # ``--project-root`` so detection never silently falls back to deft's
29
+ # own tree (#535). Relative paths resolve against the consumer root
30
+ # thanks to ``--project-root``; absolute paths are used as-is.
31
+ #
32
+ # ``env: PYTHONUTF8: "1"`` is set per-task as a belt-and-suspenders guard
33
+ # for Windows (cp1252 default crashes on -- / -> / x / !); the top-level
34
+ # Taskfile.yml also sets this (#540).
35
+
36
+ tasks:
37
+ _ensure-ts:
38
+ internal: true
39
+ desc: "Build the TS engine before lifecycle gates (#1828 s4)"
40
+ dir: '{{.USER_WORKING_DIR}}'
41
+ cmds:
42
+ - pnpm --dir "{{.DEFT_ROOT}}" run build
43
+
44
+ promote:
45
+ desc: "Promote a vBRIEF scope: proposed/ -> pending/ (status: pending)"
46
+ dir: '{{.USER_WORKING_DIR}}'
47
+ deps:
48
+ - _ensure-ts
49
+ cmds:
50
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scope-lifecycle promote {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
51
+
52
+ activate:
53
+ desc: "Activate a vBRIEF scope: pending/ -> active/ (status: running)"
54
+ dir: '{{.USER_WORKING_DIR}}'
55
+ deps:
56
+ - _ensure-ts
57
+ cmds:
58
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scope-lifecycle activate {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
59
+
60
+ complete:
61
+ desc: "Complete a vBRIEF scope: active/ -> completed/ (status: completed)"
62
+ dir: '{{.USER_WORKING_DIR}}'
63
+ deps:
64
+ - _ensure-ts
65
+ cmds:
66
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scope-lifecycle complete {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
67
+
68
+ fail:
69
+ # Terminal ``failed`` transition (#614). Parallels ``scope:complete``
70
+ # (same source + destination folders) and differs only in the
71
+ # resulting ``plan.status`` (``failed`` vs ``completed``). Semantic
72
+ # contract: use ``scope:fail`` when a scope was attempted but could
73
+ # not be completed (external blocker, infeasibility discovered
74
+ # mid-flight, deadline hit, agent exhausted retries) and should NOT
75
+ # be cancelled. ``scope:cancel`` remains the right call when the
76
+ # scope is no longer wanted / superseded / obsolete. The canonical
77
+ # v0.6 Status enum includes ``failed`` (see
78
+ # vbrief/schemas/vbrief-core.schema.json).
79
+ desc: "Fail a vBRIEF scope: active/ -> completed/ (status: failed)"
80
+ dir: '{{.USER_WORKING_DIR}}'
81
+ deps:
82
+ - _ensure-ts
83
+ cmds:
84
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scope-lifecycle fail {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
85
+
86
+ cancel:
87
+ desc: "Cancel a vBRIEF scope: any folder -> cancelled/ (status: cancelled)"
88
+ dir: '{{.USER_WORKING_DIR}}'
89
+ deps:
90
+ - _ensure-ts
91
+ cmds:
92
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scope-lifecycle cancel {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
93
+
94
+ restore:
95
+ desc: "Restore a cancelled vBRIEF scope: cancelled/ -> proposed/ (status: proposed)"
96
+ dir: '{{.USER_WORKING_DIR}}'
97
+ deps:
98
+ - _ensure-ts
99
+ cmds:
100
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scope-lifecycle restore {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
101
+
102
+ block:
103
+ desc: "Block a vBRIEF scope: stays in active/ (status: blocked)"
104
+ dir: '{{.USER_WORKING_DIR}}'
105
+ deps:
106
+ - _ensure-ts
107
+ cmds:
108
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scope-lifecycle block {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
109
+
110
+ unblock:
111
+ desc: "Unblock a vBRIEF scope: stays in active/ (status: running)"
112
+ dir: '{{.USER_WORKING_DIR}}'
113
+ deps:
114
+ - _ensure-ts
115
+ cmds:
116
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scope-lifecycle unblock {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
117
+
118
+ decompose:
119
+ desc: "Apply/check an approved epic/phase -> story decomposition draft"
120
+ dir: '{{.USER_WORKING_DIR}}'
121
+ deps:
122
+ - _ensure-ts
123
+ cmds:
124
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scope-decompose {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
125
+
126
+ # Operator-driven demote (D1 / #1121). Moves a vBRIEF scope from
127
+ # vbrief/pending/ back to vbrief/proposed/ and appends a structured
128
+ # audit entry (including a `demote_meta` block) to
129
+ # vbrief/.eval/scope-lifecycle.jsonl. Two modes are supported:
130
+ # * Single: `task scope:demote -- path/to/foo.vbrief.json [--reason TEXT]`
131
+ # * Batch: `task scope:demote -- --batch [--older-than-days 45]`
132
+ # The 30%-threshold falsification gate from D17 was explicitly dropped
133
+ # per Current Shape Decision 2 on #1121; lightweight metrics over the
134
+ # audit log live separately at #1180.
135
+ demote:
136
+ desc: "Demote a vBRIEF scope: pending/ -> proposed/ (#1121). Single-file or --batch --older-than-days N (default 45)."
137
+ dir: '{{.USER_WORKING_DIR}}'
138
+ deps:
139
+ - _ensure-ts
140
+ cmds:
141
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" scope-demote {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"