制約駆動開発 は何をしますか?
概要
このパックの他のスキルは、良い状態がどのようなものかを説明します。code-review-and-quality は5つの軸を提供し、test-driven-development はサイクルを提供し、security-and-hardening は脅威リストを提供します。これらはすべてエージェントが読む散文の中に存在し、エージェントが従うかどうかは定かではなく、セッションの終了後には残りません。
このスキルは異なるものを生成します。それは、このプロジェクトの基準を数値で文書化したものであり、会話を超えて存続し、機械的にチェックできるものです。
その理由は重要です。コードを書いたとき、それを読めば良し悪しがわかりました。エージェントはあなたがその週に読むよりも多くのコードを午後一で書くため、判断はあなたの頭の中から、ループ内で実行されるチェックへと移ります。それらのチェックは存在し、実際に選択した数値を持ち、エージェントが自身の出力を修正できる十分に作業に近いタイミングで発動する必要があります。
仕様駆動開発は何を構築するかを定義します。テスト駆動開発はそれが機能することを証明します。制約駆動開発は、プルリクエストで誰かが議論を始める前に、「出荷に十分な品質」が何を意味するかを定義します。
使用すべきタイミング
以下の場合にこのスキルを適用してください:
- プロジェクトまたは重要な機能を開始する際、品質基準が文書化されていない場合
- ユーザーが「制約を設定する」「品質ゲートを追加する」「基準を定義する」「エージェントが粗悪なものを出荷するのを止める」と依頼した場合
- エージェントが誰も一読しないような量のコードを生成している場合
- CI にチェックはあるが、どれがマージをブロックし、どれが飾りかを誰も言えない場合
- カバレッジ、パフォーマンス、アクセシビリティの数値が、一度決められるのではなく、PR ごとに議論される場合
/build autoや自律的なループを実行しようとしており、それがメインに到達するのを防ぐ唯一のものが、エージェント自身が書いたテストスイートである場合
使用すべきでない場合:
- プロジェクトにすでに
CONSTRAINTS.mdがあり、ユーザーがそれを変更していない場合 — 代わりにそれを読んで従ってください - 一回限りのスクリプト、スパイク、捨てるプロトタイプ
- ユーザーが今すぐコードレビュー(
code-review-and-quality)または CI パイプラインの構築(ci-cd-and-automation)を必要としている場合 - 期待寿命が2週間のプロダクトマーケットフィット前のコード — 以下のフロアはそれでも価値がありますが、残りはそうではありません
制約の読み込み
インタビューにはライブユーザーが必要です。非対話型コンテキスト(CI、/loop、自律実行)では実行しないでください。 制約が欠落しており、そのような状況にある場合は、以下のフロアを適用し、その旨を記録し、残りは人間にフラグを立ててください。
プロセス
ステップ 1: 質問する前に検出する
読めることを質問してはいけません。最初の質問の前に、以下を収集してください:
| 項目 | 確認場所 |
|---|---|
| 言語とスタック | package.json、pyproject.toml、go.mod、Cargo.toml |
| テストランナー | dev 依存関係、test スクリプト、既存のテストファイル |
| 既存のリンター | eslint.config.*、biome.json、.ruff.toml |
| 現在のカバレッジ | coverage/ の出力、またはスイートを一度実行 |
| CI | .github/workflows/、.gitlab-ci.yml |
| エージェントハーネス | .claude/、.codex/、AGENTS.md |
見つけたものを2行で報告し、残ったものだけを質問してください。
ステップ 2: 4つの質問、それぞれにデフォルト値あり
interview-me からの「一度に一つの質問」という規律に従いますが、一つの変更点があります:ここのすべての質問にはデフォルト値があるため、「わかりません」という回答でも、機能する設定を生成できます。
Q1: フロアに加えて、これらのうちどれを強制したいですか?
(a) 新しいコードのテストカバレッジ
(b) セキュリティスキャン
(c) パフォーマンス予算
(d) アクセシビリティ
(e) アーキテクチャ境界
推測: (a) と (b) — すでにテストランナーがあり、ユーザー入力を処理しています。
不明な場合のデフォルト: (a) と (b)。
各選択のコストを伝える: (c) と (d) には実行中の URL が必要、(e) にはルールファイルの作成が必要。
Q2: エージェントがタスク中にチェックが失敗した場合、ブロックすべきか、警告すべきか?
推測: ブロック。無人でエージェントを実行しており、誰も読まない警告は警告として機能しません。
不明な場合のデフォルト: フロアではブロック、最初の2週間はそれ以外は警告。
Q3: 目標とする数値はありますか、それとも現在の状態を測定してそのラインを維持すべきですか?
推測: 測定。ほとんどのチームには数値がなく、でっち上げた数値は無視されます。
不明な場合のデフォルト: 測定して維持。以下の「ラチェット」を参照。
Q4: エージェントが作業を返す前に許容できる最も遅いチェックは?
推測: 約90秒。それ以上だと実行を停止します。
不明な場合のデフォルト: タスク終了時は90秒、CI では制限なし。
4つで止めてください。12の質問からなる intake は、誰も理解できない設定と、始めたことを後悔するユーザーを生み出します。
ステップ 3: CONSTRAINTS.md を書く
リポジトリルートに1つのファイル。どのハーネスのエージェントでも読むことができ、その変更はそれが属するレビューに表示されます。
# 制約
最終レビュー日: 2026-08-08 by @addy
## フロア(常に強制、セットアップ不要)
- 新しい抑制コメントなし: `@ts-ignore`、`eslint-disable`、`# noqa`、`# type: ignore`
- 未実装スタブなし: `throw new Error("Not implemented")`、空の `catch {}`
- コミットメッセージに理由がない限り、テストのスキップや削除なし
- ソース内にシークレットなし
- 変更を通すためにこのファイルを弱めてはいけない
## 数値で強制
| 次元 | ルール | チェックツール | 実行タイミング |
|------|--------|--------------|--------------|
| 型 | 型エラーゼロ | `tsc --noEmit` | 編集ごと |
| リント | 設定からのエラーゼロ | `biome check` | 編集ごと |
| シークレット | ソース内にシークレットなし | `gitleaks detect --redact` | 編集ごと |
| カバレッジ | 変更行 ≥ 80% カバレッジ | `vitest run --coverage` + git diff | タスク終了、CI |
| セキュリティ: コード | 高重要度の検出なし | `semgrep scan --config p/default` | CI |
| セキュリティ: 依存関係 | 高以上なし | `osv-scanner scan source -r .` | CI |
| アクセシビリティ | 重大または深刻ゼロ | `axe $PREVIEW_URL --tags wcag2a,wcag2aa,wcag21aa` | プレビューデプロイ |
| パフォーマンス | LCP ≤ 2500ms、CLS ≤ 0.1 | `lighthouse $PREVIEW_URL --output=json` | プレビューデプロイ |
すべての行は、結果を生成するコマンドを指定します。数値があり、この列にコマンドがない次元は、制約ではなく願望です。
## 測定中、まだ強制はしていない
| メトリクス | 現在 | 方向性 |
|-----------|------|--------|
| プロジェクトカバレッジ | 62.4% | 低下させてはいけない |
| バンドルサイズ (main) | 184 kB | 増加させてはいけない |
## 例外
| ID | ルール | パス | 理由 | 所有者 | 有効期限 |
|----|--------|------|------|-------|---------|
| W1 | `no-explicit-any` | `src/legacy/**` | ENG-441 で追跡中の書き換え | @addy | 2026-11-01 |
次に、AGENTS.md と CLAUDE.md に一行追加します: コードを書く前に CONSTRAINTS.md を読んでください。変更を通すためにこれを弱めないでください。
ステップ 4: 各次元に必要なものをインストールする
次元を選択するということは、何かをインストールすることを意味します。数値だけを残してメカニズムを残さないようにしたり、デファクトのチェッカーが存在するのに自分で発明したりしないでください — これらのツールがリストされているのは、そのルール形式としきい値がエコシステム内の他のすべてのターゲットであり、チームの既存の設定が機能し続けるからです。
| 次元 | ツール | インストール | 実行 | ゲート条件 |
|---|---|---|---|---|
| 型 (TypeScript) | tsc | すでに存在 | tsc --noEmit | 任意のエラー |
| 型 (Python) | mypy | pip install mypy | mypy . | 任意のエラー |
| リント | 既存の設定 | すでに存在 | eslint . / biome check / ruff check | 任意のエラー |
| カバレッジ (JS) | テストランナー | すでに存在 | vitest run --coverage (または jest --coverage) | 変更行のカバレッジ |
| カバレッジ (Python) | pytest-cov | pip install pytest-cov | pytest --cov --cov-report=lcov | 同じ |
| セキュリティ: コード | Semgrep | pipx install semgrep | semgrep scan --config p/default --config p/owasp-top-ten | 任意の高重要度の検出 |
| セキュリティ: シークレット | gitleaks | brew install gitleaks | gitleaks detect --redact --no-banner | 任意の検出 |
| セキュリティ: 依存関係 | osv-scanner | brew install osv-scanner | osv-scanner scan source -r . | 高以上 |
| パフォーマンス: ページ | Lighthouse | npm i -D lighthouse | lighthouse $URL --output=json --quiet | LCP、CLS、パフォーマンススコア |
| パフォーマンス: バンドル | size-limit | npm i -D size-limit | size-limit --json | エントリごとのバイト予算 |
| アクセシビリティ | axe-core | npm i -D @axe-core/cli | axe $URL --tags wcag2a,wcag2aa,wcag21aa | 重大または深刻ゼロ |
| アーキテクチャ | dependency-cruiser | npm i -D dependency-cruiser | depcruise --validate src | 任意の違反 |
| アサーション品質 | Stryker | npm i -D @stryker-mutator/core | stryker run --mutate <変更ファイル> | 突然変異スコア |
スキップすると問題が発生する5つのこと:
- gitleaks の
--redactは省略できません。 これがないと、一致したシークレットがエージェントのトランスクリプトに記録され、漏洩したキーがログ、サマリー、またはコミットメッセージに残る原因になります。ルールと場所を報告し、値は決して報告しないでください。 - Lighthouse と axe には URL が必要です。 これらは実行中のアプリに対してのみ機能するため、プレビューデプロイまたは最初に起動するローカルサーバーに対して、ランタイムステージに属します。プロジェクトにアクセスする URL がない場合(CLI、ライブラリ、デスクトップアプリ)、その旨を伝え、実行できないチェックを発明する代わりに、その次元を削除してください。
- 高コストのチェックは差分にスコープしてください。 リポジトリ全体に対する
stryker run --mutateは何時間もかかり、無効にされます。変更が触れたファイルに対しては1分未満です。Semgrep も同様で、パスリストを受け取ります。 - カバレッジに2回目のテスト実行は不要です。 スイートがすでに書き出している lcov を読み、
git diffと交差させてください。数値を得るためにスイートを2回実行するのは、人々にこれを嫌わせる最も早い方法です。 - Semgrep のレジストリルールは無料で実行できますが、再配布する前にライセンスを確認してください。 法律チームにとって重要な場合は、
opengrepは同じルール形式と JSON 出力を持つドロップインのフォークです。
それぞれをプロジェクトの独自のスクリプトに追加して、エージェントなしでも再現可能にします:
{
"scripts": {
"check:fast": "tsc --noEmit && eslint . && gitleaks detect --redact --no-banner",
"check:task": "npm run check:fast && vitest run --coverage",
"check:full": "npm run check:task && semgrep scan --config p/default && osv-scanner scan source -r ."
}
}
このマッピングはツール自体よりも重要です。check:fast は編集後に実行され、check:task はエージェントが完了したと判断したときに実行され、check:full は CI で実行されます。
コマンドは現在、CONSTRAINTS.md の Checked by 列とこれらのスクリプトの2か所に存在します。CONSTRAINTS.md が正規のソースです:各コマンドとともに理由を伝え、レビューに表示されます。スクリプトはそれをミラーリングする便利なラッパーであり、第二の正規のソースではありません。ずれた場合は、ファイルが優先されます。
ステップ 5: ライフサイクルに配線する
最も大きな間違いは、すべてをあらゆる場所で実行することです。エージェントを停止させるチェックはオフにされ、オフにされたゲートはゲートがないよりも悪いです。なぜなら、基準はまだ存在しているように見えるからです。
| フェーズ | コマンド | 実行内容 | 予算 |
|---|---|---|---|
| BUILD | /build | 型、リント、シークレット、フロア | 5秒未満、変更ファイルのみ |
| VERIFY | /test | 関連テスト、変更行のカバレッジ | 90秒未満 |
| REVIEW | /review | すべて、および以下のガード | 数分 |
| SHIP | /ship | 方向性チェック、後退なし | CI |
これを許容可能に保つ2つのルール:
- 差分にスコープする。 この変更が触れた行をチェックし、リポジトリ全体ではありません。変更行のカバレッジはエージェントが動かせる数値ですが、プロジェクトカバレッジは継承したものです。
- コストが配置を決定する。 数秒を超えるものは編集ループから移動します。リポジトリ全体に対する突然変異テストは何時間もかかりますが、変更が触れたファイルに対しては1分未満であり、これが人々が実行するチェックとそうでないチェックの違いです。
ステップ 6: 基準自体を保護する
誰かが指摘するでしょう:エージェントがコードとチェックの両方を書くなら、チェックは何も証明しない、と。半分は正しいが、それを回避するためにエンジニアリングする価値があります。
エージェントは巧妙な抜け穴を作り出しません。赤いチェックに遭遇し、緑にするための最も安い道を取ります。レビュー時に、差分でこれらの5つの動きに注意してください:
- しきい値が変更された。 予算が引き下げられ、重大度が下げられ、チェックが高速ステージから削除された。
CONSTRAINTS.mdをブランチポイントでの状態と比較してください。 - テストが簡単になった。
.skipが追加された、テストファイルが削除された、残ったテストからアサーションが除去された。 - チェッカーが無効化された。 新しい
@ts-ignoreまたはeslint-disable。4つの抑制は特に注意が必要です。これらは依存しているチェックをオフにするからです:istanbul ignoreはコードをテストせずにカバレッジから除外し、Stryker disableは生存突然変異体を隠し、nosemgrepとgitleaks:allowはセキュリティ検出に対して同様のことを行います。 - 作業が未完了。 例外をスローするスタブ、失敗を沈黙に変える空の
catch、実装があるべき場所に立つTODO。 - 例外が現れた。 誰も議論していない例外テーブルの新しい行。
これには git diff 以上のツールは必要ありません。基準を厳しくすることは静かに行われるべきであり、緩めることは目立つべきです。
番号付きの次元とは異なり、フロアには独自のデファクトツールがないため、それを強制するように依頼されたエージェントは、スクラッチからチェッカーを書く傾向があり、2つのエージェントが2つの異なるものを作成します。これらの5つのチェックのリファレンス実装は、このスキルとともに references/floor-guard.md に同梱されています(差分スコープ、終了コード 0/1/2、エコシステムごとに適応可能なパターン)。それを再発明するのではなく、適応させてください。すべての次元がデファクトツールを指定するのと同じ理由です:メカニズムが実行とスタック間で同じになるように。
すべてのチェックが同様に循環的であるとは限りません。 一つの質問でランク付けしてください:エージェントは機能しないコードを書くことでこのチェックをパスできますか?
- 外部 — axe-core は WCAG をエンコードし、
osv-scannerは脆弱性データベースを読み、Lighthouse は実際のブラウザを測定します。エージェントはこれらに異議を唱えることはできません。 - プロジェクト — あなたのリントルール、あなたのレイヤー境界。人間がファイルを所有しています。
- スイート — あなた自身のテスト。最も有用で、唯一真に循環的なものです。
基準は…
[翻訳のために切り詰められました]