Turn your specs into enforceable contracts that LLMs can't violate
You write specs. An LLM "helpfully" changes something. Everything breaks:
// Your spec: "Service workers MUST NOT use localStorage"
// LLM adds this anyway:
const token = localStorage.getItem('auth') // 💥 CRASHResult: Production down. Hours debugging. Trust in AI tooling eroded.
Contracts = Specs that enforce themselves.
Write spec with IDs → Generate contracts → Auto-create tests → Violations = Build fails
Core loop:
- Write
docs/specs/authentication.mdwithAUTH-001 (MUST)requirements - Generate
docs/contracts/feature_authentication.ymlwith rules - Tests scan source code for violations
- CI blocks merges if contracts broken
# 1. Write your first spec
cat > docs/specs/authentication.md <<EOF
## REQS
### AUTH-001 (MUST)
All API endpoints must require authentication.
EOF
# 2. Give LLM this prompt
Give Claude: "Use LLM-MASTER-PROMPT.md to generate contracts for docs/specs/authentication.md"
# 3. LLM creates contracts + tests automatically
# 4. Run tests
npm test -- contracts# 1. Document what works today (plain English is fine!)
cat > current-behavior.md <<EOF
Our auth system currently works like this:
- Sessions stored in Redis with key pattern: session:{userId}
- 7-day expiry on all sessions
- Auth middleware on all /api/* routes
- Tokens in httpOnly cookies (never localStorage)
EOF
# 2. Give LLM this prompt (it will create REQ IDs for you)
Give Claude: "Read current-behavior.md and use LLM-MASTER-PROMPT.md to:
1. Convert this working behavior into SPEC-FORMAT.md with REQ IDs
2. Create 'freeze contracts' using CONTRACT-SCHEMA.md
3. Generate tests that will fail if someone breaks this
The LLM should create contracts that prevent:
- Changing Redis key patterns
- Removing auth middleware from routes
- Using localStorage for tokens"
# 3. LLM generates:
# - Spec with REQ IDs (AUTH-001, AUTH-002, etc.)
# - Contracts mapping to those IDs
# - Tests that lock current behavior
# 4. Now you can refactor safely—tests catch regressions- CONTRACTS-README.md — What contracts are, core loop, where things live, how LLMs should behave
- SPEC-FORMAT.md — How to write specs (REQ IDs like
AUTH-001, JOURNEY IDs likeJ-AUTH-REGISTER) - CONTRACT-SCHEMA.md — Lean YAML contract format (maps REQ IDs → rules → tests)
- LLM-MASTER-PROMPT.md — Reusable prompt for LLMs (incremental workflow: spec → contracts → tests → code)
- MASTER-ORCHESTRATOR.md — Complete spec → implementation automation (comprehensive, heavy)
- SPEC-TO-CONTRACT.md — Detailed conversion examples and patterns
- USER-JOURNEY-CONTRACTS.md — Journey testing vs unit testing
- MID-PROJECT-ADOPTION.md — Adding contracts to existing codebases
- META-INSTRUCTION.md — Infrastructure setup guide
- contract-example.yml — Real working contract
- test-example.test.ts — Complete test suite
- CLAUDE-MD-TEMPLATE.md — Add to your CLAUDE.md
- CI-INTEGRATION.md — GitHub Actions, GitLab, etc.
graph LR
A[Write Spec<br/>AUTH-001 MUST] --> B[Generate Contract<br/>feature_auth.yml]
B --> C[Generate Test<br/>auth.test.ts]
C --> D[Implement Code<br/>Add authMiddleware]
D --> E{Run Tests}
E -->|PASS| F[✅ Merge]
E -->|FAIL| G[❌ Fix Code]
G --> D
style A fill:#e1f5ff
style B fill:#fff3cd
style C fill:#fff3cd
style F fill:#d4edda
style G fill:#f8d7da
✅ Specs become enforceable — Requirements have IDs (AUTH-001), contracts enforce them, tests verify them
✅ Incremental workflow — Add one REQ → update contract → update test → implement → verify (not monolithic)
✅ Single source of truth — Each REQ maps to exactly one contract rule, tests reference REQ IDs
✅ LLM-friendly — Normalized spec format, clear IDs, reusable prompt, compliance checklists
✅ Mid-project safe — Document current state as contract, prevent regressions, refactor safely
✅ CI/CD integrated — Tests run automatically, violations block merges
# docs/specs/authentication.md
## REQS
### AUTH-001 (MUST)
All API endpoints (except /health) must require authentication.
### AUTH-002 (MUST)
Auth tokens must be stored in httpOnly cookies.# docs/contracts/feature_authentication.yml
rules:
non_negotiable:
- id: AUTH-001
forbidden_patterns:
- pattern: /router\.(get|post).*\/api\//
message: "Route missing authMiddleware"// src/__tests__/contracts/auth.test.ts
it('AUTH-001: API routes have authMiddleware', () => {
// Scan src/routes/ for violations
// Fail with clear message if found
})// ✅ Compliant
router.get('/api/users', authMiddleware, async (req, res) => { ... })
// ❌ Violation → Test fails → Build blocked
router.get('/api/users', async (req, res) => { ... })→ Read: SPEC-FORMAT.md for writing AUTH-001 (MUST) requirements
→ Use: LLM-MASTER-PROMPT.md to generate contracts + tests
→ Result: LLMs can't add routes without authMiddleware
→ Read: MID-PROJECT-ADOPTION.md for freezing current state
→ Create: Contract with forbidden patterns (e.g. /localStorage/)
→ Result: Build fails if LLM tries localStorage in service worker
→ Read: USER-JOURNEY-CONTRACTS.md
→ Write: J-AUTH-REGISTER journey in spec
→ Generate: Journey contract + E2E test
→ Result: Tests verify complete user flow, not just units
→ Read: MASTER-ORCHESTRATOR.md → Give LLM: Your spec + "Execute MASTER-ORCHESTRATOR.md" → Result: Full implementation with contracts, tests, CI/CD
| Approach | What It Tests | Survives Refactoring? |
|---|---|---|
| Unit Tests | Implementation details | ❌ Breaks on refactor |
| Contracts | Architectural invariants | ✅ Tests what must stay true |
Example:
- ❌ Test: "login() returns token" → Breaks if you refactor login internals
- ✅ Contract: "Users must be authenticated" → Enforces requirement, survives refactors
You're doing it right when:
- ✅ Spec has clear REQ IDs:
AUTH-001,EMAIL-042 - ✅ Contract maps IDs → rules:
AUTH-001infeature_auth.yml - ✅ Tests reference IDs:
it('AUTH-001: ...') - ✅ Intentional violation fails with clear message
- ✅ Fix makes it pass
- ✅ CI runs automatically
AUTH-001: All /api/* routes must have authMiddleware
→ Test scans src/routes/ for pattern violations
→ Build fails if route lacks authSTORAGE-001: Service workers must use chrome.storage.local
→ Test scans src/background.ts for localStorage usage
→ Build fails if forbidden API detectedJ-CHECKOUT: User adds to cart → payment → confirmation
→ E2E test drives complete flow
→ Build fails if journey breaks# Clone templates
git clone https://github.com/Hulupeep/Specflow.git
cd Specflow
# Copy to your project
cp -r * /your-project/docs/contracts/templates/
# Read quick start
cat CONTRACTS-README.mdOr browse online: github.com/Hulupeep/Specflow
- Start simple: Read CONTRACTS-README.md
- Write a spec: Follow SPEC-FORMAT.md
- Generate contracts: Use LLM-MASTER-PROMPT.md
- Run tests:
npm test -- contracts - Add to CI: See CI-INTEGRATION.md
No. Tests check how things are built. Contracts check what must stay true.
Start with: "Document what works today." Contract = "Freeze this, don't break it."
Yes, if you:
- Use CLAUDE-MD-TEMPLATE.md to add contract section to CLAUDE.md
- LLM reads this first when editing
- Even if LLM skips it → tests catch violations in CI
- ESLint: Syntax and types
- Contracts: Business rules and architecture
Both are valuable. Contracts enforce higher-level invariants.
- 📖 Documentation: Core docs above
- 🐛 Issues: github.com/Hulupeep/Specflow/issues
- 💬 Discussions: Share your contracts and patterns
- ⭐ Star this repo if it helps you!
We need:
- ✅ Real-world contract examples from your projects
- ✅ Language-specific patterns (Python, Go, Java)
- ✅ Better LLM integrations
- ✅ More test templates
See CONTRIBUTING.md
MIT - Use freely, commercially, anywhere.
┌─────────────────────────────────────────────────────────┐
│ Specflow Quick Reference │
├─────────────────────────────────────────────────────────┤
│ Core Docs (Read These First): │
│ CONTRACTS-README.md System overview │
│ SPEC-FORMAT.md How to write specs │
│ CONTRACT-SCHEMA.md YAML format │
│ LLM-MASTER-PROMPT.md LLM workflow │
│ │
│ Reference Guides: │
│ MASTER-ORCHESTRATOR.md Complete automation │
│ SPEC-TO-CONTRACT.md Conversion examples │
│ MID-PROJECT-ADOPTION.md Existing codebases │
│ │
│ Quick Commands: │
│ npm test -- contracts Run all contract tests │
│ node scripts/check-contracts Quick check files │
│ │
│ Core Loop: │
│ Spec → Contract → Test → Code → Verify │
└─────────────────────────────────────────────────────────┘
Made with ❤️ for vibe coders who want specs that actually matter