chati-dev 4.4.1 → 4.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -27
- package/bin/chati.js +235 -1
- package/framework/agents/plan/tasks.md +46 -1
- package/framework/config.yaml +2 -2
- package/framework/constitution.md +13 -16
- package/framework/context/governance.md +5 -5
- package/framework/context/root.md +5 -5
- package/framework/i18n/en.yaml +8 -2
- package/framework/i18n/es.yaml +8 -2
- package/framework/i18n/fr.yaml +8 -2
- package/framework/i18n/pt.yaml +8 -2
- package/framework/manifest.json +21 -21
- package/framework/manifest.sig +1 -1
- package/framework/orchestrator/chati.md +43 -12
- package/node_modules/@chati/browser-capability/README.md +10 -0
- package/node_modules/@chati/browser-capability/package.json +17 -0
- package/node_modules/@chati/browser-capability/src/index.js +165 -0
- package/node_modules/@chati/core/package.json +13 -0
- package/node_modules/@chati/core/src/index.js +111 -0
- package/node_modules/@chati/knowledge-context/package.json +17 -0
- package/node_modules/@chati/knowledge-context/src/index.js +202 -0
- package/node_modules/@chati/planning/package.json +17 -0
- package/node_modules/@chati/planning/src/index.js +367 -0
- package/node_modules/@chati/provider-registry/package.json +16 -0
- package/node_modules/@chati/provider-registry/src/index.js +148 -0
- package/node_modules/@chati/rail/README.md +24 -0
- package/node_modules/@chati/rail/package.json +19 -0
- package/node_modules/@chati/rail/src/index.js +437 -0
- package/node_modules/@chati/release-lane/README.md +24 -0
- package/node_modules/@chati/release-lane/package.json +17 -0
- package/node_modules/@chati/release-lane/src/index.js +172 -0
- package/node_modules/@chati/review-council/package.json +17 -0
- package/node_modules/@chati/review-council/src/index.js +264 -0
- package/node_modules/@chati/tracking-clickup/README.md +55 -0
- package/node_modules/@chati/tracking-clickup/package.json +17 -0
- package/node_modules/@chati/tracking-clickup/src/index.js +293 -0
- package/package.json +25 -3
- package/src/config/ide-configs.js +11 -0
- package/src/context/domain-loader.js +1 -1
- package/src/dashboard/data-reader.js +1 -1
- package/src/executors/runner.js +1 -1
- package/src/installer/core.js +14 -13
- package/src/installer/provider-overlay.js +8 -15
- package/src/installer/scaffold-applier.js +1 -1
- package/src/installer/templates.js +12 -25
- package/src/installer/validator.js +5 -10
- package/src/installer-v2/catalog-client.js +165 -0
- package/src/installer-v2/index.js +304 -0
- package/src/installer-v2/model-catalog-envelope.json +278 -0
- package/src/installer-v2/model-catalog.json +130 -0
- package/src/installer-v2/model-catalog.sig +1 -0
- package/src/installer-v2/wizard-installation.js +116 -0
- package/src/intelligence/registry-manager.js +1 -1
- package/src/license/client.js +27 -1
- package/src/memory/session-digest.js +1 -1
- package/src/merger/yaml-merger.js +1 -1
- package/src/orchestrator/browser-runtime.js +25 -0
- package/src/orchestrator/cli.js +93 -8
- package/src/orchestrator/clickup-projection.js +84 -0
- package/src/orchestrator/clickup-runtime.js +13 -0
- package/src/orchestrator/knowledge-runtime.js +64 -0
- package/src/orchestrator/planning-runtime.js +127 -0
- package/src/orchestrator/rail-runtime.js +421 -0
- package/src/orchestrator/release-runtime.js +14 -0
- package/src/orchestrator/review-runtime.js +74 -0
- package/src/orchestrator/runtime-installation-v2.js +57 -0
- package/src/orchestrator/session-manager.js +1 -1
- package/src/telemetry/config.js +1 -1
- package/src/terminal/adapters/grok-adapter.js +16 -0
- package/src/terminal/adapters/index.js +1 -0
- package/src/terminal/cli-registry.js +20 -5
- package/src/terminal/prompt-builder.js +4 -2
- package/src/terminal/run-agent.js +3 -0
- package/src/terminal/run-parallel.js +21 -10
- package/src/terminal/spawner.js +7 -1
- package/src/terminal/team-task-list.js +1 -1
- package/src/upgrade/checker.js +1 -1
- package/src/upgrade/migrator.js +1 -1
- package/src/utils/config-parser.js +3 -8
- package/src/wizard/i18n.js +10 -4
- package/src/wizard/index.js +49 -17
- package/src/wizard/questions.js +50 -28
package/README.md
CHANGED
|
@@ -73,7 +73,9 @@ The wizard guides you through 4 steps:
|
|
|
73
73
|
|------|-------------|
|
|
74
74
|
| **Language** | English, Portuguese, Spanish, or French |
|
|
75
75
|
| **Project Type** | Greenfield (new) or Brownfield (existing) |
|
|
76
|
-
| **AI
|
|
76
|
+
| **AI Providers** | Select any combination of Claude, Codex, and Grok |
|
|
77
|
+
| **Primary Harness and Models** | Choose the main CLI and the exact signed-catalog models the project may use |
|
|
78
|
+
| **Execution Profile** | Standard, or Focus AI internal with mandatory ClickUp tracking and completion metrics |
|
|
77
79
|
| **Confirm** | Review summary and proceed |
|
|
78
80
|
|
|
79
81
|
### 2. Activate the orchestrator
|
|
@@ -83,8 +85,8 @@ Open your AI CLI in the same project directory, then type:
|
|
|
83
85
|
| CLI | Command | Notes |
|
|
84
86
|
|-----|---------|-------|
|
|
85
87
|
| **Claude Code** | `/chati` | Slash command (native) |
|
|
86
|
-
| **Gemini CLI** | `/chati` | TOML custom command |
|
|
87
88
|
| **Codex CLI** | `$chati` | Skill invocation (Codex uses `$` for skills, not `/`) |
|
|
89
|
+
| **Grok CLI** | `/chati` | Native markdown command |
|
|
88
90
|
|
|
89
91
|
The orchestrator loads your session, detects where you left off, and routes you to the right agent. You stay inside the system until you explicitly exit.
|
|
90
92
|
|
|
@@ -98,8 +100,8 @@ The agents guide you through each phase:
|
|
|
98
100
|
|-------|-------------|--------|
|
|
99
101
|
| **DISCOVER** | Agents interview you about what you want to build | Answer questions about your project |
|
|
100
102
|
| **PLAN** | Agents create PRD, architecture, UX spec, phases, and tasks | Review and approve the plan |
|
|
101
|
-
| **
|
|
102
|
-
| **
|
|
103
|
+
| **RAIL EXECUTION** | Dependency-ready tasks run on their explicitly selected model, with independent review, bounded rework, recovery, and local evidence | Review material scope or authority escalations |
|
|
104
|
+
| **RELEASE** | A sealed release lane checks evidence, Git and CI readiness, with explicit human authorization for external actions | Authorize merge, deployment, or publication |
|
|
103
105
|
|
|
104
106
|
Quality gates run automatically between phases. If something doesn't meet the threshold, the system loops back and fixes it.
|
|
105
107
|
|
|
@@ -127,18 +129,20 @@ The system saves your full session state (pipeline position, current agent, deci
|
|
|
127
129
|
| Feature | What it means |
|
|
128
130
|
|---------|--------------|
|
|
129
131
|
| **Specialized Agents** | Each agent has a defined mission, success criteria, and handoff protocol. Not one AI trying to do everything |
|
|
130
|
-
| **
|
|
132
|
+
| **Planning Team** | Detail, Architect, UX, and QA-Planning collaborate on the approved planning artifacts before Tasks seals the RAIL handoff |
|
|
133
|
+
| **RAIL Execution** | Dependency-aware task dispatch, selected-model enforcement, leases, recovery, independent review, two bounded rework cycles, and top-tier adjudication |
|
|
131
134
|
| **Visual QA** | QA-Visual scores the rendered UI against an 8-dimension rubric (layout, typography, motion, interaction, color, spacing, accessibility, performance) with an anti-slop catalog and a spring-motion veto (linear easing and `transition: all` are rejected). Screenshots at multiple scroll positions, hover states, and brandbook compliance, powered by Playwright. |
|
|
132
135
|
| **Premium Motion** | Premium motion is required for UI projects, with cubic-bezier easing and full reduced-motion support. The visual gate is animation-stack aware: the motion-premium presets use GSAP + Lenis, the saas-dashboard preset uses framer-motion. |
|
|
133
136
|
| **Scaffold Presets** | Premium starting points applied at build time: motion-premium and motion-premium-3d for animated showcase sites, saas-dashboard for a token-driven app shell (sidebar, sortable data table, KPI cards, a Cmd+K command palette). |
|
|
134
137
|
| **Execution Kinds** | A task declares how it executes. Deterministic dev tasks (lint, tests, file and schema checks) run as zero-LLM scripts through whitelisted executors instead of spending an agent turn. Feature-flagged, off by default, fully back-compatible. |
|
|
135
|
-
| **Multi-CLI Architecture** | Choose
|
|
138
|
+
| **Multi-CLI Architecture** | Choose Claude, Codex, Grok, or any selected combination. Every invocation is restricted to the provider, harness, model, and reasoning configuration explicitly approved during installation |
|
|
136
139
|
| **Quality Gates** | Every phase is validated before moving forward, including QA-Visual for visual quality. 3-tier verdicts: APPROVED, NEEDS_REVISION, or BLOCKED |
|
|
137
140
|
| **Fault Vector Protocol** | Root Layer Routing classifies bugs by origin (INTENT/SPEC/CODE/DEFER). Evidence-Bound Verdicts, Decision Trail, and Echo Detection prevent cyclical rework |
|
|
138
141
|
| **Context Persistence** | Sessions survive restarts. Close your IDE, come back next week - the system remembers everything |
|
|
139
142
|
| **Session Lock** | Once activated, you stay inside the system. No accidentally "falling out" into generic AI mode |
|
|
140
|
-
| **Multi-Terminal** |
|
|
141
|
-
| **
|
|
143
|
+
| **Multi-Terminal** | RAIL dispatches dependency-ready tasks across the selected harnesses while preserving claim, attempt, review, and completion lineage |
|
|
144
|
+
| **Closed Loop Boundary** | CHATI may read approved Brain context and emit project-local learning candidates. It never writes directly to the Brain |
|
|
145
|
+
| **ClickUp Tracking** | The internal profile requires ClickUp projection through a durable local outbox and keeps Project Evolution as local canonical evidence |
|
|
142
146
|
| **Execution Mode** | Two modes: interactive (default) and autonomous (gate >= 95%). Safety reversion to interactive on stuck loop, quality drop, scope creep, error cascade, or user override (Article XVII) |
|
|
143
147
|
| **IDE-Agnostic** | Works with Claude Code, VS Code, Cursor, Gemini CLI, Codex CLI, and AntiGravity |
|
|
144
148
|
| **4 Languages** | Interface supports English, Portuguese, Spanish, and French. Artifacts are always generated in English |
|
|
@@ -207,14 +211,14 @@ The system starts in `interactive` mode. Transition to `autonomous` requires bot
|
|
|
207
211
|
|
|
208
212
|
## Architecture
|
|
209
213
|
|
|
210
|
-
### Specialized Agents
|
|
214
|
+
### Specialized Agents and RAIL Pipeline
|
|
211
215
|
|
|
212
216
|
| Phase | Agents | What they do |
|
|
213
217
|
|-------|--------|-------------|
|
|
214
218
|
| **DISCOVER** | Greenfield WU, Brownfield WU, Brief | Interview you, understand your project, extract requirements |
|
|
215
219
|
| **PLAN** | Planning Team (Detail + Architect + UX + QA-Planning), Phases, Tasks | Create PRD, architecture, UX spec with cross-review. QA-Planning validates all 3 artifacts before the team dissolves |
|
|
216
|
-
| **
|
|
217
|
-
| **
|
|
220
|
+
| **RAIL EXECUTION** | Selected task executors, independent reviewers, browser capability where required | Execute the sealed task graph, collect evidence, recover interrupted attempts, and resolve bounded rework |
|
|
221
|
+
| **RELEASE** | Release lane with human authority gate | Verify readiness and perform no external mutation without explicit authorization |
|
|
218
222
|
|
|
219
223
|
### How the Pipeline Works
|
|
220
224
|
|
|
@@ -249,25 +253,23 @@ The system starts in `interactive` mode. Transition to `autonomous` requires bot
|
|
|
249
253
|
│ │ │
|
|
250
254
|
│ Then: Phases → Tasks │
|
|
251
255
|
│ │
|
|
252
|
-
├─
|
|
253
|
-
│ (2 agents, Wave-Based Pipeline) │
|
|
256
|
+
├─ Seals Planning handoff ───────────────┐
|
|
254
257
|
│ │
|
|
255
|
-
│
|
|
256
|
-
│
|
|
257
|
-
│
|
|
258
|
-
│
|
|
259
|
-
│
|
|
260
|
-
│ Final QA: Triple Review │
|
|
258
|
+
│ RAIL EXECUTION │
|
|
259
|
+
│ Dependency-ready task dispatch │
|
|
260
|
+
│ Selected model and harness only │
|
|
261
|
+
│ Independent review and rework │
|
|
262
|
+
│ Recovery, tracking, local evidence │
|
|
261
263
|
│ │
|
|
262
|
-
└─
|
|
264
|
+
└─ Opens release lane ───────────────────┐
|
|
263
265
|
│
|
|
264
|
-
|
|
265
|
-
|
|
266
|
+
RELEASE │
|
|
267
|
+
Readiness checks and authority gate │
|
|
266
268
|
│
|
|
267
269
|
✓ Done │
|
|
268
270
|
```
|
|
269
271
|
|
|
270
|
-
Each
|
|
272
|
+
Each invocation runs through an installation-selected provider, harness, model, and reasoning configuration. CHATI cannot silently add an unselected provider or model. Existing v4 installations retain the old Build Team and DevOps definitions only for migration compatibility; a sealed v2 handoff can never route into them.
|
|
271
273
|
|
|
272
274
|
### Intelligence Layer
|
|
273
275
|
|
|
@@ -426,9 +428,9 @@ your-project/
|
|
|
426
428
|
│ ├── agents/ # Agent definitions
|
|
427
429
|
│ │ ├── discover/ # Greenfield WU, Brownfield WU, Brief
|
|
428
430
|
│ │ ├── plan/ # Detail, Architect, UX, Phases, Tasks
|
|
429
|
-
│ │ ├── quality/ # QA-Planning
|
|
430
|
-
│ │ ├── build/ #
|
|
431
|
-
│ │ └── deploy/ #
|
|
431
|
+
│ │ ├── quality/ # QA-Planning plus legacy compatibility definitions
|
|
432
|
+
│ │ ├── build/ # Legacy v4 compatibility only
|
|
433
|
+
│ │ └── deploy/ # Legacy v4 compatibility only
|
|
432
434
|
│ ├── workflows/ # 7 workflow blueprints
|
|
433
435
|
│ ├── templates/ # 12 artifact templates
|
|
434
436
|
│ ├── schemas/ # 5 JSON schemas
|
|
@@ -493,5 +495,5 @@ For security concerns, see our [Security Policy](.github/SECURITY.md).
|
|
|
493
495
|
|
|
494
496
|
<p align="center">
|
|
495
497
|
<sub>Built with structure, validated by agents, governed by constitution.</sub><br>
|
|
496
|
-
<sub>Chati.dev v4.
|
|
498
|
+
<sub>Chati.dev v4.5.1 "Phoenix" © 2026</sub>
|
|
497
499
|
</p>
|
package/bin/chati.js
CHANGED
|
@@ -28,6 +28,7 @@ const command = args[0] || 'init';
|
|
|
28
28
|
const KNOWN_SUBCOMMANDS = new Set([
|
|
29
29
|
// CLI subcommands
|
|
30
30
|
'next', 'advance', 'init', 'status', 'validate-handoff', 'deviation', 'exit',
|
|
31
|
+
'install-v2', 'migrate-v2', 'rail-import', 'rail-next', 'rail-release-ready', 'rail-claim', 'rail-heartbeat', 'rail-recover', 'rail-complete', 'rail-review', 'rail-tracking-reconcile',
|
|
31
32
|
'providers', 'detect-flow', 'backlog', 'qa-plan-score', 'qa-impl-score', 'scan',
|
|
32
33
|
'spawn-team', 'team-status', 'team-dissolve',
|
|
33
34
|
'stats', 'list', 'search', 'clean', 'check', // memory/registry subcommands
|
|
@@ -45,8 +46,11 @@ for (let i = 0; i < args.length; i++) {
|
|
|
45
46
|
flagValues.add(args[i + 1]);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
49
|
+
const projectDirIndex = args.indexOf('--project-dir');
|
|
50
|
+
const explicitTargetDir = projectDirIndex === -1 ? null : args[projectDirIndex + 1];
|
|
48
51
|
const targetDir = resolve(
|
|
49
|
-
|
|
52
|
+
explicitTargetDir
|
|
53
|
+
|| args.find(a => !a.startsWith('-') && a !== command && !KNOWN_SUBCOMMANDS.has(a) && !flagValues.has(a))
|
|
50
54
|
|| process.cwd()
|
|
51
55
|
);
|
|
52
56
|
|
|
@@ -59,6 +63,236 @@ async function main() {
|
|
|
59
63
|
break;
|
|
60
64
|
}
|
|
61
65
|
|
|
66
|
+
case 'install-v2': {
|
|
67
|
+
const inputIndex = args.indexOf('--input');
|
|
68
|
+
const inputPath = inputIndex === -1 ? null : args[inputIndex + 1];
|
|
69
|
+
if (!inputPath) {
|
|
70
|
+
console.error('Error: install-v2 requires --input <installation.json>');
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
let input;
|
|
75
|
+
try { input = JSON.parse(readFileSync(resolve(inputPath), 'utf8')); } catch (error) {
|
|
76
|
+
console.error(`Error: cannot read installation input: ${error.message}`);
|
|
77
|
+
process.exitCode = 1;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
const { installV2 } = await import('../src/installer-v2/index.js');
|
|
81
|
+
try {
|
|
82
|
+
const result = installV2(input, { projectDir: targetDir });
|
|
83
|
+
console.log(JSON.stringify(result, null, 2));
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error(`Error: ${error.code || 'INSTALL_V2_FAILED'}: ${error.message}`);
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
}
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
case 'migrate-v2': {
|
|
92
|
+
const inputIndex = args.indexOf('--input');
|
|
93
|
+
const inputPath = inputIndex === -1 ? null : args[inputIndex + 1];
|
|
94
|
+
if (!inputPath) {
|
|
95
|
+
console.error('Error: migrate-v2 requires --input <installation.json>');
|
|
96
|
+
process.exitCode = 1;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
let input;
|
|
100
|
+
try { input = JSON.parse(readFileSync(resolve(inputPath), 'utf8')); } catch (error) {
|
|
101
|
+
console.error(`Error: cannot read installation input: ${error.message}`);
|
|
102
|
+
process.exitCode = 1;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const { migrateV2 } = await import('../src/installer-v2/index.js');
|
|
107
|
+
const result = migrateV2(input, { projectDir: targetDir, authorize: args.includes('--apply') });
|
|
108
|
+
console.log(JSON.stringify(result, null, 2));
|
|
109
|
+
} catch (error) {
|
|
110
|
+
console.error(`Error: ${error.code || 'MIGRATE_V2_FAILED'}: ${error.message}`);
|
|
111
|
+
process.exitCode = 1;
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
case 'rail-import': {
|
|
117
|
+
const handoffIndex = args.indexOf('--handoff');
|
|
118
|
+
const handoffPath = handoffIndex === -1 ? null : args[handoffIndex + 1];
|
|
119
|
+
if (!handoffPath) {
|
|
120
|
+
console.error('Error: rail-import requires --handoff <sealed-handoff.json>');
|
|
121
|
+
process.exitCode = 1;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const handoff = JSON.parse(readFileSync(resolve(handoffPath), 'utf8'));
|
|
126
|
+
const { persistRailHandoff } = await import('../src/orchestrator/rail-runtime.js');
|
|
127
|
+
console.log(JSON.stringify(persistRailHandoff({ projectDir: targetDir, handoff }), null, 2));
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error(`Error: ${error.code || 'RAIL_IMPORT_FAILED'}: ${error.message}`);
|
|
130
|
+
process.exitCode = 1;
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
case 'rail-next': {
|
|
136
|
+
const handoffIndex = args.indexOf('--handoff-id');
|
|
137
|
+
const handoff_id = handoffIndex === -1 ? null : args[handoffIndex + 1];
|
|
138
|
+
if (!handoff_id) {
|
|
139
|
+
console.error('Error: rail-next requires --handoff-id <id>');
|
|
140
|
+
process.exitCode = 1;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
const { selectReadyRailTasks } = await import('../src/orchestrator/rail-runtime.js');
|
|
145
|
+
console.log(JSON.stringify(selectReadyRailTasks({ projectDir: targetDir, handoff_id }), null, 2));
|
|
146
|
+
} catch (error) {
|
|
147
|
+
console.error(`Error: ${error.code || 'RAIL_NEXT_FAILED'}: ${error.message}`);
|
|
148
|
+
process.exitCode = 1;
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
case 'rail-release-ready': {
|
|
154
|
+
const handoffIndex = args.indexOf('--handoff-id');
|
|
155
|
+
const handoff_id = handoffIndex === -1 ? null : args[handoffIndex + 1];
|
|
156
|
+
if (!handoff_id) {
|
|
157
|
+
console.error('Error: rail-release-ready requires --handoff-id <id>');
|
|
158
|
+
process.exitCode = 1;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
const { selectRailReleaseReadiness } = await import('../src/orchestrator/rail-runtime.js');
|
|
163
|
+
console.log(JSON.stringify(selectRailReleaseReadiness({ projectDir: targetDir, handoff_id }), null, 2));
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.error(`Error: ${error.code || 'RAIL_RELEASE_READINESS_FAILED'}: ${error.message}`);
|
|
166
|
+
process.exitCode = 1;
|
|
167
|
+
}
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
case 'rail-claim': {
|
|
172
|
+
const value = (flag) => {
|
|
173
|
+
const index = args.indexOf(flag);
|
|
174
|
+
return index === -1 ? null : args[index + 1];
|
|
175
|
+
};
|
|
176
|
+
const required = ['--handoff-id', '--task-id', '--attempt-id', '--operator-id', '--harness-process-id'];
|
|
177
|
+
if (required.some((flag) => !value(flag))) {
|
|
178
|
+
console.error(`Error: rail-claim requires ${required.join(', ')}`);
|
|
179
|
+
process.exitCode = 1;
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
const { claimRailTask } = await import('../src/orchestrator/rail-runtime.js');
|
|
184
|
+
const result = claimRailTask({
|
|
185
|
+
projectDir: targetDir, handoff_id: value('--handoff-id'), task_id: value('--task-id'), attempt_id: value('--attempt-id'),
|
|
186
|
+
operator_id: value('--operator-id'), harness_process_id: value('--harness-process-id'), git_dir: value('--git-dir') || targetDir,
|
|
187
|
+
});
|
|
188
|
+
console.log(JSON.stringify(result, null, 2));
|
|
189
|
+
} catch (error) {
|
|
190
|
+
console.error(`Error: ${error.code || 'RAIL_CLAIM_FAILED'}: ${error.message}`);
|
|
191
|
+
process.exitCode = 1;
|
|
192
|
+
}
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
case 'rail-heartbeat': {
|
|
197
|
+
const value = (flag) => { const index = args.indexOf(flag); return index === -1 ? null : args[index + 1]; };
|
|
198
|
+
const required = ['--handoff-id', '--attempt-id', '--claim-id', '--operator-id'];
|
|
199
|
+
if (required.some((flag) => !value(flag))) {
|
|
200
|
+
console.error(`Error: rail-heartbeat requires ${required.join(', ')}`);
|
|
201
|
+
process.exitCode = 1;
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
const { heartbeatRailTask } = await import('../src/orchestrator/rail-runtime.js');
|
|
206
|
+
console.log(JSON.stringify(heartbeatRailTask({
|
|
207
|
+
projectDir: targetDir, handoff_id: value('--handoff-id'), attempt_id: value('--attempt-id'),
|
|
208
|
+
claim_id: value('--claim-id'), operator_id: value('--operator-id'),
|
|
209
|
+
}), null, 2));
|
|
210
|
+
} catch (error) {
|
|
211
|
+
console.error(`Error: ${error.code || 'RAIL_HEARTBEAT_FAILED'}: ${error.message}`);
|
|
212
|
+
process.exitCode = 1;
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
case 'rail-recover': {
|
|
218
|
+
const value = (flag) => { const index = args.indexOf(flag); return index === -1 ? null : args[index + 1]; };
|
|
219
|
+
const required = ['--handoff-id', '--attempt-id', '--operator-id', '--harness-process-id', '--reconciliation'];
|
|
220
|
+
if (required.some((flag) => !value(flag))) {
|
|
221
|
+
console.error(`Error: rail-recover requires ${required.join(', ')}`);
|
|
222
|
+
process.exitCode = 1;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
const reconciliation = JSON.parse(readFileSync(resolve(value('--reconciliation')), 'utf8'));
|
|
227
|
+
const { recoverRailTask } = await import('../src/orchestrator/rail-runtime.js');
|
|
228
|
+
console.log(JSON.stringify(recoverRailTask({
|
|
229
|
+
projectDir: targetDir, handoff_id: value('--handoff-id'), attempt_id: value('--attempt-id'),
|
|
230
|
+
operator_id: value('--operator-id'), harness_process_id: value('--harness-process-id'), reconciliation,
|
|
231
|
+
git_dir: value('--git-dir') || targetDir,
|
|
232
|
+
}), null, 2));
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.error(`Error: ${error.code || 'RAIL_RECOVERY_FAILED'}: ${error.message}`);
|
|
235
|
+
process.exitCode = 1;
|
|
236
|
+
}
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
case 'rail-complete': {
|
|
241
|
+
const value = (flag) => { const index = args.indexOf(flag); return index === -1 ? null : args[index + 1]; };
|
|
242
|
+
if (!value('--handoff-id') || !value('--completion')) {
|
|
243
|
+
console.error('Error: rail-complete requires --handoff-id <id> and --completion <completion.json>');
|
|
244
|
+
process.exitCode = 1;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
try {
|
|
248
|
+
const completion = JSON.parse(readFileSync(resolve(value('--completion')), 'utf8'));
|
|
249
|
+
const { completeRailTask } = await import('../src/orchestrator/rail-runtime.js');
|
|
250
|
+
const { completion_id, attempt_id, claim_id, operator_id, state, git, ci, reviews, acceptance_evidence_refs, completed_at, metrics } = completion;
|
|
251
|
+
console.log(JSON.stringify(completeRailTask({
|
|
252
|
+
projectDir: targetDir, handoff_id: value('--handoff-id'), completion_id, attempt_id, claim_id, operator_id, state, git, ci,
|
|
253
|
+
reviews, acceptance_evidence_refs, ...(completed_at === undefined ? {} : { completed_at }), ...(metrics === undefined ? {} : { metrics }),
|
|
254
|
+
}), null, 2));
|
|
255
|
+
} catch (error) {
|
|
256
|
+
console.error(`Error: ${error.code || 'RAIL_COMPLETION_FAILED'}: ${error.message}`);
|
|
257
|
+
process.exitCode = 1;
|
|
258
|
+
}
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
case 'rail-tracking-reconcile': {
|
|
263
|
+
const value = (flag) => { const index = args.indexOf(flag); return index === -1 ? null : args[index + 1]; };
|
|
264
|
+
try {
|
|
265
|
+
const { reconcileProjectClickUpTracking } = await import('../src/orchestrator/rail-runtime.js');
|
|
266
|
+
console.log(JSON.stringify(reconcileProjectClickUpTracking({
|
|
267
|
+
projectDir: targetDir,
|
|
268
|
+
...(value('--handoff-id') ? { handoff_id: value('--handoff-id') } : {}),
|
|
269
|
+
}), null, 2));
|
|
270
|
+
} catch (error) {
|
|
271
|
+
console.error(`Error: ${error.code || 'RAIL_TRACKING_RECONCILIATION_FAILED'}: ${error.message}`);
|
|
272
|
+
process.exitCode = 1;
|
|
273
|
+
}
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
case 'rail-review': {
|
|
278
|
+
const value = (flag) => { const index = args.indexOf(flag); return index === -1 ? null : args[index + 1]; };
|
|
279
|
+
if (!value('--review') || !value('--invocation')) {
|
|
280
|
+
console.error('Error: rail-review requires --review <review.json> and --invocation <invocation.json>');
|
|
281
|
+
process.exitCode = 1;
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
const review = JSON.parse(readFileSync(resolve(value('--review')), 'utf8'));
|
|
286
|
+
const invocation = JSON.parse(readFileSync(resolve(value('--invocation')), 'utf8'));
|
|
287
|
+
const { recordRailReview } = await import('../src/orchestrator/review-runtime.js');
|
|
288
|
+
console.log(JSON.stringify(recordRailReview({ projectDir: targetDir, review, invocation }), null, 2));
|
|
289
|
+
} catch (error) {
|
|
290
|
+
console.error(`Error: ${error.code || 'RAIL_REVIEW_FAILED'}: ${error.message}`);
|
|
291
|
+
process.exitCode = 1;
|
|
292
|
+
}
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
|
|
62
296
|
case 'status': {
|
|
63
297
|
const watchFlag = args.includes('--watch') || args.includes('-w');
|
|
64
298
|
const { renderDashboard, renderDashboardWatch } = await import('../src/dashboard/renderer.js');
|
|
@@ -26,7 +26,7 @@ You are the **Tasks Agent**, responsible for breaking phases into atomic, execut
|
|
|
26
26
|
|
|
27
27
|
## Mission
|
|
28
28
|
|
|
29
|
-
Create atomic, testable, estimable tasks for each phase. Every task has a clear title, acceptance criteria in Given-When-Then format, size estimate, dependencies, and traces back to a PRD requirement. These tasks become
|
|
29
|
+
Create atomic, testable, estimable tasks for each phase. Every task has a clear title, acceptance criteria in Given-When-Then format, size estimate, dependencies, and traces back to a PRD requirement. These tasks become an immutable execution handoff for the internal RAIL engine. After that handoff is sealed, CHATI does not enter the legacy Build Team or DevOps flow.
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
@@ -204,6 +204,51 @@ Document findings and fix before presenting to user.
|
|
|
204
204
|
Validate all criteria, present to user for approval
|
|
205
205
|
```
|
|
206
206
|
|
|
207
|
+
### Step 5: Produce the RAIL task graph
|
|
208
|
+
|
|
209
|
+
When the project has a v2 installation, write the machine-readable task graph
|
|
210
|
+
to `.chati/v2/planning/tasks.json`. This file is required before the Tasks
|
|
211
|
+
agent can advance. It is the source used to create the sealed RAIL handoff.
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"version": "1.0.0",
|
|
216
|
+
"source_artifacts": {
|
|
217
|
+
"requirements_path": "artifacts/2-PRD/prd.md",
|
|
218
|
+
"architecture_path": "artifacts/3-Architecture/architecture.md",
|
|
219
|
+
"qa_plan_path": "artifacts/7-QA/qa-plan.md"
|
|
220
|
+
},
|
|
221
|
+
"tasks": [{
|
|
222
|
+
"id": "T1.1",
|
|
223
|
+
"dependencies": [],
|
|
224
|
+
"criteria": [{ "given": "the approved project baseline", "when": "the task is executed", "then": "the stated, verifiable outcome exists" }],
|
|
225
|
+
"execution_scope_ref": "artifact://task-scope/T1.1",
|
|
226
|
+
"routing_constraints_ref": "policy://routing/T1.1",
|
|
227
|
+
"execution_binding": {
|
|
228
|
+
"provider_id": "openai",
|
|
229
|
+
"harness_id": "codex",
|
|
230
|
+
"model_id": "the-model-selected-during-installation",
|
|
231
|
+
"reasoning_configuration": "high"
|
|
232
|
+
},
|
|
233
|
+
"clickup_ref": "clickup://task/T1.1",
|
|
234
|
+
"estimate": {
|
|
235
|
+
"ai_processing": { "unit": "minutes", "value": 30 },
|
|
236
|
+
"human_effort": { "unit": "minutes", "value": 10 },
|
|
237
|
+
"uncertainty": "medium"
|
|
238
|
+
},
|
|
239
|
+
"requires_browser": false
|
|
240
|
+
}]
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Rules:
|
|
245
|
+
|
|
246
|
+
- Preserve the same task IDs, dependencies and Given-When-Then criteria in the prose artifact and JSON task graph.
|
|
247
|
+
- `clickup_ref` is mandatory for the internal profile. It is an opaque mapping, not permission to mutate ClickUp directly.
|
|
248
|
+
- `execution_binding` is mandatory. Select only a provider, harness, model and reasoning configuration present in `.chati/v2/installation.json`; choose the best eligible binding for that task. Never name an unselected vendor or rely on the primary harness as an implicit fallback.
|
|
249
|
+
- If `requires_browser` is true, provide a complete task-specific `browser_policy`. A global MCP configuration is not sufficient.
|
|
250
|
+
- Do not infer missing execution scope, estimates, dependencies, ClickUp refs or browser policy. Return to planning and make the information explicit.
|
|
251
|
+
|
|
207
252
|
---
|
|
208
253
|
|
|
209
254
|
## Task Sizing Guide
|
package/framework/config.yaml
CHANGED
|
@@ -446,16 +446,13 @@ The orchestrator SHALL select the optimal AI model for each agent to balance qua
|
|
|
446
446
|
|
|
447
447
|
8. Model selections are logged in session.yaml under `model_selections[]` for cost tracking and optimization.
|
|
448
448
|
|
|
449
|
-
9.
|
|
450
|
-
- **claude**: Primary provider. Deep reasoning, complex analysis, code generation. Full hook support, MCP support.
|
|
451
|
-
- **gemini**: Large-context provider. Codebase analysis, discovery, document review. 1M token context window. Full hook support, MCP support.
|
|
452
|
-
- **codex**: Rapid-coding provider. Fast code generation, sandbox execution. No hook support, MCP support.
|
|
449
|
+
9. The initial multi-CLI bindings are **claude**, **codex**, and **grok**. An installation explicitly records its enabled providers, models, primary harness and time-bounded capability snapshot in `.chati/v2/installation.json`.
|
|
453
450
|
|
|
454
|
-
10.
|
|
451
|
+
10. The primary harness is selected during installation. No vendor has a framework-wide primary status.
|
|
455
452
|
|
|
456
|
-
11.
|
|
453
|
+
11. Every invocation MUST resolve to an enabled provider and one of its explicitly allowed models. A missing, unavailable or expired binding is a controlled block. The system MUST NOT silently substitute another provider, model or primary harness.
|
|
457
454
|
|
|
458
|
-
12.
|
|
455
|
+
12. Provider-specific capabilities may change the adapter mechanics, but not the execution contract. Where hooks are unavailable, the equivalent policy is carried through the signed invocation context and verified receipts.
|
|
459
456
|
|
|
460
457
|
**Enforcement: GUIDE** — Model recommendations are advisory in IDE mode; automatic in SDK mode.
|
|
461
458
|
|
|
@@ -485,7 +482,7 @@ The system SHALL support two execution modes that govern the degree of human inv
|
|
|
485
482
|
|
|
486
483
|
6. Safety net triggers SHALL pause autonomous execution when dangerous conditions are detected: consecutive failures, circular approaches, resource limits, or destructive operations.
|
|
487
484
|
|
|
488
|
-
7. Loop protection: the pipeline manager tracks consecutive correction cycles for each reviewer-to-rework-target pair.
|
|
485
|
+
7. Loop protection: the pipeline manager tracks consecutive correction cycles for each reviewer-to-rework-target pair. Two normal correction cycles are allowed. A third consecutive failure SHALL use the installation-selected top-tier adjudication route before a human escalation. Human escalation is reserved for authority decisions, unresolved scope or conflicting evidence.
|
|
489
486
|
|
|
490
487
|
8. Mode transitions are logged in session.yaml under `mode_transitions[]` for audit trail.
|
|
491
488
|
|
|
@@ -530,21 +527,21 @@ When multiple CLI providers are enabled, the system SHALL coordinate agent execu
|
|
|
530
527
|
|
|
531
528
|
2. The handoff format is provider-agnostic. All agents, regardless of which CLI executes them, produce handoffs in the same two-layer format (Article VIII). This ensures consistent inter-provider communication without format translation.
|
|
532
529
|
|
|
533
|
-
3. Provider availability SHALL be validated
|
|
530
|
+
3. Provider availability SHALL be validated before spawning. If a selected provider or model is unavailable, the affected task is blocked with evidence. The system SHALL NOT fall back to another provider or model.
|
|
534
531
|
|
|
535
|
-
4. Context file generation is
|
|
532
|
+
4. Context file generation is adapter-specific. The installer SHALL generate only the integration artifacts required by the selected Claude, Codex and Grok harnesses.
|
|
536
533
|
|
|
537
534
|
5. Hook-based governance (constitution-guard, mode-governance, read-protection) applies ONLY to providers with hook support. For providers without hooks, equivalent governance is enforced via prompt injection — the PRISM context block includes governance directives.
|
|
538
535
|
|
|
539
|
-
6. The orchestrator SHALL select the optimal
|
|
540
|
-
a.
|
|
541
|
-
b.
|
|
542
|
-
c.
|
|
543
|
-
d.
|
|
536
|
+
6. The orchestrator SHALL select the optimal binding only from the installation allow-list, based on:
|
|
537
|
+
a. Task routing constraints and required capabilities
|
|
538
|
+
b. The selected model catalog snapshot
|
|
539
|
+
c. The primary harness only when it is itself an allowed binding
|
|
540
|
+
d. Availability evidence, otherwise a controlled block
|
|
544
541
|
|
|
545
542
|
7. Cost tracking SHALL include provider information. Each model selection entry in session.yaml includes: provider, model, agent, timestamp, and estimated token usage.
|
|
546
543
|
|
|
547
|
-
**Enforcement:
|
|
544
|
+
**Enforcement: BLOCK** — Provider and model selection is an installation contract, not an advisory preference.
|
|
548
545
|
|
|
549
546
|
---
|
|
550
547
|
|
|
@@ -43,7 +43,7 @@ Extracted from `chati.dev/constitution.md` (25 Articles). Read the full constitu
|
|
|
43
43
|
- Controls whether human or system makes pipeline decisions
|
|
44
44
|
- Autonomous mode requires gate score >= 95% (qa-planning >= 95%, qa-implementation >= 95%)
|
|
45
45
|
- Safety reversion (Article XVII): the orchestrator reverts autonomous to interactive on a stuck loop. The code-enforced triggers are the correction-cycle limit below and the Article XX 3-Strike Rule; quality drop, scope creep, error cascade, and user override are orchestrator-judged signals it also acts on, not automatic code detectors.
|
|
46
|
-
- Loop protection:
|
|
46
|
+
- Loop protection: two normal correction cycles, then top-tier AI adjudication. Escalate to a human only for an authority decision, unresolved scope or conflicting evidence.
|
|
47
47
|
- Git authority: while a pipeline is active, only the devops agent may push to a remote or open a pull request (`git-push-authority` hook, PreToolUse Bash); other agents are denied with a clear message. Outside an active pipeline, git is unaffected.
|
|
48
48
|
- Surface criteria: even in autonomous mode, a high-stakes transition (deploy is external and irreversible) requires a human nod before proceeding; passing the quality gates alone does not auto-confirm it. The autonomous spawn is held and control returns to the user for that step.
|
|
49
49
|
|
|
@@ -53,10 +53,10 @@ Extracted from `chati.dev/constitution.md` (25 Articles). Read the full constitu
|
|
|
53
53
|
- New code SHALL use `execution_mode` only (interactive | autonomous). Do NOT add new references to `execution_profile`.
|
|
54
54
|
|
|
55
55
|
## Multi-CLI Governance (Article XIX)
|
|
56
|
-
-
|
|
57
|
-
- Provider selected at
|
|
58
|
-
- Resolution
|
|
59
|
-
-
|
|
56
|
+
- Initial providers: Claude, Codex, Grok
|
|
57
|
+
- Provider, exact models and primary harness are selected at installation and recorded in `.chati/v2/installation.json`
|
|
58
|
+
- Resolution is restricted to the installation allow-list. An unavailable binding blocks the task, it never falls back silently.
|
|
59
|
+
- Adapter-specific context files are generated only for the selected harnesses.
|
|
60
60
|
|
|
61
61
|
## Anti-Loop Protocol (Article XX)
|
|
62
62
|
- 3-Strike Rule: 3 edits to same file without resolution = STOP
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Chati.dev System Context
|
|
2
2
|
|
|
3
3
|
## Framework
|
|
4
|
-
- **Version**: 4.
|
|
5
|
-
- **Agents**: Specialized agents
|
|
4
|
+
- **Version**: 4.5.2
|
|
5
|
+
- **Agents**: Specialized discovery and planning agents feeding provider-neutral RAIL execution and a sealed release lane
|
|
6
6
|
- **Constitution**: 25 Articles + Preamble
|
|
7
7
|
- **Quality**: 5 pipeline gates + 3-tier verdicts + Fault Vector Protocol (Article XXII)
|
|
8
|
-
- **
|
|
8
|
+
- **Provider Policy**: Claude, Codex, and Grok bindings are selected at installation and enforced per task
|
|
9
9
|
|
|
10
10
|
## Key References
|
|
11
11
|
- **Session State**: `.chati/session.yaml` (runtime, not committed)
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
```
|
|
19
19
|
DISCOVER: WU -> Brief
|
|
20
20
|
PLAN: [Planning Team: Detail + Architect + UX + QA-Planning] -> Phases -> Tasks
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
RAIL: Sealed task graph -> Execute -> Independent Review -> Bounded Rework
|
|
22
|
+
RELEASE: Evidence gate -> Explicit human authorization -> External action
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
## How to Use
|
package/framework/i18n/en.yaml
CHANGED
|
@@ -22,8 +22,14 @@ installer:
|
|
|
22
22
|
llm_provider_not_installed: "(CLI not detected)"
|
|
23
23
|
llm_provider_label: "AI Provider"
|
|
24
24
|
ide_selection_title: "Select your IDEs / CLIs (multiple allowed):"
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
installation_mode_title: "Select the installation mode"
|
|
26
|
+
installation_mode_open: "Open"
|
|
27
|
+
installation_mode_open_hint: "Public framework without mandatory company integrations"
|
|
28
|
+
installation_mode_internal: "Internal"
|
|
29
|
+
installation_mode_internal_hint: "Requires an authorized license and enables ClickUp tracking plus internal policies"
|
|
30
|
+
installation_mode_label: "Installation mode"
|
|
31
|
+
model_routing_label: "Model routing"
|
|
32
|
+
model_routing_automatic: "Automatic per task across all enabled models"
|
|
27
33
|
providers_label: "Providers"
|
|
28
34
|
quick_start_switch_hint: "Switch CLIs anytime — your session continues from where you left off"
|
|
29
35
|
created_overlays: "Created provider overlay directories"
|
package/framework/i18n/es.yaml
CHANGED
|
@@ -22,8 +22,14 @@ installer:
|
|
|
22
22
|
llm_provider_not_installed: "(CLI no detectada)"
|
|
23
23
|
llm_provider_label: "Proveedor de IA"
|
|
24
24
|
ide_selection_title: "Seleccione sus IDEs / CLIs (multiples permitidos):"
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
installation_mode_title: "Seleccione el modo de instalacion"
|
|
26
|
+
installation_mode_open: "Open"
|
|
27
|
+
installation_mode_open_hint: "Framework publico sin integraciones corporativas obligatorias"
|
|
28
|
+
installation_mode_internal: "Internal"
|
|
29
|
+
installation_mode_internal_hint: "Requiere una licencia autorizada y activa el tracking en ClickUp y las politicas internas"
|
|
30
|
+
installation_mode_label: "Modo de instalacion"
|
|
31
|
+
model_routing_label: "Enrutamiento de modelos"
|
|
32
|
+
model_routing_automatic: "Automatico por tarea entre todos los modelos habilitados"
|
|
27
33
|
providers_label: "Proveedores"
|
|
28
34
|
quick_start_switch_hint: "Cambie de CLI en cualquier momento — su sesion continua desde donde quedo"
|
|
29
35
|
created_overlays: "Creados directorios de overlay de proveedores"
|