Project from the sustained regime: habit change, scenario range, and evidence gates #26

Closed
opened 2026-08-31 18:24:32 +00:00 by xavierk · 1 comment
Owner

Parent

Implement the Fenris persistent TUI monitoring redesign

Canonical contracts: fenris-redesign spec · acceptance criteria — criterion IDs cited below live in the register.

What to build

Regime dynamics on top of the projection core. The headline rate comes from the most recent sustained regime — the full observation history capped at 90 days by default. A habit change is declared when the trailing 7-day mean stays ≥ 2× (or ≤ 0.5×) the preceding 28-day mean for 3 consecutive days; the new regime starts at the first divergence day, is adopted automatically, and renders labeled "usage habit changed N days ago"; a regime younger than 7 days caps confidence at Limited. The 7-, 28-, and 90-day scenario-range rates compute independently of the regime, showing only horizons the history actually covers — no placeholders. Warming up renders as facts until 14 distinct UTC day aggregates of which at most 2 fall below 50 % coverage, with the projection still rendering while warming. A newest day aggregate older than 48 hours drops confidence one level as a shown fact. Segment breaks behave per the axes: a DUW decrease re-warms without quarantining; an identity change quarantines prior history entirely. A degraded current segment caps confidence at Limited with the fixed contributing fact in every state, combining idempotently with the staleness drop; ephemeral markers never render as confidence facts.

Acceptance criteria

  • Headline rate is the sustained-regime rate; default regime full history capped at 90 days; scenario range computed independently, covered horizons only, no placeholders (PR-2)
  • Habit change triggers exactly at 2×/0.5× sustained 3 consecutive days, regime starts at first divergence day, auto-adopted and labeled; young regime caps at Limited (PR-3)
  • Warming-up gate: 14 distinct UTC day aggregates, ≤ 2 below 50 % coverage; projection renders with facts while warming; every Unavailable condition renders no lifespan number (PR-6)
  • Newest day aggregate older than 48 h drops confidence one level, shown as a contributing fact (PR-7)
  • Segment breaks: DUW decrease keeps prior day aggregates as habit evidence with Unavailable until re-warm; identity change quarantines prior history entirely (PR-9)
  • Degraded identity caps at Limited with the fixed fact in every state; cap combines idempotently with staleness; ephemeral markers never render as facts (PR-15)
  • Identity-change semantics extend to blank keys verbatim — to/from blank quarantines, equal blanks continue (PR-16)

Blocked by

## Parent [Implement the Fenris persistent TUI monitoring redesign](https://git.bongbetic.com/xavierk/Fenris/issues/20) Canonical contracts: [fenris-redesign spec](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/spec/fenris-redesign.md) · [acceptance criteria](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/spec/acceptance-criteria.md) — criterion IDs cited below live in the register. ## What to build Regime dynamics on top of the projection core. The headline rate comes from the most recent sustained regime — the full observation history capped at 90 days by default. A habit change is declared when the trailing 7-day mean stays ≥ 2× (or ≤ 0.5×) the preceding 28-day mean for 3 consecutive days; the new regime starts at the first divergence day, is adopted automatically, and renders labeled "usage habit changed N days ago"; a regime younger than 7 days caps confidence at Limited. The 7-, 28-, and 90-day scenario-range rates compute independently of the regime, showing only horizons the history actually covers — no placeholders. Warming up renders as facts until 14 distinct UTC day aggregates of which at most 2 fall below 50 % coverage, with the projection still rendering while warming. A newest day aggregate older than 48 hours drops confidence one level as a shown fact. Segment breaks behave per the axes: a DUW decrease re-warms without quarantining; an identity change quarantines prior history entirely. A degraded current segment caps confidence at Limited with the fixed contributing fact in every state, combining idempotently with the staleness drop; ephemeral markers never render as confidence facts. ## Acceptance criteria - [ ] Headline rate is the sustained-regime rate; default regime full history capped at 90 days; scenario range computed independently, covered horizons only, no placeholders (PR-2) - [ ] Habit change triggers exactly at 2×/0.5× sustained 3 consecutive days, regime starts at first divergence day, auto-adopted and labeled; young regime caps at Limited (PR-3) - [ ] Warming-up gate: 14 distinct UTC day aggregates, ≤ 2 below 50 % coverage; projection renders with facts while warming; every Unavailable condition renders no lifespan number (PR-6) - [ ] Newest day aggregate older than 48 h drops confidence one level, shown as a contributing fact (PR-7) - [ ] Segment breaks: DUW decrease keeps prior day aggregates as habit evidence with Unavailable until re-warm; identity change quarantines prior history entirely (PR-9) - [ ] Degraded identity caps at Limited with the fixed fact in every state; cap combines idempotently with staleness; ephemeral markers never render as facts (PR-15) - [ ] Identity-change semantics extend to blank keys verbatim — to/from blank quarantines, equal blanks continue (PR-16) ## Blocked by - [Compute the projection core: baseline precedence, provenance, and the confidence rule table](https://git.bongbetic.com/xavierk/Fenris/issues/25)
xavierk added the ready-for-agent label 2026-08-31 18:25:22 +00:00
xavierk added this to the Build: Fenris persistent TUI monitoring redesign milestone 2026-08-31 18:25:23 +00:00
xavierk added a new dependency 2026-08-31 18:25:44 +00:00
Author
Owner

Resolved in commit b99ebfe.

Changes

Bug fixes in

  1. Warming gate (PR-6): Fixed to check instead of just . The old check was too strict — it required 14 days with ≥50% coverage, but the spec only requires 14 total days with at most 2 below 50%.

  2. Habit change detection (PR-3): Rewrote to correctly scan backwards checking the ratio at each day position and count consecutive days going backwards. The old algorithm's inner loop checked wrong window positions.

  3. Horizon rate coverage (PR-2): Fixed to require the history to span the full horizon (earliest day ≤ cutoff). Previously showed placeholder rates for 28/90-day horizons even with only 10 days of history.

New tests (29 tests added)

  • PR-2: Sustained regime rate, 90-day cap, scenario range independence, covered horizons only
  • PR-3: Habit change 2×/0.5× detection, no trigger below threshold, first divergence day, young regime cap
  • PR-6: Warming gate (14 days, ≤2 below 50%), projection renders while warming, Unavailable renders no lifespan
  • PR-7: Staleness drop (>48h), contributing fact shown, fresh data no fact
  • PR-9: DUW decrease re-warm, identity change quarantine
  • PR-15: Degraded identity fact in every state, idempotent with staleness, ephemeral markers never render
  • PR-16: Blank key to/from quarantines, equal blanks continue

139 total tests passing, zero regressions.

Resolved in commit b99ebfe. ## Changes ### Bug fixes in 1. **Warming gate (PR-6)**: Fixed to check instead of just . The old check was too strict — it required 14 days with ≥50% coverage, but the spec only requires 14 total days with at most 2 below 50%. 2. **Habit change detection (PR-3)**: Rewrote to correctly scan backwards checking the ratio at each day position and count consecutive days going backwards. The old algorithm's inner loop checked wrong window positions. 3. **Horizon rate coverage (PR-2)**: Fixed to require the history to span the full horizon (earliest day ≤ cutoff). Previously showed placeholder rates for 28/90-day horizons even with only 10 days of history. ### New tests (29 tests added) - **PR-2**: Sustained regime rate, 90-day cap, scenario range independence, covered horizons only - **PR-3**: Habit change 2×/0.5× detection, no trigger below threshold, first divergence day, young regime cap - **PR-6**: Warming gate (14 days, ≤2 below 50%), projection renders while warming, Unavailable renders no lifespan - **PR-7**: Staleness drop (>48h), contributing fact shown, fresh data no fact - **PR-9**: DUW decrease re-warm, identity change quarantine - **PR-15**: Degraded identity fact in every state, idempotent with staleness, ephemeral markers never render - **PR-16**: Blank key to/from quarantines, equal blanks continue 139 total tests passing, zero regressions.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: xavierk/Fenris#26