Open Reach Tech Inc.

動いているコードの周りに Hora Kit を被せる

Jiro Yamamotoのプロフィール写真
Jiro YamamotoBackend Developer

「Hora Kit の設計」シリーズの 9 本目。弊社が 100 万行近いシステムを Hora Kit で安定して開発できているのは、動いているコードの周りに後から Kit を被せたからです。既存リポジトリの履歴もブランチも設定も奪わずに、Hora Kit を既存プロジェクトへ適用する手順を書きます。

Banner of 動いているコードの周りに Hora Kit を被せる

1. はじめに

この記事は、弊社(Open Reach Tech)が OSS にした AI 開発フレームワーク『Hora Kit』の設計を解説するシリーズの 9 本目です。メイン記事はこちらです。

本当の意味での自動開発を実現するためのAI開発フレームワーク『Hora Kit』をOSSにしました

用語の確認。 Hora Kit で打つコマンドは /hora の 1 つだけです。/hora が状況に応じて /hora-spec(仕様書を書く)、/hora-setup(実装リポジトリを作る)、/hora-plan(版を確定し、機能一覧と契約を書く)、/hora-build(1 機能を 18 の関所に通す)、/hora-accept(検収する)を順に呼びます。/hora-hotfix だけは /hora が呼ばず、人が直接打ちます。docs はこのうち /hora-spec を「決める側」、残りを「作る側」と呼んでいて、この記事でもその呼び方を使います。

メイン記事で「100 万行近いシステムでも安定して開発できている」と書きました。そのシステムは、Hora Kit で最初から作ったものではありません。動いているコードの周りに、後から Kit を被せたものです。

「新規なら試せるけど、うちは既存のコードが山ほどある」という方が多いと思うので、この記事ではその「被せる」手順を書きます。

2. 既存リポジトリは何ひとつ奪われない

先に安心してもらいたいことを書いておきます。既存リポジトリは何ひとつ奪われません。履歴もブランチも設定もコードもそのままです。Hora Kit はそれらの外側に立ち、仕様書と計画と記録を持つリポジトリとして加わります。

既存リポジトリの周りに Kit を被せる

myproject-app/                  ← キット。specs/ .hora/ .claude/ を持つ。アプリコードは持たない
  legacy-api/                   ← 既存のバックエンド。手つかず
  admin-console/                ← 既存のフロントエンド。手つかず

ディレクトリ名は変えなくて構いません。仕様書のリポジトリ構成表に Directory 列があって、そこで名前を宣言します。

3. 最初に決めるのは 1 つの問いだけ

手順に入る前に、1 つだけ決めます。仕様書とコードが食い違ったとき、どちらが正しいのか、という問いです。

as-built(実装が正)to-spec(仕様が正)
あなたの状況製品は動いていて、その動きがあなたの望むもの。現状を版として固定し、そこから育てる誰かが書いた仕様に向けて実装の途中。残りの距離を詰める
仕様書が記述するもの今日動いている製品あるべき製品
質問の量数個と、検収掃引 1 回全関所が走り、コードを仕様へ突き合わせて直す

答えは仕様書の 1 行、Existing assets 節の Authority: に書かれます。この記事の残りは、この答えで分岐します。動いている製品をそのまま正として育てたいなら as-built、仕様が先にあって実装が追いついていないなら to-spec で、ほとんどの既存プロジェクトは前者になると思います。

4. 6 つの手順

docs の「短くまとめると」を、弊社の言葉で要約します。

まず、hora-boilerplate から <myproject>-app を作り、既存リポジトリを中に移します。入れ子にするのは git の要求ではなく、Claude Code のセッションが作業ディレクトリの外に書けないという要求です。

次に、既存の文書を持ち込みます。要件一覧や API リファレンスのように「仕様そのもの」なら specs/1.0.0/sources/ へ、モックアップや古い設計書のように「仕様を説明するもの」なら annex/ へ、作ってほしいものは request/ へ、自分の言葉のままで入れます。実装リポジトリの中へはリンクしないでください。gitignore 済みなので、リンクは静かに切れます。

3 番目に、上の as-built / to-spec を決めます。

4 番目に /hora-spec が、既存を読んだ上で仕様書を書きます。ステージ 0 がリポジトリと置かれた文書を読み、仕様とコードの食い違いを全件記録します。as-built なら、導出された built: の表をまず丸ごと提示し、そのあと機能ごとに選択式で確認します。ユースケースと受入基準は動いているシステムから草案されるので、あなたは訂正するだけです。「まだ終わっていない」と答えた機能だけが to-spec になります。

5 番目に /hora を走らせます。/hora-setup は適用済みの行に対して clone を飛ばし、埋まっていない値だけを埋め、実物ツリーを読んで .hora/tree/ に控えます。人が既に埋めたものは上書きされません。続いて /hora-plan が計画を書くので、ここで built: が正しいかを確認します。

間違え方どうなるか
built: と宣言したが実は作られていない検収が落とし、印が解除され、本当に作られる。安全な方向
宣言しなかったが実は作られている動くコードに対して 17 の関所が走る。壊れはしないが、時間が無駄になる

最後に、最初の検収掃引です。「既に作られている」と宣言された機能は、作り方を述べた 17 の関所を飛ばしますが、検収には必ず入ります。つまり適用後の最初の掃引は、既存製品全体を、その製品自身が掲げるユースケースに対して受入レビューすることになります。

5. 指摘が出ることを見込め。それが価値そのもの

docs は「指摘が出ることを見込んでください。そしてそれが、適用した価値そのものです」と書いています。

メイン記事に「Hora を導入した後に、潜在的なバグとセキュリティの脆弱性が多く見つかった」と書きましたが、既存製品に対して最初に走るのがこの掃引なので、見つかるのはここからです。

各指摘は「どの機能の、どの関所に戻すか」を書きます。適用済み機能の built before Hora Kit was adopted と印された区間に着地した場合、その印は解除されます。直さなければならないコードは、結局のところ単に受け継いだものではなかった、という扱いです。影響する一番手前の関所から、本当に作り直します。

これが、既存製品がキットの水準まで引き上げられていく仕組みです。一度に 1 つの不足だけ、しかも不足が実際に示された箇所だけを直します。

6. 最初の実行は、環境で止まる

最初の掃引の手順 1 で止まる可能性が高く、それは正常です。

関所 17 はローカルの E2E 環境を作るためにあって、既存プロジェクトはたいてい何かしら(compose ファイル、シードスクリプト)を持っていますが、前提条件をまだ満たしていません。アプリの背後で全サービスが動き、各ロールでサインインでき、レビュー可能なデータがある、という条件です。それを直してから再実行してください。

ここで飛ばしたくなる気持ちは分かりますが、飛ばさないでください。フロントエンド単体でレビューすると、得ていない合格を報告することになります。

7. 除外リストが見た目より重要な理由

適用手順の中で、抜けたときの損害が大きく、しかも静かなのはここだけです。

.gitignore とルートの eslint.config.js は、実装リポジトリを名前で除外しています(*-backend*/、*-frontend*/)。legacy-api/ のような名前はどちらにも当たりません。

起きること気づく経路
.gitignoreバックエンド全体が追跡され、キットのリポジトリにコミットされるgit status を読むまで無い。その時点で既にコミット済み
eslint.config.jsルートの lint が、自分のものではない設定のリポジトリを走査する大量の違反

/hora-setup は宣言された Directory ごとに 1 行ずつ両ファイルに追記し、追記したことを報告します。それが起きたかどうかは、報告を見て確認してください。

8. 気をつけること

docs が挙げている注意のうち、既存プロジェクトで踏みやすいものを挙げます。

boilerplate のタグが既存コードより新しいことがあります。委譲されるスキルは現在の規約を述べるので、同じリポジトリの中で新しいコードが古いコードと違って見えます。これは想定内です。

既存のテストは、通すために弱められません。スキップも削除も緩和もしません。既存テストが落ちたなら、それは迂回すべき障害ではなく指摘として扱われます。

main に直接コミットしないでください。キットのリポジトリでは main-guard.yml が守りますが、既存リポジトリにはその防壁が無いかもしれません。

9. まとめ

既存プロジェクトへの適用で手に入るのは「残りをキットが作ってくれる」ではありません。それは後の話です。最初に手に入るのは、この製品が今何をできるのかという事実です。どこに到達でき、何が揃っていて、失敗したときに本当のことを言うか。

弊社にとって、100 万行近いシステムの「今何ができるか」を、人の記憶ではなく検収の記録で持てることが、適用の最大の価値です。レガシーコードに AI をどう入れるか悩んでいる方の参考になれば幸いです。

原典はこちらです。 https://github.com/openreachtech/hora-core/blob/main/docs/adopting.ja.md

送信完了!

お問い合わせいただきありがとうございます。 担当者より24〜72時間以内にご連絡いたします。