/infra-audit -- Infrastructure Auditor
When to Use
- Before adding a new database, cache, or queue to a project
- When onboarding to an unfamiliar codebase and need to understand its infra
- Before planning a workspace campaign that spans multiple services
- When someone asks "what systems does this project talk to?"
Do not use when:
- The user already knows the infra and just wants to wire something up (use
/architect)
- The question is about code architecture, not infrastructure (use
/research)
Protocol
Step 1: DISCOVER
Scan the project for infrastructure configuration files. Check each category:
Container orchestration:
docker-compose.yml, docker-compose.*.yml
Dockerfile, *.dockerfile
k8s/, kubernetes/, helm/, charts/
Environment and secrets:
.env, .env.*, .env.example, .env.local
*.env files in config directories
Database and ORM:
- Prisma:
prisma/schema.prisma
- Drizzle:
drizzle.config.ts, drizzle/
- TypeORM:
ormconfig.*, data-source.ts
- Sequelize:
.sequelizerc, config/database.*
- Knex:
knexfile.*
- SQLAlchemy:
alembic.ini, alembic/
- Django:
settings.py (DATABASES section)
- Rails:
config/database.yml
- Go: look for
pgx, gorm, sqlx in go.mod
Message queues and event streaming:
- Redis: connection strings,
ioredis, redis in package.json/requirements.txt/go.mod
- RabbitMQ:
amqplib, pika, amqp imports
- Kafka:
kafkajs, confluent-kafka, sarama imports
- NATS:
nats, nats.go imports
- SQS/SNS:
@aws-sdk/client-sqs, boto3 sqs references
Cache:
- Redis (dual-use -- note if used as cache vs. pub/sub vs. primary store)
- Memcached:
memcached, pylibmc imports
Search:
- Elasticsearch:
@elastic/elasticsearch, elasticsearch-py
- Meilisearch, Typesense, Algolia client libraries
Object storage:
- S3:
@aws-sdk/client-s3, boto3 s3 references
- MinIO, GCS, Azure Blob client libraries
External APIs:
- Stripe, Twilio, SendGrid, Auth0, Firebase, Supabase client libraries
- Any
NEXT_PUBLIC_* or VITE_* env vars pointing to external services
CI/CD:
.github/workflows/, .gitlab-ci.yml, Jenkinsfile, bitbucket-pipelines.yml
For each discovered item, record:
- What: the system (e.g., "PostgreSQL 15")
- Where: config file path and line
- How: connection method (direct, pooled, ORM, SDK)
- Role: primary store, cache, queue, search, auth, etc.
Step 2: TRACE CONNECTIONS
For each discovered system, trace how the application connects:
- Find connection strings in env files or config
- Find the client initialization code (imports,
new Client(), createPool())
- Identify which modules/services use this connection
- Note connection pooling, retry logic, health checks if present
Build a connection graph:
App --> [pool: 10] --> PostgreSQL (primary store)
App --> [ioredis] --> Redis (cache + pub/sub)
App --> [SDK] --> Stripe (payments)
Step 3: ANALYZE PATTERNS
Based on what's connected and how it's used, identify:
Access patterns:
- Read-heavy vs. write-heavy (look at query patterns in ORM usage)
- Real-time vs. batch (WebSocket/SSE presence, cron jobs)
- Request/response vs. event-driven (queue usage, webhook handlers)
Missing layers (flag only when evidence supports the need):
| Signal |
Likely Missing |
Evidence Required |
| Repeated identical DB queries in hot paths |
Cache layer (Redis/Memcached) |
Same query in 3+ request handlers |
setTimeout/setInterval for deferred work |
Job queue (Bull/BullMQ/Celery) |
Processing that doesn't need to block the response |
Full-text search via LIKE '%term%' |
Search engine (Elasticsearch/Meilisearch) |
Text search on >10K rows |
| Large file uploads stored in DB or local disk |
Object storage (S3/MinIO) |
Binary columns or fs.writeFile for user content |
| Analytics queries on production tables |
Analytics DB (Snowflake/BigQuery/ClickHouse) |
Aggregation queries mixed with OLTP |
| Multiple services sharing one DB |
Event bus or API gateway |
2+ repos writing to same schema |
| No connection pooling |
Connection pooler (PgBouncer) |
Direct connections in serverless/high-concurrency |
Do not flag something as missing unless the evidence is in the code.
Step 4: WRITE MANIFEST
Output the infrastructure manifest to .planning/infra-manifest.md:
# Infrastructure Manifest
> Generated: {ISO date}
> Project: {project name from package.json or repo name}
## Current Systems
### {System Name} -- {Role}
- **Type**: {database|cache|queue|search|storage|auth|payments|...}
- **Product**: {PostgreSQL 15|Redis 7|Stripe SDK|...}
- **Config**: `{file path}`
- **Connection**: {method -- pooled, direct, SDK, ORM}
- **Used by**: {modules/services that import the client}
(repeat for each system)
## Connection Graph
{ASCII diagram of connections -- use /ascii-diagram conventions}
## Access Patterns
- {Pattern 1}: {evidence}
- {Pattern 2}: {evidence}
## Opportunities
### {Opportunity Title}
- **Signal**: {what in the code suggests this}
- **System**: {what would address it -- e.g., "Redis as cache layer"}
- **Impact**: {what improves -- latency, scalability, separation of concerns}
- **Effort**: low | medium | high
(repeat for each opportunity)
## Multi-Repo Considerations
{If the project references other repos, APIs, or shared databases, note them here.
This section feeds directly into /workspace if the user wants to act on opportunities
that span repos.}
Step 5: RETURN
Present a summary to the user:
- How many systems found
- The connection graph (inline, not just in the file)
- Top opportunities ranked by signal strength
- Whether any opportunities would require multi-repo coordination (suggest
/workspace)
Fringe Cases
- No docker-compose or env files: Scan for hardcoded connection strings in source code.
Many projects connect without formal config files. Check
src/, lib/, config/ for
connection patterns. Note the absence of externalized config as a finding.
- Monorepo with multiple services: Treat each service directory as a separate scan target.
Produce one manifest with sections per service. Note shared databases across services.
.planning/ does not exist: Create it before writing the manifest.
- No infrastructure found: Report that the project appears to be client-only or has no
external dependencies. This is a valid finding, not an error.
- Secrets in env files: Never include actual secret values in the manifest. Record the
variable name and which system it connects to, not the value.
Contextual Gates
Disclosure: "Auditing infrastructure configuration. No files modified."
Reversibility: green — read-only audit; only writes .planning/infra-manifest.md; undo with rm .planning/infra-manifest.md.
Trust gates:
- Any: full audit, manifest generation, opportunity analysis.
Quality Gates
Exit Protocol
---HANDOFF---
- Scanned {N} config files, found {M} external systems
- Key systems: {list top 3-4}
- Top opportunity: {highest-signal opportunity}
- Multi-repo scope: {yes/no -- if yes, suggest /workspace}
- Reversibility: green — delete .planning/infra-manifest.md to undo
---
1---2name: infra-audit3description: Reads docker-compose, env files, ORM configs, and connection strings to map current infrastructure. Flags missing layers (cache, queue, analytics) based on observed access patterns. Outputs a structured infrastructure manifest.4license: MIT5---67# /infra-audit -- Infrastructure Auditor89## When to Use1011- Before adding a new database, cache, or queue to a project12- When onboarding to an unfamiliar codebase and need to understand its infra13- Before planning a workspace campaign that spans multiple services14- When someone asks "what systems does this project talk to?"1516**Do not use when:**17- The user already knows the infra and just wants to wire something up (use `/architect`)18- The question is about code architecture, not infrastructure (use `/research`)1920## Protocol2122### Step 1: DISCOVER2324Scan the project for infrastructure configuration files. Check each category:2526**Container orchestration:**27- `docker-compose.yml`, `docker-compose.*.yml`28- `Dockerfile`, `*.dockerfile`29- `k8s/`, `kubernetes/`, `helm/`, `charts/`3031**Environment and secrets:**32- `.env`, `.env.*`, `.env.example`, `.env.local`33- `*.env` files in config directories3435**Database and ORM:**36- Prisma: `prisma/schema.prisma`37- Drizzle: `drizzle.config.ts`, `drizzle/`38- TypeORM: `ormconfig.*`, `data-source.ts`39- Sequelize: `.sequelizerc`, `config/database.*`40- Knex: `knexfile.*`41- SQLAlchemy: `alembic.ini`, `alembic/`42- Django: `settings.py` (DATABASES section)43- Rails: `config/database.yml`44- Go: look for `pgx`, `gorm`, `sqlx` in go.mod4546**Message queues and event streaming:**47- Redis: connection strings, `ioredis`, `redis` in package.json/requirements.txt/go.mod48- RabbitMQ: `amqplib`, `pika`, `amqp` imports49- Kafka: `kafkajs`, `confluent-kafka`, `sarama` imports50- NATS: `nats`, `nats.go` imports51- SQS/SNS: `@aws-sdk/client-sqs`, `boto3` sqs references5253**Cache:**54- Redis (dual-use -- note if used as cache vs. pub/sub vs. primary store)55- Memcached: `memcached`, `pylibmc` imports5657**Search:**58- Elasticsearch: `@elastic/elasticsearch`, `elasticsearch-py`59- Meilisearch, Typesense, Algolia client libraries6061**Object storage:**62- S3: `@aws-sdk/client-s3`, `boto3` s3 references63- MinIO, GCS, Azure Blob client libraries6465**External APIs:**66- Stripe, Twilio, SendGrid, Auth0, Firebase, Supabase client libraries67- Any `NEXT_PUBLIC_*` or `VITE_*` env vars pointing to external services6869**CI/CD:**70- `.github/workflows/`, `.gitlab-ci.yml`, `Jenkinsfile`, `bitbucket-pipelines.yml`7172For each discovered item, record:73- **What**: the system (e.g., "PostgreSQL 15")74- **Where**: config file path and line75- **How**: connection method (direct, pooled, ORM, SDK)76- **Role**: primary store, cache, queue, search, auth, etc.7778### Step 2: TRACE CONNECTIONS7980For each discovered system, trace how the application connects:81821. Find connection strings in env files or config832. Find the client initialization code (imports, `new Client()`, `createPool()`)843. Identify which modules/services use this connection854. Note connection pooling, retry logic, health checks if present8687Build a connection graph:88```89App --> [pool: 10] --> PostgreSQL (primary store)90App --> [ioredis] --> Redis (cache + pub/sub)91App --> [SDK] --> Stripe (payments)92```9394### Step 3: ANALYZE PATTERNS9596Based on what's connected and how it's used, identify:9798**Access patterns:**99- Read-heavy vs. write-heavy (look at query patterns in ORM usage)100- Real-time vs. batch (WebSocket/SSE presence, cron jobs)101- Request/response vs. event-driven (queue usage, webhook handlers)102103**Missing layers** (flag only when evidence supports the need):104105| Signal | Likely Missing | Evidence Required |106|---|---|---|107| Repeated identical DB queries in hot paths | Cache layer (Redis/Memcached) | Same query in 3+ request handlers |108| `setTimeout`/`setInterval` for deferred work | Job queue (Bull/BullMQ/Celery) | Processing that doesn't need to block the response |109| Full-text search via `LIKE '%term%'` | Search engine (Elasticsearch/Meilisearch) | Text search on >10K rows |110| Large file uploads stored in DB or local disk | Object storage (S3/MinIO) | Binary columns or `fs.writeFile` for user content |111| Analytics queries on production tables | Analytics DB (Snowflake/BigQuery/ClickHouse) | Aggregation queries mixed with OLTP |112| Multiple services sharing one DB | Event bus or API gateway | 2+ repos writing to same schema |113| No connection pooling | Connection pooler (PgBouncer) | Direct connections in serverless/high-concurrency |114115**Do not flag something as missing unless the evidence is in the code.**116117### Step 4: WRITE MANIFEST118119Output the infrastructure manifest to `.planning/infra-manifest.md`:120121```markdown122# Infrastructure Manifest123124> Generated: {ISO date}125> Project: {project name from package.json or repo name}126127## Current Systems128129### {System Name} -- {Role}130- **Type**: {database|cache|queue|search|storage|auth|payments|...}131- **Product**: {PostgreSQL 15|Redis 7|Stripe SDK|...}132- **Config**: `{file path}`133- **Connection**: {method -- pooled, direct, SDK, ORM}134- **Used by**: {modules/services that import the client}135136(repeat for each system)137138## Connection Graph139140{ASCII diagram of connections -- use /ascii-diagram conventions}141142## Access Patterns143144- {Pattern 1}: {evidence}145- {Pattern 2}: {evidence}146147## Opportunities148149### {Opportunity Title}150- **Signal**: {what in the code suggests this}151- **System**: {what would address it -- e.g., "Redis as cache layer"}152- **Impact**: {what improves -- latency, scalability, separation of concerns}153- **Effort**: low | medium | high154155(repeat for each opportunity)156157## Multi-Repo Considerations158159{If the project references other repos, APIs, or shared databases, note them here.160This section feeds directly into /workspace if the user wants to act on opportunities161that span repos.}162```163164### Step 5: RETURN165166Present a summary to the user:167- How many systems found168- The connection graph (inline, not just in the file)169- Top opportunities ranked by signal strength170- Whether any opportunities would require multi-repo coordination (suggest `/workspace`)171172## Fringe Cases173174- **No docker-compose or env files**: Scan for hardcoded connection strings in source code.175 Many projects connect without formal config files. Check `src/`, `lib/`, `config/` for176 connection patterns. Note the absence of externalized config as a finding.177- **Monorepo with multiple services**: Treat each service directory as a separate scan target.178 Produce one manifest with sections per service. Note shared databases across services.179- **`.planning/` does not exist**: Create it before writing the manifest.180- **No infrastructure found**: Report that the project appears to be client-only or has no181 external dependencies. This is a valid finding, not an error.182- **Secrets in env files**: Never include actual secret values in the manifest. Record the183 variable name and which system it connects to, not the value.184185## Contextual Gates186187**Disclosure:** "Auditing infrastructure configuration. No files modified."188**Reversibility:** green — read-only audit; only writes `.planning/infra-manifest.md`; undo with `rm .planning/infra-manifest.md`.189**Trust gates:**190- Any: full audit, manifest generation, opportunity analysis.191192## Quality Gates193194- [ ] Every discovered system has: type, product, config path, connection method195- [ ] Connection graph covers all discovered systems196- [ ] Opportunities cite specific code evidence (file:line), not speculation197- [ ] No secret values appear in the manifest198- [ ] Manifest written to `.planning/infra-manifest.md`199- [ ] Multi-repo considerations section populated if cross-repo signals exist200201## Exit Protocol202203```204---HANDOFF---205- Scanned {N} config files, found {M} external systems206- Key systems: {list top 3-4}207- Top opportunity: {highest-signal opportunity}208- Multi-repo scope: {yes/no -- if yes, suggest /workspace}209- Reversibility: green — delete .planning/infra-manifest.md to undo210---211```