Community程式設計與開發github.com

addyosmani/constraint-driven-development

為專案建立一份書面品質標準,防止 AI Agent 悄然降低標準。它會訪談使用者以了解哪些面向重要,並在使用者無確切數字時提供合理的預設閾值,記錄至 CONSTRAINTS.md,並監控 diff 以防止標準被削弱。

constraint-driven-development 是什麼?

此技能(Skill)旨在為軟體開發專案建立可執行、可持續的品質門檻。它透過結構化訪談,引導使用者定義測試覆蓋率、安全性、效能、無障礙性等關鍵維度的具體數值,並自動生成 CONSTRAINTS.md 檔案作為專案的「品質合約」。其核心價值在於:當 AI Agent 大幅產出程式碼時,能透過自動化檢查而非人工審閱來把關品質。技能支援多種開發環境,能智慧偵測專案技術棧(如 TypeScript、Python),並根據 CI/CD 流程(如 GitHub Actions)動態調整檢查階段與耗時。此外,它內建「護欄」機制,會監控 CONSTRAINTS.md 的變更,防止 Agent 透過降低閾值、跳過測試或新增抑制註解(如 @ts-ignore)來繞過品質規範。此技能適合專案啟動初期、引入自主 Agent 工作流程,或團隊對品質標準爭論不休時使用。

相容平台✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/addyosmani/agent-skills/tree/main/skills/constraint-driven-development

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

約束驅動開發

概觀

此套件中的其他技能描述了「良好」的樣貌。code-review-and-quality 提供了五個面向。test-driven-development 提供了一個循環。security-and-hardening 提供了威脅清單。這些都只存在於 Agent 閱讀、且可能不會遵循的文字中,而且它們都無法在會話結束後存留。

此技能產出了不同的東西:一份關於此專案標準的書面記錄,附有數字,會比對話更長久,並且可以機械式地檢查。

這點很重要。當你編寫程式碼時,閱讀它就能知道它好不好。而一個 Agent 一個下午產出的程式碼,比你一週內能讀的還多,因此判斷的責任必須從你的腦袋,轉移到能在循環中執行的檢查上。這些檢查必須存在,它們需要你真正選擇的數字,而且它們必須在足夠接近工作的地方觸發,以便 Agent 能夠修正自己的輸出。

規格驅動開發(Spec-driven development)說明了要建置什麼。測試驅動開發(Test-driven development)證明了它能運作。而約束驅動開發(Constraint-driven development)則是在任何人在 Pull Request 中爭論之前,就定義了什麼叫做「好到可以發佈」。

何時使用

在以下情況應用此技能:

  • 啟動一個新專案或一個重大功能,且沒有任何書面的品質標準
  • 使用者要求「設定約束」、「增加品質閘門」、「定義我們的標準」,或「阻止 Agent 產出垃圾」
  • Agent 產出大量程式碼,但沒有人會逐行審視
  • CI 有檢查,但沒有人能說哪些會阻擋合併,哪些只是裝飾
  • 覆蓋率、效能或無障礙性數字每次 PR 都在爭論,而不是一次決定好
  • 你即將執行 /build auto 或任何自主循環,且擋在主線與它之間的唯一事物,是一個同一個 Agent 也寫了的測試套件

何時不要使用:

  • 專案已有 CONSTRAINTS.md 且使用者未修改它——請直接閱讀並遵循它
  • 一次性腳本、概念驗證專案、可拋棄原型
  • 使用者現在需要程式碼審查(使用 code-review-and-quality)或建立 CI Pipeline(使用 ci-cd-and-automation)
  • 預期生命週期僅兩週、產品市場契合前的程式碼——最低標準仍然值得做,但其他部分則否

載入約束

訪談需要一個真實的使用者。請勿在非互動式上下文(CI、/loop、自主執行)中執行。如果約束條件缺失且你處於上述情境,請套用下方的最低標準,記錄你已執行此操作,並將其餘部分標記給真人處理。

流程

步驟 1:在提問前先偵測

永遠不要問你可以讀取到的東西。在第一個問題之前,請收集以下資訊:

項目查看位置
語言與技術棧package.json, pyproject.toml, go.mod, Cargo.toml
測試執行器開發依賴、test 腳本、現有測試檔案
現有 Lintereslint.config.*, biome.json, .ruff.toml
目前的覆蓋率coverage/ 輸出,或執行一次測試套件
CI.github/workflows/, .gitlab-ci.yml
Agent 框架.claude/, .codex/, AGENTS.md

用兩行回報你的發現,然後只問剩下的問題。

步驟 2:四個問題,每個都附帶預設值

遵循 interview-me 中的一次一個問題的原則,但有一個改變:這裡的每個問題都有預設值,所以「我不知道」是一個完整的答案,仍然能產出一個可運作的設定。

Q1:除了最低標準,你希望強制執行以下哪些項目?
    (a) 新程式碼的測試覆蓋率
    (b) 安全性掃描
    (c) 效能預算
    (d) 無障礙性
    (e) 架構邊界
猜測:(a) 和 (b)——你已經有測試執行器,並且正在處理使用者輸入。
如果不確定,預設值:(a) 和 (b)。
說明每個選擇的成本:(c) 和 (d) 需要一個運作中的 URL,(e) 需要編寫規則檔案。
Q2:當 Agent 在任務進行中時,某項檢查失敗,它應該封鎖還是僅發出警告?
猜測:封鎖。你在無人監控下執行 Agent,而一個沒人看的警告就只是個警告。
如果不確定,預設值:最低標準項目封鎖,其餘項目在前兩週僅發出警告。
Q3:你心中有目標數字,還是希望我衡量你今天的狀況,然後維持那個標準?
猜測:衡量。大多數團隊沒有數字,而憑空發明一個數字會被忽略。
如果不確定,預設值:衡量並維持。請參閱下方的「棘輪機制」。
Q4:在 Agent 交回工作成果之前,你能忍受的最慢檢查時間是多久?
猜測:大約 90 秒。再長的話,你就不會再執行它了。
如果不確定,預設值:任務結束時 90 秒,CI 中則不限時。

停在四個問題。一個十二題的問答會產生一個沒人懂的設定,和一個後悔開始的使用者。

步驟 3:撰寫 CONSTRAINTS.md

一個位於版本庫根目錄的檔案。任何 Agent 在任何框架上都可以讀取它,而對它的修改會在審查中出現在它該在的地方。

# Constraints

最後審閱:2026-08-08 由 @addy

## 最低標準(永遠強制執行,無需設定)

- 無新的抑制註解:`@ts-ignore`, `eslint-disable`, `# noqa`, `# type: ignore`
- 無未實作的存根:`throw new Error("Not implemented")`, 空的 `catch {}`
- 未在 commit 訊息中說明原因時,不得跳過或刪除測試
- 原始碼中不得有密碼
- 此檔案不得為了讓某項變更通過而遭到弱化

## 以數字強制執行

| 維度 | 規則 | 檢查者 | 執行時機 |
|-----------|------|-----------|---------|
| 型別 | 零型別錯誤 | `tsc --noEmit` | 每次編輯 |
| Lint | 根據我們的設定,零錯誤 | `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% | 不得下降 |
| 套件大小(主線) | 184 kB | 不得增長 |

## 例外情況

| ID | 規則 | 路徑 | 原因 | 負責人 | 到期日 |
|----|------|------|--------|-------|---------|
| W1 | `no-explicit-any` | `src/legacy/**` | 重構追蹤於 ENG-441 | @addy | 2026-11-01 |

然後在 AGENTS.md 和 CLAUDE.md 中加入一行:在編寫程式碼之前,請先閱讀 CONSTRAINTS.md。請勿為了讓變更通過而弱化它。

步驟 4:安裝每個維度所需的工具

選擇一個維度意味著要安裝某個東西。不要留給使用者一個數字卻沒有機制,也不要在已有事實上的標準檢查工具時自行發明檢查器——列出這些工具的原因是其規則格式和閾值是生態系統中其他一切工具所針對的目標,這樣團隊現有的設定才能持續運作。

維度工具安裝執行閘門條件
型別 (TS)tsc已存在tsc --noEmit任何錯誤
型別 (Python)mypypip install mypymypy .任何錯誤
Lint你現有的設定已存在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 <變更的檔案>突變測試分數

五件如果你跳過就會出問題的事:

  1. gitleaks 的 --redact 不是選配。 沒有它,比對到的密碼會出現在 Agent 的記錄中,這就是洩漏的金鑰最後如何出現在日誌、摘要或 commit 訊息中。請回報規則和位置,永遠不要回報其值。
  2. Lighthouse 和 axe 需要一個 URL。 它們只能在執行中的應用程式中運作,因此它們屬於執行階段,針對預覽佈署或你首先啟動的本機伺服器。如果專案沒有可以存取的 URL——像是 CLI、函式庫、桌面應用程式——請說明情況並放棄該維度,而不是發明一個無法執行的檢查。
  3. 針對耗時的檢查,請將範圍限定在 diff 上。 對整個倉庫執行 stryker run --mutate 需要數小時,最終會被關閉;而只對變更觸及的檔案執行則只需不到一分鐘。Semgrep 也是如此,它可以接受一個路徑列表。
  4. 覆蓋率不需要第二次測試執行。 讀取你的測試套件已經寫入的 lcov 檔案,然後與 git diff 交集。為了得到一個數字而執行測試套件兩次,是最快讓人們討厭這件事的方法。
  5. Semgrep 的 registry 規則是免費執行的;但在重新分發前請檢查其授權。 如果你的法務團隊在意,opengrep 是一個具有相同規則格式和 JSON 輸出的直接替代分支。

將每個檢查加入專案自身的腳本,使其無需 Agent 即可重現:

{
  "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 在 Agent 認為工作完成時執行,check:full 在 CI 中執行。

這些指令現在存在於兩個地方——CONSTRAINTS.md 中的「檢查者」欄位,以及這些腳本。CONSTRAINTS.md 是權威來源:它承載了每個指令背後的原因,並且會在審查中出現。腳本是必須與之同步的便利包裝,而非第二個事實來源;如果它們偏離了,以檔案為準。

步驟 5:將其連接到生命週期

最常見的錯誤是在所有地方執行所有檢查。一個會拖慢 Agent 的檢查會被關閉,而一個被關閉的閘門比沒有閘門更糟,因為標準看起來仍然存在。

階段指令執行的項目預算
BUILD/build型別、lint、密碼、最低標準小於 5 秒,僅限變更的檔案
VERIFY/test相關測試、變更行的覆蓋率小於 90 秒
REVIEW/review所有項目,加上下方的護欄數分鐘
SHIP/ship方向檢查,無倒退CI

兩個讓這一切保持可接受的規則:

  1. 範圍限定在 diff。 檢查此變更觸及的行,而非整個倉庫。變更行的覆蓋率是一個 Agent 可以改變的數字;而專案覆蓋率是它繼承來的。
  2. 成本決定擺放位置。 任何超過數秒的檢查都應移出編輯循環。對整個倉庫進行突變測試需要數小時;對變更觸及的檔案進行則只需不到一分鐘,這就是一個檢查會被人執行與不會被執行的區別。

步驟 6:守護標準本身

有人會指出,如果 Agent 同時寫了程式碼和檢查,那麼檢查就無法證明什麼。對了一半,而且值得為此進行工程設計。

Agent 不會精心設計巧妙的漏洞。它們遇到紅燈時,會選擇通往綠燈最便宜的路徑。在審查時,請留意 diff 中的這五種動作:

  1. 閾值變動了。 預算降低、嚴重性調降、檢查從快速階段被移除。將 CONSTRAINTS.md 與其在分支點時的狀態進行比較。
  2. 測試變容易了。 新增了 .skip、測試檔案被刪除、從保留的測試中移除了斷言語句。
  3. 檢查器被靜音了。 新增了 @ts-ignore 或 eslint-disable。有四個抑制註解需要特別注意,因為它們會關閉你依賴的檢查:istanbul ignore 會讓程式碼不被覆蓋,而不是測試它;Stryker disable 會隱藏存活的突變體;nosemgrep 和 gitleaks:allow 則用於安全性發現。
  4. 工作未完成。 會拋出錯誤的存根、將失敗轉為靜默的空的 catch、一個 TODO 取代了應該有實作的地方。
  5. 出現了一個例外。 例外情況表格中出現了一個未經討論的新行。

這些都不需要比 git diff 更複雜的工具。收緊標準應該悄無聲息;放寬標準則應該大聲喧嘩。

與有數字的維度不同,最低標準沒有它自己的事實上的工具,因此一個被要求強制執行它的 Agent 傾向於從頭開始編寫檢查器,而兩個 Agent 會寫出兩個不同的檢查器。此技能附帶了這五項檢查的參考實作,位於 references/floor-guard.md(範圍限定在 diff,退出碼為 0/1/2,模式可根據生態系統調整)。請調整該實作而非重新發明,原因與每個維度都指名一個事實上的工具相同:這樣機制才能在跨執行和技術棧中保持一致。

並非所有檢查都是同等循環論證的。 用一個問題來排序它們:Agent 可以透過編寫無法運作的程式碼來讓此檢查通過嗎?

  • 外部——axe-core 編碼了 WCAG,osv-scanner 讀取漏洞資料庫,Lighthouse 測量真實瀏覽器。Agent 無法與這些爭論。
  • 專案——你的 lint 規則、你的層級邊界。檔案由真人擁有。
  • 套件——你自己的測試。最有用的,而且是唯一真正循環論證的。

一個標準

…

[因翻譯限制而截斷]

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

addyosmani/agent-skills

Prepares production launches. Use when preparing to deploy to production, or when asking what needs to be in place before shipping. Use when you need a pre-launch checklist, when setting up monitoring, when planning a staged rollout, or when you need a rollback strategy.

addyosmani/agent-skills

Builds production-quality, accessible, responsive user-facing UIs. Use when building or modifying interfaces and pages, creating components, implementing layouts, meeting WCAG accessibility requirements, managing state, or when the output needs to look and feel production-quality rather than AI-generated.

addyosmani/agent-skills

Guides stable API and interface design. Use when designing APIs, module boundaries, or any public interface. Use when creating REST or GraphQL endpoints, defining type contracts between modules, or establishing boundaries between frontend and backend.

addyosmani/browser-testing-with-devtools

Tests in real browsers via Chrome DevTools MCP. Use when building or debugging anything that runs in a browser. Use when you need to inspect the DOM, capture console errors, analyze network requests, profile performance, or verify visual output with real runtime data. Requires the chrome-devtools MCP server to be configured.

addyosmani/ci-cd-and-automation

Automates CI/CD pipeline setup. Use when setting up or modifying build and deployment pipelines. Use when you need to automate quality gates, configure test runners in CI, or establish deployment strategies.

addyosmani/code-review-and-quality

Conducts multi-axis code review. Use before merging any change. Use when reviewing code written by yourself, another agent, or a human. Use when you need to assess code quality across multiple dimensions before it enters the main branch.

addyosmani/code-simplification

Simplifies code for clarity. Use when refactoring code for clarity without changing behavior. Use when code works but is harder to read, maintain, or extend than it should be. Use when reviewing code that has accumulated unnecessary complexity.

addyosmani/debugging-and-error-recovery

Guides systematic root-cause debugging. Use when tests fail, builds break, behavior doesn't match expectations, or you encounter any unexpected error. Use when you need a systematic approach to finding and fixing the root cause rather than guessing.

addyosmani/deprecation-and-migration

Manages deprecation and migration. Use when removing old systems, APIs, or features. Use when migrating users from one implementation to another. Use when deciding whether to maintain or sunset existing code.

addyosmani/documentation-and-adrs

Records decisions and documentation. Use when making architectural decisions, changing public APIs, shipping features, or when you need to record context that future engineers and agents will need to understand the codebase.

addyosmani/doubt-driven-development

Subjects every non-trivial decision to a fresh-context adversarial review before it stands. Use when correctness matters more than speed, when working in unfamiliar code, when stakes are high (production, security-sensitive logic, irreversible operations), or any time a confident output would be cheaper to verify now than to debug later.

addyosmani/git-workflow-and-versioning

Structures git workflow practices. Use when making any code change. Use when committing, branching, resolving conflicts, or when you need to organize work across multiple parallel streams.

addyosmani/idea-refine

Refines raw ideas into sharp, actionable concepts through structured divergent and convergent thinking. Use when an idea is still vague, when you need to stress-test assumptions before committing to a plan, or when you want to expand options before converging on one. Triggers on "ideate", "refine this idea", or "stress-test my plan".

addyosmani/incremental-implementation

Delivers changes incrementally. Use when implementing any feature or change that touches more than one file. Use when you're about to write a large amount of code at once, or when a task feels too big to land in one step.

addyosmani/interview-me

Extracts what the user actually wants instead of what they think they should want. Achieves this through one-question-at-a-time interview until ~95% confidence about the underlying intent. Use when an ask is underspecified ("build me X" without "for whom" or "why now"), when the user explicitly invokes ("interview me", "grill me", "are we sure?", "stress-test my thinking"), or when you catch yourself silently filling in ambiguous requirements before any plan, spec, or code exists.

addyosmani/observability-and-instrumentation

Instruments code so production behavior is visible and diagnosable. Use when adding logging, metrics, tracing, or alerting. Use when shipping any feature that runs in production and you need evidence it works. Use when production issues are reported but you can't tell what happened from the available data.

addyosmani/performance-optimization

Optimizes application performance. Use when performance requirements exist, when you suspect performance regressions, or when Core Web Vitals or load times need improvement. Use when profiling reveals bottlenecks that need fixing.

addyosmani/planning-and-task-breakdown

Breaks work into ordered tasks. Use when you have a spec or clear requirements and need to break work into implementable tasks. Use when a task feels too large to start, when you need to estimate scope, or when parallel work is possible.

addyosmani/security-and-hardening

Hardens code against vulnerabilities. Use when handling user input, authentication, data storage, or external integrations. Use when building any feature that accepts untrusted data, manages user sessions, or interacts with third-party services.

addyosmani/source-driven-development

Grounds every implementation decision in official documentation. Use when you want authoritative, source-cited code free from outdated patterns. Use when building with any framework or library where correctness matters.

相關技能