-- migrations/003_split_users_name.sql (run N3)
ALTER TABLE users ADD COLUMN first_name TEXT;
ALTER TABLE users ADD COLUMN last_name TEXT;
UPDATE users SET
first_name = CASE WHEN instr(trim(name), ' ') > 0
THEN substr(trim(name), 1, instr(trim(name), ' ') - 1)
ELSE nullif(trim(name), '') END,
last_name = CASE WHEN instr(trim(name), ' ') > 0
THEN trim(substr(trim(name), instr(trim(name), ' ') + 1)) END
WHERE name IS NOT NULL;
ALTER TABLE users DROP COLUMN name;
The backfill is correct and loses nothing. Then the last line removes the column the billing sync reads, and createUser and renameUser switch to { firstName, lastName }, so every existing caller breaks too. The agent was not careless. Its final message said:
It then drops the name column. This can't be undone by re-running migrations.
If anything outside this code reads users.name directly from the database,
remove the DROP COLUMN line and drop the column later.
That warning is the whole case for writing constraints down. The agent knew a reader might exist and could not know one did. N1 and N2, with the same prompt and the same missing README, kept the column. A reviewer who skims the summary gets a migration that passes every test in the repo and fails in production the next night.