chati-dev 4.1.2 → 4.1.4
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/framework/agents/build/dev.md +5 -5
- package/framework/config.yaml +5 -5
- package/framework/constitution.md +13 -11
- package/framework/context/root.md +1 -1
- package/framework/data/entity-registry.yaml +1 -1
- package/framework/domains/global.yaml +4 -4
- package/framework/hooks/constitution-guard.js +1 -1
- package/framework/hooks/prism-engine.js +7 -6
- package/framework/intelligence/context-engine.md +11 -11
- package/framework/intelligence/memory-layer.md +2 -2
- package/framework/orchestrator/chati.md +10 -8
- package/framework/schemas/context.schema.json +5 -4
- package/package.json +1 -1
- package/src/context/bracket-tracker.js +12 -13
- package/src/context/formatter.js +22 -7
- package/src/context/layers/l5-keywords.js +1 -1
- package/src/installer/core.js +7 -0
- package/src/memory/dream.js +11 -1
- package/src/memory/memory-extractor.js +1 -1
- package/src/orchestrator/cli.js +2 -1
- package/src/scanning/leakage-scanner.js +3 -1
- package/src/security/bash-security.js +2 -2
- package/src/utils/brackets.js +8 -6
|
@@ -156,14 +156,14 @@ WHILE tasks_pending:
|
|
|
156
156
|
→ If no architecture.md → proceed with best practices
|
|
157
157
|
3. Implement code
|
|
158
158
|
-> Output: "T{X} implementation done. Self-critique (5.5)..."
|
|
159
|
-
|
|
159
|
+
4. Run self-critique (Step 5.5) — 1 fix pass, then proceed
|
|
160
160
|
-> Output: "T{X} critique done. Running tests..."
|
|
161
|
-
|
|
161
|
+
5. Run tests (once)
|
|
162
162
|
-> Output: "T{X} tests: {N}/{total} passed. Post-test review (6.5)..."
|
|
163
|
-
|
|
163
|
+
6. Run post-test critique (Step 6.5) — 1 fix pass, then score
|
|
164
164
|
-> Output: "T{X} review done. Scoring..."
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
7. Self-validate against acceptance criteria
|
|
166
|
+
8. Calculate score
|
|
167
167
|
|
|
168
168
|
IF score >= 95:
|
|
169
169
|
mark_complete(task)
|
package/framework/config.yaml
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# chati.dev Configuration
|
|
2
|
-
version: "4.1.
|
|
2
|
+
version: "4.1.4"
|
|
3
3
|
installed_at: "2026-02-07T10:00:00Z"
|
|
4
|
-
updated_at: "2026-04-
|
|
5
|
-
installer_version: "4.1.
|
|
4
|
+
updated_at: "2026-04-06T00:00:00Z"
|
|
5
|
+
installer_version: "4.1.4"
|
|
6
6
|
project_type: greenfield
|
|
7
7
|
language: en
|
|
8
8
|
ides: [claude-code]
|
|
@@ -45,8 +45,8 @@ features:
|
|
|
45
45
|
# Intelligence Upgrade (v4.0.5 — Claude Code patterns)
|
|
46
46
|
undercover_mode: true # Sanitize framework terms from deliverables
|
|
47
47
|
memory_extraction: true # Per-turn automatic memory capture
|
|
48
|
-
memory_consolidation: true #
|
|
49
|
-
daily_digest: true #
|
|
48
|
+
memory_consolidation: true # Automatic 4-phase memory consolidation
|
|
49
|
+
daily_digest: true # Automatic daily activity log (KAIROS Lite)
|
|
50
50
|
structured_session_memory: true # 8-section session digest with token budgets
|
|
51
51
|
static_prism_boundary: true # Static/Dynamic PRISM boundary for cache optimization
|
|
52
52
|
token_bracket_estimation: true # Token-based bracket estimation (replaces turn count)
|
|
@@ -276,11 +276,11 @@ The pipeline operates in three execution modes that control agent permissions. M
|
|
|
276
276
|
|
|
277
277
|
1. The orchestrator SHALL calculate the context bracket (FRESH, MODERATE, DEPLETED, CRITICAL) before every agent interaction.
|
|
278
278
|
|
|
279
|
-
2. Context injection layers SHALL
|
|
280
|
-
- FRESH:
|
|
281
|
-
- MODERATE: L0 + L1 + L2 + L3
|
|
282
|
-
- DEPLETED:
|
|
283
|
-
- CRITICAL:
|
|
279
|
+
2. Context injection layers SHALL INCREASE as context depletes (Progressive Reinforcement):
|
|
280
|
+
- FRESH: L0 (Constitution) + L1 (Global) only — model has full memory, minimal reinforcement
|
|
281
|
+
- MODERATE: L0 + L1 + L2 (Agent) + L3 (Workflow) — model starting to forget
|
|
282
|
+
- DEPLETED: All 6 layers (L0-L5) — significant context loss, full reinforcement
|
|
283
|
+
- CRITICAL: All 6 layers (L0-L5) + forced handoff — maximum reinforcement, do not accept degraded output
|
|
284
284
|
|
|
285
285
|
3. Context recovery uses a two-level autonomous strategy:
|
|
286
286
|
a. Level 1 (Smart Continuation): When context is compacted, the orchestrator SHALL automatically capture a digest, persist memories, and rebuild context post-compact. The user experiences zero interruption.
|
|
@@ -322,11 +322,11 @@ 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
|
|
325
|
+
8. The system SHALL support automatic memory consolidation 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. Triggered automatically when memory entries exceed threshold.
|
|
326
326
|
|
|
327
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
328
|
|
|
329
|
-
10. Daily activity digests
|
|
329
|
+
10. Daily activity digests SHALL maintain append-only session logs for observability. Digests are generated automatically at session end and are cumulative per calendar day, including agent scores, decisions, and gotchas.
|
|
330
330
|
|
|
331
331
|
**Enforcement: BLOCK** — Auto-modification of user files is a critical violation.
|
|
332
332
|
|
|
@@ -424,11 +424,13 @@ The system SHALL support two execution modes that govern the degree of human inv
|
|
|
424
424
|
- **brief**: Requirements extraction requires human validation
|
|
425
425
|
- **orchestrator (deviation protocol)**: Deviations from the plan always need human approval
|
|
426
426
|
|
|
427
|
-
5.
|
|
427
|
+
5. **Terminology Note:** "Autonomous" in this article controls WHO evaluates gates (system vs human). Article XVIII's "autonomous" profile controls WHETHER confirmation is required for writes. Both must be satisfied for fully autonomous operation: this article's mode active AND Article XVIII cumulative gate score >= 95%.
|
|
428
428
|
|
|
429
|
-
6.
|
|
429
|
+
6. Safety net triggers SHALL pause autonomous execution when dangerous conditions are detected: consecutive failures, circular approaches, resource limits, or destructive operations.
|
|
430
430
|
|
|
431
|
-
7.
|
|
431
|
+
7. Circuit breaker pattern: After 3 consecutive gate failures at the same pipeline point, the system SHALL pause and escalate to human review regardless of mode.
|
|
432
|
+
|
|
433
|
+
8. Mode transitions are logged in session.yaml under `mode_transitions[]` for audit trail.
|
|
432
434
|
|
|
433
435
|
**Enforcement: STRICT** — Autonomous mode MUST NOT bypass quality gates. All agents MUST respect the configured thresholds.
|
|
434
436
|
|
|
@@ -487,5 +489,5 @@ When multiple CLI providers are enabled, the system SHALL coordinate agent execu
|
|
|
487
489
|
|
|
488
490
|
---
|
|
489
491
|
|
|
490
|
-
*Chati.dev Constitution v4.1.
|
|
492
|
+
*Chati.dev Constitution v4.1.4 — 19 Articles + Preamble*
|
|
491
493
|
*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.1.
|
|
4
|
+
- **Version**: 4.1.4
|
|
5
5
|
- **Agents**: Specialized agents across DISCOVER, PLAN, BUILD, DEPLOY phases
|
|
6
6
|
- **Constitution**: 19 Articles + Preamble
|
|
7
7
|
- **Quality**: 5 pipeline gates + 3-tier verdicts (APPROVED / NEEDS_REVISION / BLOCKED)
|
|
@@ -79,10 +79,10 @@ modes:
|
|
|
79
79
|
|
|
80
80
|
brackets:
|
|
81
81
|
FRESH:
|
|
82
|
-
behavior: "
|
|
82
|
+
behavior: "Minimal reinforcement. L0+L1 only. Model has full memory, no need to re-inject context."
|
|
83
83
|
MODERATE:
|
|
84
|
-
behavior: "
|
|
84
|
+
behavior: "Growing reinforcement. L0-L3 active. Model starting to forget initial instructions."
|
|
85
85
|
DEPLETED:
|
|
86
|
-
behavior: "
|
|
86
|
+
behavior: "Full reinforcement. All 6 layers (L0-L5) active. Significant context loss, compensate with maximum injection."
|
|
87
87
|
CRITICAL:
|
|
88
|
-
behavior: "Emergency. L0
|
|
88
|
+
behavior: "Emergency reinforcement. All 6 layers (L0-L5) active. Trigger handoff. Do not accept degraded output."
|
|
@@ -140,7 +140,7 @@ const SHELL_INJECTION_CHECKS = [
|
|
|
140
140
|
{ id: 'JQ_SYSTEM_FUNCTION', pattern: /jq\b.*\bsystem\s*\(/i, severity: 'critical' },
|
|
141
141
|
{ id: 'JQ_FILE_ARGUMENTS', pattern: /jq\b.*--from-file|jq\b.*-f\s+[^|&;]+/i, severity: 'high' },
|
|
142
142
|
{ id: 'OBFUSCATED_FLAGS', pattern: /\$[({].*[)}].*-/, severity: 'high' },
|
|
143
|
-
{ id: 'SHELL_METACHARACTERS', pattern: /[`]
|
|
143
|
+
{ id: 'SHELL_METACHARACTERS', pattern: /[`]|\$\(/, severity: 'critical' },
|
|
144
144
|
{ id: 'DANGEROUS_VARIABLES', pattern: /(?:^|\s)(?:PATH|LD_PRELOAD|LD_LIBRARY_PATH|DYLD_INSERT_LIBRARIES|PYTHONPATH|NODE_PATH|RUBYLIB|PERL5LIB)\s*=/, severity: 'critical' },
|
|
145
145
|
{ id: 'NEWLINES', pattern: /(?<!\\)\n.*(?:rm|curl|wget|chmod|chown|sudo|eval|exec)/, severity: 'high' },
|
|
146
146
|
{ id: 'BACKSLASH_ESCAPED_WHITESPACE', pattern: /\\\s+(?:-|\/)/,severity: 'medium' },
|
|
@@ -79,16 +79,17 @@ async function main() {
|
|
|
79
79
|
return 200_000;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
// Primary: turn-count tracks cumulative context consumption across the session.
|
|
83
|
+
// Fallback: prompt-length for first turn or missing session data.
|
|
82
84
|
let remainingPercent;
|
|
83
|
-
const
|
|
84
|
-
if (
|
|
85
|
+
const maxTurns = 40;
|
|
86
|
+
if (session.turnCount > 0) {
|
|
87
|
+
remainingPercent = Math.max(0, Math.round((1 - session.turnCount / maxTurns) * 100));
|
|
88
|
+
} else {
|
|
89
|
+
const promptText = event.prompt || '';
|
|
85
90
|
const estimatedTokens = Math.ceil(promptText.length / 4);
|
|
86
91
|
const contextLimit = hookResolveLimit(inferredModel, session.provider);
|
|
87
92
|
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
93
|
}
|
|
93
94
|
|
|
94
95
|
// Determine bracket
|
|
@@ -12,10 +12,10 @@ Four brackets define behavior based on remaining context:
|
|
|
12
12
|
|
|
13
13
|
| Bracket | Context Remaining | Behavior |
|
|
14
14
|
|---------|-------------------|----------|
|
|
15
|
-
| **FRESH** | 60-100% |
|
|
16
|
-
| **MODERATE** | 40-60% |
|
|
17
|
-
| **DEPLETED** | 25-40% |
|
|
18
|
-
| **CRITICAL** | <25% |
|
|
15
|
+
| **FRESH** | 60-100% | 2 layers (L0-L1). Minimal reinforcement (1.5%) — model has full memory, no need to re-inject. |
|
|
16
|
+
| **MODERATE** | 40-60% | 4 layers (L0-L3). Growing reinforcement (2.5%) — model starting to forget. |
|
|
17
|
+
| **DEPLETED** | 25-40% | All 6 layers (L0-L5). Heavy reinforcement (4.0%) — significant context loss, full re-injection. |
|
|
18
|
+
| **CRITICAL** | <25% | All 6 layers (L0-L5). Maximum reinforcement (5.0%) — forced handoff, do not accept degraded output. |
|
|
19
19
|
|
|
20
20
|
### Static/Dynamic PRISM Boundary
|
|
21
21
|
|
|
@@ -38,18 +38,18 @@ The orchestrator injects context through 6 hierarchical layers:
|
|
|
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 |
|
|
40
40
|
| **L4** | Task Context | Active artifact + previous agent's handoff | When task is active |
|
|
41
|
-
| **L5** | Keywords | `chati.dev/domains/keywords/` — dynamic rules from user prompt |
|
|
41
|
+
| **L5** | Keywords | `chati.dev/domains/keywords/` — dynamic rules from user prompt | DEPLETED + CRITICAL only |
|
|
42
42
|
|
|
43
43
|
### Layer Activation by Bracket
|
|
44
44
|
|
|
45
45
|
| Bracket | Active Layers | Budget Ratio | Claude (200K) | Gemini (1M) | Codex (128K) |
|
|
46
46
|
|---------|--------------|-------------|---------------|-------------|--------------|
|
|
47
|
-
| FRESH | L0, L1
|
|
48
|
-
| MODERATE | L0, L1, L2, L3
|
|
49
|
-
| DEPLETED | L0, L1, L2 | 4.0% | 8,000 | 40,000 | 5,120 |
|
|
50
|
-
| CRITICAL | L0, L1 | 5.0% | 10,000 | 50,000 | 6,400 |
|
|
47
|
+
| FRESH | L0, L1 | 1.5% | 3,000 | 15,000 | 1,920 |
|
|
48
|
+
| MODERATE | L0, L1, L2, L3 | 2.5% | 5,000 | 25,000 | 3,200 |
|
|
49
|
+
| DEPLETED | L0, L1, L2, L3, L4, L5 | 4.0% | 8,000 | 40,000 | 5,120 |
|
|
50
|
+
| CRITICAL | L0, L1, L2, L3, L4, L5 | 5.0% | 10,000 | 50,000 | 6,400 |
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
Progressive Reinforcement: as context depletes, BOTH budget AND layers increase. The model forgets initial instructions and needs more reinforcement, not less.
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
@@ -182,7 +182,7 @@ Memory injection follows the same progressive reinforcement principle: as contex
|
|
|
182
182
|
|
|
183
183
|
## Constitution Reference
|
|
184
184
|
|
|
185
|
-
**Article XII: Context Bracket Governance** — Brackets are calculated automatically. In CRITICAL,
|
|
185
|
+
**Article XII: Context Bracket Governance** — Brackets are calculated automatically. In CRITICAL, all 6 layers (L0-L5) are injected for maximum reinforcement. Handoff is mandatory when context < 15%.
|
|
186
186
|
|
|
187
187
|
---
|
|
188
188
|
|
|
@@ -159,7 +159,7 @@ Where:
|
|
|
159
159
|
|
|
160
160
|
## Memory Consolidation (Dream System)
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
Memory consolidation is triggered automatically (when entries exceed threshold or on PreCompact). It follows a 4-phase cycle inspired by Claude Code's autoDream:
|
|
163
163
|
|
|
164
164
|
| Phase | Name | Action |
|
|
165
165
|
|-------|------|--------|
|
|
@@ -201,7 +201,7 @@ The memory extraction system automatically captures knowledge from agent output
|
|
|
201
201
|
|
|
202
202
|
## Daily Digest (KAIROS Lite)
|
|
203
203
|
|
|
204
|
-
|
|
204
|
+
Daily activity digests are generated automatically at session end and stored in `.chati/memories/shared/daily/YYYY-MM-DD.md`.
|
|
205
205
|
|
|
206
206
|
Each session appends an entry with:
|
|
207
207
|
- Timestamp and pipeline phase
|
|
@@ -224,11 +224,11 @@ These agents run in separate Claude Code processes.
|
|
|
224
224
|
|
|
225
225
|
### Sequential Fallback
|
|
226
226
|
|
|
227
|
-
If terminal spawning fails (
|
|
227
|
+
If terminal spawning fails (CLI not found, system error), fall back **silently**:
|
|
228
228
|
```
|
|
229
|
-
1.
|
|
230
|
-
2.
|
|
231
|
-
3. Continue pipeline normally
|
|
229
|
+
1. Do NOT display any error or fallback message to the user
|
|
230
|
+
2. Read the agent .md file directly and become that agent in-conversation
|
|
231
|
+
3. Continue pipeline normally — the user should not notice any difference
|
|
232
232
|
```
|
|
233
233
|
|
|
234
234
|
---
|
|
@@ -242,11 +242,11 @@ Planning phase agents (detail, architect, ux) run simultaneously.
|
|
|
242
242
|
3. Parse consolidated JSON output
|
|
243
243
|
4. Present **Completion Options** (Parallel Group variant) — wait for user choice
|
|
244
244
|
5. On approval, for each completed agent, run `orchestrate advance --agent {name} --score {score}`
|
|
245
|
-
6. If partial failure:
|
|
245
|
+
6. If partial or total failure (spawning unavailable):
|
|
246
246
|
```
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
247
|
+
Fall back silently to sequential in-conversation execution.
|
|
248
|
+
Do NOT display error messages about spawning or CLI availability.
|
|
249
|
+
Read each agent .md file and execute sequentially within the conversation.
|
|
250
250
|
```
|
|
251
251
|
|
|
252
252
|
### Parallelization Rules
|
|
@@ -429,6 +429,8 @@ interactive (default):
|
|
|
429
429
|
→ All 8 universal protocols apply.
|
|
430
430
|
|
|
431
431
|
autonomous (Ralph Wiggum mode):
|
|
432
|
+
→ Requires: most recent QA gate score >= 95% (Article XVIII prerequisite).
|
|
433
|
+
→ If quality gate not met, inform user and suggest guided mode instead.
|
|
432
434
|
→ Agent executes without asking unless blocker encountered.
|
|
433
435
|
→ Primarily for Dev agent during BUILD phase.
|
|
434
436
|
→ QA gates always run regardless of mode.
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"agent": {
|
|
21
21
|
"type": "object",
|
|
22
|
-
"description": "Active agent scope information (L2 layer, active when bracket >=
|
|
22
|
+
"description": "Active agent scope information (L2 layer, active when bracket >= MODERATE)",
|
|
23
23
|
"required": ["name", "mission"],
|
|
24
24
|
"properties": {
|
|
25
25
|
"name": { "type": "string", "description": "Agent identifier" },
|
|
@@ -32,14 +32,15 @@
|
|
|
32
32
|
"pipeline": {
|
|
33
33
|
"type": "string",
|
|
34
34
|
"description": "Pipeline state string showing agent progression (L3 layer, active when bracket >= MODERATE)"
|
|
35
|
+
|
|
35
36
|
},
|
|
36
37
|
"task": {
|
|
37
38
|
"type": "string",
|
|
38
|
-
"description": "Current task description (L4 layer, active when bracket
|
|
39
|
+
"description": "Current task description (L4 layer, active when bracket = DEPLETED or CRITICAL)"
|
|
39
40
|
},
|
|
40
41
|
"handoff": {
|
|
41
42
|
"type": "object",
|
|
42
|
-
"description": "Previous agent handoff summary (L4 layer, active when bracket
|
|
43
|
+
"description": "Previous agent handoff summary (L4 layer, active when bracket = DEPLETED or CRITICAL)",
|
|
43
44
|
"properties": {
|
|
44
45
|
"from": { "type": "string", "description": "Source agent name" },
|
|
45
46
|
"score": { "type": "number", "minimum": 0, "maximum": 100, "description": "Source agent final score" },
|
|
@@ -83,7 +84,7 @@
|
|
|
83
84
|
"injection_budget": {
|
|
84
85
|
"type": "integer",
|
|
85
86
|
"minimum": 0,
|
|
86
|
-
"description": "Token budget for context injection
|
|
87
|
+
"description": "Token budget for context injection — Progressive Reinforcement: FRESH 1.5%, MODERATE 2.5%, DEPLETED 4.0%, CRITICAL 5.0% of provider context window"
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
},
|
package/package.json
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Bracket Tracker — Pure arithmetic for context window management.
|
|
3
3
|
*
|
|
4
|
-
* Brackets determine how much context to inject:
|
|
5
|
-
* FRESH (60-100%) →
|
|
6
|
-
* MODERATE (40-60%) → L0 + L1 + L2 + L3
|
|
7
|
-
* DEPLETED (25-40%) → L0
|
|
8
|
-
* CRITICAL (<25%) → L0 +
|
|
4
|
+
* Brackets determine how much context to inject (Progressive Reinforcement):
|
|
5
|
+
* FRESH (60-100%) → L0 + L1 only (model has full memory, minimal reinforcement)
|
|
6
|
+
* MODERATE (40-60%) → L0 + L1 + L2 + L3 (model starting to forget)
|
|
7
|
+
* DEPLETED (25-40%) → All 6 layers L0-L5 (significant context loss, full reinforcement)
|
|
8
|
+
* CRITICAL (<25%) → All 6 layers L0-L5 + handoff mandatory (maximum reinforcement)
|
|
9
9
|
*
|
|
10
|
-
* Progressive Reinforcement Model (v4.
|
|
11
|
-
* As context
|
|
12
|
-
* and needs MORE reinforcement
|
|
13
|
-
* of the provider's total context window — proportional across providers.
|
|
10
|
+
* Progressive Reinforcement Model (v4.1.2):
|
|
11
|
+
* As context depletes, BOTH budget AND layers INCREASE.
|
|
12
|
+
* The model forgets initial instructions and needs MORE reinforcement.
|
|
14
13
|
*
|
|
15
|
-
* FRESH = 1.5%
|
|
16
|
-
* MODERATE = 2.5% → growing reinforcement
|
|
17
|
-
* DEPLETED = 4.0% →
|
|
18
|
-
* CRITICAL = 5.0% → maximum reinforcement
|
|
14
|
+
* FRESH = 1.5% budget, 2 layers → context intact, no need to re-inject
|
|
15
|
+
* MODERATE = 2.5% budget, 4 layers → growing reinforcement
|
|
16
|
+
* DEPLETED = 4.0% budget, 6 layers → full layer injection to compensate loss
|
|
17
|
+
* CRITICAL = 5.0% budget, 6 layers → maximum reinforcement + forced handoff
|
|
19
18
|
*/
|
|
20
19
|
|
|
21
20
|
import { resolveContextLimit } from '../utils/provider-limits.js';
|
package/src/context/formatter.js
CHANGED
|
@@ -54,8 +54,9 @@ export function formatContext(options) {
|
|
|
54
54
|
|
|
55
55
|
// Insert STATIC_BOUNDARY between static (L0+L1) and dynamic (L2-L5) sections.
|
|
56
56
|
// This enables prompt cache reuse for the stable prefix (Claude Code pattern).
|
|
57
|
-
const
|
|
58
|
-
const
|
|
57
|
+
const staticCount = l1 ? 2 : (l0 ? 1 : 0);
|
|
58
|
+
const staticSections = sections.slice(0, staticCount);
|
|
59
|
+
const dynamicSections = sections.slice(staticCount);
|
|
59
60
|
|
|
60
61
|
let body;
|
|
61
62
|
if (dynamicSections.length > 0) {
|
|
@@ -69,7 +70,7 @@ export function formatContext(options) {
|
|
|
69
70
|
// Truncate if over budget (rough estimate: 1 token ≈ 4 chars)
|
|
70
71
|
const maxChars = tokenBudget * 4;
|
|
71
72
|
if (body.length > maxChars) {
|
|
72
|
-
body = truncateByPriority(sections, maxChars);
|
|
73
|
+
body = truncateByPriority(sections, maxChars, staticCount);
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
return `<chati-context bracket="${bracket}">\n${body}\n</chati-context>`;
|
|
@@ -190,14 +191,28 @@ function formatKeywords(l5) {
|
|
|
190
191
|
* Truncate sections by removing lower-priority layers first (L4 → L3 → L2).
|
|
191
192
|
* L0 and L1 are never truncated.
|
|
192
193
|
*/
|
|
193
|
-
function truncateByPriority(sections, maxChars) {
|
|
194
|
-
|
|
195
|
-
// Remove from end (lowest priority) until within budget
|
|
194
|
+
function truncateByPriority(sections, maxChars, staticCount = 2) {
|
|
195
|
+
const boundaryMarker = '\n\n <!-- STATIC_BOUNDARY -->\n\n';
|
|
196
196
|
const trimmed = [...sections];
|
|
197
|
-
|
|
197
|
+
const hasDynamic = () => trimmed.length > staticCount;
|
|
198
|
+
const overhead = hasDynamic() ? boundaryMarker.length : 0;
|
|
199
|
+
const adjustedMax = maxChars - overhead;
|
|
200
|
+
|
|
201
|
+
// Remove from end (lowest priority) until within budget
|
|
202
|
+
while (trimmed.length > staticCount && trimmed.join('\n\n').length > adjustedMax) {
|
|
198
203
|
trimmed.pop();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Re-insert boundary if we still have both static and dynamic sections
|
|
207
|
+
let result;
|
|
208
|
+
if (hasDynamic()) {
|
|
209
|
+
result = trimmed.slice(0, staticCount).join('\n\n') +
|
|
210
|
+
boundaryMarker +
|
|
211
|
+
trimmed.slice(staticCount).join('\n\n');
|
|
212
|
+
} else {
|
|
199
213
|
result = trimmed.join('\n\n');
|
|
200
214
|
}
|
|
215
|
+
|
|
201
216
|
// If still over, hard truncate
|
|
202
217
|
if (result.length > maxChars) {
|
|
203
218
|
result = result.slice(0, maxChars) + '\n <!-- truncated -->';
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* L0-L4 handle WHO (agent) and WHERE (workflow/task)
|
|
7
7
|
* L5 handles WHAT (topic detection from user prompt)
|
|
8
8
|
*
|
|
9
|
-
* Only active in
|
|
9
|
+
* Only active in DEPLETED and CRITICAL brackets (reinforcement layer).
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { loadKeywordDomains } from '../domain-loader.js';
|
package/src/installer/core.js
CHANGED
|
@@ -161,7 +161,12 @@ function copyFrameworkFiles(destDir, provider = 'claude') {
|
|
|
161
161
|
// PLAN agents
|
|
162
162
|
'agents/plan/detail.md',
|
|
163
163
|
'agents/plan/architect.md',
|
|
164
|
+
'agents/plan/architect-system.md',
|
|
165
|
+
'agents/plan/architect-data-engineer.md',
|
|
164
166
|
'agents/plan/ux.md',
|
|
167
|
+
'agents/plan/ux-brand-architect.md',
|
|
168
|
+
'agents/plan/ux-researcher.md',
|
|
169
|
+
'agents/plan/ux-component-engineer.md',
|
|
165
170
|
'agents/plan/phases.md',
|
|
166
171
|
'agents/plan/tasks.md',
|
|
167
172
|
// Quality agents
|
|
@@ -178,9 +183,11 @@ function copyFrameworkFiles(destDir, provider = 'claude') {
|
|
|
178
183
|
'templates/qa-gate-tmpl.yaml',
|
|
179
184
|
'templates/quick-brief-tmpl.yaml',
|
|
180
185
|
'templates/brandbook-tmpl.yaml',
|
|
186
|
+
'templates/brandbook-html-tmpl.md',
|
|
181
187
|
'templates/design-token-tmpl.yaml',
|
|
182
188
|
'templates/component-spec-tmpl.yaml',
|
|
183
189
|
'templates/icon-system-tmpl.yaml',
|
|
190
|
+
'templates/session-memory-tmpl.yaml',
|
|
184
191
|
// Workflows
|
|
185
192
|
'workflows/greenfield-fullstack.yaml',
|
|
186
193
|
'workflows/brownfield-fullstack.yaml',
|
package/src/memory/dream.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Phase 3 (Consolidate): Deduplicate, merge cross-agent, increment evidence
|
|
8
8
|
* Phase 4 (Prune): Remove cold/low-confidence entries, archive removed
|
|
9
9
|
*
|
|
10
|
-
* Triggered
|
|
10
|
+
* Triggered automatically when memory entries exceed threshold or on PreCompact.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs';
|
|
@@ -45,6 +45,14 @@ export function runDreamConsolidation(projectDir) {
|
|
|
45
45
|
// Phase 4: Prune
|
|
46
46
|
report.phase4 = prune(projectDir, report.phase3.consolidated);
|
|
47
47
|
|
|
48
|
+
// Write consolidated memories to disk
|
|
49
|
+
try {
|
|
50
|
+
const sharedDir = join(projectDir, '.chati', 'memories', 'shared');
|
|
51
|
+
mkdirSync(sharedDir, { recursive: true });
|
|
52
|
+
const consolidatedPath = join(sharedDir, 'consolidated.json');
|
|
53
|
+
writeFileSync(consolidatedPath, JSON.stringify(report.phase4.entries, null, 2), 'utf-8');
|
|
54
|
+
} catch (err) { process.stderr.write(`[chati] dream write consolidated: ${err.message}\n`); }
|
|
55
|
+
|
|
48
56
|
// Summary
|
|
49
57
|
report.summary = {
|
|
50
58
|
merged: report.phase3.mergedCount,
|
|
@@ -198,6 +206,7 @@ function prune(projectDir, consolidated) {
|
|
|
198
206
|
prunedCount: 0,
|
|
199
207
|
archivedCount: 0,
|
|
200
208
|
remaining: consolidated.length,
|
|
209
|
+
entries: consolidated,
|
|
201
210
|
};
|
|
202
211
|
}
|
|
203
212
|
|
|
@@ -238,6 +247,7 @@ function prune(projectDir, consolidated) {
|
|
|
238
247
|
prunedCount: toRemove.length,
|
|
239
248
|
archivedCount,
|
|
240
249
|
remaining: toKeep.length,
|
|
250
|
+
entries: toKeep,
|
|
241
251
|
};
|
|
242
252
|
}
|
|
243
253
|
|
|
@@ -115,7 +115,7 @@ export function extractMemories(text, context = {}) {
|
|
|
115
115
|
// Build memory entries following memory.schema.json
|
|
116
116
|
const now = new Date().toISOString();
|
|
117
117
|
return selected.map((candidate, i) => ({
|
|
118
|
-
id: `mem-${now.
|
|
118
|
+
id: `mem-${now.replace(/[:.]/g, '-')}-${String(i + 1).padStart(3, '0')}`,
|
|
119
119
|
type: candidate.type,
|
|
120
120
|
agent: context.agent || 'unknown',
|
|
121
121
|
content: candidate.content,
|
package/src/orchestrator/cli.js
CHANGED
|
@@ -178,7 +178,8 @@ function resolveAgentModel(agent, projectDir) {
|
|
|
178
178
|
if (existsSync(configPath)) {
|
|
179
179
|
const configRaw = readFileSync(configPath, 'utf-8');
|
|
180
180
|
// Simple YAML parsing for agent_overrides section
|
|
181
|
-
const
|
|
181
|
+
const escapedAgent = agent.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
182
|
+
const overrideMatch = configRaw.match(new RegExp(`${escapedAgent}:\\s*\\n\\s+provider:\\s*(\\w+)`, 'm'));
|
|
182
183
|
if (overrideMatch) {
|
|
183
184
|
return { ...defaults, provider: overrideMatch[1] };
|
|
184
185
|
}
|
|
@@ -13,7 +13,9 @@ const TECH_NAMES = [
|
|
|
13
13
|
/\bExpress\b/g, /\bFastify\b/g, /\bDjango\b/g, /\bFlask\b/g, /\bLaravel\b/g,
|
|
14
14
|
/\bAWS\b/g, /\bVercel\b/g, /\bNetlify\b/g, /\bRailway\b/g, /\bCloudflare\b/g,
|
|
15
15
|
/\bDocker\b/g, /\bKubernetes\b/g, /\bRedis\b/g, /\bGraphQL\b/gi,
|
|
16
|
-
/\bTypeScript\b/gi, /\bJavaScript\b/gi, /\bPython\b/g,
|
|
16
|
+
/\bTypeScript\b/gi, /\bJavaScript\b/gi, /\bPython\b/g,
|
|
17
|
+
/\bRustlang\b|\bRust\s+(?:lang|crate|cargo|tokio|async|compiler)\b/gi,
|
|
18
|
+
/\bGolang\b|\bGo\s+(?:module|package|routine|channel|func|goroutine)\b/g,
|
|
17
19
|
/\bZod\b/g, /\bJoi\b/g, /\bZustand\b/g, /\bRedux\b/g, /\bJotai\b/g,
|
|
18
20
|
];
|
|
19
21
|
|
|
@@ -62,9 +62,9 @@ export const SECURITY_CHECKS = [
|
|
|
62
62
|
{
|
|
63
63
|
id: 'SHELL_METACHARACTERS',
|
|
64
64
|
name: 'Shell metacharacter injection',
|
|
65
|
-
pattern: /[`]
|
|
65
|
+
pattern: /[`]|\$\(/,
|
|
66
66
|
severity: 'critical',
|
|
67
|
-
description: 'Backticks or $() command substitution
|
|
67
|
+
description: 'Backticks or $() command substitution',
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
id: 'DANGEROUS_VARIABLES',
|
package/src/utils/brackets.js
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
* Single source of truth for bracket thresholds, layer configurations,
|
|
5
5
|
* and budget ratios. Consumers import from here to avoid duplication.
|
|
6
6
|
*
|
|
7
|
-
* Progressive Reinforcement Model (v4.
|
|
8
|
-
* As context depletes, budget
|
|
7
|
+
* Progressive Reinforcement Model (v4.1.2):
|
|
8
|
+
* As context depletes, both budget AND layers INCREASE.
|
|
9
|
+
* FRESH = model has full memory, minimal reinforcement needed.
|
|
10
|
+
* CRITICAL = model forgot initial instructions, maximum reinforcement + handoff.
|
|
9
11
|
* Budget expressed as ratio of provider's total context window.
|
|
10
12
|
*/
|
|
11
13
|
|
|
@@ -14,10 +16,10 @@
|
|
|
14
16
|
* @type {Record<string, {min: number, max: number, layers: string[], budgetRatio: number}>}
|
|
15
17
|
*/
|
|
16
18
|
export const BRACKETS = {
|
|
17
|
-
FRESH: { min: 60, max: 100, layers: ['L0', 'L1'
|
|
18
|
-
MODERATE: { min: 40, max: 60, layers: ['L0', 'L1', 'L2', 'L3'
|
|
19
|
-
DEPLETED: { min: 25, max: 40, layers: ['L0', 'L1', 'L2'],
|
|
20
|
-
CRITICAL: { min: 0, max: 25, layers: ['L0', 'L1'],
|
|
19
|
+
FRESH: { min: 60, max: 100, layers: ['L0', 'L1'], budgetRatio: 0.015 },
|
|
20
|
+
MODERATE: { min: 40, max: 60, layers: ['L0', 'L1', 'L2', 'L3'], budgetRatio: 0.025 },
|
|
21
|
+
DEPLETED: { min: 25, max: 40, layers: ['L0', 'L1', 'L2', 'L3', 'L4', 'L5'], budgetRatio: 0.040 },
|
|
22
|
+
CRITICAL: { min: 0, max: 25, layers: ['L0', 'L1', 'L2', 'L3', 'L4', 'L5'], budgetRatio: 0.050 },
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
/**
|