@dzhechkov/keysarium-core 1.0.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 +126 -0
- package/governance/checkpoint-protocol.md +129 -0
- package/governance/constitution.md +144 -0
- package/governance/shard-protocol.md +118 -0
- package/index.md +89 -0
- package/memory/dream-engine.md +148 -0
- package/memory/memory-protocol.md +197 -0
- package/memory/reward-tracker.md +162 -0
- package/orchestration/background-workers.md +141 -0
- package/orchestration/model-routing.md +92 -0
- package/orchestration/queen-protocol.md +154 -0
- package/orchestration/topology-selection.md +175 -0
- package/package.json +44 -0
- package/platform/adapter-registry.md +93 -0
- package/platform/templates/copilot.md +81 -0
- package/platform/templates/cursor.md +65 -0
- package/platform/templates/opencode.md +69 -0
- package/trust-tiers/promotion-protocol.md +144 -0
- package/trust-tiers/tier-system.md +111 -0
- package/verification/audit-trail.md +154 -0
- package/verification/judge-attestation.md +130 -0
- package/verification/witness-chain.md +138 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# DreamEngine Protocol — Background Pattern Consolidation
|
|
2
|
+
|
|
3
|
+
> Background process that builds concept graphs from accumulated reward data and generates cross-domain insights.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The DreamEngine analyzes accumulated reward data to produce higher-order insights. While the Reward Tracker computes per-domain aggregates and detects simple patterns, the DreamEngine builds a concept graph and discovers cross-domain associations, temporal correlations, and stage interdependencies.
|
|
8
|
+
|
|
9
|
+
**Builds on:** memory-protocol.md (reward records), reward-tracker.md (aggregates and patterns)
|
|
10
|
+
|
|
11
|
+
## Directory Structure
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
{insights-root}/
|
|
15
|
+
├── trigger-state.json ← Trigger evaluation state (persistent)
|
|
16
|
+
├── dream-{YYYYMMDD}-{HHmmss}.json ← Dream result (newest)
|
|
17
|
+
├── ... ← Max 10 files retained
|
|
18
|
+
└── dream-{oldest}.json ← Dream result (oldest kept)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The `{insights-root}` defaults to `.keysarium/insights/` but can be configured.
|
|
22
|
+
|
|
23
|
+
## Trigger Evaluation Protocol
|
|
24
|
+
|
|
25
|
+
### Trigger State File
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"version": "1.0",
|
|
30
|
+
"last_dream_completed_at": null,
|
|
31
|
+
"last_dream_id": null,
|
|
32
|
+
"records_since_last_dream": 0,
|
|
33
|
+
"pending_events": [],
|
|
34
|
+
"config": {
|
|
35
|
+
"time_threshold_minutes": 60,
|
|
36
|
+
"volume_threshold": 20,
|
|
37
|
+
"event_triggers_enabled": true
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Trigger Evaluation Algorithm
|
|
43
|
+
|
|
44
|
+
1. **Read state:** Read trigger-state.json. If missing, create with defaults.
|
|
45
|
+
2. **Check time trigger:** If `last_dream_completed_at` is null OR elapsed time > threshold, set `time_triggered = true`.
|
|
46
|
+
3. **Check volume trigger:** If `records_since_last_dream >= volume_threshold`, set `volume_triggered = true`.
|
|
47
|
+
4. **Check event trigger:** If events are enabled AND `pending_events` is non-empty, set `event_triggered = true`.
|
|
48
|
+
5. **Result:** Return `{ should_dream: any_trigger, reason: "time" | "volume" | "event" | "none" }`.
|
|
49
|
+
|
|
50
|
+
## Dream Execution Protocol
|
|
51
|
+
|
|
52
|
+
### Step 1: Load Data
|
|
53
|
+
|
|
54
|
+
1. Check if memory root exists. If not, exit with status `no_data`.
|
|
55
|
+
2. Read reward-summary.json and domain-patterns.json if they exist.
|
|
56
|
+
3. Scan all reward record files recursively.
|
|
57
|
+
4. Exclude expired records.
|
|
58
|
+
5. Sort by reward DESC, then timestamp DESC.
|
|
59
|
+
6. Take top 200 records.
|
|
60
|
+
7. If fewer than 5 valid records, exit with status `insufficient_data`.
|
|
61
|
+
|
|
62
|
+
### Step 2: Build Concept Graph
|
|
63
|
+
|
|
64
|
+
1. Initialize empty graph: `{ nodes: [], edges: [] }`
|
|
65
|
+
2. For each record, create/update nodes: domain, stage, skill, outcome.
|
|
66
|
+
3. Create/update edges: domain->stage, stage->skill, skill->outcome (weighted by reward).
|
|
67
|
+
4. Compute per-node aggregates: avg_reward, record_count, trend.
|
|
68
|
+
5. Compute per-edge aggregates: weight (mean reward), record_count.
|
|
69
|
+
|
|
70
|
+
### Step 3: Detect Cross-Domain Associations
|
|
71
|
+
|
|
72
|
+
Four types of associations:
|
|
73
|
+
|
|
74
|
+
**3a. Cross-Domain Stage Comparison:** For each stage, compare performance across domains. If gap > 0.15, create association.
|
|
75
|
+
|
|
76
|
+
**3b. Skill-Domain Mismatch:** For each skill, compare performance across domains. If gap > 0.15, create association.
|
|
77
|
+
|
|
78
|
+
**3c. Stage Correlation:** Find stages where low rewards in one correlate with low rewards in another (co-occurrence >= 3).
|
|
79
|
+
|
|
80
|
+
**3d. Temporal Trends:** Check for systematic reward changes over time across all data.
|
|
81
|
+
|
|
82
|
+
### Step 4: Generate Insights
|
|
83
|
+
|
|
84
|
+
For each association, generate an Insight:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"insight_id": "{dream_id}-{sequential:03d}",
|
|
89
|
+
"type": "performance | effectiveness | anti_pattern",
|
|
90
|
+
"description": "{description + actionable advice}",
|
|
91
|
+
"confidence": "min(1.0, evidence_count / 10)",
|
|
92
|
+
"impact": "high | medium | low",
|
|
93
|
+
"rank_score": "confidence * impact_weight",
|
|
94
|
+
"evidence_count": 8,
|
|
95
|
+
"domains": ["list of domains involved"],
|
|
96
|
+
"stages": ["list of stages involved"],
|
|
97
|
+
"skills": ["list of skills involved"],
|
|
98
|
+
"created_at": "ISO-8601",
|
|
99
|
+
"dream_id": "{dream_id}"
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Sort by rank_score DESC. Take top 20 insights.
|
|
104
|
+
|
|
105
|
+
### Step 5: Store and Clean
|
|
106
|
+
|
|
107
|
+
1. Write dream result file to `{insights-root}/dream-{timestamp}.json`.
|
|
108
|
+
2. Apply retention policy: keep max 10 dream files, delete oldest.
|
|
109
|
+
3. Reset trigger state.
|
|
110
|
+
|
|
111
|
+
## Dream Result Schema
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"version": "1.0",
|
|
116
|
+
"dream_id": "dream-{YYYYMMDD}-{HHmmss}",
|
|
117
|
+
"status": "completed",
|
|
118
|
+
"trigger_reason": "time | volume | event | manual",
|
|
119
|
+
"started_at": "ISO-8601",
|
|
120
|
+
"completed_at": "ISO-8601",
|
|
121
|
+
"records_analyzed": 200,
|
|
122
|
+
"concept_graph_nodes": 24,
|
|
123
|
+
"concept_graph_edges": 36,
|
|
124
|
+
"associations_found": 8,
|
|
125
|
+
"insights": [ ... ],
|
|
126
|
+
"metadata": {
|
|
127
|
+
"domains_covered": [],
|
|
128
|
+
"stages_covered": [],
|
|
129
|
+
"total_reward_records_in_memory": 42
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Error Handling
|
|
135
|
+
|
|
136
|
+
| Error | Behavior |
|
|
137
|
+
|-------|----------|
|
|
138
|
+
| Memory root does not exist | Exit with status `no_data`, zero insights |
|
|
139
|
+
| Fewer than 5 valid records | Exit with status `insufficient_data` |
|
|
140
|
+
| reward-summary.json missing | Proceed from raw records only |
|
|
141
|
+
| domain-patterns.json missing | Generate all patterns from scratch |
|
|
142
|
+
| Malformed reward record | Skip record, log warning, continue |
|
|
143
|
+
| trigger-state.json missing | Create with defaults |
|
|
144
|
+
| Write failure | Log error, set dream status to `failed` |
|
|
145
|
+
|
|
146
|
+
## Modular Reuse
|
|
147
|
+
|
|
148
|
+
The DreamEngine protocol is domain-agnostic. It operates on any data conforming to the RewardRecord schema. The association detection rules and insight generation can be adapted for any multi-stage pipeline with reward tracking.
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Memory Protocol — Reward-Calibrated Learning
|
|
2
|
+
|
|
3
|
+
> Core protocol for persistent memory in multi-agent pipelines. Provides `memory_query()` before stages and `memory_store()` after stages.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Memory Protocol enables a pipeline to learn from past executions. Each stage outcome is stored with a reward score (0.0-1.0), and future executions query historical patterns to improve performance.
|
|
8
|
+
|
|
9
|
+
## Memory Namespace
|
|
10
|
+
|
|
11
|
+
All memory files live in a dedicated directory:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
{memory-root}/
|
|
15
|
+
├── config.json ← Global configuration
|
|
16
|
+
├── _patterns/
|
|
17
|
+
│ └── domain-patterns.json ← Detected domain patterns
|
|
18
|
+
├── _stats/
|
|
19
|
+
│ └── reward-summary.json ← Aggregate statistics
|
|
20
|
+
├── {domain}/ ← Domain-specific subdirectory
|
|
21
|
+
│ └── {project-slug}/
|
|
22
|
+
│ └── {stage}_{timestamp}.json ← Individual reward records
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The `{memory-root}` defaults to `.keysarium/memory/` but can be configured.
|
|
26
|
+
|
|
27
|
+
## Configuration
|
|
28
|
+
|
|
29
|
+
### config.json (auto-created with defaults on first access)
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"version": "1.0",
|
|
34
|
+
"retention_days": 90,
|
|
35
|
+
"max_results_per_query": 10,
|
|
36
|
+
"enabled": true,
|
|
37
|
+
"known_domains": [],
|
|
38
|
+
"reward_levels": {
|
|
39
|
+
"excellent": 1.0,
|
|
40
|
+
"good": 0.7,
|
|
41
|
+
"needs_work": 0.3,
|
|
42
|
+
"failed": 0.0
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Protocol: memory_query(context)
|
|
48
|
+
|
|
49
|
+
Call at the **start** of each pipeline stage to load relevant historical patterns.
|
|
50
|
+
|
|
51
|
+
### Input
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"stage": "{stage-id}",
|
|
56
|
+
"domain": "{domain-name}",
|
|
57
|
+
"slug": "{project-slug}",
|
|
58
|
+
"skill": "{skill-name}"
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Algorithm
|
|
63
|
+
|
|
64
|
+
1. **Check enabled:** Read `{memory-root}/config.json`. If `enabled` is false or directory does not exist, return empty result.
|
|
65
|
+
2. **Resolve path:** Construct `{memory-root}/{domain}/` (scan all project slugs, not just current).
|
|
66
|
+
3. **Scan records:** Read all `{stage}_*.json` files matching the requested stage across all slugs in the domain.
|
|
67
|
+
4. **Filter expired:** Exclude records where `expires_at < current_date`.
|
|
68
|
+
5. **Sort:** By `reward` DESC, then `timestamp` DESC.
|
|
69
|
+
6. **Limit:** Return top `max_results_per_query` records (default 10).
|
|
70
|
+
7. **Enrich:** Also load `{memory-root}/_patterns/domain-patterns.json` for matching domain patterns.
|
|
71
|
+
|
|
72
|
+
### Output
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"records": [
|
|
77
|
+
{
|
|
78
|
+
"project_slug": "{slug}",
|
|
79
|
+
"stage": "{stage-id}",
|
|
80
|
+
"reward": 1.0,
|
|
81
|
+
"reward_label": "excellent",
|
|
82
|
+
"skill_used": "{skill-name}",
|
|
83
|
+
"outcome_summary": "{description of what happened}",
|
|
84
|
+
"timestamp": "2026-02-15T14:30:00Z"
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
"patterns": [
|
|
88
|
+
{
|
|
89
|
+
"pattern_id": "{domain}-{stage}-{type}",
|
|
90
|
+
"description": "{human-readable pattern description}",
|
|
91
|
+
"confidence": 0.85,
|
|
92
|
+
"actionable_advice": "{what to do about it}"
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"count": 3,
|
|
96
|
+
"domain": "{domain-name}"
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Usage After Query
|
|
101
|
+
|
|
102
|
+
1. Log: "Loaded {count} historical patterns for {stage} in {domain} domain"
|
|
103
|
+
2. If `records` is non-empty, review the top 3 records for relevant approaches
|
|
104
|
+
3. If `patterns` is non-empty, apply actionable advice to current stage execution
|
|
105
|
+
4. If both are empty (first run), proceed normally
|
|
106
|
+
|
|
107
|
+
## Protocol: memory_store(result, reward)
|
|
108
|
+
|
|
109
|
+
Call at each **checkpoint** after the human responds, to persist the stage outcome.
|
|
110
|
+
|
|
111
|
+
### Input
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"project_slug": "{slug}",
|
|
116
|
+
"domain": "{domain}",
|
|
117
|
+
"stage": "{stage-id}",
|
|
118
|
+
"stage_name": "{stage human-readable name}",
|
|
119
|
+
"skill_used": "{skill-name}",
|
|
120
|
+
"reward": 0.7,
|
|
121
|
+
"reward_label": "good",
|
|
122
|
+
"reward_reason": "{why this reward was assigned}",
|
|
123
|
+
"context": {
|
|
124
|
+
"stage_number": 2,
|
|
125
|
+
"domain_detected": "{domain}",
|
|
126
|
+
"upstream_promises": ["{PROMISE_1}", "{PROMISE_2}"],
|
|
127
|
+
"patterns_loaded": 3,
|
|
128
|
+
"time_budget_pct": 15.0,
|
|
129
|
+
"agent_count": 3
|
|
130
|
+
},
|
|
131
|
+
"outcome": {
|
|
132
|
+
"artifacts_created": ["{file1.md}", "{file2.md}"],
|
|
133
|
+
"checkpoint_response": "{what the human said}",
|
|
134
|
+
"iterations": 2,
|
|
135
|
+
"promise_emitted": "{PROMISE_TAG}"
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Algorithm
|
|
141
|
+
|
|
142
|
+
1. **Ensure directory exists:** Create `{memory-root}/{domain}/{slug}/` if it does not exist.
|
|
143
|
+
2. **Build record:** Construct full RewardRecord JSON from input.
|
|
144
|
+
3. **Compute expires_at:** `current_date + retention_days` (from config, default 90 days).
|
|
145
|
+
4. **Generate filename:** `{stage}_{ISO-timestamp}.json`.
|
|
146
|
+
5. **Write file:** Write JSON to `{memory-root}/{domain}/{slug}/{filename}`.
|
|
147
|
+
6. **Log:** "Stored reward {reward} ({reward_label}) for {stage} of {slug}"
|
|
148
|
+
|
|
149
|
+
### RewardRecord JSON Schema
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"id": "{slug}_{stage}_{timestamp}",
|
|
154
|
+
"version": "1.0",
|
|
155
|
+
"timestamp": "ISO-8601",
|
|
156
|
+
"project_slug": "{slug}",
|
|
157
|
+
"domain": "{domain}",
|
|
158
|
+
"stage": "{stage-id}",
|
|
159
|
+
"stage_name": "{human name}",
|
|
160
|
+
"skill_used": "{skill}",
|
|
161
|
+
"reward": 0.7,
|
|
162
|
+
"reward_label": "good",
|
|
163
|
+
"reward_reason": "{reason}",
|
|
164
|
+
"context": { ... },
|
|
165
|
+
"outcome": { ... },
|
|
166
|
+
"promise_tag": "{PROMISE_TAG}",
|
|
167
|
+
"expires_at": "ISO-8601"
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Reward Assignment Rules
|
|
172
|
+
|
|
173
|
+
| Human Behavior | Reward | Label | Detection |
|
|
174
|
+
|---------------|--------|-------|-----------|
|
|
175
|
+
| Approves immediately ("ok", "proceed") | 1.0 | excellent | Single-word approval |
|
|
176
|
+
| Requests minor adjustments (one section) | 0.7 | good | Feedback scoped to one area |
|
|
177
|
+
| Requests significant rework (multiple sections, changed approach) | 0.3 | needs_work | Feedback affects multiple areas |
|
|
178
|
+
| Restarts stage entirely / result unusable | 0.0 | failed | Stage restarts from scratch |
|
|
179
|
+
|
|
180
|
+
## Purge Protocol
|
|
181
|
+
|
|
182
|
+
To prevent unbounded growth:
|
|
183
|
+
|
|
184
|
+
1. **Trigger:** At each `memory_query()` call, check for expired records
|
|
185
|
+
2. **Scan:** Within the queried domain directory, find records where `expires_at < current_date`
|
|
186
|
+
3. **Delete:** Remove expired JSON files
|
|
187
|
+
4. **Log:** "Purged {count} expired records from {domain}"
|
|
188
|
+
|
|
189
|
+
## Error Handling
|
|
190
|
+
|
|
191
|
+
| Error | Behavior |
|
|
192
|
+
|-------|----------|
|
|
193
|
+
| Memory root does not exist | `memory_query()` returns empty; `memory_store()` creates directory |
|
|
194
|
+
| `config.json` missing | Use defaults (90 days, 10 results, enabled) |
|
|
195
|
+
| Malformed JSON file | Skip that record, log warning, continue |
|
|
196
|
+
| Write fails (permissions, disk) | Log error, continue pipeline without storing |
|
|
197
|
+
| Domain not in `known_domains` | Use "unknown" as domain directory |
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Reward Tracker — Analytics and Pattern Detection
|
|
2
|
+
|
|
3
|
+
> Computes aggregate statistics and detects domain patterns from accumulated reward records.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Reward Tracker operates on data stored by the Memory Protocol. It reads all RewardRecord JSON files and produces two output artifacts:
|
|
8
|
+
|
|
9
|
+
1. **reward-summary.json** — aggregate statistics per stage, domain, and skill
|
|
10
|
+
2. **domain-patterns.json** — detected patterns with confidence scores
|
|
11
|
+
|
|
12
|
+
## Computation Protocol
|
|
13
|
+
|
|
14
|
+
### Step 1: Load All Records
|
|
15
|
+
|
|
16
|
+
1. Scan `{memory-root}/` recursively for all `*.json` files (excluding config.json, domain-patterns.json, reward-summary.json).
|
|
17
|
+
2. Parse each JSON file as a RewardRecord.
|
|
18
|
+
3. Exclude records where `expires_at < current_date`.
|
|
19
|
+
4. Collect into a list sorted by `timestamp` DESC.
|
|
20
|
+
|
|
21
|
+
### Step 2: Per-Stage Reward Averages
|
|
22
|
+
|
|
23
|
+
Group records by `stage` and compute:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"{stage-id}": {
|
|
28
|
+
"avg_reward": 0.85,
|
|
29
|
+
"total_runs": 12,
|
|
30
|
+
"distribution": {
|
|
31
|
+
"excellent": 8,
|
|
32
|
+
"good": 3,
|
|
33
|
+
"needs_work": 1,
|
|
34
|
+
"failed": 0
|
|
35
|
+
},
|
|
36
|
+
"trend": "stable",
|
|
37
|
+
"best_project": "{slug}",
|
|
38
|
+
"worst_project": "{slug}"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Trend Detection Algorithm:**
|
|
44
|
+
1. Split records for each stage into two halves by timestamp (older half, newer half).
|
|
45
|
+
2. Compute average reward for each half.
|
|
46
|
+
3. If newer_avg - older_avg > 0.15 -> "improving"
|
|
47
|
+
4. If older_avg - newer_avg > 0.15 -> "degrading"
|
|
48
|
+
5. Otherwise -> "stable"
|
|
49
|
+
6. Minimum 4 records required for trend detection; otherwise "insufficient_data".
|
|
50
|
+
|
|
51
|
+
### Step 3: Per-Domain Reward Averages
|
|
52
|
+
|
|
53
|
+
Group records by `domain` and compute:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"{domain}": {
|
|
58
|
+
"avg_reward": 0.72,
|
|
59
|
+
"total_runs": 18,
|
|
60
|
+
"stage_breakdown": {
|
|
61
|
+
"{stage-0}": 0.85,
|
|
62
|
+
"{stage-1}": 0.90,
|
|
63
|
+
"{stage-2}": 0.55
|
|
64
|
+
},
|
|
65
|
+
"bottleneck_stage": "{stage-id}",
|
|
66
|
+
"strongest_stage": "{stage-id}"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Bottleneck Detection:**
|
|
72
|
+
- Stage with the lowest average reward in a domain is flagged as `bottleneck_stage`.
|
|
73
|
+
- Stage with the highest average reward is flagged as `strongest_stage`.
|
|
74
|
+
- Only computed if domain has 3+ records.
|
|
75
|
+
|
|
76
|
+
### Step 4: Per-Skill Effectiveness
|
|
77
|
+
|
|
78
|
+
Group records by `skill_used` and cross-reference with domain:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"{skill-name}": {
|
|
83
|
+
"overall_avg": 0.74,
|
|
84
|
+
"total_runs": 15,
|
|
85
|
+
"by_domain": {
|
|
86
|
+
"{domain-a}": { "avg": 0.65, "runs": 8 },
|
|
87
|
+
"{domain-b}": { "avg": 0.85, "runs": 7 }
|
|
88
|
+
},
|
|
89
|
+
"best_domain": "{domain}",
|
|
90
|
+
"worst_domain": "{domain}"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Step 5: Domain Pattern Detection
|
|
96
|
+
|
|
97
|
+
Analyze accumulated data to detect actionable patterns.
|
|
98
|
+
|
|
99
|
+
**Pattern Detection Rules:**
|
|
100
|
+
|
|
101
|
+
| Rule | Condition | Pattern Template |
|
|
102
|
+
|------|-----------|-----------------|
|
|
103
|
+
| Stage Bottleneck | Stage avg < 0.5 in domain, 3+ records | "{domain} projects struggle in {stage} (avg reward: {avg})" |
|
|
104
|
+
| Stage Excellence | Stage avg > 0.9 in domain, 3+ records | "{domain} projects excel in {stage} (avg reward: {avg})" |
|
|
105
|
+
| Skill-Domain Mismatch | Skill avg < 0.5 in domain but > 0.7 in another | "{skill} underperforms in {domain} vs {other_domain}" |
|
|
106
|
+
| Improving Trend | Trend = "improving" for stage in domain | "{stage} quality is improving in {domain}" |
|
|
107
|
+
| Degrading Trend | Trend = "degrading" for stage in domain | "{stage} quality is degrading in {domain} -- investigate" |
|
|
108
|
+
| Time Overhead | Stage avg iterations > 2.0 in domain | "{domain} projects require more iterations in {stage}" |
|
|
109
|
+
|
|
110
|
+
**Confidence Calculation:**
|
|
111
|
+
```
|
|
112
|
+
confidence = min(1.0, evidence_count / 10)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Step 6: Write Outputs
|
|
116
|
+
|
|
117
|
+
#### reward-summary.json
|
|
118
|
+
|
|
119
|
+
Write to `{memory-root}/_stats/reward-summary.json`:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"version": "1.0",
|
|
124
|
+
"generated_at": "ISO-8601",
|
|
125
|
+
"total_records": 42,
|
|
126
|
+
"total_domains": 3,
|
|
127
|
+
"total_projects": 8,
|
|
128
|
+
"stage_averages": { ... },
|
|
129
|
+
"domain_averages": { ... },
|
|
130
|
+
"skill_effectiveness": { ... },
|
|
131
|
+
"overall_average": 0.76,
|
|
132
|
+
"overall_trend": "improving"
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
#### domain-patterns.json
|
|
137
|
+
|
|
138
|
+
Write to `{memory-root}/_patterns/domain-patterns.json`:
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"version": "1.0",
|
|
143
|
+
"generated_at": "ISO-8601",
|
|
144
|
+
"patterns": [
|
|
145
|
+
{
|
|
146
|
+
"pattern_id": "{domain}-{stage}-{type}",
|
|
147
|
+
"domain": "{domain}",
|
|
148
|
+
"description": "{human-readable description}",
|
|
149
|
+
"category": "{bottleneck|excellence|mismatch|trend|overhead}",
|
|
150
|
+
"confidence": 0.80,
|
|
151
|
+
"evidence_count": 8,
|
|
152
|
+
"detected_at": "ISO-8601",
|
|
153
|
+
"examples": ["{slug1}", "{slug2}"],
|
|
154
|
+
"actionable_advice": "{what to do about it}"
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Modular Reuse
|
|
161
|
+
|
|
162
|
+
This tracker is domain-agnostic. It works with any RewardRecord JSON that conforms to the schema defined in `memory-protocol.md`. The pattern detection rules can be extended by adding entries to the Pattern Detection Rules table.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Background Workers Protocol
|
|
2
|
+
|
|
3
|
+
> Core protocol for managing non-blocking background workers in multi-agent pipelines.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Background workers enable long-running operations (pattern consolidation, knowledge export, health checks) to execute without blocking the foreground session. Each worker is an isolated agent that reads instructions from a template and writes output to a dedicated directory.
|
|
8
|
+
|
|
9
|
+
## Worker Type Registry
|
|
10
|
+
|
|
11
|
+
Define worker types for your pipeline:
|
|
12
|
+
|
|
13
|
+
| Property | Description |
|
|
14
|
+
|----------|-------------|
|
|
15
|
+
| `type` | Unique identifier for the worker type |
|
|
16
|
+
| `description` | Human-readable description |
|
|
17
|
+
| `model` | Model tier (haiku, sonnet, opus) |
|
|
18
|
+
| `template` | Path to the worker instruction template |
|
|
19
|
+
|
|
20
|
+
Example registry:
|
|
21
|
+
|
|
22
|
+
| Type | Description | Model |
|
|
23
|
+
|------|-------------|-------|
|
|
24
|
+
| `consolidate` | Scan completed projects for patterns | sonnet |
|
|
25
|
+
| `export-brain` | Non-blocking knowledge export | haiku |
|
|
26
|
+
| `health-check` | Verify skill tiers, check stale data | haiku |
|
|
27
|
+
| `pattern-analysis` | Analyze reward data and trends | sonnet |
|
|
28
|
+
|
|
29
|
+
## Directory Structure
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
{workers-root}/
|
|
33
|
+
├── registry.json ← Central registry (orchestrator-managed)
|
|
34
|
+
├── wkr-{YYYYMMDD}-{HHmmss}-{type}/ ← Per-worker directory
|
|
35
|
+
│ ├── status.json ← Worker-managed status
|
|
36
|
+
│ ├── stop-requested ← Flag file (orchestrator writes to request stop)
|
|
37
|
+
│ ├── output/ ← Worker output files
|
|
38
|
+
│ └── error.log ← Written on failure
|
|
39
|
+
└── ...
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Worker ID Format
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
wkr-{YYYYMMDD}-{HHmmss}-{type}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Example: `wkr-20260301-143022-consolidate`
|
|
49
|
+
|
|
50
|
+
## Registry Schema
|
|
51
|
+
|
|
52
|
+
The registry file is managed ONLY by the orchestrator. Workers NEVER modify it.
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"version": "1.0",
|
|
57
|
+
"max_concurrent": 3,
|
|
58
|
+
"workers": [
|
|
59
|
+
{
|
|
60
|
+
"worker_id": "wkr-20260301-143022-consolidate",
|
|
61
|
+
"type": "consolidate",
|
|
62
|
+
"status": "running",
|
|
63
|
+
"model": "sonnet",
|
|
64
|
+
"started_at": "ISO-8601",
|
|
65
|
+
"completed_at": null,
|
|
66
|
+
"output_dir": "{workers-root}/wkr-20260301-143022-consolidate/",
|
|
67
|
+
"retry_count": 0
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Worker Status Schema
|
|
74
|
+
|
|
75
|
+
Each worker writes its own `status.json`:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"worker_id": "wkr-...",
|
|
80
|
+
"type": "consolidate",
|
|
81
|
+
"status": "running",
|
|
82
|
+
"started_at": "ISO-8601",
|
|
83
|
+
"completed_at": null,
|
|
84
|
+
"progress": {
|
|
85
|
+
"phase": "scanning projects",
|
|
86
|
+
"items_processed": 3,
|
|
87
|
+
"total_items": 7
|
|
88
|
+
},
|
|
89
|
+
"error": null
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Status values: `starting`, `running`, `completing`, `completed`, `failed`, `stop-requested`, `stopped`
|
|
94
|
+
|
|
95
|
+
## Launch Protocol
|
|
96
|
+
|
|
97
|
+
1. **Validate:** Check type is valid, count active workers, enforce max_concurrent limit.
|
|
98
|
+
2. **Create directory:** `mkdir -p {workers-root}/wkr-{id}/output/`
|
|
99
|
+
3. **Update registry:** Add entry with status `starting`.
|
|
100
|
+
4. **Load template:** Read the worker template.
|
|
101
|
+
5. **Spawn agent:** Launch with background execution, injecting worker_id and output_dir.
|
|
102
|
+
6. **Confirm:** Report worker ID and output directory to user.
|
|
103
|
+
|
|
104
|
+
## Status Query Protocol
|
|
105
|
+
|
|
106
|
+
1. Read registry.json
|
|
107
|
+
2. For each worker, read its status.json
|
|
108
|
+
3. Update registry with latest status
|
|
109
|
+
4. Prune entries older than 24 hours (completed/failed/stopped)
|
|
110
|
+
5. Display formatted status table
|
|
111
|
+
|
|
112
|
+
## Stop Protocol
|
|
113
|
+
|
|
114
|
+
1. Verify worker exists and is running
|
|
115
|
+
2. Write empty file: `{worker-dir}/stop-requested`
|
|
116
|
+
3. Update registry status to `stop-requested`
|
|
117
|
+
4. Worker checks for this file between operations and exits gracefully
|
|
118
|
+
|
|
119
|
+
## Error Handling
|
|
120
|
+
|
|
121
|
+
- Maximum 2 retries per original request
|
|
122
|
+
- Each retry creates a NEW worker (new ID) with incremented retry_count
|
|
123
|
+
- If retry_count >= 2, mark as permanently failed
|
|
124
|
+
|
|
125
|
+
## Worker Isolation Rules
|
|
126
|
+
|
|
127
|
+
1. Workers MUST only write to their own directory
|
|
128
|
+
2. Workers MUST NOT modify project files directly
|
|
129
|
+
3. Workers MUST NOT modify pipeline configuration
|
|
130
|
+
4. Workers MUST NOT spawn sub-agents
|
|
131
|
+
5. Workers MAY read project files (read-only access)
|
|
132
|
+
6. Workers write deltas/reports that the user decides whether to apply
|
|
133
|
+
|
|
134
|
+
## Model Routing
|
|
135
|
+
|
|
136
|
+
| Worker Type | Recommended Model | Rationale |
|
|
137
|
+
|-------------|------------------|-----------|
|
|
138
|
+
| Pattern synthesis | sonnet | Analytical reasoning required |
|
|
139
|
+
| File operations | haiku | Primarily reading and formatting |
|
|
140
|
+
| Structural checks | haiku | Pattern matching only |
|
|
141
|
+
| Trend analysis | sonnet | Deeper reasoning needed |
|