The Blueprint · 30 min mission
Kiro Guide: Spec-Governed Agentic Engineering
Go zero-to-hero on Kiro across IDE, CLI, and Web — the real syntax for specs, EARS criteria, steering, hooks, and MCP, with interactive builders that emit paste-ready `.kiro/` files.
On this page
Kiro is an agentic development tool from AWS that comes in three surfaces — a VS Code-style IDE, a terminal CLI (kiro-cli), and a browser Web agent that opens pull requests. What makes it different from "chat that writes code" is the workflow it pushes you toward: instead of prompting your way to a diff, you turn an idea into a committed, reviewable spec — requirements.md, design.md, tasks.md checked into your repo — and only then write code against it.
The 15-year-old version: normal AI chat is asking a clever helper to start typing from a one-line description. Kiro first makes the helper write the plan, the checklist, and the acceptance tests, gets you to approve them, and then builds — ticking off the checklist while you watch the diff.
The senior version: Kiro is two interaction axes layered over those three surfaces. The first axis is Vibe vs Spec — a vibe session is conversational and good for exploration and small fixes; a spec session is the structured requirements → design → tasks loop with tracked execution. The second axis is Autopilot vs Supervised — autopilot acts end-to-end, supervised yields after each edit for hunk-level review. The docs state that supervised mode is a code-review convenience, not a security boundary.
Reach for Kiro's spec workflow when a change has several requirements, crosses files, needs review, or has real drift risk. Stay in vibe chat — or another editor agent — when the task is tiny, exploratory, or better handled by an inline edit than by a durable artifact you then have to maintain.
How a senior reads Kiro: four control planes
For an experienced engineer the question isn't "can it write code" but "can it preserve my intent while it changes a real repo?" That reframes Kiro as four control planes you operate at once:
Intent — specs, bugfix specs, Quick Plan, requirements analysis, #spec. This is where scope, acceptance criteria, and traceability live.
Context — steering, AGENTS.md, skills, powers, open files, and retrieved docs. Drift starts here, when stale context outranks the real architecture.
Automation — hooks, CLI agents, Web autonomous mode, subagents, and the GitHub/GitLab issue→PR flow. This is what can run without you watching.
Trust — MCP provenance, sandbox policy, internet access, secrets, repo permissions, and review gates. Treat the blast radius as part of the design: write down the threat model before you grant a tool, not after.
The rest of this guide is built from that frame, with the real on-disk syntax for each plane and an interactive tool to apply it. Where Kiro's own docs only document part of a format, this guide says so rather than dressing a guess up as fact.
| Control plane | Kiro mechanisms | The question you must answer |
|---|---|---|
| Intent | Feature specs, bugfix specs, Quick Plan, requirements analysis, #spec | Can every task and diff line trace back to approved intent? |
| Context | Steering, AGENTS.md, skills, powers, retrieved docs | Which context is authoritative, stale, duplicated, or too broad? |
| Automation | Hooks, CLI agents, Web autonomous mode, subagents | What can run without a human watching — and what must pause? |
| Trust | MCP, sandbox, internet access, secrets, repo permissions | What is the blast radius if the agent follows bad context or a hostile tool? |
The spec loop, end to end
A spec session front-loads the thinking that ordinary chat hides. You supply intent and judgment; Kiro produces artifacts and runs tasks; the final check is never "it finished" — it's whether the files, tests, and diff still match the spec you approved. The loop has explicit gates, and the gates are the point.
idea → requirements → design → tasks → implementation → review
Idea
State the outcome, the user, the risk, the files in scope, and the definition of done.
Requirements
Kiro drafts numbered user stories with EARS acceptance criteria. Run requirements analysis to catch ambiguity while it is still cheap.
Design
Kiro proposes architecture, data models, and a testing strategy. Constrain it to existing modules before approving.
Tasks
Kiro breaks the design into a checklist where each leaf task back-references the requirement it satisfies (
_Requirements: 1.2_).Implementation
"Run all Tasks" executes in dependency waves — independent tasks run concurrently. Watch the diff; stop drift early.
Review
Compare the diff to the spec, run the real test suite, then sync the spec so the artifacts do not rot.
Spec lifecycle playground
Spec lifecycle playground
You are the reviewer — your gate decisions decide the drift
Walk one feature through Kiro's spec loop. Every choice you make at a gate propagates: skip requirements analysis and the ambiguities resurface as rework at implementation; flip on Quick Plan and you lose the gates entirely. Watch spec health react.
Ambiguities → code
2
Traceability
72%
Drift risk
High
Step 1 of 5 · requirements.md
Requirements
### Requirement 1: Password reset
**User Story:** As a returning user, I want to reset my
password by email, so that I can recover a locked account.
#### Acceptance Criteria
1. WHEN a user requests a reset THE SYSTEM SHALL email a
single-use token valid for a limited time.
2. THE SYSTEM SHALL handle token reuse appropriately. ⚠ vague
3. THE SYSTEM SHALL respond quickly. ⚠ vagueYour call at the requirements gate
Knowledge check
A teammate wants to use Quick Plan for a risky, multi-team feature and approve the generated tasks immediately. What is the right move?
Specs deep dive
Specs live under .kiro/specs/, one feature-named directory per spec, committed to the repo alongside the code. A feature spec holds three files; a bugfix spec swaps requirements.md for bugfix.md and keeps the other two. Spec files use no YAML front-matter — front-matter is a steering and hooks thing.
When you create a spec, Kiro asks Feature or Bug. For a feature you pick Requirements-First (requirements → design → tasks) or Design-First (design → requirements → tasks); you cannot switch later. Quick Plan produces all three in one pass with no gates.
.kiro/specs/
├── password-reset/
│ ├── requirements.md # user stories + EARS acceptance criteria
│ ├── design.md # architecture, data models, testing strategy
│ └── tasks.md # checklist; each task back-refs a requirement
├── product-catalog/
│ └── …
└── name-apostrophe-fix/
├── bugfix.md # current / expected / unchanged behavior
├── design.md
└── tasks.mdAcceptance criteria are EARS
The reason Kiro specs work is that acceptance criteria are written so a machine can verify them. Kiro's docs document one EARS form — the event-driven form:
WHEN <trigger> THE SYSTEM SHALL <observable response>Bugfix specs add two more: WHEN <condition> THEN the system SHALL <correct behavior> and … SHALL CONTINUE TO <existing behavior>. The wider EARS standard has more patterns — and they are worth knowing — but note clearly: the patterns below are the EARS standard, not all documented by Kiro. Kiro reliably emits the event form; you can write the others by hand.
| Pattern | Skeleton | Use it for |
|---|---|---|
| Event-driven *(Kiro-documented)* | WHEN <trigger> THE SYSTEM SHALL <response> | A response to a discrete event or request. |
| Unwanted behavior | IF <condition> THEN THE SYSTEM SHALL <response> | Error handling, abuse, and edge cases. |
| State-driven | WHILE <state> THE SYSTEM SHALL <response> | Behavior that holds during a mode or state. |
| Optional feature | WHERE <feature> THE SYSTEM SHALL <response> | Behavior that only applies when a feature is present. |
| Ubiquitous | THE SYSTEM SHALL <response> | An always-true invariant with no precondition. |
# Requirements Document
## Introduction
An automated password-reset flow for returning users, scoped to the auth service.
## Requirements
### Requirement 1: Password reset
**User Story:** As a returning user, I want to reset my password by email,
so that I can recover a locked account.
#### Acceptance Criteria
1. WHEN a user requests a reset THE SYSTEM SHALL email a single-use token
that expires after 30 minutes
2. IF a token is reused THEN THE SYSTEM SHALL reject the second attempt and
show "link expired"
3. WHEN three resets are requested within an hour THE SYSTEM SHALL rate-limit
further requests for that account# Design Document
## Overview
Reset flow built on the existing AuthService + MailQueue (no new top-level service).
## Architecture
- Add a PasswordResetToken store; everything else reuses current modules.
## Components and Interfaces
- POST /auth/reset/request → AuthService.issueResetToken()
- POST /auth/reset/confirm → AuthService.consumeResetToken()
## Data Models
- PasswordResetToken { hash, userId, expiresAt, usedAt }
## Error Handling
- Reused token → 410; expired → 410; over rate limit → 429.
## Testing Strategy
- One test per acceptance criterion; negative cases for reuse and expiry.# Implementation Plan: Password reset
- [x] 1. Add PasswordResetToken model and migration
- _Requirements: 1.1_
- [ ] 2. Issue + email a single-use token
- [ ] 2.1 Generate, hash, and store the token with a 30-minute expiry
- _Requirements: 1.1_
- [ ]* 2.2 Unit-test token generation and expiry
- _Requirements: 1.1_
- [ ] 3. Reject reused or expired tokens
- _Requirements: 1.2_
- [ ]* 4. Rate-limit reset requests per account
- _Requirements: 1.3_Read the format like a senior reviewer: - [ ] / - [x] track completion, decimal numbering nests sub-tasks, - [ ]* marks an optional test task, and the trailing _Requirements: 1.2_ is your traceability matrix in plain text — every leaf task names the acceptance criterion it satisfies. If a task has no requirement reference, it is scope you never approved.
Bugfix specs force you to separate three things before touching code — the current behavior that is wrong, the expected behavior that is right, and the unchanged behavior that must not regress. The bugfix design adds a root-cause section and "properties to test for," and the tasks phase generates property-based tests that prove the bug existed, the fix works, and nothing regressed.
# Bugfix Analysis
## Current Behavior (Defect)
WHEN a name contains an apostrophe THEN the system returns a 500 error
## Expected Behavior (Correct)
WHEN a name contains an apostrophe THEN the system SHALL persist the name and
return 200
## Unchanged Behavior (Regression Prevention)
WHEN an email or password is validated THEN the system SHALL CONTINUE TO apply
the existing validation rulesTwo more spec tools matter. Requirements analysis runs after requirements and before design (via the chat option or the Continue dropdown) and flags logical inconsistencies, ambiguities like "large files" or "fast response times," conflicting constraints, unstated assumptions, and missing edge cases; resolving its questions updates requirements.md. And #spec pulls a whole spec into chat — #spec:password-reset implement task 2.1, or #spec:password-reset does my implementation meet the acceptance criteria for task 3?.
The expert moves the docs imply but won't do for you: keep the spec committed so the diff and intent travel together, and run a drift detector after implementation — ask Kiro to list any file or behavior that changed outside the approved spec. A beautiful spec is a liability the moment the PR diverges from it and nobody updates it.
Good spec vs weak spec
Weak spec
Broad outcome, no named actor, criteria like "handle errors appropriately," no non-goals, no test plan. Kiro has to invent intent — and it will optimize for the wrong behavior.
Good spec
Named user, concrete triggers, EARS criteria you could write a test against, explicit non-goals, and tasks that each back-reference a requirement. Every diff line traces home.
Spec risk analyzer + EARS editor
Spec risk analyzer + EARS editor
Build acceptance criteria the right way, get a paste-ready spec pack
The hard part of a Kiro spec is writing acceptance criteria a machine can verify. Compose each one from an EARS pattern below — the editor flags vague wording — and the requirements/design/tasks files regenerate with real requirement → task traceability.
Spec type
Risk
Acceptance criteria (EARS)
all testableWHEN a user requests a reset THE SYSTEM SHALL email a single-use token that expires after 30 minutes
Testable.
IF a token is reused THEN THE SYSTEM SHALL reject the request and show "link expired"
Testable.
.kiro/specs/password-reset/requirements.md
# Requirements Document ## Introduction Password reset for returning user. I can recover a locked account ## Requirements ### Requirement 1: Password reset **User Story:** As a returning user, I want reset my password by email, so that I can recover a locked account. #### Acceptance Criteria 1. WHEN a user requests a reset THE SYSTEM SHALL email a single-use token that expires after 30 minutes2. IF a token is reused THEN THE SYSTEM SHALL reject the request and show "link expired"- Every task ends with _Requirements: N.M_ — copy it and you have a real traceability matrix.
- Run the drift detector after coding: ask Kiro to list any file changed outside this spec.
- Before "Run all Tasks", use requirements analysis to catch ambiguity while it is cheap.
- Keep the spec committed in .kiro/specs/ so the diff and intent travel together.
Knowledge check
Kiro generated a tasks.md where two tasks have no `_Requirements:` line. What does that tell you?
Steering: durable project memory
Steering is markdown that Kiro keeps in mind across sessions. Workspace steering lives in .kiro/steering/ and overrides global steering in ~/.kiro/steering/. The three foundation files — product.md, tech.md, structure.md — are generated by the Generate Steering Docs button and load on every interaction. Custom files should be scoped, so they only load when relevant.
.kiro/steering/
├── product.md # purpose, users, goals (always loaded)
├── tech.md # stack, constraints, commands (always loaded)
├── structure.md # layout, naming, architecture (always loaded)
├── api-design.md # inclusion: auto (loads when the topic is relevant)
└── frontend.md # inclusion: fileMatch (loads for matching files only)A custom file controls when it loads through front-matter at the very top of the file. There are four inclusion modes, and using the right one is how you stop always-on context from swallowing every prompt.
--- always (default): loaded into every interaction ---
---
inclusion: always
---
--- fileMatch: only when an edited file matches the glob ---
---
inclusion: fileMatch
fileMatchPattern: "components/**/*.tsx"
---
--- manual: only when you type #file-name in chat ---
---
inclusion: manual
---
--- auto: loaded when the description is semantically relevant ---
---
inclusion: auto
name: api-design
description: REST API patterns. Use when creating or modifying API endpoints.
---Note the exact keys: fileMatchPattern (not fileMatch) only applies to fileMatch mode and takes a quoted glob or an array of globs; name + description only apply to auto mode. Inside any steering file you can embed a live project file with #[[file:<path>]] — for example #[[file:api/openapi.yaml]] — so the agent reads the real contract instead of a stale paraphrase.
Kiro also reads the cross-tool AGENTS.md standard. The catch: AGENTS.md is always included and ignores inclusion modes, so keep it short and portable and keep Kiro-specific, conditionally-loaded rules in steering. The failure mode here isn't missing context — it's conflicting context, where global steering, workspace steering, and AGENTS.md give overlapping instructions. A serious team needs a steering-conflict policy: workspace beats global, every custom file has an owner, and stale files get deleted during architecture review.
Steering generator + context-budget advisor
Steering generator + context-budget advisor
Durable project memory without drowning every prompt in context
Foundation files (product/tech/structure) load on every interaction. Scoped custom files should not. Pick an inclusion mode and the front-matter regenerates with the exact keys Kiro expects — plus a read on how much always-on context you are carrying.
Custom file
inclusion mode
Always-on files
3
Context budget
Healthy
.kiro/steering/frontend-standards.md
---inclusion: fileMatchfileMatchPattern: "components/**/*.tsx"--- # frontend-standards Use semantic HTML, label every control, and keep client islands deterministic. # Embed a live file for the agent to follow:#[[file:.eslintrc.json]]- Workspace steering (.kiro/steering/) overrides global (~/.kiro/steering/) — keep machine-wide defaults thin.
- AGENTS.md is always included and ignores inclusion modes; keep Kiro-only rules in steering.
- Good: this scoped file only loads when it is relevant, not on every prompt.
- Never put secrets, tokens, or credentials in steering — it is context, not a vault.
| Layer | Use it for | Avoid |
|---|---|---|
Global steering (~/.kiro/steering/) | Personal defaults across all your repos. | Repo-specific architecture (workspace overrides it anyway). |
Workspace steering (.kiro/steering/) | This repo: product, stack, structure, testing. | One feature's scope — that is a spec. |
Custom scoped file (fileMatch / auto) | Frontend, API, security, or docs rules that load on demand. | One giant always-on standards file. |
AGENTS.md | Portable, cross-agent guidance, kept short. | Kiro-only inclusion behavior (it ignores it). |
Knowledge check
You keep pasting the same component conventions into every frontend task. Where should they live?
Hooks: event-triggered automation
Hooks run an agent prompt or a shell command when something happens. The trap that breaks people: Kiro has two hook systems with different schemas and different casing. IDE agent hooks are JSON files; CLI hooks are camelCase keys inside the agent config. Do not copy one into the other.
IDE hooks are created by asking Kiro in natural language or by filling in a form, and stored as .kiro/hooks/<name>.kiro.hook JSON. Triggers include file create/save/delete, prompt submit, agent stop, pre/post tool use, and pre/post spec-task execution. The action is either an agent prompt (askAgent, which consumes credits) or a shell command (which doesn't). One field note: steering refreshes live, but a new hook needs a Kiro restart to be discovered.
{
"enabled": true,
"name": "Auto Test on Save",
"description": "Run related tests when a TS/JS file is saved.",
"version": "1",
"when": {
"type": "fileEdited",
"patterns": ["**/*.ts", "**/*.tsx"]
},
"then": {
"type": "askAgent",
"prompt": "A code file was saved. Run the related tests and report failures only."
}
}CLI hooks live in the agent config under hooks, keyed by camelCase events — agentSpawn, userPromptSubmit, preToolUse, postToolUse, stop — each an array of { command, matcher? }. The matcher (preToolUse/postToolUse only) filters by tool: fs_read, fs_write, execute_bash, use_aws, or *. The blocking model is precise and worth memorizing: exit code 2 on preToolUse blocks the tool and returns stderr to the model; any other non-zero code is just a warning and the tool still runs; a stop hook can block the agent from ending by printing {"decision":"block","reason":"…"}.
{
"hooks": {
"agentSpawn": [ { "command": "git status" } ],
"userPromptSubmit": [ { "command": "ls -la" } ],
"preToolUse": [
{ "matcher": "execute_bash",
"command": "scripts/guard.sh" } ],
"postToolUse": [
{ "matcher": "fs_write",
"command": "cargo fmt --all" } ]
}
}
// guard.sh exits 2 to BLOCK the bash tool (stderr is returned to the model);
// any other non-zero exit only warns and the tool still runs.Hook builder (IDE + CLI)
Hook builder (IDE + CLI) with a noise budget
Real hook configs — and the casing gotcha that breaks them
Kiro has two hook systems with different schemas. IDE agent hooks are .kiro.hook JSON with camelCase trigger types; CLI hooks live in the agent config under camelCase event keys and can block on exit code 2. Pick a surface and copy the right one.
Surface
when.type (trigger)
then.type (action)
.kiro/hooks/source-audit-on-save.kiro.hook
{ "enabled": true, "name": "source-audit-on-save", "description": "Generated agent hook.", "version": "1", "when": { "type": "fileEdited", "patterns": ["lib/ai-hub/content/**/*.ts"] }, "then": { "type": "askAgent", "prompt": "A guide file was saved. Flag any factual claim with no source URL and any placeholder text. Suggest edits; do not auto-apply." }}Blocking behavior
An agent-prompt (askAgent) hook adds a prompt and consumes credits — it advises, it does not hard-block.
- A hook that fires on every save and returns generic advice gets ignored. Scope it by glob and keep output to blocking issues.
- Reserve blocking (exit code 2 on preToolUse) for protected paths, secrets, dangerous commands, or missing tests.
- IDE events are camelCase and IDE hooks need a Kiro restart to be discovered; CLI events are camelCase too — do not mix them.
- Test it: trigger a matching case, a non-matching case, and one known-bad case before sharing it with a team.
Knowledge check
You wrote a CLI hook with the event name `PreToolUse` and it never fires. Why?
MCP, skills, powers — and which one to reach for
These four mechanisms solve different problems, and the classic mistake is using the most powerful one for everything. MCP connects Kiro to external tools and data. Skills package a reusable procedure as portable instructions. Powers bundle MCP tools with guidance and steering so they install and load together. (Steering and hooks, covered above, round out the set.)
MCP config lives in .kiro/settings/mcp.json (workspace) and ~/.kiro/settings/mcp.json (user); both merge, workspace wins. The transport is implicit — command means a local stdio server, url means a remote one. There is no type or transport key, and no top-level timeout.
{
"mcpServers": {
"web-search": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-bravesearch"],
"env": { "BRAVE_API_KEY": "${BRAVE_API_KEY}" },
"disabled": false,
"autoApprove": []
},
"github": {
"url": "https://api.github.com/mcp",
"oauth": { "clientId": "your-app-client-id" },
"oauthScopes": ["repo", "user"],
"disabledTools": ["delete_repo"]
}
}
}MCP is the sharpest edge in the whole tool: an MCP server is third-party code that can read secrets, run commands outside the sandbox, and exfiltrate data. Kiro only expands env vars you've explicitly allowed and warns on the rest, but the governing rule is yours to enforce — apply least privilege, autoApprove only narrow, read-only, trusted tools, and chmod 600 your mcp.json so secrets don't leak. Name the mcp risk before you connect, not after.
Skills are an open-standard procedure package: .kiro/skills/<name>/SKILL.md plus optional scripts/, references/, and assets/. The SKILL.md front-matter needs name (matching the folder) and description (which decides when it activates, by progressive disclosure). Powers go further: a power-<name>/ folder with POWER.md, an mcp.json, and a steering/ directory, where keywords in POWER.md drive activation. The reason Powers exist is context economy — raw MCP loads every tool definition up front (five servers can be ~100+ tool defs and tens of thousands of tokens before your first prompt), while a Power loads tools on demand.
# .kiro/skills/pr-review/SKILL.md
---
name: pr-review
description: Review PRs for quality, security, and test coverage. Use when reviewing PRs.
---
# PR review
1. Check for security vulnerabilities
2. Verify error handling
3. Confirm test coverage
# power-supabase/POWER.md
---
name: "supabase"
displayName: "Supabase with local CLI"
description: "Build fullstack apps with Supabase Postgres, auth, storage, realtime"
keywords: ["database", "postgres", "auth", "storage", "supabase"]
author: "Supabase"
---| Mechanism | Reach for it when | Lives in |
|---|---|---|
| Spec | A scoped change needs requirements, design, tasks, and review. | .kiro/specs/<feature>/ |
| Steering | Kiro needs durable project or team context. | .kiro/steering/*.md |
| Skill | A reusable procedure should be discoverable and portable. | .kiro/skills/<name>/SKILL.md |
| Power | Tools + guidance should install and load together on demand. | power-<name>/ (POWER.md + mcp.json + steering) |
| MCP | The agent needs a live external tool or data source. | .kiro/settings/mcp.json |
| Hook | An event should trigger a prompt or command. | IDE .kiro/hooks/*.kiro.hook · CLI agent config |
Mechanism selector
Mechanism selector
Pick the smallest Kiro mechanism that does the job
The classic mistake is reaching for MCP or a Power when steering or a skill would do. Answer what the work actually needs and get the minimal mechanism, the file it lives in, and what not to use.
Use
Steering
It is a durable project or team standard the agent should keep in mind.
.kiro/steering/*.md (inclusion: always | fileMatch | manual | auto)
- Do not put one-off feature scope here — that belongs in a spec.
- Use fileMatch for domain rules so always-on context stays small.
MCP risk rule
Whenever the answer touches MCP or a Power, name the blast radius first: what data the server can read, what it can write, and the rollback path. Grant least privilege, deny unrelated tools, and never auto-approve write tools.
Knowledge check
You want Kiro to call an internal issue-tracker API and follow a team runbook whenever it does. Which mechanism fits best?
CLI, IDE, Web, and subagents
The same spec/steering/hook/MCP model runs across all three surfaces; pick the surface by the review model you need.
Kiro CLI (kiro-cli chat) is the terminal surface: headless review, custom agents, and scriptable validation. Use --no-interactive for one-shot runs and pipe diffs straight in. Custom agents are JSON in .kiro/agents/<name>.json with keys like tools, allowedTools, toolsSettings, resources, hooks, and mcpServers — and resources is how you surface steering to a CLI agent.
# Review a diff with read-only tools; findings only, no edits.
git diff | kiro-cli chat --no-interactive --trust-tools=read,grep \
"Review these changes for bugs, missing tests, and security risk."
# Run a named custom agent on a one-shot task.
kiro-cli chat --no-interactive --agent reviewer "Audit src/auth for unsafe input handling"{
"name": "reviewer",
"description": "Read-only repo reviewer",
"tools": ["read", "grep", "@git/git_status"],
"allowedTools": ["read", "grep"],
"resources": [
"file://README.md",
"file://.kiro/steering/**/*.md"
],
"prompt": "You are a senior reviewer. Report findings first; never edit unless asked.",
"model": "claude-sonnet-4"
}Kiro Web is a different trust boundary from the local IDE — it clones your repo into a sandbox and opens PRs. It is preview-only and limited to certain accounts and regions. It runs in two modes: collaborative (the default — it iterates with you and opens a branch/PR on request) and autonomous mode (it owns the outcome through a Clarification → Planning → Execution → Completion arc, and even picks the model). From a GitHub issue you trigger it with the kiro label or a /kiro comment; GitLab uses a personal access token and opens an MR. On the PR you steer it with /kiro all (address every comment) or /kiro fix (one thread).
Because Web executes remotely, its sandbox controls are the security surface. Internet access has three tiers — connections-only (default), a built-in allowlist of common package registries, or open internet — plus a custom domain allowlist. And secrets carry the most risk: they're exposed to the sandbox as env vars, and the docs warn plainly that "the agent may exfiltrate these secrets through code changes, logs, or external requests, so only provide secrets necessary for the task and only use the agent with repositories you trust."
Subagents give you context isolation: each runs in its own context window and returns a summary, so research and review don't pollute the main thread. They run in parallel (the CLI caps at four concurrent), but note the limits — inside a subagent, specs are unavailable and hooks don't fire. The senior pattern is to fan out subagents for research and review lanes but keep a single writer for implementation unless ownership boundaries are explicit.
| Surface | Use when | Verify |
|---|---|---|
| IDE | You want visible spec, steering, hook, MCP, and code-edit flow. | Inspect artifacts, the diff, tests, and generated guidance. |
| CLI | You need terminal review, custom agents, or headless checks. | Keep tool trust narrow; run the repo test/lint commands yourself. |
| Web | You want issue → sandbox → PR/MR delegation. | Review sandbox + internet-access policy, secrets scope, the diff, and CI. |
| Subagents | Independent research/review can be isolated and summarized. | Require compact briefs with sources; prefer one writer for code. |
Workspace explorer
Workspace explorer
What a real .kiro/ project actually looks like
Specs, steering, hooks, MCP and skills all live under one committed .kiro/ directory. Click any file to read the real, paste-ready contents — front-matter, JSON shapes and requirement back-references included.
- .kiro/
- specs/
- password-reset/
- steering/
- hooks/
- settings/
- skills/
.kiro/specs/password-reset/requirements.md
# Requirements Document ## IntroductionPassword reset for returning users, scoped to the auth service. ## Requirements ### Requirement 1: Password reset**User Story:** As a returning user, I want to reset my password by email,so that I can recover a locked account. #### Acceptance Criteria1. WHEN a user requests a reset THE SYSTEM SHALL email a single-use token that expires after 30 minutes.2. IF a token is reused THEN THE SYSTEM SHALL reject it and show "link expired".Kiro prompt generator
Kiro prompt generator
Turn a goal into a Kiro-ready request
A good first message tells Kiro which surface to use, what artifacts to produce, the trust boundary, and how to prove the result. This composes one — including the Web sandbox policy, internet-access stance, and secret handling when you pick Web.
Surface
Risk
kiro-ready-prompt.md
Task: Add password reset to the auth service Context: Next.js app, existing AuthService + mail queue, strict TypeScriptFiles / areas: lib/auth/**, app/(auth)/**, tests/auth/**Risk: high Workflow: Create a feature spec (requirements-first). Run requirements analysis before design; do not start tasks until I approve the design. Required controls:- Produce/update `.kiro/specs/<feature>/{requirements,design,tasks}.md`; every task ends with `_Requirements: N.M_`.- Check whether `.kiro/steering/` should change; use fileMatch for domain-only rules. Definition of done:- Requirements analyzed; design matches existing architecture; tasks small and traceable.- Real test/lint/build commands run, with failures shown — not just claimed.- A reviewer can trace every diff line back to approved intent. If the output is weak, reply: "Rewrite acceptance criteria as observable EARS, split broad tasks, add a verification step per task, and list anything you could not verify."Knowledge check
A Kiro Web task needs a repo secret and internet access to build a PR. What is the safe posture?
How Kiro compares
There's no universal winner — pick by planning model, context model, automation, repo workflow, and how much review evidence you need. Kiro's one real differentiator is the committed three-file spec (requirements/design/tasks with EARS criteria and dependency-wave execution). Most rivals center a single rules file — CLAUDE.md, AGENTS.md, .cursor/rules, GEMINI.md — plus mode toggles, without Kiro's on-disk spec triad. Claude Code is the flexible terminal/IDE harness; Codex is strong for local/cloud continuity and PR review; Cursor is the fast editor loop; Gemini CLI is scriptable terminal work; Cline and Roo Code are approval-first BYO-model editing; GitHub Copilot's agent is GitHub-native issue→PR.
Comparison matrix
Comparison matrix
Compare by workflow, not by brand
Every agent here is good at something. The honest split is the planning model and the context file: Kiro is the one that commits a three-file spec (requirements/design/tasks) to the repo; the others center a single rules file plus mode toggles.
| Tool | Best use | Planning model | Context / rules file | Automation | Repo workflow | Caution |
|---|---|---|---|---|---|---|
| Kiro | Spec-driven dev with an audit trail across IDE/CLI/Web | Spec sessions: requirements (EARS) → design → tasks, committed | .kiro/steering/*.md inclusion modes + AGENTS.md | .kiro.hook (IDE), hooks field (CLI), Powers, Web autonomous | IDE local; Web opens co-authored, sandboxed PR/MR | Trusted-commands is prefix-match only; Web is Preview/Pro+/us-east-1 |
| Claude Code | Terminal/IDE/desktop agent, same engine everywhere | Plan mode, /loop, subagents | CLAUDE.md (managed→user→project→local) + .claude/rules | Hooks in settings.json, GH Actions/GitLab CI, Agent SDK | CI PR review & issue triage; background agents | Reads CLAUDE.md not AGENTS.md unless you @-import it |
| Codex | App/IDE/CLI/Cloud agent with PR review | AGENTS.md-driven; cloud delegation | AGENTS.md + ~/.codex/config.toml | codex exec (headless), Cloud tasks | Cloud opens PRs | Cloud env setup matters; approval/sandbox modes need care |
| Cursor | IDE-native daily coding with rule types | Plan mode; Always/Auto-Attached/Manual rules | .cursor/rules/*.mdc + AGENTS.md | Background Agents | In-IDE; background agents | Not a committed spec-first system by default |
| Gemini CLI | Open-source scriptable terminal agent | Interactive; checkpointing | GEMINI.md + ~/.gemini/settings.json | Headless JSON output; Gemini CLI GitHub Action | GitHub Action: PR review, issue triage | Native PR-lifecycle evidence is thinner |
| Cline / Roo Code | In-editor, approval-first, bring-your-own-model | Plan/Act (Cline); modes (Roo) | .clinerules / .roo/rules + AGENTS.md | MCP + auto-approve controls | In-editor | Managed repo/PR delegation is weaker |
| GitHub Copilot agent | GitHub-native issue → draft PR | Assign issue → autonomous run | Repo custom instructions | Ephemeral env powered by GitHub Actions | Opens a draft PR on a branch | Hard ~59-min session cap; poor fit outside GitHub |
Coding-agent decision tree
Coding-agent decision tree
Route the task before you open a tool
Kiro is the answer when a committed spec is the point. This routes that need against editor speed, terminal harnesses, GitHub-native PR work, and local BYO-model setups — with why-not-the-others.
Recommended
Kiro specs
The task has multiple requirements and needs a reviewable, committed audit trail.
- Vibe chat or an editor agent moves faster but leaves no traceable spec.
- Create a feature spec (requirements-first), run requirements analysis, then design.
- Check requirements → design → tasks → diff alignment and run the real test suite.
Troubleshooting
Weak requirements — tasks look polished but miss intent. Fix: rewrite acceptance criteria as observable EARS; run requirements analysis. Verify: every task maps back to a requirement.
Broad spec — it tries to redesign the repo. Fix: name non-goals and unchanged behavior. Verify: unrelated files stay untouched.
Over-generated tasks — a long list with no dependency order. Fix: ask for fewer, smaller tasks, each with one verification line and a requirement reference.
Design ignores the codebase — Fix: point Kiro at steering and existing modules; call out any deliberate deviation. Verify with a code-owner review.
Steering conflicts — Kiro follows an old rule. Fix: narrow global steering, update workspace steering, delete stale files. Verify with a "summarize this repo's conventions" prompt.
Noisy hooks — repeated generic advice. Fix: narrow the glob and severity; downgrade to manual if it fires too often. Verify with matching and non-matching sample files.
MCP overload — Kiro considers irrelevant tools, or context fills before the first prompt. Fix: disable unused servers/tools, prefer Powers for on-demand loading. Verify the allowed-tool list.
Hook never fires — usually a casing or surface mix-up (IDE PascalCase UI labels vs CLI camelCase keys), or a new IDE hook that needs a Kiro restart to be discovered.
Spec rot — the diff diverged and nobody updated the spec. Fix: run a drift detector and sync requirements/design/tasks to the accepted diff. Verify the spec matches shipped behavior.
Security and governance
Treat Kiro as a powerful actor with real reach. The minimum threat model for a serious workflow names: trusted vs untrusted inputs, writable paths, network egress, secrets, MCP servers, generated code, generated tests, CI, reviewers, and the rollback path. If you can't name the blast radius, don't run autonomous mode with broad repo or network access.
The concrete rules: never put secrets in steering, skills, powers, prompts, hooks, or example configs. Don't connect an MCP server just because it exists — apply least privilege and review provenance. Remember that supervised mode is a review convenience, not an isolation boundary, and that Kiro's "trusted commands" use simple prefix matching — they don't analyze command chains or special characters, so a trusted prefix can still hide a dangerous tail. Reserve hard hook blocking (exit code 2 on preToolUse) for genuinely dangerous actions. For Web, scope repo permissions, the sandbox, internet access, and secrets to the task, and keep a human in the loop on every PR/MR. Enterprise MCP governance exists (an org allowlist via an MCP registry) but the docs are explicit that it's client-side enforced and can be circumvented by a user with local admin — so it's a guardrail, not a wall.
Reach the end and this star joins your charted sky.