Skip to content
frontmatter
キー値
specdojo.idprj-0001:pjr-6hf3-hook-script-dependency-free-entry
specdojo.typeproject
specdojo.statusready
specdojo.rulebookspecdojo:pjr-rulebook
specdojo.part_ofprj-0001:pjr-index
specdojo.item_typeissue
specdojo.item_statusdone
specdojo.priorityhigh
specdojo.ownerARC
specdojo.registered_at2026-08-22T23:09:24Z
specdojo.due_on2026-08-31
specdojo.completed_at2026-08-22T23:52:46Z
specdojo.conclusionhook から起動する入口を Node 標準だけで動く tools/build-if-stale.mjs へ置き換えた。linked worktree と依存未インストールを委譲より前に判定するため、node_modules の無い新規 worktree でも hook が失敗しない。tsx の CLI は package.json の bin から解決し、PATH やパッケージ内部のレイアウトに依存しない。

PJR-6HF3 git hook から呼ぶスクリプトが devDependency に依存し、新規 worktree で失敗する ​

1. 課題内容 ​

post-checkout hook が npm run build:if-stale を実行し、その実体は tsx src/build-if-stale.ts である。exec run --worktree が新規 worktree を作る時点では node_modules が無く、tsx を解決できずに hook が非ゼロ終了する。その結果 git worktree add が失敗し、checkpoint failed として claim がロールバックされる。build-if-stale.ts には linked worktree なら何もしない判定を入れてあるが、その判定へ到達する前に起動が失敗しており、ガードが自分の前提条件に依存する構造になっている。routine 経由の自動実行が claim と release を繰り返す状態になっている。

2. 影響範囲 ​

観点影響
スコープworktree を新規作成する全タスク。exec run --worktree と routine 経由の exec cycle が該当する
スケジュール自動実行が claim と release を繰り返し、Ready タスクが進まない。実質的に自動実行が停止している
コスト追加の外部コストはなく、影響は復旧と再実行に要する作業時間
品質データ破損は起きない。ロールバックは正しく動作し、claim も解放されている
関係者ARC(実装)。自動実行を利用する運用者

3. 対応方針 ​

項目内容
原因hook から呼ぶ入口が tsx に依存している。新規 worktree では node_modules が無く、TypeScript のガード(linked worktree なら何もしない)へ到達する前に起動が失敗する
対応策Node 標準だけで動く plain JS の入口(tools/build-if-stale.mjs など)を追加し、linked worktree と依存未インストールを判定して即終了する。条件を満たす場合のみ既存の判定処理へ委譲する。prepare の node tools/install-lefthook.mjs と同じ方式に揃える
依存事項なし。npx tsx へ切り替える案は、依存が無い環境ではレジストリ取得を試みるため採らない
完了条件新規 worktree の作成で hook が失敗しないこと。primary worktree でのブランチ切り替えでは従来どおり再ビルド判定が働くこと

4. 対応結果 ​

  • Node 標準機能だけで起動する tools/build-if-stale.mjs を追加した。.git がファイルになる linked worktree では node_modules を確認する前に終了コード 0 で終了する。
  • primary worktree ではローカルの tsx が存在する場合だけ src/build-if-stale.ts へ委譲し、従来の鮮度判定と再ビルドを維持した。依存未インストール時や委譲失敗時も、best-effort の hook を止めず終了コード 0 とする。
  • lefthook.yml の post-merge / post-checkout と package.json の build:if-stale を、依存不要な入口を node で直接実行する形へ変更した。
  • 回帰テスト tests/tools/build-if-stale.test.ts を追加し、linked worktree、依存未インストールの primary worktree、既存実装への委譲、委譲失敗の各経路を確認した。

検討時に却下した案を記録する。

  • npx tsx へ切り替える: 新規 worktree では親ディレクトリを遡っても node_modules が無く、npx はレジストリ取得を試みる。ネットワークの無い実行環境では失敗し、ある環境でも worktree 作成のたびに取得が走る。
  • post-checkout から外して post-merge だけにする: worktree 作成での失敗は消えるが、primary worktree でのブランチ切り替え後に dist が古いままになり、当初の目的を一部失う。

5. 関連ドキュメント ​