Files
chemenu/docs/how-to/back-up-to-a-synced-folder.md
T
torbenandClaude Code 99945c4841
CI / verify (push) Successful in 9m2s
CI / pwsh (push) Successful in 2m48s
Release / release (push) Successful in 34s
Release / wiki-mirror (push) Skipped
export: export run writes selected kb/ pages as a derived, read-only version into configured target folders (markdown and command handlers, manifest, after_publish), raw accept also refuses manifest-listed files, doctor checks the section (#214); 10.0.0-beta.13
Files changed:
- CHANGES.md
- VERSION
- docs/how-to/README.md
- docs/how-to/back-up-to-a-synced-folder.md
- docs/how-to/collect-from-a-synced-folder.md
- docs/how-to/export-guidelines.md
- docs/how-to/export-to-a-synced-folder.md
- docs/reference/commands/README.md
- docs/reference/commands/exports.md
- docs/reference/commands/git.md
- docs/reference/commands/guideline-export.md
- docs/reference/commands/instance-health.md
- docs/reference/commands/raw-material-and-uploads.md
- docs/reference/configuration.md
- docs/reference/exit-codes.md
- instructions/setup-instance.md
- raw/CONTRACT.md
- tools/CONTRACT.md
- tools/README.md
- tools/chemenu/backup.py
- tools/chemenu/cli_contract.py
- tools/chemenu/commands/doctor.py
- tools/chemenu/commands/export_cmd.py
- tools/chemenu/commands/git_publish.py
- tools/chemenu/commands/raw/_common.py
- tools/chemenu/commands/raw/accept.py
- tools/chemenu/commands/raw/capture.py
- tools/chemenu/config_shapes.py
- tools/chemenu/guideline_export.py
- tools/chemenu/page_export.py
- tools/chemenu/reference_doc.py
- tools/chemenu/repo_capture.py
- tools/chemenu/tests/test_config_shapes.py
- tools/chemenu/tests/test_export_run.py

Co-Authored-By: Claude Code <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
2026-10-13 05:53:48 +02:00

163 lines
8.5 KiB
Markdown

# Back up to a synced folder
Back an instance up into a folder a sync client uploads - OneDrive, or any other client that keeps a
local folder in step with a server - when there is no git server to push to. The instance itself
stays in a folder the sync client does not touch; the synced folder receives a git repository to
push to and a copy of the files on this machine that are not in git. What the settings look like:
[configuration reference](../reference/configuration.md#backup-to-a-synced-folder).
<!-- wikitool:toc -->
## Contents
- [Why the instance does not live in the synced folder](#why-the-instance-does-not-live-in-the-synced-folder)
- [Set it up](#set-it-up)
- [What is backed up, and what is not](#what-is-backed-up-and-what-is-not)
- [Restore](#restore)
- [One device writes](#one-device-writes)
<!-- /wikitool:toc -->
## Why the instance does not live in the synced folder
Putting the whole instance - `.git` included - into the synced folder looks like the simplest
backup, and fails in three ways:
- **Locks.** On Windows, OneDrive holds a file it is uploading open for a moment. `git gc` and
`git repack` then fail to delete or replace a file under `.git` ("unlink failed").
- **Placeholders.** With Files On-Demand, the client offloads files it considers unused and leaves a
placeholder behind; git then reads objects that first have to be downloaded, or are not there
when the machine is offline.
- **Conflict copies.** As soon as a second device syncs the same folder, two writers meet inside
`.git`, and the client resolves that by making copies of the files both changed - a repository
git can no longer read.
So the instance lives outside the synced folder, and the synced folder gets a layout git writes to
in a way a sync client handles well:
```
<target>/git/ a bare repository - origin of the instance; publish pushes to it
<target>/<machine>/ a copy of this machine's files that are not in git, plus .chemenu-backup.json
```
Git writes into the bare repository only on a push, and then mostly adds new files that never
change again.
`tools/wikitool doctor` reports `sync-folder` as a `WARN` when the instance's git directory lies in
a synced folder. On Windows, check that line even if you never chose such a folder: when Documents
or Desktop is redirected into OneDrive (Known Folder Move), an instance under Documents lies in
OneDrive without looking like it. Move the instance to a folder outside it - `C:\Wiki\<name>`, say -
before you go on.
## Set it up
1. **Pick the target**: a folder inside the synced folder, for example
`C:\Users\<you>\OneDrive - <company>\Chemenu-Backup`. It must not lie inside the instance.
2. **Write the `backup` section** into `.wikitool-local.json` at the root of the instance - by hand,
since its fields decide what leaves this machine and `config set` refuses them:
```json
{
"backup": {
"target": "C:\\Users\\<you>\\OneDrive - <company>\\Chemenu-Backup",
"machine_data": true,
"machine_name": "WORK-LAPTOP",
"extra": [".claude/settings.local.json"]
}
}
```
Backslashes in a JSON string are doubled. `machine_name` defaults to the computer's host name;
`extra` lists further paths inside the instance to copy, and can be left out.
3. **Tell the agent:**
> Set up the backup target from the `backup` section.
The agent runs `tools/wikitool backup init`. It creates `<target>/git` as a bare repository and
makes it `origin` - unless the instance already has an `origin` that points elsewhere: then it
changes nothing and shows you both URLs, and whether `origin` moves is yours to decide
(`git remote set-url origin "<target>\git"`).
4. **Allow the push target**, if your `.wikitool-local.json` has a `remotes` section: `backup init`
then prints that section with `<target>\git` added. Copy it into the file yourself - the list is
the Publish-Remote Gate, and no agent edits it. Without a `remotes` section there is nothing to do.
5. **Publish.** The next `tools/wikitool publish` pushes the whole history to `<target>/git` and,
with `machine_data` on, copies the machine data into `<target>/<machine>/`. From then on every
publish that pushes does both. `tools/wikitool backup run` copies the machine data on its own,
whenever you want it current without publishing - after dropping a file into `incoming/`, for
instance, which is otherwise only copied by the next publish.
6. **Check it:** `tools/wikitool doctor`. The `backup` line names the target and how old the last
copy of the machine data is; a `WARN` there names what is missing.
If a publish reports a `WARN` that the machine-data backup failed, the commit and the push have
still happened. Fix what the line names - a synced folder that is not there, a folder that is not
writable - and run `tools/wikitool backup run`. Another publish does not help: it has nothing new to
push.
## What is backed up, and what is not
| Path | Backed up | Why |
|------|-----------|-----|
| Everything committed (`kb/`, `raw/`, `wikitool.json`, ...) | yes, in `<target>/git` | that is what `publish` pushes |
| `.wikitool-local.json` | yes | the settings of this checkout |
| `ENVIRONMENT.md` | yes, if present | written by hand |
| Everything in `incoming/` but `.gitkeep` | yes | sources waiting there are backed up nowhere else |
| The `extra` paths | yes | what you named |
| `quarantine/` | no | material that arrived through an intake channel and that nobody has reviewed yet |
| `reports/` | no | regenerated by `lint`; telemetry holds prompts |
| `.wikitool-tools.json`, `tools/.venv/`, the published skills | no | the preflight and `instructions sync` rebuild them |
| The secrets file | **never** | it lies outside the instance, and a backup reads nothing outside it |
**Private values reach the synced folder.** `.wikitool-local.json` is copied as it is, so a plain
private value in it - an internal host name, an internal URL - ends up in OneDrive. A secret does
not: a secret is never in that file, only a reference to it, and the secrets file it resolves
through (`%APPDATA%\chemenu\<instance_id>\secrets.json`, with the sessions `raw login` stored)
lies outside the instance. An `extra` path that leads outside the instance - through `..` or a
link - is refused, so no setting can copy it either.
In `<target>/<machine>/` a run writes and deletes only what is its own: it removes a file only when
its previous run copied it and the instance no longer has it (a source `raw accept` moved out of
`incoming/`, say), and refuses a folder that is not empty and has no `.chemenu-backup.json`, rather
than copying into somebody else's folder. A link inside a copied directory is skipped and named,
never followed.
## Restore
On the same machine or a new one:
1. **Clone the repository and check it:**
```bash
git clone "<target>/git" "<new folder>"
cd "<new folder>"
git fsck --full
```
The clone is outside the synced folder, like the original; its `origin` is the bare repository
already.
2. **Copy the machine data back**: everything in `<target>/<machine>/` except
`.chemenu-backup.json`, into the new folder, keeping the paths. On Windows:
`robocopy "<target>\<machine>" "<new folder>" /E /XF .chemenu-backup.json`; elsewhere:
`rsync -a --exclude .chemenu-backup.json "<target>/<machine>/" "<new folder>/"`.
3. **Bootstrap the checkout** - tell the agent:
> Bootstrap this checkout.
It follows [instructions/bootstrap.md](../../instructions/bootstrap.md): the preflight, the
published skills, `doctor`.
4. **Provide the secrets again.** They were never in the backup. Put each value back where its
reference reads it - 1Password, the secrets file, or a `WIKITOOL_SECRET_<NAME>` variable
([use-1password-for-settings.md](use-1password-for-settings.md)) - and sign in again with
`raw login` for each host that needs it. `doctor`'s `settings-secrets` line names every reference
that does not resolve yet.
`doctor` must then run through without a `FAIL`.
## One device writes
Only one device publishes to `<target>/git`. Two devices pushing into the same synced folder are two
writers again, only one step removed - and the sync client resolves that with conflict copies, not
with a merge. An instance on a second device gets a target of its own. The sync client is a backup
here, not a way to work on one instance from two devices.
A folder the sync client uploads can also hold a read-only version of selected pages, for readers
outside the repository: [Export pages to a synced folder](export-to-a-synced-folder.md). It is a
separate folder with its own settings, and never the backup target.