chati-dev 4.0.1 → 4.0.3

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 (44) hide show
  1. package/framework/agents/build/dev.md +118 -26
  2. package/framework/agents/plan/ux.md +411 -8
  3. package/framework/config.yaml +3 -3
  4. package/framework/constitution.md +4 -3
  5. package/framework/domains/agents/architect.yaml +1 -3
  6. package/framework/domains/agents/brief.yaml +1 -1
  7. package/framework/domains/agents/brownfield-wu.yaml +2 -2
  8. package/framework/domains/agents/detail.yaml +1 -1
  9. package/framework/domains/agents/devops.yaml +2 -4
  10. package/framework/domains/agents/greenfield-wu.yaml +2 -2
  11. package/framework/domains/agents/phases.yaml +1 -1
  12. package/framework/domains/agents/qa-implementation.yaml +4 -6
  13. package/framework/domains/agents/qa-planning.yaml +7 -10
  14. package/framework/domains/agents/tasks.yaml +1 -1
  15. package/framework/domains/agents/ux.yaml +21 -3
  16. package/framework/domains/constitution.yaml +4 -4
  17. package/framework/domains/global.yaml +1 -1
  18. package/framework/intelligence/context-engine.md +1 -1
  19. package/framework/templates/brandbook-tmpl.yaml +40 -0
  20. package/framework/templates/component-spec-tmpl.yaml +50 -3
  21. package/package.json +2 -2
  22. package/src/api/index.js +10 -19
  23. package/src/autonomy/build-loop.js +1 -1
  24. package/src/autonomy/cause-analyzer.js +1 -1
  25. package/src/autonomy/worktree-manager.js +7 -2
  26. package/src/config/agent-customizer.js +1 -5
  27. package/src/config/context-file-generator.js +1 -1
  28. package/src/context/bracket-tracker.js +2 -13
  29. package/src/decision/engine.js +4 -0
  30. package/src/health/auto-fix.js +1 -1
  31. package/src/installer/core.js +8 -1
  32. package/src/intelligence/context-status.js +2 -17
  33. package/src/intelligence/decision-engine.js +5 -2
  34. package/src/intelligence/timeline.js +1 -1
  35. package/src/merger/semantic-merger.js +1 -1
  36. package/src/orchestrator/pipeline-manager.js +33 -46
  37. package/src/quality/metrics-collector.js +0 -2
  38. package/src/telemetry/config.js +2 -2
  39. package/src/telemetry/schema.js +1 -1
  40. package/src/terminal/isolation.js +10 -1
  41. package/src/terminal/prompt-builder.js +77 -9
  42. package/src/utils/brackets.js +29 -0
  43. package/src/utils/event-bus.js +1 -1
  44. package/src/utils/provider-limits.js +13 -0
@@ -1,13 +1,13 @@
1
1
  # QA Planning Agent Domain — Authority boundaries and behavioral rules for PRISM L2
2
2
 
3
- mission: "Define test strategy, quality gates, coverage plans, and risk matrices for the project."
3
+ mission: "Validate traceability, consistency, and completeness across all PLAN artifacts (Brief -> PRD -> Phases -> Tasks -> Criteria)."
4
4
 
5
5
  authority:
6
6
  exclusive:
7
- - test_strategy_definition
8
- - qa_gate_definition
9
- - coverage_planning
10
- - risk_matrix_creation
7
+ - traceability_validation
8
+ - plan_consistency_check
9
+ - criteria_quality_review
10
+ - adversarial_planning_review
11
11
  allowed:
12
12
  - read_any_file
13
13
  - read_architecture_docs
@@ -21,10 +21,7 @@ authority:
21
21
  redirectMessage: "QA Planning defines the strategy. QA Implementation executes it."
22
22
 
23
23
  outputs:
24
- - qa-plan.yaml
25
- - test-strategy.yaml
26
- - coverage-plan.yaml
27
- - risk-matrix.yaml
24
+ - qa-planning-report.md
28
25
 
29
26
  rules:
30
27
  - id: qap-score
@@ -45,7 +42,7 @@ rules:
45
42
 
46
43
  - id: qap-adversarial
47
44
  text: >
48
- ADVERSARIAL REVIEW: Every planning validation MUST identify minimum 3
45
+ ADVERSARIAL REVIEW: Every planning validation MUST identify minimum 5
49
46
  findings (gaps, improvements, or suggestions). Zero findings is
50
47
  suspiciously clean — re-analyze with deeper scrutiny across all
51
48
  traceability chains. Findings can be any severity.
@@ -24,7 +24,7 @@ authority:
24
24
  redirectMessage: "Task decomposition is complete. Redirecting to dev agent for implementation."
25
25
 
26
26
  outputs:
27
- - tasks/*.yaml
27
+ - tasks.md
28
28
 
29
29
  rules:
30
30
  - id: tk-01
@@ -24,9 +24,7 @@ authority:
24
24
  redirectMessage: "UX design is complete. Redirecting to dev agent for implementation."
25
25
 
26
26
  outputs:
27
- - ux-spec.yaml
28
- - component-map.yaml
29
- - wireframes.yaml
27
+ - ux-specification.md
30
28
 
31
29
  rules:
32
30
  - id: ux-01
@@ -48,3 +46,23 @@ rules:
48
46
  - id: ux-05
49
47
  text: "MUST NOT design backend logic or data flows; focus on user-facing experience only"
50
48
  priority: critical
49
+
50
+ - id: ux-06
51
+ text: "MUST NOT produce centered single-column layouts as default; minimum 2 distinct layout structures per page"
52
+ priority: high
53
+
54
+ - id: ux-07
55
+ text: "MUST specify all interactive states (default, hover, active, focus, disabled) and all data view states (populated, empty, loading, error, skeleton) for every component"
56
+ priority: critical
57
+
58
+ - id: ux-08
59
+ text: "MUST NOT use placeholder content (lorem ipsum, John Doe, example.com); all sample data must be domain-realistic"
60
+ priority: high
61
+
62
+ - id: ux-09
63
+ text: "MUST define Motion System: specify animation library by stack, include animation token layer (duration + easing), and catalogue mandatory micro-interactions and scroll animations with reduced-motion alternatives (Directive 6)"
64
+ priority: critical
65
+
66
+ - id: ux-10
67
+ text: "MUST perform component discovery via 21st.dev for all Molecules and Organisms before designing custom components; document source or rationale for each (Directive 7)"
68
+ priority: high
@@ -2,7 +2,7 @@
2
2
  # Source: chati.dev/constitution.md (19 Articles + Preamble)
3
3
 
4
4
  summary: >
5
- Constitution governance: self-validation required (loop until quality >= 95%),
5
+ Constitution governance: self-validation required (loop until tier-specific threshold met),
6
6
  guided options (1,2,3 format), persistent session state, two-layer handoff,
7
7
  language protocol (interaction=user lang, artifacts=English),
8
8
  deviation protocol, mode governance (planning/build/deploy),
@@ -17,7 +17,7 @@ rules:
17
17
  priority: critical
18
18
 
19
19
  - id: art-ii
20
- text: "Quality >= 95% self-validation required. Loop until threshold met."
20
+ text: "Quality self-validation required. Tiered thresholds: QA >= 95%, standard >= 90%, discovery >= 85%. Loop until met."
21
21
  priority: critical
22
22
 
23
23
  - id: art-iii
@@ -77,7 +77,7 @@ rules:
77
77
  priority: high
78
78
 
79
79
  - id: art-xvii
80
- text: "Execution mode governance: autonomous requires gate >= 90%. Safety net with circuit breaker (3 failures)."
80
+ text: "Execution mode governance: QA gates >= 95%, other agents >= 90%. Safety net with circuit breaker (3 failures)."
81
81
  priority: critical
82
82
 
83
83
  articles:
@@ -89,7 +89,7 @@ articles:
89
89
  priority: critical
90
90
  - profile-guided: "In guided profile, agents propose actions and wait for user confirmation before writes."
91
91
  priority: high
92
- - profile-autonomous: "In autonomous profile, agents execute without confirmation when gate scores >= 90%."
92
+ - profile-autonomous: "In autonomous profile, agents execute without confirmation when gate scores >= 95%."
93
93
  priority: critical
94
94
  - profile-always-confirm: "Destructive operations, deployments, deviations, and backward transitions always require confirmation regardless of profile."
95
95
  priority: critical
@@ -28,7 +28,7 @@ rules:
28
28
  priority: critical
29
29
  - guided-confirmation: "In guided profile, significant writes require user confirmation."
30
30
  priority: high
31
- - autonomous-gate-check: "Autonomous profile requires cumulative gate scores >= 90%."
31
+ - autonomous-gate-check: "Autonomous profile requires cumulative gate scores >= 95%."
32
32
  priority: critical
33
33
  - profile-downgrade: "If quality drops below threshold during autonomous execution, auto-downgrade to guided."
34
34
  priority: critical
@@ -165,7 +165,7 @@ Memory injection follows the same progressive reinforcement principle: as contex
165
165
 
166
166
  ---
167
167
 
168
- *Context Engine v2.0 — Chati.dev Intelligence Layer (Progressive Reinforcement Model)*
168
+ *Context Engine v4.0 — Chati.dev Intelligence Layer (Progressive Reinforcement Model)*
169
169
 
170
170
  ---
171
171
 
@@ -19,6 +19,7 @@ sections:
19
19
  - color_philosophy
20
20
  - spacing_rhythm
21
21
  - iconography_style
22
+ - motion_philosophy
22
23
 
23
24
  brand_voice:
24
25
  description: "Brand personality, tone, and communication style"
@@ -65,6 +66,9 @@ typography_rationale:
65
66
  color_philosophy:
66
67
  description: "Color palette rationale and emotional associations"
67
68
  fields:
69
+ - name: industry_specific_reasoning
70
+ type: string
71
+ description: "Why these colors for THIS industry/sector — must reference Industry-Specific Palette Reasoning table from Directive 4"
68
72
  - name: primary_palette
69
73
  type: array
70
74
  description: "Primary colors with emotional rationale"
@@ -74,6 +78,9 @@ color_philosophy:
74
78
  - name: accessibility_notes
75
79
  type: string
76
80
  description: "WCAG contrast compliance notes"
81
+ - name: bias_check
82
+ type: object
83
+ description: "Anti-bias validation: confirm primary color is NOT generic SaaS blue, saturation is intentional, neutral scale has 9+ steps"
77
84
 
78
85
  spacing_rhythm:
79
86
  description: "Spacing scale rationale and rhythm system"
@@ -101,6 +108,36 @@ iconography_style:
101
108
  type: array
102
109
  description: "Guidelines for icon metaphor selection"
103
110
 
111
+ motion_philosophy:
112
+ description: "Animation personality and motion system definition (Directive 6)"
113
+ fields:
114
+ - name: scroll_personality
115
+ type: enum
116
+ values: [Energetic, Elegant, Minimal, Playful]
117
+ description: "Animation character aligned with brand visual direction"
118
+ - name: micro_animation_style
119
+ type: string
120
+ description: "Description of hover and interaction animation character"
121
+ - name: timing_defaults
122
+ type: object
123
+ description: "Default duration and easing tokens for this brand"
124
+ sub_fields:
125
+ - name: primary_duration
126
+ type: string
127
+ description: "Primary animation duration token (e.g. --motion-duration-normal)"
128
+ default: "--motion-duration-normal (350ms)"
129
+ - name: primary_easing
130
+ type: string
131
+ description: "Primary easing token (e.g. --motion-ease-standard)"
132
+ default: "--motion-ease-standard"
133
+ - name: library
134
+ type: string
135
+ description: "Animation library for this project's stack"
136
+ examples:
137
+ - "motion/react (React/Next.js)"
138
+ - "@vueuse/motion (Vue 3)"
139
+ - "CSS animations (plain HTML/CSS)"
140
+
104
141
  rules:
105
142
  - id: brand-before-tokens
106
143
  text: "Brandbook MUST be completed before design tokens are defined."
@@ -111,3 +148,6 @@ rules:
111
148
  - id: brand-voice-artifacts
112
149
  text: "All user-facing text in artifacts must follow brand voice guidelines."
113
150
  priority: high
151
+ - id: brand-no-default-blue
152
+ text: "Primary color MUST NOT be generic SaaS blue (#3B82F6 or similar) unless the brand explicitly requires it with documented rationale."
153
+ priority: high
@@ -38,9 +38,53 @@ fields:
38
38
  description: "Size variants (xs, sm, md, lg, xl)"
39
39
  required: true
40
40
  - name: states
41
- type: array
42
- description: "Interactive states (default, hover, active, focus, disabled, loading, error)"
41
+ type: object
42
+ description: "Component states organized by category"
43
43
  required: true
44
+ sub_fields:
45
+ - name: interactive
46
+ type: array
47
+ description: "REQUIRED: default, hover, active, focus, disabled"
48
+ required: true
49
+ - name: input
50
+ type: array
51
+ description: "For input components: empty, filled, error, success, loading"
52
+ required: false
53
+ - name: data_view
54
+ type: array
55
+ description: "For data display components: populated, empty, loading, error, skeleton"
56
+ required: false
57
+ - name: animation
58
+ type: object
59
+ description: "Animation states using motion tokens from Design System Layer 5"
60
+ required: false
61
+ sub_fields:
62
+ - name: entrance
63
+ type: object
64
+ description: "How component enters the DOM (opacity + translateY default)"
65
+ example:
66
+ property: "opacity + translateY"
67
+ duration: "--motion-duration-normal"
68
+ easing: "--motion-ease-decelerate"
69
+ - name: hover
70
+ type: object
71
+ description: "Transform on hover — GPU properties only"
72
+ example:
73
+ property: "transform"
74
+ duration: "--motion-duration-fast"
75
+ easing: "--motion-ease-spring"
76
+ - name: exit
77
+ type: object
78
+ description: "How component exits the DOM"
79
+ example:
80
+ property: "opacity + scale"
81
+ duration: "--motion-duration-fast"
82
+ easing: "--motion-ease-accelerate"
83
+ - name: reduced_motion
84
+ type: object
85
+ description: "Fallback for prefers-reduced-motion"
86
+ example:
87
+ fallback: "opacity only, duration --motion-duration-fast"
44
88
  - name: anatomy
45
89
  type: object
46
90
  description: "Component parts and their structure"
@@ -70,5 +114,8 @@ rules:
70
114
  text: "Every component MUST have ARIA roles and keyboard navigation defined."
71
115
  priority: critical
72
116
  - id: state-coverage
73
- text: "All interactive states must be specified including disabled and loading."
117
+ text: "All 5 interactive states (default, hover, active, focus, disabled) are mandatory. Data display components must also include populated, empty, loading, error, and skeleton."
118
+ priority: critical
119
+ - id: no-placeholder-content
120
+ text: "All example content in component specs must be domain-realistic. No lorem ipsum or generic names."
74
121
  priority: high
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chati-dev",
3
- "version": "4.0.1",
3
+ "version": "4.0.3",
4
4
  "description": "AI-Powered Multi-Agent Orchestration System — Structured vibe coding for Full Stack Development",
5
5
  "type": "module",
6
6
  "bin": {
@@ -70,7 +70,7 @@
70
70
  },
71
71
  "devDependencies": {
72
72
  "@eslint/js": "^10.0.1",
73
- "eslint": "^10.0.0",
73
+ "eslint": "^10.1.0",
74
74
  "globals": "^17.3.0"
75
75
  }
76
76
  }
package/src/api/index.js CHANGED
@@ -37,27 +37,18 @@ export { selectAgent } from '../orchestrator/agent-selector.js';
37
37
  // Session Management
38
38
  // ---------------------------------------------------------------------------
39
39
 
40
- import {
41
- initSession as _initSession,
42
- loadSession as _loadSession,
43
- updateSession as _updateSession,
44
- validateSession as _validateSession,
45
- getSessionSummary as _getSessionSummary,
46
- claimSession as _claimSession,
47
- releaseSession as _releaseSession,
48
- getSessionOwner as _getSessionOwner,
49
- } from '../orchestrator/session-manager.js';
40
+ import { initSession as _initSession } from '../orchestrator/session-manager.js';
50
41
 
51
42
  export {
52
- _initSession as initSession,
53
- _loadSession as loadSession,
54
- _updateSession as updateSession,
55
- _validateSession as validateSession,
56
- _getSessionSummary as getSessionSummary,
57
- _claimSession as claimSession,
58
- _releaseSession as releaseSession,
59
- _getSessionOwner as getSessionOwner,
60
- };
43
+ initSession,
44
+ loadSession,
45
+ updateSession,
46
+ validateSession,
47
+ getSessionSummary,
48
+ claimSession,
49
+ releaseSession,
50
+ getSessionOwner,
51
+ } from '../orchestrator/session-manager.js';
61
52
 
62
53
  // ---------------------------------------------------------------------------
63
54
  // Autonomy
@@ -124,7 +124,7 @@ export async function runBuildLoop(config) {
124
124
 
125
125
  // --- Escalation check (before execution) ---
126
126
  const previousAttempts = attemptHistory.get(checkpoint.taskId) || [];
127
- let executorOptions = {};
127
+ const executorOptions = {};
128
128
 
129
129
  if (checkpoint.attempts > 0 && checkpoint.error) {
130
130
  // Analyze the cause of the previous failure
@@ -147,7 +147,7 @@ function extractRootCause(text, category) {
147
147
  * @param {string} rootCause
148
148
  * @returns {string}
149
149
  */
150
- function generateSuggestion(category, rootCause) {
150
+ function generateSuggestion(category, _rootCause) {
151
151
  const suggestions = {
152
152
  [FAILURE_CATEGORIES.SYNTAX_ERROR]: 'Check for missing brackets, semicolons, or malformed expressions. Review the exact line mentioned in the error.',
153
153
  [FAILURE_CATEGORIES.TEST_FAILURE]: 'Review the failing test assertions. Ensure the implementation matches the expected behavior described in the test.',
@@ -9,7 +9,7 @@
9
9
 
10
10
  /**
11
11
  * @deprecated Not currently imported by any production module.
12
- * Retained for potential future integration. Remove if still unused by v4.0.
12
+ * Retained for potential future integration. Review for removal or integration by v5.0.
13
13
  */
14
14
 
15
15
  import { execSync } from 'child_process';
@@ -32,12 +32,17 @@ const MAX_WORKTREE_AGE_MS = 24 * 60 * 60 * 1000;
32
32
 
33
33
  /**
34
34
  * Execute a git command in a given directory and return trimmed stdout.
35
+ * Sanitizes `cmd` to reject shell metacharacters (prevents injection).
35
36
  *
36
37
  * @param {string} cmd - Git command (without the `git` prefix)
37
38
  * @param {string} cwd - Working directory
38
39
  * @returns {string} Trimmed stdout
40
+ * @throws {Error} If cmd contains shell metacharacters
39
41
  */
40
42
  function git(cmd, cwd) {
43
+ if (/[`$;|&><(){}]/.test(cmd)) {
44
+ throw new Error(`Unsafe characters in git command: ${cmd}`);
45
+ }
41
46
  return execSync(`git ${cmd}`, {
42
47
  cwd,
43
48
  encoding: 'utf-8',
@@ -157,7 +162,7 @@ export function mergeWorktree(projectDir, worktreeBranch, mainBranch) {
157
162
  try {
158
163
  git(`merge "${worktreeBranch}" --no-edit`, absProject);
159
164
  return { success: true, conflicts: [] };
160
- } catch (err) {
165
+ } catch {
161
166
  // Parse conflicts from error output
162
167
  const conflicts = [];
163
168
  try {
@@ -103,11 +103,7 @@ export function applyCustomization(agentPrompt, customization) {
103
103
  if (customization.skip_sections && Array.isArray(customization.skip_sections)) {
104
104
  for (const sectionName of customization.skip_sections) {
105
105
  // Match section heading + all content until the next heading of same or higher level, or end of text
106
- const pattern = new RegExp(
107
- `^#{1,3}\\s+${escapeRegex(sectionName)}\\s*\\n[\\s\\S]*?(?=\\n#{1,3}\\s|\\Z)`,
108
- 'gm'
109
- );
110
- // \\Z is not JS — use two-pass: try lookahead for next heading, then fallback to end
106
+ // Two-pass approach: try lookahead for next heading, then fallback to end
111
107
  const headingPattern = new RegExp(
112
108
  `^(#{1,3})\\s+${escapeRegex(sectionName)}[^\\n]*\\n([\\s\\S]*?)(?=^#{1,3}\\s)`,
113
109
  'gm'
@@ -151,7 +151,7 @@ export function generateAgentsMd(content, contextFiles = null) {
151
151
  // Inline context files for full governance parity (Codex has no @import)
152
152
  if (contextFiles) {
153
153
  const sections = [];
154
- for (const [name, fileContent] of Object.entries(contextFiles)) {
154
+ for (const [, fileContent] of Object.entries(contextFiles)) {
155
155
  if (fileContent) {
156
156
  // Adapt context for Codex (replace Claude-specific refs)
157
157
  let adapted = fileContent;
@@ -18,19 +18,8 @@
18
18
  * CRITICAL = 5.0% → maximum reinforcement (last interactions before handoff)
19
19
  */
20
20
 
21
- /** Provider context window limits (tokens). */
22
- const PROVIDER_LIMITS = {
23
- claude: 200_000,
24
- gemini: 1_000_000,
25
- codex: 128_000,
26
- };
27
-
28
- const BRACKETS = {
29
- FRESH: { min: 60, max: 100, layers: ['L0', 'L1', 'L2', 'L3', 'L4', 'L5'], budgetRatio: 0.015 },
30
- MODERATE: { min: 40, max: 60, layers: ['L0', 'L1', 'L2', 'L3', 'L5'], budgetRatio: 0.025 },
31
- DEPLETED: { min: 25, max: 40, layers: ['L0', 'L1', 'L2'], budgetRatio: 0.040 },
32
- CRITICAL: { min: 0, max: 25, layers: ['L0', 'L1'], budgetRatio: 0.050 },
33
- };
21
+ import { PROVIDER_LIMITS } from '../utils/provider-limits.js';
22
+ import { BRACKETS } from '../utils/brackets.js';
34
23
 
35
24
  /**
36
25
  * Memory injection level per bracket.
@@ -2,6 +2,10 @@
2
2
  * Decision Engine - Core COMPASS module for chati.dev
3
3
  * Analyzes intent and recommends: REUSE (>=90%), ADAPT (60-89%), CREATE (<60%)
4
4
  *
5
+ * NOTE: This module handles entity-level routing (registry lookup).
6
+ * For intent-level similarity scoring (weighted keyword + purpose),
7
+ * see `intelligence/decision-engine.js` (calculateIntentSimilarity).
8
+ *
5
9
  * @module decision/engine
6
10
  */
7
11
 
@@ -45,7 +45,7 @@ const STALE_LOCK_AGE_MS = 30_000;
45
45
  * @param {object[]} [checkResults=[]] - Results from health checks (for targeted fixes)
46
46
  * @returns {AutoFixResult}
47
47
  */
48
- export function autoFix(projectDir, checkResults = []) {
48
+ export function autoFix(projectDir, _checkResults = []) {
49
49
  const actions = [];
50
50
 
51
51
  // Fix 1: Ensure required directories exist
@@ -177,6 +177,10 @@ function copyFrameworkFiles(destDir, provider = 'claude') {
177
177
  'templates/task-tmpl.yaml',
178
178
  'templates/qa-gate-tmpl.yaml',
179
179
  'templates/quick-brief-tmpl.yaml',
180
+ 'templates/brandbook-tmpl.yaml',
181
+ 'templates/design-token-tmpl.yaml',
182
+ 'templates/component-spec-tmpl.yaml',
183
+ 'templates/icon-system-tmpl.yaml',
180
184
  // Workflows
181
185
  'workflows/greenfield-fullstack.yaml',
182
186
  'workflows/brownfield-fullstack.yaml',
@@ -184,6 +188,7 @@ function copyFrameworkFiles(destDir, provider = 'claude') {
184
188
  'workflows/brownfield-service.yaml',
185
189
  'workflows/brownfield-ui.yaml',
186
190
  'workflows/quick-flow.yaml',
191
+ 'workflows/standard-flow.yaml',
187
192
  // Quality gates
188
193
  'quality-gates/planning-gate.md',
189
194
  'quality-gates/implementation-gate.md',
@@ -205,6 +210,7 @@ function copyFrameworkFiles(destDir, provider = 'claude') {
205
210
  'intelligence/decision-engine.md',
206
211
  // Patterns
207
212
  'patterns/elicitation.md',
213
+ 'patterns/elicitation-library.yaml',
208
214
  // Hooks
209
215
  'hooks/prism-engine.js',
210
216
  'hooks/mode-governance.js',
@@ -235,6 +241,7 @@ function copyFrameworkFiles(destDir, provider = 'claude') {
235
241
  'domains/workflows/brownfield-service.yaml',
236
242
  'domains/workflows/brownfield-ui.yaml',
237
243
  'domains/workflows/quick-flow.yaml',
244
+ 'domains/workflows/standard-flow.yaml',
238
245
  // i18n
239
246
  'i18n/en.yaml',
240
247
  'i18n/pt.yaml',
@@ -274,7 +281,7 @@ function copyFrameworkFiles(destDir, provider = 'claude') {
274
281
  * Configure a specific IDE
275
282
  */
276
283
  async function configureIDE(targetDir, ideKey, selectedMCPs, options = {}) {
277
- const { orchestratorPath, isSecondary } = options;
284
+ const { orchestratorPath } = options;
278
285
  const config = IDE_CONFIGS[ideKey];
279
286
  if (!config) return;
280
287
 
@@ -1,23 +1,8 @@
1
1
  import { existsSync, readFileSync } from 'fs';
2
2
  import { join } from 'path';
3
3
 
4
- /** Provider context window limits (tokens). */
5
- const PROVIDER_LIMITS = {
6
- claude: 200_000,
7
- gemini: 1_000_000,
8
- codex: 128_000,
9
- };
10
-
11
- const BRACKETS = [
12
- { name: 'FRESH', min: 60, max: 100, layers: ['L0', 'L1', 'L2', 'L3', 'L4', 'L5'], budgetRatio: 0.015 },
13
- { name: 'MODERATE', min: 40, max: 60, layers: ['L0', 'L1', 'L2', 'L3', 'L5'], budgetRatio: 0.025 },
14
- { name: 'DEPLETED', min: 25, max: 40, layers: ['L0', 'L1', 'L2'], budgetRatio: 0.040 },
15
- { name: 'CRITICAL', min: 0, max: 25, layers: ['L0', 'L1'], budgetRatio: 0.050 },
16
- ];
17
- // NOTE: This BRACKETS array is intentionally duplicated from src/context/bracket-tracker.js
18
- // for module isolation. bracket-tracker.js is the canonical source of truth.
19
- // Progressive Reinforcement Model (v4.0): budgets as ratio of provider context window.
20
- // If bracket ranges or ratios change, update BOTH files.
4
+ import { PROVIDER_LIMITS } from '../utils/provider-limits.js';
5
+ import { BRACKETS_LIST as BRACKETS } from '../utils/brackets.js';
21
6
 
22
7
  /**
23
8
  * Get context status based on session state
@@ -4,6 +4,9 @@
4
4
  * Before creating any new artifact, scores existing registry entities
5
5
  * for similarity. Enforces Constitution Article XIV: REUSE > ADAPT > CREATE.
6
6
  *
7
+ * NOTE: This module handles intent-level similarity with weighted scoring.
8
+ * For entity-level routing (COMPASS registry lookup), see `decision/engine.js`.
9
+ *
7
10
  * Algorithm:
8
11
  * similarity = (keywordOverlap * 0.6) + (purposeSimilarity * 0.4)
9
12
  * >= 90% → REUSE, 60-89% → ADAPT, < 60% → CREATE
@@ -61,7 +64,7 @@ export function evaluateDecision(intent, registryPath) {
61
64
  let bestId = null;
62
65
 
63
66
  for (const entity of entities) {
64
- const score = calculateSimilarity(intent, entity);
67
+ const score = calculateIntentSimilarity(intent, entity);
65
68
  if (score > bestScore) {
66
69
  bestScore = score;
67
70
  bestMatch = entity;
@@ -104,7 +107,7 @@ export function evaluateDecision(intent, registryPath) {
104
107
  * @param {{ keywords: string[], purpose: string }} entity
105
108
  * @returns {number} 0.0 to 1.0
106
109
  */
107
- export function calculateSimilarity(intent, entity) {
110
+ export function calculateIntentSimilarity(intent, entity) {
108
111
  const kwScore = keywordOverlap(intent.keywords, entity.keywords || []);
109
112
  const purposeScore = purposeSimilarity(intent.purpose, entity.purpose || '');
110
113
  return (kwScore * 0.6) + (purposeScore * 0.4);
@@ -8,7 +8,7 @@
8
8
 
9
9
  /**
10
10
  * @deprecated Not currently imported by any production module.
11
- * Retained for potential future integration. Remove if still unused by v4.0.
11
+ * Retained for potential future integration. Review for removal or integration by v5.0.
12
12
  */
13
13
 
14
14
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
@@ -165,7 +165,7 @@ export function mergeChanges(changes, strategy = MERGE_STRATEGIES.CONSERVATIVE)
165
165
  const merged = [];
166
166
  const skipped = [];
167
167
 
168
- for (const [file, agentChanges] of fileAgentMap.entries()) {
168
+ for (const [, agentChanges] of fileAgentMap.entries()) {
169
169
  const agents = [...new Set(agentChanges.map(c => c.agent))];
170
170
 
171
171
  if (agents.length === 1) {