Claude Code の並列エージェント(agent teams・teammate)の後始末と無応答時の打ち切りルール。`name` を付けて Agent を起動するとき、TeamCreate でチームを組むとき、teammate から `idle_notification` が届いたとき、評価ループ等で次のイテレーションのエージェントを起動する前、エージェントの返信が届かないときに参照する。`name` を付けない通常のサブエージェント起動だけなら対象外。
nix-store-lookup
/nix/store 配下の store path・ファイルを特定するときに必ず参照する。`find /nix/store` で名前を総当たりする前に読む。
「あのパッケージの store path が知りたい」「nix-unit のバイナリはどこ」「flake input の実体パスを知りたい」「derivation の出力パスを取りたい」「store の中のこのファイルを探したい」「store path が実在するか確かめたい」といった場面が対象。
/nix/store は数万エントリあり深さ無制限の find は完了しない(実測: 20秒でも終わらず出力ゼロ)。同梱の collect_store_lookup.sh が入力の種別判定・一意な解決・候補収集・実在確認までを決定論的に行うので、まずそれを実行してから分析する。
nix-locate が返す path はローカルに存在しないことがあるという反直感的な挙動も、データとして検出される。
含まれるファイル(3)
- SKILL.md7.5 KB
- scripts/collect_store_lookup.sh16.3 KB
- scripts/tests/collect_store_lookup.test.sh11.0 KB
SKILL.md(原文)
インストールする前に、エージェントに与えられる指示の中身を確認できます。
nix-store-lookup — /nix/store の探索を決定論的な解決に置き換える
なぜ find を使ってはいけないか
/nix/store はこの種の環境で数万エントリある(実測 35,220)。深さで所要時間が破滅的に変わる:
| コマンド | 実測 |
|---|---|
find /nix/store -maxdepth 1 -name '*nix-unit*' | 0.22s |
find /nix/store -maxdepth 2 ... | 5.5s |
find /nix/store -name '*nix-unit*'(深さ無制限) | 20秒経っても完了せず出力ゼロ |
| 同梱スクリプト(分類・解決・実在確認まで込み) | 0.3s |
速度以上に問題なのは 結果が一意に決まらないこと。find /nix/store -maxdepth 1 -name '*nput*' は 0.14s で終わるが、.drv・-vendor.drv・manifest を含む 20 件が返り、どれが目的か判断できない。探索ではなく、入力から一意に引くのが正しい。
手順
1. 収集(必ず最初に実行する)
手段を選ぶ前に、決定論で取れるものを一括で取る。入力の種別を事前に判定する必要はない(スクリプトが分類する)。
bash <skill-dir>/scripts/collect_store_lookup.sh <query>
<query> はコマンド名・store path・derivation パス・パッケージ名のいずれでもよい。
オプション:
--all— ローカルで一意に解決できた場合でも upstream index(nix-locate)を照会する。既定は skip(理由は後述)--flake <dir>— 指定 flake の input も収集する(既定: カレントが flake なら自動)
2. 出力の読み方
{
"classified_as": "command_on_path",
"resolved": { "store_path": "...", "via": "...", "exists": true },
"candidates": {
"local_db": { "matches": [...], "count": 4, "total_matched": 4, "truncated": false },
"upstream_index": { "skipped": "...", "matches": null }
},
"context": { "store_entries": 35220, "db_valid_paths": 35141, "flake": {...} },
"warnings": [...]
}
判断はこの順で行う:
resolvedが null でなければそれが答え。分岐は不要で、追加のコマンドも要らないresolvedが null ならcandidates.local_db.matchesを見る。is_drvでビルド定義を除外し、existsで実在を確認して選ぶtruncated: trueなら候補を絞れていない。より長い検索語で再実行する(warningsが具体的に指示する)warningsは必ず読む。誤誘導を招く事象がここに出る
classified_as の値と、それぞれで resolved に入るもの:
| classified_as | 入力の例 | resolved の内容 | 実測 |
|---|---|---|---|
command_on_path | nput, rg | symlink を辿った store path | 0.005s |
derivation | /nix/store/xxx-foo.drv | --query --outputs の出力パス | 0.072s |
store_path | /nix/store/xxx-foo | 正規化した store path と deriver | 0.075s |
name_query | nix-unit | null(候補から選ぶ) | 0.022s |
3. 追加で必要になる操作
収集結果で足りるのが大半だが、次は個別に実行する。
store path の中身を探す — store path が確定しているなら、その配下だけを見る:
nix store ls -R /nix/store/xxx-ripgrep-15.2.0 # 0.087s
find /nix/store/xxx-ripgrep-15.2.0/ -name '*.so' のように単一 store path 配下に限定するなら find でも構わない。禁じられているのは /nix/store そのものを起点にすることだけ。
依存関係を辿る:
nix-store --query --referrers /nix/store/yyy-foo # これに依存しているもの
実行できればよい(path 不要):
nix shell --offline nixpkgs#<pkg> -c <cmd> # 0.9s
落とし穴(すべて実測で確認済み)
nix-locate が返す path はローカルに存在しないことがある
最も誤解しやすい点。 nix-locate / nix-index は upstream nixpkgs の index であって、ローカル store の索引ではない。実測では nix-locate -w bin/rg が返した 3 件中 2 件がディスクに存在しなかった。
スクリプトは全 upstream 候補に exists_locally を付け、未存在があれば warnings に出す。この判定を記憶や推測で代替しない(出力を見ればよい)。
既定で upstream を照会しないのもこのため。ローカルで一意に解決済みなのに、実在しない候補を並べると誤誘導になる。nixpkgs 側を調べたいときだけ --all を付ける。
同じ理由で nix eval --raw nixpkgs#<pkg> が返す outPath も実在するとは限らない(pin が違えばハッシュが変わる)。実在確認は nix path-info <path>(未ビルドなら exit 1 / 0.071s)。
lookup 目的で nix build を使わない
nix build --print-out-paths --no-link は path を表示するが 実際にビルド・fetch する。実測で 25.1s かかり 2.1MiB の転送が始まった。--dry-run でも 4.0s + 依存解決が走る。path を知りたいだけなら nix eval か nix-store --query。
nix eval には --offline を付ける
--offline 無しだと substituter に問い合わせに行く。実測 14.9s(copying path ... from https://cache.numtide.com が発生)vs --offline で 0.56s。ただしローカルに無いものは解決できないので、upstream を引きたいときは外す。
nix-store --query --roots は読み取り専用ではない
stale な gcroot symlink を削除する副作用がある。「安全な参照系」として無自覚に実行しない(スクリプトも使っていない)。
DB と filesystem は完全一致しない
実測で filesystem 35,220 / DB 35,141 と 79 件ずれる。差分はビルド中の一時ファイル・.lock・GC 待ちの残骸で、DB クエリでは出ない。スクリプトはこのずれを検出して warnings に出す。
find /nix/store が残る例外
次の場合に限り使ってよい。いずれも -maxdepth 1 を必ず付ける(深さ 2 で 5.5s、無制限で完了しない):
- DB に載らない一時ファイル(
.lock、ビルド中の中間物)を探すとき - store DB が読めない環境
それ以外で /nix/store を起点にした探索が必要になったら、収集スクリプトに戻る。
関連スキル
- nix-cache-check: バイナリキャッシュ未ヒットの原因調査(store path の特定ではなく、substituter / Hydra 側の問題を扱う)
レビュー
まだレビューはありません。使ってみた感想をお寄せください。
同じリポジトリのスキル
概要と使いどころ
spec.md の REQ-# を入力に、機能一覧・モジュール構成・インターフェース・データフローを持つ docs/dev/<対象>/basic-design.md を作成・改訂するスキル。/basic-design <対象名> で明示的に呼び出されたときのみ使用する。
技術的な内容を、技術用語を排したビジネス職向けの平易な説明文に翻訳する。`/biz-translate` と明示的に呼ばれたときのみ実行する。
`git commit` / `git commit --amend` を実行する前、または「commit」「amend」「コミット」「コミットして」の一語・短文だけを渡された時点で必ず発火する git コミット実施ルール。理由や差分の説明が一切無くても、ファイル全文を読んでメッセージを組み立てる前に先に参照する。主目的は論理的に独立した修正を都度・適切な粒度でコミットすること。メッセージは Conventional Commits 形式、素材は同梱の決定論スクリプト commit-context.sh が出す staged diff のみ。「コミット分けて」と依頼される、独立した複数修正をまとめるか分けるか判断する、レビューコメント対応をコミットする、rebase / squash / cherry-pick 後のメッセージを整える、`gh pr create` の PR タイトルをコミット流儀へ揃える場面でも参照する。plan モードでのコミット計画の立案は commit-plan スキルの領分。
実装計画・リファクタリング計画・レビュー対応計画・並列作業のタスク分解など、計画を成果物として書き出すときに必ず参照するコミット計画ルール。plan モードでは ExitPlanMode で plan を提示する前に必須、計画ドキュメントや job-graph のタスク分解・エージェントへの指示文でも同様に適用する。計画成果物にコミット計画セクション(論理的に独立した修正単位での分割と Conventional Commits 形式のメッセージ)が無ければ実装に入らない。「実装計画を立てて」「planを立てて」「実行計画を作って」「リファクタリング計画を立てて」「コミット計画を立てて」「タスクを分解して」と依頼される、複数の独立した修正をまとめるか分けるか計画段階で判断する等の場面では、ユーザーが「コミット」に一切言及していなくても必ず発火する。コミットの実施(素材収集・メッセージ確定・git commit 実行)は commit-flow スキルが担う。
プロジェクトに 1 つの「完成の定義」docs/dev/definition-of-done.md を対話で構築・改訂し、機械判定節と人判定節の二部構成で書き出すスキル。/def-done で明示的に呼び出されたときのみ使用する。