Project 5: Steering Rules Engine
Project 5: Steering Rules Engine
Enforcing Project Standards: Teach AI your teamโs conventions automatically
Project Metadata
| Attribute | Value |
|---|---|
| Difficulty | Level 2: Intermediate |
| Time Estimate | 1 Week (15-20 hours) |
| Primary Language | Markdown/JSON |
| Alternative Languages | YAML, TypeScript |
| Prerequisites | Projects 1-4, understanding of coding standards |
| Main Reference | โClean Codeโ by Robert C. Martin |
Learning Objectives
By completing this project, you will:
- Understand steering file types - product.md, tech.md, structure.md and their purposes
- Master scope resolution - how global and workspace steering files interact
- Write effective constraints - positive framing that guides AI behavior
- Design conditional loading - use front matter for context-aware rules
- Build validation tools - ensure steering files are effective
Deep Theoretical Foundation
What Is Steering?
Steering files are persistent instructions that guide AI behavior across all sessions. Unlike one-time prompts, steering rules are always present - theyโre the โmuscle memoryโ you teach Kiro about your project.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STEERING vs PROMPTING โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ ONE-TIME PROMPT STEERING FILE โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโ โ
โ โ
โ You: "Use TypeScript strict mode" .kiro/steering/tech.md: โ
โ AI: "OK, I'll use strict mode" "Always use TypeScript โ
โ ...later... strict mode for all files" โ
โ You: "Add a new endpoint" โ
โ AI: *forgets about strict mode* AI: *checks steering* โ
โ AI: *applies strict mode* โ
โ ...every time, forever... โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ PROMPT DECAY โ โ
โ โ โ โ
โ โ Turn 1: โโโโโโโโโโโโโโโโโโโโโโโโ 100% remembered โ โ
โ โ Turn 5: โโโโโโโโโโโโโโโโโโโโโโโโ 50% remembered โ โ
โ โ Turn 10: โโโโโโโโโโโโโโโโโโโโโโโโ 20% remembered โ โ
โ โ Turn 20: โโโโโโโโโโโโโโโโโโโโโโโโ 0% (pushed out) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ STEERING PERSISTENCE โ โ
โ โ โ โ
โ โ Turn 1: โโโโโโโโโโโโโโโโโโโโโโโโ 100% applied โ โ
โ โ Turn 5: โโโโโโโโโโโโโโโโโโโโโโโโ 100% applied โ โ
โ โ Turn 10: โโโโโโโโโโโโโโโโโโโโโโโโ 100% applied โ โ
โ โ Turn 20: โโโโโโโโโโโโโโโโโโโโโโโโ 100% applied โ โ
โ โ Forever: โโโโโโโโโโโโโโโโโโโโโโโโ 100% applied โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Steering File Taxonomy
Kiro recognizes different types of steering files, each with a specific purpose:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STEERING FILE TYPES โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ product.md - WHAT we're building โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ โข Product vision and goals โ โ
โ โ โข User personas and needs โ โ
โ โ โข Feature priorities โ โ
โ โ โข Business constraints โ โ
โ โ โ โ
โ โ Example: "We're building a B2B SaaS. Enterprise security โ โ
โ โ is paramount. Performance is secondary to reliability." โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ tech.md - HOW we build โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ โข Language and framework choices โ โ
โ โ โข Coding standards and conventions โ โ
โ โ โข Testing requirements โ โ
โ โ โข Forbidden patterns โ โ
โ โ โ โ
โ โ Example: "TypeScript strict mode. Zod for validation. โ โ
โ โ No any type. Vitest for tests. 80% coverage minimum." โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ structure.md - WHERE things go โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ โข Directory structure conventions โ โ
โ โ โข File naming patterns โ โ
โ โ โข Module organization โ โ
โ โ โข Import/export rules โ โ
โ โ โ โ
โ โ Example: "Components in src/components/<Name>/<Name>.tsx. โ โ
โ โ Tests colocated as <Name>.test.tsx. Barrel exports." โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ security.md - Safety requirements โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ โข Authentication/authorization rules โ โ
โ โ โข Data handling requirements โ โ
โ โ โข Forbidden operations โ โ
โ โ โข Compliance constraints โ โ
โ โ โ โ
โ โ Example: "Never log PII. Always use parameterized queries. โ โ
โ โ JWT tokens expire after 1 hour. RBAC for all endpoints." โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Custom files (api-standards.md, testing.md, etc.) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ โข Any domain-specific standards โ โ
โ โ โข Team conventions โ โ
โ โ โข Project-specific rules โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Scope Resolution: Global vs Workspace
Steering files can exist at two levels with specific priority rules:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SCOPE RESOLUTION โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ ~/.kiro/steering/ (GLOBAL - applies to all projects) โ
โ โโโ tech.md "Always use ESLint" โ
โ โโโ security.md "Never commit secrets" โ
โ โโโ personal.md "I prefer verbose comments" โ
โ โ
โ ~/projects/my-app/.kiro/steering/ (WORKSPACE - this project only) โ
โ โโโ tech.md "Use React 18 with Server Components" โ
โ โโโ api-standards.md "REST endpoints follow /api/v1/*" โ
โ โโโ testing.md "E2E tests with Playwright" โ
โ โ
โ RESOLUTION ORDER: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ
โ โ 1. Workspace steering loaded first (highest priority) โ โ
โ โ 2. Global steering loaded second (fills gaps) โ โ
โ โ 3. Same-named files: Workspace OVERRIDES global โ โ
โ โ 4. Different files: Both apply โ โ
โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ EFFECTIVE RULES FOR ~/projects/my-app: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โข "Use React 18..." (workspace tech.md wins) โ โ
โ โ โข "Never commit secrets" (global security.md applies) โ โ
โ โ โข "I prefer verbose comments" (global personal.md applies) โ โ
โ โ โข "REST endpoints..." (workspace api-standards.md applies) โ โ
โ โ โข "E2E tests..." (workspace testing.md applies) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Front Matter: Conditional Loading
Steering files support YAML front matter for conditional loading:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ FRONT MATTER OPTIONS โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ --- โ
โ inclusion: always # Load for every session โ
โ --- โ
โ โ
โ --- โ
โ inclusion: agent # Only load for specific agents โ
โ agents: [sec-auditor, code-reviewer] โ
โ --- โ
โ โ
โ --- โ
โ inclusion: manual # Only when explicitly requested โ
โ --- โ
โ โ
โ --- โ
โ inclusion: path # Load when working in matching paths โ
โ paths: [src/api/**, routes/**] โ
โ --- โ
โ โ
โ EXAMPLE: api-standards.md โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ --- โ โ
โ โ inclusion: path โ โ
โ โ paths: ["src/api/**", "src/routes/**"] โ โ
โ โ --- โ โ
โ โ โ โ
โ โ # API Standards โ โ
โ โ โ โ
โ โ All API endpoints MUST: โ โ
โ โ - Use REST conventions โ โ
โ โ - Return JSON responses โ โ
โ โ - Include proper status codes โ โ
โ โ ... โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ Result: API standards only consume context when working on APIs โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Writing Effective Constraints
The way you phrase steering rules dramatically affects AI compliance:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ POSITIVE vs NEGATIVE CONSTRAINTS โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ NEGATIVE (Less Effective) POSITIVE (More Effective) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ "Don't use any type" โ "Use explicit types or unknown" โ
โ โ
โ "Never use console.log" โ "Use the logger utility from โ
โ @/lib/logger for all output" โ
โ โ
โ "Don't write long โ "Functions should have a single โ
โ functions" responsibility and fit in โ
โ 50 lines or less" โ
โ โ
โ "Avoid callbacks" โ "Use async/await for all โ
โ asynchronous operations" โ
โ โ
โ WHY POSITIVE WORKS BETTER: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 1. Tells AI WHAT to do, not just what to avoid โ โ
โ โ 2. Provides concrete alternatives โ โ
โ โ 3. Measurable compliance (50 lines vs "not long") โ โ
โ โ 4. Reduces ambiguity ("any" vs "explicit types") โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ INCLUDE EXAMPLES: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ## Error Handling โ โ
โ โ โ โ
โ โ All async functions must use try/catch with structured โ โ
โ โ logging: โ โ
โ โ โ โ
โ โ ```typescript โ โ
โ โ async function fetchUser(id: string): Promise<User> { โ โ
โ โ try { โ โ
โ โ return await db.users.findUnique({ where: { id } }); โ โ
โ โ } catch (error) { โ โ
โ โ logger.error('Failed to fetch user', { id, error }); โ โ
โ โ throw new AppError('USER_NOT_FOUND', error); โ โ
โ โ } โ โ
โ โ } โ โ
โ โ ``` โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Real-World Analogy: The Style Guide
Think of steering files like a comprehensive style guide for a publication:
| Publication Element | Steering Equivalent |
|---|---|
| AP Stylebook | Global steering (org-wide) |
| Brand Guidelines | Workspace steering (project-specific) |
| Editorial Notes | Conditional steering (context-specific) |
| Examples in Guide | Code snippets in steering files |
Just as writers internalize style guides, Kiro internalizes your steering rules.
Complete Project Specification
What You Are Building
A Steering Rules Engine that:
- Provides Complete Templates: Ready-to-use steering files for TypeScript projects
- Validates Steering Files: Checks for effectiveness and conflicts
- Tests Rule Enforcement: Verifies AI follows steering rules
- Manages Scope: Tools for global vs. workspace steering
- Generates Documentation: Auto-document steering rules
Architecture Overview
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STEERING ENGINE ARCHITECTURE โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ CLI Interface โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ steering-engine [command] โ โ โ
โ โ โ โ โ โ
โ โ โ Commands: โ โ โ
โ โ โ init Setup steering for project โ โ โ
โ โ โ validate Check steering files for issues โ โ โ
โ โ โ test Verify rules are enforced โ โ โ
โ โ โ list Show all active steering rules โ โ โ
โ โ โ effective Show merged rules for current context โ โ โ
โ โ โ share Export steering for team โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Steering Manager โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ โข Load global steering (~/.kiro/steering/) โ โ โ
โ โ โ โข Load workspace steering (.kiro/steering/) โ โ โ
โ โ โ โข Parse front matter โ โ โ
โ โ โ โข Resolve conflicts โ โ โ
โ โ โ โข Apply conditional loading โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Validators โ โ
โ โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โ
โ โ โ Syntax Checker โ โ Conflict Finder โ โ Quality Scorer โโ โ
โ โ โ โ โ โ โ โโ โ
โ โ โ โข Front matter โ โ โข Global vs โ โ โข Positive โโ โ
โ โ โ โข Markdown โ โ workspace โ โ framing โโ โ
โ โ โ โข Code blocks โ โ โข Rule overlap โ โ โข Examples โโ โ
โ โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Rule Tester โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ โข Generate test prompts that should violate rules โ โ โ
โ โ โ โข Send to Kiro with steering active โ โ โ
โ โ โ โข Check if AI refuses or complies with rules โ โ โ
โ โ โ โข Report enforcement rate โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Expected Deliverables
steering-engine/
โโโ src/
โ โโโ index.ts # CLI entry point
โ โโโ commands/
โ โ โโโ init.ts # Setup steering
โ โ โโโ validate.ts # Check files
โ โ โโโ test.ts # Test enforcement
โ โ โโโ list.ts # List rules
โ โ โโโ effective.ts # Show merged rules
โ โโโ manager/
โ โ โโโ SteeringLoader.ts # Load and parse
โ โ โโโ ScopeResolver.ts # Merge global/workspace
โ โโโ validators/
โ โ โโโ SyntaxChecker.ts # Validate format
โ โ โโโ ConflictFinder.ts # Find conflicts
โ โ โโโ QualityScorer.ts # Rate effectiveness
โ โโโ templates/
โ โโโ typescript/
โ โ โโโ product.md
โ โ โโโ tech.md
โ โ โโโ structure.md
โ โ โโโ security.md
โ โ โโโ api-standards.md
โ โ โโโ testing.md
โ โโโ python/
โ โโโ tech.md
โ โโโ ...
โโโ tests/
โ โโโ loader.test.ts
โ โโโ validator.test.ts
โโโ package.json
โโโ README.md
# Creates in target project:
.kiro/steering/
โโโ product.md
โโโ tech.md
โโโ structure.md
โโโ security.md
โโโ api-standards.md
โโโ testing.md
Solution Architecture
Comprehensive Steering Templates
tech.md for TypeScript:
---
inclusion: always
---
# Technology Stack
## Languages & Frameworks
- **Language**: TypeScript 5.x in strict mode
- **Runtime**: Node.js 20+ or Bun 1.0+
- **Framework**: Express.js for APIs, React 18 for UI
- **Testing**: Vitest for unit tests, Playwright for E2E
## TypeScript Standards
### Type Safety
Use explicit types for all function parameters and return values:
```typescript
// CORRECT
function calculateTotal(items: CartItem[]): number {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
// INCORRECT - implicit any
function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
Validation
Use zod for runtime validation of external data:
import { z } from 'zod';
const UserSchema = z.object({
id: z.string().uuid(),
email: z.string().email(),
role: z.enum(['admin', 'user', 'guest'])
});
type User = z.infer<typeof UserSchema>;
function processUser(data: unknown): User {
return UserSchema.parse(data);
}
Error Handling
All async functions must use try/catch with structured logging:
import { logger } from '@/lib/logger';
import { AppError } from '@/lib/errors';
async function fetchUser(id: string): Promise<User> {
try {
const user = await db.users.findUnique({ where: { id } });
if (!user) {
throw new AppError('USER_NOT_FOUND', `User ${id} not found`);
}
return user;
} catch (error) {
logger.error('Failed to fetch user', { id, error });
throw error instanceof AppError ? error : new AppError('DB_ERROR', error);
}
}
Forbidden Patterns
- Do NOT use
anytype; useunknownand narrow with type guards - Do NOT use callbacks; use async/await for all asynchronous operations
- Do NOT use
console.login production code; use the logger utility - Do NOT use
var; useconstby default,letonly when reassignment needed - Do NOT commit
.envfiles; use.env.exampleas template ```
security.md:
---
inclusion: always
---
# Security Standards
## Authentication & Authorization
### Token Handling
- JWT tokens MUST expire after 1 hour
- Refresh tokens MUST be stored in httpOnly cookies
- NEVER store tokens in localStorage or sessionStorage
```typescript
// CORRECT: httpOnly cookie
res.cookie('refreshToken', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days
});
// INCORRECT: localStorage
localStorage.setItem('token', token); // NEVER do this
Authorization
All API endpoints MUST verify user permissions:
async function updateUser(req: Request, res: Response) {
const { userId } = req.params;
// ALWAYS check authorization
if (req.user.id !== userId && req.user.role !== 'admin') {
throw new ForbiddenError('Cannot update other users');
}
// Proceed with update...
}
Data Protection
Query Safety
ALWAYS use parameterized queries to prevent SQL injection:
// CORRECT: Parameterized
const user = await db.query(
'SELECT * FROM users WHERE id = $1',
[userId]
);
// INCORRECT: String concatenation
const user = await db.query(
`SELECT * FROM users WHERE id = '${userId}'` // SQL INJECTION RISK
);
Sensitive Data
- NEVER log PII (emails, names, addresses)
- NEVER include secrets in error messages
- ALWAYS sanitize user input before display (XSS prevention)
// Logging - mask sensitive data
logger.info('User action', {
userId: user.id,
email: maskEmail(user.email), // shows j***@example.com
action: 'login'
});
Forbidden Operations
- NEVER disable HTTPS in production
- NEVER use
eval()ornew Function() - NEVER expose stack traces to users
- NEVER store passwords in plain text
- NEVER commit credentials to git ```
Steering Validation Logic
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ VALIDATION CHECKS โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ 1. SYNTAX VALIDATION โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โข Valid YAML front matter โ โ
โ โ โข Proper markdown structure โ โ
โ โ โข Code blocks have language tags โ โ
โ โ โข No broken links to other files โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ 2. CONFLICT DETECTION โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Global tech.md: "Use Express.js" โ โ
โ โ Workspace tech.md: "Use Fastify" โ โ
โ โ โ WARNING: Conflicting framework requirements โ โ
โ โ โ โ
โ โ Global security.md: "Tokens expire in 1 hour" โ โ
โ โ Workspace security.md: "Tokens expire in 24 hours" โ โ
โ โ โ WARNING: Security policy conflict โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ 3. QUALITY SCORING โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Criteria Points โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ Has code examples +2 per example โ โ
โ โ Uses positive framing +1 per rule โ โ
โ โ Uses negative framing -1 per rule โ โ
โ โ Has measurable criteria +1 per rule โ โ
โ โ Has front matter +1 โ โ
โ โ Has clear sections +1 โ โ
โ โ โ โ
โ โ Score interpretation: โ โ
โ โ โข 0-5: Needs improvement โ โ
โ โ โข 6-10: Adequate โ โ
โ โ โข 11-15: Good โ โ
โ โ โข 16+: Excellent โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Rule Enforcement Testing
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ENFORCEMENT TEST FLOW โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Steering rule: "Never use console.log; use logger utility" โ
โ โ
โ TEST PROMPT: โ
โ "Add a debug statement to print the user object" โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ EXPECTED RESPONSE (rule followed): โ โ
โ โ โ โ
โ โ "I'll add a debug statement using the logger utility: โ โ
โ โ logger.debug('User object', { user });" โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ UNEXPECTED RESPONSE (rule violated): โ โ
โ โ โ โ
โ โ "I'll add a console.log: โ โ
โ โ console.log(user);" โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ AUTOMATED TEST: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ function testRule(rule: Rule): TestResult { โ โ
โ โ const prompt = generateViolationPrompt(rule); โ โ
โ โ const response = await kiro.send(prompt); โ โ
โ โ โ โ
โ โ // Check if response violates rule โ โ
โ โ const violated = checkForViolation(response, rule); โ โ
โ โ โ โ
โ โ return { โ โ
โ โ rule: rule.name, โ โ
โ โ passed: !violated, โ โ
โ โ response: response โ โ
โ โ }; โ โ
โ โ } โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Phased Implementation Guide
Phase 1: Template Creation (3-4 hours)
Goal: Create comprehensive steering templates
What to Build:
- Complete tech.md template
- Security.md template
- Structure.md template
- At least 3 domain-specific templates
Hint 1: Start with your actual project standards:
# Document what you repeatedly tell AI
cat ~/.bash_history | grep -i "always use\|never use\|make sure" | sort | uniq
Hint 2: Include both rules and examples:
## Naming Conventions
### Files
- Components: `PascalCase.tsx` (e.g., `UserProfile.tsx`)
- Utilities: `camelCase.ts` (e.g., `formatDate.ts`)
- Constants: `SCREAMING_SNAKE_CASE.ts` (e.g., `API_ENDPOINTS.ts`)
### Variables
```typescript
// Components - PascalCase
const UserProfile = () => { ... };
// Hooks - camelCase starting with 'use'
const useUserData = () => { ... };
// Constants - SCREAMING_SNAKE_CASE
const MAX_RETRIES = 3;
Validation Checkpoint: You have 5+ steering files with examples.
Phase 2: Validation System (4-5 hours)
Goal: Build validators for steering files
What to Build:
- Front matter parser and validator
- Conflict detection between scopes
- Quality scoring algorithm
Hint 1: Parse YAML front matter:
import matter from 'gray-matter';
interface SteeringFrontMatter {
inclusion?: 'always' | 'agent' | 'manual' | 'path';
agents?: string[];
paths?: string[];
}
function parseSteeringFile(content: string): {
frontMatter: SteeringFrontMatter;
body: string;
} {
const { data, content: body } = matter(content);
return {
frontMatter: data as SteeringFrontMatter,
body
};
}
Hint 2: Detect conflicting rules:
function findConflicts(
global: SteeringFile[],
workspace: SteeringFile[]
): Conflict[] {
const conflicts: Conflict[] = [];
for (const ws of workspace) {
const globalMatch = global.find(g => g.name === ws.name);
if (globalMatch) {
// Same file exists in both scopes
const diffs = findDifferences(globalMatch.content, ws.content);
if (diffs.length > 0) {
conflicts.push({
file: ws.name,
global: globalMatch.content,
workspace: ws.content,
differences: diffs
});
}
}
}
return conflicts;
}
Hint 3: Score quality with heuristics:
function scoreQuality(content: string): QualityReport {
const score = {
total: 0,
breakdown: {} as Record<string, number>
};
// Check for code examples
const codeBlocks = (content.match(/```/g) || []).length / 2;
score.breakdown.codeExamples = Math.min(codeBlocks * 2, 10);
score.total += score.breakdown.codeExamples;
// Check for positive framing
const positivePatterns = /\b(use|prefer|always|should|must|ensure)\b/gi;
const negativePatterns = /\b(don't|never|avoid|do not|cannot)\b/gi;
const positive = (content.match(positivePatterns) || []).length;
const negative = (content.match(negativePatterns) || []).length;
score.breakdown.framing = Math.max(0, positive - negative);
score.total += Math.min(score.breakdown.framing, 5);
// Check for measurable criteria
const measurable = /\b(\d+ (lines?|characters?|%|percent|seconds?|ms))\b/gi;
score.breakdown.measurable = (content.match(measurable) || []).length;
score.total += Math.min(score.breakdown.measurable, 5);
return score;
}
Validation Checkpoint: Running steering-engine validate shows issues and quality scores.
Phase 3: Testing and CLI (4-5 hours)
Goal: Build enforcement testing and CLI
What to Build:
- Rule enforcement tester
- Full CLI interface
- Team sharing export
Hint 1: Generate violation prompts from rules:
function generateViolationPrompt(rule: string): string {
// Parse the rule to understand what it forbids
const patterns = {
'console.log': 'Add a debug statement to log the current state',
'any type': 'Add a function that accepts any argument',
'var ': 'Declare a counter variable',
'callback': 'Add an async operation to fetch data'
};
for (const [pattern, prompt] of Object.entries(patterns)) {
if (rule.toLowerCase().includes(pattern)) {
return prompt;
}
}
return 'Generate code that might violate the project standards';
}
Hint 2: Check responses for violations:
function checkForViolation(response: string, rule: Rule): boolean {
// Extract code from response
const codeBlocks = response.match(/```[\s\S]*?```/g) || [];
const code = codeBlocks.join('\n');
// Check for violation patterns
for (const pattern of rule.violationPatterns) {
if (new RegExp(pattern, 'i').test(code)) {
return true; // Violation found
}
}
return false; // No violation
}
Hint 3: Export for team sharing:
async function exportForTeam(outputPath: string): Promise<void> {
const steeringDir = '.kiro/steering';
const files = await glob(`${steeringDir}/**/*.md`);
// Create a single merged document
let output = '# Team Steering Rules\n\n';
output += `Generated: ${new Date().toISOString()}\n\n`;
for (const file of files) {
const content = await fs.readFile(file, 'utf8');
const { frontMatter, body } = parseSteeringFile(content);
output += `## ${path.basename(file)}\n\n`;
output += body + '\n\n---\n\n';
}
await fs.writeFile(outputPath, output);
console.log(`Exported to ${outputPath}`);
}
Validation Checkpoint: Full CLI works, tests pass, team export generates correctly.
Testing Strategy
Unit Tests
// tests/validator.test.ts
describe('Steering Validator', () => {
describe('Front Matter Parsing', () => {
it('parses valid front matter', () => {
const content = `---
inclusion: always
---
# Rules`;
const { frontMatter } = parseSteeringFile(content);
expect(frontMatter.inclusion).toBe('always');
});
it('handles missing front matter', () => {
const content = '# Rules\n\nSome rules here';
const { frontMatter, body } = parseSteeringFile(content);
expect(frontMatter).toEqual({});
expect(body).toContain('# Rules');
});
});
describe('Quality Scoring', () => {
it('scores higher for code examples', () => {
const withExamples = `# Rules\n\`\`\`typescript\nconst x = 1;\n\`\`\``;
const withoutExamples = '# Rules\n\nNo examples here';
const scoreWith = scoreQuality(withExamples);
const scoreWithout = scoreQuality(withoutExamples);
expect(scoreWith.total).toBeGreaterThan(scoreWithout.total);
});
it('penalizes negative framing', () => {
const positive = 'Always use strict mode';
const negative = 'Never use any type. Do not use var.';
const scorePos = scoreQuality(positive);
const scoreNeg = scoreQuality(negative);
expect(scorePos.breakdown.framing).toBeGreaterThan(scoreNeg.breakdown.framing);
});
});
});
Integration Tests
describe('Steering Integration', () => {
it('detects conflicts between global and workspace', async () => {
// Setup
await fs.writeFile(
path.join(HOME, '.kiro/steering/tech.md'),
'Use Express.js for APIs'
);
await fs.writeFile(
'.kiro/steering/tech.md',
'Use Fastify for APIs'
);
// Test
const result = await validateSteering();
expect(result.conflicts).toHaveLength(1);
expect(result.conflicts[0].file).toBe('tech.md');
});
it('merges non-conflicting rules correctly', async () => {
const effective = await getEffectiveRules();
// Global rules should apply when no workspace override
expect(effective).toContain('Global rule');
// Workspace rules should override
expect(effective).toContain('Workspace override');
});
});
Common Pitfalls and Debugging
Pitfall 1: Rules Not Applied
Symptom: AI ignores steering rules
Cause: Front matter misconfigured or file not in correct location
Debug:
# Check if steering files are loaded
kiro-cli /steering show
# Verify file locations
ls -la .kiro/steering/
ls -la ~/.kiro/steering/
Solution: Ensure files are in correct directory with proper front matter.
Pitfall 2: Too Many Tokens
Symptom: Context warnings, steering files consuming too much space
Cause: Steering files too verbose or all set to inclusion: always
Debug:
// Count tokens in steering
const files = await glob('.kiro/steering/*.md');
for (const file of files) {
const content = await fs.readFile(file, 'utf8');
const tokens = countTokens(content);
console.log(`${file}: ${tokens} tokens`);
}
Solution: Use conditional loading:
---
inclusion: path
paths: ["src/api/**"]
---
Pitfall 3: Conflicting Rules
Symptom: AI produces inconsistent output
Cause: Global and workspace rules contradict
Debug:
steering-engine effective # Show merged rules
steering-engine validate # Check for conflicts
Solution: Workspace should completely override global when they conflict:
<!-- workspace tech.md -->
---
override: true # Completely replaces global tech.md
---
Extensions and Challenges
Extension 1: Rule Inheritance
Create base templates that projects extend:
---
extends: "@company/base-typescript"
---
# Project-specific overrides
Extension 2: Dynamic Rules
Rules that change based on context:
---
inclusion: dynamic
condition: "git.branch === 'main'"
---
# Production Branch Rules
When on main branch, additional safety checks apply:
- All changes require tests
- No direct commits (PRs only)
Extension 3: Rule Analytics
Track which rules are most often violated:
interface RuleMetrics {
ruleId: string;
violations: number;
lastViolation: Date;
commonContexts: string[];
}
function trackViolation(rule: string, context: string): void {
// Log to analytics
}
Challenge: AI Rule Suggester
Use AI to suggest new steering rules based on code review feedback:
Input: "You used console.log again. Please use the logger."
Suggested Rule: "Use logger utility (@/lib/logger) instead of console.log for all output"
Real-World Connections
How Professionals Use This
- Enterprise Teams: Share steering configs via MDM/group policy
- Open Source: Include steering in repo for contributor consistency
- Consulting: Bring steering templates to client projects
- Education: Use steering to enforce learning patterns
Industry Patterns
Configuration as Code: Steering files are declarative configuration, similar to .eslintrc, tsconfig.json, or Dockerfile.
Policy as Code: Like AWS Config Rules or Open Policy Agent, steering encodes policies that govern behavior.
Documentation as Code: Living documentation that actively influences the system.
Self-Assessment Checklist
Understanding Verification
- Can you explain the difference between product.md and tech.md?
- product.md: What weโre building (vision, users, priorities)
- tech.md: How we build it (languages, patterns, tools)
- How does scope resolution work?
- Workspace steering has priority
- Same-named files: workspace overrides global
- Different files: both apply
- Why is positive framing more effective?
- Tells AI what TO do, not just what to avoid
- Provides concrete alternatives
- More measurable compliance
- When should you use conditional loading?
- Domain-specific rules (API, UI, tests)
- Large rule sets that donโt always apply
- Performance-sensitive contexts
Skill Demonstration
- I can create comprehensive steering files
- I can validate steering for quality and conflicts
- I can test rule enforcement
- I can manage global vs. workspace scope
- I can share steering configurations with teams
Interview Preparation
Be ready to answer:
- โHow would you encode coding standards for an AI assistant?โ
- โWhatโs the difference between positive and negative constraints?โ
- โHow do you balance flexibility with enforcement?โ
- โHow would you share coding standards across a team?โ
Recommended Reading
| Topic | Resource | Why It Helps |
|---|---|---|
| Clean Code | โClean Codeโ by Martin, Ch. 1-5 | Standards to encode |
| Configuration | โThe Pragmatic Programmerโ Ch. 4 | Config management patterns |
| Documentation | โDocs for Developersโ by Gentle et al. | Writing effective docs |
| Policy | โEffective TypeScriptโ by Vanderkam | TypeScript conventions |
| Team Standards | Google Style Guides | Industry-standard patterns |
What Success Looks Like
When you complete this project, you will have:
- Comprehensive Steering: Full set of steering files for your stack
- Validation Tools: CLI to check and score steering quality
- Test Framework: Verify AI follows your rules
- Team Sharing: Export and distribute steering configs
- Deep Understanding: Know how to guide AI behavior persistently
Next Steps: Move to Project 6 (MCP Server Connector) to learn how to integrate external tools with Kiro.