# CLAUDE.md: Pulumi (TypeScript)

## Commands
- `npm run build` (tsc) · `npm test` (unit tests with mocks) · `pulumi preview --stack <stack> --diff`
- **Never run `pulumi up`, `pulumi destroy`, `pulumi refresh --yes`, `pulumi state delete`, or `pulumi stack rm` unless explicitly asked.** Show the preview instead.

## Structure
- `index.ts` composes components; reusable pieces are `ComponentResource` classes in `components/` with typed args interfaces and `registerOutputs`.
- Pass `{ parent: this }` to child resources in components so names and deletion order stay right.
- Stack differences live in `Pulumi.<stack>.yaml` config, read via `new pulumi.Config()` with `require`/`get` and typed defaults. No `if (stack === "prod")` scattered around; centralize it.

## Rules
- Secrets: `pulumi config set --secret dbPassword ...` and `config.requireSecret(...)`; never commit plain secrets or log Outputs that contain them.
- Outputs are async: combine with `pulumi.interpolate` or `pulumi.all([...]).apply(...)`. Don't create resources inside `apply` callbacks.
- Don't hard-code physical names unless needed; let Pulumi auto-name. Renaming a resource's logical name replaces it; use `aliases` to avoid replacement.
- Protect stateful production resources with `protect: true`; set `retainOnDelete` where data must survive.
- Tag/label everything via a shared `defaultTags` transform or provider config.
- Pin provider package versions in `package.json`.

## Testing
Unit tests use `pulumi.runtime.setMocks` to assert on resource properties; policy packs (CrossGuard) if configured.

## In summaries
List resources to be created, updated, and especially replaced or deleted from the preview.
