chati-dev 4.0.10 → 4.1.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.
- package/README.md +5 -0
- package/bin/chati.js +23 -2
- package/framework/agents/build/dev.md +43 -10
- package/framework/agents/discover/brief.md +38 -8
- package/framework/agents/discover/brownfield-wu.md +44 -3
- package/framework/agents/discover/greenfield-wu.md +14 -0
- package/framework/agents/plan/architect.md +6 -0
- package/framework/agents/plan/detail.md +25 -0
- package/framework/agents/plan/tasks.md +29 -1
- package/framework/agents/plan/ux-brand-architect.md +215 -0
- package/framework/agents/plan/ux-component-engineer.md +289 -0
- package/framework/agents/plan/ux-researcher.md +166 -0
- package/framework/agents/plan/ux.md +126 -1008
- package/framework/agents/quality/qa-implementation.md +121 -22
- package/framework/agents/quality/qa-planning.md +18 -0
- package/framework/config.yaml +15 -4
- package/framework/constitution.md +8 -2
- package/framework/context/root.md +1 -1
- package/framework/data/entity-registry.yaml +59 -3
- package/framework/hooks/constitution-guard.js +67 -1
- package/framework/hooks/license-guard.js +4 -4
- package/framework/hooks/model-governance.js +2 -1
- package/framework/hooks/prism-engine.js +74 -6
- package/framework/hooks/read-protection.js +1 -1
- package/framework/hooks/session-digest.js +159 -7
- package/framework/hooks/settings.json +16 -4
- package/framework/hooks/style-guard.js +134 -0
- package/framework/hooks/undercover-guard.js +220 -0
- package/framework/intelligence/context-engine.md +21 -0
- package/framework/intelligence/hooks-performance.md +54 -0
- package/framework/intelligence/memory-layer.md +47 -0
- package/framework/migrations/v4.0-to-v4.1.yaml +165 -0
- package/framework/orchestrator/chati.md +327 -1067
- package/framework/templates/brandbook-html-tmpl.md +107 -0
- package/framework/templates/session-memory-tmpl.yaml +68 -0
- package/package.json +1 -1
- package/src/autonomy/build-state.js +1 -1
- package/src/autonomy/worktree-manager.js +13 -13
- package/src/config/agent-customizer.js +1 -1
- package/src/config/gemini-hooks-generator.js +6 -6
- package/src/config/ide-configs.js +1 -1
- package/src/context/bracket-tracker.js +25 -4
- package/src/context/engine.js +37 -7
- package/src/context/formatter.js +45 -1
- package/src/context/index.js +3 -3
- package/src/dashboard/data-reader.js +7 -7
- package/src/decision/engine.js +2 -2
- package/src/decision/registry-healer.js +1 -1
- package/src/decision/registry-updater.js +2 -2
- package/src/extensions/loader.js +1 -1
- package/src/gates/g1-planning-complete.js +1 -1
- package/src/gates/g2-qa-planning.js +1 -1
- package/src/gates/g3-implementation.js +4 -4
- package/src/gates/g4-qa-implementation.js +2 -2
- package/src/health/auto-fix.js +3 -3
- package/src/health/engine.js +2 -2
- package/src/installer/brownfield-upgrader.js +3 -3
- package/src/installer/manifest.js +1 -1
- package/src/installer/transaction.js +1 -1
- package/src/installer/validator.js +2 -2
- package/src/intelligence/decision-engine.js +1 -1
- package/src/intelligence/memory-manager.js +1 -1
- package/src/intelligence/registry-manager.js +2 -2
- package/src/intelligence/timeline.js +1 -1
- package/src/license/client.js +20 -2
- package/src/license/commands.js +7 -7
- package/src/memory/agent-memory.js +3 -3
- package/src/memory/daily-digest.js +170 -0
- package/src/memory/dream.js +254 -0
- package/src/memory/gotchas.js +2 -2
- package/src/memory/index.js +18 -0
- package/src/memory/magic-docs.js +98 -0
- package/src/memory/memory-extractor.js +163 -0
- package/src/memory/session-digest.js +144 -6
- package/src/merger/yaml-merger.js +1 -1
- package/src/orchestrator/cli.js +980 -0
- package/src/orchestrator/handoff-engine.js +25 -4
- package/src/orchestrator/index.js +9 -0
- package/src/orchestrator/session-manager.js +1 -1
- package/src/preview/detector.js +3 -3
- package/src/preview/launcher.js +2 -2
- package/src/quality/metrics-collector.js +1 -1
- package/src/quality/test-runner.js +2 -4
- package/src/scanning/density-scanner.js +51 -0
- package/src/scanning/env-scanner.js +97 -0
- package/src/scanning/index.js +7 -0
- package/src/scanning/leakage-scanner.js +54 -0
- package/src/scanning/placeholder-scanner.js +40 -0
- package/src/scanning/security-scanner.js +94 -0
- package/src/security/bash-security.js +335 -0
- package/src/security/index.js +9 -0
- package/src/telemetry/config.js +3 -5
- package/src/telemetry/sender.js +19 -17
- package/src/terminal/cli-registry.js +1 -1
- package/src/terminal/cost-tracker.js +1 -2
- package/src/terminal/prompt-builder.js +11 -27
- package/src/terminal/rate-limiter.js +1 -2
- package/src/terminal/run-agent.js +3 -3
- package/src/terminal/spawner.js +41 -4
- package/src/upgrade/checker.js +2 -2
- package/src/upgrade/migrator.js +1 -1
- package/src/utils/config-parser.js +1 -1
- package/src/utils/file-lock.js +3 -3
- package/src/utils/provider-limits.js +35 -4
- package/src/wizard/i18n.js +2 -2
- package/src/wizard/index.js +2 -1
- package/src/wizard/questions.js +4 -2
|
@@ -78,9 +78,30 @@ Categories:
|
|
|
78
78
|
9. Prototype Pollution
|
|
79
79
|
10. Insecure Configuration
|
|
80
80
|
|
|
81
|
+
Language-Specific Patterns (scan for these exact patterns):
|
|
82
|
+
|
|
83
|
+
JavaScript/TypeScript:
|
|
84
|
+
- eval(), new Function(), setTimeout/setInterval with string arg: RCE risk
|
|
85
|
+
- innerHTML, outerHTML, document.write(): XSS risk
|
|
86
|
+
- dangerouslySetInnerHTML (React): XSS risk
|
|
87
|
+
- getElementById/querySelector without null check: runtime crash risk
|
|
88
|
+
- JSON.parse without try/catch: crash on malformed input
|
|
89
|
+
|
|
90
|
+
Python:
|
|
91
|
+
- eval(), exec(), compile(): RCE risk
|
|
92
|
+
- subprocess with shell=True: command injection
|
|
93
|
+
- pickle.loads from untrusted source: deserialization attack
|
|
94
|
+
- format strings with user input: injection
|
|
95
|
+
|
|
96
|
+
For ALL languages:
|
|
97
|
+
- Hardcoded secrets matching /api[_-]?key|secret|password|token.*[:=]\s*["'][^"']{8,}/i
|
|
98
|
+
- SQL with string interpolation (template literals, f-strings in queries)
|
|
99
|
+
- Missing input validation (direct req.body/req.params without validation)
|
|
100
|
+
- Insecure CORS (Access-Control-Allow-Origin: *)
|
|
101
|
+
|
|
81
102
|
Severity Classification:
|
|
82
|
-
- Critical: Immediate exploitation risk
|
|
83
|
-
- High: Exploitable with
|
|
103
|
+
- Critical: Immediate exploitation risk (eval, innerHTML, shell=True, hardcoded secrets)
|
|
104
|
+
- High: Exploitable with effort (null DOM, missing validation, insecure CORS)
|
|
84
105
|
- Medium: Potential risk, lower probability
|
|
85
106
|
- Low: Best practice improvement
|
|
86
107
|
|
|
@@ -101,6 +122,12 @@ Review code for:
|
|
|
101
122
|
6. Code duplication detection
|
|
102
123
|
7. Performance anti-patterns
|
|
103
124
|
8. Accessibility compliance
|
|
125
|
+
9. Client-side analysis (if project has frontend):
|
|
126
|
+
- DOM queries (getElementById, querySelector) have null checks
|
|
127
|
+
- Event listeners are cleaned up (removeEventListener on unmount)
|
|
128
|
+
- No memory leaks (intervals/timeouts cleared, subscriptions unsubscribed)
|
|
129
|
+
- Form validation exists on client side (not just server)
|
|
130
|
+
- Loading/error states handled (not just happy path)
|
|
104
131
|
|
|
105
132
|
If CodeRabbit MCP available:
|
|
106
133
|
- Run CodeRabbit review
|
|
@@ -120,23 +147,53 @@ For each completed task:
|
|
|
120
147
|
Flag unverified criteria for manual review
|
|
121
148
|
```
|
|
122
149
|
|
|
123
|
-
### Phase
|
|
150
|
+
### Phase 4b: Evidence Validation (by change type)
|
|
151
|
+
```
|
|
152
|
+
Validate that appropriate evidence exists for the type of change:
|
|
153
|
+
|
|
154
|
+
| Change Type | Required Evidence |
|
|
155
|
+
|-------------|-------------------|
|
|
156
|
+
| Bug fix | Before/after reproduction, root cause documented, regression test added |
|
|
157
|
+
| New feature | All acceptance criteria mapped to implementation, new tests cover feature |
|
|
158
|
+
| Refactor | No behavior change proof (same test results before/after), no new features |
|
|
159
|
+
| Performance | Benchmark data (before/after measurements with methodology) |
|
|
160
|
+
| Security fix | Vulnerability scan results, exploit reproduction steps |
|
|
161
|
+
| UI change | Visual comparison (screenshots or description of visual diff) |
|
|
162
|
+
|
|
163
|
+
If evidence is missing for the change type, flag as WARNING.
|
|
124
164
|
```
|
|
125
|
-
RULE: Every QA pass MUST identify minimum 5 findings.
|
|
126
|
-
Zero findings = suspiciously clean -> mandatory re-review.
|
|
127
165
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
166
|
+
### Phase 5: Triple Review Protocol (Mandatory)
|
|
167
|
+
```
|
|
168
|
+
Execute 3 review passes INDEPENDENTLY. Each pass has a different scope
|
|
169
|
+
and produces its own findings. Findings are merged at the end.
|
|
170
|
+
|
|
171
|
+
Pass 1 -- Shadow Review (zero-context adversarial):
|
|
172
|
+
Analyze ONLY the diff/changes. Do NOT read project context, architecture,
|
|
173
|
+
or acceptance criteria. Judge the code purely on its own merits:
|
|
174
|
+
- Does the code make sense in isolation?
|
|
175
|
+
- Are there obvious bugs, missing error handling, or logic flaws?
|
|
176
|
+
- Would a senior developer reject this in a PR review?
|
|
177
|
+
- Are there hardcoded values, magic numbers, or unclear naming?
|
|
178
|
+
|
|
179
|
+
Pass 2 -- Sentinel Review (edge case enumeration):
|
|
180
|
+
With full project access, enumerate ALL execution paths:
|
|
181
|
+
- What happens with null/undefined/empty inputs?
|
|
182
|
+
- What happens under concurrent access?
|
|
183
|
+
- What happens at scale (10x data, 100x users)?
|
|
184
|
+
- What happens when external services fail (timeout, 500, unreachable)?
|
|
185
|
+
- What happens with malformed/malicious input?
|
|
186
|
+
- Are there resource leaks (unclosed connections, streams, file handles)?
|
|
187
|
+
|
|
188
|
+
Pass 3 -- Compliance Review (spec alignment):
|
|
189
|
+
With spec + acceptance criteria + architecture:
|
|
190
|
+
- Does every Given-When-Then criterion have a matching implementation?
|
|
191
|
+
- Does the code follow architecture patterns from architecture.md?
|
|
192
|
+
- Are Design System tokens used (no hardcoded visual values)?
|
|
193
|
+
- Does the API contract match the spec?
|
|
194
|
+
- Are all component states implemented (not just happy path)?
|
|
195
|
+
|
|
196
|
+
After all 3 passes, execute the 5 Structural Checks:
|
|
140
197
|
|
|
141
198
|
Structural Checks (5 mandatory):
|
|
142
199
|
1. DEPENDENCY AUDIT: Scan for unused imports, circular dependencies,
|
|
@@ -154,8 +211,12 @@ Structural Checks (5 mandatory):
|
|
|
154
211
|
prototype pollution, ReDoS (regex denial of service), path traversal,
|
|
155
212
|
command injection via string interpolation, timing attacks.
|
|
156
213
|
|
|
214
|
+
Each check produces a classified finding (ERROR, WARNING, SUGGESTION, or ATTESTATION).
|
|
215
|
+
ATTESTATION documents WHY the check passed and what was verified. It is a quality
|
|
216
|
+
record proving thoroughness, not a padding finding.
|
|
217
|
+
|
|
157
218
|
Devil's Advocate Pass:
|
|
158
|
-
After
|
|
219
|
+
After the Triple Review concludes:
|
|
159
220
|
1. Assume the opposite: "This code has a hidden flaw"
|
|
160
221
|
2. Spend one focused pass actively seeking:
|
|
161
222
|
- Race conditions, memory leaks, unhandled edge cases
|
|
@@ -172,6 +233,41 @@ Findings Classification:
|
|
|
172
233
|
- ATTESTATION: Explicit documentation of why something is clean
|
|
173
234
|
```
|
|
174
235
|
|
|
236
|
+
### Phase 5b: Cross-File Consistency (Mandatory)
|
|
237
|
+
```
|
|
238
|
+
Check for inconsistencies ACROSS files (not just within code):
|
|
239
|
+
|
|
240
|
+
1. ENV SYNC: Compare .env.example against all env references in code
|
|
241
|
+
(process.env.X, import.meta.env.X). Flag missing or extra vars.
|
|
242
|
+
2. README ACCURACY: Verify that features described in README.md actually
|
|
243
|
+
exist in the codebase. Flag phantom features (documented but not implemented).
|
|
244
|
+
3. API CONTRACT: Compare error response format across ALL endpoints.
|
|
245
|
+
Flag inconsistent error shapes ({error: ...} vs {message: ...}).
|
|
246
|
+
4. CONFIG SYNC: Verify that config files (package.json scripts, tsconfig paths,
|
|
247
|
+
etc.) match actual file structure.
|
|
248
|
+
5. DEPENDENCY AUDIT: Check for unused dependencies in package.json and
|
|
249
|
+
missing dependencies (imported but not in package.json).
|
|
250
|
+
6. DOCUMENTATION SYNC: If API docs exist, verify endpoints match actual routes.
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Phase 5c: Causation Verification (for bug fixes)
|
|
254
|
+
```
|
|
255
|
+
If the implementation includes a bug fix, verify causation:
|
|
256
|
+
|
|
257
|
+
1. ROOT CAUSE: Is the fix addressing the root cause or just a symptom?
|
|
258
|
+
Ask: "If we remove this fix, does the original bug return?"
|
|
259
|
+
2. PLACEBO CHECK: Does the fix actually change the execution path
|
|
260
|
+
that causes the bug? Or is it a cosmetic change nearby?
|
|
261
|
+
3. COMPLETENESS: Does the fix handle ALL variations of the bug?
|
|
262
|
+
(different inputs, different timing, different environments)
|
|
263
|
+
4. REGRESSION: Could this fix break existing functionality?
|
|
264
|
+
Check: are there tests that cover the changed behavior?
|
|
265
|
+
5. ENVIRONMENT: Will this fix work in production? Or only in dev?
|
|
266
|
+
Check: hardcoded URLs, localhost references, debug flags.
|
|
267
|
+
|
|
268
|
+
If not a bug fix, skip this phase and document: "Not a bug fix -- causation verification N/A."
|
|
269
|
+
```
|
|
270
|
+
|
|
175
271
|
### Phase 6: Score & Decide
|
|
176
272
|
```
|
|
177
273
|
Calculate overall quality score:
|
|
@@ -382,13 +478,16 @@ Criteria (binary pass/fail):
|
|
|
382
478
|
4. Zero High security vulnerabilities
|
|
383
479
|
5. Code review completed (architecture adherence, patterns, error handling)
|
|
384
480
|
6. All acceptance criteria from tasks verified
|
|
385
|
-
7. Adversarial review completed with
|
|
481
|
+
7. Adversarial review completed: all 5 structural checks executed with classified outcomes
|
|
386
482
|
8. Devil's Advocate pass documented
|
|
387
483
|
9. Correction loops executed for all issues (or escalated with justification)
|
|
388
484
|
10. No skipped tests without documented reason
|
|
485
|
+
11. Triple Review Protocol completed (Shadow + Sentinel + Compliance passes)
|
|
486
|
+
12. Cross-file consistency checks completed (ENV, README, API, Config, Deps, Docs)
|
|
487
|
+
13. Evidence validation completed for change type (bug/feature/refactor/performance/security)
|
|
389
488
|
|
|
390
489
|
Score = criteria met / total criteria
|
|
391
|
-
Threshold: >= 95% (
|
|
490
|
+
Threshold: >= 95% (12/13 minimum)
|
|
392
491
|
```
|
|
393
492
|
|
|
394
493
|
---
|
|
@@ -410,7 +509,7 @@ Threshold: >= 95% (10/10 minimum, no criteria may fail)
|
|
|
410
509
|
| `sast-scan` | SAST Security Scan | Scan codebase for security vulnerabilities across 10 categories | After run-tests |
|
|
411
510
|
| `code-review` | Code Review | Review code for architecture adherence, patterns, error handling, Design System tokens | After sast-scan |
|
|
412
511
|
| `verify-criteria` | Verify Acceptance Criteria | Check each task's Given-When-Then criteria against implementation | After code-review |
|
|
413
|
-
| `adversarial` | Adversarial Review | Run mandatory
|
|
512
|
+
| `adversarial` | Adversarial Review | Run 5 mandatory structural checks + Devil's Advocate pass. Each check produces classified finding (ERROR/WARNING/SUGGESTION/ATTESTATION) | After verify-criteria |
|
|
414
513
|
| `score-decide` | Score and Decide | Calculate weighted quality score and issue APPROVED or NEEDS CORRECTION verdict | After adversarial |
|
|
415
514
|
|
|
416
515
|
---
|
|
@@ -453,7 +552,7 @@ Beyond self-validation (Protocol 5.1), the QA-Implementation agent enforces:
|
|
|
453
552
|
2. **Full Acceptance Coverage**: Every task's Given-When-Then criteria must be verified against the implementation — unverified criteria block approval
|
|
454
553
|
3. **Pattern Adherence**: Code must follow architecture patterns defined in the Architecture artifact — deviations must be justified
|
|
455
554
|
4. **Token Enforcement**: Design System tokens must be used — hardcoded visual values (colors, spacing, typography) reduce the score
|
|
456
|
-
5. **Adversarial Completeness**:
|
|
555
|
+
5. **Adversarial Completeness**: All 5 structural checks must be executed, each producing a classified finding (ERROR, WARNING, SUGGESTION, or ATTESTATION). Attestations document verified quality, not filler.
|
|
457
556
|
|
|
458
557
|
---
|
|
459
558
|
|
|
@@ -122,6 +122,24 @@ For each agent that completed PLANNING:
|
|
|
122
122
|
- Example: Brief said "Brief is well-written" (subjective, not binary)
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
+
### Step 3b: Dimensional Validation (6 quality dimensions)
|
|
126
|
+
```
|
|
127
|
+
Validate planning artifacts across 6 independent dimensions.
|
|
128
|
+
Each dimension produces PASS/FAIL with evidence.
|
|
129
|
+
|
|
130
|
+
| Dimension | What It Checks | FAIL Trigger |
|
|
131
|
+
|-----------|---------------|--------------|
|
|
132
|
+
| TRACEABILITY | Brief to PRD to Phases to Tasks chains complete | Any orphaned requirement |
|
|
133
|
+
| INFORMATION DENSITY | No filler phrases, padding, or LLM-generated fluff | "It is important to note", "Furthermore", "In conclusion", repetitive restatements |
|
|
134
|
+
| IMPLEMENTATION LEAKAGE | PRD says WHAT not HOW. No technology names in FRs | React, PostgreSQL, Tailwind, etc. found inside FR descriptions |
|
|
135
|
+
| MEASURABILITY | All success metrics and NFRs are quantifiable | "Fast", "responsive", "secure" without numeric thresholds |
|
|
136
|
+
| COMPLETENESS | All Brief categories covered, no gaps | Missing user personas, constraints, negative scope |
|
|
137
|
+
| SMART | Requirements are Specific, Measurable, Achievable, Relevant, Time-bound | Vague scope, unmeasurable criteria, unrealistic estimates |
|
|
138
|
+
|
|
139
|
+
Report as dimensional audit table in the QA report.
|
|
140
|
+
Apply penalties: -10 per FAIL dimension (in addition to existing per-item penalties).
|
|
141
|
+
```
|
|
142
|
+
|
|
125
143
|
### Step 4: Adversarial Review (Mandatory)
|
|
126
144
|
|
|
127
145
|
```
|
package/framework/config.yaml
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# chati.dev Configuration
|
|
2
|
-
version: "4.0
|
|
2
|
+
version: "4.1.0"
|
|
3
3
|
installed_at: "2026-02-07T10:00:00Z"
|
|
4
|
-
updated_at: "2026-
|
|
5
|
-
installer_version: "4.0
|
|
4
|
+
updated_at: "2026-04-02T00:00:00Z"
|
|
5
|
+
installer_version: "4.1.0"
|
|
6
6
|
project_type: greenfield
|
|
7
7
|
language: en
|
|
8
8
|
ides: [claude-code]
|
|
@@ -28,7 +28,7 @@ providers:
|
|
|
28
28
|
# provider: gemini
|
|
29
29
|
# model: pro
|
|
30
30
|
|
|
31
|
-
# Feature flags — toggle new capabilities (v4.0 Pegasus)
|
|
31
|
+
# Feature flags — toggle new capabilities (v4.0 Pegasus + Intelligence Upgrade)
|
|
32
32
|
features:
|
|
33
33
|
hybrid_budget: true
|
|
34
34
|
anti_dash: true
|
|
@@ -42,6 +42,17 @@ features:
|
|
|
42
42
|
tech_presets: true
|
|
43
43
|
doctor_autofix: true
|
|
44
44
|
brandbook: true
|
|
45
|
+
# Intelligence Upgrade (v4.0.5 — Claude Code patterns)
|
|
46
|
+
undercover_mode: true # Sanitize framework terms from deliverables
|
|
47
|
+
memory_extraction: true # Per-turn automatic memory capture
|
|
48
|
+
memory_consolidation: true # /chati dream — 4-phase memory consolidation
|
|
49
|
+
daily_digest: true # /chati digest — KAIROS Lite daily activity log
|
|
50
|
+
structured_session_memory: true # 8-section session digest with token budgets
|
|
51
|
+
static_prism_boundary: true # Static/Dynamic PRISM boundary for cache optimization
|
|
52
|
+
token_bracket_estimation: true # Token-based bracket estimation (replaces turn count)
|
|
53
|
+
model_fallback: true # Automatic opus→sonnet fallback on overload
|
|
54
|
+
frustration_detection: true # Detect user frustration and adapt response style
|
|
55
|
+
bash_security_checks: true # 23-point shell injection defense system
|
|
45
56
|
|
|
46
57
|
# Telemetry — opt-in anonymous usage tracking
|
|
47
58
|
telemetry:
|
|
@@ -322,6 +322,12 @@ The pipeline operates in three execution modes that control agent permissions. M
|
|
|
322
322
|
|
|
323
323
|
7. Memory attention scoring SHALL use natural decay — memories not accessed lose relevance organically. No memory is permanent unless explicitly marked as durable by the user.
|
|
324
324
|
|
|
325
|
+
8. The system SHALL support memory consolidation (`/chati dream`) to merge, deduplicate, and prune accumulated memories. Consolidation follows a 4-phase cycle (Orient, Gather, Consolidate, Prune) and archives removed entries rather than deleting them.
|
|
326
|
+
|
|
327
|
+
9. Per-turn memory extraction MAY capture decisions, resolutions, corrections, and validated patterns automatically from agent output. Extracted memories start at warm tier (confidence 0.5) and are promoted through evidence accumulation.
|
|
328
|
+
|
|
329
|
+
10. Daily activity digests (`/chati digest`) SHALL maintain append-only session logs for observability. Digests are cumulative per calendar day and include agent scores, decisions, and gotchas.
|
|
330
|
+
|
|
325
331
|
**Enforcement: BLOCK** — Auto-modification of user files is a critical violation.
|
|
326
332
|
|
|
327
333
|
---
|
|
@@ -461,7 +467,7 @@ When multiple CLI providers are enabled, the system SHALL coordinate agent execu
|
|
|
461
467
|
|
|
462
468
|
1. The CLI Provider Registry (`packages/chati-dev/src/terminal/cli-registry.js`) is the source of truth for provider capabilities: command syntax, model flags, stdin support, hook support, MCP support, and context file format.
|
|
463
469
|
|
|
464
|
-
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
|
|
470
|
+
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.
|
|
465
471
|
|
|
466
472
|
3. Provider availability SHALL be validated by the health check engine before spawning. If a configured provider is unavailable, the system SHALL fall back to the primary provider (claude) with a warning.
|
|
467
473
|
|
|
@@ -481,5 +487,5 @@ When multiple CLI providers are enabled, the system SHALL coordinate agent execu
|
|
|
481
487
|
|
|
482
488
|
---
|
|
483
489
|
|
|
484
|
-
*Chati.dev Constitution v4.0
|
|
490
|
+
*Chati.dev Constitution v4.1.0 — 19 Articles + Preamble*
|
|
485
491
|
*All agents are bound by this Constitution. Violations are enforced per article.*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Chati.dev System Context
|
|
2
2
|
|
|
3
3
|
## Framework
|
|
4
|
-
- **Version**: 4.
|
|
4
|
+
- **Version**: 4.1.0
|
|
5
5
|
- **Agents**: 13 (12 specialized + orchestrator)
|
|
6
6
|
- **Constitution**: 19 Articles + Preamble
|
|
7
7
|
- **Quality**: 5 pipeline gates + 3-tier verdicts (APPROVED / NEEDS_REVISION / BLOCKED)
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
# and by the Health Check for system integrity validation.
|
|
4
4
|
|
|
5
5
|
metadata:
|
|
6
|
-
version: "4.
|
|
7
|
-
last_updated: "2026-
|
|
8
|
-
entity_count:
|
|
6
|
+
version: "4.1.0"
|
|
7
|
+
last_updated: "2026-04-02T00:00:00Z"
|
|
8
|
+
entity_count: 62
|
|
9
9
|
checksum_algorithm: sha256
|
|
10
10
|
|
|
11
11
|
entities:
|
|
@@ -195,6 +195,14 @@ entities:
|
|
|
195
195
|
dependencies: [brandbook]
|
|
196
196
|
adaptability: 0.8
|
|
197
197
|
|
|
198
|
+
session-memory:
|
|
199
|
+
path: chati.dev/templates/session-memory-tmpl.yaml
|
|
200
|
+
type: template
|
|
201
|
+
purpose: "8-section structured digest template for session memory capture"
|
|
202
|
+
keywords: [memory, digest, session, structured, sections, budget]
|
|
203
|
+
dependencies: [constitution]
|
|
204
|
+
adaptability: 0.6
|
|
205
|
+
|
|
198
206
|
workflows:
|
|
199
207
|
greenfield-fullstack:
|
|
200
208
|
path: chati.dev/workflows/greenfield-fullstack.yaml
|
|
@@ -351,6 +359,54 @@ entities:
|
|
|
351
359
|
dependencies: []
|
|
352
360
|
adaptability: 0.7
|
|
353
361
|
|
|
362
|
+
memory-consolidation:
|
|
363
|
+
path: packages/chati-dev/src/memory/dream.js
|
|
364
|
+
type: module
|
|
365
|
+
purpose: "4-phase memory consolidation (Orient, Gather, Consolidate, Prune)"
|
|
366
|
+
keywords: [memory, consolidation, dream, deduplication, pruning, archive]
|
|
367
|
+
dependencies: [memory-layer]
|
|
368
|
+
adaptability: 0.3
|
|
369
|
+
|
|
370
|
+
memory-extraction:
|
|
371
|
+
path: packages/chati-dev/src/memory/memory-extractor.js
|
|
372
|
+
type: module
|
|
373
|
+
purpose: "Per-turn automatic memory extraction from agent output"
|
|
374
|
+
keywords: [memory, extraction, patterns, decisions, resolutions, corrections]
|
|
375
|
+
dependencies: [memory-layer]
|
|
376
|
+
adaptability: 0.4
|
|
377
|
+
|
|
378
|
+
daily-digest:
|
|
379
|
+
path: packages/chati-dev/src/memory/daily-digest.js
|
|
380
|
+
type: module
|
|
381
|
+
purpose: "KAIROS Lite daily activity digest with append-only entries"
|
|
382
|
+
keywords: [digest, daily, kairos, activity, summary, sessions]
|
|
383
|
+
dependencies: [memory-layer]
|
|
384
|
+
adaptability: 0.5
|
|
385
|
+
|
|
386
|
+
magic-docs:
|
|
387
|
+
path: packages/chati-dev/src/memory/magic-docs.js
|
|
388
|
+
type: module
|
|
389
|
+
purpose: "Auto-updating CLAUDE.md Current State section after handoffs"
|
|
390
|
+
keywords: [documentation, auto-update, claude-md, handoff, state]
|
|
391
|
+
dependencies: [constitution]
|
|
392
|
+
adaptability: 0.4
|
|
393
|
+
|
|
394
|
+
undercover-guard:
|
|
395
|
+
path: chati.dev/hooks/undercover-guard.js
|
|
396
|
+
type: hook
|
|
397
|
+
purpose: "Sanitize framework terminology from user-facing deliverables"
|
|
398
|
+
keywords: [security, sanitization, undercover, internal-terms, deliverables]
|
|
399
|
+
dependencies: [constitution]
|
|
400
|
+
adaptability: 0.2
|
|
401
|
+
|
|
402
|
+
bash-security:
|
|
403
|
+
path: packages/chati-dev/src/security/bash-security.js
|
|
404
|
+
type: module
|
|
405
|
+
purpose: "23-point shell injection defense system for bash commands"
|
|
406
|
+
keywords: [security, bash, injection, shell, defense, checks]
|
|
407
|
+
dependencies: [constitution]
|
|
408
|
+
adaptability: 0.1
|
|
409
|
+
|
|
354
410
|
quality-gates:
|
|
355
411
|
planning-gate:
|
|
356
412
|
path: chati.dev/quality-gates/planning-gate.md
|
|
@@ -99,6 +99,25 @@ async function main() {
|
|
|
99
99
|
}));
|
|
100
100
|
return;
|
|
101
101
|
}
|
|
102
|
+
|
|
103
|
+
// Run 23-point shell injection security checks
|
|
104
|
+
const injectionFindings = runShellInjectionChecks(command);
|
|
105
|
+
if (injectionFindings.length > 0) {
|
|
106
|
+
const critical = injectionFindings.filter(f => f.severity === 'critical');
|
|
107
|
+
if (critical.length > 0) {
|
|
108
|
+
process.stdout.write(JSON.stringify({
|
|
109
|
+
decision: 'block',
|
|
110
|
+
reason: `[Article IV] Shell injection risk detected (${critical.length} critical): ${critical.map(f => f.id).join(', ')}. Command: "${command.slice(0, 60)}..."`,
|
|
111
|
+
}));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
// High/medium findings: allow with warning (advisory)
|
|
115
|
+
process.stdout.write(JSON.stringify({
|
|
116
|
+
decision: 'allow',
|
|
117
|
+
reason: `[Security Advisory] ${injectionFindings.length} shell security finding(s): ${injectionFindings.map(f => f.id).join(', ')}`,
|
|
118
|
+
}));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
102
121
|
}
|
|
103
122
|
|
|
104
123
|
process.stdout.write(JSON.stringify({ decision: 'allow' }));
|
|
@@ -108,7 +127,54 @@ async function main() {
|
|
|
108
127
|
}
|
|
109
128
|
}
|
|
110
129
|
|
|
111
|
-
|
|
130
|
+
/**
|
|
131
|
+
* 23-point shell injection security checks.
|
|
132
|
+
* Inline implementation (hooks are standalone — no imports from src/).
|
|
133
|
+
* Based on Claude Code's bashSecurity.ts patterns.
|
|
134
|
+
*/
|
|
135
|
+
// SYNC: These 23 check IDs MUST match packages/chati-dev/src/security/bash-security.js
|
|
136
|
+
// Hooks are standalone (no imports from src/), so duplication is necessary.
|
|
137
|
+
// If you update here, update bash-security.js too. Run: npm test to verify both.
|
|
138
|
+
const SHELL_INJECTION_CHECKS = [
|
|
139
|
+
{ id: 'INCOMPLETE_COMMANDS', pattern: /[|&;]\s*$/, severity: 'high' },
|
|
140
|
+
{ id: 'JQ_SYSTEM_FUNCTION', pattern: /jq\b.*\bsystem\s*\(/i, severity: 'critical' },
|
|
141
|
+
{ id: 'JQ_FILE_ARGUMENTS', pattern: /jq\b.*--from-file|jq\b.*-f\s+[^|&;]+/i, severity: 'high' },
|
|
142
|
+
{ id: 'OBFUSCATED_FLAGS', pattern: /\$[({].*[)}].*-/, severity: 'high' },
|
|
143
|
+
{ id: 'SHELL_METACHARACTERS', pattern: /[`]|(?:\$\((?!.*\becho\b))/, severity: 'critical' },
|
|
144
|
+
{ id: 'DANGEROUS_VARIABLES', pattern: /(?:^|\s)(?:PATH|LD_PRELOAD|LD_LIBRARY_PATH|DYLD_INSERT_LIBRARIES|PYTHONPATH|NODE_PATH|RUBYLIB|PERL5LIB)\s*=/, severity: 'critical' },
|
|
145
|
+
{ id: 'NEWLINES', pattern: /(?<!\\)\n.*(?:rm|curl|wget|chmod|chown|sudo|eval|exec)/, severity: 'high' },
|
|
146
|
+
{ id: 'BACKSLASH_ESCAPED_WHITESPACE', pattern: /\\\s+(?:-|\/)/,severity: 'medium' },
|
|
147
|
+
// eslint-disable-next-line no-control-regex
|
|
148
|
+
{ id: 'CONTROL_CHARACTERS', pattern: /[\x00-\x08\x0e-\x1f\x7f]/, severity: 'critical' },
|
|
149
|
+
{ id: 'UNICODE_WHITESPACE', pattern: /[\u200B-\u200F\u2028-\u202F\uFEFF\u00A0\u2060\u180E]/, severity: 'critical' },
|
|
150
|
+
{ id: 'DANGEROUS_PATTERNS_COMMAND_SUBSTITUTION', pattern: /\$\(.*(?:curl|wget|nc|bash|sh|python|perl|ruby|node)\b/i, severity: 'critical' },
|
|
151
|
+
{ id: 'DANGEROUS_PATTERNS_INPUT_REDIRECTION', pattern: /<\s*(?:\/etc\/(?:passwd|shadow|sudoers)|\/proc\/|~\/\.ssh\/|~\/\.aws\/)/, severity: 'critical' },
|
|
152
|
+
{ id: 'DANGEROUS_PATTERNS_OUTPUT_REDIRECTION', pattern: />\s*(?:\/etc\/|~\/\.ssh\/|~\/\.bashrc|~\/\.zshrc|~\/\.profile|~\/\.gitconfig)/, severity: 'critical' },
|
|
153
|
+
{ id: 'IFS_INJECTION', pattern: /\bIFS\s*=/, severity: 'critical' },
|
|
154
|
+
{ id: 'BRACE_EXPANSION', pattern: /\{.*(?:rm|curl|wget|chmod|eval|exec|sudo).*[,}]/, severity: 'high' },
|
|
155
|
+
{ id: 'GIT_COMMIT_SUBSTITUTION', pattern: /git\s+(?:commit|push|tag).*\$[({]/, severity: 'high' },
|
|
156
|
+
{ id: 'PROC_ENVIRON_ACCESS', pattern: /\/proc\/(?:self|\d+)\/(?:environ|cmdline|maps|mem)/, severity: 'critical' },
|
|
157
|
+
{ id: 'MALFORMED_TOKEN_INJECTION', pattern: /\\x[0-9a-f]{2}|\\u[0-9a-f]{4}|\\[0-7]{3}/i, severity: 'high' },
|
|
158
|
+
{ id: 'MID_WORD_HASH', pattern: /\w#\w/, severity: 'medium' },
|
|
159
|
+
{ id: 'COMMENT_QUOTE_DESYNC', pattern: /#.*['"][^'"]*$/, severity: 'medium' },
|
|
160
|
+
{ id: 'QUOTED_NEWLINE', pattern: /["'][^"']*\n[^"']*["']/, severity: 'high' },
|
|
161
|
+
{ id: 'ZSH_DANGEROUS_COMMANDS', pattern: /\b(?:zmodload|sysopen|sysread|syswrite|zsystem|zselect|ztcp)\b/, severity: 'critical' },
|
|
162
|
+
{ id: 'BACKSLASH_ESCAPED_OPERATORS', pattern: /\\[|;&]/, severity: 'medium' },
|
|
163
|
+
];
|
|
164
|
+
|
|
165
|
+
function runShellInjectionChecks(command) {
|
|
166
|
+
if (!command || typeof command !== 'string') return [];
|
|
167
|
+
const findings = [];
|
|
168
|
+
for (const check of SHELL_INJECTION_CHECKS) {
|
|
169
|
+
check.pattern.lastIndex = 0;
|
|
170
|
+
if (check.pattern.test(command)) {
|
|
171
|
+
findings.push({ id: check.id, severity: check.severity });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return findings;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export { containsSecrets, isDestructiveCommand, runShellInjectionChecks, SECRET_PATTERNS, DESTRUCTIVE_COMMANDS, SHELL_INJECTION_CHECKS };
|
|
112
178
|
|
|
113
179
|
// Only run main when executed directly (not imported by tests)
|
|
114
180
|
import { fileURLToPath } from 'url';
|
|
@@ -89,11 +89,11 @@ async function main() {
|
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
91
|
block(buildMessage(data.status, data.reason));
|
|
92
|
-
} catch {
|
|
93
|
-
allow();
|
|
92
|
+
} catch { /* expected: API may be unreachable — fail open */
|
|
93
|
+
allow();
|
|
94
94
|
}
|
|
95
|
-
} catch {
|
|
96
|
-
allow();
|
|
95
|
+
} catch { /* expected: stdin parse may fail — fail open */
|
|
96
|
+
allow();
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
@@ -88,7 +88,8 @@ async function main() {
|
|
|
88
88
|
} else {
|
|
89
89
|
process.stdout.write(JSON.stringify({ result: 'allow' }));
|
|
90
90
|
}
|
|
91
|
-
} catch {
|
|
91
|
+
} catch (err) {
|
|
92
|
+
process.stderr.write(`[chati] model-governance: ${err.message}\n`);
|
|
92
93
|
process.stdout.write(JSON.stringify({ result: 'allow' }));
|
|
93
94
|
}
|
|
94
95
|
}
|
|
@@ -32,6 +32,7 @@ function readSessionState(projectDir) {
|
|
|
32
32
|
workflow: extract('workflow') || null,
|
|
33
33
|
pipelinePosition: extract('pipeline_position') || null,
|
|
34
34
|
turnCount: parseInt(extract('turn_count') || '0', 10),
|
|
35
|
+
provider: extract('provider') || 'claude',
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -56,9 +57,39 @@ async function main() {
|
|
|
56
57
|
return;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
// Estimate remaining context
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
// Estimate remaining context — prefer token-based estimation over turn count
|
|
61
|
+
// Token estimation: 1 token ≈ 4 characters (Claude Code pattern)
|
|
62
|
+
// SYNC: These limits MUST match packages/chati-dev/src/utils/provider-limits.js
|
|
63
|
+
const HOOK_MODEL_LIMITS = { opus: 1_000_000, sonnet: 200_000, haiku: 200_000, pro: 1_000_000, flash: 1_000_000, codex: 128_000 };
|
|
64
|
+
const HOOK_PROVIDER_LIMITS = { claude: 200_000, gemini: 1_000_000, codex: 128_000 };
|
|
65
|
+
|
|
66
|
+
// Infer model from current agent via AGENT_MODELS map
|
|
67
|
+
const HOOK_AGENT_MODELS = {
|
|
68
|
+
orchestrator: 'sonnet', 'greenfield-wu': 'haiku', 'brownfield-wu': 'opus',
|
|
69
|
+
brief: 'sonnet', detail: 'opus', architect: 'opus', ux: 'sonnet',
|
|
70
|
+
phases: 'sonnet', tasks: 'sonnet', 'qa-planning': 'opus',
|
|
71
|
+
'qa-implementation': 'opus', dev: 'opus', devops: 'sonnet',
|
|
72
|
+
};
|
|
73
|
+
const inferredModel = session.currentAgent ? HOOK_AGENT_MODELS[session.currentAgent] : null;
|
|
74
|
+
|
|
75
|
+
// Resolve context limit: model > provider > default
|
|
76
|
+
function hookResolveLimit(model, provider) {
|
|
77
|
+
if (model && HOOK_MODEL_LIMITS[model]) return HOOK_MODEL_LIMITS[model];
|
|
78
|
+
if (provider && HOOK_PROVIDER_LIMITS[provider]) return HOOK_PROVIDER_LIMITS[provider];
|
|
79
|
+
return 200_000;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let remainingPercent;
|
|
83
|
+
const promptText = event.prompt || '';
|
|
84
|
+
if (promptText.length > 0) {
|
|
85
|
+
const estimatedTokens = Math.ceil(promptText.length / 4);
|
|
86
|
+
const contextLimit = hookResolveLimit(inferredModel, session.provider);
|
|
87
|
+
remainingPercent = Math.max(0, Math.round((1 - estimatedTokens / contextLimit) * 100));
|
|
88
|
+
} else {
|
|
89
|
+
// Fallback to turn-count heuristic when prompt text unavailable
|
|
90
|
+
const maxTurns = 40;
|
|
91
|
+
remainingPercent = Math.max(0, Math.round((1 - session.turnCount / maxTurns) * 100));
|
|
92
|
+
}
|
|
62
93
|
|
|
63
94
|
// Determine bracket
|
|
64
95
|
let bracket = 'FRESH';
|
|
@@ -79,6 +110,15 @@ async function main() {
|
|
|
79
110
|
}
|
|
80
111
|
}
|
|
81
112
|
|
|
113
|
+
// Frustration detection — adapt response style when user is frustrated
|
|
114
|
+
const frustrationDetected = detectFrustration(promptText);
|
|
115
|
+
|
|
116
|
+
// Microcompact advisory — hint to economize context when depleted + idle
|
|
117
|
+
let microcompactAdvisory = '';
|
|
118
|
+
if ((bracket === 'DEPLETED' || bracket === 'CRITICAL') && session.turnCount > 10) {
|
|
119
|
+
microcompactAdvisory = ' <advisory priority="medium">Context constrained. Avoid re-reading files already in context. Summarize stale outputs before proceeding.</advisory>';
|
|
120
|
+
}
|
|
121
|
+
|
|
82
122
|
// Build minimal context block (full PRISM pipeline is used by orchestrator internally)
|
|
83
123
|
const contextBlock = [
|
|
84
124
|
`<chati-context bracket="${bracket}">`,
|
|
@@ -87,6 +127,8 @@ async function main() {
|
|
|
87
127
|
session.pipelinePosition ? ` <pipeline-position>${session.pipelinePosition}</pipeline-position>` : '',
|
|
88
128
|
memoryBlock,
|
|
89
129
|
bracket === 'CRITICAL' ? ' <advisory>Context running low. Consider handoff or summary.</advisory>' : '',
|
|
130
|
+
microcompactAdvisory,
|
|
131
|
+
frustrationDetected ? ' <advisory priority="high">User shows signs of frustration. Be more direct, acknowledge the issue explicitly, focus on the solution, avoid repeating previous suggestions.</advisory>' : '',
|
|
90
132
|
'</chati-context>',
|
|
91
133
|
].filter(Boolean).join('\n');
|
|
92
134
|
|
|
@@ -94,13 +136,39 @@ async function main() {
|
|
|
94
136
|
result: 'allow',
|
|
95
137
|
prefix: contextBlock,
|
|
96
138
|
}));
|
|
97
|
-
} catch {
|
|
98
|
-
|
|
139
|
+
} catch (err) {
|
|
140
|
+
process.stderr.write(`[chati] prism-engine: ${err.message}\n`);
|
|
99
141
|
process.stdout.write(JSON.stringify({ result: 'allow' }));
|
|
100
142
|
}
|
|
101
143
|
}
|
|
102
144
|
|
|
103
|
-
|
|
145
|
+
/**
|
|
146
|
+
* Frustration detection patterns.
|
|
147
|
+
* Inspired by Claude Code's regex-based emotion detection.
|
|
148
|
+
* Soft advisory only — never blocks or overrides behavior.
|
|
149
|
+
*/
|
|
150
|
+
const FRUSTRATION_PATTERNS = [
|
|
151
|
+
/this (is|isn't|isnt) working/i,
|
|
152
|
+
/I (already|just) (told|said|asked)/i,
|
|
153
|
+
/why (won't|doesn't|can't|isn't|wont|doesnt|cant|isnt)/i,
|
|
154
|
+
/stop (doing|repeating|ignoring)/i,
|
|
155
|
+
/you('re| are) (not|never) (listening|reading|understanding)/i,
|
|
156
|
+
/for the (second|third|fourth|last) time/i,
|
|
157
|
+
/!!+/,
|
|
158
|
+
/\b(WTF|WHAT THE|FFS|OMG)\b/i,
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Detect user frustration from prompt text.
|
|
163
|
+
* @param {string} prompt - User prompt text
|
|
164
|
+
* @returns {boolean} True if frustration patterns detected
|
|
165
|
+
*/
|
|
166
|
+
function detectFrustration(prompt) {
|
|
167
|
+
if (!prompt || prompt.length < 5) return false;
|
|
168
|
+
return FRUSTRATION_PATTERNS.some(p => p.test(prompt));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export { readSessionState, detectFrustration };
|
|
104
172
|
|
|
105
173
|
// Only run main when executed directly (not imported by tests)
|
|
106
174
|
import { fileURLToPath } from 'url';
|