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

The no-release alarm reaches the owner when production stands still for 90 minutes while main moves: a test replays 2026-11-11 #11680

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

On 2026-11-11 production stayed on 0.7.535 for 5 h 50 min while main kept merging, and the no-release alarm said nothing. This fixes why and makes its message more specific.

shipped production is serving it deploy 1a20738

opened this

On 2026-11-11 production stayed on 0.7.535 for 5 h 50 min while main kept merging, and the no-release alarm said nothing. This fixes why and makes its message more specific.

Cause: split() in src/release/landings.ts looked for the newest merge already live across every public repository. A pull in another repository counts as live as soon as it merges. Everything the forge's own repository merged before such a pull was then also counted as live. So waitingSince returned undefined and src/flow/alarm_no_release.ts never started its 90-minute clock. The owner was never told because the alarm never fired.

Fix: split() now only treats earlier own pulls as live when the live merge is one of the forge's own repository's pulls. A new waiting(db) returns when the oldest waiting merge happened and how many merged pulls are waiting. waitingSince is kept as a thin wrapper around it.

Alarm text: it now names production's version and short commit, the number of merged pulls waiting, and for how long, e.g. "N merged pulls have waited 5 h 50 min and nothing has gone live: production runs …". This is the same no_release alarm, not a second one beside it.

Test: the new file test/flow-alarm-no-release-1111.test.ts rebuilds the 11-11 situation in-process (temp dir, createApp, no servers):

  • production is fixed on one commit, the own repository has merged pulls after it, another repository has a later merge, there are no keeper rows and no new tag;
  • at 89 minutes after the oldest unreleased merge, no alarm fires;
  • at 91 minutes, exactly one no_release alarm fires in flowAlarms and the owner is told exactly once;
  • once production runs a commit that contains the merges, the alarm clears.

With the old landings.ts put back, this test fails. test/flow-alarm-no-release.test.ts changed by one line because the alarm's wording changed.

Left alone: the release workflow, the chart, and the notifier, which was not at fault.

Checks: bun scripts/gate.ts and bun x tsc --noEmit are clean, and the alarm and landing tests pass (48 across 11 files). To try it: bun test test/flow-alarm-no-release-1111.test.ts test/flow-alarm-no-release.test.ts.

🤖 Generated with Claude Code

Closes #11673

commented

On 2026-11-11 production stayed on 0.7.535 for 5 h 50 min while main kept merging, and the no-release alarm said nothing. This fixes why and makes its message more specific.

Cause: split() in src/release/landings.ts looked for the newest merge already live across every public repository. A pull in another repository counts as live as soon as it merges. Everything the forge's own repository merged before such a pull was then also counted as live. So waitingSince returned undefined and src/flow/alarm_no_release.ts never started its 90-minute clock. The owner was never told because the alarm never fired.

Fix: split() now only treats earlier own pulls as live when the live merge is one of the forge's own repository's pulls. A new waiting(db) returns when the oldest waiting merge happened and how many merged pulls are waiting. waitingSince is kept as a thin wrapper around it.

Alarm text: it now names production's version and short commit, the number of merged pulls waiting, and for how long, e.g. "N merged pulls have waited 5 h 50 min and nothing has gone live: production runs …". This is the same no_release alarm, not a second one beside it.

Test: the new file test/flow-alarm-no-release-1111.test.ts rebuilds the 11-11 situation in-process (temp dir, createApp, no servers):

  • production is fixed on one commit, the own repository has merged pulls after it, another repository has a later merge, there are no keeper rows and no new tag;
  • at 89 minutes after the oldest unreleased merge, no alarm fires;
  • at 91 minutes, exactly one no_release alarm fires in flowAlarms and the owner is told exactly once;
  • once production runs a commit that contains the merges, the alarm clears.

With the old landings.ts put back, this test fails. test/flow-alarm-no-release.test.ts changed by one line because the alarm's wording changed.

Left alone: the release workflow, the chart, and the notifier, which was not at fault.

Checks: bun scripts/gate.ts and bun x tsc --noEmit are clean, and the alarm and landing tests pass (48 across 11 files). To try it: bun test test/flow-alarm-no-release-1111.test.ts test/flow-alarm-no-release.test.ts.

🤖 Generated with Claude Code

Changes requested — before the latest push

The cause is right and the fix is small, and the replay test covers the 89/91/clear shape. One change to make: waitingSince in src/release/landings.ts has no caller at this head, because alarm_no_release.ts now uses waiting. Delete it, since a wrapper kept for nobody is dead code. Also check that no test imports it. I did not run the tests or open the preview.

commented

On 2026-11-11 production stayed on 0.7.535 for 5 h 50 min while main kept merging, and the no-release alarm said nothing. This fixes why and makes its message more specific.

Cause: split() in src/release/landings.ts looked for the newest merge already live across every public repository. A pull in another repository counts as live as soon as it merges. Everything the forge's own repository merged before such a pull was then also counted as live. So the alarm saw nothing waiting and never started its 90-minute clock. The owner was never told because the alarm never fired.

Fix: split() now only treats earlier own pulls as live when the live merge is one of the forge's own repository's pulls. waitingSince is replaced by waiting(db), which returns when the oldest waiting merge happened and how many merged pulls are waiting. alarm_no_release.ts now calls waiting and nothing calls the old function, so it is deleted rather than kept as an unused wrapper (no test imported it).

Alarm text: it now names production's version and short commit, the number of merged pulls waiting, and for how long, e.g. "N merged pulls have waited 5 h 50 min and nothing has gone live: production runs …". This is the same no_release alarm, not a second one beside it.

Test: the new file test/flow-alarm-no-release-1111.test.ts rebuilds the 11-11 situation in-process (temp dir, createApp, no servers):

  • production is fixed on one commit, the own repository has merged pulls after it, another repository has a later merge, there are no keeper rows and no new tag;
  • at 89 minutes after the oldest unreleased merge, no alarm fires;
  • at 91 minutes, exactly one no_release alarm fires in flowAlarms and the owner is told exactly once;
  • once production runs a commit that contains the merges, the alarm clears.

With the old landings.ts put back, this test fails. test/flow-alarm-no-release.test.ts changed by one line because the alarm's wording changed.

Left alone: the release workflow, the chart, and the notifier, which was not at fault.

Checks: bun scripts/gate.ts and bun x tsc --noEmit are clean, and both alarm test files pass (4 tests) with waitingSince removed. The wider landing tests (48 across 11 files) last passed before that removal; the forge's full check reruns them on this push. To try it: bun test test/flow-alarm-no-release-1111.test.ts test/flow-alarm-no-release.test.ts.

🤖 Generated with Claude Code

Approved

The cause is right (split() let a merge in another repository mark every earlier own pull live, so the 90 min clock never started). The fix is small, there is one alarm, and the replay test covers 89 min silent, 91 min one alarm and one message, and clear. The diff replaces waitingSince with waiting, so no dead wrapper remains. UI untouched. Next: 1) add a one-line test of split() directly for the own/other mix in test/ for landings; 2) check that the /changelog page wording for pulls on its way still reads right now that other-repo merges no longer mark own pulls live.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs