config value comparison strict and surfaced - Liplus-Project/liplus-language GitHub Wiki

Li+config の値比較は厳格に、外れた値は名指しで surface する

Question

Li+config.md の値を hook が読んで分岐するとき、大小混在や綴り違いのような設定ミスをどう扱うか。

Current resolution

厳格化と検出を併せて行う。正規化はしない。

  • 厳格化 —— 3 port(adapter/claude/hooks/*.sh / adapter/codex/hooks/*.sh / adapter/codex/hooks/*.ps1)で大小を区別する比較に揃える。PowerShell は既定が case-insensitive なので、値比較は -ceq / -cne、switch は -CaseSensitive、Select-String によるキー名照合も -CaseSensitive を明示する。bash は sed / awk / case / [ がいずれも既定で区別するため変更しない。
  • 検出 —— 値が既知集合のいずれでもなく、かつ空でもないとき、hook はキー名と実際の値を含む1行を emit する。既定へ倒す挙動そのものは変えない。空値は未設定であり既定が正しいため、検出対象に含めない。

対象は Li+config.md から読んだ値の比較のみ。ホストが生成して hook へ渡す文字列(SessionStart の matcher、PostToolUse の tool 名)は入力の出所が違うため別軸(#1884)。

Edges

  • distributed-source-carries-no-resolved-config-value に relates to —— 同 entry は解決値を配布面へ書かない軸、本判断は読んだ値をどう比較するかの軸。どちらも Li+config.md の記述と実際の挙動の間にずれを作らない方向に働く。
  • workspace-clone-identity-resolved-by-remote に relates to —— 同 entry も「判定が黙って一方へ倒れる」欠陥への解であり、分岐集合を全域にして曖昧な入力を STOP へ送る形を採っている。本判断の検出はその hook 版。

Background

LI_PLUS_WEBHOOK_DELIVERY=Mcp_Hook と書かれた workspace で、bash port と PowerShell port が逆の結論に至っていた。bash の [ "$v" != "mcp_hook" ] は区別して「違う」と読み、PowerShell の -ne は区別せず「同じ」と読む。同一 config を読んで、片方は poll の呼び出し半分を emit し、もう片方は抑止する。

決定前の掃引(2026-09-05、hook 6本)で同型がもう1件見つかった。LI_PLUS_CHANNEL は bash が case ... in latest) release) tag)、PowerShell が switch ($channel) で、後者は既定で case-insensitive。Latest と書かれた場合、bash はどの分岐にも入らず needed へ倒れ、PowerShell は一致して tag を解決し unnecessary を出しうる。倒れる向きが逆で、PowerShell が危険側にある。

第二の軸も出た。値の比較だけでなくキー名の照合でも割れていて、on-session-start.ps1 は3箇所とも -CaseSensitive を明示しているのに on-user-prompt.ps1 だけ付いていない。PowerShell port の内部で不整合だった。

Constraints

  • Li+config.md テンプレートのコメントは既知値を小文字で列挙しており、大小混在を有効と述べる記述はどこにも無い。したがって混在値は設定ミスである。
  • 最も悪い性質は分岐そのものではなく沈黙。port が割れることも問題だが、揃っていても黙って既定へ倒れるなら、設定ミスは誰にも観測されない。
  • 検出の対象は「未知の値」であって「大小混在」ではない。綴り違い(mcp-hook)も同じ経路で名指しされる。

Conclusion

正規化(読み取り直後に小文字化して受理する)を採らなかった。 塞ぐ範囲が狭いため。Mcp_Hook は通るようになるが、mcp-hook は依然として黙って既定へ倒れる。検出はこのクラス全体を塞ぐので、正規化を重ねても検出の担う範囲は減らない。加えて、受理値集合を広げる根拠が文書のどこにも無いまま広げることになる(rules/model/subtractive-structural-beauty.md の subtraction 既定に反する)。

厳格化だけでも足りない。 3 port が揃って黙って倒れるだけで、沈黙という最悪の性質が残る。

検出だけでも足りない。 port 間の分岐が残る。

両方が要る、という結論。rules/model/subtractive-structural-beauty.md の「binary only —— required or unnecessary」に照らせば、設定ミスは有効でないのだから、黙って既定へ倒れるのではなく必ず名指しされなければならない。

Related

  • issue #1804 / PR #1883(2026-09-05、AI 単独 initiator 経路)
  • 派生 issue #1884(ホスト生成文字列の比較。本判断の対象外として据え置いた分)
  • tests/test_config_value_parity.py(3 port × 大小混在 / 未知値の契約テスト)