Skip to content
Santekno.com | Level Up Your Engineering Skills
EN
📖 0%
18 Sep 2026 · 24 min read ·Article 48 / 208
Go

AWS Kiro Golang: Complete Spec-First IDE Setup and Workflow

A deep dive into AWS Kiro for Go developers. Built-in spec-first workflow, steering documents, agent hooks, a spec vs Spec Kit comparison, and how to use it for a Golang project.

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

AWS Kiro: A Spec-First IDE for Go Developers

AWS Kiro for Golang is the most provocative tool in the 2026 landscape — not because of its features alone, but because philosophically it takes a bold stance: you should not code straight away without a clear, written spec. For Go teams already familiar with SDD from previous topics, this is nothing strange — it is validation.

In this article we dissect Kiro’s setup for Go, steering documents as project memory, the built-in spec-first workflow, agent hooks for quality automation, and an honest comparison with GitHub Spec Kit.


08.1 AWS Kiro’s Philosophy: Spec-First by Design

Almost every AI coding tool is designed to answer the question “how can I code faster?” Kiro is designed to answer a different question: “how do I make sure I build the right thing the right way?” The flow comparison below shows the difference concretely.

text
 1Traditional AI coding workflow:
 2  Developer → Prompt → AI generates code → Developer reviews
 3
 4Kiro workflow:
 5  Developer → Describe need → Kiro asks clarifying questions
 6  → Kiro generates spec → Developer approves spec
 7  → Kiro generates plan → Developer approves plan
 8  → Kiro implements → Kiro verifies against spec
 9
10A difference that looks small but has a big impact:
11  → Requirement ambiguity detected BEFORE implementation
12  → Implementation tracked against the spec explicitly
13  → Spec becomes the single source of truth
14  → Onboarding a new developer: read the spec, not the code

The core of the difference lies at one point: requirement ambiguity is caught before implementation, not after. This is exactly the SDD principle we have followed throughout the series — except Kiro makes it the default, not a manual discipline.


08.2 Installation and Setup

Before enjoying the spec-first workflow, you need to install Kiro and connect it to an AWS account. The commands and steps below cover cross-platform installation, login, and verifying Go support.

bash
 1# Download Kiro from kiro.aws
 2# Install per platform:
 3# macOS: open Kiro.dmg, drag to Applications
 4# Windows: run KiroSetup.exe
 5# Linux: AppImage or .deb package
 6
 7# Login with an AWS account
 8# Kiro button in the sidebar → Sign in with AWS
 9
10# Verify Go support:
11# Kiro automatically detects go.mod → sets up the Go toolchain
12# Go files will have AI hints with no extra config needed
13
14# Setup Bedrock model (if enterprise):
15# Kiro Settings → AI Model → Amazon Bedrock
16# Region: pick the closest
17# Model: Claude 3.5 Sonnet or Claude 3 Opus
18
19# Create project:
20# Kiro → New Project → Go → Next
21# Or: open an existing Go project folder

Because Kiro automatically detects go.mod and sets up the toolchain, setup for a Go project is nearly frictionless — just open the project folder and Kiro immediately becomes aware of the language context.


08.3 Steering Documents: CLAUDE.md for Kiro

Steering documents in Kiro are similar to CLAUDE.md but more structured and can be split per topic. The first file below defines the overview, architecture standards, error handling, and type safety of the project.

markdown
 1# .kiro/steering/project.md
 2# Kiro uses every file in .kiro/steering/ as persistent context
 3
 4## Project Overview
 5Santekno Shop — Go 1.22 e-commerce, high-traffic, Clean Architecture.
 6Stack: Echo v4, pgx/v5, Redis, Kafka.
 7
 8## Architecture Standards
 9Clean Architecture layers:
10  delivery/http/handler → usecase → repository → domain
11
12Rules (STRICT):
13  - handler: import ONLY usecase interfaces
14  - usecase: import ONLY domain types + repository interfaces
15  - repository: import ONLY domain types + drivers
16  - domain: ZERO external imports
17
18## Error Handling
19Repository not-found: (nil, nil) — NOT error
20Error wrap: fmt.Errorf("package.Method: %w", err)
21HTTP errors: {"error": "UPPERCASE_SNAKE_CASE"}
22
23## Type Safety
24Monetary: int64 cents ONLY
25IDs: UUID (github.com/google/uuid)
26```

The second steering file focuses specifically on testing standards, so Kiro knows the framework, naming pattern, and suite structure expected. The example below sets it out explicitly.

markdown
 1# .kiro/steering/testing.md
 2
 3## Testing Standards
 4Framework: github.com/stretchr/testify/suite
 5Mocking: go.uber.org/mock/gomock
 6
 7## Test Naming
 8Pattern: Test[Domain]_[Scenario]_[ExpectedResult]
 9Example: TestCancelOrder_WindowExpired_ReturnsError
10
11## Test Suite Structure
12type [Name]Suite struct {
13    suite.Suite
14    ctrl     *gomock.Controller
15    mock[Repo] *mock.Mock[Repo]
16    uc      *[Name]UseCase
17}
18
19func (s *[Name]Suite) SetupTest() {
20    s.ctrl = gomock.NewController(s.T())
21    // setup mocks
22}
23
24func (s *[Name]Suite) TearDownTest() {
25    s.ctrl.Finish()
26}
27```

Splitting steering into several themed files (project, testing, go-conventions) makes the context easy to maintain and validate — Kiro reads them all as a single, persistent guardrail.


08.4 Kiro’s Spec-First Workflow: Step by Step

Kiro’s core feature is a six-step flow from a description of the need to verification against the spec. The transcript below follows a single cancel-order feature through clarification, spec, plan, implementation, and a compliance score.

text
 1Step 1: Describe the need
 2> "Customers need to be able to cancel an order that is still PENDING within 30 minutes"
 3
 4Kiro generates clarifying questions (like speckit.clarify):
 5  Q1: What happens to stock on cancel?
 6  Q2: Who can cancel — only the customer or admins too?
 7  Q3: What if the cancel window has expired?
 8  Q4: Is a Kafka event needed for cancel?
 9
10Step 2: Answer questions → Kiro generates .kiro/features/cancel-order/spec.md
11
12# CancelOrder Feature Specification
13## Acceptance Criteria
14AC1: Customer can cancel an order with PENDING status
15AC2: The order must have been created at most 30 minutes ago
16AC3: Stock is restored atomically within a database transaction
17AC4: An ORDER_CANCELLED event is sent to Kafka (best-effort)
18AC5: Response: 204 No Content for success
19AC6: Error codes: ORDER_NOT_FOUND, ORDER_NOT_CANCELLABLE, CANCEL_WINDOW_EXPIRED
20
21Step 3: Review and approve the spec (can be edited directly in the IDE)
22
23Step 4: Generate plan → .kiro/features/cancel-order/plan.md
24## Files to Create/Modify
251. internal/domain/order/entity.go — add CanBeCancelled() bool
262. internal/domain/order/errors.go — add error types
273. internal/usecase/order/cancel_order.go — new file
284. internal/repository/postgres/order_repository.go — add methods
295. internal/delivery/http/handler/order_handler.go — add handler
30
31## Implementation Order (dependency-first)
32Phase 1: Domain (entity + errors)
33Phase 2: Repository interface + PostgreSQL impl
34Phase 3: Usecase + tests
35Phase 4: Handler + router
36
37Step 5: Implement → Kiro implements all files per the plan
38
39Step 6: Verify against the spec:
40  AC1: ✅ — handler present, usecase checks status
41  AC2: ✅ — CanBeCancelled() checks the 30-minute window
42  AC3: ✅ — CancelWithStockRestore inside a transaction
43  AC4: ⚠️ — Kafka publish present, but error handling needs review
44  AC5: ✅ — handler returns 204
45  AC6: ✅ — all error codes present
46Score: 95/100

What sets Kiro apart from other tools is Step 6: every AC is explicitly verified against the implementation and given a score. Ambiguity is answered in Step 1, not discovered in production — that is the essence of spec-first value.


08.5 Agent Hooks: Powerful Automation

Agent hooks are a Kiro feature no other tool has — automation that runs on specific triggers. The first hook below runs a chain of quality checks (build, vet, test, lint) every time a Go file is saved.

yaml
 1# .kiro/hooks/go-quality.yaml
 2
 3name: "Go Quality Automation"
 4description: "Automate quality checks every time a Go file is saved"
 5triggers:
 6  - type: file_saved
 7    pattern: "**/*.go"
 8    exclude:
 9      - "**/*_test.go"
10      - "**/mock_*.go"
11  - type: before_commit
12
13actions:
14  - name: "Build check"
15    run: "go build ./..."
16    on_failure:
17      message: "🔴 Build failed — fix before continuing"
18      stop: true
19
20  - name: "Vet check"
21    run: "go vet ./..."
22    on_failure:
23      message: "⚠️ Vet issues found"
24      stop: false
25
26  - name: "Test changed packages"
27    run: |
28      CHANGED_PKG=$(dirname $KIRO_CHANGED_FILE)
29      go test ./${CHANGED_PKG}/... -race
30    on_failure:
31      message: "🔴 Tests failing in changed package"
32      stop: true
33
34  - name: "Lint"
35    run: "golangci-lint run $KIRO_CHANGED_FILE"
36    on_failure:
37      message: "⚠️ Lint issues"
38      stop: false

The second hook runs on a PR-ready event and triggers a spec compliance audit, so compliance with the specification is also maintained automatically. Its configuration is as follows.

yaml
 1# .kiro/hooks/spec-compliance.yaml
 2
 3name: "Spec Compliance Check"
 4triggers:
 5  - type: pull_request_ready
 6
 7actions:
 8  - name: "Run spec audit"
 9    run: "specify audit --all --fast"
10    on_failure:
11      message: "❌ Spec compliance issues detected"
12      create_issue: true
13      stop: false

The third hook closes a maintenance gap that is often forgotten: automatic mock regeneration every time a repository interface changes. Its example is as short as this.

yaml
 1# .kiro/hooks/mock-generation.yaml
 2
 3name: "Auto Mock Generation"
 4triggers:
 5  - type: file_saved
 6    pattern: "internal/domain/**/repository.go"
 7
 8actions:
 9  - name: "Regenerate mocks"
10    run: "go generate ./internal/domain/..."
11    on_success:
12      message: "✅ Mocks regenerated"

With agent hooks, quality discipline (build, test, lint, mock regen, spec audit) is enforced by tooling automatically at the right moment — not dependent on the manual discipline of developers who easily forget.


08.6 Kiro vs GitHub Spec Kit: Detailed Comparison

We are already familiar with Spec Kit from previous topics, so it is natural to compare it with Kiro honestly. The table below places the two side by side from interface to pricing, then maps out when to use each.

text
 1                    GitHub Spec Kit    AWS Kiro
 2─────────────────────────────────────────────────────
 3Interface           CLI                IDE-embedded
 4Installation        npm install        Desktop app download
 5Trigger mechanism   Manual command     Automatic + IDE integrated
 6Output location     .specify/          .kiro/
 7Spec format         Markdown (open)    Markdown (.kiro proprietary)
 8Portability         Any tool           Kiro-specific workflow
 9LLM                 Configurable       Claude (via Bedrock)
10Agent hooks         ❌                 ✅ Built-in
11Quality automation  Via CI only        Built-in + CI
12Open source         Yes                No (proprietary)
13AWS integration     ❌                 ✅ Native
14Pricing             Free (API cost)    Free beta; TBD post-beta
15Go-specific support via config         Good out-of-box
16
17When to use Spec Kit:
18  → Already using Claude Code (CLI workflow)
19  → Tool-agnostic requirement (not locked to one IDE)
20  → Want open source + full control
21
22When to use Kiro:
23  → Want spec-first INSIDE the IDE (no CLI)
24  → AWS-heavy infrastructure
25  → Want built-in agent hooks for quality automation
26  → Team onboarding with built-in spec guidance

The dividing line is clear: choose Spec Kit if you need portability and full control via open-source CLI; choose Kiro if you want spec-first fused into the IDE with built-in agent hooks and AWS infrastructure.


08.7 AWS Kiro for Go + AWS Infrastructure

Kiro’s value spikes for Go projects that deploy to AWS. The first example shows Kiro producing a Lambda handler with the correct AWS Lambda Go SDK signature — not a generic HTTP handler.

go
 1// Prompt: "Implement cancel order as a Lambda function"
 2package main
 3
 4import (
 5    "context"
 6    "encoding/json"
 7    "github.com/aws/aws-lambda-go/events"
 8    "github.com/aws/aws-lambda-go/lambda"
 9)
10
11type CancelOrderRequest struct {
12    OrderID string `json:"order_id"`
13    UserID  string `json:"user_id"`
14}
15
16func handler(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
17    var input CancelOrderRequest
18    if err := json.Unmarshal([]byte(req.Body), &input); err != nil {
19        return events.APIGatewayProxyResponse{
20            StatusCode: 400,
21            Body:       `{"error":"INVALID_REQUEST"}`,
22            Headers:    map[string]string{"Content-Type": "application/json"},
23        }, nil
24    }
25
26    // ... business logic via dependency injection
27
28    return events.APIGatewayProxyResponse{
29        StatusCode: 204,
30    }, nil
31}
32
33func main() {
34    lambda.Start(handler)
35}
36// Kiro knows the Lambda Go SDK pattern correctly
37// Other tools often generate a generic HTTP handler

The second example shows Kiro building a DynamoDB repository with the correct SDK v2, including the (nil, nil) not-found convention per the steering docs.

go
 1import (
 2    "github.com/aws/aws-sdk-go-v2/service/dynamodb"
 3    "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
 4    "github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
 5)
 6
 7type OrderDynamoRepository struct {
 8    client    *dynamodb.Client
 9    tableName string
10}
11
12func (r *OrderDynamoRepository) GetByID(ctx context.Context, id uuid.UUID) (*domain.Order, error) {
13    result, err := r.client.GetItem(ctx, &dynamodb.GetItemInput{
14        TableName: &r.tableName,
15        Key: map[string]types.AttributeValue{
16            "PK": &types.AttributeValueMemberS{Value: "ORDER#" + id.String()},
17        },
18    })
19    if err != nil {
20        return nil, fmt.Errorf("orderDynamoRepo.GetByID: %w", err)
21    }
22    if result.Item == nil {
23        return nil, nil  // not found
24    }
25
26    var order domain.Order
27    if err := attributevalue.UnmarshalMap(result.Item, &order); err != nil {
28        return nil, fmt.Errorf("orderDynamoRepo.GetByID unmarshal: %w", err)
29    }
30    return &order, nil
31}

Kiro can also produce infrastructure artifacts such as an ECS task definition directly from a Go service configuration. The example below is output that aligns with the service’s environment and health check.

json
 1{
 2  "family": "cancel-order-service",
 3  "networkMode": "awsvpc",
 4  "containerDefinitions": [
 5    {
 6      "name": "cancel-order",
 7      "image": "your-ecr.amazonaws.com/cancel-order:latest",
 8      "environment": [
 9        {"name": "GO_ENV", "value": "production"},
10        {"name": "DB_MAX_CONNECTIONS", "value": "10"}
11      ],
12      "secrets": [
13        {"name": "DATABASE_URL", "valueFrom": "arn:aws:secretsmanager:..."}
14      ],
15      "healthCheck": {
16        "command": ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"]
17      }
18    }
19  ]
20}

These three examples confirm Kiro’s situational advantage: for a Go-on-AWS stack, it is natively aware of SDK patterns and infrastructure artifacts — something that leaves generic tools often producing code that is “almost right” but not AWS-idiomatic.


08.8 Kiro’s Spec Quality: An Honest Assessment

Kiro produces good specs for standard features, but it still has limits. The honest assessment below sorts out what Kiro does well, what needs review, and what it often misses.

text
 1✅ What Kiro does well:
 2  - Basic CRUD features: very good
 3  - Error handling patterns: automatically include standard error codes
 4  - AWS service patterns: native awareness
 5  - Acceptance criteria structure: well-formed
 6
 7⚠️ What the developer needs to review:
 8  - Complex business rules: need manual verification
 9  - Cross-service dependencies: often over/under-specify
10  - Performance requirements: sometimes generic ("response time < 200ms")
11  - Edge cases: not always comprehensive
12
13❌ What Kiro often gets wrong or misses:
14  - Domain-specific business rules (cancel window = 30 minutes)
15  - Security requirements (authentication, authorization)
16  - Data consistency requirements in a distributed system

The recommendation is firm: always review the spec Kiro generates before approving. Treat it as a starting point that needs refinement, not a final artifact — especially for domain-specific business rules and security requirements.


08.9 Team Onboarding with Kiro

Kiro is very useful for onboarding new developers to a Go project. The day-one comparison below shows the difference between without Kiro and with Kiro backed by good steering docs.

text
 1A new developer joins the Santekno team:
 2
 3Day 1 without Kiro:
 4  "Read the codebase for a few days first"
 5  → Developer confused, doesn't know what's important
 6  → Asks a senior for review on every small step
 7
 8Day 1 with Kiro + good steering docs:
 9  Kiro reads all steering docs:
10    - .kiro/steering/project.md (architecture)
11    - .kiro/steering/go-conventions.md (patterns)
12    - .kiro/steering/testing.md (test patterns)
13
14  Developer: "Implement CRUD for Product Review"
15
16  Kiro: "Based on the architecture from the steering docs,
17   here is the spec I propose for Product Review CRUD:
18   [spec per the team's Clean Architecture convention]
19   Plan: [plan per the layer pattern the team uses]"
20
21  Developer productive from day 1,
22  because Kiro uses the steering docs as guardrails.

The key is not Kiro itself, but the quality of the steering docs: once the team’s conventions are written down, Kiro turns them into guardrails that make a junior developer productive from day one without constantly interrupting seniors.


08.10 Kiro Beta: What to Expect

Kiro in mid-2026 is still in beta and free, with a number of limitations you need to anticipate. The summary below separates the current beta limitations from post-beta cost estimates.

text
 1Kiro status mid-2026: Beta (free)
 2
 3Known beta limitations:
 4  - Spec verification sometimes false positive
 5  - Agent hooks still experimental in some edge cases
 6  - Large monorepo support still beta
 7  - Some AWS services not yet covered (newer services)
 8
 9Post-beta expectations (best estimate):
10  Pricing: $15-30/dev/month (estimate)
11  Bedrock cost: separate (~$5-20/dev/month for moderate usage)
12  Total: ~$20-50/dev/month

A sensible strategy: adopt now while it’s free to evaluate its value, then make the final decision when post-beta pricing is announced. Remember that the Bedrock cost is billed separately from the Kiro license.


08.11 Troubleshooting Kiro for Go

Several common problems arise when using Kiro for Go, and nearly all of them trace back to steering docs that lack detail. For the case where Kiro doesn’t detect Go 1.22 features, add an explicit version constraint like the following.

markdown
1# .kiro/steering/go-version.md
2## Go Version Requirements
3This project uses Go 1.22 ONLY.
4Features available: generics (basic), for-range variables, maps.Must
5NOT available: range-over-func, slices.Collect, iter.Seq (Go 1.23+)
6```

If the generated spec doesn’t follow Clean Architecture, spell out layer-specific rules for spec generation in the steering doc. The example is as follows.

markdown
1# .kiro/steering/architecture.md
2## Layer Rules for Spec Generation
3
4When generating a spec for ANY feature:
51. Handler layer ONLY calls usecase (via interface)
62. Usecase layer ONLY calls repository (via interface)
73. Repository layer ONLY accesses database/cache
84. No direct DB access from handler or usecase
9```

For mocks that don’t regenerate automatically, install an agent hook that watches for repository file changes. Its minimal config is like this.

yaml
1# .kiro/hooks/auto-mock.yaml
2triggers:
3  - type: file_saved
4    pattern: "internal/domain/**/repository.go"
5actions:
6  - run: "go generate ./internal/domain/..."

The solution pattern is consistent: nearly every Kiro problem is solved by clarifying the steering docs or adding an agent hook — the upfront investment in written context pays off as far more compliant output.


08.12 Kiro + Spec Kit: A Usable Combination

If a team already uses Spec Kit and wants to try Kiro, the two don’t have to replace each other. The two combination options below let you take the best of each.

text
 1Option A: Spec Kit for spec generation, Kiro for IDE implementation
 2  1. specify feature → generate .specify/features/x/spec.md
 3  2. Copy/reference the spec to .kiro/features/x/spec.md
 4  3. Kiro: "Implement based on this spec"
 5  4. Kiro's agent hooks for quality automation
 6
 7Option B: Kiro for spec, Spec Kit for audit
 8  1. Kiro → generate and implement the feature
 9  2. specify audit → verify compliance (Spec Kit's audit is more mature)
10  3. CI: specify audit in GitHub Actions
11
12Best of both worlds: Kiro's IDE-embedded workflow + Spec Kit's mature audit tools

This combination lowers adoption risk: you take advantage of Kiro’s smooth IDE workflow while still leaning on Spec Kit’s more mature audit for final verification.


08.13 Kiro in the Context of a Team Already Using SDD

For a team already running SDD from previous topics, Kiro adoption should be gradual. The per-sprint adoption map below shows a low-risk path from a mere “IDE companion” to a full workflow.

text
 1Sprint 1: Kiro as an "IDE companion" for the existing workflow
 2  - Use Kiro for inline coding (like Cursor)
 3  - Don't yet use Kiro's spec feature
 4  - Set up steering docs first
 5
 6Sprint 2-3: Try the spec feature for new features
 7  - Let Kiro generate the spec (still use Spec Kit for audit)
 8  - Compare: Kiro spec vs manual spec from Spec Kit
 9
10Sprint 4+: Full Kiro workflow for one project
11  - Kiro for spec + implementation
12  - Spec Kit only for audit (specify audit --all)
13  - Agent hooks for quality automation

This gradual adoption is low-risk because Spec Kit remains a fallback and its audit capability stays in use — the team doesn’t need to abandon a proven tool just to try a new one.


08.14 Kiro for Go Testing: A Complete Workflow

Kiro has a unique approach: test generation is tied directly to the spec. Before writing test code, Kiro creates a test plan that maps every case to an AC. Its example test plan is as follows.

markdown
 1# .kiro/features/cancel-order/test-plan.md
 2
 3## Test Plan: Cancel Order
 4
 5### Unit Tests (usecase layer)
 6- [ ] TC-01: Happy path — PENDING within 30 min → nil error
 7- [ ] TC-02: Order not found → ErrOrderNotFound
 8- [ ] TC-03: Order not owned by user → ErrOrderNotFound
 9- [ ] TC-04: Status not PENDING → OrderNotCancellableError
10- [ ] TC-05: Window expired (> 30 min) → ErrCancelWindowExpired
11- [ ] TC-06: Repository cancel fails → wrapped error
12- [ ] TC-07: Kafka publish fails → nil (best-effort, no error)
13- [ ] TC-08: Concurrent cancel → only first succeeds
14
15### Integration Tests
16- [ ] TC-09: Full flow via HTTP endpoint
17- [ ] TC-10: Database rollback on stock restore failure
18```

After the test plan is approved, Kiro implements the tests with testify/suite + gomock per the steering doc. The snippet below shows a full suite for the happy-path and window-expired scenarios.

go
 1type CancelOrderSuite struct {
 2    suite.Suite
 3    ctrl          *gomock.Controller
 4    mockOrderRepo *mock.MockOrderRepository
 5    mockPublisher *mock.MockEventPublisher
 6    uc            *usecase.CancelOrderUseCase
 7}
 8
 9func (s *CancelOrderSuite) SetupTest() {
10    s.ctrl = gomock.NewController(s.T())
11    s.mockOrderRepo = mock.NewMockOrderRepository(s.ctrl)
12    s.mockPublisher = mock.NewMockEventPublisher(s.ctrl)
13    s.uc = usecase.NewCancelOrderUseCase(s.mockOrderRepo, s.mockPublisher)
14}
15
16func (s *CancelOrderSuite) TearDownTest() {
17    s.ctrl.Finish()
18}
19
20func (s *CancelOrderSuite) TestExecute_PendingWithinWindow_ReturnsNil() {
21    orderID := uuid.New()
22    userID := uuid.New()
23    order := &domain.Order{
24        ID:        orderID,
25        UserID:    userID,
26        Status:    domain.StatusPending,
27        CreatedAt: time.Now().Add(-10 * time.Minute),
28    }
29
30    s.mockOrderRepo.EXPECT().
31        GetByIDAndUserID(gomock.Any(), orderID, userID).
32        Return(order, nil)
33    s.mockOrderRepo.EXPECT().
34        CancelWithStockRestore(gomock.Any(), orderID).
35        Return(nil)
36    s.mockPublisher.EXPECT().
37        PublishOrderCancelled(gomock.Any(), orderID, userID)
38
39    err := s.uc.Execute(context.Background(), usecase.CancelOrderInput{
40        OrderID: orderID,
41        UserID:  userID,
42    })
43    s.NoError(err)
44}
45
46func (s *CancelOrderSuite) TestExecute_WindowExpired_ReturnsError() {
47    orderID := uuid.New()
48    userID := uuid.New()
49    order := &domain.Order{
50        ID:        orderID,
51        UserID:    userID,
52        Status:    domain.StatusPending,
53        CreatedAt: time.Now().Add(-31 * time.Minute), // expired
54    }
55
56    s.mockOrderRepo.EXPECT().
57        GetByIDAndUserID(gomock.Any(), orderID, userID).
58        Return(order, nil)
59
60    err := s.uc.Execute(context.Background(), usecase.CancelOrderInput{
61        OrderID: orderID,
62        UserID:  userID,
63    })
64    s.ErrorIs(err, domain.ErrCancelWindowExpired)
65}
66
67func TestCancelOrderSuite(t *testing.T) {
68    suite.Run(t, new(CancelOrderSuite))
69}

Because every test case comes from a test plan tied to an AC, the resulting coverage can be traced directly to the specification — not merely tests that “look complete” but leave it unclear which requirement they cover.


08.15 Kiro CloudFormation and Terraform Integration

For a Go developer on AWS who also manages infrastructure, Kiro is aware of AWS resource patterns and can generate templates while aligning the Go code. The illustration below shows the flow from a prompt to a CloudFormation template and code adjustments.

text
 1"Add a DynamoDB table for orders"
 2→ Kiro generates a CloudFormation template:
 3
 4Resources:
 5  OrdersTable:
 6    Type: AWS::DynamoDB::Table
 7    Properties:
 8      TableName: orders
 9      BillingMode: PAY_PER_REQUEST
10      AttributeDefinitions:
11        - AttributeName: pk
12          AttributeType: S
13        - AttributeName: sk
14          AttributeType: S
15      KeySchema:
16        - AttributeName: pk
17          KeyType: HASH
18        - AttributeName: sk
19          KeyType: RANGE
20      PointInTimeRecoverySpecification:
21        PointInTimeRecoveryEnabled: true
22
23And updates the Go code to match the table structure:
24→ DynamoDB repository implementation
25→ Config struct with the table name from an env var
26→ Test with local DynamoDB (DynamoDB Local)

The selling point here is cross-layer consistency: Kiro not only creates the infrastructure template, but also aligns the Go repository, config, and tests to the same table structure — reducing drift between the IaC and the application code.


08.16 Kiro Adoption on a Team: Rollout Strategy

For a team already using another tool, the Kiro rollout should be gradual and evidence-based. The four-phase plan below moves from a small pilot to a full post-beta adoption decision.

text
 1PHASE 1 — Pilot (2 weeks):
 2  Volunteers: the 2 most open-minded developers
 3  Task: implement 1-2 medium-complexity features with Kiro
 4  Deliverable: retrospective with concrete pros/cons
 5
 6PHASE 2 — Expanded Pilot (2 weeks):
 7  Expand to the whole team
 8  New feature: use Kiro; bug fixes: keep the old tool
 9  Deliverable: team survey, metric baseline
10
11PHASE 3 — Full Adoption (if the pilot is positive):
12  Kiro as the primary for new features
13  Steering documents become a team standard (commit to the repo)
14  Agent hooks standardized
15
16PHASE 4 — Hybrid Post-Beta:
17  Evaluate pricing vs value
18  If pricing is OK: continue full adoption
19  If pricing is high: Kiro for complex features, another tool for everyday

What matters in this rollout is a metric-based decision, not hype: the baseline is taken in the pilot phase, and full adoption proceeds only if the pilot proves positive and post-beta pricing is reasonable.


08.17 Kiro Features Not Yet Covered

Several Kiro features are rarely highlighted but relevant to Go developers. The points below summarize additional capabilities that enrich the day-to-day experience.

Terminal Integration: Kiro has a built-in terminal that is aware of AI context. When an error appears in the terminal, Kiro can auto-suggest a fix without you needing to copy-paste into the chat.

Diff-based Review: Like Cursor, Kiro shows a diff before applying changes, reducing the anxiety of “AI changing code without a preview”.

Workspace Management: Kiro has a workspace concept similar to VS Code, but with persistent AI context — useful for monorepos.

Custom Tools/Plugins: Kiro supports custom tools via an API, so a team can integrate it with internal systems (Jira, internal CI, etc.).

These features confirm that Kiro is not merely a spec generator: it is designed as a complete IDE with diff previews, a context-aware terminal, and extensibility — bringing it close to Cursor’s comfort while preserving spec-first discipline.


08.18 Post-Beta Prediction: Worth It or Not?

Because post-beta pricing has not been announced, the long-term adoption decision depends on the pricing scenario. The cost-benefit analysis below maps three possibilities along with recommendations.

text
 1Scenario 1: Kiro pricing $15-20/dev/month
 2  TCO with Bedrock: ~$20-30/dev/month total
 3  Comparable to Cursor ($20) or Windsurf Pro ($15)
 4  Recommendation: Worth it IF in the AWS ecosystem
 5
 6Scenario 2: Kiro pricing $30-40/dev/month
 7  TCO with Bedrock: ~$40-50/dev/month total
 8  More expensive than a Cursor + Bedrock combo
 9  Recommendation: Evaluate based on unique value (spec-first, hooks)
10
11Scenario 3: Kiro pricing > $50/dev/month
12  Not competitive unless there is very compelling enterprise value
13  Recommendation: Stick with Claude Code + Spec Kit

The practical conclusion: Kiro is worth keeping at low-to-mid pricing scenarios, especially for AWS teams, but once total cost (including Bedrock) breaks $50/dev, the Claude Code + Spec Kit combination becomes the more rational alternative.


08.19 Benchmark: Kiro on Santekno Shop

To place Kiro objectively, we ran the same five benchmark scenarios as the other tools. The numbers below summarize the overall and per-scenario scores.

text
 1AWS Kiro performance on our benchmark:
 2
 3Overall: 88/100 (rank #2 after Claude Code)
 4
 5By scenario:
 6  S1 (Implement from spec):  87/100 — spec auto-generation is very helpful
 7  S2 (Write unit tests):     91/100 — one of the best, strong spec awareness
 8  S3 (Refactoring):          86/100 — adequate, not as powerful as Cursor Composer
 9  S4 (Debug race condition): 85/100 — adequate, not as deep as Claude Code
10  S5 (OpenAPI generation):   91/100 — generation is very aligned with the spec
11
12Kiro's unique strength: the spec-first workflow reduces ambiguity
13that often causes deviation in other tools.

The score of 88 places Kiro in second, with standout strength in test generation and OpenAPI (both 91) — proof that spec awareness genuinely reduces deviation from requirements. Its weakness is consistent in complex debugging.


08.20 Kiro Setup Checklist for a Go Project

To keep setup on track, use the phased checklist below. It divides the work into the first day, the first week, and weeks two through four.

text
 1Initial setup (Day 1):
 2□ Download and install Kiro
 3□ Connect to an AWS account
 4□ Create .kiro/steering/project.md
 5□ Create .kiro/steering/go-conventions.md
 6□ Create .kiro/steering/testing.md
 7□ Set up a basic agent hook (go build on save)
 8□ Test with a simple feature
 9
10Week 1:
11□ Refine steering docs based on the generated output
12□ Add more agent hooks (lint, test)
13□ Try spec generation for one feature
14□ Compare spec quality with a manual spec
15
16Week 2-4:
17□ Set up spec generation for every new feature
18□ Evaluate: does adoption improve vs Spec Kit?
19□ Decide: full Kiro or hybrid with Spec Kit?

This checklist deliberately delays the big decision (full Kiro vs hybrid) until the fourth week — after you have enough data from spec comparisons and real experience, not first impressions.


08.21 Tips & Gotchas

The following field lessons help you maximize Kiro while avoiding the traps commonly encountered by Go teams.

💡 Tip 1: Invest in steering documents — good steering docs make Kiro far more effective. Just like CLAUDE.md for Claude Code, spend 2-3 hours upfront.

💡 Tip 2: Review the spec before approving — don’t immediately approve the generated spec. An ambiguous spec = a wrong implementation. Review the ACs one by one.

💡 Tip 3: Agent hooks for quality automation — set up hooks (build check, test, vet) from day one to save wasted debugging time.

💡 Tip 4: Use it while it’s free — beta = free = no risk. Try a full sprint before evaluating.

⚠️ Gotcha 1: Kiro’s spec is too prescriptive — sometimes Kiro puts implementation detail into the spec (which should be in the plan). Review and simplify when it happens.

⚠️ Gotcha 2: Non-AWS projects benefit less — if your project is not on AWS, many of Kiro’s unique advantages are irrelevant. Consider Claude Code or Cursor.

⚠️ Gotcha 3: Kiro is still beta — some edge cases may not be stable yet. Don’t rely on Kiro for tight production-critical deadlines without a backup plan.

The common thread: Kiro’s value is directly proportional to your upfront investment in steering docs and agent hooks, as well as how deeply your stack is rooted in AWS — these two factors determine whether Kiro is right for you.


08.22 Summary

AWS Kiro is the best choice for Go developers who are in the AWS ecosystem, want a spec-first workflow built into the IDE (without a CLI), need structured onboarding via steering docs, and are willing to try it for free while in beta.

Its weaknesses: still beta, non-AWS projects benefit less, and post-beta pricing is still TBD.

The 88/100 score on our benchmark is real and impressive — Kiro proves that a built-in spec-first workflow produces code more compliant with requirements, independently validating the SDD approach. The recommended strategy: try it now while free, set up good steering docs, evaluate after a full sprint, and decide on post-beta adoption based on the pricing to be announced.

In the next article, we switch to the dark horse from Codeium that excels at cross-session context retention: Windsurf with its Cascade feature and deep contextual coding.

Related Articles

💬 Comments