AWS Builder Center
The bug fix that didn't need my laptop to stay open: a governed bug-fix pipeline with Kiro CLI on Amazon Bedrock AgentCore

The bug fix that didn't need my laptop to stay open: a governed bug-fix pipeline with Kiro CLI on Amazon Bedrock AgentCore

An open-source proof of concept that turns AI-assisted bug fixing into a governed AWS pipeline: paste a bug report, approve a fix plan at a human gate, and Kiro CLI writes, builds, and validates the fix inside an ephemeral Amazon Bedrock AgentCore container while your laptop stays closed. Every run produces independent validation evidence, a full audit trail including MCP tool calls, and an itemized cost breakdown, with the demo fix landing in under two minutes for under a dime.

Every team that experiments with AI-assisted coding ends up asking the same three questions:
  1. Accountability. AI can generate code faster than we can read it. How do we keep a human accountable for the decisions that matter, without making that human the bottleneck for the decisions that don't?
  2. Trust. An agent that grades its own homework will always tell you the fix looks great. What independent evidence should a change produce before anyone thinks about merging it?
  3. Visibility. What did this specific fix cost? Not the monthly bill. This fix: which models ran, how many tokens, how many agent credits, how much compute.
There is a fourth question that gets less attention but bites everyone who moves past the demo stage: where does the coding agent actually run? In most setups today the agent runs on a developer's machine. So the laptop lid stays open until the agent finishes, or someone keeps an old PC running in the basement as a self-hosted "agent box" that they patch by hand and load up with long-lived credentials.
I wanted to answer all four questions with something I could actually run, so I built an open-source proof of concept. You paste a bug report into a web UI, approve a fix plan (or let simple ones approve themselves), and everything else happens in AWS: cloning the repo, writing the code, building, validating, pushing the fix branch. You can start a run from a browser tab and close the laptop. The full source is here:
https://github.com/MichaelShapira/adlc

What the pipeline does

A React app (CloudFront and Cognito) submits a bug report through API Gateway, which kicks off an AWS Step Functions execution. Triage classifies the bug as Simple or Complex. A draft step produces two candidate artifacts: a short, precise prompt for the simple path and a full Markdown spec (requirements, design, tasks, acceptance criteria) for the complex path. A human gate lets you pick a path, edit the artifact, and approve it. The implement step hands the approved artifact to Kiro CLI running headlessly inside an Amazon Bedrock AgentCore container. A build gate and an independent validator model check the result, a bounded fix loop retries up to three times if validation finds problems, and a final report assembles the outcome with a full usage breakdown.
The target repository is a small seeded CodeCommit repo with two intentional bugs, a TypeScript compile error and a SQL injection. Every fix lands on its own fix/<run-id> branch and the agent can never touch main, so the demo resets cleanly and you can run it as many times as you like.

The human gate, and when to skip it

Triage is advisory. When a run reaches the gate you see both paths side by side, with the recommendation marked, and you pick one. The artifact underneath is editable, and whatever text you approve is frozen. Retries in the fix loop reuse it byte for byte. Validation findings get appended as extra context on the next attempt, but the approved artifact itself never changes. Nothing drifts between what you signed off on and what gets implemented.
For genuinely routine work, there is an "auto-execute simple fixes" checkbox on the run form. If triage says SIMPLE, the drafted prompt is approved automatically and the run keeps moving, and the auto-approval is written to the audit trail like any human decision would be. If triage says COMPLEX, the run stops and waits for a person no matter what the checkbox says. That split felt right in practice: the gate exists for judgment calls, not for rubber-stamping one-line type fixes.

Why AgentCore carries the interesting part

The implementation step is where agentic pipelines usually get vague. "And then the agent writes the code." Here it is concrete. The coding agent is a container image (a Python harness, git, Node.js, and Kiro CLI) deployed as an AgentCore Runtime. Each implementation attempt is a single InvokeAgentRuntime call with its own session ID.
What AgentCore contributes is hard to replicate with a laptop or a self-managed box:
  • A fresh microVM per attempt. The agent clones the repo into a temporary workspace, does its work, and the whole environment disappears afterward. No state leaks between runs. Nothing to patch on weekends.
  • Serverless economics for a bursty workload. A run needs real compute for about two minutes, then nothing for hours. There is no fleet to keep warm.
  • A small, explicit identity. The runtime's IAM role can push fix/* branches to exactly one repository and read exactly one secret (the Kiro API key). It has no Bedrock model access at all, because the coding engine is Kiro CLI and nothing else. You can draw the entire blast radius on a napkin.
  • Compute you can actually measure. The harness samples cgroup v2 counters inside the container every 250 ms and reports CPU seconds and peak memory per attempt, tied to the AgentCore session ID.
That last point surprised me. Once the environment is isolated and short-lived, resource usage stops being a fleet-level guess and becomes a per-fix data point.

What Kiro CLI brings

Three Kiro capabilities shaped the design more than anything else.
It behaves like a component, not a chat window. The harness runs it as a plain process:
1
2
kiro-cli chat --agent-engine v2 --no-interactive --trust-all-tools \
--output-format stream-json [--model <id>] "<the approved artifact>"
The stream-json flag is the one that matters. It turns the whole run into a stream of structured events, one JSON object per line. From that stream the harness pulls the agent's final message, its step-by-step narrative, every tool call it made, and the exact credit consumption from the metering events:
1
{"type":"metadata","data":{"meteringUsage":[{"value":0.486,"unit":"credit"}],"turnDurationMs":2312}}
Before I switched to the event stream I was scraping terminal text for a credits line that headless mode never actually prints. If the agent tool you build on has a machine-readable output mode, start there.
You choose the model per run. The UI lists the models available to the Kiro account (discovered live through --list-models --format json, executed inside the same AgentCore runtime) and passes your choice as --model. Analysis and implementation are deliberately decoupled, so a cheap fast model can do triage and drafting while a stronger one writes the code, or the other way around.
It speaks Model Context Protocol. The UI has an MCP tab with a JSON editor. Whatever servers you define get snapshotted when a run starts, written to .kiro/settings/mcp.json in the agent's temporary workspace, and removed before anything is committed. Kiro discovers the servers on startup and can call their tools mid-task.
To exercise that path end to end, I configured the AWS Documentation MCP server and wrote the bug ticket so it asked the agent to double-check its approach against public documentation before applying it. Is a documentation lookup strictly necessary for a one-line type fix? No. The point of the exercise was the plumbing: the config snapshot, the injection into the container, and above all the audit trail. Every MCP tool the agent calls is written to the run's log with a call count, so when someone asks "did the agent go outside its sandbox, and where?", the answer is right there.

Evidence beats confidence

The validation design follows one rule: the model that checks the change never wrote it. Different model, different prompt, different Lambda.
And before any model gets an opinion, a deterministic gate runs first. Inside the container, npm install && npm run build must exit 0. A failed build cannot be reported as a validated fix, no matter how confident the coding agent's summary sounds. Cheap deterministic checks first, model judgment second. The validator then reviews the diff against the frozen artifact and produces named pass/fail checks.
The UI shows the agent's own summary too, but with an explicit note that this text is the agent's account of what it did, captured verbatim, and should be read as a claim. The proof sits right below it: the build result and the validator's checks. I added that note after catching myself skimming a confident agent summary and nodding along. The wording costs nothing and it changes how you read the page.
Every fix branch also gets a side-by-side review against main, so the human review step looks like a normal code review, except the diff arrives pre-validated. Here you can see the actual change for the seeded TypeScript bug, the type guard added at lines 39 to 41 on the right:

What a fix costs, exactly

Every run ends with a measured breakdown, split by what consumed it:
  • Analysis. Input and output tokens with cost, for the triage, draft, and validation calls on the Bedrock model you picked.
  • Kiro. Credits per implementation attempt, parsed from the structured event stream, with a dollar approximation.
  • AgentCore. CPU seconds and peak memory from the in-container sampling, plus session and trace IDs so you can cross-reference AWS telemetry.
The run in the screenshot fixed the seeded TypeScript bug end to end, from triage through validated push, in 1 minute 56 seconds for $0.096 total. About 10,000 analysis tokens, 0.49 Kiro credits, 14.3 CPU seconds and 1 GB peak memory in the container. When numbers like this exist per fix, model right-sizing turns from a debate into a spreadsheet.

Things I would tell a friend building the same thing

  • Get structured output from your agent before building anything else. Half of the observability in this project fell out of one CLI flag.
  • Put the deterministic gate in front of the model gate. An exit code catches the embarrassing failures for free, and the validator model spends its tokens on questions worth asking.
  • Treat ephemeral compute as a governance feature, not just an ops convenience. Fresh environment per attempt means reproducible runs and an IAM story a security reviewer can absorb in one sitting.
  • Snapshot everything a run depends on at submission time. The approved artifact, the MCP config, even the triage guidance text. When someone asks six weeks later why a run behaved a certain way, you want the exact inputs, not a reconstruction.
  • Mark the agent's self-summary as a claim. Put the independent evidence next to it. Reviewers calibrate fast once the page itself teaches them what is proof and what is narration.

Try it

The repository has the full CDK stack, the AgentCore container, the UI, the seeded demo app, and an in-app user guide: https://github.com/MichaelShapira/adlc. You need an AWS account with Bedrock model access for the analysis models, a Kiro subscription for the API key (it lives in Secrets Manager, never in code), Node.js, and Docker. One cdk deploy brings up everything including the seeded buggy repository, and the README covers the two post-deploy steps: storing the Kiro key and creating a Cognito user.
Then paste a bug, click start, and close the laptop.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article