feat(#73): publish trustworthy first usage history

- Schema migration 1-2: add segment_id to samples, unattributed bytes to day_aggregates

- Collector now derives hour observations and day aggregates from sample pairs

- Cross-hour deltas tracked as unattributed (no proportional allocation)

- Display states: 0 samples -> awaiting first, 1 sample -> awaiting another

- Monitoring period ensured open on each collection run

- Derivation failures preserve prior history

Closes #73
This commit is contained in:
xavierk
2026-09-14 03:19:08 +05:30
parent f406285a0f
commit d790ff84c5
7 changed files with 1074 additions and 26 deletions
+24 -7
View File
@@ -447,15 +447,32 @@ class FenrisTuiApp(App):
def _render_all_regions(self, conn: sqlite3.Connection) -> None:
"""Render all four regions from live store data."""
# --- Headline band (§7.2) ---
# --- Sample count for single-sample state (issue #73 AC3) ---
try:
proj = compute_projection(conn, self._clock_now)
headline = self._format_headline(proj)
confidence = self._format_confidence(proj)
scenario = self._format_scenario(proj)
self._render_headline(headline + "\n" + confidence + "\n" + scenario)
cursor = conn.execute("SELECT COUNT(*) FROM samples")
sample_count = cursor.fetchone()[0]
cursor = conn.execute("SELECT COUNT(*) FROM day_aggregates")
day_count = cursor.fetchone()[0]
except Exception:
self._render_headline("[bold]No projection available[/bold]")
sample_count = 0
day_count = 0
# --- Headline band (§7.2) ---
if sample_count <= 1 and day_count == 0:
# Single sample: awaiting another sample
self._render_headline(
"[bold]Awaiting another sample[/bold]\n\n"
"Collecting usage data — the first projection requires at least two samples."
)
else:
try:
proj = compute_projection(conn, self._clock_now)
headline = self._format_headline(proj)
confidence = self._format_confidence(proj)
scenario = self._format_scenario(proj)
self._render_headline(headline + "\n" + confidence + "\n" + scenario)
except Exception:
self._render_headline("[bold]No projection available[/bold]")
# --- Usage-history pane (§7.2 left) ---
history = _query_usage_history(conn)