Most AI coding tools work the same way: you describe what you want, the model writes code, you iterate. Kiro is built around a different premise. When you describe a feature, it doesn't start coding but instead writes three documents first, requirements.md with user stories and acceptance criteria, design.md with architecture and TypeScript interface contracts, and tasks.md with executable tasks and dependencies between them, and only after you review and approve that plan does any code get generated.
In a hackathon with a two-day window (due to personal circumstances), that upfront process sounds like overhead you can't afford. We ended up finding out it was what kept us on track.
The project
Entiscore is an agent that audits a website's digital entity, checking schema markup, identity consistency, authority signals, and technical accessibility. It returns a scored report with a breakdown by axis and an AI-generated action plan with code snippets ready to implement. Built for the Kiro powered by AWS hackathon organized by Código Facilito, with two days of actual development after a rough start.
The stack was Next.js, TypeScript, Supabase, and Claude API via Anthropic. No AWS infrastructure because we had no credits available, something worth being honest about for a hackathon that promoted AWS services. Kiro was our IDE for the entire build.
What the spec phase actually produced
Before touching the editor we wrote three documents, and in Kiro this happens through a structured flow where you describe the feature and the IDE generates the spec for you to review and edit. What came out wasn't boilerplate.
requirements.md had user stories, acceptance criteria, and a priority column with P0 and P1 labels, where P0 meant the feature had to ship for the product to make sense and P1 meant it was valuable but cuttable if time ran out. We had five axes of analysis planned: structured data, identity consistency, authority signals, technical accessibility, and a fifth that didn't survive the first day. The P1 label on identity consistency and authority signals gave us a documented reason to deprioritize them without feeling like we were abandoning scope. When the clock was ticking, we didn't debate, we just looked at the column.
design.md had the architecture with TypeScript interface contracts for every major boundary in the system. This mattered more than we expected. When two people are writing different parts of the same system in parallel, shared interface definitions prevent a category of integration bugs that are particularly expensive to debug under time pressure. We never had a mismatch between what the orchestrator expected and what an analyzer returned because the contract was written before either was implemented.
tasks.md had a dependency graph with an explicit ordering where task B depends on task A and task D can start in parallel with task C, and that structure turned into a natural division of work between two developers without a planning meeting.
Steering and hooks, the invisible layer
Kiro has two features that don't get as much coverage as specs but turned out to be more consistently useful during the build.
Steering documents are instructions that Kiro applies to everything it generates across the entire project without you having to repeat them in every prompt. We defined coding-standards.md with rules that were non-negotiable, including no comments in code, strict TypeScript with no any, one responsibility per function with a thirty-line limit, and strict separation between server and client layers. Kiro respected those rules consistently across hundreds of generated files over two days. We never had to say "remember to not use any" or "keep the function small". It was already in the context.
Commit conventions were also in Steering, typed prefixes in Spanish (feat, fix, chore, refactor, docs) with a specific format. The git history from that weekend is readable.
Hooks are actions that run automatically when something happens in the project. We configured a type check hook that ran npx tsc --noEmit on every file save. TypeScript errors surfaced immediately instead of accumulating until a build. In a codebase that was growing fast with two people writing in parallel, that feedback loop caught problems before they compounded.
Where spec-driven development saved us
The most concrete example came on day two. We were implementing the scoring engine, which takes the output of four parallel analyzers and produces a weighted average. The design document had the weight distribution, with 30% for structured data, 20% for identity consistency, 20% for authority signals, and 30% for technical accessibility, and it also had a note about dynamic weight redistribution where if an analyzer returned failed or partial status, its weight should redistribute proportionally among the ones that succeeded.
That behavior was written in the design phase before any code existed, so when we implemented it the behavior was already defined and we didn't have to invent the edge case handling during implementation but simply read the spec.
What we'd do differently
The spec phase has a cost that becomes visible when you're operating under a hard deadline. The ten to twenty minutes to generate and review documents at the start of each major feature added up. For features we were confident about, we sometimes skimmed the spec instead of reading it, which defeated part of the purpose.
The tasks document was the weakest of the three in practice. Kiro generates it based on the design, and the dependencies it infers are generally correct, but the task granularity is sometimes too coarse to be directly actionable. We ended up using it as a checklist more than a dependency graph.
Kiro's defaults lean toward AWS services, which makes sense given what it is. When you describe a persistence layer, it tends to suggest DynamoDB. When you describe a deployment target, it suggests Lambda or Amplify. That's fine to override but it's worth knowing in advance, especially if your stack already points somewhere else.
The process lesson that transferred
Something we noticed by the end of the weekend was that we stopped accepting Kiro's "done" reports at face value, because the share button that disappeared after an animation refactor, the chat component that vanished after another, and the favicon that was missing in a deployment comparison were none of them caught by Kiro reporting completion but by opening the deployed URL and looking at it.
Working with an AI agent that writes, runs, and reports on its own output creates a specific dynamic where it's easy to mistake fluent execution for correct execution, and those two things aren't the same. Kiro is very good at the former while verifying the latter is still on you, and that's not a criticism of Kiro specifically but a property of any agentic tool that can complete tasks without a human in the loop at every step.
Entiscore is available at entiscore.vercel.app. Built with Next.js, TypeScript, Supabase and Claude API.

