Problem (friction log F25, S1 — confirmed live, twice)
The agent's scheduler is one serial worker with no per-run time bound. When the walk's S3 endpoint stopped accepting writes, the in-flight rclone hung and everything froze — no cloudbox pushes, no NAS→HTPC peer-sync, no kopia snapshots, across all volumes — for 12.6 minutes until the run failed; during a later full endpoint outage, indefinitely, until an operator killed the rclone process by hand. No rclone timeout fired, no run failed, and the only trace was a kicked line with no finished. In the reference household this means a dark cloud destination silently stops local NAS→HTPC replication too.
Decision (Martin, 2026-07-24 — option 4b: one PR)
Go straight to per-destination worker queues plus timeouts in a single change:
Notes
- Keep per-volume index runs serialized against that volume's syncs (pre-sync index ordering must hold); the concurrency unit is the destination, not the volume.
- Scheduler-log discipline (kicked/skipped/finished/error) stays;
skipped reason="in-flight sync run" becomes per-pair.
- Acceptance: re-run walk scenario "endpoint goes dark" on the testbed — other destinations keep syncing, the stuck pair fails within the bound with a diagnosable error.
See design/friction-log.md F25.
Problem (friction log F25, S1 — confirmed live, twice)
The agent's scheduler is one serial worker with no per-run time bound. When the walk's S3 endpoint stopped accepting writes, the in-flight rclone hung and everything froze — no cloudbox pushes, no NAS→HTPC peer-sync, no kopia snapshots, across all volumes — for 12.6 minutes until the run failed; during a later full endpoint outage, indefinitely, until an operator killed the rclone process by hand. No rclone timeout fired, no run failed, and the only trace was a
kickedline with nofinished. In the reference household this means a dark cloud destination silently stops local NAS→HTPC replication too.Decision (Martin, 2026-07-24 — option 4b: one PR)
Go straight to per-destination worker queues plus timeouts in a single change:
--contimeout/--timeouton every rclone invocation, plus a squirrel-side wall-clock/no-progress bound that kills the child, fails the run with a real error (composes with runs: every failure and refusal becomes a run row or a standing state #157's stderr capture), and lets the pair retry next cadence.Notes
skipped reason="in-flight sync run"becomes per-pair.See
design/friction-log.mdF25.