devflow-kit 3.5.0 → 3.7.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 (146) hide show
  1. package/CHANGELOG.md +178 -1
  2. package/README.md +10 -6
  3. package/dist/agents/code.md +7 -11
  4. package/dist/agents/{diagnose.md → debug.md} +4 -4
  5. package/dist/agents/{code-fix.md → fix.md} +7 -8
  6. package/dist/agents/{scrutinize.md → harden.md} +6 -6
  7. package/dist/agents/{code-edit.md → refactor.md} +8 -9
  8. package/dist/agents/review.md +2 -0
  9. package/dist/cli/agents-view/render.js +1 -1
  10. package/dist/cli/commands/gates.js +276 -0
  11. package/dist/cli/commands/init-seed.js +9 -1
  12. package/dist/cli/commands/init.js +34 -11
  13. package/dist/cli/commands/learning.js +12 -12
  14. package/dist/cli/commands/legacy-hooks.js +1 -1
  15. package/dist/cli/commands/memory.js +18 -0
  16. package/dist/cli/commands/uninstall.js +111 -5
  17. package/dist/cli.js +2 -0
  18. package/dist/commands/bug-analysis.md +21 -17
  19. package/dist/commands/code-review.md +65 -66
  20. package/dist/commands/debug.md +17 -17
  21. package/dist/commands/dynamic-build.md +104 -116
  22. package/dist/commands/dynamic-plan.md +13 -11
  23. package/dist/commands/dynamic-profile.md +9 -7
  24. package/dist/commands/dynamic-tickets.md +13 -11
  25. package/dist/commands/explore.md +15 -15
  26. package/dist/commands/implement.md +80 -154
  27. package/dist/commands/plan.md +34 -66
  28. package/dist/commands/release.md +11 -7
  29. package/dist/commands/research.md +14 -10
  30. package/dist/commands/resolve.md +44 -88
  31. package/dist/commands/self-review.md +44 -44
  32. package/dist/core/agent-models.js +47 -11
  33. package/dist/core/{learning-tuning-config.js → curate-tuning-config.js} +14 -14
  34. package/dist/core/echo-value.js +42 -0
  35. package/dist/core/evidence-policy.js +17 -5
  36. package/dist/core/gate-level.js +213 -0
  37. package/dist/core/learning-queue-cleanup.js +1 -1
  38. package/dist/core/manifest.js +26 -10
  39. package/dist/core/migrations.js +63 -44
  40. package/dist/core/model-discovery.js +7 -1
  41. package/dist/core/plugins.js +14 -12
  42. package/dist/core/project-paths.js +3 -3
  43. package/dist/core/tracker.js +5 -33
  44. package/dist/hud/codex-usage.js +247 -0
  45. package/dist/hud/components/codex-quota.js +37 -0
  46. package/dist/hud/components/usage-quota.js +1 -1
  47. package/dist/hud/config.js +1 -0
  48. package/dist/hud/index.js +16 -3
  49. package/dist/hud/render.js +3 -1
  50. package/dist/learning-off/agents/code.md +7 -11
  51. package/dist/learning-off/agents/{diagnose.md → debug.md} +4 -4
  52. package/dist/learning-off/agents/{code-fix.md → fix.md} +7 -8
  53. package/dist/learning-off/agents/{scrutinize.md → harden.md} +6 -6
  54. package/dist/learning-off/agents/{code-edit.md → refactor.md} +8 -9
  55. package/dist/learning-off/agents/review.md +2 -0
  56. package/dist/learning-off/commands/bug-analysis.md +9 -9
  57. package/dist/learning-off/commands/code-review.md +54 -59
  58. package/dist/learning-off/commands/debug.md +6 -10
  59. package/dist/learning-off/commands/dynamic-build.md +98 -112
  60. package/dist/learning-off/commands/dynamic-plan.md +5 -5
  61. package/dist/learning-off/commands/dynamic-profile.md +1 -1
  62. package/dist/learning-off/commands/dynamic-tickets.md +5 -5
  63. package/dist/learning-off/commands/explore.md +4 -8
  64. package/dist/learning-off/commands/implement.md +68 -146
  65. package/dist/learning-off/commands/plan.md +23 -58
  66. package/dist/learning-off/commands/release.md +4 -2
  67. package/dist/learning-off/commands/research.md +2 -2
  68. package/dist/learning-off/commands/resolve.md +33 -81
  69. package/dist/learning-off/commands/self-review.md +32 -36
  70. package/dist/skills/git/references/pr/check-merge-readiness.md +2 -0
  71. package/dist/skills/git/references/pr/update-pr-evidence.md +4 -6
  72. package/dist/skills/git/references/tracker/github/ensure-pr-ready.md +7 -9
  73. package/dist/skills/git/references/tracker/jira/ensure-pr-ready.md +7 -15
  74. package/dist/skills/git/references/tracker/linear/ensure-pr-ready.md +7 -15
  75. package/dist/targets/claude-code/installer.js +117 -84
  76. package/dist/targets/claude-code/learning-install.js +15 -3
  77. package/dist/targets/claude-code/tracker-servers.js +1 -1
  78. package/package.json +1 -1
  79. package/src/assets/agents/_partials/_code.mds +7 -8
  80. package/src/assets/agents/code.mds +4 -7
  81. package/src/assets/agents/{learning.md → curate.md} +8 -10
  82. package/src/assets/agents/{diagnose.mds → debug.mds} +4 -4
  83. package/src/assets/agents/evaluate.md +4 -4
  84. package/src/assets/agents/{code-fix.mds → fix.mds} +5 -5
  85. package/src/assets/agents/{scrutinize.mds → harden.mds} +6 -6
  86. package/src/assets/agents/{simplify.md → polish.md} +4 -4
  87. package/src/assets/agents/{code-edit.mds → refactor.mds} +6 -6
  88. package/src/assets/agents/review.mds +2 -0
  89. package/src/assets/agents/synthesize.md +2 -2
  90. package/src/assets/agents/test.md +2 -2
  91. package/src/assets/commands/_partials/_compliance.mds +1 -1
  92. package/src/assets/commands/_partials/_decisions.mds +26 -6
  93. package/src/assets/commands/_partials/_engine.mds +15 -15
  94. package/src/assets/commands/_partials/_evidence_policy.mds +0 -17
  95. package/src/assets/commands/_partials/_knowledge.mds +14 -9
  96. package/src/assets/commands/_partials/_preamble.mds +4 -2
  97. package/src/assets/commands/_partials/_roster.mds +4 -4
  98. package/src/assets/commands/_partials/_settings.mds +2 -2
  99. package/src/assets/commands/_partials/_wave.mds +10 -17
  100. package/src/assets/commands/bug-analysis.mds +7 -7
  101. package/src/assets/commands/code-review.mds +51 -56
  102. package/src/assets/commands/debug.mds +2 -2
  103. package/src/assets/commands/dynamic-build.mds +67 -74
  104. package/src/assets/commands/implement.mds +65 -127
  105. package/src/assets/commands/plan.mds +21 -61
  106. package/src/assets/commands/release.mds +5 -1
  107. package/src/assets/commands/resolve.mds +28 -76
  108. package/src/assets/commands/self-review.mds +27 -27
  109. package/src/assets/mds/git/_ops_steps.mds +3 -3
  110. package/src/assets/mds/git/_pr.mds +6 -6
  111. package/src/assets/mds/tracker/_common.mds +23 -12
  112. package/src/assets/mds/tracker/_github.mds +2 -9
  113. package/src/assets/mds/tracker/_jira.mds +2 -15
  114. package/src/assets/mds/tracker/_linear.mds +2 -15
  115. package/src/assets/scripts/ci-wait.cjs +22 -4
  116. package/src/assets/scripts/claude-md-audit.cjs +66 -51
  117. package/src/assets/scripts/hooks/assets/orchestrator-charter.md +4 -3
  118. package/src/assets/scripts/hooks/background-memory-update +404 -95
  119. package/src/assets/scripts/hooks/capture-prompt +1 -1
  120. package/src/assets/scripts/hooks/capture-question +1 -1
  121. package/src/assets/scripts/hooks/capture-turn +1 -1
  122. package/src/assets/scripts/hooks/json-helper.cjs +13 -2
  123. package/src/assets/scripts/hooks/json-parse +18 -3
  124. package/src/assets/scripts/hooks/lib/learning-store.cjs +1 -1
  125. package/src/assets/scripts/hooks/lib/project-paths.cjs +4 -4
  126. package/src/assets/scripts/hooks/memory-permission +358 -0
  127. package/src/assets/scripts/hooks/preamble +1 -1
  128. package/src/assets/scripts/hooks/session-start-context +60 -47
  129. package/src/assets/scripts/hooks/session-start-memory +26 -5
  130. package/src/assets/scripts/lib/project-config.cjs +19 -4
  131. package/src/assets/scripts/resolve-settings.cjs +200 -32
  132. package/src/assets/scripts/verify-evidence.cjs +726 -9
  133. package/src/assets/skills/agent-references/SKILL.md +14 -6
  134. package/src/assets/skills/agent-references/references/commands/code-review-levels.md +19 -0
  135. package/src/assets/skills/agent-references/references/commands/implement-evidence-asks.md +35 -0
  136. package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +15 -0
  137. package/src/assets/skills/agent-references/references/commands/plan-levels.md +40 -0
  138. package/src/assets/skills/agent-references/references/synthesize/bug-analysis.md +1 -1
  139. package/src/assets/skills/agent-references/references/synthesize/planning.md +9 -22
  140. package/src/assets/skills/agent-references/references/synthesize/review.md +11 -11
  141. package/src/assets/skills/apply-decisions/SKILL.md +6 -4
  142. package/src/assets/skills/docs-framework/SKILL.md +3 -3
  143. package/src/assets/skills/qa/SKILL.md +1 -1
  144. package/src/assets/skills/quality-gates/SKILL.md +7 -7
  145. package/src/assets/skills/quality-gates/references/report-template.md +7 -7
  146. /package/src/assets/skills/agent-references/references/{learning → curate}/maintain.md +0 -0
@@ -7,7 +7,7 @@ import color from 'picocolors';
7
7
  import { getInstallationPaths, getClaudeDirectory, getHomeDirectory, getManagedSettingsPath } from '../../targets/claude-code/claude-paths.js';
8
8
  import { getGitRoot } from '../../core/git.js';
9
9
  import { isSameLocation } from '../../core/same-location.js';
10
- import { DEVFLOW_PLUGINS, SKILL_NAMESPACE, getAllSkillNames, getAllAgentNames, getAllCommandNames, parsePluginSelection, resolveFeatureRedirect, prefixSkillName, unprefixSkillName, skillsOf, FEATURE_OWNED_SKILLS } from '../../core/plugins.js';
10
+ import { DEVFLOW_PLUGINS, SKILL_NAMESPACE, buildAssetMaps, getAllSkillNames, getAllAgentNames, getAllCommandNames, parsePluginSelection, resolveFeatureRedirect, prefixSkillName, unprefixSkillName, skillsOf, FEATURE_OWNED_SKILLS } from '../../core/plugins.js';
11
11
  import { readManifest, removeManifestPlugins } from '../../core/manifest.js';
12
12
  import { sweepOrphanedAssets, mdFileName, mdEntryName } from '../../core/orphan-sweep.js';
13
13
  import { LEGACY_SKILL_NAMES } from '../../targets/claude-code/legacy.js';
@@ -20,7 +20,7 @@ import { removeContextHook } from './context.js';
20
20
  import { applyProxyTeardownToSettings } from './proxy.js';
21
21
  import { readProxyState, proxyJsonExists } from '../../core/proxy-state.js';
22
22
  import { hudCacheDir } from '../../core/cache.js';
23
- import { TRACKER_ATTEMPTS_NAMES, TRACKER_CLAIM_FILE, TRACKER_CONVENTIONS_DIR, TRACKER_ENABLED_FILE, TRACKER_LEGACY_ATTEMPTS_FILE, TRACKER_LEGACY_CONVENTIONS_FILE, TRACKER_PROVIDER_IDS, TRACKER_STAGED_PREFIX, } from '../../core/tracker.js';
23
+ import { effectiveTrackerServers, TRACKER_ATTEMPTS_NAMES, TRACKER_CLAIM_FILE, TRACKER_CONVENTIONS_DIR, TRACKER_ENABLED_FILE, TRACKER_LEGACY_ATTEMPTS_FILE, TRACKER_LEGACY_CONVENTIONS_FILE, TRACKER_PROVIDER_IDS, TRACKER_STAGED_PREFIX, } from '../../core/tracker.js';
24
24
  import { CLAUDE_MD_AUDIT_STAMP_FILE, CLAUDE_MD_AUDIT_STAMP_TMP_PREFIX } from '../../core/claude-md-audit.js';
25
25
  import { revertExternalAgents } from '../../core/agent-models.js';
26
26
  import { detectShell, getProfilePath } from '../../core/safe-delete.js';
@@ -32,6 +32,7 @@ import { stripDevflowTeammateModeFromJson } from '../../core/teammate-mode-clean
32
32
  import { getPackageRoot, isContainedIn } from '../../core/paths.js';
33
33
  import { firstSymbolicLink } from '../../core/linked-path.js';
34
34
  import { restampInstalledCommands } from '../../targets/claude-code/language-stamp.js';
35
+ import { installCommandsAndAgents } from '../../targets/claude-code/installer.js';
35
36
  /**
36
37
  * Where a retired repo-local install lives: `<gitRoot>/.claude` and `<gitRoot>/.devflow`.
37
38
  *
@@ -488,7 +489,7 @@ export function userContentPaths(devflowDir) {
488
489
  const name = `${TRACKER_LEGACY_CONVENTIONS_FILE}.${id}.bak`;
489
490
  return { relPath: name, label: `${name} (previous issue tracker conventions)` };
490
491
  }),
491
- // learning.json — global learning agent tuning config
492
+ // learning.json — global curate agent tuning config
492
493
  { relPath: 'learning.json', label: 'learning.json' },
493
494
  // hud.json — user HUD enable/disable preference and display config
494
495
  { relPath: 'hud.json', label: 'hud.json (HUD configuration)' },
@@ -885,6 +886,89 @@ export async function runDryRunPhase(opts) {
885
886
  }
886
887
  }
887
888
  }
889
+ /**
890
+ * After a selective uninstall removed a retired agent file, write the current commands
891
+ * and agents of the plugins that stay installed.
892
+ *
893
+ * A retired agent file only exists on a machine that ran an older release. That
894
+ * release's commands, for the plugins that stay, still spawn the retired name, and the
895
+ * agents that replaced it are not installed. Removing the file without this step would
896
+ * leave those plugins unable to spawn their agents until the next full `devflow init`.
897
+ *
898
+ * Writes only commands and agents, through the same copy path `devflow init` uses
899
+ * ({@link installCommandsAndAgents}). It does not touch the hooks, the scripts or
900
+ * settings.json, so the notice tells the user to run `devflow init` for those.
901
+ *
902
+ * Never runs in a legacy local scope (D-CLI-NO-SYMLINK): a repository can commit a command
903
+ * file as a symbolic link, and the copy writes through it. The folder guard below does not
904
+ * check files. `devflow init` can not update a legacy local install either, so the warning
905
+ * tells the user to remove it in full.
906
+ *
907
+ * Skipped, with a warning, when there is no readable manifest or it lists no known plugin (the
908
+ * retained set would be a guess), or when a folder is behind a link the caller's guard
909
+ * refuses. Those warnings name `devflow init` as the remedy. When the copy fails, it stops
910
+ * at the first failure: files it wrote before then stay, and the warning names the same
911
+ * remedy. Never throws: an uninstall must finish.
912
+ * Agent model lines are reverted again after the copy, as the selective phase does before
913
+ * its removal, so a freshly written agent carries no external-model line. Like the
914
+ * selective phase, it prints the warnings of that revert only with `verbose`.
915
+ */
916
+ export async function refreshRetainedCommandsAndAgents(opts) {
917
+ const { claudeDir, devflowDir, retained, retiredAgents } = opts;
918
+ const scope = opts.scope ?? 'user';
919
+ const verbose = opts.verbose ?? false;
920
+ const mayChange = opts.mayChange ?? changeAnything;
921
+ const agentsDir = path.join(claudeDir, 'agents', 'devflow');
922
+ const commandsDir = path.join(claudeDir, 'commands', 'devflow');
923
+ const retired = `Removed the agent file(s) of an older Devflow release: ${retiredAgents.join(', ')}.`;
924
+ const remedy = 'Run `devflow init` to update the commands, agents, hooks and scripts of the plugins that stay installed.';
925
+ if (retained.length === 0)
926
+ return;
927
+ if (scope === 'local') {
928
+ p.log.warn(`${retired} Devflow does not rewrite files in a legacy local install, so the remaining commands can still name the removed agents. Remove the legacy local install in full with \`devflow uninstall --scope local\`.`);
929
+ return;
930
+ }
931
+ // readManifest returns null for a missing file and for one it can not parse or validate.
932
+ const manifest = await readManifest(devflowDir).catch(() => null);
933
+ if (manifest === null) {
934
+ p.log.warn(`${retired} There is no readable manifest, so Devflow did not rewrite the remaining files. ${remedy}`);
935
+ return;
936
+ }
937
+ if (manifest.plugins.length === 0) {
938
+ p.log.warn(`${retired} The manifest lists no plugins, so Devflow did not rewrite the remaining files. ${remedy}`);
939
+ return;
940
+ }
941
+ // resolveInstalledPlugins falls back to the whole registry when no manifest name resolves, so
942
+ // the retained set would hold plugins that were never installed.
943
+ if (!manifest.plugins.some(name => DEVFLOW_PLUGINS.some(plugin => plugin.name === name))) {
944
+ p.log.warn(`${retired} The manifest lists no known plugin, so Devflow did not rewrite the remaining files. ${remedy}`);
945
+ return;
946
+ }
947
+ if (!(await mayChange(agentsDir)) || !(await mayChange(commandsDir))) {
948
+ p.log.warn(`${retired} A linked folder blocks the rewrite. ${remedy}`);
949
+ return;
950
+ }
951
+ try {
952
+ await installCommandsAndAgents({
953
+ plugins: retained,
954
+ agentsMap: buildAssetMaps(retained).agentsMap,
955
+ claudeDir,
956
+ learning: manifest.features.learning,
957
+ trackerServers: effectiveTrackerServers(manifest.features.tracker),
958
+ warn: (msg) => p.log.warn(msg),
959
+ });
960
+ }
961
+ catch (err) {
962
+ p.log.warn(`${retired} Devflow could not write the current commands and agents (${err instanceof Error ? err.message : String(err)}). ${remedy}`);
963
+ return;
964
+ }
965
+ try {
966
+ await revertExternalAgents({ installDir: agentsDir, devflowDir, onWarning: (msg) => { if (verbose)
967
+ p.log.warn(msg); } });
968
+ }
969
+ catch { /* the revert is best effort, as in the selective phase */ }
970
+ p.log.info(`${retired} Devflow wrote the current commands and agents of the plugins that stay installed. Run \`devflow init\` to update the hooks and scripts.`);
971
+ }
888
972
  /**
889
973
  * SELECTIVE PHASE (per scope): revert agent model overrides, remove the
890
974
  * selected plugins' assets, and clean up the ambient hook if the ambient
@@ -919,7 +1003,23 @@ export async function runSelectivePhaseForScope(opts) {
919
1003
  }
920
1004
  catch { /* agents dir absent or revert failed — non-fatal */ }
921
1005
  }
922
- await removeSelectedPlugins(claudeDir, selectedPlugins, verbose, installedPlugins, mayChange);
1006
+ const sweeps = await removeSelectedPlugins(claudeDir, selectedPlugins, verbose, installedPlugins, mayChange);
1007
+ // A retired agent file means the install is from an older release, and the commands of the
1008
+ // plugins that stay installed still spawn the name that was just removed. Write their
1009
+ // current commands and agents so the install stays whole. Runs before the language stamp
1010
+ // below, which then restamps the command this wrote.
1011
+ if (sweeps.agents.removed.length > 0) {
1012
+ const removed = new Set(selectedPlugins.map(sp => sp.name));
1013
+ await refreshRetainedCommandsAndAgents({
1014
+ claudeDir,
1015
+ devflowDir,
1016
+ retained: installedPlugins.filter(plugin => !removed.has(plugin.name)),
1017
+ retiredAgents: sweeps.agents.removed,
1018
+ scope,
1019
+ verbose,
1020
+ mayChange,
1021
+ });
1022
+ }
923
1023
  // D-LANGUAGE-FOCUS-STAMP: re-stamp the installed /code-review from the selection that REMAINS.
924
1024
  // A language plugin owns a skill and no command, so removing it deletes the skill while its
925
1025
  // name would stay on the stamped line, and /code-review would spawn a focus whose skill is gone.
@@ -1627,6 +1727,9 @@ export async function removeAllDevFlow(claudeDir, devflowScriptsDir, verbose, ma
1627
1727
  * A folder `mayChange` refuses is not swept at all (D-CLI-NO-SYMLINK,
1628
1728
  * legacyLocalChangeGuard). An entry in a swept folder that is itself a link is
1629
1729
  * only unlinked: `fs.rm` never follows the link it is given.
1730
+ *
1731
+ * Returns what each sweep removed and failed to remove, so a caller can tell that
1732
+ * a retired agent was removed (see {@link refreshRetainedCommandsAndAgents}).
1630
1733
  */
1631
1734
  export async function sweepDevflowNamespaces(claudeDir, verbose, mayChange = changeAnything) {
1632
1735
  const agentsDir = path.join(claudeDir, 'agents', 'devflow');
@@ -1656,6 +1759,7 @@ export async function sweepDevflowNamespaces(claudeDir, verbose, mayChange = cha
1656
1759
  p.log.warn(`Could not remove orphaned ${kind} "${failure.name}" (${reason}) — remove it manually`);
1657
1760
  }
1658
1761
  }
1762
+ return { agents: agentsSweep, commands: commandsSweep, skills: skillsSweep };
1659
1763
  }
1660
1764
  /**
1661
1765
  * Remove only specific plugin assets (selective uninstall).
@@ -1665,6 +1769,8 @@ export async function sweepDevflowNamespaces(claudeDir, verbose, mayChange = cha
1665
1769
  * For skills: only remove skills that are NOT used by any remaining plugin.
1666
1770
  * Each removal passes `mayChange` first, which skips one a symbolic link would
1667
1771
  * redirect in a legacy local install (D-CLI-NO-SYMLINK, legacyLocalChangeGuard).
1772
+ *
1773
+ * Returns what the closing registry-diff sweep removed.
1668
1774
  */
1669
1775
  export async function removeSelectedPlugins(claudeDir, plugins, verbose, installedPlugins = DEVFLOW_PLUGINS, mayChange = changeAnything) {
1670
1776
  const { skills, agents, commands, rules } = computeAssetsToRemove(plugins, installedPlugins);
@@ -1734,6 +1840,6 @@ export async function removeSelectedPlugins(claudeDir, plugins, verbose, install
1734
1840
  // Removes any orphaned files whose names left the registry (retired, renamed,
1735
1841
  // or deleted from all plugins). Spans ALL plugins so assets belonging to
1736
1842
  // non-selected plugins are never swept.
1737
- await sweepDevflowNamespaces(claudeDir, verbose, mayChange);
1843
+ return sweepDevflowNamespaces(claudeDir, verbose, mayChange);
1738
1844
  }
1739
1845
  //# sourceMappingURL=uninstall.js.map
package/dist/cli.js CHANGED
@@ -21,6 +21,7 @@ import { agentsCommand } from './cli/commands/agents.js';
21
21
  import { complianceCommand } from './cli/commands/compliance.js';
22
22
  import { behaviorCommand } from './cli/commands/behavior.js';
23
23
  import { trackerCommand } from './cli/commands/tracker.js';
24
+ import { gatesCommand } from './cli/commands/gates.js';
24
25
  const __filename = fileURLToPath(import.meta.url);
25
26
  const __dirname = dirname(__filename);
26
27
  // Read version from package.json
@@ -51,6 +52,7 @@ program.addCommand(agentsCommand);
51
52
  program.addCommand(complianceCommand);
52
53
  program.addCommand(behaviorCommand);
53
54
  program.addCommand(trackerCommand);
55
+ program.addCommand(gatesCommand);
54
56
  // Handle no command (bare `devflow`) or unknown subcommand.
55
57
  // When Commander sees an unrecognised first argument it does not route to any
56
58
  // registered subcommand; instead the root action fires with that argument
@@ -187,27 +187,27 @@ If no tool produced findings: set `STATIC_FINDINGS` to `(none)`.
187
187
  node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
188
188
  ```
189
189
 
190
- Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> LEARNING=<on|off> KNOWLEDGE=<on|off>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on LEARNING=on KNOWLEDGE=off` instead.
190
+ Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> LEARNING=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on LEARNING=on KNOWLEDGE=off GATE_LEVEL=full` instead.
191
191
 
192
- The accepted line is the only source of these values: the script alone folds the committed `.devflow/project.json`, the personal `.devflow/config.json` and the machine manifest.
192
+ The accepted line is the only source of these values.
193
193
 
194
194
  ### Load DECISIONS_CONTEXT
195
195
 
196
196
  When the settings line says `LEARNING=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
197
197
 
198
- The decisions ledger belongs to the repository, not to one checkout: in a linked worktree it lives in the main worktree, and a session started in a subdirectory reads the copy at the repository root. Locate it with ONE git call, run from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`):
198
+ The decisions ledger belongs to the repository, not to one checkout: a linked worktree reads the main worktree's copy, a subdirectory session the repository root's. Locate it with ONE git call, run from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`):
199
199
 
200
200
  ```bash
201
201
  git -C "{start}" rev-parse --path-format=absolute --show-toplevel --git-common-dir
202
202
  ```
203
203
 
204
- Line 1 is the checkout's toplevel, line 2 the repository's common git directory. A git older than 2.31 echoes `--path-format=absolute` back as a line of its own first. `{ledger}` is the first of these that applies:
204
+ Line 1 is the checkout's toplevel, line 2 the common git directory. A git older than 2.31 echoes `--path-format=absolute` back as a line of its own first. `{ledger}` is the first that applies:
205
205
 
206
206
  1. **The main worktree** — line 2 without its trailing `/.git`, when the output is exactly two lines each beginning with `/`, line 2 ends in `/.git`, and the directory left once it is removed is not your home directory and contains a `.devflow/` directory.
207
207
  2. **The toplevel** — line 1, or on an older git the line after the echoed flag.
208
208
  3. **The start directory itself** — when the command failed or printed no absolute toplevel (outside a git repository).
209
209
 
210
- This is the rule the learning hooks apply (D-LEDGER-MAIN-WORKTREE, D-PROMPT-ROOT), so you read the index the Learning agent writes.
210
+ This is the rule the learning hooks apply, so you read the index the Curate agent writes.
211
211
 
212
212
  **Step 1 — Read the pre-rendered index:**
213
213
 
@@ -216,11 +216,15 @@ Attempt to read `{ledger}/.devflow/learning/index.md`.
216
216
  - If the file exists and contains non-empty content: use that content as `DECISIONS_CONTEXT`.
217
217
  - If the file is absent or empty: set `DECISIONS_CONTEXT` to `(none)`.
218
218
 
219
- The index is one direct file read, written at render time by `render-decisions.cjs` alongside `decisions.md`/`pitfalls.md` — no `.cjs` script runs here, and the index's own footer names the files that hold each entry's full body.
219
+ The index is one direct file read, written at render time by `render-decisions.cjs` — no `.cjs` script runs here.
220
220
 
221
- **Step 2 — Agents apply the decisions:**
221
+ **Step 2 — Slice the index, then hand it on:**
222
222
 
223
- When `DECISIONS_CONTEXT` is not `(none)`, hand it only to the agents whose contract declares it. They follow `devflow:apply-decisions`: scan the index, identify plausibly-relevant entries, Read full entry bodies on demand, and cite verbatim IDs in their reasoning. A host that uses the index in its own thread says so in its own step.
223
+ When `DECISIONS_CONTEXT` is not `(none)`, hand it only to the agents whose contract declares it.
224
+
225
+ Hand each agent that takes `DECISIONS_CONTEXT` a slice, not the whole index: the index lines whose title, scope or area touch the files and task it works on, verbatim, led by `(slice: N of M entries — full index: <absolute index path>)` and closed by the index footer. When unsure, include the line. Siblings over one diff share ONE slice.
226
+
227
+ Those agents follow `devflow:apply-decisions`. A host that uses the index in its own thread says so in its own step.
224
228
 
225
229
  #### Feature Knowledge
226
230
 
@@ -246,7 +250,7 @@ If `index.md` exists and contains at least one entry line, use it for relevance
246
250
 
247
251
  **Step 2 — Fallback: glob frontmatter (if `index.md` is absent or empty):**
248
252
 
249
- Glob `{worktree}/.devflow/features/*/KNOWLEDGE.md`. For each file found, read only its YAML frontmatter block (between the opening and closing `---` delimiters). The frontmatter fields `name`, `description`, and `directories` are the authoritative relevance surface — `index.md` is only a cache.
253
+ Glob `{worktree}/.devflow/features/*/KNOWLEDGE.md`. For each file found, read only its YAML frontmatter block (between the opening and closing `---` delimiters).
250
254
 
251
255
  **Step 3 — Pick relevant KBs:**
252
256
 
@@ -277,7 +281,7 @@ Headings: L5 Rules · L40 Overview · L62 Anti-Patterns · L118 Key Files
277
281
 
278
282
  A KB with no Rules section labels its entries `Rules ({section name}):` and gives them no ID. `FEATURE_KNOWLEDGE` is these blocks; `FEATURE_KNOWLEDGE_RULES` is the same blocks without the `Headings:` line. Both come from this one selection, and each spawn names the variable its recipient takes. If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set both to `(none)`.
279
283
 
280
- **One git call, then direct reads — no `.cjs` script.** After resolving `{worktree}`, this step is 1 index read (or N frontmatter reads on fallback), plus one heading listing and one Rules read per selected KB, bounded by KB count.
284
+ **One git call, then direct reads — no `.cjs` script.**
281
285
 
282
286
  #### Plan Artifact
283
287
 
@@ -306,11 +310,11 @@ Determine which focus analyzers to run using `CHANGED_FILES` (already computed i
306
310
  **Produces:** ANALYZER_OUTPUTS
307
311
  **Requires:** DIFF_RANGE, ANALYSIS_DIR, ACTIVE_FOCUSES, STATIC_FINDINGS, ACCEPTANCE_RULES, PLAN_CONTEXT, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE
308
312
 
309
- Spawn ALL active Diagnose agents **in a single message** (parallel, NOT background):
313
+ Spawn ALL active Debug agents **in a single message** (parallel, NOT background):
310
314
 
311
315
  For each active focus, spawn:
312
316
  ```
313
- Agent(subagent_type="Diagnose", run_in_background=false):
317
+ Agent(subagent_type="Debug", run_in_background=false):
314
318
  "Analyze focusing on {focus}.
315
319
  FOCUS: {focus}
316
320
  DIFF_COMMAND: git diff {DIFF_RANGE}
@@ -408,10 +412,10 @@ Run `/resolve` to process and fix these findings.
408
412
  │ └─ Detect active focuses (security + functional always; integration + usability conditional)
409
413
  │
410
414
  ├─ Phase 5: Bug Analysis (PARALLEL)
411
- │ ├─ Diagnose agent: security (+ STATIC_FINDINGS)
412
- │ ├─ Diagnose agent: functional
413
- │ ├─ Diagnose agent: integration (conditional)
414
- │ └─ Diagnose agent: usability (conditional)
415
+ │ ├─ Debug agent: security (+ STATIC_FINDINGS)
416
+ │ ├─ Debug agent: functional
417
+ │ ├─ Debug agent: integration (conditional)
418
+ │ └─ Debug agent: usability (conditional)
415
419
  │
416
420
  ├─ Phase 6: Synthesis
417
421
  │ └─ Synthesize agent (mode: bug-analysis)
@@ -448,7 +452,7 @@ Run `/resolve` after `/bug-analysis` to fix identified bugs. `/resolve` automati
448
452
  2. **Parallel, not background** — Analyzers spawn in one message with `run_in_background=false`
449
453
  3. **Static + semantic** — Two complementary tracks, each validates the other
450
454
  4. **Incremental by default** — Only analyze new changes unless `--full` specified
451
- 5. **Verify before reporting** — Diagnose agents self-verify every finding
455
+ 5. **Verify before reporting** — Debug agents self-verify every finding
452
456
  6. **Honest reporting** — Display risk level and counts directly from synthesis
453
457
 
454
458
  ## Phase Completion Checklist