spec 1.0 · 規範
コンテキストレイヤー
Leji コンテキストレイヤーとは、チームが自分たちの仕事をどう捉えているかを表す、人が読める文書の集合です。バージョン管理され、統制されています。ドメインの言葉、システムの不変条件、規約、ガードレール、決定記録が含まれます。人もエージェントも実際の仕事の中でこれを読み、同じレビューのゲートを通じて変更を提案します。履歴、現在性、承認を継続的に検証できるよう、バージョン管理下に置かれます。その仕組みは以下の要件、関係者の関わり方は参加で説明します。
参加#
コンテキストレイヤーへの参加は、ツールではなくロールに基づきます。リポジトリにおけるレビューと承認の意味が保たれるインターフェースであれば、読む、提案する、レビューする、承認するといった行為をどのインターフェースから行っても構いません。参加に git やコマンドラインを直接扱う知識は必要ありません。
- アクセスできる者は全員が読みます。ここでのアクセスとは、チームの通常のツールを通じた実質的なアクセスであって、リポジトリへのシェルアクセスのことではありません。
- 誰でも提案し、承認するのは人です。提案とは、コンテキストレイヤーを変更するための意図的な要求です。人が直接書いても、人の依頼を受けてエージェントが生成しても、観察した作業を基にエージェントが生成しても構いません(MAY)。実際には、コンテキスト変更の多くをエージェントが記述します。人にしかできない寄与はガバナンス、すなわち意図の提案と、何を正典とするかの承認です。変更を承認する人が説明責任を負うのは、その意味と帰結であり、自らバージョン管理システムを操作することではありません。
- 意味は人のもの、サーフェスは機械のもの。チームの運用上のコンテキストについて規範となる出典は、人が読める文書です。機械可読なファイル(マニフェスト、インデックス、変更履歴)は、ツールがその意味を見つけ、インデックスし、検証し、同期できるようにするために存在します。それらが意味に取って代わることはありません。
これらの流れの規範的な形、すなわち輪(全員が読み、誰でも提案し、人が承認する)は governance.md で定義されます。
記録を読む#
統制された内容には、content-categories.md で定義される 2 つの種類があります。現在の真実として維持される意図と、後の状態によって訂正されるのではなく置き換えられる、日付付きの証拠である記録です。どちらも同じように統制されます。異なるのは、読み手が読み込んだ内容をどう扱えるかです。読み手は、記録を現在の意図として扱ってはなりません(MUST NOT)。記録は、記載された境界内で真である証拠として情報を提供します。記録の主張であることを明示せずに現在の状態として提示すると、読み手はその文書にない現在性を作り出すことになります。これは、以下の縮退モードの規則と同じ構図です。いずれの場合も読み手には、自分がどの種類の現在性を得ているかを把握し、それを明示する義務があります。
要件#
-
コンテキストレイヤーは git リポジトリの中に置かれなければならず(MUST)、それが説明する仕事と一緒にバージョン管理されなければなりません(MUST。同じリポジトリでも、distribution.md に従って利用される専用のコンテキストリポジトリでも構いません)。コンテキストレイヤーの履歴、チェックアウトの現在性(手元の写しが正典のリポジトリと一致しているか)、追記のみの変更履歴の完全性を検証可能にしているのが git リポジトリであり、適合するツールはその 3 つすべてをそこから導きます。そのリポジトリなしにコンテキストレイヤーを読むことは、読み取りモードで定義される、対応はされているが縮退したモードです。
-
Leji を採用するリポジトリは、リポジトリルートにマニフェストファイル
leji.jsonを持たなければならず(MUST)、それはcontext-manifest.schema.jsonに照らして妥当でなければなりません。マニフェストは機械向けのエントリポイントです。仕様バージョン(自らを名乗るlejiキー)、コンテキストレイヤーの名前、コンテキストルート、ブートプロファイルのパス、カテゴリの割り当て、任意の適合性の宣言、そして所有を宣言します。ロール識別子(たとえばthought-partner、reviewer)をエージェントプロファイル文書に結び付けるagentsマップを持っても構いません(MAY)。プロトコルがロールを関与させ、そのロールを誰が担うかはこのマップが決めます。このマップはロールの一覧であって読み込み順ではありません。defaultキーのものも含め、バインディングがプロファイルを読ませることは決してなく、それを行うのはブートプロファイルの Loading セクションだけです。 -
マニフェストはアクター、すなわちロールを担える名前付きの参加者を宣言しても構いません(MAY)。各アクターは、自分が担えるロールと、ロールごとのコマンドテンプレートを宣言します。コマンドをロールで引くことが要点です。ひとつのアクターでも、どのロールを担うかによって必要な起動方法が変わりうるので、アクターごとに 1 つのコマンドでは表現できません。アクターが宣言するロールと、そのコマンドのキーは、同じ集合でなければなりません(MUST)。あるロールにアクターがいる場合、そのロールに結び付いたエージェントプロファイルは
invocationを併せて宣言してはなりません(MUST NOT)。優先順位の定めのない権威あるコマンドが 2 つあることは矛盾であり、レイヤーはコマンドを 1 か所で宣言することでそれを解消します。アクターは任意であり、ほとんどのレイヤーには不要です。それが役に立つのは、ひとつのロールに担える者が複数いる場合か、ひとつのアクターが担うロールによって別の起動方法を必要とする場合です。どちらか一方でも十分な理由になります。担い手がひとりで、必要なコマンドもひとつであるロールには、プロファイル自身のhostとinvocationで足ります。アクターを宣言しても権限は与えられません。それが言うのは、誰にロールを頼めるかであって、誰が承認してよいかではありません。コマンドテンプレートは、どこに現れるものであっても(アクターの
commandsの値でも、エージェントプロファイルのinvocation.commandでも)ひとつの規則に従います。テンプレートは、呼び出す側が選んだシェル向けのコマンドラインです。シェルの形をとらない関与の仕方(構造化された argv 呼び出し、プロセス内での起動)は、1.0 系列ではこれらのフィールドでは表現できません。すべてのテンプレートは<prompt>プレースホルダーを含まなければならず(MUST)、その各出現は、引用符の中や他のテキストと結合した形ではなく、引数の位置にある引用符のないひとつのシェル語として立たなければなりません(MUST)。置換は 1 回限りです。書かれたテンプレートに存在する出現が、同時に、ちょうど一度だけ置き換えられるので、プロンプト本文の中にある文字列<prompt>はデータのまま残り、再展開されることはありません。受け渡しは呼び出す側の責任であり、契約となるのは引用の手順ではなく、求められる結果です。すなわち各出現は、値がプロンプト本文と等しい引数をちょうど 1 つ生み、その一部がシェルの構文として評価されることはありません。スキーマが確かめるのは置換箇所の存在です。配置と受け渡しは、この規則が要求し、呼び出す側が守るべきものです。 -
マニフェストはコンテキストルート(
rootPath)を宣言しなければなりません(MUST)。推奨される既定値はdocs/です。コンテキストレイヤーのパスはすべて POSIX 形式で、リポジトリルートからの相対です。rootPathはコンテキストレイヤーがどこにあるかを宣言するものであって、自らが管轄するパスの基点を変えるものではありません。インデックスのエントリ、ピン留めしたページ、プロファイルのパスをはじめ、Leji のあらゆる成果物のその他すべてのパスは、rootPathの接頭辞を繰り返しているものも含め、リポジトリルートから解決されます。ビューアーのhomepage、logo、faviconは例外です。これらはコンテキストルートからの相対で書かれ、その下に収まるリポジトリルートからの相対パスも受け付けられます。カテゴリとmachineのパスはrootPathの下にあるべきです(SHOULD)。そうでない場合、バリデーターは警告します。 -
コンテキストレイヤーは、boot-profile.md に従うブートプロファイルを持たなければなりません(MUST)。推奨される既定の場所は
docs/boot-profile.mdです。実際の場所はマニフェストのbootProfilePathが宣言します。 -
コンテキストレイヤーの内容は、まず人が読めるものでなければなりません(MUST)。散文には markdown が推奨される形式です。構造化されたメタデータには YAML フロントマターか、machine-readable-surface.md で定義される JSON 成果物を使います。機械にしか読めない文書は、コンテキストレイヤーに属しません。
-
コンテキストレイヤーには、名前の分かる所有者(マニフェストの
owners.primary)がいなければなりません(MUST)。その内容がいまのものであることに責任を負う人です。所有者のいないコンテキストレイヤーは腐ります。
読み取りモード#
コンテキストレイヤーは 2 つのモードで読まれます。保証が異なるので、読み手は自分がどちらのモードにいるかを知らなければなりません(MUST)。読み手は、何を解決できるかから自分のモードを判断します。リポジトリルートに到達可能な leji.json があり、かつ git のワーキングツリーかホストプラットフォームのリポジトリのリビジョン識別のどちらかがある場合は正典です。そのどちらもなく、ただのファイルとして到達した内容は縮退です。
- 正典(canonical)。読み手は、git リポジトリを通じてコンテキストレイヤーを解決します。チェックアウトか、ホストプラットフォームのリポジトリビューです。履歴、チェックアウトの現在性、変更履歴の完全性が検証可能であり、承認された内容は読んだリビジョンの時点でいまのものだと分かります。
- 縮退(degraded)。読み手は、アクセス可能な git のワーキングツリーもバージョンのメタデータもない、ただのファイル内容としてコンテキストレイヤーに到達します。リポジトリを伴わずに、別のインターフェースへアップロード、同期、コピーされたファイルです。ただのファイルとして読むことは、読むことについては一級です(文書は要件により人が読めるものであり、機械可読な変更履歴は宣言された新しさをなお伝えます)。しかし縮退した読み手は、チェックアウトの現在性と承認の状態を未知として扱わなければならず(MUST)、いまのものとして扱ってはなりません(governance.md の鮮度を参照)。このモードでは、変更履歴が持ち運び可能な、宣言された新しさのサーフェスです。それ自体が、その写しが正典のリポジトリと一致していることを立証するわけではありません。
縮退した読み取りは、誰が何をコンテキストレイヤーの読み手にできるかを広げますが、正典の権威への道になることは決してありません。変更が正典になるのは、git に支えられたレビューのゲートを通ったときだけです。また縮退した写しは、フェデレーションが依存する正典モードのチェック(ピンの現在性、古いピンの状態、所有の健全性、distribution.md に従う制限付きマウントのアクセス)を満たせません。
ベンダーアダプタの規則#
エージェントホストの設定ファイル(たとえば CLAUDE.md、AGENTS.md、GEMINI.md、.cursorrules、.cursor/rules、.windsurfrules、.github/copilot-instructions.md)について。
- 正典のコンテキストレイヤーの内容を持ってはなりません(MUST NOT)。
- 存在する場合、ブートプロファイルへ誘導しなければなりません(MUST。通常は一行のポインタです)。
- そのエージェントホストの外では意味を持たないホスト固有の仕組み(モデル選択、ランナーの設定)を持っても構いません(MAY)。ただし、チームの知識がそこに置かれないことが条件です。
- ツールは、どのエントリポイントを確認すべきかを 2 つの出典から知ります。マニフェストの任意の
vendorAdaptersの一覧と、公開された周知の集合(上に挙げたファイル群)です。上の例の一覧が、この系列における周知の集合です。エントリポイントがそこに含まれないホストは、マニフェストがvendorAdaptersでそれを名指ししたときにだけ確認されます。
既存のエントリポイントの慣習は、エージェントホストにどこを見るかを伝えます。Leji が定めるのは、エージェントがそこで何を見つけるかです。出典はひとつで、すべての参加者がそれを読みます。
コンテキストレイヤーではないもの(非規範的)#
- ウィキではありません。ウィキには、最新の状態を保つ仕組みがありません。コンテキストレイヤーが機能し続けるのは、エージェントが作業のたびに読み(誤ったコンテキストは、すぐに問題だと分かる誤出力を生みます)、変更がコードと同じようにレビューされ、ツールによって古さが可視化されるからです。
- 従来の意味でのドキュメントではありません。ドキュメントは、システムが何をするかを事後的に説明します。コンテキストレイヤーは、チームがどう考えているかを現在形で表し、人にもエージェントにも継続的に読まれます。
- 取り込むテンプレートではありません。借りてきたコンテキストは、すぐに古くなります。コンテキストレイヤーの価値は、そのチーム自身の考えが表現されていることにあります。Leji が標準化するのは形とガバナンスであり、内容ではありません。