chati-dev 4.3.1 → 4.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 (158) hide show
  1. package/README.md +18 -13
  2. package/bin/chati.js +28 -4
  3. package/framework/agents/build/dev.md +5 -1
  4. package/framework/agents/discover/greenfield-wu.md +16 -1
  5. package/framework/agents/plan/tasks.md +31 -0
  6. package/framework/agents/plan/ux-brand-architect.md +21 -2
  7. package/framework/agents/plan/ux-component-engineer.md +10 -0
  8. package/framework/agents/quality/qa-implementation.md +1 -1
  9. package/framework/agents/quality/qa-planning.md +1 -1
  10. package/framework/agents/quality/qa-visual.md +24 -21
  11. package/framework/config.yaml +5 -4
  12. package/framework/constitution.md +60 -11
  13. package/framework/context/governance.md +12 -10
  14. package/framework/context/root.md +2 -2
  15. package/framework/data/entity-registry.yaml +12 -4
  16. package/framework/data/qa-rubrics.yaml +335 -0
  17. package/framework/domains/constitution.yaml +3 -3
  18. package/framework/executors/json-validate.js +80 -0
  19. package/framework/executors/npm-script.js +72 -0
  20. package/framework/executors/path-check.js +67 -0
  21. package/framework/executors/registry.yaml +36 -0
  22. package/framework/hooks/advance-trigger.js +47 -3
  23. package/framework/hooks/constitution-guard.js +9 -4
  24. package/framework/hooks/git-push-authority.js +113 -0
  25. package/framework/hooks/license-guard.js +59 -9
  26. package/framework/hooks/model-governance.js +40 -17
  27. package/framework/hooks/prism-engine.js +78 -11
  28. package/framework/hooks/session-digest.js +12 -3
  29. package/framework/hooks/settings.json +7 -3
  30. package/framework/hooks/style-guard.js +52 -3
  31. package/framework/hooks/team-quality-gate.js +43 -5
  32. package/framework/i18n/en.yaml +3 -3
  33. package/framework/i18n/es.yaml +3 -3
  34. package/framework/i18n/fr.yaml +3 -3
  35. package/framework/i18n/pt.yaml +3 -3
  36. package/framework/intelligence/confidence.yaml +85 -6
  37. package/framework/intelligence/context-engine.md +9 -5
  38. package/framework/intelligence/decision-engine.md +1 -1
  39. package/framework/manifest.json +1351 -0
  40. package/framework/manifest.sig +1 -0
  41. package/framework/orchestrator/chati-router.js +1 -1
  42. package/framework/orchestrator/chati-update.md +19 -3
  43. package/framework/orchestrator/chati.md +24 -3
  44. package/framework/quality-gates/planning-gate.md +2 -0
  45. package/framework/scaffold/motion-premium/scaffold.yaml +2 -1
  46. package/framework/scaffold/motion-premium-3d/components/webgl/WebGLContext.tsx.template +1 -1
  47. package/framework/scaffold/saas-dashboard/README.md +58 -0
  48. package/framework/scaffold/saas-dashboard/app/dashboard/page.tsx.template +546 -0
  49. package/framework/scaffold/saas-dashboard/app/globals.css.template +746 -0
  50. package/framework/scaffold/saas-dashboard/app/layout.tsx.template +192 -0
  51. package/framework/scaffold/saas-dashboard/app/shell.css.template +1070 -0
  52. package/framework/scaffold/saas-dashboard/components/data/Chart.tsx.template +725 -0
  53. package/framework/scaffold/saas-dashboard/components/data/DataTable.tsx.template +623 -0
  54. package/framework/scaffold/saas-dashboard/components/data/DataTable.types.ts.template +104 -0
  55. package/framework/scaffold/saas-dashboard/components/data/DataTablePagination.tsx.template +234 -0
  56. package/framework/scaffold/saas-dashboard/components/data/SkeletonBlock.tsx.template +111 -0
  57. package/framework/scaffold/saas-dashboard/components/data/StatCard.tsx.template +393 -0
  58. package/framework/scaffold/saas-dashboard/components/data/StatCardGrid.tsx.template +121 -0
  59. package/framework/scaffold/saas-dashboard/components/feedback/EmptyState.tsx.template +281 -0
  60. package/framework/scaffold/saas-dashboard/components/interaction/CommandPalette.tsx.template +767 -0
  61. package/framework/scaffold/saas-dashboard/components/interaction/Field.tsx.template +351 -0
  62. package/framework/scaffold/saas-dashboard/components/interaction/Form.tsx.template +424 -0
  63. package/framework/scaffold/saas-dashboard/components/primitives/Badge.tsx.template +193 -0
  64. package/framework/scaffold/saas-dashboard/components/primitives/Button.tsx.template +261 -0
  65. package/framework/scaffold/saas-dashboard/components/primitives/Card.tsx.template +287 -0
  66. package/framework/scaffold/saas-dashboard/components/primitives/Input.tsx.template +310 -0
  67. package/framework/scaffold/saas-dashboard/components/primitives/Spinner.tsx.template +135 -0
  68. package/framework/scaffold/saas-dashboard/components/primitives/index.ts.template +60 -0
  69. package/framework/scaffold/saas-dashboard/components/shell/AppShell.tsx.template +174 -0
  70. package/framework/scaffold/saas-dashboard/components/shell/Breadcrumb.tsx.template +186 -0
  71. package/framework/scaffold/saas-dashboard/components/shell/Container.tsx.template +86 -0
  72. package/framework/scaffold/saas-dashboard/components/shell/NavItem.tsx.template +147 -0
  73. package/framework/scaffold/saas-dashboard/components/shell/Sidebar.tsx.template +378 -0
  74. package/framework/scaffold/saas-dashboard/components/shell/SidebarContext.tsx.template +169 -0
  75. package/framework/scaffold/saas-dashboard/components/shell/ThemeToggle.tsx.template +128 -0
  76. package/framework/scaffold/saas-dashboard/components/shell/Topbar.tsx.template +301 -0
  77. package/framework/scaffold/saas-dashboard/lib/brand.ts.template +324 -0
  78. package/framework/scaffold/saas-dashboard/scaffold.yaml +225 -0
  79. package/framework/schemas/session.schema.json +5 -0
  80. package/framework/schemas/task.schema.json +9 -0
  81. package/framework/scripts/visual-qa.js +87 -1
  82. package/framework/tasks/orchestrator-health.md +4 -4
  83. package/framework/tasks/qa-impl-verdict.md +11 -5
  84. package/framework/templates/qa-gate-tmpl.yaml +24 -11
  85. package/package.json +4 -4
  86. package/src/config/claude-settings-generator.js +9 -6
  87. package/src/config/context-file-generator.js +0 -6
  88. package/src/dashboard/renderer.js +0 -36
  89. package/src/executors/runner.js +204 -0
  90. package/src/installer/core.js +35 -4
  91. package/src/installer/manifest.js +30 -4
  92. package/src/installer/signing-public-key.pem +1 -1
  93. package/src/installer/templates.js +5 -6
  94. package/src/installer/validator.js +2 -1
  95. package/src/intelligence/registry-manager.js +3 -2
  96. package/src/license/client.js +9 -3
  97. package/src/license/commands.js +12 -2
  98. package/src/license/machine-id.js +42 -1
  99. package/src/memory/gotchas.js +58 -40
  100. package/src/memory/magic-docs.js +7 -2
  101. package/src/memory/session-digest.js +9 -4
  102. package/src/orchestrator/cli.js +195 -23
  103. package/src/orchestrator/deviation-handler.js +5 -3
  104. package/src/orchestrator/doctor.js +98 -16
  105. package/src/orchestrator/pipeline-manager.js +44 -22
  106. package/src/orchestrator/session-manager.js +56 -8
  107. package/src/telemetry/sender.js +7 -19
  108. package/src/terminal/run-parallel.js +14 -14
  109. package/src/terminal/run-team.js +3 -3
  110. package/src/upgrade/backup.js +22 -44
  111. package/src/upgrade/migrator.js +51 -12
  112. package/src/upgrade/tracked-files-detector.js +34 -16
  113. package/src/utils/constitution-meta.js +12 -0
  114. package/src/utils/feature-flags.js +26 -2
  115. package/src/utils/flatten-entities.js +4 -40
  116. package/src/utils/schema-validator.js +0 -14
  117. package/src/wizard/i18n.js +3 -3
  118. package/src/api/index.js +0 -120
  119. package/src/autonomy/autonomous-gate.js +0 -294
  120. package/src/autonomy/build-loop.js +0 -281
  121. package/src/autonomy/build-state.js +0 -286
  122. package/src/autonomy/cause-analyzer.js +0 -177
  123. package/src/autonomy/escalation.js +0 -214
  124. package/src/autonomy/index.js +0 -51
  125. package/src/autonomy/mode-manager.js +0 -225
  126. package/src/autonomy/mode-suggester.js +0 -283
  127. package/src/autonomy/progress-reporter.js +0 -275
  128. package/src/autonomy/safety-net.js +0 -370
  129. package/src/config/agent-customizer.js +0 -231
  130. package/src/decision/analyzer.js +0 -291
  131. package/src/decision/engine.js +0 -250
  132. package/src/decision/index.js +0 -38
  133. package/src/decision/registry-healer.js +0 -468
  134. package/src/decision/registry-updater.js +0 -339
  135. package/src/extensions/loader.js +0 -145
  136. package/src/extensions/registry.js +0 -134
  137. package/src/gates/circuit-breaker.js +0 -151
  138. package/src/gates/g1-planning-complete.js +0 -154
  139. package/src/gates/g2-qa-planning.js +0 -156
  140. package/src/gates/g3-implementation.js +0 -215
  141. package/src/gates/g4-qa-implementation.js +0 -240
  142. package/src/gates/g5-deploy-ready.js +0 -181
  143. package/src/gates/gate-base.js +0 -185
  144. package/src/gates/index.js +0 -46
  145. package/src/health/auto-fix.js +0 -216
  146. package/src/health/engine.js +0 -246
  147. package/src/merger/semantic-merger.js +0 -292
  148. package/src/preview/detector.js +0 -238
  149. package/src/preview/index.js +0 -20
  150. package/src/preview/launcher.js +0 -235
  151. package/src/preview/log-buffer.js +0 -103
  152. package/src/quality/metrics-collector.js +0 -281
  153. package/src/quality/test-runner.js +0 -366
  154. package/src/tasks/executor.js +0 -195
  155. package/src/tasks/index.js +0 -4
  156. package/src/tasks/loader.js +0 -210
  157. package/src/tasks/router.js +0 -182
  158. package/src/utils/event-bus.js +0 -126
@@ -1,177 +0,0 @@
1
- /**
2
- * @fileoverview Cause analysis for failed build loop tasks.
3
- *
4
- * Analyzes agent output to classify failure categories, detect
5
- * repetitive patterns, and generate retry guidance.
6
- *
7
- * Constitution Article XVII — Execution Mode Governance.
8
- */
9
-
10
- // ---------------------------------------------------------------------------
11
- // Failure Categories
12
- // ---------------------------------------------------------------------------
13
-
14
- /**
15
- * Categories of task failures.
16
- * @enum {string}
17
- */
18
- export const FAILURE_CATEGORIES = {
19
- SYNTAX_ERROR: 'syntax_error',
20
- TEST_FAILURE: 'test_failure',
21
- LINT_VIOLATION: 'lint_violation',
22
- TYPE_ERROR: 'type_error',
23
- TIMEOUT: 'timeout',
24
- SCOPE_VIOLATION: 'scope_violation',
25
- DEPENDENCY: 'dependency',
26
- RUNTIME_ERROR: 'runtime_error',
27
- UNKNOWN: 'unknown',
28
- };
29
-
30
- /**
31
- * Patterns for classifying failure output.
32
- */
33
- const CATEGORY_PATTERNS = [
34
- { regex: /SyntaxError|Unexpected token|parsing error|unterminated/i, category: FAILURE_CATEGORIES.SYNTAX_ERROR },
35
- { regex: /test.*fail|assertion.*fail|expect.*receive|expected.*but got/i, category: FAILURE_CATEGORIES.TEST_FAILURE },
36
- { regex: /lint.*error|eslint|prettier.*error|formatting/i, category: FAILURE_CATEGORIES.LINT_VIOLATION },
37
- { regex: /TypeError|type.*mismatch|cannot read propert|is not a function/i, category: FAILURE_CATEGORIES.TYPE_ERROR },
38
- { regex: /timeout|ETIMEDOUT|exceeded.*time|timed out/i, category: FAILURE_CATEGORIES.TIMEOUT },
39
- { regex: /scope.*violation|cannot write|not allowed.*mode|Article XI/i, category: FAILURE_CATEGORIES.SCOPE_VIOLATION },
40
- { regex: /Cannot find module|ENOENT|module not found|import.*failed|missing dependency/i, category: FAILURE_CATEGORIES.DEPENDENCY },
41
- { regex: /ReferenceError|RangeError|Error:|runtime error|ENOMEM/i, category: FAILURE_CATEGORIES.RUNTIME_ERROR },
42
- ];
43
-
44
- // ---------------------------------------------------------------------------
45
- // Public API
46
- // ---------------------------------------------------------------------------
47
-
48
- /**
49
- * Analyze the cause of a task failure.
50
- *
51
- * @param {string} output - Agent output/error text
52
- * @param {Array<{category: string, output: string}>} [previousAttempts=[]] - History of prior attempts
53
- * @returns {{ category: string, rootCause: string, suggestion: string, isRepetitive: boolean }}
54
- */
55
- export function analyzeCause(output, previousAttempts = []) {
56
- const text = output || '';
57
- const category = classifyOutput(text);
58
- const rootCause = extractRootCause(text, category);
59
- const suggestion = generateSuggestion(category, rootCause);
60
- const isRepetitive = checkRepetitive(category, previousAttempts);
61
-
62
- return { category, rootCause, suggestion, isRepetitive };
63
- }
64
-
65
- /**
66
- * Build retry guidance for the next attempt based on cause analysis.
67
- *
68
- * @param {{ category: string, rootCause: string, suggestion: string, isRepetitive: boolean }} analysis
69
- * @param {number} attempt - Current attempt number
70
- * @returns {string} Guidance text for the agent
71
- */
72
- export function buildRetryGuidance(analysis, attempt) {
73
- const parts = [];
74
-
75
- parts.push(`## Retry Guidance (Attempt ${attempt})`);
76
- parts.push('');
77
- parts.push(`**Previous failure**: ${analysis.category}`);
78
-
79
- if (analysis.rootCause) {
80
- parts.push(`**Root cause**: ${analysis.rootCause}`);
81
- }
82
-
83
- parts.push(`**Suggestion**: ${analysis.suggestion}`);
84
-
85
- if (analysis.isRepetitive) {
86
- parts.push('');
87
- parts.push('**WARNING**: This is a REPETITIVE failure. The same category of error occurred in previous attempts.');
88
- parts.push('You MUST try a fundamentally different approach — do not repeat the same fix.');
89
- }
90
-
91
- return parts.join('\n');
92
- }
93
-
94
- // ---------------------------------------------------------------------------
95
- // Internal Helpers
96
- // ---------------------------------------------------------------------------
97
-
98
- /**
99
- * Classify output text into a failure category.
100
- *
101
- * @param {string} text
102
- * @returns {string}
103
- */
104
- function classifyOutput(text) {
105
- for (const { regex, category } of CATEGORY_PATTERNS) {
106
- if (regex.test(text)) {
107
- return category;
108
- }
109
- }
110
- return FAILURE_CATEGORIES.UNKNOWN;
111
- }
112
-
113
- /**
114
- * Extract a concise root cause from the output.
115
- *
116
- * @param {string} text
117
- * @param {string} category
118
- * @returns {string}
119
- */
120
- function extractRootCause(text, category) {
121
- if (!text) return 'No output available';
122
-
123
- // Try to find the most informative error line
124
- const lines = text.split('\n').filter(l => l.trim());
125
-
126
- // Look for lines containing "Error:" or similar markers
127
- const errorLine = lines.find(l =>
128
- /error:|Error:|ERR!|FAIL|failed/i.test(l)
129
- );
130
-
131
- if (errorLine) {
132
- return errorLine.trim().slice(0, 200);
133
- }
134
-
135
- // Fall back to last non-empty line (often the summary)
136
- if (lines.length > 0) {
137
- return lines[lines.length - 1].trim().slice(0, 200);
138
- }
139
-
140
- return `${category} detected (no specific error line found)`;
141
- }
142
-
143
- /**
144
- * Generate a suggestion based on the failure category.
145
- *
146
- * @param {string} category
147
- * @param {string} rootCause
148
- * @returns {string}
149
- */
150
- function generateSuggestion(category, _rootCause) {
151
- const suggestions = {
152
- [FAILURE_CATEGORIES.SYNTAX_ERROR]: 'Check for missing brackets, semicolons, or malformed expressions. Review the exact line mentioned in the error.',
153
- [FAILURE_CATEGORIES.TEST_FAILURE]: 'Review the failing test assertions. Ensure the implementation matches the expected behavior described in the test.',
154
- [FAILURE_CATEGORIES.LINT_VIOLATION]: 'Fix formatting and style issues. Check import ordering, unused variables, and indentation.',
155
- [FAILURE_CATEGORIES.TYPE_ERROR]: 'Verify that variable types match expected types. Check for null/undefined access and incorrect function signatures.',
156
- [FAILURE_CATEGORIES.TIMEOUT]: 'The operation took too long. Consider optimizing the approach or breaking the task into smaller pieces.',
157
- [FAILURE_CATEGORIES.SCOPE_VIOLATION]: 'The write operation is outside the allowed scope for the current mode. Only modify files within the permitted directories.',
158
- [FAILURE_CATEGORIES.DEPENDENCY]: 'A required module or dependency is missing. Ensure all imports reference existing files and packages are installed.',
159
- [FAILURE_CATEGORIES.RUNTIME_ERROR]: 'A runtime error occurred during execution. Check for logic errors, invalid operations, and edge cases.',
160
- [FAILURE_CATEGORIES.UNKNOWN]: 'Review the full output to identify the issue. The error does not match known patterns.',
161
- };
162
-
163
- return suggestions[category] || suggestions[FAILURE_CATEGORIES.UNKNOWN];
164
- }
165
-
166
- /**
167
- * Check if the same failure category appeared in previous attempts.
168
- *
169
- * @param {string} category
170
- * @param {Array<{category: string}>} previousAttempts
171
- * @returns {boolean}
172
- */
173
- function checkRepetitive(category, previousAttempts) {
174
- if (category === FAILURE_CATEGORIES.UNKNOWN) return false;
175
- const sameCategory = previousAttempts.filter(a => a.category === category);
176
- return sameCategory.length >= 2;
177
- }
@@ -1,214 +0,0 @@
1
- /**
2
- * @fileoverview Progressive escalation for build loop retries.
3
- *
4
- * When a task fails repeatedly, escalation progressively increases
5
- * the resources (model tier, context enrichment) and ultimately
6
- * pauses for human intervention.
7
- *
8
- * Constitution Article XVII — Execution Mode Governance.
9
- */
10
-
11
- // ---------------------------------------------------------------------------
12
- // Escalation Levels
13
- // ---------------------------------------------------------------------------
14
-
15
- /**
16
- * Escalation level definitions.
17
- * @enum {number}
18
- */
19
- export const ESCALATION_LEVELS = {
20
- /** Standard — use configured model, no extra context. */
21
- STANDARD: 0,
22
- /** Enriched — same model, inject cause analysis + retry guidance. */
23
- ENRICHED: 1,
24
- /** Upgraded — escalate to higher-tier model (e.g. sonnet → opus). */
25
- UPGRADED: 2,
26
- /** Max — pause execution and request human intervention. */
27
- MAX: 3,
28
- };
29
-
30
- /**
31
- * Model upgrade map — maps current model tier to the next tier.
32
- * Keys are logical tier names used in chati config.
33
- */
34
- const MODEL_UPGRADE_MAP = {
35
- haiku: 'sonnet',
36
- sonnet: 'opus',
37
- opus: 'opus', // opus is ceiling
38
- // Gemini equivalents
39
- flash: 'pro',
40
- pro: 'pro',
41
- // Codex equivalents
42
- codex: 'codex',
43
- };
44
-
45
- /**
46
- * Thresholds for automatic escalation.
47
- */
48
- const ESCALATION_THRESHOLDS = {
49
- /** Attempts before escalating from STANDARD to ENRICHED. */
50
- ENRICHED_AFTER: 2,
51
- /** Attempts before escalating from ENRICHED to UPGRADED. */
52
- UPGRADED_AFTER: 4,
53
- /** Attempts before escalating from UPGRADED to MAX. */
54
- MAX_AFTER: 7,
55
- };
56
-
57
- // ---------------------------------------------------------------------------
58
- // Public API
59
- // ---------------------------------------------------------------------------
60
-
61
- /**
62
- * Get the current escalation level for a task checkpoint.
63
- *
64
- * @param {{ attempts: number, escalationLevel?: number }} checkpoint
65
- * @returns {number} Current escalation level (0-3)
66
- */
67
- export function getEscalationLevel(checkpoint) {
68
- if (!checkpoint) return ESCALATION_LEVELS.STANDARD;
69
-
70
- // Explicit level takes precedence (set by previous escalation)
71
- if (typeof checkpoint.escalationLevel === 'number') {
72
- return checkpoint.escalationLevel;
73
- }
74
-
75
- // Derive from attempt count
76
- const attempts = checkpoint.attempts || 0;
77
-
78
- if (attempts >= ESCALATION_THRESHOLDS.MAX_AFTER) {
79
- return ESCALATION_LEVELS.MAX;
80
- }
81
- if (attempts >= ESCALATION_THRESHOLDS.UPGRADED_AFTER) {
82
- return ESCALATION_LEVELS.UPGRADED;
83
- }
84
- if (attempts >= ESCALATION_THRESHOLDS.ENRICHED_AFTER) {
85
- return ESCALATION_LEVELS.ENRICHED;
86
- }
87
-
88
- return ESCALATION_LEVELS.STANDARD;
89
- }
90
-
91
- /**
92
- * Determine whether escalation should occur based on checkpoint
93
- * state and cause analysis.
94
- *
95
- * @param {{ attempts: number, escalationLevel?: number }} checkpoint
96
- * @param {{ isRepetitive: boolean, category: string }} analysis - Cause analysis result
97
- * @returns {{ escalate: boolean, newLevel: number, reason: string }}
98
- */
99
- export function shouldEscalate(checkpoint, analysis) {
100
- const currentLevel = getEscalationLevel(checkpoint);
101
- const attempts = checkpoint?.attempts || 0;
102
-
103
- // Already at max — no further escalation
104
- if (currentLevel >= ESCALATION_LEVELS.MAX) {
105
- return {
106
- escalate: false,
107
- newLevel: ESCALATION_LEVELS.MAX,
108
- reason: 'Already at maximum escalation level',
109
- };
110
- }
111
-
112
- // Repetitive failures trigger immediate escalation (+1 level)
113
- if (analysis?.isRepetitive) {
114
- const newLevel = Math.min(currentLevel + 1, ESCALATION_LEVELS.MAX);
115
- return {
116
- escalate: true,
117
- newLevel,
118
- reason: `Repetitive ${analysis.category} failure — escalating to level ${newLevel}`,
119
- };
120
- }
121
-
122
- // Threshold-based escalation
123
- let targetLevel = ESCALATION_LEVELS.STANDARD;
124
- if (attempts >= ESCALATION_THRESHOLDS.MAX_AFTER) {
125
- targetLevel = ESCALATION_LEVELS.MAX;
126
- } else if (attempts >= ESCALATION_THRESHOLDS.UPGRADED_AFTER) {
127
- targetLevel = ESCALATION_LEVELS.UPGRADED;
128
- } else if (attempts >= ESCALATION_THRESHOLDS.ENRICHED_AFTER) {
129
- targetLevel = ESCALATION_LEVELS.ENRICHED;
130
- }
131
-
132
- if (targetLevel > currentLevel) {
133
- return {
134
- escalate: true,
135
- newLevel: targetLevel,
136
- reason: `Attempt ${attempts} reached threshold for level ${targetLevel}`,
137
- };
138
- }
139
-
140
- return {
141
- escalate: false,
142
- newLevel: currentLevel,
143
- reason: 'No escalation needed',
144
- };
145
- }
146
-
147
- /**
148
- * Get configuration for a given escalation level.
149
- *
150
- * @param {number} level - Escalation level (0-3)
151
- * @param {string} [currentModel='sonnet'] - Current model tier name
152
- * @returns {{ model: string|null, contextBoost: boolean, shouldPause: boolean, description: string }}
153
- */
154
- export function getEscalationConfig(level, currentModel = 'sonnet') {
155
- switch (level) {
156
- case ESCALATION_LEVELS.STANDARD:
157
- return {
158
- model: null, // no override
159
- contextBoost: false,
160
- shouldPause: false,
161
- description: 'Standard execution — no escalation',
162
- };
163
-
164
- case ESCALATION_LEVELS.ENRICHED:
165
- return {
166
- model: null, // same model
167
- contextBoost: true,
168
- shouldPause: false,
169
- description: 'Enriched context — cause analysis + retry guidance injected',
170
- };
171
-
172
- case ESCALATION_LEVELS.UPGRADED:
173
- return {
174
- model: MODEL_UPGRADE_MAP[currentModel] || currentModel,
175
- contextBoost: true,
176
- shouldPause: false,
177
- description: `Model upgraded from ${currentModel} to ${MODEL_UPGRADE_MAP[currentModel] || currentModel}`,
178
- };
179
-
180
- case ESCALATION_LEVELS.MAX:
181
- return {
182
- model: MODEL_UPGRADE_MAP[currentModel] || currentModel,
183
- contextBoost: true,
184
- shouldPause: true,
185
- description: 'Maximum escalation — pausing for human intervention',
186
- };
187
-
188
- default:
189
- return {
190
- model: null,
191
- contextBoost: false,
192
- shouldPause: false,
193
- description: `Unknown escalation level: ${level}`,
194
- };
195
- }
196
- }
197
-
198
- /**
199
- * Build a human-readable escalation summary.
200
- *
201
- * @param {number} level - Escalation level
202
- * @param {string} reason - Escalation reason
203
- * @returns {string}
204
- */
205
- export function buildEscalationSummary(level, reason) {
206
- const levelNames = ['STANDARD', 'ENRICHED', 'UPGRADED', 'MAX'];
207
- const name = levelNames[level] || 'UNKNOWN';
208
- return `[Escalation ${name}] ${reason}`;
209
- }
210
-
211
- /**
212
- * Exported for testing — escalation thresholds.
213
- */
214
- export { ESCALATION_THRESHOLDS };
@@ -1,51 +0,0 @@
1
- /**
2
- * @fileoverview Autonomy module barrel exports
3
- * Execution modes, quality gates, progress reporting, and safety nets
4
- */
5
-
6
- export {
7
- EXECUTION_MODES,
8
- getCurrentMode,
9
- setExecutionMode,
10
- canActAutonomously,
11
- getAlwaysHumanAgents,
12
- getModeHistory,
13
- clearExecutionMode,
14
- getModeStatistics,
15
- } from './mode-manager.js';
16
-
17
- export {
18
- suggestMode,
19
- calculateRiskScore,
20
- getHighRiskDomains,
21
- } from './mode-suggester.js';
22
-
23
- export {
24
- GATE_RESULTS,
25
- evaluateGate,
26
- getGateThreshold,
27
- resolveGateAction,
28
- getGateHistory,
29
- recordGateEvaluation,
30
- getGateStatistics,
31
- getAgentGateStatistics,
32
- clearGateHistory,
33
- } from './autonomous-gate.js';
34
-
35
- export {
36
- buildProgressReport,
37
- formatProgressLine,
38
- formatDetailedReport,
39
- calculateCompletion,
40
- getStageProgress,
41
- } from './progress-reporter.js';
42
-
43
- export {
44
- SAFETY_TRIGGERS,
45
- checkSafety,
46
- evaluateTrigger,
47
- getRecommendedAction,
48
- getCriticalRiskKeywords,
49
- isCriticalRisk,
50
- buildSafetyReport,
51
- } from './safety-net.js';
@@ -1,225 +0,0 @@
1
- /**
2
- * @fileoverview Manages execution mode transitions for chati.dev
3
- * Handles human-in-the-loop vs autonomous execution modes
4
- */
5
-
6
- import { loadSession, updateSession } from '../orchestrator/session-manager.js';
7
-
8
- export const EXECUTION_MODES = {
9
- HUMAN_IN_THE_LOOP: 'human-in-the-loop',
10
- AUTONOMOUS: 'autonomous',
11
- };
12
-
13
- // Agents that ALWAYS require human validation
14
- const ALWAYS_HUMAN_AGENTS = ['brief', 'deviation'];
15
-
16
- /**
17
- * Get current execution mode from session.
18
- * @param {string} projectDir
19
- * @returns {{ mode: string, setAt: string|null, reason: string|null }}
20
- */
21
- export function getCurrentMode(projectDir) {
22
- const result = loadSession(projectDir);
23
-
24
- if (!result.loaded || !result.session) {
25
- return {
26
- mode: EXECUTION_MODES.HUMAN_IN_THE_LOOP,
27
- setAt: null,
28
- reason: null,
29
- };
30
- }
31
-
32
- const session = result.session;
33
-
34
- if (!session.execution_mode) {
35
- return {
36
- mode: EXECUTION_MODES.HUMAN_IN_THE_LOOP,
37
- setAt: null,
38
- reason: null,
39
- };
40
- }
41
-
42
- return {
43
- mode: session.execution_mode.mode || EXECUTION_MODES.HUMAN_IN_THE_LOOP,
44
- setAt: session.execution_mode.setAt || null,
45
- reason: session.execution_mode.reason || null,
46
- };
47
- }
48
-
49
- /**
50
- * Set execution mode with reason and persist to session.
51
- * @param {string} projectDir
52
- * @param {string} mode - 'human-in-the-loop' | 'autonomous'
53
- * @param {string} reason - Why this mode was selected
54
- * @returns {{ set: boolean, previous: string }}
55
- */
56
- export function setExecutionMode(projectDir, mode, reason) {
57
- if (!Object.values(EXECUTION_MODES).includes(mode)) {
58
- throw new Error(`Invalid execution mode: ${mode}`);
59
- }
60
-
61
- const result = loadSession(projectDir);
62
-
63
- if (!result.loaded || !result.session) {
64
- return {
65
- set: false,
66
- previous: EXECUTION_MODES.HUMAN_IN_THE_LOOP,
67
- error: result.error || 'Failed to load session',
68
- };
69
- }
70
-
71
- const session = result.session;
72
- const previous = session.execution_mode?.mode || EXECUTION_MODES.HUMAN_IN_THE_LOOP;
73
-
74
- // Initialize mode_transitions array if it doesn't exist
75
- if (!session.mode_transitions) {
76
- session.mode_transitions = [];
77
- }
78
-
79
- // Record the transition
80
- const transition = {
81
- from: previous,
82
- to: mode,
83
- timestamp: new Date().toISOString(),
84
- reason,
85
- };
86
-
87
- session.mode_transitions.push(transition);
88
-
89
- // Update current mode
90
- const updates = {
91
- execution_mode: {
92
- mode,
93
- setAt: transition.timestamp,
94
- reason,
95
- },
96
- mode_transitions: session.mode_transitions,
97
- };
98
-
99
- updateSession(projectDir, updates);
100
-
101
- return {
102
- set: true,
103
- previous,
104
- };
105
- }
106
-
107
- /**
108
- * Check if current mode allows autonomous action for a given agent.
109
- * Even in autonomous mode, some agents always require human input (brief, deviation).
110
- * @param {string} mode
111
- * @param {string} agentName
112
- * @returns {{ allowed: boolean, reason: string }}
113
- */
114
- export function canActAutonomously(mode, agentName) {
115
- // Brief and deviation ALWAYS require human input
116
- if (ALWAYS_HUMAN_AGENTS.includes(agentName)) {
117
- return {
118
- allowed: false,
119
- reason: `${agentName} always requires human interaction`,
120
- };
121
- }
122
-
123
- // In human-in-the-loop mode, nothing is autonomous
124
- if (mode === EXECUTION_MODES.HUMAN_IN_THE_LOOP) {
125
- return {
126
- allowed: false,
127
- reason: 'Human-in-the-loop mode requires user validation',
128
- };
129
- }
130
-
131
- // In autonomous mode, all non-always-human agents can act autonomously
132
- return {
133
- allowed: true,
134
- reason: 'Autonomous mode enabled for this agent',
135
- };
136
- }
137
-
138
- /**
139
- * Get agents that ALWAYS require human validation regardless of mode.
140
- * @returns {string[]}
141
- */
142
- export function getAlwaysHumanAgents() {
143
- return [...ALWAYS_HUMAN_AGENTS];
144
- }
145
-
146
- /**
147
- * Get mode transition history.
148
- * @param {string} projectDir
149
- * @returns {object[]}
150
- */
151
- export function getModeHistory(projectDir) {
152
- const result = loadSession(projectDir);
153
- if (!result.loaded || !result.session) {
154
- return [];
155
- }
156
- return result.session.mode_transitions || [];
157
- }
158
-
159
- /**
160
- * Clear execution mode (reset to default).
161
- * @param {string} projectDir
162
- * @returns {{ cleared: boolean }}
163
- */
164
- export function clearExecutionMode(projectDir) {
165
- const result = loadSession(projectDir);
166
-
167
- if (!result.loaded || !result.session) {
168
- return {
169
- cleared: false,
170
- error: result.error || 'Failed to load session',
171
- };
172
- }
173
-
174
- const previous = result.session.execution_mode;
175
-
176
- updateSession(projectDir, { execution_mode: null });
177
-
178
- return {
179
- cleared: true,
180
- previous: previous || null,
181
- };
182
- }
183
-
184
- /**
185
- * Get mode statistics from history.
186
- * @param {string} projectDir
187
- * @returns {{ totalTransitions: number, timeInAutonomous: number, timeInHuman: number, currentStreak: number }}
188
- */
189
- export function getModeStatistics(projectDir) {
190
- const history = getModeHistory(projectDir);
191
- const current = getCurrentMode(projectDir);
192
-
193
- let timeInAutonomous = 0;
194
- let timeInHuman = 0;
195
- let currentStreak = 0;
196
-
197
- for (let i = 0; i < history.length; i++) {
198
- const transition = history[i];
199
- const nextTransition = history[i + 1];
200
-
201
- // Calculate time in each mode
202
- if (nextTransition) {
203
- const duration = new Date(nextTransition.timestamp) - new Date(transition.timestamp);
204
- if (transition.to === EXECUTION_MODES.AUTONOMOUS) {
205
- timeInAutonomous += duration;
206
- } else {
207
- timeInHuman += duration;
208
- }
209
- }
210
-
211
- // Calculate current streak
212
- if (transition.to === current.mode) {
213
- currentStreak++;
214
- } else {
215
- currentStreak = 0;
216
- }
217
- }
218
-
219
- return {
220
- totalTransitions: history.length,
221
- timeInAutonomous: Math.floor(timeInAutonomous / 1000), // seconds
222
- timeInHuman: Math.floor(timeInHuman / 1000), // seconds
223
- currentStreak,
224
- };
225
- }