Bell reliability: rate-budget separation, anti-starvation, bell ledger + watchdog (v0.3.1) #21
Loading…
Reference in a new issue
No description provided.
Delete branch "oss-oo/bell-reliability-v031-lrel20260925"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes the owner-reported chain break (2026-09-25): a validation bell sat undelivered for ~2 h because the shared per-parent rate limit (3/15 min) was consumed by the owner’s own queued steer deliveries while the parent was busy in long owner conversations.
bellvssteer, legacy classified byevent="steer"); budgets are per kind per parent / 15 min: bells 3 (anti-spam), steersZDO_STEER_RATE_LIMIT(default 20). Owner input is never throttled by bell spam protection.ZDO_STARVATION_S(default 600) delivers regardless of the budget, and every guard fire is logged.notify_parent()appends a spawn-time record tostream-bells.json{child, parent, event, spawned_at, result_out, …}(deduped per child+event, last 200); delivery stampsdelivered_at— the authoritative bell audit trail.ZDO_BELL_WATCHDOG_S(default 300): re-queued with original age (budget bypass), escalated via MQTTzcode/session/<parent>/bell-stuck{child, age, action}+ one-shot desktop notification (“🔔 WATCHDOG: undelivered bell re-queued”); after 3 rescues a record is marked lost, never re-queued.stream_functional_test.py, wired intomake functional): replays the exact incident (3 steer deliveries in window + queued bell → delivers via starvation guard / kind separation), proves oldest-first fairness, the intact bell throttle, the lost-spawn watchdog (requeue + escalation + ledger reconcile) and the spawn-time ledger + busy self-queue.Docs: USAGE.md §8 (budgets, guard, ledger, watchdog, env vars), MQTT-TOPICS.md (bell-stuck topic), README, .zcode/AGENTS.md.
Fixes the owner-reported chain break (2026-09-25): a validation bell sat undelivered for ~2 h because the shared per-parent rate limit (3/15 min) was consumed by the owner's own queued steer deliveries while the parent was busy in long owner conversations. - Kind on every queue/history entry (bell vs steer, event="steer" fallback for legacy records); rate budgets are per kind per parent per 15 min: bells 3 (anti-spam), steers ZDO_STEER_RATE_LIMIT (default 20) — owner input is never throttled by bell spam protection. - Sweep delivers OLDEST queue entries first; a starvation guard (ZDO_STARVATION_S, default 600) delivers anything older regardless of the budget and logs every fire. - Bell ledger: notify_parent() appends a spawn-time record to stream-bells.json {child, parent, event, spawned_at, result_out, …} (deduped per child+event, last 200); delivery stamps delivered_at — the authoritative bell audit trail. - Watchdog: each sweep rescues ledger bells neither queued nor delivered past ZDO_BELL_WATCHDOG_S (default 300) — re-queued with original age (budget bypass), escalated via MQTT zcode/session/<parent>/bell-stuck {child, age, action} plus a one-shot desktop notification; after 3 rescues a record is marked lost, never re-queued. - stream_functional_test.py (wired into make functional): offline replay of the exact incident plus lost-spawn watchdog, fairness, throttle and spawn-time ledger legs against the real sweep code. Docs: USAGE.md §8 (budgets, guard, ledger, watchdog, env vars), MQTT-TOPICS.md (bell-stuck), README, .zcode/AGENTS.md.