4. Operations - Liplus-Project/liplus-language GitHub Wiki
本文書は Li+ プログラムのオペレーションレイヤー(rules/operations/*.md + skills/operations-on-*/SKILL.md)の仕様を定義する。要求(何を満たすか)と仕様(どう振る舞うか)を一体として記述する。
rules/operations/*.md は .claude/rules/ 経由で常時コンテキストに存在する(compaction を生存)。skills/operations-on-*/SKILL.md はトリガー時に skill auto-invocation で読み込まれ、ブランチ作成、コミット、PR、マージ、リリース等の操作詳細を提供する。
本文書の各セクションは冒頭に (→ ソース) 形式で対応する権威ソースを明示する。docs/4 は日本語の要求仕様記述面であり、英語の rules/skills が literal なソース・オブ・トゥルースである。両者に差異がある場合はソース側が正となる。
L3 タスクレイヤーとの境界:issue Format、Issue Maturity、Sub-issue Rules は L4 の event-driven トリガーから呼ばれるが、語彙(issue 型・成熟度・ラベル辞書)は L3 タスクレイヤー(rules/task/task.md)が正本である。本文書からは L3 を参照する形にする。
(→ rules/operations/operations.md の [TRIGGER_INDEX] + 各 skill)
| トリガー | 対象セクション | 権威ソース |
|---|---|---|
| act_now | ブランチとラベルフロー | skills/operations-on-branch/SKILL.md |
| on_issue_create | Issue Format | skills/operations-on-issue-format/SKILL.md |
| on_issue_edit | Issue Format | 同上 |
| on_issue_view | Issue Maturity | skills/operations-on-issue-maturity/SKILL.md |
| on_issue_sub | Sub-issue Rules | skills/operations-on-sub-issue/SKILL.md |
| on_commit | コミットとプッシュ + docs 同期 |
skills/operations-on-commit/SKILL.md + skills/operations-on-docs-ownership/SKILL.md
|
| on_pr | PR 作成 | skills/operations-on-pr-creation/SKILL.md |
| on_ci | CI ループ | skills/operations-on-ci/SKILL.md |
| on_review | PR レビュー |
skills/operations-on-pr-review/SKILL.md + skills/task-pr-review-judgment/SKILL.md(判断側、L3) |
| on_merge | マージ | skills/operations-on-merge/SKILL.md |
| on_release | 人間確認が必要な操作 / リリース | skills/operations-on-release/SKILL.md |
| on_webhook_intake | フォアグラウンド webhook 取込 | skills/operations-foreground-webhook-intake/SKILL.md |
| on_long_output | 長 output / 出力途切れ | skills/operations-chat-output-limit/SKILL.md |
| on_discussions_reference | Discussions 経路 | skills/operations-discussions/SKILL.md |
| on_session_boundary | session 境界での引き継ぎ | skills/operations-handoff-continuity/SKILL.md |
| on_notifications_api_call | notifications API 直接操作 | skills/operations-notifications-api/SKILL.md |
(→ skills/task-subagent-delegation/SKILL.md(L3、L4 から cross-layer 利用))
長時間セッションでの注意劣化対策として、全 operations トリガーの手順実行をサブエージェントに委任できる。サブエージェントは毎回新鮮なコンテキストで rules/operations/*.md と skills/operations-on-*/SKILL.md を読むため、注意の薄まりが発生しない。
サブは手順を実行して結果を報告する。メインは報告を受けて判断する。PR レビュー判断基準はタスクレイヤー(skills/task-pr-review-judgment/SKILL.md)に置き、メインが operations 系 skill を直接読む場面をゼロにする。
サブエージェント機能は最適化であり必須ではない。使えない環境では従来通りメインが実行する。委任の詳細(何を伝え、何をメインに残すか、モード別スコープ)は L3 の権威ソースに従う。
(→ rules/operations/operations.md の ## Operations Rules)
破ったら壊れる一文一制約。理由・条件なし。
- issue リンク(
gh issue develop)は常に必須。GitHub への初回 push より前に実行する - 親 issue = 1ブランチ。sub-issue ごとの個別ブランチは作成しない
- sub-issue を持つ親 issue = 親 PR 1本。sub-issue ごとの個別 PR は禁止
- コミット単位の CI 可視化は draft PR を親ブランチ上で早期に open することで実現する(PR を分割しない)
- コミットタイトル = ASCII 英語のみ、1行
- 日本語コミットタイトルは禁止
- コミットボディは省略不可
- コミットボディに含めるもの:変更要約 + 意図または背景 + issue 番号
- コミットボディに最低1文の日本語を含める
- 英語のみコミットボディは禁止
- PR タイトル = ASCII 英語のみ、1行
- PR ボディ = 日本語
- 実装変更を含む PR は、対応する
docs/の更新を同一 PR 内に含める。分割は禁止 -
docs/を正本とする。Wiki は反映先であり、正本にしない - リリース後の Wiki 同期は必須。省略は禁止。Wiki 同期はリリースフロー完了の gate
- 要求仕様書は実装後のフォローアップではない。実装前に作成・更新する
- PR タイトルには変更の影響範囲を含める
- AI の
gh release createデフォルトは state フラグなし(prerelease=false、latest=false) - prerelease フラグは AI の裁量オプション。明示的なテスト期間を取りたい時のみ付与する。タグ名は最終形のまま(alpha.N / rc.N / -pre などの suffix は付けない)。昇格時はフラグを外すだけでタグは作り直さない
- latest フラグは人間専用。実機検証後に
gh release edit {tag} --latest=trueで人間が flip する(判断 ↔ 実行軸:「人間専用」「人間が flip する」は判断主体を指す表記であって CLI 実行主体ではない。human が判断し、明示的な go-sign 後に AI が gh CLI を実行する。詳細は本ドキュメントの「human 判断ゲート」節) - リリース body は GitHub generated release notes を使う(
--generate-notesを渡す。--notes ""で空 body を渡さない) -
mark_processedは消費した全 webhook イベントに対して必須。省略すると backlog が蓄積する
(→ rules/operations/operations.md の ## Autonomous Run Stop Condition)
AI が人間の介在なしに走る場合(夜間、semi_auto / auto モードで deploy まで到達するケース)、「deploy 成功」は停止条件にならない。静的検証(TS check、unit test、CI)は runtime 正しさを保証しない。subrequest 上限、IPC、rate limit、schema migration の副作用などの runtime 経路は、静的検証とは別軸に存在する。
production に到達する自走では、以下を最終ステップとして必ず実行する:
- deploy 完了後、production log を最低 5 分観測する
- cron 駆動のワークでは、「deploy 完了」とは「deploy コマンドが exit 0 で終わった時点」ではなく「deploy 後の最初の cron 周回が log で観測できた時点」を指す
- ホストの logs surface(ブラウザの dashboard、
wrangler tail、同等の CLI)を使う。事前付与済みのブラウザ権限は、人間監視下のセッションのために留保するのではなく、自走中に積極的に活用する
アンチパターン:「human が朝に確認するから、自走の post-deploy 観測は不要」。検出タイミングの利得(夜間検出 vs 朝検出)こそ自走が提供すべき価値であり、観測を省略するとその価値を放棄することになる。
停止条件が誤適用されている兆候:
- deploy 成功の瞬間に走完サマリを書き始めている
- 自走自身が verify する前に「人間が見てくれる」を理由にしている
- dashboard / log アクセス権限が事前付与されているのに自走中に未使用
- 走完報告が cron interval 1 周分より短い時間で提出されている
条件→行動。省略不可。AI が条件を判断し、条件に合致したら必ず実行する。
(→ skills/operations-on-branch/SKILL.md)
着手意思は対話の空気から判断する。チェックリストで確認しない。不明瞭な場合は機械的にではなく、感じをもって聞く。
| タイミング | ラベル | ブランチ |
|---|---|---|
| NOW(今やる) | in-progress |
作成する |
| SOON(近いうち) | backlog |
作成しない |
| SOMEDAY(いつか) | deferred |
作成しない |
ライフサイクルラベルは「いつ着手するか」、成熟度ラベルは「どこまで収束したか」。ライフサイクルラベルを成熟度の代用にしない。
空気読みは timing tier 判定(NOW / SOON / SOMEDAY)にのみ適用する。label 付与は tier 結果からの決定的な写像であり、空気読みの二度目を伴わない。tier が決まればラベルは上表に従って機械的に付与する。
trigger mode でも issue の作成・本文更新とブランチ準備は待たない。人間トリガーの対象は実装開始と PR レビューである。
(→ skills/operations-on-branch/SKILL.md)
gh issue develop は親 issue のみに対して実行する。sub-issue(子・孫・…)は親ブランチ上でコミットする。親ブランチは gh issue develop で親 issue にリンクされるため、そのブランチからの PR マージは親を自動クローズする。これは single parent PR flow(後述「sub-issue ルール」参照)の下では意図通りの挙動である。親 PR 1本のマージは全 sub-issue 完了後に行われるため、親の自動クローズもそのタイミングで正しく発火する。
sub-issue ごとに親ブランチ上で個別 PR を作る運用は禁止する。最初の PR が merge された時点で、残りの sub-issue が未完了のまま親が自動クローズされるためである。独立ブランチ・独立 PR が必要な単位は sub-issue ではなく sibling issue として切る。
ブランチ作成前にローカルとリモートの存在確認を行う。リモートに既存ブランチがある場合、後からリンクは張れない。
# 存在確認
local: git branch --list {branch-name}
remote: gh api repos/{owner}/{repo}/branches/{branch-name} # 404 = not exists
# ブランチ作成 + issue リンク
gh issue develop {issue_number} -R {owner}/{repo} --name {session-branch} --base main
# アサイニー設定
gh api repos/{owner}/{repo}/issues/{issue_number}/assignees --method POST -f 'assignees[]=liplus-lin-lay'
ローカルエラー時の対処:gh issue develop がローカルで失敗してもGitHub 側では成功する場合がある。リンク済みブランチを確認してから判断する。
gh api graphql -f query='{ repository(owner:"{owner}",name:"{repo}") { issue(number:{number}) { linkedBranches { nodes { ref { name } } } } } }'
リンク済みならそのブランチを使用する。リンクなしならリトライまたは人間にエスカレーションする。
(→ skills/operations-on-sub-issue/SKILL.md + rules/operations/operations.md の親子 PR 制約)
sub-issue は AI が追跡する作業単位。粒度ではなく責務で分ける。
問い:「この単位は親の atomic deliverable を壊さず独立に ship できるか?」
| 答え | 分類 | 運用 |
|---|---|---|
| Yes(独立 ship 可) | sibling issue | 親子ではなく独立 issue として立てる。各 issue が自前のブランチと PR を持つ |
| No(親と一体で初めて意味を持つ) | 正当な sub-issue | 親ブランチ上でコミットし、親 PR 1本に合流させる |
独立に ship できるなら sub-issue にする意味がない。「sub-issue ごとに別 PR で独立に出したい」と感じた時点で、それは元々 sibling issue にすべき単位だったというシグナルである。PR を分割するのではなく、分類を見直す。
sub-issue を持つ親 issue は、以下の構造で運用する:
- 全 sub-issue のコミットを1本の親ブランチに蓄積する
- 親ブランチに対する PR は親 issue あたり1本だけ、
mainへ向けて作成する - sub-issue はその1本の PR の中で処理される
- コミット単位の CI を見たい場合は、最初のコミット push 直後に親 PR を draft で open する。
pull_request.synchronizeによって以降の push ごとに CI が走り、PR を分割せずに per-commit CI が得られる - 親 PR の ready for review(
gh pr ready {pr})は全 sub-issue 完了と PR 本文の確定後に行う - merge は全 sub-issue 完了後に1回だけ行う
- parent auto-close はこの構造下では正しく働く:親 PR の merge は最後のイベントであり、その時点で全 sub-issue は既に closed になっている
sub-issue ごとに個別 PR を作る運用は禁止する。親ブランチ上で複数 PR を連続 merge すると、最初の merge で親が自動クローズされ、残りの sub-issue が未完のまま親が閉じる事故が発生する(観測: github-webhook-mcp#198 / PR #203)。
同一セッション内で複数のタスクを並行で扱う場合は、独立 issue の並列作成ではなく親子構造(親 issue + sub-issue)にする。複数 ready issue のファイル重複分析は target files で判定する。
| 重複 | 判断 |
|---|---|
| なし | 並列安全。並列 sub-issue 構造を人間に提案 |
| 部分重複 | 共有ファイルへの変更を統合 sub-issue に分離して提案 |
| 統合 sub-issue | 並列 sub-issue 完了後に直列実行(依存順序あり) |
target files が issue body に無い場合は、purpose と premise から推定する。
(→ skills/operations-on-docs-ownership/SKILL.md)
配布向けプロジェクトでは、最低限の docs/ として要求仕様書を持つ。新規・小規模プロジェクトではまず1ファイルの要求仕様書を作ればよい。規模が大きい場合は分割してよい。
実装を始める前に、対応する要求仕様書を先に作成または更新する。挙動変更・バグ修正・仕様変更では、まず要求仕様書の該当箇所を変更し、コードとテストはその仕様差分を実装・検証するために更新する。
Li+ の挙動や運用ルールに効く判断は、番号付き要求仕様書(1–9)と対応するプログラムファイルへ固定する。補助メモや実験ログを残してもよいが、それを正本にしない。要求仕様書は可読性が向上する場合に分割してよい。
spec(Li+*.md)または動作コードを変更するコミットでは、docs/ に対応する更新があるか確認する。未更新であれば push 前に追加する。別 PR への分離は禁止。
同期が必要な集合のメンバーを 1 つ編集するときは、編集の前後で grep-sweep を pair で実行する。編集前に所属する集合全体を grep して全メンバーを列挙し(記憶ではなく列挙から編集対象を確定)、編集後に同集合を再 grep して旧形のメンバーが残っていないことを確認する。典型的な集合 = docs mirror 同期対象(docs/ とその wiki mirror)/ parity 全 block(claude CLAUDE.md ⇔ codex AGENTS.md 等)/ 同一規範文の全出現箇所。
PR タイトルの良い例・悪い例:
# bad: fix(config): negative duration handling
# good: fix(config): treat negative durations as below-minimum rather than error
(→ skills/operations-on-commit/SKILL.md)
プライマリは git push。git が使えない環境では GitHub API フォールバック(blob/tree/commit/ref 作成)を使う。複数ファイル時は tree 作成後にファイル数を検証し、減少していた場合はコミット中止する。
# プライマリ
git push origin {session-branch}:{target-branch}
# フォールバック(単一ファイル)
gh api repos/{owner}/{repo}/contents/{path} # PUT base64 sha
# フォールバック(複数ファイル)
1. create blobs: gh api .../git/blobs # per file
2. create tree: gh api .../git/trees # verify count after
3. create commit: gh api .../git/commits
4. update ref: gh api .../git/refs/heads/{branch}
(→ skills/operations-on-pr-creation/SKILL.md)
親 issue あたり PR は1本(上の「single parent PR フロー」参照)。sub-issue を持つ親 issue では、すべての sub-issue と親自身を1つの PR の merge で閉じる。sub-issue ごとの個別 PR は禁止する。
sub-issue を持つ親 issue では、最初のコミットを push した直後に親 PR を draft で open してよい。
gh pr create --draft -R {owner}/{repo} --base main --head {session-branch} ...
以降の push ごとに pull_request.synchronize で CI が走り、PR を分割せずコミット単位の CI 可視化が得られる。全 sub-issue 完了と PR body 確定後に gh pr ready {pr} で ready for review に切り替える。draft PR の早期 open は必須ではなく、長期化する親作業のための利便機能である。
issue ごとのブロック形式で記述する。クローズさせる issue(sub-issue と親 issue の両方)は Closes #xxx で参照する。各ブロックに2〜3行の要約を書く。詳細は issue を参照。deferred・open のまま残す子 issue は含めない。
single parent PR flow 下では、親 issue も sub-issue と同じく Closes #xxx で参照する。親 PR は最終 merge 1回で親と全 sub-issue を同時に閉じるため、親をクローズしない理由がない。
Part of #xxx は、現在の PR が最終親 PR ではない場合にのみ使う(例:別の親 issue に対して明示的に deferred な残部を先行 merge するケース)。canonical な single parent PR flow では Part of は登場しない。
GitHub の自動クローズキーワード(公式リスト):close / closes / closed / fix / fixes / fixed / resolve / resolves / resolved。Refs はクローズキーワードではなく自動クローズしない。マージ時にクローズさせたい issue には Refs を使わない。
PR 作成後:
-
AI bot を PR の assignee に self-assign する:
gh pr edit {pr} -R {owner}/{repo} --add-assignee liplus-lin-lay目的:issue 側の assignee は PR エンティティに自動継承されないため、PR の Assignees フィールドに AI bot を明示し「この PR は AI が owner」という UI 上の trail を残す。 メカニズム注記:GitHub は
--add-reviewerの自己指定を silent に拒否するが、--add-assigneeによる PR author 自身の assignee 追加は許可される(2026-04-20 に PR #1099 で empirical 検証済)。 スコープ:assignee self-assign は UI trail のためであり、正式な self-review 記録(gh pr review --comment、「PR レビュー」節参照)を置き換えるものではない。 -
CI ループへ即座に移行する。人間の指示は不要。
-
マージの実行者は全モードで AI に統一されている(「マージ」節参照)。GitHub の auto-merge 機能への一般的な委譲は廃止されているが、
triggerモードでは例外として PR 作成時点で--auto --squashを有効化する(下記「モード別の PR auto-merge ポリシー」参照)。
(→ rules/operations/operations.md の PR auto-merge policy is mode-specific)
PR 作成時の gh pr merge --auto --squash 付与は実行モードで振る舞いが異なる。一律ではない。
| モード | auto-merge 付与 | 根拠 |
|---|---|---|
trigger |
PR 作成時点で gh pr merge {pr} --auto --squash を必須で有効化する |
承認 gate は人間レビューが担う。auto-merge は承認が入った瞬間に自動でマージするだけで、毎回「merge strategy どれ?」と確認する往復を省く |
semi_auto |
minor / major PR には --auto を付けない(人間レビューが gate)。patch PR はセルフレビュー pass → AI が直接 merge(auto-merge 不要) |
minor / major は人間レビュー必須のため、auto-merge で承認即マージしても意味がない。patch は即マージで十分 |
auto |
repo 設定の "Allow auto-merge" を意図的に無効化する。gh pr merge --auto が enablePullRequestAutoMerge 権限不足で蹴られるのは設計通り |
repo-level auto-merge が有効だと CI pass 時点で GitHub が自動マージし、parent AI のセルフレビューを飛ばす抜け道になる。Parent AI がセルフレビュー後に手動 gh pr merge {pr} --squash を実行する |
auto モードで --auto --squash が拒否された場合、それは設定漏れではなく意図された状態である。「auto-merge を有効化することを提案」してはならない。Li+config.md の対象リポジトリの _EXE_MODE(例: USER_REPO1_EXE_MODE / LI_PLUS_REPO_EXE_MODE)を確認してからモード分岐する。
subagent に PR 作成を delegate する場合、parent は delegation prompt 内に mode 判定結果と auto-merge 指示を literal で注入する(subagent は parent の memory を読まない)。
(→ skills/operations-on-ci/SKILL.md)
CI ループは PR 作成とは独立したタスクである。PR 作成後または修正リコミット後に開始する。
step 1: 最新コミット SHA 取得
gh pr view {pr} -R {owner}/{repo} --json headRefOid --jq '.headRefOid'
step 2: 全チェックランの完了を待機
webhook 経由を優先する。
mcp__github-webhook-mcp が利用可能な場合:
-
get_pending_statusを60秒間隔でポーリング - check_run の pending があれば
list_pending_events→get_eventで SHA 一致を確認 →mark_processed - 全チェックランが完了するまで収集
利用不可の場合:
gh api repos/{owner}/{repo}/commits/{sha}/check-runs --jq '.check_runs[] | {name,status,conclusion}'
全ての status=="completed" になるまで sleep で繰り返す。
step 3: 結論判定
- CI FAIL = いずれかの
conclusion=="failure" - CI PASS = 全て
conclusionが success / skipped / neutral
CI PASS → PR レビューへ移行。 CI FAIL → 修正してリコミット(CI ループを step 1 から再開)。ループ安全閾値(3回)を超えた場合は issue コメントに外部化し、人間に委ねる。
(→ skills/operations-on-pr-review/SKILL.md + skills/task-pr-review-judgment/SKILL.md(判断側、L3))
AI セルフレビューは全モード(trigger / semi_auto / auto)で必ず実行する。 マージ前のセルフレビュー省略は仕様違反である。セルフレビューが先に走り、必要に応じて人間レビューがその上に重ねられる(置き換えではない)。
レビューの基準は repository state first である。issue 本文、リンク済みブランチの差分、PR 本文、CI 結果を読む。ローカルで動いたことだけではレビュー完了にしない。
メインエージェントが PR diff を issue 要件と照合してレビューする(判断基準は L3 の skills/task-pr-review-judgment/SKILL.md)。
- セルフレビュー pass → formal review record 投稿(下記)→ モード別の人間ゲートへ。
- セルフレビュー fail → 修正してリコミット(CI ループ再開)。
内部のセルフレビューが pass した後、AI は結果を GitHub 上の正式な PR review として必ず投稿する:
gh pr review {pr} -R {owner}/{repo} --comment --body "<セルフレビュー結果の要約>"
目的は PR の Reviews タブに audit trail を残し、AI レビュー記録を PR 作者属性から分離すること。
実装メカニズムの注記:GitHub は --add-reviewer による self-assignment を silent に拒否する。PR author が自己レビュー記録を残す唯一の手段は gh pr review --comment(2026-04-20 に PR #1095 で empirical 検証済)。
body には以下を含める:受け入れ条件の照合結果、scope deviation(ある場合)、次ステップ想定(例:trigger / semi_auto の minor-major では「人間レビュー待ち」)。
execution_mode == auto:人間ゲートなし。セルフレビュー pass → マージへ移行。
execution_mode == semi_auto:タイプ連動の人間ゲート。
-
patch→ 人間ゲートなし。セルフレビュー pass → マージへ移行。 -
minor/major→ セルフレビュー pass 後に人間確認が必要(手順は trigger モードと同じ)。
バージョン種別の判断軸はリリース時と同じ(「バージョン種別」節参照)。AI は PR 作成時点でタイプを提案し、判断が曖昧な場合は安全側(minor)に寄せて人間に確認する。
Per-PR exception(content-based axis):親 issue が minor / major であっても、当該 PR の修正そのものが rules/operations/release-version-rule.md の patch 定義(例:言語整合 / typo / コメント / 内部 literal / docs 整合)に該当するなら、人間ゲートを waive し AI 直接 merge する。AI は exception 適用判断の理由を self-review コメントに literal で記録する(human observability)。判断が曖昧な場合は base 軸(親 issue の release type)に寄せる safer-side fallback。
execution_mode == trigger:全 PR で人間確認が必要。セルフレビュー pass 後に以下を実施する。
webhook 経由を優先する。
mcp__github-webhook-mcp が利用可能な場合:
-
get_pending_statusを60秒間隔でポーリング -
pull_request_reviewの pending があればlist_pending_events→get_eventで当該 PR を確認 →mark_processed
利用不可の場合:
- 人間がレビュー完了を通知するまで待機(ポーリングしない)
- 通知を受けたら確認:
gh pr view {pr} -R {owner}/{repo} --json reviewDecision --jq '.reviewDecision'
-
APPROVED→ マージへ移行。 -
CHANGES_REQUESTED→ レビューコメントを読んで修正し CI ループを再開する。
セルフレビュー記録は項目を「PR scope 外」として正当に deferred 化することがある(例:workspace memory のクリーンアップ、フォローアップ issue 起票、docs-only フォローアップ)。deferred は ignore と同義ではない:
- workspace 側の deferral(memory 編集、ローカル設定変更)は merge 直後の同一セッション内で実行する。次セッションに先送りしない
- repo 側の deferral(フォローアップ issue、関係ない掃除の別 PR)は merge 前に file しておく。merge してから後追いで作ると流れる
- 人間の APPROVED コメントに「〜したんだよね?」「did you also do X?」のような確認文が埋め込まれている場合、それは承認条件の一部であり small talk ではない。追加 gate として扱い、同一セッション内で応答する
merge は閉じ括弧ではない。deferred 項目の handoff まで完了して初めて閉じる。
(→ skills/operations-on-merge/SKILL.md)
マージの実行者は全モード(trigger / semi_auto / auto)で AI に統一されている。 すべての前提条件(セルフレビュー、モード別の人間ゲート、マージ可能状態チェック)が揃った時点で、AI が gh pr merge を実行する。GitHub auto-merge(--auto)への委譲は trigger モードのみ(human approval で fire)。semi_auto / auto は AI 直接 merge(--auto なし)。authoritative は operations.md PR auto-merge policy。
gh pr view {pr} -R {owner}/{repo} --json mergeStateStatus --jq '.mergeStateStatus'
-
CLEAN→ そのままマージへ進む。 -
BEHIND→git fetch origin main && git rebase origin/main && git push --force-with-leaseで CI ループを step 1 から再開。 -
CONFLICTING→ rebase を試行。成功なら再 push + CI 再実行。失敗ならgit rebase --abort→ issue コメント → 人間にエスカレーション。 -
BLOCKED/UNKNOWN→ 待機して再確認(GitHub が計算中の可能性)。
既定のマージ戦略は squash(リポジトリの慣例に従う)。
gh pr merge {pr} -R {owner}/{repo} --squash
AI が squash 以外を選ぶ必要があると判断した場合のみ人間に確認する(pause して確認)。
PR 本文に Closes #xxx が含まれていると、マージ時にプラットフォームが issue を自動クローズする(Refs はクローズキーワードではないため自動クローズしない)。
実機テストはマージ後に main 上で行う。マージゲートにはしない。
(→ skills/operations-on-release/SKILL.md の # Human Confirmation Required)
「待って」「止めて」「まって」と言われたら即座に停止する。
確認が必要な操作:
- リリース作成(バージョン種別とターゲットタグ)— 実行前に CD チェックが必要
- ブランチ削除(リンクされた issue がクローズされる可能性がある場合)
- force push
- trigger mode のみ:issue 選択、issue 実行開始
(→ skills/operations-on-release/SKILL.md の ## Release checks (pre-create))
リリース作成前に以下を確認する。
CD チェック: CD PASS なら次へ。CD FAIL なら人間にエスカレートし、リリースは作成しない。
mcp__github-webhook-mcp が利用可能な場合:
-
get_pending_statusを60秒間隔でポーリング -
workflow_runの pending があればlist_pending_events→get_eventで conclusion を確認 →mark_processed
利用不可の場合:
-
gh apiで全 CD チェックが完了するまでポーリングする。
(→ rules/operations/release-version-rule.md 権威ソース(判定基準、always-on rules 層に移設 #1484)。Version Base Rule は skills/operations-on-release/SKILL.md。本節はその日本語ミラー)
v0.x.x は初期開発版。何でも変わりうる。v1.0.0 以降が正式版(semver 準拠)。
判断軸は「変更の規模」と「user/system から観測できるか」の2つ。
| バージョン | 適用条件 | 判断者 |
|---|---|---|
| patch | それ以外すべて(docs / 小 fix / 小 spec / config / 内部ルール変更 / user/system から観測できない governance 構造変更) | AI が提案 |
| minor | 大きな refactor または大きな構造変更であり、かつ user/system から観測できる | AI が提案、人間が承認 |
| major | 大規模変更または大きな目標達成(フェーズ移行、プロジェクト節目) | 人間が判断 |
重要な注記: 「構造変更 → minor」ではない。「構造変更かつ user/system observable → minor」。governance や spec rule の変更は、構造的には大きくても観測できなければ patch で扱う。本 issue (#1087) 自身がその典型で、release rule の再設計は governance 構造の変更だが Li+ ユーザーの surface から見えないため patch で ship する。
AI は patch または minor を提案する。minor / major の採用は人間が確認し、AI が実行する。バージョン番号はプレリリースを含む直近のリリースを基準にする。
Application-moment trigger(判断形成の瞬間で発動): バージョン分類(patch / minor / major)を任意の artifact に書く直前に、本 rule(rules/operations/release-version-rule.md)を literal 再読する。再発失敗は minor の "large" 修飾子省略 — observable な変更を minor と誤分類するが scope は incremental(つまり patch)というケース。詳細は skills/model-trigger-check-gate-actions/SKILL.md の Trigger moments を参照。
(→ rules/operations/operations.md の Release terminology interpretation ladder)
「プレリリースタグ」「stable タグ」等の人間発話は、GitHub Release の prerelease フラグ(boolean 属性) を指すものとして第一解釈する。git tag オブジェクトや release entry そのものの削除を指すとは解釈しない。
「〜を削除で」「〜外して」等の曖昧な発話は、release 属性変更 vs release 削除 vs git tag 削除で挙動が全く異なる。より保存的な解釈を先に試し、literal delete は最後に置く。
| 順位 | 解釈 | 例 |
|---|---|---|
| 1 | 属性・フラグ変更(最も保存的) |
prerelease → stable 昇格、draft → published、latest flip |
| 2 | 可視性変更 | archive、hide、unlist |
| 3 | 新 release で置換 | supersede、後継 release で deprecate |
| 4 | 明示確認(停止して人間に問う) | 上記で解釈不能な場合、destructive 操作の前に確認 |
| 5 | 文字通りの削除 | 人間が明示的に「削除」「消す」「unpublish」「tag 削除」と言った場合のみ |
「削除」指示に対して step 4(明示確認)で必ず停止する対象成果物: GitHub Release、git tag、npm / PyPI / crates.io のバージョン、merge 済み PR(close は削除ではない)、main ブランチ(revert は削除ではない)、公開済み docs、公開済み wiki。これらは公開済みかつ不可逆性の高い成果物であり、確認前の literal delete は禁止する。
復元手順(git tag を誤って削除した場合の参考):
git for-each-ref refs/tags/... # ローカル保持 SHA 確認
git push origin refs/tags/{tag} # tag 復元
gh release create {tag} --generate-notes --latest=false # release 復元
(→ skills/operations-on-release/SKILL.md の # Release State Rule 節)
state は version type(patch / minor / major)に依存しない独立 axis として扱う。
| state | 既定値と意味 | 操作者 |
|---|---|---|
| default(state フラグなし) |
gh release create の既定。prerelease=false、latest=false。version type に関係なく AI はこの default で出す |
AI |
| prerelease | AI が明示的にテスト期間を取りたい時のみ付与する裁量フラグ。タグ名は最終形のまま(alpha.N / rc.N / -pre などの suffix は付けない)。昇格時はフラグを外すだけでタグは作り直さない | AI |
| latest | 実機検証済みを示す。version type(patch / minor / major)に関係なく実機テストが gate。gh release edit {tag} --latest=true で flip |
人間のみ(判断主体) |
判断 ↔ 実行軸:上表の「人間のみ」は判断主体を指す。CLI(
gh release edit ... --latest=true)を打つのは AI で、human が明示的な go-sign を出してから AI が実行する。詳細は本ドキュメント「human 判断ゲート」節を参照。
AI が release を作成する際は、以下の形を canonical とする。
gh release create {tag} \
--target main \
--title {version} \
--generate-notes \
--latest=false
--latest=false は明示必須。省略すると gh CLI の default は legacy(semver + date の auto-pick)に fallback し、新 release が Latest に昇格してしまい、既存の Latest anchor を黙って降格させる。
repo には常に1つ以上、explicit Latest な release(make_latest=true)が存在している必要がある。この release を Latest anchor と呼ぶ。
anchor が不在の状態で新 release に --latest=false を渡しても、legacy default に巻き込まれて無効化され、新 release が Latest 化してしまう。anchor は「各 release の属性」ではなく「repo 全体の persistent な state」として扱う。
gh release edit {new_tag} --repo {owner}/{repo} --latest=true
GitHub の one-Latest-only 制約により、旧 anchor は自動で Latest badge を失い、default(state なし)に遷移する。新 release が Latest anchor に昇格する。タグ名は flip 前後で不変で、state のみが移動する。
repo の初回非 prerelease release、または anchor 消失時は、GitHub が legacy auto-pick によって一時的に最新 release を Latest 化する。この transient Latest state は、人間が explicit Latest anchor を設定した時点で one-Latest-only 制約によって自然に解消される。
この transient Latest は AI が意図的に付けた state ではなく、プラットフォーム側の default 挙動であり、governance 上の判断ではない。
既存の複数 release を一括で default(state なし)に正常化する場合、先に1つを anchor(--latest=true)に固定してから、他を --latest=false で PATCH する。順序を逆にすると anchor 不在の状態で --latest=false が無効化され、ターゲットのいずれかが再び Latest 化してしまう。
- リリースタグ・タイトルはプロジェクト固有の規約に従う
- リリース body は GitHub generated release notes を使う(
--generate-notesを渡す。--notes ""で空 body を渡さない)
バージョン番号はプレリリースを含む直近のリリースを基準にする(latest stable のみではない)。
gh release list --limit 1 # プレリリースを含む
(→ skills/operations-on-release/SKILL.md の # Release Tag and Title Rule 節)
プロジェクトの docs/ または CI/CD 設定を確認してから作成する。
| プロジェクト種別 | タグ形式 | タイトル形式 |
|---|---|---|
| Li+ language(デフォルト) | build-YYYY-MM-DD.N |
{version}(例: v1.9.0) |
| npm パッケージ | v{semver} |
v{semver} |
CD workflow がタグを作成するプロジェクトでは、既存の CD 作成タグを使い、新規タグを作らない。npm version を使うプロジェクトでは、npm version コマンドがタグを作成する。
(→ skills/operations-on-release/SKILL.md の ## Post-release wiki sync)
ファイル所有境界(2026-04-26 以降、命名 refactor 2026-05-21):
-
docs/ 所有ファイル(大文字 + 数字 prefix +
Home.md+_Footer.md): docs/ が正本、Wiki は同期先。同期後は byte 単位で一致する。docs/Decision-Structure.md(判断構造レイヤー Decision Structure の index)は通常の docs/ 所有大文字ファイルとして扱う(docs/ 側はadapter/claude/hooks/on-session-start.shが cold-start synthesis 素材として head を emit、Wiki 側はナビでの可視化) -
Wiki 専属ファイル(小文字 kebab-case
[a-z]*.mdの判断構造 +_Sidebar.md等の Wiki 専用ナビ): Wiki が所有、docs/ に counterpart を持たない、同期は preserve する。判断構造 entry は順序 prefix を持たず、順序はdocs/Decision-Structure.mdと_Sidebar.mdで明示する
push 前検証(手順 5/6 のコミット前に必須):
-
git -C {tmpdir} status --shortを実行し、削除(D)と更新(M)に docs/ 所有パスのみが現れることを確認する -
Wiki 専属ファイル(小文字 kebab-case
[a-z]*.mdまたは_Sidebar.md)にD/Mが出た場合は STOP して人間にエスカレートする。selective wipe パターンの逸脱は再発する故障モードであり、この信号で wiki に push してはならない -
Sidebar 整合性アサーション(手順 4 後・手順 5 前):
{tmpdir}/_Sidebar.mdが navigable entry を網羅的に参照しているか検証する。期待 slug 集合を{tmpdir}ファイルシステムから構築する:Home-
{tmpdir}/[A-Z]*.mdのすべて(docs/ 所有の大文字 + 数字 prefix、slug は拡張子を除いたファイル名) -
{tmpdir}/[0-9]*.mdのすべて -
{tmpdir}/[a-z]*.mdのすべて(Wiki 専属 kebab-case 判断構造 entry)
期待集合から除外:
_Sidebar.md、_Footer.md(ナビ基盤であって被参照エントリではない)。{tmpdir}/_Sidebar.mdから](<slug>)リンク先を抽出し、期待 − 参照が空でなければ STOP して欠落 slug を名指しで人間にエスカレートする。この信号で wiki に push してはならない。sidebar drift は entry を追加した PR がナビを保守しなかったということであり、release sync は黙って自動修正する層ではない。理由:entry 作成 / rename のコミットは release タイミングから分離されて行われるため、release 間に sidebar drift が静かに蓄積する。sync は invariant を強制する自然な再帰チェックポイント。Dogfood(2026-05-21):build-2026-05-20.1 sync で E-J と p / r / s / t / u が
_Sidebar.mdから欠落していたが検出できず、wiki commit5e47a90で手動回収した -
Cross-reference 整合性アサーション(手順 4 後・手順 5 前):
{tmpdir}/*.md内のすべての wiki 内部リンクが実在 entry を指していることを検証する。解決集合を構築する:- 実在 slug =
Home+{tmpdir}/[A-Z]*.md+{tmpdir}/[0-9]*.md+{tmpdir}/[a-z]*.md(すべて拡張子なし) - 抽出 slug =
{tmpdir}/*.md本文内のすべての](<x>)出現箇所のうち、<x>が://を含まず、#で始まらず、/を含まないもの(wiki 内部リンク)。<x>に#sectionフラグメントがあれば剥がしてから resolution する
抽出 slug のうち解決集合に存在しないものが 1 件でもあれば STOP して、リンク元ファイルと壊れた target slug を名指しで人間にエスカレートする。この信号で wiki に push してはならない。broken cross-reference は entry rename 時に referrer 側更新が漏れたサインであり、release sync は黙って自動 rewrite する層ではない。
理由:kebab-case 命名(prefix なし)の採用により entry rename がルーチン操作になった。broken cross-reference は release 間で静かに蓄積する。sync は表面化させる自然な再帰チェックポイント。sidebar 整合性アサーションと同型の構造(STOP & escalate、自動修正なし)。
- 実在 slug =
新規 repo セットアップ(初回 sync 前のワンショット):
- 初期 docs/ に
Home.md/_Footer.md/ 正規の大文字 + 数字 prefix ファイル(docs/[A-Z]*.md、docs/[0-9]*.md)を配置。docs/Decision-Structure.mdは判断構造レイヤー Decision Structure の index として含める -
_Sidebar.mdは wiki repo 側に直接 push(docs/ 経由ではない) - 判断構造 entry(
<topic>.md小文字 kebab-case、順序 prefix なし)は作成時点から Wiki 専属。docs/ には置かない
手順:
1. Wiki リポジトリを clone: git clone https://github.com/{owner}/{repo}.wiki.git {tmpdir}
2. identity 設定(clone-and-throw-away パターンのため明示設定が必要):
git -C {tmpdir} config user.name "{commit-author-name}"
git -C {tmpdir} config user.email "{commit-author-email}"
3. drift set 計算(diff-targeted、bounded blast radius):docs/ source と wiki/ working tree で内容が異なる docs/ 所有ファイルだけを列挙し、その集合のみ操作する:
- to_copy = docs/ 側に存在し wiki 側と内容が異なる docs/ 所有ファイル(新規 + 内容変更。解決 glob: `docs/[A-Z]*.md` / `docs/[0-9]*.md` / `docs/Home.md` / `docs/_Footer.md`)
- to_delete = wiki 側に存在するが docs/ 側に無い docs/ 所有ファイル(docs/ 側での rename / 削除)
- 小文字 kebab-case(`[a-z]*.md`、判断構造 entry)と `_Sidebar.md` は drift set から明示除外(wiki 専属、to_copy / to_delete に入らない)
4. drift set を per-file 操作で適用(bounded、unbounded glob 削除なし):
for name in "${to_delete[@]}"; do rm -f "{tmpdir}/$name"; done
for name in "${to_copy[@]}"; do cp "docs/$name" "{tmpdir}/$name"; done
※ to_copy・to_delete とも空 = drift なし。commit/push を skip して step 8(後片付け)へ。no-op を報告。詳細 rationale は `skills/operations-on-release/SKILL.md`(diff-targeted パターン、旧 wipe-and-copy を置換)が source
5. 追加・削除を全てステージング: git -C {tmpdir} add -A
6. コミット: git -C {tmpdir} commit -m "sync: docs → wiki ({release_tag})"
7. push: git -C {tmpdir} push
8. 後片付け: rm -rf {tmpdir}
push が権限等で失敗した場合は人間にエスカレートする。省略は禁止。
Windows 固有(case-only rename ハザード):
Windows ホストの wiki repo ファイルシステムは case-insensitive。Installation.md → installation.md のような rename は 1 回の git mv では適用できず、index に旧 case が残る。
case-only rename を含む同期での 2 段 rename パターン:
git mv Installation.md __tmp_inst.md
git mv __tmp_inst.md installation.md
検出: git -C {tmpdir} status --short に同名で case 違いの D と ?? のペアが現れる。Linux/Mac はこのハザードを起こさないが、mirror-parity の規律として 2 段 rename は同様に適用する。
Wiki 同期はリリース手順の一部であり、後続タスクに分離しない。Wiki 同期はリリースフロー完了の gate である。
条件→行動。省略不可。
(→ rules/operations/execution-mode.md)
リポジトリごとの _EXE_MODE(USER_REPO1_EXE_MODE / LI_PLUS_REPO_EXE_MODE 等、対象リポジトリ key 名 + _EXE_MODE)によって AI の自律度を切り替える。未設定の場合、セッション開始時に AI が対話で設定する。有効値は trigger / semi_auto / auto の3種。デフォルトは trigger。
| 軸 | trigger |
semi_auto |
auto |
|---|---|---|---|
| 着手タイミング | 人間が判断 | AI が判断 | AI が判断 |
| AI セルフレビュー | 必須 | 必須 | 必須 |
| 人間による PR レビュー | 全 PR |
minor / major のみ |
なし |
| マージ実行者 | AI | AI | AI |
| リリース承認 | 人間 | 人間 | 人間 |
AI セルフレビューは全モードで必ず実行する(「PR レビュー」節参照)。
マージは全モードで AI が実行する(「マージ」節参照)。GitHub auto-merge(--auto)は trigger モードのみ。semi_auto / auto は AI 直接 merge。
-
triggerモード:実装開始のタイミングを人間が決める。PR は AI のセルフレビューの上に、全 PR で人間レビューが必要。実装開始の合図が出たら、ローカル専用の作業空間ではなく issue にリンクした個人ブランチを主作業面として使う。 -
semi_autoモード:着手タイミングは AI が決める。PR レビューはタイプ連動。-
patch→ セルフレビュー pass で AI が即マージ(人間レビューなし) -
minor/major→ セルフレビュー pass 後に人間確認 → 承認で AI マージ - 狙い:自己進化ループの回転が設計目標であり、低リスク変更(patch)の人間ボトルネックを外す。
minor/majorには人間の目を残す。 - 多層防御(意図的に2層):Layer 1 = AI セルフレビュー + Li+ 仕様規律(日常的なミスを吸収)、Layer 2 = リリース時の人間ゲート(latest flip、致命的な user 露出を防止)。
-
-
autoモード:着手タイミングも PR レビューも AI が完結。人間レビューなし。
- issue 作成・クローズ・修正はアサイニー(AI)の責任
- 情報不足時は人間に確認する
- リリースは全モードで人間の確認が必要
(→ rules/operations/execution-mode.md の human judgment gate 節)
以下の操作は human 判断ゲートの対象。release create / Latest flip / force push / tag delete / マージ済み PR delete / main ブランチへの破壊的変更 / 公開済み artifact への破壊的変更。これらのゲートは判断権限に対するものであって、実行権限に対するものではない。
- human が yes / no を判断する。
- 明示的な go-sign(例:「yes」「latest にして」「両方で」)を受けてから AI が gh CLI を実行する。
- 仕様文中の「human-only」「human flips via ...」「人間専用」「人間が flip する」等の表記は判断主体を指し、実行主体ではない。
- AI の返答内で human に gh CLI を打つように指示しない。CLI は AI が打ち、human は go-sign を出す。
ゲート対象操作に対する human の発話が曖昧な場合は、最も保存的な解釈をデフォルトとして採る。先行する go-sign を別ゲートに自動拡張しない(release create の go-sign は Latest flip の go-sign ではない)。
AIが自律的に判断して動く領域。
(→ skills/operations-on-branch/SKILL.md の # Repo-first Execution Surface 節)
高注意で扱うのは、main のような保護された共有ブランチである。issue にリンクした個人ブランチは通常の実装面として扱う。リポジトリ全体を過度に「間違えてはいけない場所」とみなさない。
ローカル確認はブランチ作業と両立する。push の前でも後でも実行してよい。ただし、作業継続性の正本は issue にリンクしたブランチ側に置く。ローカルで動いたことだけを完了条件にしない。
(→ skills/operations-handoff-continuity/SKILL.md)
トークン上限、セッション切断、モデル切り替えなどで作業が中断されそうな時は、issue にリンクした個人ブランチへ中間状態を push してよい。引き継ぎ時の正本は、会話ログではなく issue body + linked branch + commit / PR state である。
意味のある進捗をローカルワークスペースや一時的な会話だけに閉じ込めない。
(→ skills/operations-chat-output-limit/SKILL.md)
長い出力は途中で止まることがある。物理的な制限であり、破損ではない。必要に応じてチャンキングする。
(→ ラベル辞書の正本は L3 タスクレイヤー rules/task/task.md の ## Task Label Definitions。本節は運用ルールと廃止履歴のみ保持。L4 と L3 の ### Sync 相互参照により辞書変更時の同期義務が成立する)
(→ rules/operations/operations.md の ## Operations Label)
- すべての issue に作成時点でタイプラベルを1つ以上付与する
- すべての issue に作成時点で成熟度ラベルを1つ付与する
- ライフサイクルラベルは状態変化時に適用する
- ラベルは AI の可読性とフィルタリングのためにある
| ラベル | 廃止理由 |
|---|---|
done |
issue の closed 状態と冗長 |
ラベルの追加・変更・廃止を行った場合はタスクレイヤー(rules/task/task.md の Label Definitions セクション)も合わせて更新する。
(→ skills/operations-notifications-api/SKILL.md)
GET /notifications?all=false -> 200 inbox 確認
PATCH /notifications/threads/{id} -> 205 既読(Inbox に残る)
PUT /notifications {"read":true} -> 205 全既読
DELETE /notifications/threads/{id} -> 204 完了(Inbox から除去)
scope = notifications(classic PAT)
通知 API の生操作はオペレーションレイヤーから参照してよい。ただし、前景関連性判定、claim、ack/read、consume/done、mention、cleanup の意味論は 5. Notifications を正本とする。
(→ skills/operations-foreground-webhook-intake/SKILL.md)
各ユーザー turn の開始時に webhook イベントを検査し、前景関連または特記すべき項目のみ言及する。前景関連性が安価に判定できない場合は保持して沈黙する。別 AI プロセスの起動は本フローでは禁止。
webhook 通知には自分の操作結果(push、PR、issue、リリースなど)も含まれる。これらは GitHub への到達確認として機能する。自操作イベントはフォアグラウンドチェック時または操作直後に速やかに mark_processed する。一括クリアのために溜め込まない。外部からのイベント(他ユーザー、bot)は保持し、フォアグラウンド報告または明示的な処理フローに委ねる。
(→ skills/operations-discussions/SKILL.md)
Discussions は外部ユーザーの入口。bot が常駐し、issue 作成と issue 読込が可能。コミット・コード変更はできない。
外部ユーザーが Discussions に投稿 → bot が issue を作成 → AI が issue から実装する。
再構築・削除・最適化はすべて許容する。構造の一貫性のみ維持する。