Project 2: “The Steering Enforcer” — Prompt Engineering
| Attribute | Value |
|---|---|
| File | KIRO_CLI_MASTERY.md |
| Main Programming Language | Markdown |
| Coolness Level | Level 3: Genuinely Clever |
| Business Potential | 3. Service & Support (Team Standardization) |
| Difficulty | Level 1: Beginner |
| Knowledge Area | Prompt Engineering / Context Management |
What you’ll build: A set of hierarchical steering files (tech.md, product.md, style.md) for a dummy project. Verify that Kiro refuses output that violates these rules.
Why it teaches Steering: This is the foundation of enterprise AI: constrain creativity to adhere to strict invariants.
Core challenges you’ll face:
- Writing positive constraints.
- Structuring intent vs implementation.
Success criteria:
- A test prompt fails until you align it with steering.
Real World Outcome
You’ll have a set of steering files that enforce your coding standards automatically. When you ask Kiro to write code, it will follow your rules without you having to remind it every time.
Example Output:
$ cd my-web-app
$ ls .kiro/steering/
tech.md product.md style.md
$ cat .kiro/steering/tech.md
# Technical Standards
## TypeScript
- All functions must have explicit return types
- Use `interface` for public APIs, `type` for internal code
- Prefer functional patterns over classes
- No `any` types except in migration code (mark with TODO)
## React
- Functional components only (no class components)
- Use custom hooks for all side effects
- Colocate styles with components
- Prefer server components (mark client with "use client")
## Testing
- Unit test coverage minimum: 80%
- Integration tests for all API endpoints
- Use React Testing Library for component tests
$ kiro chat
You: "Create a new React component for displaying user profiles"
Kiro: [reads .kiro/steering/tech.md, product.md, style.md]
Following your steering rules:
✓ Functional component with TypeScript
✓ Explicit return type
✓ Colocated styles
✓ Server component (no client-side state)
interface UserProfileProps {
userId: string;
}
export function UserProfile({ userId }: UserProfileProps): React.ReactElement {
// Component implementation following your standards...
}
You: "Actually use a class component"
Kiro: I cannot do that. Your tech.md steering file explicitly states "Functional components only (no class components)". If you need to override this rule for a specific case, you should either:
1. Update .kiro/steering/tech.md to allow exceptions
2. Provide a strong justification for why this component requires a class
3. Use /steer off to temporarily disable steering (not recommended)
Would you like me to explain why functional components are preferred in your standards?
Your .kiro/steering/tech.md file enforces project rules across all sessions.
The Core Question You’re Answering
“How do I make Kiro follow my team’s coding standards, architectural patterns, and best practices without explaining them in every single conversation?”
Before building this, understand: Most AI tools require constant reminders about your conventions. Kiro’s steering system solves this by loading markdown files into every session’s context. This project teaches you how to encode knowledge that persists.
Concepts You Must Understand First
Stop and research these before coding:
- Steering vs Prompts
- How does steering differ from the agent’s base prompt?
- When should a rule go in steering vs in a custom agent’s prompt field?
- How does steering interact with the model’s training?
- Book Reference: “The Pragmatic Programmer” by Hunt & Thomas - Ch. 7 (While You Are Coding)
- Markdown as Configuration
- Why does Kiro use
.mdfiles instead of JSON for steering? - How does markdown structure (headings, lists, code blocks) affect AI understanding?
- What’s the difference between declarative rules and example-based rules?
- Reference: Kiro Steering Guide
- Why does Kiro use
- Constraint Design
- How do you write constraints that are specific enough to enforce but flexible enough to allow creativity?
- What’s the difference between “never use X” vs “prefer Y over X”?
- How do you test that a steering rule actually works?
- Reference: Best Kiro Steering Rules (2025)
Questions to Guide Your Design
Before implementing, think through these:
- File Organization
- Should you have one monolithic
steering.mdor separate files per domain? - How do you decide what belongs in
tech.mdvsproduct.mdvsstyle.md? - Should steering files be committed to version control?
- Should you have one monolithic
- Rule Specificity
- How specific should rules be? (“Use TypeScript” vs “All functions must have explicit return types”)
- Should you include examples of good code, bad code, or both?
- How do you handle edge cases and exceptions?
- Team Alignment
- If this is a team project, who has authority to add/change steering rules?
- How do you communicate steering changes to team members?
- Should different team members have different local steering overrides?
Thinking Exercise
Exercise: Design a Steering Hierarchy
You’re building a full-stack TypeScript monorepo with:
- 2 frontend apps (React + Next.js)
- 1 backend API (Express)
- Shared libraries (utils, types, components)
Design the steering file structure. For each file, list 3-5 rules it should enforce.
.kiro/steering/
├── _______________.md → Rules for: _______________
├── _______________.md → Rules for: _______________
└── _______________.md → Rules for: _______________
Questions while designing:
- Which rules apply globally vs per-domain?
- How do you prevent contradictory rules (e.g., frontend prefers X, backend requires Y)?
- What happens when a prompt violates multiple steering files?
- Should shared libraries have their own steering file?
The Interview Questions They’ll Ask
- “Explain the difference between a steering file and a custom agent’s prompt.”
- “How would you enforce a team coding standard using Kiro’s steering system?”
- “What are the tradeoffs between specific rules (‘no any types’) vs general principles (‘write type-safe code’)?”
- “How do you test that a steering file is working correctly?”
- “When would you use global steering (~/.kiro/steering/) vs project steering (.kiro/steering/)?”
- “What security considerations exist when writing steering files?”
Hints in Layers
Hint 1: Start with Examples, Not Rules Don’t write abstract rules like “write clean code.” Instead, paste examples of code you like and code you don’t like. The AI learns patterns from examples better than from principles.
Hint 2: Use Hierarchical Markdown Organize steering with H2 headers for domains (## React, ## TypeScript) and H3 for specific topics (### Component Structure, ### Type Safety). This helps Kiro understand which rules apply when.
Hint 3: Test with Violations After creating a steering file, intentionally ask Kiro to violate a rule. Example: If you wrote “no class components,” ask “create a class-based React component.” Verify Kiro refuses or warns you.
Hint 4: Version Control Your Steering
Treat .kiro/steering/ like code. Commit it, review changes in PRs, and document why rules exist. This creates a living document of your team’s standards.
Books That Will Help
| Topic | Book | Chapter |
|---|---|---|
| Writing effective constraints | “Clean Code” by Robert C. Martin | Ch. 17: Smells and Heuristics |
| Team coding standards | “The Pragmatic Programmer” by Hunt & Thomas | Ch. 7: While You Are Coding |
| Documentation best practices | “Docs for Developers” by Nunez & Seward | Ch. 4: Writing Technical Documentation |
Common Pitfalls & Debugging
Problem 1: “Kiro ignores my steering rules”
- Why: Steering file has syntax errors or isn’t in the correct directory
- Fix: Verify file is at
.kiro/steering/*.md(not~/.kiro/steering/for project-specific rules) - Quick test:
ls .kiro/steering/should list your files;cat .kiro/steering/tech.mdshould show valid markdown
Problem 2: “Kiro follows steering too rigidly”
- Why: Rules are written as absolute prohibitions (“never use X”) instead of preferences
- Fix: Soften language: “Prefer functional components. Use class components only for error boundaries or third-party library requirements.”
- Quick test: Ask Kiro to explain when it’s acceptable to violate a rule
Problem 3: “Contradictory steering files”
- Why:
tech.mdsays “use Prettier with 2 spaces” butstyle.mdsays “4 space indentation” - Fix: Consolidate related rules into a single file, or establish precedence (e.g., tech.md overrides style.md)
- Quick test:
grep -r "space" .kiro/steering/to find conflicting rules
Problem 4: “Steering files are too long (5000+ lines)”
- Why: Trying to document every pattern in one file
- Fix: Split by domain:
react.md,typescript.md,testing.md,api-design.md - Quick test: Each steering file should be < 500 lines; if longer, split into sub-domains
Definition of Done
- Created at least 3 steering files in
.kiro/steering/directory - Each file uses hierarchical markdown (H2 sections, H3 subsections)
- Includes both positive examples (“Do this”) and negative examples (“Don’t do this”)
- At least one rule includes code snippets showing preferred vs discouraged patterns
- Tested by asking Kiro to violate a rule—it should refuse or warn
- Documented why each major rule exists (rationale for future developers)
- Steering files are committed to version control
- Team members can override steering locally if needed (using ~/.kiro/steering/)