← all posts

12 june 2026

Today was mostly about tightening up the “last mile” around my personal 2brn project: making the UI theming story real (and testable), and putting some enforceable process around PR-based development so I stop relying on willpower.

What I learned

  • Deriving duration from sampled activity data needs explicit semantics. I revisited the tradeoffs between “gap-to-next” derived spans, capping long gaps, persisting an ended_at, and session-grouping. The big takeaway: keep raw samples immutable, and make sessionization a policy-driven derivation so you can change heuristics without corrupting history.
  • GitHub workflow discipline is easiest with forcing functions. For solo/hobby repos, commit-heavy graphs are normal—but if I want PRs/issues to be first-class, branch protection + lightweight local hooks are the only reliable way to enforce it.
  • UI snapshot tests fail in surprisingly “silent” ways. My screenshot gallery tooling was rendering ErrorBoundaries because a stub route matched too broadly (e.g. /settings catching /settings/exclusions). Ordering and specificity in mocks matter as much as production routing.

What I built

  • Sessionization + cleanup plumbing (backend):
  • Implemented a “sessionizer” layer to convert point-in-time samples into derived time blocks.
  • Added maintenance routines to address capture-loop artifacts (e.g., orphaned screenshot files) and wired sweep/cleanup into periodic purge work.
  • Hardened test coverage, including timezone-independent verification passes.

  • Classification reliability improvements:

  • Added classification backfill behavior to reduce “unclassified” gaps caused by sparse OCR, failed inference, or queue drops.
  • Implemented a metadata-only classification fallback for cases where OCR is too thin but app/window context is still useful.

  • UI theming infrastructure (modern ↔ minimal):

  • Introduced a skin/theme architecture (ThemeContext + registry approach), defaulting to modern with persistence (local storage).
  • Landed the minimal “app chrome” and then iteratively ported screens in batches (home/chat/journal/blog → timeline/insights → plugins/settings/instructions), verifying both themes and fixing screenshot capture edge cases.

  • Repo workflow enforcement:

  • Added guards to prevent committing directly to main and configured GitHub rulesets/branch protections so the “issue → branch → PR → review → merge” flow is the default.

Experimenting with

  • Evaluation harness roadmap planning: sketched an expansion path for an evaluation tool (production hardening, CI/CD reporting, observability, dataset management) with the idea of executing via PR-sized slices.
  • Local provider wiring: poked at running the app against a local OpenAI-compatible endpoint (for chat + embeddings) to keep the stack usable offline.