spec(bootstrap): sentinel-skip walkthrough + relocate gh install to hook#1310
Conversation
セッション開始時の Li+config / Li+bootstrap walkthrough による context 消費(実測約 4%)を削減する。99% のセッションでは tag 変化なし・schema canonical・config 解決済みで verification only に終わるため、毎回 spec walkthrough する構造的必然性がない。 変更内容: 1. `Li+bootstrap.md` Phase 2.1: gh CLI install の手順記述を「prerequisite install は hook が管理」の 1 行に圧縮。install 実行責任を `on-session-start.sh` に移譲。 2. `adapter/claude/hooks/on-session-start.sh`: - 冒頭に gh CLI install ブロック追加(`~/.local/bin/gh` 不在時のみ install、失敗時は `━━━ gh install ━━━` marker に Master 介入要旨を emit) - matcher 解決直後に Bootstrap sentinel-skip 検証ブロック追加。3 軸(adapter sentinel tag == target tag / Li+config schema canonical / language contract 解決済み)を verify し、全 OK で `LI_PLUS_BOOTSTRAP_STATUS=unnecessary` marker、いずれか FAIL で `LI_PLUS_BOOTSTRAP_STATUS=needed reason=...` marker を emit - target tag 解決は `LI_PLUS_CHANNEL` (latest/release/tag) 別。失敗時は target=unknown として needed 側に倒す(safer-side fallback) - marker は cold-start material より先に emit。pre-bootstrap state(`liplus-language/` 不在)では gh install 失敗 marker のみ emit して exit 3. `adapter/claude/CLAUDE.md` Execute block: AI 側 contract を追記。 - `LI_PLUS_BOOTSTRAP_STATUS=unnecessary` → Li+config.md / Li+bootstrap.md を読まない - `LI_PLUS_BOOTSTRAP_STATUS=needed` または marker 不在 → 通常 bootstrap path - 強制再走: Master の user input に literal `Li+configを実行` / `Li+config を実行` (space 有無問わず) が含まれる場合は marker を bypass して通常 path design 判断: - marker format = `LI_PLUS_BOOTSTRAP_STATUS=<unnecessary|needed>` 単一行 + reason 補足。machine/AI parse 容易な KEY=VALUE 形式に統一 - failure axis を `reason=axis1,axis2,...` で列挙し、AI が何を再 verify すべきか即座に判断できる - bootstrap status marker は startup / resume / clear / compact 全 matcher で emit(cold-start material と独立) local test: - live workspace (build-2026-05-18.3) で `unnecessary` 正常 emit 確認 - legacy schema + 古い sentinel tag + 未解決 language の fixture で `needed reason=sentinel-tag(...),legacy-schema-keys-present,language-contract-unresolved(...)` 3 軸全列挙確認 - sentinel tag 不一致のみの fixture で対応 reason のみ列挙確認 Closes #1309 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
liplus-lin-lay
left a comment
There was a problem hiding this comment.
AI 自己レビュー (semi_auto mode)
Now(merge 前対処)
なし。
Later(後続 issue 化候補)
-
target tag 解決の caching 検討: 現状
gh release listを毎 session start で叩く(releasechannel の場合)。99% session で同じ tag を返すため、{workspace_root}/.claude/state/に短寿命 cache を置けば API rate limit 削減 + 速度改善が可能。ただし sentinel-skip の意義は「読み込まない」にあり API call は副次的問題なので優先度低。 -
tagchannel での local fallback の整合性:git ls-remote失敗時に localgit tagに倒すが、local が stale だと「target tag 自体は取れたが古い」状況でunnecessary誤判定リスクがある。現状のunnecessary判定は 3 軸 AND なので、adapter sentinel と同期している限り問題ないが、bootstrap walkthrough を skip した結果として liplus-language clone の fetch も skip されるという連鎖を実機で確認した方が良い。本 PR 範囲外。 -
gh install version pin の昇格機構:
GH_VERSION=2.62.0を hook source に hardcode。次回 upgrade で source を直接編集する必要があるが、Li+ release cycle と gh release cycle が独立しているため、hooks-settings.mdの鏡像({LI_PLUS_TAG})と同等の version 注入機構を別途検討する価値あり。Distribution 観点では非緊急。
Accepted(本 PR 内で受容したトレードオフ)
-
target tag 解決失敗時の safer-side fallback:
ghコマンドが network 不通 / rate limit 等で失敗した場合target=unknownで needed 側に倒す。結果として network 不通環境では毎回 bootstrap walkthrough を走らせることになるが、誤って stale sentinel でunnecessaryを返すよりは安全。 -
bootstrap status marker の matcher 範囲: startup / resume / clear / compact 全 matcher で emit する。resume/clear/compact は work context 継続のため cold-start material は anchor のみだが、bootstrap status は AI 側の判定 surface として独立しているため常時 emit。冗長性は受容(軽量で副作用なし)。
-
gh install 失敗時の bootstrap 進行: install 失敗時も hook は exit 0 で進む(marker のみ emit)。AI / Master 介入で復旧する設計。install 必須を hard gate にすると pre-bootstrap 初回 session が永久に止まる懸念があるためこの設計を選択。
言及事項
- semi_auto mode のため、本 PR は spec 変更で minor 相当(仕様面では bootstrap 経路に新 marker を導入する仕様追加)。merge は Master 確認待ち。
Closes #1309で issue 自動 close。
…-+-relocate-gh-install-to-hook
概要
セッション開始時の Li+config / Li+bootstrap walkthrough による context 消費(実測約 4%、Li+config 実行で 10% vs 未実行 6%)を削減する。99% のセッションでは tag 変化なし・schema canonical・config 解決済みで verification only に終わるため、毎回 spec walkthrough する構造的必然性がない。
#1065で確立した sentinel-based auto action mechanic を bootstrap walkthrough 全体の gating に拡張する形。変更内容
1. install logic の hook 移譲
Li+bootstrap.mdPhase 2.1 を「prerequisite install は hook が管理」の参照 1 行に圧縮adapter/claude/hooks/on-session-start.sh冒頭に~/.local/bin/ghinstall ブロック追加(不在時のみ install、gh_2.62.0_linux_amd64.tar.gzを curl → 抽出 → 配置)━━━ gh install ━━━marker にGH_INSTALL_STATUS=failed: ...を emit、Master 介入要旨を AI に届けるliplus-language/不在)でも install 失敗 marker のみ emit して silent exit する fail-safe を維持2. sentinel-skip 機構
on-session-start.shが matcher 解決直後に 3 軸を verify:.claude/CLAUDE.md== 現 LI_PLUS_REPO target tag(LI_PLUS_CHANNEL別解決)Li+config.mdschema canonical(LI_PLUS_REPOSITORY/USER_REPOSITORY/*_EXECUTION_MODE等の legacy key 不在)LI_PLUS_BASE_LANGUAGE/LI_PLUS_PROJECT_LANGUAGE解決済み(非 comment かつ非空)marker format(machine/AI parseable、cold-start material より先に emit):
LI_PLUS_BOOTSTRAP_STATUS=unnecessary tag=<tag> channel=<channel>LI_PLUS_BOOTSTRAP_STATUS=needed reason=<axis1>,<axis2>,...target tag 解決失敗時は
target=unknownとして needed 側に倒す(safer-side fallback)。3. 強制再走経路(AI 側 contract)
adapter/claude/CLAUDE.mdExecute block を拡張:unnecessarymarker → Li+config.md / Li+bootstrap.md を読まないneededまたは marker 不在 → 通常 bootstrap pathLi+configを実行/Li+config を実行(space 有無問わず)が含まれる場合は marker bypass で通常 pathdesign 判断(Master 確認希望ポイント)
marker format:
KEY=VALUE単一行 +reason=axis1,axis2形式を採用。HTML/JSON ではなく plain text で AI parse 負荷を下げた。区切り banner━━━ Li+ bootstrap status ━━━で cold-start material と視覚的に分離。target tag 解決の channel 別実装:
latest:gh release view --json tagNamerelease:gh release list --limit 1tag:git ls-remote --tags --sort=-creatordate→ fallback to localgit tagどれも失敗時は
target=unknownで needed に倒す。tagchannel の remote 解決失敗時に local fallback を入れたのは、offline / network 不安定環境での誤判定回避。marker emit の matcher 範囲: startup / resume / clear / compact 全 matcher で emit。resume/clear/compact では cold-start material は anchor のみだが、bootstrap status は独立判定として常時 emit(軽量で副作用なし)。
gh install の version pin:
GH_VERSION=2.62.0を hardcode。bootstrap walkthrough から hook に責任が移ったため version 管理点もここに集約。upgrade 時は本 file を編集。local test
unnecessary正常 emit 確認reason=sentinel-tag(adapter=build-2020-01-01.0,target=build-2026-05-17.4),legacy-schema-keys-present,language-contract-unresolved(base=unset,project=unset)関連
Closes #1309