[ ] Once a week the forge runs the part-1 drill against the newest snapshot, in a scratch directory under FORGE_APP_DATA that it removes after.
[ ] The result (when, how long, counts matched or which did not, key opened) is kept in the existing restore-drills table and shown on the Backups page as "last drill: <date>, <duration>, all counts matched".
[ ] A failed drill is an incident: one board line and one push, reusing #1804's line.
[ ] Tests: a drill due is run once and not twice; a mismatched count is red on the page and raises the line.
Start from today's main, at or after 91fd5057. Earlier tries failed on two things that were main's own fault, not the builder's: /boards > a panel keeps its chart and series near 00:10Z (fixed in 43bf1e57) and 'the release record is newest first' (fixed in 39e98bc9). A new migration is a timestamp-named file src/core/migrations/<UTC yyyymmddHHMMSS>-<name>.ts, never a number; do not hand-edit src/core/releases.json. Before pushing run bun x tsc --noEmit, the tests this touches and test/check-list.test.ts; name every new test file in GATE in scripts/gate.ts in the same commit. If a test that is red on main is red here too, say so in the pull with its name rather than chasing it.
Split from #1147.
Done looks like:
Start from today's main, at or after 91fd5057. Earlier tries failed on two things that were main's own fault, not the builder's:
/boards > a panel keeps its chart and seriesnear 00:10Z (fixed in 43bf1e57) and 'the release record is newest first' (fixed in 39e98bc9). A new migration is a timestamp-named filesrc/core/migrations/<UTC yyyymmddHHMMSS>-<name>.ts, never a number; do not hand-editsrc/core/releases.json. Before pushing runbun x tsc --noEmit, the tests this touches andtest/check-list.test.ts; name every new test file inGATEinscripts/gate.tsin the same commit. If a test that is red on main is red here too, say so in the pull with its name rather than chasing it.