devflow-kit 3.4.0 → 3.6.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 (221) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/README.md +12 -8
  3. package/dist/agents/code.md +39 -182
  4. package/dist/agents/{diagnose.md → debug.md} +4 -4
  5. package/dist/agents/design.md +0 -1
  6. package/dist/agents/fix.md +165 -0
  7. package/dist/agents/git.md +31 -693
  8. package/dist/agents/{scrutinize.md → harden.md} +9 -6
  9. package/dist/agents/knowledge.md +8 -2
  10. package/dist/agents/refactor.md +133 -0
  11. package/dist/agents/research.md +6 -0
  12. package/dist/agents/review.md +0 -4
  13. package/dist/agents/skim.md +4 -0
  14. package/dist/agents/triage.md +8 -1
  15. package/dist/cli/agents-view/render.js +1 -1
  16. package/dist/cli/commands/behavior-prompts.js +77 -0
  17. package/dist/cli/commands/behavior.js +123 -0
  18. package/dist/cli/commands/flags.js +8 -2
  19. package/dist/cli/commands/init-seed.js +7 -3
  20. package/dist/cli/commands/init.js +75 -8
  21. package/dist/cli/commands/learning.js +12 -12
  22. package/dist/cli/commands/legacy-hooks.js +1 -1
  23. package/dist/cli/commands/rules.js +16 -0
  24. package/dist/cli/commands/tracker.js +112 -15
  25. package/dist/cli/commands/uninstall.js +111 -5
  26. package/dist/cli.js +2 -0
  27. package/dist/commands/bug-analysis.md +22 -18
  28. package/dist/commands/code-review.md +25 -29
  29. package/dist/commands/debug.md +36 -15
  30. package/dist/commands/dynamic-build.md +64 -78
  31. package/dist/commands/dynamic-plan.md +18 -14
  32. package/dist/commands/dynamic-profile.md +8 -6
  33. package/dist/commands/dynamic-tickets.md +19 -15
  34. package/dist/commands/explore.md +14 -14
  35. package/dist/commands/implement.md +122 -225
  36. package/dist/commands/plan.md +32 -47
  37. package/dist/commands/release.md +12 -7
  38. package/dist/commands/research.md +26 -15
  39. package/dist/commands/resolve.md +53 -92
  40. package/dist/commands/self-review.md +42 -42
  41. package/dist/core/agent-frontmatter.js +101 -0
  42. package/dist/core/agent-models.js +47 -11
  43. package/dist/core/compliance-compose.js +6 -4
  44. package/dist/core/{learning-tuning-config.js → curate-tuning-config.js} +14 -14
  45. package/dist/core/feature-switch.js +23 -2
  46. package/dist/core/flags.js +111 -0
  47. package/dist/core/learning-queue-cleanup.js +1 -1
  48. package/dist/core/manifest.js +11 -3
  49. package/dist/core/mds-variants.js +68 -26
  50. package/dist/core/migrations.js +63 -44
  51. package/dist/core/plugins.js +49 -70
  52. package/dist/core/project-paths.js +3 -7
  53. package/dist/core/proxy-log.js +1 -1
  54. package/dist/core/proxy-state.js +1 -1
  55. package/dist/core/tracker.js +120 -2
  56. package/dist/hud/codex-usage.js +247 -0
  57. package/dist/hud/components/codex-quota.js +37 -0
  58. package/dist/hud/components/usage-quota.js +1 -1
  59. package/dist/hud/config.js +1 -0
  60. package/dist/hud/index.js +16 -3
  61. package/dist/hud/render.js +3 -1
  62. package/dist/learning-off/agents/code.md +37 -180
  63. package/dist/learning-off/agents/{diagnose.md → debug.md} +4 -4
  64. package/dist/learning-off/agents/design.md +0 -1
  65. package/dist/learning-off/agents/fix.md +161 -0
  66. package/dist/learning-off/agents/{scrutinize.md → harden.md} +9 -6
  67. package/dist/learning-off/agents/knowledge.md +8 -2
  68. package/dist/learning-off/agents/refactor.md +129 -0
  69. package/dist/learning-off/agents/research.md +6 -0
  70. package/dist/learning-off/agents/review.md +0 -4
  71. package/dist/learning-off/agents/skim.md +4 -0
  72. package/dist/learning-off/agents/triage.md +8 -1
  73. package/dist/learning-off/commands/bug-analysis.md +12 -12
  74. package/dist/learning-off/commands/code-review.md +14 -22
  75. package/dist/learning-off/commands/debug.md +24 -8
  76. package/dist/learning-off/commands/dynamic-build.md +58 -74
  77. package/dist/learning-off/commands/dynamic-plan.md +12 -10
  78. package/dist/learning-off/commands/dynamic-profile.md +2 -2
  79. package/dist/learning-off/commands/dynamic-tickets.md +13 -11
  80. package/dist/learning-off/commands/explore.md +3 -7
  81. package/dist/learning-off/commands/implement.md +110 -217
  82. package/dist/learning-off/commands/plan.md +21 -39
  83. package/dist/learning-off/commands/release.md +7 -4
  84. package/dist/learning-off/commands/research.md +16 -9
  85. package/dist/learning-off/commands/resolve.md +42 -85
  86. package/dist/learning-off/commands/self-review.md +30 -34
  87. package/dist/skills/git/references/learn-conventions.md +27 -3
  88. package/dist/skills/git/references/pr/check-ci-status.md +19 -0
  89. package/dist/skills/git/references/pr/check-merge-readiness.md +21 -0
  90. package/dist/skills/git/references/pr/fetch-review-threads.md +30 -0
  91. package/dist/skills/git/references/pr/post-resolution-summary.md +18 -0
  92. package/dist/skills/git/references/pr/post-review-summary.md +20 -0
  93. package/dist/skills/git/references/pr/resolve-review-threads.md +28 -4
  94. package/dist/skills/git/references/pr/update-pr-evidence.md +17 -6
  95. package/dist/skills/git/references/pr/validate-branch.md +26 -0
  96. package/dist/skills/git/references/tracker/github/associate-release.md +24 -0
  97. package/dist/skills/git/references/tracker/github/backlink-shipped-issues.md +31 -1
  98. package/dist/skills/git/references/tracker/github/create-release.md +30 -1
  99. package/dist/skills/git/references/tracker/github/ensure-pr-ready.md +89 -2
  100. package/dist/skills/git/references/tracker/github/ensure-traceable-issue.md +16 -1
  101. package/dist/skills/git/references/tracker/github/fetch-issue.md +36 -1
  102. package/dist/skills/git/references/tracker/github/fetch-issues-batch.md +47 -1
  103. package/dist/skills/git/references/tracker/github/gather-release-evidence.md +25 -0
  104. package/dist/skills/git/references/tracker/github/manage-debt.md +21 -1
  105. package/dist/skills/git/references/tracker/github/post-wave-report.md +15 -1
  106. package/dist/skills/git/references/tracker/github/setup-task.md +41 -1
  107. package/dist/skills/git/references/tracker/jira/associate-release.md +24 -0
  108. package/dist/skills/git/references/tracker/jira/backlink-shipped-issues.md +31 -1
  109. package/dist/skills/git/references/tracker/jira/create-release.md +30 -1
  110. package/dist/skills/git/references/tracker/jira/ensure-pr-ready.md +89 -2
  111. package/dist/skills/git/references/tracker/jira/ensure-traceable-issue.md +16 -1
  112. package/dist/skills/git/references/tracker/jira/fetch-issue.md +36 -1
  113. package/dist/skills/git/references/tracker/jira/fetch-issues-batch.md +47 -1
  114. package/dist/skills/git/references/tracker/jira/gather-release-evidence.md +25 -0
  115. package/dist/skills/git/references/tracker/jira/manage-debt.md +21 -1
  116. package/dist/skills/git/references/tracker/jira/post-wave-report.md +15 -1
  117. package/dist/skills/git/references/tracker/jira/setup-task.md +41 -1
  118. package/dist/skills/git/references/tracker/linear/associate-release.md +24 -0
  119. package/dist/skills/git/references/tracker/linear/backlink-shipped-issues.md +31 -1
  120. package/dist/skills/git/references/tracker/linear/create-release.md +30 -1
  121. package/dist/skills/git/references/tracker/linear/ensure-pr-ready.md +89 -2
  122. package/dist/skills/git/references/tracker/linear/ensure-traceable-issue.md +16 -1
  123. package/dist/skills/git/references/tracker/linear/fetch-issue.md +36 -1
  124. package/dist/skills/git/references/tracker/linear/fetch-issues-batch.md +47 -1
  125. package/dist/skills/git/references/tracker/linear/gather-release-evidence.md +25 -0
  126. package/dist/skills/git/references/tracker/linear/manage-debt.md +21 -1
  127. package/dist/skills/git/references/tracker/linear/post-wave-report.md +15 -1
  128. package/dist/skills/git/references/tracker/linear/setup-task.md +41 -1
  129. package/dist/targets/claude-code/agent-type-owner.js +164 -0
  130. package/dist/targets/claude-code/behavior-install.js +111 -0
  131. package/dist/targets/claude-code/installer.js +177 -77
  132. package/dist/targets/claude-code/learning-install.js +9 -1
  133. package/dist/targets/claude-code/tracker-install.js +33 -16
  134. package/dist/targets/claude-code/tracker-servers.js +107 -0
  135. package/package.json +4 -3
  136. package/src/assets/agents/_partials/_code.mds +109 -0
  137. package/src/assets/agents/code.mds +18 -222
  138. package/src/assets/agents/{learning.md → curate.md} +22 -72
  139. package/src/assets/agents/{diagnose.mds → debug.mds} +4 -4
  140. package/src/assets/agents/design.mds +0 -1
  141. package/src/assets/agents/evaluate.md +11 -5
  142. package/src/assets/agents/explore.md +58 -0
  143. package/src/assets/agents/fix.mds +113 -0
  144. package/src/assets/agents/git.mds +31 -693
  145. package/src/assets/agents/{scrutinize.mds → harden.mds} +9 -6
  146. package/src/assets/agents/knowledge.mds +8 -2
  147. package/src/assets/agents/{simplify.md → polish.md} +7 -4
  148. package/src/assets/agents/refactor.mds +81 -0
  149. package/src/assets/agents/research.mds +6 -0
  150. package/src/assets/agents/review.mds +0 -4
  151. package/src/assets/agents/skim.mds +4 -0
  152. package/src/assets/agents/synthesize.md +26 -352
  153. package/src/assets/agents/test.md +10 -2
  154. package/src/assets/agents/tracker.md +20 -7
  155. package/src/assets/agents/triage.mds +8 -1
  156. package/src/assets/agents/validate.md +5 -0
  157. package/src/assets/commands/_partials/_compliance.mds +36 -0
  158. package/src/assets/commands/_partials/_decisions.mds +26 -6
  159. package/src/assets/commands/_partials/_engine.mds +17 -17
  160. package/src/assets/commands/_partials/_evidence_policy.mds +0 -17
  161. package/src/assets/commands/_partials/_knowledge.mds +14 -9
  162. package/src/assets/commands/_partials/_preamble.mds +5 -3
  163. package/src/assets/commands/_partials/_roster.mds +6 -5
  164. package/src/assets/commands/_partials/_wave.mds +2 -2
  165. package/src/assets/commands/bug-analysis.mds +10 -10
  166. package/src/assets/commands/code-review.mds +12 -22
  167. package/src/assets/commands/debug.mds +24 -2
  168. package/src/assets/commands/dynamic-build.mds +34 -51
  169. package/src/assets/commands/dynamic-plan.mds +4 -3
  170. package/src/assets/commands/dynamic-tickets.mds +5 -4
  171. package/src/assets/commands/explore.mds +1 -1
  172. package/src/assets/commands/implement.mds +108 -201
  173. package/src/assets/commands/plan.mds +19 -44
  174. package/src/assets/commands/release.mds +8 -3
  175. package/src/assets/commands/research.mds +14 -7
  176. package/src/assets/commands/resolve.mds +37 -82
  177. package/src/assets/commands/self-review.mds +27 -27
  178. package/src/assets/mds/.mdsroot +4 -0
  179. package/src/assets/mds/git/_ops.mds +383 -0
  180. package/src/assets/mds/git/_ops_pr.mds +201 -0
  181. package/src/assets/mds/git/_ops_steps.mds +147 -0
  182. package/src/assets/mds/git/_pr.mds +45 -50
  183. package/src/assets/mds/git/_references.mds +6 -3
  184. package/src/assets/mds/tracker/_common.mds +5 -5
  185. package/src/assets/mds/tracker/_contract.mds +4 -3
  186. package/src/assets/mds/tracker/_github.mds +60 -14
  187. package/src/assets/mds/tracker/_jira.mds +60 -14
  188. package/src/assets/mds/tracker/_linear.mds +60 -14
  189. package/src/assets/mds/tracker/_steps.mds +10 -9
  190. package/src/assets/rules/behavior.md +6 -0
  191. package/src/assets/scripts/hooks/assets/orchestrator-charter.md +5 -3
  192. package/src/assets/scripts/hooks/capture-prompt +1 -1
  193. package/src/assets/scripts/hooks/capture-question +1 -1
  194. package/src/assets/scripts/hooks/capture-turn +1 -1
  195. package/src/assets/scripts/hooks/json-helper.cjs +2 -2
  196. package/src/assets/scripts/hooks/lib/learning-store.cjs +1 -1
  197. package/src/assets/scripts/hooks/lib/project-paths.cjs +4 -10
  198. package/src/assets/scripts/hooks/preamble +1 -1
  199. package/src/assets/scripts/hooks/session-start-context +58 -45
  200. package/src/assets/scripts/verify-evidence.cjs +726 -9
  201. package/src/assets/skills/agent-references/SKILL.md +37 -0
  202. package/src/assets/skills/agent-references/references/commands/implement-evidence-asks.md +35 -0
  203. package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +15 -0
  204. package/src/assets/skills/agent-references/references/curate/maintain.md +71 -0
  205. package/src/assets/skills/agent-references/references/synthesize/bug-analysis.md +71 -0
  206. package/src/assets/skills/agent-references/references/synthesize/design.md +36 -0
  207. package/src/assets/skills/agent-references/references/synthesize/exploration.md +38 -0
  208. package/src/assets/skills/agent-references/references/synthesize/planning.md +60 -0
  209. package/src/assets/skills/agent-references/references/synthesize/research.md +61 -0
  210. package/src/assets/skills/agent-references/references/synthesize/review.md +76 -0
  211. package/src/assets/skills/apply-decisions/SKILL.md +6 -4
  212. package/src/assets/skills/compliance/SKILL.md +1 -1
  213. package/src/assets/skills/docs-framework/SKILL.md +81 -84
  214. package/src/assets/skills/docs-framework/references/patterns.md +14 -25
  215. package/src/assets/skills/docs-framework/references/violations.md +7 -7
  216. package/src/assets/skills/gap-analysis/SKILL.md +0 -16
  217. package/src/assets/skills/gap-analysis/references/compliance.md +19 -0
  218. package/src/assets/skills/qa/SKILL.md +1 -1
  219. package/src/assets/skills/quality-gates/SKILL.md +7 -7
  220. package/src/assets/skills/quality-gates/references/report-template.md +7 -7
  221. 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
  {
@@ -14,6 +14,55 @@ import { writeFileAtomicExclusive } from './fs-atomic.js';
14
14
  import { getMemoryDir } from './project-paths.js';
15
15
  import { LEGACY_AGENT_KEYS, canonicaliseAgentKeys, parseAgentMappingEnvelope } from './agent-models.js';
16
16
  import { migrateLegacyTrackerConventions } from './tracker.js';
17
+ /**
18
+ * The body of every canonicalise-agent-keys-vN migration: read agent-models.json raw,
19
+ * apply LEGACY_AGENT_KEYS once, and write the result back atomically when a key changed.
20
+ * Each migration id passes its own id so that its warnings name it. Idempotent, and a
21
+ * file with no legacy key is left untouched.
22
+ */
23
+ function canonicaliseAgentKeysRun(migrationId) {
24
+ return async (ctx) => {
25
+ const infos = [];
26
+ const warnings = [];
27
+ // Fast path: no legacy keys defined — skip without touching the file.
28
+ if (Object.keys(LEGACY_AGENT_KEYS).length === 0)
29
+ return { infos, warnings };
30
+ const filePath = path.join(ctx.devflowDir, 'agent-models.json');
31
+ // parseAgentMappingEnvelope handles IO, BOM-strip, JSON parse, and shape validation.
32
+ // Raw read intentionally avoids readAgentMapping (which would drop unknown fields).
33
+ const envelope = await parseAgentMappingEnvelope(filePath);
34
+ if (envelope.kind === 'skip')
35
+ return { infos, warnings };
36
+ if (envelope.kind === 'warn') {
37
+ warnings.push(`${migrationId}: ${envelope.message}`);
38
+ return { infos, warnings };
39
+ }
40
+ const onWarning = (msg) => warnings.push(msg);
41
+ const { agents: migrated, didMutate, renamed, dropped, guardDropped } = canonicaliseAgentKeys(envelope.rawAgents, onWarning);
42
+ if (!didMutate)
43
+ return { infos, warnings };
44
+ // Write back with the canonical keys, preserving the rest of the envelope.
45
+ // Idempotent under concurrent execution (no lock needed; see D31 comment above).
46
+ const updated = { ...envelope.envelope, agents: migrated };
47
+ try {
48
+ await writeFileAtomicExclusive(filePath, JSON.stringify(updated, null, 2) + '\n');
49
+ }
50
+ catch (err) {
51
+ warnings.push(`${migrationId}: failed to write ${filePath}: ${err.message}`);
52
+ return { infos, warnings };
53
+ }
54
+ if (renamed.length > 0) {
55
+ infos.push(`Migrated agent-models.json: renamed ${renamed.map(k => `'${k}' → '${LEGACY_AGENT_KEYS[k]}'`).join(', ')}`);
56
+ }
57
+ if (dropped.length > 0) {
58
+ warnings.push(`${migrationId}: dropped legacy key(s) ${dropped.map(k => `'${k}'`).join(', ')} — the replacement key already holds a value, existing value kept`);
59
+ }
60
+ if (guardDropped.length > 0) {
61
+ warnings.push(`${migrationId}: dropped legacy key(s) ${guardDropped.map(k => `'${k}'`).join(', ')} — skipped due to prototype-pollution guard`);
62
+ }
63
+ return { infos, warnings };
64
+ };
65
+ }
17
66
  /**
18
67
  * D31: Registry pattern over scattered `if (!applied.includes(...))` conditionals.
19
68
  *
@@ -33,9 +82,9 @@ import { migrateLegacyTrackerConventions } from './tracker.js';
33
82
  * This was acceptable with an empty MIGRATIONS registry (D37: the vacuous-truth
34
83
  * case); this registry's first real entry is added below. Fix deferred.
35
84
  *
36
- * Note how that interacts with `canonicalise-agent-keys-v1`: runGlobalMigration
37
- * marks a migration applied for ANY non-throwing return, and that entry never
38
- * throws — it catches every I/O and parse failure and returns it as a *warning*.
85
+ * Note how that interacts with the `canonicalise-agent-keys-vN` entries: runGlobalMigration
86
+ * marks a migration applied for ANY non-throwing return, and those entries never
87
+ * throw — it catches every I/O and parse failure and returns it as a *warning*.
39
88
  * So it does NOT hit the unbounded-retry path. It hits the opposite one: a
40
89
  * transient EACCES or a failed write records the migration as applied and it
41
90
  * never runs again, leaving legacy keys on disk permanently.
@@ -52,47 +101,17 @@ export const MIGRATIONS = [
52
101
  id: 'canonicalise-agent-keys-v1',
53
102
  description: 'Rename legacy agent keys in ~/.devflow/agent-models.json to their canonical names',
54
103
  scope: 'global',
55
- async run(ctx) {
56
- const infos = [];
57
- const warnings = [];
58
- // Fast path: no legacy keys defined — skip without touching the file.
59
- if (Object.keys(LEGACY_AGENT_KEYS).length === 0)
60
- return { infos, warnings };
61
- const filePath = path.join(ctx.devflowDir, 'agent-models.json');
62
- // parseAgentMappingEnvelope handles IO, BOM-strip, JSON parse, and shape validation.
63
- // Raw read intentionally avoids readAgentMapping (which would drop unknown fields).
64
- const envelope = await parseAgentMappingEnvelope(filePath);
65
- if (envelope.kind === 'skip')
66
- return { infos, warnings };
67
- if (envelope.kind === 'warn') {
68
- warnings.push(`canonicalise-agent-keys-v1: ${envelope.message}`);
69
- return { infos, warnings };
70
- }
71
- const onWarning = (msg) => warnings.push(msg);
72
- const { agents: migrated, didMutate, renamed, dropped, guardDropped } = canonicaliseAgentKeys(envelope.rawAgents, onWarning);
73
- if (!didMutate)
74
- return { infos, warnings };
75
- // Write back with the canonical keys, preserving the rest of the envelope.
76
- // Idempotent under concurrent execution (no lock needed; see D31 comment above).
77
- const updated = { ...envelope.envelope, agents: migrated };
78
- try {
79
- await writeFileAtomicExclusive(filePath, JSON.stringify(updated, null, 2) + '\n');
80
- }
81
- catch (err) {
82
- warnings.push(`canonicalise-agent-keys-v1: failed to write ${filePath}: ${err.message}`);
83
- return { infos, warnings };
84
- }
85
- if (renamed.length > 0) {
86
- infos.push(`Migrated agent-models.json: renamed ${renamed.map(k => `'${k}' → '${LEGACY_AGENT_KEYS[k]}'`).join(', ')}`);
87
- }
88
- if (dropped.length > 0) {
89
- warnings.push(`canonicalise-agent-keys-v1: dropped legacy key(s) ${dropped.map(k => `'${k}'`).join(', ')} — canonical key already present, existing value kept`);
90
- }
91
- if (guardDropped.length > 0) {
92
- warnings.push(`canonicalise-agent-keys-v1: dropped legacy key(s) ${guardDropped.map(k => `'${k}'`).join(', ')} — skipped due to prototype-pollution guard`);
93
- }
94
- return { infos, warnings };
95
- },
104
+ run: canonicaliseAgentKeysRun('canonicalise-agent-keys-v1'),
105
+ },
106
+ {
107
+ // v1 is already recorded as applied on every machine that upgraded through 2.x, so the
108
+ // six-agent rename needs an id of its own. Both ids run the same body. On a 1.x machine
109
+ // v1 runs first and, with the single-hop LEGACY_AGENT_KEYS, already lands every key on its
110
+ // final slug, so v2 finds nothing to rewrite and makes no write.
111
+ id: 'canonicalise-agent-keys-v2',
112
+ description: 'Rename the keys of the six renamed agents in ~/.devflow/agent-models.json to their new names',
113
+ scope: 'global',
114
+ run: canonicaliseAgentKeysRun('canonicalise-agent-keys-v2'),
96
115
  },
97
116
  {
98
117
  id: 'tracker-conventions-per-provider-v1',
@@ -34,7 +34,7 @@ export const DEVFLOW_PLUGINS = [
34
34
  *
35
35
  * Guard 5 reverse (registry-integrity.test.ts, "declared agents are spawned")
36
36
  * skips a plugin whose commands spawn nothing — `if (spawned.size === 0)
37
- * continue` — and this plugin ships no commands at all. So `learning` and
37
+ * continue` — and this plugin ships no commands at all. So `curate` and
38
38
  * `tracker`, which are spawned by a SessionStart directive rather than by any
39
39
  * command, satisfy the reverse check STRUCTURALLY.
40
40
  *
@@ -48,8 +48,17 @@ export const DEVFLOW_PLUGINS = [
48
48
  * set-equal, both directions, against the `agentType` values present in
49
49
  * dist/commands/, and a hook-spawned agent appears in none of them.
50
50
  */
51
- agents: ['learning', 'tracker'],
52
- skills: ['apply-decisions', 'apply-feature-knowledge', 'software-design', 'docs-framework', 'git', 'boundary-validation', 'test-driven-development', 'testing', 'dependency-research'],
51
+ agents: ['curate', 'tracker'],
52
+ /**
53
+ * D-AGENT-REFS: `agent-references` is a reference-only skill. It holds the Synthesize mode
54
+ * templates and the Curate maintain step, which those two agents read by explicit path, and
55
+ * the command branches that D-CMD-REF-HAND moves out of a command (`references/commands/`),
56
+ * which a command reads by explicit path, so it sits here (core-skills is always installed)
57
+ * and no other plugin lists or requires it.
58
+ * It is never preloaded: tests/guards/agent-references.test.ts holds that, and the one
59
+ * exception to the repo-wide ban on `disable-model-invocation` names this skill alone.
60
+ */
61
+ skills: ['apply-decisions', 'apply-feature-knowledge', 'software-design', 'docs-framework', 'git', 'boundary-validation', 'test-driven-development', 'testing', 'dependency-research', 'agent-references'],
53
62
  requires: [
54
63
  'architecture',
55
64
  'complexity',
@@ -76,28 +85,18 @@ export const DEVFLOW_PLUGINS = [
76
85
  name: 'devflow-plan',
77
86
  description: 'Unified design planning with gap analysis and design review',
78
87
  commands: ['/plan'],
79
- agents: ['git', 'skim', 'synthesize', 'design'],
88
+ agents: ['git', 'skim', 'synthesize', 'design', 'explore'],
80
89
  skills: ['gap-analysis', 'design-review', 'patterns', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge'],
81
90
  // D-CHARTER-BOUNDED-INLINE: /plan's main thread orchestrates and loads no
82
91
  // companion skills, so `requires:` lists only skills this plugin's command,
83
92
  // agents and skills reference. `software-design` and `test-driven-development`
84
93
  // have no reader here; the closure guard's reverse arm rejects an unread entry.
94
+ // `docs-framework` is read: Phase 14 loads it at the step that names the
95
+ // design document (D-DOCS-NAMES-AUTHORITY).
85
96
  requires: [
86
97
  'apply-decisions',
87
- 'architecture',
88
- 'complexity',
89
- 'consistency',
90
- 'database',
91
- 'dependencies',
92
98
  'docs-framework',
93
- 'documentation',
94
99
  'git',
95
- 'performance',
96
- 'regression',
97
- 'reliability',
98
- 'review-methodology',
99
- 'security',
100
- 'testing',
101
100
  ],
102
101
  rules: [],
103
102
  },
@@ -105,17 +104,15 @@ export const DEVFLOW_PLUGINS = [
105
104
  name: 'devflow-implement',
106
105
  description: 'Complete task implementation workflow - accepts plan documents, issues, or task descriptions',
107
106
  commands: ['/implement'],
108
- agents: ['git', 'code', 'simplify', 'scrutinize', 'evaluate', 'test', 'validate', 'knowledge'],
107
+ agents: ['git', 'code', 'fix', 'polish', 'harden', 'evaluate', 'test', 'validate', 'knowledge'],
109
108
  skills: ['patterns', 'qa', 'quality-gates', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge'],
110
109
  requires: [
111
110
  'apply-decisions',
112
111
  'architecture',
113
- 'boundary-validation',
114
112
  'complexity',
115
113
  'consistency',
116
114
  'database',
117
115
  'dependencies',
118
- 'dependency-research',
119
116
  'documentation',
120
117
  'git',
121
118
  'performance',
@@ -139,23 +136,21 @@ export const DEVFLOW_PLUGINS = [
139
136
  // no companion skills, so `requires:` lists only skills this plugin's command,
140
137
  // agents and skills reference. `quality-gates` and `software-design` have no
141
138
  // reader here; the closure guard's reverse arm rejects an unread entry.
142
- requires: ['apply-decisions', 'docs-framework', 'git'],
139
+ requires: ['apply-decisions', 'git'],
143
140
  rules: [],
144
141
  },
145
142
  {
146
143
  name: 'devflow-resolve',
147
144
  description: 'Process and fix code review issues with blast-radius triage, Code agent fixes, and Validate agent verification',
148
145
  commands: ['/resolve'],
149
- agents: ['git', 'triage', 'code', 'simplify', 'validate', 'test', 'knowledge'],
150
- skills: ['patterns', 'security', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge', 'apply-decisions'],
146
+ agents: ['git', 'triage', 'code', 'fix', 'polish', 'validate', 'test', 'knowledge'],
147
+ skills: ['patterns', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge', 'apply-decisions'],
151
148
  requires: [
152
149
  'architecture',
153
- 'boundary-validation',
154
150
  'complexity',
155
151
  'consistency',
156
152
  'database',
157
153
  'dependencies',
158
- 'dependency-research',
159
154
  'documentation',
160
155
  'git',
161
156
  'performance',
@@ -163,6 +158,7 @@ export const DEVFLOW_PLUGINS = [
163
158
  'regression',
164
159
  'reliability',
165
160
  'review-methodology',
161
+ 'security',
166
162
  'software-design',
167
163
  'test-driven-development',
168
164
  'testing',
@@ -173,8 +169,11 @@ export const DEVFLOW_PLUGINS = [
173
169
  name: 'devflow-debug',
174
170
  description: 'Debugging workflows with competing hypothesis investigation via parallel subagents',
175
171
  commands: ['/debug'],
176
- agents: ['git', 'synthesize', 'simplify', 'knowledge'],
172
+ agents: ['git', 'synthesize', 'polish', 'knowledge', 'explore', 'code'],
177
173
  skills: ['git', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge'],
174
+ // D-DEBUG-FIX-VIA-CODE: the fix is a Code spawn. Code loads no skill by language or mode
175
+ // (D-NO-RUNTIME-SKILLS), so `requires:` lists only the skills this command, its agents and the
176
+ // skills they preload reference; the closure guard rejects an entry nothing reads.
178
177
  requires: [
179
178
  'apply-decisions',
180
179
  'architecture',
@@ -182,9 +181,7 @@ export const DEVFLOW_PLUGINS = [
182
181
  'consistency',
183
182
  'database',
184
183
  'dependencies',
185
- 'docs-framework',
186
184
  'documentation',
187
- 'patterns',
188
185
  'performance',
189
186
  'regression',
190
187
  'reliability',
@@ -200,23 +197,12 @@ export const DEVFLOW_PLUGINS = [
200
197
  name: 'devflow-explore',
201
198
  description: 'Codebase exploration with structured analysis and optional knowledge base creation',
202
199
  commands: ['/explore'],
203
- agents: ['skim', 'synthesize', 'knowledge'],
200
+ // 'explore' is devflow's override of Claude Code's built-in Explore agent, spawned by
201
+ // type name (D-EXPLORE-OVERRIDE and D-EXPLORE-NO-CLOBBER, targets/claude-code/agent-type-owner.ts).
202
+ agents: ['skim', 'synthesize', 'knowledge', 'explore'],
204
203
  skills: ['worktree-support', 'apply-feature-knowledge', 'feature-knowledge'],
205
204
  requires: [
206
205
  '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
206
  ],
221
207
  rules: [],
222
208
  },
@@ -226,21 +212,11 @@ export const DEVFLOW_PLUGINS = [
226
212
  commands: ['/research'],
227
213
  agents: ['research', 'skim', 'synthesize', 'knowledge'],
228
214
  skills: ['worktree-support', 'apply-feature-knowledge', 'feature-knowledge', 'research-codebase', 'research-external', 'research-market', 'research-competitor', 'research-technology'],
215
+ // `docs-framework` is read: Phase 2 loads it at the step that names the
216
+ // research directory (D-DOCS-NAMES-AUTHORITY).
229
217
  requires: [
230
218
  'apply-decisions',
231
- 'architecture',
232
- 'complexity',
233
- 'consistency',
234
- 'database',
235
- 'dependencies',
236
219
  'docs-framework',
237
- 'documentation',
238
- 'performance',
239
- 'regression',
240
- 'reliability',
241
- 'review-methodology',
242
- 'security',
243
- 'testing',
244
220
  ],
245
221
  rules: [],
246
222
  },
@@ -258,9 +234,9 @@ export const DEVFLOW_PLUGINS = [
258
234
  },
259
235
  {
260
236
  name: 'devflow-self-review',
261
- description: 'Self-review workflow: Simplify agent + Scrutinize agent for code quality',
237
+ description: 'Self-review workflow: Polish agent + Harden agent for code quality',
262
238
  commands: ['/self-review'],
263
- agents: ['simplify', 'scrutinize', 'validate', 'knowledge'],
239
+ agents: ['polish', 'harden', 'validate', 'knowledge'],
264
240
  skills: ['quality-gates', 'software-design', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge'],
265
241
  // D-PRELOAD-TRIM: no agent, command or skill in this plugin's corpus names
266
242
  // `testing` (Validate preloads only `worktree-support`), so it is not required here.
@@ -271,7 +247,7 @@ export const DEVFLOW_PLUGINS = [
271
247
  name: 'devflow-bug-analysis',
272
248
  description: 'Proactive bug finding with static and semantic analysis',
273
249
  commands: ['/bug-analysis'],
274
- agents: ['git', 'diagnose', 'synthesize'],
250
+ agents: ['git', 'debug', 'synthesize'],
275
251
  skills: [
276
252
  'apply-decisions',
277
253
  'apply-feature-knowledge',
@@ -286,7 +262,6 @@ export const DEVFLOW_PLUGINS = [
286
262
  'architecture',
287
263
  'database',
288
264
  'dependencies',
289
- 'docs-framework',
290
265
  'documentation',
291
266
  'git',
292
267
  'performance',
@@ -299,7 +274,7 @@ export const DEVFLOW_PLUGINS = [
299
274
  name: 'devflow-ambient',
300
275
  description: 'Orchestrator ambient mode — session charter, per-prompt reminder, plan handoff',
301
276
  commands: [],
302
- agents: ['code', 'validate', 'simplify', 'scrutinize', 'evaluate', 'test', 'skim', 'review', 'git', 'synthesize', 'triage', 'design', 'knowledge', 'research', 'learning'],
277
+ agents: ['code', 'refactor', 'validate', 'polish', 'harden', 'evaluate', 'test', 'skim', 'review', 'git', 'synthesize', 'triage', 'design', 'knowledge', 'research', 'curate', 'explore'],
303
278
  skills: [
304
279
  'review-methodology',
305
280
  'security',
@@ -323,9 +298,6 @@ export const DEVFLOW_PLUGINS = [
323
298
  ],
324
299
  requires: [
325
300
  'apply-decisions',
326
- 'boundary-validation',
327
- 'dependency-research',
328
- 'docs-framework',
329
301
  'git',
330
302
  'quality-gates',
331
303
  'research-codebase',
@@ -343,22 +315,19 @@ export const DEVFLOW_PLUGINS = [
343
315
  description: 'Dynamic workflow recipes - dependency-aware tickets→plan→build delivery pipeline',
344
316
  // Commands compiled from commands/*.mds at build time (build:mds).
345
317
  commands: ['/dynamic-tickets', '/dynamic-plan', '/dynamic-build', '/dynamic-profile'],
346
- agents: ['code', 'validate', 'simplify', 'scrutinize', 'evaluate', 'test', 'review', 'git', 'synthesize', 'knowledge', 'design'],
318
+ agents: ['code', 'fix', 'validate', 'polish', 'harden', 'evaluate', 'test', 'review', 'git', 'synthesize', 'knowledge', 'design'],
347
319
  skills: ['apply-decisions', 'apply-feature-knowledge', 'worktree-support', 'docs-framework'],
348
320
  requires: [
349
321
  'architecture',
350
- 'boundary-validation',
351
322
  'complexity',
352
323
  'consistency',
353
324
  'database',
354
325
  'dependencies',
355
- 'dependency-research',
356
326
  'design-review',
357
327
  'documentation',
358
328
  'feature-knowledge',
359
329
  'gap-analysis',
360
330
  'git',
361
- 'patterns',
362
331
  'performance',
363
332
  'qa',
364
333
  'quality-gates',
@@ -491,16 +460,26 @@ export const FEATURE_OWNED_SKILLS = ['compliance'];
491
460
  /**
492
461
  * Rules owned by the feature system — not any plugin in DEVFLOW_PLUGINS.
493
462
  * The compliance rule (src/assets/rules/compliance.md) is stamped and installed
494
- * by convergeComplianceArtifacts, not by the plugin installer.
463
+ * by convergeComplianceArtifacts, not by the plugin installer. The behavior rule
464
+ * (src/assets/rules/behavior.md) is installed and removed by convergeBehaviorRule.
465
+ *
466
+ * D-BEHAVIOR-OPT-IN: the behavior rule is OPT-IN and default off. How agents reply and
467
+ * act is a taste, so no install carries it until the user asks: `features.behavior` in
468
+ * the machine manifest (`devflow init --behavior`, `devflow behavior --enable`). That is
469
+ * why it sits here and in no plugin's `rules` array: a plugin's rules install for every
470
+ * install that selects the plugin, with no switch, and the core plugin is always
471
+ * selected. The rule is one bullet per behavior and stays small, because every session
472
+ * and every subagent that loads the rules pays for it; tests/rules.test.ts pins the
473
+ * shape, the length and this registration.
495
474
  *
496
475
  * Used by:
497
476
  * - rules.ts: union into allRules for shadow/unshadow/list
498
- * - tests: independent literal ['compliance'] (avoids EXCLUDED-as-oracle trap)
477
+ * - tests: independent literal ['compliance', 'behavior'] (avoids EXCLUDED-as-oracle trap)
499
478
  *
500
479
  * D-FO-2: FEATURE_OWNED_RULES must be disjoint from getAllRuleNames()
501
480
  * (guarded by plugins.test.ts FEATURE_OWNED constants describe block).
502
481
  */
503
- export const FEATURE_OWNED_RULES = ['compliance'];
482
+ export const FEATURE_OWNED_RULES = ['compliance', 'behavior'];
504
483
  /**
505
484
  * Skills a learning-off machine does not install.
506
485
  *
@@ -543,8 +522,8 @@ export function omitLearningGatedSkills(skillsMap, learning) {
543
522
  * user may deliberately not have. The referencing prompts are written to
544
523
  * proceed without it: `/code-review` spawns a language focus only when the
545
524
  * 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
525
+ * {@link installedLanguageFocuses}), and the Review agent continues when the
526
+ * Skill invocation fails. Putting them in a `requires` would reinstate
548
527
  * the universal install for exactly the eight skills the selection prompt
549
528
  * exists to let a user decline (AC-25).
550
529
  *
@@ -46,7 +46,7 @@ export function getFeatureConfigPath(projectRoot) {
46
46
  export function getLearningPendingTurnsPath(projectRoot) {
47
47
  return path.join(projectRoot, '.devflow', 'learning', '.pending-turns.jsonl');
48
48
  }
49
- /** .devflow/learning/.pending-turns.processing — the claimed batch a Learning run holds while it processes it */
49
+ /** .devflow/learning/.pending-turns.processing — the claimed batch a Curate run holds while it processes it */
50
50
  export function getLearningPendingTurnsProcessingPath(projectRoot) {
51
51
  return path.join(projectRoot, '.devflow', 'learning', '.pending-turns.processing');
52
52
  }
@@ -65,8 +65,8 @@ export function getDecisionsFilePath(projectRoot) {
65
65
  export function getPitfallsFilePath(projectRoot) {
66
66
  return path.join(projectRoot, '.devflow', 'learning', 'pitfalls.md');
67
67
  }
68
- /** .devflow/learning/learning.json — project-level learning agent tuning config */
69
- export function getLearningTuningConfigPath(projectRoot) {
68
+ /** .devflow/learning/learning.json — project-level curate agent tuning config */
69
+ export function getCurateTuningConfigPath(projectRoot) {
70
70
  return path.join(projectRoot, '.devflow', 'learning', 'learning.json');
71
71
  }
72
72
  /** .devflow/learning/decisions-ledger.jsonl — anchored ledger rows (single source of truth for rendering) */
@@ -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