Skip to content

feat(cloud): automatic backup, every day or week, only when something changed - #219

Merged
httpsphl merged 5 commits into
mainfrom
feat/auto-cloud-backup
Oct 7, 2026
Merged

httpsphl merged 5 commits into
mainfrom
feat/auto-cloud-backup

Conversation

@httpsphl

@httpsphl httpsphl commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

What

Automatic cloud backup (spec 27.10). Once the owner turns it on, a light copy goes up every day or week, and only when something the owner made has changed.

  • Fingerprint (Store::light_fingerprint plus the bots' memory and rules): a SHA-256 of what the light copy would hold. What changes by itself (the model and effort Claude Code reported, when a routine runs next) is zeroed, so it does not look new every few minutes. A new column that moves by itself only costs a copy too many, never one missed.
  • Passphrase: kept in the Windows Credential Manager (CredWriteW, generic, current user only), behind a SecretStore trait so tests keep it in memory. Never in a file, the database or the log. Linux and macOS have no store yet: autobackup.status says available: false and the app offers nothing there.
  • Loop (autobackup::run, a pass a minute and when it is turned on): sends when due and changed. Retries in 15 min when offline, in a period when the account is full, in an hour otherwise. It turns itself off when the passphrase is gone, and when the owner signs out. A copy sent by hand counts for it, and one copy goes up at a time.
  • Protocol: autobackup.status, .enable, .set_every, .disable, and the autobackup.changed notification. The optional fields of the two status types are now left out of the JSON when absent (they went out as null, which the app reads as a value).
  • App: an "Automatic copies" block in the account, in the three languages.
  • Docs: spec 27.10; the README and the policy no longer say a copy only goes on a click.
  • The account-server test helpers move to tests/common/cloud_server.rs, shared by the cloud and the automatic backup tests.

Checked

  • fmt, clippy -D warnings, 641 Rust tests and pnpm check (460 tests, three full runs in a row) pass.
  • The Windows credential store is tested for real (own target name, cleaned up).
  • The loop is tested against the real account server running in the test process: daily, weekly, nothing changed, a manual copy, no connection, the passphrase gone, signing out, no credential store.
  • Real run against the production server (botloft.comitium.com.br, a scratch daemon, the owner's test account), 24 checks: the default address is the real one; turning it on keeps the passphrase in the Credential Manager and the first light copy goes up about 4 s later; a look with nothing changed sends nothing; an edit to a bot's CLAUDE.md sends a second copy; the newest copy opens with the stored passphrase (and a wrong one is refused); the passphrase is in no log and not in autobackup.json; turning it off removes it from the Credential Manager; the test copies were deleted and the scratch account signed out.
  • That run found two bugs, fixed here with tests: the status went out with null for absent fields (the screen would show an invalid date under "Last copy sent"; CloudStatus had the same), and a frequency chosen while a copy was going up was overwritten when the send finished.

Flaky tests touched

The account tests (the new ones and a copy is deleted only after the owner confirms) failed now and then on a busy machine: a 5 s test timeout, and a button looked for before a list had reloaded. They wait for what loads now.

…ng changed

A hash of what the light copy would hold now: the database tables (with what
changes by itself zeroed: the model Claude Code reported, the effort it
reported and when a routine runs next) and each bot's memory and rules. A
column added later that moves by itself only costs one copy too many, never
one missed.
…he credential store

Once on, a light copy goes up every day or week, only when the fingerprint
changed. The passphrase lives in the Windows Credential Manager (a trait, so
tests keep it in memory); Linux and macOS have none yet and the feature stays
off there. It stops by itself when the account or the passphrase is gone, a
copy sent by hand counts for it, and one copy goes up at a time.

New: autobackup.status/enable/set_every/disable and autobackup.changed. The
account-server test helpers move to tests/common/cloud_server.rs.
Turn it on with the passphrase twice and how often (every day or week), see
the last copy and the next look, and the last failure in words. The spec gets
27.10, the privacy text in the README and the policy no longer says a copy
only goes on a click, and section 19 records the Windows credential store
check.
…and a new frequency survives a send in progress

Found by the real test against the production server: the status went out
with null where the app reads an absent field (and CloudStatus had the same),
and a frequency chosen while a copy was going up was overwritten with the old
period when the send finished. The spec records the real run.
… busy machine

The automatic backup tests get a longer test timeout and wait for their block
before using it; the delete-a-copy test waits for the reloaded list before
looking for its button.
@httpsphl
httpsphl enabled auto-merge October 7, 2026 21:41
@httpsphl
httpsphl merged commit 440aade into main Oct 7, 2026
7 of 8 checks passed
@httpsphl httpsphl mentioned this pull request Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant