environment-and-build-hazardslisted
Install: claude install-skill HamzaYM/reliable-ai-skills
# Environment and build hazards
Most local-environment pain falls into two buckets: a privilege/role mismatch that only shows up as a confusing runtime error, and "local" actually being a shared remote resource in disguise. Both are worth documenting explicitly rather than re-discovering per session.
## The two-role model, if your database enforces row-level isolation
If your database enforces tenant isolation via row-level security (or an equivalent per-tenant policy), you need **two distinct database roles**, not one:
- A schema-owning role, used **only** for running migrations.
- A least-privilege application role with no bypass privileges, used for everything the running app does.
The reason this has to be two roles: a superuser or bypass-privileged connection skips row-level security unconditionally and silently. No error, no warning: every isolation policy just quietly does nothing. If your app ever connects with the migration-owning role "because it was easier," every isolation guarantee in the system is inert without any visible signal that it's broken. On first-time setup, the app-only role is often created by an init script that runs once, at cluster creation. If you ever reset the underlying data volume, that role won't exist until you either re-run the init script by hand or fully recreate the environment.
## Seed data: know exactly what's idempotent and what isn't
Document precisely what a seed script does on a second run: does it add more data, or does it