← 中文版 / Read in Chinese

Vibe Coding: From Chaos to Order Takes More Than Agents

Cover: an agent's scattered output passes through a task board, a testing station, and a human acceptance gate, converging into an ordered, complete project

Over the past few months I've been building my side-project apps with Codex and Zcode, and the coding ability of large language models has genuinely stunned this software engineer with a decade-plus of "classical" programming behind him. Ideas that once lived only in my head became real products through Codex and Zcode, and that feeling brought back my passion for building software. ("No way around it — I'd been battered enough by the heavy processes of big tech.")

Three Superpowers — High Intelligence, Fast Delivery, Computer Use — Beat Classical Programming

First, the breadth of knowledge and intelligence. Whether I'm building for iOS, macOS, Node.js, a Chrome extension, or an FCP plugin, it handles everything with ease.

Second, delivery speed. Once it understands my intent, it outputs a working product almost immediately. If I hit a bug while using it, a quick conversation later the fixed version pops out just as fast.

Third, Computer Use. The first time I used Codex's Computer Use, I was stunned: it opened the caption animation library of a video editor, studied it, and then wrote an FCP plugin that reproduced similar animations — fully automatic. The first version it produced was only passable, but doing the same thing myself would have taken at least half a month, and I would hardly have matched what the model delivered on its first try.

A large model is like a knowledgeable, never-tiring, quick-responding engineer assistant that complements me very effectively. I propose ideas; it discusses them with me round after round until we settle on a plan, and then quickly ships a product. That kind of joy makes it hard for me to imagine how I ever lived with hand-typing every line of code.

The Chaos That Followed Made Me Think About Three Hidden Problems Behind Vibe Coding

As I kept iterating on the product, I found that this human-plus-Agent development model was plunging me into disorder instead.

Many days, all of my time went to three things: recalling when and in which sentence I had specified the "optimize the build script" requirement; checking whether that claim of "done" actually counted as done; and making the calls that Agents dare not — and should not — make themselves.

I went from an engineer who builds everything with creativity to a project manager who watches everything with his own eyes. My enthusiasm was draining away.

After serious reflection, I traced it back to three causes:

One: state is invisible. Requirements are scattered across conversations. Who raised a requirement, how far it has progressed, why it was decided that way at the time — close the chat and the context evaporates. Next time you either keep it all in your head or do archaeology through chat history. Agents don't lack execution power; what they lack is management of that execution power.

Two: quality is uncontrollable. An Agent saying "done" and you daring to believe it are two different things. Writing "run the tests first" in a prompt, or "never auto-push" in a skill — these are all advice. The model will most likely comply, but nothing guarantees it. Compliance is probabilistic, so verification has to be exhaustive: behind every "done" stands a round of manual acceptance — did the tests really run? Were the edge cases handled? Did it break something else along the way? Every time AI output speed multiplies, verification cost multiplies with it, and the person responsible for verifying remains only you. You become the only hard constraint on the entire pipeline — which is exactly why quality is the hardest thing to control.

Three: decisions are unmanaged. Agents at work will inevitably run into moments that need a human call. The decisions for every requirement or bug are scattered across conversations: either the work sits blocked waiting for your input, or it proceeds anyway and "we'll deal with it at review time". Over time, no decision is traceable anymore.

None of these three problems depends on Agent count — a single session already collects them all. But when you want to run multiple Agents in parallel like managing a dev team, the problems get amplified in sync.

Interestingly, human dev teams ran into exactly these problems long ago; their names are division of labor, boundaries, handoffs, verification, and traceability. The human answers were Jira, Git Flow, and code review.

So in the "human + Agent" era of Vibe Coding, is there a corresponding answer? Of course you could let the Agents keep their own records and manage themselves, and ask them for progress when you need it. But that approach is unacceptable to me, for one fundamental reason: every conversation with an Agent is a cost, and that money should be spent on having it do creative work for me — not on round after round of deterministic work like status confirmation. Besides, every conversation makes the Agent think for a while; if I ask it to file a bug ticket and it responds with a lengthy essay, that experience is unacceptable to me too.

So, as a software engineer who enjoys building wheels, I developed "Agent Team Board" (ATB for short), attempting to provide a comprehensive solution to the problems above. ATB is open source — feel free to take a look and give it a try.

ATB Embeds the Requirements Board into the Git Repository

ATB is not yet another framework that "lets Agents develop autonomously" — quite the opposite. From day one it assumes Agents cannot be autonomous. What it does is embed the requirements board into the Git repository, using an explicit state machine and execution spec, so that Agents collaborate like a real dev team under human gatekeeping.

One of my core design decisions: all requirement content is represented as files, committed into Git together with the code. No external database, no cloud service, no extra board page to maintain — just one more directory in your business project.

The benefit of this design is that requirements share the same Git platform as the business code, and the all-text architecture is very friendly to both humans and Agents, while Git's history and version management are more than powerful enough. The trade-off you can foresee: once the data volume grows large, query performance will become the first bottleneck — indexing can wait until then.

The Human–Agent Boundary Doesn't Rely on Prompts, but on Enforced Hard Constraints

ATB uses a simple state line to clarify "what Agents may do, and what humans do":

submitted → accepted → planned → in-progress → done
     ↑                          ↑               ↑
     └── human acceptance ──────┴── human sign-off ──┘
                              Agent claims

The key of this line is not how many states there are, but that the transition permission of every state is strictly limited:

Transition Operator Meaning
→ submitted Anyone / Agent A human (or an Agent) raised a requirement
submitted → accepted Human A human judges that this requirement is worth doing
accepted → planned Human A human confirms the technical plan and test cases are ready
planned → in-progress Agent An Agent claims the item and starts implementing
in-progress → done Human A human confirms the work is complete and passes acceptance

An Agent cannot make any key decision in a human's place: it cannot accept requirements, cannot confirm completion, cannot skip the planned state and start coding, and cannot make its own trade-offs when stuck.

This is not distrust of Agents — it is a clear division of labor. Agents excel at executing well-defined instructions; humans excel at defining which instructions are worth executing. Mixing the two is the root cause of most "the Agent wrecked my project" stories.

ATB also provides hook scripts that can restrict which files and commands an Agent may execute, ensuring it can never accept requirements or mark them complete on its own. Blocking the flow at the tool layer is far more reliable than writing "you are forbidden from changing requirement states" a hundred times in a prompt.

Make Requirements the Unit of Context Isolation, Eliminating Context Pollution and Bloat

A main session (the dispatcher) can batch-dispatch multiple requirements in the planned state at once; each sub-Agent (worker) claims one of them and completes it independently. Each worker loads, on demand, only the documents of the requirement it claimed for analysis or development, and when it finishes, nothing is passed back to the main session or on to the next sub-Agent.

A requirement is a natural carrier of context isolation — just like human teams working on a project. On this point the two worlds converge.

As for whether this truly eliminates context pollution and bloat, I can only say that in principle it should work, but I haven't run an A/B test. So far the results look stable: no sudden drops in capability, and the context window usage shown in the Agent has stayed at a fairly low level.

Serial or Parallel AI — That Is the Question

I know many people like having multiple Agents develop multiple requirements simultaneously, believing it improves efficiency — after all, human dev teams work that way too.

But I believe in the AI era this needs to be viewed separately:

  1. The requirement analysis phase can indeed run in parallel, because the output at this stage is requirement documents — different Agents produce different documents, with no conflicts to merge, so you can parallelize boldly.
  2. The implementation phase should not be parallelized. The reason is simple: the code quality of AI Agents is not yet stable enough to let two Agents modify the same codebase at the same time with confidence. File conflicts, dependency ordering, interface inconsistencies — things human teams coordinate carefully — only become harder for Agents.
  3. The verification phase is similar to analysis and can also be boldly parallelized.

So ATB uses an impl mutex to protect the execution phase. The dispatcher can line up multiple workers, but only one actually runs; the others block at $ATB batch next and continue only after the previous one finishes and the mutex is released. This is not "cannot parallelize" but "conservatively parallel" — batch dispatch keeps a clear division of labor and task list, while execution stays serial for safety.

I hope future progress in large models will let me drop this concern and restriction. After all, "fast and good — who wouldn't want that?"

Making TDD an Enforced Constraint, Not a Suggestion

Every worker's execution spec contains a rigid procedure:

  1. TDD implementation: add cases in test-cases.md and run red → implement → run green → refactor. Log new issues as /bug. Bug fixes must attribute the introducing source (REQ-/BUG- number).

This is not "we suggest you write tests first". worker-spec.md spells out the command sequence: first run atb claim to take the item, then must read test-cases.md, then red-green-refactor, then atb report to submit coverage and framework, and finally atb run receipt for the receipt.

What if the Agent skips the tests? Then it simply cannot get through the reporting flow — the report command requires --coverage and --framework arguments, and an Agent that never actually ran the tests cannot produce them.

Push constraints from "advice" down to "cannot proceed". Missing arguments means no delivery; the flow is blocked at the tool layer, closing off the "never ran the tests" path.

Human Involvement Is Visible and Traceable Throughout

Any Agent at work will run into questions that need a human call. In the past, at that moment the Agent either made the call itself (and might get it wrong) or froze there waiting for a human to fish it out.

ATB gives the Agent a third path:

$ATB hold declare <ID> \
  --question "Should we use SQLite or PostgreSQL here?" \
  --reason "The requirement doc doesn't specify; it affects later deployment" \
  --run <runId> --by <agentId>

Once the declaration is sent, the current run ends with a blocked receipt, the item itself stays in-progress, and it moves into the board's "awaiting human confirmation" aggregation area (atb hold list shows wait time and unanswered counts); the question and its decision are recorded in runtime/holds/decisions/<ID>.md. While on hold, the item refuses new claims — preventing a second implementer from stepping in.

A human then fills in the decision on the board (hold answer, humans only, with draft-saving support). Once the decisions are complete, a single action resumes the work (hold resume), and the item returns through a dedicated path to the planned queue to wait for re-claiming; you can also skip unanswered holds and confirm completion directly, or void the block entirely (hold cancel).

The key point: declarations and decisions are fully traceable — who asked, how long it waited, and why the human answered the way they did are all on the record. The next time a similar question comes up, a new Agent can directly read why that choice was made, instead of agonizing over it from scratch.

Conclusion: Constraints Must Sink into Gates, Not Stay as Advice

Today's mainstream AI Agent narratives are either "let Agents autonomously do everything" or "Agents are just assistants, one per person, playing solo". ATB tries the middle path: with minimal engineering overhead, let multiple Agents collaborate like an orderly dev team while keeping humans in full control of key decisions.

The essence of the three problems from the opening is: prompt-level compliance is forever probabilistic, so any quality assurance that lives only at the level of "advice" will eventually be paid out of your verification time. ATB's approach is to push constraints down layer by layer — no tests run, no report to submit; mutex not released, no second worker gets in; state not reached, the Agent cannot move any human-owned node. The gates that truly cannot be bypassed physically belong to humans alone.

What it solves is not a hard technical problem but a collaboration problem. Project development in the Vibe Coding era needs not cleverer prompts, but clearer rules, a clearer human–Agent boundary, and a "project memory" that travels with the code.