idle: EWMA activity tracking

Track activity level as an EWMA (exponentially weighted moving average)
driven by turn duration. Long turns (engaged work) produce large boosts;
short turns (bored responses) barely register.

Asymmetric time constants: 60s boost half-life for fast wake-up, 5-minute
decay half-life for gradual wind-down. Self-limiting boost formula
converges toward 0.75 target — can't overshoot.

- Add activity_ewma, turn_start, last_nudge to persisted state
- Boost on handle_response proportional to turn duration
- Decay on every tick and state transition
- Fix kent_present: self-nudge responses (fired=true) don't update
  last_user_msg, so kent_present stays false during autonomous mode
- Nudge only when Kent is away, minimum 15s between nudges
- CLI: `poc-daemon ewma [VALUE]` to query or set
- Status output shows activity percentage
This commit is contained in:
ProofOfConcept 2026-03-07 02:05:27 -05:00
parent 7ea7c78a35
commit 22a9fdabdb
4 changed files with 157 additions and 24 deletions

View file

@ -44,6 +44,7 @@ struct Status {
sinceActivity @14 :Float64; # secs since max(lastUserMsg, lastResponse)
sinceUser @15 :Float64; # secs since lastUserMsg
blockReason @16 :Text; # why idle timer hasn't fired
activityEwma @17 :Float64; # 0-1, EWMA of recent activity (running fraction)
}
interface Daemon {
@ -71,6 +72,8 @@ interface Daemon {
save @17 () -> ();
debug @18 () -> (json :Text);
ewma @20 (value :Float64) -> (current :Float64);
# Modules
moduleCommand @15 (module :Text, command :Text, args :List(Text))
-> (result :Text);