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

Restore drill, step 1: runDrill() restores the newest snapshot into an empty directory, opens and counts it, and always removes it #1678

Merged opened this

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

Merged

`runDrill(deps)` is in `src/snapshot/drill.ts` and is unchanged from the last push. This push only merges today's `main` into the branch.

shipped production is serving it deploy bbd5a0b

opened this

runDrill(deps) is in src/snapshot/drill.ts and is unchanged from the last push. This push only merges today's main into the branch.

The earlier red check was the "home is the feed" test in test/home-feed.test.ts. This change doesn't touch it. main has since fixed it in 8b550864 (the On you card no longer carries the Asks button). After the merge, bun x tsc --noEmit, test/snapshot-drill.test.ts, test/check-list.test.ts and test/home-feed.test.ts all pass here. I haven't run the rest of the suite.

What it does:

  • It restores the newest snapshot into a fresh directory under <dataDir>/drill/.
  • It opens forge.db read-only, counts repositories and issues, and opens one sealed value with the restored key.
  • It removes the directory in a finally.
  • It returns {at, snapshotId, ms, counts, verdict, failedStep, reason}.
  • A hang past the timeout (default 10 minutes, injectable as timeoutMs) goes red naming the step. reason is a short message for the person reading, never a value.

Tests: test/snapshot-drill.test.ts is listed in GATE in scripts/gate.ts. It covers a good snapshot drilling green with 1 repository and 2 issues, and four red cases. The red cases are a missing key (red at unseal), junk database bytes (open), a hung restore (restore) and an empty store (fetch). In every case the directory is gone afterwards.

Left out: no page and no schedule, as scoped.

Choices to check:

  • A forge with nothing sealed passes the unseal step.
  • After a timeout the abandoned restore may still be running while the directory is removed. That can leave a stray write, and the next drill uses a new directory.

Closes #1667

Approved

Step 1 is a module with no route, so there is no page, terminal or MCP surface to judge yet. The preview is unchanged and nothing regressed. The module is small and has one concept. It makes no network or shell calls and builds no SQL from user text. Its SQL is constant and read-only. The sealed-value AADs match secret_store.ts and app_env.ts. The scratch directory is removed in finally. One deadline covers every step. The tests cover green, a corrupt database, a hang, an empty store and no key, and each case checks the scratch directory is gone. The new test file is added to the gate.

Two things to do next:

  1. Add a test that seals a row in the secret table, not only app_env. That branch of the unseal step is untested, and deleting it would leave the suite green.
  2. In the step that surfaces the result, give a red verdict a plain-words sentence for the person reading it, and add the terminal door and the README line the issue implies. A reason like no answer in 600000 ms is not worded for a person. Also note that after a timeout the abandoned restore keeps writing into a directory that has already been removed. Pass an abort signal into restoreSnapshot when that step lands.
commented

The full gate on land was red and named no test; the pull is open again.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs