Feature Discovery Nudges
The gentle, roughly-daily inbox card that pitches one feature you have never used — how a nudge opens in the main panel, how the "Start using it" button works, how nudges rotate and auto-stop, and how to see what they have achieved.
What it is
A gentle, roughly-daily inbox card that pitches one Omniscio feature you have never used — "Here's a feature you're missing, and here's why it'd help." Selecting the card opens its detail in the main panel: the feature's name, a short hand-written pitch, a clean animation, and two buttons: "Start using it" turns the feature on (if it's off) and takes you straight to it, while "Maybe later" dismisses the card for good — the same as the X. Nudges rotate through the features you don't use, release at most one per ~24 hours, auto-stop once you've seen them all, and each card is dismissible and snoozeable like any other inbox row.
Some nudges open a full landing page instead of the short pitch card — see below.
It is off by default — opt-in: the registry entry feature-discovery-nudge carries
status: 'in-development', so nobody sees a nudge until they turn on Feature Discovery
Nudges in Settings → Lab (which flips featureDiscoveryNudgeEnabled;
AMC_SHOW_FEATURE_DISCOVERY_NUDGE=1 is the dev-only reveal). Once enabled, the built-in
bounds are the user controls: at most one card per ~24 hours, never the same card twice,
features you already use are skipped, every card is dismissible and snoozeable, and the
rotation auto-stops once every card has been seen.
Where to find it
Landing pages — the richer sell-and-teach detail
Catalog entries can ship a landing page: opening the card shows a hero tagline, a self-running animated demonstration of the feature in a miniature Omniscio, two-to-four benefit cards (why you'd want it), numbered "How to use it" steps with keyboard-shortcut chips, and a tailored call-to-action. Entries without a landing page keep the classic short pitch card. If your system has "reduce motion" turned on, the animation is replaced by a calm three-panel storyboard that teaches the same thing with nothing moving.
Snooze is the first landing page. Its demonstration loops a noisy miniature inbox:
press H (or right-click → Snooze), type a time in plain English ("tomorrow 9am"), watch
the card glide away — and return exactly on time. Its call-to-action is "Try it on this
card": instead of navigating anywhere, it opens the real snooze palette on the nudge
card itself. Pick a time and the card vanishes from your inbox, then comes back when you
said — the feature demonstrates itself on a zero-risk target. (Trying it does not dismiss
the nudge; the card's return completes the lesson, and you can dismiss it then.)
Under the hood the landing content lives in the same hand-authored catalog (src/shared/feature-nudges/catalog.ts); each demo is a lazy-loaded component keyed by the entry (FeatureNudgeLandingContent.tsx, SnoozeDemo.tsx).
Fixed alongside this feature: snoozing a feature-nudge card from the right-click menu (or
H) used to be a silent no-op — the snooze was recorded under the wrong key, so the card never hid. Nudge cards now snooze like every other inbox row, and the detail pane closes itself once its card is snoozed.
Inline on/off toggle nudges
Some nudges don't send you anywhere — they put a live on/off switch right in the card.
Instead of "Start using it", the card shows the feature's current state as a real toggle you
can flip either way, plus a "Done" button that just closes it (your choice is already
saved). The first one is the desktop icon badge: your app icon (Windows taskbar / macOS
dock) normally shows a little count of sessions that need you — this nudge lets you keep it
or turn it off without leaving the card. The same switch also lives in Settings →
Notifications ("App icon attention count"), and flipping it in either place updates the badge
immediately. Under the hood this is the catalog's toggleSettingKey start-action bound to a
boolean setting (read !== false so an existing install with no saved value defaults ON); the
nudge auto-stops once you've engaged the control.
How it behaves
How it works
- What it knows you've used comes from the existing on-master
feature_eventstelemetry — a curated feature with zero matching events is "never used" and eligible to pitch. No new tracking; nothing leaves the device for this decision. - What it can pitch is a hand-authored catalog (src/shared/feature-nudges/catalog.ts) — a curated set of notable features (including Snooze and a "Check in on your Stats & Records" card), each with a one-line pitch and a one-click start action (enable a toggle, navigate to the feature, flip a live on/off switch right in the card, or — for try-it-live entries like snooze — act right on the card). The catalog is the single source of nudge wording and landing-page content.
- The daily scanner (feature-nudge-scanner-service.ts) runs hourly: if the feature is enabled and the last nudge was ≥24h ago, it picks the first catalog entry you haven't used and haven't already been pitched, inserts a row in its own
feature_nudge_releasestable, and pushes it to the inbox. When nothing is left it simply stops. - The inbox card is a standalone inbox source (its own
feature_nudge_releasestable — it does NOT use the shared alert/Drip table). It groups under a "DISCOVER" header. Dismissing archives it; snoozing rides the universal inbox-snooze table; a dismissed feature is never pitched again. - The in-pane detail (FeatureNudgeDetailPane.tsx) renders in the main panel via the generic
activeInboxDetailroute (like recipe / pr-inbox rows), so the inbox cursor can land on it. "Start using it" flips the feature's setting on (if gated), marks the nudge accepted, and navigates you to the feature; if turning it on fails it shows an error instead of leaving you stranded. "Maybe later" archives the card (same as the X) AND advances the inbox to the next item — it routes through the one shared inbox-dismiss chokepoint (dismissActiveInboxItem) that every reading pane uses, which captures the visually-next card and moves you to it, exactly like archiving an SMS or a weekly summary. (It does NOT merely deselect: a plain deselect would leave nothing selected and the inbox would re-open the newest card, bouncing the panel straight back open on this same nudge.)
Seeing whether nudges are working — the Nudges tab
Once Feature Discovery Nudges is on, a Nudges tab appears in Stats (it stays hidden otherwise, so it never clutters Stats for people who don't use nudges). Per nudge you've been shown, it puts how much you used the pitched feature before the nudge next to how much after it — side by side, with the difference — plus where the nudge landed (shown → accepted / dismissed / still-pending) and a "still filling" marker while the after window hasn't fully elapsed.
The "before" figure is ~0 by design: a nudge only ever fires for a feature you've never used, so the honest signal is the after adoption and the accept/dismiss funnel — a non-zero "before" is a red flag that a nudge was mis-targeted, not a bug. The window is a fixed 14 days on either side of when the nudge was shown, anchored on the show date (so every nudge gets a row, not just accepted ones).
This reads existing data — the feature_nudge_releases rows plus the same feature_events
telemetry the nudge system already uses — and adds no new tracking
(queries-nudge-effectiveness.ts). The same
per-nudge numbers, scrubbed to anonymous counts (no timestamps, no personal data), also ride
the daily fleet digest so the product team can see fleet-wide which nudges actually move people
to adopt a feature.
Seeing what WILL happen — the preview
The Nudges tab above looks backwards at nudges already shown. The preview is the look forwards, and it exists because nudge delivery is otherwise almost unobservable: at most one card every 24 hours, chosen in catalog order, and off by default — so "is this actually working?" could only be answered by waiting a day to see whether anything turned up.
GET /feature-nudge/preview (bearer read, like GET /feature-nudge)
It answers three questions at once:
- Would anything land at all right now?
canLand, plusblockedBynaming the specific gate when the answer is no —flag-off(the feature is switched off, the usual answer),paused(the scanner service is paused), orcadence(a card already went out; the next is not due yet).explanationsays the same thing in plain English. - Which card is next, and when?
next, plus the full projectedschedule— every remaining card, one per 24 hours, in the order they will actually fire. - Why is a card NOT in the list?
skippedgives a reason per entry:already-pitched(spent — a nudge is never re-pitched, even after you archive it),already-used(you already use that feature, so there is nothing to discover), orineligible.
Two honesty details worth knowing. Each schedule entry is a window (earliestAt to
noLaterThan), not a single time — the scanner wakes hourly, so a card fires at the first wake-up
at or after its due mark. And the schedule assumes the app keeps running: the scanner only
advances while Omniscio is open, so a machine left closed for two days shifts everything later.
The preview reports the same rotation the scanner itself uses (queue.ts) rather than keeping its own copy of the rules, so it cannot drift into describing a schedule that never happens — a guard test fails the build if either side stops using it. It is also read-only: previewing never creates a card, never notifies you, and never marks a feature as shown.
Because the rotation is computed independently of the gates, the preview still shows the full schedule while nudges are switched off — which is the point: you can see exactly what you would get before deciding to turn them on.
Relationship to the Workflow Coach
This is separate from the weekly AI Workflow Coach "feature-discovery" suggestions. The Workflow Coach is weekly, LLM-generated (costs money, needs an API key) and lives in the coach surface. Feature Discovery Nudges is the daily, deterministic, hand-curated (free) surface with a richer popup and one-click enable. They're complementary.
For agents
Full invariants
See the contract: .claude/memory/contracts/feature-nudge-contract.md.
Related
Feature Suite Recommendations groups the same features into themed suites and is what the proactive recommenders consult; Empty-inbox discovery tip is the other one-time, teach-by-doing card Omniscio puts in the Inbox.
Last verified 2026-09-23