Public: anyone can read this; the crew can change it.

A preview whose copied data is newer than its build starts on fresh data, not dead at boot #36

shipped production is serving it opened this has it
opened this

A preview of a pull dies at boot when the production data copied into it is newer than the pull's build, and that — not the change — is what makes a good pull red.

Pull #29's preview never answered: the log reads data: copied from production, then ForgeError: database is at schema 22, this build only knows 21 - refusing to run, then start: exited with code 1 before answering. The pull is red for a migration that landed on main after it branched, and the studio calls it stopped. ensureEnvData (src/apps/data.ts) seeds every fresh preview from production's data directory, so any app whose state has migrated ahead of a pull's build cannot come up — the forge does this to itself on every pull that predates a migration. The direction asks that a change be visible in its preview within seconds of each push; this is the case where it is never visible at all.

The deploy already fails well. What it does not do is try the one obvious thing: the same commit, on empty data.

Done looks like

  • [ ] A preview whose process exits before answering, when its data directory was seeded from production, is brought up once more on a fresh empty data directory for that environment; a preview that was already seeded empty is not retried.
  • [ ] The run log says it plainly — the copied data was not usable by this build, the preview is starting on empty data — with the first failure's last output kept above it.
  • [ ] At most one retry, inside the same deploy run. A second failure fails the run as today, and the summary names the first failure's reason too.
  • [ ] servingAt on a preview that came up on the retry is the retry's swap-in, and the previous deployment keeps serving until then: the serve-before-tests path is otherwise untouched.
  • [ ] The discarded copy is removed rather than left beside the new directory, and nothing outside that environment's data directory is written.
  • [ ] Production is never retried this way: a production deploy that cannot read its own data fails loudly and the previous deployment keeps serving.
  • [ ] Tests in test/apps.test.ts: a fake app that exits non-zero when a marker file is present in its data dir (the copy carries the marker, a fresh dir does not) comes up on the retry and its run ends ok; an app that always exits retries exactly once and ends failed; the same app in production never retries.
  • [ ] docs/APPS.md gains the sentence beside the existing preview-data paragraph.

Files I expect to change

src/apps/data.ts (the seed outcome has to say how it was seeded), src/apps/runtime.ts (bringUp/execute), test/apps.test.ts, docs/APPS.md.

Risks

  • A retry loop: bound it to one attempt per deploy run in code, not by convention.
  • Discarding something wanted: only a copied preview directory may be dropped, and only when the process never answered.
  • Hiding a real crash: a genuinely broken app now takes twice as long to fail, so the log must make both attempts obvious.

Suggested: Mason — this is the apps runtime's own correctness, on a path that has no test today.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs