【必須】現在のアクティビティを完了にする、または完了にせず中断して寝かせる。「/af」「この作業完了」「クローズして」「一旦ここまで」「今日はここで止める」「いったん置いておく」など終える・中断する意図で発動。このスキルを経由せずにupdate_activityでcompleted・pending・snoozed・shelvedにしない。
db-recovery
CALMのDB件数の異常減少に対し、スナップショット確認・復旧方法の提示・承認後の復元・再検証まで進める。SessionStartの異常減少警告、記録の消失に気づいたとき、「データ消えてない?」などで発動。
実行スコア 未検証
インストール方法を見る含まれるファイル(1)
- SKILL.md9.9 KB
SKILL.md(原文)
インストールする前に、エージェントに与えられる指示の中身を確認できます。
db-recovery
SessionStart hookが検知したDBデータ異常減少への自律復旧スキル。検知 → 確認 → 提示 → 承認 → 実行 → 再検証の順で進める。全自動実行はしない。実行前に必ずユーザー承認を取る。
発動契機
以下のいずれかで発動する。
- SessionStart hookがDB異常減少警告(🚨🚨🚨 DBデータ異常減少を検知)を注入した
- 会話中に、activity/decision/log等の想定件数の少なさや直近記録の消失に自分で気づいた
- ユーザーから「データ消えてない?」「件数減ってない?」と指摘された
以下では発動しない。
- 警告が無く、通常のDB状態である
- 直前の正当な操作(大量retract・tag-cleanup等)による説明可能な減少だと確認済みである
- ユーザーが既に別経路で復旧完了したと明言した
発動したら、異常警告を放置したり、calm:manの手動手順だけを案内して終わらせたりしない。
発動時の前提
hookの警告は _build_snapshot_section(hooks/session_start_hook.py)がSessionStartのadditionalContextとして注入する。警告本文には対象テーブルと減少件数(前回件数 → 現在件数 (-N件))が含まれる。このスキルはこの警告文を読み取るところから始まる。
復元本体(restore_snapshot)は以下を内蔵している。このスキルは重複実装しない:
- 復元前の現行DBの自動退避(
prerestoreスナップショット) - サーバー稼働中チェック(稼働中は
--forceなしで実行不可) - スナップショットの整合性検証(
verify_snapshot) - schema互換性チェック(巻き戻し疑いは
--yesなしで実行不可)
手順
1. 異常確認
- hook警告本文をパースし、どのテーブルが何件減ったか(
discussion_topics/decisions/discussion_logs/activities/materials)を把握する - 現在のDB状態を実際にクエリして裏取りする(
get_activities/get_decisions等のCALMツール、またはuv run --directory "${CLAUDE_PLUGIN_ROOT}" python "${CLAUDE_PLUGIN_ROOT}/scripts/snapshot.py" listで分かる直近の行数)。警告は前回スナップショット取得時点との差分であり、直近の正当な操作(大量retract・tag-cleanup等)による見かけ上の減少でないか確認する - 確度を判定する:
- 明確な異常: 直近セッションで該当テーブルへの意図的な大量削除・retract操作の記憶がない
- 説明可能: 直近でtag-cleanup・大量retract等の正当な操作があったことが会話履歴やlogから確認できる
- 不明: 判断材料が無い
2. スナップショット所在確認
uv run --directory "${CLAUDE_PLUGIN_ROOT}" python "${CLAUDE_PLUGIN_ROOT}/scripts/snapshot.py" listで全kind横断の一覧を取得する- 各エントリの
kind/created_at/db_size_bytes/quick_checkを確認する。quick_checkがok以外のものは復元候補から除外する - 異常検知直前(=データがまだ健全だった時点)に最も近いスナップショットを候補として特定する
- 補足:
_build_snapshot_sectionは異常検知時(is_healthy=False)に新規periodicスナップショットの取得をスキップする実装のため、異常検知セッション中に直前の健全世代が壊れたスナップショットで上書きされることはない
3. 復旧方法の提示
ユーザーに以下をA/B/Cの選択肢として提示し、承認を取る。承認なしに実行しない。
[db-recovery] DBデータ異常減少を検知:
- 対象テーブル: (例: decisions: 1200 → 1050 (-150件))
- 確度: (明確な異常 / 説明可能 / 不明)
- 復元候補: (スナップショットのcreated_at / kind / パス、quick_check結果)
復旧方法を選んでください:
- A: 最新スナップショットから全体復元 — 復元後、復元時点以降に記録した内容は失われる
- B: 部分復元(特定テーブルのみ、または欠落範囲を特定して手動補完)— backup_serviceはテーブル単位・行単位の部分復元を自動化していないため、実質SQLレベルの手動作業になる。工数とリスクを明示した上で提案する
- C: 復旧せず先に進む(誤検知と判断、または復元コストが見合わない場合)
- 各選択肢について「何が起きるか」「何を失うリスクがあるか」を必ず併記する
- A/Bは「MCPサーバーの停止が必要」という制約を必ず明示する(
restore_snapshotは稼働中サーバーに対して--forceなしでは実行できない)。--force/--yesを自発的に付けて安全装置を回避しない
4. 承認後の実行(Aを選んだ場合)
- サーバー停止・復元を一連の操作として承認を取る。「復旧していい?」への直接的なyes/noが必要(「任せる」等の一般的信任表明では実行しない)。この承認は停止・復元までを対象とし、再起動は含まない(下記6.で復元結果提示後に別途承認を取る)
- サーバーを停止するとMCP接続が切れて記録できなくなるため、停止前に現状(検知内容・確度・提示した復旧方法・ユーザーが承認した内容)を
add_logsで記録する uv run --no-sync --directory "${CLAUDE_PLUGIN_ROOT}" python "${CLAUDE_PLUGIN_ROOT}/scripts/restart_server.py" --stopでサーバーを停止する(接続中のブリッジプロセスは巻き添えにせずLISTEN中のプロセスだけを狙って止める)uv run --directory "${CLAUDE_PLUGIN_ROOT}" python "${CLAUDE_PLUGIN_ROOT}/scripts/snapshot.py" restore --latest(Step2で特定した候補が最新でない場合は該当パスを直接指定)を実行する復元エラー: サーバーが稼働中のため復元を中断しましたが返った場合、上記3.(サーバー停止)が漏れている。サーバー停止を再確認してからリトライする- schema互換性警告(
--yesを要求するメッセージ)が出た場合は、警告文をそのままユーザーに見せて--yes付き再実行の可否を確認する。自己判断で--yesを付けない
- 実行結果(
復元完了: ... -> ...、行数の変化テーブル、prerestore_path)をそのままユーザーに提示する - 実行結果の提示後、サーバー再起動について改めてユーザーの明示承認を取る。上記1.の一括承認は再起動を含まないため、ここで新たにyes/noを得るまで再起動を実行しない。承認が得られたら、restart skillでClaudeが再起動する。復元の後はプラグインの更新を省き、再起動だけを行う。
restart_server.pyやkill・起動コマンドは直接打たない。 - MCP再接続後、経緯を
add_logsで追記する(実行結果)
Bを選んだ場合は、対象範囲の特定と手動SQL操作の手順を個別に提示し、実行前に再度承認を取る。サーバー停止を伴う場合は、停止前にAの2.と同様に現状を add_logs で記録する。
Cを選んだ場合は、誤検知と判断した理由を add_logs に記録してスキップする。
5. 再検証
- 復元後、主要データが戻っているかを確認する(
get_activities/search等、またはuv run --directory "${CLAUDE_PLUGIN_ROOT}" python "${CLAUDE_PLUGIN_ROOT}/scripts/snapshot.py" listで最新スナップショットの行数と突き合わせ) - 異常が解消していない場合、Step2に戻り別の復元候補(一つ古い世代等)を提案する
- 解消しない場合は「これ以上の自動復旧は困難」と報告し、ユーザー判断に委ねる(無限に世代を遡り続けない。現存する全世代を試して尽きたら停止する)
Edge Cases
| ケース | 期待挙動 |
|---|---|
| スナップショットが1件もない | 警告のみ提示し、復元不能である旨を伝える。「先に進む」以外の選択肢がないことを明示 |
復元に使えるスナップショットが全て quick_check 失敗(破損) | 破損している旨を明示し、直近の非破損世代 or 「復元不能」を報告する |
復元実行が失敗(RestoreBlockedError) | エラーメッセージをそのまま提示し、原因(サーバー稼働中 / 整合性検証失敗 / schema非互換)に応じた対処を提案。無断で --force / --yes を付けて再実行しない |
| 誤検知(直近の正当な大量retract等が原因と判明) | Cを選択してskipし、判断理由をlogに記録する |
| SessionStart警告以外でDB異常に気づいた場合(会話中に件数の少なさに気づく等) | 同じフローに入ってよい(TRIGGERの2つ目のケース)。Step1で「hook警告なし・自己認識起点」である旨を明記する |
| 復元後も異常が解消しない | Step5の通り別世代を試すか、解消不能として報告する |
注意
- 復元前の自動バックアップ(
prerestore退避)はrestore_snapshotが内部で行うため、このスキルが別途手動バックアップを取る必要はない - MCPサーバーの停止・再起動はユーザー影響が大きい操作。実行前に必ず明示的な承認を取る(一般的な「任せるよ」は承認とみなさない)
--force/--yesフラグは安全装置を無効化するものであり、スキル側が自発的に付与しない
レビュー
まだレビューはありません。使ってみた感想をお寄せください。
コメント
ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。
まだコメントはありません。最初のコメントを書いてみませんか。
同じリポジトリのスキル
【必須】新しいアクティビティを作成してcheck-inする。「/as」「新しい作業始める」「アクティビティ作って」「これやる」など新規作業の開始で発動。このスキルを経由せずにadd_activityを呼ばない(orchの起票はorch skillに従う)。
【必須】open askを1件ずつ人間に提示し、回答をanswer_askで記録する。「askに答える」「open ask消化して」「溜まってるask片付けたい」などで発動。このスキルを経由せずにanswer_askを呼ばない。
【必須】add_askでaskを起票する前に、question/contextをテンプレートで組み立てる。離席中・セッション跨ぎでしか答えられない判断が出たときや、「これ聞いといて」「判断委譲しといて」「後で確認して」などで発動。このスキルを経由せずにaskの文面を書かない(メタaskを除く)。
add_askの応答のsimilar_asksを見て、同型の問いが繰り返され裁定が一貫していると気づいたとき、判例をまとめてメタask(kind="meta")を起票する。
人間の判断待ちaskの受け箱をMonitorで監視し、判断構造が同じopen askが溜まっていればメタaskを起票する。「ask storeを監視して」「asksを見張って」「open askの滞留をチェックして」などで発動。