purpose
clone mode の exists 経路(Li+update.md:128-139)は、clone の HEAD が tag に detached で乗っていることを前提に書かれている。HEAD がブランチに在ると a. が解決を要求する current checked-out tag が定義されず、b. / c. のどちらにも噛み合わないまま人間ゲートに入る。
穴の位置は「ブランチの枝が無いこと」ではない。Li+update 自身はその状態を作らない(not exists 経路は git checkout {target_tag} で detached を作る)。穴は、自分が作らない HEAD 状態を渡されたときに a. が解決不能になり、そのことを検出しないまま先へ進むことの側にある。
premise(検証済み、2026-09-08 実測)
(1) 実際にその状態の clone が在る。
{workspace_root}/liplus-language の実測:
$ git branch --show-current -> main
$ git rev-parse --short HEAD -> f8e8c6f
$ git describe --tags -> build-2026-09-07.6
$ git rev-parse build-2026-09-07.6 -> f8e8c6f
HEAD は tag ではなくブランチ main に乗っている。describe が綺麗な tag 名を返すのは、main の先端がたまたまその tag の指す commit と一致しているためであって、tag を checkout しているからではない。
(2) この状態は今日の運用操作で作られた。
.claude/ を共有する 2 セッションの一方が、ローカル main の遅れを追従させるため git checkout main + git merge --ff-only origin/main を実行した。それ以前は detached で tag に乗っていた。仕様の literal がこの状態を作ったという主張ではない。 not exists 経路(Li+update.md:124-127)は git checkout {target_tag} で detached を作る。
(3) a. の値が定義されない。
a. の literal:
a. Resolve and report both values: current checked-out tag and target tag from LI_PLUS_CHANNEL.
HEAD がブランチに在るとき「checked-out tag」は存在しない。git describe --tags はブランチ先端が tag を追い越していれば <tag>-<N>-g<sha> を返すが、これは tag 名ではないので b. If same とも c. If different とも比較できない。現在は main の先端が .6 と一致しているため describe が偶然 tag 名を返しているだけで、main が 1 commit 進んだ時点で比較対象そのものが tag でなくなる。
(4) 誤読の実例が出ている。
2026-09-08、本 issue の起票者自身が git describe --tags --exact-match の戻り値を current checked-out tag として報告し、部屋と human への報告の両方に載せてから訂正した。exact-match は「HEAD の commit にその tag が付いている」しか言わず、tag を checkout しているかは言わない。手順が名指す値を、それを答えない道具で答えられてしまう形が現に踏まれている。
constraints
解(2026-09-08 確定)
(b) を採る —— exists 経路の入口で想定外の HEAD 状態を検出し、STOP して報告する。修理はしない。
根拠は同一ファイル内の先例。Li+update.md:497-498 は、workspace のディレクトリ解決が曖昧になったとき STOP して両方のパスと出所を報告し、こう述べている:
Which of the two is the working tree is not a judgment Li+ makes.
同じ形の問題が、同じファイルで既に一度この形に解かれている。 「Li+ が作らない状態を渡され、どちらが正かを Li+ は決めない」という構造が一致する。HEAD がブランチに在るとき、それが事故なのか運用上の意図なのかは clone の外にある情報で、Li+update.md はそれを判定する材料を持たない。
棄却 — (a) a. に attachment 判定を足し、「tag 無し」として解決して c. へ流す。 c. は既に 2 択の人間ゲートを持っており、そこへ「そもそも tag に乗っていない」を第 3 の状態として流し込むと、選択肢の意味が枝ごとに変わる(update now to the target tag は detached からの checkout と、ブランチからの離脱で副作用が違う)。rules/model/subtractive-structural-beauty.md Surfaces of freedom の Decision 面を増やす側。
棄却 — (c) detached を要求し、tag へ戻すことを human に求める。 clone をどう置くかは運用の選択であり、Li+update.md が決めることではない。(b) の報告を受けた human が tag へ戻すことを選ぶのは自由だが、手順がそれを要求する形は判断の越権にあたる。
検出の literal。 git symbolic-ref -q HEAD が値を返す(= ブランチに在る)ことを判定に使う。git describe 系は使わない —— 本 issue の premise (4) が示すとおり、あれは attachment を答えない道具である。
未検証の前提(ready 後も残る)
- 他ワークスペースでの再現性。 観測は 1 clone のみ。ただし解が「検出して報告する」である以上、再現性は解の妥当性に影響しない(在れば報告され、無ければ何も起きない)。
実装順序(#1911 との直列化)
#1911 と target files が全面的に重なる。 両者とも Li+update.md の clone mode exists 経路(128 行目付近)を触る。rules/operations/main-agent-procedures.md Sub-issue rules, Parallel conflict analysis の判定では overlap 有り = 並列不可。
両者は sibling issue であって sub-issue ではない(分類 litmus: どちらも単独で ship でき、他方の成果物を壊さない)。したがって親子構造は作らず、直列に実行する。後続は先行のマージ後に base を取り直す。
順序 = #1911 → #1917(2026-09-08 合意)。 単なる base 取り直しの回数ではなく、解の形が片方向に依存するため:
#1911 の未決の解には (b) refspec を自動修復するが含まれている。これが採られると exists 経路は「検出して報告する」だけでなく「検出して直す」を持つことになる。本 issue の解 (b) は「検出して報告する。修理はしない」で確定しているので、#1911 が自動修復側に倒れた場合、同一経路の中に修理する検査としない検査が並ぶことになる。その並びを許すかどうかは #1911 の決定時に見えているべきで、逆順だと本 issue の実装後に前提が動く。
したがって #1911 の解を決める時点で、本 issue が「報告のみ」で確定していることを材料に入れてよい。
決着(2026-09-08)。 #1911 の解は (a) 検出のみ・自動修復なしに確定した。したがって上記の分岐は起きない —— exists 経路は、本 issue の解 (b) と合わせて 「気づかない状態を検出して報告する。直さない」という一つの姿勢で揃う。同一経路の中に直す検査と直さない検査が並ぶことはない。
この確定により、本 issue の実装は #1911 のマージ後に着手できる。前提は動かない。
target files(予想、解が決まるまで暫定)
Li+update.md — clone mode exists 経路(128-139 行)
docs/ — 該当する要件仕様(同一 PR で更新)
分類
Li+update.md は governed surface(rules/evolution/initiator-autonomy.md Governed surface)なので self-evolution PR に当たり、brake 1 が発火する。release type は解に依存するため未定。
関連
purpose
clone mode の
exists経路(Li+update.md:128-139)は、clone の HEAD が tag に detached で乗っていることを前提に書かれている。HEAD がブランチに在るとa.が解決を要求するcurrent checked-out tagが定義されず、b./c.のどちらにも噛み合わないまま人間ゲートに入る。穴の位置は「ブランチの枝が無いこと」ではない。Li+update 自身はその状態を作らない(
not exists経路はgit checkout {target_tag}で detached を作る)。穴は、自分が作らない HEAD 状態を渡されたときにa.が解決不能になり、そのことを検出しないまま先へ進むことの側にある。premise(検証済み、2026-09-08 実測)
(1) 実際にその状態の clone が在る。
{workspace_root}/liplus-languageの実測:HEAD は tag ではなくブランチ
mainに乗っている。describeが綺麗な tag 名を返すのは、main の先端がたまたまその tag の指す commit と一致しているためであって、tag を checkout しているからではない。(2) この状態は今日の運用操作で作られた。
.claude/を共有する 2 セッションの一方が、ローカルmainの遅れを追従させるためgit checkout main+git merge --ff-only origin/mainを実行した。それ以前は detached で tag に乗っていた。仕様の literal がこの状態を作ったという主張ではない。not exists経路(Li+update.md:124-127)はgit checkout {target_tag}で detached を作る。(3)
a.の値が定義されない。a.の literal:HEAD がブランチに在るとき「checked-out tag」は存在しない。
git describe --tagsはブランチ先端が tag を追い越していれば<tag>-<N>-g<sha>を返すが、これは tag 名ではないのでb. If sameともc. If differentとも比較できない。現在は main の先端が.6と一致しているためdescribeが偶然 tag 名を返しているだけで、main が 1 commit 進んだ時点で比較対象そのものが tag でなくなる。(4) 誤読の実例が出ている。
2026-09-08、本 issue の起票者自身が
git describe --tags --exact-matchの戻り値をcurrent checked-out tagとして報告し、部屋と human への報告の両方に載せてから訂正した。exact-match は「HEAD の commit にその tag が付いている」しか言わず、tag を checkout しているかは言わない。手順が名指す値を、それを答えない道具で答えられてしまう形が現に踏まれている。constraints
exists経路のみが対象。not existsの 2 コマンド literal には触れない。exists経路だが別の欠陥。あちらは fetch 能力(refspec が branch を含むか)、こちらは HEAD の attachment。片方を直しても他方は残る。解(2026-09-08 確定)
(b) を採る ——
exists経路の入口で想定外の HEAD 状態を検出し、STOP して報告する。修理はしない。根拠は同一ファイル内の先例。
Li+update.md:497-498は、workspace のディレクトリ解決が曖昧になったとき STOP して両方のパスと出所を報告し、こう述べている:同じ形の問題が、同じファイルで既に一度この形に解かれている。 「Li+ が作らない状態を渡され、どちらが正かを Li+ は決めない」という構造が一致する。HEAD がブランチに在るとき、それが事故なのか運用上の意図なのかは clone の外にある情報で、
Li+update.mdはそれを判定する材料を持たない。棄却 — (a)
a.に attachment 判定を足し、「tag 無し」として解決してc.へ流す。c.は既に 2 択の人間ゲートを持っており、そこへ「そもそも tag に乗っていない」を第 3 の状態として流し込むと、選択肢の意味が枝ごとに変わる(update now to the target tagは detached からの checkout と、ブランチからの離脱で副作用が違う)。rules/model/subtractive-structural-beauty.mdSurfaces of freedom の Decision 面を増やす側。棄却 — (c) detached を要求し、tag へ戻すことを human に求める。 clone をどう置くかは運用の選択であり、
Li+update.mdが決めることではない。(b) の報告を受けた human が tag へ戻すことを選ぶのは自由だが、手順がそれを要求する形は判断の越権にあたる。検出の literal。
git symbolic-ref -q HEADが値を返す(= ブランチに在る)ことを判定に使う。git describe系は使わない —— 本 issue の premise (4) が示すとおり、あれは attachment を答えない道具である。未検証の前提(ready 後も残る)
実装順序(#1911 との直列化)
#1911 と target files が全面的に重なる。 両者とも
Li+update.mdの clone modeexists経路(128 行目付近)を触る。rules/operations/main-agent-procedures.mdSub-issue rules, Parallel conflict analysis の判定では overlap 有り = 並列不可。両者は sibling issue であって sub-issue ではない(分類 litmus: どちらも単独で ship でき、他方の成果物を壊さない)。したがって親子構造は作らず、直列に実行する。後続は先行のマージ後に base を取り直す。
順序 = #1911 → #1917(2026-09-08 合意)。 単なる base 取り直しの回数ではなく、解の形が片方向に依存するため:
#1911 の未決の解には (b) refspec を自動修復するが含まれている。これが採られると
exists経路は「検出して報告する」だけでなく「検出して直す」を持つことになる。本 issue の解 (b) は「検出して報告する。修理はしない」で確定しているので、#1911 が自動修復側に倒れた場合、同一経路の中に修理する検査としない検査が並ぶことになる。その並びを許すかどうかは #1911 の決定時に見えているべきで、逆順だと本 issue の実装後に前提が動く。したがって #1911 の解を決める時点で、本 issue が「報告のみ」で確定していることを材料に入れてよい。
決着(2026-09-08)。 #1911 の解は (a) 検出のみ・自動修復なしに確定した。したがって上記の分岐は起きない ——
exists経路は、本 issue の解 (b) と合わせて 「気づかない状態を検出して報告する。直さない」という一つの姿勢で揃う。同一経路の中に直す検査と直さない検査が並ぶことはない。この確定により、本 issue の実装は #1911 のマージ後に着手できる。前提は動かない。
target files(予想、解が決まるまで暫定)
Li+update.md— clone modeexists経路(128-139行)docs/— 該当する要件仕様(同一 PR で更新)分類
Li+update.mdは governed surface(rules/evolution/initiator-autonomy.mdGoverned surface)なので self-evolution PR に当たり、brake 1 が発火する。release type は解に依存するため未定。関連
exists経路の、別の未検査前提(clone が branch を引けるか)。両者は独立に立つ