@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,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}}"
@@ -0,0 +1,19 @@
1
+ version: '3'
2
+
3
+ # tasks/session.yml -- fail-closed session ritual state surface (#1348).
4
+ #
5
+ # Per conventions/task-caching.md: no sources/generates because the task
6
+ # forwards user-facing flags (--defer, --json, --no-history) via CLI_ARGS.
7
+
8
+ vars:
9
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
10
+
11
+ tasks:
12
+ start:
13
+ desc: "Run quick-tier session-start ritual and write .deft/ritual-state.json (#1348). Flags: --defer step=reason / --json"
14
+ dir: '{{.USER_WORKING_DIR}}'
15
+ deps: [":ts:build"]
16
+ env:
17
+ PYTHONUTF8: "1"
18
+ cmds:
19
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" session:start --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
@@ -0,0 +1,37 @@
1
+ version: '3'
2
+
3
+ # Windows toolchain bootstrap fragment (#902).
4
+ #
5
+ # Wired into the parent Taskfile.yml `includes:` block under namespace key
6
+ # `setup`, so the inner task `toolchain` is reachable as `task setup:toolchain`.
7
+ # This fragment is independent of the root-level `setup` task in
8
+ # Taskfile.yml (which configures git hooks via core.hooksPath); the two
9
+ # coexist because go-task treats `setup` and `setup:toolchain` as distinct
10
+ # task names.
11
+ #
12
+ # Companion script: scripts/setup_windows.ps1
13
+ # Companion test: tests/scripts/test_setup_windows.ps1
14
+ # Issue: #902
15
+ #
16
+ # Per `conventions/task-caching.md` (#574): NO `sources:` / `generates:`
17
+ # declarations on these tasks because user-facing behaviour is determined at
18
+ # runtime by host platform detection and the script's idempotent probe-
19
+ # before-install logic, not by file mtimes.
20
+
21
+ vars:
22
+ # Resolve the deft framework root from this fragment's directory. The
23
+ # joinPath idiom mirrors the convention documented in the root Taskfile.yml
24
+ # header (#566): {{.TASKFILE_DIR}}/.. evaluated by go-task's eager
25
+ # templating yields a native-separator absolute path that pwsh / Bash can
26
+ # open on Windows / macOS / Linux.
27
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
28
+
29
+ tasks:
30
+ toolchain:
31
+ desc: "Bootstrap the Windows maintainer toolchain (Go, Python, uv, Task, gh) via winget. Windows-only -- no-op on macOS / Linux. -- task setup:toolchain"
32
+ dir: '{{.USER_WORKING_DIR}}'
33
+ cmds:
34
+ - cmd: pwsh -NoProfile -ExecutionPolicy Bypass -File "{{.DEFT_ROOT}}/scripts/setup_windows.ps1"
35
+ platforms: [windows]
36
+ - cmd: echo "setup:toolchain currently supports Windows only. See CONTRIBUTING.md for macOS / Linux setup."
37
+ platforms: [linux, darwin]
@@ -0,0 +1,69 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ # slice:* fragment (N7 / #1147).
7
+ #
8
+ # Exposes the canonical `task slice:record-existing` backfill verb plus
9
+ # the companion `task slice:list` read surface. Both delegate to
10
+ # `scripts/slice_record_existing.py`. Inner tasks below are
11
+ # `internal: true` so the fragment-namespace forms (`slice:record-existing`
12
+ # under the include key `slice`) are surfaced as user-facing aliases in
13
+ # the root `Taskfile.yml` (mirrors the established triage:* / scope:*
14
+ # pattern -- see Taskfile.yml header comment for why aliases live at the
15
+ # root rather than here).
16
+ #
17
+ # CLI_ARGS is forwarded bare -- go-task's shell-escape pipeline misbehaves
18
+ # on Windows when CLI_ARGS is wrapped in double quotes (#577). The driver
19
+ # script owns argv parsing (including the dynamic `--wave-N=<csv>` flag
20
+ # shape that argparse cannot natively model).
21
+ #
22
+ # Windows quoting limitation (#1231 / SLizard P2): because CLI_ARGS is
23
+ # substituted bare, arguments containing spaces (e.g. `--notes "A note
24
+ # with spaces"`) may be re-split by the shell before `argparse` sees
25
+ # them. The operator-facing workaround is to either avoid spaces in flag
26
+ # values (use a single token like `--notes=backfill-after-N7`) or to
27
+ # write the rationale to a file and embed a pointer. The fully-quoted
28
+ # `{{.CLI_ARGS | shellQuote}}` form misbehaves on Windows go-task per
29
+ # #577; switching to a temp-file dispatch is the long-term fix and is
30
+ # tracked under #1231. The same caveat applies to every other verb that
31
+ # forwards `{{.CLI_ARGS}}` bare under `tasks/` (audit list: every fragment
32
+ # in this directory does -- the pattern is repo-wide).
33
+ #
34
+ # `dir: '{{.USER_WORKING_DIR}}'` keeps Python CWD at the consumer project
35
+ # root so `--project-root` / `--repo` resolution lands in the consumer
36
+ # tree, not in deft's own checkout (#535 path-resolution invariant).
37
+ #
38
+ # `env: PYTHONUTF8: "1"` is a belt-and-suspenders guard for Windows
39
+ # cp1252 default (#540); root Taskfile.yml also sets this.
40
+ #
41
+ # Per `conventions/task-caching.md` (#574) no `sources:` / `generates:`
42
+ # because the verbs forward user-facing flags (`--dry-run`, `--force`,
43
+ # `--wave-N=<csv>`, `--actor`, etc.) via {{.CLI_ARGS}}.
44
+
45
+ tasks:
46
+ _ensure-ts:
47
+ internal: true
48
+ desc: "Build the TS engine before slice gates (#1828 s4)"
49
+ dir: '{{.USER_WORKING_DIR}}'
50
+ cmds:
51
+ - pnpm --dir "{{.DEFT_ROOT}}" run build
52
+
53
+ record-existing:
54
+ desc: "Retrofit a slices.jsonl entry for a hand-filed cohort (#1147 / N7). Windows note (#1231): CLI_ARGS is forwarded bare to argparse so values containing spaces (e.g. --notes \"A note with spaces\") may be re-split by the shell -- prefer hyphenated single-token values like --notes=backfill-after-N7. -- task slice:record-existing -- --umbrella=N --children=A,B,C [--wave-1=A,B] [--wave-2=C] [--actor=manual:operator] [--expected-close-signal=all-children-merged] [--sliced-at=ISO] [--notes=TEXT] [--dry-run] [--force] [--skip-validation] [--repo OWNER/NAME]"
55
+ internal: true
56
+ dir: '{{.USER_WORKING_DIR}}'
57
+ deps:
58
+ - _ensure-ts
59
+ cmds:
60
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" slice record-existing {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
61
+
62
+ list:
63
+ desc: "List recorded slices in vbrief/.eval/slices.jsonl (umbrella + child count + actor + sliced_at). -- task slice:list [-- --json]"
64
+ internal: true
65
+ dir: '{{.USER_WORKING_DIR}}'
66
+ deps:
67
+ - _ensure-ts
68
+ cmds:
69
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" slice list {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
package/tasks/spec.yml ADDED
@@ -0,0 +1,41 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ # spec 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
+ _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
+ validate:
22
+ desc: Validate that vbrief/specification.vbrief.json exists and is well-formed JSON
23
+ dir: '{{.USER_WORKING_DIR}}'
24
+ deps:
25
+ - _ts-build
26
+ cmds:
27
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" spec-validate "{{.USER_WORKING_DIR}}/vbrief/specification.vbrief.json"
28
+
29
+ render:
30
+ desc: Render vbrief/specification.vbrief.json to SPECIFICATION.md
31
+ dir: '{{.USER_WORKING_DIR}}'
32
+ deps:
33
+ - _ts-build
34
+ cmds:
35
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" spec-render "{{.USER_WORKING_DIR}}/vbrief/specification.vbrief.json" "{{.USER_WORKING_DIR}}/SPECIFICATION.md"
36
+
37
+ pipeline:
38
+ desc: Run full spec pipeline (validate then render)
39
+ cmds:
40
+ - task: validate
41
+ - task: render
@@ -0,0 +1,85 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ tasks:
7
+ readiness:
8
+ desc: "Report whether story vBRIEFs are ready for concurrent swarm allocation"
9
+ dir: '{{.USER_WORKING_DIR}}'
10
+ deps: [":ts:build"]
11
+ env:
12
+ PYTHONUTF8: "1"
13
+ cmds:
14
+ # Keep CLI_ARGS bare; go-task shell-escapes pass-through args and quoting breaks globs/multi-arg calls.
15
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" swarm-readiness {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
16
+
17
+ # swarm:launch -- deterministic headless launch engine (#1387). Turns an
18
+ # operator-supplied, pre-approved cohort into a ready-to-spawn launch
19
+ # manifest: resolves --stories (issue numbers / story ids / paths) against
20
+ # vbrief/active, enforces the #810 preflight and swarm:readiness gates per
21
+ # story (exiting non-zero and naming the FIRST failing story), and emits
22
+ # the C2 launch-manifest JSON carrying the #1378 allocation-context token
23
+ # for each agent. Bare {{.CLI_ARGS}} per the readiness/verify-review-clean
24
+ # convention -- go-task already shell-escapes pass-through args, so wrapping
25
+ # in double quotes breaks multi-arg / path forwarding (see tasks/vbrief.yml
26
+ # preflight for the full rationale and tests/content/test_taskfile_cli_args.py).
27
+ #
28
+ # Companion script: scripts/swarm_launch.py
29
+ # Companion test: tests/cli/test_swarm_launch.py
30
+ launch:
31
+ desc: "Resolve a pre-approved cohort, enforce the #810 + swarm:readiness gates and sub-agent backend policy per story, and emit the launch-manifest JSON (#1387, #1531e)"
32
+ deps: [":ts:build"]
33
+ dir: '{{.USER_WORKING_DIR}}'
34
+ cmds:
35
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" swarm-launch {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
36
+
37
+ # swarm:routing-set -- record an operator coding sub-agent model decision
38
+ # (#1739) into the gitignored, per-machine .deft/routing.local.json keyed by
39
+ # (dispatch_provider, worker_role). Supersedes the swarmSubagentBackend enum
40
+ # (#1531 / #1735): the resolved model is threaded into the launch manifest
41
+ # (resolved_model / model_source) so dispatch can actually honor it.
42
+ routing-set:
43
+ desc: "Record an operator coding sub-agent model decision (#1739): --role <role> (--model <slug> | --harness-default) [--provider <p>]. Writes the gitignored, per-machine .deft/routing.local.json."
44
+ deps: [":ts:build"]
45
+ dir: '{{.USER_WORKING_DIR}}'
46
+ cmds:
47
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" swarm-routing-set {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
48
+
49
+ # swarm:verify-review-clean -- cohort-level CLEAN verification gate (#1364).
50
+ # Mandate the monitor invokes this after Phase 6 pollers report and BEFORE
51
+ # the Phase 5 -> 6 merge discussion. Re-uses the Greptile rolling-summary
52
+ # parser from scripts/pr_merge_readiness.py so the per-PR merge gate and
53
+ # the cohort gate stay in lockstep -- a parser fix lands in both surfaces
54
+ # at once. The companion script writes its own diagnostics; this Taskfile
55
+ # target just forwards CLI_ARGS bare per the established convention.
56
+ #
57
+ # Companion script: scripts/swarm_verify_review_clean.py
58
+ # Companion test: tests/cli/test_swarm_verify_review_clean.py
59
+ # Skill citation: skills/deft-directive-swarm/SKILL.md Phase 5 Exit Condition + Phase 5 -> 6 gate
60
+ verify-review-clean:
61
+ desc: "Verify EVERY PR in a swarm cohort is CLEAN on current HEAD (confidence > 3, no P0/P1, not errored) before raising the Phase 5 -> 6 merge gate (#1364)"
62
+ deps: [":ts:build"]
63
+ dir: '{{.USER_WORKING_DIR}}'
64
+ cmds:
65
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" swarm-verify-review-clean {{.CLI_ARGS}}
66
+
67
+ # swarm:complete-cohort -- deterministic cohort completion sweep (#1487).
68
+ # The REQUIRED Phase 6 step that moves a finished cohort's story vBRIEFs
69
+ # active/ -> completed/ and completes the decompose-created epic parents
70
+ # once all their children are settled. Routes every move through
71
+ # scripts/scope_lifecycle.py so the #1485 (child-move) and #1487 (parent-
72
+ # move) reference maintenance keeps `task vbrief:validate` green with no
73
+ # manual repair. Bare {{.CLI_ARGS}} per the readiness / verify-review-clean
74
+ # convention -- go-task already shell-escapes pass-through args, so wrapping
75
+ # in double quotes breaks multi-arg / glob forwarding.
76
+ #
77
+ # Companion script: scripts/swarm_complete_cohort.py
78
+ # Companion test: tests/cli/test_swarm_complete_cohort.py
79
+ # Skill citation: skills/deft-directive-swarm/SKILL.md Phase 6 cohort completion sweep
80
+ complete-cohort:
81
+ desc: "Sweep a finished swarm cohort's stories active/ -> completed/ and complete their epic parents, keeping vbrief:validate green (#1487)"
82
+ deps: [":ts:build"]
83
+ dir: '{{.USER_WORKING_DIR}}'
84
+ cmds:
85
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" swarm-complete-cohort {{.CLI_ARGS}} --project-root "{{.USER_WORKING_DIR}}"
@@ -0,0 +1,13 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ tasks:
7
+ check:
8
+ desc: Verify required toolchain is installed (go, uv, git, gh, node, pnpm)
9
+ deps: [":ts:build"]
10
+ env:
11
+ PYTHONUTF8: "1"
12
+ cmds:
13
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" toolchain:check
@@ -0,0 +1,94 @@
1
+ version: '3'
2
+
3
+ # tasks/triage-actions.yml -- per-issue triage commands (#845 Story 3).
4
+ #
5
+ # Wired into the parent Taskfile.yml `includes:` block under namespace key
6
+ # `triage-actions` (#845 Story 6). Inner task names below dropped the
7
+ # `triage:` prefix in #913 -- the prior names produced a doubled prefix
8
+ # (`triage-actions:triage:accept`) under go-task's include-namespace
9
+ # concatenation. Combined with `internal: true` the fragment-namespace
10
+ # forms (`triage-actions:accept` / `triage-actions:reject` / ...) are
11
+ # hidden from `task -l`; the documented `task triage:accept` / `triage:reject`
12
+ # / `triage:defer` / `triage:needs-ac` / `triage:mark-duplicate` /
13
+ # `triage:status` / `triage:reset` / `triage:history` surface lives as
14
+ # root-level alias tasks in Taskfile.yml that delegate here.
15
+ #
16
+ # Per `conventions/task-caching.md`: NO `sources:` / `generates:` because every
17
+ # target accepts user-facing flags via `{{.CLI_ARGS}}` (--issue, --repo,
18
+ # --reason, --of, --comment, --actor) -- the cached `cmds:` skip would
19
+ # silently swallow recovery flags. Same rationale that gated `task release`
20
+ # (#74), `task pr:check-protected-issues` (#702), and `task verify:encoding`
21
+ # (#798).
22
+ #
23
+ # Companion script: scripts/triage_actions.py
24
+ # Companion tests: tests/test_triage_actions.py
25
+ # Upstream contracts (frozen): scripts/candidates_log.py (#845 Story 2 audit log),
26
+ # scripts/cache.py (#883 Story 2 unified cache).
27
+
28
+ vars:
29
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
30
+
31
+ tasks:
32
+ accept:
33
+ desc: "Accept an issue for triage. Records an audit entry. (#845 Story 3)"
34
+ internal: true
35
+ deps: [":ts:build"]
36
+ dir: '{{.USER_WORKING_DIR}}'
37
+ cmds:
38
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-actions accept {{.CLI_ARGS}}
39
+
40
+ reject:
41
+ desc: "Reject an issue. Closes upstream via gh + applies triage-rejected label; rolls audit back on gh failure. (#845 Story 3)"
42
+ internal: true
43
+ deps: [":ts:build"]
44
+ dir: '{{.USER_WORKING_DIR}}'
45
+ cmds:
46
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-actions reject {{.CLI_ARGS}}
47
+
48
+ defer:
49
+ desc: "Defer an issue. Records an audit entry. (#845 Story 3)"
50
+ internal: true
51
+ deps: [":ts:build"]
52
+ dir: '{{.USER_WORKING_DIR}}'
53
+ cmds:
54
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-actions defer {{.CLI_ARGS}}
55
+
56
+ needs-ac:
57
+ desc: "Mark an issue as needing acceptance criteria + post AC-request comment upstream. (#845 Story 3)"
58
+ internal: true
59
+ deps: [":ts:build"]
60
+ dir: '{{.USER_WORKING_DIR}}'
61
+ cmds:
62
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-actions needs-ac {{.CLI_ARGS}}
63
+
64
+ mark-duplicate:
65
+ desc: "Link an issue as a duplicate of another (validated against Story 1 cache). (#845 Story 3)"
66
+ internal: true
67
+ deps: [":ts:build"]
68
+ dir: '{{.USER_WORKING_DIR}}'
69
+ cmds:
70
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-actions mark-duplicate {{.CLI_ARGS}}
71
+
72
+ status:
73
+ desc: "Print the latest triage decision for an issue. Read-only. (#845 Story 3)"
74
+ internal: true
75
+ deps: [":ts:build"]
76
+ dir: '{{.USER_WORKING_DIR}}'
77
+ cmds:
78
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-actions status {{.CLI_ARGS}}
79
+
80
+ reset:
81
+ desc: "Reset an issue's triage state. Appends a reset audit entry referencing prior; does NOT delete history. (#845 Story 3)"
82
+ internal: true
83
+ deps: [":ts:build"]
84
+ dir: '{{.USER_WORKING_DIR}}'
85
+ cmds:
86
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-actions reset {{.CLI_ARGS}}
87
+
88
+ history:
89
+ desc: "Print the full triage timeline for an issue, ordered by timestamp. Read-only. (#845 Story 3)"
90
+ internal: true
91
+ deps: [":ts:build"]
92
+ dir: '{{.USER_WORKING_DIR}}'
93
+ cmds:
94
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-actions history {{.CLI_ARGS}}
@@ -0,0 +1,43 @@
1
+ version: '3'
2
+
3
+ # Triage v1 bootstrap fragment (#845 Story 6).
4
+ #
5
+ # Standalone fragment: this file is wired into the parent Taskfile.yml via the
6
+ # `includes:` block (see Taskfile.yml `## triage v1 fragment includes` comment).
7
+ # When included under namespace key `triage-bootstrap`, the inner task
8
+ # `bootstrap` is reachable as `task triage-bootstrap:bootstrap`. The parent
9
+ # Taskfile.yml additionally exposes the user-facing alias `task triage:bootstrap`
10
+ # which delegates here.
11
+ #
12
+ # Companion files in the four-fragment cluster (#845):
13
+ # tasks/triage-cache.yml (Story 1 -- cache populate + show)
14
+ # tasks/triage-actions.yml (Story 3 -- accept/reject/defer/...)
15
+ # tasks/triage-bulk.yml (Story 4 -- bulk ops + freshness)
16
+ # tasks/triage-bootstrap.yml (Story 6 -- this file)
17
+ #
18
+ # Companion script: scripts/triage_bootstrap.py
19
+ # Companion test: tests/test_triage_bootstrap.py
20
+ #
21
+ # Per `conventions/task-caching.md` (#574): NO `sources:` / `generates:`
22
+ # declarations on this task because user-facing recovery flags
23
+ # (`--repo`, `--fetch-timeout-s`, `--json`, `--quiet`) are forwarded via
24
+ # {{.CLI_ARGS}} and go-task's incremental-build cache layer would silently
25
+ # swallow them. The Story 3 rebind dropped the v0.25.x `--skip-gitcrawl`
26
+ # install path entirely (#951): the script's argparse never accepted it.
27
+
28
+ vars:
29
+ # Resolve the deft framework root from this fragment's directory. The
30
+ # joinPath idiom mirrors the existing convention documented in the root
31
+ # Taskfile.yml header (#566): `{{.TASKFILE_DIR}}/..` evaluated by go-task's
32
+ # eager templating yields a native-separator absolute path that
33
+ # `node .../bin.js` can open on Windows / macOS / Linux.
34
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
35
+
36
+ tasks:
37
+ bootstrap:
38
+ desc: "Idempotent triage v1 installer (#845): populate cache, backfill audit log, ensure gitignore for .deft-cache/ and vbrief/.eval/. Re-runnable; per-step progress on stderr; cache:fetch-all wall-clock cap (#952). -- task triage:bootstrap [-- --repo OWNER/NAME] [--limit N] [--state open|closed|all] [--fetch-timeout-s N] [--quiet] [--json]"
39
+ internal: true
40
+ deps: [":ts:build"]
41
+ dir: '{{.USER_WORKING_DIR}}'
42
+ cmds:
43
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-bootstrap --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
@@ -0,0 +1,75 @@
1
+ version: '3'
2
+
3
+ # tasks/triage-bulk.yml -- Story 4 of #845 + #915 cache-walk re-enable.
4
+ #
5
+ # Wired into the parent ../Taskfile.yml `includes:` block under namespace
6
+ # key `triage-bulk` (#845 Story 6). The user-facing `task triage:bulk-accept`
7
+ # / `triage:bulk-reject` / `triage:bulk-defer` / `triage:bulk-needs-ac` /
8
+ # `triage:refresh-active` surface lives as root-level alias tasks in
9
+ # Taskfile.yml that delegate here (#913); inner tasks below are
10
+ # `internal: true` so the fragment-namespace forms (`triage-bulk:bulk-*`)
11
+ # are hidden from `task -l`.
12
+ #
13
+ # The disable-gate `cmds:` blocks introduced by PR #916 (#915 hot-fix) were
14
+ # REVERSED once scripts/triage_bulk.py was rewritten to walk the local
15
+ # cache instead of live `gh issue list`. As of #883 Story 3 the cache walk
16
+ # consumes the unified `cache:get` surface
17
+ # (`.deft-cache/github-issue/<owner>/<repo>/<N>/`); the four `bulk-*`
18
+ # targets continue to invoke triage_bulk.py directly. The cache-empty
19
+ # hard-fail (exit 2) and Tier-2 audit-log short-circuit are enforced
20
+ # inside triage_bulk.py itself (#915 fix).
21
+ #
22
+ # Per `conventions/task-caching.md` (#574): every target here accepts user
23
+ # flags via `{{.CLI_ARGS}}` (--label, --author, --age-days, --cluster,
24
+ # --reason, --repo, --re-action) so MUST NOT declare `sources:` /
25
+ # `generates:` -- the cached cmds: skip would silently swallow the
26
+ # recovery flag.
27
+ #
28
+ # Path resolution mirrors the convention from tasks/issue.yml + tasks/policy.yml:
29
+ # `DEFT_ROOT` is defined locally via `joinPath .TASKFILE_DIR ".."` so
30
+ # `node .../bin.js` resolves cleanly on Windows under go-task's mvdan/sh
31
+ # interpreter (#566).
32
+
33
+ vars:
34
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
35
+
36
+ tasks:
37
+ bulk-accept:
38
+ desc: "Bulk accept candidates (#845 Story 4) -- task triage:bulk-accept -- --repo OWNER/NAME [--label L] [--author A] [--age-days N] [--cluster C] [--re-action]"
39
+ internal: true
40
+ deps: [":ts:build"]
41
+ dir: '{{.USER_WORKING_DIR}}'
42
+ cmds:
43
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-bulk accept {{.CLI_ARGS}}
44
+
45
+ bulk-reject:
46
+ desc: "Bulk reject candidates (#845 Story 4) -- task triage:bulk-reject -- --repo OWNER/NAME --reason 'why' [--label L] [--author A] [--age-days N] [--cluster C] [--re-action]"
47
+ internal: true
48
+ deps: [":ts:build"]
49
+ dir: '{{.USER_WORKING_DIR}}'
50
+ cmds:
51
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-bulk reject {{.CLI_ARGS}}
52
+
53
+ bulk-defer:
54
+ desc: "Bulk defer candidates (#845 Story 4) -- task triage:bulk-defer -- --repo OWNER/NAME [--label L] [--author A] [--age-days N] [--cluster C] [--re-action]"
55
+ internal: true
56
+ deps: [":ts:build"]
57
+ dir: '{{.USER_WORKING_DIR}}'
58
+ cmds:
59
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-bulk defer {{.CLI_ARGS}}
60
+
61
+ bulk-needs-ac:
62
+ desc: "Bulk needs-ac candidates (#845 Story 4) -- task triage:bulk-needs-ac -- --repo OWNER/NAME [--label L] [--author A] [--age-days N] [--cluster C] [--re-action]"
63
+ internal: true
64
+ deps: [":ts:build"]
65
+ dir: '{{.USER_WORKING_DIR}}'
66
+ cmds:
67
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-bulk needs-ac {{.CLI_ARGS}}
68
+
69
+ refresh-active:
70
+ desc: "Pre-swarm freshness gate (#845 Story 4) -- detects drift between cached and live `gh issue view` for every issue referenced in vbrief/active/*.vbrief.json"
71
+ internal: true
72
+ deps: [":ts:build"]
73
+ dir: '{{.USER_WORKING_DIR}}'
74
+ cmds:
75
+ - node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" triage-refresh --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}