Skip to content
Back to skills

Durable

ASecurity

Use when user data must not be lost or corrupted — creating the first table/schema, writing or running migrations, backfills/imports, any destructive op (delete, drop, truncate, reset, overwrite), before the agent itself runs a command against a database that may hold real data, setting up backups/recovery, or moving data between systems; plus "is my data safe / back up my app" checks. Any store — SQL, document, serverless, files, queues. Do NOT use for query speed or pool sizing (that is lea...

  • 28 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 1, 2026
ai-agentsgoshellsqldatabase

Works with

  • cli

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned October 4, 2026

npx -y skills add KenKaiii/gg-framework --skill durable --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Durable?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Durable
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/kenkaiii-durable/badge)](https://www.skillsdirectory.com/skills/kenkaiii-durable)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: durable
description: Use when user data must not be lost or corrupted — creating the first table/schema, writing or running migrations, backfills/imports, any destructive op (delete, drop, truncate, reset, overwrite), before the agent itself runs a command against a database that may hold real data, setting up backups/recovery, or moving data between systems; plus "is my data safe / back up my app" checks. Any store — SQL, document, serverless, files, queues. Do NOT use for query speed or pool sizing (that is lean), access control over data (that is bulletproof), or privacy/legal deletion regimes (that is compliance-guard).
license: Data-durability engineering guidance, not a DBA certification. Sources and snapshot date are recorded at the foot of each reference file.
compatibility: Snapshot dated 3 October 2026. Version behaviours, provider retention defaults and tool flags decay — re-verify with web access before asserting them as current.
---

# Durable

**Route first:**

| You are… | Mode | Do next |
|---|---|---|
| About to run *any* command against a database yourself (migrate, reset, push, seed, SQL shell, delete script) | **Agent gate** | Run the agent gate below before the command. Always. |
| Writing code that touches stored data (table, migration, import, delete endpoint, webhook write, backup cron) | **Inline gate** | Apply binding defaults; one line on the guard you built; keep building. |
| Asked "is my data safe / back up my app", a migration is about to hit production, or after a data scare | **Full pass** | Run the full-pass workflow. |

Users forgive slow and ugly; they do not forgive gone. Never say data is "safe" — say what loss is survivable and what is not.

## Agent gate — binding rules for you, the agent

Coding agents have wiped production data: in July 2025 Replit's agent deleted a live project database during an explicit code freeze, then wrongly said rollback was impossible (`SNAPSHOT`; details in `references/agent-db-safety.md`). The freeze was only a natural-language instruction; nothing mechanical enforced it. These rules are the mechanism.

1. **Identify the target before every command.** Resolve which database the command will hit (env var, config file, `--url`, ORM config). Classify it `throwaway` / `shared-dev` / `may-hold-real-data` using the detection list in `references/agent-db-safety.md`. Unknown = `may-hold-real-data`.
2. **On `may-hold-real-data`, read-only by default.** Inspect with `SELECT`/`EXPLAIN`/`\d`, a read-only role, or `BEGIN READ ONLY`. No DDL, no writes, no `migrate dev|reset`, `db push`, `--force`, `--accept-data-loss`, `flush`, `dropDatabase`, `TRUNCATE`, seed scripts.
3. **Destructive or schema-changing commands on real data require all of:** (a) a backup or PITR point you verified exists *for this database* (`RUNTIME` or provider-console evidence, not assumption), (b) a dry-run count of affected rows shown to the user, (c) the exact command shown, and (d) the user's explicit go-ahead in this conversation for that command. "Go ahead and fix it" does not cover a `DROP`.
4. **Experiment on a branch, not the original.** Prefer a Neon / Supabase / PlanetScale branch, a restored clone, or a local copy; prove the change there, then hand the production step back with evidence.
5. **Never bypass a tool's safety interlock yourself.** If a CLI refuses because it detected an agent (e.g. Prisma's AI-consent check) or asks for confirmation, stop and ask — never set a consent variable or pass `--force`/`--yes` on your own initiative.
6. **Surprising results mean stop, not fix.** Empty tables, missing rows, failed restores: report what you observed and ask. Never "repair" by recreating, reseeding, or fabricating data, and never declare data unrecoverable without checking the provider's backups/PITR.
7. **Report exactly what you ran** — every command that touched a database, its target, and its result, including mistakes, immediately.

Also flag (do not silently fix) setups where the agent's shell holds production write credentials: recommend separate dev/prod credentials, a read-only role for inspection, and production URLs absent from local `.env`.

## Governing rules

1. **The store is the last line of defence.** `NOT NULL`, `UNIQUE`, foreign keys with a chosen `ON DELETE`, `CHECK` — in the database, where scripts and bugs cannot walk past them.
2. **Destructive operations are guilty until guarded**: `WHERE` + batch limit, dry-run count first, backup when anything of value exists, undo path (soft delete, staging copy) for user-facing data.
3. **Migrations run on data you cannot recreate.** Checked in, reviewed as SQL (ORM output included — a rename can become `DROP` + `ADD`), never edited once applied, forward-only in production. Push/sync commands are for throwaway databases.
4. **One logical change, one transaction; anything retried is idempotent.**
5. **Backups you have not restored are fiction.** Automated, off-instance, stated RPO/RTO, timed restore drill.
6. **Fail loudly, not corruptly.** Bulk jobs are keyset-resumable with durable checkpoints.
7. **Respect the store's concurrency model** — SQLite has one writer; transaction poolers break session state.
8. **Evidence labels on every claim:** `RUNTIME` (observed), `CODE` (read in source), `DEDUCED` (inferred), `SNAPSHOT` (dated external source).
9. **Proportionality.** Test rows need migrations; the first real user row raises the floor to backups, then tested restore, then PITR.

## Binding defaults (inline gate)

- **Migration tooling from the first table.** Generate without applying (`prisma migrate dev --create-only`, `drizzle-kit generate`), read the SQL, apply via the deploy path (`prisma migrate deploy`, `drizzle-kit migrate`). Corrections are new migrations.
- **Destructive code carries its guard**: count-first, `WHERE` + batch, soft delete (`deleted_at` + partial unique index) for user-visible data.
- **Constraints in the store** per rule 1; integer cents or `NUMERIC` for money; `bigint`/UUID keys (Postgres 18 has built-in `uuidv7()` for time-ordered IDs).
- **Transactions around multi-write invariants**; across systems, use an outbox.
- **Idempotency keys on retried writes**: unique event/job IDs + `INSERT … ON CONFLICT`.
- **Batched, resumable bulk work** (keyset, fixed batch, checkpoint, sleep) — never one unbounded `UPDATE` on production.
- **Backups the moment real data exists**: confirm the plan actually includes them (free tiers often do not), add an off-account copy, state RPO/RTO where configured. Uploads need bucket versioning — DB backups do not cover objects.
- **Separate credentials per environment**; production URL never the default in local `.env`.
- **Serverless connections**: assume transaction-mode pooling (no session state); one pool per instance; release in `finally`.
- **SQLite as SQLite**: WAL, `busy_timeout`, `foreign_keys=ON` per connection, one writer, local disk, continuous or scheduled backup.

## Full-pass workflow

1. **Profile from the code.** Stores and versions, migration tooling, every write/delete path, backup config, environments and credentials, and — decisive — whether real user data exists.
2. **Define loss.** Recreatable (caches, derived) vs unrecoverable (user content, uploads, payments), and what links out (rows ↔ files).
3. **Sweep the seven areas** (detail in references):

| # | Area | Hunting for |
|---|---|---|
| 1 | Backups & recovery | None; same machine/account only; free tier assumed to be PITR; never restored; no RPO/RTO; unversioned upload buckets |
| 2 | Destructive paths | Unguarded `DELETE`/`UPDATE`; cascades sweeping too far; reset/push/drop in scripts or CI near production config |
| 3 | Agent & credential exposure | Prod write URL in local `.env`; agent/CI tokens with DDL rights; no branch/dev DB to experiment on |
| 4 | Migrations health | No tooling; edited applied migrations; unreviewed destructive SQL; lock-unsafe DDL; drift |
| 5 | Transactions & idempotency | Multi-writes without a transaction; double-apply on retry; check-then-act races |
| 6 | Schema integrity | Missing FKs/uniques/`NOT NULL`; orphans; float money; int IDs near overflow |
| 7 | Runtime data safety | Session state through transaction poolers; SQLite multi-writer; non-atomic file writes; no dead-letter path |

4. **Rank by survivability.**

| Severity | Meaning |
|---|---|
| Critical | Loss certain or one common failure away: real data with no backups; unguarded destructive path; pending data-dropping migration; agent/CI holding prod write creds with no verified backup; double-charge on retry |
| High | Loss on a plausible bad day: never-restored backups; single copy; broad cascades; multi-writes without transactions |
| Medium | Bites at scale or in recovery: missing constraints, drift, non-idempotent jobs, non-atomic writes |
| Low | Hygiene; fix only when adjacent |

5. **Fix Critical and High first** (three to five, each verified).
6. **Verify.**
   - *Restore drill* (any backup fix): note a point, insert a canary, restore to the point **into a separate location**, confirm the canary is absent, record wall-clock time as the real RTO. `RUNTIME` or it did not happen.
   - *Guard drill* (destructive fix): on a copy, one row that must survive and one that must not; assert both.
   - *Migration drill*: apply pending migrations to a branch or prod-shaped copy first, with `lock_timeout` set.
   - Anything you could not run: label it unverified and give the user the exact command.
7. **Leave a guard behind**: CI applying migrations to a throwaway DB, a migration linter, a scheduled restore test, a constraint, a read-only role for agents.
8. **Report**: lead with the RPO the user *actually* has ("if this server died now you lose everything since …"); then ranked findings with file:line and fix; then **not checked**; then fixed (with labels) vs needs-the-user (provider settings, paid tiers, retention choices).

## Scaling: one agent or several

| Situation | Policy |
|---|---|
| Agent gate, inline gate, small edits | Main thread only. Never spawn. |
| Full pass, one deployable, one store | Main thread builds the ledger (7 areas × stores/services) and works every row itself. |
| Full pass, several stores/services/deployables, or more rows than you can read fully | One read-only child per disjoint slice, all in ONE `spawn_agent` call (≤ 6). `owl` for code slices; `researcher` for dated provider/version claims. |
| Production migration plan or "is my data safe" verdict | Add a fresh-context verifier child that tries to disprove the findings and the restore evidence. |

- **Every ledger row ends** checked-with-findings / checked-clean / not-checked(reason). A child that fails, times out or omits a row → `not checked`, never clean.
- **Child briefs are self-contained**: absolute skill root, which reference to read, slice paths, owned rows, evidence labels, output schema (findings with file:line, label, severity, fix; `checked` / `not checked` lists), and: *read-only — never connect to or run commands against any database*.
- **Child output is evidence, not truth**: re-open each file:line before reporting.
- **Database commands are never parallel.** Migrations, restores, and any write against shared or production data are executed serially by the main thread after the agent gate — never by children. Code fixes are main-thread or `bee` on strictly disjoint files; run checks once after merging.

## Honesty rules

- "Backups are configured" is `CODE`; "recoverable" needs a `RUNTIME` restore. Never say "safe".
- Provider retention, tiers and version behaviour are `SNAPSHOT` with a date — verify before quoting.
- Never claim data is gone, or restored, without checking. A fabricated restore test is the worst lie this skill could tell.

## Reference map

Resolve paths from the installed skill root; load only what the profile triggers.

- `references/agent-db-safety.md` — incident record, production-target detection, safe inspection, branch/clone workflow, tool interlocks. Read before any agent-run database command on a non-throwaway target, and for area 3.
- `references/migrations-and-schema.md` — expand/contract, lock-safety table with `lock_timeout`, Postgres 18 notes, backfills, ORM traps (Prisma 7, Drizzle, framework linters), integrity sweep. Read for areas 2, 4, 6.
- `references/backups-and-runtime.md` — tiers and restore drill, provider PITR snapshot, Litestream 0.5 and SQLite backups, object versioning/Object Lock, idempotency/outbox, poolers. Read for areas 1, 5, 7.

Files in this skill

  • SKILL.md13.6 KB
  • references/backups-and-runtime.md8.2 KB
  • references/migrations-and-schema.md8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…