Repository navigation
Move your books between servers: restore a full export into empty books - #185
Merged
Merged
Conversation
A person can now move their books from one Salli server to another. The export gains export_version (2) and rows, the person's stored rows table by table, and an archive form (GET /v1/onboarding/export/archive, salli profile export --archive) that zips it with the uploaded files. POST /v1/onboarding/restore (salli restore <file>) takes either into the person's books, first-party sign-ins only, behind the step-up and the two-step code, and only while those books are empty: no entries, no lock date, nothing but the starter chart, seeded tags, digest preferences and onboarding memories, which it replaces. The restore checks the version and the exported ledger's hash chain (the first break refuses it), then writes everything in one transaction under the person's row-level security: their id in place of the exported one, their files under their folder, their entries chained again (a return's chain_head_hash mapped), every other hash kept, the lock date last so no trigger needs relaxing. Rows pointing at records the export doesn't hold, or already on the server, are refused. The old server's audit rows are kept apart in the new restores table, outside this server's chain, which records books.restore with the export's hash and both chain heads. core_0053 adds restores and widens cma_packs.content_hash, which at 64 characters could not hold the "sha256:" hash it is given, so no CMA pack could be imported on Postgres. A round-trip test on the golden households exports, restores into a fresh person on a fresh database and exports again: equal but for the person's id, the entry hashes, profile times and the audit trail; the ledger verifies and the balance sheet, FI score and safe-to-spend agree. Docs: docs/self-host.md "Moving your books". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A person can now move their books from one Salli server to another (the hosted server to their own, or between self-hosted ones).
export_version(2) androws, the person's stored rows table by table (adapters/db/portable.py, tables indomain/export/restore.TABLES).GET /v1/onboarding/export/archive(salli profile export --archive) zips it with the uploaded files.POST /v1/onboarding/restore(salli restore <file>), JSON or archive. First-party sign-ins only (no PAT, no AI connector), the step-up and two-step code. Refused unless the books are empty: no entries, no lock date, and no row in any other restored table except the starter chart, seeded tags, digest preferences and onboarding memories, which are replaced.chain_head_hashmapped), every other hash kept. Rows pointing at records the export doesn't hold, or already on the server, are refused (409).restorestable (core_0053), outside this chain, which recordsbooks.restorewith the export hash and both chain heads.cma_packs.content_hash(64 chars could not holdsha256:…, so CMA import failed on Postgres).No console pages changed.
🤖 Generated with Claude Code