homehub: implement + validate sync, tombstones, manifest, alerts

Tested end-to-end with two throwaway homes against a scratch hub root:
deletion propagation, new-machine join safety, edit-wins-over-delete,
reaping, forget, alert timing. Fixes found by those tests:
 - harvest deletions BEFORE the pull (pull used to undo every deletion)
 - gate attribution on $STATE/seen (a new machine would have tombstoned
   every hub file its peers had just uploaded)
 - active_path probed '+ /dir***' instead of '+ /dir/***' -> every tombstone
   looked out-of-scope, so deletions never applied
 - tombstone excludes must precede includes in the filter (first match wins)
 - rsync must get -e with the deploy key; harvest stderr must not be dropped
 - guard hub sync root that already holds unrelated data (178 G here)
 - scrub credentials out of repo remote URLs before publishing the manifest
This commit is contained in:
druppy committed 2026-10-24 16:36:40 +02:00
1 parent 78496330f3
commit be375fb312
4 files changed
+150 -45

No files matched your search

+25 -2
View File
@@ -1,6 +1,29 @@
# homehub — lean home-drive sync across 3–4 machines via Synology
Status: **design, no code yet**. Open decisions in §13.
Status: **implemented and tested on g9; no personal file data uploaded yet.** Decisions in §13,
operations in `README.md`.
### Verification status (2026-10-24)
| Behaviour | Method | Result |
|---|---|---|
| default-deny filter, shadow warnings | `homehub filter` on real `$HOME` | 35 include / 95 deny rules, no shadowing |
| pending set is genuinely personal | dry run on real `$HOME` | 571 files, 470 MB (docs, photos, dotfiles, pi sessions) |
| class B manifest, no byte-sync of repos | `git inventory` | 114 repos in 11 s, credentials scrubbed from 3 remotes |
| class C union merge + idempotency | synthetic 2-host export | 53 urls, re-merge stable |
| alert timing (silent → 24 h → once) | backdated `broken.auth` | silent at 0 m, single alert at 2 d |
| new machine must not tombstone the hub | 2 fake homes + scratch hub root | 5 never-seen hub files correctly ignored |
| deletion propagates, never resurrects | same | harvested pre-pull; peer applied it; no resurrection |
| **edit wins over a later delete** | same | re-pulled peer's newer copy, classified `EDITED-ELSEWHERE` |
| reaper preserves the last copy | `GRACE_DAYS=0` | hub copy moved to `.hub/prev/reaped/2026-10/…`, tombstone pruned |
| `forget` escape hatch | same | file travels again after forgetting it |
Not yet exercised: 3+ machine convergence, suspend/resume with `Persistent=true`,
real mtime-conflict resolution across skewed clocks, and the bookmark write-back
(v1 deliberately stops before overwriting the live file).
**Blocking step before any real sync:** `ssh-copy-id -i ~/.ssh/homehub_ed25519.pub nas.lue.dk`
— see §0 row on the passphrase/agent problem.
## 0. Ground truth this design was built against
@@ -256,7 +279,7 @@ freshness monitor, not an error notifier.
- Transport: `sendmail` → your existing `mail.lue.dk`. Works with no GUI session,
which `notify-send` does not.
## 11. Files to be created (this repo = the policy; ~200 lines of shell total)
## 11. Files to be created (~750 lines of bash in total — the comments are half of it)
```
~/homehub/ # small git repo, hub-backed via a bare repo on the NAS