quak backup can report a clean run on old or empty data.
Library.backup() passes refresh: () => this.runRefresh() to runBackup (src/library/index.ts:553). runRefresh (src/library/index.ts:594-595) returns at once when a refresh is already running, and swallows a failed one.
With an existing cache, Library.open has always just started a background refresh (src/library/index.ts:425), so runBackup (src/backup.ts:288-289) never waits for it and backs up the previous run's file list.
With an expired session or no network, the refresh fails silently. On an empty cache the result is Total files: 0 and exit code 0. That is a failed backup reported as a success.
Definition of done
backup() waits for a completed refresh before touching any file: it joins a refresh already running, or starts one (the same behaviour lib.fresh() has).
A failed refresh rejects backup() before any download, and leaves failures.json untouched.
quak backup prints the refresh error on one line and exits 1.
Tests cover: a refresh already running when backup() is called (the backup sees its result), a failed refresh with an existing cache, and a failed refresh with an empty cache.
make check green; TODO.md updated in the same commit.
Model: opus-5-5
## Problem
`quak backup` can report a clean run on old or empty data.
- `Library.backup()` passes `refresh: () => this.runRefresh()` to `runBackup` (`src/library/index.ts:553`). `runRefresh` (`src/library/index.ts:594-595`) returns at once when a refresh is already running, and swallows a failed one.
- With an existing cache, `Library.open` has always just started a background refresh (`src/library/index.ts:425`), so `runBackup` (`src/backup.ts:288-289`) never waits for it and backs up the previous run's file list.
- With an expired session or no network, the refresh fails silently. On an empty cache the result is `Total files: 0` and exit code 0. That is a failed backup reported as a success.
## Definition of done
1. `backup()` waits for a completed refresh before touching any file: it joins a refresh already running, or starts one (the same behaviour `lib.fresh()` has).
2. A failed refresh rejects `backup()` before any download, and leaves `failures.json` untouched.
3. `quak backup` prints the refresh error on one line and exits 1.
4. Tests cover: a refresh already running when `backup()` is called (the backup sees its result), a failed refresh with an existing cache, and a failed refresh with an empty cache.
5. `make check` green; `TODO.md` updated in the same commit.
Model: opus-5-5
clawbot
self-assigned this 2026-09-23 05:34:58 +02:00
Built in #122: backup() now waits for a completed refresh, joining one already running, and fails before touching any file when it fails; quak backup then prints the error on one line and exits 1.
Model: opus-5-5
Built in https://git.eeqj.de/sneak/quak/pulls/122: `backup()` now waits for a completed refresh, joining one already running, and fails before touching any file when it fails; `quak backup` then prints the error on one line and exits 1.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
quak backupcan report a clean run on old or empty data.Library.backup()passesrefresh: () => this.runRefresh()torunBackup(src/library/index.ts:553).runRefresh(src/library/index.ts:594-595) returns at once when a refresh is already running, and swallows a failed one.Library.openhas always just started a background refresh (src/library/index.ts:425), sorunBackup(src/backup.ts:288-289) never waits for it and backs up the previous run's file list.Total files: 0and exit code 0. That is a failed backup reported as a success.Definition of done
backup()waits for a completed refresh before touching any file: it joins a refresh already running, or starts one (the same behaviourlib.fresh()has).backup()before any download, and leavesfailures.jsonuntouched.quak backupprints the refresh error on one line and exits 1.backup()is called (the backup sees its result), a failed refresh with an existing cache, and a failed refresh with an empty cache.make checkgreen;TODO.mdupdated in the same commit.Model: opus-5-5
Built in #122:
backup()now waits for a completed refresh, joining one already running, and fails before touching any file when it fails;quak backupthen prints the error on one line and exits 1.Model: opus-5-5