# Safety And Ownership

Read this before a cp9 action can change local runtime state or cloud resources.

## Route First

- Config: copy [`../../../cp9.dev-full.remote-ec2-k3d.example.yaml`](../../../cp9.dev-full.remote-ec2-k3d.example.yaml); its comments are the field-level source of truth.
- Remote Dev full setup, iteration, diagnosis, or closeout: read [`dev-full-aws-runtime.md`](dev-full-aws-runtime.md).
- Product-specific work: return to [`../SKILL.md`](../SKILL.md) and select the product skill.
- Known remote bring-up failure: read [`troubleshooting-remote-cp9-up.md`](troubleshooting-remote-cp9-up.md).

## Invariants

- Treat staging as source/template evidence, never the runtime to mutate for CP9 success.
- Resolve the exact account, region, owner, unique session, TTL, persona, and requested mutation before acting.
- Use the shared `cp9-developer` role unless the human explicitly supplies a different temporary credential boundary.
- Keep `.cp9/<session>/` and its Terraform/destroy evidence until `cp9 destroy` exits. Resume an owned interrupted Session with the same config; use a fresh name for concurrent work.
- Close a broken or abandoned Session through `cp9 destroy`. Do not substitute service APIs, manual state deletion, or broad AWS cleanup.
- Preserve the first unexpected red and diagnose it in place. Restart only when the owned state cannot be made consistent.
- Stop for human review when ownership is unprovable, a change broadens IAM/account scope, or staging/shared infrastructure would be mutated.

## Command Source

Use `bin/cp9 cmds.tree` and `bin/cp9 cmd <name>` for the live command/argument inventory. [`cli-output.md`](cli-output.md) owns non-obvious completion semantics; product skills own their subcommands. Prefer those shipped surfaces over hand-built local/AWS/Kubernetes commands.

## Operator Cleanup And Inventory

These commands are account-scoped operator surfaces, not replacements for normal Session closeout. They require the environment-selected cleanup account/profile/role and fail closed on identity mismatch.

| Command | Boundary |
| --- | --- |
| `cp9 purge dry-run=true region=<r>` | Read-only plan. No owner/session selects expired managed scopes; paired owner+session selects one exact scope. |
| `cp9 purge dry-run=false region=<r>` | Destructive plan, tag assurance, aws-nuke delete, and survivor verification for provable scope only. |
| `cp9 inventory volumes region=<r>` | Read-only volume attribution, including standalone orphans purge cannot prove. |
| `cp9 inventory instances region=<r>` | Read-only instance attribution. |
| `cp9 inventory security-groups region=<r>` | Read-only security-group attribution; default SG protected. |
| `cp9 inventory eks region=<r>` | Read-only EKS attribution, including missing-scope metadata. |

`purge` acts only on exact tags or trusted-parent proof. `inventory` sees unattributed/standalone resources without mutation. See [`../../../docs/adr/0007-purge-vs-inventory-boundary.md`](../../../docs/adr/0007-purge-vs-inventory-boundary.md).

Account ID, role ARN, profile, and timeouts come from `CP9_CLEANUP_*` operator configuration. An ordinary caller cannot redirect cleanup through public command arguments.

## Normal Session Flow

1. Copy the root config reference; edit only task-owned values.
2. Run `setup`, `doctor`, then `up dry-run=true`.
3. Run `up` only after required checks are green. Continue only on top-level `ready`.
4. Use `status`, bounded `logs`, and previewed `deploy` for iteration.
5. Prove the requested product behavior through its owning surface.
6. Run `destroy` and record the closeout.

If observation detaches after lifecycle completion, reattach with `cp9 status --watch`; rerunning `up` is for owned reconciliation, not observation alone.

## Evidence And Recovery

- For automation or a task handoff, use JSON `doctor`/`status` and cite structured fields rather than paraphrasing away the failing layer.
- Remote-host claims come from `layers.host.execution`: controller, source sync, private-module download, build/import hosts, k3d runtime, kube tunnel/config, and remote state directory.
- A direct cleanup is complete only from its produced final-survivor result. A delegated cleanup is complete for Session handoff when `destroy` records the accepted workflow and removes local state; observe the workflow only when its terminal result is an explicit acceptance criterion.
- A stale tag-index row is not a survivor only when the corresponding direct service verifier proves the resource gone.
- A running destroy owns its Session. Wait, repair/resume it, or start a different uniquely named Session and report both tracks separately.

## Human Gates

Stop before acting when the request would mutate staging/shared account infrastructure, credentials or target account are wrong, ownership tags are missing/conflicting, the source/live/stub boundary would change unexpectedly, or cleanup would extend beyond the exact authorized Session/account.

## References

- [`../SKILL.md`](../SKILL.md)
- [`../../../cp9.dev-full.remote-ec2-k3d.example.yaml`](../../../cp9.dev-full.remote-ec2-k3d.example.yaml)
- [`dev-full-aws-runtime.md`](dev-full-aws-runtime.md)
- [`cli-output.md`](cli-output.md)
- [`../../../docs/adr/0007-purge-vs-inventory-boundary.md`](../../../docs/adr/0007-purge-vs-inventory-boundary.md)
