nudge: add digest/batching mode for care nudges

When enabled, eligible nudges (sev ≤ ceiling) are queued in memory
instead of sent immediately. Every 'window' duration (or when
'max_items' reached), the queue is flushed as a single digest
notification with concatenated bodies.

Config:
  digest:
    enabled: true           # default false
    window: 30m             # flush window (default 30m)
    max_items: 5            # flush at this count (default 5)
    severity_ceiling: 2     # max sev batched (default 2; sev3+ bypass)

Changes:
- config.go: add DigestConfig struct with defaults
- tick.go: QueuedNudge type, digest queue/flush in TickLoop,
  shouldQueue/maybeFlush/flushDigest helpers
- main.go: pass cfg.Digest to newTickLoop
- tick_test.go: 6 new tests covering queue, flush, bypass, dedup
This commit is contained in:
kami
2026-07-05 13:07:28 +04:00
parent 5afff001c3
commit 354990fed0
5 changed files with 388 additions and 18 deletions
+1 -1
View File
@@ -175,7 +175,7 @@ func run(args []string) error {
tickInterval := time.Duration(cfg.TickInterval)
repeatInterval := time.Duration(cfg.RepeatInterval)
autotuneInterval := time.Duration(cfg.AutotuneInterval)
loop := newTickLoop(st, gatherer, dispatcher, phr, rules, tickInterval, repeatInterval, autotuneInterval)
loop := newTickLoop(st, gatherer, dispatcher, phr, rules, tickInterval, repeatInterval, autotuneInterval, cfg.Digest)
// ----- IPC boundary (core ↔ modules) -----
coreAPI := ipc.NewStoreAPI(st)