You’ll receive an email confirming your submission.
Our team will contact you within 24–72 hours, depending on the complexity of your request.
By submitting, you agree to our [Privacy Policy] and consent to receive updates or consultation support from Open Reach Tech.
Please select the privacy consent checkbox.

components..title

components..description

components..title

components..description

You’ll receive an email confirming your submission.
Our team will contact you within 24–72 hours, depending on the complexity of your request.
By submitting, you agree to our [Privacy Policy] and consent to receive updates or consultation support from Open Reach Tech.
Please select the privacy consent checkbox.

Why Hora Kit does not run features in parallel

Portrait of Jiro Yamamoto
Jiro YamamotoBackend Developer

The seventh article in the "Hora Kit design" series. The main cause of Hora Kit's slowness is that it does not run features in parallel. While running multiple agents side by side at the same time is in fashion, why do we make it "features serial, units parallel"? We write about the unresolved git problems that stand in the way of parallelization.

Banner of Why Hora Kit does not run features in parallel

1. Introduction

This article is the seventh in a series explaining the design of Hora Kit, the AI development framework that we (Open Reach Tech) released as open source. The main article is here.

We open-sourced Hora Kit, an AI development framework for truly automated development

A note on terminology. The only command you type in Hora Kit is /hora. Depending on the situation, /hora calls /hora-spec (writes the spec), /hora-setup (creates the implementation repositories), /hora-plan (fixes the version and writes the feature list and contracts), /hora-build (takes one feature through the 18 checkpoints), and /hora-accept (performs acceptance) in order. Only /hora-hotfix is not called by /hora; a person runs it directly. The docs call /hora-spec "the deciding side" and the rest "the building side", and this article uses those names as well.

In the main article we wrote honestly that "Hora Kit is slow". The main cause of the slowness is that it does not run features in parallel.

Since running multiple agents side by side at the same time is in fashion, we are often asked "why not run in parallel?". The docs have a section called "Why serial" that answers this question, and it opens like this: a design that does not keep a record of "why serial" looks like mere corner-cutting to the next person who touches it. That is also why we left this section in the docs; unless it is written down, someone will eventually implement parallel execution and run into the same problems.

In this article we write about what those problems are.

2. What is serial is features and checkpoints. Units are parallel

Let us be precise first. What does not run in parallel in Hora Kit is "two features" and "two checkpoints". Inside a single checkpoint, however, its units run concurrently. One agent works per table, per module, per operation, per component, per screen.

"Features serial, units parallel." The distance between these two claims is the subject of this article.

3. The problem is git, not throughput

What stands in the way of parallelization is git, not performance.

In Hora Kit, implementation agents do not touch git. Their output lands in the working tree uncommitted. If you run two tasks at the same time here, the output of both mixes in the same working tree. When you then try to separate it into clean per-task commits, you hit the following problem.

A parallel task's commit silently absorbs someone else's work

Imagine an aggregate file such as resolvers/index.js. Task A and task B run at the same time, and both rewrite index.js in full. If you assemble commit A from "the files A touched", index.js also contains B's part. In the docs' words, the commit silently absorbs work that is not its own.

The absorbing itself is not the problem; absorbing "silently" is. The meaning of the commit breaks without anyone noticing.

4. Separate branches solve it. But

If you thought "just cut a branch per task", you are right, and that solves it. But a single working directory can have only one branch checked out at a time. And Hora Kit does not use git worktree.

The same constraint shows up during execution. When a dependency is discovered midway, in serial you just stop that one task, introduce the dependency, and rebase. In parallel, each of the several open branches demands a rebase, and that means switching the whole working directory out from under something being edited.

The docs conclude as follows: until this is truly solved, serial is not a cautious default but the only option that commits correctly.

5. The value of parallelism is not as large as it sounds

There is one more point the docs make. Hora Kit's unit is not a small task but one feature, ending in acceptance against the whole product. Since one feature proceeds serially through spec → backend → frontend → acceptance, there is not much room left for features to overlap.

Parallelization shrinks only the implementation part; acceptance still ends up passing one feature at a time.

6. Why only the inside of a checkpoint can be parallel

The units inside a checkpoint avoid both sides of the problem above. That is why they alone run concurrently.

First, a unit is smaller than a commit. Every unit in checkpoint 6 lands in that gate's single commit, so there is no earlier commit into which a later unit's output could be absorbed. Second, the shared folders are regenerated by the main session after all units finish, so no unit writes an aggregate file. When a dependency becomes necessary, the serial-case answer is used as is: the unit that needs it reports it, /hora-build introduces it on a dedicated branch, and then work continues.

7. What matters is not wall clock but how much each agent carries

Speed is not the only reason to split into units.

An agent that writes 6 resolvers by itself carries a context that has grown to 6 resolvers' worth, and pays that full amount on every subsequent turn. Split among 6 agents, each carries only one resolver's worth. The docs have a measurement: the heaviest single agent during a build was the one at checkpoint 6, which ran for 308 turns while holding the largest resident context.

Pay the full amount over 308 turns, or split into 6 and have each pay for one. This affects both token volume and accuracy.

8. How we came to accept this slowness

Restating the numbers from the main article: taking a system of 100,000 to 200,000 lines to release takes 2 weeks with Hora Kit, and 2 to 3 days at the fastest with full vibe coding that skips verification. Around 5 times slower, and most of that gap comes from the per-feature serialization and the per-feature acceptance.

The reason we accepted this is that the time it takes to untangle a feature built on top of the wrong table is longer than the time saved by parallelization. We quote the table from the docs' section "Per feature, not per layer".

Per layerPer feature
When a design flaw surfacesThe final testing phaseThat feature's own acceptance
How much is stacked on top at that pointEverythingZero
How a regression appearsOne of 20 changes broke itThe change just made broke it
CostBringing up the environment onceOnce per feature

The cost is real, and we accept it knowingly.

9. Summary

Using worktrees would lift the branch constraint. The docs do not deny that either; they only state the current situation: "this design does not use git worktree." We left the reasons in the docs so that whoever takes on parallelizing features does not start without knowing the problems above.

A design that has "why serial" written down is also a design that has written down what to solve when parallelizing. We hope this is useful to anyone considering parallel execution of agents.

The original source is here. https://github.com/openreachtech/hora-core/blob/main/docs/architecture.ja.md