fix: stop a run that predates origin from blocking every start #15

Merged
day01 merged %!d() commits from %!s() into %!s() 2026-08-12 10:54:39 +00:00
Owner

A run opened before the control plane wrote down where a run came from has no origin, cannot be read back, and took the whole service down with it: the restore refused the row, the process exited, and it did so again on the next start and every one after. One unusable row was an outage with no way out but editing the database by hand. Dev spent this morning that way, and prod would have hit the same wall on its first control-plane deploy.

Applying the schema now drops such a run and makes both columns mandatory, so no later one can look like it. Inventing an origin is still off the table — what changed is the cost of refusing. A run with no origin can never be assigned, because a node cannot be told what it is building, so keeping it bought nothing and cost everything.

With the columns mandatory there is no longer a row shaped like that to read, so the case and its error go away.

The test drives the real migration path: it puts the table back in the old shape, opens a run the way the old version did, restarts, and asserts the readable run survived while the unreadable one did not. Without the migration it fails on the null it used to die on.

A run opened before the control plane wrote down where a run came from has no origin, cannot be read back, and took the whole service down with it: the restore refused the row, the process exited, and it did so again on the next start and every one after. One unusable row was an outage with no way out but editing the database by hand. Dev spent this morning that way, and prod would have hit the same wall on its first control-plane deploy. Applying the schema now drops such a run and makes both columns mandatory, so no later one can look like it. Inventing an origin is still off the table — what changed is the cost of refusing. A run with no origin can never be assigned, because a node cannot be told what it is building, so keeping it bought nothing and cost everything. With the columns mandatory there is no longer a row shaped like that to read, so the case and its error go away. The test drives the real migration path: it puts the table back in the old shape, opens a run the way the old version did, restarts, and asserts the readable run survived while the unreadable one did not. Without the migration it fails on the null it used to die on.
day01 added 1 commit 2026-08-12 10:50:06 +00:00
		A run opened before the control plane wrote down where a run came from has
no origin, cannot be read back, and took the whole service down with it: the
restore refused the row, the process exited, and it did so again on the next
start and every one after. One unusable row was an outage with no way out but
editing the database by hand. Dev spent this morning that way.

Applying the schema now drops such a run and makes both columns mandatory, so
no later one can look like it. Inventing an origin is still off the table --
what changed is the cost of refusing. A run with no origin can never be
assigned, because a node cannot be told what it is building, so keeping it
bought nothing and cost everything.

With the columns mandatory there is no longer a row shaped like that to read,
so the case and its error go away.
	
day01 merged commit 5ab2b3597d into %!s() 2026-08-12 10:54:39 +00:00
day01 deleted branch fix/a-run-that-predates-origin-must-not-block-every-start 2026-08-12 10:54:41 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: syncode/control#15