chati-dev 4.5.11 → 4.5.13

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 (37) hide show
  1. package/framework/config.yaml +2 -2
  2. package/framework/constitution.md +21 -22
  3. package/framework/context/root.md +1 -1
  4. package/framework/data/entity-registry.yaml +1 -1
  5. package/framework/domains/constitution.yaml +1 -1
  6. package/framework/domains/workflows/brownfield-fullstack.yaml +5 -3
  7. package/framework/domains/workflows/brownfield-service.yaml +2 -3
  8. package/framework/domains/workflows/brownfield-ui.yaml +2 -3
  9. package/framework/domains/workflows/greenfield-fullstack.yaml +5 -3
  10. package/framework/domains/workflows/quick-flow.yaml +7 -6
  11. package/framework/domains/workflows/standard-flow.yaml +4 -5
  12. package/framework/frameworks/quality-dimensions.yaml +3 -3
  13. package/framework/manifest.json +37 -37
  14. package/framework/manifest.sig +1 -1
  15. package/framework/schemas/session.schema.json +1 -1
  16. package/framework/workflows/brownfield-fullstack.yaml +17 -123
  17. package/framework/workflows/brownfield-service.yaml +15 -109
  18. package/framework/workflows/brownfield-ui.yaml +15 -115
  19. package/framework/workflows/greenfield-fullstack.yaml +17 -130
  20. package/framework/workflows/quick-flow.yaml +20 -111
  21. package/framework/workflows/standard-flow.yaml +14 -158
  22. package/package.json +1 -1
  23. package/src/config/claude-settings-generator.js +4 -3
  24. package/src/config/context-file-generator.js +10 -1
  25. package/src/config/framework-adapter.js +31 -0
  26. package/src/installer/core.js +89 -8
  27. package/src/installer/templates.js +33 -3
  28. package/src/installer/validator.js +8 -2
  29. package/src/intelligence/registry-manager.js +11 -4
  30. package/src/orchestrator/cli.js +54 -28
  31. package/src/terminal/handoff-parser.js +23 -4
  32. package/src/terminal/prompt-builder.js +15 -1
  33. package/src/terminal/provider-preflight.js +78 -0
  34. package/src/terminal/run-agent.js +66 -23
  35. package/src/terminal/spawner.js +5 -1
  36. package/src/utils/schema-validator.js +5 -2
  37. package/src/wizard/index.js +1 -0
@@ -1,127 +1,36 @@
1
- # Quick Flow Workflow
2
- # Fast-track pipeline for simple tasks: bug fixes, small features, config changes
3
- # Skips full DISCOVER/PLAN phases when complexity is low
4
-
5
1
  workflow:
6
2
  id: quick-flow
7
- name: Quick Flow — Fast Track Development
8
- version: "1.0.0"
3
+ name: Quick Flow
4
+ version: "2.0.0"
9
5
  type: any
10
6
  project_types: [bug-fix, small-feature, config-change, hotfix, refactor]
11
- description: >
12
- Condensed pipeline for tasks that don't need full discovery/planning.
13
- Used when the orchestrator detects low complexity: clear requirements,
14
- known codebase, small scope. Skips Detail, Architect, UX, Phases, Tasks,
15
- and QA-Planning. Goes straight from Brief (quick) to Dev.
7
+ execution_authority: rail
8
+ description: Condensed planning with the same sealed RAIL and Release contracts as the full workflow.
16
9
 
17
10
  detection:
18
- # Orchestrator uses these signals to auto-detect quick-flow eligibility
19
- triggers:
20
- - "User explicitly requests quick fix or hotfix"
21
- - "Single, well-defined requirement (can be stated in one sentence)"
22
- - "Bug report with reproduction steps"
23
- - "Configuration or environment change"
24
- - "Small refactoring with clear scope"
25
- - "User says 'just do it' or 'quick fix' or similar urgency signals"
26
- - "Simple, fun, or experimental project (single-purpose tool, game, prototype)"
27
- - "Single-page utility or learning project with no production requirements"
28
- disqualifiers:
29
- - "New feature requiring architecture decisions (multiple services, database design, auth system)"
30
- - "Multiple interconnected requirements (>3 distinct features)"
31
- - "Complex greenfield project (enterprise, multi-service, compliance requirements)"
32
- - "Enterprise or compliance context"
33
- - "User explicitly requests full pipeline"
34
- - "Scope involves more than 5 files"
35
- - "Requires database schema changes"
36
- - "Requires new API endpoints (>2)"
37
-
38
11
  confidence_threshold: 0.8
39
12
  user_confirmation: true
13
+ disqualifiers:
14
+ - architecture decision required
15
+ - more than five files expected
16
+ - database schema change
17
+ - more than two new API endpoints
40
18
 
41
19
  phases:
42
20
  - phase: 0
43
- name: Quick Brief
44
- category: DISCOVER
45
- sequence:
46
- - agent: brief
47
- action: quick-extraction
48
- creates: [artifacts/1-Brief/quick-brief.md]
49
- notes: >
50
- Condensed extraction: single-pass, no 5-phase process.
51
- Capture: what, why, constraints, acceptance criteria.
52
- Duration: 2-5 min max.
53
- template: quick-brief-tmpl.yaml
54
- config:
55
- max_rounds: 2
56
- require_approval: true
57
-
58
- - phase: 1
59
- name: Implementation
60
- category: BUILD
61
- sequence:
62
- - agent: dev
63
- action: implement-tasks
64
- notes: >
65
- Dev works directly from Quick Brief (no PRD, no architecture doc).
66
- Scope is tight: fix the bug, add the small feature, make the change.
67
- Self-critique checklist still applies.
68
-
69
- - phase: 2
70
- name: Validation
71
- category: BUILD
72
- sequence:
73
- - agent: qa-implementation
74
- action: validate-code
75
- creates: [artifacts/9-QA-Implementation/qa-implementation-report.md]
76
- notes: >
77
- Full QA-Implementation validation still applies (no shortcuts on quality).
78
- Adversarial review still mandatory.
79
- Tests must pass, SAST must be clean.
80
- config:
81
- adversarial_review: true
82
- minimum_findings: 3
83
-
84
- - phase: 3
85
- name: Deployment
86
- category: DEPLOY
21
+ name: Compact Planning
22
+ category: PLAN
87
23
  sequence:
88
- - agent: devops
89
- action: deploy
90
- creates: [artifacts/10-Deploy/deploy-report.md]
91
- notes: "Standard deployment process"
24
+ - { agent: brief, action: quick-extraction, creates: [artifacts/1-Brief/quick-brief.md] }
25
+ - { agent: tasks, action: compact-sealed-task-graph, creates: [artifacts/6-Tasks/tasks.md] }
26
+ - { agent: qa-planning, action: validate-compact-plan, creates: [artifacts/7-QA-Planning/qa-planning-report.md] }
27
+ - { phase: 1, name: RAIL Execution, category: RAIL, runtime: project-local-rail }
28
+ - { phase: 2, name: Release Lane, category: RELEASE, requires: [rail_complete, independent_review_approved, explicit_human_authorization] }
92
29
 
93
30
  transitions:
94
- quick_brief_to_build:
95
- trigger: "brief.status == completed"
96
- type: automatic
97
- action: "Skip full PLAN phase, go directly to BUILD"
98
- notes: "No Detail, Architect, UX, Phases, Tasks, or QA-Planning"
99
- build_to_validate:
100
- trigger: "dev.status == completed"
101
- type: automatic
102
- action: "Update project.state = validate"
103
- validate_to_deploy:
104
- trigger: "qa-implementation.status == approved"
105
- type: automatic
106
- action: "Update project.state = deploy"
107
- notes: "User preview skipped for quick-flow (scope too small)"
108
- deploy_to_completed:
109
- trigger: "devops.status == completed"
110
- type: automatic
111
- action: "Update project.state = completed"
31
+ plan_to_rail: { trigger: "qa-planning.score >= 95 && tasks.handoff == sealed", target: rail }
32
+ rail_to_release: { trigger: "rail.all_tasks_approved == true", target: release }
112
33
 
113
34
  escalation:
114
- # If at any point the quick-flow feels insufficient, escalate to full pipeline
115
- triggers:
116
- - "Dev discovers the change is more complex than expected"
117
- - "QA-Implementation finds architectural issues"
118
- - "Scope creep detected (>5 files, new APIs, schema changes)"
119
- - "Dev agent requests escalation"
120
- action: >
121
- Pause quick-flow, notify user:
122
- "This task is more complex than initially estimated.
123
- Recommend switching to full pipeline for proper planning.
124
- Options:
125
- 1. Switch to full pipeline (Recommended)
126
- 2. Continue with quick-flow (document risk)
127
- 3. Abort and reassess"
35
+ triggers: [scope-expansion, architecture-decision, planning-gate-failure]
36
+ action: restart with the appropriate full planning workflow
@@ -1,174 +1,30 @@
1
- # Standard Flow Workflow
2
- # Mid-tier pipeline for moderate tasks: new features, integrations, brownfield enhancements
3
- # Uses 8 agents — between Quick Flow (4) and Full Flow (12)
4
-
5
1
  workflow:
6
2
  id: standard-flow
7
- name: Standard Flow — Balanced Development
8
- version: "1.0.0"
3
+ name: Standard Flow
4
+ version: "2.0.0"
9
5
  type: any
10
6
  project_types: [feature, integration, enhancement, module, component, brownfield-moderate]
11
- description: >
12
- Balanced pipeline for moderate complexity tasks that need proper planning
13
- but not the full 12-agent pipeline. Skips WU (assumes existing codebase
14
- context), UX (no design-heavy work), and Phases (tasks agent handles
15
- scope directly). Ideal for 2-5 requirements in brownfield projects.
16
-
17
- detection:
18
- triggers:
19
- - "Moderate complexity feature with 2-5 requirements"
20
- - "Brownfield project enhancement or integration"
21
- - "New module or component within existing architecture"
22
- - "User explicitly requests standard flow"
23
- - "Feature that needs architecture review but not full UX design"
24
- - "API integration or service connection"
25
- - "Database-backed feature with clear data model"
26
- disqualifiers:
27
- - "Quick fix, hotfix, or single-line change (use Quick Flow)"
28
- - "Enterprise-scale project with compliance requirements (use Full Flow)"
29
- - "Greenfield project requiring full discovery (use Full Flow)"
30
- - "UX-heavy feature requiring design system work (use Full Flow)"
31
- - "Multi-service architecture changes (use Full Flow)"
32
- - "User explicitly requests full pipeline"
33
-
34
- confidence_threshold: 0.8
35
- user_confirmation: true
36
-
37
- agents:
38
- included:
39
- - brief
40
- - detail
41
- - architect
42
- - tasks
43
- - qa-planning # runs inside Planning Team; score synced via team dissolution
44
- - dev
45
- - qa-implementation
46
- - devops
47
- excluded:
48
- - greenfield-wu
49
- - brownfield-wu
50
- - ux
51
- - phases
7
+ execution_authority: rail
8
+ description: Balanced planning followed by the canonical RAIL and Release contracts.
52
9
 
53
10
  phases:
54
11
  - phase: 0
55
12
  name: Discovery
56
13
  category: DISCOVER
57
14
  sequence:
58
- - agent: brief
59
- action: extract-requirements
60
- creates: [artifacts/1-Brief/brief.md]
61
- notes: >
62
- Full brief extraction (5 phases). Since no WU precedes it,
63
- Brief must also capture codebase context from user input.
64
- config:
65
- max_rounds: 5
66
- require_approval: true
67
-
15
+ - { agent: brief, action: problem-extraction, creates: [artifacts/1-Brief/brief-report.md] }
68
16
  - phase: 1
69
17
  name: Planning
70
18
  category: PLAN
71
19
  sequence:
72
- - agent: detail
73
- action: expand-requirements
74
- creates: [artifacts/2-Detail/prd.md]
75
- notes: "Full PRD from brief output"
76
- parallel_with: [architect]
77
-
78
- - agent: architect
79
- action: design-architecture
80
- creates: [artifacts/3-Architecture/architecture.md]
81
- notes: "Architecture decisions, no UX constraints needed"
82
- parallel_with: [detail]
83
-
84
- - agent: tasks
85
- action: create-tasks
86
- creates: [artifacts/5-Tasks/tasks.md]
87
- notes: >
88
- Tasks agent works directly from PRD + Architecture.
89
- No phases agent — tasks agent determines task breakdown directly.
90
-
91
- - agent: qa-planning
92
- action: validate-plan
93
- creates: [artifacts/6-QA-Planning/qa-planning-report.md]
94
- notes: >
95
- Runs inside Planning Team (Article XXI), not as a standalone step.
96
- Activates after Detail, Architect complete. Score >= 95% required to advance.
97
- Score synced to session.yaml by orchestrator on team dissolution.
98
- config:
99
- minimum_score: 95
100
-
101
- - phase: 2
102
- name: Implementation
103
- category: BUILD
104
- sequence:
105
- - agent: dev
106
- action: implement-tasks
107
- notes: "Dev works from full PRD + architecture + tasks"
108
-
109
- - agent: qa-implementation
110
- action: validate-code
111
- creates: [artifacts/9-QA-Implementation/qa-implementation-report.md]
112
- notes: >
113
- Full QA-Implementation validation. Score >= 95% required.
114
- Adversarial review mandatory.
115
- config:
116
- adversarial_review: true
117
- minimum_findings: 5
118
- minimum_score: 95
119
-
120
- - phase: 3
121
- name: Deployment
122
- category: DEPLOY
123
- sequence:
124
- - agent: devops
125
- action: deploy
126
- creates: [artifacts/10-Deploy/deploy-report.md]
127
- notes: "Standard deployment process"
20
+ - { agent: detail, action: create-prd, creates: [artifacts/2-PRD/prd.md] }
21
+ - { agent: architect, action: focused-architecture, creates: [artifacts/3-Architecture/architecture.md] }
22
+ - { agent: tasks, action: seal-task-graph, creates: [artifacts/6-Tasks/tasks.md] }
23
+ - { agent: qa-planning, action: validate-planning, creates: [artifacts/7-QA-Planning/qa-planning-report.md] }
24
+ - { phase: 2, name: RAIL Execution, category: RAIL, runtime: project-local-rail }
25
+ - { phase: 3, name: Release Lane, category: RELEASE, requires: [rail_complete, independent_review_approved, explicit_human_authorization] }
128
26
 
129
27
  transitions:
130
- discover_to_plan:
131
- trigger: "brief.status == completed"
132
- type: automatic
133
- action: "Advance to PLAN phase"
134
- plan_to_build:
135
- trigger: "qa-planning.score >= 95"
136
- type: automatic
137
- action: "Advance to BUILD phase"
138
- build_to_validate:
139
- trigger: "dev.status == completed"
140
- type: automatic
141
- action: "Run QA-Implementation"
142
- validate_to_deploy:
143
- trigger: "qa-implementation.score >= 95"
144
- type: user_preview
145
- action: "User preview gate, then advance to DEPLOY"
146
- deploy_to_completed:
147
- trigger: "devops.status == completed"
148
- type: automatic
149
- action: "Pipeline complete"
150
-
151
- escalation:
152
- to_full_flow:
153
- triggers:
154
- - "Architect discovers multi-service complexity"
155
- - "QA-Planning finds UX requirements not addressed"
156
- - "Scope creep: more than 5 distinct requirements discovered"
157
- - "User requests full pipeline"
158
- action: >
159
- Pause standard-flow, notify user:
160
- "This task is more complex than the standard flow can handle.
161
- Options:
162
- 1. Switch to full pipeline (Recommended)
163
- 2. Continue with standard flow (document gaps)
164
- 3. Reduce scope and continue"
165
- to_quick_flow:
166
- triggers:
167
- - "Detail agent finds only 1 simple requirement"
168
- - "Architect confirms no architecture changes needed"
169
- action: >
170
- Suggest downgrade:
171
- "This task might be simpler than expected.
172
- Options:
173
- 1. Switch to quick flow (faster)
174
- 2. Continue with standard flow"
28
+ discover_to_plan: { trigger: "brief.status == completed", target: plan }
29
+ plan_to_rail: { trigger: "qa-planning.score >= 95 && tasks.handoff == sealed", target: rail }
30
+ rail_to_release: { trigger: "rail.all_tasks_approved == true", target: release }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chati-dev",
3
- "version": "4.5.11",
3
+ "version": "4.5.13",
4
4
  "description": "AI-Powered Multi-Agent Orchestration System - Structured vibe coding for Full Stack Development",
5
5
  "type": "module",
6
6
  "bin": {
@@ -176,10 +176,11 @@ const PERMISSIONS_DENY = [
176
176
  * Group HOOK_REGISTRY entries by event, then by matcher within each event.
177
177
  * Returns the shape Claude Code expects under the top-level "hooks" key.
178
178
  */
179
- function buildHooksObject() {
179
+ function buildHooksObject(options = {}) {
180
180
  const events = {};
181
181
 
182
182
  for (const entry of HOOK_REGISTRY) {
183
+ if (options.runtimeVersion === 2 && entry.name === 'post-dev') continue;
183
184
  if (!events[entry.event]) events[entry.event] = new Map();
184
185
  const matcherGroups = events[entry.event];
185
186
  if (!matcherGroups.has(entry.matcher)) {
@@ -208,7 +209,7 @@ function buildHooksObject() {
208
209
  *
209
210
  * @returns {string} JSON string with trailing newline, ready to write to disk.
210
211
  */
211
- export function generateClaudeSettings() {
212
+ export function generateClaudeSettings(options = {}) {
212
213
  const settings = {
213
214
  $schema: 'https://json.schemastore.org/claude-code-settings.json',
214
215
  permissions: {
@@ -216,7 +217,7 @@ export function generateClaudeSettings() {
216
217
  deny: PERMISSIONS_DENY,
217
218
  defaultMode: 'default',
218
219
  },
219
- hooks: buildHooksObject(),
220
+ hooks: buildHooksObject(options),
220
221
  };
221
222
 
222
223
  return JSON.stringify(settings, null, 2) + '\n';
@@ -68,10 +68,17 @@ function buildCodexReplacements(frameworkDir = 'chati.dev') {
68
68
  ['claude --print', 'codex exec'],
69
69
  ['claude -p', 'codex exec'],
70
70
  ['CLAUDE.local.md', 'AGENTS.override.md'],
71
- ['/chati', '$chati'],
72
71
  ];
73
72
  }
74
73
 
74
+ /**
75
+ * Convert the interactive slash command without touching filesystem paths such
76
+ * as `.chati.dev/orchestrator/chati.md`.
77
+ */
78
+ function adaptCodexInvocation(content) {
79
+ return content.replace(/(?<![\w/])\/chati(?=\s|$|[`'".,;:!?)]|\b)/gm, '$chati');
80
+ }
81
+
75
82
  // ---------------------------------------------------------------------------
76
83
  // Generators
77
84
  // ---------------------------------------------------------------------------
@@ -144,6 +151,7 @@ export function generateAgentsMd(content, contextFiles = null, frameworkDir = 'c
144
151
  for (const [search, replace] of replacements) {
145
152
  result = result.replaceAll(search, replace);
146
153
  }
154
+ result = adaptCodexInvocation(result);
147
155
 
148
156
  // Clean up any double blank lines left by stripping
149
157
  result = result.replace(/\n{3,}/g, '\n\n');
@@ -166,6 +174,7 @@ export function generateAgentsMd(content, contextFiles = null, frameworkDir = 'c
166
174
  for (const [search, replace] of replacements) {
167
175
  adapted = adapted.replaceAll(search, replace);
168
176
  }
177
+ adapted = adaptCodexInvocation(adapted);
169
178
  sections.push(adapted.trim());
170
179
  }
171
180
  }
@@ -65,6 +65,30 @@ const PROVIDER_META = {
65
65
  },
66
66
  };
67
67
 
68
+ const CODEX_CREDENTIAL_BOUNDARY = `
69
+ ## Codex external provider credential boundary
70
+
71
+ Commands returned in any \`spawn_command\`, \`parallel_spawn_command\` or
72
+ \`parallel_spawn_commands\` start another provider CLI. Codex MUST execute each
73
+ of these commands with native escalated execution so the child CLI can access
74
+ its existing local credentials:
75
+
76
+ - Set \`sandbox_permissions\` to \`require_escalated\`.
77
+ - Explain that Chati needs to run the selected provider CLI using its existing
78
+ local authentication.
79
+ - Offer the narrow reusable prefix made from the first two command arguments:
80
+ \`["node", "<absolute path from the command to run-agent.js>"]\`.
81
+ - Keep the project working directory and the router-provided command unchanged.
82
+
83
+ Never test a routed provider command inside the workspace sandbox first. A
84
+ \`PROVIDER_NOT_READY\` or \`PROVIDER_NOT_AUTHENTICATED\` result obtained inside
85
+ that sandbox is inconclusive because the sandbox can hide OS credentials. If a
86
+ sandboxed attempt already failed, rerun it once with native escalated execution.
87
+ Only a failure from that escalated attempt may be reported as an authentication
88
+ failure. Do not repeat the same sandboxed command and do not offer to skip a
89
+ required v2 pipeline stage.
90
+ `;
91
+
68
92
  // ---------------------------------------------------------------------------
69
93
  // Replacement Configuration Builder
70
94
  // ---------------------------------------------------------------------------
@@ -225,5 +249,12 @@ export function adaptFrameworkFile(content, filePath, provider) {
225
249
  result = result.replace(pattern, replacement);
226
250
  }
227
251
 
252
+ if (provider === 'codex' && filePath === 'orchestrator/chati.md') {
253
+ const routedAction = '## Action: Routed Interactive Agent';
254
+ result = result.includes(routedAction)
255
+ ? result.replace(routedAction, `${CODEX_CREDENTIAL_BOUNDARY}\n${routedAction}`)
256
+ : `${result.trimEnd()}\n\n${CODEX_CREDENTIAL_BOUNDARY.trimStart()}`;
257
+ }
258
+
228
259
  return result;
229
260
  }
@@ -1,4 +1,4 @@
1
- import { mkdirSync, writeFileSync, copyFileSync, existsSync, readFileSync, readdirSync, statSync } from 'fs';
1
+ import { mkdirSync, writeFileSync, copyFileSync, existsSync, readFileSync, readdirSync, statSync, rmSync } from 'fs';
2
2
  import { execFileSync } from 'child_process';
3
3
  import { join, dirname } from 'path';
4
4
  import { fileURLToPath } from 'url';
@@ -12,6 +12,7 @@ import { generateClaudeSettings } from '../config/claude-settings-generator.js';
12
12
  import { generateProviderOverlays } from './provider-overlay.js';
13
13
  import { applyInstalledPathReplacement } from './path-replacement.js';
14
14
  import { verifyManifest } from './manifest.js';
15
+ import * as yaml from 'js-yaml';
15
16
 
16
17
  const __dirname = dirname(fileURLToPath(import.meta.url));
17
18
 
@@ -70,7 +71,13 @@ export async function installFramework(config) {
70
71
 
71
72
  // 2b. Create artifacts/ at PROJECT ROOT (visible to user — this is their output)
72
73
  const artifactsDir = join(targetDir, 'artifacts');
73
- const artifactDirs = [
74
+ const isRuntimeV2 = config.runtimeVersion === 2;
75
+ const artifactDirs = isRuntimeV2 ? [
76
+ '0-WU', '1-Brief', '2-PRD',
77
+ '3-Architecture', '4-UX', '5-Phases',
78
+ '6-Tasks', '7-QA-Planning', '8-RAIL', '9-Release',
79
+ 'handoffs', 'decisions',
80
+ ] : [
74
81
  '0-WU', '1-Brief', '2-PRD',
75
82
  '3-Architecture', '4-UX', '5-Phases',
76
83
  '6-Tasks', '7-QA-Planning', '8-QA-Visual', '9-QA-Implementation', '10-Deploy',
@@ -96,7 +103,7 @@ export async function installFramework(config) {
96
103
 
97
104
  // Create .chati/memories/ directory tree for Memory Layer
98
105
  const memoriesBase = join(targetDir, '.chati', 'memories');
99
- const memoryDirs = [
106
+ const planningMemoryDirs = [
100
107
  'shared/durable', 'shared/daily', 'shared/session',
101
108
  'greenfield-wu/durable', 'greenfield-wu/daily',
102
109
  'brownfield-wu/durable', 'brownfield-wu/daily',
@@ -107,11 +114,16 @@ export async function installFramework(config) {
107
114
  'phases/durable', 'phases/daily',
108
115
  'tasks/durable', 'tasks/daily',
109
116
  'qa-planning/durable', 'qa-planning/daily',
117
+ ];
118
+ const legacyExecutionMemoryDirs = [
110
119
  'qa-implementation/durable', 'qa-implementation/daily',
111
120
  'qa-visual/durable', 'qa-visual/daily',
112
121
  'dev/durable', 'dev/daily',
113
122
  'devops/durable', 'devops/daily',
114
123
  ];
124
+ const memoryDirs = isRuntimeV2
125
+ ? [...planningMemoryDirs, 'rail/durable', 'rail/daily', 'release/durable', 'release/daily']
126
+ : [...planningMemoryDirs, ...legacyExecutionMemoryDirs];
115
127
  for (const dir of memoryDirs) {
116
128
  createDir(join(memoriesBase, dir));
117
129
  }
@@ -125,6 +137,11 @@ export async function installFramework(config) {
125
137
  generateProviderOverlays(targetDir, FRAMEWORK_SOURCE, allProviders);
126
138
  }
127
139
 
140
+ if (isRuntimeV2) {
141
+ pruneLegacyExecutionSurface(frameworkDir, allProviders || []);
142
+ pruneLegacyRegistryEntities(frameworkDir);
143
+ }
144
+
128
145
  // Bundle the CLI source into the framework dir so chati-router.js can run
129
146
  // commands locally without depending on `npx chati-dev` (which fetches from
130
147
  // the npm registry — version drift causes inconsistent behavior).
@@ -162,7 +179,7 @@ export async function installFramework(config) {
162
179
  // Write config.yaml
163
180
  writeFileSync(
164
181
  join(frameworkDir, 'config.yaml'),
165
- generateConfigYaml({ version, projectType, language, selectedIDEs, allProviders }),
182
+ generateConfigYaml({ version, projectType, language, selectedIDEs, allProviders, runtimeVersion: config.runtimeVersion }),
166
183
  'utf-8'
167
184
  );
168
185
 
@@ -174,7 +191,12 @@ export async function installFramework(config) {
174
191
  const orchestratorPath = hasProviderOverlay
175
192
  ? `.chati.dev/.adapted/${ideProvider}/orchestrator/chati.md`
176
193
  : '.chati.dev/orchestrator/chati.md';
177
- await configureIDE(targetDir, ideKey, selectedMCPs, { orchestratorPath, isSecondary: false, providerName: ideProvider });
194
+ await configureIDE(targetDir, ideKey, selectedMCPs, {
195
+ orchestratorPath,
196
+ isSecondary: false,
197
+ providerName: ideProvider,
198
+ runtimeVersion: config.runtimeVersion,
199
+ });
178
200
  }
179
201
 
180
202
  const hasClaude = selectedIDEs.includes('claude-code');
@@ -224,6 +246,55 @@ export async function installFramework(config) {
224
246
  ensureGitRepository(targetDir);
225
247
  }
226
248
 
249
+ function pruneLegacyRegistryEntities(frameworkDir) {
250
+ const registryPath = join(frameworkDir, 'data', 'entity-registry.yaml');
251
+ if (!existsSync(registryPath)) return;
252
+ const registry = yaml.load(readFileSync(registryPath, 'utf-8'));
253
+ if (!registry?.entities) return;
254
+ const legacyPath = /\/(?:agents\/(?:build|deploy)\/|agents\/quality\/qa-(?:implementation|visual)\.md$|hooks\/post-dev\.js$|templates\/team-build-tasks\.yaml$|quality-gates\/implementation-gate\.md$|domains\/agents\/(?:dev|devops|qa-implementation|qa-visual)\.yaml$|tasks\/(?:dev-|devops-|qa-impl-))/;
255
+ let count = 0;
256
+ for (const entities of Object.values(registry.entities)) {
257
+ if (!entities || typeof entities !== 'object') continue;
258
+ for (const [name, entity] of Object.entries(entities)) {
259
+ if (legacyPath.test(entity?.path || '')) delete entities[name];
260
+ else if (entity?.path) count += 1;
261
+ }
262
+ }
263
+ registry.metadata = { ...(registry.metadata || {}), entity_count: count };
264
+ writeFileSync(registryPath, yaml.dump(registry, { lineWidth: -1 }), 'utf-8');
265
+ }
266
+
267
+ const V2_LEGACY_EXECUTION_PATHS = [
268
+ 'agents/build',
269
+ 'agents/deploy',
270
+ 'agents/quality/qa-implementation.md',
271
+ 'agents/quality/qa-visual.md',
272
+ 'quality-gates/implementation-gate.md',
273
+ 'templates/team-build-tasks.yaml',
274
+ 'hooks/post-dev.js',
275
+ 'domains/agents/dev.yaml',
276
+ 'domains/agents/devops.yaml',
277
+ 'domains/agents/qa-implementation.yaml',
278
+ 'domains/agents/qa-visual.yaml',
279
+ ];
280
+
281
+ function pruneLegacyExecutionSurface(frameworkDir, providers) {
282
+ const roots = [frameworkDir, ...providers.map(provider => join(frameworkDir, '.adapted', provider))];
283
+ for (const root of roots) {
284
+ for (const relativePath of V2_LEGACY_EXECUTION_PATHS) {
285
+ rmSync(join(root, relativePath), { recursive: true, force: true });
286
+ }
287
+ const tasksDir = join(root, 'tasks');
288
+ if (existsSync(tasksDir)) {
289
+ for (const entry of readdirSync(tasksDir)) {
290
+ if (/^(?:dev-|devops-|qa-impl-)/.test(entry)) {
291
+ rmSync(join(tasksDir, entry), { force: true });
292
+ }
293
+ }
294
+ }
295
+ }
296
+ }
297
+
227
298
  export function ensureGitRepository(targetDir) {
228
299
  try {
229
300
  execFileSync('git', ['-C', targetDir, 'rev-parse', '--show-toplevel'], { stdio: 'ignore' });
@@ -415,7 +486,7 @@ Parse the JSON output. This single command already handled: license validation,
415
486
  // hook system and applies a baseline permission policy. THIS IS THE FILE
416
487
  // CLAUDE CODE READS — without it, every hook in chati.dev/hooks/ is dormant.
417
488
  // (Pre-v4.2.2 bug: this file was never written, hooks never ran.)
418
- writeClaudeSettingsWithMerge(join(targetDir, '.claude', 'settings.json'));
489
+ writeClaudeSettingsWithMerge(join(targetDir, '.claude', 'settings.json'), { runtimeVersion: options.runtimeVersion });
419
490
 
420
491
  // Claude project-scope MCP config lives at the project root. Preserve
421
492
  // unknown user-managed servers while replacing CHATI's known entries.
@@ -883,9 +954,9 @@ export function copyCliDependencies(pkgDir, destNodeModules) {
883
954
  * If the file exists but is malformed: leave it alone, log a warning. We will
884
955
  * not silently destroy user data.
885
956
  */
886
- export function writeClaudeSettingsWithMerge(settingsPath) {
957
+ export function writeClaudeSettingsWithMerge(settingsPath, options = {}) {
887
958
  createDir(dirname(settingsPath));
888
- const fresh = JSON.parse(generateClaudeSettings());
959
+ const fresh = JSON.parse(generateClaudeSettings(options));
889
960
 
890
961
  if (!existsSync(settingsPath)) {
891
962
  writeFileSync(settingsPath, JSON.stringify(fresh, null, 2) + '\n', 'utf-8');
@@ -900,6 +971,16 @@ export function writeClaudeSettingsWithMerge(settingsPath) {
900
971
  return;
901
972
  }
902
973
 
974
+ if (options.runtimeVersion === 2 && existing.hooks) {
975
+ for (const groups of Object.values(existing.hooks)) {
976
+ if (!Array.isArray(groups)) continue;
977
+ for (const group of groups) {
978
+ if (Array.isArray(group.hooks)) {
979
+ group.hooks = group.hooks.filter(hook => !/\.chati\.dev\/hooks\/post-dev\.js$/.test(hook.command || ''));
980
+ }
981
+ }
982
+ }
983
+ }
903
984
  const merged = mergeClaudeSettings(existing, fresh);
904
985
  writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
905
986
  }