設計ドキュメントの書き方
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(境界の書き方が明快)です。
- 守備範囲 — この文書は何を決めるか。
- 境界 — 何を決めないか。隣の文書はどれか(リンク)。
- 実現方法 — この文書が扱う概念を、エンジンのどの機能へどう写したか。どの trait・タグ・ スロット名・プロパティ名を使うか(=この文書が導入する語彙)。新設した文法は何か。 新設ゼロならそれを明記します——汎用機能に載せた場合こそ、写し方の記述が唯一の設計判断です。
- 在処 — 定義(
src/assets/world-codex/*.yaml)・実装(src/)・検証(tests/)はどこか。 - 確定度と実装状況 — 検討結果か確定仕様か。未決事項は何節か。未実装の節はどれか(4 節)。
節の一覧をなぞる「目次の要約」は書きません。目次で分かることに一等地を使ううえ、全節を挙げるため 網羅的に見え、書かれていないこと(実現方法の欠落など)に気付けなくなります。
3. 見出しと節番号
- 節番号が識別子です。 他の文書やコードからの参照は節番号で行うため、既存の節番号は
付け替えません。節の追加は末尾か枝番(
4.1の後に4.2)で行います。 - 見出しにはその節が決める論点を書き、結論は本文の先頭 1 文に太字で置きます。結論を 見出しに書くと、結論の推敲のたびに参照が壊れます(名前で参照している場合)。ただし結論を 見出しにした方が目次が読みやすい場合は禁じません——その見出しを名前で参照しないだけです。
概要と未決事項・今後の検討課題は番号付き節の外に置いてもかまいません(既存文書の慣例)。
4. 実装状況は宣言し、丸ごと未実装の節にラベルを付ける
ドキュメント先行で書かれた設計は、実装済みの節と未実装の節が同じ断定調で並び、読み手の判断を 誤らせます。
- 文書全体の実装状況は概要で 1 回言います(模範:
ClimateSystem.md)。 多数派を既定として宣言し、例外の節だけに印を付けます。 - 節の主題が丸ごと存在しないときだけ、見出しの末尾に
【未実装: 識別子】を付けます。 識別子はその節が導入する語彙から 1 つ選びます(例:【未実装: 海図】)。子節はラベルを 継承するので繰り返しません。 - 識別子を書くのは検証のためです。自動テストが
src/を照合し、実装されたのに剥がし忘れた ラベルを検出します。識別子の無い【未実装】は検証できないので使いません。 - 節の一部だけが未実装の場合はラベルにせず、本文で書きます。「一部未実装」というラベルは 結局本文を読まないと判断できず、警告として機能しません。
- 語彙は「未実装」の一語に統一します(「未対応」「実装していません」等を混在させない)。 ラベルは TODO 管理ではありません——目的は読み手の判断を誤らせないことだけで、進捗表として 細かく付けるほど更新漏れが増えます。
4.1 いつか実装したいものは、別の印と一覧で分ける
【未実装: 識別子】 を付けるのは無いと完成と言えないものだけです。無くても完成を宣言できるが、
いつか実装したいものは 【いつか: 識別子】 で分けます。1つの印で両方を扱うと、残りの作業量を
誰も答えられなくなります。
| 印 | 意味 | 実体はどこ |
|---|---|---|
【未実装: 識別子】 |
無いと完成と言えない。残作業 | kind:task の issue |
【いつか: 識別子】 |
無くても完成を宣言できる | Someday.md に必ず1項目 |
- 印と項目は1対1です。 項目の無い印も、印の無い項目も、自動テストが落とします。
- 節の主題が丸ごと「いつか」なら見出しの末尾へ、節の一部ならその節の本文に1行書きます
(
【未実装】と同じ切り分け)。本文に書く形は「印 + 何を待っているかの1文 +Someday.mdへの リンク」で、中身は書きません——詳しい説明はSomeday.mdにだけ置きます。 - 「未決事項・今後の検討課題」節は、決まっていないこと専用です。 やると決まっていて、やっていない だけのものは、どちらかの印へ振り分けます。
- 確定度(6 節)とは別の軸です。両方付くときは
【確定】を先に書きます。
5. 参照の書き方
- 他の文書の節は
文書名.md N節で指します。コメント・YAML では要旨を添えます (例:GameElementDefinition.md 6.4節のalert)。番号だけでは読み手に何の話か伝わらず、 名前だけでは見出しの推敲で切れるためです。 - 「節」の字を省きません(
文書名.md Nと書かない)。自動テストは番号を拾ってから 「節」の有無を見るので、文書名の直後で省いた形はそこで赤くなります——規約から外れた分だけが 検査の外に出ると、書いた側は指しているつもりのまま、指し先が消えても緑になります。 拾えるのは文書名の直後だけです——「同 N」と裸の「N」(並びの続きも含みます)で「節」を落とした 形は、同840・2 節、1 つの物のような数量と字面で見分けが付きません。そこで省いた番号は、 参照ではなく数量として扱われます——指し先の実在も中身も、自動テストと参照を検める係 (refs-prompt.md)のどちらも読みません。節を指すなら、 書く位置にかかわらず「節」を書きます。 - 範囲(
N〜M節)と列挙(N・M節)は、末尾の「節」が並び全体に掛かります。 挙げた番号は どれも実在の節として検査されます。並びに繋げてよいのは節番号だけです——段0・N節のように 別のものを混ぜると、そちらまで節番号として読まれます。 - 番号だけの参照(「4 節」)は同じ文書の節を指します。コード・YAML では
GameElementDefinition.md(WorldCodex 文法)の節を指す既定とします。「同 N節」は、同じファイル内で 直前に名前を挙げた文書の節を指します。文書名の言及から離れた場所で、他の文書の節を番号だけで 指してはいけません——読み手にも自動テストにも解決できません。 - 節番号を持たない見出し(
Localization.mdの項目など)は文書名.md 〇〇節と名前で指せます。自動テストが実在を検査します。 - Markdown 以外のファイル(スクリプト・コード・YAML・Python・
tools/**の JSON)の節は、`スクリプト.sh`「〇〇」と鉤括弧で指します。 引けるのは、散文に書いた見出し (# ## 〇〇/// ## 〇〇)と太字の一文、それにテストの題(it('〇〇'))です ——冒頭の塊には見出しが無いので、そこへ置いた一文は太字が名前の代わりになります。散文は ふつうコメントですが、Python は docstring、JSON は文字列の値に置いたものを読みます。 どれも自動テストが実在を検査します。地の文の一文を引きたいなら、指し先の側で太字にします。 コードの字面(出力の頭に付く綴り・場合分けの値) を指すなら、鉤括弧ではなくバッククォートで囲みます——鉤括弧は「そこに在る主張を名指した」と いう宣言なので、名前になっていないものに付けると参照切れとして赤くなります。 - 長い見出しは、省略の
…を挟んで端だけを引けます(`archive-session.sh`「片付かなかった行は…」)。 照合では任意の字に当たるので、省いた形でも実在が検査されます。 - 文書内・文書間の Markdown リンク(
[<表示名>](#<アンカー>)/[<表示名>](<パス>#<アンカー>))も 自動テストが解決を検査します。ソースのコメントに書いたリンクも同じ検査に入ります ——TypeDoc が/reference/を作るときに読む側なので、切れたままだと公開の頁のリンクが死にます。 見るのはコメントだけで、行の途中から始まるコメントは落とします(文字列・正規表現の中の//・#と見分けられないためです)。どの形式を読むかはtests/docs/docReferences.test.ts(COMMENTED_EXTENSIONS)が持ちます——そこに挙がっていない 形式は、コメントを書けても読まれません。 - リポジトリ直下から書いたパス(
agent-ops/policies.md・tests/art/**)も、実在の指し先です。 リンクでなくても、囲みの中でも地の文でも同じに検査されます——置き場が動けば、どちらの綴りも同じ ように嘘になるためです。パスとして読むのは、末尾が/・*を含む・最後の段に拡張子が付いて いるのどれかを満たす綴りだけで、それ以外(MCP のtools/callのような名前)は在り処を指して いないものとして外れます。省略の…を含む綴りも外れます——在り処ではなく形を見せている ためで、リンクの指し先と同じ線です(この節の最後)。当時の在り処をそのまま残す側は、この形だけ 検査から外れます(10 節)。 - 検査はコードフェンスの中も本文と同じに見ます。 YAML の例に添えたコメントの参照も、指し先が 動けば嘘になるためです(確定度の印(6 節)はこの逆で、フェンスの中を見ません——そちらは規約が 書式そのものを見せる場所だからです)。
- ひな形(
agent-ops/prompts/)の囲みの中に書くリンクも、他と同じくそのひな形からの相対です。 囲みの中身がセッションの本文になり、受け取った側はリポジトリ直下で読みますが、起点を揃えるのは 渡す手前のscripts/daemon/prompt-body.mjsで、書き手ではありません。先回りして直下からの相対を 書かないでください——ひな形の頁からは開けないうえ、渡る先では起点が二重に付いて外れます。 渡った先で開けるかはtests/docs/docReferences.test.tsが、ひな形の位置から解決するのとは別に見ます。 - 囲みの中の見出しは、
文書名.md 〇〇節では引けますが、アンカーでは引けません。 囲みの中身は 公開の頁ではコードのままで、見出しの ID が振られないためです。ひな形の本体の節を指すなら名前で 指します(アンカーで指すと、リンクが実在の見出しへ解決しないものとして赤くなります)。 - 今は無い名前は
Xxx.yyyの形で書きません。 その形は「今も在るものを指す参照」として自動 テストが検査するためです。消えたメンバーを語るなら「Xxxに生えていたyyy」のように所有者と メンバーを切り離します(そもそも書けるのは、経緯を主題とする文書だけです。9.1 節)。 - ファイルと名前を並べて書いた行は、「その名前がそのファイルに在る」という主張です。 並べ方と、
指し先として引く形式は
tests/docs/docMemberReferences.test.tsが持ちます——形式で絞らない ので、追跡しているファイルなら.ts以外を挙げた行も同じに検査されます。書く場所も問いません ——ソースのコメントに書いた並びも、宣言の値に書いた散文(tools/**の JSON)も同じ主張です。 無いことを語るなら並べません——「board-labels.ymlを挙げたoriginまわり」のように、 主張と読める並びを崩します。名前でないものも並べません(「Foo.mjsの issue #867」)—— こちらは崩さないと、名前として指し先に要求されます。 - 廃止した宣言キー(
RETIRED_SLOT_KEYS(src/loader/parseSlots.ts))を、今も書けるものとして 挙げません。 YAML へ書けばロードが止まりますが、説明が現役のキーとして挙げていても止まりません ——宣言を書く人が先に読むのはそちらです。書き方は、その綴りが今も何かを指しているかで変わります。 今はどこも指していない綴りなら、同じ段のどこかで廃止したと断ります。 一方、スロットの外では現役の 綴り(object_def側のキー・画面側のフィールド)はそのまま挙げてよく、避けるのは YAML の例でslots:の下へキーとして置くことだけです。どちらもtests/docs/retiredSlotKeys.test.tsが検査します。 - 参照ではなく書式そのものを見せたい行は、指し先として読めない形で書きます——リンクなら
<パス>のようなプレースホルダ、節の参照ならファイル名を日本語にした文書名.md N節。 囲み(バッククォート)は逃げ道になりません——囲みは「これは識別子だ」を表す記法で、参照の 書き手は指し先を明示するために付けているためです。リンクの指し先として読むのはASCII のパスに 使える字(英数字と. _ ~ % / -)だけでできていて、点だけではないもので、それ以外 (<パス>・省略の…・コメントが引いた正規表現)は全部、書式の例示として外れます。
6. 確定していることにだけ印を付ける
決定は後から覆ります。印の無い記述を暫定——今はこう書いてあるが覆りうる——という既定にし、 覆すのに判断が要るものにだけ印を付けます。
- 確定した節は、見出しの末尾に
【確定】を付けます。 意味は「覆すには人間の判断が要る」。 読み手は従い、疑問があれば書き換えずに問いとして出します。 - 印が無い節は暫定です(文書単位の宣言がある文書を除く。6.2 節)。従ってよいが、矛盾や不都合を 見つけたら覆す提案を出してよい。決まっていない箇所に仮決めを書いたときも、印を付けずにここへ 入れます。
- 印は確定の側にだけ付けます。 大半は暫定なので、暫定に印を付けると全ページに印が並び、
背景になって読めなくなります。印は少数側に付けたときだけ印として働きます。 暫定の側に印を
付ける語(
【未確定】・【暫定】)は使いません。自動テストが検出します。 【確定】は内容が正しいという主張ではなく、変更権限の宣言です。 確定節の記述が実装や他の節と 食い違っていても、直さずに問いとして挙げます。「動いている方が正しい」で上書きすると、 印の意味が消えます。印そのものも同じです——条件(6.1 節)を満たしていない印を見つけても、 外さずに問いとして挙げます。外せば、覆すのに要るはずの判断を通らずに確定が覆ります。- 確定度と実装状況(4 節)は別の軸です。 確定した未実装の節も、暫定の実装済みの節もあります。
両方付くときは
【確定】を先に書きます(### 節番号 見出し【確定】【未実装: 識別子】)。 - 概要の「確定度と実装状況」(2 節)は文書全体の要約として残しますが、節の印が優先します。
- 印の条件は、印を使う文書すべてに同じに掛かります(掛かる範囲と、そこから外れる記録は 10 節)。
印の意味は置き場で変わらないので、条件も変わりません。記録では印が題材として現れる
(見出しに「
【確定】の印の射程が変わる」と書く)ので、そこは 10 節が外す側に挙げているほか、agent-ops/analysis/**も同じ理由でこの節だけ外れます。条件を満たしていない印を見つけても、 検査を理由に外せません——外すのはユーザーの判断です(この節の「変更権限の宣言」の箇条)。
文書ごとの節数・確定節数・未実装節数は npm run stats:docs が一覧にします。並ぶのは、この節の
条件が掛かる文書すべてです——docs/ の外に置いた確定節も同じ表から数えます(10 節)。
6.1 印を付けてよいのは、射程・中身・出どころ・権限を満たす節だけ
【確定】 は「決定事項に、人間の判断していないことが混ざっていない」ことを保証する印です。
混ざり始めた時点で、決定と暫定の区別が付かないという印を作る前の状態へ戻ります。混ざる経路を
塞ぐのが、見出しに挙げた条件です。射程・中身・出どころは tests/docs/docReferences.test.ts が検査します。権限は
機械では判定できないので、出どころの1行が書けるかという形で出どころの検査に載せています。
-
射程はその節の本文だけで、下位節には及びません。 そのため確定節は下位節を持ちません—— 抱えているなら親には付けず、確定した子だけに付けます(
GameEndings.md8.1節 がこの形です)。親に付けると、見出し1つで下位節の全行が確定になり、どこまでが人間の判断 だったかを読み手が数えられません。【未実装】(4 節)が子節へ継承するのとは逆です——あちらは 主題が無いという事実なので子にも当てはまりますが、こちらは節ごとの変更権限の宣言です。 -
書けるのは、人間が判断したことだけです。 そこから導いた数値・記法・実現方法・名前は仮決め なので、印の外(枝番の節・未決事項)へ出します。本文に「目安です」と添えても効きません—— 印は見出しに付くので、但し書きは印の内側にあります。導出まで囲うと、導出の誤りが人間を通さ ないと直せなくなります。暫定を表す語(「目安」「仮置き」など)が確定節の本文に出ないことを 自動テストが検査します。
-
本文に、出どころの1行を持ちます。 形は
**出どころ**:で始まる1行で、指すのはユーザーが 判断した場所です。### 8.1 1 周回の長さは、作る物の量から出た実測に合わせる【確定】 **1 周回の長さは、作る物を積み上げて出た日数をそのまま想定にします。** **出どころ**: [#656](https://github.com/gooyyu1/UnmappedIsland/issues/656)(1 周回の長さは実測に合わせる)指せる番号があるなら番号で、無ければ何を決めたかで指します。 確認は問い1つにつき issue を 1本立てて訊く(
CLAUDE.md「確認は、1問1 issue で出す」)ので、指すのはその issue の番号です。一覧の中の項目番号は「指せる番号」ではありません——答えの済んだものから詰め替わるので、 書いた当時に正しくても、後から別の決定を指します。 上の例が指しているのは issue そのもの (
#656)と、何を決めたかです。一覧を指すなら、その両方が要ります。 一覧の番号だけを書いた行は、辿り着く先が問いの束なので、 読み手はどれが根拠かを選べず、指した先に対応する項目が無いことにも気づけません。 1問1 issue で 立てた番号は、それ自体が問いと答えなので番号だけで足ります。一覧かどうかは番号から読めないので、 自動テストは一覧の番号を名指しで持っています(
tests/docs/docReferences.test.ts)——閉じない一覧を 新しく作ったなら、そこへ足さないと検査は素通りします。issue を通っていない決定——対話の中で決まったもの——は、
ユーザーの指示と書きます (GameConcept.mdの宣言とVoyage.md2.3 節が この形です)。指す先が無いからと issue の番号を書きません——行は在るのに指した先に何も 無いので、節を読んでも印の根拠に辿り着けません。印は「覆すには人間の判断が要る」という宣言なので、判断の在処が節から読めなければ、宣言が本当か を誰も確かめられません。 これは経緯(旧仕様・変更履歴)ではなく印の根拠なので、
CLAUDE.mdの「経緯はドキュメント本文に書かない」とはぶつかりません。 節のどこに置くかは決めません——本文の先頭は結論の1文の場所(3 節)なので、そこを出どころで 取ると、節の書き方の規約が2箇所へ割れます。自動テストも置き場は見ず、行が在るかと、指し方が 上の形(issue の中の項目を番号で指していない・一覧の番号だけで済ませていない)かを見ます。この行は、印を足したPRがユーザーへ回されるかどうかも決めます。 出どころの無い印は「誰が 決めたのか」を訊きに止まり、issue の番号を指す出どころのある印は、その issue から
判断待ちが 外れているときだけそのままマージされます (needs-user-review.sh)。まだ答えを待っている issue を 指した印は、申告だけで確定が増える形なので止まります。機械が見ているのはここまでで、「答えが 本当にこの節のことか」は見ていません——読むのは差分を読むレビュアーです。ユーザーの指示と 書いた印も止まります——チェックという確かめられる跡が無いので、ユーザーに見せるのが正しい 扱いです。 関門が見るのは、この節の条件が掛かる文書と同じ範囲です(10 節。射程を決めているのはdocScope.mjsの1つで、検査も関門もそこから引きます)——docs/の外の 印も、同じように止まります。ただしmainへ直接 push できる置き場(agent-ops/**)では、 PRにならなかった差分に関門が掛かりません(ParallelAgents.md2節)。 -
付けてよいのは、ユーザー本人の発言か、
判断待ちの issue でユーザーが選んだ答えが あるときだけです。 エージェントの判断——デーモンの指令・issue 本文・レビューコメント・自分の設計判断——からは付けません。 そこから付けた印は、ユーザーの決定ではなく自分の考えをユーザーの名前で配ったものになり、以後の 全セッションがそれを覆せない前提として受け取ります。上の出どころの1行が書けない節には、印を 付けません。
6.2 文書まるごとが土台なら、節ではなく文書単位で宣言する
全節が確定に当たる文書は、節ごとに印を付けず、題名の直後で1回宣言します。
(GameConcept.md がこの形です。)「印は少数側に付けたときだけ働く」
(6 節)は1つの文書の中でも同じで、全節に印が並べば、その文書では印が背景になります。
- 書式は
**本書は全体が確定です。**で始まる段落で、題名(#)と最初の節の間に置きます。 射程はその文書の全行です。 - 宣言のある文書には、節ごとの
【確定】を付けません。 射程が重なるので、印の有る節と無い節の 差が何も意味しなくなります。 - 出どころの1行(6.1 節)を、文書に1本持ちます。 節の印と同じ理由です——判断の在処が読めなければ、 宣言が本当かを誰も確かめられません。
- 中身の条件(6.1 節)は文書の全行に掛かります。 人間が判断したことから導いた数値・記法・名前・ 見せ方は、この文書には書かず、それを持つ仕様書へ移して参照に替えます。確定に耐えない記述を 抱えたまま宣言することはできません——節なら枝番へ逃がせますが、文書の射程に外側はありません。
npm run stats:docsは、宣言のある文書の確定欄を全と出します。
7. 生成物の数値は、結論を支えるものだけ書き写す
stats/*.yaml は生成物で、定義(src/assets/world-codex/)を触るたびに動きます。そこから文書へ
書き写した数値は、動くたびに書き直す義務を生み、同じ行を触る変更どうしがぶつかります。
- 書き写してよいのは、その数を知らないと結論が読めない数値だけです。 結論が「線を跨ぐか」
「どちらが大きいか」で言えるなら、値は判断の根拠でしかないので書かず、
stats/のどのファイルの どの節かだけを指します。読み手が確かめたくなったらそこを開けば、今の値が読めます。 - 同じ値は1箇所にだけ書きます。 他の節からは、その節を番号で指します。2箇所に書くと、片方だけが 古くなるか、生成物が動くたびに両方を書き直すことになります。
- 生成物の表は、そのまま写しません。 表は
stats/に1本だけ持ち、文書にはそこから読み取れる結論 だけを書きます(ContentSkeleton.md8.1.3節・8.3節がこの形)。複数の 節から組み立てた要約は表にしてかまいません(同 8.3節の局面ごとの表)——写しではないので、生成物の 側に置き場がありません。 - 書き写した数値には、出どころのキーを名乗る印を直後に置きます。 印の無い数値は照合に載らず、
再生成で黙って古くなります。書式と、下位桁が主張に効いていないときに書く粗さは
diagnostics/README.mdが持ちます。
結論を支えるものだけに絞る線は、生成物にだけ掛かります。人が書いた定義から引いた数値は、再生成で
ずれる問題を持ちません。印を置くことは定義にも掛かります——定義を動かしたときに文書だけが古いまま
残らないよう、書き写した値の直後に codex: の印を置きます。定義を YAML のまま抜粋するときは、
フェンスに出どころを名乗ります(書式はどちらも同じ diagnostics/README.md)。
8. 数の推移を見せるとき
運用の決め方で動く数を推移として出すときは、数だけを出しません。 7 節の生成物の数値と違い、 こちらは測り方も方式も変わり続けるので、値そのものだけでは何の記録なのかが読めません。
- 何の方式の記録なのかと、1件あたりの規模を添えます。 これらは成果ではなくやり方の記録で、 分母が付いて初めて変化の向きが決まります。
- 「今日時点」として書いた規模の数値は、後の作業でずれても測り直さず、測った日のまま据え置きます。 この種の数値はどうせ動き続けるので、追いかけても正確になる先がありません。効くのはいつ測ったかです。
- 全体の一部しか覆っていない指標は、測れている範囲を注記して載せるのではなく、消します。 表に数がある限り、注記より先に数のほうが全体の話として読まれます。
9. 文書は、失敗の履歴で作らない
書くのは、今どうなっているかと、それが何のために要るかです。 踏んだ失敗から書き起こすと、 文書は起きたことの一覧になり、起きなかったことを構造的に落とします。
- 誤読された記述は、「〜ではない」と打ち消しを足すのではなく、元の記述の曖昧さを直します。 打ち消しは起きた1つの誤読しか塞ぎません。曖昧さが残る限り、次は別の形で誤読されます。
- 仕組みは、踏んだ失敗を並べるのではなく、何のために要ったかとして説明します。 失敗の一覧は、 先回りできて問題にならなかったものを構造的に落とします。
- その仕組み以前から在ったものを、その仕組みの前提として書きません。 それが無くても要るものと、 その仕組みで初めて要るものを分けます。混ぜると、その仕組みが実際に足したものが1つも残りません。
9.1 経緯を書いてよいのは、経緯そのものを主題とする文書と、当時を残す記録だけ
過去の姿を書き残す場所は、それを主題とする文書と、当時を残す記録(10 節)に限ります。
ここに挙げていない文書では、
CLAUDE.md の「ドキュメント・コメントのスタイル」
の禁止どおり、経緯(旧仕様・変更履歴・不採用案・検討過程)を本文へ書きません。
| 文書 | 主題 |
|---|---|
DesignNotes.md |
繰り返さないために残す価値のある、過去の失敗・不採用の決定 |
HowWeGotHere.md |
作り方そのものをどう変えてきたか |
表に無い文書に、過去の姿を語り出す語が生えていないかは自動テスト
(tests/docs/docHistory.test.ts)が検査します(この文書も対象です)。見る語と、除外する文書を
この表から引くことは、そちらが持ちます。この節が docs/ の外のどこまで掛かるかは 10 節です。
次の項目は、この表の文書の中での書き方です——他の文書には掛かりません。そちらには、書き方を 決める対象そのものがありません。
- 変えてきた経緯は、全部を貫く1本の理由で説明せず、回ごとの理由をそのまま並べます。 1本の筋へ 揃えると、筋に乗らない回の理由が事実のほうから削られます。
- ある段が何だったのかは、後で何に効いたかではなく、当時何のために要ったかで書きます。 効いた先 から逆算した説明は、そこへ辿り着くことを最初から狙っていたことにしてしまいます。
- 当時の名前・置き場は、後から変わってもそのまま残します。 今の名前へ書き換えると、その日に その名前の物ができたことになります。今どこに在るかは、経緯を読む人が要るものではありません ——改名や移動で参照を一括して直すときは、この表の文書を対象から外してください。
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)を変えると言い換えた側は一斉に嘘になりますが、
言い換えは宣言から自動では出ないので、この形に揃えない限り見ているものがありません。
- 丸括弧で直接隣に置きます。前後はどちらでもかまいません(
480 tick(5日)・54時間(216 tick))。=でつなぎません——間に語を挟める形にすると、どこまでが言い換えなのかを機械が決められません。 - 人の単位は
日・時間・分だけで組み立てます(1時間15分)。幅を持つなら両側とも〜で 書きます(240〜480 tick(2.5〜5日))。 - 割り切れるならそのままの数を、割り切れないときだけ小数を付けて丸めた数を書きます
(
320 tick(3.3 日))。整数へ丸めた言い換えは書けません——丸めの幅が広すぎて、暦が変わって 長さがずれても同じ字面のまま通ってしまいます。 - レート(
-1/tick)から出した長さも、tick の数を書いてから言い換えます (-1/tick で 960 tick(10日))。レートと人の単位を直接並べた形は、tick の数が書かれていないので 暦から計算し直せません。 - 「一晩」は夜の長さ(
core.yamlのhourの段のうちnightで始まるものの幅)だけを指します。 寝床で通しで眠る1回(sleep)の長さは「睡眠1回」と書き、一晩とは呼びません——夜のあいだの 一部なので、同じ語を当てると長さの違う2つが並んで読めてしまいます。一晩(48 tick)のように 並べれば、夜の長さと照合されます。 - 経過時間ではない tick を数えるカウンタは、この言い換えの対象ではありません。 干し場・塩田の
drying_remaining(drying.yaml)が数えるのは強い日差しの当たった tick だけで、1 日に貯まるのは 24 です。丸括弧で人の単位と並べず、何を数えている tick かを添えて書きます。
tests/docs/tickReadings.test.ts が、並べた数を暦から計算し直して照合します。この照合に見えない
ものもあります。
- 文章で説いた換算(「5 tick かかるので昼を過ぎる」)。数が隣り合っていないので拾えません。
- 定数を埋め込んで組み立てている行(
${...}を含む行)。暦を字で書いていないものとして行ごと 読まないので、同じ行へ字で書いた言い換えを混ぜると、そちらも読まれません。 - 括弧で長さを添えていない「一晩」(「一晩では眠気は返らない」)。夜を指しているのか睡眠1回を 指しているのかは、語だけでは決められません。
- 時間以外の量への換算(
+2/tickから出した「1日あたり 200mL」)。TICKS_PER_DAYに依りますが、 長さではないので照合の形に乗りません。