devflow-kit 3.4.0 → 3.5.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 (186) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +8 -4
  3. package/dist/agents/code-edit.md +133 -0
  4. package/dist/agents/code-fix.md +165 -0
  5. package/dist/agents/code.md +39 -182
  6. package/dist/agents/design.md +0 -1
  7. package/dist/agents/git.md +31 -693
  8. package/dist/agents/knowledge.md +8 -2
  9. package/dist/agents/research.md +6 -0
  10. package/dist/agents/review.md +0 -4
  11. package/dist/agents/scrutinize.md +3 -0
  12. package/dist/agents/skim.md +4 -0
  13. package/dist/agents/triage.md +8 -1
  14. package/dist/cli/commands/behavior-prompts.js +77 -0
  15. package/dist/cli/commands/behavior.js +123 -0
  16. package/dist/cli/commands/flags.js +8 -2
  17. package/dist/cli/commands/init-seed.js +7 -3
  18. package/dist/cli/commands/init.js +72 -5
  19. package/dist/cli/commands/rules.js +16 -0
  20. package/dist/cli/commands/tracker.js +112 -15
  21. package/dist/cli.js +2 -0
  22. package/dist/commands/bug-analysis.md +5 -5
  23. package/dist/commands/code-review.md +14 -9
  24. package/dist/commands/debug.md +25 -4
  25. package/dist/commands/dynamic-build.md +28 -38
  26. package/dist/commands/dynamic-plan.md +11 -9
  27. package/dist/commands/dynamic-profile.md +3 -3
  28. package/dist/commands/dynamic-tickets.md +12 -10
  29. package/dist/commands/explore.md +3 -3
  30. package/dist/commands/implement.md +91 -125
  31. package/dist/commands/plan.md +15 -8
  32. package/dist/commands/release.md +3 -2
  33. package/dist/commands/research.md +16 -9
  34. package/dist/commands/resolve.md +20 -15
  35. package/dist/commands/self-review.md +2 -2
  36. package/dist/core/agent-frontmatter.js +101 -0
  37. package/dist/core/compliance-compose.js +6 -4
  38. package/dist/core/feature-switch.js +23 -2
  39. package/dist/core/flags.js +111 -0
  40. package/dist/core/manifest.js +11 -3
  41. package/dist/core/mds-variants.js +68 -26
  42. package/dist/core/plugins.js +42 -65
  43. package/dist/core/project-paths.js +0 -4
  44. package/dist/core/proxy-log.js +1 -1
  45. package/dist/core/proxy-state.js +1 -1
  46. package/dist/core/tracker.js +120 -2
  47. package/dist/learning-off/agents/code-edit.md +129 -0
  48. package/dist/learning-off/agents/code-fix.md +161 -0
  49. package/dist/learning-off/agents/code.md +37 -180
  50. package/dist/learning-off/agents/design.md +0 -1
  51. package/dist/learning-off/agents/knowledge.md +8 -2
  52. package/dist/learning-off/agents/research.md +6 -0
  53. package/dist/learning-off/agents/review.md +0 -4
  54. package/dist/learning-off/agents/scrutinize.md +3 -0
  55. package/dist/learning-off/agents/skim.md +4 -0
  56. package/dist/learning-off/agents/triage.md +8 -1
  57. package/dist/learning-off/commands/bug-analysis.md +3 -3
  58. package/dist/learning-off/commands/code-review.md +12 -7
  59. package/dist/learning-off/commands/debug.md +22 -2
  60. package/dist/learning-off/commands/dynamic-build.md +27 -37
  61. package/dist/learning-off/commands/dynamic-plan.md +10 -8
  62. package/dist/learning-off/commands/dynamic-profile.md +2 -2
  63. package/dist/learning-off/commands/dynamic-tickets.md +11 -9
  64. package/dist/learning-off/commands/explore.md +1 -1
  65. package/dist/learning-off/commands/implement.md +89 -123
  66. package/dist/learning-off/commands/plan.md +13 -6
  67. package/dist/learning-off/commands/release.md +3 -2
  68. package/dist/learning-off/commands/research.md +14 -7
  69. package/dist/learning-off/commands/resolve.md +18 -13
  70. package/dist/skills/git/references/learn-conventions.md +27 -3
  71. package/dist/skills/git/references/pr/check-ci-status.md +19 -0
  72. package/dist/skills/git/references/pr/check-merge-readiness.md +19 -0
  73. package/dist/skills/git/references/pr/fetch-review-threads.md +30 -0
  74. package/dist/skills/git/references/pr/post-resolution-summary.md +18 -0
  75. package/dist/skills/git/references/pr/post-review-summary.md +20 -0
  76. package/dist/skills/git/references/pr/resolve-review-threads.md +28 -4
  77. package/dist/skills/git/references/pr/update-pr-evidence.md +13 -0
  78. package/dist/skills/git/references/pr/validate-branch.md +26 -0
  79. package/dist/skills/git/references/tracker/github/associate-release.md +24 -0
  80. package/dist/skills/git/references/tracker/github/backlink-shipped-issues.md +31 -1
  81. package/dist/skills/git/references/tracker/github/create-release.md +30 -1
  82. package/dist/skills/git/references/tracker/github/ensure-pr-ready.md +89 -2
  83. package/dist/skills/git/references/tracker/github/ensure-traceable-issue.md +16 -1
  84. package/dist/skills/git/references/tracker/github/fetch-issue.md +36 -1
  85. package/dist/skills/git/references/tracker/github/fetch-issues-batch.md +47 -1
  86. package/dist/skills/git/references/tracker/github/gather-release-evidence.md +25 -0
  87. package/dist/skills/git/references/tracker/github/manage-debt.md +21 -1
  88. package/dist/skills/git/references/tracker/github/post-wave-report.md +15 -1
  89. package/dist/skills/git/references/tracker/github/setup-task.md +41 -1
  90. package/dist/skills/git/references/tracker/jira/associate-release.md +24 -0
  91. package/dist/skills/git/references/tracker/jira/backlink-shipped-issues.md +31 -1
  92. package/dist/skills/git/references/tracker/jira/create-release.md +30 -1
  93. package/dist/skills/git/references/tracker/jira/ensure-pr-ready.md +89 -2
  94. package/dist/skills/git/references/tracker/jira/ensure-traceable-issue.md +16 -1
  95. package/dist/skills/git/references/tracker/jira/fetch-issue.md +36 -1
  96. package/dist/skills/git/references/tracker/jira/fetch-issues-batch.md +47 -1
  97. package/dist/skills/git/references/tracker/jira/gather-release-evidence.md +25 -0
  98. package/dist/skills/git/references/tracker/jira/manage-debt.md +21 -1
  99. package/dist/skills/git/references/tracker/jira/post-wave-report.md +15 -1
  100. package/dist/skills/git/references/tracker/jira/setup-task.md +41 -1
  101. package/dist/skills/git/references/tracker/linear/associate-release.md +24 -0
  102. package/dist/skills/git/references/tracker/linear/backlink-shipped-issues.md +31 -1
  103. package/dist/skills/git/references/tracker/linear/create-release.md +30 -1
  104. package/dist/skills/git/references/tracker/linear/ensure-pr-ready.md +89 -2
  105. package/dist/skills/git/references/tracker/linear/ensure-traceable-issue.md +16 -1
  106. package/dist/skills/git/references/tracker/linear/fetch-issue.md +36 -1
  107. package/dist/skills/git/references/tracker/linear/fetch-issues-batch.md +47 -1
  108. package/dist/skills/git/references/tracker/linear/gather-release-evidence.md +25 -0
  109. package/dist/skills/git/references/tracker/linear/manage-debt.md +21 -1
  110. package/dist/skills/git/references/tracker/linear/post-wave-report.md +15 -1
  111. package/dist/skills/git/references/tracker/linear/setup-task.md +41 -1
  112. package/dist/targets/claude-code/agent-type-owner.js +164 -0
  113. package/dist/targets/claude-code/behavior-install.js +111 -0
  114. package/dist/targets/claude-code/installer.js +69 -2
  115. package/dist/targets/claude-code/learning-install.js +9 -1
  116. package/dist/targets/claude-code/tracker-install.js +33 -16
  117. package/dist/targets/claude-code/tracker-servers.js +107 -0
  118. package/package.json +4 -3
  119. package/src/assets/agents/_partials/_code.mds +109 -0
  120. package/src/assets/agents/code-edit.mds +81 -0
  121. package/src/assets/agents/code-fix.mds +113 -0
  122. package/src/assets/agents/code.mds +18 -222
  123. package/src/assets/agents/design.mds +0 -1
  124. package/src/assets/agents/evaluate.md +7 -1
  125. package/src/assets/agents/explore.md +58 -0
  126. package/src/assets/agents/git.mds +31 -693
  127. package/src/assets/agents/knowledge.mds +8 -2
  128. package/src/assets/agents/learning.md +19 -69
  129. package/src/assets/agents/research.mds +6 -0
  130. package/src/assets/agents/review.mds +0 -4
  131. package/src/assets/agents/scrutinize.mds +3 -0
  132. package/src/assets/agents/simplify.md +3 -0
  133. package/src/assets/agents/skim.mds +4 -0
  134. package/src/assets/agents/synthesize.md +26 -352
  135. package/src/assets/agents/test.md +8 -0
  136. package/src/assets/agents/tracker.md +20 -7
  137. package/src/assets/agents/triage.mds +8 -1
  138. package/src/assets/agents/validate.md +5 -0
  139. package/src/assets/commands/_partials/_compliance.mds +36 -0
  140. package/src/assets/commands/_partials/_decisions.mds +2 -2
  141. package/src/assets/commands/_partials/_engine.mds +8 -8
  142. package/src/assets/commands/_partials/_preamble.mds +3 -3
  143. package/src/assets/commands/_partials/_roster.mds +4 -3
  144. package/src/assets/commands/_partials/_wave.mds +2 -2
  145. package/src/assets/commands/bug-analysis.mds +3 -3
  146. package/src/assets/commands/code-review.mds +11 -8
  147. package/src/assets/commands/debug.mds +24 -2
  148. package/src/assets/commands/dynamic-build.mds +14 -25
  149. package/src/assets/commands/dynamic-plan.mds +4 -3
  150. package/src/assets/commands/dynamic-tickets.mds +5 -4
  151. package/src/assets/commands/explore.mds +1 -1
  152. package/src/assets/commands/implement.mds +89 -125
  153. package/src/assets/commands/plan.mds +12 -7
  154. package/src/assets/commands/release.mds +3 -2
  155. package/src/assets/commands/research.mds +14 -7
  156. package/src/assets/commands/resolve.mds +17 -14
  157. package/src/assets/mds/.mdsroot +4 -0
  158. package/src/assets/mds/git/_ops.mds +383 -0
  159. package/src/assets/mds/git/_ops_pr.mds +201 -0
  160. package/src/assets/mds/git/_ops_steps.mds +147 -0
  161. package/src/assets/mds/git/_pr.mds +39 -44
  162. package/src/assets/mds/git/_references.mds +6 -3
  163. package/src/assets/mds/tracker/_common.mds +5 -5
  164. package/src/assets/mds/tracker/_contract.mds +4 -3
  165. package/src/assets/mds/tracker/_github.mds +60 -14
  166. package/src/assets/mds/tracker/_jira.mds +60 -14
  167. package/src/assets/mds/tracker/_linear.mds +60 -14
  168. package/src/assets/mds/tracker/_steps.mds +10 -9
  169. package/src/assets/rules/behavior.md +6 -0
  170. package/src/assets/scripts/hooks/assets/orchestrator-charter.md +2 -1
  171. package/src/assets/scripts/hooks/lib/project-paths.cjs +0 -6
  172. package/src/assets/skills/agent-references/SKILL.md +33 -0
  173. package/src/assets/skills/agent-references/references/learning/maintain.md +71 -0
  174. package/src/assets/skills/agent-references/references/synthesize/bug-analysis.md +71 -0
  175. package/src/assets/skills/agent-references/references/synthesize/design.md +36 -0
  176. package/src/assets/skills/agent-references/references/synthesize/exploration.md +38 -0
  177. package/src/assets/skills/agent-references/references/synthesize/planning.md +60 -0
  178. package/src/assets/skills/agent-references/references/synthesize/research.md +61 -0
  179. package/src/assets/skills/agent-references/references/synthesize/review.md +76 -0
  180. package/src/assets/skills/compliance/SKILL.md +1 -1
  181. package/src/assets/skills/docs-framework/SKILL.md +80 -83
  182. package/src/assets/skills/docs-framework/references/patterns.md +14 -25
  183. package/src/assets/skills/docs-framework/references/violations.md +7 -7
  184. package/src/assets/skills/gap-analysis/SKILL.md +0 -16
  185. package/src/assets/skills/gap-analysis/references/compliance.md +19 -0
  186. package/dist/skills/git/references/pr/ensure-pr-ready.md +0 -24
@@ -271,32 +271,38 @@ export const TRACKER_OPS = [
271
271
  */
272
272
  export const TRACKER_GITHUB_OPS = TRACKER_OPS;
273
273
  /**
274
- * The 9 PR/review operations whose mechanics are generated once, for every
274
+ * The 8 PR/review operations whose references are generated once, for every
275
275
  * provider, under `pr/`.
276
276
  *
277
277
  * A PR-HOST roster, not a tracker roster, and the distinction is the whole
278
278
  * reason this list exists separately from {@link TRACKER_OPS}: pull requests, PR
279
279
  * reviews and PR checks stay on GitHub under every issue-tracker provider, so
280
- * these steps are the SAME file whatever `TRACKER_PROVIDER` resolves to. Filing
281
- * them under `tracker/github/` would make a jira user's PR mechanics read as
282
- * their tracker's, and fanning them across the three provider directories would
283
- * ship three identical trees.
284
- *
285
- * `ensure-pr-ready` is a member of BOTH rosters by design, and the two halves do
286
- * not overlap: the PR skeleton (branch/commit/push, create, retitle, and step
287
- * 4b's open-PR lookup and body edit) is a PR-host fact and lives here; step 4b
288
- * itself — the issue-number lookup and the link line it renders — is a tracker
289
- * fact and lives in `tracker/{provider}/ensure-pr-ready.md`. The operation
290
- * carries one pointer to each.
291
- *
292
- * 9 entries, one above {@link MIN_VARIANT_PAIRS}, which is a floor and not a
280
+ * these operations are the SAME file whatever `TRACKER_PROVIDER` resolves to.
281
+ * Filing them under `tracker/github/` would make a jira user's PR mechanics read
282
+ * as their tracker's, and fanning them across the three provider directories
283
+ * would ship three identical trees.
284
+ *
285
+ * D-OP-ONE-REF. Each file is the WHOLE operation: its contract (description,
286
+ * `**Input:**`, degradation notes, `**Output:**` template, written once in
287
+ * `src/assets/mds/git/_ops.mds`) and then its steps. The operation loads this one
288
+ * file and no other operation reference.
289
+ *
290
+ * `ensure-pr-ready` is deliberately NOT a member. It is a tracker operation: step
291
+ * 4b, the issue-number lookup and the link line it renders, is a tracker fact and
292
+ * differs per provider, so the operation is one file per provider under
293
+ * `tracker/{provider}/ensure-pr-ready.md`. That file carries the PR skeleton
294
+ * (branch/commit/push, create, retitle, and step 4b's open-PR lookup and body edit)
295
+ * as well, written once in `_ops.mds` and expanded into all three, so the PR-host
296
+ * half is the same bytes under every provider and the operation still loads one
297
+ * file.
298
+ *
299
+ * 8 entries, exactly {@link MIN_VARIANT_PAIRS}, which is a floor and not a
293
300
  * target: a shorter roster makes every parity assertion over it vacuous (GAP-42)
294
- * and `expandVariants` refuses the build, so the roster can grow
295
- * but never drop below 8. `update-pr-evidence` (#363) is the ninth — it edits the
296
- * PR body and comments on the PR, both GitHub whatever the tracker is.
301
+ * and `expandVariants` refuses the build, so the roster can grow but never drop
302
+ * below 8. `update-pr-evidence` (#363) is the newest member: it edits the PR body
303
+ * and comments on the PR, both GitHub whatever the tracker is.
297
304
  */
298
305
  export const PR_HOST_OPS = [
299
- 'ensure-pr-ready',
300
306
  'validate-branch',
301
307
  'post-review-summary',
302
308
  'check-ci-status',
@@ -354,6 +360,44 @@ export const GIT_CROSS_CUTTING_DOCS = [
354
360
  'publication-gate',
355
361
  'trust-rule',
356
362
  ];
363
+ /**
364
+ * The Git operations whose one operation reference is a cross-cutting document
365
+ * rather than a per-op file in `pr/` or `tracker/{provider}/` (D-OP-ONE-REF).
366
+ *
367
+ * `learn-conventions` is the only one: it has no PR-host half and no provider half,
368
+ * so its reference is the named document {@link GIT_CROSS_CUTTING_DOCS} already emits
369
+ * at the references root. Its contract is compiled into that document like every
370
+ * other operation's (D-OP-CONTRACT-ONCE).
371
+ */
372
+ export const DOC_BACKED_OPS = ['learn-conventions'];
373
+ /**
374
+ * Every operation the Git agent routes, derived from the three rosters that emit its
375
+ * reference — never retyped. Each one loads exactly one operation reference
376
+ * ({@link operationReferenceRel}).
377
+ */
378
+ export const GIT_OPERATIONS = [...PR_HOST_OPS, ...TRACKER_OPS, ...DOC_BACKED_OPS];
379
+ /**
380
+ * The skill-relative path (under `references/`) of the one reference an operation
381
+ * loads, or `null` for a name that is not a Git operation.
382
+ *
383
+ * D-OP-ONE-REF. A PR-host operation is `pr/{op}.md`, the same file under every
384
+ * provider; a tracker operation is `tracker/{provider}/{op}.md` for the resolved
385
+ * provider; a doc-backed operation is its named document. The Git agent's
386
+ * `## Loading the mechanics` table states these paths in prose, and
387
+ * `tests/tracker/reference-reachability.test.ts` holds the table to this function.
388
+ *
389
+ * Total and pure: an unknown operation is `null`, never a throw. `ensure-pr-ready` is
390
+ * a tracker operation, so it resolves per provider even though its PR half is shared.
391
+ */
392
+ export function operationReferenceRel(op, provider) {
393
+ if (TRACKER_OPS.includes(op))
394
+ return `${TRACKER_DESTINATION_ROOT}/${provider}/${op}.md`;
395
+ if (PR_HOST_OPS.includes(op))
396
+ return `${PR_HOST_DESTINATION_ROOT}/${op}.md`;
397
+ if (DOC_BACKED_OPS.includes(op))
398
+ return `${op}.md`;
399
+ return null;
400
+ }
357
401
  /**
358
402
  * Every reference module the build knows about — a closed registry, read the
359
403
  * same way ALLOWED_OUTPUT_DIRS is read.
@@ -378,9 +422,9 @@ export const GIT_CROSS_CUTTING_DOCS = [
378
422
  * that used to sit in the always-loaded Git agent, where every spawn paid for
379
423
  * them although most spawns run a PR-host operation that never touches the
380
424
  * issue tracker. A spawn now reads the file once, only when it runs a tracker
381
- * operation, before its first tracker step. The agent's retained
382
- * `## Loading the mechanics` section is the one line that names it; it keeps
383
- * the PR-mechanics load rule and the merged step order, which a PR-only spawn
425
+ * operation, before its first tracker step. The agent's `## Loading the mechanics`
426
+ * section is the one line that names it; it keeps the one-reference rule and the
427
+ * table naming every non-tracker operation's reference, which a PR-only spawn
384
428
  * needs and which this file cannot instruct a spawn to load. It is ungated for
385
429
  * the reason the registry's other provider-independent files are: every install
386
430
  * carries every provider, GitHub included, so no registered provider is the
@@ -389,11 +433,9 @@ export const GIT_CROSS_CUTTING_DOCS = [
389
433
  * The budget clause: the file is a per-SPAWN term of each tracker row (GitHub,
390
434
  * Jira, Linear), charged the way the tool-call contract is (`contractTerm` in
391
435
  * tests/tracker/budget-model.ts) and added in `providerLoadedSet`. It is not part
392
- * of `ownLoadForProvider`, of the PR-host row or of the per-operation PR-host
393
- * cap. ensure-pr-ready is both a PR-host and a tracker operation, so charging it
394
- * the contract there would put it over a lower-only cap; its full cost,
395
- * contract included, is priced through the tracker rows, where it is already a
396
- * candidate.
436
+ * of `ownLoadForProvider`, of the PR-host row or of the per-operation load cap
437
+ * (D-OP-LOAD-CAP): the cap prices one operation's own reference, which is the same
438
+ * whichever tracker row it is read through.
397
439
  */
398
440
  export const VARIANT_MODULES = [
399
441
  {
@@ -49,7 +49,14 @@ export const DEVFLOW_PLUGINS = [
49
49
  * dist/commands/, and a hook-spawned agent appears in none of them.
50
50
  */
51
51
  agents: ['learning', 'tracker'],
52
- skills: ['apply-decisions', 'apply-feature-knowledge', 'software-design', 'docs-framework', 'git', 'boundary-validation', 'test-driven-development', 'testing', 'dependency-research'],
52
+ /**
53
+ * D-AGENT-REFS: `agent-references` is a reference-only skill. It holds the Synthesize mode
54
+ * templates and the Learning maintain step, which those two agents read by explicit path, so
55
+ * it sits here (core-skills is always installed) and no other plugin lists or requires it.
56
+ * It is never preloaded: tests/guards/agent-references.test.ts holds that, and the one
57
+ * exception to the repo-wide ban on `disable-model-invocation` names this skill alone.
58
+ */
59
+ skills: ['apply-decisions', 'apply-feature-knowledge', 'software-design', 'docs-framework', 'git', 'boundary-validation', 'test-driven-development', 'testing', 'dependency-research', 'agent-references'],
53
60
  requires: [
54
61
  'architecture',
55
62
  'complexity',
@@ -76,28 +83,18 @@ export const DEVFLOW_PLUGINS = [
76
83
  name: 'devflow-plan',
77
84
  description: 'Unified design planning with gap analysis and design review',
78
85
  commands: ['/plan'],
79
- agents: ['git', 'skim', 'synthesize', 'design'],
86
+ agents: ['git', 'skim', 'synthesize', 'design', 'explore'],
80
87
  skills: ['gap-analysis', 'design-review', 'patterns', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge'],
81
88
  // D-CHARTER-BOUNDED-INLINE: /plan's main thread orchestrates and loads no
82
89
  // companion skills, so `requires:` lists only skills this plugin's command,
83
90
  // agents and skills reference. `software-design` and `test-driven-development`
84
91
  // have no reader here; the closure guard's reverse arm rejects an unread entry.
92
+ // `docs-framework` is read: Phase 14 loads it at the step that names the
93
+ // design document (D-DOCS-NAMES-AUTHORITY).
85
94
  requires: [
86
95
  'apply-decisions',
87
- 'architecture',
88
- 'complexity',
89
- 'consistency',
90
- 'database',
91
- 'dependencies',
92
96
  'docs-framework',
93
- 'documentation',
94
97
  'git',
95
- 'performance',
96
- 'regression',
97
- 'reliability',
98
- 'review-methodology',
99
- 'security',
100
- 'testing',
101
98
  ],
102
99
  rules: [],
103
100
  },
@@ -105,17 +102,15 @@ export const DEVFLOW_PLUGINS = [
105
102
  name: 'devflow-implement',
106
103
  description: 'Complete task implementation workflow - accepts plan documents, issues, or task descriptions',
107
104
  commands: ['/implement'],
108
- agents: ['git', 'code', 'simplify', 'scrutinize', 'evaluate', 'test', 'validate', 'knowledge'],
105
+ agents: ['git', 'code', 'code-fix', 'simplify', 'scrutinize', 'evaluate', 'test', 'validate', 'knowledge'],
109
106
  skills: ['patterns', 'qa', 'quality-gates', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge'],
110
107
  requires: [
111
108
  'apply-decisions',
112
109
  'architecture',
113
- 'boundary-validation',
114
110
  'complexity',
115
111
  'consistency',
116
112
  'database',
117
113
  'dependencies',
118
- 'dependency-research',
119
114
  'documentation',
120
115
  'git',
121
116
  'performance',
@@ -139,23 +134,21 @@ export const DEVFLOW_PLUGINS = [
139
134
  // no companion skills, so `requires:` lists only skills this plugin's command,
140
135
  // agents and skills reference. `quality-gates` and `software-design` have no
141
136
  // reader here; the closure guard's reverse arm rejects an unread entry.
142
- requires: ['apply-decisions', 'docs-framework', 'git'],
137
+ requires: ['apply-decisions', 'git'],
143
138
  rules: [],
144
139
  },
145
140
  {
146
141
  name: 'devflow-resolve',
147
142
  description: 'Process and fix code review issues with blast-radius triage, Code agent fixes, and Validate agent verification',
148
143
  commands: ['/resolve'],
149
- agents: ['git', 'triage', 'code', 'simplify', 'validate', 'test', 'knowledge'],
150
- skills: ['patterns', 'security', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge', 'apply-decisions'],
144
+ agents: ['git', 'triage', 'code', 'code-fix', 'simplify', 'validate', 'test', 'knowledge'],
145
+ skills: ['patterns', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge', 'apply-decisions'],
151
146
  requires: [
152
147
  'architecture',
153
- 'boundary-validation',
154
148
  'complexity',
155
149
  'consistency',
156
150
  'database',
157
151
  'dependencies',
158
- 'dependency-research',
159
152
  'documentation',
160
153
  'git',
161
154
  'performance',
@@ -163,6 +156,7 @@ export const DEVFLOW_PLUGINS = [
163
156
  'regression',
164
157
  'reliability',
165
158
  'review-methodology',
159
+ 'security',
166
160
  'software-design',
167
161
  'test-driven-development',
168
162
  'testing',
@@ -173,8 +167,11 @@ export const DEVFLOW_PLUGINS = [
173
167
  name: 'devflow-debug',
174
168
  description: 'Debugging workflows with competing hypothesis investigation via parallel subagents',
175
169
  commands: ['/debug'],
176
- agents: ['git', 'synthesize', 'simplify', 'knowledge'],
170
+ agents: ['git', 'synthesize', 'simplify', 'knowledge', 'explore', 'code'],
177
171
  skills: ['git', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge'],
172
+ // D-DEBUG-FIX-VIA-CODE: the fix is a Code spawn. Code loads no skill by language or mode
173
+ // (D-NO-RUNTIME-SKILLS), so `requires:` lists only the skills this command, its agents and the
174
+ // skills they preload reference; the closure guard rejects an entry nothing reads.
178
175
  requires: [
179
176
  'apply-decisions',
180
177
  'architecture',
@@ -182,9 +179,7 @@ export const DEVFLOW_PLUGINS = [
182
179
  'consistency',
183
180
  'database',
184
181
  'dependencies',
185
- 'docs-framework',
186
182
  'documentation',
187
- 'patterns',
188
183
  'performance',
189
184
  'regression',
190
185
  'reliability',
@@ -200,23 +195,12 @@ export const DEVFLOW_PLUGINS = [
200
195
  name: 'devflow-explore',
201
196
  description: 'Codebase exploration with structured analysis and optional knowledge base creation',
202
197
  commands: ['/explore'],
203
- agents: ['skim', 'synthesize', 'knowledge'],
198
+ // 'explore' is devflow's override of Claude Code's built-in Explore agent, spawned by
199
+ // type name (D-EXPLORE-OVERRIDE and D-EXPLORE-NO-CLOBBER, targets/claude-code/agent-type-owner.ts).
200
+ agents: ['skim', 'synthesize', 'knowledge', 'explore'],
204
201
  skills: ['worktree-support', 'apply-feature-knowledge', 'feature-knowledge'],
205
202
  requires: [
206
203
  'apply-decisions',
207
- 'architecture',
208
- 'complexity',
209
- 'consistency',
210
- 'database',
211
- 'dependencies',
212
- 'docs-framework',
213
- 'documentation',
214
- 'performance',
215
- 'regression',
216
- 'reliability',
217
- 'review-methodology',
218
- 'security',
219
- 'testing',
220
204
  ],
221
205
  rules: [],
222
206
  },
@@ -226,21 +210,11 @@ export const DEVFLOW_PLUGINS = [
226
210
  commands: ['/research'],
227
211
  agents: ['research', 'skim', 'synthesize', 'knowledge'],
228
212
  skills: ['worktree-support', 'apply-feature-knowledge', 'feature-knowledge', 'research-codebase', 'research-external', 'research-market', 'research-competitor', 'research-technology'],
213
+ // `docs-framework` is read: Phase 2 loads it at the step that names the
214
+ // research directory (D-DOCS-NAMES-AUTHORITY).
229
215
  requires: [
230
216
  'apply-decisions',
231
- 'architecture',
232
- 'complexity',
233
- 'consistency',
234
- 'database',
235
- 'dependencies',
236
217
  'docs-framework',
237
- 'documentation',
238
- 'performance',
239
- 'regression',
240
- 'reliability',
241
- 'review-methodology',
242
- 'security',
243
- 'testing',
244
218
  ],
245
219
  rules: [],
246
220
  },
@@ -286,7 +260,6 @@ export const DEVFLOW_PLUGINS = [
286
260
  'architecture',
287
261
  'database',
288
262
  'dependencies',
289
- 'docs-framework',
290
263
  'documentation',
291
264
  'git',
292
265
  'performance',
@@ -299,7 +272,7 @@ export const DEVFLOW_PLUGINS = [
299
272
  name: 'devflow-ambient',
300
273
  description: 'Orchestrator ambient mode — session charter, per-prompt reminder, plan handoff',
301
274
  commands: [],
302
- agents: ['code', 'validate', 'simplify', 'scrutinize', 'evaluate', 'test', 'skim', 'review', 'git', 'synthesize', 'triage', 'design', 'knowledge', 'research', 'learning'],
275
+ agents: ['code', 'code-edit', 'validate', 'simplify', 'scrutinize', 'evaluate', 'test', 'skim', 'review', 'git', 'synthesize', 'triage', 'design', 'knowledge', 'research', 'learning', 'explore'],
303
276
  skills: [
304
277
  'review-methodology',
305
278
  'security',
@@ -323,9 +296,6 @@ export const DEVFLOW_PLUGINS = [
323
296
  ],
324
297
  requires: [
325
298
  'apply-decisions',
326
- 'boundary-validation',
327
- 'dependency-research',
328
- 'docs-framework',
329
299
  'git',
330
300
  'quality-gates',
331
301
  'research-codebase',
@@ -343,22 +313,19 @@ export const DEVFLOW_PLUGINS = [
343
313
  description: 'Dynamic workflow recipes - dependency-aware tickets→plan→build delivery pipeline',
344
314
  // Commands compiled from commands/*.mds at build time (build:mds).
345
315
  commands: ['/dynamic-tickets', '/dynamic-plan', '/dynamic-build', '/dynamic-profile'],
346
- agents: ['code', 'validate', 'simplify', 'scrutinize', 'evaluate', 'test', 'review', 'git', 'synthesize', 'knowledge', 'design'],
316
+ agents: ['code', 'code-fix', 'validate', 'simplify', 'scrutinize', 'evaluate', 'test', 'review', 'git', 'synthesize', 'knowledge', 'design'],
347
317
  skills: ['apply-decisions', 'apply-feature-knowledge', 'worktree-support', 'docs-framework'],
348
318
  requires: [
349
319
  'architecture',
350
- 'boundary-validation',
351
320
  'complexity',
352
321
  'consistency',
353
322
  'database',
354
323
  'dependencies',
355
- 'dependency-research',
356
324
  'design-review',
357
325
  'documentation',
358
326
  'feature-knowledge',
359
327
  'gap-analysis',
360
328
  'git',
361
- 'patterns',
362
329
  'performance',
363
330
  'qa',
364
331
  'quality-gates',
@@ -491,16 +458,26 @@ export const FEATURE_OWNED_SKILLS = ['compliance'];
491
458
  /**
492
459
  * Rules owned by the feature system — not any plugin in DEVFLOW_PLUGINS.
493
460
  * The compliance rule (src/assets/rules/compliance.md) is stamped and installed
494
- * by convergeComplianceArtifacts, not by the plugin installer.
461
+ * by convergeComplianceArtifacts, not by the plugin installer. The behavior rule
462
+ * (src/assets/rules/behavior.md) is installed and removed by convergeBehaviorRule.
463
+ *
464
+ * D-BEHAVIOR-OPT-IN: the behavior rule is OPT-IN and default off. How agents reply and
465
+ * act is a taste, so no install carries it until the user asks: `features.behavior` in
466
+ * the machine manifest (`devflow init --behavior`, `devflow behavior --enable`). That is
467
+ * why it sits here and in no plugin's `rules` array: a plugin's rules install for every
468
+ * install that selects the plugin, with no switch, and the core plugin is always
469
+ * selected. The rule is one bullet per behavior and stays small, because every session
470
+ * and every subagent that loads the rules pays for it; tests/rules.test.ts pins the
471
+ * shape, the length and this registration.
495
472
  *
496
473
  * Used by:
497
474
  * - rules.ts: union into allRules for shadow/unshadow/list
498
- * - tests: independent literal ['compliance'] (avoids EXCLUDED-as-oracle trap)
475
+ * - tests: independent literal ['compliance', 'behavior'] (avoids EXCLUDED-as-oracle trap)
499
476
  *
500
477
  * D-FO-2: FEATURE_OWNED_RULES must be disjoint from getAllRuleNames()
501
478
  * (guarded by plugins.test.ts FEATURE_OWNED constants describe block).
502
479
  */
503
- export const FEATURE_OWNED_RULES = ['compliance'];
480
+ export const FEATURE_OWNED_RULES = ['compliance', 'behavior'];
504
481
  /**
505
482
  * Skills a learning-off machine does not install.
506
483
  *
@@ -543,8 +520,8 @@ export function omitLearningGatedSkills(skillsMap, learning) {
543
520
  * user may deliberately not have. The referencing prompts are written to
544
521
  * proceed without it: `/code-review` spawns a language focus only when the
545
522
  * installer stamped it into the command (D-LANGUAGE-FOCUS-STAMP,
546
- * {@link installedLanguageFocuses}), and the Review and Code agents continue
547
- * when the Skill invocation fails. Putting them in a `requires` would reinstate
523
+ * {@link installedLanguageFocuses}), and the Review agent continues when the
524
+ * Skill invocation fails. Putting them in a `requires` would reinstate
548
525
  * the universal install for exactly the eight skills the selection prompt
549
526
  * exists to let a user decline (AC-25).
550
527
  *
@@ -131,8 +131,4 @@ export function getDesignDir(projectRoot) {
131
131
  export function getResearchDir(projectRoot) {
132
132
  return path.join(projectRoot, '.devflow', 'docs', 'research');
133
133
  }
134
- /** .devflow/docs/handoff-{branchSlug}.md — Code agent phase handoff artifact */
135
- export function getHandoffPath(projectRoot, branchSlug) {
136
- return path.join(projectRoot, '.devflow', 'docs', `handoff-${branchSlug}.md`);
137
- }
138
134
  //# sourceMappingURL=project-paths.js.map
@@ -34,7 +34,7 @@ export const PROXY_LOG_TAIL_BYTES = 1_048_576;
34
34
  * XDG_CONFIG_HOME (user-config lookup, reached only on an implicit config load —
35
35
  * see D-EFR-6 in model-discovery.ts). CI is read only by `init`; CODEX_HOME and
36
36
  * CLAUDE_CONFIG_DIR only by the Codex ingress, `init` and the Codex doctor, none of
37
- * which devflow enables or invokes. Verified by whole-dist grep of the 0.5.0
37
+ * which devflow enables or invokes. Verified by whole-dist grep of the 0.6.0
38
38
  * package. An allowlist is the correct shape: 61 inherited vars → 6.
39
39
  *
40
40
  * HOME is retained: the runtime's loadConfig resolves ~ paths via homedir().
@@ -91,7 +91,7 @@ export async function writeProxyState(devflowDir, state) {
91
91
  * Top-level keys devflow carries into the routing config. Unknown top-level keys
92
92
  * cause a hard relay startup error — never emit them.
93
93
  *
94
- * @D-EFR-4 Subswitch 0.5.0 routing config contract:
94
+ * @D-EFR-4 Subswitch 0.6.0 routing config contract:
95
95
  * FileConfigSchema is a z.strictObject with exactly 6 accepted top-level keys:
96
96
  * port, logLevel, anthropic, providers, limits, codexIngress. Unknown keys cause a
97
97
  * hard startup error — the relay refuses to start. anthropic and limits are
@@ -60,6 +60,44 @@ export const TRACKER_PROVIDER_IDS = TRACKER_PROVIDERS.map(p => p.id);
60
60
  */
61
61
  export const DEFAULT_TRACKER_PROVIDER = 'github';
62
62
  // ---------------------------------------------------------------------------
63
+ // Tracker tool servers — the allowlist half of the Git and Tracker agents
64
+ // ---------------------------------------------------------------------------
65
+ /**
66
+ * D-TRACKER-SERVER-ALLOWLIST: the Git and Tracker agents hold a tool ALLOWLIST, and the
67
+ * tracker tool servers a user has connected differ per machine, so the shipped allowlist
68
+ * names no server (the agent sources stay vendor-neutral). The installer stamps one
69
+ * whole-server entry per name below onto the INSTALLED `tools:` line of those two agents
70
+ * (`stampAgentTools`, src/core/agent-frontmatter.ts), after the file is copied. Claude Code
71
+ * has no pattern form for an allowlist entry, so a server is granted by its name; a name
72
+ * that matches no connected server is inert (it grants nothing and blocks nothing).
73
+ *
74
+ * The default is one FLAT list, stamped whatever the provider: every install carries every
75
+ * provider, and a repository may select a provider other than the machine's, so a list
76
+ * keyed on the machine's provider would strand that repository. A server the user runs
77
+ * under another name is added with `devflow tracker --servers`. A wrong or missing name
78
+ * does not fail silently: the agent finds no tool for the capability it needs and reports
79
+ * `TRACEABILITY: DEGRADED (no tracker tool for {capability})`.
80
+ *
81
+ * The default leaves `github` out. Under the github provider the Git agent uses `gh` and
82
+ * never reads `_mcp.md`, so a stamped `github` server is never used by a tracker operation;
83
+ * under jira or linear, a connected GitHub server that also advertises issue creation would
84
+ * make the `_mcp.md` capability selection ambiguous, which is a degraded run. A user who
85
+ * wants it adds it with `devflow tracker --servers`.
86
+ */
87
+ export const TRACKER_MCP_SERVERS_DEFAULT = Object.freeze([
88
+ 'atlassian',
89
+ 'jira',
90
+ 'claude_ai_Atlassian',
91
+ 'linear',
92
+ 'claude_ai_Linear',
93
+ ]);
94
+ /** A server name as a user may configure it. Byte-exact, like a provider token. */
95
+ export const TRACKER_SERVER_NAME_RE = /^[A-Za-z0-9_-]{1,64}$/;
96
+ /** The most servers one list may hold; every entry lands in a prompt-adjacent frontmatter line. */
97
+ export const TRACKER_SERVERS_MAX = 32;
98
+ /** The reserved word that returns the setting to {@link TRACKER_MCP_SERVERS_DEFAULT}. */
99
+ export const TRACKER_SERVERS_DEFAULT_WORD = 'default';
100
+ // ---------------------------------------------------------------------------
63
101
  // Artifact basenames — one spelling for every TypeScript reader
64
102
  //
65
103
  // NOT the only spelling in the repository, and a rename that assumes it is will
@@ -238,6 +276,72 @@ export function parseTrackerId(input) {
238
276
  }
239
277
  return { ok: true, value: input };
240
278
  }
279
+ /**
280
+ * Validate a list of tracker server names. The one rule set behind both the CLI argument
281
+ * and the manifest field.
282
+ *
283
+ * REJECT, NEVER REPAIR (as {@link parseTrackerId}): a name is accepted byte-exact against
284
+ * {@link TRACKER_SERVER_NAME_RE} and must not hold `__`, which is what separates a server
285
+ * from its tool in an entry such as `mcp__server__tool`. No trim, no case folding, no
286
+ * alias. Exact duplicates collapse to the first occurrence and the order is kept. The list
287
+ * is non-empty and holds at most {@link TRACKER_SERVERS_MAX} distinct names.
288
+ */
289
+ export function validateTrackerServers(raw) {
290
+ if (raw.length === 0) {
291
+ return { ok: false, error: 'No tracker servers given. Pass one or more server names, or "default".' };
292
+ }
293
+ const seen = new Set();
294
+ for (const entry of raw) {
295
+ if (typeof entry !== 'string' || !TRACKER_SERVER_NAME_RE.test(entry)) {
296
+ return {
297
+ ok: false,
298
+ error: `Invalid tracker server name: "${describeTrackerValue(entry)}". ` +
299
+ 'Names are 1-64 characters from A-Z, a-z, 0-9, "_" and "-".',
300
+ };
301
+ }
302
+ if (entry.includes('__')) {
303
+ return {
304
+ ok: false,
305
+ error: `Invalid tracker server name: "${describeTrackerValue(entry)}". ` +
306
+ 'A name must not contain "__" (it separates a server from its tool).',
307
+ };
308
+ }
309
+ seen.add(entry);
310
+ }
311
+ if (seen.size > TRACKER_SERVERS_MAX) {
312
+ return { ok: false, error: `Too many tracker servers: ${seen.size} (at most ${TRACKER_SERVERS_MAX}).` };
313
+ }
314
+ return { ok: true, value: [...seen] };
315
+ }
316
+ /**
317
+ * Strict boundary parser for `devflow tracker --servers <list>`.
318
+ *
319
+ * `default` alone selects {@link TRACKER_MCP_SERVERS_DEFAULT}; anything else is a
320
+ * comma-separated list of names handed to {@link validateTrackerServers} unchanged. An
321
+ * empty argument, an empty item (`a,,b`, a trailing comma) and the reserved word inside a
322
+ * list are errors, never silently dropped.
323
+ */
324
+ export function parseTrackerServers(input) {
325
+ if (input === '') {
326
+ return { ok: false, error: 'Missing tracker servers. Pass a comma-separated list of names, or "default".' };
327
+ }
328
+ if (input === TRACKER_SERVERS_DEFAULT_WORD)
329
+ return { ok: true, value: { kind: 'default' } };
330
+ const items = input.split(',');
331
+ if (items.includes(TRACKER_SERVERS_DEFAULT_WORD)) {
332
+ return { ok: false, error: `"${TRACKER_SERVERS_DEFAULT_WORD}" is reserved: pass it alone, not inside a list.` };
333
+ }
334
+ const validated = validateTrackerServers(items);
335
+ return validated.ok ? { ok: true, value: { kind: 'list', servers: validated.value } } : validated;
336
+ }
337
+ /** The servers in force for `state`: its own list, else the default. */
338
+ export function effectiveTrackerServers(state) {
339
+ return state.servers ?? TRACKER_MCP_SERVERS_DEFAULT;
340
+ }
341
+ /** The whole-server allowlist entries for `servers`, in order: `github` becomes `mcp__github`. */
342
+ export function trackerServerTools(servers) {
343
+ return servers.map(name => `mcp__${name}`);
344
+ }
241
345
  /**
242
346
  * Tolerant sink normaliser for a raw `manifest.features.tracker` value.
243
347
  *
@@ -249,9 +353,11 @@ export function parseTrackerId(input) {
249
353
  * D-TRACKER-SELF-HEAL [DR-26]: self-healing here is SILENT and emits no
250
354
  * DEGRADED — that is the correct self-heal behaviour, and it is a different
251
355
  * condition from a per-repo config value outside the domain (which does emit
252
- * `unknown tracker provider`). The two must not be conflated.
356
+ * `unknown tracker provider`). The two must not be conflated. The one exception is
357
+ * `servers` (see the body): a present but invalid list heals to the default AND reaches
358
+ * `onWarning` when a caller supplies one, because the user wrote that list on purpose.
253
359
  */
254
- export function normalizeTrackerFeature(raw) {
360
+ export function normalizeTrackerFeature(raw, onWarning) {
255
361
  const DEFAULT = { provider: DEFAULT_TRACKER_PROVIDER };
256
362
  if (raw === null || raw === undefined || typeof raw !== 'object' || Array.isArray(raw)) {
257
363
  return DEFAULT;
@@ -259,6 +365,18 @@ export function normalizeTrackerFeature(raw) {
259
365
  const obj = raw;
260
366
  if (!isTrackerProvider(obj.provider))
261
367
  return DEFAULT;
368
+ // `servers`: absent is the default, silently. A present value that is not a valid list is
369
+ // dropped WHOLE (never trimmed to its valid names) and reported through `onWarning`, which a
370
+ // caller with a terminal passes; the reader itself has no output channel. The state then
371
+ // reads as the default list, and the next `devflow tracker --servers` or `devflow init`
372
+ // writes the manifest without the bad value.
373
+ if (obj.servers === undefined)
374
+ return { provider: obj.provider };
375
+ const servers = Array.isArray(obj.servers) ? validateTrackerServers(obj.servers) : undefined;
376
+ if (servers?.ok === true)
377
+ return { provider: obj.provider, servers: servers.value };
378
+ onWarning?.(`The manifest's tracker servers setting is not a valid list (${servers?.ok === false ? servers.error : 'not a list'}); ` +
379
+ 'using the default. Run `devflow tracker --servers <names>` to set it, or `devflow tracker --servers default`.');
262
380
  return { provider: obj.provider };
263
381
  }
264
382
  // ---------------------------------------------------------------------------