Task
observe_disk and observe_chain must be event-driven, with the 10-minute timer kept as a backstop — not replaced by events.
Stated by the user 2026-08-31: "the observe_disk and observe_chain need to be event based, only using a timer as backup".
This does NOT contradict the existing rationale — read it before building
mirror/mod.rs:20-22 says:
"The start-up reconcile is the reliable path, not the file watcher. A watcher's event is exactly what a crash loses; a scan at start-up re-derives the whole answer from two observations that survive anything."
That rejects a watcher as the correctness mechanism. The user is asking for a watcher as an accelerant over a scan that stays. Those are the same position: events for latency, the scan for correctness.
So the invariant is: no behaviour may depend on an event arriving. Every event is a hint that lets the pass run sooner; the periodic scan and the start-up reconcile remain the guarantee, unchanged. If every event were dropped forever, the node must still converge — which is exactly what #464 requires, and this ticket must not weaken it.
Do not delete the timer. Do not lengthen it to "compensate" for having events — that trades the correctness floor for responsiveness, which is backwards.
What the events are
Disk: a capsule landing or being removed under the cache. Note the pass already consumes debounced presence deltas (runner.rs:243-245, server.rs:2742/2816/2821) with a settling window — check whether an event source already exists and is merely not wired to the mirror pass, before adding a watcher. Reuse before building (§2.0).
Chain: a new peak, or a coin-state update for the operator's puzzle hash. dig-node already runs a Chia light client with peer subscriptions and there is a chia-block-listener crate in the tree — measure what is already subscribed before adding anything. A mirror pass triggered on every new peak (~18.75s) would be far too often; see amplification below.
The two things that will go wrong if unattended
- Amplification. A burst of capsule writes, or a peak every ~19 seconds, must not produce a pass per event. Each pass reads chain and may spend money. Coalesce: a settling window like the existing
SETTLING_WINDOW_MS (30s) and a minimum interval between passes, so N events in a window cause ONE pass. State the chosen bound and what happens when events arrive during a pass.
- A wedged pass. If a pass hangs, events must not queue unboundedly behind it, and the backstop timer must still fire afterwards. Passes must not overlap — confirm the current loop's guarantee and preserve it.
Also settle, because it is a real fork
Should a chain event trigger a pass at all, or only refresh the observation? A create is decided from disk presence; chain events mostly matter for reclaim (an epoch rolled over, a coin was spent by someone else) and for resolving landed spends. Triggering a full pass on chain activity may be more than is wanted. Decide, and say why (§1.10 — settle the shape before building).
Acceptance
Parent
Lifecycle #412 · self-healing sibling #464 · epic https://github.com/DIG-Network/dig_ecosystem/issues/3166
Task
observe_diskandobserve_chainmust be event-driven, with the 10-minute timer kept as a backstop — not replaced by events.Stated by the user 2026-08-31: "the observe_disk and observe_chain need to be event based, only using a timer as backup".
This does NOT contradict the existing rationale — read it before building
mirror/mod.rs:20-22says:That rejects a watcher as the correctness mechanism. The user is asking for a watcher as an accelerant over a scan that stays. Those are the same position: events for latency, the scan for correctness.
So the invariant is: no behaviour may depend on an event arriving. Every event is a hint that lets the pass run sooner; the periodic scan and the start-up reconcile remain the guarantee, unchanged. If every event were dropped forever, the node must still converge — which is exactly what #464 requires, and this ticket must not weaken it.
Do not delete the timer. Do not lengthen it to "compensate" for having events — that trades the correctness floor for responsiveness, which is backwards.
What the events are
Disk: a capsule landing or being removed under the cache. Note the pass already consumes debounced presence deltas (
runner.rs:243-245,server.rs:2742/2816/2821) with a settling window — check whether an event source already exists and is merely not wired to the mirror pass, before adding a watcher. Reuse before building (§2.0).Chain: a new peak, or a coin-state update for the operator's puzzle hash. dig-node already runs a Chia light client with peer subscriptions and there is a
chia-block-listenercrate in the tree — measure what is already subscribed before adding anything. A mirror pass triggered on every new peak (~18.75s) would be far too often; see amplification below.The two things that will go wrong if unattended
SETTLING_WINDOW_MS(30s) and a minimum interval between passes, so N events in a window cause ONE pass. State the chosen bound and what happens when events arrive during a pass.Also settle, because it is a real fork
Should a chain event trigger a pass at all, or only refresh the observation? A create is decided from disk presence; chain events mostly matter for reclaim (an epoch rolled over, a coin was spent by someone else) and for resolving landed spends. Triggering a full pass on chain activity may be more than is wanted. Decide, and say why (§1.10 — settle the shape before building).
Acceptance
Parent
Lifecycle #412 · self-healing sibling #464 · epic https://github.com/DIG-Network/dig_ecosystem/issues/3166