設計ドキュメントの書き方

docs/ 配下のドキュメントが従う定型です(参照の書き方(5 節)と確定度の印の条件(6 節)は、 このリポジトリのMarkdownすべてに掛かります——10 節)。文章そのもののスタイル(簡潔さ・コメントにも 同じく掛かる「経緯を書かない」等)は CLAUDE.md が持ち(その禁止が掛からない文書の別は 9.1 節)、本書は構造——見出し・節番号・概要・実装状況の表し方——と、 文書へ何を書き残し、何を書かないかを決めます。リンクと参照の解決は 自動テスト(tests/docs/docReferences.test.ts)が検査します。

1. 文書の種別

定型は種別ごとに違います。どの文書がどの種別かは各フォルダの README.md の分類に従います。

種別 例 構成
設計 HuntingSystem.md、docs/ui/ の各文書 概要(2 節)+論点ごとの節+未決事項
リファレンス GameElementDefinition.md、Localization.md 位置づけ+項目の網羅+対象外。概要は要らない
カタログ Animals.md、Containers.md 分類の軸+一覧+住み分け+未決事項
実装ガイド TerrainGenerationImplementation.md 呼び出し関係+索引。設計理由は書かず設計文書へリンク
教訓集 DesignNotes.md、DesignPrinciples.md 結論を見出しにした項目の列挙
測定 docs/diagnostics/ diagnostics/README.md に従う

実装ガイドの索引と README.md の収録一覧は、CLAUDE.md「数え上げを書かない」が 禁じる書き写しには当たりません。行ごとに、在り処を見ても出ない対応——どの節が説明しているか・ その文書が何を決めるか——を持つためです。その対応を持たせられないなら、一覧は置かずに在り処を 指します。 個数は、対応があっても書きません。

ただし、各フォルダの README.md だけは一覧を省けません(分類がそこにしか無いので、対応は必ず 書けます)。置き場が合っているかの跡は、そのフォルダの一覧がその文書を指しているかどうかにしか 残らないためです——実装全般の規約が docs/engine/ に在るのに engine の一覧へ載っていない、という 形で現れます(tests/docs/docFiling.test.ts が検査します)。

2. 設計文書の概要は、次の問いに答える

この順で、最初の画面に収まる分量で書きます。模範は LiquidContainerSystem.md(実現方法が明快)と ExplorationSystem.md(境界の書き方が明快)です。

  1. 守備範囲 — この文書は何を決めるか。
  2. 境界 — 何を決めないか。隣の文書はどれか(リンク)。
  3. 実現方法 — この文書が扱う概念を、エンジンのどの機能へどう写したか。どの trait・タグ・ スロット名・プロパティ名を使うか(=この文書が導入する語彙)。新設した文法は何か。 新設ゼロならそれを明記します——汎用機能に載せた場合こそ、写し方の記述が唯一の設計判断です。
  4. 在処 — 定義(src/assets/world-codex/*.yaml)・実装(src/)・検証(tests/)はどこか。
  5. 確定度と実装状況 — 検討結果か確定仕様か。未決事項は何節か。未実装の節はどれか(4 節)。

節の一覧をなぞる「目次の要約」は書きません。目次で分かることに一等地を使ううえ、全節を挙げるため 網羅的に見え、書かれていないこと(実現方法の欠落など)に気付けなくなります。

3. 見出しと節番号

4. 実装状況は宣言し、丸ごと未実装の節にラベルを付ける

ドキュメント先行で書かれた設計は、実装済みの節と未実装の節が同じ断定調で並び、読み手の判断を 誤らせます。

4.1 いつか実装したいものは、別の印と一覧で分ける

【未実装: 識別子】 を付けるのは無いと完成と言えないものだけです。無くても完成を宣言できるが、 いつか実装したいものは 【いつか: 識別子】 で分けます。1つの印で両方を扱うと、残りの作業量を 誰も答えられなくなります。

印 意味 実体はどこ
【未実装: 識別子】 無いと完成と言えない。残作業 kind:task の issue
【いつか: 識別子】 無くても完成を宣言できる Someday.md に必ず1項目

5. 参照の書き方

6. 確定していることにだけ印を付ける

決定は後から覆ります。印の無い記述を暫定——今はこう書いてあるが覆りうる——という既定にし、 覆すのに判断が要るものにだけ印を付けます。

文書ごとの節数・確定節数・未実装節数は npm run stats:docs が一覧にします。並ぶのは、この節の 条件が掛かる文書すべてです——docs/ の外に置いた確定節も同じ表から数えます(10 節)。

6.1 印を付けてよいのは、射程・中身・出どころ・権限を満たす節だけ

【確定】 は「決定事項に、人間の判断していないことが混ざっていない」ことを保証する印です。 混ざり始めた時点で、決定と暫定の区別が付かないという印を作る前の状態へ戻ります。混ざる経路を 塞ぐのが、見出しに挙げた条件です。射程・中身・出どころは tests/docs/docReferences.test.ts が検査します。権限は 機械では判定できないので、出どころの1行が書けるかという形で出どころの検査に載せています。

6.2 文書まるごとが土台なら、節ではなく文書単位で宣言する

全節が確定に当たる文書は、節ごとに印を付けず、題名の直後で1回宣言します。 (GameConcept.md がこの形です。)「印は少数側に付けたときだけ働く」 (6 節)は1つの文書の中でも同じで、全節に印が並べば、その文書では印が背景になります。

7. 生成物の数値は、結論を支えるものだけ書き写す

stats/*.yaml は生成物で、定義(src/assets/world-codex/)を触るたびに動きます。そこから文書へ 書き写した数値は、動くたびに書き直す義務を生み、同じ行を触る変更どうしがぶつかります。

結論を支えるものだけに絞る線は、生成物にだけ掛かります。人が書いた定義から引いた数値は、再生成で ずれる問題を持ちません。印を置くことは定義にも掛かります——定義を動かしたときに文書だけが古いまま 残らないよう、書き写した値の直後に codex: の印を置きます。定義を YAML のまま抜粋するときは、 フェンスに出どころを名乗ります(書式はどちらも同じ diagnostics/README.md)。

8. 数の推移を見せるとき

運用の決め方で動く数を推移として出すときは、数だけを出しません。 7 節の生成物の数値と違い、 こちらは測り方も方式も変わり続けるので、値そのものだけでは何の記録なのかが読めません。

9. 文書は、失敗の履歴で作らない

書くのは、今どうなっているかと、それが何のために要るかです。 踏んだ失敗から書き起こすと、 文書は起きたことの一覧になり、起きなかったことを構造的に落とします。

9.1 経緯を書いてよいのは、経緯そのものを主題とする文書と、当時を残す記録だけ

過去の姿を書き残す場所は、それを主題とする文書と、当時を残す記録(10 節)に限ります。 ここに挙げていない文書では、 CLAUDE.md の「ドキュメント・コメントのスタイル」 の禁止どおり、経緯(旧仕様・変更履歴・不採用案・検討過程)を本文へ書きません。

文書 主題
DesignNotes.md 繰り返さないために残す価値のある、過去の失敗・不採用の決定
HowWeGotHere.md 作り方そのものをどう変えてきたか

表に無い文書に、過去の姿を語り出す語が生えていないかは自動テスト (tests/docs/docHistory.test.ts)が検査します(この文書も対象です)。見る語と、除外する文書を この表から引くことは、そちらが持ちます。この節が docs/ の外のどこまで掛かるかは 10 節です。

次の項目は、この表の文書の中での書き方です——他の文書には掛かりません。そちらには、書き方を 決める対象そのものがありません。

10. どこまで掛かるか

参照の書き方(5 節)と確定度の印の条件(6 節)は、このリポジトリのMarkdownすべてに掛かります。 docs/ の外の文書も互いを節名でもリンクでも引き合っており、指し先を畳めば同じように嘘になるためです。 5 節はソースのコメントにも掛かります——節番号の参照もリンクも、そこから同じように文書を指し、 ファイルと並べた名前も同じように指し先を失います(読む形式の別は 5 節)。 検査する tests/docs/docReferences.test.ts は、射程を在り処の一覧で持たず git の追跡から出します ——一覧は足した日にしか更新されないので、フォルダを作るたびに黙って射程の外が増えます。

数えて見せる表(npm run stats:docs)も、6 節と同じ射程です。 条件を課す側だけが外まで掛かって いると、docs/ の外の確定節はどの表にも載らず、印を持たない文書と見分けが付きません——注意を 向ける先を選ぶための表なので、載らないぶんは選びようがありません。絞りは docScope.mjs が持つ1つで、条件を課す側も、関門も、表もそこを読みます。

暦から換算した長さの書き方(11 節)も、docs/ の外まで掛かります。 宣言された tick の数を言い換える 場所は、文書より src/assets/world-codex/**.yaml のコメントのほうが多いためです。どこを読むかは 検査する tests/docs/tickReadings.test.ts が持ちます。

経緯を書かないこと(9.1 節)も、docs/ の外まで掛かります——盤面を回す文書(agent-ops/)にも、 スクリプト・データ・ワークフローのコメントにも。どこも今の形の理由を書く場所なのは docs/ と同じで、 理由は失敗の履歴ではなく、何のために要るかとして書けば、規則の隣に残せます(9 節)。外れるのは、 経緯を主題とする文書(9.1 節の表)と、下の記録と、その回の観測(agent-ops/analysis/)です。 絞りは docScope.mjs の historyRuleSources が持ちます。

残りの節は docs/ の中だけです。 実装状況の印(4 節)は src/ との照合と Someday.md の項目との対応で見るもので、指し先が docs/ の外にありません。種別 (1 節)も、その分類を置いているのが docs/ の各フォルダの README.md だけです。

掛からない文書は、当時の現物をそのまま残す記録だけです。

記録 残しているもの
agent-ops/decisions/ ユーザーの発言の原文
review/ の日付フォルダ 当時のコードに対する、その回の答え

そこを緑へ戻す手が、記録の書き換えしか無いためです。書き換えないと決めた場所で赤を出す検査は、 次にそこを踏んだ人に検査のほうを外させます。指し先の側も過去に在ります—— review/2026-08-22-placement/areas/codex.md はコメントの指し先がずれていること自体を指摘として 引いており、直すと引用でなくなります。

ただし、未処理の判断の履歴(agent-ops/decisions/ の直下)の ## エージェントの解釈 には 5 節が 掛かります。 解釈は次の棚卸しが今の文書と突き合わせて読む材料で、指し先が消えたり別の決めごとへ 入れ替わったりすると、今の文書に無いことを根拠に畳まれます。そして解釈の側は書き換えてよい (書き換えないのは原文だけ)ので、上の理由が当たりません。外すのは原文と context:、それに畳み終えた archive/ です。指し先の中身まで読むのは参照を検める係(refs-prompt.md) で、番号の繰り上げで中身だけが入れ替わった参照もそこへ回ります。切り出しは docScope.mjs の refProseOf が持ちます。

一方 agent-ops/analysis/ は、その回の観測を自分の言葉で書き、参照は今のリポジトリを指すので 5 節が 掛かります(6 節は外れます——あちらでは印が題材として現れるためです)。

5 節のうち、当時をそのまま残す側には掛けない規約があります。 以下の段落がそれです。

パスの綴りは、当時の在り処をそのまま残す側に掛けません——9.1 節の表の文書と、 その回の観測(agent-ops/analysis/)です。どちらも書いているのは当時の在り処で、今の綴りへ直すと その日にその名前の物ができたことになります(9.1 節。観測どうしは行番号で引き合ってもいるので、 直した行を後の回が「旧の置き場を指している」と名指したまま残ります)。

Markdown 以外を鉤括弧で引く形(`スクリプト.sh`「〇〇」)は、観測(agent-ops/analysis/)に 掛けません。 そこの鉤括弧は名前ではなく観測した当時の文言の引用で、引いた文言はその観測を受けて 書き換わるのが常です。

11. 暦から換算した長さは、tick の数の隣へ丸括弧で置く

宣言された tick の数を人に読める長さへ言い換えるときは、480 tick(5日) の形で並べます。 暦 (core.yaml の minutes_per_tick と hour・minute の range。コードが持つ同じものは worldTime.ts)を変えると言い換えた側は一斉に嘘になりますが、 言い換えは宣言から自動では出ないので、この形に揃えない限り見ているものがありません。

tests/docs/tickReadings.test.ts が、並べた数を暦から計算し直して照合します。この照合に見えない ものもあります。