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 holds not a single procedure

Portrait of Jiro Yamamoto
Jiro YamamotoBackend Developer

The second article in the series "The design of Hora Kit." Hora Kit itself (hora-core) holds neither how a resolver is written nor the shape of a table; it holds only "what happens when" and "what must be true before moving on." We explain why procedures and pass/fail criteria were split out into four skill packages, and how that leads to independence from the technology stack.

Banner of Why Hora Kit holds not a single procedure

1. Introduction

This is the second article 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 terms. There is only one command to type in Hora Kit: /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 18 checkpoints), and /hora-accept (acceptance), in order. Only /hora-hotfix is not called by /hora; a person types it directly. The docs call /hora-spec "the deciding side" and the rest "the building side," and this article uses the same terms.

Of everything in Hora Kit's design, this is the part that draws the most surprised looks when we explain it. Hora Kit itself holds none of: how a resolver is written, the shape of a table, or what a review fails on. All it holds is "what happens when" and "what must be true before moving on."

You may wonder, "then how does it write any code at all?" In this article we cover, in order, why we did it this way, how it actually works, and how it leads to independence from the technology stack.

2. It started with the problem of copied conventions going stale

The starting point of this design is an entirely ordinary problem.

When you have an AI agent write code, you hand it coding conventions as skills. For example, a rule like "stub resolvers go in server/graphql/resolvers/<audience>/stub/." When you explain the implementation procedure, you are tempted to write that rule on the procedure side as well. It looks kinder, since everything can be read in one place.

But when the package that owns the convention is updated and the path changes, the convention on the package side becomes new while the copy written on the procedure side stays as it was. And the copy does not tell you "I have gone stale." The docs put it this way: "it remains word for word as authoritative as the day it was written, and an agent that follows it confidently puts its deliverable in the wrong place."

Something similar happens in human teams. The conventions page on the wiki and the conventions in the actual codebase differ, and nobody fixes the wiki: that one. But a human can suspect "maybe the wiki is out of date." An agent believes the text it is given as it is, so this problem was more serious than in the human case.

3. What the Kit owns, what the packages own

So we set one rule for Hora Kit. The procedures, conventions, and pass/fail criteria that the skill packages already hold are not written on the Hora skill side. Write only "what kind of work this is," and delegate. That is the rule.

What Hora Kit holds, and what it does not

What it ownsExample
Hora KitWhat happens when. What must be true before moving on"Checkpoint 4 passes once a schema-conforming stub exists for every operation this feature adds"
Skill packagesHow to do it. What counts as "done properly""Stubs go in stub/{queries,mutations}/, mirror the schema, have no DB access, and share their class name with the implementation resolver"

These two sentences do not overlap. There is also a criterion for judging whether they overlap: if a line in the Kit could be judged to "disagree" when checked against a package, that line should not be in the Kit. Simple, but it works as the criterion when trimming the Kit's documents.

4. Four packages, 119 skills

The procedures and pass/fail criteria are split into four packages by domain.

PackagePrefixApplies toSkill count
hora-skills-ort-corehoc-Both backend / frontend39
hora-skills-ort-renchanhor-Backend repositories31
hora-skills-ort-furohof-Frontend repositories46
hora-skills-ort-supporthos-Both, and their surroundings (explanation, documentation)3

When you run npm install, the contents of these four and of @openreachtech/hora are laid out side by side in a single flat .claude/skills/.

node_modules/@openreachtech/hora/dist/skills/<skill>/                     ─>  .claude/skills/<skill>/
node_modules/@openreachtech/hora-skills-ort-core/dist/skills/<skill>/     ─>  .claude/skills/<skill>/
node_modules/@openreachtech/hora-skills-ort-renchan/dist/skills/<skill>/  ─>  .claude/skills/<skill>/
node_modules/@openreachtech/hora-skills-ort-furo/dist/skills/<skill>/     ─>  .claude/skills/<skill>/
                          Copied as is. No renaming, no rewriting

The prefixes are there so that someone looking at the flat list can tell at a glance which package each skill came from.

5. Matching by description, not by name

This is the most detailed part of the design. It gets a little involved, but the separation above does not hold without this mechanism, so we write it down.

Hora Kit's files do not write a single package skill name. Not even "as an example." The reason is that skill names belong to the packages, and a package is free to rename them. A renamed skill disagrees with nothing. The name simply stops matching, the checkpoint runs without that convention, and the run reports "pass." This is the kind of failure a checkpoint must never produce.

Instead, at run time it works like this.

1. The checkpoint, stage, or acceptance step states "what kind of work this is"
2. The main session reads the descriptions of the equipped skills under .claude/skills/
   and picks the ones that cover that work
3. It records which ones were picked, against that checkpoint, in .hora/
4. It passes the picked names, with a digest, to the agent that performs the work

The reason step 2 is done by the main session rather than by the agent is reproducibility. If the agent chooses for itself, it picks something different on every rerun, and nobody can say which was used. Recording the choice in step 3 makes a package rename visible in the diff.

The digest in step 4 is the only "copy" this rule permits. But it names the package and version it came from, and it stops being read the moment that version is no longer the one running. The implementing agent opens the original skill as soon as a question arises.

When no covering skill is found, it does not guess a substitute; it says "none" and continues. The judgment is that proceeding while reporting the gap is better than proceeding with a guessed replacement.

6. The path to stack independence

Taking "holds no procedures" all the way yields one more by-product. The Kit no longer holds the name of the stack either.

The boilerplate's name, the framework, the middleware, the defaults. None of these are written anywhere in the Kit's files. Instead, the stack handbook in the project's docs/stack/ holds them. In the docs' words, "the location itself is the contract": a Hora skill looks for docs/stack/README.md at the project root, and if it is not there, it stops and asks. It never guesses the stack.

The handbook answers five things.

SectionWhat it settles
Where it comes fromThe repository URL, and how to choose the version to fetch
What to fill inThe placeholders the boilerplate brings, and the value to put in each
What to put in placeFiles the boilerplate does not bundle but the project needs
Which skills to copy into that rowThe equipped skills to copy into the created repository's own .claude/skills/
What to read once it arrivesThe checklist /hora-setup uses when reading the actual tree

Only the boilerplate and skills lean on a technology. hora-core does not know the stack

In other words, when you want to put Hora Kit on a different stack, only two things change. Write a new skill package holding that stack's procedures and pass/fail criteria under a hoX- prefix, and write that stack's docs/stack/ handbook. Not a single line of the Kit's skills changes, because the order and the checkpoints do not know the stack.

7. An honest status report

If you have read this far and are thinking "so I can use it with Rails, or with Django?", we have to answer: not yet.

As of today, the only skill package and handbook available are for our own stack (renchan for the backend, furo-nuxt for the frontend). By design, "write a package and a handbook and it goes on," but nobody has written them yet.

Even so, it is because of this separation that we can say flatly "it can be put on." hora-core holds not a single framework or database name; it is structured for general web development. Had we baked the procedures into the Kit, we would have had to rewrite the Kit itself every time the stack changed.

We are looking for development partners to work with us on this activity of "defining a set of skills for each technology stack." If you want to distill your own stack's conventions and review criteria into skills and put them on Hora Kit, please reach out via an Issue.

8. Conclusion

We think this way of splitting things is usable even by people who do not use Hora Kit. Separate the document that holds "when and what" from the document that holds "how," have the former never write the latter's names, and do the matching at run time against descriptions.

Once you start operating Claude Code skills across an organization, copies of conventions scatter everywhere. The answer we adopted in Hora Kit was to forbid copies and allow only delegation. We hope this helps anyone facing the same problem.

The originals are here. https://github.com/openreachtech/hora-boilerplate/blob/main/docs/skills.ja.mdhttps://github.com/openreachtech/hora-core/blob/main/kit/skills/hora/references/structure.md