mk:database — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited mk:database (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Data invariants first, engine syntax second. Discover what the repository already runs before proposing anything.
| Owner | Owns | Does NOT own |
|---|---|---|
mk:api-design-principles | Interface contract: resource/type/message shape, error and authorization requirements, compatibility and deprecation, consumer discovery | Implementation, persistence, security verdict, release |
mk:backend-development | End-to-end backend change: discovery, classification, service/handler/integration work | Contract authorship, schema/SQL, security verdict, deploy |
mk:database | Data invariants, schema, migration and recovery, query/index evidence, ORM data-access boundary | API contract, authorization verdict, infrastructure execution |
mk:devops | Infrastructure-as-code, containers, CI, runtime config, deployment safety design, rollback, incident diagnosis | Deploy approval and execution, security verdict, code root-cause, schema semantics |
Routing rules — identical in all four skills:
owned by another skill. "Contract" means what a consumer can observe: field set, error shape, status semantics, pagination, versioning. Extending an endpoint without changing any of those is not a contract change.
when a new, public, or breaking contract is in scope.
mk:api-design-principles; the producer or consumer implementation belongs to mk:backend-development.
migration or generic SQL.
mk:backend-development locates where the time actually goes, then hands a query or index question to mk:database and a capacity or runtime question to mk:devops. No skill invents the target.
mk:devops owns the operational picture — whatchanged, where it fails, which signal proves it — and hands the defect over.
workflow owns the verdict.
Read, in this order, and stop guessing as soon as evidence appears: the dependency manifest, the schema or model definitions, the migration directory and its tool, the ORM configuration, the call sites that query, the data tests and fixtures, and the active plan.
Record the engine, its version if the repository states one, the migration tool, and whether an ORM owns the schema. There is no default engine. If the repository does not say, ask — proposing syntax for the wrong engine wastes the whole answer.
| Class | Load |
|---|---|
| Data model or schema change | references/schema-design.md |
| Migration, backfill, or recovery | references/migration-patterns.md |
| Slow query, index choice, access-path question | references/query-optimization.md |
| Datastore or ORM selection | The section below; no reference needed |
Write these down before a line of schema. Mark anything unknown as unknown rather than filling it in:
An invariant nobody can state is the finding. Report it.
Model the invariants, then let the engine's capabilities shape the syntax. Normalize or denormalize only with a stated query, consistency, or evolution rationale — never speculatively, in either direction. Choose an index from the filter, join, and ordering evidence gathered above, weighed against its write cost; an index with no query behind it is overhead.
Follow the naming, key, and timestamp conventions the repository already uses. Where a convention is absent, propose one and say it is a proposal.
For any change to a table that already holds data, state: compatibility with the code that is currently running, the locking or runtime behavior on this engine at this size, the backfill approach if one is needed, the signal that proves it worked, and the recovery path — a reverse migration or a documented forward recovery.
An expand → migrate/backfill → contract sequence fits most non-trivial changes on a live table. Use it where it fits; say why when it does not.
Never run a reset, drop, backfill, or migration against a live or production database. Prepare it and hand execution to mk:ship or a human.
Validate on a disposable database with synthetic, non-personal fixtures. Copying production data into another environment is a data-protection decision for the user, not a testing technique to recommend.
Hand off with: engine evidence, invariants, the change, the migration and its recovery path, the query/index evidence, and what remains unproven.
Only when the project is greenfield or the user explicitly asks to change stores.
Decide from the invariants in step 3, not from familiarity: the shape of the data and its relationships, the consistency requirement, the read and write patterns, the operational capability the team actually has, and what the rest of the system already runs. Adding a second store adds a second operational burden — it needs a reason beyond convenience.
An ORM is a data-access boundary, not the data model. Keep the invariants expressed in the database where the database can enforce them, let the ORM express access, and expect to drop to the query language for anything the ORM shapes badly. Whichever the repository already uses is the one to use.
Never build a query by string interpolation or template concatenation. Use the parameter mechanism the driver or ORM provides — this is a blocked pattern, not a style preference.
Never log, print, or copy personal data while investigating. A row that reproduces a bug can be described by its shape.
| File | Load when |
|---|---|
references/schema-design.md | Modelling entities, keys, relationships, tenancy, or constraints |
references/migration-patterns.md | Changing a table that holds data; backfills; recovery |
references/query-optimization.md | A query is slow, or an index decision needs evidence |
Each is conditional on the engine the repository actually runs. Confirm the engine before applying one.
PostgreSQL before 12 it takes an exclusive lock for the rewrite. Add the column nullable, backfill in batches, then add the constraint — on PostgreSQL 12 and later that final step is a validating scan, not a rewrite. Other engines differ; check yours.
cannot run inside a transaction block and can leave an invalid index if it fails. Other engines have their own online-DDL rules — MySQL's depend on the algorithm chosen, and SQLite rewrites the table for most schema changes.
before any bulk delete, in any engine that supports them.
INSERT/UPDATE/DELETE outside a transaction you will roll back; plain EXPLAIN is the safe form for a mutating statement.
timeout fires while connections sit idle in an open transaction. Check for connections held past their work before optimizing the query.
one transaction can disagree. Financial and inventory logic needs a stricter level, chosen explicitly. Engines differ in their default and in what each level actually guarantees.
intended workloads; it only becomes a problem where write concurrency or online DDL is required. Do not treat it as a reason to propose a different engine.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.