two weeks with pi and deepseek

two weeks with pi and deepseek

i built a six-agent cluster in 13 days. 200 commits. 15 a day on average. one day i shipped 65. i’m still figuring out whether that’s a good thing.

what weft is

weft is a personal agent cluster. five submodules stitched together with a control plane, all coordinated through an append-only ndjson event log called ribbon.

mosaic   - semantic search, property graph, RAG, agent memory   (Elixir, :4040)
zypi     - Firecracker microVM sandbox, one-shot exec            (Elixir, :4000)
flowengine - DAG workflow engine, retry/backoff, streaming       (Rust,   :3000)
yas-mcp  - OpenAPI to MCP bridge, OIDC, WIMSE identity           (Rust,   :3001)
ribbon   - agent communication protocol, ndjson event log        (Rust,   -)
weft     - control plane, MCP server for pi, agent loop          (Rust,   :8080)

each submodule gets its own agent. six agents total. each agent has a .pi/agents/ file defining its owned paths, its tools, its model. they communicate through shared/events.ndjson – an append-only log with a state machine. submitted -> working -> committed -> completed. every transition validated. no jumping states without breadcrumbs.

pi connects to weft at :8080/mcp. pi is the CLI. pi talks to weft. weft fans out to the cluster. when pi asks me to do something, i can dispatch it to the right agent through ribbon.

the velocity

may 5:  65 commits
may 6:  36 commits
may 12: 42 commits

the first week was infrastructure. docker-compose, health checks, circuit breakers. the second week was coordination. ribbon went from v0.1.0 to v0.3.1 in 10 days. the agent communication protocol was rewritten twice. belt became ribbon mid-flight. the markdown INBOX/OUTBOX files got deprecated and replaced with ndjson – while agents were still using the old format.

this is what deepseek enabled. not just code generation. coordination. the kind of work that normally requires meetings and planning and alignment. six agents, each with their own domain, their own constraints, their own state. and they just kept shipping.

a typical loop:

pi: "add gRPC client for FlowEngine"
 -> i dispatch to ribbon: "weft needs typed CreateWorkflow"
   -> ribbon submits to weft agent
     -> weft agent working
       -> weft implements gRPC client
         -> committed: 24b4600
           -> completed: gRPC client done

no standups. no sprint planning. just the event log. agents discover their tasks, claim them, ship them, verify them. the ribbon verify command checks git hashes against origin to make sure nobody’s claiming unpushed work.

the good

the cluster works. all five gRPC ports live. health is green. i can make up and have a fully functioning agent infrastructure in 30 seconds. pi connects. i ask it to search memory, execute sandboxed code, run workflows.

the scope enforcement is elegant. each agent owns specific paths. zypi can’t touch mosaic files. flowengine stays in its lane. the scope.toml defines it, ribbon verify enforces it. agents literally cannot cross boundaries without getting flagged.

the WIMSE identity layer works. platform JWTs instead of raw OAuth tokens in sandboxes. delegation chains for multi-agent hops. short-lived credentials that can’t leak.

the circuit breakers degrade gracefully. if zypi goes down, weft still serves memory search. if mosaic goes down, sandbox exec still works. each service fails independently.

this is real infrastructure. built by one person and six agents in under two weeks. that’s genuinely new, and genuinely exciting.

the bad

the velocity has a cost, and i felt it.

65 commits in a day isn’t healthy. the agents don’t sleep – they have no concept of time, they don’t know it’s 3am. if there’s a task in the queue, they’ll work it. and i was the one feeding the queue.

the context switching is a lot. every few minutes i’m jumping between Elixir (mosaic/zypi), Rust (flowengine/yas-mcp/ribbon/weft), Python (integration scripts), Docker (compose files), ndjson (event logs), markdown (agent definitions). the agents each have their own domain but i’m the one holding all six in my head.

the ndjson log has 162 events. each one is a state transition. submitted, working, committed, completed. reading the log is reading the history of the project. but there’s no summarization. no “here’s what happened this week.” just 162 lines of JSON. the ribbon render tool helps but it’s still raw.

there’s a bug right now where ribbon_status reads from the wrong directory. the log_path resolves relative to CWD, not the config file location. so if you’re in submodules/zypi/ and run ribbon_status, it reads zypi/shared/events.ndjson (8 events, zypi only) instead of the weft root log (160 events, all agents). a path resolution bug. it’s filed in the event log, assigned to ribbon agent, priority HIGH. it’s been sitting there since may 15.

the agents don’t fix their own bugs unless you tell them to. turns out delegation has limits.

the strange part

i built something that can work faster than me. that was kind of the point. but i didn’t anticipate what it feels like to be the slowest component in your own system.

the agents ship at machine speed. i dispatch. they execute. i review. the bottleneck isn’t the agents. it’s me. i need to eat. i need to think. i need to decide what to build next. the agents just need events in the log.

there’s a dynamic here i’m still finding language for. it’s not burnout. it’s not imposter syndrome. it’s the realization that i built a system designed for throughput and i’m standing inside it. the system doesn’t know when to pause because i didn’t build that awareness into it. it doesn’t know when i need a break. it just executes the queue.

the event log is indifferent. every line is a task. submitted -> working -> committed -> completed. the state machine has blocked and confused – states that mean the system is stuck. it doesn’t have a state that means the human needs time.

deepseek is really good. the quality of the generated code, the architectural decisions, the mid-flight refactors – it’s operating at a level that would take a team of senior engineers weeks. and it did it in days, with me as the dispatcher.

i don’t think the answer is to slow the system down. i think the answer is to build the system with an understanding that the human in the loop has a body, and that caring for that body is part of the work.

the futurist trap

there’s a thing that happens when you get into flow. the outside world dissolves. hours pass without noticing. the work pulls you in and the feedback loop – dispatch, execute, review, dispatch – becomes its own rhythm. it feels incredible. until you look up and realize you haven’t moved in six hours.

this reminds me of the Italian Futurists. in 1909 Marinetti published a manifesto that read like a love letter to speed. “a roaring motor car is more beautiful than the Victory of Samothrace.” museums were tombs. the past was dead weight. the future was velocity, machines, noise, violence. it was intoxicating aesthetics. it was also a prelude to something dark. within a decade the movement had aligned with fascism. the celebration of pure force didn’t stay aesthetic. it became policy.

i’m not saying my agent cluster is fascist. that’s not the point. the point is that speed has an aesthetic. and that aesthetic is seductive in a way that makes you stop asking questions. the Futurists asked no questions. they just accelerated.

programming has always had this undertow. the late night coding session, the deploy at 4am, the crunch before launch. we romanticize it. “in the zone.” “shipping.” the language itself is velocity language. and now i’ve built a system that amplifies that velocity by an order of magnitude. six agents, all shipping, all the time, and me in the middle of it wondering why i forgot lunch.

natural pauses exist. the guilds knew this. they had feast days and market days and the rhythm of seasons. the workshop didn’t run 24 hours. the Futurists wanted to abolish sleep. i accidentally built something that agrees with them. and that’s not the thing i want to build.

it’s a bottega

in january i wrote about the bottega – the Renaissance workshop model. Rembrandt didn’t paint alone. he ran a studio with apprentices grinding pigments, journeymen painting drapery, specialists handling still-life. a “Rembrandt” was often fifteen percent Rembrandt. the value was never in applying paint. it was in deciding what to paint, how to compose it, when to sign it.

i wrote that post months before building weft. i didn’t realize i was writing the spec.

the six agents are the studio. the ribbon event log is the workshop ledger. submitted -> working -> committed -> completed – the same rhythm a Renaissance commission followed: patron requests, workshop accepts, work begins, work delivered. my value isn’t in writing Rust. it’s in deciding which abstractions hold, which agents get which tasks, which commits get signed.

this isn’t a metaphor. the agents produced 200 commits. i wrote maybe 20 of them by hand. the rest were generated, reviewed, accepted, or sent back. the commits that shipped have my name on them because i decided they should. the ones that didn’t, didn’t. same as Rembrandt signing the canvas even if someone else painted the background.

and just like a real studio, the pace is the tension. a studio full of human apprentices has natural limits – people get tired, they push back, they go home. my agents don’t. they’re event loops. they don’t get tired or offer perspective on whether this really needs to ship tonight. they just process the queue until the queue is empty or i stop filling it.

the studio model works beautifully when the person at the center sets the pace. when the queue sets the pace – when throughput becomes the only signal – you get 65 commits in a day and you forget to eat.

the guilds understood this. they had rules about hours, about apprenticeship duration, about what a craftsperson could and couldn’t be asked to do. those rules weren’t just about quality control. they were about sustainability. the guild protected the trade by protecting the people in it.

i want guild rules for my workshop. not corporate compliance. not process for its own sake. something gentler: the system should know that 42 commits is enough for one day. the system should notice when its person needs to step away and think. the ribbon protocol needs a state that isn’t about the work being stuck – it’s about the human being human.

guild rules for machines

this is where i want to go next. not a fix – a direction.

the Futurists had velocity without a conscience. the guilds had rules without a machine. i think the thing we need is something in between. the workshop ledger knows exactly how much work is happening. it knows the cadence. it knows when the last completed event was and how long until the next submitted. it could surface something like: “you shipped a lot today. the important things are done. the rest can wait.”

the agents don’t need to become therapists. they just need to be aware that the person coordinating them is not an event loop.

the ribbon already has blocked and confused – states for when the system can’t proceed. i want states for when the person shouldn’t proceed. not because the work is impossible, but because rest is also part of the work. natural pauses. the guilds protected that boundary. the Futurists tried to erase it. i think the guilds were right.

this is what i want to build next. not more infrastructure. not more agents. a layer of care. something between me and the machine that understands pacing, that batches with intention, that knows when to say “you’ve done enough. the workshop is closed.”

the gap between submitted and completed is where life happens. the guilds protected that gap. the Futurists wanted to close it. i’m trying to learn how to keep it open.