ワンクリックで
org-suspend
組織を中断し、全状態をディスクに保存する。「中断」「保存して終了」 「閉じたい」「一旦やめる」「今日は終わり」と言われたときに使う。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
組織を中断し、全状態をディスクに保存する。「中断」「保存して終了」 「閉じたい」「一旦やめる」「今日は終わり」と言われたときに使う。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
ワーカーClaudeを派遣して作業を委譲する。窓口は司令塔であり、 手を動かす実作業は原則としてワーカーに任せる。 ユーザーから作業の依頼を受けたとき、ファイル編集・実装・調査等の 実作業が発生する場合に発動する。
組織の全ロール(窓口・ディスパッチャー・キュレーター・ワーカー)に必要な Claude Code の許可設定・環境変数を一括で配置・更新するスキル。 「設定して」「許可設定を更新して」「セットアップして」 「permissions設定」「org-setup」等で発動する。
open Issue を triage して「次の仕事候補(N 件 + 推奨 1 件)」を窓口が人間へ提示する。 決定的ツール tools/work_discovery_scan.py を 1 回実行し、その候補 JSON を 設計書 §5.2 の人間可読フォーマットでレンダリングするところで停止する(propose-only)。 起動主体は窓口に限定。手動 / イベント起動のみ(常駐 /loop なし)。 「次の仕事候補出して」「triage して」「次なにやる?」や PR マージ後の proactive next-dispatch で窓口が手動起動する。
蓄積された生の学び(knowledge/raw/)を整理・統合する。 ディスパッチャーが worker クローズ時の閾値チェック (tools/check_curate_threshold.py) 超過でオンデマンド起動した キュレーターから 1 回だけ呼び出される(常駐 /loop は廃止)。 手動で「知見を整理して」と言われたときにも使う。
委譲プロセスの振り返り。ワーカーへの作業委譲が完了したとき、 委譲の進め方自体を振り返り、プロセス改善の知見を記録する。 さらに、完了タスクの作業パターンをwork-skillとして蓄積すべきか判断する。 実作業の技術的な振り返りはワーカーが自動的に行うため、ここでは扱わない。
skill の棚卸し(廃止候補 / 重複統合 / owner 明記チェック)。 状態ベースで発火する: 候補キュー knowledge/skill-candidates.md の pending が 5 件以上、 または .claude/skills/ 配下の work-skill 数(org-* を除く)が 20 以上になった場合のみ実行。 時間ベースの /loop では起動しない(変化の無い日に raw ログを汚す副作用を避けるため)。
| name | org-suspend |
| description | 組織を中断し、全状態をディスクに保存する。「中断」「保存して終了」 「閉じたい」「一旦やめる」「今日は終わり」と言われたときに使う。 |
| effort | low |
| allowed-tools | ["Read","Bash(bash tools/journal_append.sh:*)","Bash(py -3 tools/journal_append.py:*)","Bash(python -m tools.state_db.importer:*)","Bash(python3 tools/secretary_queue_watcher.py:*)","Bash(py -3 tools/secretary_queue_watcher.py:*)","Bash(rm -f .state/attention_pane.json)","Bash(del .state\\attention_pane.json)","mcp__org-broker__check_messages","mcp__org-broker__close_pane","mcp__org-broker__inspect_pane","mcp__org-broker__list_panes","mcp__org-broker__list_peers","mcp__org-broker__poll_events","mcp__org-broker__send_keys","mcp__org-broker__send_message","mcp__org-broker__set_pane_identity","mcp__org-broker__set_summary","mcp__org-broker__spawn_claude_pane","mcp__org-broker__spawn_pane"] |
全ワーカーの状態を収集し、ディスクに保存し、全ペインを停止する。
curator 不在は正常系(オンデマンド化): キュレーターは常駐しない。state.db の
curator_pane_id/curator_peer_idは null が正常で、list_panes/list_peersに curator が見えないことは異常ではない。curator ペインが存在するのは「worker クローズ起点の オンデマンド curate が実行中に suspend が重なった」一時的なケースのみで、その場合だけ Phase 4 の停止対象に含める。
責務境界(/org-suspend と
/org-down): /org-suspend は 「状態保存 + ja 管理下の補助プロセス(dashboard / secretary_queue_watcher / attention watcher)とペインの停止」までを担い、claude-org-runtime org down(broker daemon の停止)は 呼ばない。suspend 単体は「また/org-startで再開する」前提の中断であり、broker daemon は 走らせたままにする(端末を閉じても daemon はすぐ再開できるよう生存する)。daemon ごと完全に 落とすのは/org-downの責務で、/org-down が suspend の成功を確認した 後にのみorg downを実行する。
ペイン操作は mcp__org-broker__* MCP ツール経由で行う。pane_exited
相当の lifecycle イベントは mcp__org-broker__poll_events で long-poll、画面スクレイプ
は mcp__org-broker__inspect_pane で取得、raw キー入力は mcp__org-broker__send_keys。
輸送層(transport)両系 — 既定
broker/ opt-inrenga: 本ファイル(および各スキル)のmcp__org-broker__*呼び出しは 既定broker(ORG_TRANSPORT無設定)で書いてあり、そのまま従えばよい(既定挙動)。ORG_TRANSPORT=renga(opt-in・切戻し可)では MCP サーバー名がrenga-peersになり、ツールの 完全修飾名がmcp__org-broker__*→mcp__renga-peers__*に機械置換される(引数形・セマンティクスは同一なので手順の論理は変わらない)。輸送依存で手順が変わる点だけ renga 併記する:
- 受信モデル: 既定 broker は push 一次(各ペイン同居の channel sidecar
server:org-broker-channelが broker キューを ~1 秒間隔で claim→notifications/claude/channelで idle セッションへ本文注入。pull = ナッジ +check_messagesは sidecar 不在 / unhealthy / channel 非対応ペイン(codex pull-peer)/ claude.ai login 不在時のフォールバック層)。ORG_TRANSPORT=renga時は dispatcher / worker メッセージが<channel source="renga-peers" …>として in-band で push される。- spawn 儀式: 既定 broker は
--mcp-config <broker>注入による Claude Code folder-trust プロンプトのsend_keys(enter=true)機械承認に加え、push 一次のため channel sidecar を--dangerously-load-development-channels server:org-broker-channelで load し dev-channel 承認プロンプトをsend_keys(enter=true)で機械承認する(2 段承認)。ORG_TRANSPORT=renga時は--dangerously-load-development-channels server:renga-peersの「Load development channel?」を Enter 承認する 1 段。- エラー分岐: 既定 broker は shared codes(
pane_not_found/last_pane/invalid-params)に加え broker 固有[token_invalid]/[session_invalid]/[tool_not_authorized]/[no_backend](= adapter_unavailable)/[nudge_failed]/[peer_not_found]/[name_taken]を返しうる(未知コードは default-branch で escalate)。ORG_TRANSPORT=renga時は broker 固有コードは発生しない。
new_tab/focus_paneは broker surface に無い(意図的除外)。契約面の正本はdocs/contracts/backend-interface-contract.mdSurface 8 + push-primary amendment(broker push 一次が 既定の契約、pull は fallback として retain)。opt-inrengaは削除せず常時有効な切戻しの安全装置として維持する。broker 実走(dogfood)は Epic #6 Issue G スコープで本ファイルの既定運用経路ではない(二フレーム注記(Refs #604): ここの「既定broker」はコード既定(tools/transport.py: DEFAULT_TRANSPORT、生成面はこれで render)。運用既定は broker dogfood が Epic #6 Issue G まで未活性のためrengaで、両者は指す対象が異なり矛盾しない。総説は rootCLAUDE.md。)
mcp__org-broker__list_peers で稼働中のピアを列挙するmcp__org-broker__send_message で以下を送信:
SUSPEND: 現在の状態を報告してください。
1. これまでに完了したこと
2. 変更したファイル(コミット済み/未コミット)
3. 次にやろうとしていたこと
4. ブロッカーや未解決の問題
mcp__org-broker__check_messages で応答を待つ(5 秒間隔でポーリング)応答がなかったワーカーについて:
.state/workers/ から該当ワーカーの状態ファイルを読み、Pane Name と Directory を取得mcp__org-broker__inspect_pane(target="worker-{task_id}", format="text")
画面表示だけでは不十分な場合は、次の Step 3 の git 情報で補完するgit statusgit diff --statgit log --oneline -5state-db cutover (M4, Issue #267):
.state/state.dbが唯一の SoT。 構造化セクション (Status / Updated / Suspended / Dispatcher / Curator / Worker Directory Registry / Active Work Items / Resume Instructions) は 必ず StateWriter 経由で書く。transaction()の post-commit hook が.state/org-state.mdを DB から自動再生成する (markdown 直接編集禁止 — drift_check で検出される)。free-form な session notes / Pending Lead / 学び等はnotes/配下に保存する (notes/README.md参照)。.state/journal.jsonlは M4 で廃止 (events テーブルが SoT)。 DB が古い場合はpython -m tools.state_db.importer --db .state/state.db --rebuild --no-strictで再構築する。
既存の org-state.md を org-state.prev.md にコピー(バックアップ)
DB に Status / Suspended を書く (StateWriter.transaction() 経由。post-commit hook が .state/org-state.md を自動再生成、regen 失敗時も DB は確定済みで stderr 警告のみ):
python -c "
from datetime import datetime, timezone
from pathlib import Path
from tools.state_db import connect
from tools.state_db.writer import StateWriter
ts = datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%fZ')
conn = connect('.state/state.db')
with StateWriter(conn, claude_org_root=Path('.')).transaction() as w:
w.update_session(status='SUSPENDED', suspended_at=ts, updated_at=ts)
"
"..." 内の改行をそのまま透過するので multi-line でも cross-shell。Windows CMD は heredoc 不可なので py -3 -c "ts=...; conn=...; w=...; w.begin(); w.update_session(...); w.commit()" の単行 fallback を使う(その場合 transaction() の rollback / regen 自動 swallow は失われるので追加で try/except を書く).state/org-state.md の Status 行を SUSPENDED に切り替える (DB 由来で再生成)notes/ に保存する (notes/README.md 参照)。markdown 直接編集は drift_check で検出される。update_session(resume_instructions=...) は構造化セクションとして DB に書く各 Work Item の状態を更新する場合は upsert_run(task_id=..., status=...) を transaction() 内で呼ぶ
各ワーカーの .state/workers/worker-{id}.md を更新:
suspend イベントを DB に追記 (tools/journal_append.py は M4 で DB-only ルーティング。ts は自動付与):
py -3 tools/journal_append.py suspend \
reason=user_requested \
--json '{"active_workers": ["worker-xxx"], "pending_items": ["blog-redesign"]}'
event 名と payload key の規約は docs/journal-events.md を参照。
kill $(cat .state/dashboard.pid 2>/dev/null) 2>/dev/null || true
注: この blind kill は「/org-start で再開する前提の中断」なので簡素なまま残す。daemon ごと 落とす
/org-downでは、pid recycle による誤 kill を避ける stale-pid-safe な 停止(/proc/Get-CimInstanceの CommandLine 照合)に差し替える。
broker 面(ORG_TRANSPORT=broker)で org-start Block C3 が run_in_background で
常駐させた滞留 watcher を停止する。renga では watcher が存在しない(queue.jsonl 非依存)ので、
transport が renga なら本 Phase はまるごと skipする。
watcher は起動時に .state/secretary_queue_watcher.json へ自分の pid / cwd / cmdline / started_at /
broker_state_dir を記録している。停止は pid 単独で kill せず、(a) 記録された broker_state_dir が
現在の ORG_BROKER_STATE_DIR と一致し(別 org / 別 broker の watcher 誤停止防止)、かつ (b) pid が
生存し live argv(Linux/WSL は /proc/<pid>/cmdline、macOS/BSD は ps -p <pid> -o args= フォールバック)が
本 watcher であることを照合できたときだけ SIGTERM する。照合が外れたら kill せず sidecar を stale として
削除する(誤 kill 防止)。この照合ロジックは helper に入っているので、POSIX では 1 行呼ぶだけでよい:
Mac / Linux / WSL:
python3 tools/secretary_queue_watcher.py --stop # Windows で console python を使う場合は py -3 ...
出力の 1 行(STOP: ...)で結果を確認する(SIGTERM を送信し停止 / stale sidecar を削除 /
既に停止済み)。exit 0 が正常系(停止・stale 掃除・既停止のいずれも 0)。macOS は ps フォールバックで
identity 照合できるので --stop がそのまま効く。exit 2(identity 未確認)は /proc も ps も無い環境
(Windows native)でのみ出るシグナルで、その場合は次の PowerShell 手順を使う。
Windows native(PowerShell) — /proc が無く helper の argv 照合が使えないので、
Get-CimInstance Win32_Process の CommandLine で identity を照合してから Stop-Process する
(kill -0 / kill -TERM の直訳ではなく Windows 別手順):
$pf = ".state\secretary_queue_watcher.json"
if (Test-Path $pf) {
$rec = Get-Content $pf -Raw | ConvertFrom-Json
$wpid = [int]$rec.pid
$ownOk = $false
try {
if ($env:ORG_BROKER_STATE_DIR) {
$ownOk = ((Resolve-Path $rec.broker_state_dir).Path -eq (Resolve-Path $env:ORG_BROKER_STATE_DIR).Path)
} else {
$ownOk = ((Resolve-Path $rec.cwd).Path -eq (Get-Location).Path)
}
} catch { $ownOk = $false }
$proc = Get-CimInstance Win32_Process -Filter "ProcessId=$wpid" -ErrorAction SilentlyContinue
$idOk = $proc -and ($proc.CommandLine -match 'secretary_queue_watcher\.py')
if ($ownOk -and $idOk) {
Stop-Process -Id $wpid -Force
Write-Output "secretary_queue_watcher (pid=$wpid) stopped"
} else {
Write-Output "watcher pid stale / different org / not running; not killing, removing stale sidecar"
}
Remove-Item $pf -ErrorAction SilentlyContinue
}
attention watcher は dispatcher ペインの右 split に常駐する CLI ペインなので、Phase 4 のペイン 一括 teardown より前に停止する(dispatcher を先に閉じると attention ペインが孤児化 / pane_id recycle され、後続の識別を壊すため)。attention watcher を起動していないセッションでは sidecar も live pane も無く、本 Phase は no-op。
停止は /org-attention-stop と同じ identity 照合を使う
(sidecar の pane_id を無検証で close_pane しない。pane_id が別ペインへ再割当てされていると
無関係なペインを kill する — Issue #468):
mcp__org-broker__list_panes で name="attention" または role="attention" の live pane を
全て集める(= 確認済み attention ペイン集合。各 数値 pane_id を控える).state/attention_pane.json を Read で開けたら pane_id を読む(= sidecar pane_id)。無ければ
「sidecar 無し」mcp__org-broker__close_pane(target="<id>") する
(target="attention" の name 指定はしない — role だけ持つ孤児に当たらないため)。
[pane_not_found] / [pane_vanished] は既に閉じた扱いで skiprm -f .state/attention_pane.json # Windows native は del .state\attention_pane.json
reason=stale_sidecar にする(無関係なペインを停めた誤記録を防ぐ):
bash tools/journal_append.sh attention_watch_stopped pane_id=<N> # close した場合
bash tools/journal_append.sh attention_watch_stopped reason=stale_sidecar # close しなかった場合
分類別の詳細な挙動と報告文は /org-attention-stop を参照(本 Phase は
その要点を suspend フローに埋め込んだもの)。
停止順序が重要。ワーカー → ディスパッチャー → キュレーターの順で停止する。
mcp__org-broker__list_peers で稼働中のピアを列挙
ワーカーを先に停止: 全ワーカーピアに mcp__org-broker__send_message で終了を指示:
「SHUTDOWN: 作業を終了してください。」
ワーカーペインが閉じたことを確認 — 2-pass 構造で実施:
Pass 1 (polite shutdown の観察、最大 10 秒):
mcp__org-broker__poll_events で pane_exited を long-poll する。types=["pane_exited"] フィルタで他 type を除外しつつ、deadline 内でループして待機対象が全て閉じたら break:
pending_workers = {全ワーカーの name set}
cursor = None # 初回は since 省略
deadline = now + 10 秒
while pending_workers not empty and now < deadline:
remaining_ms = (deadline - now) ミリ秒
result = mcp__org-broker__poll_events(
since=cursor,
timeout_ms=min(remaining_ms, 10000),
types=["pane_exited"]
)
cursor = result.next_since
for ev in result.events:
if ev.role == "worker" and ev.name in pending_workers:
pending_workers.remove(ev.name)
# deadline 到達 or pending_workers が空で抜ける
since 省略で「今以降のイベントだけ」セマンティクス(過去の pane_exited を replay しない)types=["pane_exited"] filter は cursor を全 type で advance させるので重複 scan なしevents:[] + advanced cursor) するため、空応答時は deadline までループ継続Pass 2 (残留ワーカーへのフォールバック + 再確認、最大 5 秒):
mcp__org-broker__close_pane(target="worker-{task_id}")
でペインを明示破棄する。成功時は "Closed pane id=N." テキストが返る。[pane_not_found] / [pane_vanished] は既に閉じた扱いで skip(references/renga-error-codes.md 参照)。[last_pane] はワーカー停止段階では通常発生しない(窓口/ディスパッチャー/キュレーターが残っているため)poll_events ループを timeout_ms=5000 / deadline 5 秒で再度回し、close_pane 由来の pane_exited を消化するmcp__org-broker__list_panes で生存確認し、残存なら journal に記録して人間に報告(強制終了は現状未サポート)ディスパッチャーを停止: ディスパッチャーに mcp__org-broker__send_message で終了を指示:
「SHUTDOWN: 作業を終了してください。」
キュレーターを停止(存在する場合のみ): curator は常駐しないため、通常このステップは
no-op。mcp__org-broker__list_panes に name == "curator" のペインが存在する場合
(オンデマンド curate 実行中に suspend が重なったケース)のみ、send_message で終了を指示:
「SHUTDOWN: 作業を終了してください。」(curate は move-then-mark 設計のため途中停止でも
破壊的な中間状態は残らない)
ディスパッチャー(および存在した場合のみキュレーター)も (3) と同じ 2-pass 構造で確認(pending = {"dispatcher"}、curator が存在した場合は "curator" も集合に入れ、role == "dispatcher" または role == "curator" の pane_exited を待つ):
poll_events(types=["pane_exited"], timeout_ms=10000) 相当ループmcp__org-broker__close_pane(target="dispatcher")(curator 残存時は close_pane(target="curator") も)を送り、poll_events ループ (timeout_ms=5000) で再確認最後のペイン (窓口) の扱い: ディスパッチャー(と存在した場合のキュレーター)を閉じた時点でタブに残るのは窓口
ペインのみになる。窓口が自分自身を mcp__org-broker__close_pane(target="secretary") で
閉じようとすると [last_pane] (唯一のタブの唯一のペイン) が返るので、窓口は自分自身で
exit して自然終了させる (人間が端末を閉じる、または /exit でシェルに戻る)。
org-suspend は窓口ペインを閉じる責任を負わない。
組織を中断しました。
- 保存済み: {N}件の作業アイテム
- 状態ファイル: .state/org-state.md
/org-start で再開できます。