agileflow 3.3.0 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +6 -6
  3. package/lib/skill-loader.js +0 -1
  4. package/package.json +1 -1
  5. package/scripts/agileflow-statusline.sh +81 -0
  6. package/scripts/agileflow-welcome.js +79 -0
  7. package/scripts/claude-tmux.sh +90 -23
  8. package/scripts/claude-watchdog.sh +225 -0
  9. package/scripts/generators/agent-registry.js +14 -1
  10. package/scripts/generators/inject-babysit.js +22 -9
  11. package/scripts/generators/inject-help.js +19 -9
  12. package/scripts/lib/ac-test-matcher.js +452 -0
  13. package/scripts/lib/audit-cleanup.js +250 -0
  14. package/scripts/lib/audit-registry.js +304 -0
  15. package/scripts/lib/configure-features.js +35 -0
  16. package/scripts/lib/feature-catalog.js +3 -3
  17. package/scripts/lib/gate-enforcer.js +295 -0
  18. package/scripts/lib/model-profiles.js +118 -0
  19. package/scripts/lib/quality-gates.js +163 -0
  20. package/scripts/lib/signal-detectors.js +44 -1
  21. package/scripts/lib/skill-catalog.js +557 -0
  22. package/scripts/lib/skill-recommender.js +311 -0
  23. package/scripts/lib/status-writer.js +255 -0
  24. package/scripts/lib/story-claiming.js +128 -45
  25. package/scripts/lib/task-sync.js +32 -38
  26. package/scripts/lib/tdd-phase-manager.js +455 -0
  27. package/scripts/lib/team-events.js +34 -3
  28. package/scripts/lib/tmux-audit-monitor.js +611 -0
  29. package/scripts/lib/tmux-group-colors.js +113 -0
  30. package/scripts/lib/tool-registry.yaml +241 -0
  31. package/scripts/lib/tool-shed.js +441 -0
  32. package/scripts/messaging-bridge.js +209 -1
  33. package/scripts/native-team-observer.js +219 -0
  34. package/scripts/obtain-context.js +14 -0
  35. package/scripts/ralph-loop.js +30 -5
  36. package/scripts/smart-detect.js +21 -0
  37. package/scripts/spawn-audit-sessions.js +877 -0
  38. package/scripts/team-manager.js +56 -16
  39. package/scripts/tmux-close-windows.sh +180 -0
  40. package/src/core/agents/a11y-analyzer-aria.md +155 -0
  41. package/src/core/agents/a11y-analyzer-forms.md +162 -0
  42. package/src/core/agents/a11y-analyzer-keyboard.md +175 -0
  43. package/src/core/agents/a11y-analyzer-semantic.md +153 -0
  44. package/src/core/agents/a11y-analyzer-visual.md +158 -0
  45. package/src/core/agents/a11y-consensus.md +248 -0
  46. package/src/core/agents/ads-audit-budget.md +181 -0
  47. package/src/core/agents/ads-audit-compliance.md +169 -0
  48. package/src/core/agents/ads-audit-creative.md +164 -0
  49. package/src/core/agents/ads-audit-google.md +226 -0
  50. package/src/core/agents/ads-audit-meta.md +183 -0
  51. package/src/core/agents/ads-audit-tracking.md +197 -0
  52. package/src/core/agents/ads-consensus.md +396 -0
  53. package/src/core/agents/ads-generate.md +145 -0
  54. package/src/core/agents/ads-performance-tracker.md +197 -0
  55. package/src/core/agents/api-quality-analyzer-conventions.md +148 -0
  56. package/src/core/agents/api-quality-analyzer-docs.md +176 -0
  57. package/src/core/agents/api-quality-analyzer-errors.md +183 -0
  58. package/src/core/agents/api-quality-analyzer-pagination.md +171 -0
  59. package/src/core/agents/api-quality-analyzer-versioning.md +143 -0
  60. package/src/core/agents/api-quality-consensus.md +214 -0
  61. package/src/core/agents/arch-analyzer-circular.md +148 -0
  62. package/src/core/agents/arch-analyzer-complexity.md +171 -0
  63. package/src/core/agents/arch-analyzer-coupling.md +146 -0
  64. package/src/core/agents/arch-analyzer-layering.md +151 -0
  65. package/src/core/agents/arch-analyzer-patterns.md +162 -0
  66. package/src/core/agents/arch-consensus.md +227 -0
  67. package/src/core/agents/brainstorm-analyzer-features.md +169 -0
  68. package/src/core/agents/brainstorm-analyzer-growth.md +161 -0
  69. package/src/core/agents/brainstorm-analyzer-integration.md +172 -0
  70. package/src/core/agents/brainstorm-analyzer-market.md +147 -0
  71. package/src/core/agents/brainstorm-analyzer-ux.md +167 -0
  72. package/src/core/agents/brainstorm-consensus.md +237 -0
  73. package/src/core/agents/completeness-consensus.md +5 -5
  74. package/src/core/agents/perf-consensus.md +2 -2
  75. package/src/core/agents/security-consensus.md +2 -2
  76. package/src/core/agents/seo-analyzer-content.md +167 -0
  77. package/src/core/agents/seo-analyzer-images.md +187 -0
  78. package/src/core/agents/seo-analyzer-performance.md +206 -0
  79. package/src/core/agents/seo-analyzer-schema.md +176 -0
  80. package/src/core/agents/seo-analyzer-sitemap.md +172 -0
  81. package/src/core/agents/seo-analyzer-technical.md +144 -0
  82. package/src/core/agents/seo-consensus.md +289 -0
  83. package/src/core/agents/test-consensus.md +2 -2
  84. package/src/core/commands/adr.md +1 -0
  85. package/src/core/commands/ads/audit.md +375 -0
  86. package/src/core/commands/ads/budget.md +97 -0
  87. package/src/core/commands/ads/competitor.md +112 -0
  88. package/src/core/commands/ads/creative.md +85 -0
  89. package/src/core/commands/ads/generate.md +238 -0
  90. package/src/core/commands/ads/google.md +112 -0
  91. package/src/core/commands/ads/health.md +327 -0
  92. package/src/core/commands/ads/landing.md +119 -0
  93. package/src/core/commands/ads/linkedin.md +112 -0
  94. package/src/core/commands/ads/meta.md +91 -0
  95. package/src/core/commands/ads/microsoft.md +115 -0
  96. package/src/core/commands/ads/plan.md +321 -0
  97. package/src/core/commands/ads/test-plan.md +317 -0
  98. package/src/core/commands/ads/tiktok.md +129 -0
  99. package/src/core/commands/ads/track.md +288 -0
  100. package/src/core/commands/ads/youtube.md +124 -0
  101. package/src/core/commands/ads.md +140 -0
  102. package/src/core/commands/assign.md +1 -0
  103. package/src/core/commands/audit.md +43 -6
  104. package/src/core/commands/babysit.md +315 -1266
  105. package/src/core/commands/baseline.md +1 -0
  106. package/src/core/commands/blockers.md +1 -0
  107. package/src/core/commands/board.md +1 -0
  108. package/src/core/commands/changelog.md +1 -0
  109. package/src/core/commands/choose.md +1 -0
  110. package/src/core/commands/ci.md +1 -0
  111. package/src/core/commands/code/accessibility.md +347 -0
  112. package/src/core/commands/code/api.md +297 -0
  113. package/src/core/commands/code/architecture.md +297 -0
  114. package/src/core/commands/{audit → code}/completeness.md +72 -25
  115. package/src/core/commands/{audit → code}/legal.md +63 -16
  116. package/src/core/commands/{audit → code}/logic.md +64 -16
  117. package/src/core/commands/{audit → code}/performance.md +67 -20
  118. package/src/core/commands/{audit → code}/security.md +69 -19
  119. package/src/core/commands/{audit → code}/test.md +67 -20
  120. package/src/core/commands/configure.md +1 -0
  121. package/src/core/commands/council.md +1 -0
  122. package/src/core/commands/deploy.md +1 -0
  123. package/src/core/commands/diagnose.md +1 -0
  124. package/src/core/commands/docs.md +1 -0
  125. package/src/core/commands/epic/edit.md +213 -0
  126. package/src/core/commands/epic.md +1 -0
  127. package/src/core/commands/export.md +238 -0
  128. package/src/core/commands/help.md +16 -1
  129. package/src/core/commands/{discovery → ideate}/brief.md +12 -12
  130. package/src/core/commands/{discovery/new.md → ideate/discover.md} +20 -16
  131. package/src/core/commands/ideate/features.md +496 -0
  132. package/src/core/commands/ideate/new.md +158 -124
  133. package/src/core/commands/impact.md +1 -0
  134. package/src/core/commands/learn/explain.md +118 -0
  135. package/src/core/commands/learn/glossary.md +135 -0
  136. package/src/core/commands/learn/patterns.md +138 -0
  137. package/src/core/commands/learn/tour.md +126 -0
  138. package/src/core/commands/migrate/codemods.md +151 -0
  139. package/src/core/commands/migrate/plan.md +131 -0
  140. package/src/core/commands/migrate/scan.md +114 -0
  141. package/src/core/commands/migrate/validate.md +119 -0
  142. package/src/core/commands/multi-expert.md +1 -0
  143. package/src/core/commands/pr.md +1 -0
  144. package/src/core/commands/review.md +1 -0
  145. package/src/core/commands/seo/audit.md +373 -0
  146. package/src/core/commands/seo/competitor.md +174 -0
  147. package/src/core/commands/seo/content.md +107 -0
  148. package/src/core/commands/seo/geo.md +229 -0
  149. package/src/core/commands/seo/hreflang.md +140 -0
  150. package/src/core/commands/seo/images.md +96 -0
  151. package/src/core/commands/seo/page.md +198 -0
  152. package/src/core/commands/seo/plan.md +163 -0
  153. package/src/core/commands/seo/programmatic.md +131 -0
  154. package/src/core/commands/seo/references/cwv-thresholds.md +64 -0
  155. package/src/core/commands/seo/references/eeat-framework.md +110 -0
  156. package/src/core/commands/seo/references/quality-gates.md +91 -0
  157. package/src/core/commands/seo/references/schema-types.md +102 -0
  158. package/src/core/commands/seo/schema.md +183 -0
  159. package/src/core/commands/seo/sitemap.md +97 -0
  160. package/src/core/commands/seo/technical.md +100 -0
  161. package/src/core/commands/seo.md +107 -0
  162. package/src/core/commands/skill/list.md +68 -212
  163. package/src/core/commands/skill/recommend.md +216 -0
  164. package/src/core/commands/sprint.md +1 -0
  165. package/src/core/commands/status/undo.md +191 -0
  166. package/src/core/commands/status.md +1 -0
  167. package/src/core/commands/story/edit.md +204 -0
  168. package/src/core/commands/story/view.md +29 -7
  169. package/src/core/commands/story-validate.md +1 -0
  170. package/src/core/commands/story.md +1 -0
  171. package/src/core/commands/tdd-next.md +238 -0
  172. package/src/core/commands/tdd.md +211 -0
  173. package/src/core/commands/team/start.md +10 -6
  174. package/src/core/commands/tests.md +1 -0
  175. package/src/core/commands/verify.md +27 -1
  176. package/src/core/commands/workflow.md +2 -0
  177. package/src/core/experts/_core-expertise.yaml +105 -0
  178. package/src/core/experts/analytics/expertise.yaml +5 -99
  179. package/src/core/experts/codebase-query/expertise.yaml +3 -72
  180. package/src/core/experts/compliance/expertise.yaml +6 -72
  181. package/src/core/experts/database/expertise.yaml +9 -52
  182. package/src/core/experts/documentation/expertise.yaml +7 -140
  183. package/src/core/experts/integrations/expertise.yaml +7 -127
  184. package/src/core/experts/mentor/expertise.yaml +8 -35
  185. package/src/core/experts/monitoring/expertise.yaml +7 -49
  186. package/src/core/experts/performance/expertise.yaml +1 -26
  187. package/src/core/experts/security/expertise.yaml +9 -34
  188. package/src/core/experts/ui/expertise.yaml +6 -36
  189. package/src/core/knowledge/ads/ad-audit-checklist-scoring.md +424 -0
  190. package/src/core/knowledge/ads/ad-optimization-logic.md +590 -0
  191. package/src/core/knowledge/ads/ad-technical-specifications.md +385 -0
  192. package/src/core/knowledge/ads/definitive-advertising-reference-2026.md +506 -0
  193. package/src/core/knowledge/ads/paid-advertising-research-2026.md +445 -0
  194. package/src/core/teams/backend.json +41 -0
  195. package/src/core/teams/frontend.json +41 -0
  196. package/src/core/teams/qa.json +41 -0
  197. package/src/core/teams/solo.json +35 -0
  198. package/src/core/templates/agileflow-metadata.json +20 -1
  199. package/tools/cli/commands/setup.js +85 -3
  200. package/tools/cli/commands/update.js +42 -0
  201. package/tools/cli/installers/ide/_base-ide.js +42 -5
  202. package/tools/cli/installers/ide/claude-code.js +71 -3
  203. package/tools/cli/lib/content-injector.js +160 -12
  204. package/tools/cli/lib/docs-setup.js +1 -1
  205. package/src/core/commands/skill/create.md +0 -698
  206. package/src/core/commands/skill/delete.md +0 -316
  207. package/src/core/commands/skill/edit.md +0 -359
  208. package/src/core/commands/skill/test.md +0 -394
  209. package/src/core/commands/skill/upgrade.md +0 -552
  210. package/src/core/templates/skill-template.md +0 -117
@@ -0,0 +1,118 @@
1
+ /**
2
+ * model-profiles.js - Model resolution for audit subagents
3
+ *
4
+ * Resolves which model (haiku/sonnet/opus) to use for agent subagents.
5
+ * Models are specified inline via command arguments (MODEL=opus).
6
+ *
7
+ * Resolution order:
8
+ * 1. Explicit MODEL= argument (highest priority)
9
+ * 2. Agent frontmatter model (from .md file)
10
+ * 3. Fallback: 'haiku'
11
+ *
12
+ * Usage:
13
+ * const { resolveModel, estimateCost } = require('./model-profiles');
14
+ * const model = resolveModel('opus', 'haiku'); // returns 'opus'
15
+ * const model2 = resolveModel(null, 'sonnet'); // returns 'sonnet'
16
+ * const model3 = resolveModel(null, null); // returns 'haiku'
17
+ */
18
+
19
+ const VALID_MODELS = ['haiku', 'sonnet', 'opus'];
20
+
21
+ /**
22
+ * Resolve which model to use for a given agent.
23
+ *
24
+ * Resolution order:
25
+ * 1. Explicit model argument (MODEL= from command)
26
+ * 2. Agent frontmatter model
27
+ * 3. Fallback: 'haiku'
28
+ *
29
+ * @param {string} [explicitModel] - MODEL= argument value
30
+ * @param {string} [frontmatterModel] - Model from agent .md frontmatter
31
+ * @returns {string} Model name: 'haiku', 'sonnet', or 'opus'
32
+ */
33
+ function resolveModel(explicitModel, frontmatterModel) {
34
+ // 1. Explicit MODEL= argument
35
+ if (explicitModel && VALID_MODELS.includes(explicitModel.toLowerCase())) {
36
+ return explicitModel.toLowerCase();
37
+ }
38
+
39
+ // 2. Frontmatter model
40
+ if (frontmatterModel && VALID_MODELS.includes(frontmatterModel.toLowerCase())) {
41
+ return frontmatterModel.toLowerCase();
42
+ }
43
+
44
+ // 3. Fallback
45
+ return 'haiku';
46
+ }
47
+
48
+ /**
49
+ * Validate a model name.
50
+ *
51
+ * @param {string} model - Model name to validate
52
+ * @returns {boolean} True if valid
53
+ */
54
+ function isValidModel(model) {
55
+ return !!model && VALID_MODELS.includes(model.toLowerCase());
56
+ }
57
+
58
+ /**
59
+ * Estimate cost multiplier for a model relative to haiku baseline.
60
+ *
61
+ * @param {string} model - Model name
62
+ * @param {number} [analyzerCount=5] - Number of analyzers
63
+ * @param {number} [partitions=1] - Number of partitions (extreme mode)
64
+ * @returns {{ multiplier: number, model: string, perAnalyzerCost: string, totalEstimate: string, partitions?: number, totalSessions?: number }}
65
+ */
66
+ function estimateCost(model, analyzerCount, partitions) {
67
+ let MODEL_PRICING;
68
+ try {
69
+ MODEL_PRICING = require('./team-events').MODEL_PRICING;
70
+ } catch (_) {
71
+ MODEL_PRICING = {
72
+ haiku: { input: 0.8, output: 4.0 },
73
+ sonnet: { input: 3.0, output: 15.0 },
74
+ opus: { input: 15.0, output: 75.0 },
75
+ };
76
+ }
77
+
78
+ const count = analyzerCount || 5;
79
+ const partCount = typeof partitions === 'number' && partitions > 1 ? partitions : 1;
80
+ const resolved = resolveModel(model);
81
+ const pricing = MODEL_PRICING[resolved] || MODEL_PRICING.haiku;
82
+ const haikuPricing = MODEL_PRICING.haiku;
83
+
84
+ const multiplier = pricing.output / haikuPricing.output;
85
+ const perAnalyzerCostNum =
86
+ (pricing.input * 50000) / 1_000_000 + (pricing.output * 10000) / 1_000_000;
87
+ const perAnalyzer = `$${perAnalyzerCostNum.toFixed(3)}`;
88
+
89
+ // For extreme mode: each partition has a coordinator + all analyzers as sub-agents
90
+ // Estimated cost per partition coordinator session in USD (~10k input + 2k output at haiku rates)
91
+ const coordinatorCostUSD = 0.05;
92
+ const totalSessions = partCount * count;
93
+ const totalCost =
94
+ partCount > 1
95
+ ? partCount * coordinatorCostUSD + totalSessions * perAnalyzerCostNum
96
+ : count * perAnalyzerCostNum;
97
+
98
+ const result = {
99
+ multiplier: Math.round(multiplier * 100) / 100,
100
+ model: resolved,
101
+ perAnalyzerCost: perAnalyzer,
102
+ totalEstimate: `~$${totalCost.toFixed(2)}`,
103
+ };
104
+
105
+ if (partCount > 1) {
106
+ result.partitions = partCount;
107
+ result.totalSessions = totalSessions;
108
+ }
109
+
110
+ return result;
111
+ }
112
+
113
+ module.exports = {
114
+ VALID_MODELS,
115
+ resolveModel,
116
+ isValidModel,
117
+ estimateCost,
118
+ };
@@ -561,6 +561,164 @@ function createValidationReport(gateResults, options = {}) {
561
561
  return lines.join('\n');
562
562
  }
563
563
 
564
+ // ============================================================================
565
+ // CI Feedback Loop
566
+ // ============================================================================
567
+
568
+ /**
569
+ * Default CI feedback loop configuration
570
+ */
571
+ const CI_FEEDBACK_DEFAULTS = {
572
+ enabled: true,
573
+ max_rounds: 3,
574
+ };
575
+
576
+ /**
577
+ * Load CI feedback loop config from agileflow-metadata.json
578
+ * @param {string} projectRoot - Project root directory
579
+ * @returns {Object} CI feedback loop config
580
+ */
581
+ function loadCIFeedbackConfig(projectRoot) {
582
+ const metadataPath = path.join(projectRoot, 'docs', '00-meta', 'agileflow-metadata.json');
583
+ try {
584
+ if (fs.existsSync(metadataPath)) {
585
+ const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
586
+ if (metadata.ci_feedback_loops) {
587
+ return {
588
+ ...CI_FEEDBACK_DEFAULTS,
589
+ ...metadata.ci_feedback_loops,
590
+ };
591
+ }
592
+ }
593
+ } catch {
594
+ // Fall through to defaults
595
+ }
596
+ return { ...CI_FEEDBACK_DEFAULTS };
597
+ }
598
+
599
+ /**
600
+ * Execute a CI feedback loop - runs gates, and if they fail, returns
601
+ * structured feedback for the agent to retry (up to max_rounds).
602
+ *
603
+ * This implements the Stripe "Minions" pattern: deterministic CI check
604
+ * followed by agent retry, with a hard iteration limit.
605
+ *
606
+ * @param {Object[]} gates - Quality gate definitions to check
607
+ * @param {Object} options - Loop options
608
+ * @param {string} [options.projectRoot] - Project root directory
609
+ * @param {number} [options.maxRounds] - Override max retry rounds (default: from config)
610
+ * @param {number} [options.currentRound] - Current round number (1-based, default: 1)
611
+ * @param {string} [options.cwd] - Working directory for gate execution
612
+ * @returns {Object} Loop result with status and agent feedback
613
+ */
614
+ function executeCIFeedbackLoop(gates, options = {}) {
615
+ const { projectRoot = process.cwd(), maxRounds, currentRound = 1, cwd } = options;
616
+
617
+ const config = loadCIFeedbackConfig(projectRoot);
618
+
619
+ if (!config.enabled) {
620
+ return {
621
+ status: 'disabled',
622
+ message: 'CI feedback loops are disabled in agileflow-metadata.json',
623
+ should_retry: false,
624
+ round: currentRound,
625
+ max_rounds: 0,
626
+ };
627
+ }
628
+
629
+ const effectiveMaxRounds = maxRounds || config.max_rounds || CI_FEEDBACK_DEFAULTS.max_rounds;
630
+
631
+ // Execute all gates
632
+ const gateResults = executeGates(gates, { cwd, stopOnFailure: false });
633
+
634
+ if (gateResults.passed) {
635
+ return {
636
+ status: 'passed',
637
+ message: `All ${gateResults.passed_count} gates passed on round ${currentRound}`,
638
+ should_retry: false,
639
+ round: currentRound,
640
+ max_rounds: effectiveMaxRounds,
641
+ gate_results: gateResults,
642
+ };
643
+ }
644
+
645
+ // Gates failed - determine if we should retry
646
+ const hasRoundsLeft = currentRound < effectiveMaxRounds;
647
+
648
+ if (!hasRoundsLeft) {
649
+ return {
650
+ status: 'exhausted',
651
+ message: `Gates failed after ${currentRound}/${effectiveMaxRounds} rounds. Escalating to human.`,
652
+ should_retry: false,
653
+ round: currentRound,
654
+ max_rounds: effectiveMaxRounds,
655
+ gate_results: gateResults,
656
+ failures: gateResults.results
657
+ .filter(r => r.status === GATE_STATUS.FAILED || r.status === GATE_STATUS.ERROR)
658
+ .map(r => ({
659
+ gate: r.gate,
660
+ message: r.message,
661
+ output: r.output,
662
+ error: r.error,
663
+ })),
664
+ };
665
+ }
666
+
667
+ // Build structured feedback for agent retry
668
+ const failures = gateResults.results.filter(
669
+ r => r.status === GATE_STATUS.FAILED || r.status === GATE_STATUS.ERROR
670
+ );
671
+
672
+ const feedbackLines = [
673
+ `## CI Feedback Loop - Round ${currentRound}/${effectiveMaxRounds}`,
674
+ '',
675
+ `**${failures.length} gate(s) failed.** ${effectiveMaxRounds - currentRound} retry round(s) remaining.`,
676
+ '',
677
+ '### Failures',
678
+ '',
679
+ ];
680
+
681
+ for (const failure of failures) {
682
+ feedbackLines.push(`#### ${failure.gate} (${failure.type})`);
683
+ feedbackLines.push(`- **Status**: ${failure.status}`);
684
+ feedbackLines.push(`- **Message**: ${failure.message}`);
685
+ if (failure.output) {
686
+ feedbackLines.push('- **Output**:');
687
+ feedbackLines.push('```');
688
+ feedbackLines.push(failure.output);
689
+ feedbackLines.push('```');
690
+ }
691
+ if (failure.error) {
692
+ feedbackLines.push('- **Error**:');
693
+ feedbackLines.push('```');
694
+ feedbackLines.push(failure.error);
695
+ feedbackLines.push('```');
696
+ }
697
+ feedbackLines.push('');
698
+ }
699
+
700
+ feedbackLines.push('### Action Required');
701
+ feedbackLines.push('');
702
+ feedbackLines.push('Fix the failing gates above, then re-run verification.');
703
+
704
+ return {
705
+ status: 'retry',
706
+ message: `Round ${currentRound}/${effectiveMaxRounds} failed. Agent should fix and retry.`,
707
+ should_retry: true,
708
+ round: currentRound,
709
+ max_rounds: effectiveMaxRounds,
710
+ next_round: currentRound + 1,
711
+ gate_results: gateResults,
712
+ agent_feedback: feedbackLines.join('\n'),
713
+ failures: failures.map(r => ({
714
+ gate: r.gate,
715
+ message: r.message,
716
+ output: r.output,
717
+ error: r.error,
718
+ })),
719
+ };
720
+ }
721
+
564
722
  // ============================================================================
565
723
  // Exports
566
724
  // ============================================================================
@@ -595,4 +753,9 @@ module.exports = {
595
753
 
596
754
  // Reporting
597
755
  createValidationReport,
756
+
757
+ // CI Feedback Loop
758
+ CI_FEEDBACK_DEFAULTS,
759
+ loadCIFeedbackConfig,
760
+ executeCIFeedbackLoop,
598
761
  };
@@ -233,6 +233,24 @@ const FEATURE_DETECTORS = {
233
233
  });
234
234
  },
235
235
 
236
+ 'scale-adaptive': signals => {
237
+ const { scale } = signals;
238
+ if (!scale || !scale.tier) return null;
239
+ // Only trigger when scale info provides actionable guidance
240
+ const rec = scale.recommendations;
241
+ if (!rec) return null;
242
+ // Suggest scale-adaptive workflow when project is not medium (the default)
243
+ if (scale.tier === 'medium') return null;
244
+ const label = scale.tier.charAt(0).toUpperCase() + scale.tier.slice(1);
245
+ return recommend('scale-adaptive', {
246
+ priority: scale.tier === 'enterprise' || scale.tier === 'large' ? 'medium' : 'low',
247
+ trigger: `${label} project detected (${scale.metrics.files} files, ${scale.metrics.stories} stories) — ${rec.description}`,
248
+ action: 'suggest',
249
+ command: '/agileflow:workflow',
250
+ phase: 'pre-story',
251
+ });
252
+ },
253
+
236
254
  // =========================================================================
237
255
  // PLANNING PHASE
238
256
  // =========================================================================
@@ -517,6 +535,29 @@ const FEATURE_DETECTORS = {
517
535
  });
518
536
  },
519
537
 
538
+ 'ac-verify': signals => {
539
+ const { story, tests } = signals;
540
+ if (!story || story.status !== 'in-progress') return null;
541
+ if (!tests || tests.passing !== true) return null; // Only after tests pass
542
+ if (!storyHasAC(story)) return null;
543
+ // Check if AC already verified (count by index to avoid extra keys)
544
+ const acStatus = story.ac_status || {};
545
+ const acList = story.acceptance_criteria || story.ac || [];
546
+ const verifiedCount = acList.filter(
547
+ (_, i) =>
548
+ acStatus[i] === 'verified' || acStatus[i] === 'auto-verified' || acStatus[i] === true
549
+ ).length;
550
+ if (verifiedCount === acList.length) return null;
551
+ const unverifiedCount = acList.length - verifiedCount;
552
+ return recommend('ac-verify', {
553
+ priority: 'high',
554
+ trigger: `Tests pass but ${unverifiedCount}/${acList.length} AC unverified`,
555
+ action: 'suggest',
556
+ command: '/agileflow:audit',
557
+ phase: 'post-impl',
558
+ });
559
+ },
560
+
520
561
  // =========================================================================
521
562
  // POST-IMPLEMENTATION PHASE
522
563
  // =========================================================================
@@ -546,7 +587,7 @@ const FEATURE_DETECTORS = {
546
587
  priority: 'medium',
547
588
  trigger: `${coreFiles} source files modified - logic audit available`,
548
589
  action: 'offer',
549
- command: '/agileflow:audit:logic',
590
+ command: '/agileflow:code:logic',
550
591
  phase: 'post-impl',
551
592
  });
552
593
  },
@@ -704,6 +745,7 @@ const PHASE_MAP = {
704
745
  'workflow',
705
746
  'template',
706
747
  'configure',
748
+ 'scale-adaptive',
707
749
  ],
708
750
  planning: [
709
751
  'impact',
@@ -728,6 +770,7 @@ const PHASE_MAP = {
728
770
  'serve',
729
771
  ],
730
772
  'post-impl': [
773
+ 'ac-verify',
731
774
  'review',
732
775
  'logic-audit',
733
776
  'docs',