Koko Development
Use this skill when working on the Koko Elixir project — the BEAM co-resident agent alongside joelclaw.
When to Use
- Building new GenServers, supervisors, or event handlers in Koko
- Implementing workloads (health pulse, event digest, shadow executor)
- Wiring Koko to new Redis channels or joelclaw events
- Debugging OTP supervision trees or process crashes
- Comparing Koko shadow results against TypeScript equivalents
Triggers: koko, elixir agent, beam, otp, shadow executor, koko workload, koko event, mix
Project Location
- Repo:
~/Code/joelhooks/koko (github.com/joelhooks/koko)
- Host: Overlook (Mac Mini M4 Pro), accessible via
ssh joel@panda
- AGENTS.md: Full context in repo root
ADR Awareness
Always check relevant ADRs before implementing. Koko's architecture is ADR-driven.
Before adding a new workload: Check ADR-0117 for the workload plan and ADR-0118 for shadow execution patterns.
Before changing Redis integration: Check ADR-0116 for the bridge protocol and phase boundaries.
Before any architectural change: Propose or update an ADR in ~/Vault/docs/decisions/.
Key Constraints
- Koko is read-only (Phase 1). PubSub observer only. No LPUSH drain, no authoritative writes.
- Shadow results only. Write to
joelclaw:koko:shadow:<function> in Redis or local files. Never to Typesense, Todoist, gateway, or any production state.
- If Koko crashes, nothing breaks. The TypeScript stack doesn't depend on it.
- Redis at localhost:6379 — k8s NodePort on Overlook.
Development Commands
# Run
cd ~/Code/joelhooks/koko
mix deps.get
mix run --no-halt
# Test
mix test
# Interactive
iex -S mix
Koko.events_seen()
# Format
mix format
# Remote (from another machine)
ssh joel@panda "cd ~/Code/joelhooks/koko && mix run --no-halt"
OTP Patterns to Follow
- One GenServer per concern — health checker, event accumulator, shadow runner are separate processes
- Supervisor strategy:
one_for_one unless processes are coupled (then rest_for_one)
- Pattern match event types in
handle_info — don't use if/else chains
- Use
Logger.info("[koko]") prefix for all log output
- Crash early — let supervisors handle recovery, don't defensive-code around failures
Implementation Phases
Phase 1: Passive Observer (current)
- Subscribe to
joelclaw:gateway:events via PubSub ✅
- Log and classify events ✅
- Next: Add health pulse GenServer (Workload 1 from ADR-0117)
Phase 2: Dedicated Channel
- Create
joelclaw:koko:events for claimed work
- TypeScript fans out to Koko:
LPUSH joelclaw:koko:events <payload>
- Koko writes results to
joelclaw:koko:results
Phase 3: Shadow Executor
- Mirror select Inngest functions as Koko GenServers
- Same inputs, parallel execution, compare results
- Shadow log at
joelclaw:koko:shadow:<function>
Phase 4: Graduation
- Koko handles a workload more reliably than TypeScript
- Survived 30 days without manual intervention
- DX is enjoyable
1---
2name: koko
3displayName: Koko Development
4description: Develop and extend Koko — the Elixir/OTP agent living alongside joelclaw. Covers OTP patterns, Redis bridge protocol, shadow execution, and workload implementation.
5version: 1.0.0
6author: joel
7tags: [elixir, beam, otp, koko, agent]
8---
9
10# Koko Development
11
12Use this skill when working on the Koko Elixir project — the BEAM co-resident agent alongside joelclaw.
13
14## When to Use
15
16- Building new GenServers, supervisors, or event handlers in Koko
17- Implementing workloads (health pulse, event digest, shadow executor)
18- Wiring Koko to new Redis channels or joelclaw events
19- Debugging OTP supervision trees or process crashes
20- Comparing Koko shadow results against TypeScript equivalents
21
22Triggers: `koko`, `elixir agent`, `beam`, `otp`, `shadow executor`, `koko workload`, `koko event`, `mix`
23
24## Project Location
25
26- **Repo**: `~/Code/joelhooks/koko` ([github.com/joelhooks/koko](https://github.com/joelhooks/koko))
27- **Host**: Overlook (Mac Mini M4 Pro), accessible via `ssh joel@panda`
28- **AGENTS.md**: Full context in repo root
29
30## ADR Awareness
31
32**Always check relevant ADRs before implementing.** Koko's architecture is ADR-driven.
33
34| ADR | Title | Status | URL |
35|-----|-------|--------|-----|
36| 0114 | Elixir/BEAM/Jido Migration | proposed | [joelclaw.com/adrs/0114-elixir-beam-jido-migration](https://joelclaw.com/adrs/0114-elixir-beam-jido-migration) |
37| 0115 | Koko Project Charter | proposed | [joelclaw.com/adrs/0115-koko-project-charter](https://joelclaw.com/adrs/0115-koko-project-charter) |
38| 0116 | Redis Bridge Protocol | proposed | [joelclaw.com/adrs/0116-koko-redis-bridge-protocol](https://joelclaw.com/adrs/0116-koko-redis-bridge-protocol) |
39| 0117 | First Workloads | proposed | [joelclaw.com/adrs/0117-koko-first-workloads](https://joelclaw.com/adrs/0117-koko-first-workloads) |
40| 0118 | Shadow Executor | proposed | [joelclaw.com/adrs/0118-koko-shadow-executor](https://joelclaw.com/adrs/0118-koko-shadow-executor) |
41
42**Before adding a new workload**: Check ADR-0117 for the workload plan and ADR-0118 for shadow execution patterns.
43
44**Before changing Redis integration**: Check ADR-0116 for the bridge protocol and phase boundaries.
45
46**Before any architectural change**: Propose or update an ADR in `~/Vault/docs/decisions/`.
47
48## Key Constraints
49
501. **Koko is read-only (Phase 1).** PubSub observer only. No LPUSH drain, no authoritative writes.
512. **Shadow results only.** Write to `joelclaw:koko:shadow:<function>` in Redis or local files. Never to Typesense, Todoist, gateway, or any production state.
523. **If Koko crashes, nothing breaks.** The TypeScript stack doesn't depend on it.
534. **Redis at localhost:6379** — k8s NodePort on Overlook.
54
55## Development Commands
56
57```bash
58# Run
59cd ~/Code/joelhooks/koko
60mix deps.get
61mix run --no-halt
62
63# Test
64mix test
65
66# Interactive
67iex -S mix
68Koko.events_seen()
69
70# Format
71mix format
72
73# Remote (from another machine)
74ssh joel@panda "cd ~/Code/joelhooks/koko && mix run --no-halt"
75```
76
77## OTP Patterns to Follow
78
79- **One GenServer per concern** — health checker, event accumulator, shadow runner are separate processes
80- **Supervisor strategy**: `one_for_one` unless processes are coupled (then `rest_for_one`)
81- **Pattern match event types** in `handle_info` — don't use if/else chains
82- **Use `Logger.info("[koko]")`** prefix for all log output
83- **Crash early** — let supervisors handle recovery, don't defensive-code around failures
84
85## Implementation Phases
86
87### Phase 1: Passive Observer (current)
88- Subscribe to `joelclaw:gateway:events` via PubSub ✅
89- Log and classify events ✅
90- Next: Add health pulse GenServer (Workload 1 from ADR-0117)
91
92### Phase 2: Dedicated Channel
93- Create `joelclaw:koko:events` for claimed work
94- TypeScript fans out to Koko: `LPUSH joelclaw:koko:events <payload>`
95- Koko writes results to `joelclaw:koko:results`
96
97### Phase 3: Shadow Executor
98- Mirror select Inngest functions as Koko GenServers
99- Same inputs, parallel execution, compare results
100- Shadow log at `joelclaw:koko:shadow:<function>`
101
102### Phase 4: Graduation
103- Koko handles a workload more reliably than TypeScript
104- Survived 30 days without manual intervention
105- DX is enjoyable