スペックアンカード開発
AIエージェントは、人間が手作業でドキュメントを正しく保てる速度を超えて
スペックアンカード開発
AIエージェントは、人間が手作業でドキュメントを正しく保てる速度を超えて コードを書きます。Gurenの答えはひとつの原則です:
導出できるものは導出し、できないものは宣言し、常に検証する。 (Derived where possible, declared where not, checked always.)
- 導出(Derived) — コードから証明できるものはコードから生成します。 ER図、ドメインモデル、画面一覧、モジュールマップ、エンティティの 完全なコンテキスト。
- 宣言(Declared) — コードで表現できないものは書き残し、対象の コードへ明示的にリンクします。意思決定、ビジネスルール、背景。
- 検証(Checked) — どちらも機械的に検証されます。古くなった生成 ビューや切れたdocリンクは、コードレビューではなくチェックが落とします。
その結果、コードが動いても嘘をつかない仕様が手に入ります — あなたに とっても、リポジトリで作業するすべてのエージェントにとっても。
導出: スペックビュー
bunx guren spec:generate
は docs/spec/ に4つのMarkdownビューを生成します。それぞれが1つの
問いに答えます:
| ファイル | 答える問い |
|---|---|
er.md |
データベースはどんな形か? db/schema.ts 由来のMermaid ER図 — カラム・型・キー、エッジはモデルのリレーション宣言から |
domain.md |
ドメインオブジェクトは何か? モジュールごとにグループ化したモデルのクラス図(カーディナリティ付き) |
screens.md |
各画面は何を受け取るか? ページ → Props型 → それを描画するルート |
modules.md |
アプリはどう分割されているか? モジュール・所属モデル・モジュール間依存 |
出力は決定的で、コード変更なしの再生成はバイト単位で一致します。 だからファイルはコミットされ、PRのdiffが「その変更が仕様に何をしたか」 をそのまま見せます。手で編集してはいけません — 信頼を人に頼らないため のドリフトゲートがあります:
bunx guren check --spec # メモリ内で再生成し、ドリフトがあれば非ゼロexit
導出: エンティティコンテキスト
bunx guren context User
は1つのモデルについてプロジェクトが知るすべてを結合します — テーブルと
カラム、双方向のリレーション、バリデーションスキーマ付きのルート、
コントローラのアクション、Props付きInertiaページ、Resource、Policy、
ファクトリ、シーダー、テスト、そして紐付いたドキュメント。エージェント
向けには --json、同名モデルは --module <name> で解決します
(--module app はアプリルートを指します)。MCP接続エージェントには
guren_entity_context ツールとして同じバンドルが提供されます。
宣言: ドキュメントとコードの紐付け
意思決定やビジネス背景は docs/(および modules/<name>/docs/)配下の
Markdownとして残します。frontmatterが「この文書が何を統べるか」を宣言します:
---
kind: adr
status: accepted
entities: [Invoice]
related:
- app/Http/Controllers/InvoiceController.ts
- modules/billing/**
last_reviewed: 2026-07-25
---
entitiesはモデルのクラス名でリンクします —bunx guren context Invoiceが、次にそのモデルを触る誰かにこの文書を提示します。relatedはモデル以外のコードを統べる文書のためのファイル/globリンクです。- モデルとコントローラからは JSDoc タグで逆リンクを張れます:
/** @docs docs/adr/0001-billing.md */(それ以外のファイルのタグは走査されません)
意思決定はジェネレータで記録します:
bunx guren make:adr "Billing cycle is end-of-month" --entity Invoice
docs/adr/ 配下に採番されたファイルを作り、frontmatterを記入済みに
します。--entity は既存のコードから entities: と related: を
自動補完します。新規Gurenアプリには、この規約を説明するシードADRが
最初から同梱されています。
検証: ゲート
bunx guren check は、route/controller/pageの整合性チェックと並んで、
切れたdocリンク(リネームされた related パス、存在しなくなった
エンティティ、宛先を失った @docs タグ)と古くなったスペックビューを
報告します。プレーンなコマンドは情報提供で、CIをゲートする(非ゼロexit)
のはスイートフラグです:
bunx guren check --docs # docリンクのみ
bunx guren check --spec # スペックドリフトのみ
bunx guren check --arch # アーキテクチャ境界のみ
docs/specのチェックはどちらもコンテンツ起動です: docs/ も
docs/spec/ も @docs タグもなければ結果ゼロなので、規約を採用する
まで何も赤くなりません。check --changed(エージェントハーネスの
edit hookがルート・コントローラ・モデル・スキーマ・ページの編集後に
実行するモード)では、検証はその変更が影響しうる範囲に絞られ、ループは
高速なままです。CIではフルのゲートが走ります。
なぜエージェントに効くのか
古いドキュメントは、AIエージェントにとって「ないより悪い」存在です —
エージェントは嘘を全幅の信頼で読みます。導出ビューはコードから再生成
され、宣言リンクはcheckスイートが検証するので、bunx guren context Invoice
を実行したエージェントが得るコンテキストは「リンクと導出ビューは検証済み
だとチェッカーが確認したもの」です(本文の鮮度は別軸のオプトイン警告で、
check --docs --docs-ttl <days> が last_reviewed の古い文書を指摘
します)。新規アプリのエージェントハーネスはこのループを
教えます — モデルに触る前にエンティティコンテキストを引く、ファイルを
動かしたらfrontmatterも同じ変更で更新する、構造を変えたらスペックビュー
を再生成する — そしてedit hookがそれを機械的に強制します。