sinapse-ai 1.20.1 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/.claude/rules/coderabbit-integration.md +6 -0
  2. package/.claude/rules/documentation-first-reference.md +146 -0
  3. package/.claude/rules/documentation-first.md +27 -119
  4. package/.claude/rules/mandatory-delegation-reference.md +93 -0
  5. package/.claude/rules/mandatory-delegation.md +29 -93
  6. package/.claude/rules/project-intelligence-reference.md +159 -0
  7. package/.claude/rules/project-intelligence.md +37 -155
  8. package/.claude/rules/safe-collaboration-reference.md +163 -0
  9. package/.claude/rules/safe-collaboration.md +32 -173
  10. package/.sinapse-ai/core/doctor/checks/index.js +1 -1
  11. package/.sinapse-ai/core/execution/build-orchestrator.js +4 -3
  12. package/.sinapse-ai/core/execution/subagent-dispatcher.js +2 -2
  13. package/.sinapse-ai/core/ideation/ideation-engine.js +2 -1
  14. package/.sinapse-ai/core/orchestration/brownfield-progress.js +219 -0
  15. package/.sinapse-ai/core/orchestration/cli-commands.js +13 -0
  16. package/.sinapse-ai/core/orchestration/doc-first-resolver.js +96 -2
  17. package/.sinapse-ai/core/orchestration/executors/epic-3-executor.js +15 -2
  18. package/.sinapse-ai/core/orchestration/executors/epic-4-executor.js +3 -1
  19. package/.sinapse-ai/core/orchestration/greenfield-handler.js +97 -0
  20. package/.sinapse-ai/core/orchestration/index.js +5 -0
  21. package/.sinapse-ai/core/orchestration/spec-complexity.js +141 -0
  22. package/.sinapse-ai/core/orchestration/workflow-executor.js +17 -1
  23. package/.sinapse-ai/core-config.yaml +30 -0
  24. package/.sinapse-ai/data/entity-registry.yaml +81 -35
  25. package/.sinapse-ai/development/agents/architect.md +3 -15
  26. package/.sinapse-ai/development/agents/data-engineer.md +3 -15
  27. package/.sinapse-ai/development/agents/developer.md +3 -24
  28. package/.sinapse-ai/development/agents/devops.md +4 -25
  29. package/.sinapse-ai/development/agents/quality-gate.md +3 -25
  30. package/.sinapse-ai/development/knowledge-base/token-economy-guide.md +1 -1
  31. package/.sinapse-ai/development/tasks/execute-epic-plan.md +3 -0
  32. package/.sinapse-ai/development/tasks/resolve-github-issue.md +1 -1
  33. package/.sinapse-ai/development/workflows/brownfield-discovery.yaml +16 -0
  34. package/.sinapse-ai/development/workflows/epic-orchestration.yaml +11 -0
  35. package/.sinapse-ai/docs/standards/SINAPSE-LIVRO-DE-OURO-V2.1-COMPLETE.md +6 -2
  36. package/.sinapse-ai/docs/standards/SINAPSE-LIVRO-DE-OURO-V2.2-SUMMARY.md +4 -1
  37. package/.sinapse-ai/install-manifest.yaml +58 -50
  38. package/.sinapse-ai/product/templates/story-tmpl.yaml +11 -6
  39. package/.sinapse-ai/quality/judge-calibration/README.md +75 -0
  40. package/.sinapse-ai/quality/judge-calibration/calibration-log.md +70 -0
  41. package/.sinapse-ai/quality/judge-calibration/golden-set.json +105 -0
  42. package/.sinapse-ai/quality/judge-calibration/scenarios.json +90 -0
  43. package/CHANGELOG.md +55 -10
  44. package/README.en.md +1 -1
  45. package/README.md +6 -6
  46. package/bin/sinapse-minimal.js +5 -4
  47. package/docs/community/README-community-snippet-core.md +1 -1
  48. package/docs/community/README-community-snippet-mcp.md +2 -2
  49. package/docs/framework/README.md +2 -2
  50. package/docs/framework/architecture-overview.md +2 -2
  51. package/docs/framework/core-architecture.md +1 -1
  52. package/docs/framework/feature-process.md +5 -5
  53. package/docs/framework/guiding-principles.md +1 -1
  54. package/docs/framework/roadmap.md +4 -4
  55. package/docs/framework/source-tree.md +1 -1
  56. package/docs/framework/versioning-and-releases.md +1 -1
  57. package/docs/getting-started.md +1 -1
  58. package/docs/guides/agent-selection-guide.md +1 -1
  59. package/docs/guides/agents/traces/README.md +1 -1
  60. package/docs/guides/config-migration-guide.md +1 -1
  61. package/docs/guides/development-setup.md +1 -1
  62. package/docs/guides/docker-mcp-setup.md +5 -5
  63. package/docs/guides/getting-started.md +1 -1
  64. package/docs/guides/git-workflow-guide.md +3 -3
  65. package/docs/guides/ide-integration.md +3 -3
  66. package/docs/guides/ide-sync-guide.md +1 -1
  67. package/docs/guides/mcp/desktop-commander.md +2 -2
  68. package/docs/guides/mcp/docker-gateway-tutorial.md +1 -1
  69. package/docs/guides/mcp-global-setup.md +3 -3
  70. package/docs/guides/memory-intelligence-system.md +10 -10
  71. package/docs/guides/meta-agent-commands.md +1 -1
  72. package/docs/guides/quality-gates.md +1 -1
  73. package/docs/guides/security-hardening.md +1 -1
  74. package/docs/guides/service-discovery.md +1 -1
  75. package/docs/guides/squad-examples/README.md +1 -1
  76. package/docs/guides/squads-guide.md +1 -1
  77. package/docs/guides/testing-guide.md +2 -2
  78. package/docs/guides/user-guide.md +22 -22
  79. package/docs/guides/workflows/BROWNFIELD-DISCOVERY-WORKFLOW.md +3 -3
  80. package/docs/guides/workflows/BROWNFIELD-SERVICE-WORKFLOW.md +1 -1
  81. package/docs/guides/workflows/GREENFIELD-UI-WORKFLOW.md +2 -2
  82. package/docs/guides/workflows/SPEC-PIPELINE-WORKFLOW.md +3 -3
  83. package/docs/guides/workflows/STORY-DEVELOPMENT-CYCLE-WORKFLOW.md +3 -3
  84. package/docs/guides/workflows/pro-developer-workflow.md +2 -2
  85. package/docs/guides/workflows-guide.md +1 -1
  86. package/docs/guides/workflows-overview.md +1 -1
  87. package/docs/installation/npx-install.md +1 -1
  88. package/docs/installation/uninstallation.md +1 -1
  89. package/docs/installation/v4-quick-start.md +1 -1
  90. package/docs/pt/guides/user-guide.md +18 -18
  91. package/docs/pt/security.md +2 -2
  92. package/docs/security/overview.md +2 -2
  93. package/docs/security/security-best-practices.md +1 -1
  94. package/docs/sinapse-agent-flows/architect-system.md +1 -1
  95. package/docs/sinapse-agent-flows/data-engineer-system.md +1 -1
  96. package/docs/sinapse-agent-flows/dev-system.md +1 -1
  97. package/docs/sinapse-agent-flows/devops-system.md +2 -2
  98. package/docs/sinapse-agent-flows/qa-system.md +1 -1
  99. package/docs/sinapse-agent-flows/sm-system.md +2 -2
  100. package/docs/sinapse-agent-flows/snps-orqx-system.md +4 -4
  101. package/docs/sinapse-agent-flows/squad-creator-system.md +1 -1
  102. package/docs/sinapse-workflows/README.md +2 -2
  103. package/docs/sinapse-workflows/brownfield-discovery-workflow.md +3 -3
  104. package/docs/sinapse-workflows/brownfield-service-workflow.md +3 -3
  105. package/docs/sinapse-workflows/greenfield-ui-workflow.md +2 -2
  106. package/docs/sinapse-workflows/spec-pipeline-workflow.md +3 -3
  107. package/docs/sinapse-workflows/story-development-cycle-workflow.md +3 -3
  108. package/docs/troubleshooting.md +1 -1
  109. package/package.json +7 -1
  110. package/scripts/calibrate-judge.js +134 -0
  111. package/scripts/eval-e2e.js +149 -0
  112. package/scripts/validate-all.js +8 -0
  113. package/scripts/validate-article-iv.js +289 -0
  114. package/scripts/validate-constitution.js +58 -0
  115. package/scripts/validate-evals.js +9 -2
  116. package/scripts/validate-story-acs.js +174 -0
  117. package/scripts/validate-tool-descriptions.js +128 -0
  118. package/scripts/wave-gate.js +207 -0
  119. package/squads/claude-code-mastery/agents/project-integrator.md +3 -10
  120. package/squads/claude-code-mastery/knowledge-base/context-window-optimization.md +2 -2
  121. package/squads/claude-code-mastery/knowledge-base/memory-systems-reference.md +1 -1
  122. package/squads/squad-copy/knowledge-base/ai-copy-human-loop-canon.md +1 -1
@@ -14,6 +14,7 @@
14
14
  const fs = require('fs-extra');
15
15
  const path = require('path');
16
16
  const EpicExecutor = require('./epic-executor');
17
+ const { classifyComplexity } = require('../spec-complexity');
17
18
 
18
19
  /**
19
20
  * Spec Pipeline phases
@@ -131,14 +132,26 @@ class Epic3Executor extends EpicExecutor {
131
132
  this._addArtifact('spec', specPath);
132
133
 
133
134
  // Collect complexity and requirements from phases
134
- const complexity = phaseResults['assess-complexity']?.complexity || 'STANDARD';
135
+ const assess = phaseResults['assess-complexity'] || {};
136
+ const complexity = assess.complexity || 'STANDARD';
135
137
  const requirements = phaseResults['gather-requirements']?.requirements || [];
136
138
 
139
+ // M4 (AF-20260704 #9b): turn the COMPLEX≥16 rule from prose into a
140
+ // deterministic classification. Prefer the numeric dimension score when the
141
+ // assess phase provides one; otherwise fall back to the level string.
142
+ const classification = classifyComplexity(
143
+ typeof assess.score === 'number' ? assess.score : assess.dimensions || complexity,
144
+ );
145
+
137
146
  // Honesty invariant (epic: orchestration-consolidation, F0a):
138
147
  // if the spec was auto-stubbed (no real agent ran), report STUB, not success.
139
148
  const specResult = {
140
149
  specPath,
141
- complexity,
150
+ complexity: classification.level,
151
+ complexityScore: classification.score,
152
+ requiresRevisionCycle: classification.requiresRevisionCycle,
153
+ requiresFullSpecPipeline: classification.requiresFullSpecPipeline,
154
+ specPipelinePhases: classification.phases,
142
155
  requirements,
143
156
  phases: Object.keys(phaseResults),
144
157
  };
@@ -193,12 +193,14 @@ class Epic4Executor extends EpicExecutor {
193
193
  async _executeViaBuildOrchestrator(storyId, context) {
194
194
  try {
195
195
  const { BuildOrchestrator } = require('../../execution/build-orchestrator');
196
+ // buildOptions is passed once, via build() — which already merges it over
197
+ // the constructor config ({...this.config, ...options}). Passing it in both
198
+ // places (AF-20260704 Lote B) was redundant, not wrong.
196
199
  const builder = new BuildOrchestrator({
197
200
  rootPath: this.projectRoot,
198
201
  useWorktree: false,
199
202
  autoMerge: false,
200
203
  runQA: false,
201
- ...(context.buildOptions || {}),
202
204
  });
203
205
  return await builder.build(storyId, context.buildOptions || {});
204
206
  } catch (err) {
@@ -152,9 +152,63 @@ class GreenfieldHandler extends EventEmitter {
152
152
  // Phase progress tracking
153
153
  this.phaseProgress = {};
154
154
 
155
+ // Onda3-S2: cached read of workflow metadata (confirmation_required).
156
+ this._confirmationRequired = null;
157
+
155
158
  this._log('GreenfieldHandler initialized');
156
159
  }
157
160
 
161
+ /**
162
+ * Reads `metadata.confirmation_required` from the resolved workflow YAML.
163
+ * Onda3-S2 (AF-20260702 item 3.4): the field used to be decorative — no code
164
+ * consumed it. Now `false` turns go_pause surfaces into auto-GO; `true` or
165
+ * any read/parse failure preserves the safe default (pause for the human).
166
+ *
167
+ * @returns {boolean} true = pause between phases (default), false = auto-GO
168
+ */
169
+ getConfirmationRequired() {
170
+ if (this._confirmationRequired !== null) return this._confirmationRequired;
171
+ let required = true;
172
+ try {
173
+ const yaml = require('js-yaml');
174
+ const raw = fs.readFileSync(this.workflowPath, 'utf8');
175
+ const parsed = yaml.load(raw);
176
+ if (parsed && parsed.metadata && parsed.metadata.confirmation_required === false) {
177
+ required = false;
178
+ }
179
+ } catch (error) {
180
+ this._log(`confirmation_required unreadable (default: true): ${error.message}`, 'warn');
181
+ }
182
+ this._confirmationRequired = required;
183
+ return required;
184
+ }
185
+
186
+ /**
187
+ * Deterministic artifact gate (Onda3-S2, AF-20260702 item 3.4).
188
+ * For every step that declares a file artifact (`creates` ending in .md),
189
+ * verifies the artifact exists on disk with content. Echoes the empty-build
190
+ * honesty fix: a phase does not advance on promises, only on artifacts.
191
+ *
192
+ * @param {Array<{agent: string, task: string, creates: ?string}>} sequence
193
+ * @returns {{passed: boolean, missing: Array<{agent: string, task: string, artifact: string}>, checked: number}}
194
+ */
195
+ evaluateArtifactGate(sequence) {
196
+ // Lazy require: doc-first-resolver imports constants from this module, so a
197
+ // top-level require here would create a load-order cycle with partial exports.
198
+ const { fileHasContent } = require('./doc-first-resolver');
199
+ const missing = [];
200
+ let checked = 0;
201
+ for (const step of sequence) {
202
+ if (!step.creates || !step.creates.endsWith('.md')) continue;
203
+ checked += 1;
204
+ const artifactPath = path.join(this.projectRoot, step.creates);
205
+ if (!fileHasContent(artifactPath)) {
206
+ missing.push({ agent: step.agent, task: step.task, artifact: step.creates });
207
+ }
208
+ }
209
+ return { passed: missing.length === 0, missing, checked };
210
+ }
211
+
158
212
  // ═══════════════════════════════════════════════════════════════════════════════════
159
213
  // LAZY DEPENDENCY LOADING
160
214
  // ═══════════════════════════════════════════════════════════════════════════════════
@@ -453,10 +507,45 @@ class GreenfieldHandler extends EventEmitter {
453
507
  }
454
508
  }
455
509
 
510
+ // Onda3-S2: deterministic artifact gate — the phase only completes when
511
+ // every declared artifact actually exists with content on disk.
512
+ const gate = this.evaluateArtifactGate(PHASE_1_SEQUENCE);
513
+ if (!gate.passed) {
514
+ this.phaseProgress[GreenfieldPhase.DISCOVERY] = {
515
+ status: 'gated',
516
+ endTime: Date.now(),
517
+ stepResults,
518
+ gate,
519
+ };
520
+ this.emit('phaseGated', { phase: GreenfieldPhase.DISCOVERY, gate, context });
521
+
522
+ const missingList = gate.missing
523
+ .map((m) => ` - ${m.artifact} (${m.agent} → *${m.task})`)
524
+ .join('\n');
525
+ return {
526
+ action: 'greenfield_gate_blocked',
527
+ phase: GreenfieldPhase.DISCOVERY,
528
+ nextPhase: 1,
529
+ data: {
530
+ gate: 'missing_artifact',
531
+ missing: gate.missing,
532
+ message:
533
+ 'Gate de artefato: a Phase 1 não avança sem os artefatos no disco.\n' +
534
+ `Faltando:\n${missingList}\n\n` +
535
+ 'Execute os agentes indicados (ou crie os documentos) e responda GO para revalidar.',
536
+ promptType: 'go_pause',
537
+ options: ['GO', 'PAUSE'],
538
+ resumeFromPhase: 1,
539
+ context: { ...context, phase1Results: stepResults },
540
+ },
541
+ };
542
+ }
543
+
456
544
  this.phaseProgress[GreenfieldPhase.DISCOVERY] = {
457
545
  status: 'complete',
458
546
  endTime: Date.now(),
459
547
  stepResults,
548
+ gate,
460
549
  };
461
550
 
462
551
  this.emit('phaseComplete', { phase: GreenfieldPhase.DISCOVERY, result: stepResults, context });
@@ -667,6 +756,14 @@ class GreenfieldHandler extends EventEmitter {
667
756
  * @private
668
757
  */
669
758
  _surfaceBetweenPhases(fromPhase, toPhase, surfaceConfig) {
759
+ // Onda3-S2: honor metadata.confirmation_required from the workflow YAML.
760
+ // Only go_pause surfaces auto-advance — text_input needs the human's words,
761
+ // and gate blocks never route through here.
762
+ if (surfaceConfig.promptType === 'go_pause' && this.getConfirmationRequired() === false) {
763
+ this._log(`confirmation_required=false — auto-GO Phase ${fromPhase} → ${toPhase}`);
764
+ return this._executeFromPhase(toPhase, surfaceConfig.context);
765
+ }
766
+
670
767
  const surfaceChecker = this._getSurfaceChecker();
671
768
 
672
769
  // Build options based on prompt type
@@ -158,6 +158,8 @@ const {
158
158
 
159
159
  module.exports = {
160
160
  // Main orchestrators
161
+ // @deprecated WorkflowOrchestrator has no internal consumers (AF-20260704);
162
+ // kept exported because the barrel is public package API. Prefer MasterOrchestrator.
161
163
  WorkflowOrchestrator,
162
164
  MasterOrchestrator, // Epic 0: ADE Master Orchestrator
163
165
 
@@ -290,6 +292,9 @@ module.exports = {
290
292
  STALE_SNAPSHOT_DAYS,
291
293
 
292
294
  // Story 12.4: Epic Context Accumulator (Projeto Bob)
295
+ // @deprecated EpicContextAccumulator has no internal consumers (AF-20260704;
296
+ // multi-story orchestration was measured and rejected — see KNOWN-LIMITATIONS.md).
297
+ // Kept exported because the barrel is public package API.
293
298
  EpicContextAccumulator,
294
299
  createEpicContextAccumulator,
295
300
  CompressionLevel,
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Spec-Pipeline Complexity — deterministic threshold + phase plan.
3
+ *
4
+ * The COMPLEX≥16 rule lived only in prose (`workflow-execution.md` §3,
5
+ * `documentation-first.md` complexity gate): "score ≥16 → COMPLEX → run the full
6
+ * Spec Pipeline (6 phases + revision cycle) FIRST". Nothing in code enforced the
7
+ * threshold or derived the phase plan from it, so the assessment was advisory.
8
+ *
9
+ * This module turns the threshold and the per-level phase plan into deterministic,
10
+ * tested code (Story rodada2-m4, AF-20260704 #9b). It does NOT invent HOW the five
11
+ * dimensions are scored — those values come from the `assess-complexity` phase; it
12
+ * only encodes the mapping score → level → required phases, canonically defined in
13
+ * `workflow-execution.md`.
14
+ *
15
+ * @module core/orchestration/spec-complexity
16
+ */
17
+
18
+ 'use strict';
19
+
20
+ /** The five complexity dimensions, each scored 1-5 (min 5, max 25). */
21
+ const DIMENSIONS = Object.freeze(['scope', 'integration', 'infrastructure', 'knowledge', 'risk']);
22
+
23
+ /**
24
+ * Canonical thresholds (`workflow-execution.md` §3):
25
+ * score <= 8 → SIMPLE
26
+ * 9..15 → STANDARD
27
+ * score >= 16 → COMPLEX
28
+ */
29
+ const THRESHOLDS = Object.freeze({ SIMPLE_MAX: 8, COMPLEX_MIN: 16 });
30
+
31
+ const LEVELS = Object.freeze({ SIMPLE: 'SIMPLE', STANDARD: 'STANDARD', COMPLEX: 'COMPLEX' });
32
+
33
+ /**
34
+ * Phase plans per level (`workflow-execution.md` §3 table):
35
+ * SIMPLE → gather → spec → critique (3)
36
+ * STANDARD → gather → assess → research → spec → critique → plan (6)
37
+ * COMPLEX → the 6 phases + a revision cycle (6 + revision)
38
+ */
39
+ const PHASES_BY_LEVEL = Object.freeze({
40
+ SIMPLE: Object.freeze(['gather-requirements', 'write-spec', 'critique']),
41
+ STANDARD: Object.freeze([
42
+ 'gather-requirements',
43
+ 'assess-complexity',
44
+ 'research-dependencies',
45
+ 'write-spec',
46
+ 'critique',
47
+ 'plan',
48
+ ]),
49
+ COMPLEX: Object.freeze([
50
+ 'gather-requirements',
51
+ 'assess-complexity',
52
+ 'research-dependencies',
53
+ 'write-spec',
54
+ 'critique',
55
+ 'plan',
56
+ ]),
57
+ });
58
+
59
+ /**
60
+ * Map a numeric complexity score to its level. Deterministic; no side effects.
61
+ * @param {number} score - Sum of the five dimensions (nominally 5..25).
62
+ * @returns {'SIMPLE'|'STANDARD'|'COMPLEX'}
63
+ */
64
+ function scoreToLevel(score) {
65
+ const n = Number(score);
66
+ if (!Number.isFinite(n)) return LEVELS.STANDARD; // conservative default
67
+ if (n <= THRESHOLDS.SIMPLE_MAX) return LEVELS.SIMPLE;
68
+ if (n >= THRESHOLDS.COMPLEX_MIN) return LEVELS.COMPLEX;
69
+ return LEVELS.STANDARD;
70
+ }
71
+
72
+ /** Normalize a level-ish input (a level string, in any case) to a canonical level. */
73
+ function normalizeLevel(level) {
74
+ const u = String(level || '').trim().toUpperCase();
75
+ return LEVELS[u] || null;
76
+ }
77
+
78
+ /**
79
+ * Sum an object of dimension → score (1-5). Missing dimensions count as 0.
80
+ * @param {Record<string, number>} dimensions
81
+ * @returns {number}
82
+ */
83
+ function sumDimensions(dimensions) {
84
+ if (!dimensions || typeof dimensions !== 'object') return NaN;
85
+ return DIMENSIONS.reduce((total, d) => {
86
+ const v = Number(dimensions[d]);
87
+ return total + (Number.isFinite(v) ? v : 0);
88
+ }, 0);
89
+ }
90
+
91
+ /**
92
+ * Classify complexity from either a numeric score, a dimensions object, or an
93
+ * already-decided level string. Returns the deterministic plan.
94
+ *
95
+ * @param {number|string|Record<string, number>} input
96
+ * @returns {{
97
+ * level: 'SIMPLE'|'STANDARD'|'COMPLEX',
98
+ * score: number|null,
99
+ * phases: string[],
100
+ * requiresRevisionCycle: boolean,
101
+ * requiresFullSpecPipeline: boolean
102
+ * }}
103
+ */
104
+ function classifyComplexity(input) {
105
+ let level;
106
+ let score = null;
107
+
108
+ if (typeof input === 'number') {
109
+ score = input;
110
+ level = scoreToLevel(input);
111
+ } else if (typeof input === 'string') {
112
+ level = normalizeLevel(input) || LEVELS.STANDARD;
113
+ } else if (input && typeof input === 'object') {
114
+ const s = sumDimensions(input);
115
+ score = Number.isFinite(s) ? s : null;
116
+ level = Number.isFinite(s) ? scoreToLevel(s) : LEVELS.STANDARD;
117
+ } else {
118
+ level = LEVELS.STANDARD; // conservative default when nothing usable is given
119
+ }
120
+
121
+ return {
122
+ level,
123
+ score,
124
+ phases: [...PHASES_BY_LEVEL[level]],
125
+ // COMPLEX is the only level that adds the revision cycle.
126
+ requiresRevisionCycle: level === LEVELS.COMPLEX,
127
+ // SIMPLE runs the trimmed 3-phase pipeline; STANDARD/COMPLEX run the full one.
128
+ requiresFullSpecPipeline: level !== LEVELS.SIMPLE,
129
+ };
130
+ }
131
+
132
+ module.exports = {
133
+ DIMENSIONS,
134
+ THRESHOLDS,
135
+ LEVELS,
136
+ PHASES_BY_LEVEL,
137
+ scoreToLevel,
138
+ normalizeLevel,
139
+ sumDimensions,
140
+ classifyComplexity,
141
+ };
@@ -474,7 +474,7 @@ class WorkflowExecutor {
474
474
  return { success: false, error: `Workflow definition is empty: ${workflowPath}` };
475
475
  }
476
476
 
477
- return {
477
+ const result = {
478
478
  success: true,
479
479
  workflowPath,
480
480
  workflow,
@@ -484,6 +484,22 @@ class WorkflowExecutor {
484
484
  techStack: options.techStack || {},
485
485
  },
486
486
  };
487
+
488
+ // Onda3-S3 (AF-20260702 item 3.3): the brownfield handoff now carries
489
+ // deterministic state — phase progress measured from artifacts on disk and
490
+ // the Phase 7 QA gate parsed by code (with capped rework loop). Fail-open:
491
+ // enrichment errors degrade to the plain handoff, never to a crash.
492
+ if (workflow.id === 'brownfield-discovery') {
493
+ try {
494
+ const { resolveBrownfieldProgress, evaluateQaGate } = require('./brownfield-progress');
495
+ result.progress = resolveBrownfieldProgress(result.context.projectRoot, workflow);
496
+ result.qaGate = evaluateQaGate(result.context.projectRoot);
497
+ } catch (error) {
498
+ result.progressError = `brownfield progress unavailable: ${error.message}`;
499
+ }
500
+ }
501
+
502
+ return result;
487
503
  }
488
504
 
489
505
  /**
@@ -193,6 +193,12 @@ github:
193
193
  draft_by_default: false
194
194
  semantic_release:
195
195
  enabled: true
196
+ # ── CodeRabbit integration — SINGLE SOURCE OF TRUTH ──────────────────────────
197
+ # This section (machine config) + .claude/rules/coderabbit-integration.md
198
+ # (auto-loaded, human-readable) are the ONE canonical source for WSL execution
199
+ # mechanics, self-healing thresholds, canonical review commands and report
200
+ # location. Agents REFERENCE this — they must NOT copy the mechanics into their
201
+ # own definitions. (Dedup: Story rodada2-m6-coderabbit-dedup.)
196
202
  coderabbit_integration:
197
203
  enabled: true
198
204
  installation_mode: wsl
@@ -213,11 +219,35 @@ coderabbit_integration:
213
219
  graceful_degradation:
214
220
  skip_if_not_installed: true
215
221
  fallback_message: 'CodeRabbit CLI not found. Skipping automated review. Install via: pip install coderabbit-cli'
222
+ # Canonical review commands (referenced by all agents; keyed by intent, not by agent).
216
223
  commands:
224
+ review_uncommitted: |
225
+ wsl bash -c 'cd ${PROJECT_ROOT} && ~/.local/bin/coderabbit --prompt-only -t uncommitted'
226
+ review_committed_base_main: |
227
+ wsl bash -c 'cd ${PROJECT_ROOT} && ~/.local/bin/coderabbit --prompt-only -t committed --base main'
228
+ review_against_main: |
229
+ wsl bash -c 'cd ${PROJECT_ROOT} && ~/.local/bin/coderabbit --prompt-only --base main'
230
+ review_committed: |
231
+ wsl bash -c 'cd ${PROJECT_ROOT} && ~/.local/bin/coderabbit --prompt-only -t committed'
232
+ # Back-compat aliases (previous key names):
217
233
  qa_pre_review_uncommitted: |
218
234
  wsl bash -c 'cd ${PROJECT_ROOT} && ~/.local/bin/coderabbit --prompt-only -t uncommitted'
219
235
  qa_story_review_committed: |
220
236
  wsl bash -c 'cd ${PROJECT_ROOT} && ~/.local/bin/coderabbit --prompt-only -t committed --base main'
237
+ execution_guidelines: |
238
+ CRITICAL: CodeRabbit CLI is installed in WSL, not Windows.
239
+
240
+ **How to Execute:**
241
+ 1. Use 'wsl bash -c' wrapper for all commands
242
+ 2. Navigate to project directory in WSL path format (/mnt/c/...)
243
+ 3. Use full path to coderabbit binary (~/.local/bin/coderabbit)
244
+
245
+ **Timeout:** dev/pre-push 15 min (900000ms); full QA review 30 min (1800000ms) — reviews take 7-30 min.
246
+
247
+ **Error Handling:**
248
+ - If "coderabbit: command not found" → verify installation in WSL (wsl_config.installation_path)
249
+ - If timeout → increase timeout, review is still processing
250
+ - If "not authenticated" → user needs to run: wsl bash -c '~/.local/bin/coderabbit auth status'
221
251
  report_location: docs/qa/coderabbit-reports/
222
252
  squads:
223
253
  templateLocation: templates/squad