Non-destructive ARA and AdGuard recovery preparation — 2026-10-24¶
PR #472 merged the deployment evidence for the first two repairs. Their recovery acceptance remains open. PR #473 addresses REC-002 and REC-003 in source: correct recovery paths and removal of destructive live-volume restore examples. No live preparation or application recovery was performed.
What changed¶
- ARA selects the exact nested
_datadirectory from its snapshot, not the outer restic staging tree. The operator supplies the reviewed SQLite-relative path; no database filename is guessed. - AdGuard selects only its backed-up configuration volume. Work/query history is
not protected by this backup policy, and the archived
unbound.confis not mounted by current Compose. Neither is selected for preparation. - A shared preparer defaults to a filesystem-only JSON plan with zero Docker
calls. Explicit
--preparemay populate only a new labelled recovery volume, after destination/ownership/attachment checks and an empty-target gate. - Copying uses a vetted, preloaded digest-pinned utility image, strict read-only source mounting, no network and no implicit image pull. Existing volumes and running services are not changed. Failed/partial recovery volumes are retained.
- Production cutover remains a separate reviewed change to both GitOps volume mapping and backup paths, with original volumes retained for rollback.
The required utility is GNU cp supporting --update=none-fail (introduced in
coreutils 9.5), not generic BusyBox cp. A successful preparation is not
SQLite integrity, AdGuard DNS correctness, content/metadata fidelity or recovery
acceptance. Trusted stable staging, a trusted local daemon/image, and sufficient
storage headroom remain explicit prerequisites.
Validation boundary¶
Tests use synthetic staged files and fake Docker, covering exact source selection,
plan-only refusal to invoke Docker, existing/raced/nonempty/attached destinations,
image and endpoint checks, and retained failure data. Separate tests execute the
actual fixed shell/copy command with installed GNU cp: hidden files and ordinary
modes are preserved, nonempty targets are refused, and conflicting files are not
overwritten. This is not a real Docker mount or application restore test.
Independent review found no blocker within the documented trust boundary. Exact commands, local results and limitations are retained privately; check PR #473's exact-head CI before merging. Prior source, deployment and failed-check records remain unchanged.
Phase status and next gates¶
| Concern | Status in this slice | Remaining gate |
|---|---|---|
| REC-001 / INC-002 / OPS-043 | Previously observed deployed | New local/offsite recovery sets and isolated application integrity/rollback |
| INC-003 | Previously observed deployed | Trusted relocated artifacts and isolated application recovery |
| REC-002 / REC-003 | Source implementation under review | Exact-head CI, reviewed deployment, approved real preparation and application/rollback checks |
| Other 249 groups | Backlog | Separately scoped repairs and evidence |
flowchart TD
Stage[Reviewed snapshot staging] --> Plan[Filesystem-only preparation plan]
Plan --> Approval[Owner approves image, daemon, storage and destination]
Approval --> Prepare[Populate a new recovery volume only]
Prepare --> Validate[Isolated application and metadata validation]
Validate --> Review[Separate GitOps and backup-path cutover review]
Review --> Accept[Owner acceptance and rollback retention]
Operating guides: ARA restore,
AdGuard restore, and the private registry
linked from the repository README.
The shared checkout was left untouched; work used an isolated worktree from merged
main. No backup, live Docker operation, service restart, restore, cleanup,
credential decryption or merge was executed by this source-repair session.