Skip to content
Back to skills

Verify Bootstrap

ASecurity

repo に機械ゲート(format / lint / type check / security / dependency audit / test)を立てる、または既存のゲートが古びていないか棚卸しする。Use when starting a new project, when a repo has no automated quality gate, when the user says 「lint を入れて」「この repo にゲートを立てて」「型チェックを入れたい」「静的解析を整備して」「ツールが古い」「verify を棚卸しして」, \"set up linting\", \"add a quality gate\", \"bootstrap the toolchain\", or invokes /verify-bootstrap. ツール表を持たない設計なので、未知のスタックでも同じ手順で使える。NOT for — 既に立っているゲートを 1 回実行するだけ(それは repo の verify entrypoint を直接実行)、コードの意味的レビュー(→ imp...

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 4, 2026
ai-agentspythongoswiftbashgitapisecurity

Works with

  • claude code
  • api

Security analysis

A100/100

Scanned October 7, 2026

npx -y skills add shimo4228/claude-harness --skill verify-bootstrap --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Verify Bootstrap?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Verify Bootstrap
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/shimo4228-verify-bootstrap/badge)](https://www.skillsdirectory.com/skills/shimo4228-verify-bootstrap)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: verify-bootstrap
description: "repo に機械ゲート(format / lint / type check / security / dependency audit / test)を立てる、または既存のゲートが古びていないか棚卸しする。Use when starting a new project, when a repo has no automated quality gate, when the user says 「lint を入れて」「この repo にゲートを立てて」「型チェックを入れたい」「静的解析を整備して」「ツールが古い」「verify を棚卸しして」, \"set up linting\", \"add a quality gate\", \"bootstrap the toolchain\", or invokes /verify-bootstrap. ツール表を持たない設計なので、未知のスタックでも同じ手順で使える。NOT for — 既に立っているゲートを 1 回実行するだけ(それは repo の verify entrypoint を直接実行)、コードの意味的レビュー(→ implementation-chain の Review 群)。"
compatibility: Developed and tested on Claude Code; portable to other Agent Skills-compatible agents.
license: MIT
metadata:
  author: shimo4228
  version: "1.0"
user-invocable: true
origin: shimo4228
---

# verify-bootstrap — repo に機械ゲートを立てる

人間がコードを読む速度は、AI が書く速度に追いつかない。だから構造的な正しさの判定は
**機械に移す**。この skill は repo ごとに、
その時点で最良の検査ツールを立てる。

## この skill が持たないもの(設計上の中核)

**ツール名の一覧を持たない。言語の検出テーブルも持たない。** ツールは陳腐化する
(flake8 + black + isort → ruff は 2 年で起きた)。固定表を持てば表が腐り、
腐った表が repo に配られる。

持つのは **調べ方と契約**だけ:

- repo の実態を列挙する手順(静的な言語リストを参照しない)
- category ごとに何を search-first に問うか
- 生成物 `.claude/verify.sh` の契約(global hook がこれだけを知る)
- strictness と陳腐化検知の規律

結果として、この skill が書かれた時点で存在しなかった言語・ツールでも同じ手順で回る。

## モード

| モード | 起動条件 | やること |
|---|---|---|
| **bootstrap** | `.claude/verify.sh` が無い | Step 1–6 を通す |
| **audit** | 既にある(`--audit` / 「棚卸し」) | Step 1 を再実行し、`.claude/verify.md` の選定を search-first で引き直して差分を提案 |

## Step 1 — repo の実態を列挙する(検出、静的表なし)

推測しない。**実測する**。

```bash
# 追跡ファイルの拡張子分布(上位)— 生成物・依存ディレクトリは除く
git ls-files | sed -n 's/.*\.\([A-Za-z0-9_]*\)$/\1/p' | sort | uniq -c | sort -rn | head -20
# ビルド/依存マニフェストの実在
git ls-files | grep -iE '(^|/)(pyproject\.toml|package\.json|Cargo\.toml|go\.mod|Gemfile|pom\.xml|build\.gradle.*|[^/]*\.xcodeproj/.*|Package\.swift|mix\.exs|composer\.json|Makefile|justfile)$'
# 既存のゲート痕跡(重複導入の防止)
git ls-files | grep -iE '(pre-commit-config|lefthook|\.github/workflows/|trunk\.yaml|\.golangci|\.eslintrc|ruff\.toml)'
```

上のマニフェスト grep は**発見の補助であって権威ではない**。1 本目の拡張子分布が正本で、
grep に載っていない生態系が出てきたらそれを Step 2 にそのまま渡す(表を編集して
この skill に足さない — 表を持たないことがこの skill の設計)。

散文・設定・スキーマも対象に含める。コードだけがゲートの対象ではない
(Markdown の日本語 prose、YAML、CI 定義、シェルスクリプトはいずれも機械検査できる)。

## Step 2 — category ごとに現時点の最適ツールを調べる

検出した生態系ごとに、**6 category** を埋める。埋まらない category は「無い」と明記する
(空欄と「その言語には該当がない」は別物)。

| category | 問い |
|---|---|
| **format** | 整形の正規化。差分ノイズを消し、レビュー対象を意味の変化だけにする |
| **lint** | 構造的な誤り・複雑度・デッドコード |
| **type check** | 型で表現できる契約。型なし言語なら「型注釈を段階導入する手段があるか」 |
| **security** | 危険な構文・秘密の混入(秘密スキャンは harness 側にもあるので重複を確認) |
| **dependency** | 既知脆弱性・未使用依存・ライセンス |
| **test** | テストランナーとカバレッジ測定 |

**予算系 rule(閾値を要する複雑度・関数/ファイル長・bundle サイズ等)は既定に頼らない。**
主要 linter は予算系を既定 OFF で出荷するのが通例(閾値が opinionated なため)—
「最大 strict」の運用では構造的に素通りする(2026-08-28 実測でカバー 0 を確認 —
数値の正本は ADR-0056)。lint category を埋めるとき明示的に問う。stack の標準 toolchain が
既定で予算を持つ場合(例: SwiftLint の cyclomatic_complexity / file_length)は追認して
verify.md に 1 行記録するだけでよい。閾値は global に定めない — repo 間で分布は数倍
割れる(同実測、正本は ADR-0056)。
既存 corpus 全件の分布を実測してから、現状の外れ値だけが赤くなる位置に置く
(skill `review-to-lint` の免除境界の原則。ゲートを初日に赤くする閾値は設計ミス)。

**lint / type check の選定方針は LLM-first**(読者・編集者とも LLM で、人間はコードを
読まない前提。実例と根拠は `~/.claude/.claude/verify.md` の「lint の LLM-first 棚卸しと ANN 導入」節)。言語を問わず同じ 4 軸で select を組む:

1. **バグクラス検出**(未定義名・未使用・既知の危険パターン・型矛盾)— 無相関の
   検証者の中核。最優先
2. **正準形**(formatter・import 順)— 目のためでなく diff 安定のため。別セッションが
   触っても偽 diff が出ない = golden・review が静かに保てる
3. **予算**(複雑度・ファイル長)— context 制限つきの次の編集者のための編集信頼性予算
   (閾値は上の分布実測で)
4. **境界の明示型強制** — 型は機械検証可能な仕様で、再生成・別セッション編集の凍結端。
   production 側のみ(テスト関数は消費される境界ではないので除外)。
   Python での実装例: ANN001-003 + ANN201 + ANN401、`tests/**` 除外

**人間美学系(docstring 様式・命名規約・コメント整形)は select しない。** 削る対象では
なく、最初から入れない。「人間が読みにくい」だけを理由とする rule には LLM-first の
正当化が立たない。

各 category について **`search-first` skill を呼ぶ**(WebSearch を直接叩かない —
依存追加・自作 utility の前は search-first、が `rules/common/planning.md` の配線)。問いには必ず
「**今日の日付時点で**」の時点指定と「既存の代替から乗り換えが起きていないか」を含める。
記憶している定番を答えにしない — この skill が防ごうとしているのはまさにそれ。

報告を受けたら、次を確認してから採用する:

- **最終リリースが 12 ヶ月以内か**(放置プロジェクトを新規 repo に入れない)
- **単一バイナリ / on-demand 実行が可能か**(`uvx` / `npx` / `brew` 等。repo の
  実行環境を汚さずに走るか)
- **設定を持ち込めるか**(strictness を宣言でき、例外を許可リスト化できるか)
- **CI とローカルで同じものが走るか**(乖離するとローカルが形骸化する)

## Step 3 — 最大 strict で導入する

**既定は最大 strict**。AI は厳しさに文句を言わないので、従来「人間の忍耐」を理由に
緩められていた分の天秤は正しさ側に倒す。

- 警告を warning のまま放置しない — **error にする**
- 型の抜け穴(`any` 相当・型チェック抑制コメント)を **禁止側に倒す**
- 版を **pin する**(`ruff==0.16.0` のように。supply chain の固定。bump は手動)
- 例外は**インラインの抑制コメントでなく、設定ファイルの許可リストで理由付き**に
  (インライン抑制は理由が消えて無限増殖する)
- repo 固有の例外が要るときは、**まずスタックを標準に寄せる** — 寄せた上で残る分だけ
  理由付きで許可リストへ(「この repo だけ独自」は設計不足のサイン)

**新規 repo は初日から最大 strict**(drain すべき負債がゼロなので ratchet 不要)。
**既存 repo への後付けだけ ratchet を使う** — 全 rule を warn で入れ、既存違反を
drain し切ってから error に上げる。初日から block にすると「回避の作法」が育つ。

予算系 rule の閾値も同じく**一方向** — 超過したら閾値を上げるのではなく**刈る**
(dead code・重複の除去、分割)。閾値の設定行に「上げずに刈る — 変更は verify.md に
日付つき理由」のコメントを付ける。ゲートが赤くなった瞬間に config を触る agent の
目に入る位置が、この運用規約の配達点である。

## Step 4 — `.claude/verify.sh` を生成する(global hook との契約)

repo が持つ **唯一の入口**。ハーネス側の hook はこのファイルの存在と exit code しか
見ない — だから repo が何語で書かれていても hook を変更せずに済む。

**契約(厳守)**:

| 項目 | 仕様 |
|---|---|
| パス | `<repo root>/.claude/verify.sh`(実行可能) |
| 引数 | `--staged` = commit 境界の高速検査(staged ファイルのみ)。引数なし = repo 全体の完全検査 |
| 環境 | `$VERIFY_REPO_ROOT` があれば repo root として使う(承認機構が渡す) |
| exit code | `0` = PASS / `1` = FAIL(commit を止める)/ `2` = 検査不能(ツール不在等、fail-soft) |
| 出力 | FAIL 時は**人間と LLM が読んで直せる検出行**。PASS 時の出力は **advisory**(commit は止めないが伝えたいこと — 昇格待ちの ratchet、眠っているゲートの通知)として `verify-precommit.sh` が model へ渡す。言うことが無ければ**無出力**(無言 PASS にノイズを足さない)。**stdout と stderr は区別されない** — hook は `2>&1` でまとめて受けるので、成功時に stderr へ出る進捗・非推奨警告も advisory になる。黙っていたいものは黙らせる |
| 実行時間 | `--staged` は**数秒以内**。超えるものは無引数側にだけ置く |

**速い / 遅いの分離**(これを守らないと bypass の作法が育つ):

- `--staged`: format check・lint・security scan(ファイル単位で完結するもの)
- 無引数: build・type check・test・dependency audit(repo 全体・分単位)

ツール解決は `PATH にあれば使う → 無ければ on-demand 実行(uvx / npx 等)→ それも
無ければ exit 2 で fail-soft`。**fail-soft でも無音にしない** — どのゲートが眠って
いるかを stdout に出す(眠っているゲートは、無いゲートより危険)。

**実装上の罠(どちらも実測で踏んだもの)**:

- **repo root は `$VERIFY_REPO_ROOT` → 自分自身の位置、の順で決める** — cwd 起点にすると
  hook 経由で**別 repo を検査して無言で PASS する fail-open** になる。承認機構は照合済み
  バイト列を一時ファイルに置いて実行する(TOCTOU 回避)ので `BASH_SOURCE` が repo を
  指さない場合がある。両対応が必須:

  ```bash
  if [[ -n "${VERIFY_REPO_ROOT:-}" ]]; then
    ROOT="$VERIFY_REPO_ROOT"
  else
    ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P) || exit 2
  fi
  ```
- **追跡されているか確認する** — `.gitignore` が `.claude/*` を除外している repo は多い。
  除外されたままだと CI と他クローンからゲートが消える。`git check-ignore` で確認し、
  必要なら `!.claude/verify.sh` / `!.claude/verify.md` を足す

**生成しただけでは commit 境界で走らない** — hook は permission プロンプトを経ずに実行するため、
「ファイルがある」を「実行してよい」と読み替えない設計になっている(clone しただけの外部 repo で
コードが自動実行される経路を塞ぐ)。**人間が内容を読んで承認**して初めて実行される:

```
python3 ~/.claude/scripts/hooks/verify_allow.py approve <repo>
```

承認は内容ハッシュに紐づくので、`verify.sh` を編集したら `verify_allow.py` の台帳を更新する前に
新しい本文を確認する。これは permission prompt を経ない repo-local code 実行の信頼境界である。

生成した `verify.sh` は**その場で 1 回実行して動作を確認する**。さらに
**違反を一時注入して category ごとに発火を実証する**(format 崩し・未使用 import・
`eval` 等)。PASS するだけの確認は、ゲートが眠っていても PASS するので証拠にならない。
実証が済んだら注入した probe を必ず削除する。

## Step 5 — 選定を記録する(陳腐化を可視化する)

`<repo root>/.claude/verify.md` に、category ごとに次を残す:

```
## type check
tool: pyright ==1.1.x
選定日: 2026-07-31
理由: mypy より速く既定が strict。ty / pyrefly は 2026-07 時点で pre-1.0
再調査トリガー: 12 ヶ月経過 / 代替が 1.0 到達 / 現行ツールの最終リリースが 12 ヶ月以上前
```

この記録が無いと audit モードが「何を引き直すべきか」を判断できない。
**選定日と再調査トリガーは必須**、理由は 1 行でよい。予算系 rule は**閾値と実測分布の
as-of** も記録する(例: `C901=15 — p99=14、2026-08-28 実測`。audit 時に分布の再実測と
突き合わせる基点になる)。

## Step 6 — CI に同じものを配線する

ローカルゲートだけでは、bypass された commit が素通りする。CI が `.claude/verify.sh`
を無引数で実行する job を持てば、ローカルと CI の乖離が構造的に起きない
(**同じ入口を両方から呼ぶ**。CI 用に別のコマンド列を書くと必ず drift する)。
build 役が cloud session で走る repo では、CI が verify の唯一の判定者になる — 判断役は
ローカルで再実行せず、branch tip に対する run の結論を読む(ADR-0075)。CI を持たない repo は
cloud に出せないので、github.com に remote がある repo ではこの Step を bootstrap に含める。

雛形は `references/ci-verify.yml`。固定するもの: `main` と `claude/**` への push で発火 /
actions は commit SHA で pin(tag から `gh api repos/<o>/<r>/git/ref/tags/<tag>` で引く)/
`permissions: contents: read` / `persist-credentials: false` / 履歴全体の secret scan job
(ローカル hook `secret-scan-precommit.sh` は staged 追加分しか見ない)。埋めるもの: verify.sh が
PATH から解決するツールの導入(`.claude/verify.md` の選定記録が正本)と言語 setup。
Linux runner で落ちるテスト(macOS 専用の launchd / BSD `stat`)は `skipif` で自己申告させ、
production 側の platform ガードでテストが `SystemExit` になる形は直す — 「CI で赤 = ローカルでも
赤」を保つため。

## audit モード

1. Step 1 を再実行(stack が変わっていないか — 言語が増えていれば category が空く)
2. `.claude/verify.md` の各 category について、**再調査トリガーに該当するものだけ**
   search-first で引き直す(全件引き直すと毎回コストが出る)
3. 差分を提示: 現行 → 候補、乗り換えコスト、据え置きの理由
4. 判断はユーザー。**自動で乗り換えない** — ツール変更は repo 全体の diff を生み、
   元に戻すコストが導入コストを上回る

## 関連

- Phase 0 のエントリポイント: skill `search-first`(ツール選定は必ずここを通す)
- ゲートを含む実装フロー全体: skill `implementation-chain`

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.