type: user

role: user

content:
You are a spec compliance reviewer. Read `/Users/steve.briggs/projects/operations/terraform/iac-library/aws/storage/database-tools-db/main.tf` and confirm all requirements are met:

1. `terraform` block: `required_version = "~> 1.0"`, providers `hashicorp/aws ~> 4.0` (with `aws.backup` alias), `hashicorp/vault ~> 3.0`, `random ~> 3.6.0`
2. `locals`: `name` (defaults to `tools-database-${var.env}` when empty) and `kms_key_name`
3. `module "database_kms"`: source `crow.infrastructure.immuta.io/internal/security-kms-key/aws` v1.4.0, count-gated on `var.storage_encrypted`
4. `resource "aws_kms_replica_key" "replica_key"`: count-gated on `var.storage_encrypted && var.encrypt_replicas`, `provider = aws.backup`
5. `module "database"`: source `crow.infrastructure.immuta.io/internal/data-database-rds/aws` v3.0.1, `subnet_ids = var.private_subnet_ids`, KMS args use `null` (not `""`) when disabled, includes `parameters = var.parameters`
6. `resource "vault_generic_secret" "admin_credentials"`: path `var.vault_secret_path`, stores `username`, `password`, `endpoint`, `address`, `port`, `db_name`

End with `SPEC REVIEW: ✅ COMPLIANT` or `SPEC REVIEW: ❌ ISSUES` with details.

userType: external

entrypoint: cli


content:
- obsidian-load: Load context from Obsidian notes in the `Claude/` directory into the current conversation.
- obsidian-save: Save current conversation context to an Obsidian note under the `Claude/` directory.
- mind:search: Search memories for specific content or patterns
- mind:stats: Show memory statistics and storage information
- mind:ask: Ask questions about memories and get context-aware answers
- mind:recent: Show recent memories and activity timeline
- mind:memory: Claude Mind - Search and manage Claude's persistent memory stored in a single portable .mv2 file
- mind:mind: Claude Mind - Search and manage Claude's persistent memory stored in a single portable .mv2 file
- superpowers:dispatching-parallel-agents: Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies
- superpowers:test-driven-development: Use when implementing any feature or bugfix, before writing implementation code
- superpowers:systematic-debugging: Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes
- superpowers:executing-plans: Use when you have a written implementation plan to execute in a separate session with review checkpoints
- superpowers:using-superpowers: Use when starting any conversation - establishes how to find and use skills, requiring Skill tool invocation before ANY response including clarifying questions
- superpowers:using-git-worktrees: Use when starting feature work that needs isolation from current workspace or before executing implementation plans - ensures an isolated workspace exists via native tools or git worktree fallback
- superpowers:requesting-code-review: Use when completing tasks, implementing major features, or before merging to verify work meets requirements
- superpowers:finishing-a-development-branch: Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
- superpowers:brainstorming: You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.
- superpowers:writing-plans: Use when you have a spec or requirements for a multi-step task, before touching code
- superpowers:receiving-code-review: Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation
- superpowers:verification-before-completion: Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always
- superpowers:writing-skills: Use when creating new skills, editing existing skills, or verifying skills work before deployment
- superpowers:subagent-driven-development: Use when executing implementation plans with independent tasks in the current session
- update-config: Use this skill to configure the Claude Code harness via settings.json. Automated behaviors ("from now on when X", "each time X", "whenever X", "before/after X") require hooks configured in settings.json - the harness executes these, not Claude, so memory/preferences cannot fulfill them. Also use for: permissions ("allow X", "add permission", "move permission to"), env vars ("set X=Y"), hook troubleshooting, or any changes to settings.json/settings.local.json files. Examples: "allow npm commands", "add bq permission to global settings", "move permission to user settings", "set DEBUG=true", "when claude stops show X". For simple settings like theme/model, suggest the /config command.
- keybindings-help: Use when the user wants to customize keyboard shortcuts, rebind keys, add chord bindings, or modify ~/.claude/keybindings.json. Examples: "rebind ctrl+s", "add a chord shortcut", "change the submit key", "customize keybindings".
- verify: Verify that a code change actually does what it's supposed to by running the app and observing behavior. Use when asked to verify a PR, confirm a fix works, test a change manually, check that a feature works, or validate local changes before pushing.
- simplify: Review changed code for reuse, quality, and efficiency, then fix any issues found.
- fewer-permission-prompts: Scan your transcripts for common read-only Bash and MCP tool calls, then add a prioritized allowlist to project .claude/settings.json to reduce permission prompts.
- loop: Run a prompt or slash command on a recurring interval (e.g. /loop 5m /foo). Omit the interval to let the model self-pace. - When the user wants to set up a recurring task, poll for status, or run something repeatedly on an interval (e.g. "check the deploy every 5 minutes", "keep running /babysit-prs"). Do NOT invoke for one-off tasks.
- schedule: Create, update, list, or run scheduled remote agents (routines) that execute on a cron schedule. - When the user wants to schedule a recurring remote agent, set up automated tasks, create a cron job for Claude Code, or manage their scheduled agents/routines. Also use when the user wants a one-time scheduled run ("run this once at 3pm", "remind me to check X tomorrow").
- claude-api: Build, debug, and optimize Claude API / Anthropic SDK apps. Apps built with this skill should include prompt caching. Also handles migrating existing Claude API code between Claude model versions (4.5 → 4.6, 4.6 → 4.7, retired-model replacements).
TRIGGER when: code imports `anthropic`/`@anthropic-ai/sdk`; user asks for the Claude API, Anthropic SDK, or Managed Agents; user adds/modifies/tunes a Claude feature (caching, thinking, compaction, tool use, batch, files, citations, memory) or model (Opus/Sonnet/Haiku) in a file; questions about prompt caching / cache hit rate in an Anthropic SDK project.
SKIP: file imports `openai`/other-provider SDK, filename like `*-openai.py`/`*-generic.py`, provider-neutral code, general programming/ML.
- run: Launch and drive this project's app to see a change working. Use when asked to run, start, or screenshot the app, or to confirm a change works in the real app (not just tests). First looks for a project skill that already covers launching the app; otherwise falls back to built-in patterns per project type (CLI, server, TUI, Electron, browser-driven, library).
- init: Initialize a new CLAUDE.md file with codebase documentation
- review: Review a pull request
- security-review: Complete a security review of the pending changes on the current branch

type: attachment


type: message

role: assistant

type: text

text: I'll review the terraform file against the specifications you've provided.

service_tier: standard

attributionAgent: general-purpose

attributionPlugin: superpowers

type: assistant


Read

type: direct

speed: standard


content:
1	# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2	# SET UP THE DATABASE FOR TOOLS
3	# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5	terraform {
6	  required_version = "~> 1.0"
7
8	  required_providers {
9	    aws = {
10	      source                = "hashicorp/aws"
11	      version               = "~> 4.0"
12	      configuration_aliases = [aws.backup]
13	    }
14	    vault = {
15	      source  = "hashicorp/vault"
16	      version = "~> 3.0"
17	    }
18	    random = {
19	      version = "~> 3.6.0"
20	    }
21	  }
22	}
23
24	locals {
25	  name         = var.name != "" ? var.name : "tools-database-${var.env}"
26	  kms_key_name = "${local.name}-db-key"
27	}
28
29	# ----------------------------------------------------------------------------------------------------------------------
30	# CREATE KMS KEYS
31	# ----------------------------------------------------------------------------------------------------------------------
32
33	module "database_kms" {
34	  source  = "crow.infrastructure.immuta.io/internal/security-kms-key/aws"
35	  version = "1.4.0"
36	  count   = var.storage_encrypted ? 1 : 0
37
38	  customer_master_keys = {
39	    (local.kms_key_name) = {
40	      allow_manage_key_permissions_with_iam = true
41	      deletion_window_in_days               = var.kms_key_deletion_window_in_days
42	      enable_key_rotation                   = false
43	      multi_region                          = true
44	      tags                                  = var.tags
45	    }
46	  }
47	}
48
49	resource "aws_kms_replica_key" "replica_key" {
50	  count = var.storage_encrypted && var.encrypt_replicas ? 1 : 0
51
52	  provider   = aws.backup
53	  depends_on = [module.database_kms]
54
55	  description             = "KMS Replica Key for tools database"
56	  deletion_window_in_days = var.kms_key_deletion_window_in_days
57	  primary_key_arn         = module.database_kms[0].key_arns[local.kms_key_name]
58
59	  tags = var.tags
60	}
61
62	# ----------------------------------------------------------------------------------------------------------------------
63	# CREATE THE RDS INSTANCE
64	# ----------------------------------------------------------------------------------------------------------------------
65
66	module "database" {
67	  source  = "crow.infrastructure.immuta.io/internal/data-database-rds/aws"
68	  version = "3.0.1"
69
70	  providers = {
71	    aws.backup = aws.backup
72	  }
73
74	  name               = local.name
75	  pg_version         = var.pg_version
76	  env                = var.env
77	  ca_cert_identifier = var.ca_cert_identifier
78
79	  db_name        = var.db_name
80	  admin_username = var.admin_username
81	  instance_class = var.rds_instance_size
82
83	  enhanced_monitoring_enabled  = var.enhanced_monitoring_enabled
84	  performance_insights_enabled = var.performance_insights_enabled
85	  multi_az                     = var.multi_az
86	  parameters                   = var.parameters
87
88	  kms_key_arn             = var.storage_encrypted ? module.database_kms[0].key_arns[local.kms_key_name] : null
89	  kms_replication_key_arn = var.storage_encrypted && var.encrypt_replicas ? aws_kms_replica_key.replica_key[0].arn : null
90
91	  vpc_id              = var.vpc_id
92	  subnet_ids          = var.private_subnet_ids
93	  trusted_cidr_blocks = var.trusted_cidr_blocks
94
95	  subnet_group_name_override       = var.subnet_group_name_override
96	  dba_security_group_name_override = var.dba_security_group_name_override
97	  security_group_name_override     = var.security_group_name_override
98
99	  allocated_storage     = var.allocated_storage
100	  max_allocated_storage = var.max_allocated_storage
101	  storage_encrypted     = var.storage_encrypted
102	  storage_type          = var.storage_type
103
104	  backup_retention_period  = var.backup_retention_period
105	  replica_retention_period = var.replica_retention_period
106	  final_snapshot           = var.final_snapshot
107	  encrypt_replicas         = var.encrypt_replicas
108
109	  tags = var.tags
110
111	  depends_on = [module.database_kms, aws_kms_replica_key.replica_key]
112	}
113
114	# ----------------------------------------------------------------------------------------------------------------------
115	# STORE ADMIN CREDENTIALS IN VAULT
116	# ----------------------------------------------------------------------------------------------------------------------
117
118	resource "vault_generic_secret" "admin_credentials" {
119	  path = var.vault_secret_path
120
121	  data_json = jsonencode({
122	    username = module.database.admin_username
123	    password = module.database.admin_password
124	    endpoint = module.database.endpoint
125	    address  = module.database.address
126	    port     = module.database.port
127	    db_name  = module.database.name
128	  })
129	}
130


text:
Now I'll verify each requirement against the file:

**Requirement 1: `terraform` block**
- ✅ `required_version = "~> 1.0"` (line 6)
- ✅ `hashicorp/aws ~> 4.0` with `aws.backup` alias (lines 9-12)
- ✅ `hashicorp/vault ~> 3.0` (lines 14-16)
- ✅ `random ~> 3.6.0` (lines 18-19)

**Requirement 2: `locals`**
- ✅ `name` with default `tools-database-${var.env}` (line 25)
- ✅ `kms_key_name` defined (line 26)

**Requirement 3: `module "database_kms"`**
- ✅ Source `crow.infrastructure.immuta.io/internal/security-kms-key/aws` v1.4.0 (lines 34-35)
- ✅ Count-gated on `var.storage_encrypted` (line 36)

**Requirement 4: `resource "aws_kms_replica_key" "replica_key"`**
- ✅ Count-gated on `var.storage_encrypted && var.encrypt_replicas` (line 50)
- ✅ Provider set to `aws.backup` (line 52)

**Requirement 5: `module "database"`**
- ✅ Source `crow.infrastructure.immuta.io/internal/data-database-rds/aws` v3.0.1 (lines 67-68)
- ✅ `subnet_ids = var.private_subnet_ids` (line 92)
- ✅ KMS args use `null` when disabled (lines 88-89)
- ✅ Includes `parameters = var.parameters` (line 86)

**Requirement 6: `resource "vault_generic_secret" "admin_credentials"`**
- ✅ Path is `var.vault_secret_path` (line 119)
- ✅ Stores all required fields: `username`, `password`, `endpoint`, `address`, `port`, `db_name` (lines 122-127)

---

**SPEC REVIEW: ✅ COMPLIANT**

All requirements are met. The configuration file is properly structured with correct provider versions, local variable definitions, module sources and versions, count gates, KMS configurations, subnet mappings, and Vault secret storage.