kli

Task graphs and pattern playbooks for Claude Code.

what it is

Thousands of tasks. Months of context. One queryable graph.

kli writes every task, observation, and file edit as an immutable event in an append-only log. State is computed from events, never stored. After months and thousands of tasks, the graph holds everything your agents learned. Any agent can query it.

Claude Code records conversation history in JSONL and has built-in task support. kli extends that across months and repos. Agents and humans change plans, update specs, pick up where any prior session left off.

Patterns emerge from completed work. Each carries a helpful and harmful score. High-scoring patterns surface in future sessions. Low-scoring ones sink in rank.


the cycle

Research. Plan. Implement. Reflect.

01

research

Read the code. Spawn agents to search across repos. Record what you find as observations. They persist across sessions.

02

plan

Break work into phases with dependencies. Each phase has success criteria. kli scaffolds the DAG in one expression.

03

implement

Work phase by phase. Write tests first, then code, then verify. kli tracks which files each session touches.

04

reflect

Review what the session did from its event log. Mark patterns that helped. Demote ones that didn't. Next session benefits.


built with itself

The task graph that built kli.

Every node is a real task from kli's own development. Hub nodes are planning tasks; satellites are implementation phases. Hover to inspect. This graph was queried live from kli's task server.

hub
complete
active
phase-of
depends-on
related-to
topic

your control center

Not a viewer. A control surface.

kli dashboard launches a local control surface. Browse ready tasks, inspect plans, pin what you're working on, take notes in the scratchpad. Complete phases and cut edges. All from the browser.

The graph view shows every task and edge. Health checks flag stale forks and orphaned phases. Topic clusters group related tasks without manual tagging. All state derives from the event log. Mutations show up immediately.

$ kli dashboard

Dashboard listening on http://localhost:9091

Frontier: 8 ready / 1,043 total tasks
Health: no stale phases
Graph: 1,043 nodes, 9,217 edges
Sessions: 1 active
frontier
activity
stats
sessions
plans
clusters
graph
health
8 ready1,006 completed29 dormant·1,043 total
Pick Up Where You Left Off (2)
FIX-TQ-CORE-BUGS
3 sess · 8 obs
Latest Handoff
SSE encoding bug fixed across 3 call sites. CSRF meta-tag approach chosen over middleware. Next: modal overlay for blog code blocks...
EXPLORE-LOL-REACTIVE4 sess · 27 obs
Pinned (1)
PLAN-KLEISLI-BLOG
Ready to Work (6)
Task Graph (3)
ADD-SPREAD-ACTIVATIONWRITE-CRDT-PROPERTY-TESTSFIX-VECTOR-CLOCK-MERGE
Dashboard (3)
DASHBOARD-WEBGL-GRAPHADD-PQ-PIPELINE-STEPSSTYLE-DASHBOARD-DARK
scratchpad
TQ core done — need spread activation weights. Then CRDT property tests before blog post...
1,043 tasks · 1 pinnedlocalhost:9091

coordination without messages

Agents leave traces. Others adapt.

No message bus. No coordination protocol. Agents write events to a shared log. Other agents read those traces and adjust. Biologists call this pattern stigmergy.

01

Deposit

Every tool call, file edit, and observation appends to the task log. Session fingerprints record which tools ran and which files changed.

{type: tool.call, tool: Edit,
file: state.lisp, sid: s-3979..}
02

Accumulate

CRDTs merge concurrent writes without locks. The task graph gains edges and observations with each session. File activity records track who touched what and when.

G-Set
observations
OR-Set
edges
LWW
claims
03

Discover

A new session joins and bootstrap runs. It shows who's working nearby, which files were recently edited, which phases are orphaned. All from replaying the shared log.

state.lisp edited by s-3979
task: FIX-TQ-CORE-BUGS
last: "refactored edge sever"

Five trace types make this work: event logs (append-only JSONL), session fingerprints (tool and file vectors), file activity records (edit history), active PID tracking (liveness), and departure events (orphan detection). kli ships with Claude Code agent team support. Session fingerprinting groups teammates, detects file conflicts across teams, and picks up orphaned phases when sessions crash. kli reads the environment variables Claude Code already sets. No new abstractions needed.


the math underneath

Structure with proven convergence.

CRDTs guarantee that concurrent edits merge to the same state regardless of ordering. Coordination follows from structure.

state = foldl apply ∅ events
E X (transition)

Event-sourced state

State exists only as a fold over events. Given an event E, apply-task-event produces the next state. Given a query, the system replays the log and returns the current CRDT values. The event log is the sole persistent artifact. State is computed on read, never stored.

merge(a, b) = merge(b, a)
merge(a, a) = a
merge(a, merge(b, c)) = merge(merge(a, b), c)

CRDT convergence

Commutativity, idempotence, associativity. These three properties guarantee that distributed sessions always converge to the same state regardless of event ordering. G-Sets grow monotonically. OR-Sets support removal via tombstones. LWW-Registers break ties by timestamp. No locks. No coordination protocol. Convergence follows from the algebra.

t ∼ t' ⟺ label(t) = label(t')
Tasks/∼ induces Topics
equivalence classes → topic graph

Emergent topology

Nobody assigns topic clusters. A labeling function parses each task name into a short stem. Tasks that share a stem are grouped. It is a simple heuristic, but the resulting partition induces the topic graph: edges connect co-grouped tasks without manual tagging.

Event sourcing makes this coordination possible. Agents replay the log, observe the current graph, read traces left by predecessors, and adapt. CRDTs guarantee concurrent writes converge. The quotient topology reveals structure agents collectively build. At a thousand tasks, these guarantees stop being academic.


install

One binary. Zero telemetry.

kli ships as a single native binary. No Python, no Node, no Docker. One external dependency: a local embedding model for observation search.

Your data stays local. Always.

$ curl -fsSL https://kli.kleisli.io/install | sh
$ cd my-project && kli init

Kleisli initialized in /home/user/my-project

Tasks: .kli/tasks/ event-sourced, CRDT merge-safe
Patterns: .kli/playbook.md helpful/harmful scoring
Dashboard: http://localhost:9091 task graph visualization
Embeddings: active ollama/nomic-embed-text

Claude Code: 7 skills, 11 commands, 6 hooks installed