devflow-kit 3.5.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.
- package/CHANGELOG.md +98 -0
- package/README.md +4 -4
- package/dist/agents/{diagnose.md → debug.md} +4 -4
- package/dist/agents/{code-fix.md → fix.md} +2 -2
- package/dist/agents/{scrutinize.md → harden.md} +6 -6
- package/dist/agents/{code-edit.md → refactor.md} +3 -3
- package/dist/cli/agents-view/render.js +1 -1
- package/dist/cli/commands/init.js +3 -3
- package/dist/cli/commands/learning.js +12 -12
- package/dist/cli/commands/legacy-hooks.js +1 -1
- package/dist/cli/commands/uninstall.js +111 -5
- package/dist/commands/bug-analysis.md +19 -15
- package/dist/commands/code-review.md +13 -22
- package/dist/commands/debug.md +15 -15
- package/dist/commands/dynamic-build.md +51 -55
- package/dist/commands/dynamic-plan.md +11 -9
- package/dist/commands/dynamic-profile.md +7 -5
- package/dist/commands/dynamic-tickets.md +11 -9
- package/dist/commands/explore.md +13 -13
- package/dist/commands/implement.md +58 -127
- package/dist/commands/plan.md +19 -41
- package/dist/commands/release.md +9 -5
- package/dist/commands/research.md +12 -8
- package/dist/commands/resolve.md +42 -86
- package/dist/commands/self-review.md +42 -42
- package/dist/core/agent-models.js +47 -11
- package/dist/core/{learning-tuning-config.js → curate-tuning-config.js} +14 -14
- package/dist/core/learning-queue-cleanup.js +1 -1
- package/dist/core/migrations.js +63 -44
- package/dist/core/plugins.js +14 -12
- package/dist/core/project-paths.js +3 -3
- package/dist/hud/codex-usage.js +247 -0
- package/dist/hud/components/codex-quota.js +37 -0
- package/dist/hud/components/usage-quota.js +1 -1
- package/dist/hud/config.js +1 -0
- package/dist/hud/index.js +16 -3
- package/dist/hud/render.js +3 -1
- package/dist/learning-off/agents/{diagnose.md → debug.md} +4 -4
- package/dist/learning-off/agents/{code-fix.md → fix.md} +2 -2
- package/dist/learning-off/agents/{scrutinize.md → harden.md} +6 -6
- package/dist/learning-off/agents/{code-edit.md → refactor.md} +3 -3
- package/dist/learning-off/commands/bug-analysis.md +9 -9
- package/dist/learning-off/commands/code-review.md +2 -15
- package/dist/learning-off/commands/debug.md +4 -8
- package/dist/learning-off/commands/dynamic-build.md +45 -51
- package/dist/learning-off/commands/dynamic-plan.md +5 -5
- package/dist/learning-off/commands/dynamic-profile.md +1 -1
- package/dist/learning-off/commands/dynamic-tickets.md +5 -5
- package/dist/learning-off/commands/explore.md +2 -6
- package/dist/learning-off/commands/implement.md +46 -119
- package/dist/learning-off/commands/plan.md +8 -33
- package/dist/learning-off/commands/release.md +4 -2
- package/dist/learning-off/commands/research.md +2 -2
- package/dist/learning-off/commands/resolve.md +31 -79
- package/dist/learning-off/commands/self-review.md +30 -34
- package/dist/skills/git/references/pr/check-merge-readiness.md +2 -0
- package/dist/skills/git/references/pr/update-pr-evidence.md +4 -6
- package/dist/targets/claude-code/installer.js +117 -84
- package/dist/targets/claude-code/tracker-servers.js +1 -1
- package/package.json +1 -1
- package/src/assets/agents/_partials/_code.mds +2 -2
- package/src/assets/agents/code.mds +2 -2
- package/src/assets/agents/{learning.md → curate.md} +4 -4
- package/src/assets/agents/{diagnose.mds → debug.mds} +4 -4
- package/src/assets/agents/evaluate.md +4 -4
- package/src/assets/agents/{code-fix.mds → fix.mds} +5 -5
- package/src/assets/agents/{scrutinize.mds → harden.mds} +6 -6
- package/src/assets/agents/{simplify.md → polish.md} +4 -4
- package/src/assets/agents/{code-edit.mds → refactor.mds} +6 -6
- package/src/assets/agents/test.md +2 -2
- package/src/assets/commands/_partials/_compliance.mds +1 -1
- package/src/assets/commands/_partials/_decisions.mds +26 -6
- package/src/assets/commands/_partials/_engine.mds +15 -15
- package/src/assets/commands/_partials/_evidence_policy.mds +0 -17
- package/src/assets/commands/_partials/_knowledge.mds +14 -9
- package/src/assets/commands/_partials/_preamble.mds +4 -2
- package/src/assets/commands/_partials/_roster.mds +4 -4
- package/src/assets/commands/bug-analysis.mds +7 -7
- package/src/assets/commands/code-review.mds +1 -14
- package/src/assets/commands/debug.mds +2 -2
- package/src/assets/commands/dynamic-build.mds +26 -32
- package/src/assets/commands/implement.mds +45 -102
- package/src/assets/commands/plan.mds +7 -37
- package/src/assets/commands/release.mds +5 -1
- package/src/assets/commands/resolve.mds +28 -76
- package/src/assets/commands/self-review.mds +27 -27
- package/src/assets/mds/git/_pr.mds +6 -6
- package/src/assets/scripts/hooks/assets/orchestrator-charter.md +4 -3
- package/src/assets/scripts/hooks/capture-prompt +1 -1
- package/src/assets/scripts/hooks/capture-question +1 -1
- package/src/assets/scripts/hooks/capture-turn +1 -1
- package/src/assets/scripts/hooks/json-helper.cjs +2 -2
- package/src/assets/scripts/hooks/lib/learning-store.cjs +1 -1
- package/src/assets/scripts/hooks/lib/project-paths.cjs +4 -4
- package/src/assets/scripts/hooks/preamble +1 -1
- package/src/assets/scripts/hooks/session-start-context +58 -45
- package/src/assets/scripts/verify-evidence.cjs +726 -9
- package/src/assets/skills/agent-references/SKILL.md +9 -5
- package/src/assets/skills/agent-references/references/commands/implement-evidence-asks.md +35 -0
- package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +15 -0
- package/src/assets/skills/agent-references/references/synthesize/bug-analysis.md +1 -1
- package/src/assets/skills/apply-decisions/SKILL.md +6 -4
- package/src/assets/skills/docs-framework/SKILL.md +3 -3
- package/src/assets/skills/qa/SKILL.md +1 -1
- package/src/assets/skills/quality-gates/SKILL.md +7 -7
- package/src/assets/skills/quality-gates/references/report-template.md +7 -7
- /package/src/assets/skills/agent-references/references/{learning → curate}/maintain.md +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { promises as fs } from 'fs';
|
|
2
2
|
import { existsSync } from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
|
-
import { SKILL_NAMESPACE, prefixSkillName, unprefixSkillName, getAllSkillNames, getAllAgentNames, getAllCommandNames, FEATURE_OWNED_SKILLS, resolveSkillInstallPlan, omitLearningGatedSkills } from '../../core/plugins.js';
|
|
4
|
+
import { SKILL_NAMESPACE, buildAssetMaps, prefixSkillName, unprefixSkillName, getAllSkillNames, getAllAgentNames, getAllCommandNames, FEATURE_OWNED_SKILLS, resolveSkillInstallPlan, omitLearningGatedSkills } from '../../core/plugins.js';
|
|
5
5
|
import { skillsDir, agentSourceDirs, rulesDir, commandSourceDirs, scriptsDir, compiledSkillRefsDir } from '../../core/assets.js';
|
|
6
6
|
import { getPackageRoot, isContainedIn } from '../../core/paths.js';
|
|
7
7
|
import { sweepOrphanedAssets, mdFileName, mdEntryName } from '../../core/orphan-sweep.js';
|
|
@@ -1432,6 +1432,90 @@ async function removeDeselectedSkills(skillsDir, names) {
|
|
|
1432
1432
|
}
|
|
1433
1433
|
return { removed, failed };
|
|
1434
1434
|
}
|
|
1435
|
+
/**
|
|
1436
|
+
* Write the commands and the agents of `plugins` into `claudeDir`, and nothing else:
|
|
1437
|
+
* no sweep, no stamp, no skills. The one copy path shared by `installViaFileCopy` and
|
|
1438
|
+
* the selective uninstall, which rewrites the files of the plugins that stay installed
|
|
1439
|
+
* after it removed a retired agent.
|
|
1440
|
+
*
|
|
1441
|
+
* Commands come from dist/commands/{name}.md, or — with learning off — the learning-off
|
|
1442
|
+
* variant dist/learning-off/commands/{name}.md when the host has one
|
|
1443
|
+
* (D-LEARNING-VARIANT-INSTALL; commandSourceDirs owns the order). A declared command
|
|
1444
|
+
* with no compiled source file is a hard error, not a skip.
|
|
1445
|
+
*
|
|
1446
|
+
* Agents resolve dist-first with a src fallback: dist/agents/{name}.md (compiled from an
|
|
1447
|
+
* .mds generator host) wins over src/assets/agents/{name}.md. A declared agent absent from
|
|
1448
|
+
* BOTH is a build/packaging failure and throws rather than silently skipping (matches the
|
|
1449
|
+
* command pattern); the message names the build step as well as the tree.
|
|
1450
|
+
*
|
|
1451
|
+
* D-TRACKER-AGENT-OWNER: every declared agent but ONE. The Tracker agent is converged by
|
|
1452
|
+
* `convergeTrackerArtifacts` alone (plan A3), which runs after the install in init and
|
|
1453
|
+
* reports whether this run wrote it. Copying it here too would make every install do the
|
|
1454
|
+
* work twice, and a fresh install would never report `installed` because converge would
|
|
1455
|
+
* find this loop's byte-identical copy already in place. The name is skipped from the COPY
|
|
1456
|
+
* set only. It stays declared in `devflow-core-skills.agents`, so the agent sweep — which
|
|
1457
|
+
* keys on the full registry via getAllAgentNames() — still treats a converged tracker.md as
|
|
1458
|
+
* known and leaves it alone.
|
|
1459
|
+
*/
|
|
1460
|
+
export async function installCommandsAndAgents(opts) {
|
|
1461
|
+
const { plugins, agentsMap, claudeDir, learning, trackerServers, warn } = opts;
|
|
1462
|
+
const commandsTarget = path.join(claudeDir, 'commands', 'devflow');
|
|
1463
|
+
const commandDirs = commandSourceDirs(learning);
|
|
1464
|
+
const commandsSourceNames = new Set();
|
|
1465
|
+
for (const plugin of plugins) {
|
|
1466
|
+
for (const cmd of plugin.commands) {
|
|
1467
|
+
const name = cmd.startsWith('/') ? cmd.slice(1) : cmd;
|
|
1468
|
+
commandsSourceNames.add(name);
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
if (commandsSourceNames.size > 0) {
|
|
1472
|
+
await fs.mkdir(commandsTarget, { recursive: true });
|
|
1473
|
+
for (const name of commandsSourceNames) {
|
|
1474
|
+
const srcFile = await firstExisting(commandDirs.map(dir => path.join(dir, mdFileName(name))));
|
|
1475
|
+
if (srcFile === undefined) {
|
|
1476
|
+
// The error names the learning-ON path: that file exists for every declared
|
|
1477
|
+
// command, while a learning-off file exists only for a host with an arm.
|
|
1478
|
+
throw new Error(`Command source not found for declared command "${name}": ${path.join(commandSourceDirs(true)[0], mdFileName(name))}. ` +
|
|
1479
|
+
`Ensure build:mds ran successfully before install.`);
|
|
1480
|
+
}
|
|
1481
|
+
await fs.copyFile(srcFile, path.join(commandsTarget, mdFileName(name)));
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
const agentsTarget = path.join(claudeDir, 'agents', 'devflow');
|
|
1485
|
+
// Learning-aware (D-LEARNING-VARIANT-INSTALL). An injected list wins as given.
|
|
1486
|
+
const agentDirs = opts.agentSourceDirs ?? agentSourceDirs(undefined, learning);
|
|
1487
|
+
const allAgentNames = new Set();
|
|
1488
|
+
for (const plugin of plugins) {
|
|
1489
|
+
for (const agent of plugin.agents) {
|
|
1490
|
+
if (agent === TRACKER_AGENT_NAME)
|
|
1491
|
+
continue;
|
|
1492
|
+
if (!allAgentNames.has(agent) && agentsMap.get(agent) === plugin.name) {
|
|
1493
|
+
allAgentNames.add(agent);
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
if (allAgentNames.size > 0) {
|
|
1498
|
+
await fs.mkdir(agentsTarget, { recursive: true });
|
|
1499
|
+
for (const agentName of allAgentNames) {
|
|
1500
|
+
if (await skipsForUserOwnedType(agentName, claudeDir, agentsTarget, warn))
|
|
1501
|
+
continue;
|
|
1502
|
+
const candidates = agentDirs.map(dir => path.join(dir, mdFileName(agentName)));
|
|
1503
|
+
const srcFile = await firstExisting(candidates);
|
|
1504
|
+
if (srcFile === undefined) {
|
|
1505
|
+
throw new Error(`Agent source not found for declared agent "${agentName}": ${path.join(opts.agentSourceDirs?.[0] ?? agentSourceDirs()[0], mdFileName(agentName))}. ` +
|
|
1506
|
+
`Run \`npm run build:mds\` if it is compiled from an .mds generator host, otherwise ` +
|
|
1507
|
+
`ensure the agent file exists in src/assets/agents/ (searched: ${candidates.join(', ')}).`);
|
|
1508
|
+
}
|
|
1509
|
+
const agentTarget = path.join(agentsTarget, mdFileName(agentName));
|
|
1510
|
+
if (isTrackerStampedAgent(agentName)) {
|
|
1511
|
+
await writeStampedAgent(srcFile, agentTarget, trackerServers, warn);
|
|
1512
|
+
}
|
|
1513
|
+
else {
|
|
1514
|
+
await fs.copyFile(srcFile, agentTarget);
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1435
1519
|
/**
|
|
1436
1520
|
* Install plugins via manual file copy.
|
|
1437
1521
|
* Handles cleanup of old monolithic structure, deduplication of shared assets,
|
|
@@ -1576,38 +1660,42 @@ export async function installViaFileCopy(options) {
|
|
|
1576
1660
|
for (const failure of deselected.failed) {
|
|
1577
1661
|
warn(`Could not remove deselected skill "${prefixSkillName(failure.name)}" — ${String(failure.error)}`);
|
|
1578
1662
|
}
|
|
1579
|
-
//
|
|
1580
|
-
//
|
|
1581
|
-
//
|
|
1582
|
-
//
|
|
1583
|
-
//
|
|
1663
|
+
// Retired agents. The sweep runs BEFORE the copy so the copy can see what it found:
|
|
1664
|
+
// an agent file whose name left the registry means a previous release is installed
|
|
1665
|
+
// here, and every command of that release still spawns the retired name. Sweeping
|
|
1666
|
+
// alone would then strand the plugins that stay installed without their agents.
|
|
1667
|
+
//
|
|
1668
|
+
// Ungated: runs on every install shape. knownNames spans ALL plugins
|
|
1669
|
+
// (getAllAgentNames) so agents from uninstalled plugins survive a partial run. Only
|
|
1670
|
+
// names absent from the full registry are removed.
|
|
1671
|
+
const agentsTarget = path.join(claudeDir, 'agents', 'devflow');
|
|
1672
|
+
const agentSweep = await sweepOrphanedAssets(agentsTarget, new Set(getAllAgentNames()), mdEntryName);
|
|
1673
|
+
recordSweep(report, 'agent', agentSweep);
|
|
1674
|
+
// A partial install writes the selected plugins' commands and agents and leaves every
|
|
1675
|
+
// other plugin's files alone, which is only safe while those files still name agents
|
|
1676
|
+
// that exist. After a retired agent was removed they do not, so a partial install
|
|
1677
|
+
// writes the commands and agents of every plugin the manifest records instead. The
|
|
1678
|
+
// widening is conditional because an ordinary add-one run has nothing to repair and
|
|
1679
|
+
// must not rewrite files the user did not ask about.
|
|
1680
|
+
const widenToInstalled = isPartialInstall && agentSweep.removed.length > 0;
|
|
1681
|
+
const commandAgentPlugins = widenToInstalled ? (options.effectivePlugins ?? plugins) : plugins;
|
|
1682
|
+
const commandAgentMap = widenToInstalled ? buildAssetMaps(commandAgentPlugins).agentsMap : agentsMap;
|
|
1683
|
+
// Install commands and agents (D-TRACKER-AGENT-OWNER and the source-resolution rules
|
|
1684
|
+
// are documented on installCommandsAndAgents).
|
|
1584
1685
|
spinner.message('Installing commands and agents...');
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
}
|
|
1594
|
-
if (commandsSourceNames.size > 0) {
|
|
1595
|
-
await fs.mkdir(commandsTarget, { recursive: true });
|
|
1596
|
-
for (const name of commandsSourceNames) {
|
|
1597
|
-
const srcFile = await firstExisting(commandDirs.map(dir => path.join(dir, mdFileName(name))));
|
|
1598
|
-
if (srcFile === undefined) {
|
|
1599
|
-
// The error names the learning-ON path: that file exists for every declared
|
|
1600
|
-
// command, while a learning-off file exists only for a host with an arm.
|
|
1601
|
-
throw new Error(`Command source not found for declared command "${name}": ${path.join(commandSourceDirs(true)[0], mdFileName(name))}. ` +
|
|
1602
|
-
`Ensure build:mds ran successfully before install.`);
|
|
1603
|
-
}
|
|
1604
|
-
await fs.copyFile(srcFile, path.join(commandsTarget, mdFileName(name)));
|
|
1605
|
-
}
|
|
1606
|
-
}
|
|
1686
|
+
await installCommandsAndAgents({
|
|
1687
|
+
plugins: commandAgentPlugins,
|
|
1688
|
+
agentsMap: commandAgentMap,
|
|
1689
|
+
claudeDir,
|
|
1690
|
+
learning,
|
|
1691
|
+
trackerServers,
|
|
1692
|
+
agentSourceDirs: options.agentSourceDirs,
|
|
1693
|
+
warn,
|
|
1694
|
+
});
|
|
1607
1695
|
// Sweep stale command files — ungated: runs on every install shape.
|
|
1608
1696
|
// knownNames spans ALL plugins (getAllCommandNames) so commands from uninstalled
|
|
1609
1697
|
// plugins survive a partial run. Only names absent from the full registry are removed.
|
|
1610
|
-
recordSweep(report, 'command', await sweepOrphanedAssets(
|
|
1698
|
+
recordSweep(report, 'command', await sweepOrphanedAssets(path.join(claudeDir, 'commands', 'devflow'), new Set(getAllCommandNames()), mdEntryName));
|
|
1611
1699
|
// D-LANGUAGE-FOCUS-STAMP: record the language focuses the EFFECTIVE selection installs on the
|
|
1612
1700
|
// installed /code-review, on every install shape. This is the language gate the command reads
|
|
1613
1701
|
// (no run-time probe of Claude Code's directory), so it runs after the copy and the sweep and
|
|
@@ -1620,61 +1708,6 @@ export async function installViaFileCopy(options) {
|
|
|
1620
1708
|
effectivePlugins: options.effectivePlugins ?? plugins,
|
|
1621
1709
|
warn,
|
|
1622
1710
|
});
|
|
1623
|
-
// Install agents (deduplicated), resolved dist-first with a src fallback:
|
|
1624
|
-
// dist/agents/{name}.md (compiled from an .mds generator host) wins over
|
|
1625
|
-
// src/assets/agents/{name}.md. A declared agent absent from BOTH is a
|
|
1626
|
-
// build/packaging failure and throws rather than silently skipping (matches
|
|
1627
|
-
// command pattern); the message names the build step as well as the tree.
|
|
1628
|
-
//
|
|
1629
|
-
// D-TRACKER-AGENT-OWNER: every declared agent but ONE. The Tracker agent is
|
|
1630
|
-
// converged by `convergeTrackerArtifacts` alone (plan A3), which runs after this
|
|
1631
|
-
// function in init and reports whether this run wrote it. Copying it here too
|
|
1632
|
-
// would make every install do the work twice, and a fresh install would never
|
|
1633
|
-
// report `installed` because converge would find this loop's byte-identical copy
|
|
1634
|
-
// already in place.
|
|
1635
|
-
//
|
|
1636
|
-
// The name is skipped from the COPY set only. It stays declared in
|
|
1637
|
-
// `devflow-core-skills.agents`, so the sweep below — which keys on the full
|
|
1638
|
-
// registry via getAllAgentNames() — still treats a converged tracker.md as known
|
|
1639
|
-
// and leaves it alone.
|
|
1640
|
-
const agentsTarget = path.join(claudeDir, 'agents', 'devflow');
|
|
1641
|
-
// Learning-aware (D-LEARNING-VARIANT-INSTALL). An injected list wins as given.
|
|
1642
|
-
const agentDirs = options.agentSourceDirs ?? agentSourceDirs(undefined, learning);
|
|
1643
|
-
const allAgentNames = new Set();
|
|
1644
|
-
for (const plugin of plugins) {
|
|
1645
|
-
for (const agent of plugin.agents) {
|
|
1646
|
-
if (agent === TRACKER_AGENT_NAME)
|
|
1647
|
-
continue;
|
|
1648
|
-
if (!allAgentNames.has(agent) && agentsMap.get(agent) === plugin.name) {
|
|
1649
|
-
allAgentNames.add(agent);
|
|
1650
|
-
}
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
if (allAgentNames.size > 0) {
|
|
1654
|
-
await fs.mkdir(agentsTarget, { recursive: true });
|
|
1655
|
-
for (const agentName of allAgentNames) {
|
|
1656
|
-
if (await skipsForUserOwnedType(agentName, claudeDir, agentsTarget, warn))
|
|
1657
|
-
continue;
|
|
1658
|
-
const candidates = agentDirs.map(dir => path.join(dir, mdFileName(agentName)));
|
|
1659
|
-
const srcFile = await firstExisting(candidates);
|
|
1660
|
-
if (srcFile === undefined) {
|
|
1661
|
-
throw new Error(`Agent source not found for declared agent "${agentName}": ${path.join(options.agentSourceDirs?.[0] ?? agentSourceDirs()[0], mdFileName(agentName))}. ` +
|
|
1662
|
-
`Run \`npm run build:mds\` if it is compiled from an .mds generator host, otherwise ` +
|
|
1663
|
-
`ensure the agent file exists in src/assets/agents/ (searched: ${candidates.join(', ')}).`);
|
|
1664
|
-
}
|
|
1665
|
-
const agentTarget = path.join(agentsTarget, mdFileName(agentName));
|
|
1666
|
-
if (isTrackerStampedAgent(agentName)) {
|
|
1667
|
-
await writeStampedAgent(srcFile, agentTarget, trackerServers, warn);
|
|
1668
|
-
}
|
|
1669
|
-
else {
|
|
1670
|
-
await fs.copyFile(srcFile, agentTarget);
|
|
1671
|
-
}
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
// Sweep stale agent files — ungated: runs on every install shape.
|
|
1675
|
-
// knownNames spans ALL plugins (getAllAgentNames) so agents from uninstalled
|
|
1676
|
-
// plugins survive a partial run. Only names absent from the full registry are removed.
|
|
1677
|
-
recordSweep(report, 'agent', await sweepOrphanedAssets(agentsTarget, new Set(getAllAgentNames()), mdEntryName));
|
|
1678
1711
|
// Install skills from ALL plugins (skillsMap covers all plugins, not just selected).
|
|
1679
1712
|
// Resolved from flat src/assets/skills/{name}/ (no per-plugin subdirectory).
|
|
1680
1713
|
// A declared skill whose source directory is absent is a build/packaging failure
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* and `devflow tracker --servers` changes it. Decided here:
|
|
11
11
|
*
|
|
12
12
|
* - Stamped agents: Git and Tracker, the two that call tracker tools. Code and Research keep a
|
|
13
|
-
* denylist and so every tool server;
|
|
13
|
+
* denylist and so every tool server; Harden and Polish deny them all.
|
|
14
14
|
* - Where the stamp is written. Every path that writes an installed copy of either agent either
|
|
15
15
|
* stamps it or carries the stamp it finds:
|
|
16
16
|
* 1. `installViaFileCopy` stamps Git as it writes it (full install and `--plugin` alike);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devflow-kit",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "A meta-harness for Claude Code — turns a single coding agent into an engineering team: orchestration, parallel review, persistent memory, self-learning, and graph workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
A partial: the text the three Code variants share. `code.mds` (Code: implement, issue-fix),
|
|
2
|
-
`
|
|
3
|
-
(
|
|
2
|
+
`fix.mds` (Fix: validation-fix, alignment-fix, qa-fix, ci-fix) and `refactor.mds`
|
|
3
|
+
(Refactor: edit) are the hosts. A host is any file with `output-dir:`; this file declares none,
|
|
4
4
|
so the build skips it and it reaches an artifact only through the hosts that import it.
|
|
5
5
|
|
|
6
6
|
D-CODE-VARIANTS: a spawn runs exactly one mode, so one agent for every mode would pay for every
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
output-dir: dist/agents
|
|
3
|
-
# D-CODE-VARIANTS: Code runs implement and issue-fix. The gate-failure fixes run on
|
|
4
|
-
# edit runs on
|
|
3
|
+
# D-CODE-VARIANTS: Code runs implement and issue-fix. The gate-failure fixes run on Fix and
|
|
4
|
+
# edit runs on Refactor; the three hosts share _partials/_code.mds.
|
|
5
5
|
# D-CODE-PRELOADS: Code preloads git, testing, test-driven-development, worktree-support,
|
|
6
6
|
# apply-feature-knowledge and apply-decisions: implement writes tests first, and only the
|
|
7
7
|
# implement and issue-fix spawns pass FEATURE_KNOWLEDGE.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: Curate
|
|
3
3
|
description: Background decisions maintenance agent — claims the pending learning queue, captures decisions and pitfalls from the claimed turns, and maintains the decisions ledger through the learning ops. Spawned by the session-start directive when the queue is non-empty.
|
|
4
4
|
model: opus
|
|
5
5
|
tools:
|
|
@@ -10,7 +10,7 @@ tools:
|
|
|
10
10
|
omitClaudeMd: true
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
#
|
|
13
|
+
# Curate Agent
|
|
14
14
|
|
|
15
15
|
You process one project's pending decisions queue: claim it, capture the decisions and
|
|
16
16
|
pitfalls worth keeping from the claimed turns, maintain the entries the ledger hands you,
|
|
@@ -108,7 +108,7 @@ cd "<project root>" && node "$HOME/.devflow/scripts/hooks/json-helper.cjs" claim
|
|
|
108
108
|
|
|
109
109
|
- `claimed <token>` — the batch is yours. Keep the 16-hex token: your FINAL act releases the claim with it.
|
|
110
110
|
- `claimed <token> takeover` — you took over a run that stopped sending heartbeats. The batch is yours, though that run may have stored part of it.
|
|
111
|
-
- `busy` — another
|
|
111
|
+
- `busy` — another Curate agent holds the claim. Exit silently; change nothing.
|
|
112
112
|
- `none` — nothing is queued. Report "no pending decisions work" and finish.
|
|
113
113
|
- A non-zero exit — stop and report its stderr line.
|
|
114
114
|
|
|
@@ -275,7 +275,7 @@ cd "<project root>" && node "$HOME/.devflow/scripts/hooks/json-helper.cjs" claim
|
|
|
275
275
|
```
|
|
276
276
|
|
|
277
277
|
`due none` ends Part 2. Any other output lists due entries: resolve `${CLAUDE_CONFIG_DIR:-$HOME/.claude}`
|
|
278
|
-
in Bash, Read `<that directory>/skills/devflow:agent-references/references/
|
|
278
|
+
in Bash, Read `<that directory>/skills/devflow:agent-references/references/curate/maintain.md`
|
|
279
279
|
with the Read tool, and follow it for those entries.
|
|
280
280
|
|
|
281
281
|
## Finishing
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
output-dir: dist/agents
|
|
3
3
|
---
|
|
4
4
|
---
|
|
5
|
-
name:
|
|
6
|
-
description: Proactive bug finding agent with static+semantic analysis. Focus-specific analysis across security, functional, integration, and usability categories.
|
|
5
|
+
name: Debug
|
|
6
|
+
description: Proactive bug finding agent with static+semantic analysis. Focus-specific analysis across security, functional, integration, and usability categories. The /bug-analysis command spawns it. It is not the /debug command.
|
|
7
7
|
model: opus
|
|
8
8
|
effort: medium
|
|
9
9
|
skills:
|
|
@@ -21,7 +21,7 @@ tools:
|
|
|
21
21
|
- Skill
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
-
#
|
|
24
|
+
# Debug Agent
|
|
25
25
|
|
|
26
26
|
You are a proactive bug finding agent. Your focus area is specified in the prompt. You hunt for real bugs — not style issues — using a 5-step methodology that combines static analysis findings with semantic code understanding.
|
|
27
27
|
|
|
@@ -126,7 +126,7 @@ Assign to each verified finding:
|
|
|
126
126
|
|
|
127
127
|
**Category mapping** (for `/resolve` compatibility — severity-based approximation):
|
|
128
128
|
|
|
129
|
-
> **Trade-off**: The Review agent uses location-based categories (lines you added / lines you touched / unchanged lines). The
|
|
129
|
+
> **Trade-off**: The Review agent uses location-based categories (lines you added / lines you touched / unchanged lines). The Debug agent focuses on diff-changed code and lacks per-line location context, so it approximates using severity as a proxy. This means a LOW-severity bug in newly-added code is placed in Pre-existing — not because it predates the change, but to signal lower urgency. The resolve pipeline should treat Pre-existing findings from the Debug agent as low-urgency, not as assertions about code origin.
|
|
130
130
|
|
|
131
131
|
- CRITICAL / HIGH severity → `## Issues in Your Changes (BLOCKING)` — must fix before merge
|
|
132
132
|
- MEDIUM severity → `## Issues in Code You Touched (Should Fix)` — fix while here
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: Evaluate
|
|
3
|
-
description: Validates implementation aligns with original request and plan. Catches missed requirements, scope creep, and intent drift. Reports misalignments for
|
|
3
|
+
description: Validates implementation aligns with original request and plan. Catches missed requirements, scope creep, and intent drift. Reports misalignments for the Fix agent to fix.
|
|
4
4
|
model: sonnet
|
|
5
5
|
effort: medium
|
|
6
6
|
skills:
|
|
@@ -17,7 +17,7 @@ omitClaudeMd: true
|
|
|
17
17
|
|
|
18
18
|
# Evaluate Agent
|
|
19
19
|
|
|
20
|
-
You are an alignment validation specialist. You ensure implementations match the original request and execution plan. You catch missed requirements, scope creep, and intent drift. You report misalignments with structured details for the
|
|
20
|
+
You are an alignment validation specialist. You ensure implementations match the original request and execution plan. You catch missed requirements, scope creep, and intent drift. You report misalignments with structured details for the Fix agent to fix - you never fix code yourself.
|
|
21
21
|
|
|
22
22
|
## Input Context
|
|
23
23
|
|
|
@@ -38,14 +38,14 @@ You receive from orchestrator:
|
|
|
38
38
|
3. **Goal-backward verification**: Start from the user's observable goals. For each goal, ask whether the implementation delivers it. Report any goal that is not delivered.
|
|
39
39
|
4. **Check completeness**: Verify all plan steps implemented, all acceptance criteria met
|
|
40
40
|
5. **Check scope**: Identify out-of-scope additions not justified by design improvements
|
|
41
|
-
6. **Report misalignments**: Document issues with sufficient detail for
|
|
41
|
+
6. **Report misalignments**: Document issues with sufficient detail for the Fix agent to fix
|
|
42
42
|
|
|
43
43
|
**Gate ownership:** Run no build, test or lint command. Git read commands only. Only Validate runs the full suite.
|
|
44
44
|
|
|
45
45
|
## Principles
|
|
46
46
|
|
|
47
47
|
1. **Intent over letter** - Validate the spirit of the request, not just literal interpretation
|
|
48
|
-
2. **Report, don't fix** - Document misalignments for
|
|
48
|
+
2. **Report, don't fix** - Document misalignments for the Fix agent to fix; never modify code yourself
|
|
49
49
|
3. **Allow justified improvements** - Design enhancements that don't change functionality are OK
|
|
50
50
|
4. **Structured details** - Provide file references and suggested fixes for each misalignment
|
|
51
51
|
5. **Honest assessment** - Report all issues found, don't minimize
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
output-dir: dist/agents
|
|
3
|
-
# D-CODE-VARIANTS:
|
|
3
|
+
# D-CODE-VARIANTS: Fix runs validation-fix, alignment-fix, qa-fix and ci-fix, and has no default
|
|
4
4
|
# mode. Its text is the shared partial _partials/_code.mds plus the four mode sections below.
|
|
5
|
-
# D-CODE-PRELOADS:
|
|
5
|
+
# D-CODE-PRELOADS: Fix preloads git, testing, worktree-support and apply-decisions: a gate-failure
|
|
6
6
|
# fix runs the named tests and is not a test-first build, and no fix spawn passes FEATURE_KNOWLEDGE.
|
|
7
|
-
# D-VARIANT-SLUGS:
|
|
7
|
+
# D-VARIANT-SLUGS: fix is its own `devflow agents` slug with Code's model and effort; a `code`
|
|
8
8
|
# override does not reach it.
|
|
9
9
|
---
|
|
10
10
|
@import "./_partials/_code.mds" as code
|
|
11
11
|
---
|
|
12
|
-
name:
|
|
12
|
+
name: Fix
|
|
13
13
|
description: Autonomous gate-failure repair on feature branch. Fixes the listed validation, alignment, QA or CI failures, verifies, and commits.
|
|
14
14
|
model: sonnet
|
|
15
15
|
effort: high
|
|
@@ -40,7 +40,7 @@ disallowedTools:
|
|
|
40
40
|
- DesignSync
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
-
#
|
|
43
|
+
# Fix Agent
|
|
44
44
|
|
|
45
45
|
You are an autonomous repair specialist working on a feature branch. A quality gate (validation, alignment, QA or CI) reported failures. You fix exactly the failures you are given, verify the fix and commit it. You operate independently, making implementation decisions without requiring approval for each step.
|
|
46
46
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
output-dir: dist/agents
|
|
3
3
|
---
|
|
4
4
|
---
|
|
5
|
-
name:
|
|
5
|
+
name: Harden
|
|
6
6
|
description: Self-review agent that evaluates and fixes implementation issues using 9-pillar framework. Runs in fresh context after Code agent completes.
|
|
7
7
|
model: opus
|
|
8
8
|
effort: medium
|
|
@@ -36,9 +36,9 @@ disallowedTools:
|
|
|
36
36
|
- mcp__*
|
|
37
37
|
---
|
|
38
38
|
|
|
39
|
-
#
|
|
39
|
+
# Harden Agent
|
|
40
40
|
|
|
41
|
-
You are a meticulous self-review specialist. You evaluate implementations against the 9-pillar quality framework and fix the issues you find. You run in a fresh context after the Code and
|
|
41
|
+
You are a meticulous self-review specialist. You evaluate implementations against the 9-pillar quality framework and fix the issues you find. You run in a fresh context after the Code and Polish agents complete, ensuring adequate resources for thorough review and fixes.
|
|
42
42
|
|
|
43
43
|
## Input Context
|
|
44
44
|
|
|
@@ -68,7 +68,7 @@ Follow the `devflow:apply-decisions` skill to scan the index, Read full bodies o
|
|
|
68
68
|
|
|
69
69
|
4. **Evaluate P1 pillars** (Complexity, Error Handling, Tests): These SHOULD pass. Fix all issues found.
|
|
70
70
|
|
|
71
|
-
5. **Evaluate P2** (Documentation): Fix if straightforward. Naming and Consistency belong to the
|
|
71
|
+
5. **Evaluate P2** (Documentation): Fix if straightforward. Naming and Consistency belong to the Polish agent: report them as SKIP.
|
|
72
72
|
|
|
73
73
|
6. **Commit fixes**: If any changes were made, create a commit with message "fix: address self-review issues".
|
|
74
74
|
|
|
@@ -106,8 +106,8 @@ Return structured completion status:
|
|
|
106
106
|
- Tests: PASS | FIXED (description)
|
|
107
107
|
|
|
108
108
|
### P2 Pillars
|
|
109
|
-
- Naming: SKIP (
|
|
110
|
-
- Consistency: SKIP (
|
|
109
|
+
- Naming: SKIP (Polish agent)
|
|
110
|
+
- Consistency: SKIP (Polish agent)
|
|
111
111
|
- Documentation: PASS | FIXED (description)
|
|
112
112
|
|
|
113
113
|
### Files Modified
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description:
|
|
2
|
+
name: Polish
|
|
3
|
+
description: "Judgment-based clarity pass on recently changed code: improves naming, structure and consistency and keeps all behaviour. Use for 'make this code cleaner'. For a given mechanical change (rename, move, boilerplate) use Refactor."
|
|
4
4
|
model: sonnet
|
|
5
5
|
effort: medium
|
|
6
6
|
skills:
|
|
@@ -28,7 +28,7 @@ disallowedTools:
|
|
|
28
28
|
- mcp__*
|
|
29
29
|
---
|
|
30
30
|
|
|
31
|
-
#
|
|
31
|
+
# Polish Agent
|
|
32
32
|
|
|
33
33
|
You are an expert code simplification specialist focused on enhancing code clarity, consistency, and maintainability while preserving exact functionality. Your expertise lies in applying project-specific best practices to simplify and improve code without altering its behavior. You prioritize readable, explicit code over overly compact solutions. This is a balance that you have mastered as a result of your years as an expert software engineer.
|
|
34
34
|
|
|
@@ -106,7 +106,7 @@ Code-scanning runs in the Code agent; do not scan here.
|
|
|
106
106
|
Return structured completion status:
|
|
107
107
|
|
|
108
108
|
```markdown
|
|
109
|
-
##
|
|
109
|
+
## Polish Report
|
|
110
110
|
|
|
111
111
|
### Changes Applied
|
|
112
112
|
- {file}: {description of simplification}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
output-dir: dist/agents
|
|
3
|
-
# D-CODE-VARIANTS:
|
|
3
|
+
# D-CODE-VARIANTS: Refactor runs edit, a mechanical change that adds no behaviour. Its text is the
|
|
4
4
|
# shared partial _partials/_code.mds plus the one mode section below.
|
|
5
|
-
# D-CODE-PRELOADS:
|
|
5
|
+
# D-CODE-PRELOADS: Refactor preloads git, worktree-support and apply-decisions: no tests are written
|
|
6
6
|
# and no FEATURE_KNOWLEDGE is passed.
|
|
7
|
-
# D-VARIANT-SLUGS:
|
|
7
|
+
# D-VARIANT-SLUGS: refactor is its own `devflow agents` slug with Code's model and effort; a `code`
|
|
8
8
|
# override does not reach it.
|
|
9
9
|
---
|
|
10
10
|
@import "./_partials/_code.mds" as code
|
|
11
11
|
---
|
|
12
|
-
name:
|
|
13
|
-
description: Autonomous mechanical edit on feature branch.
|
|
12
|
+
name: Refactor
|
|
13
|
+
description: Autonomous mechanical edit on feature branch. Makes a given rename, move or boilerplate change and commits. For judgment-based cleanup use Polish.
|
|
14
14
|
model: sonnet
|
|
15
15
|
effort: high
|
|
16
16
|
skills:
|
|
@@ -39,7 +39,7 @@ disallowedTools:
|
|
|
39
39
|
- DesignSync
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
-
#
|
|
42
|
+
# Refactor Agent
|
|
43
43
|
|
|
44
44
|
You are an autonomous editing specialist working on a feature branch. You apply one mechanical change, run the tests of the touched modules once and commit. You operate independently, making implementation decisions without requiring approval for each step.
|
|
45
45
|
|
|
@@ -143,7 +143,7 @@ One row per TP line, in TP order. PASS only when every scenario covering the TP
|
|
|
143
143
|
- **Expected**: {what should happen}
|
|
144
144
|
- **Actual**: {what actually happened}
|
|
145
145
|
- **Evidence**: {stdout/stderr/exit code}
|
|
146
|
-
- **Remediation**: {what
|
|
146
|
+
- **Remediation**: {what the Fix agent should fix}
|
|
147
147
|
|
|
148
148
|
### Evidence Log
|
|
149
149
|
{Each command run's `LOG=` path, for traceability}
|
|
@@ -154,7 +154,7 @@ Report cap: final message at most about 1,500 tokens; longer material goes to a
|
|
|
154
154
|
## Principles
|
|
155
155
|
|
|
156
156
|
1. **User perspective** - Test what the user asked for, not implementation internals
|
|
157
|
-
2. **Report, don't fix** - Document failures for
|
|
157
|
+
2. **Report, don't fix** - Document failures for the Fix agent to fix; never modify code yourself
|
|
158
158
|
3. **Evidence-based** - Every result backed by captured stdout/stderr/exit codes
|
|
159
159
|
4. **Severity-aware** - BLOCKING for acceptance criteria violations, WARNING for edge cases
|
|
160
160
|
5. **Deterministic** - Scenarios must produce consistent results across runs
|
|
@@ -4,7 +4,7 @@ its consumers, and the lens is set from the line resolved there for the
|
|
|
4
4
|
worktree's root.
|
|
5
5
|
|
|
6
6
|
D-COMPLIANCE-INJECT: the compliance instruction reaches an agent only through a spawn
|
|
7
|
-
prompt, and only when the resolved lens is on. No Code,
|
|
7
|
+
prompt, and only when the resolved lens is on. No Code, Fix, Review or Design body names
|
|
8
8
|
the compliance skill, so a lens-off spawn pays nothing for it. `compliance_directive()` is the
|
|
9
9
|
one home of the directive text; `compliance_inject()` is how a pass-through host sets it.
|
|
10
10
|
An install-time variant keyed on the machine switch would be wrong: the lens is the union of
|
|
@@ -19,24 +19,39 @@ learning-on build. `decisions_gate()` and `decisions_locate()` are leaves, reach
|
|
|
19
19
|
inside an arm (`decisions_load()`, `authoring_decisions()`, or a host's own on arm), and carry
|
|
20
20
|
no arm of their own: an arm cannot nest.
|
|
21
21
|
|
|
22
|
+
D-DECISIONS-SLICE: the index is handed on as a slice, never whole. The orchestrating main model
|
|
23
|
+
copies the index lines that touch an agent's work, verbatim, behind a
|
|
24
|
+
`(slice: N of M entries — full index: <path>)` marker and ahead of the footer, so an agent reads what
|
|
25
|
+
bears on its task and `devflow:apply-decisions` sends it to the full index only when its work leaves
|
|
26
|
+
that scope. Siblings over one diff share ONE slice, so their prompts stay identical. No script cuts
|
|
27
|
+
it: the index stays a pre-rendered file read, never built on demand, and matching a line to a task is
|
|
28
|
+
judgment, which stays with the model. When unsure, include the line: a slice that misses costs one
|
|
29
|
+
full-index read, a slice that over-includes costs only its bytes. `decisions_slice()` is a leaf like
|
|
30
|
+
the gate and the locator, reached only from inside a learning-on arm, so a learning-off build carries
|
|
31
|
+
none of the rule (D-LEARNING-VARIANTS).
|
|
32
|
+
|
|
22
33
|
@define decisions_gate():
|
|
23
34
|
When the settings line says `LEARNING=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
|
|
24
35
|
@end
|
|
25
36
|
|
|
26
37
|
@define decisions_locate():
|
|
27
|
-
The decisions ledger belongs to the repository, not to one checkout:
|
|
38
|
+
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`):
|
|
28
39
|
|
|
29
40
|
```bash
|
|
30
41
|
git -C "{start}" rev-parse --path-format=absolute --show-toplevel --git-common-dir
|
|
31
42
|
```
|
|
32
43
|
|
|
33
|
-
Line 1 is the checkout's toplevel, line 2 the
|
|
44
|
+
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:
|
|
34
45
|
|
|
35
46
|
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.
|
|
36
47
|
2. **The toplevel** — line 1, or on an older git the line after the echoed flag.
|
|
37
48
|
3. **The start directory itself** — when the command failed or printed no absolute toplevel (outside a git repository).
|
|
38
49
|
|
|
39
|
-
This is the rule the learning hooks apply
|
|
50
|
+
This is the rule the learning hooks apply, so you read the index the Curate agent writes.
|
|
51
|
+
@end
|
|
52
|
+
|
|
53
|
+
@define decisions_slice():
|
|
54
|
+
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.
|
|
40
55
|
@end
|
|
41
56
|
|
|
42
57
|
@define decisions_load():
|
|
@@ -54,15 +69,20 @@ Attempt to read `{ledger}/.devflow/learning/index.md`.
|
|
|
54
69
|
- If the file exists and contains non-empty content: use that content as `DECISIONS_CONTEXT`.
|
|
55
70
|
- If the file is absent or empty: set `DECISIONS_CONTEXT` to `(none)`.
|
|
56
71
|
|
|
57
|
-
The index is one direct file read, written at render time by `render-decisions.cjs`
|
|
72
|
+
The index is one direct file read, written at render time by `render-decisions.cjs` — no `.cjs` script runs here.
|
|
73
|
+
|
|
74
|
+
**Step 2 — Slice the index, then hand it on:**
|
|
75
|
+
|
|
76
|
+
When `DECISIONS_CONTEXT` is not `(none)`, hand it only to the agents whose contract declares it.
|
|
58
77
|
|
|
59
|
-
|
|
78
|
+
{{decisions_slice()}}
|
|
60
79
|
|
|
61
|
-
|
|
80
|
+
Those agents follow `devflow:apply-decisions`. A host that uses the index in its own thread says so in its own step.
|
|
62
81
|
|
|
63
82
|
<!-- learning:end -->
|
|
64
83
|
@end
|
|
65
84
|
|
|
66
85
|
@export decisions_gate
|
|
67
86
|
@export decisions_locate
|
|
87
|
+
@export decisions_slice
|
|
68
88
|
@export decisions_load
|