chati-dev 4.2.1 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/README.md +80 -53
  2. package/bin/chati.js +150 -5
  3. package/framework/agents/build/dev.md +509 -76
  4. package/framework/agents/deploy/devops.md +40 -25
  5. package/framework/agents/discover/brief.md +156 -22
  6. package/framework/agents/discover/brownfield-wu.md +24 -14
  7. package/framework/agents/discover/greenfield-wu.md +100 -14
  8. package/framework/agents/plan/architect-data-engineer.md +6 -6
  9. package/framework/agents/plan/architect-system.md +46 -12
  10. package/framework/agents/plan/architect.md +40 -20
  11. package/framework/agents/plan/detail.md +36 -24
  12. package/framework/agents/plan/phases.md +36 -26
  13. package/framework/agents/plan/tasks.md +114 -33
  14. package/framework/agents/plan/ux-brand-architect.md +240 -8
  15. package/framework/agents/plan/ux-component-engineer.md +28 -13
  16. package/framework/agents/plan/ux-researcher.md +7 -6
  17. package/framework/agents/plan/ux.md +55 -22
  18. package/framework/agents/quality/qa-implementation.md +143 -74
  19. package/framework/agents/quality/qa-planning.md +115 -42
  20. package/framework/agents/quality/qa-visual.md +439 -0
  21. package/framework/agents/shared/visualizer.md +128 -0
  22. package/framework/config.yaml +8 -7
  23. package/framework/constitution.md +127 -43
  24. package/framework/context/governance.md +12 -7
  25. package/framework/context/quality.md +6 -5
  26. package/framework/context/root.md +6 -6
  27. package/framework/data/entity-registry.yaml +377 -4
  28. package/framework/data/model-limits.json +19 -0
  29. package/framework/domains/agents/qa-visual.yaml +74 -0
  30. package/framework/domains/constitution.yaml +46 -2
  31. package/framework/domains/workflows/greenfield-fullstack.yaml +2 -2
  32. package/framework/hooks/advance-trigger.js +131 -0
  33. package/framework/hooks/brief-validator.js +83 -0
  34. package/framework/hooks/constitution-guard.js +91 -36
  35. package/framework/hooks/license-guard.js +129 -190
  36. package/framework/hooks/mode-governance.js +68 -16
  37. package/framework/hooks/model-governance.js +19 -8
  38. package/framework/hooks/package.json +3 -0
  39. package/framework/hooks/post-dev.js +207 -0
  40. package/framework/hooks/prism-engine.js +288 -105
  41. package/framework/hooks/read-protection.js +37 -9
  42. package/framework/hooks/reasoning-escalator.js +371 -0
  43. package/framework/hooks/reference-trigger.js +117 -0
  44. package/framework/hooks/session-digest.js +94 -20
  45. package/framework/hooks/settings.json +32 -1
  46. package/framework/hooks/style-guard.js +52 -13
  47. package/framework/hooks/team-quality-gate.js +58 -25
  48. package/framework/hooks/undercover-guard.js +34 -13
  49. package/framework/i18n/en.yaml +3 -3
  50. package/framework/i18n/es.yaml +3 -3
  51. package/framework/i18n/fr.yaml +3 -3
  52. package/framework/i18n/pt.yaml +3 -3
  53. package/framework/intelligence/context-engine.md +4 -5
  54. package/framework/intelligence/decision-engine.md +1 -1
  55. package/framework/intelligence/hooks-performance.md +3 -3
  56. package/framework/migrations/v1.0-to-v1.1.yaml +1 -1
  57. package/framework/migrations/v1.4-to-v2.0.yaml +11 -11
  58. package/framework/migrations/v4.0-to-v4.1.yaml +2 -2
  59. package/framework/migrations/v4.2-to-v4.3.yaml +29 -0
  60. package/framework/orchestrator/chati-router.js +387 -0
  61. package/framework/orchestrator/chati-update.md +40 -40
  62. package/framework/orchestrator/chati.md +318 -115
  63. package/framework/scaffold/motion-premium/README.md +89 -0
  64. package/framework/scaffold/motion-premium/app/globals.css.template +400 -0
  65. package/framework/scaffold/motion-premium/app/layout.tsx.template +110 -0
  66. package/framework/scaffold/motion-premium/components/animation/BackgroundCrossfadeProvider.tsx.template +170 -0
  67. package/framework/scaffold/motion-premium/components/animation/LenisProvider.tsx.template +49 -0
  68. package/framework/scaffold/motion-premium/components/animation/PageTransitionWrapper.tsx.template +83 -0
  69. package/framework/scaffold/motion-premium/components/animation/Preloader.tsx.template +171 -0
  70. package/framework/scaffold/motion-premium/components/ui/Container.tsx.template +69 -0
  71. package/framework/scaffold/motion-premium/components/ui/PageSection.tsx.template +74 -0
  72. package/framework/scaffold/motion-premium/lib/animations/gsap.ts.template +112 -0
  73. package/framework/scaffold/motion-premium/lib/animations/refreshCoordinator.ts.template +75 -0
  74. package/framework/scaffold/motion-premium/lib/animations/tokens.ts.template +119 -0
  75. package/framework/scaffold/motion-premium/lib/animations/useGsapContext.ts.template +92 -0
  76. package/framework/scaffold/motion-premium/lib/animations/useScrollSnapStepper.ts.template +265 -0
  77. package/framework/scaffold/motion-premium/lib/animations/useSmoothScroll.ts.template +67 -0
  78. package/framework/scaffold/motion-premium/lib/brand.ts.template +43 -0
  79. package/framework/scaffold/motion-premium/scaffold.yaml +174 -0
  80. package/framework/scaffold/motion-premium-3d/README.md +80 -0
  81. package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/ScrollDemoCanvas.tsx.template +81 -0
  82. package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/ScrollDemoClient.tsx.template +75 -0
  83. package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/page.tsx.template +26 -0
  84. package/framework/scaffold/motion-premium-3d/components/3d/CameraRig.tsx.template +100 -0
  85. package/framework/scaffold/motion-premium-3d/components/3d/CanvasProvider.tsx.template +85 -0
  86. package/framework/scaffold/motion-premium-3d/components/3d/InvalidateOnScroll.tsx.template +51 -0
  87. package/framework/scaffold/motion-premium-3d/components/3d/MeshCrossfade.tsx.template +79 -0
  88. package/framework/scaffold/motion-premium-3d/components/3d/ScrollCrossfade.tsx.template +88 -0
  89. package/framework/scaffold/motion-premium-3d/components/3d/ScrollScene.tsx.template +121 -0
  90. package/framework/scaffold/motion-premium-3d/components/webgl/SceneFallback.tsx.template +65 -0
  91. package/framework/scaffold/motion-premium-3d/components/webgl/WebGLContext.tsx.template +68 -0
  92. package/framework/scaffold/motion-premium-3d/lib/webgl/detect.ts.template +69 -0
  93. package/framework/scaffold/motion-premium-3d/scaffold.yaml +133 -0
  94. package/framework/schemas/session.schema.json +109 -21
  95. package/framework/scripts/reference-capture.js +430 -0
  96. package/framework/scripts/visual-qa.js +674 -0
  97. package/framework/tasks/orchestrator-handoff.md +1 -1
  98. package/framework/tasks/orchestrator-resume.md +1 -1
  99. package/framework/tasks/orchestrator-route.md +1 -1
  100. package/framework/tasks/orchestrator-status.md +3 -3
  101. package/framework/tasks/qa-planning-gate-define.md +1 -1
  102. package/framework/templates/brandbook-html-tmpl.md +1 -1
  103. package/framework/templates/brandbook-tmpl.yaml +1 -1
  104. package/framework/templates/component-spec-tmpl.yaml +1 -1
  105. package/framework/templates/design-token-tmpl.yaml +1 -1
  106. package/framework/templates/icon-system-tmpl.yaml +1 -1
  107. package/framework/templates/team-planning-tasks.yaml +6 -5
  108. package/framework/workflows/brownfield-discovery.yaml +2 -2
  109. package/framework/workflows/brownfield-fullstack.yaml +15 -11
  110. package/framework/workflows/brownfield-service.yaml +14 -10
  111. package/framework/workflows/brownfield-ui.yaml +15 -11
  112. package/framework/workflows/greenfield-fullstack.yaml +16 -13
  113. package/framework/workflows/quick-flow.yaml +3 -3
  114. package/framework/workflows/standard-flow.yaml +12 -9
  115. package/package.json +10 -5
  116. package/src/autonomy/autonomous-gate.js +1 -0
  117. package/src/autonomy/build-state.js +1 -2
  118. package/src/autonomy/progress-reporter.js +1 -1
  119. package/src/config/agent-customizer.js +11 -3
  120. package/src/config/claude-settings-generator.js +226 -0
  121. package/src/config/context-file-generator.js +41 -21
  122. package/src/config/framework-adapter.js +1 -0
  123. package/src/config/gemini-hooks-generator.js +76 -6
  124. package/src/config/mcp-configs.js +1 -0
  125. package/src/context/layers/l1-global.js +2 -1
  126. package/src/dashboard/data-reader.js +4 -3
  127. package/src/dashboard/layout.js +2 -1
  128. package/src/decision/analyzer.js +6 -30
  129. package/src/decision/engine.js +4 -28
  130. package/src/decision/registry-healer.js +3 -2
  131. package/src/decision/registry-updater.js +23 -14
  132. package/src/extensions/loader.js +2 -8
  133. package/src/gates/g1-planning-complete.js +2 -1
  134. package/src/gates/g2-qa-planning.js +2 -1
  135. package/src/gates/g3-implementation.js +2 -1
  136. package/src/gates/g4-qa-implementation.js +3 -2
  137. package/src/gates/g5-deploy-ready.js +2 -1
  138. package/src/health/engine.js +4 -3
  139. package/src/installer/core.js +557 -81
  140. package/src/installer/preflight.js +131 -0
  141. package/src/installer/provider-overlay.js +3 -3
  142. package/src/installer/scaffold-applier.js +358 -0
  143. package/src/installer/templates.js +52 -31
  144. package/src/installer/validator.js +17 -12
  145. package/src/intelligence/registry-manager.js +22 -29
  146. package/src/intelligence/timeline.js +11 -6
  147. package/src/license/commands.js +1 -1
  148. package/src/license/wait.js +102 -0
  149. package/src/memory/agent-memory.js +81 -0
  150. package/src/memory/dream.js +32 -1
  151. package/src/merger/replace-merger.js +28 -15
  152. package/src/orchestrator/agent-selector.js +2 -1
  153. package/src/orchestrator/cli.js +1908 -80
  154. package/src/orchestrator/doctor.js +270 -0
  155. package/src/orchestrator/handoff-engine.js +4 -3
  156. package/src/orchestrator/index.js +2 -0
  157. package/src/orchestrator/pipeline-manager.js +306 -15
  158. package/src/orchestrator/session-manager.js +331 -6
  159. package/src/tasks/handoff.js +3 -2
  160. package/src/telemetry/config.js +4 -3
  161. package/src/telemetry/schema.js +1 -0
  162. package/src/terminal/collector.js +3 -2
  163. package/src/terminal/index.js +1 -2
  164. package/src/terminal/isolation.js +52 -18
  165. package/src/terminal/prompt-builder.js +42 -25
  166. package/src/terminal/run-parallel.js +1 -1
  167. package/src/terminal/run-team.js +3 -3
  168. package/src/terminal/team-task-list.js +43 -4
  169. package/src/upgrade/backup.js +3 -2
  170. package/src/upgrade/checker.js +3 -2
  171. package/src/upgrade/migrator.js +65 -7
  172. package/src/upgrade/tracked-files-detector.js +86 -0
  173. package/src/upgrade/user-messages.js +94 -0
  174. package/src/utils/config-parser.js +2 -1
  175. package/src/utils/feature-flags.js +2 -1
  176. package/src/utils/flatten-entities.js +69 -0
  177. package/src/utils/framework-dir.js +16 -0
  178. package/src/utils/model-id.js +85 -0
  179. package/src/utils/provider-limits.js +84 -23
  180. package/src/utils/schema-validator.js +1 -1
  181. package/src/wizard/i18n.js +5 -4
  182. package/src/wizard/index.js +14 -0
  183. package/assets/logo - c/303/263pia.png +0 -0
  184. package/assets/logo.svg +0 -42
  185. package/assets/logo2.png +0 -0
  186. package/assets/social-preview.png +0 -0
  187. package/scripts/bundle-framework.js +0 -69
  188. package/scripts/changelog-generator.js +0 -222
  189. package/scripts/codebase-mapper.js +0 -728
  190. package/scripts/commit-message-generator.js +0 -167
  191. package/scripts/coverage-analyzer.js +0 -260
  192. package/scripts/dependency-analyzer.js +0 -280
  193. package/scripts/doctor/checks/agents.js +0 -77
  194. package/scripts/doctor/checks/constitution.js +0 -41
  195. package/scripts/doctor/checks/domain-alignment.js +0 -58
  196. package/scripts/doctor/checks/prism-layers.js +0 -84
  197. package/scripts/doctor/checks/registry.js +0 -55
  198. package/scripts/doctor/checks/schemas.js +0 -61
  199. package/scripts/doctor/fixes/reference-fix.js +0 -100
  200. package/scripts/doctor/fixes/registry-fix.js +0 -56
  201. package/scripts/doctor/index.js +0 -212
  202. package/scripts/framework-analyzer.js +0 -308
  203. package/scripts/generate-constitution-domain.js +0 -253
  204. package/scripts/generate-signing-key.js +0 -33
  205. package/scripts/health-check.js +0 -481
  206. package/scripts/ide-sync.js +0 -326
  207. package/scripts/performance-analyzer.js +0 -325
  208. package/scripts/plan-tracker.js +0 -278
  209. package/scripts/populate-entity-registry.js +0 -481
  210. package/scripts/pr-review.js +0 -317
  211. package/scripts/rollback-manager.js +0 -310
  212. package/scripts/semantic-lint.js +0 -328
  213. package/scripts/sign-manifest.js +0 -53
  214. package/scripts/stuck-detector.js +0 -343
  215. package/scripts/test-quality-assessment.js +0 -257
  216. package/scripts/validate-agents.js +0 -368
  217. package/scripts/validate-package.js +0 -367
  218. package/scripts/validate-tasks.js +0 -465
  219. package/src/autonomy/worktree-manager.js +0 -250
  220. package/src/intelligence/decision-engine.js +0 -256
  221. package/src/intelligence/document-sharder.js +0 -221
  222. package/src/intelligence/elicitation.js +0 -265
@@ -16,6 +16,10 @@
16
16
  {
17
17
  "type": "command",
18
18
  "command": "node chati.dev/hooks/model-governance.js"
19
+ },
20
+ {
21
+ "type": "command",
22
+ "command": "node chati.dev/hooks/reasoning-escalator.js"
19
23
  }
20
24
  ]
21
25
  }
@@ -31,6 +35,29 @@
31
35
  ]
32
36
  }
33
37
  ],
38
+ "PostToolUse": [
39
+ {
40
+ "matcher": "Write",
41
+ "hooks": [
42
+ {
43
+ "type": "command",
44
+ "command": "node chati.dev/hooks/advance-trigger.js"
45
+ },
46
+ {
47
+ "type": "command",
48
+ "command": "node chati.dev/hooks/reference-trigger.js"
49
+ },
50
+ {
51
+ "type": "command",
52
+ "command": "node chati.dev/hooks/brief-validator.js"
53
+ },
54
+ {
55
+ "type": "command",
56
+ "command": "node chati.dev/hooks/post-dev.js"
57
+ }
58
+ ]
59
+ }
60
+ ],
34
61
  "PreToolUse": [
35
62
  {
36
63
  "matcher": "Read",
@@ -42,7 +69,7 @@
42
69
  ]
43
70
  },
44
71
  {
45
- "matcher": "Write|Edit",
72
+ "matcher": "Write|Edit|NotebookEdit",
46
73
  "hooks": [
47
74
  {
48
75
  "type": "command",
@@ -63,6 +90,10 @@
63
90
  {
64
91
  "type": "command",
65
92
  "command": "node chati.dev/hooks/team-quality-gate.js"
93
+ },
94
+ {
95
+ "type": "command",
96
+ "command": "node chati.dev/hooks/reasoning-escalator.js"
66
97
  }
67
98
  ]
68
99
  },
@@ -6,7 +6,7 @@
6
6
  * - No em-dashes (U+2013 EN DASH, U+2014 EM DASH)
7
7
  * - No emojis in generated content
8
8
  *
9
- * Mode: Advisory (warn, not block). Agent receives warning and should self-correct.
9
+ * Mode: Em-dashes are HARD BLOCKED (deny). Emojis are advisory (warn).
10
10
  * Feature-flag gated: respects anti_dash and no_emojis in config.yaml.
11
11
  *
12
12
  * Exempt paths: framework files (chati.dev/, .chati/), YAML configs, CLAUDE.md
@@ -35,8 +35,9 @@ const EXEMPT_PATTERNS = [
35
35
  /AGENTS\.md$/,
36
36
  /\.yaml$/,
37
37
  /\.yml$/,
38
- /\.json$/,
39
38
  /package\.json$/,
39
+ /package-lock\.json$/,
40
+ /tsconfig\.json$/,
40
41
  /\.lock$/,
41
42
  ];
42
43
 
@@ -97,7 +98,7 @@ async function main() {
97
98
  // Skip exempt paths
98
99
  const filePath = toolInput.file_path || '';
99
100
  if (isExemptPath(filePath, projectDir)) {
100
- process.stdout.write(JSON.stringify({ decision: 'allow' }));
101
+ process.stdout.write(JSON.stringify(allowOutput()));
101
102
  return;
102
103
  }
103
104
 
@@ -111,25 +112,63 @@ async function main() {
111
112
  result = checkBashStyle(command);
112
113
  }
113
114
 
114
- if (result.violations.length > 0) {
115
- // Block all style violationsagent must rewrite
116
- process.stdout.write(JSON.stringify({
117
- decision: 'block',
118
- reason: `[Style Guard] ${result.violations.join(' ')} Rewrite without em-dashes and emojis.`,
119
- }));
115
+ if (result.hasDash) {
116
+ // Em-dashes are HARD BLOCKEDthey are never acceptable in project output.
117
+ // Use commas, semicolons, colons, or periods instead.
118
+ process.stdout.write(JSON.stringify(denyOutput(
119
+ `[Style Guard] Em-dash or en-dash detected. REWRITE without em-dashes. Use commas, semicolons, colons, or periods instead. This is non-negotiable.`
120
+ )));
120
121
  return;
121
122
  }
122
123
 
123
- process.stdout.write(JSON.stringify({ decision: 'allow' }));
124
+ if (result.hasEmoji) {
125
+ // Emojis are advisory — warn but allow
126
+ process.stdout.write(JSON.stringify(allowOutput(
127
+ `[Style Guard] Emoji detected. Consider using icons from approved libraries instead.`
128
+ )));
129
+ return;
130
+ }
131
+
132
+ process.stdout.write(JSON.stringify(allowOutput()));
124
133
  } catch (err) {
125
134
  process.stderr.write(`[chati] style-guard: ${err.message}\n`);
126
- process.stdout.write(JSON.stringify({ decision: 'allow' }));
135
+ process.stdout.write(JSON.stringify(allowOutput()));
127
136
  }
128
137
  }
129
138
 
139
+ function denyOutput(reason) {
140
+ return {
141
+ hookSpecificOutput: {
142
+ hookEventName: 'PreToolUse',
143
+ permissionDecision: 'deny',
144
+ permissionDecisionReason: reason,
145
+ },
146
+ };
147
+ }
148
+
149
+ function allowOutput(reason) {
150
+ const out = {
151
+ hookSpecificOutput: {
152
+ hookEventName: 'PreToolUse',
153
+ permissionDecision: 'allow',
154
+ },
155
+ };
156
+ if (reason) out.hookSpecificOutput.permissionDecisionReason = reason;
157
+ return out;
158
+ }
159
+
130
160
  export { checkStyle, checkBashStyle, isExemptPath, EM_DASH_PATTERN, EMOJI_PATTERN };
131
161
 
162
+ // Only run main when executed directly (not imported by tests).
163
+ // realpathSync resolves symlinks on both sides — important on macOS where
164
+ // /tmp is a symlink to /private/tmp. Without realpath the comparison fails
165
+ // silently and main() never runs.
132
166
  import { fileURLToPath } from 'url';
133
- if (process.argv[1] === fileURLToPath(import.meta.url)) {
134
- main();
167
+ import { realpathSync } from 'fs';
168
+ if (process.argv[1]) {
169
+ try {
170
+ if (realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))) {
171
+ main();
172
+ }
173
+ } catch { /* path resolution failed — not invoked as a script */ }
135
174
  }
@@ -19,18 +19,18 @@ import { join } from 'path';
19
19
  // Artifact scope per agent — defines which output paths each agent owns
20
20
  const AGENT_ARTIFACT_SCOPES = {
21
21
  detail: [
22
- 'chati.dev/artifacts/2-PRD/',
23
- 'chati.dev/artifacts/handoffs/detail-',
22
+ 'artifacts/2-PRD/',
23
+ 'artifacts/handoffs/detail-',
24
24
  'prd.md',
25
25
  ],
26
26
  architect: [
27
- 'chati.dev/artifacts/3-Architecture/',
28
- 'chati.dev/artifacts/handoffs/architect-',
27
+ 'artifacts/3-Architecture/',
28
+ 'artifacts/handoffs/architect-',
29
29
  'architecture.md',
30
30
  ],
31
31
  ux: [
32
- 'chati.dev/artifacts/4-UX/',
33
- 'chati.dev/artifacts/handoffs/ux-',
32
+ 'artifacts/4-UX/',
33
+ 'artifacts/handoffs/ux-',
34
34
  'ux-specification.md',
35
35
  'brandbook.md',
36
36
  'brandbook.html',
@@ -50,20 +50,27 @@ const AGENT_ARTIFACT_SCOPES = {
50
50
  'test/',
51
51
  'tests/',
52
52
  '__tests__/',
53
- 'chati.dev/artifacts/8-Implementation/',
54
- 'chati.dev/artifacts/handoffs/dev-',
53
+ 'artifacts/8-Implementation/',
54
+ 'artifacts/handoffs/dev-',
55
+ ],
56
+ 'qa-planning': [
57
+ 'artifacts/7-QA-Planning/',
58
+ 'artifacts/handoffs/qa-planning',
55
59
  ],
56
60
  'qa-implementation': [
57
- 'chati.dev/artifacts/9-QA-Implementation/',
58
- 'chati.dev/artifacts/handoffs/qa-implementation-',
61
+ 'artifacts/9-QA-Implementation/',
62
+ 'artifacts/handoffs/qa-implementation-',
63
+ ],
64
+ 'qa-visual': [
65
+ 'artifacts/handoffs/qa-visual',
59
66
  ],
60
67
  };
61
68
 
62
69
  // Shared paths any teammate can write to
63
70
  const SHARED_PATHS = [
64
71
  '.chati/',
65
- 'chati.dev/artifacts/handoffs/teams/',
66
- 'chati.dev/artifacts/decisions/',
72
+ 'artifacts/handoffs/teams/',
73
+ 'artifacts/decisions/',
67
74
  ];
68
75
 
69
76
  async function main() {
@@ -79,7 +86,7 @@ async function main() {
79
86
  // Quick exit: no team active → allow everything
80
87
  const teamId = process.env.CHATI_TEAM_ID;
81
88
  if (!teamId) {
82
- process.stdout.write(JSON.stringify({ result: 'allow' }));
89
+ process.stdout.write(JSON.stringify(allowOutput()));
83
90
  return;
84
91
  }
85
92
 
@@ -87,14 +94,14 @@ async function main() {
87
94
  const currentAgent = process.env.CHATI_TEAM_MEMBER || detectAgentFromSession(projectDir);
88
95
  if (!currentAgent) {
89
96
  // Cannot determine agent → allow (fail-open for safety)
90
- process.stdout.write(JSON.stringify({ result: 'allow' }));
97
+ process.stdout.write(JSON.stringify(allowOutput()));
91
98
  return;
92
99
  }
93
100
 
94
101
  // Get the file path being written
95
102
  const filePath = event.tool_input?.file_path || '';
96
103
  if (!filePath) {
97
- process.stdout.write(JSON.stringify({ result: 'allow' }));
104
+ process.stdout.write(JSON.stringify(allowOutput()));
98
105
  return;
99
106
  }
100
107
 
@@ -103,7 +110,7 @@ async function main() {
103
110
 
104
111
  // Check shared paths first — always allowed
105
112
  if (SHARED_PATHS.some(sp => relativePath.startsWith(sp))) {
106
- process.stdout.write(JSON.stringify({ result: 'allow' }));
113
+ process.stdout.write(JSON.stringify(allowOutput()));
107
114
  return;
108
115
  }
109
116
 
@@ -112,24 +119,42 @@ async function main() {
112
119
  if (agent === currentAgent) continue;
113
120
  for (const scope of scopes) {
114
121
  if (relativePath.startsWith(scope) || (!scope.includes('/') && relativePath.endsWith(scope))) {
115
- process.stdout.write(JSON.stringify({
116
- result: 'block',
117
- reason: `[Team Quality Gate] ${currentAgent} cannot write to ${relativePath} — this path belongs to ${agent}. Use the team mailbox to coordinate changes (Article XXI).`,
118
- }));
122
+ process.stdout.write(JSON.stringify(denyOutput(
123
+ `[Team Quality Gate] ${currentAgent} cannot write to ${relativePath} — this path belongs to ${agent}. Use the team mailbox to coordinate changes (Article XXI).`
124
+ )));
119
125
  return;
120
126
  }
121
127
  }
122
128
  }
123
129
 
124
130
  // Path not owned by anyone specific → allow
125
- process.stdout.write(JSON.stringify({ result: 'allow' }));
131
+ process.stdout.write(JSON.stringify(allowOutput()));
126
132
  } catch (err) {
127
133
  // Fail-open: hook errors should not block execution
128
134
  process.stderr.write(`[chati] team-quality-gate: ${err.message}\n`);
129
- process.stdout.write(JSON.stringify({ result: 'allow' }));
135
+ process.stdout.write(JSON.stringify(allowOutput()));
130
136
  }
131
137
  }
132
138
 
139
+ function allowOutput() {
140
+ return {
141
+ hookSpecificOutput: {
142
+ hookEventName: 'PreToolUse',
143
+ permissionDecision: 'allow',
144
+ },
145
+ };
146
+ }
147
+
148
+ function denyOutput(reason) {
149
+ return {
150
+ hookSpecificOutput: {
151
+ hookEventName: 'PreToolUse',
152
+ permissionDecision: 'deny',
153
+ permissionDecisionReason: reason,
154
+ },
155
+ };
156
+ }
157
+
133
158
  function detectAgentFromSession(projectDir) {
134
159
  const sessionPath = join(projectDir, '.chati', 'session.yaml');
135
160
  if (!existsSync(sessionPath)) return null;
@@ -138,8 +163,16 @@ function detectAgentFromSession(projectDir) {
138
163
  return match ? match[1].trim().replace(/^["']|["']$/g, '') : null;
139
164
  }
140
165
 
141
- // Only run main when executed directly
166
+ // Only run main when executed directly (not imported by tests).
167
+ // realpathSync resolves symlinks on both sides — important on macOS where
168
+ // /tmp is a symlink to /private/tmp. Without realpath the comparison fails
169
+ // silently and main() never runs.
142
170
  import { fileURLToPath } from 'url';
143
- if (process.argv[1] === fileURLToPath(import.meta.url)) {
144
- main();
171
+ import { realpathSync } from 'fs';
172
+ if (process.argv[1]) {
173
+ try {
174
+ if (realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))) {
175
+ main();
176
+ }
177
+ } catch { /* path resolution failed — not invoked as a script */ }
145
178
  }
@@ -13,7 +13,7 @@
13
13
  * What gets sanitized:
14
14
  * - Agent names (greenfield-wu, brownfield-wu, qa-planning, etc.)
15
15
  * - Pipeline terminology (PRISM, L0-L5, deviation protocol)
16
- * - Internal paths (chati.dev/artifacts/, .chati/)
16
+ * - Internal paths (artifacts/, .chati/)
17
17
  * - Framework name references in generated code/commits
18
18
  * - Constitution/Article references
19
19
  * - Quality gate internals (adversarial review, devil's advocate)
@@ -44,6 +44,7 @@ const UNDERCOVER_RULES = [
44
44
  { pattern: /\bbrownfield-wu\b/gi, replacement: 'codebase analysis', category: 'agent' },
45
45
  { pattern: /\bqa-planning\b/gi, replacement: 'planning review', category: 'agent' },
46
46
  { pattern: /\bqa-implementation\b/gi, replacement: 'code review', category: 'agent' },
47
+ { pattern: /\bqa-visual\b/gi, replacement: 'visual review', category: 'agent' },
47
48
  { pattern: /\bdevops agent\b/gi, replacement: 'deployment', category: 'agent' },
48
49
  { pattern: /\bdev agent\b/gi, replacement: 'implementation', category: 'agent' },
49
50
  { pattern: /\bbrief agent\b/gi, replacement: 'requirements analysis', category: 'agent' },
@@ -110,7 +111,8 @@ function isExemptPath(filePath, projectDir) {
110
111
  */
111
112
  function isUndercoverEnabled(projectDir) {
112
113
  try {
113
- const configPath = join(projectDir, 'chati.dev', 'config.yaml');
114
+ const fwDir = existsSync(join(projectDir, '.chati.dev')) ? '.chati.dev' : 'chati.dev';
115
+ const configPath = join(projectDir, fwDir, 'config.yaml');
114
116
  if (!existsSync(configPath)) return true;
115
117
  const raw = readFileSync(configPath, 'utf-8');
116
118
  const match = raw.match(/^\s*undercover_mode:\s*(false|no|off|0)/mi);
@@ -173,14 +175,14 @@ async function main() {
173
175
 
174
176
  // Check if undercover mode is enabled
175
177
  if (!isUndercoverEnabled(projectDir)) {
176
- process.stdout.write(JSON.stringify({ decision: 'allow' }));
178
+ process.stdout.write(JSON.stringify(allowOutput()));
177
179
  return;
178
180
  }
179
181
 
180
182
  // Skip framework-internal files
181
183
  const filePath = toolInput.file_path || '';
182
184
  if (isExemptPath(filePath, projectDir)) {
183
- process.stdout.write(JSON.stringify({ decision: 'allow' }));
185
+ process.stdout.write(JSON.stringify(allowOutput()));
184
186
  return;
185
187
  }
186
188
 
@@ -196,25 +198,44 @@ async function main() {
196
198
 
197
199
  if (scan.found) {
198
200
  const terms = scan.matches.map(m => `"${m.term}" → "${m.replacement}"`).join(', ');
199
- process.stdout.write(JSON.stringify({
200
- decision: 'allow', // Advisory — don't block, just warn
201
- reason: `[Undercover] Internal references detected in output: ${terms}. Please sanitize before shipping to production. Replace internal terms with their generic equivalents.`,
202
- }));
201
+ // Advisory only — surface findings as reason, allow operation.
202
+ process.stdout.write(JSON.stringify(allowOutput(
203
+ `[Undercover] Internal references detected: ${terms}. Sanitize before shipping. Replace internal terms with their generic equivalents.`
204
+ )));
203
205
  return;
204
206
  }
205
207
 
206
- process.stdout.write(JSON.stringify({ decision: 'allow' }));
208
+ process.stdout.write(JSON.stringify(allowOutput()));
207
209
  } catch (err) {
208
210
  process.stderr.write(`[chati-hook-error] undercover-guard: ${err?.message || 'unknown'}\n`);
209
211
  // Fail-open: undercover is advisory, not security-critical
210
- process.stdout.write(JSON.stringify({ decision: 'allow' }));
212
+ process.stdout.write(JSON.stringify(allowOutput()));
211
213
  }
212
214
  }
213
215
 
216
+ function allowOutput(reason) {
217
+ const out = {
218
+ hookSpecificOutput: {
219
+ hookEventName: 'PreToolUse',
220
+ permissionDecision: 'allow',
221
+ },
222
+ };
223
+ if (reason) out.hookSpecificOutput.permissionDecisionReason = reason;
224
+ return out;
225
+ }
226
+
214
227
  export { scanForInternals, scanBashForInternals, isExemptPath, isUndercoverEnabled, UNDERCOVER_RULES };
215
228
 
216
- // Only run main when executed directly (not imported by tests)
229
+ // Only run main when executed directly (not imported by tests).
230
+ // realpathSync resolves symlinks on both sides — important on macOS where
231
+ // /tmp is a symlink to /private/tmp. Without realpath the comparison fails
232
+ // silently and main() never runs.
217
233
  import { fileURLToPath } from 'url';
218
- if (process.argv[1] === fileURLToPath(import.meta.url)) {
219
- main();
234
+ import { realpathSync } from 'fs';
235
+ if (process.argv[1]) {
236
+ try {
237
+ if (realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))) {
238
+ main();
239
+ }
240
+ } catch { /* path resolution failed — not invoked as a script */ }
220
241
  }
@@ -31,7 +31,7 @@ installer:
31
31
  agents_count: "Agent definitions across DISCOVER, PLAN, BUILD, DEPLOY phases"
32
32
  workflows_count: "7 workflow blueprints"
33
33
  templates_count: "10 templates (PRD, Brownfield PRD, Architecture, Task, QA Gate, Quick Brief, Brandbook, Design Tokens, Component Spec, Icon System)"
34
- constitution: "Constitution (19 Articles + Preamble)"
34
+ constitution: "Constitution (23 Articles + Preamble)"
35
35
  session_mgmt: "Session management system"
36
36
  quality_gates: "Quality gates (3-tier verdicts)"
37
37
  proceed: "Proceed with installation?"
@@ -39,7 +39,7 @@ installer:
39
39
  created_chati: "Created .chati/ session directory"
40
40
  created_framework: "Created chati.dev/ system directory (agents, templates, workflows)"
41
41
  created_commands: "Created .claude/commands/ (thin router)"
42
- installed_constitution: "Installed Constitution (Articles I-XIX)"
42
+ installed_constitution: "Installed Constitution (Articles I-XXIII)"
43
43
  created_session: "Created session.yaml schema"
44
44
  created_claude_md: "Created CLAUDE.md"
45
45
  configured_mcps: "Configured MCPs:"
@@ -47,7 +47,7 @@ installer:
47
47
  agents_valid: "All agents implement 8 protocols"
48
48
  handoff_ok: "Handoff protocol: OK"
49
49
  validation_ok: "Self-validation criteria: OK"
50
- constitution_ok: "Constitution: 19 articles verified"
50
+ constitution_ok: "Constitution: 23 articles verified"
51
51
  created_memories: "Created .chati/memories/ (Memory Layer)"
52
52
  installed_intelligence: "Installed Intelligence Layer (Context Engine, Memory, Registry)"
53
53
  intelligence_valid: "Intelligence: 6 spec files verified"
@@ -31,7 +31,7 @@ installer:
31
31
  agents_count: "Definiciones de agentes en las fases DISCOVER, PLAN, BUILD, DEPLOY"
32
32
  workflows_count: "7 blueprints de workflow"
33
33
  templates_count: "10 templates (PRD, PRD Brownfield, Arquitectura, Task, QA Gate, Quick Brief, Brandbook, Design Tokens, Component Spec, Icon System)"
34
- constitution: "Constitucion (19 Articulos + Preambulo)"
34
+ constitution: "Constitucion (22 Articulos + Preambulo)"
35
35
  session_mgmt: "Sistema de gestion de sesion"
36
36
  quality_gates: "Quality gates (veredictos en 3 niveles)"
37
37
  proceed: "Proceder con la instalacion?"
@@ -39,7 +39,7 @@ installer:
39
39
  created_chati: "Creado directorio de sesion .chati/"
40
40
  created_framework: "Creado directorio del sistema chati.dev/ (agentes, templates, workflows)"
41
41
  created_commands: "Creado .claude/commands/ (enrutador)"
42
- installed_constitution: "Instalada Constitucion (Articulos I-XIX)"
42
+ installed_constitution: "Instalada Constitucion (Artículos I-XXIII)"
43
43
  created_session: "Creado schema session.yaml"
44
44
  created_claude_md: "Creado CLAUDE.md"
45
45
  configured_mcps: "MCPs configurados:"
@@ -47,7 +47,7 @@ installer:
47
47
  agents_valid: "Todos los agentes implementan 8 protocolos"
48
48
  handoff_ok: "Protocolo de handoff: OK"
49
49
  validation_ok: "Criterios de auto-validacion: OK"
50
- constitution_ok: "Constitucion: 19 articulos verificados"
50
+ constitution_ok: "Constitucion: 22 articulos verificados"
51
51
  created_memories: "Creado .chati/memories/ (Memory Layer)"
52
52
  installed_intelligence: "Instalada Intelligence Layer (Context Engine, Memory, Registry)"
53
53
  intelligence_valid: "Intelligence: 6 archivos de spec verificados"
@@ -31,7 +31,7 @@ installer:
31
31
  agents_count: "Definitions d'agents dans les phases DISCOVER, PLAN, BUILD, DEPLOY"
32
32
  workflows_count: "7 blueprints de workflow"
33
33
  templates_count: "10 templates (PRD, PRD Brownfield, Architecture, Task, QA Gate, Quick Brief, Brandbook, Design Tokens, Component Spec, Icon System)"
34
- constitution: "Constitution (19 Articles + Preambule)"
34
+ constitution: "Constitution (23 Articles + Preambule)"
35
35
  session_mgmt: "Systeme de gestion de session"
36
36
  quality_gates: "Quality gates (verdicts en 3 niveaux)"
37
37
  proceed: "Proceder a l'installation?"
@@ -39,7 +39,7 @@ installer:
39
39
  created_chati: "Cree le repertoire de session .chati/"
40
40
  created_framework: "Cree le repertoire du systeme chati.dev/ (agents, templates, workflows)"
41
41
  created_commands: "Cree .claude/commands/ (routeur)"
42
- installed_constitution: "Installee la Constitution (Articles I-XIX)"
42
+ installed_constitution: "Installee la Constitution (Articles I-XXIII)"
43
43
  created_session: "Cree le schema session.yaml"
44
44
  created_claude_md: "Cree CLAUDE.md"
45
45
  configured_mcps: "MCPs configures:"
@@ -47,7 +47,7 @@ installer:
47
47
  agents_valid: "Tous les agents implementent 8 protocoles"
48
48
  handoff_ok: "Protocole de passation: OK"
49
49
  validation_ok: "Criteres d'auto-validation: OK"
50
- constitution_ok: "Constitution: 19 articles verifies"
50
+ constitution_ok: "Constitution: 23 articles verifies"
51
51
  created_memories: "Cree .chati/memories/ (Memory Layer)"
52
52
  installed_intelligence: "Installee Intelligence Layer (Context Engine, Memory, Registry)"
53
53
  intelligence_valid: "Intelligence: 6 fichiers de spec verifies"
@@ -31,7 +31,7 @@ installer:
31
31
  agents_count: "Definicoes de agentes nas fases DISCOVER, PLAN, BUILD, DEPLOY"
32
32
  workflows_count: "7 blueprints de workflow"
33
33
  templates_count: "10 templates (PRD, PRD Brownfield, Arquitetura, Task, QA Gate, Quick Brief, Brandbook, Design Tokens, Component Spec, Icon System)"
34
- constitution: "Constituicao (19 Artigos + Preambulo)"
34
+ constitution: "Constituicao (22 Artigos + Preambulo)"
35
35
  session_mgmt: "Sistema de gerenciamento de sessao"
36
36
  quality_gates: "Quality gates (veredictos em 3 niveis)"
37
37
  proceed: "Prosseguir com a instalacao?"
@@ -39,7 +39,7 @@ installer:
39
39
  created_chati: "Criado diretorio de sessao .chati/"
40
40
  created_framework: "Criado diretorio do sistema chati.dev/ (agentes, templates, workflows)"
41
41
  created_commands: "Criado .claude/commands/ (roteador)"
42
- installed_constitution: "Instalada Constituicao (Artigos I-XIX)"
42
+ installed_constitution: "Instalada Constituicao (Artigos I-XXIII)"
43
43
  created_session: "Criado schema session.yaml"
44
44
  created_claude_md: "Criado CLAUDE.md"
45
45
  configured_mcps: "MCPs configurados:"
@@ -47,7 +47,7 @@ installer:
47
47
  agents_valid: "Todos os agentes implementam 8 protocolos"
48
48
  handoff_ok: "Protocolo de handoff: OK"
49
49
  validation_ok: "Criterios de auto-validacao: OK"
50
- constitution_ok: "Constituicao: 19 artigos verificados"
50
+ constitution_ok: "Constituicao: 22 artigos verificados"
51
51
  created_memories: "Criado .chati/memories/ (Memory Layer)"
52
52
  installed_intelligence: "Instalada Intelligence Layer (Context Engine, Memory, Registry)"
53
53
  intelligence_valid: "Intelligence: 6 arquivos de spec verificados"
@@ -33,7 +33,7 @@ The orchestrator injects context through 6 hierarchical layers:
33
33
 
34
34
  | Layer | Name | Source | When Active |
35
35
  |-------|------|--------|-------------|
36
- | **L0** | Constitution | `chati.dev/constitution.md` (Articles I-XIX) | ALWAYS (non-negotiable) |
36
+ | **L0** | Constitution | `chati.dev/constitution.md` (Articles I-XXIII) | ALWAYS (non-negotiable) |
37
37
  | **L1** | Mode + Global | `config.yaml` + mode governance (planning/build/deploy) | ALWAYS |
38
38
  | **L2** | Agent Scope | `chati.dev/agents/{agent}/` — mission, inputs, outputs, criteria | When agent is active |
39
39
  | **L3** | Pipeline State | `.chati/session.yaml` — pipeline position, scores, backlog | When session is active |
@@ -60,7 +60,7 @@ The orchestrator produces a structured XML block injected into agent prompts:
60
60
  ```xml
61
61
  <chati-context bracket="MODERATE">
62
62
  <constitution>
63
- Articles I-XIX governing agent behavior.
63
+ Articles I-XXIII governing agent behavior.
64
64
  Key: Self-validation required. Loop until quality threshold.
65
65
  Guided options (1,2,3). Persistent session state.
66
66
  Two-layer handoff. Language protocol. Deviation protocol.
@@ -77,8 +77,7 @@ The orchestrator produces a structured XML block injected into agent prompts:
77
77
  </agent>
78
78
 
79
79
  <pipeline>
80
- WU(100%) -> Brief(in_progress, 45%) -> Detail(pending) -> Architect(pending)
81
- -> UX(pending) -> Phases(pending) -> Tasks(pending) -> QA-Planning(pending)
80
+ WU(100%) -> Brief(in_progress, 45%) -> [Planning Team: Detail+Architect+UX+QA-Planning](pending) -> Phases(pending) -> Tasks(pending)
82
81
  </pipeline>
83
82
 
84
83
  <task>Phase 2: Core Requirements Elicitation</task>
@@ -186,7 +185,7 @@ Memory injection follows the same progressive reinforcement principle: as contex
186
185
 
187
186
  ---
188
187
 
189
- *Context Engine v4.0 — Chati.dev Intelligence Layer (Progressive Reinforcement Model)*
188
+ *Context Engine v4.3.0 — Chati.dev Intelligence Layer (Progressive Reinforcement Model)*
190
189
 
191
190
  ---
192
191
 
@@ -96,7 +96,7 @@ npx chati-dev health
96
96
  Checks:
97
97
  1. All registered entities exist on disk
98
98
  2. Schema files are valid JSON
99
- 3. Constitution has >= 19 articles
99
+ 3. Constitution has >= 23 articles
100
100
  4. Agents contain required protocol references
101
101
  5. Entity count matches actual file count
102
102
  6. Checksums match (if calculated)
@@ -16,7 +16,7 @@ Claude Code spawns each hook as a child process, waits for JSON output, then pro
16
16
  | PreCompact | `.*` | session-digest.js | Session state capture + auto-dream + daily digest |
17
17
  | PreToolUse | `Read` | read-protection.js | Block reading sensitive files |
18
18
  | PreToolUse | `Write\|Edit` | mode-governance.js | Write scope enforcement by phase |
19
- | PreToolUse | `Write\|Edit` | constitution-guard.js | Secret detection + 23 shell injection checks |
19
+ | PreToolUse | `Write\|Edit` | constitution-guard.js | Secret detection + 21 shell injection checks |
20
20
  | PreToolUse | `Write\|Edit` | undercover-guard.js | Sanitize framework terms from deliverables |
21
21
  | PreToolUse | `Write\|Edit` | style-guard.js | Em-dash and emoji enforcement |
22
22
  | PreToolUse | `Bash` | constitution-guard.js | Destructive command + shell injection checks |
@@ -31,7 +31,7 @@ Claude Code spawns each hook as a child process, waits for JSON output, then pro
31
31
  | PreCompact | 1 | ~50-200ms | Runs rarely (context compaction). Auto-dream may add 5-10s if triggered |
32
32
  | PreToolUse (Read) | 1 | ~30ms | Minimal overhead per file read |
33
33
  | PreToolUse (Write/Edit) | 4 | ~200ms | Heaviest path. 4 sequential hooks |
34
- | PreToolUse (Bash) | 3 | ~150ms | 23 regex checks in constitution-guard are negligible (<5ms) |
34
+ | PreToolUse (Bash) | 3 | ~150ms | 21 regex checks in constitution-guard are negligible (<5ms) |
35
35
 
36
36
  ## Performance Characteristics
37
37
 
@@ -42,7 +42,7 @@ Claude Code spawns each hook as a child process, waits for JSON output, then pro
42
42
 
43
43
  ## Optimization Notes
44
44
 
45
- 1. constitution-guard's 23 shell injection regex checks run in <5ms total (all patterns compiled once)
45
+ 1. constitution-guard's 21 shell injection regex checks run in <5ms total (all patterns compiled once)
46
46
  2. undercover-guard and style-guard could be skipped in discover/plan phases (no code being written)
47
47
  3. If latency becomes noticeable, consider merging undercover-guard + style-guard into one hook (same event, similar logic)
48
48
  4. license-guard has a 5-minute ping throttle to avoid network latency on every message
@@ -45,4 +45,4 @@ notes: |
45
45
  - Every migration is idempotent (safe to run multiple times)
46
46
  - Backup is created BEFORE any migration
47
47
  - Automatic rollback on failure
48
- - User artifacts (chati.dev/artifacts/, chati.dev/intelligence/) are NEVER modified
48
+ - User artifacts (artifacts/, chati.dev/intelligence/) are NEVER modified
@@ -34,17 +34,17 @@ operations:
34
34
  - .chati/checkpoints
35
35
  - .chati/decisions
36
36
  - chati.dev/data
37
- - chati.dev/artifacts/0-WU
38
- - chati.dev/artifacts/1-Brief
39
- - chati.dev/artifacts/2-PRD
40
- - chati.dev/artifacts/3-Architecture
41
- - chati.dev/artifacts/4-UX
42
- - chati.dev/artifacts/5-Phases
43
- - chati.dev/artifacts/6-Tasks
44
- - chati.dev/artifacts/7-QA-Planning
45
- - chati.dev/artifacts/8-QA-Impl
46
- - chati.dev/artifacts/9-Deploy
47
- - chati.dev/artifacts/handoffs
37
+ - artifacts/0-WU
38
+ - artifacts/1-Brief
39
+ - artifacts/2-PRD
40
+ - artifacts/3-Architecture
41
+ - artifacts/4-UX
42
+ - artifacts/5-Phases
43
+ - artifacts/6-Tasks
44
+ - artifacts/7-QA-Planning
45
+ - artifacts/8-QA-Impl
46
+ - artifacts/9-Deploy
47
+ - artifacts/handoffs
48
48
 
49
49
  # 2. Create agent memory directories
50
50
  - type: create_directory
@@ -17,8 +17,8 @@ preconditions:
17
17
  version: "4.0.0"
18
18
  message: "Requires chati.dev v4.0.0 or later"
19
19
  - type: constitution_articles
20
- count: 19
21
- message: "Requires Constitution with 19 Articles"
20
+ count: 22
21
+ message: "Requires Constitution with 22 Articles"
22
22
 
23
23
  backup:
24
24
  directories: