Development journal (formerly the thinking heatmap)¶
Shown in Practice
Since #645 the journal is drawn as the Ideas developed strip of Health › Practice — the last 12 weeks, a cell per day. The separate Momentum mode and its 52-week grid (the old Thinking heatmap) were merged into Practice. Show practice (show-thinking-heatmap, id kept) opens it.
The development journal counts ideas developed per day — not a "notes created" volume chart. It rewards developing ideas: advancing a note's state, adding a source, adding a connection.
What counts as "development"¶
The journal records an event when — comparing a note before and after an edit — one of these happens (creation itself does not count; momentum is about developing existing ideas):
| Event | Fires when |
|---|---|
| State advanced | the note's lifecycle state factor rose (e.g. fleeting → permanent) |
| Source added | the note gained its first source |
| Connection added | the note's outgoing links grew |
Events are detected at the knowledge-index's upsert choke point by diffing the note's model signals; the initial vault scan is bypassed so first-load never floods the journal.
The journal (local & private)¶
The data source is a capped, per-day count map stored in the plugin's data.json: { "2026-08-12": 3, … } — day → count only. It records no note names, no content, and makes no network request. It is pruned to the last ~year, and persisted with a debounced save so a burst of edits collapses to one write.
It is on by default (it only records benign aggregate counts); turn it off any time under Settings → Thinking → What ZettelFlow remembers (Record development events). See Capabilities & privacy.
Architecture¶
detectDevelopmentEvents(before, after) (pure, Obsidian-free, unit-tested) → event types
buildHeatmapGrid(counts, now, weeks) (pure, unit-tested) → 52×7 cells + levels
recordDay / pruneCounts (pure, unit-tested) → bounded tally update
DevelopmentJournal (runtime singleton, host injected at load)
fed at KnowledgeIndex.upsert (best-effort, wrapped so it can never break indexing)
reads/writes settings.journal.counts, debounced saveSettings
PracticeRenderer (Health › Practice, #645) — the 12-week strip
intensity is a --l0…--l4 CSS class (theme-aware), each cell aria-labelled with a tooltip
What this is not¶
The heatmap counts development events — notes you connected, sourced, advanced. It is a history of what you did.
It is deliberately not the same thing as the Cultivate/Home streak, which since #339 counts days you exercised judgement (see cognitive agency). The streak is the momentum signal, so it had to stop rewarding mere activity; the heatmap is a record, and rewriting it would have discarded a year of real data to add no insight. Two questions, two answers, both stated plainly.