agent file criteria owned by sentinel region - Liplus-Project/liplus-language GitHub Wiki

エージェント定義ファイルの判定基準を sentinel 区画で所有する判断

Question

.claude/agents/ / .codex/agents/ のエージェント定義ファイルは、ユーザーがカスタマイズする runtime instance なのか、Li+ が所有する判定基準なのか。マージされた基準の変更を既存ワークスペースへ届けるには、所有をどの粒度で決めるか。

Current resolution

どちらでもない — 1つのファイルが両方を同時に運んでおり、所有の粒度がファイル単位であることが欠陥そのものだった。境界をファイル内の sentinel 区画へ移す。 実装は #1740 / PR #1783(2026-08-17、release type = patch は Master 判断)。

  • Li+ BEGIN / Li+ END で囲まれた区画が Li+ 所有・タグ追跡対象。タグ更新で区画のみ置換し、区画外(frontmatter / instance フィールド / ユーザーの書き足し / Codex の skills-disable enumeration)は逐語的に保存する。
  • Li+update.md 4c.6 / 4x.5 は Create-only から3分岐へ。target 不在なら生成、sentinel ありならタグ比較して区画置換、sentinel 無しならユーザーへ確認。
  • 機構は新規ではない。Li+update.md が CLAUDE.md / AGENTS.md に対して既に同じ形を適用しており、それを agent ファイルへ広げたもの。

どのファイルが区画を持つかは、順序つき2問で決まる

列挙ではなく基準で閉じる。

  1. Li+ が判定基準として所有する本文を運ぶか。 No → Create-only。基準がどちらにも置けないファイルも Create-only を既定とする。
  2. ユーザー所有の内容を巻き込まずに、1つの連続区画でその本文を覆えるか。 Yes → 区画を持つ。No(2種が交互に現れる)→ Create-only、そのファイルの伝播欠落は開いたまま。

問い2は brake 1 が生んだものである。初版は問い1のみで、dialogue-evaluator を非 carrier と記録していた。3体の評価者が独立に、その基準の文言を同ファイルの本文へ当てて carrier 側に落ちると判定した — 5つの評価軸・採点モデル・middle-read 要求はいずれも Li+ 所有の判定基準であり、l1-gate-eval の根本基準と構造的に同種だからである。

決め手は1体が加えた区別。初版の fallback は「基準が置けないファイル」を覆う語であって、「本文が両側にまたがるファイル」を覆う語ではなかった。混在は問い1では解けない。問い2を足すことで dialogue-evaluator は Create-only に解決するが、それは伝播させる価値が無いと判定されたからではなく、この基準が閉じられないファイルだからであり、区別が記録に残る。残余は #1784。

Edges

  • relates to brake2-scoped-to-content-not-evidence — 同 entry の「未決の論点」節が本判断の直接の観測元。同 PR のマージが自らの評価者に届かず、Post-L1-Merge 観測が not observable になったことが2度目の測定。
  • relates to l1-brake2-root-criteria-evaluator — 凍結されていたのは同 entry が定めた brake 2 の判定基準そのもの。ゲートの座を専用プロンプトへ移した判断が、そのプロンプトの更新経路を前提にしていた。
  • relates to brake1-firing-closed-by-criterion — 列挙ではなく基準で閉じる同型。ただし本件は基準を1問で閉じたつもりが混在ファイルを取り違え、brake 1 の実測で2問へ広がった。基準化は列挙より強いが、基準自身が射程を測られていなければ同じ穴が開く。
  • relates to bootstrap-walkthrough-skip-and-gh-install-relocation — 再確認の周期が同 entry の3軸 AND gate に寄生している(下記)。

Background

2度測定した。

  • PR #1738(2026-08-13)— マージ直後、main の評価者プロンプトが根本基準6項、インストール済みファイルが5項。Li+update.md 4c.6 が Create-only を定めており、挙動としては仕様どおりだった。
  • PR #1778(2026-08-17)— この評価者プロンプト自体を変更する PR をマージしたが、マージしたワークスペースの評価者には届かない。5分の trigger sample を走らせる経路が無く、Post-L1-Merge 観測の verdict は fire / partial / miss ではなく not observable になった。L1 変更に対して Li+ が要求する観測が、伝播経路の欠落によって実行不能になっていた。

Create-only の設計意図(subagent 定義はユーザーの runtime instance であり、character_Instance.md と同じ扱い)自体は妥当である。問題はその意図が同じファイルが根本基準を運んでいることを見ていなかった点にある。根本基準はユーザーのカスタマイズ対象ではなく、更新が届かないことは「ユーザーの編集を保存した」ではなく「ゲートが古い基準で動き続ける」を意味する。

Constraints

  • rules/model/character_Instance.md の Create-only は変更しない。 問い1で非該当 — Li+ が所有する判定基準を運んでいない。ユーザーのキャラクター定義がタグ更新で消える経路を作らない。
  • Li+update.md の CLAUDE.md 側 sentinel 処理には legacy migration 分岐があり、## Optional Webhook Notification Flow ブロックは byte-frozen である。 agent 側の分岐は新規であり、その migration の非適用を明記した(適用すればユーザー内容を消す)。
  • 区画は1ファイルに1つ、sentinel 文字列は他所に現れない。 区画は最初の出現で位置決めするため、2度目の言及が境界として読まれる。実装中にこの欠陥が実際に発生し、追加したテストが捕まえた — TOML ヘッダへ書いた説明コメントが sentinel 文字列を literal に含んでいた。
  • タグ carrier は区画1箇所のみ。 区画外にタグを持つと、区画だけが更新されるためインストール時のタグで凍り、ファイルが実際に走らせていない版を名乗る。

Conclusion

採った案 = sentinel 区画による所有の分割。

却下した案:

  • cold-start で差分を surface する。 伝播はせず陳腐化だけ見せる案。伝播そのものを閉じる案がある以上、これは safety net であり、rules/model/subtractive-structural-beauty.md の Spec write は required か unnecessary の二値を要求している。
  • 編集有無を判定して上書きする。 Create-only を維持し、ユーザー編集が無いファイルのみ上書きする案。判定の粒度がファイル単位のままで、欠陥の原因を保持したまま条件だけ足す。ユーザーが1文字編集した瞬間に Li+ 所有の本文まで凍る。shipped template の hash を保持する新しい state も要る。
  • マージ後手順に確認を足す。 issue #1740 起票時に自ら「procedure-vs-structure 判定では置き換え対象」と書いていたとおり。

受容した代償

  • Claude 側では sentinel 2行が評価者の system prompt に入る。 frontmatter 以降の全体が system prompt になり、Markdown には host が落とすコメント形式が無い。brake 1 で3/3 が指摘し、修正ではなく受容とした — 回避する唯一の代替は「あの port に区画を置かない」=測定された欠陥を開いたまま残すこと。Codex 側は TOML コメントが developer_instructions 文字列の外に置けるため代償ゼロ。brake 2 の評価者自身がこの2行を「inert as prose — 何も主張せず、軸を足さず、評価を逸らさない」と判定した。
  • 再確認は .claude/CLAUDE.md のタグに寄生する。 sentinel 無しの既存インストールは全て branch (c) に入り確認を受ける。skip を選んだ場合、答えを記録する state は無く branch (c) は target のバイトから毎回判定し直すため、次に bootstrap が走れば再度確認する。bootstrap が走るのはセッション開始マーカーが needed を出したときで、そのタグ軸が読むのは .claude/CLAUDE.md の sentinel であって agent ファイルではない。したがって再確認は次のタグ更新=次のリリースに着地する。リリース間は、skip したワークスペースが追加のプロンプトなしに古い基準のまま座る。 これは branch (c) が隠す欠陥ではなく残余である — 区画導入前の挙動はプロンプト自体が一度も無かった。

検証の到達点

本変更の受理は、マージしたセッションでは確認できない。 host はエージェント定義をセッション開始時に解決してキャッシュしており(#1782)、セッション中の .claude/agents/ への書き込みは以後の spawn に届かない。加えてマージ自体も Create-only の既存インストールには届かない。証拠は「再 bootstrap + 新規セッションで、インストール済みファイルの区画が更新されていること」であり、それが得られるまで本判断は仕様として正しいだけで実挙動としては未確認である。

セッション内で得たものは、テスト(71件)と、追加した assertion のうち効くもの3つの mutation 確認(Codex の sentinel を文字列内へ移す / dialogue-evaluator に区画を付ける / migration 除外条項を落とす —— いずれも落ちる)に留まる。

Related

  • issue #1740 / PR #1783
  • PR #1738 / PR #1778 — 2度の測定
  • issue #1784 — 問い2側の残余(dialogue-evaluator は基準を運ぶが単一区画で覆えない)
  • issue #1782 — セッション内到達の欠落。別軸
  • issue #1779 — 本サイクルで再発した親側の計器欠陥(promotion)