{"slug": "the-agent-wrote-the-migration-are-you-really-going-to-approve-it", "title": "The agent wrote the migration. Are you really going to Approve it?", "summary": "A developer warns that AI-generated database migrations are outpacing human review, creating a 'reviewed without reviewing' risk where engineers approve plausible-looking SQL that may contain semantic errors. The post argues that stricter CI and agent self-review are insufficient, and calls for declarative diff tools and finer review policies to address the gap.", "body_md": "Tuesday, 3 p.m. A PR notification lands in Slack. Junior writes in the channel: \"Cursor generated this migration for me — can you take a look?\"\n\nYou open the diff. Eighty lines of `ALTER TABLE`\n\n. Add columns, change types, add indexes, attach foreign keys — every line is familiar on its own. Syntax is clean. Naming matches team conventions. Mechanically, **it all looks plausible**.\n\nBut together? That `NOT NULL`\n\non `biz_order`\n\nhas no default — will it pass on existing rows? How long does the type change on `sys_user`\n\nlock the table? Does the down migration actually restore the previous schema? The PR description says \"Agent self-review: should be fine\" — that is not evidence.\n\nReject the whole thing and you look like you are blocking the team or fighting AI. Click Approve and **your name** is on it. When production blows up, the postmortem asks \"who approved this version?\" and you say: \"CI passed; it looked okay to me.\"\n\nYou cannot spin up a database for every PR. In the end there are only two performances: **pretend to understand** — comment on naming and click Approve; **pretend to be strict** — send it back three times for formatting, and still nobody notices the missing join table.\n\nThis is not a moral failure of \"not reading carefully enough.\" It has a name — **reviewed without reviewing**: generation speed went up; human review speed did not. The Agent spits out eighty lines of `ALTER`\n\nin three seconds; your brain still runs at \"read SQL line by line.\" SQL diffs are mostly noise — `VARCHAR(64)`\n\nto `VARCHAR(128)`\n\nfills half the screen, while the change that actually blows up (missing join table, FK pointing at the wrong parent) hides in the middle and looks like any other edit.\n\nPeople in the industry summarize it in one line: **No human can review at this speed.** That is not an insult — it is a mechanism claim. When the output is executable statements and the input is an eighty-line character diff, the Tech Lead is effectively signing blind. The moment you lose face and own the blame is the postmortem, not the Approve button on GitHub.\n\nThere is a sneakier variant: **which three lines in this migration are hallucinated?** Not syntax errors — semantic errors. The Agent used a stale `@schema.sql`\n\nand invented a join table that \"should\" exist. Or it set a default on `del_flag`\n\nthat your team never uses. Every line runs; together they break a query you did not think to test.\n\n**Stricter CI.** Lint migration file names, require down files, run sqlfluff. Helpful — but CI checks format and parseability, not \"will this table lock for ten minutes on Tuesday peak traffic.\" Green does not mean \"I will sign Approve.\"\n\n**Agent self-review.** \"Check this migration for risk and output a confidence score.\" The model politely returns \"low risk\" — it did not run that `ALTER`\n\nagainst your real row counts either. Self-review is tone, not acceptance.\n\n**Declarative diff tools.** Prisma, Atlas, and similar tell you \"what changed in the model vs last revision.\" Progress — the diff object is no longer raw SQL. But the declaration is still not \"what will execute\": the migration that lands in prod can diverge from the declaration; and field-level diffs are still noise, not \"what this change means for the business.\"\n\n**Finer code review policy.** \"Migrations need two approvers.\" \"Agents cannot push to main.\" Process is right; the object under review is still SQL noise. If the second approver only glances at green CI, you now have two \"looked fine to me\" signatures.\n\nSomeone will say: wire the Agent to live DB so column names stop hallucinating. Job 1 already covered why — production credentials in the IDE are a red line; 240-table dumps blow context; permission-filtered schema is another hallucination. Even when structure reads correctly, **that is not what the Lead needs to review**.\n\nThe Lead needs to answer the product question in the meeting: \"Will this schema change blow up?\" — which means \"relative to the **last approved version**, what are the semantic changes?\" not eighty lines of `ALTER`\n\n. Live catalog MCP solves \"does this column exist?\" **Semantics** — soft delete still on this table?, is this status code still valid?, should this FK point at `sys_user`\n\nnot `biz_user`\n\n? — live in notes, review records, and **human-approved versions**, not in `information_schema`\n\n.\n\nSo the trap is not \"we need a better SQL linter.\" It is **reviewing the wrong artifact**: you Approve executable statements without an \"approved intent\" to align against.\n\nOur approach moves the Agent write path from \"dump SQL for you to sign\" to **\"declare intent → save as a version → human diffs in the designer.\"**\n\nThe flow:\n\n`projectJSON`\n\nis the approved contract.`put_project_json`\n\nto overwrite the workspace (API 200 is not human approval). It calls `create_version`\n\n`status`\n\n, \"1=valid 9=dirty\" is closer to what you review than `CHAR(1)`\n\n.DDL drafts can be generated from approved versions for DBA reference; **ERD does not execute SQL**. Landing migrations in the database is still Atlas / Flyway / your CI. The Agent gets no production credentials; the Lead does not blind-sign raw migrations.\n\nOne sentence on the difference vs \"Agent writes migration, you sign SQL\": **API 200 is not human approval.** Approval happens after you read the diff in the designer.\n\nBy now you might want MCP — not at the opening of the article.\n\nToday the only MCP write path is ** create_version**: the Agent reads the approved contract via\n\n`list_tables`\n\n/ `describe_table`\n\n, updates the model, submits a suggestion; you diff in the designer. See One honest gap: **semantic diff_versions** — ask MCP \"what three semantic changes between v1.3 and v1.2?\" instead of scanning the version panel by eye. That is the Job 2 build target; until the tool ships, Leads still open two versions in the designer — but the object is at least the\n\nPlanned optional capability: DDL draft from two contract versions as a DBA starting point — **still no execution**. Hard merge gates and DBA veto before main — that is another journey (Job 4). This article stops at the Lead's Approve button: you sign intent you diffed, not eighty lines the Agent spat out.\n\nThe next step from this article is not \"go install MCP first.\" It is more basic: **save a version and walk through diff approval once.**\n\nOpen the demo, change one table, save a named version, change something else, save again, open the diff between the two — 30 seconds, no signup. If you have not walked \"Agent suggests → human diffs → approve\" yet, practice with your own two hand-edited versions first: what \"field added\" vs \"FK retargeted\" looks like in the diff, so when the Agent calls `create_version`\n\nyou know where to look.\n\nThe moment you save that first named version, you have a \"last approved baseline\" to align against. Without it, the Agent's eighty lines are a blind sign — the Approve button is there; whether you dare click depends on whether you reviewed SQL or the contract.\n\n{{CTA}}", "url": "https://wpnews.pro/news/the-agent-wrote-the-migration-are-you-really-going-to-approve-it", "canonical_source": "https://dev.to/erdonline/the-agent-wrote-the-migration-are-you-really-going-to-approve-it-4l6d", "published_at": "2026-08-30 06:35:49+00:00", "updated_at": "2026-08-30 06:52:12.583888+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-safety"], "entities": ["Cursor", "Prisma", "Atlas", "GitHub", "Slack"], "alternates": {"html": "https://wpnews.pro/news/the-agent-wrote-the-migration-are-you-really-going-to-approve-it", "markdown": "https://wpnews.pro/news/the-agent-wrote-the-migration-are-you-really-going-to-approve-it.md", "text": "https://wpnews.pro/news/the-agent-wrote-the-migration-are-you-really-going-to-approve-it.txt", "jsonld": "https://wpnews.pro/news/the-agent-wrote-the-migration-are-you-really-going-to-approve-it.jsonld"}}