Roadmap

What's next, in order, and what's deferred.

This page captures everything that has been agreed-on but not yet built. Sequencing is intentional — earlier items unlock later ones — but each item has its own readiness criteria, so "next" is not a calendar promise.

For settled decisions about what we're not building, see decisions.

Near-term — sequenced

Thin join table heartbeat.metric_cut_link(metric_id, cut_id, role) where role ∈ {explains, drilldown}. Filled from per-metric and per-cut config files. UI: cockpit tile expansion gets a "see in audit →" deep-link to the relevant cut anchor on /audit/<page>; each audit cut gets a backlink "feeds metric N". Closes the gap between cockpit (red zone surface) and audit (the breakdown that explains the red).

Why now. The cockpit and the audit pages already share a data model and a shell. The only thing missing is the navigation between them — clicking a red tile should take the operator to the chart that explains it, not leave them to scroll three pages of audit prose.

Status. Not started.

(e) /docs content driven by registries

Today this site (the page you're reading) is hand-written MDX. The plan is to read metric_registry and audit_cut_registry at build or request time and render every metric's name / how_to_read / methodology / sources / owner / verification_state, and every cut's equivalent fields, into auto-generated pages. Static MDX sits next to it for process docs (this page, lifecycle, architecture).

The GET /api/audit/registry endpoint already ships with this in mind. Single page per topic, grouped by section, with anchor links matching the cockpit / audit deep-links from (d).

Why after (d). Anchors only matter once there's something linking to them.

Status. Static MDX baseline shipped 2026-05-07; auto-generation not started.

(f) Automated alerts — email and Telegram

Connect threshold crossings on the 5-tuple to a notification channel. Verification gates this: only verification_state='verified' metrics with a non-null owner email fire alerts.

Channels (MVP). Both email and Telegram. Email is the durable paper trail; Telegram is the instant interrupt for the working day. The heartbeat.owner email column already holds the right shape for routing — both channels derive the recipient from it.

What triggers an alert.

  • value crosses alert_value (red) → immediate notification.
  • value crosses norm_value (amber) → notification if state was previously green (entry-edge only, not repeated every tick).
  • Staleness beyond the period threshold → separate "pipeline stale" notification, distinct from a metric alert.

Hysteresis, ack, snooze. Live in heartbeat.alerts (new table), not on the registry — that keeps the read contract intact.

  • Hysteresis: alert only fires if the threshold is crossed for N consecutive compute ticks (configurable per metric). Prevents single-tick spikes from waking someone at 3 AM.
  • Acknowledgement: an operator can ack an alert from the cockpit; the alert is suppressed until the value re-enters normal range and crosses the threshold again.
  • Snooze: time-boxed silence for planned outages or known spikes.

Routing. The owner email on the metric drives Telegram delivery (via the per-owner Telegram handle mapping in heartbeat.owner) and CC on email. Unowned alerts go to a default ops inbox.

Why after (e). (e) gives an alert a human-readable surface for "what would alert me, what does it mean, what is the threshold saying about commitment vs. SLA". Without that, alert fatigue is guaranteed.

Status. Not started. Verification + email-validated owner columns landed 2026-05-07 to gate this work. Alerting channel infrastructure (Telegram bot token, SMTP) is an ops task before any code is written.

(g) Automated metrics discovery

Today metrics-discovery is a skill that an agent runs on demand. The next step is a scheduled agent that proactively scans landed schemas for high-ROI metric candidates and surfaces them without a human having to think to ask.

What it does.

  • Runs weekly (or on each new source landing) against marts-db.
  • Compares heartbeat.metric_registry against available tables to find gaps — columns that carry business-signal values but have no corresponding metric.
  • Scores candidates by estimated revenue impact or loss-avoidance potential (same heuristic as the current skill).
  • Produces a dated candidates file and sends a Telegram summary to Ivan with the top 3 proposals, each with a one-line business case.
  • Ivan approves/rejects; the agent then follows the full metrics-discovery flow for approved candidates.

Difference from the current skill. The current skill is reactive (invoked by a human). This item makes discovery proactive: the agent looks without being asked, once per week.

Why after (f). Proactive discovery is only useful if new metrics can trigger alerts. Without (f), a newly discovered metric sits on the cockpit but never wakes anyone up.

Status. Not started.

(h) Starred metrics and watchlists

A thin personalization layer on top of the cockpit:

  • Any operator can star individual metrics; starred metrics always appear at the top of the cockpit, regardless of their domain group or status.
  • Watchlists — named groups of metrics (e.g. "week-end check", "compliance", "CEO morning view") that can be bookmarked and shared. A watchlist URL opens the cockpit pre-filtered to those tiles.
  • Watchlist state lives in heartbeat.watchlist (new table, per user or shared), not in the registry — operator preference is not metric state.

Why after (g). Watchlists are most useful once the registry is large (50+ metrics). With 31 metrics today the cockpit is still readable in full. The value of pinning grows with registry size.

Status. Not started.

Sequencing rationale

(d) lights up navigation between cockpit and audit, which makes (e)'s drill-down anchors useful; (e) gives (f) a human-readable surface for "what would alert me, what does it mean"; (f) is the payoff that justified building verification + owners in the first place. (g) and (h) compound on top — proactive discovery only makes sense once new metrics can alert, and watchlists only earn their keep at scale.

Always-on work

Two streams that run in parallel with the sequenced items:

  • Grow the registry via metrics-discovery against real data. The 31 metrics live today are a starting set, not a finished one.
  • Add marts-db indexes and audit replace-strategy tables as new sources and metrics land. See the Data quality and performance section in architecture for the rule set.

Later

  • MCP server over the registry / history (agent-queryable Heartbeat). Same data, different surface — agent / chat / Telegram instead of a screen. Comes after alerting; uses the same metric_registry + metric_history as single source of truth.
  • OKR overlay. Once Heartbeat reliably produces metrics, those metrics become the input for departmental OKRs. Heartbeat is the substrate, not the OKR system itself.
  • Per-team views. Filtered cockpit by metric ownership / domain.
  • EMT (stablecoin) metrics. Once the EMT product line generates data Heartbeat can land.
  • SaaS sources beyond the MVP-15. Driven by metric demand, not source completeness.

CEO data-access skill (deferred)

A separate, larger initiative: a Claude Code skill that gives the CEO natural-language access to live business data and lets them contribute new metrics through the same pipeline Ivan uses, with PII masking and single-user access control as hard guarantees.

JTBD specs live under specs/ in the repo (01–09). The SLC minimum (top-row in the spec story map) is **single-user access + query-time masking + a working NL question

  • a captured metric idea that opens a PR** — none of which is built today.

This is deferred behind (d)/(e)/(f) — it depends on a verified metric registry and an alerting layer to be useful, and it adds a security perimeter (single-user, PII-free replica) that is its own chunk of work.