DEV Community

arun rajkumar
arun rajkumar

Posted on

I Got Obsessed With Killing Scrum. So I Built a World Out of 12 AI Agents.

DEV Weekend Challenge: Passion Edition Submission

This is a submission for Weekend Challenge: Passion Edition

What I Built

I built Bodhiorchard — an open-source platform that replaces Scrum, Jira, and the team wiki with 12 specialised AI agents and a living 3D world you can actually walk around in.

I call the methodology Agent-Driven Development (ADD). Instead of story points, planning poker, and a graveyard of stale Confluence pages, the work lives in one place: a BUD (Business Understanding Document) — a single, vector-indexed source of truth that carries a feature from a Slack conversation all the way to production.

The agents handle the busywork I never wanted humans doing: triage, design drafts, tech plans, standups, test plans, estimation, retros. Your repos show up as trees in an orchard. Features are branches. The whole team walks around as avatars — WASD to move, emotes, houses you upgrade with points you only earn when something actually ships to prod and stays healthy.

The scoreboard is the part I'm proudest of: it rewards quality, not output. Ship a BUD to production: +1. A bug escapes to prod: -1. It scores the things AI is bad at and humans are good at.

Honest status: the platform, the BUD lifecycle, the code-dependency graph, skill profiling, and the 3D world are all live. The fully autonomous execution loop is still being built — today it's agents-assisted, human-in-the-loop. I'd rather undersell it than lie to you.

Demo

Two views ship today: GARDEN (the orchard) and GRAPH (a cross-repo dependency graph with Bus Factor, Threats, and BUD-stage lenses). Two Slack bots sit on top — one triages new requests and kills duplicates before they become tickets; the other answers plain-English questions like "are we on track for go-live?" straight from the live BUD.

Code

Open source, Apache 2.0, self-hosted — it runs on a Mac mini.

GitHub logo mickyarun / bodhiorchard

Bodhiorchard is the open-source, self-hosted alternative to Jira and Linear for AI-native software teams. Specialised agents draft every spec, forecast cycle times, and reason over your real repositories, commits, and pull requests — replacing story points, standups, and stale tickets so engineers can focus on building.

Bodhiorchard™

Ship software, not Scrum ceremonies.

The open-source, self-hosted alternative to Jira & Scrum — AI agents run the process end-to-end, developers earn XP for what actually ships, and your data never leaves your machine.

License Website Python 3.12+ Vue 3 Docker

Website · Quick Start · Why Bodhiorchard · The Twelve Agents · Docs · FAQ

The BUD board — every feature tracked from backlog to production in one view

▶ Watch the demo — a Slack message becomes a scoped, estimated BUD. No sprints, no story points, no standups.


Bodhiorchard replaces sprint, scrum, and Jira ceremony with Agent-Driven Development (ADD) — twelve specialised AI agents handle the busywork (triage, specs, estimates, test plans, retrospectives) while humans keep the decisions that matter, and developers earn XP for the work that actually reaches production. It's a self-hosted Jira alternative for the full lifecycle: intake → spec → design → development → testing → deploy → retrospective. The data plane stays on your hardware; inference runs through your choice of agent CLI…

How I Built It

This is a solo project. Nights and weekends, on my own, because I couldn't leave it alone.

The stack: FastAPI + Python 3.12 on the backend, Vue 3 + PlayCanvas for the 3D world, Postgres + pgvector for the BUD memory, and Redis underneath. Inference runs through Claude Code today, with Ollama and OpenAI on the roadmap so you can bring your own model.

The hard part wasn't the agents. It was the ontology — deciding that a BUD, not a ticket, is the atom of work, and that everything (estimates, design, tests, the retro's estimated-vs-actual drift table) hangs off that one object. Once that clicked, the agents became small. Each one reads BUD context over a local MCP server and writes back only in the three creative phases where a human is still driving.

The 3D layer looks like the toy. It's actually the point. A dependency graph as a spreadsheet is a chore. A dependency graph as an orchard you can lose an afternoon in — that's the thing that made me want to open it every day.

The Passion Angle

I've spent years watching good engineers spend half their week on Jira instead of building. That quietly made me angry. This is the project I built to get that time back — mine first, then anyone else's who wants it.

"Build well. Then go outside." That's the whole idea.

Bodhi means awakening. An orchard is a grove you tend on purpose. The name is the pitch.

If you've ever felt sprints were broken and wanted to do something about it instead of just complaining in retro — clone it, break it, tell me where I'm wrong. That feedback is the only prize I'm actually chasing.

Top comments (17)

Collapse
 
alexshev profile image
Alex Shev •

The useful part of this experiment is that it treats process as something that can be simulated, not just complained about. I would be most curious where the 12-agent world breaks: ownership handoffs, priority conflicts, stale assumptions, or agents optimizing their local role while the whole delivery system gets slower.

Collapse
 
mickyarun profile image
arun rajkumar •

You picked the exact question I built it to answer. Where it breaks first, so far: stale assumptions. Agents don't complain when a decision upstream changes; they keep optimizing against the version they were given. Handoffs turned out easier than I expected because handoff is explicit in the design. Every agent passes structured context forward, nothing lives in a hallway conversation.

Priority conflicts are the honest gap. A human resolves those with judgment and organizational memory, and right now that human is me. I suspect the world always keeps one human in it, and that stopped bothering me once I noticed the human is doing judgment, not ceremony.

Collapse
 
alexshev profile image
Alex Shev •

Stale assumptions are probably the most realistic failure point. The dangerous part is that the agents keep producing coherent work, so the system looks busy even after the premise moved.

I like your point that handoffs are easier when they are designed as explicit objects. The harder layer is exactly what you said: priority conflicts. That is where process stops being routing and becomes judgment.

Thread Thread
 
mickyarun profile image
arun rajkumar •

"The system looks busy even after the premise moved" is the sentence I wish I'd put in the post. That's the failure I'm most scared of, because busy looks like healthy right up until you read the output. The half-answer I've landed on: make the premise a first-class object the agents re-read, not something they inherited once at kickoff. When a decision upstream changes, the BUD changes, and anything downstream still optimizing against the old version gets flagged as stale instead of quietly continuing. It doesn't solve priority conflicts though. You're right that those are judgment, not routing, and that's the one seat I don't think the human ever leaves. Routing I can automate. Deciding what matters more than what, when both are on fire, I can't, and I've stopped trying.

Thread Thread
 
alexshev profile image
Alex Shev •

Making the premise a first-class object is the right direction. The failure mode is not that agents forget to work; it is that they keep optimizing against yesterday's world. Even a simple stale-premise flag would be a big improvement over discovering the mismatch only after a polished deliverable appears.

Thread Thread
 
mickyarun profile image
arun rajkumar •

Exactly the failure mode I built this around. Agents don't stall, they sprint confidently at a target that moved three commits ago, and you only find out when the polished thing lands and doesn't fit. A stale-premise flag is the right instinct, framed as a first-class check rather than a nice-to-have. The premise is already versioned, so a downstream agent can detect the context it's building against has shifted. Making that mismatch loud at generation time, not review time, is the piece that matters. Appreciate the sharp read.

Thread Thread
 
alexshev profile image
Alex Shev •

That stale-premise check is the part I would make painfully visible. Agents can produce a lot of impressive motion after the target moved. A first-class premise object gives the system something concrete to revalidate instead of just continuing the sprint.

Thread Thread
 
alexshev profile image
Alex Shev •

Busy-looking failure is the worst kind because it gives everyone false comfort. Making the premise explicit gives agents a thing to compare against reality, and gives humans a place to see when the work is no longer anchored.

Thread Thread
 
mickyarun profile image
arun rajkumar •

Busy-looking failure is the right name for it, and it is worse than a stall because a stall gets escalated.

The part I have had to keep honest since: the premise object is only useful if something revalidates it without being asked. Versioned and inert is just a record of what you believed. The revalidation has to sit on the path — the agent cannot take the next step until the premise it is building against has been checked against current state — or it becomes another thing that is true in a file and false in the world.

And there is a limit I do not have a clean answer for. I can version the premise. I cannot version the thing the premise was about. A premise that says "the API returns X" stays valid-looking while the API quietly stops. The check confirms the premise has not changed, which is not the same as confirming it is still true.

Thread Thread
 
mickyarun profile image
arun rajkumar • • Edited

@alexshev — picking your stale-premise comment back up; DEV would not take a reply at that depth, so it lands here.

"Impressive motion after the target moved" is the whole failure in five words, and agents only make it worse because the motion got cheap.

One correction to myself, since I argued upthread that revalidation has to sit on the path. The gate does. What it checks cannot be a re-derivation, because almost nothing that invalidates a premise lives in the repo: a customer changed their mind, a counterparty moved a deadline, a rule changed. Code detects none of those. So the premise object's useful fields are not assertions a check can run. They are who is allowed to invalidate this, and when they last confirmed it. Then the thing sitting on the path is arithmetic on a date, which is the only part of this a machine can do honestly, and the painfully visible version is "last confirmed by X, 34 days ago" next to work that assumes it.

That also tells you when to skip the ceremony. A premise nobody outside the team can move does not need the object. The ones worth it are the ones where the person who can change the answer is not in the room.

Thread Thread
 
alexshev profile image
Alex Shev •

Yes—the premise record should expose ownership and freshness, not pretend the system can infer the world from repository state. A visible “confirmed by / confirmed at” field also makes the escalation path explicit: when it goes stale, the agent knows it needs a human answer rather than another internal check.

Thread Thread
 
mickyarun profile image
arun rajkumar •

Needs a human answer rather than another internal check is the sentence, and it names the failure better than anything I wrote in the article. An agent that notices its premise is stale and responds by deriving harder is the busy-looking failure you named months ago, now with a reason.

Which makes ownership the load-bearing field and freshness only the trigger. An agent that knows a premise is 34 days old and does not know who can refresh it will do the one thing available to it, which is more internal work. Freshness without an owner is a number that makes the agent anxious and changes nothing.

One place I would shrink the claim. The owner is usually not on the team. It is a customer, a counterparty, a bank, someone with no channel an agent can reach. So the honest output is not ask the owner, it is stop and name the owner to the nearest human. Smaller than it sounds, and it is the version that survives contact, because the alternative quietly assumes an escalation path that does not exist.

The field I keep leaving out and should not. How long the premise is good for by default, declared when it is created, separate from when it was last confirmed. A premise confirmed yesterday about a deadline in March is fresher than one confirmed yesterday about this week's exchange rate. One staleness threshold across a mixed set of premises is wrong for nearly all of them, and it will be wrong in the generous direction for exactly the volatile ones that matter. Volatility is declared, not measured, for the same reason the ownership is: the thing that moves it is outside the repo.

What I still cannot do is detect a premise whose owner confirmed it honestly and whose world then changed inside the window. The date arithmetic reports green and it is right to.

Thread Thread
 
alexshev profile image
Alex Shev •

Exactly — that suggests a premise needs two independent fields: a declared validity horizon and an escalation boundary. The first tells the system when evidence may have decayed; the second tells it whether refresh is even possible. If the owner is outside the reachable system, the correct action is not ‘ask’ as a generic verb, but a structured stop: name what changed, who could resolve it, and the nearest human who can carry the question. That makes the unknown executable without pretending the agent can close it.

Thread Thread
 
mickyarun profile image
arun rajkumar •

@alexshev — two independent fields is the thing I was circling and did not separate. A validity horizon on its own produces an agent that knows its premise is stale and has nowhere to take that, which is the deriving-harder failure with better instrumentation. Agreed, and the second field is the one doing the work.

One change I would make to where the second field lives. Reachability is a property of the environment, not of the premise. Whether a counterparty answers email, whether a bank has a channel, whether the person who knew has left — all of that moves without anything happening to the premise it was written on. Store it on the premise and it goes stale on its own schedule, and then you have a stale field about staleness, which is the worst version of this.

So let the premise hold the owner's identity and let the boundary be resolved at stop time. The premise says this came from the treasury team at Bank X. The stop asks, now, whether there is a channel to Bank X, and if there is not, it walks up to whoever holds that relationship. Same output, and the part that rots is computed fresh instead of remembered.

The declared horizon I would make mandatory at creation and un-defaultable, because a default will become one number applied to a mixed set and the whole point is that a premise about a March deadline and a premise about today's exchange rate cannot share a threshold. If the thing creating the premise cannot say how long it is good for, that is information, and it should be recorded as unknown rather than as thirty days.

Thread Thread
 
alexshev profile image
Alex Shev •

A declared validity horizon makes the environmental assumption visible, but it also needs an owner and a revalidation trigger. I would model it as an expiring lease with the last successful check and the fallback behavior recorded beside it. Then a stop-time resolver can distinguish an expired assumption from a transiently unreachable dependency.

Thread Thread
 
mickyarun profile image
arun rajkumar •

@alexshev — the lease is the right object and it buys the thing my version did not have, which is somewhere to put what happens when it runs out.

Two changes to the fields.

Last successful check cannot separate expired from unreachable. After one failed revalidation and after fifty it reads the same, and the resolver you want needs the difference: a dependency that answered yesterday and not today is a different event from one that has not answered since August. So store the failures, or at least the count and the first one. That is also the number that decides whether to walk up to a human now or wait, which is what the whole structure exists for.

Fallback behaviour I would move off the premise. It gets declared at creation by whoever created it, and that is the party least able to say what should happen in a situation they have not met. Mandates work the other way round in payments. What happens when a direct debit's authority lapses is set by the scheme that clears it, not by the merchant who collected it, and the reason is that the consequence lands on the scheme. The equivalent is that fallback belongs to the surface acting on the premise, because the cost of acting on a stale one is paid there. Same premise, two consumers, two correct fallbacks.

What I still cannot do is the case underneath both of these: an owner who confirms honestly and a world that moves anyway. The lease expires on schedule and the premise was already wrong on day two. Nothing in the record sees that, and I have stopped expecting it to.

Collapse
 
mickyarun profile image
arun rajkumar •

@alexshev — a post went up today that you are credited in, though the premise-lease argument is not the spine of it.

dev.to/mickyarun/i-have-four-contr...

It is about the four controls in my threads that stop measuring once people know they are there. Your version of the problem is the one case that does not fit the pattern: a premise whose owner confirms honestly and whose world moves anyway is not adapting to being watched, it is just wrong. That is a different failure and I have left it out rather than bent it to fit. Worth its own write-up.