pg-migration Skill Evaluation Report¶
Evaluation date: 2026-04-18 | Method: A/B blind comparison | Total assertions: 23 | Scenarios: 3
The pg-migration skill reveals an interesting pattern: the baseline Claude already performs well at 87.0% (compared to 52% for mysql-migration), because PostgreSQL migration safety rules like CONCURRENTLY, NOT VALID, and lock_timeout are widely documented and thoroughly trained into the base model. The skill's core value, then, is not knowledge injection — it is structural enforcement: requiring all §9 sections on every review, enforcing the Data basis traceability label, and applying strict original-SQL scoring. It also cuts token consumption by 46.1% by eliminating exploratory reasoning and external tool calls.
1. Skill Overview¶
Core files:
| File | Lines | Purpose |
|---|---|---|
SKILL.md | 353 | Main framework: 3 depths, lock classification rules, §9.1–§9.9 output contract, Scorecard format |
references/lock-matrix.md | — | Per-DDL lock level reference (AccessExclusiveLock, ShareLock, RowShareLock) |
references/large-table-migration.md | — | pg_repack, shadow-table, and CONCURRENTLY strategies for >10M-row tables |
references/anti-examples.md | — | Common migration anti-patterns with corrected SQL |
Key safety rules the skill enforces:
- CREATE INDEX must use
CONCURRENTLYto avoid ShareLock blocking writes - Foreign keys must follow the
NOT VALID→VALIDATE CONSTRAINTtwo-step pattern on live tables - All DDL must be wrapped with
SET lock_timeoutto prevent indefinite waits ALTER COLUMN TYPEon large tables triggers a full table rewrite — must be replaced by pg_repack or shadow-table-swap- Hard rule: Never classify a migration as SAFE without explicit evidence; conserve assumptions in degraded mode
- Original SQL scoring: the submitted SQL is scored independently from any corrected DDL produced during review
2. Test Design¶
2.1 Evaluation Method¶
Framework: A/B blind test. Each scenario runs two parallel sub-agents:
- Without Skill: receives only the scenario description and SQL — no SKILL.md content
- With Skill: receives the scenario description, SQL, complete SKILL.md, and depth-appropriate reference files
Scoring:
| Grade | Meaning |
|---|---|
| PASS | Output explicitly includes the element (exact language or clear equivalent) |
| PARTIAL | Partially addressed but incomplete or methodologically flawed |
| FAIL | Element completely absent from the output |
2.2 Scenarios¶
| # | Name | Context | Core challenge |
|---|---|---|---|
| S0 | Standard DDL Review | PostgreSQL 14.5, users table, 2M rows, 1,500 QPS, streaming replication, golang-migrate, no maintenance window | Three DDL statements mixing lock levels and risk classes |
| S1 | Large-Table High-Risk Migration | PostgreSQL 13.8, events table, 60M rows, ~85 GB, 24/7 service, streaming (2 replicas) + logical replication (analytics) | ALTER COLUMN TYPE triggering full table rewrite + irreversible DROP COLUMN |
| S2 | Degraded Mode Boundary | PostgreSQL version unknown (possibly 11–15), products table — all key metrics unknown (rows, size, QPS, replication) | Review with near-zero context; conservative assumptions required |
2.3 Assertion Matrix¶
Scenario 0 — Standard DDL Review (8 assertions)
Input SQL:
ALTER TABLE users ADD COLUMN last_login_at TIMESTAMPTZ NOT NULL DEFAULT now();
CREATE UNIQUE INDEX ON users(email);
ALTER TABLE sessions ADD CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id);
| ID | Assertion | With Skill | Without Skill | Notes |
|---|---|---|---|---|
| A0-1 | Flags CREATE UNIQUE INDEX missing CONCURRENTLY (ShareLock blocks writes) | PASS | PASS | Both identify this explicitly |
| A0-2 | Recommends NOT VALID + VALIDATE CONSTRAINT two-step pattern for FK | PASS | PASS | Both provide corrected SQL |
| A0-3 | Lists missing lock_timeout as a Critical-tier risk | PASS | PASS | Both flag it in the summary |
| A0-4 | Identifies DEFAULT now() as a volatile function that may trigger a table rewrite (not a metadata-only change) | PASS | PASS | Both reach this analysis correctly |
| A0-5 | Provides a lock-level classification table for each DDL (AccessExclusiveLock / ShareLock) | PASS | PASS | Both produce comparable formatting |
| A0-6 | Outputs X/12 Scorecard format (Critical Y/3, Standard Z/5, Hygiene W/4) | PASS | PASS | Without-Skill spontaneously matches the format |
| A0-7 | §9.9 / Uncovered Risks contains ≥3 assumptions or unconfirmed items | PASS | PASS | Without-Skill lists 7 items; With-Skill presents them in structured form |
| A0-8 | Output includes Data basis: full/degraded/minimal traceability label | PASS | FAIL | Without-Skill never includes this label |
Scenario 0 result: With Skill 8/8 (100%) — Without Skill 7/8 (87.5%). The only gap is the missing Data basis label.
Scenario 1 — Large-Table High-Risk Migration (9 assertions)
Input SQL:
ALTER TABLE events ALTER COLUMN payload TYPE jsonb USING payload::jsonb;
CREATE INDEX ON events(user_id, created_at);
ALTER TABLE events DROP COLUMN deprecated_field;
| ID | Assertion | With Skill | Without Skill | Notes |
|---|---|---|---|---|
| A1-1 | Identifies ALTER COLUMN TYPE as a full table rewrite (AccessExclusiveLock, 15–90+ minutes on 85 GB) | PASS | PASS | Both quantify the 85 GB risk |
| A1-2 | Recommends pg_repack or create-swap-rename instead of direct ALTER | PASS | PASS | Both propose a shadow-table approach |
| A1-3 | Recommends CREATE INDEX CONCURRENTLY to avoid ShareLock | PASS | PASS | Both explicitly cite the lock risk |
| A1-4 | Requires SET lock_timeout before all DDL | PASS | PASS | Both include it in corrected SQL |
| A1-5 | Notes that DROP COLUMN is irreversible after COMMIT | PASS | PASS | Both mark it irreversible |
| A1-6 | Quantifies disk space requirement (~90 GB) and WAL amplification impact | PASS | PASS | Both provide concrete estimates |
| A1-7 | Provides a zero-downtime phased execution plan (shadow table → backfill → atomic swap → cleanup) | PASS | PASS | 5-phase plan complete in both |
| A1-8 | Identifies the logical replication DDL gap (analytics replica requires separate DDL sync) | PASS | PASS | Both flag this as high-risk |
| A1-9 | Original SQL scored independently: all Critical checks FAIL (no lock_timeout / no CONCURRENTLY / no rollback plan) | PASS | PARTIAL | Without-Skill credits its own §9.7 rollback plan toward the original SQL score — Critical 1/3 instead of 0/3, making the risk assessment incorrectly lenient |
Scenario 1 result: With Skill 9/9 (100%) — Without Skill 8.5/9 (94.4%). The gap is a scoring methodology flaw: Without-Skill counts its own reviewer-added rollback as a pass on the original submitted SQL.
The With-Skill agent correctly applies the "original SQL scored independently" rule:
"The original submitted SQL would score 0/3 Critical: no lock_timeout, no CONCURRENTLY, no rollback plan — overall FAIL."
Scenario 2 — Degraded Mode Boundary (6 assertions)
Input SQL:
ALTER TABLE products ADD COLUMN price_usd NUMERIC(10,2) NOT NULL;
ALTER TABLE products ALTER COLUMN description TYPE TEXT;
| ID | Assertion | With Skill | Without Skill | Notes |
|---|---|---|---|---|
| A2-1 | Explicitly enters Minimal / Degraded Mode (does not invent missing context) | PASS | PASS | Both declare Minimal mode and list conservative assumptions |
| A2-2 | Enforces the hard rule "Never claim SAFE without evidence" | PASS | PARTIAL | Without-Skill behaves conservatively but never states this as an explicit constraint; under weaker prompting its behavior may be unreliable |
| A2-3 | Lists all conservative assumptions (PG version, row count, QPS, replication type) | PASS | PASS | Without-Skill lists 8; With-Skill lists 18 |
| A2-4 | Identifies version-dependent rewrite risk for ALTER COLUMN TYPE TEXT (VARCHAR→TEXT is metadata-only in PG 12+; otherwise a table rewrite) | PASS | PASS | Both correctly address the version split |
| A2-5 | §9.9 / Uncovered Risks uses complete table format with ≥8 known-unknowns | PASS | PASS | Both exceed the 8-item threshold |
| A2-6 | Identifies that ADD COLUMN NOT NULL without DEFAULT is a hard error on a non-empty table (not a performance concern — it fails immediately at runtime) | PASS | PASS | Both precisely identify this hard error |
Scenario 2 result: With Skill 6/6 (100%) — Without Skill 5.5/6 (91.7%). The gap is the "Never claim SAFE" rule not being explicitly stated.
3. Pass Rate Summary¶
3.1 Overall¶
| Configuration | PASS | PARTIAL | FAIL | Strict pass rate |
|---|---|---|---|---|
| With Skill | 23/23 | 0 | 0 | 100% |
| Without Skill | 20/23 | 2 | 1 | 87.0% (95.7% with PARTIAL) |
Delta: +13 percentage points (strict PASS)
3.2 By Scenario¶
| Scenario | With Skill | Without Skill | Where points were lost |
|---|---|---|---|
| S0 Standard DDL Review | 8/8 (100%) | 7/8 (87.5%) | A0-8: Data basis label absent |
| S1 Large-Table High-Risk | 9/9 (100%) | 8.5/9 (94.4%) | A1-9: original SQL scoring methodology flawed |
| S2 Degraded Mode | 6/6 (100%) | 5.5/6 (91.7%) | A2-2: "Never claim SAFE" rule not explicitly declared |
3.3 Full Assertion Matrix¶
| ID | Category | With Skill | Without Skill |
|---|---|---|---|
| A0-1 | Critical (S0) | PASS | PASS |
| A0-2 | Critical (S0) | PASS | PASS |
| A0-3 | Critical (S0) | PASS | PASS |
| A0-4 | Standard (S0) | PASS | PASS |
| A0-5 | Standard (S0) | PASS | PASS |
| A0-6 | Standard (S0) | PASS | PASS |
| A0-7 | Hygiene (S0) | PASS | PASS |
| A0-8 | Hygiene (S0) | PASS | FAIL |
| A1-1 | Critical (S1) | PASS | PASS |
| A1-2 | Critical (S1) | PASS | PASS |
| A1-3 | Critical (S1) | PASS | PASS |
| A1-4 | Critical (S1) | PASS | PASS |
| A1-5 | Standard (S1) | PASS | PASS |
| A1-6 | Hygiene (S1) | PASS | PASS |
| A1-7 | Standard (S1) | PASS | PASS |
| A1-8 | Hygiene (S1) | PASS | PASS |
| A1-9 | Standard (S1) | PASS | PARTIAL |
| A2-1 | Standard (S2) | PASS | PASS |
| A2-2 | Critical (S2) | PASS | PARTIAL |
| A2-3 | Standard (S2) | PASS | PASS |
| A2-4 | Standard (S2) | PASS | PASS |
| A2-5 | Hygiene (S2) | PASS | PASS |
| A2-6 | Critical (S2) | PASS | PASS |
| Total | — | 23/23 (100%) | 20/23 + 2 PARTIAL (87.0%) |
4. Key Differences¶
4.1 Behaviors unique to the With-Skill group¶
| Behavior | Appears in | Source |
|---|---|---|
Data basis: full/degraded/minimal label appended to every scorecard | S0, S1, S2 | §9 Output Contract |
| Original SQL scored independently from reviewer-added DDL | S1 | "Original SQL independent scoring" rule |
| Hard rule "Never claim SAFE without evidence" explicitly declared | S2 | Degraded Mode hard rules |
| §9.1–§9.9 all nine sections consistently present | S0, S1, S2 | §9 Output Contract |
| Conservative assumption list (18 items vs 8) in Minimal mode | S2 | Degraded Mode checklist |
4.2 Technical knowledge comparison¶
| Check | With Skill | Without Skill |
|---|---|---|
CONCURRENTLY for index creation | PASS | PASS |
NOT VALID + VALIDATE two-step for FK | PASS | PASS |
lock_timeout before all DDL | PASS | PASS |
ALTER COLUMN TYPE = full table rewrite | PASS | PASS |
DROP COLUMN is irreversible | PASS | PASS |
| pg_repack / shadow-table-swap strategy | PASS | PASS |
| Logical replication DDL gap | PASS | PASS |
Data basis traceability label | PASS | FAIL |
| Original SQL scored independently | PASS | PARTIAL |
| Explicit "Never claim SAFE" rule | PASS | PARTIAL |
The pattern is clear: all three failures are framework compliance gaps, not knowledge gaps. The baseline knows PostgreSQL migration safety — it just doesn't enforce the output contract or apply the stricter scoring rules.
5. Token Cost Analysis¶
5.1 Actual token consumption¶
| Agent | Scenario | Total tokens | Tool calls |
|---|---|---|---|
| Without Skill | S0 | 33,097 | 2 |
| With Skill | S0 | 19,042 | 0 |
| Without Skill | S1 | 38,406 | 3 |
| With Skill | S1 | 19,069 | 0 |
| Without Skill | S2 | 33,658 | 2 |
| With Skill | S2 | 18,589 | 0 |
5.2 Efficiency summary¶
| Metric | S0 (Standard) | S1 (Deep) | S2 (Minimal) | Average |
|---|---|---|---|---|
| Without Skill tokens | 33,097 | 38,406 | 33,658 | 35,054 |
| With Skill tokens | 19,042 | 19,069 | 18,589 | 18,900 |
| Tokens saved | 14,055 (42%) | 19,337 (50%) | 15,069 (45%) | −46.1% |
| Without Skill tool calls | 2 | 3 | 2 | 2.3 |
| With Skill tool calls | 0 | 0 | 0 | 0 |
The efficiency paradox: With-Skill agents receive a longer input context (SKILL.md ~4,500 tokens + reference files ~1,800–5,600 tokens depending on depth), yet their total token consumption is 46% lower overall. Three reasons:
- Focused output: the structured §9 framework directs the model to fill sections rather than engage in exploratory reasoning before organizing a response
- Eliminating tool calls: Without-Skill agents average 2–3 Web searches per scenario to retrieve PostgreSQL documentation; With-Skill agents embed that knowledge directly, requiring zero external calls
- Avoiding re-derivation: Without-Skill agents "rediscover" best practices (CONCURRENTLY, NOT VALID, lock_timeout) from scratch each time; With-Skill agents retrieve them directly from the framework
5.3 ROI estimate¶
Based on Sonnet 4 API pricing; token cost only, excludes engineer time.
| Scenario | Without Skill | With Skill | Per-review saving |
|---|---|---|---|
| Standard DDL review | ~$0.052 | ~$0.030 | ~$0.022 |
| Large-table high-risk migration | ~$0.061 | ~$0.030 | ~$0.031 |
| Monthly 100 reviews | ~$5.60 | ~$3.00 | ~$2.60/month |
7. Findings¶
Finding 1: The pg-migration baseline is already strong¶
| Skill | Baseline (Without Skill) | With Skill | Delta |
|---|---|---|---|
| mysql-migration | 52% | 100% | +48 pp |
| pg-migration | 87% | 100% | +13 pp |
| oracle-migration | (not evaluated) | — | — |
PostgreSQL migration safety rules — CONCURRENTLY, NOT VALID, lock_timeout — are extensively documented and deeply embedded in the base model. Without-Skill agents even spontaneously produce X/12 Scorecard formatting and §9.9 Uncovered Risks sections that match the skill's output contract. This contrasts sharply with mysql-migration, where the baseline gap is nearly five times larger.
Finding 2: The skill's value is framework enforcement, not knowledge delivery¶
All three points lost by Without-Skill are framework compliance failures, not knowledge failures:
| Assertion | Failure type |
|---|---|
A0-8: missing Data basis label | Output contract compliance |
| A1-9: original SQL scoring methodology flawed | Scoring rule enforcement |
| A2-2: "Never claim SAFE" not explicitly declared | Hard-rule declaration |
Without the skill, a capable model reaches the right safety conclusions — but doesn't produce an auditable, traceable, consistently-formatted output. When reviews are used for compliance, CI gating, or cross-team comparison, format consistency is not cosmetic: it is the deliverable.
Finding 3: Tool-call dependency is a hidden cost¶
Without-Skill agents averaged 2.3 tool calls per scenario (inferred to be Web searches for PostgreSQL documentation). This introduces three compounding risks:
- Token cost: search results accumulate in context, amplifying total consumption
- Latency risk: network dependency adds unpredictable delay
- Consistency risk: search results change over time; the skill's reference files are fixed and curated
Finding 4: Token efficiency is pg-migration's primary differentiator¶
Unlike mysql-migration — where the skill adds ~51% token overhead because the baseline needs extensive prompting to produce acceptable output — pg-migration achieves a 46% token reduction despite a longer input context. PostgreSQL DDL is inherently more complex (lock matrices, CONCURRENTLY restrictions, pg_repack strategies), which means Without-Skill agents do more exploratory reasoning; With-Skill agents skip that exploration and fill the framework directly.
Cross-skill comparison:
| Skill | SKILL.md lines | Reference files | Baseline pass rate | Token effect | Primary value |
|---|---|---|---|---|---|
| mysql-migration | ~300 | 3 | 52% | +51% overhead | Knowledge injection + error prevention |
| pg-migration | 353 | 3 | 87% | −46% savings | Consistency + efficiency |
| Unique coverage | — | — | — | — | CONCURRENTLY limits, NOT VALID, transactional DDL rollback |
8. Conclusion¶
Rating: Production-ready. Recommended for all PostgreSQL DDL review workflows.
Three things the skill does well:
-
Structural enforcement: §9.1–§9.9 all nine sections are required on every review.
Data basislabeling is mandatory. These constraints eliminate the "silent skip" risk — where a capable model produces a correct-looking but incomplete output. -
Token efficiency: 46% token savings make pg-migration one of the highest-ROI migration skills evaluated. At 100 reviews/month, the savings compound meaningfully at scale.
-
Evaluation framework consistency: Gate analysis, independent original-SQL scoring, and the Scorecard format are enforced on every run — making review results repeatable, comparable, and auditable across teams and time.
Recommended use cases:
- All PostgreSQL production changes involving
ALTER TABLE,CREATE INDEX, orCONSTRAINTmodifications - Large-table migration planning (>10M rows) as a decision framework for choosing between pg_repack and shadow-table-swap
- CI/CD pipeline migration file review — the token efficiency makes it practical to run on every PR at low cost
Not recommended for:
- Query optimization and connection pool tuning → use
postgresql-best-practise - Application code security review → use
security-review