Archive and Wake are each one conditional write that acts only when it moved the repository, and a Wake asked during an Archive's stop starts production after that stop #45

Merged
grokbot merged 4 commits from dev/archive-wake-atomic into main 2026-10-17 21:27:13 +00:00
Owner

Problem. Archive and Wake were not atomic. Two Archives from the same view both stopped the app and both wrote an archived event. A Wake during a slow Archive stop did not start the app: the stop aborted the deploy that the Wake reused. The result was an awake repository with production down.

Root cause. updateRepoSettings wrote archived_at without a condition. It found the transition by a comparison with the repo it read before. The stop and the reconcile were not in order with each other.

Fix.

  • moveArchived in core/repos.ts is one conditional UPDATE ... WHERE archived_at IS NULL (or IS NOT NULL). It returns true only when one row changed. The action stops or reconciles only then, and writes archived in the event only then.
  • The core updateRepoSettings takes Omit<RepoSettings, "archived">, so it cannot write archived_at.
  • Each repository's transitions take one turn after another. A Wake that comes during an Archive's stop starts production after that stop.

Test. test/apps-archive-race.test.ts (real apps runtime). A Wake during an Archive's stop (a redeploy is in flight) leaves production running. Two Archives from one stale view give one archived event. On main: both fail (production failed; 2 events). With the fix: both pass. archive-web, crew and guests tests use a setArchivedIn helper on moveArchived.

Validate (fast). Result: flaky, no new failure. contain.test.ts is baseline (box DNS). tui-sentinel.test.ts failed one time in the full run. It passes alone on this branch and is not red on main. tsc passes.

**Problem.** Archive and Wake were not atomic. Two Archives from the same view both stopped the app and both wrote an `archived` event. A Wake during a slow Archive stop did not start the app: the stop aborted the deploy that the Wake reused. The result was an awake repository with production down. **Root cause.** `updateRepoSettings` wrote `archived_at` without a condition. It found the transition by a comparison with the `repo` it read before. The stop and the reconcile were not in order with each other. **Fix.** - `moveArchived` in `core/repos.ts` is one conditional `UPDATE ... WHERE archived_at IS NULL` (or `IS NOT NULL`). It returns true only when one row changed. The action stops or reconciles only then, and writes `archived` in the event only then. - The core `updateRepoSettings` takes `Omit<RepoSettings, "archived">`, so it cannot write `archived_at`. - Each repository's transitions take one turn after another. A Wake that comes during an Archive's stop starts production after that stop. **Test.** `test/apps-archive-race.test.ts` (real apps runtime). A Wake during an Archive's stop (a redeploy is in flight) leaves production running. Two Archives from one stale view give one `archived` event. On main: both fail (production `failed`; 2 events). With the fix: both pass. `archive-web`, `crew` and `guests` tests use a `setArchivedIn` helper on `moveArchived`. **Validate (fast).** Result: flaky, no new failure. `contain.test.ts` is baseline (box DNS). `tui-sentinel.test.ts` failed one time in the full run. It passes alone on this branch and is not red on main. tsc passes.
Archive and Wake are each one conditional write that acts only when it moved the repository, and a Wake asked during an Archive's stop starts production after that stop
Some checks failed
check / gate (2) (pull_request) Successful in 5m11s
check / gate (3) (pull_request) Successful in 4m1s
preview / preview (pull_request) Failing after 1m12s
check / gate (1) (pull_request) Successful in 10m46s
check / check (pull_request) Successful in 0s
5b121e88bd
Merge remote-tracking branch 'origin/main' into dev/archive-wake-atomic
Some checks failed
check / gate (1) (pull_request) Has been cancelled
check / gate (2) (pull_request) Has been cancelled
check / gate (3) (pull_request) Has been cancelled
check / check (pull_request) Has been cancelled
preview / preview (pull_request) Has been cancelled
d63d5f2741
Merge remote-tracking branch 'origin/main' into dev/archive-wake-atomic
Some checks failed
check / gate (2) (pull_request) Successful in 5m18s
preview / preview (pull_request) Failing after 4m24s
check / gate (1) (pull_request) Successful in 10m42s
check / gate (3) (pull_request) Successful in 14m16s
check / check (pull_request) Has been cancelled
7835af3940
Merge remote-tracking branch 'origin/main' into dev/archive-wake-atomic
All checks were successful
check / gate (2) (pull_request) Successful in 5m19s
check / gate (3) (pull_request) Successful in 4m5s
check / gate (1) (pull_request) Successful in 10m52s
check / check (pull_request) Successful in 0s
preview / preview (pull_request) Successful in 21s
f32a1b9790
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
trevato-apps/forge!45
No description provided.