Feedback channel opt-out (silence outbound email per install)
Three switches that silence the email leg of Omniscio's outbound reports for your install alone — what each one governs, what it deliberately does not change, and why the local on-disk copy of a report always survives.
What it is
Three user-level toggles at Settings → Diagnostics → Outbound email that let you silence the email leg of Omniscio's outbound reports for just your install. They do not change anyone else's install. All are on by default so an upgrade or a fresh install behaves identically to today — every user-clicked bug / feedback / QW-miss / overlay report still emails the team, and every crash + weekly digest still goes out by email — until you flip yours off.
The on-disk fallback (<userData>/bug-reports/...json) is untouched by these toggles — it is local storage, not egress, so a deliberate opt-out never loses your report. The bug/feedback toggle gates both remote legs — Resend and Firestore (see the note below). The two telemetry-email toggles still govern their own email legs only.
Changed by the privacy audit. This note used to read "email off does not mean nothing is sent": in-app bug/feedback delivery fanned out to Resend (email) AND Firestore, and
bugReportEmailEnabledgated the Resend leg only — so an opted-out report still reached the team via Firestore, and Firestore's only gate (bugReportTransport) was absent from every settings schema, so nothing could flip it. That was a consent control that did not withdraw consent. NowbugReportEmailEnabledgates both legs,bugReportTransportis reachable throughupdateSettingsSchema(and still chooses BETWEEN email and Firestore for a user who IS sending), and an opted-out report is kept on the local disk fallback instead.
The three toggles are:
| Toggle | Setting key | Gates |
|---|---|---|
| Send bug reports & feedback | bugReportEmailEnabled |
BOTH remote legs of in-app bug/feedback delivery — Resend (email) and Firestore — gated in one place, deliverReport (report-delivery.ts): the feedback path (toolbar bug-icon clicks + the CLI POST /feedback route) and the bundle path (overlay "Report bad overlay" + QW-miss right-click "Should have rendered as QW" + the CLI POST /feedback/bug-report route) now run the SAME chain. Off ⇒ local disk fallback only. |
| Email diagnostics to the team (master) | telemetryEmailEnabled |
The entirety of sendTelemetryEmail() — [MC Crash] alerts plus the once-a-week [MC Digest] rollup. Off silences BOTH. |
| Email crash reports (crash sub-gate) | crashAlertEmailEnabled |
ONLY the [MC Crash] email leg inside reportCrash. Off drops crash mail while the weekly digest (still gated by the master) keeps going. A crash email sends iff both telemetryEmailEnabled !== false and crashAlertEmailEnabled !== false. |
They are split so you can tune the noise: crash + digest emails are auto-fired by the runtime (noisier during a crash loop) while user-clicked bug reports are deliberate and signal-rich. The crash sub-gate exists so you can drop crash mail while keeping the weekly digest — the exact case for a user whose crashes already auto-triage inside Omniscio (via the Sentry intake path), so the per-crash email is redundant. Turning off crash mail never affects Sentry or that triage — the crash still gets investigated; you just stop getting the email.
Where to find it
Where they live in Settings
Open Settings → Diagnostics → Health and the rows appear grouped under an "Outbound email" heading. Each is a toggle with helper text spelling out what it gates and what survives when you turn it off:
Send bug reports & feedback — When on, clicking the bug-report icon, sending feedback, or reporting a missed question widget sends the report to the Omniscio team by email and to the report database. Off sends nothing: reports stay on this computer and go out when you turn this back on.
Email diagnostics to the team — Master switch for Omniscio's diagnostic emails from this install. On = the weekly usage digest, plus each crash unless you turn off "Email crash reports" below. Off silences both; the on-disk crash log, Sentry, and Omniscio triage keep working.
Email crash reports — When diagnostics email is on, also email the team on each crash. Turn OFF to email only the weekly digest — crashes still auto-triage inside Omniscio (via Sentry), and the on-disk crash log continues.
They are also reachable from Settings search (Ctrl+K). Useful keywords include "resend", "feedback email", "crash email", "weekly digest email", "telemetry email", "email crashes", "stop crash emails", and "outbound email".
How it behaves
What happens when you flip a toggle off
Both toggles share the same gating idiom: the runtime reads the field as getSettings().<field> !== false (or === false for the early-return path). Only an explicit false changes behavior — undefined and true both keep the email path firing.
Flipping bugReportEmailEnabled off
- Both remote legs are skipped at once — Resend and Firestore.
deliverReport(report-delivery.ts) checksplan.optedOutfirst and returns immediately when it's true, so no leg is even attempted: nothing lands in either the delivered or the failed set, and a deliberate opt-out is never counted as a delivery failure. - The report is not lost — it goes to the on-disk fallback at
<userData>/bug-reports/...json. Disk is local storage, not egress, so the opt-out does not forbid it. bugReportTransportstill chooses BETWEEN email and Firestore for a user who IS sending, and is now reachable through the settings schema (it never was before).
What a report carries, and what switching it off therefore withholds (2026-09-29)
Every in-app bug / feedback report also carries a changed-from-default export of your settings: the settings you have moved away from their shipped defaults — including the ones that have no row on any Settings screen — plus a one-line "is it set?" marker for each credential you have configured. bugReportEmailEnabled governs it too, so switching reports off withholds this along with everything else, and it rides the same cloud-intake consent purpose.
- No credential VALUE is ever included. A configured key reads as
<set>; an unconfigured one is simply absent from the export. The value itself never leaves the machine. - Only what you changed. A setting left at its default is not listed, so the export stays readable instead of shipping ~2,000 no-op rows. On a fresh install with nothing configured it is empty, and the section is not rendered at all.
- You can see it before you send. The report dialog shows how many settings are attached, and the feedback consent names the settings among the categories it covers.
- It is bounded, so a heavy configuration can never be the reason a report fails to send; the operator email previews long values and the full value rides in the stored copy of the report.
- Two reports are filed with no dialog at all — a project folder that fails to open, and a snooze whose time cannot be read. Those carry the settings too, under the same consent purpose and the same off switch.
Flipping telemetryEmailEnabled off (the master — silences BOTH crash + digest)
sendTelemetryEmail()returns immediately on its first statement — before it relays anything to the bug-report Cloud Function, so no send is even attempted. (The app no longer holds a Resend client at all; the relay function does the actual send — see "Recipient routing" below.) This gates BOTH the crash email and the weekly digest.- A single diagnostic line lands in the main log:
[Telemetry] Suppressed (telemetryEmailEnabled=false): <subject>. - The on-disk crash log and Sentry-side delivery keep firing — crash forensics are not gated by this toggle.
Flipping crashAlertEmailEnabled off (drop crash mail, KEEP the digest)
reportCrash()returns early — right after thegetCrashAutoSendEnabled()gate and before the throttle — so the crash EMAIL is skipped and never even consumes a daily email slot. Only the crash email; nothing else.reportFleetCrashhas already fired (it runs first, before the gate) and the SentrycaptureExceptionlives in the crash handlers (notreportCrash), so the crash still reaches Sentry → Omniscio triage. Turning off crash mail never stops crashes from being investigated.- The weekly digest never calls
reportCrash, so it is completely unaffected — this is the whole point of the sub-gate. - Because the crash path still passes through
sendTelemetryEmail(which keeps its owntelemetryEmailEnabledcheck), a legacytelemetryEmailEnabled=falseopt-out still suppresses crash mail — no migration was needed to preserve it.
Migration semantics — none required
No one-shot migration writes anything to existing users' config.json from this code path. The defensive read handles all four cases correctly:
| Scenario | Disk state | getSettings() reads |
Result |
|---|---|---|---|
| Fresh install | no config.json |
DEFAULT_SETTINGS.bugReportEmailEnabled = true |
true !== false → enabled ✅ |
| Existing install pre-upgrade | config.json exists, no key |
undefined |
undefined !== false → enabled ✅ |
| User flips toggle off | key is false |
false |
false !== false → disabled ✅ |
| User flips back on | key is true |
true |
true !== false → enabled ✅ |
There is no way to opt out for everyone — no env var, no master kill switch, no migration that hand-edits anyone else's config.json. The toggle is the only path to false, and it only ever writes to the current install's own config.
How to silence your install
- Open Settings → Diagnostics → Health.
- Toggle Email bug reports & feedback off if you don't want the team emailed on your bug-icon / overlay-report / QW-miss /
/feedbackclicks. - Toggle Email diagnostics to the team off if you don't want ANY diagnostic emails — crashes AND the weekly digest — from your install.
- Or, to stop ONLY crash emails while keeping the weekly digest, leave the master on and toggle Email crash reports off — crashes still auto-triage inside Omniscio via Sentry.
That's it. Flip any back on the same way. No restart required — the next report after each flip respects the new state.
What the toggles do NOT change
- The Sentry upload path on crashes. Crash forensics are a separate channel.
- The on-disk
<userData>/bug-reports/...jsonfallback. It fires when every ENABLED sink fails — and, whenever the user has switched sending off, which is how an opted-out report is preserved locally rather than lost. - Recipient routing. These toggles never touch where mail goes — only whether it's sent. Recipients are decided server-side by the bug-report Cloud Function, not by the app: the app only tags each send with a
leg(telemetryfor crash/digest → the owner's Gmail only;feedbackfor bug reports → the owner's Gmail and the AgentMail intake inbox). The app never specifies an address, so there is no recipient to change here. - The relay's credentials, or any other install's behavior. The Resend API key now lives server-side in the bug-report Cloud Function, not in the app — a toggle only decides whether this install relays a send at all. Every other install (the CEO's, Steve's, every tester's) is unaffected.
Related
- cli-feedback.md —
POST /feedbackroute covered bybugReportEmailEnabled. - plain-speak-feedback.md — overlay "Report bad overlay" path covered by
bugReportEmailEnabled. - qw-miss-reporting.md — "Should have rendered as QW" path covered by
bugReportEmailEnabled. - logs-and-debugging.md — automatic crash reporting (separate channel; not gated by these toggles).
Last verified 2026-09-29