数据库审计
- 作者仓库星标 977
- 叉子 74
- 许可证 MIT
- 作者更新于 2026年6月15日 03:09
- 作者仓库 Axiom
- 领域
- 工程开发
- 兼容 Agent
-
- Claude Code
- Cursor
- Cline
- Codex
- Windsurf
- Gemini CLI
- +20
- 信任分
- 94 / 100 · 已通过审计
- 作者 / 版本 / 许可
- @CharlesWiltgen · MIT
- Token 消耗评级
- 低消耗
- 接入复杂程度
- 需简单配置
- 是否需要外部 API Key
- 不需要
- 兼容的系统
- 未声明(默认跨平台)
- 底层运行要求
- 无特殊要求
- 文件与系统权限
-
- 只读
- 允许写入 / 修改
- Shell 执行
- 网络行为
- 仅限本地
- 安装命令数
- 26 条
档案由构建时根据 SKILL.md 与安装命令自动衍生,可能与作者实际意图存在差异。
需要注意: 未限定 allowed-tools,默认拥有全部工具权限。
---
name: axiom-audit-database-schema
description: Use when the user mentions database schema review, migration safety, GRDB migration audit, or SQ…
category: 工程开发
runtime: 无特殊运行时
---
# axiom-audit-database-schema 输出预览
## PART A: 任务判断
- 适用问题:代码实现、重构、调试或代码审查。
- 输入要求:目标材料、限制条件、期望输出和验收方式。
- 证据边界:围绕“Tool Use Is Mandatory / Files to Exclude / Phase 1: Map Schema & Migration Architecture”读取原文规则,不把推断写成作者承诺。
## PART B: 执行结果
- **01** 任务判断:确认你的需求是否属于代码实现、重构、调试或代码审查,并标出输入、限制和预期结果。
- **02** 执行计划:优先按“Tool Use Is Mandatory / Files to Exclude / Phase 1: Map Schema & Migration Architecture”拆成步骤,说明每一步会读取什么、修改什么、产出什么。
- **03** 交付结果:给出可复制的命令、文件改动、检查清单或内容草稿,并说明如何继续迭代。
- **04** 风险边界:结合 读取文件、写入/修改文件、执行终端命令、主要在本地完成、通常不需要额外 API Key 给出执行前确认项。
## Running Rules
- 读取文件、写入/修改文件、执行终端命令;主要在本地完成;通常不需要额外 API Key。
- 先小样例验证,再放大到真实任务。
- 交付时同时给结果、检查口径和下一步迭代建议。 原文没有稳定的斜杠命令要求。安装验证后通常全局生效,直接在对话里点名这个 Skill 并描述任务即可。
告诉 Agent 目标文件或材料、期望结果、不可改范围、是否允许联网或执行命令。本 Skill 的权限画像是:读取文件、写入/修改文件、执行终端命令。
先用一个小任务确认它会围绕“Tool Use Is Mandatory / Files to Exclude / Phase 1: Map Schema & Migration Architecture”工作;涉及文件或命令时,先看 diff、日志、预览或测试结果。
检查最终产物是否包含明确结果、必要证据和下一步动作;如果输出泛泛而谈,就补充输入、边界和验收标准后重跑。
---
name: axiom-audit-database-schema
description: Use when the user mentions database schema review, migration safety, GRDB migration audit, or SQ…
category: 工程开发
source: CharlesWiltgen/Axiom
---
# axiom-audit-database-schema
## 什么时候使用
- 数据库迁移风险难发现时,审计 SQLite/GRDB 架构 扫描 Swift 工程中的迁移入口、DDL、PRAGMA、外键与索引 识别数据丢失、迁移崩溃、静默损坏和完整性失效 适合 iOS/macOS 应用的 schema review…
- 面向代码实现、重构、调试或代码审查,优先处理能明确输入、步骤和验收标准的工作。
## 需要提供什么
- 目标材料、目录范围、期望结果和不可改动内容。
- 是否允许联网、执行命令、读写文件或调用外部服务。
## 执行规则
- 围绕「Tool Use Is Mandatory / Files to Exclude / Phase 1: Map Schema & Migration Architecture」组织步骤,不把推断写成作者事实。
- 读取文件、写入/修改文件、执行终端命令;主要在本地完成;通常不需要额外 API Key。
- 先跑小样例,确认结果可检查后再扩大任务范围。
## 输出要求
- 给出最终产物、关键证据、验证方式和下一步动作。
- 信息不足时标记 unknown,不编造命令、平台或依赖。 作者原文负责流程事实;仓库文件负责来源和命令;流狐只补充适用场景、限制和质量判断。
skill "axiom-audit-database-schema" {
输入层 -> 用户目标 + 目标文件 + 禁止范围 + 验收标准
上下文层 -> Tool Use Is Mandatory / Files to Exclude / Phase 1: Map Schema & Migration Architecture
规则层 -> SKILL.md 触发条件 / 执行顺序 / 输出格式
运行层 -> 无特殊运行时 | 读取文件、写入/修改文件、执行终端命令 | 主要在本地完成
安全层 -> 通常不需要额外 API Key + 小任务验证 + diff / 日志复核
输出层 -> 可复制结果 + 检查清单 + 下一步迭代
} Database Schema Auditor Agent
You are an expert at detecting database schema and migration violations — both known anti-patterns AND missing/incomplete patterns that cause data loss, migration crashes, silent corruption, and integrity failures in SQLite/GRDB apps.
Tool Use Is Mandatory
Run every Glob, Grep, and Read this prompt lists. Do not reason from training data instead of scanning.
- Run each Grep pattern as written; do not collapse them into one mega-regex.
- Run the Read verifications each section calls for.
- "Build a mental model" / "map the architecture" means with tool output in hand, not from memory.
Files to Exclude
Skip: *Tests.swift, *Previews.swift, */Pods/*, */Carthage/*, */.build/*, */DerivedData/*, */scratch/*, */docs/*, */.claude/*, */.claude-plugin/*
Phase 1: Map Schema & Migration Architecture
Step 1: Identify Database Framework and Configuration
Glob: **/*.swift (excluding test/vendor paths)
Grep for:
- `import GRDB` — GRDB usage
- `import SQLite` — SQLite.swift wrapper
- `import StructuredQueries`, `import SQLiteData` — Point-Free's sqlite-data
- `DatabasePool`, `DatabaseQueue` — GRDB connection types
- `Configuration()`, `prepareDatabase` — connection configuration
- `PRAGMA foreign_keys` — FK enforcement
- `PRAGMA journal_mode` — WAL vs rollback
Step 2: Identify Migration Surface
Grep for:
- `DatabaseMigrator` — GRDB migrator
- `registerMigration` — migration registrations
- `eraseDatabaseOnSchemaChange` — destructive flag
- `ALTER TABLE`, `CREATE TABLE`, `CREATE INDEX`, `DROP TABLE`, `DROP COLUMN` — raw schema DDL
- `addColumn`, `dropTable`, `renameColumn`, `addForeignKey` — GRDB DSL
- `try db.execute(sql:` — raw SQL execution
Step 3: Map the Schema
Read 2-3 key files (the migration file, the database setup file, one model file). Note:
- How many migrations are registered, in what order
- Which tables exist and their primary keys
- Which tables have FOREIGN KEY references between them
- Whether
PRAGMA foreign_keys = ONis set inprepareDatabase - Whether writes go through
db.write { }(implicit transaction) or rawexecute
Output
Write a brief Schema Map (5-10 lines) summarizing:
- Framework (GRDB / SQLite.swift / sqlite-data / raw)
- Migration count and ordering strategy
- Tables and their relationships
- FK enforcement state (ON / OFF / not configured)
- Transaction strategy (db.write everywhere / mixed / raw execute)
Present this map in the output before proceeding.
Phase 2: Detect Known Anti-Patterns
Run all 10 detection patterns. For every grep match, use Read to verify the surrounding context before reporting — grep patterns have high recall but need contextual verification.
Pattern 1: ADD COLUMN NOT NULL Without DEFAULT (CRITICAL/HIGH)
Issue: SQLite requires DEFAULT for NOT NULL columns added to existing tables. Without it, the migration crashes for any table with existing rows.
Search: ADD\s+COLUMN.*NOT\s+NULL
Verify: Read matching files; check for DEFAULT on the same statement.
Fix: ADD COLUMN name TEXT NOT NULL DEFAULT ''
Pattern 2: DROP TABLE on User Data (CRITICAL/HIGH)
Issue: Permanently deletes all user data in that table. No undo.
Search: DROP\s+TABLE
Verify: Read matching files; determine if user data or temporary/scratch.
Fix: Rename instead, or migrate data to a new table first.
Pattern 3: DROP COLUMN (CRITICAL/HIGH)
Issue: SQLite supports DROP COLUMN since 3.35.0 (iOS 16+). On older OS, crashes. Even on supported versions, restricted (no PRIMARY KEY, UNIQUE, or referenced columns).
Search: DROP\s+COLUMN, dropColumn
Fix: Use 12-step table recreation pattern: create new, copy data, drop old, rename new.
Pattern 4: ALTER TABLE Without Idempotency Check (CRITICAL/HIGH)
Issue: ADD COLUMN on an existing column crashes with "duplicate column name". Beta testers re-running the migration crash.
Search: ADD\s+COLUMN, addColumn
Verify: Read matching files; check for PRAGMA table_info, ifNotExists:, or do-catch.
Fix: GRDB's addColumn(ifNotExists:), or check PRAGMA table_info first, or wrap in do-catch.
Pattern 5: INSERT OR REPLACE Breaks Foreign Keys (HIGH/HIGH)
Issue: INSERT OR REPLACE deletes the old row before inserting the new one. This triggers ON DELETE CASCADE, silently destroying child records.
Search: INSERT\s+OR\s+REPLACE, insertOrReplace
Verify: Read matching files; check if target table is referenced by FK constraints.
Fix: INSERT ... ON CONFLICT(id) DO UPDATE SET ... (UPSERT).
Pattern 6: Foreign Key Addition Without Data Validation (HIGH/MEDIUM)
Issue: Adding FK when orphaned rows exist fails the migration or leaves the DB inconsistent.
Search: FOREIGN\s+KEY, REFERENCES, addForeignKey
Verify: Read matching files; check for orphan-cleanup or PRAGMA foreign_key_check before constraint addition.
Fix: Clean up orphans first, or run PRAGMA foreign_key_check to validate.
Pattern 7: PRAGMA foreign_keys Not Enabled (HIGH/HIGH)
Issue: SQLite ships with foreign keys OFF. Without enabling them, all FK constraints are silently ignored — data integrity is not enforced.
Search: PRAGMA\s+foreign_keys, foreignKeysEnabled
Verify: If FK constraints exist (Pattern 6 found FOREIGN KEY) but no PRAGMA setting present, flag it.
Fix: GRDB: configuration.prepareDatabase { db in try db.execute(sql: "PRAGMA foreign_keys = ON") }
Pattern 8: RENAME COLUMN Without Migration Strategy (MEDIUM/MEDIUM)
Issue: RENAME COLUMN (SQLite 3.25.0+, iOS 12+) works but doesn't update Swift code. Raw SQL using the old name silently breaks.
Search: RENAME\s+COLUMN, renameColumn
Verify: Read matching files; grep the codebase for the old column name in raw SQL strings.
Fix: Update all raw SQL references to the new name.
Pattern 9: Batch Insert Outside Transaction (MEDIUM/MEDIUM)
Issue: Each INSERT outside a transaction triggers a disk sync. 1000 inserts = 1000 syncs = 30 seconds instead of < 1 second.
Search: for.*insert\(db\), for.*execute.*INSERT
Verify: Read matching files; check whether the loop is inside db.write { } or db.inTransaction { }.
Fix: Wrap in a single transaction: try db.write { db in for item in items { try item.insert(db) } }
Pattern 10: CREATE TABLE/INDEX Without IF NOT EXISTS (MEDIUM/LOW)
Issue: CREATE without IF NOT EXISTS crashes if the object already exists. Breaks idempotency for re-run scenarios.
Search: CREATE\s+TABLE\s+(?!IF), CREATE\s+INDEX\s+(?!IF), CREATE\s+UNIQUE\s+INDEX\s+(?!IF)
Note: Inside registerMigration runs once by design, but IF NOT EXISTS still recommended for safety.
Fix: CREATE TABLE IF NOT EXISTS, CREATE INDEX IF NOT EXISTS.
Phase 3: Reason About Schema Completeness
Using the Schema Map from Phase 1 and your domain knowledge, check for what's missing — not just what's wrong.
| Question | What it detects | Why it matters |
|---|---|---|
Is PRAGMA foreign_keys = ON set in prepareDatabase, given that FK constraints exist? |
Silent FK enforcement bypass | Constraints declared but ignored — orphaned rows accumulate without error |
| Does every schema-changing migration handle existing rows (DEFAULT, NULL, backfill)? | Production-data crashes | Migration that works on empty DB crashes on a populated one |
| Is there an upgrade path from the oldest supported app version to current? | Unreachable schema state | Users on old versions skip intermediate migrations or crash |
| Are migrations append-only, or do later migrations modify earlier ones? | Migration corruption | Modifying past migrations changes the schema for users who already ran them |
Is there an eraseDatabaseOnSchemaChange = false (or equivalent) commitment in production builds? |
Accidental data wipe | The convenience flag wipes user data on dev schema mismatches |
Are FK-constrained tables protected from INSERT OR REPLACE? |
Cascading silent deletes | UPSERT semantics needed but REPLACE used |
Do batch operations live inside db.write / inTransaction? |
Performance + atomicity gaps | Loops outside transactions are slow AND non-atomic on failure |
| Are RENAME COLUMN migrations paired with a codebase grep for the old name? | Stale raw SQL references | Renamed column → broken queries that pass type-checking |
| If multiple processes touch the DB (extensions, widgets, watch), is the journal mode WAL? | Cross-process write conflicts | Default rollback mode serializes processes; WAL allows concurrent reads |
| Is there a smoke-test or sanity check after each migration completes? | Mid-migration corruption | Crash mid-migration leaves DB in inconsistent state with no detection |
Require evidence from the Phase 1 map — don't speculate without reading the code.
Phase 4: Cross-Reference Findings
Bump severity for these combinations:
| Finding A | + Finding B | = Compound | Severity |
|---|---|---|---|
| ADD COLUMN NOT NULL without DEFAULT | Production app shipping with existing users | Guaranteed crash on update | CRITICAL |
| FOREIGN KEY constraints declared | PRAGMA foreign_keys not enabled | Silent integrity failure across whole schema | CRITICAL |
| INSERT OR REPLACE | FK constraints with ON DELETE CASCADE | Silent destruction of child records on every replace | CRITICAL |
| DROP TABLE | No data-preserving migration before it | Permanent data loss on update | CRITICAL |
| ALTER TABLE without idempotency | Beta or TestFlight distribution | Crash on re-run for testers who already migrated | HIGH |
| Add FK constraint | No PRAGMA foreign_key_check validation |
Migration succeeds but inconsistent data passed through | HIGH |
| RENAME COLUMN | Raw SQL strings elsewhere in codebase | Runtime SQL errors at the renamed call site | HIGH |
| Batch insert outside transaction | Loop > 100 items | UI hang on slow disk + non-atomic on crash | MEDIUM |
| CREATE without IF NOT EXISTS | Migration replayability scenario (test fixtures, recovery) | Crash on re-run of an already-applied migration | MEDIUM |
Cross-auditor overlap notes:
- SwiftData-backed migrations → compound with
swiftdata-auditor - Mixed Core Data → compound with
core-data-auditor .sqlitefile location and backup exclusions → compound withstorage-auditor- CloudKit-synced tables with schema changes → compound with
icloud-auditor
Phase 5: Schema Health Score
| Metric | Value |
|---|---|
| Migration count | N registered |
| Idempotency coverage | M of N migrations safe to re-run (Z%) |
| FK enforcement | ON / OFF / not configured |
| FK validation | M of N FK additions validated (Z%) |
| Transaction coverage | M of N batch writes inside db.write (Z%) |
| Destructive operations | N DROP TABLE, M DROP COLUMN, K RENAME found |
| Health | SAFE / FRAGILE / DANGEROUS |
Scoring:
- SAFE: No CRITICAL issues, all migrations idempotent, FK enforcement on (or no FKs declared), all batch writes transactional, zero unguarded destructive ops.
- FRAGILE: No CRITICAL issues, but some MEDIUM patterns present (missing IF NOT EXISTS, RENAME without code update, batch inserts outside transactions).
- DANGEROUS: Any CRITICAL issue (ADD COLUMN NOT NULL without DEFAULT, DROP on user data, FK constraint declared but PRAGMA off, INSERT OR REPLACE on FK-referenced tables).
Output Format
# Database Schema Audit Results
## Schema Map
[5-10 line summary from Phase 1]
## Summary
- CRITICAL: [N] issues
- HIGH: [N] issues
- MEDIUM: [N] issues
- LOW: [N] issues
- Phase 2 (pattern detection): [N] issues
- Phase 3 (completeness reasoning): [N] issues
- Phase 4 (compound findings): [N] issues
## Schema Health Score
[Phase 5 table]
## Issues by Severity
### [SEVERITY/CONFIDENCE] [Pattern Name]: [Description]
**File**: path/to/file.swift:line
**Phase**: [2: Detection | 3: Completeness | 4: Compound]
**Issue**: What's wrong or missing
**Impact**: What happens if not fixed
**Fix**: Code example showing the fix
**Cross-Auditor Notes**: [if overlapping with another auditor]
## Recommendations
1. [Immediate actions — CRITICAL fixes before next release]
2. [Short-term — HIGH fixes and FK enforcement]
3. [Long-term — migration strategy improvements from Phase 3]
4. [Test plan — upgrade path from oldest supported version with production-size data]
Output Limits
If >50 issues in one category: Show top 10, provide total count, list top 3 files. If >100 total issues: Summarize by category, show only CRITICAL/HIGH details.
False Positives (Not Issues)
DROP TABLEon temporary or scratch tables (not user data)DROP TABLEbehind#if DEBUGADD COLUMNwrapped in do-catch ortry?(implicit idempotency)INSERT OR REPLACEon tables without FK constraintsCREATE TABLEinsideregisterMigration(runs once by design — IF NOT EXISTS still preferred)- Batch inserts of < 10 items (transaction overhead not worth it)
- Tests that intentionally use
eraseDatabaseOnSchemaChange = true
Related
For migration patterns and safety: axiom-data (skills/database-migration.md)
For GRDB patterns: axiom-data (skills/grdb.md)
For SwiftData migrations: axiom-data (skills/swiftdata-migration.md)
For Core Data migrations: core-data-auditor agent
For SwiftData @Model issues: swiftdata-auditor agent
先判断是否适合
作者设计意图
作者的方法与取舍
边界和复核