A task ledger for agent workforces
Goals in, evidence out, with a lease, an audit trail, and a deterministic ledger in between.
One agent on one task is a solved problem: you hand it a prompt and read the result. The moment you want several agents working a larger goal, the hard part is not the intelligence, it is the bookkeeping. What tasks exist. Which are unblocked. Who is holding which one right now, and whether that one is still alive or wedged. What each agent actually produced, and whether the result is even the right shape. Get that wrong and the classic failure follows: two agents redo the same task, a dependent starts before its blocker finishes, a crashed worker leaves its task claimed forever.
Harness is the part of the Memkeeper family that keeps that book. It is a local-first task ledger, dispatcher, and runner for coordinating AI agents: it tracks goals, tasks, and dependencies; hands work out under leases; records evidence and an append-only audit trail; and accepts or rejects each result against a declared shape. The design choice underneath all of it is that the control path is deterministic. No LLM decides who works on what, or whether a lease has expired. Models do the work inside a task; they never run the ledger.
How it works
- A deterministic ledger. A SQLite store of goals, tasks, dependencies, leases, evidence, and task events. The core is clock-free: the current time is passed in explicitly, so lease math and expiry sweeps are testable instead of wall-clock-dependent. Every mutation is a short, committed transaction, and no LLM call ever runs inside one.
- TTL + heartbeat leases. Claiming a task takes out a lease that a heartbeat keeps alive. From the outside, a crashed agent and a merely slow one look identical, so recovery is driven by TTL expiry rather than by trying to detect liveness. When a lease lapses, the task becomes claimable again. A failed task blocks its dependents instead of letting them run on a broken premise.
- Role-based dispatch. Given a goal and a set of available agent slots, the dispatcher matches claimable tasks to slots by role and claims each under a lease. It decides who works on what, not how, and it does so with no model in the loop.
- Output-envelope acceptance. The runner builds task context, invokes an executor, then validates what comes back against an output envelope. Malformed output, a missing envelope, or an unknown status fails the task loudly, with the raw output preserved as evidence, rather than being waved through as success.
A ladder, not a monolith
Coordinating agents is not one feature you either have or lack. It is a ladder, and most useful work lives on the lower rungs. Harness is built so you can stop wherever the value stops for you.
| Level | What it means |
|---|---|
| 0 · Shared memory | Agents independently read and write durable context through memkeeper. |
| 1 · Shared context | Agents draw from the same indexed repos, docs, and files via ingest and memkeeper. |
| 2 · Policy-gated solo agent | One agent works a goal while Warden denies undeclared capabilities and requires validation gates. |
| 3 · Cooperative task ledger | Goals become tasks with status, dependencies, owners, leases, evidence, and handoffs. The first real harness layer. |
| 4 · Orchestrated workforce | A coordinator decomposes goals, assigns roles, monitors leases, resolves conflicts, and synthesizes the final output. |
| 5 · Autonomous operating loop | Recurring goals with triggers, schedules, budgets, explicit grants, escalation policy, and rollback paths. |
The v0.1 release lands the machinery for rung three and reaches toward four: the durable ledger, TTL leases, role dispatch, output-envelope acceptance, and an optional planner that turns a single goal into a validated task graph (no cycles, no dangling or self-dependencies) and commits it atomically.
Why deterministic control
It would be easy to let a model run the whole thing: read the goal, decide the tasks, pick who does them, judge whether they are done. That is exactly the design we avoided. A ledger that an LLM narrates is a ledger you cannot reason about: the same state can produce different bookkeeping twice, and a bad turn can silently mark a broken task complete. Keeping goals, tasks, leases, dependencies, and acceptance in deterministic code means the coordination layer is inspectable and reproducible, and the model's judgment is confined to the one place it belongs, doing the task, where its output is checked on the way back in.
Run it
The harness binary is a thin command surface over the ledger, planner, dispatcher, and runner. Queries print JSON; mutations print a one-line acknowledgement. The store defaults to $HOME/.harness/ledger.sqlite, and --now <unix> overrides the clock for deterministic scripting.
git clone https://github.com/teflon07/memkeeper-harness
cd memkeeper-harness
cargo build --release
cargo test --workspace
H=./target/release/harness
# A goal, decomposed into a validated task graph automatically.
$H goal create "Ship the auth refactor" --constraints "no breaking changes"
$H plan 1 --claude --role research --role implement --role review
# Or build the graph by hand: task 2 waits on task 1.
$H task add 1 implementer "Apply review feedback"
$H task dep 2 1
# Claim under a 300s lease, heartbeat it, attach evidence, complete it.
$H task claim 1 agent-a --ttl 300
$H task evidence 1 note "looks good, two nits" --agent agent-a
$H task complete 1 agent-a
# Reclaim tasks whose leases expired; dispatch the rest by role.
$H sweep
$H dispatch 1 --slot agent-a:reviewer --slot agent-b:implementer --ttl 300
# Run a claimed task end-to-end with a headless claude agent.
$H run 1 agent-a --claude --model sonnet
Honest edges
This is the newest and least battle-tested piece of the family, and it is worth saying so plainly.
- It is an early prototype. v0.1, with rough edges, not recommended for production yet. The ledger schema and CLI may change before 1.0.
- It is not a sandbox. The runner executes whatever agent command it is given and applies no isolation or capability gating to that work. That is deliberate: containment is a separate contract. Pair the harness with Warden when you need a deny-by-default gate around what those agents can actually do.
- Leases detect absence, not correctness. A TTL tells you a task stopped being heartbeated, not that its work was good. Acceptance is the envelope's job, and the envelope checks shape, not truth. What counts as a correct result is still yours to define.
Memory gives an agent something to stand on. A gate keeps it in its lane. The harness is what lets more than one of them pull on the same goal without pulling it apart.