Vibe coding is dead in mission-critical engineering. In this deep dive into AWS Kiro, discover how Spec-Driven Development (SDD) transforms AI coding by treating source code as a deterministic build artifact of requirements.md (EARS syntax), design.md, and tasks.md.

Executive Summary: The Fall of Vibe Coding and the Rise of Spec-Driven Development
Between 2023 and 2025, the software engineering industry underwent an intoxicating phase characterized by "vibe coding"—a paradigm where developers treated Large Language Models (LLMs) as conversational clairvoyants. Engineers fed natural language prompts into chat sidebars, prayed that the model's context window wouldn't degrade, and frantically reviewed 800-line diffs across forty disjointed files.
While prompt-and-pray iteration succeeded for greenfield MVPs, landing pages, and standalone prototypes, it catastrophically failed in mission-critical, regulated enterprise environments. By late 2025, enterprise engineering organizations were grappling with a severe hangover:
- Context Window Rot & Hallucinated Assumptions: As codebases grew beyond 50,000 lines of code, LLM agent context windows silently dropped critical architectural invariants, inventing non-existent database columns, violating tenancy boundaries, and deprecating API contracts mid-generation.
- The Reviewability Crisis: Senior Staff Engineers spent more time reverse-engineering AI-generated diffs than they would have spent writing the code by hand. Without formal requirements or architectural blueprints, code reviews degenerated into guessing the agent's hidden assumptions.
- Zero Architectural Traceability: If a production outage occurred at 3:00 AM, there was zero audit trail linking a specific line of generated code back to a formal business requirement or security constraint.
Enter AWS Kiro (General Availability May 2026)—the revolutionary successor to Amazon Q Developer that inverts the traditional AI coding workflow. Rather than treating code as the primary input and conversation as the driver, Kiro introduces Spec-Driven Development (SDD).
Under Spec-Driven Development, code is treated as an ephemeral, deterministic build artifact generated from three strictly enforced, version-controlled markdown specifications:
$$\text{Codebase} = \mathcal{F}\Big(\texttt{requirements.md}, \texttt{design.md}, \texttt{tasks.md}, \texttt{steering.md}\Big)$$
In this comprehensive technical architectural guide, we dissect the inner mechanics of AWS Kiro, unpack the formal EARS (Easy Approach to Requirements Syntax) methodology, evaluate deterministic steering and hook lifecycles, and present an end-to-end enterprise authentication case study demonstrating why SDD represents the permanent foundation of enterprise software engineering in 2026 and beyond.

Vibe Coding vs. Spec-Driven Development: The Paradigm Shift
To understand why AWS Kiro has captured the enterprise market, we must contrast the operational mechanics of conversational prompt engineering against formal spec-driven generation:
| Architectural Dimension | Vibe / Prompt Coding (Cursor / Chat) | Spec-Driven Development (AWS Kiro SDD) |
|---|---|---|
| Primary Source of Truth | Ephemeral chat conversation history & volatile memory | Version-controlled markdown triad (requirements.md, design.md, tasks.md) |
| Requirements Rigor | Ambiguous natural language prompts ("Add OAuth2 login") | Formal EARS syntax with invariant predicates and boundary error conditions |
| Architectural Enforcement | Post-hoc diff inspection; agent invents system structure | Pre-generation C4 architecture models, OpenAPI contracts, and entity schemas |
| Execution Granularity | Monolithic multi-file agentic sweeps with high blast radius | Directed Acyclic Graph (DAG) of atomic, independently verifiable task units |
| Quality & Governance Gates | Manual code review after code is generated | Zero-token deterministic hooks (linters, typecheckers, security policies) |
| Auditability & Traceability | Zero backward traceability to product requirements | 100% bi-directional mapping from PRD $\to$ EARS $\to$ Design $\to$ Task $\to$ Code $\to$ PR |
| Team Collaboration | Individual siloed chat sessions impossible to share or merge | Collaborative Git-backed living specifications reviewed via standard PR workflows |
| Regression Resilience | High hallucination drift during multi-file refactoring | Strict preservation of system invariants across autonomous task executions |

The Triad Architecture: Requirements, Design, and Tasks
At the heart of AWS Kiro is the 3-Artifact Triad. Before Kiro writes a single line of production code (whether TypeScript, Python, Go, Rust, or Java), it mandates the iterative generation and human approval of three sequential, tightly coupled specification files located within the project's .kiro/specs/ directory:
.kiro/
├── steering.md class="tok-cm"># Global project conventions & invariants
├── hooks/
│ ├── pre-task-lint.sh class="tok-cm"># Deterministic quality gate before agent executes
│ └── post-task-verify.sh class="tok-cm"># Test suite & schema validator after agent completes
└── specs/
└── enterprise-rbac-auth/
├── requirements.md class="tok-cm"># Step 1: Formal EARS user stories & acceptance criteria
├── design.md class="tok-cm"># Step 2: C4 architecture, data models, and API contracts
└── tasks.md class="tok-cm"># Step 3: Atomic execution DAG & verification milestones
1. requirements.md — The Contract of Intent
The requirements.md document captures what the system must do without prescribing implementation details. It translates high-level Product Requirement Documents (PRDs) or Jira tickets into formal, unambiguous functional requirements structured using the EARS notation. Every requirement must have a globally unique identifier (e.g., REQ-AUTH-001) and a discrete list of testable acceptance criteria.
2. design.md — The Structural Blueprint
Once requirements.md is approved, Kiro generates or ingests design.md. This artifact details how the feature will be constructed within the existing codebase. It specifies:
- Component architecture following the C4 model (Context, Containers, Components, Code).
- Exact database schemas, migration definitions, and index structures.
- Strict API contracts formatted in OpenAPI 3.1 / JSON Schema.
- Error handling strategies, rate-limiting algorithms, and latency budgets.
- Explicit mapping table demonstrating how each design component satisfies every
REQ-IDfromrequirements.md.
3. tasks.md — The Directed Acyclic Graph (DAG) of Execution
With the architectural blueprint locked, Kiro decomposes the design into tasks.md. Crucially, tasks in Kiro are not vague to-do lists; they are atomic, single-responsibility execution steps arranged in a dependency DAG. Each task specifies:
- Target files to create or modify.
- Prerequisites (tasks that must pass verification before this task starts).
- Verification command (e.g.,
pytest tests/unit/test_token_service.py -v). - Rollback criteria if tests fail.

Mastering EARS (Easy Approach to Requirements Syntax) for Deterministic AI Reasoning
The single greatest source of LLM coding errors is linguistic ambiguity. Phrases such as "The system should authenticate users quickly and handle bad passwords gracefully" provide zero boundary conditions, causing AI agents to guess timeout thresholds, error response codes, and rate limits.
AWS Kiro solves this by enforcing EARS (Easy Approach to Requirements Syntax)—a formal requirements engineering syntax originally developed for safety-critical aerospace and defense systems.
EARS organizes all software requirements into five mathematical clause patterns:
1. Ubiquitous Requirements (System-Wide Invariants)
Ubiquitous requirements apply at all times without preconditions or triggering events.
- Syntax:
Theshall - Example:
The Authentication Service shall hash all stored passwords using Argon2id with memory cost 65536 KiB, time cost 3 iterations, and parallelism factor 4.
2. Event-Driven Requirements (Triggered Actions)
Event-driven requirements execute only when a discrete triggering condition occurs.
- Syntax:
WHEN, the shall - Example:
WHEN a valid OAuth2 Authorization Code is presented to POST /api/v1/auth/token, the Authentication Service shall issue an Ed25519-signed JWT access token with a 900-second TTL.
3. State-Driven Requirements (Active-State Behaviors)
State-driven requirements govern behaviors that remain active throughout a specific operational state.
- Syntax:
WHILE, the shall - Example:
WHILE a user account is in LOCKED_MFA_CHALLENGE state, the Authentication Service shall reject all API requests with HTTP 403 Forbidden and error code ERR_MFA_REQUIRED.
4. Unwanted Behavior / Error Handling Requirements (Fault Invariants)
Unwanted behavior requirements specify how the system must deterministically handle exceptions, edge cases, and attacks.
- Syntax:
IF, THEN the shall - Example:
IF five consecutive failed login attempts occur for an IP within a 300-second window, THEN the Rate Limiter shall block incoming requests from that IP for 900 seconds and emit a SecurityAuditEvent.
5. Optional Feature Requirements (Feature Flags & Tenancy)
Optional feature requirements dictate behavior contingent on runtime flags or subscription tiers.
- Syntax:
WHERE, the shall - Example:
WHERE tenant_tier == 'ENTERPRISE', the Identity Provider shall enforce SAML 2.0 Single Sign-On redirection via the tenant-configured IdP metadata endpoint.
Real-World Case Study: Spec-First vs. Prompt-First Authentication System
To demonstrate the transformative power of AWS Kiro's Spec-Driven Development, let us analyze a real-world enterprise engineering scenario: implementing an Ed25519 Asymmetric JWT Token Exchange Service with Multi-Tenant Key Rotation.
The Failure of the Prompt-First Approach (Vibe Coding)
In a traditional prompt-driven workflow, an engineer types into Cursor or Claude Code:
"Build an authentication service in Python with FastAPI that uses Ed25519 JWT tokens, supports tenant key rotation, validates scopes, and logs security audits to Redis."
The Result: The model generates 400 lines of code across three files. However:
- It uses standard RSA SHA-256 instead of Ed25519 because training data heavily favors RSA.
- It fails to handle key rotation grace periods, invalidating all active sessions the moment a tenant generates a new public key.
- It forgets to sanitize token payload logs, inadvertently writing raw PII into Redis audit streams.
- Fixing these issues requires four additional conversational prompts, each introducing regression breaks in previously working middleware.
The Kiro Spec-Driven Approach
In AWS Kiro, the engineer initiates the feature with a formal specification triad.
Step 1: .kiro/specs/auth-service/requirements.md
class="tok-cm"># Requirements Specification: Ed25519 Multi-Tenant Token Service
class="tok-cm">## Invariant Identifiers & EARS Formal Rules
- **REQ-AUTH-001 (Ubiquitous):** The Token Service shall sign all issued JWT access tokens using Ed25519 (EdDSA algorithm) asymmetric cryptographic key pairs.
- **REQ-AUTH-002 (Event-Driven):** WHEN a client sends a valid `POST /v1/auth/token` request with valid credentials, the Token Service shall class="tok-kw">return a JWT containing `iss`, `sub`, `aud`, `exp` (15 minutes), `iat`, `tenant_id`, and `roles` claims.
- **REQ-AUTH-003 (State-Driven):** WHILE a tenant key pair is in `ACTIVE_ROTATING` state, the Token Service shall sign new tokens using the primary key AND validate existing tokens against both primary and secondary public keys.
- **REQ-AUTH-004 (Unwanted Behavior):** IF an expired, malformed, or signature-invalid token is presented to any protected route, THEN the Token Validator shall class="tok-kw">return `HTTP 401 Unauthorized` with header `WWW-Authenticate: Bearer error=class="tok-str">"invalid_token"` and emit a `TokenValidationError` telemetry event.
- **REQ-AUTH-005 (Optional Feature):** WHERE `tenant.compliance_mode == &class="tok-cm">#039;FEDRAMP_HIGH039;`, the Token Service shall enforce a maximum token expiration of 300 seconds and require hardware-backed HSM signing.
Step 2: .kiro/specs/auth-service/design.md
class="tok-cm"># Architectural Design: Ed25519 Multi-Tenant Token Service
class="tok-cm">## 1. System Architecture & C4 Component Model
graph TD
Client[API Client / Gateway] -->|POST /v1/auth/token| Controller[TokenController]
Controller --> Validator[CredentialValidator]
Controller --> Signer[Ed25519TokenSigner]
Signer --> KeyManager[TenantKeyManager]
KeyManager --> Vault[(AWS Secrets Manager / KMS)]
Controller --> Auditor[StructuredSecurityAuditor]
Auditor --> AuditStream[(Redis / OpenTelemetry Kafka)]
class="tok-cm">## 2. API Contract Specification (OpenAPI 3.1 Excerpt)
openapi: 3.1.0
paths:
/v1/auth/token:
post:
summary: Issue Tenant Access Token
operationId: issueToken
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [client_id, client_secret, tenant_id]
properties:
client_id: { type: string, format: uuid }
client_secret: { type: string, minLength: 32 }
tenant_id: { type: string, pattern: '^[a-z0-9-]+$' }
responses:
'200':
description: Token issued successfully
content:
application/json:
schema:
type: object
required: [access_token, token_type, expires_in]
properties:
access_token: { type: string }
token_type: { type: string, enum: [Bearer] }
expires_in: { type: integer, example: 900 }
'401':
$ref: '#/components/responses/UnauthorizedError'
class="tok-cm">## 3. Cryptographic Key Management Schema
| Database Column | Data Type | Constraint | Purpose |
|---|---|---|---|
| `key_id` | `UUID` | `PRIMARY KEY` | Unique Key Identifier (`kid` in JWT header) |
| `tenant_id` | `VARCHAR(64)` | `INDEX, NOT NULL` | Owning Tenant Isolation Boundary |
| `public_key_pem` | `TEXT` | `NOT NULL` | Ed25519 Public Key (PEM format) |
| `secret_arn` | `VARCHAR(256)` | `NOT NULL` | AWS Secrets Manager ARN storing Private Key |
| `status` | `ENUM` | `ACTIVE, ACTIVE_ROTATING, RETIRED` | Lifecycle Status (REQ-AUTH-003) |
| `created_at` | `TIMESTAMPTZ` | `DEFAULT NOW()` | Key creation audit timestamp |
| `expires_at` | `TIMESTAMPTZ` | `NOT NULL` | Mandatory Key Retirement Deadline |
Step 3: .kiro/specs/auth-service/tasks.md
class="tok-cm"># Execution DAG: Ed25519 Multi-Tenant Token Service
- [ ] **Task 1: Core Cryptographic Service**
- **Files:** `app/services/crypto.py`, `tests/unit/test_crypto.py`
- **Requirements:** REQ-AUTH-001
- **Action:** Implement `Ed25519Signer` and `Ed25519Verifier` using `cryptography.hazmat.primitives.asymmetric.ed25519`.
- **Verification:** `pytest tests/unit/test_crypto.py -v`
- [ ] **Task 2: Tenant Key Manager & Rotation State Machine**
- **Files:** `app/services/key_manager.py`, `app/models/tenant_key.py`, `tests/unit/test_key_manager.py`
- **Requirements:** REQ-AUTH-003, REQ-AUTH-005
- **Prerequisites:** Task 1
- **Action:** Implement key retrieval with cache, dual-key validation during `ACTIVE_ROTATING`, and tenant isolation.
- **Verification:** `pytest tests/unit/test_key_manager.py -v`
- [ ] **Task 3: FastAPI Token Endpoint & Error Middleware**
- **Files:** `app/api/v1/auth.py`, `app/core/middleware.py`, `tests/integration/test_auth_api.py`
- **Requirements:** REQ-AUTH-002, REQ-AUTH-004
- **Prerequisites:** Task 2
- **Action:** Wire `POST /v1/auth/token`, strict EARS error responses, and audit logging.
- **Verification:** `pytest tests/integration/test_auth_api.py -v && ruff check .`
The Generated Production Code (Build Artifact)
When Kiro executes Task 1 and Task 2 from tasks.md, it outputs production-ready, typed Python adhering precisely to the specification invariants without hallucinated drift:
class="tok-str">""class="tok-str">"
Enterprise Ed25519 Token Signing & Multi-Tenant Key Management Service.
Build Artifact generated from .kiro/specs/auth-service/
Requirements: REQ-AUTH-001, REQ-AUTH-002, REQ-AUTH-003, REQ-AUTH-004
"class="tok-str">""
import time
import uuid
from typing import Dict, Any, Optional, Tuple
from enum import Enum
import jwt
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives import serialization
from pydantic import BaseModel, Field
class KeyStatus(str, Enum):
ACTIVE = class="tok-str">"ACTIVE"
ACTIVE_ROTATING = class="tok-str">"ACTIVE_ROTATING"
RETIRED = class="tok-str">"RETIRED"
class TokenPayload(BaseModel):
iss: str = Field(default=class="tok-str">"https:class="tok-cm">//auth.enterprise.internal")
sub: str
aud: str = Field(default=class="tok-str">"enterprise-api")
exp: int
iat: int
tenant_id: str
roles: list[str] = Field(default_factory=list)
class Ed25519TokenService:
class="tok-kw">def __init__(self, key_store_client: Any) -> None:
self.key_store = key_store_client
class="tok-kw">def generate_key_pair(self) -> Tuple[str, str]:
class="tok-str">""class="tok-str">"Generates PEM-encoded Ed25519 private and public keys."class="tok-str">""
private_key = ed25519.Ed25519PrivateKey.generate()
public_key = private_key.public_key()
private_pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
).decode(class="tok-str">"utf-8")
public_pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
).decode(class="tok-str">"utf-8")
return private_pem, public_pem
class="tok-kw">def issue_token(
self,
tenant_id: str,
user_id: str,
roles: list[str],
ttl_seconds: int = 900
) -> Dict[str, Any]:
class="tok-str">""class="tok-str">"
Implements REQ-AUTH-001, REQ-AUTH-002.
Signs token using the active Ed25519 private key for tenant.
"class="tok-str">""
now = int(time.time())
key_record = self.key_store.get_active_signing_key(tenant_id)
if not key_record:
raise RuntimeError(fclass="tok-str">"No ACTIVE signing key provisioned for tenant {tenant_id}")
payload = {
class="tok-str">"iss": class="tok-str">"https:class="tok-cm">//auth.enterprise.internal",
class="tok-str">"sub": user_id,
class="tok-str">"aud": class="tok-str">"enterprise-api",
class="tok-str">"iat": now,
class="tok-str">"exp": now + ttl_seconds,
class="tok-str">"tenant_id": tenant_id,
class="tok-str">"roles": roles
}
headers = {
class="tok-str">"kid": key_record[class="tok-str">"key_id"],
class="tok-str">"alg": class="tok-str">"EdDSA"
}
token = jwt.encode(
payload,
key_record[class="tok-str">"private_key_pem"],
algorithm=class="tok-str">"EdDSA",
headers=headers
)
return {
class="tok-str">"access_token": token,
class="tok-str">"token_type": class="tok-str">"Bearer",
class="tok-str">"expires_in": ttl_seconds
}
class="tok-kw">def verify_token(self, token: str, tenant_id: str) -> Dict[str, Any]:
class="tok-str">""class="tok-str">"
Implements REQ-AUTH-003, REQ-AUTH-004.
Verifies signature against primary and secondary keys during rotation.
"class="tok-str">""
unverified_headers = jwt.get_unverified_header(token)
kid = unverified_headers.get(class="tok-str">"kid")
if not kid:
raise jwt.InvalidTokenError(class="tok-str">"Missing &class="tok-cm">#039;kid039; in token header")
class="tok-cm"># Retrieve public key by kid (validates primary or retiring key)
public_key_pem = self.key_store.get_public_key(tenant_id=tenant_id, key_id=kid)
if not public_key_pem:
raise jwt.InvalidTokenError(fclass="tok-str">"Key ID {kid} not recognized or retired for tenant")
class="tok-cm"># Decode and strictly validate claims
decoded = jwt.decode(
token,
public_key_pem,
algorithms=[class="tok-str">"EdDSA"],
audience=class="tok-str">"enterprise-api",
issuer=class="tok-str">"https:class="tok-cm">//auth.enterprise.internal",
options={class="tok-str">"require": [class="tok-str">"exp", class="tok-str">"iat", class="tok-str">"sub", class="tok-str">"tenant_id"]}
)
if decoded.get(class="tok-str">"tenant_id") != tenant_id:
raise jwt.InvalidTokenError(class="tok-str">"Cross-tenant token forgery detected")
return decoded

Deterministic Quality Control: Kiro Steering Documents and Automated Hooks
In addition to the 3-Artifact Triad, AWS Kiro introduces two foundational mechanisms that guarantee deterministic code quality without wasting LLM token context: Steering Documents and Automated Quality Hooks.
1. Steering Documents (.kiro/steering.md)
Unlike Cursor's .cursorrules or generic system prompts, Kiro's steering.md operates as a hierarchical, compile-time set of architectural rules. Steering documents define:
- Global Technology Stack Invariants: e.g., "All database queries must use prepared statements via SQLAlchemy Core; raw string concatenation is strictly disallowed."
- Directory-Scoped Rules: Specific subdirectories can contain their own
steering.mdoverlays (e.g.,app/api/steering.mdenforcing OpenAPI error schemas, whileapp/domain/steering.mdforbids any direct HTTP imports). - Prohibited Patterns: Explicit blacklists of deprecated libraries, unsafe functions (e.g.,
eval(),pickle.loads()), or unvetted third-party packages.
2. Zero-Token Deterministic Hooks (.kiro/hooks/)
One of the most profound innovations in AWS Kiro is the decoupling of code generation from code validation.
In chat-based agents, verifying whether code passes a linter or test suite requires sending compiler errors back into the LLM context window—consuming millions of tokens and inducing hallucination loops.
Kiro executes deterministic local shell hooks at discrete lifecycle boundaries:
pre-task-hook: Executed before Kiro begins modifying code. Ensures the workspace is clean, dependencies are locked, and Git branches are synchronized.post-task-hook: Executed immediately after Kiro finishes an individual task intasks.md. It triggers native, deterministic CLI tools:
- Static Type Analysis (mypy --strict / tsc --noEmit)
- Linter & Formatting (ruff check / biome check)
- Fast Unit Tests (pytest tests/unit/ -k "test_crypto")
- Security Vulnerability Scan (trivy fs . --security-checks vuln)
If a hook fails, Kiro is fed only the specific compiler error stdout rather than a whole conversational back-and-forth, allowing it to perform localized surgical repairs. If the hook passes, Kiro automatically marks the task as completed in tasks.md and advances to the next node in the DAG.
Strategic Decision Matrix: AWS Kiro SDD vs. Cursor vs. Claude Code
Every AI-assisted development tool occupies a specific niche in the 2026 engineering ecosystem. Choosing the right tool depends on project scale, regulatory compliance, and team structure:
┌────────────────────────────────────────────────────────┐
│ ENTERPRISE CODEBASE? │
└───────────────────────────┬────────────────────────────┘
│
┌────────────────┴────────────────┐
YES NO
│ │
┌──────────────┴──────────────┐ ┌────────┴────────┐
│ Strict Compliance / SDD? │ │ Rapid Greenfield│
│ (Regulated, Core Backend) │ │ MVP / Frontend? │
└──────────────┬──────────────┘ └────────┬────────┘
│ │
┌────────┴────────┐ ┌────────┴────────┐
YES NO YES NO
│ │ │ │
┌───────▼───────┐ ┌──────▼──────┐ ┌──────▼──────┐ ┌───────▼───────┐
│ AWS KIRO │ │ CLAUDE CODE │ │ CURSOR │ │ COPILOT CLI │
│ (Spec-First) │ │(CLI Agentic)│ │(Fast Vibe) │ │(Inline Tab) │
└───────────────┘ └─────────────┘ └─────────────┘ └───────────────┘
| Dimension | AWS Kiro (SDD) | Cursor (Agent Mode) | Claude Code (CLI Agent) |
|---|---|---|---|
| Primary Workflow | Spec-First (requirements $\to$ design $\to$ tasks) | Prompt-First (Sidebar Chat + Inline Composer) | Terminal-First (Autonomous CLI Loop) |
| Best Suited For | Enterprise core systems, FinTech, MedTech, complex backends | Rapid frontend prototyping, exploratory coding, MVPs | Monorepo refactors, large-scale CLI migrations |
| Context Management | Static, structured markdown artifacts + deterministic hooks | Dynamic context retrieval + @-symbol file indexing | Large-context bash tool invocation & grep traversal |
| Quality Control Gate | Zero-token deterministic shell hooks before task commit | Human diff review + inline terminal feedback | Bash test command feedback loops |
| Team Sync & Reviews | Living specs reviewed in Git before code generation | Code diffs reviewed in IDE after generation | PR descriptions auto-generated from git log |
| Compliance & Traceability | 100% EARS-to-PR bi-directional audit trail | Limited to IDE session logs and git commits | Limited to CLI session recordings |

Team Lifecycle & Collaborative Governance: Living Specs Across Git & CI/CD
The greatest organizational advantage of Spec-Driven Development is that it transforms AI from an individual productivity toy into an enterprise engineering standard.
In traditional teams using vibe coding, individual developers prompt agents locally in isolation. Knowledge is trapped in ephemeral chat tabs, resulting in fragmented codebases where three engineers implement database access in three completely different ways.
In an SDD organization, the development lifecycle follows a standardized, version-controlled flow:
1. Specification Pull Requests (PR #1)
Before writing any code, the Staff Architect or Tech Lead submits a Pull Request containing only the .kiro/specs/ directory (requirements.md and design.md).
- Product Managers verify that every business requirement is captured in EARS syntax.
- Security and Compliance teams audit data models, token flows, and cryptographic schemes.
- Disagreements and architectural debates happen at the specification layer, where changes cost minutes rather than days of refactoring code.
2. Autonomous Task Execution (PR #2)
Once PR #1 is merged to the feature branch, the AWS Kiro agent is initialized. Kiro reads the approved specs, generates tasks.md, and autonomously executes each task step by step. Developers monitor the task execution DAG, intervening only if a deterministic hook fails.
3. Living Documentation
Because specifications are version-controlled alongside source code, the .kiro/specs/ directory never becomes obsolete. When a feature is refactored six months later, developers update requirements.md and design.md first, allowing Kiro to safely regenerate or modify existing modules while strictly preserving system invariants.
The 3-Step Monday Morning Action Plan: Transitioning Your Team to SDD
Transitioning an enterprise engineering team from prompt-based vibe coding to Spec-Driven Development does not require an overnight rewrite of your entire stack. Follow this practical, three-step blueprint:
Step 1: Enforce the EARS Syntax on All Feature Tickets (Week 1)
Replace vague Jira/Linear issue descriptions with mandatory EARS requirements templates. Train Product Managers and Tech Leads to write requirements using the five formal patterns (Ubiquitous, Event-Driven, State-Driven, Unwanted Behavior, Optional).
Step 2: Establish the .kiro/ Foundation (Week 2)
In your primary repository, initialize the Kiro directory structure:
mkdir -p .kiro/hooks .kiro/specs
touch .kiro/steering.md
Populate steering.md with your team's core architectural guidelines, approved library lists, and testing conventions. Add a simple post-task-verify.sh hook that runs your linter and test suite.
Step 3: Implement the Two-Phase PR Workflow (Weeks 3–4)
Mandate that all new features exceeding 200 lines of code must submit a Spec PR (requirements.md + design.md) prior to code implementation. Use AWS Kiro to execute the execution DAG from tasks.md, locking code quality behind deterministic quality gates.
Frequently Asked Questions (FAQ)
1. What is AWS Kiro and how does it relate to Amazon Q Developer?
AWS Kiro (released GA in May 2026) is the official next-generation successor to Amazon Q Developer. While Amazon Q Developer focused on inline code completion, conversational chat, and legacy code transformations, Kiro is an agentic, spec-first development environment purpose-built for Spec-Driven Development (SDD). It enforces structured markdown artifacts (requirements.md, design.md, tasks.md) and automated deterministic quality gates to eliminate prompt drift in enterprise codebases.
2. What is EARS notation and why is it mandatory in Kiro?
EARS stands for Easy Approach to Requirements Syntax. It is a formal requirements engineering framework that uses five standardized clause structures (Ubiquitous, Event-Driven, State-Driven, Unwanted Behavior, Optional Features) to eliminate linguistic ambiguity. Kiro mandates EARS syntax because natural language prompts lead to hallucinated assumptions and boundary failures, whereas EARS provides deterministic logical predicates that LLMs can translate into code with near-zero error rates.
3. Can I use Spec-Driven Development without AWS Kiro?
Yes. While AWS Kiro natively automates the spec-to-code execution loop, task DAG management, and zero-token deterministic hooks, the underlying philosophy of Spec-Driven Development (writing formal requirements.md, design.md, and tasks.md before code generation) can be manually applied using Claude Code, Cursor, or custom script wrappers. However, Kiro provides the native IDE tooling and AWS Bedrock integration optimized specifically for this workflow.
4. How do Kiro steering documents differ from Cursor rules (.cursorrules)?
While .cursorrules provides general prompt guidance to chat and inline completions, Kiro's steering.md functions as a compile-time architectural contract. Steering documents support hierarchical scoping (applying distinct rules to specific subdirectories), explicit tool and library blacklists, and integration with local execution hooks that deterministically block agent commits if conventions are violated.
5. Does Spec-Driven Development slow down prototyping speed?
For trivial, 50-line throwaway scripts, SDD adds slight upfront overhead. However, for multi-file features or enterprise systems exceeding 1,000 lines of code, SDD is significantly faster than vibe coding. By resolving architectural ambiguities, API contracts, and edge cases in markdown before generating code, teams avoid the time-consuming "prompt-debug-hallucinate" cycles that plague unstructured chat-based coding.
6. How does SDD integrate with CI/CD and compliance frameworks (SOC 2, ISO 27001)?
SDD provides an unbroken, auditable chain of custody from business requirements to production deployment. Every Pull Request references a specific version of requirements.md (EARS) and design.md. Compliance auditors can verify that every security invariant (e.g., encryption at rest, tenant isolation, rate limiting) was formally specified, architecturally reviewed, verified by deterministic hooks, and covered by automated regression tests.
Structural Schema Markup (JSON-LD)
{
class="tok-str">"@context": class="tok-str">"https:class="tok-cm">//schema.org",
class="tok-str">"@graph": [
{
class="tok-str">"@type": class="tok-str">"TechArticle",
class="tok-str">"@id": class="tok-str">"https:class="tok-cm">//shahvatsal.com/blog/kiro-spec-driven-development-requirements-design-tasks-aws-2026#article",
class="tok-str">"isPartOf": {
class="tok-str">"@type": class="tok-str">"WebSite",
class="tok-str">"@id": class="tok-str">"https:class="tok-cm">//shahvatsal.com/#website",
class="tok-str">"name": class="tok-str">"Vatsal Shah",
class="tok-str">"url": class="tok-str">"https:class="tok-cm">//shahvatsal.com"
},
class="tok-str">"headline": class="tok-str">"Spec-Driven Development with Kiro: Build Production Features from requirements.md, Not Prompts",
class="tok-str">"name": class="tok-str">"Spec-Driven Development with Kiro: Build Production Features from requirements.md, Not Prompts",
class="tok-str">"description": class="tok-str">"Master Spec-Driven Development (SDD) with AWS Kiro. Discover how requirements.md (EARS syntax), design.md, and tasks.md eliminate prompt drift and turn code into a deterministic build artifact.",
class="tok-str">"url": class="tok-str">"https:class="tok-cm">//shahvatsal.com/blog/kiro-spec-driven-development-requirements-design-tasks-aws-2026",
class="tok-str">"datePublished": class="tok-str">"2026-05-18T00:00:00+05:30",
class="tok-str">"dateModified": class="tok-str">"2026-05-18T00:00:00+05:30",
class="tok-str">"author": {
class="tok-str">"@type": class="tok-str">"Person",
class="tok-str">"@id": class="tok-str">"https:class="tok-cm">//shahvatsal.com/#author",
class="tok-str">"name": class="tok-str">"Vatsal Shah",
class="tok-str">"url": class="tok-str">"https:class="tok-cm">//shahvatsal.com/about"
},
class="tok-str">"publisher": {
class="tok-str">"@type": class="tok-str">"Person",
class="tok-str">"@id": class="tok-str">"https:class="tok-cm">//shahvatsal.com/#author",
class="tok-str">"name": class="tok-str">"Vatsal Shah",
class="tok-str">"url": class="tok-str">"https:class="tok-cm">//shahvatsal.com"
},
class="tok-str">"image": class="tok-str">"https:class="tok-cm">//shahvatsal.com/uploads/content/blog/kiro-spec-driven-development-requirements-design-tasks-aws-2026//uploads/content/blog/kiro-spec-driven-development-requirements-design-tasks-aws-2026/banner.webp",
class="tok-str">"articleSection": class="tok-str">"AI Engineering",
class="tok-str">"keywords": [
class="tok-str">"Kiro",
class="tok-str">"AWS",
class="tok-str">"Spec-Driven Development",
class="tok-str">"Agentic IDE",
class="tok-str">"EARS Notation",
class="tok-str">"Software Engineering",
class="tok-str">"AI Coding",
class="tok-str">"Architecture"
],
class="tok-str">"inLanguage": class="tok-str">"en-US",
class="tok-str">"mainEntityOfPage": class="tok-str">"https:class="tok-cm">//shahvatsal.com/blog/kiro-spec-driven-development-requirements-design-tasks-aws-2026"
},
{
class="tok-str">"@type": class="tok-str">"FAQPage",
class="tok-str">"@id": class="tok-str">"https:class="tok-cm">//shahvatsal.com/blog/kiro-spec-driven-development-requirements-design-tasks-aws-2026#faq",
class="tok-str">"mainEntity": [
{
class="tok-str">"@type": class="tok-str">"Question",
class="tok-str">"name": class="tok-str">"What is AWS Kiro and how does it relate to Amazon Q Developer?",
class="tok-str">"acceptedAnswer": {
class="tok-str">"@type": class="tok-str">"Answer",
class="tok-str">"text": class="tok-str">"AWS Kiro is the official next-generation successor to Amazon Q Developer released in May 2026. It is an agentic, spec-first development environment purpose-built for Spec-Driven Development (SDD), enforcing structured markdown artifacts (requirements.md, design.md, tasks.md) and automated deterministic quality gates."
}
},
{
class="tok-str">"@type": class="tok-str">"Question",
class="tok-str">"name": class="tok-str">"What is EARS notation and why is it mandatory in Kiro?",
class="tok-str">"acceptedAnswer": {
class="tok-str">"@type": class="tok-str">"Answer",
class="tok-str">"text": class="tok-str">"EARS stands for Easy Approach to Requirements Syntax. It is a formal requirements engineering framework that uses five standardized clause structures (Ubiquitous, Event-Driven, State-Driven, Unwanted Behavior, Optional Features) to eliminate linguistic ambiguity, providing deterministic logical predicates for AI code generation."
}
},
{
class="tok-str">"@type": class="tok-str">"Question",
class="tok-str">"name": class="tok-str">"Can I use Spec-Driven Development without AWS Kiro?",
class="tok-str">"acceptedAnswer": {
class="tok-str">"@type": class="tok-str">"Answer",
class="tok-str">"text": class="tok-str">"Yes. While AWS Kiro natively automates the spec-to-code execution loop, task DAG management, and zero-token deterministic hooks, the underlying philosophy of Spec-Driven Development can be applied using Claude Code, Cursor, or custom script wrappers."
}
},
{
class="tok-str">"@type": class="tok-str">"Question",
class="tok-str">"name": class="tok-str">"How do Kiro steering documents differ from Cursor rules (.cursorrules)?",
class="tok-str">"acceptedAnswer": {
class="tok-str">"@type": class="tok-str">"Answer",
class="tok-str">"text": class="tok-str">"Kiro steering documents class="tok-kw">function as compile-time architectural contracts with hierarchical scoping, explicit tool/library blacklists, and integration with local deterministic execution hooks that block agent commits class="tok-kw">if conventions are violated."
}
},
{
class="tok-str">"@type": class="tok-str">"Question",
class="tok-str">"name": class="tok-str">"Does Spec-Driven Development slow down prototyping speed?",
class="tok-str">"acceptedAnswer": {
class="tok-str">"@type": class="tok-str">"Answer",
class="tok-str">"text": class="tok-str">"For trivial scripts, SDD adds slight upfront overhead. However, for multi-file features or enterprise systems exceeding 1,000 lines of code, SDD is significantly faster than vibe coding because it eliminates prompt drift, debugging loops, and architectural hallucinations."
}
},
{
class="tok-str">"@type": class="tok-str">"Question",
class="tok-str">"name": class="tok-str">"How does SDD integrate with CI/CD and compliance frameworks (SOC 2, ISO 27001)?",
class="tok-str">"acceptedAnswer": {
class="tok-str">"@type": class="tok-str">"Answer",
class="tok-str">"text": class="tok-str">"SDD provides an unbroken, auditable chain of custody from business requirements to production deployment. Every Pull Request references a specific version of requirements.md and design.md, proving that security invariants were formally specified and verified by automated tests."
}
}
]
}
]
}