Skip to content

プロジェクト概要を先に作る ​

hatake は定義を書けば画面が出る。雛形を出して項目名を並べれば、その日には動くものが見える。いきなり書けるのがこの枠組みの売りだ。

けれど、いきなり書いていいのは何を作るかが決まっているときだけ。決まっていない状態で書き始めると、動く画面ができてから作り直すことになる。そして AI に書かせるほど、この失敗は速く大きくなる ── AI は決まっていないことを聞かずに、書ける方に倒すからだ。

決めていなかったこと出てくるもの気づくとき
このマスタは直せるのか編集ボタンと入力フォームが付いた画面現場に見せたとき(「これ購買部のシステムで入れてます」)
「取引先」と呼ぶのか「顧客」なのか画面ごとに customer と partner が混ざった定義画面が10枚を超えたあたり
項目名の付け方order_date と orderDate が同居した APIバックエンドと繋ぐとき
誰が押していいボタンか誰でも押せる CSV 出力監査で聞かれたとき

どれも定義としては正しいので、検証も警告も何も言わない。書いていないことは検査に出てこない。だから先に決める。

先に決めるのは5つ ​

多くはない。1時間で埋まる。

決めること何を書くか決めないと
何の業務か1〜3行。「卸売の受注。営業が電話で受けた注文を入れて、出荷指示まで出す」画面の粒度が人によって変わる
使う人と置かれ方「営業10人・事務所の PC」「出荷担当・倉庫のタブレット・手袋のまま触る」ボタンの大きさも一覧の件数も決まらない
できないこと「商品マスタは購買部の別システムが正。こちらからは直せない」「締めたあとの受注は直せない」AI が書ける方に倒す(上の表の1行目)
データの出どころRepository の名前と、その向こうに誰が居るか(「商品マスタ=購買システムの REST・持ち主は購買部」)繋ぐ日まで「まだ無い」が見えない
言葉業務の言葉と、定義に書く名前の対(「取引先 → partnerCode」)。呼ばない言い換えも画面ごとに字が揺れる

3番目の「できないこと」がいちばん抜ける。仕様書は普通「できること」を書く紙なので、書く欄が無いのだ。けれど画面を作る側にとっては、できないことのほうが強い制約になる。

読み物で終わらせない ​

ここまでを Word や Wiki に書いて終わりにすると、3か月後に誰も読んでいない。機械が読める1枚に落とす。定義の隣に hatake.project.yaml を置く。

yaml
project_version: "1.0"

system:
  what: 卸売の受注。営業が電話で受けた注文を入れて、出荷指示まで出す。
  users:
    - 営業(10人・事務所の PC)
    - 出荷担当(倉庫のタブレット。手袋のまま触る)
  premises:
    - 商品マスタは購買部の別システムが正。こちらからは直せない(照会だけ)。
    - 締めは月末。締めたあとの受注は直せない。
  external:
    - name: productRepository
      what: 商品マスタ(購買システムの REST)
      owner: 購買部

glossary:
  - term: 取引先
    field: partnerCode
    avoid: [顧客, 得意先]
    note: 社内の帳票が全部「取引先」なので、画面もそう呼ぶ

naming:
  page: snake_case
  field: camelCase
  role: snake_case
  suffix:
    date: Date

読み返すのはこれ。

bash
npx -p @hatake-fw/api hatake project

置いておけば、道具は渡さなくても読む(定義の隣にあれば拾う)。

決めたことが、実際に守られる ​

概要を紙で持っているだけなら「読んでね」で終わる。1枚に落とすと、そのうち一部は機械が突き合わせられる。

bash
npx -p @hatake-fw/api hatake advise page.yaml --project hatake.project.yaml
# page.table.columns.1 [project-glossary-word]
  こうなる: ラベル「顧客コード」に「顧客」が入っています。案件の決めごとでは「取引先」と呼びます(社内の帳票が全部「取引先」なので、画面もそう呼ぶ)。
  書き足す: 「取引先」で言い直す。

# page.search.filters.0 [project-name-suffix]
  こうなる: `type: date` の項目 "orderDay" は、案件の決めごとでは名前を "Date" で終わらせます。
  書き足す: "Date" で終わる名前に直す(決めごと: naming.suffix.date = Date)。

これは警告ではなく助言(終了コードは変えない)。名前と言葉は「書いたのに効かない」ではなく案件の好みなので、CI を落とす種類の話ではない。

雛形も決めごとの形で出る。

bash
npx -p @hatake-fw/api hatake new crud --id order_entry --title 受注入力 --project hatake.project.yaml

縛れているものと、縛れていないもの ​

ここは正直に分けて見ておいたほうがいい。読み返し(npx -p @hatake-fw/api hatake project)は毎回これを言う。

書いたもの誰が見るか
用語(glossary)と名前の決めごと(naming)機械が定義と突き合わせる
何の業務か・使う人・業務の前提・外の相手人と AI が読むだけ。 誰も突き合わせていない

つまり「商品マスタは直せない」と書いても、編集ボタンを足した定義は普通に通る。前提は定義に書きようがないので、機械には見えない。1枚に落とす値打ちは「守らせる」ことではなく、読まれる場所に置くことにある。

AI に渡す ​

MCP を繋いでいれば、最初に読む道具がこれになる(hatake_project)。順番は AI に書かせる にある。

繋がない使い方(Copilot・Cursor・ふつうのチャット)なら、AGENTS.md や CLAUDE.md に貼る断片を出せる。

bash
npx -p @hatake-fw/api hatake project --agents                      # 貼る断片(印つき)
npx -p @hatake-fw/api hatake project --agents --merge AGENTS.md    # 2回目以降:印の中だけを差し替える
npx -p @hatake-fw/api hatake project --agents --merge AGENTS.md --check   # CI:貼った節が古くないか

同じことを2か所に手で書くと、前書きを直したのに設定ファイルが古いが必ず起きる。だから1枚を正にして、貼る側は生成する。ブランチ名やコミット規約は前書きが持たない(定義に現れないものは機械が突き合わせられない)ので、そこは印の外に手で書いておけば、貼り直しても消えない。

貼ったあとに前書きだけ直すこともあるので、古くなったら CI が言う口も付けてある(--check。見るだけで書かない)。生成物なのに古い節が貼ってあると、AI はそれを読む。

どこまでを hatake がやるか、も先に見る ​

概要を書くと、hatake では書けないものが必ず混ざる。締め処理、承認フロー、認証、在庫の引当。これらは持たないと決めているので(この Framework が持たないもの)、誰がやるかを先に決めておく。

引ける表になっている。

bash
npx -p @hatake-fw/api hatake where 締め処理        # → 枠組みの外(なぜ持たないか+画面側でできること)
npx -p @hatake-fw/api hatake where 承認            # → 枠組みの外(画面は状態を見せるだけ)
npx -p @hatake-fw/api hatake where 一覧の並べ替え   # → 定義で書ける(書くキーと次に引く道具)
npx -p @hatake-fw/api hatake where --where outside # 持たないものの一覧

区分は4つ。definition(定義で書ける)/plugin(アプリ側に登録して足す)/server(サーバの担当)/outside(枠組みの外)。

長い依頼文なら、まとめて仕分けられる(外が混ざっていたら先に言う)。

bash
npx -p @hatake-fw/api hatake where --from 依頼.md
仕分けた行は 7 件。**うち 3 件は枠組みの外**(当てられなかった行が 4 件)。

・締めたあとの受注は直せないようにする
    [枠組みの外(hatake は持たない)] 業務ロジック(締め・引当・与信・按分)
・承認フローを組んで、承認されたら出荷指示に回す
    [枠組みの外(hatake は持たない)] 承認フロー・状態遷移のエンジン

当て方は言葉の一致だけなので下書き。当てられなかった行も必ず一覧に出る(黙って落とすと、仕分けたつもりで抜ける)。

outside と出たものは、前書きに置き場として記録しておく。premises に「できないこと」を書き、logic: に「何の規則が誰の担当か」を書く。

yaml
premises:
  - 締めは会計システムが持つ。画面は「締めたら直せない」を見せるだけ。

logic:
  - what: 締めたあとの受注は直せない
    where: server
    name: orderCloseGuard
    why: 締めは会計側が持っているので、画面で判断すると二重管理になる

書くのは名前と担当と理由だけ(規則の中身は書かない)。こうしておくと2つ効く。

  • AI が最初に読む1枚に「これは外」が入る(--agents の断片にも載る)
  • 外の担当と書いたのに画面から呼んでいたら、道具が言う(npx -p @hatake-fw/api hatake advise --project)
  • 言われた規則に担当が付いたかを突き合わせられる(意図の1枚から covers: [logic:orderCloseGuard] で指す → 言ったことを残す)

AI に「締め処理も作って」と頼むと、外だと言えないまま Dart を書き始める。これはこの Framework でいちばんやってほしくないことなので、道具の側でも止めるようにしてある(MCP なら hatake_where)。

定義に書けないことは、道具が聞いてくる ​

仕分けても、聞かれていないから決めていないことが残る。排他(2人で同時に直したら)・ 採番(新しい番号は誰が付けるか)・論理削除(消したものは残るか)・端数(切り捨てか 四捨五入か)。どれも定義には書けないので、定義を読んでも空欄が無い=決まっていない ようには見えない。

画面を1枚書いたら、聞かせる。

bash
npx -p @hatake-fw/api hatake ask order_entry.yaml

返る問いには誰の担当か(サーバ/枠組みの外)と、この定義で聞いた理由 (どの画面の何を見たか)が付く。答えが決まったら、この前書きの logic に1行足して 印を付けると、次からその問いは出ない。

yaml
logic:
  - what: 受注は更新日時が変わっていたら弾いて、読み直させる(後勝ちにしない)
    where: server
    answers: [concurrency]

聞かれるのは12種類だけ。出なかった=決まっている、ではない(道具が毎回そう言う)。 → AI への頼み方

この1枚が育っているかを数える ​

前書きは足していく紙だ。1枚書いて満足して、画面が30枚になっても用語が3語のまま、 はよくある。育ち具合は数えられる。

bash
npx -p @hatake-fw/api hatake project hatake.project.yaml --coverage definitions/
text
決めごとの棚卸し(画面 2 枚・項目 14 個を読みました)。

用語: 3語(項目名を名指ししているのは 3語)
  定義の項目 14 個のうち、辞書が名指ししているのは 3 個
  ・"nowhere" は辞書にありますが、定義のどこにも出てきません

名前の決めごと: 5/5 の対象に形を決めた
業務ロジックの置き場: 4件
問い返し: 答えた 1件・既定のままでよいと決めた 1件・まだ答えていない 1件

総合点は付けない。 辞書が要らない案件もあるので、少ないことが悪いとは限らない。 定義を渡さなければ、そこは「数えていない」と言う(0 と出すと「全部載っている」に読める)。 この案件の説明と業務の前提は誰も突き合わせていないので、数にも出てこない。

育っているかは、1回の数では分からない ​

前回の棚卸しを渡すと、移り変わりが出る。

bash
npx -p @hatake-fw/api hatake project hatake.project.yaml --coverage definitions/ --since 前回.json

「画面だけ増えて用語が3語のまま」は事実として出る。ただし増えていない=悪い、とは 言わない(その領域が固まっただけかもしれない)。道具が言えるのは数の増減までだ。

最初の1枚は、資料から起こせる ​

白紙から書くのが重いなら、もう在る資料(提案書・要件メモ)から起こせる。

bash
npx -p @hatake-fw/api hatake project --draft --from 要件メモ.md --out hatake.project.yaml

拾うのは見出しのある所だけで、書いてある字のまま。拾えなかった行は捨てずに出るし、 拾えなかった所は TODO_ のまま残る(機械が埋めると、読んだ人は人が書いたものだと思う)。

定義を渡したら落ちる。 page: や app: から前書きを起こすと、前書きが定義と必ず 一致して読む値打ちが消えるので、そこは機械で止めてある。

辞書は、書いてあるものから起こせる ​

途中から前書きを入れるなら、辞書を白紙から書かなくていい。揺れている所は数えられる。

bash
npx -p @hatake-fw/api hatake project hatake.project.yaml --drift definitions/
text
同じ項目名に、違う言葉が付いています:

  "amount"
    ・金額(12か所)
    ・支給額(1か所)

「同じ項目名に違う言葉」と「同じ言葉が違う項目名」の2つの向きを見る。辞書に載せた字は 次から出ない ── 決めたら静かになる。

どちらが正しいかは言わない(業務の言葉なので、決めるのは人)。辞書も作らないし、 前書きも書き換えない。

--draft を足すと、そのまま貼れる形(glossary: の塊)で出る。term には多い呼び方を 仮に置いてあるだけで、正しいという意味ではない ── そう出力にも書いてある。 --since に前回の結果を渡せば、増えた揺れだけが出る(新しい画面を足した回に決めるのが いちばん軽い)。

決めたなら、落としてもいい ​

名前と用語の助言は好みなので、既定では終了コードを変えない。案件が「命名の揺れは直す」と 決めたなら、CI で落とせる。

bash
npx -p @hatake-fw/api hatake advise app.yaml --project hatake.project.yaml --project-as-error

落ちるのは案件の決めごとだけ(組み込みの助言では落ちない)。旗を渡さなければ絶対に 落ちない ── 助言を勝手に落とす道具になった時点で、事実を言う警告まで読まれなくなるから。

宣言した担当が、本当に登録されているか ​

「これはアプリ側の担当」と書いて、画面から呼ぶ所も書いた。登録を忘れると、押しても 何も起きない画面になる(押すまで気づけない)。

bash
npx hatake advise app.yaml --project hatake.project.yaml --registry hatake-registry.json

登録済みの一覧を渡したときだけ言う(知らないのに「登録が無い」と言うのは嘘なので)。 一覧は npx hatake registry <アプリのソース> で実装から作れる。

画面ごとの話は、この次 ​

案件の前書きは案件ぜんたいの話で、1回書けばあとは足していくだけ。画面1枚ごとに「何を言われたか」を残すのは別の紙になる。

紙何が書いてあるかいつ
プロジェクト概要(hatake.project.yaml)何のシステムか・できないこと・用語・名前案件の最初に1回
頼み方のテンプレこの画面で何をするか・業務の決めごと・終わりの判定画面を作るたび → AI への頼み方
意図の1枚(<画面id>.intent.yaml)言われたこと・決めた理由・決まっていないこと画面を作るたび → 言ったことを残す

作る順番 ​

  1. プロジェクト概要を決める(このページ。1時間)
  2. hatake.project.yaml に落とす(npx -p @hatake-fw/api hatake project で読み返す)
  3. AI に渡す(MCP、または --agents で AGENTS.md に貼る)
  4. 画面ごとに頼む(頼み方のテンプレ)→ 言われたことを残す(意図の1枚)
  5. 定義を書く・書かせる(機能別の書き方)→ 検証して読み返す(AI に書かせる)
  6. 決めごとと突き合わせる(npx -p @hatake-fw/api hatake advise --project)

よくある失敗 ​

  • 概要を散文だけで持つ。 読まれないし、機械も見られない。せめて用語と名前は表にする
  • 用語を決めずに始める。 あとから揃えるのは、項目名を変える話になる(Repository・API・試験・他の画面の遷移まで直すことになるので、道具は自動で当てない)
  • 前提を書かない。 「できないこと」の欄が無い仕様書をそのまま渡すと、AI は書ける方に倒す
  • 命名を後で揃えるつもりでいる。 決めごとを1枚に書いておけば雛形から従うので、最初に書くほうが安い

書き方の詳しい所(キーの意味・機械が見る範囲・--agents の印)は 案件の前書き。