Parent epic: https://github.com/DIG-Network/dig_ecosystem/issues/3173
Consumer: DIG-Network/dig-app#306 (raises the notification from these states)
Contract: DIG-Network/dig-node-control-interface#32 (closed, published 0.23.0)
Body corrected 2026-08-28. This ticket was filed carrying dig-app#306's body verbatim — a
double-file. The title was always right; the body described the app-side notification. Rewritten
below to the node-side scope. Nothing about the work changed.
Task
Calculate a recommended $DIG buffer from the node's actual state, and expose the three funding
states over the control plane. The node computes; dig-app#306 displays and notifies.
User directive, 2026-08-28, verbatim:
"we also need a os notification when we are dangeriously out of DIG, there should be a calculated
recommended buffer of DIG based on the state of the node."
This extends DIG-Network/dig-app#300, which distinguishes only shortfall
from no shortfall. A binary signal cannot say how much to add, which is the only question a
person receiving it actually has.
The subtlety that decides whether the number is useful or alarmist
Collateral is RECLAIMED, not spent. Each epoch the node creates coins for (store, root, epoch n)
and reclaims epoch n-1 — and #377 specifies that
reclaims run first in every pass and are never gated on funds, precisely so returned collateral
funds the creates behind it.
So the steady-state requirement is roughly one epoch's lock, not one per epoch. A buffer computed
as "requirement x epochs of runway" overstates by the number of epochs and tells a user to acquire
many times what they need.
What the buffer must cover:
- One epoch's lock —
pairs x required_per_store x (1 + margin). The standing commitment.
- The transition overlap — the window where epoch
n coins exist before n-1 is reclaimed, or
where a reclaim fails or is delayed. This is the real peak, and it is what an operator who has
never seen a failed reclaim will not have budgeted for.
- Escalation headroom — the requirement can rise, bounded at +12.5% per epoch
(UP_STEP_DENOM = 8 in dig-mirror-collateral).
Escalation compounds, so headroom is a horizon choice, not a constant:
| after |
wall clock |
factor |
headroom |
| 1 epoch |
7 days |
x1.12 |
12.5% |
| 2 epochs |
14 days |
x1.27 |
26.6% |
| 4 epochs |
28 days |
x1.60 |
60.2% |
| 8 epochs |
56 days |
x2.57 |
156.6% |
| 13 epochs |
91 days |
x4.62 |
362.4% |
Pick a horizon and justify it in the output. A quarter of worst-case escalation demands 4.6x the
current lock, which is not advice anyone will follow; around a month reads as prudent. State the
horizon so the number is checkable rather than magic, and say plainly that the ceiling is a worst
case, not a forecast — in the dead band the multiplier does not move at all.
The three states
| state |
meaning |
dig-app#306 surface |
| Short now |
cannot cover the current epoch; stores are already going uncollateralised |
notify |
| Dangerously low |
covers now, but cannot cover the next epoch at the escalation ceiling |
notify |
| Below recommended buffer |
fine for several epochs, no cushion |
readout only, never a notification |
The third must not notify. A node in normal operation sits below a comfortable buffer much of the
time; notifying on it produces a recurring alert that is usually ignorable, which is how a user learns
to ignore the two that matter. That policy is stated here because this ticket owns the state
classification; the notification behaviour itself is dig-app#306.
Requirements
- Say the number. The output must support "Add ~N DIG", not "balance low". The whole point of
a calculated buffer is that it converts an alarm into an action.
- Show the working — pairs served, current
required_per_store, margin, and the horizon used. A
figure a client cannot render a justification for is a figure a user will not act on.
- Never report a figure on unknown state. If the node cannot determine its requirement or its
store set, the answer is unknown — not zero and not a guess. This is the money-lie rule;
BalanceReading's pending/known/unknown split is the shape to reuse.
- Use
dig-mirror-collateral's required_per_store. Do not restate the arithmetic:
equilibrium x multiplier - handicap omits the floor clamp and is wrong as a formula.
- $DIG has 3 decimals; its base unit is 0.001 DIG. A mojo is XCH's base unit (1e-12 XCH). Nine
orders of magnitude apart — do not let one name touch the other here.
Where it lives
In the node. It needs the store set, the epoch requirement, the margin and the reclaim state, all
of which are node-side. It is a natural fit for the control.collateral.* methods declared in
dig-node-control-interface 0.23.0, so one answer serves the readout, the notification and the margin
cost figure together — and dign can answer the same question on a headless host where no
notification will ever fire.
Acceptance
On a real funded node: the recommended buffer is a specific number the operator can check against
their own arithmetic; the three states are distinguishable over the control plane and from dign; and
a node with unknown state reports unknown rather than a figure.
Parent epic: https://github.com/DIG-Network/dig_ecosystem/issues/3173
Consumer: DIG-Network/dig-app#306 (raises the notification from these states)
Contract: DIG-Network/dig-node-control-interface#32 (closed, published 0.23.0)
Task
Calculate a recommended $DIG buffer from the node's actual state, and expose the three funding
states over the control plane. The node computes; dig-app#306 displays and notifies.
User directive, 2026-08-28, verbatim:
This extends DIG-Network/dig-app#300, which distinguishes only shortfall
from no shortfall. A binary signal cannot say how much to add, which is the only question a
person receiving it actually has.
The subtlety that decides whether the number is useful or alarmist
Collateral is RECLAIMED, not spent. Each epoch the node creates coins for
(store, root, epoch n)and reclaims
epoch n-1— and #377 specifies thatreclaims run first in every pass and are never gated on funds, precisely so returned collateral
funds the creates behind it.
So the steady-state requirement is roughly one epoch's lock, not one per epoch. A buffer computed
as "requirement x epochs of runway" overstates by the number of epochs and tells a user to acquire
many times what they need.
What the buffer must cover:
pairs x required_per_store x (1 + margin). The standing commitment.ncoins exist beforen-1is reclaimed, orwhere a reclaim fails or is delayed. This is the real peak, and it is what an operator who has
never seen a failed reclaim will not have budgeted for.
(
UP_STEP_DENOM = 8indig-mirror-collateral).Escalation compounds, so headroom is a horizon choice, not a constant:
Pick a horizon and justify it in the output. A quarter of worst-case escalation demands 4.6x the
current lock, which is not advice anyone will follow; around a month reads as prudent. State the
horizon so the number is checkable rather than magic, and say plainly that the ceiling is a worst
case, not a forecast — in the dead band the multiplier does not move at all.
The three states
The third must not notify. A node in normal operation sits below a comfortable buffer much of the
time; notifying on it produces a recurring alert that is usually ignorable, which is how a user learns
to ignore the two that matter. That policy is stated here because this ticket owns the state
classification; the notification behaviour itself is dig-app#306.
Requirements
a calculated buffer is that it converts an alarm into an action.
required_per_store, margin, and the horizon used. Afigure a client cannot render a justification for is a figure a user will not act on.
store set, the answer is unknown — not zero and not a guess. This is the money-lie rule;
BalanceReading's pending/known/unknown split is the shape to reuse.dig-mirror-collateral'srequired_per_store. Do not restate the arithmetic:equilibrium x multiplier - handicapomits the floor clamp and is wrong as a formula.orders of magnitude apart — do not let one name touch the other here.
Where it lives
In the node. It needs the store set, the epoch requirement, the margin and the reclaim state, all
of which are node-side. It is a natural fit for the
control.collateral.*methods declared indig-node-control-interface0.23.0, so one answer serves the readout, the notification and the margincost figure together — and
digncan answer the same question on a headless host where nonotification will ever fire.
Acceptance
On a real funded node: the recommended buffer is a specific number the operator can check against
their own arithmetic; the three states are distinguishable over the control plane and from
dign; anda node with unknown state reports unknown rather than a figure.