devflow-kit 3.3.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.
- package/CHANGELOG.md +47 -0
- package/README.md +8 -4
- package/dist/agents/code-edit.md +133 -0
- package/dist/agents/code-fix.md +165 -0
- package/dist/agents/code.md +187 -0
- package/{src/assets → dist}/agents/design.md +1 -2
- package/{src/assets → dist}/agents/diagnose.md +1 -2
- package/dist/agents/git.md +33 -722
- package/{src/assets → dist}/agents/knowledge.md +12 -5
- package/{src/assets → dist}/agents/research.md +8 -2
- package/{src/assets → dist}/agents/review.md +8 -11
- package/{src/assets → dist}/agents/scrutinize.md +4 -1
- package/dist/agents/skim.md +152 -0
- package/{src/assets → dist}/agents/triage.md +9 -2
- package/dist/cli/commands/behavior-prompts.js +77 -0
- package/dist/cli/commands/behavior.js +123 -0
- package/dist/cli/commands/flags.js +8 -2
- package/dist/cli/commands/init-seed.js +7 -3
- package/dist/cli/commands/init.js +134 -5
- package/dist/cli/commands/learning.js +38 -3
- package/dist/cli/commands/rules.js +16 -0
- package/dist/cli/commands/tracker.js +112 -15
- package/dist/cli/commands/uninstall.js +42 -1
- package/dist/cli.js +2 -0
- package/dist/commands/bug-analysis.md +35 -13
- package/dist/commands/code-review.md +155 -69
- package/dist/commands/debug.md +39 -16
- package/dist/commands/dynamic-build.md +61 -72
- package/dist/commands/dynamic-plan.md +39 -25
- package/dist/commands/dynamic-profile.md +28 -14
- package/dist/commands/dynamic-tickets.md +38 -22
- package/dist/commands/explore.md +18 -16
- package/dist/commands/implement.md +121 -150
- package/dist/commands/plan.md +51 -31
- package/dist/commands/release.md +72 -6
- package/dist/commands/research.md +49 -20
- package/dist/commands/resolve.md +54 -46
- package/dist/commands/self-review.md +38 -25
- package/dist/core/agent-frontmatter.js +101 -0
- package/dist/core/agent-models.js +43 -0
- package/dist/core/assets.js +55 -10
- package/dist/core/claude-md-audit.js +190 -0
- package/dist/core/compliance-compose.js +6 -4
- package/dist/core/feature-switch.js +41 -1
- package/dist/core/flags.js +139 -0
- package/dist/core/fs-atomic.js +8 -3
- package/dist/core/learning-variants.js +213 -0
- package/dist/core/manifest.js +73 -3
- package/dist/core/mds-variants.js +98 -19
- package/dist/core/plugins.js +111 -72
- package/dist/core/project-paths.js +0 -4
- package/dist/core/proxy-log.js +1 -1
- package/dist/core/proxy-state.js +1 -1
- package/dist/core/tracker.js +120 -2
- package/dist/learning-off/agents/code-edit.md +129 -0
- package/dist/learning-off/agents/code-fix.md +161 -0
- package/dist/learning-off/agents/code.md +183 -0
- package/dist/learning-off/agents/design.md +118 -0
- package/dist/learning-off/agents/diagnose.md +210 -0
- package/dist/learning-off/agents/knowledge.md +96 -0
- package/dist/learning-off/agents/research.md +155 -0
- package/dist/learning-off/agents/review.md +224 -0
- package/dist/learning-off/agents/scrutinize.md +120 -0
- package/{src/assets → dist/learning-off}/agents/skim.md +5 -8
- package/dist/learning-off/agents/triage.md +170 -0
- package/dist/learning-off/commands/bug-analysis.md +420 -0
- package/dist/learning-off/commands/code-review.md +530 -0
- package/dist/learning-off/commands/debug.md +314 -0
- package/dist/learning-off/commands/dynamic-build.md +1245 -0
- package/dist/learning-off/commands/dynamic-plan.md +426 -0
- package/dist/learning-off/commands/dynamic-profile.md +214 -0
- package/dist/learning-off/commands/dynamic-tickets.md +634 -0
- package/dist/learning-off/commands/explore.md +210 -0
- package/dist/learning-off/commands/implement.md +774 -0
- package/dist/learning-off/commands/plan.md +671 -0
- package/dist/learning-off/commands/release.md +311 -0
- package/dist/learning-off/commands/research.md +229 -0
- package/dist/learning-off/commands/resolve.md +842 -0
- package/dist/learning-off/commands/self-review.md +266 -0
- package/dist/skills/git/references/learn-conventions.md +27 -3
- package/dist/skills/git/references/pr/check-ci-status.md +19 -0
- package/dist/skills/git/references/pr/check-merge-readiness.md +19 -0
- package/dist/skills/git/references/pr/fetch-review-threads.md +30 -0
- package/dist/skills/git/references/pr/post-resolution-summary.md +18 -0
- package/dist/skills/git/references/pr/post-review-summary.md +20 -0
- package/dist/skills/git/references/pr/resolve-review-threads.md +28 -4
- package/dist/skills/git/references/pr/update-pr-evidence.md +13 -0
- package/dist/skills/git/references/pr/validate-branch.md +26 -0
- package/dist/skills/git/references/tracker/_contract.md +33 -0
- package/dist/skills/git/references/tracker/github/associate-release.md +24 -0
- package/dist/skills/git/references/tracker/github/backlink-shipped-issues.md +31 -1
- package/dist/skills/git/references/tracker/github/create-release.md +30 -1
- package/dist/skills/git/references/tracker/github/ensure-pr-ready.md +89 -2
- package/dist/skills/git/references/tracker/github/ensure-traceable-issue.md +16 -1
- package/dist/skills/git/references/tracker/github/fetch-issue.md +38 -1
- package/dist/skills/git/references/tracker/github/fetch-issues-batch.md +49 -1
- package/dist/skills/git/references/tracker/github/gather-release-evidence.md +29 -0
- package/dist/skills/git/references/tracker/github/manage-debt.md +21 -1
- package/dist/skills/git/references/tracker/github/post-wave-report.md +17 -1
- package/dist/skills/git/references/tracker/github/setup-task.md +53 -1
- package/dist/skills/git/references/tracker/jira/associate-release.md +25 -1
- package/dist/skills/git/references/tracker/jira/backlink-shipped-issues.md +31 -1
- package/dist/skills/git/references/tracker/jira/create-release.md +30 -1
- package/dist/skills/git/references/tracker/jira/ensure-pr-ready.md +89 -2
- package/dist/skills/git/references/tracker/jira/ensure-traceable-issue.md +16 -1
- package/dist/skills/git/references/tracker/jira/fetch-issue.md +38 -1
- package/dist/skills/git/references/tracker/jira/fetch-issues-batch.md +49 -1
- package/dist/skills/git/references/tracker/jira/gather-release-evidence.md +29 -0
- package/dist/skills/git/references/tracker/jira/manage-debt.md +21 -1
- package/dist/skills/git/references/tracker/jira/post-wave-report.md +17 -1
- package/dist/skills/git/references/tracker/jira/setup-task.md +55 -3
- package/dist/skills/git/references/tracker/linear/associate-release.md +25 -1
- package/dist/skills/git/references/tracker/linear/backlink-shipped-issues.md +31 -1
- package/dist/skills/git/references/tracker/linear/create-release.md +30 -1
- package/dist/skills/git/references/tracker/linear/ensure-pr-ready.md +89 -2
- package/dist/skills/git/references/tracker/linear/ensure-traceable-issue.md +16 -1
- package/dist/skills/git/references/tracker/linear/fetch-issue.md +38 -1
- package/dist/skills/git/references/tracker/linear/fetch-issues-batch.md +49 -1
- package/dist/skills/git/references/tracker/linear/gather-release-evidence.md +29 -0
- package/dist/skills/git/references/tracker/linear/manage-debt.md +21 -1
- package/dist/skills/git/references/tracker/linear/post-wave-report.md +17 -1
- package/dist/skills/git/references/tracker/linear/setup-task.md +55 -3
- package/dist/targets/claude-code/agent-type-owner.js +164 -0
- package/dist/targets/claude-code/behavior-install.js +111 -0
- package/dist/targets/claude-code/installer.js +140 -37
- package/dist/targets/claude-code/language-stamp.js +185 -0
- package/dist/targets/claude-code/learning-install.js +497 -0
- package/dist/targets/claude-code/tracker-install.js +33 -16
- package/dist/targets/claude-code/tracker-servers.js +107 -0
- package/package.json +4 -3
- package/src/assets/agents/_partials/_code.mds +109 -0
- package/src/assets/agents/code-edit.mds +81 -0
- package/src/assets/agents/code-fix.mds +113 -0
- package/src/assets/agents/code.mds +135 -0
- package/src/assets/agents/design.mds +148 -0
- package/src/assets/agents/diagnose.mds +225 -0
- package/src/assets/agents/evaluate.md +8 -4
- package/src/assets/agents/explore.md +58 -0
- package/src/assets/agents/git.mds +33 -722
- package/src/assets/agents/knowledge.mds +131 -0
- package/src/assets/agents/learning.md +19 -69
- package/src/assets/agents/research.mds +182 -0
- package/src/assets/agents/review.mds +282 -0
- package/src/assets/agents/scrutinize.mds +135 -0
- package/src/assets/agents/simplify.md +3 -0
- package/src/assets/agents/skim.mds +165 -0
- package/src/assets/agents/synthesize.md +26 -352
- package/src/assets/agents/test.md +8 -0
- package/src/assets/agents/tracker.md +20 -7
- package/src/assets/agents/triage.mds +201 -0
- package/src/assets/agents/validate.md +13 -6
- package/src/assets/commands/_partials/_compliance.mds +41 -4
- package/src/assets/commands/_partials/_decisions.mds +33 -2
- package/src/assets/commands/_partials/_engine.mds +14 -6
- package/src/assets/commands/_partials/_knowledge.mds +25 -12
- package/src/assets/commands/_partials/_preamble.mds +34 -10
- package/src/assets/commands/_partials/_publication.mds +5 -4
- package/src/assets/commands/_partials/_roster.mds +4 -3
- package/src/assets/commands/_partials/_settings.mds +13 -5
- package/src/assets/commands/_partials/_wave.mds +9 -1
- package/src/assets/commands/bug-analysis.mds +27 -5
- package/src/assets/commands/code-review.mds +158 -52
- package/src/assets/commands/debug.mds +41 -3
- package/src/assets/commands/dynamic-build.mds +47 -27
- package/src/assets/commands/dynamic-plan.mds +40 -9
- package/src/assets/commands/dynamic-profile.mds +9 -1
- package/src/assets/commands/dynamic-tickets.mds +21 -6
- package/src/assets/commands/explore.mds +28 -2
- package/src/assets/commands/implement.mds +126 -129
- package/src/assets/commands/plan.mds +58 -14
- package/src/assets/commands/{release.md → release.mds} +30 -26
- package/src/assets/commands/research.mds +42 -11
- package/src/assets/commands/resolve.mds +59 -15
- package/src/assets/commands/self-review.mds +30 -5
- package/src/assets/mds/.mdsroot +4 -0
- package/src/assets/mds/git/_ops.mds +383 -0
- package/src/assets/mds/git/_ops_pr.mds +201 -0
- package/src/assets/mds/git/_ops_steps.mds +147 -0
- package/src/assets/mds/git/_pr.mds +39 -44
- package/src/assets/mds/git/_references.mds +6 -3
- package/src/assets/mds/tracker/_common.mds +5 -5
- package/src/assets/mds/tracker/_contract.mds +73 -0
- package/src/assets/mds/tracker/_github.mds +73 -16
- package/src/assets/mds/tracker/_jira.mds +77 -19
- package/src/assets/mds/tracker/_linear.mds +77 -19
- package/src/assets/mds/tracker/_mcp.mds +2 -2
- package/src/assets/mds/tracker/_steps.mds +98 -0
- package/src/assets/rules/behavior.md +6 -0
- package/src/assets/rules/context-economy.md +10 -0
- package/src/assets/rules/go.md +1 -0
- package/src/assets/rules/java.md +1 -0
- package/src/assets/rules/python.md +1 -0
- package/src/assets/rules/rust.md +1 -0
- package/src/assets/rules/typescript.md +1 -0
- package/src/assets/scripts/claude-md-audit.cjs +611 -0
- package/src/assets/scripts/hooks/assets/orchestrator-charter.md +3 -3
- package/src/assets/scripts/hooks/json-helper.cjs +13 -5
- package/src/assets/scripts/hooks/json-parse +34 -10
- package/src/assets/scripts/hooks/lib/project-paths.cjs +0 -6
- package/src/assets/scripts/hooks/session-start-context +315 -7
- package/src/assets/skills/agent-references/SKILL.md +33 -0
- package/src/assets/skills/agent-references/references/learning/maintain.md +71 -0
- package/src/assets/skills/agent-references/references/synthesize/bug-analysis.md +71 -0
- package/src/assets/skills/agent-references/references/synthesize/design.md +36 -0
- package/src/assets/skills/agent-references/references/synthesize/exploration.md +38 -0
- package/src/assets/skills/agent-references/references/synthesize/planning.md +60 -0
- package/src/assets/skills/agent-references/references/synthesize/research.md +61 -0
- package/src/assets/skills/agent-references/references/synthesize/review.md +76 -0
- package/src/assets/skills/apply-decisions/SKILL.md +1 -1
- package/src/assets/skills/apply-feature-knowledge/SKILL.md +5 -5
- package/src/assets/skills/compliance/SKILL.md +1 -1
- package/src/assets/skills/docs-framework/SKILL.md +80 -83
- package/src/assets/skills/docs-framework/references/patterns.md +14 -25
- package/src/assets/skills/docs-framework/references/violations.md +7 -7
- package/src/assets/skills/feature-knowledge/SKILL.md +43 -12
- package/src/assets/skills/gap-analysis/SKILL.md +0 -16
- package/src/assets/skills/gap-analysis/references/compliance.md +19 -0
- package/src/assets/skills/quality-gates/SKILL.md +1 -1
- package/dist/skills/git/references/pr/ensure-pr-ready.md +0 -24
- package/src/assets/agents/code.md +0 -330
|
@@ -8,7 +8,7 @@ import { getInstallationPaths, getClaudeDirectory, getHomeDirectory, getManagedS
|
|
|
8
8
|
import { getGitRoot } from '../../core/git.js';
|
|
9
9
|
import { isSameLocation } from '../../core/same-location.js';
|
|
10
10
|
import { DEVFLOW_PLUGINS, SKILL_NAMESPACE, getAllSkillNames, getAllAgentNames, getAllCommandNames, parsePluginSelection, resolveFeatureRedirect, prefixSkillName, unprefixSkillName, skillsOf, FEATURE_OWNED_SKILLS } from '../../core/plugins.js';
|
|
11
|
-
import { readManifest } from '../../core/manifest.js';
|
|
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';
|
|
14
14
|
import { removeAmbientHook } from './ambient.js';
|
|
@@ -21,6 +21,7 @@ import { applyProxyTeardownToSettings } from './proxy.js';
|
|
|
21
21
|
import { readProxyState, proxyJsonExists } from '../../core/proxy-state.js';
|
|
22
22
|
import { hudCacheDir } from '../../core/cache.js';
|
|
23
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';
|
|
24
|
+
import { CLAUDE_MD_AUDIT_STAMP_FILE, CLAUDE_MD_AUDIT_STAMP_TMP_PREFIX } from '../../core/claude-md-audit.js';
|
|
24
25
|
import { revertExternalAgents } from '../../core/agent-models.js';
|
|
25
26
|
import { detectShell, getProfilePath } from '../../core/safe-delete.js';
|
|
26
27
|
import { isAlreadyInstalled, removeFromProfile } from '../../core/safe-delete-install.js';
|
|
@@ -30,6 +31,7 @@ import { stripFlags } from '../../core/flags.js';
|
|
|
30
31
|
import { stripDevflowTeammateModeFromJson } from '../../core/teammate-mode-cleanup.js';
|
|
31
32
|
import { getPackageRoot, isContainedIn } from '../../core/paths.js';
|
|
32
33
|
import { firstSymbolicLink } from '../../core/linked-path.js';
|
|
34
|
+
import { restampInstalledCommands } from '../../targets/claude-code/language-stamp.js';
|
|
33
35
|
/**
|
|
34
36
|
* Where a retired repo-local install lives: `<gitRoot>/.claude` and `<gitRoot>/.devflow`.
|
|
35
37
|
*
|
|
@@ -607,6 +609,12 @@ export function installArtifactPaths(devflowDir) {
|
|
|
607
609
|
...TRACKER_ATTEMPTS_NAMES.map(name => ({ relPath: name })),
|
|
608
610
|
{ relPath: TRACKER_LEGACY_ATTEMPTS_FILE },
|
|
609
611
|
{ relPath: TRACKER_ENABLED_FILE },
|
|
612
|
+
// The CLAUDE.md import audit's stamp (D-AUDIT-STAMP): machine state the SessionStart
|
|
613
|
+
// hook and `devflow init` write, holding paths, existence flags and finding keys and no
|
|
614
|
+
// user-authored content. Its sibling temp file, `<stamp>.tmp.<pid>`, is a prefix family:
|
|
615
|
+
// a SIGKILL between the write and the rename leaves one behind.
|
|
616
|
+
{ relPath: CLAUDE_MD_AUDIT_STAMP_FILE },
|
|
617
|
+
{ relPath: CLAUDE_MD_AUDIT_STAMP_TMP_PREFIX, isPrefix: true },
|
|
610
618
|
// The agent's scrubbed staging file, one per invocation under a mktemp name
|
|
611
619
|
// it removes from a trap — a SIGKILL outruns the trap and leaves it behind.
|
|
612
620
|
// A prefix, because the names exist only on disk. Content is a scrubbed copy
|
|
@@ -912,6 +920,39 @@ export async function runSelectivePhaseForScope(opts) {
|
|
|
912
920
|
catch { /* agents dir absent or revert failed — non-fatal */ }
|
|
913
921
|
}
|
|
914
922
|
await removeSelectedPlugins(claudeDir, selectedPlugins, verbose, installedPlugins, mayChange);
|
|
923
|
+
// D-LANGUAGE-FOCUS-STAMP: re-stamp the installed /code-review from the selection that REMAINS.
|
|
924
|
+
// A language plugin owns a skill and no command, so removing it deletes the skill while its
|
|
925
|
+
// name would stay on the stamped line, and /code-review would spawn a focus whose skill is gone.
|
|
926
|
+
// The remaining selection is the retained set the removal above used (installedPlugins minus the
|
|
927
|
+
// selected plugins, D-RETAIN-FROM-MANIFEST), so the stamp and the skills on disk cannot disagree.
|
|
928
|
+
// Narrowly scoped: only the stamped line of a command that is still installed is rewritten, and
|
|
929
|
+
// nothing else converges here. A damaged copy is a warning, never a failure.
|
|
930
|
+
{
|
|
931
|
+
const removed = new Set(selectedPlugins.map(sp => sp.name));
|
|
932
|
+
await restampInstalledCommands({
|
|
933
|
+
claudeDir,
|
|
934
|
+
effectivePlugins: installedPlugins.filter(plugin => !removed.has(plugin.name)),
|
|
935
|
+
warn: (msg) => p.log.warn(msg),
|
|
936
|
+
mayChange,
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
// D-UNINSTALL-DROPS-PLUGIN: the manifest is the install record `devflow init` seeds its plugin
|
|
940
|
+
// selection from (a re-init keeps the prior selection), so a plugin removed here but still listed
|
|
941
|
+
// would be installed again by the next plain init. Take the selected names off the list;
|
|
942
|
+
// knownPlugins and every other key stay.
|
|
943
|
+
// Behind the scope guard like every other write here. A failed write is a warning, never a failure.
|
|
944
|
+
{
|
|
945
|
+
const manifestPath = path.join(devflowDir, 'manifest.json');
|
|
946
|
+
if (await mayChange(manifestPath)) {
|
|
947
|
+
const recorded = await removeManifestPlugins(devflowDir, selectedPlugins.map(sp => sp.name));
|
|
948
|
+
if (!recorded.ok) {
|
|
949
|
+
p.log.warn(`Could not drop the plugin from manifest.json — a later devflow init would install it again: ${recorded.error}`);
|
|
950
|
+
}
|
|
951
|
+
else if (verbose && recorded.removed.length > 0) {
|
|
952
|
+
p.log.success(`Removed ${recorded.removed.join(', ')} from manifest.json`);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
915
956
|
// Clean up ambient hook if ambient plugin is being removed
|
|
916
957
|
if (selectedPlugins.some(sp => sp.name === 'devflow-ambient')) {
|
|
917
958
|
const settingsPath = path.join(claudeDir, 'settings.json');
|
package/dist/cli.js
CHANGED
|
@@ -19,6 +19,7 @@ import { safeDeleteCommand } from './cli/commands/safe-delete.js';
|
|
|
19
19
|
import { proxyCommand } from './cli/commands/proxy.js';
|
|
20
20
|
import { agentsCommand } from './cli/commands/agents.js';
|
|
21
21
|
import { complianceCommand } from './cli/commands/compliance.js';
|
|
22
|
+
import { behaviorCommand } from './cli/commands/behavior.js';
|
|
22
23
|
import { trackerCommand } from './cli/commands/tracker.js';
|
|
23
24
|
const __filename = fileURLToPath(import.meta.url);
|
|
24
25
|
const __dirname = dirname(__filename);
|
|
@@ -48,6 +49,7 @@ program.addCommand(safeDeleteCommand);
|
|
|
48
49
|
program.addCommand(proxyCommand);
|
|
49
50
|
program.addCommand(agentsCommand);
|
|
50
51
|
program.addCommand(complianceCommand);
|
|
52
|
+
program.addCommand(behaviorCommand);
|
|
51
53
|
program.addCommand(trackerCommand);
|
|
52
54
|
// Handle no command (bare `devflow`) or unknown subcommand.
|
|
53
55
|
// When Commander sees an unrecognised first argument it does not route to any
|
|
@@ -38,7 +38,7 @@ git -C "{start}" rev-parse --show-toplevel
|
|
|
38
38
|
and using its one-line output. If the command fails (outside a git repository), `{worktree}` is the start directory itself. Every docs path below is written `{worktree}/.devflow/docs/…`; a repo-relative docs path handed to an agent always travels with a `WORKTREE_PATH` naming the checkout it is relative to.
|
|
39
39
|
|
|
40
40
|
Render the test-plan block from `/implement`'s evidence file, and from nothing else:
|
|
41
|
-
1. `branch_slug` is `git branch --show-current` with every `/` replaced by `-`.
|
|
41
|
+
1. `branch_slug` is `git -C "{worktree}" branch --show-current` with every `/` replaced by `-`.
|
|
42
42
|
2. Only when `branch_slug` matches `^[A-Za-z0-9._-]{1,200}$` and the file exists, run (the path double-quoted):
|
|
43
43
|
|
|
44
44
|
```bash
|
|
@@ -177,12 +177,24 @@ If no tool produced findings: set `STATIC_FINDINGS` to `(none)`.
|
|
|
177
177
|
|
|
178
178
|
### Phase 3: Context Loading
|
|
179
179
|
|
|
180
|
-
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, PLAN_CONTEXT, ACCEPTANCE_RULES
|
|
180
|
+
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, PLAN_CONTEXT, ACCEPTANCE_RULES
|
|
181
181
|
|
|
182
182
|
#### Decisions Index
|
|
183
183
|
|
|
184
|
+
**Resolve the settings line** once per worktree root, reusing a line this run already resolved for the same root. `{root}` is the worktree the values are for — the repository root when the run has one worktree:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
188
|
+
```
|
|
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.
|
|
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.
|
|
193
|
+
|
|
184
194
|
### Load DECISIONS_CONTEXT
|
|
185
195
|
|
|
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
|
+
|
|
186
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`):
|
|
187
199
|
|
|
188
200
|
```bash
|
|
@@ -206,9 +218,9 @@ Attempt to read `{ledger}/.devflow/learning/index.md`.
|
|
|
206
218
|
|
|
207
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.
|
|
208
220
|
|
|
209
|
-
**Step 2 —
|
|
221
|
+
**Step 2 — Agents apply the decisions:**
|
|
210
222
|
|
|
211
|
-
When `DECISIONS_CONTEXT` is not `(none)`, follow `devflow:apply-decisions
|
|
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.
|
|
212
224
|
|
|
213
225
|
#### Feature Knowledge
|
|
214
226
|
|
|
@@ -240,27 +252,37 @@ Glob `{worktree}/.devflow/features/*/KNOWLEDGE.md`. For each file found, read on
|
|
|
240
252
|
|
|
241
253
|
Match the current task area and description against each index line (or frontmatter `description` + `directories` on fallback). Select entries whose documented area overlaps the current task. This is a relevance judgment — prefer specificity over breadth.
|
|
242
254
|
|
|
243
|
-
**Step 4 — Read selected
|
|
255
|
+
**Step 4 — Read each selected KB's Rules:**
|
|
256
|
+
|
|
257
|
+
For each selected entry, `{kb}` is `{worktree}/.devflow/features/{slug}/KNOWLEDGE.md`:
|
|
258
|
+
|
|
259
|
+
1. List its `##` headings with line numbers through Bash: `command grep -n '^## ' "{kb}"`. This only locates sections; the text of a KB comes from the Read view alone.
|
|
260
|
+
2. Read the `## Rules` range (its line to the next heading) with the Read tool, using `offset` and `limit`, and choose the one to three bullets most relevant to the current task. The choice is yours, made per KB.
|
|
261
|
+
3. If the KB has no `## Rules` section, choose one to three entries from its `## Anti-Patterns` or `## Gotchas` range the same way, and label them by that section's name instead of an ID.
|
|
244
262
|
|
|
245
|
-
|
|
263
|
+
When a KB contradicts the code you observe, **trust the code** — the code is the freshness mechanism; the KB may lag behind. A missing Rules section, a missing heading list and `(none)` are legitimate states, not errors.
|
|
246
264
|
|
|
247
|
-
**Step 5 — Set FEATURE_KNOWLEDGE:**
|
|
265
|
+
**Step 5 — Set FEATURE_KNOWLEDGE and FEATURE_KNOWLEDGE_RULES:**
|
|
248
266
|
|
|
249
|
-
|
|
267
|
+
Write one block per selected KB. Paste each bullet verbatim from the Read view, never from a shell view. The path is relative to the checkout root; an agent resolves it under `WORKTREE_PATH` when one is provided.
|
|
250
268
|
|
|
251
269
|
```
|
|
252
270
|
--- Feature knowledge: {slug} ---
|
|
253
|
-
{
|
|
271
|
+
KB: .devflow/features/{slug}/KNOWLEDGE.md
|
|
272
|
+
Rules:
|
|
273
|
+
- **KB-AP-2** {bullet text, verbatim}
|
|
274
|
+
- **KB-INV-1** {bullet text, verbatim}
|
|
275
|
+
Headings: L5 Rules · L40 Overview · L62 Anti-Patterns · L118 Key Files
|
|
254
276
|
```
|
|
255
277
|
|
|
256
|
-
If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set
|
|
278
|
+
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)`.
|
|
257
279
|
|
|
258
|
-
**One git call, then direct
|
|
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.
|
|
259
281
|
|
|
260
282
|
#### Plan Artifact
|
|
261
283
|
|
|
262
|
-
1. List `{worktree}/.devflow/docs/design/*.md`
|
|
263
|
-
2. Read the most recent file
|
|
284
|
+
1. List the design plans: `{worktree}/.devflow/docs/design/*.md` (a `/plan` artifact) and `{worktree}/.devflow/docs/design/*/*/*-plan.md` (a `/dynamic-plan` per-ticket plan). Sort by timestamp, newest first, and scan the 10 most recent. A `/plan` artifact's timestamp is the `YYYY-MM-DD_HHMM` before its `.md`; a per-ticket plan's is the name of its parent directory. Never sort by file name, which starts with an issue ID or a ticket slug. A per-ticket plan counts only when its `{ticket-slug}` (its file name without `-plan.md`) appears in the worktree's branch name
|
|
285
|
+
2. Read the most recent file that carries an `## Acceptance Criteria` section
|
|
264
286
|
3. Extract `## Acceptance Criteria` section → parse into table: `| ID | Criterion | Type | Testable Condition |`
|
|
265
287
|
4. Set `PLAN_CONTEXT` to plan summary; `ACCEPTANCE_RULES` to the table
|
|
266
288
|
5. If no plan files exist or section not found: `PLAN_CONTEXT=(none)`, `ACCEPTANCE_RULES=(none)`
|
|
@@ -22,9 +22,10 @@ Run a comprehensive code review of the current branch by spawning parallel revie
|
|
|
22
22
|
|
|
23
23
|
**Produces:** WORKTREES
|
|
24
24
|
|
|
25
|
-
1. **Discover reviewable worktrees
|
|
26
|
-
- Run `git worktree list --porcelain`
|
|
27
|
-
- Invoke the `devflow:worktree-support` skill, then Read its `references/discovery.md` from the skill's base directory for the full 7-step algorithm; the canonical protected branch list stays in the skill
|
|
25
|
+
1. **Discover reviewable worktrees**:
|
|
26
|
+
- Run `git worktree list --porcelain` and count the worktrees it lists
|
|
27
|
+
- **More than one listed:** Invoke the `devflow:worktree-support` skill, then Read its `references/discovery.md` from the skill's base directory for the full 7-step algorithm; the canonical protected branch list stays in the skill. Parse the list, filter (skip protected/detached/mid-rebase), dedup by branch, sort by recent commit
|
|
28
|
+
- **Exactly one listed:** load neither the skill nor the reference — that worktree is the only candidate, and Step 0c's Git agent validates its branch
|
|
28
29
|
2. **If `--path` flag provided:** use only that worktree, skip discovery
|
|
29
30
|
**`--path` validation**: Before proceeding, verify the path exists as a directory and appears in `git worktree list` output. If not: report error and stop.
|
|
30
31
|
3. **If only 1 reviewable worktree** (the common case): proceed as single-worktree flow — zero behavior change
|
|
@@ -34,8 +35,6 @@ Run a comprehensive code review of the current branch by spawning parallel revie
|
|
|
34
35
|
|
|
35
36
|
**Produces:** COMPLIANCE_ACTIVE, COMPLIANCE_FRAMEWORKS
|
|
36
37
|
|
|
37
|
-
**Resolve the compliance lens** for each worktree root, from its settings line (every framework reference is installed on every machine, so no file check decides it):
|
|
38
|
-
|
|
39
38
|
**Resolve the settings line** once per worktree root, reusing a line this run already resolved for the same root. `{root}` is the worktree the values are for — the repository root when the run has one worktree:
|
|
40
39
|
|
|
41
40
|
```bash
|
|
@@ -46,6 +45,8 @@ Accept the output only when it is exactly two lines: `exit=0` last and, before i
|
|
|
46
45
|
|
|
47
46
|
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.
|
|
48
47
|
|
|
48
|
+
**Resolve the compliance lens** for each worktree root, from its settings line — the line resolved above for that root, by the settings block when this run has not yet resolved it (every framework reference is installed on every machine, so no file check decides it).
|
|
49
|
+
|
|
49
50
|
**Set the compliance lens** from that line: `COMPLIANCE_FRAMEWORKS` is the settings line's `COMPLIANCE` with `generic` written `none`: `off`, `none`, or the framework ids the machine and this repository declare.
|
|
50
51
|
|
|
51
52
|
`COMPLIANCE_ACTIVE` is `true` unless `COMPLIANCE_FRAMEWORKS` is `off`.
|
|
@@ -71,9 +72,9 @@ Set `EVIDENCE_POLICY`, `ISSUE_REQUIRED`, `APPLY_CONVENTIONS` and `REQUIRE_NON_AU
|
|
|
71
72
|
**Requires:** WORKTREES
|
|
72
73
|
|
|
73
74
|
Discover PR description guidance from plan artifact (per worktree):
|
|
74
|
-
1. List `{worktree}/.devflow/docs/design/*.md`
|
|
75
|
-
2. Sort by timestamp
|
|
76
|
-
3. Read the most recent file, extract `## PR Description Guidance` section
|
|
75
|
+
1. List the design plans: `{worktree}/.devflow/docs/design/*.md` (a `/plan` artifact) and `{worktree}/.devflow/docs/design/*/*/*-plan.md` (a `/dynamic-plan` per-ticket plan)
|
|
76
|
+
2. Sort by timestamp, newest first, and scan the 10 most recent. A `/plan` artifact's timestamp is the `YYYY-MM-DD_HHMM` before its `.md`; a per-ticket plan's is the name of its parent directory. Never sort by file name, which starts with an issue ID or a ticket slug. A per-ticket plan counts only when its `{ticket-slug}` (its file name without `-plan.md`) appears in the worktree's branch name
|
|
77
|
+
3. Read the most recent file that carries the section, extract `## PR Description Guidance` section
|
|
77
78
|
4. If no plan files exist or section not found, set `PR_DESCRIPTION_GUIDANCE` to `(none)`
|
|
78
79
|
|
|
79
80
|
Render the test-plan block (per worktree) from `/implement`'s evidence file, and from nothing else:
|
|
@@ -176,28 +177,56 @@ MAX_REVIEW_CYCLES = 10
|
|
|
176
177
|
|
|
177
178
|
For each reviewable worktree, call:
|
|
178
179
|
|
|
179
|
-
**Resolve
|
|
180
|
+
**Resolve `REVIEW_PUBLICATION` per worktree:** take `REVIEW_PUBLICATION` from that worktree's settings line — the line resolved above for `{root}`, the worktree's root, by the settings block when this run has not yet resolved that root; multi-worktree repos may resolve different values per worktree. The line already caps the personal choice at the team's (D-PUBLICATION-CEILING), so it is `off`, `auto` or `full`, and `off` when the line was unresolvable.
|
|
181
|
+
|
|
182
|
+
**Evidence stub:** only when `EVIDENCE_POLICY` is `required`, a resolved `off` becomes `stub`, so a counts-only record still reaches the PR. `stub` is never a config value: the settings line never carries it.
|
|
183
|
+
|
|
184
|
+
Note: `auto` is NOT fail-open — under `auto`, the Git agent probes the repository visibility and treats any error or unrecognised value as PUBLIC (mode STUB). What each value does is decided by the Git agent's publication gate (`references/publication-gate.md` step 2); this partial only resolves the value.
|
|
185
|
+
|
|
186
|
+
### Phase 1: Analyze Changed Files
|
|
187
|
+
|
|
188
|
+
**Produces:** REVIEW_FOCUS_LIST, DIFF_CLASS, DIFF_FILES
|
|
189
|
+
**Requires:** DIFF_RANGE, REVIEW_DIR, COMPLIANCE_ACTIVE (from Step 0b)
|
|
190
|
+
|
|
191
|
+
Per worktree, in order. Each `git` command here writes to a file and prints nothing.
|
|
192
|
+
|
|
193
|
+
#### Step 1.1: Classify the diff
|
|
194
|
+
|
|
195
|
+
**Produces:** DIFF_CLASS, CHANGED_PATHS, REVIEW_FOCUS_LIST (reduced classes)
|
|
196
|
+
**Requires:** DIFF_RANGE, REVIEW_DIR
|
|
197
|
+
|
|
198
|
+
List the changed paths into `{REVIEW_DIR}/paths.txt` and print only the line count (drop `-C "{WORKTREE_PATH}"` when there is no `WORKTREE_PATH`):
|
|
180
199
|
|
|
181
200
|
```bash
|
|
182
|
-
|
|
201
|
+
git -C "{WORKTREE_PATH}" diff --name-only --no-renames {DIFF_RANGE} > "{REVIEW_DIR}/paths.txt"
|
|
202
|
+
wc -l < "{REVIEW_DIR}/paths.txt"
|
|
183
203
|
```
|
|
184
204
|
|
|
185
|
-
|
|
205
|
+
Read `paths.txt` once when the count is about 40 or fewer, and in ranges of about 40 lines (Read with offset and limit) when it is more. `--no-renames` lists a moved file under its old path and its new one, so a move cannot take a file out of its own class.
|
|
186
206
|
|
|
187
|
-
|
|
207
|
+
Set `DIFF_CLASS` by these rules, in order; the first that decides wins:
|
|
188
208
|
|
|
189
|
-
**
|
|
209
|
+
1. **Instruction and config paths are `code`.** Any changed path that is `CLAUDE.md`, `AGENTS.md`, under `.claude/` or `src/assets/`, a `*.mds` file, under a plugin's `agents/`, `skills/` or `commands/` directory, `.devflow/project.json`, `.devflow/conventions.md`, or a manifest or build file (`package.json`, `go.mod`, `Cargo.toml`, `pyproject.toml`, `requirements*.txt`, `CMakeLists.txt`). This rule runs first, so a diff made only of such files is `code` and never `docs-only`.
|
|
210
|
+
2. **`docs-only`.** Every changed path matches `*.md`, `*.mdx`, `*.rst`, `*.txt`, `docs/**` or `CHANGELOG*`.
|
|
211
|
+
3. **`tests-only`.** Every changed path matches `tests/**`, `**/__tests__/**`, `*.test.*`, `*.spec.*`, `*_test.go`, `test_*.py` or `*_test.py`.
|
|
212
|
+
4. **`lockfile-only`.** Every changed path is `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, `bun.lockb`, `Cargo.lock`, `go.sum`, `poetry.lock`, `uv.lock`, `Gemfile.lock` or `composer.lock`.
|
|
213
|
+
5. **Mixed non-code.** Every changed path matches the docs, tests or lockfile patterns, but no single rule above holds (docs with tests, tests with a lockfile): `DIFF_CLASS` names each class involved.
|
|
214
|
+
6. **Fail-safe is `code`.** A changed path that matches no class pattern makes the diff `code`, and so does an empty path list. A manifest change is `code` and never `lockfile-only`.
|
|
190
215
|
|
|
191
|
-
|
|
216
|
+
Each reduced class runs only its focus set, every member reading `diff.patch`:
|
|
192
217
|
|
|
193
|
-
|
|
218
|
+
- `docs-only`: documentation, consistency, security
|
|
219
|
+
- `tests-only`: testing, reliability, consistency, security
|
|
220
|
+
- `lockfile-only`: dependencies, security
|
|
194
221
|
|
|
195
|
-
|
|
222
|
+
A mixed non-code diff runs the union of the sets of the classes it holds. Language and conditional triggers inside a reduced class are suppressed: they add no focus, and Step 1.2 applies to the `code` class only.
|
|
196
223
|
|
|
197
|
-
|
|
198
|
-
**Requires:** DIFF_RANGE, COMPLIANCE_ACTIVE (from Step 0b)
|
|
224
|
+
#### Step 1.2: Choose the focuses
|
|
199
225
|
|
|
200
|
-
|
|
226
|
+
**Produces:** REVIEW_FOCUS_LIST (code class)
|
|
227
|
+
**Requires:** DIFF_CLASS, CHANGED_PATHS, COMPLIANCE_ACTIVE
|
|
228
|
+
|
|
229
|
+
When `DIFF_CLASS` is `code`, read the file types from the paths in `paths.txt` to determine conditional reviews:
|
|
201
230
|
|
|
202
231
|
| Condition | Adds Review |
|
|
203
232
|
|-----------|-------------|
|
|
@@ -216,20 +245,49 @@ Per worktree, detect file types in diff using `DIFF_RANGE` to determine conditio
|
|
|
216
245
|
|
|
217
246
|
If `COMPLIANCE_ACTIVE` AND the diff touches regulated surface (data models, auth flows, logging/observability, payments, IaC, retention): add `compliance` to REVIEW_FOCUS_LIST for this worktree.
|
|
218
247
|
|
|
219
|
-
**Language focus
|
|
248
|
+
**Language focus stamp.** The eight language focuses — `typescript`, `react`, `accessibility`, `ui-design`, `go`, `java`, `python`, `rust` — ship with optional plugins, and the installer stamps the ones installed on this machine onto this line, rewriting it on every install and on `uninstall --plugin`:
|
|
249
|
+
|
|
250
|
+
Installed language focuses: (none)
|
|
251
|
+
|
|
252
|
+
A language focus is spawned only when its file-type condition above fires AND its name appears in that stamped line. A focus missing from the line is never spawned, even when its trigger fires. The eight core focuses are unconditional and are never stamp-gated.
|
|
253
|
+
|
|
254
|
+
#### Step 1.3: Write the diff files
|
|
255
|
+
|
|
256
|
+
**Produces:** DIFF_FILES
|
|
257
|
+
**Requires:** DIFF_RANGE, REVIEW_DIR, REVIEW_FOCUS_LIST
|
|
258
|
+
|
|
259
|
+
Write `diff.patch` once per worktree, by redirect:
|
|
220
260
|
|
|
221
261
|
```bash
|
|
222
|
-
|
|
262
|
+
git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE} > "{REVIEW_DIR}/diff.patch"
|
|
223
263
|
```
|
|
224
264
|
|
|
225
|
-
|
|
265
|
+
It holds the whole diff of `DIFF_RANGE`. On a `code` diff, add one patch for each language focus in REVIEW_FOCUS_LIST, by the same command with quoted pathspecs from this table:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE} -- '<pathspec>' ... > "{REVIEW_DIR}/diff-{focus}.patch"
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
| Focus | Pathspecs |
|
|
272
|
+
|-------|-----------|
|
|
273
|
+
| typescript | `'*.ts' '*.tsx'` |
|
|
274
|
+
| react, accessibility | `'*.tsx' '*.jsx'` |
|
|
275
|
+
| ui-design | `'*.tsx' '*.jsx' '*.css' '*.scss'` |
|
|
276
|
+
| go | `'*.go'` |
|
|
277
|
+
| java | `'*.java'` |
|
|
278
|
+
| python | `'*.py'` |
|
|
279
|
+
| rust | `'*.rs'` |
|
|
280
|
+
|
|
281
|
+
The core, database, dependencies, documentation and compliance focuses, and every reduced-class focus, read `diff.patch`. A language focus sees only its own extensions and reaches anything else through `DIFF_RANGE`. Set `DIFF_FILES` to the files written. They live in `REVIEW_DIR`, under the gitignored `.devflow/` tree, with `paths.txt`: never committed, posted or passed to the Git agent.
|
|
226
282
|
|
|
227
283
|
### Phase 1b: Load Decisions Index
|
|
228
284
|
|
|
229
|
-
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, COMPLIANCE_FRAMEWORKS (carried from Step 0b)
|
|
285
|
+
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, COMPLIANCE_FRAMEWORKS (carried from Step 0b)
|
|
230
286
|
|
|
231
287
|
### Load DECISIONS_CONTEXT
|
|
232
288
|
|
|
289
|
+
When the settings line says `LEARNING=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
|
|
290
|
+
|
|
233
291
|
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`):
|
|
234
292
|
|
|
235
293
|
```bash
|
|
@@ -253,9 +311,9 @@ Attempt to read `{ledger}/.devflow/learning/index.md`.
|
|
|
253
311
|
|
|
254
312
|
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.
|
|
255
313
|
|
|
256
|
-
**Step 2 —
|
|
314
|
+
**Step 2 — Agents apply the decisions:**
|
|
257
315
|
|
|
258
|
-
When `DECISIONS_CONTEXT` is not `(none)`, follow `devflow:apply-decisions
|
|
316
|
+
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.
|
|
259
317
|
|
|
260
318
|
This produces a compact index of active ADR/PF entries. Pass `DECISIONS_CONTEXT` to all Review agents. Review agents use `devflow:apply-decisions` to Read full entry bodies on demand.
|
|
261
319
|
|
|
@@ -287,56 +345,73 @@ Glob `{worktree}/.devflow/features/*/KNOWLEDGE.md`. For each file found, read on
|
|
|
287
345
|
|
|
288
346
|
Match the current task area and description against each index line (or frontmatter `description` + `directories` on fallback). Select entries whose documented area overlaps the current task. This is a relevance judgment — prefer specificity over breadth.
|
|
289
347
|
|
|
290
|
-
**Step 4 — Read selected
|
|
348
|
+
**Step 4 — Read each selected KB's Rules:**
|
|
349
|
+
|
|
350
|
+
For each selected entry, `{kb}` is `{worktree}/.devflow/features/{slug}/KNOWLEDGE.md`:
|
|
351
|
+
|
|
352
|
+
1. List its `##` headings with line numbers through Bash: `command grep -n '^## ' "{kb}"`. This only locates sections; the text of a KB comes from the Read view alone.
|
|
353
|
+
2. Read the `## Rules` range (its line to the next heading) with the Read tool, using `offset` and `limit`, and choose the one to three bullets most relevant to the current task. The choice is yours, made per KB.
|
|
354
|
+
3. If the KB has no `## Rules` section, choose one to three entries from its `## Anti-Patterns` or `## Gotchas` range the same way, and label them by that section's name instead of an ID.
|
|
291
355
|
|
|
292
|
-
|
|
356
|
+
When a KB contradicts the code you observe, **trust the code** — the code is the freshness mechanism; the KB may lag behind. A missing Rules section, a missing heading list and `(none)` are legitimate states, not errors.
|
|
293
357
|
|
|
294
|
-
**Step 5 — Set FEATURE_KNOWLEDGE:**
|
|
358
|
+
**Step 5 — Set FEATURE_KNOWLEDGE and FEATURE_KNOWLEDGE_RULES:**
|
|
295
359
|
|
|
296
|
-
|
|
360
|
+
Write one block per selected KB. Paste each bullet verbatim from the Read view, never from a shell view. The path is relative to the checkout root; an agent resolves it under `WORKTREE_PATH` when one is provided.
|
|
297
361
|
|
|
298
362
|
```
|
|
299
363
|
--- Feature knowledge: {slug} ---
|
|
300
|
-
{
|
|
364
|
+
KB: .devflow/features/{slug}/KNOWLEDGE.md
|
|
365
|
+
Rules:
|
|
366
|
+
- **KB-AP-2** {bullet text, verbatim}
|
|
367
|
+
- **KB-INV-1** {bullet text, verbatim}
|
|
368
|
+
Headings: L5 Rules · L40 Overview · L62 Anti-Patterns · L118 Key Files
|
|
301
369
|
```
|
|
302
370
|
|
|
303
|
-
If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set
|
|
371
|
+
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)`.
|
|
304
372
|
|
|
305
|
-
**One git call, then direct
|
|
373
|
+
**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.
|
|
306
374
|
|
|
307
375
|
Pass `FEATURE_KNOWLEDGE` to all Review agents alongside `DECISIONS_CONTEXT`.
|
|
308
376
|
|
|
309
377
|
### Phase 2: Run Reviews (Parallel)
|
|
310
378
|
|
|
311
379
|
**Produces:** REVIEW_FOCUS_OUTPUTS
|
|
312
|
-
**Requires:** DIFF_RANGE, REVIEW_DIR, TIMESTAMP, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, PR_DESCRIPTION, PRIOR_RESOLUTIONS, REVIEW_FOCUS_LIST
|
|
313
|
-
|
|
314
|
-
Spawn Review agents **in a single message
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
|
320
|
-
|
|
321
|
-
|
|
|
322
|
-
|
|
|
323
|
-
|
|
|
324
|
-
|
|
|
325
|
-
|
|
|
326
|
-
|
|
|
327
|
-
|
|
|
328
|
-
|
|
|
329
|
-
|
|
|
330
|
-
|
|
|
331
|
-
|
|
|
332
|
-
|
|
|
333
|
-
|
|
|
334
|
-
|
|
|
335
|
-
|
|
|
336
|
-
|
|
|
337
|
-
|
|
|
338
|
-
|
|
339
|
-
|
|
380
|
+
**Requires:** DIFF_RANGE, REVIEW_DIR, TIMESTAMP, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, PR_DESCRIPTION, PRIOR_RESOLUTIONS, REVIEW_FOCUS_LIST, DIFF_CLASS, DIFF_FILES
|
|
381
|
+
|
|
382
|
+
Spawn Review agents **in a single message**, for the focus set `DIFF_CLASS` selects (max 20 per worktree):
|
|
383
|
+
|
|
384
|
+
- `code`: the 8 core reviews on the full `diff.patch`, plus the language and conditional focuses Phase 1 added.
|
|
385
|
+
- `docs-only`, `tests-only`, `lockfile-only`: only the reduced set Phase 1 names, each reading `diff.patch`; a mixed non-code diff runs the union. No language or conditional focus is spawned, whatever its trigger.
|
|
386
|
+
|
|
387
|
+
| Focus | Runs | Pattern Skill | DIFF_FILE |
|
|
388
|
+
|-------|------|---------------|-----------|
|
|
389
|
+
| security | ✓ | devflow:security | diff.patch |
|
|
390
|
+
| architecture | ✓ | devflow:architecture | diff.patch |
|
|
391
|
+
| performance | ✓ | devflow:performance | diff.patch |
|
|
392
|
+
| complexity | ✓ | devflow:complexity | diff.patch |
|
|
393
|
+
| consistency | ✓ | devflow:consistency | diff.patch |
|
|
394
|
+
| regression | ✓ | devflow:regression | diff.patch |
|
|
395
|
+
| testing | ✓ | devflow:testing | diff.patch |
|
|
396
|
+
| reliability | ✓ | devflow:reliability | diff.patch |
|
|
397
|
+
| typescript | stamp-gated | devflow:typescript | diff-typescript.patch |
|
|
398
|
+
| react | stamp-gated | devflow:react | diff-react.patch |
|
|
399
|
+
| accessibility | stamp-gated | devflow:accessibility | diff-accessibility.patch |
|
|
400
|
+
| ui-design | stamp-gated | devflow:ui-design | diff-ui-design.patch |
|
|
401
|
+
| go | stamp-gated | devflow:go | diff-go.patch |
|
|
402
|
+
| java | stamp-gated | devflow:java | diff-java.patch |
|
|
403
|
+
| python | stamp-gated | devflow:python | diff-python.patch |
|
|
404
|
+
| rust | stamp-gated | devflow:rust | diff-rust.patch |
|
|
405
|
+
| database | conditional | devflow:database | diff.patch |
|
|
406
|
+
| dependencies | conditional | devflow:dependencies | diff.patch |
|
|
407
|
+
| documentation | conditional | devflow:documentation | diff.patch |
|
|
408
|
+
| compliance | diff-driven | devflow:compliance | diff.patch |
|
|
409
|
+
|
|
410
|
+
Review agent count: `code` runs 8 core, +1-12 added by Phase 1 (max 20 total per worktree); a reduced class or a mix runs 2-6.
|
|
411
|
+
|
|
412
|
+
**Set the compliance focus directive** from `COMPLIANCE_FRAMEWORKS`. `COMPLIANCE_FOCUS_DIRECTIVE` is this one line, with `<ids>` replaced by the value of `COMPLIANCE_FRAMEWORKS`; only the compliance focus's spawn carries it:
|
|
413
|
+
|
|
414
|
+
> For this compliance focus, invoke Skill(skill="devflow:compliance") and load references/{id}.md only for the ids in <ids> (none: generic controls only); never fabricate guidance for a framework you were not given.
|
|
340
415
|
|
|
341
416
|
Each Review agent invocation (all in one message, **NOT background**):
|
|
342
417
|
```
|
|
@@ -345,12 +420,13 @@ Agent(subagent_type="Review", run_in_background=false):
|
|
|
345
420
|
Follow 6-step process from devflow:review-methodology.
|
|
346
421
|
PR: #{pr_number}, Base: {base_branch}
|
|
347
422
|
WORKTREE_PATH: {worktree_path} (omit if cwd)
|
|
348
|
-
|
|
423
|
+
DIFF_FILE: {diff_file} (absolute: {REVIEW_DIR}/diff.patch, or {REVIEW_DIR}/diff-{focus}.patch for a language focus, per the table)
|
|
424
|
+
DIFF_RANGE: {DIFF_RANGE} (information only)
|
|
349
425
|
DECISIONS_CONTEXT: {decisions_context}
|
|
350
426
|
FEATURE_KNOWLEDGE: {feature_knowledge}
|
|
351
427
|
PR_DESCRIPTION: <pr-description>{pr_description}</pr-description>
|
|
352
428
|
PRIOR_RESOLUTIONS: <prior-resolution-summary>{prior_resolutions}</prior-resolution-summary>
|
|
353
|
-
|
|
429
|
+
{COMPLIANCE_FOCUS_DIRECTIVE} (compliance focus only)
|
|
354
430
|
If PRIOR_RESOLUTIONS is not (none), follow Cross-Cycle Awareness in review.md.
|
|
355
431
|
Follow devflow:apply-decisions to scan the index and Read full ADR/PF bodies on demand.
|
|
356
432
|
Follow devflow:apply-feature-knowledge for FEATURE_KNOWLEDGE — feature-specific patterns and anti-patterns inform findings.
|
|
@@ -425,13 +501,15 @@ In multi-worktree mode, report results per worktree.
|
|
|
425
501
|
├─ Per worktree (SEQUENTIAL — one worktree at a time):
|
|
426
502
|
│ │
|
|
427
503
|
│ ├─ Phase 1: Analyze changed files
|
|
428
|
-
│ │
|
|
504
|
+
│ │ ├─ Classify the diff (paths.txt → DIFF_CLASS)
|
|
505
|
+
│ │ ├─ Choose the focuses (code class: file types + the language stamp)
|
|
506
|
+
│ │ └─ Write diff.patch and diff-{focus}.patch, by redirect
|
|
429
507
|
│ │
|
|
430
508
|
│ ├─ Phase 2: Reviews (PARALLEL within worktree)
|
|
431
|
-
│ │ ├─ Review
|
|
432
|
-
│ │
|
|
433
|
-
│ │ ├─
|
|
434
|
-
│ │ └─
|
|
509
|
+
│ │ ├─ code: Review agents security, architecture, performance, complexity,
|
|
510
|
+
│ │ │ consistency, regression, testing, reliability (diff.patch)
|
|
511
|
+
│ │ ├─ code: + language (diff-{focus}.patch) and conditional Review agents
|
|
512
|
+
│ │ └─ docs-only / tests-only / lockfile-only: the reduced set (diff.patch)
|
|
435
513
|
│ │
|
|
436
514
|
│ ├─ Phase 3: Synthesis → Review Comment (SEQUENTIAL within worktree)
|
|
437
515
|
│ │ ├─ Step 3a: Synthesize agent (mode: review, writes review-summary.md)
|
|
@@ -460,6 +538,14 @@ In multi-worktree mode, report results per worktree.
|
|
|
460
538
|
| `--full` flag | Bypass incremental detection (Step 0d), still load PRIOR_RESOLUTIONS for cross-cycle awareness |
|
|
461
539
|
| Parsing failure on resolution-summary.md | fp_ratio = 0, convergence tracking degraded (see Step 0e-ii) |
|
|
462
540
|
| Concurrent sessions | Advisory only, each session computes independently |
|
|
541
|
+
| Docs-only diff | `docs-only`: documentation, consistency, security on `diff.patch`; no language or conditional focus |
|
|
542
|
+
| Tests-only diff | `tests-only`: testing, reliability, consistency, security on `diff.patch`; no language or conditional focus |
|
|
543
|
+
| Lockfile-only diff | `lockfile-only`: dependencies, security on `diff.patch` |
|
|
544
|
+
| Mixed non-code diff (docs with tests, tests with a lockfile) | The union of the matching sets, on `diff.patch` |
|
|
545
|
+
| A path matching no class pattern, or an empty path list | `code` (fail-safe): the 8 core focuses on the full diff |
|
|
546
|
+
| A file moved across classes | `--no-renames` lists the old and the new path, so a code path makes the diff `code` |
|
|
547
|
+
| Path listing above about 40 lines | The count is printed; `paths.txt` is read in ranges of about 40 lines |
|
|
548
|
+
| Language files changed, plugin not installed | The focus is absent from the stamped line: not spawned |
|
|
463
549
|
| Public repo (`auto` mode) | Git agent probes visibility, posts counts-only STUB comment; full report stays local |
|
|
464
550
|
| `reviewPublication: off` | Git agent skips posting the review comment (OFF) — except that, only when `EVIDENCE_POLICY` is `required`, Step 0f passes `stub` and a counts-only STUB comment posts |
|
|
465
551
|
|
|
@@ -470,9 +556,9 @@ In multi-worktree mode, report results per worktree.
|
|
|
470
556
|
|
|
471
557
|
## Principles
|
|
472
558
|
|
|
473
|
-
1. **Orchestration only** - Command spawns agents, doesn't do git/review work itself
|
|
559
|
+
1. **Orchestration only** - Command spawns agents, doesn't do git/review work itself. The exceptions are the read-only Phase 0 probes (`git worktree list`, `git -C ... branch --show-current`, `git -C ... cat-file -t`), the bounded Phase 1 path listing (a redirect into `paths.txt`, a `wc -l` count and ranged reads) and the redirect-only patch writes (`diff.patch`, `diff-{focus}.patch`). Redirect-only writes print nothing, so no diff content reaches this thread
|
|
474
560
|
2. **Parallel, not background** - Multiple agents in one message, but `run_in_background=false` so phases complete before proceeding
|
|
475
|
-
3. **Git agent for git work** - All git operations go through Git agent
|
|
561
|
+
3. **Git agent for git work** - All git operations go through Git agent, except the exceptions named in Principle 1; redirect-only writes print nothing
|
|
476
562
|
4. **Clear ownership** - Each agent owns its output completely
|
|
477
563
|
5. **Honest reporting** - Display agent outputs directly
|
|
478
564
|
6. **Incremental by default** - Only review new changes unless `--full` specified
|