backup: an instance backs up into a synced folder - backup init makes a bare repository under <target>/git its origin, backup run and publish mirror the machine data into <target>/<machine>/, doctor warns about .git in a synced folder (#186); 10.0.0-beta.10
CI / verify (push) Successful in 8m24s
CI / pwsh (push) Successful in 2m45s
Release / release (push) Successful in 34s
Release / wiki-mirror (push) Skipped

Files changed:
- CHANGES.md
- INSTALL.md
- VERSION
- docs/explanation/configuration-tiers.md
- docs/how-to/README.md
- docs/how-to/back-up-to-a-synced-folder.md
- docs/reference/commands/README.md
- docs/reference/commands/git.md
- docs/reference/commands/instance-health.md
- docs/reference/configuration.md
- instructions/publish-cycle.md
- instructions/setup-instance.md
- tools/CONTRACT.md
- tools/README.md
- tools/chemenu/backup.py
- tools/chemenu/cli.py
- tools/chemenu/cli_contract.py
- tools/chemenu/commands/backup_cmd.py
- tools/chemenu/commands/doctor.py
- tools/chemenu/commands/git_publish.py
- tools/chemenu/config_shapes.py
- tools/chemenu/reference_doc.py
- tools/chemenu/tests/conftest.py
- tools/chemenu/tests/test_backup.py
- tools/chemenu/tests/test_config_shapes.py

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
This commit is contained in:
torbenandClaude Opus 5.5 committed 2026-10-12 19:39:49 +02:00
1 parent e789146116
commit 9736472f48
25 files changed
+2024 -15

No files matched your search

+52 -1
View File
@@ -30,6 +30,7 @@ something you run.
- [MCP submissions](#mcp-submissions)
- [Site handlers](#site-handlers)
- [Fetch routes](#fetch-routes)
- [Backup to a synced folder](#backup-to-a-synced-folder)
- [Files of earlier versions](#files-of-earlier-versions)
<!-- /wikitool:toc -->
@@ -91,7 +92,8 @@ Each file is a JSON object of sections, one per feature, beside two keys of its
`instance_id` sits in `wikitool.json` only. The first `wikitool config set` creates the file and
the id; the id names the directory of the secrets file below. The sections are [telemetry](#telemetry),
[remotes](#allowed-push-urls), [tasks, superproductivity and caldav](#task-tracker) and
[upload](#mcp-submissions), [sites](#site-handlers) and [fetch](#fetch-routes). `config set` names the sections it knows, and `doctor` reports a
[upload](#mcp-submissions), [sites](#site-handlers), [fetch](#fetch-routes) and
[backup](#backup-to-a-synced-folder). `config set` names the sections it knows, and `doctor` reports a
section it does not read as a `WARN`.
**One place per value.** A value in the file its tier does not name is an error naming the file,
@@ -533,6 +535,55 @@ Example:
```
<!-- /wikitool:reference-config-fetch -->
## Backup to a synced folder
The `backup` section of `.wikitool-local.json` backs this checkout up into a folder a sync client
uploads - OneDrive and the like - while the working tree itself stays outside it. The target gets
two kinds of content:
```
<target>/git/ bare repository, the checkout's origin; publish pushes here
<target>/<machine>/ mirror of this machine's files that are not in git, plus .chemenu-backup.json
```
`tools/wikitool backup init` creates `<target>/git` and makes it `origin` when the checkout has none.
With `machine_data` on, every `publish` that pushed mirrors `.wikitool-local.json`, `ENVIRONMENT.md`,
what waits in `incoming/` and the `extra` paths into `<target>/<machine>/`; `tools/wikitool backup
run` does the same on its own. The secrets file is never among them - it lies outside the instance,
and a backup reads nothing outside it. Plain private values in `.wikitool-local.json`, an internal
host name for one, do reach the synced folder.
<!-- wikitool:reference-config-backup -->
| Field | Tier | Type | Required | Default | Description |
|-------|------|------|----------|---------|-------------|
| `target` | checkout, gate | string | yes | - | The backup folder: an absolute path outside the instance. `backup init` creates `<target>/git` in it, `backup run` writes only to `<target>/<machine>/`. |
| `machine_data` | checkout, gate | boolean | no | `false` | Mirror this machine's files after every `publish` that pushed, and with `backup run`: `.wikitool-local.json`, `ENVIRONMENT.md`, what waits in `incoming/`, and `extra`. |
| `machine_name` | checkout | string | no | the host name | The name of this machine's folder under the target. Every character outside letters, digits, `-` and `_` becomes `-`, and leading and trailing `-` are dropped; a name that is empty afterwards, or `git` in any case, is an error. |
| `extra` | checkout, gate | array of strings | no | `[]` | Further files or directories to mirror, relative to the instance. One that resolves outside the instance, or into `.git/`, is an error. |
- **Absent:** No backup: `publish` behaves as without it, and `backup init` and `backup run` stop with exit 1 naming the section.
- **Malformed:** An error. `publish` stops with exit 1 before it commits anything, `backup init` and `backup run` stop with exit 1, and `doctor` reports `FAIL`. A broken section is never read as "no backup".
Example:
```json
{
"backup": {
"target": "C:\\Users\\<user>\\OneDrive - <company>\\Chemenu-Backup",
"machine_data": true,
"machine_name": "WORK-LAPTOP",
"extra": [
".claude/settings.local.json"
]
}
}
```
<!-- /wikitool:reference-config-backup -->
`target`, `machine_data` and `extra` decide what leaves this machine, so they are marked `gate`:
`config set` exits 42 for them, and only you write them. The procedure, restoring included:
[back-up-to-a-synced-folder.md](../how-to/back-up-to-a-synced-folder.md).
## Files of earlier versions
Until version 10 every feature above had a file of its own at the root: `.wikitool-telemetry.json`,