mcpField
C
constraint-driven-development

constraint-driven-development

github.com/addyosmaniテスト・品質111.5k35.2k 回インストール2 週間前に更新
リポジトリ

constraint-driven-development について

エージェントを使って開発するチーム向けに、品質基準を記録し機械的に検査できる制約へ落とし込むスキルです。基準の決定、開発段階へのチェック導入、基準を弱める変更の確認を支援します。

主な機能

  1. 01既存のプロジェクトチェックを調査
  2. 02対話による品質基準の設定
  3. 03CONSTRAINTS.md の作成
  4. 04品質項目ごとのチェック設定
  5. 05開発段階に応じたチェック配置
  6. 06制約の弱体化や回避をレビュー

活用シーン

  1. 01新規プロジェクトの品質ゲート設定
  2. 02自律コーディングループの出荷基準策定
  3. 03CI チェックのブロック条件と警告条件の明確化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/addyosmani/agent-skills --skill constraint-driven-development

インストール後、Claude Code で/constraint-driven-developmentを入力して読み込まれたか確認します。

同梱ファイルreferences/floor-guard.md

詳細

制約駆動開発

概要

このパックのほかのスキルでは、望ましい状態を説明します。code-review-and-quality では5つの評価軸を、test-driven-development ではサイクルを、security-and-hardening では脅威の一覧を示します。これらはすべて、エージェントが読んでも従うとは限らない文章として存在し、セッションが終われば何も残りません。

このスキルが作るのは、それとは違うものです。数値を含む、このプロジェクトの品質基準を記した記録であり、会話が終わっても残り、機械的にチェックできます。

その理由は重要です。コードを書いたときは、それを読めば出来のよしあしが分かりました。エージェントは、あなたが1週間で読む量より多くのコードを午後のうちに書くため、判断はあなたの頭の中から、開発サイクルの周囲で実行されるチェックへと移ります。そのチェックが存在し、実際にあなたが選んだ数値が設定されていて、エージェントが自分の出力を修正できるほど作業に近いタイミングで実行される必要があります。

仕様駆動開発は、何を作るかを示します。テスト駆動開発は、動作することを証明します。制約駆動開発は、プルリクエストで誰かが議論する前に、「出荷できる品質」の基準を定めます。

使用するタイミング

次のような場合に、このスキルを適用してください。

  • プロジェクトや重要な機能に着手する際、品質基準が文書化されていない
  • ユーザーが「制約を設定する」「品質ゲートを追加する」「標準を定義する」「エージェントが粗悪なものを出荷するのを止める」と依頼している
  • エージェントが大量のコードを生成し、誰も1行ずつ読んでいない
  • CI にチェックはあるが、マージをブロックするものと、形だけのものを説明できる人がいない
  • カバレッジ、パフォーマンス、アクセシビリティの数値について、一度決める代わりにプルリクエストごとに議論している
  • /build auto や自律的なループを実行しようとしていて、それを main から隔てているのがエージェント自身も書いたテストスイートだけである

使用しない場合:

  • プロジェクトにすでに CONSTRAINTS.md があり、ユーザーが変更しようとしていない場合 — その内容を読み、それに従ってください
  • 単発のスクリプト、試作、使い捨てのプロトタイプ
  • ユーザーが今すぐコードレビューを求めている(code-review-and-quality)、または CI パイプラインの構築を求めている(ci-cd-and-automation)
  • プロダクトマーケットフィット前のコードで、想定寿命が2週間の場合 — 以下の最低限の基準には価値がありますが、それ以上は不要です

制約の読み込み

ヒアリングには、対話中のユーザーが必要です。非対話型のコンテキスト(CI、/loop、自律実行)では実行しないでください。制約がなく、そのいずれかのコンテキストで作業している場合は、以下の最低限の基準を適用したことを記録し、残りは人間に確認するよう伝えてください。

プロセス

ステップ1:質問する前に検出する

読めば分かることを質問しないでください。最初の質問をする前に、次の項目を確認してください。

項目確認先
言語とスタックpackage.json、pyproject.toml、go.mod、Cargo.toml
テストランナー開発用依存関係、test スクリプト、既存のテストファイル
既存のリンターeslint.config.*、biome.json、.ruff.toml
現在のカバレッジcoverage/ の出力、またはテストスイートを1回実行
CI.github/workflows/、.gitlab-ci.yml
エージェントの実行環境.claude/、.codex/、AGENTS.md

見つかった内容を2行で報告してから、まだ分からないことだけを質問してください。

ステップ2:デフォルト値付きの4つの質問

interview-me の「一度に1つの質問」という方針に従ってください。ただし、ここでの質問にはすべてデフォルト値があります。そのため、「分かりません」と答えても、それだけで機能する設定を作成できます。

Q1: Beyond the floor, which of these do you want enforced?
    (a) Test coverage on new code
    (b) Security scanning
    (c) Performance budgets
    (d) Accessibility
    (e) Architecture boundaries
GUESS: (a) and (b) — you have a test runner already and you're handling user input.
DEFAULT if unsure: (a) and (b).
Say what each pick costs: (c) and (d) need a running URL, (e) needs a rules file written.
Q2: When a check fails while the agent is mid-task, should it block or warn?
GUESS: Block. You're running agents unattended and a warning nobody reads is a warning.
DEFAULT if unsure: Block on the floor, warn on everything else for the first two weeks.
Q3: Do you have target numbers in mind, or should I measure where you are today and hold that line?
GUESS: Measure. Most teams don't have a number, and an invented one gets ignored.
DEFAULT if unsure: Measure and hold. See "Ratchets" below.
Q4: What's the slowest check you'll tolerate before the agent hands work back?
GUESS: About 90 seconds. Longer and you'll stop running it.
DEFAULT if unsure: 90 seconds at task end, unlimited in CI.

質問は4つで止めてください。12問のヒアリングでは、誰も理解できない設定と、始めたことを後悔するユーザーが生まれます。

ステップ3:CONSTRAINTS.md を作成する

リポジトリのルートに1つのファイルを作成します。どの実行環境のどのエージェントからでも読め、変更内容は適切な場所であるレビューに表示されます。

# Constraints

Last reviewed: 2026-08-08 by @addy

## Floor (always enforced, no setup required)

- No new suppression comments: `@ts-ignore`, `eslint-disable`, `# noqa`, `# type: ignore`
- No unimplemented stubs: `throw new Error("Not implemented")`, empty `catch {}`
- No skipped or deleted tests without a reason in the commit message
- No secrets in source
- This file does not get weakened to make a change pass

## Enforced with numbers

| Dimension | Rule | Checked by | Runs at |
|-----------|------|-----------|---------|
| Types | Zero type errors | `tsc --noEmit` | every edit |
| Lint | Zero errors from our config | `biome check` | every edit |
| Secrets | No secrets in source | `gitleaks detect --redact` | every edit |
| Coverage | Changed lines ≥ 80% covered | `vitest run --coverage` + git diff | task end, CI |
| Security: code | No high findings | `semgrep scan --config p/default` | CI |
| Security: deps | Nothing at high or above | `osv-scanner scan source -r .` | CI |
| Accessibility | Zero critical or serious | `axe $PREVIEW_URL --tags wcag2a,wcag2aa,wcag21aa` | preview deploy |
| Performance | LCP ≤ 2500ms, CLS ≤ 0.1 | `lighthouse $PREVIEW_URL --output=json` | preview deploy |

Every row names the command that produces the verdict. A dimension with a
number and no command in this column is an aspiration, not a constraint.

## Measured, not yet enforced

| Metric | Today | Direction |
|--------|-------|-----------|
| Project coverage | 62.4% | must not fall |
| Bundle size (main) | 184 kB | must not grow |

## Exceptions

| ID | Rule | Path | Reason | Owner | Expires |
|----|------|------|--------|-------|---------|
| W1 | `no-explicit-any` | `src/legacy/**` | Rewrite tracked in ENG-441 | @addy | 2026-11-01 |

次に、AGENTS.md と CLAUDE.md に次の1行を追加します。コードを書く前に CONSTRAINTS.md を読んでください。変更を通すために制約を緩めてはいけません。

ステップ 4:各項目に必要なツールをインストールする

項目を選ぶということは、何かをインストールするということです。数値だけを示して、実行手段を用意しないままにしないでください。また、事実上の標準ツールがあるのに独自のチェッカーを作らないでください。これらのツールが一覧にあるのは、そのルール形式としきい値がエコシステム全体で対象としているものだからです。これにより、チームの既存の設定をそのまま使い続けられます。

項目ツールインストール実行ゲート条件
型(TS)tscすでにインストール済みtsc --noEmitエラーがあれば
型(Python)mypypip install mypymypy .エラーがあれば
リント既存の設定すでにインストール済みeslint . / biome check / ruff checkエラーがあれば
カバレッジ(JS)テストランナーすでにインストール済みvitest run --coverage(または jest --coverage)変更行のカバレッジ
カバレッジ(Python)pytest-covpip install pytest-covpytest --cov --cov-report=lcov同上
セキュリティ:コードSemgreppipx install semgrepsemgrep scan --config p/default --config p/owasp-top-ten重大度「高」以上の検出があれば
セキュリティ:シークレットgitleaksbrew install gitleaksgitleaks detect --redact --no-banner検出があれば
セキュリティ:依存関係osv-scannerbrew install osv-scannerosv-scanner scan source -r .重大度「高」以上
パフォーマンス:ページLighthousenpm i -D lighthouselighthouse $URL --output=json --quietLCP、CLS、パフォーマンススコア
パフォーマンス:バンドルsize-limitnpm i -D size-limitsize-limit --jsonエントリーごとのバイト数上限
アクセシビリティaxe-corenpm i -D @axe-core/cliaxe $URL --tags wcag2a,wcag2aa,wcag21aa重大または深刻な問題がゼロ
アーキテクチャdependency-cruisernpm i -D dependency-cruiserdepcruise --validate src違反があれば
アサーションの品質Strykernpm i -D @stryker-mutator/corestryker run --mutate <changed files>ミューテーションスコア

省略すると問題になる点が 5 つあります。

  1. gitleaks の --redact は必須です。 これがないと、一致したシークレットがエージェントの会話ログに含まれ、漏えいしたキーがログ、要約、コミットメッセージに残ることになります。報告するのはルールと場所だけにし、値は決して報告しないでください。
  2. Lighthouse と axe には URL が必要です。 実行中のアプリに対してのみ動作するため、プレビュー環境へのデプロイ、または先に起動しておいたローカルサーバーに対するランタイム段階で実行します。プロジェクトにアクセス可能な URL がない場合(CLI、ライブラリ、デスクトップアプリなど)は、その旨を明記し、実行できないチェックをでっち上げるのではなく、この項目を削除してください。
  3. 時間のかかるものは差分の範囲に限定してください。 リポジトリ全体に対する stryker run --mutate は数時間かかり、使われなくなります。変更されたファイルだけなら 1 分もかかりません。パスのリストを指定する Semgrep も同様です。
  4. カバレッジのためにテストを再実行する必要はありません。 テストスイートがすでに出力している lcov を読み込み、git diff と照合してください。数値を得るためにテストスイートを 2 回実行するのは、これを最も嫌われる仕組みにする近道です。
  5. Semgrep のレジストリルールは無料で実行できますが、再配布する前にライセンスを確認してください。 法務チームの判断が必要な場合は、同じルール形式と JSON 出力を備えた、ドロップイン対応のフォーク opengrep があります。

エージェントなしでも再現できるよう、各ツールをプロジェクト独自のスクリプトに追加してください。

{
  "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、CI で実行するのが check:full です。

コマンドは現在、CONSTRAINTS.md の Checked by 列と、これらのスクリプトの 2 か所にあります。正本は CONSTRAINTS.md です。各コマンドの理由も記載されており、レビューにも表示されます。スクリプトは利便性のためのラッパーであり、正本を反映する必要があります。第二の信頼できる情報源にしてはいけません。内容が食い違った場合は、ファイルを優先してください。

ステップ 5:ライフサイクルに組み込む

何でもかんでもあらゆる場面で実行するのが、最大の失敗です。エージェントの動きを止めるチェックは無効にされます。そして、無効にされたゲートは、基準がまだ存在するように見えるため、ゲートがないよりも悪い結果を招きます。

フェーズコマンド実行内容予算
BUILD/build型チェック、lint、シークレット、最低限のチェック5 秒未満、変更したファイルのみ
VERIFY/test関連するテスト、変更行のカバレッジ90 秒未満
REVIEW/reviewすべて、および以下のガード数分
SHIP/ship方針チェック、リグレッションなしCI

これを許容できる範囲に保つためのルールは 2 つです。

  1. 差分に対象を絞ります。 リポジトリ全体ではなく、この変更で触れた行をチェックします。変更行のカバレッジはエージェントが改善できる数値ですが、プロジェクト全体のカバレッジは引き継いだ数値です。
  2. 実行コストで配置を決めます。 数秒を超えるものは編集ループの外に移します。リポジトリ全体のミューテーションテストには数時間かかりますが、変更が触れたファイルだけなら 1 分未満です。この違いによって、チェックが実行されるか、実行されないかが決まります。
ステップ 6:基準自体を守る

エージェントがコードとチェックの両方を書くなら、チェックは何の証明にもならない、と指摘する人がいるでしょう。それは半分正しく、対策を講じる価値があります。

エージェントは巧妙な抜け道を考案するわけではありません。赤になったチェックに対して、緑にする最も安易な方法を選びます。レビュー時には、差分に次の 5 つの変更がないか確認してください。

  1. しきい値が変更されています。 予算が引き下げられた、重大度が下げられた、高速ステージからチェックが削除された、といった変更です。CONSTRAINTS.md をブランチの分岐点での状態と比較してください。
  2. テストが簡単になっています。 .skip が追加された、テストファイルが削除された、残されたテストからアサーションが取り除かれた、といった変更です。
  3. チェッカーが無効にされています。 新たな @ts-ignore や eslint-disable が追加されています。4 つの抑制には特に注意してください。これらは頼りにしているチェックを無効にするからです。istanbul ignore はテストする代わりにコードをカバレッジ対象から除外し、Stryker disable は生き残ったミュータントを隠し、nosemgrep と gitleaks:allow はセキュリティ上の検出結果を無視します。
  4. 作業が未完了です。 例外をスローするスタブ、失敗を黙って処理する空の catch、実装されるべき箇所に残された TODO などです。
  5. 例外が追加されています。 誰も話し合っていない例外テーブルの新しい行です。

これらに対応するために必要なのは git diff だけで、特別なツールは不要です。基準を厳しくする変更は目立たないようにし、緩める変更は明確にしてください。

番号付きの各観点とは異なり、最低限のチェックにはデファクトツールがありません。そのため、これを強制するよう依頼されたエージェントはチェッカーを一から作りがちで、2 つのエージェントが異なるものを作ることになります。この 5 つのチェックのリファレンス実装は、このスキルに含まれています:references/floor-guard.md(差分を対象とし、終了コードは 0/1/2、パターンはエコシステムごとに調整可能)。すべての観点でデファクトツールを指定するのと同じ理由から、これを作り直すのではなく調整して使ってください。実行やスタックをまたいで、仕組みを統一するためです。

すべてのチェックが同じ程度に循環論法的とは限りません。 次の 1 つの問いでランク付けしてください。動作しないコードを書けば、エージェントはこのチェックに合格できますか?

  • 外部チェック — axe-core は WCAG をエンコードし、osv-scanner は脆弱性データベースを読み込み、Lighthouse は実際のブラウザーを測定します。エージェントがこれらに異議を唱えることはできません。
  • プロジェクトチェック — 独自の lint ルールやレイヤー境界です。そのファイルは人間が管理します。
  • テストスイート — 独自のテストです。最も有用であり、真に循環論法的なのはこれだけです。

3 つ目の種類だけで構成された基準は、外部の判断が含まれる基準よりも価値が低くなります。少なくとも 1 つは外部制約が含まれていることを確認してください。

ステップ 7:数値がないときはラチェットを使う

コードベースのカバレッジが 62% の状態で 80% に設定すると、ビルドはいつまでも失敗し続け、やがてチームは失敗するビルドを無視するようになります。

別の方法なら、何も決める必要はありません。現状を記録し、それより悪化しないようにします。「測定済み、まだ未適用」の表に今日の数値と方向性を記入します。すべてのチェックでは、目標値ではなく記録した値と比較します。数値が改善したら更新し、下がったらそれを問題として捉えます。

これは、トレーニングに対するもっともな異論にも答えます。モデルはテストに合格することで報酬を得ますが、その評価は数秒でできます。アーキテクチャの劣化が表面化するには数カ月かかり、重みに反映されることはありません。ラチェットは欠けていたペナルティです。ビルドから見える場所に明記します。

妥当なデフォルト

ユーザーに意見がない場合は、以下を使います。初日から大半のコードベースで達成できるように選んでいます。

制約デフォルトこの数値の理由
変更した行のカバレッジ≥ 80%テストを必須にするには十分高く、設定行を許容するには十分低い
プロジェクトのカバレッジ今日の値を維持し、低下させない導入に異論の余地がない
ミューテーションスコア(使用する場合)最初は ≥ 60%これまでミューテーションを実施していないスイートでは一般的な水準。80% は成熟した状態
依存関係の脆弱性高以上のものをゼロにするそれ未満はほとんどがノイズ
LCP≤ 2500 msCore Web Vitals の「良好」のしきい値
CLS≤ 0.1同上
アクセシビリティaxe の重大または深刻な違反をゼロにする中程度や軽微な違反は意見が分かれることが多い
例外の有効期間90 日修正を計画するには十分長く、忘れずにいられる程度には短い
ラチェットの許容誤差0.5%無関係なファイルの移動による数値の変動を吸収する

数値と理由はセットで記載します。根拠のないしきい値は、次にそれに直面した人に削除されます。

段階的な適用

制約の強制力には 3 つの段階があります。まずは 1 から始めましょう。

  1. 文書に記載するだけ。 CONSTRAINTS.md を用意し、エージェントに読ませます。コストはかからず、うっかりしたミスを防げますが、エージェントの遵守に依存します。
  2. スクリプトで実行する。 高速なチェックを実行する npm run check(または make check)を用意し、エージェントの編集後フックと CI に組み込みます。決定論的で、新しい依存関係も不要です。
  3. 専用ツールで実行する。 差分の範囲指定、予算、ラチェット、ガードチェックを処理する専用のランナーを使います。設定がシェルスクリプトでは手に負えなくなったら導入しましょう。references/floor-guard.md にあるフロアガードのリファレンスは、このうちガードチェック部分の出発点です。

ほとんどのプロジェクトでは 2 で十分です。チェックを実行するシェルスクリプトの保守が 30 行を大きく超えるようになったら、3 に移行しましょう。

最初の実行はフロアチェックだけでもかまいません。 フロアガードは差分のみを対象とし、インストールも不要です。そのため、最初のコミットを保護する前にすべてのチェッカーを準備する必要はなく、初日からフロアを強制し、各ツールをインストールするのに合わせて数値を使う項目を追加できます。gitleaks や osv-scanner など、マシン全体にインストールするセキュリティツールは、開発用ノート PC をクリーンに保ちたい場合、CI のみで実行してもかまいません。各項目をどこで実行するかは、Runs at 列に記載してください。

よくある合理化

言い訳実態
「コードが落ち着いてから制約を追加しよう」コードは、変更中に許されていたものに合わせて落ち着きます
「テストが制約の役割を果たす」自分で書いたテストが証明するのは、自分の考えに自分が同意していることです。新しいコードのカバレッジ、依存関係のリスク、バンドルの肥大化については何も示しません
「カバレッジ 80% は達成できない」ならば 80% にしなければよいのです。今日の数値を設定し、それを維持しましょう
「エージェントの速度が落ちる」遅いチェックを高速なループに入れた場合に限ります。それは配置の誤りであって、制約に反対する理由ではありません
「自分たちの基準は覚えておける」しかしエージェントは覚えていません。しかもコードの大半を書いているのはエージェントです
「制約のせいで出荷できなくなる」担当者と期限を定めた例外を設ければ、作業を続けられます。制約を削除すれば、全員がいつまでも制約なしで進められます

レッドフラグ

次の点に気づいたら、いったん立ち止まって見直してください。

  • 質問が4つを超えた、またはユーザーが説明できない設定が作られた
  • 現在のコードベースでは達成できない予算が設定されており、それを達成する計画もない
  • 数値は記載されているものの、それを裏付けるツールがない項目が CONSTRAINTS.md に書かれた
  • 事実上の標準ツールがあるのにチェッカーを独自実装し、チーム既存の設定が無視されている
  • すべての制約をプロジェクト独自のテストスイートだけでチェックし、外部の見解がない
  • 問題が発生していた機能と同じコミットで CONSTRAINTS.md が変更された
  • 例外に責任者がいない、または期限が1年以上先になっている
  • コードを修正する代わりに、しきい値を緩和するようエージェントが提案した
  • 時間のかかるチェックが編集ループに追加され、誰かが --no-verify を使い始めた
  • CONSTRAINTS.md が書かれて以来、誰も開いていない

検証

次の条件を満たしていれば、このスキルは正しく適用されています。

  • CONSTRAINTS.md が存在し、記載されているすべての数値に明確な理由がある
  • 下限が強制されており、変更を加えなくても現在のコードベースで合格する
  • ユーザーが選んだすべての項目にツールがインストールされており、今日実行できるコマンドがある
  • 各制約に実行場所が記載されており、高速なステージは数秒以内に完了する
  • 少なくとも1つの制約が外部のものである(このプロジェクト独自のテストで判定されない)
  • 計測のみのメトリクスには、今日の値と方向性が記録されている
  • 例外には責任者と期限が設定されている
  • AGENTS.md または CLAUDE.md からこのファイルが参照されている
  • 現在のブランチで試験実行しても、ユーザーが同意しない失敗が発生しない

関連項目

  • interview-me — このスキルの聞き取りで採用している、一度に1つずつ質問する規律
  • code-review-and-quality — レビューの方法。このスキルでは、レビューで何を強制するかを決めます
  • ci-cd-and-automation — これらの制約を実行するパイプラインの構築
  • test-driven-development — カバレッジとミューテーションの制約を測定するテストスイート
  • security-and-hardening — セキュリティ項目に含めるべき内容
  • performance-optimization — パフォーマンスの数値の参照元

コメント