schema-review
Use when reviewing a migration diff or schema change for scale hazards — indexes, unsafe migrations, unbounded growth, N+1. Triggers on 'review this migration', 'will this scale'.
- License 许可
- MIT
- 最近更新
- 2026-11-14
- Stars
- ★ 19
- Forks
- 1
01 前言 Front Matter
- name
- schema-review
- packs
- [ "scale-discipline" ]
- trust
- { "level": "professional" }
- domain
- engineering
- install
- { "default": false, "removable": true }
- model_tier
- medium
- workspaces
- [ "engineering" ]
- description
- Use when reviewing a migration diff or schema change for scale hazards — indexes, unsafe migrations, unbounded growth, N+1. Triggers on 'review this migration', 'will this scale'.
02 资源文件 1
- 参考文档evals/triggers.json1.3 KB
03 SKILL.md 正文
schema-review
When to use
- A migration diff, new migration file, or schema change is under review and the question is scale-shaped: indexes, reversibility, growth, query patterns against the new columns.
- The user asks "will this scale", "review this migration", "check the
schema", or a PR touches
migrations/,schema.prisma, or raw.sqlmigration files. - NOT for runtime performance analysis of live traffic (no APM here —
route to
performance-analysis) and NOT for authoring a new migration from scratch (route tolaravel-migrationor the stack-native tool, then come back with the diff), and NOT for designing the schema itself (route todatabase, which owns relational modeling).
Procedure
-
Detect the stack surface in the diff: Laravel migrations (
database/migrations/*.php), Prisma (schema.prisma+prisma/migrations/**/migration.sql), raw SQL (*.sql). One diff can carry several. -
Run the deterministic linter on the touched files plus the query surface that references the changed tables:
npx tsx node_modules/@event4u/agent-config/src/scripts/lint_persistence.ts --dir <path> [--stack eloquent|prisma|raw-sql] --format jsonThe linter emits
gatefindings (pattern-detected: F1 N+1, F2 index-parity, F3 unbounded reads, F6 migration-safety, F7 growth-budget, F8 audit-coverage, F9 sync-in-handler, F11 non-durable async) andadvicefindings (heuristics — never treat as blockers). -
Walk the gap table — for every
gatefinding decide: fix, or waiver with a reason (// no-index: <reason>,// sync-required: <reason>,-- no-retention: <reason>, …). An empty waiver reason is itself a finding. -
Check the R-A6/R-A7 invariants by hand where the linter is blind: reversibility of data transformations, retention policy for any new append-only table (the
-- retention: <policy>line), backfill plan for new NOT NULL columns on large tables. -
A drop or rename → run the consumer census before judging it safe: app side via
blast-radius-analyzer, catalog side viaconsumer-census. -
Report waiver density neutrally — count waivers per rule; state both readings (informed exceptions vs rule misfit) and let the human decide. Density alone is never a verdict.
Output
The review MUST contain:
- Gap table — one row per finding:
rule · file:line · finding · proposed action (fix | waiver | accepted), gate findings first, advice findings clearly marked as advice. - Waiver-density line —
N waivers across M findingswith the two-reading note (informed exceptions vs rule misfit). - A one-line verdict: ready / needs fixes / needs human schema decision — never a bare "looks good" without the table.
Gotcha
- The linter proves pattern presence, not instance-level correctness
— a flagged
Http::call in a controller may be legitimately sync (then it gets a// sync-required:waiver with a reason), and a clean run does not prove the schema scales. Say what was checked, not more. - Prisma's
@relationfields are indexed implicitly on some connectors and not on others — when the linter reports a missing FK index on a Prisma model, verify the connector before calling it a defect.
Do NOT
- Do NOT gate a review on
advice-tier findings (F4 denormalization, F10 event-decoupling heuristics) — they are review inputs, not blockers. - Do NOT strip or rewrite existing waivers — surface stale-looking ones and ask.
- Do NOT invent index recommendations for columns the query surface never filters or orders by — index parity cuts both ways; unused indexes cost write throughput.
04 同仓库更多 Skills
unknown-key-fixture
Declares a key the schema does not know.
portable-fixture
Declares only semantics the MCP-lite carrier transports whole.
non-portable-fixture
Declares a runtime semantic the carrier drops.
candidate-zero-width
A candidate whose prose carries an invisible joiner.
candidate-disclosure-suppression
A candidate whose prose tells the agent to withhold from the user.
candidate-dangerous-frontmatter
A candidate claiming an unscoped tool grant and a permission bypass.