홈 / Skills / 개발 생산성 / 제약 주도 개발 Constraint-Driven Development
개발 생산성

제약 주도 개발 Constraint-Driven Development

Addy OsmaniMITSkill 언어: 영어
라이선스 확인됨스크립트 없음중간 위험
실행 예시실제 실행 · claude-sonnet-5-5 · 2026년 10월
Set up quality constraints for our project (fictional example). Facts you may rely on instead of asking: TypeScript 5, Vitest, Biome for lint, GitHub Actions CI, the web app has a preview URL on every PR, AGENTS.md exists, project coverage today is 58.2%, bundle is 212 kB. I know this is normally an interview, so here are my answers: Q1 pick coverage, security scanning and accessibility; Q2 block on the floor, warn on the rest for two weeks; Q3 measure where we are and hold it; Q4 90 seconds. Write CONSTRAINTS.md in the current folder and tell me what to install and wire up. Then check this agent-made diff against the floor and tell me what it violates: ``` --- a/src/cart.test.ts +++ b/src/cart.test.ts @@ - it('rejects negative quantities', () => { expect(() => addItem(-1)).toThrow(); }); + it.skip('rejects negative quantities', () => {}); --- a/src/pay.ts +++ b/src/pay.ts @@ + // @ts-ignore + const total: number = order.total; + try { await charge(total); } catch {} --- a/CONSTRAINTS.md +++ b/CONSTRAINTS.md -| Coverage | Changed lines >= 80% covered | vitest | task end | +| Coverage | Changed lines >= 60% covered | vitest | task end | ```
Skill: constraint-driven-development

I wrote CONSTRAINTS.md in the current folder. There is no AGENTS.md here, so I didn't add the pointer line to it. In your real repo, add this line to AGENTS.md: Read CONSTRAINTS.md before writing code. Do not weaken it to make a change pass.

What's in it

  • Floor (blocks now): no new suppressions, no stubs or empty catch, no skipped or deleted tests, no stripped assertions, no secrets, and no weakening the file itself.
  • Warn until 2026-10-24, then block: types, lint, changed-line coverage ≥ 80%, Semgrep, osv-scanner and axe.
  • Held, not enforced: project coverage stays at 58.2% (0.5% tolerance) and the bundle stays at 212 kB.
  • Budget: checks at task end must finish in 90 seconds. Semgrep, osv-scanner and axe run in CI or on the preview deploy.
  • Performance budget: you didn't pick one, so bundle size is only tracked. I picked 80% for changed-line coverage myself, because you asked to hold the current level and 80% is the skill's default for new code. Say so if you'd rather not have it.

What to install and wire up

You already have tsc, Vitest and Biome.

Tool Install
Coverage npm i -D @vitest/coverage-v8, with the lcov reporter on
gitleaks brew install gitleaks
Semgrep pipx install semgrep
osv-scanner brew install osv-scanner
axe npm i -D @axe-core/cli

Add these scripts to package.json:

"check:fast": "tsc --noEmit && biome check . && 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 --config p/owasp-top-ten && osv-scanner scan source -r ."
  • After each edit: run check:fast, for example from an agent post-edit hook.
  • At task end: run check:task. Compare the lcov it writes against git diff for the 80% changed-line check, without running the tests a second time.
  • In GitHub Actions: run check:full on every PR. After the preview deploy, run axe $PREVIEW_URL --tags wcag2a,wcag2aa,wcag21aa.
  • Floor guard: it needs no installs and only reads the diff. Adapt the reference implementation in the skill's references/floor-guard.md, which I haven't opened.
  • gitleaks: always use --redact, so a leaked key never lands in a transcript.

The diff against the floor

It violates the floor in four places, and one of them also edits the constraints file.

  1. cart.test.ts: it.skip adds a skipped test, and the assertion expect(...).toThrow() is stripped. Nothing in the diff gives a reason in a commit message. The negative-quantity rule is no longer tested.
  2. pay.ts, // @ts-ignore: this is a new suppression. It hides a type problem on order.total that should be fixed.
  3. pay.ts, catch {}: this is an empty catch around charge(total). A failed payment now passes silently and the code carries on as if it worked. This is the most dangerous change in the diff.
  4. CONSTRAINTS.md: the changed-line coverage threshold drops from 80% to 60% in the same change as the code it would excuse. That breaks the rule against weakening the file.

The four edits fit one pattern: the agent hit red checks and took the cheapest route to green. Reject the diff. The agent should restore the test, fix the type of order.total, handle or rethrow the charge error, and put the threshold back at 80%.

Test run with the interview answers given up front, because the Skill does not run its interview in non-interactive mode. The model wrote CONSTRAINTS.md in a temporary folder, listed what to install, and correctly found four floor violations in a sample diff. It chose the 80% coverage figure itself and said so, and it did not open the floor-guard reference file. Nothing was installed.

하는 일

짧은 인터뷰(기술 스택, 현재 기준선, 이미 있는 검사, 에이전트가 바꿔도 되는 범위)를 한 뒤 CONSTRAINTS.md를 씁니다. 첫날부터 막는 최저선(새 억제 주석 금지, 스텁이나 빈 catch 금지, 테스트 건너뛰기나 삭제 금지, 단언 제거 금지, 비밀 정보 금지, 이 파일 자체를 약화하지 않기), 도구 이름과 실행 시점이 적힌 숫자 규칙(타입, 린트, 비밀 정보, 변경 줄 커버리지, 코드와 의존성 보안, 접근성), 오늘의 수치를 올리지 않고 지키는 래칫, 에이전트 자체 검사의 시간 예산, 담당자와 만료일이 있는 예외 표가 들어 있습니다. 새 규칙은 먼저 경고로 시작하고 차단으로 바꿀 날짜를 적습니다. 설치할 것과 추가할 스크립트 목록을 알려 주고, 에이전트의 diff를 최저선에 비춰 검토할 수도 있습니다.

결과물

CONSTRAINTS.md, 설치와 연결 안내, (요청 시) diff에 대한 판정.

이런 때 좋습니다

에이전트에게 코드를 쓰게 하면서도, 초록불을 얻으려고 에이전트가 검사를 고쳐 쓰지 못하게 하고 싶은 팀.

참고 사항 및 위험

중간 위험:Skill 자체는 지침만 있고(최저선 가드 스크립트의 참고 파일 포함) 에이전트가 CONSTRAINTS.md를 쓰게 하며, 도구(커버리지, gitleaks, Semgrep, osv-scanner, axe) 설치와 스크립트, 훅 추가를 제안합니다. 실행하기 전에 그 명령들을 확인하세요. 인터뷰는 비대화형 모드에서 실행되지 않아 시험 때는 답을 미리 주었습니다. 임시 폴더에 파일을 쓰고 설치할 목록을 냈으며(실제 설치는 없음) 예제 diff에서 최저선 위반 네 곳을 찾았습니다. 80%라는 수치는 모델이 직접 골랐고 그렇게 밝혔습니다. 최저선 가드 참고 파일은 열지 않았습니다. 작성자 Addy Osmani, MIT.

SKILL.md 원본패키지에 파일 3개