@dzhechkov/keysarium 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/package.json +10 -2
  2. package/src/commands/init.js +1 -1
  3. package/templates/.claude/commands/dream.md +101 -0
  4. package/templates/.claude/commands/feature-adr.md +92 -0
  5. package/templates/.claude/commands/init-platform.md +161 -0
  6. package/templates/.claude/commands/learning-stats.md +130 -0
  7. package/templates/.claude/commands/workers.md +140 -0
  8. package/templates/.claude/rules/background-workers.md +72 -0
  9. package/templates/.claude/rules/dream-cycles.md +90 -0
  10. package/templates/.claude/rules/feature-adr-conventions.md +82 -0
  11. package/templates/.claude/rules/reward-learning.md +124 -0
  12. package/templates/.claude/shards/feature-adr.shard.md +98 -0
  13. package/templates/.claude/skills/feature-adr/SKILL.md +252 -0
  14. package/templates/.claude/skills/feature-adr/examples/sample-feature-output.md +257 -0
  15. package/templates/.claude/skills/feature-adr/modules/00-complexity-router.md +114 -0
  16. package/templates/.claude/skills/feature-adr/modules/01-requirements.md +113 -0
  17. package/templates/.claude/skills/feature-adr/modules/02-research.md +92 -0
  18. package/templates/.claude/skills/feature-adr/modules/03-adr.md +135 -0
  19. package/templates/.claude/skills/feature-adr/modules/04-ddd.md +114 -0
  20. package/templates/.claude/skills/feature-adr/modules/05-architecture.md +149 -0
  21. package/templates/.claude/skills/feature-adr/modules/06-implementation-plan.md +129 -0
  22. package/templates/.claude/skills/feature-adr/modules/07-code.md +126 -0
  23. package/templates/.claude/skills/feature-adr/modules/08-qe.md +167 -0
  24. package/templates/.claude/skills/feature-adr/references/adr-template.md +102 -0
  25. package/templates/.claude/skills/feature-adr/references/c4-template.md +120 -0
  26. package/templates/.claude/skills/feature-adr/references/complexity-matrix.md +139 -0
  27. package/templates/.claude/skills/feature-adr/references/qe-checklist.md +86 -0
  28. package/templates/CLAUDE.md +124 -3
  29. package/templates/docs/improvement-directions.md +16 -16
  30. package/templates/docs/keysarium/01-deployment-guide.md +21 -12
  31. package/templates/docs/keysarium/02-admin-guide.md +204 -3
  32. package/templates/docs/keysarium/03-user-guide.md +224 -0
  33. package/templates/docs/keysarium/05-architecture.md +181 -0
  34. package/templates/docs/keysarium/06-user-flows.md +235 -0
  35. package/templates/lib/background-workers.md +278 -0
  36. package/templates/lib/dream-engine.md +460 -0
  37. package/templates/lib/judge-attestation.md +322 -0
  38. package/templates/lib/memory-protocol.md +239 -0
  39. package/templates/lib/platform-adapters.md +100 -0
  40. package/templates/lib/platform-templates/copilot.md +134 -0
  41. package/templates/lib/platform-templates/cursor.md +95 -0
  42. package/templates/lib/platform-templates/opencode.md +155 -0
  43. package/templates/lib/reward-tracker.md +256 -0
  44. package/templates/lib/witness-chain.md +372 -0
  45. package/templates/lib/worker-templates/brain-export.md +187 -0
  46. package/templates/lib/worker-templates/consolidate.md +180 -0
  47. package/templates/lib/worker-templates/dream-cycle.md +154 -0
  48. package/templates/lib/worker-templates/health-check.md +255 -0
@@ -0,0 +1,322 @@
1
+ # Judge Attestation Protocol
2
+
3
+ > Cryptographic proof of BTO judge isolation via SHA-256 hash chain attestations.
4
+
5
+ ## Purpose
6
+
7
+ This protocol defines how BTO judges (Domain Expert, Critic, Completeness Auditor) create cryptographic attestations proving their evaluations were performed independently. Each judge records a hash of its evaluation before seeing other judges' scores. The attestations are chained to provide ordering proof.
8
+
9
+ ## Constants
10
+
11
+ ```
12
+ NULL_HASH = "0000000000000000000000000000000000000000000000000000000000000000"
13
+ ATTESTATION_FILE = ".judge-attestations.json"
14
+ HASH_PREFIX = "sha256:"
15
+ STANDARD_PANEL_SIZE = 3
16
+ HIGH_STAKES_PANEL_SIZE = 5
17
+ ```
18
+
19
+ ## Section 1: Attestation Creation
20
+
21
+ ### Hash Input Construction
22
+
23
+ Each judge's evaluation hash is computed from a deterministic concatenation of:
24
+
25
+ ```
26
+ evaluation_hash = SHA-256(judge_id + "|" + artifact_hash + "|" + score + "|" + rationale_summary)
27
+ ```
28
+
29
+ The pipe character `|` serves as a delimiter to prevent ambiguity in concatenation.
30
+
31
+ **Fields:**
32
+ - `judge_id`: One of `"domain-expert"`, `"critic"`, `"completeness-auditor"` (or `"meta-judge"` for escalation)
33
+ - `artifact_hash`: SHA-256 hash of the artifact being evaluated (computed before evaluation starts)
34
+ - `score`: The numeric score as a string with one decimal place (e.g., `"8.2"`)
35
+ - `rationale_summary`: First 500 characters of the judge's rationale text, trimmed of leading/trailing whitespace
36
+
37
+ ### Computing the Artifact Hash
38
+
39
+ Before any judge starts evaluation, compute the artifact hash:
40
+
41
+ ```bash
42
+ ARTIFACT_HASH=$(${SHA_CMD} "path/to/artifact.md" | awk '{print $1}')
43
+ ```
44
+
45
+ This hash is shared with all judges and recorded in each attestation. It proves all judges evaluated the same artifact.
46
+
47
+ ### Computing the Evaluation Hash
48
+
49
+ After a judge completes its evaluation:
50
+
51
+ ```bash
52
+ JUDGE_ID="domain-expert"
53
+ ARTIFACT_HASH="<computed above>"
54
+ SCORE="8.2"
55
+ RATIONALE_SUMMARY="<first 500 chars of rationale>"
56
+
57
+ EVAL_HASH=$(printf '%s' "${JUDGE_ID}|${ARTIFACT_HASH}|${SCORE}|${RATIONALE_SUMMARY}" | ${SHA_CMD} | awk '{print $1}')
58
+ ```
59
+
60
+ **Important:** The rationale_summary must be trimmed to exactly 500 characters (or fewer if the rationale is shorter) to ensure deterministic reproduction during verification.
61
+
62
+ ## Section 2: Chain Linking
63
+
64
+ ### Attestation Order
65
+
66
+ Judges are recorded in a fixed order within each evaluation round:
67
+
68
+ 1. Domain Expert (first, previous = NULL_HASH)
69
+ 2. Critic (second, previous = Domain Expert's evaluation_hash)
70
+ 3. Completeness Auditor (third, previous = Critic's evaluation_hash)
71
+
72
+ For a 5-judge high-stakes panel:
73
+ 4. Additional Expert (fourth, previous = Auditor's evaluation_hash)
74
+ 5. Tiebreaker (fifth, previous = Additional Expert's evaluation_hash)
75
+
76
+ ### Chain Link Protocol
77
+
78
+ ```bash
79
+ # Judge 1 (Domain Expert)
80
+ PREV_ATTESTATION_HASH="${NULL_HASH}"
81
+ # ... compute evaluation_hash_1 ...
82
+ # Record attestation with previous = NULL_HASH
83
+
84
+ # Judge 2 (Critic)
85
+ PREV_ATTESTATION_HASH="${EVAL_HASH_1}"
86
+ # ... compute evaluation_hash_2 ...
87
+ # Record attestation with previous = evaluation_hash_1
88
+
89
+ # Judge 3 (Completeness Auditor)
90
+ PREV_ATTESTATION_HASH="${EVAL_HASH_2}"
91
+ # ... compute evaluation_hash_3 ...
92
+ # Record attestation with previous = evaluation_hash_2
93
+ ```
94
+
95
+ ### Ordering Note
96
+
97
+ The chain records the ORDER in which attestations were finalized, not the order in which judges started evaluating. Since judges evaluate in parallel but record sequentially, the chain proves:
98
+ - Each attestation was recorded after the previous one
99
+ - The evaluation_hash was computed from the judge's OWN data only
100
+ - The previous_attestation_hash links to the preceding record (not to the preceding judge's score)
101
+
102
+ ## Section 3: Isolation Verification
103
+
104
+ ### Verification Algorithm
105
+
106
+ ```
107
+ 1. Load .judge-attestations.json
108
+ 2. For each evaluation round:
109
+ a. Verify artifact_hash matches across all attestations
110
+ b. For each attestation (index i):
111
+ i. Reconstruct evaluation_hash from (judge_id, artifact_hash, score, rationale_summary)
112
+ ii. Compare reconstructed hash with stored evaluation_hash
113
+ iii. If i == 0: verify previous_attestation_hash == NULL_HASH
114
+ iv. If i > 0: verify previous_attestation_hash == attestations[i-1].evaluation_hash
115
+ v. Verify timestamp > attestations[i-1].timestamp (if i > 0)
116
+ 3. Produce verification report
117
+ ```
118
+
119
+ ### Isolation Proof Logic
120
+
121
+ The isolation proof works as follows:
122
+
123
+ 1. **Hash Independence:** Each evaluation_hash is computed from `judge_id|artifact_hash|score|rationale`. If a judge had seen another judge's score, it would not affect its own hash computation -- but it would be detectable if the rationale text references specific scores from other judges.
124
+
125
+ 2. **Chain Integrity:** The previous_attestation_hash links attestations in order but does NOT include other judges' scores in the hash input. This means the chain proves ORDER but the evaluation content is provably independent.
126
+
127
+ 3. **Timestamp Monotonicity:** Timestamps must be strictly increasing. If Judge B's timestamp is BEFORE Judge A's, but Judge B's previous_attestation_hash points to Judge A, then something is wrong.
128
+
129
+ ### Verification Script
130
+
131
+ ```bash
132
+ python3 << 'VERIFY_ATTESTATION'
133
+ import json, subprocess, sys
134
+
135
+ NULL_HASH = "0" * 64
136
+
137
+ def sha256(content):
138
+ result = subprocess.run(
139
+ ["sha256sum"],
140
+ input=content.encode(),
141
+ capture_output=True
142
+ )
143
+ if result.returncode != 0:
144
+ result = subprocess.run(
145
+ ["shasum", "-a", "256"],
146
+ input=content.encode(),
147
+ capture_output=True
148
+ )
149
+ return result.stdout.decode().split()[0]
150
+
151
+ DIR = sys.argv[1] if len(sys.argv) > 1 else "."
152
+
153
+ with open(f"{DIR}/.judge-attestations.json") as f:
154
+ data = json.load(f)
155
+
156
+ for eval_round in data.get("evaluations", [data]):
157
+ attestations = eval_round.get("attestations", [])
158
+ artifact_hash = eval_round.get("artifact_hash", "")
159
+ violations = []
160
+
161
+ for i, att in enumerate(attestations):
162
+ # Reconstruct evaluation hash
163
+ hash_input = f"{att['judge_id']}|{artifact_hash}|{att['score']}|{att.get('rationale_summary', '')}"
164
+ expected = sha256(hash_input)
165
+ actual = att["evaluation_hash"].replace("sha256:", "")
166
+
167
+ if expected != actual:
168
+ violations.append(f"Judge {att['judge_id']}: evaluation_hash mismatch")
169
+
170
+ # Verify chain link
171
+ if i == 0:
172
+ expected_prev = NULL_HASH
173
+ else:
174
+ expected_prev = attestations[i-1]["evaluation_hash"].replace("sha256:", "")
175
+
176
+ actual_prev = att["previous_attestation_hash"].replace("sha256:", "")
177
+ if expected_prev != actual_prev:
178
+ violations.append(f"Judge {att['judge_id']}: chain link broken")
179
+
180
+ if not violations:
181
+ print(f"PASS: All {len(attestations)} judge attestations verified. Isolation confirmed.")
182
+ else:
183
+ print(f"FAIL: {len(violations)} violations detected:")
184
+ for v in violations:
185
+ print(f" - {v}")
186
+
187
+ VERIFY_ATTESTATION
188
+ ```
189
+
190
+ ## Section 4: File Format
191
+
192
+ ### .judge-attestations.json Schema
193
+
194
+ ```json
195
+ {
196
+ "evaluations": [
197
+ {
198
+ "evaluation_id": "string — unique ID for this evaluation round",
199
+ "artifact_path": "string — path to the evaluated artifact",
200
+ "artifact_hash": "string — sha256:<hex> of the artifact content",
201
+ "panel_size": "integer — 3 (standard) or 5 (high-stakes)",
202
+ "started_at": "ISO-8601 — when evaluation round began",
203
+ "completed_at": "ISO-8601 — when last attestation recorded",
204
+ "attestations": [
205
+ {
206
+ "judge_id": "string — domain-expert|critic|completeness-auditor",
207
+ "score": "float — 0.0-10.0",
208
+ "rationale_summary": "string — first 500 chars of rationale",
209
+ "evaluation_hash": "string — sha256:<hex>",
210
+ "timestamp": "ISO-8601 — when attestation was recorded",
211
+ "previous_attestation_hash": "string — sha256:<hex> or null hash"
212
+ }
213
+ ],
214
+ "final_score": "float — weighted average",
215
+ "weights": {
216
+ "domain-expert": 0.4,
217
+ "critic": 0.3,
218
+ "completeness-auditor": 0.3
219
+ }
220
+ }
221
+ ]
222
+ }
223
+ ```
224
+
225
+ ### Example Attestation File
226
+
227
+ ```json
228
+ {
229
+ "evaluations": [
230
+ {
231
+ "evaluation_id": "bto-eval-2026-03-01T12:00:00Z",
232
+ "artifact_path": ".claude/skills/explore/SKILL.md",
233
+ "artifact_hash": "sha256:abc123def456789012345678901234567890123456789012345678901234fedc",
234
+ "panel_size": 3,
235
+ "started_at": "2026-03-01T12:00:00Z",
236
+ "completed_at": "2026-03-01T12:01:45Z",
237
+ "attestations": [
238
+ {
239
+ "judge_id": "domain-expert",
240
+ "score": 8.2,
241
+ "rationale_summary": "Strong SKILL.md with clear protocol steps. References directory provides good examples...",
242
+ "evaluation_hash": "sha256:111222333444555666777888999000aaabbbcccdddeeefff000111222333444555",
243
+ "timestamp": "2026-03-01T12:00:30Z",
244
+ "previous_attestation_hash": "sha256:0000000000000000000000000000000000000000000000000000000000000000"
245
+ },
246
+ {
247
+ "judge_id": "critic",
248
+ "score": 7.5,
249
+ "rationale_summary": "Missing edge case handling for multi-language inputs. Error recovery protocol unclear...",
250
+ "evaluation_hash": "sha256:222333444555666777888999000aaabbbcccdddeeefff000111222333444555666",
251
+ "timestamp": "2026-03-01T12:01:00Z",
252
+ "previous_attestation_hash": "sha256:111222333444555666777888999000aaabbbcccdddeeefff000111222333444555"
253
+ },
254
+ {
255
+ "judge_id": "completeness-auditor",
256
+ "score": 8.0,
257
+ "rationale_summary": "All required sections present. References directory has 3 examples. Missing: performance benchmarks...",
258
+ "evaluation_hash": "sha256:333444555666777888999000aaabbbcccdddeeefff000111222333444555666777",
259
+ "timestamp": "2026-03-01T12:01:30Z",
260
+ "previous_attestation_hash": "sha256:222333444555666777888999000aaabbbcccdddeeefff000111222333444555666"
261
+ }
262
+ ],
263
+ "final_score": 7.94,
264
+ "weights": {
265
+ "domain-expert": 0.4,
266
+ "critic": 0.3,
267
+ "completeness-auditor": 0.3
268
+ }
269
+ }
270
+ ]
271
+ }
272
+ ```
273
+
274
+ ## Section 5: Integration with BTO Pipeline
275
+
276
+ ### When to Create Attestations
277
+
278
+ Attestations are created during **BTO Layer 2 evaluation** (the judge panel stage):
279
+
280
+ 1. **Before panel starts:** Compute `artifact_hash` of the artifact being evaluated
281
+ 2. **After each judge completes:** Create attestation record with evaluation_hash
282
+ 3. **After all judges complete:** Write `.judge-attestations.json`
283
+ 4. **If meta-judge is invoked:** Add a 4th attestation with `judge_id: "meta-judge"`
284
+
285
+ ### Integration Points
286
+
287
+ | BTO Stage | Attestation Action |
288
+ |-----------|-------------------|
289
+ | Layer 0 (structural) | No attestation needed (deterministic checks) |
290
+ | Layer 1 (semantic) | No attestation needed (single haiku agent) |
291
+ | Layer 2 (judge panel) | Create attestation set with 3 attestations |
292
+ | Meta-judge (escalation) | Append meta-judge attestation to the set |
293
+ | Optimization rounds | Create new attestation set per round's final evaluation |
294
+
295
+ ### Disagreement Detection Enhancement
296
+
297
+ With attestations, disagreement detection gains cryptographic backing:
298
+
299
+ ```
300
+ If max_score - min_score > 3.0:
301
+ 1. Verify all attestations are valid (no tampering)
302
+ 2. Verify isolation (no judge influenced another)
303
+ 3. If isolation verified: escalate to meta-judge (genuine disagreement)
304
+ 4. If isolation violated: flag conformity collapse warning
305
+ ```
306
+
307
+ ## Section 6: Meta-Judge Attestation
308
+
309
+ When the meta-judge is invoked (disagreement > 3 points), it creates its own attestation:
310
+
311
+ ```json
312
+ {
313
+ "judge_id": "meta-judge",
314
+ "score": 7.8,
315
+ "rationale_summary": "Disagreement between domain-expert (8.5) and critic (5.2) on dimension 'completeness'...",
316
+ "evaluation_hash": "sha256:...",
317
+ "timestamp": "2026-03-01T12:02:00Z",
318
+ "previous_attestation_hash": "sha256:<last judge's eval hash>"
319
+ }
320
+ ```
321
+
322
+ The meta-judge's rationale MAY reference other judges' scores (it has access to them for arbitration). This is expected and does not violate isolation -- the meta-judge is explicitly a synthesizer, not an independent evaluator.
@@ -0,0 +1,239 @@
1
+ # Memory Protocol -- Reward-Calibrated Learning
2
+
3
+ Core protocol for persistent memory in the Keysarium pipeline. Provides `memory_query()` before tasks and `memory_store()` after tasks.
4
+
5
+ ## Memory Namespace
6
+
7
+ All memory files live in `.keysarium/memory/`:
8
+
9
+ ```
10
+ .keysarium/memory/
11
+ ├── config.json ← Global configuration
12
+ ├── _patterns/
13
+ │ └── domain-patterns.json ← Detected domain patterns
14
+ ├── _stats/
15
+ │ └── reward-summary.json ← Aggregate statistics
16
+ ├── {domain}/ ← banking | retail | enterprise | healthcare
17
+ │ └── {case-slug}/
18
+ │ └── {phase}_{timestamp}.json ← Individual reward records
19
+ ```
20
+
21
+ ## Configuration
22
+
23
+ ### config.json (auto-created with defaults on first access)
24
+
25
+ ```json
26
+ {
27
+ "version": "1.0",
28
+ "retention_days": 90,
29
+ "max_results_per_query": 10,
30
+ "enabled": true,
31
+ "known_domains": ["banking", "retail", "enterprise", "healthcare"],
32
+ "reward_levels": {
33
+ "excellent": 1.0,
34
+ "good": 0.7,
35
+ "needs_work": 0.3,
36
+ "failed": 0.0
37
+ }
38
+ }
39
+ ```
40
+
41
+ ## Protocol: memory_query(context)
42
+
43
+ Call at the **start** of each pipeline phase to load relevant historical patterns.
44
+
45
+ ### Input
46
+
47
+ ```json
48
+ {
49
+ "phase": "phase-2",
50
+ "domain": "banking",
51
+ "slug": "bank_kc_automation",
52
+ "skill": "goap-research-ed25519"
53
+ }
54
+ ```
55
+
56
+ ### Algorithm
57
+
58
+ 1. **Check enabled:** Read `.keysarium/memory/config.json`. If `enabled` is false or directory does not exist, return empty list.
59
+ 2. **Resolve path:** Construct `.keysarium/memory/{domain}/` (scan all slugs, not just current).
60
+ 3. **Scan records:** Read all `{phase}_*.json` files matching the requested phase across all slugs in the domain.
61
+ 4. **Filter expired:** Exclude records where `expires_at < current_date`.
62
+ 5. **Sort:** By `reward` DESC, then `timestamp` DESC.
63
+ 6. **Limit:** Return top `max_results_per_query` records (default 10).
64
+ 7. **Enrich:** Also load `.keysarium/memory/_patterns/domain-patterns.json` for matching domain patterns.
65
+
66
+ ### Output
67
+
68
+ ```json
69
+ {
70
+ "records": [
71
+ {
72
+ "case_slug": "bank_loan_approval",
73
+ "phase": "phase-2",
74
+ "reward": 1.0,
75
+ "reward_label": "excellent",
76
+ "skill_used": "goap-research-ed25519",
77
+ "outcome_summary": "Research completed with all claims verified...",
78
+ "timestamp": "2026-02-15T14:30:00Z"
79
+ }
80
+ ],
81
+ "patterns": [
82
+ {
83
+ "pattern_id": "banking-phase2-slow",
84
+ "description": "Banking cases take 2x longer in Phase 2 due to regulatory research",
85
+ "confidence": 0.85,
86
+ "actionable_advice": "Allocate extra time budget for Phase 2 in banking domain"
87
+ }
88
+ ],
89
+ "count": 3,
90
+ "domain": "banking"
91
+ }
92
+ ```
93
+
94
+ ### Usage in Phase
95
+
96
+ After calling `memory_query()`, the agent should:
97
+ 1. Log: "Loaded {count} historical patterns for {phase} in {domain} domain"
98
+ 2. If `records` is non-empty, review the top 3 records for relevant approaches
99
+ 3. If `patterns` is non-empty, apply actionable advice to current phase execution
100
+ 4. If both are empty (first run), proceed normally
101
+
102
+ ## Protocol: memory_store(result, reward)
103
+
104
+ Call at each **checkpoint** after the user responds, to persist the phase outcome with a reward score.
105
+
106
+ ### Input
107
+
108
+ ```json
109
+ {
110
+ "case_slug": "bank_kc_automation",
111
+ "domain": "banking",
112
+ "phase": "phase-2",
113
+ "phase_name": "Research",
114
+ "skill_used": "goap-research-ed25519",
115
+ "reward": 0.7,
116
+ "reward_label": "good",
117
+ "reward_reason": "User requested minor edits to competitor analysis section",
118
+ "context": {
119
+ "phase_number": 2,
120
+ "domain_detected": "banking",
121
+ "upstream_promises": ["DISCOVERY_COMPLETE", "CASE_EXPLORED"],
122
+ "patterns_loaded": 3,
123
+ "time_budget_pct": 15.0,
124
+ "agent_count": 3
125
+ },
126
+ "outcome": {
127
+ "artifacts_created": ["02_research_findings.md"],
128
+ "checkpoint_response": "ok, but expand the FinTech competitor section",
129
+ "iterations": 2,
130
+ "promise_emitted": "RESEARCH_PARANOID_PASSED"
131
+ }
132
+ }
133
+ ```
134
+
135
+ ### Algorithm
136
+
137
+ 1. **Ensure directory exists:** Create `.keysarium/memory/{domain}/{slug}/` if it does not exist.
138
+ 2. **Build record:** Construct full RewardRecord JSON from input.
139
+ 3. **Compute expires_at:** `current_date + retention_days` (from config, default 90 days).
140
+ 4. **Generate filename:** `{phase}_{ISO-timestamp}.json` (e.g., `phase-2_2026-03-01T12-30-00.json`).
141
+ 5. **Write file:** Write JSON to `.keysarium/memory/{domain}/{slug}/{filename}`.
142
+ 6. **Log:** "Stored reward {reward} ({reward_label}) for {phase} of {slug}"
143
+
144
+ ### RewardRecord JSON Schema
145
+
146
+ ```json
147
+ {
148
+ "id": "bank_kc_automation_phase-2_2026-03-01T12-30-00",
149
+ "version": "1.0",
150
+ "timestamp": "2026-03-01T12:30:00Z",
151
+ "case_slug": "bank_kc_automation",
152
+ "domain": "banking",
153
+ "phase": "phase-2",
154
+ "phase_name": "Research",
155
+ "skill_used": "goap-research-ed25519",
156
+ "reward": 0.7,
157
+ "reward_label": "good",
158
+ "reward_reason": "User requested minor edits to competitor analysis section",
159
+ "context": {
160
+ "phase_number": 2,
161
+ "domain_detected": "banking",
162
+ "upstream_promises": ["DISCOVERY_COMPLETE", "CASE_EXPLORED"],
163
+ "patterns_loaded": 3,
164
+ "time_budget_pct": 15.0,
165
+ "agent_count": 3
166
+ },
167
+ "outcome": {
168
+ "artifacts_created": ["02_research_findings.md"],
169
+ "checkpoint_response": "ok, but expand the FinTech competitor section",
170
+ "iterations": 2,
171
+ "promise_emitted": "RESEARCH_PARANOID_PASSED"
172
+ },
173
+ "promise_tag": "RESEARCH_PARANOID_PASSED",
174
+ "expires_at": "2026-05-30T12:30:00Z"
175
+ }
176
+ ```
177
+
178
+ ## Reward Assignment Rules
179
+
180
+ The reward score is determined by the user's response at the checkpoint:
181
+
182
+ | User Behavior | Reward | Label | Detection |
183
+ |---------------|--------|-------|-----------|
184
+ | Says "ok" / "ок" / proceeds to next phase immediately | 1.0 | excellent | Exact match or single-word approval |
185
+ | Requests minor adjustments ("углуби X", small edits to one section) | 0.7 | good | Feedback is scoped to one area, does not change direction |
186
+ | Requests significant rework (multiple sections, changed approach, re-research) | 0.3 | needs_work | Feedback affects multiple areas or changes phase direction |
187
+ | Restarts phase entirely / says result is unusable / requests complete redo | 0.0 | failed | Phase restarts from scratch |
188
+
189
+ ### Edge Cases
190
+
191
+ - **"углуби [section]"** = 0.7 (deepening is enhancement, not failure)
192
+ - **Multiple rounds of minor feedback** = 0.7 on first round, 0.3 if third+ round
193
+ - **Positive feedback with minor note** ("great, just fix the typo in section 3") = 1.0
194
+ - **No explicit response** (session ends) = do not store (no record created)
195
+
196
+ ## Purge Protocol
197
+
198
+ To prevent unbounded growth, expired records should be cleaned up:
199
+
200
+ 1. **Trigger:** At each `memory_query()` call, check for expired records
201
+ 2. **Scan:** Within the queried domain directory, find records where `expires_at < current_date`
202
+ 3. **Delete:** Remove expired JSON files
203
+ 4. **Log:** "Purged {count} expired records from {domain}"
204
+
205
+ ## Error Handling
206
+
207
+ | Error | Behavior |
208
+ |-------|----------|
209
+ | `.keysarium/memory/` does not exist | `memory_query()` returns empty; `memory_store()` creates directory |
210
+ | `config.json` missing | Use defaults (90 days, 10 results, enabled) |
211
+ | Malformed JSON file | Skip that record, log warning, continue |
212
+ | Write fails (permissions, disk) | Log error, continue pipeline without storing |
213
+ | Domain not in `known_domains` | Use "unknown" as domain directory |
214
+
215
+ ## Integration with Brain Export
216
+
217
+ When `/brain-export` runs, it should include a `"reward_data"` section:
218
+
219
+ ```json
220
+ {
221
+ "reward_data": {
222
+ "total_records": 42,
223
+ "domains": ["banking", "retail"],
224
+ "phase_averages": {
225
+ "phase-0": 0.85,
226
+ "phase-1": 0.92,
227
+ "phase-2": 0.65,
228
+ "phase-2.5": 0.78,
229
+ "phase-3": 0.71,
230
+ "phase-4": 0.89,
231
+ "phase-5": 0.74
232
+ },
233
+ "top_patterns": [],
234
+ "exported_from": ".keysarium/memory/"
235
+ }
236
+ }
237
+ ```
238
+
239
+ Individual records are NOT exported (too voluminous). Only aggregates and patterns are included.
@@ -0,0 +1,100 @@
1
+ # Platform Adapter Definitions
2
+
3
+ Central registry for multi-platform support. Maps each supported AI coding platform to its configuration format, output paths, and translation strategy.
4
+
5
+ ## Supported Platforms
6
+
7
+ | Platform | Template | Config Format | Output Structure |
8
+ |----------|----------|---------------|------------------|
9
+ | Cursor | `lib/platform-templates/cursor.md` | Single `.cursorrules` file + optional `.cursor/skills/` | Flat rules file with inlined skills |
10
+ | OpenCode | `lib/platform-templates/opencode.md` | `.opencode/` directory with `config.yaml` + skill files | Directory hierarchy matching `.claude/` |
11
+ | GitHub Copilot | `lib/platform-templates/copilot.md` | `.github/copilot-instructions.md` single file | Single markdown file with all instructions |
12
+
13
+ ## Platform Details
14
+
15
+ ### Cursor
16
+
17
+ | Property | Value |
18
+ |----------|-------|
19
+ | Config file | `.cursorrules` (project root) |
20
+ | Format | Plain text / TOML-style rules |
21
+ | Skills directory | `.cursor/skills/` (optional, one file per skill) |
22
+ | Rules handling | All rules concatenated into `.cursorrules` under sections |
23
+ | Skill handling | Key instructions extracted from SKILL.md and inlined; large skills get separate files in `.cursor/skills/` |
24
+ | Max config size | Recommended < 10,000 tokens |
25
+ | Platform docs | Cursor uses `.cursorrules` for project-level AI instructions |
26
+
27
+ ### OpenCode
28
+
29
+ | Property | Value |
30
+ |----------|-------|
31
+ | Config directory | `.opencode/` (project root) |
32
+ | Config file | `.opencode/config.yaml` |
33
+ | Skills directory | `.opencode/skills/` (one `.md` file per skill) |
34
+ | Rules directory | `.opencode/rules/` (one `.md` file per rule) |
35
+ | Rules handling | Each rule file copied with format adaptation |
36
+ | Skill handling | Each skill gets its own markdown file with instructions |
37
+ | Platform docs | OpenCode uses directory-based configuration |
38
+
39
+ ### GitHub Copilot
40
+
41
+ | Property | Value |
42
+ |----------|-------|
43
+ | Config file | `.github/copilot-instructions.md` |
44
+ | Format | Single markdown file |
45
+ | Skills handling | All skills summarized into sections within the file |
46
+ | Rules handling | All rules merged into the instructions file |
47
+ | Max config size | Recommended < 8,000 tokens (Copilot context window considerations) |
48
+ | Platform docs | GitHub Copilot reads `.github/copilot-instructions.md` for custom instructions |
49
+
50
+ ## Translation Strategy
51
+
52
+ ### Source Structure (`.claude/`)
53
+
54
+ ```
55
+ .claude/
56
+ ├── skills/
57
+ │ ├── explore/SKILL.md
58
+ │ ├── goap-research-ed25519/SKILL.md
59
+ │ ├── problem-solver-enhanced/SKILL.md
60
+ │ ├── frontend-design/SKILL.md
61
+ │ ├── presentation-storyteller/SKILL.md
62
+ │ ├── reverse-engineering-unicorn/SKILL.md
63
+ │ ├── bto/SKILL.md
64
+ │ └── feature-adr/SKILL.md
65
+ ├── rules/
66
+ │ ├── agent-swarm.md
67
+ │ ├── anti-patterns.md
68
+ │ ├── checkpoint-protocol.md
69
+ │ ├── domain-specific.md
70
+ │ ├── file-conventions.md
71
+ │ ├── modular-reuse.md
72
+ │ ├── research-quality.md
73
+ │ ├── model-routing.md
74
+ │ ├── trust-tiers.md
75
+ │ ├── bto-quality-gates.md
76
+ │ ├── feature-adr-conventions.md
77
+ │ └── feedback-loops.md
78
+ └── commands/
79
+ └── *.md
80
+ ```
81
+
82
+ ### Translation Rules
83
+
84
+ 1. **Skills:** Read each `SKILL.md`, extract the core protocol/instructions section. For single-file platforms (Cursor, Copilot), summarize to key points. For directory-based platforms (OpenCode), preserve full content.
85
+
86
+ 2. **Rules:** Read each rule file. For single-file platforms, merge all rules under a unified "Rules" section with subsections. For directory-based platforms, create one file per rule.
87
+
88
+ 3. **Commands:** Commands are Claude Code-specific and generally not translatable. Include a note in generated configs pointing users to the `.claude/commands/` directory for reference.
89
+
90
+ 4. **Shards:** Governance shards (`.claude/shards/`) are pipeline-specific. Include them as supplementary context in platforms that support directory structures; omit from single-file platforms.
91
+
92
+ ## Adding a New Platform
93
+
94
+ To add support for a new platform:
95
+
96
+ 1. Create `lib/platform-templates/<platform-name>.md` following the template pattern
97
+ 2. Add an entry to the "Supported Platforms" table above
98
+ 3. Add a "Platform Details" section with config format, paths, and constraints
99
+ 4. Update `/init-platform` command's `--platform` argument to include the new name
100
+ 5. Test generation with the new platform