brake1 firing closed by criterion - Liplus-Project/liplus-language GitHub Wiki

brake 1 の発火条件は path 列挙でなく「検出器が読み手しか無い面か」の基準で閉じる

Question

self-evolution PR の定義(2 条件の AND)のうち条件 2 は、rules/**/*.md / skills/**/SKILL.md / adapter/**/* の 3 種を列挙する形だった。この列挙はリポジトリの実ツリーとずれており、同じ欠落に対して逆方向の判断が 2 回下されている。条件 2 を何で閉じるか。

Current resolution

列挙ではなく基準で閉じる。基準は「その面は振る舞いを規定し、かつ誤りを捕まえるものが読み手しか無いか」。

導出は装置の性質から来る —— brake 1 の検出器は読み手(N>=3 の評価者)である。したがって brake 1 が意味を持つのは、読む以外に誤りが露出しない面に限られる。列挙されている path は「これまで出てきた事例」であって条件を閉じるものではない、と本文が明示する。

3 つの帰結が literal になった。

  • 発火側: 散文として読まれ実行される面(rules/**/*.md / skills/**/SKILL.md / adapter/**/* / Li+update.md)と、強制の後ろ盾(tests/** と .github/workflows/** = 実行コードだが背後にチェックが立たない。テストは黙って通る方向で壊れても green を返し、workflow はトリガが噛み合わなければ run 自体が起きず赤いチェックすら出ない)。
  • 非該当: 記録面(docs/** / wiki / README.md / LICENSE / NOTICE —— 誤りの代償は引き直し 1 回)と、背後にチェックが立つ実行コード(scripts/** / .github/scripts/**)。
  • 既定の腕: 基準がどちらにも置かない面は発火側に落ちる。「不要な eval の代償は eval 1 回、取り逃がしの代償は門そのもの」という非対称による。これにより基準は全域的になり、ツリーに未登場の path についても判断の残余が残らない。

あわせて、Scope 列挙(AI が起票してよい面)と条件 2(brake 1 が門を張る面)が別軸であることを条件 2 側に 1 箇所だけ明記した。同一ファイル内に docs/ が逆の membership で 2 度現れるためで、写しは Scope 側に置かない。

Edges

  • depends on parallel-subagent-eval-cost-acceptance — 基準の導出が「brake 1 の検出器は N>=3 の読み手である」に全面的に乗っている。brake 1 が読み手以外の検出器(静的解析・自動 lint 等)を持つ設計へ動けば、基準そのものが再評価対象になる
  • depends on liplus-evaluation-criterion — 既定の腕の非対称(eval 1 回 vs 門そのもの)を秤にかけている軸
  • conflicts with (現時点で対立 entry なし)

背景

同じ欠落が 2 回、逆方向の判断で埋まっていた。

PR 変更面 親の判断 根拠
#1670 tests/ のみ brake 1 を適用 安全側。当該テストは #1662 が「description 上限を構造で止める」ために置いた検査そのもので、抽出器が黙って通る方向で壊れることは brake 1 が守る失敗モードと同型。literal でなく判断
#1698 docs/ のみ brake 1 を回さない 条件 2 に docs/ が無い(字義)/記録面である/実質の変更が wiki にあり PR 差分に載らない。literal に従った

個別にはどちらも筋が通るが、次に同型が来た時の再現が保証されない。

加えて 2026-08-08、PR #1700 の委譲先が「brake 1 のみ該当」と報告した。条件 1(起票経路)だけで判定した形で、AND の片方の連言だけで発火条件を判定する誤り。実害は safer-side 方向のため出力には現れず、報告文の一語にしか出なかった。

親が実ツリーと突き合わせた結果、ドリフトは issue が挙げていた tests/ にとどまらなかった。.github/ も両列挙の外、hooks/(トップレベル)は存在しないパスを Scope が名指ししている状態だった(hook は adapter/claude/hooks/ と adapter/codex/hooks/ にあり adapter/ が既に覆う)。

制約

  • brake 1 / brake 2 の意味論・発火位置・N 数は不変。触るのは「どの PR が brake 1 の対象か」の判定面のみ
  • Scope の射程は広げない。tests/ / .github/ を Scope へ足したのは行使済みの権限を記録する行為であり、実測(#1670 / #1404 / #1408 / #1571)に裏づけられた path だけを入れる。見込みでは入れない(brake-adjudication-by-resumed-author の元となった #1694 が置いた「実測された逸脱に対してのみ格上げ」と同じ形)
  • 「親が忘れないようにする」形の解(注意書き・チェックリスト追記)は不可。根拠は rules/model/subtractive-structural-beauty.md の procedure-vs-structure 二値

却下した選択肢

列挙に tests/ と .github/ を足して閉じる案。 足せば当座は埋まるが、次にツリーへ現れた path で同じ判断が再発する。#1691 / PR #1694 が注入リストに対して出した「列挙でなく基準で閉じる」と同型の問いであり、同じ側へ倒した。

除外側に carve-out を積む案。 brake 1 の評価で実際に浮上した形。.github/workflows/** の取りこぼしに対し carve-out を足せば、除外の property ラベル(当時は "自ら失敗を報告する実行コード")が偽のまま例外だけが増える —— 条件 2 から取り除いた「property のラベルを名乗る path 列挙」を、除外側で再生産することになる。property の側を書き換える(Executed code a check stands behind / 発火側は enforcement backstop)形へ寄せて、1 行で 3 つの対象を解決した。

brake 1 で親側の欠陥が 2 件出た

本 entry の判断そのものが brake 1 の指摘で 2 箇所変わっている。記録として残す。

  1. 基準の穴(軸 2、2/3)= 親の書いた除外 property「実行コードは自ら失敗を報告する」は、トリガが噛み合わなくなった workflow が run 自体を起こさないケースを覆っていなかった。基準の全域性を問う軸が、その軸を書いた親の基準を突いた形。
  2. 引用の事実誤り(軸 3、1/3)= .github/ の実測引用 4 件のうち #1568 は Master 起点で、当該 PR の本文が自ら「initiator path に該当しない」と書いている。親は著者の挙げた引用をそのまま軸の Basis に載せ、開いていなかった。同時に「initiator path とは起票と実装を決めた主体であって push したアカウントではない」という literal が追加された。

検出サイン(この判断が後で疑問視される場合)

  • 「この path を列挙へ足すべき」と提案された時 → 足す前に基準を当てる。基準が判定するなら列挙は不要で、判定できないなら基準の側に穴がある
  • 除外側へ carve-out を足そうとしている時 → property ラベルが偽になっていないか。偽になるなら property を書き換える側が正しい
  • docs/ の membership を Scope 側から読んで条件 2 を判定しようとした時 → 二つは別軸で、docs/ はまさにその 2 つが食い違う唯一のエントリ
  • 発火条件を「AI が起票して AI が実装した」だけで判定した時 → 2 条件の AND であり、片方では決まらない(#1700 の実測)