Flipping a row here does not turn a feature on; PostHog / bundle identity /
runtime_env remain the live levers. This file is a catalog of which lever
owns each gate, not the switch itself.
Inventory below was measured 2026-09-04 against origin/main 7704e0b plus
live PostHog project 302298, then re-checked on this tree
(3d72f77aea). Prefer the worktree if a key has moved.
This is not a second classification of deployment wiring. Secret vs config
vs public_build still lives only in
config/deployment-setting-classification.json
and deployment-setting-classification.mdx.
JIT admission (allowlist, jit-processing-v1, kill, decoy names) is specified
in jit_rollout_authority.mdx; this registry
points at that contract and does not replace it.
Omi Beta (com.omi.computer-macos.beta) vs stable (com.omi.computer-macos).
Use this for dogfood features whose backend half is only on the dev API:
Beta is the only production-family identity that talks to that API
(DesktopBackendEnvironment.shouldForceDevelopmentServingEndpoints). Stable
stays dark until an explicit PostHog enable flag is true. Named/dev bundles
are a third identity (non-production) and usually take a local OMI_FORCE_*
override instead of PostHog.
Per-user, percent, or remote kill without a new build. The SDK
(PostHogManager.isFeatureEnabled) is fail-closed while uninitialized: a
missing row is false. That is why a Beta-by-default feature needs an
inverted kill (*_kill true means off) so "flag missing" leaves Beta on,
and why a dark production launch needs a positive enable flag so "flag
missing" stays off.
Whole environment or Cloud Run job, declared in
backend/deploy/runtime_env/{_base,dev.overlay,prod.overlay}.yaml. Use this
for fleet-wide backend switches. Do not put those in PostHog.
- If Swift or Python names a PostHog key, the PostHog row must exist (even inactive / 0%). Missing kill rows cannot disarm a bad Beta.
- If a PostHog row exists and no code reads it for enablement, delete it or
mark it
unused. - Kill switches for Beta-by-default features must exist in PostHog (inactive) so a bad Beta can be disarmed without a build.
- Do not put fleet-wide backend switches in PostHog.
- Do not put Beta-vs-stable enablement in PostHog person properties.
update_channelwas measured unreliable (person-side channel null orstablefor most Beta installs). Bundle identity is the authority.
BetaDogfoodRollout is the shared client shape: non-production requires an
explicit OMI_FORCE_*=1 (except where noted), Beta is on unless the kill is
true, stable is on only when the enable flag is true.
Columns: PH row is live PostHog 302298 as of 2026-09-04 (yes / no /
unused = row exists but code does not read it for gating). Fail is what
happens when the live lever is missing or unreachable.
| Key | Name | Authority | Fail | Who it hits today | PH row | runtime_env | Code |
|---|---|---|---|---|---|---|---|
desktop-onboarding-rerun |
Onboarding rerun | posthog | closed (off) | 100% of clients; each install evaluates payload locally | yes (100%, payload generation=1, min_account_age_days=7, active_questions_30d=8) |
— | OnboardingRerunPolicy in desktop/macos/Desktop/Sources/Onboarding/OnboardingRerunPolicy.swift |
context_buckets |
Context buckets enable | bundle | n/a for PH; stable off, Beta on unless kill | Beta Mac; stable stays on fallback assistants | unused (active; cohort 484445 ~307 or person update_channel=beta. Client does not read this for enablement) |
— | ContextBucketsFeature.flagName / isEnabled in desktop/macos/Desktop/Sources/ProactiveAssistants/Core/ContextBucketsFeature.swift |
context_buckets_kill |
Context buckets kill | posthog | Beta fail-open (inverted) | nobody (inactive) | yes (inactive) | — | ContextBucketsFeature.killSwitchFlagName |
context_buckets_destination_kill |
Destination routing kill | posthog | Beta fail-open (inverted) | nobody (row missing ⇒ hop stays on for Beta) | no | — | ContextBucketsFeature.destinationKillSwitchFlagName / isDestinationRoutingEnabled |
context_buckets_retrieval_kill |
Retrieval hop kill | posthog | Beta fail-open (inverted) | nobody (row missing) | no | — | ContextBucketsFeature.retrievalKillSwitchFlagName / isRetrievalHopEnabled |
context_buckets_departure_eval_kill |
Departure evaluation kill | posthog | Beta fail-open (inverted) | nobody (row missing) | no | — | ContextBucketsFeature.departureEvaluationKillSwitchFlagName / isDepartureEvaluationEnabled |
context_buckets_dwell_refresh_kill |
Dwell refresh kill | posthog | Beta fail-open (inverted) | nobody (row missing) | no | — | ContextBucketsFeature.dwellRefreshKillSwitchFlagName / isDwellRefreshEnabled |
context_buckets_fact_write_policy_kill |
Fact write-policy kill | posthog | Beta fail-open (inverted) | nobody (row missing) | no | — | ContextBucketsFeature.factWritePolicyKillSwitchFlagName / isFactWritePolicyEnabled |
| (none) | Workstream pooling | bundle (hardcoded) | n/a | non-prod only (OMI_FORCE_BUCKET_WORKSTREAMS=0 off). Production/Beta always false. No remote flag on purpose |
no | — | ContextBucketsFeature.isWorkstreamPoolingEnabled |
| (none) | Proactive candidates | bundle (hardcoded) | n/a | non-prod only (OMI_FORCE_BUCKET_CANDIDATES=0 off). Production/Beta always false. No remote flag on purpose |
no | — | ContextBucketsFeature.isProactiveCandidatesEnabled |
system_calendar_meeting_context |
System calendar meeting context | hybrid | Beta fail-open / stable fail-closed | Beta Mac (dev API has calendar read on). Stable off (flag missing). Kill row missing | no | pairs with CONVERSATION_CALENDAR_CONTEXT_READ_ENABLED |
SystemCalendarMeetingContextFeature in desktop/macos/Desktop/Sources/CalendarMeetingContext/SystemCalendarMeetingContextFeature.swift |
system_calendar_meeting_context_kill |
System calendar kill | posthog | Beta fail-open (inverted) | nobody (row missing; cannot remotely disarm Beta) | no | — | SystemCalendarMeetingContextFeature.killSwitchFlagName |
on_device_meeting_identity |
On-device meeting identity | hybrid | Beta fail-open / stable fail-closed | Beta Mac. Stable off. Kill row missing | no | pairs with CONVERSATION_OCR_CONTEXT_ENABLED |
OnDeviceMeetingIdentityFeature in the same file |
on_device_meeting_identity_kill |
On-device identity kill | posthog | Beta fail-open (inverted) | nobody (row missing) | no | — | OnDeviceMeetingIdentityFeature.killSwitchFlagName |
desktop_interject |
Interject (voice reply on floating cards) | hybrid | Beta fail-open / stable fail-closed | Beta Mac. Stable off. Kill row missing | no | — | InterjectFeature in desktop/macos/Desktop/Sources/FloatingControlBar/Interject/InterjectFeature.swift |
desktop_interject_kill |
Interject kill | posthog | Beta fail-open (inverted) | nobody (row missing) | no | — | InterjectFeature.killSwitchFlagName |
negative_feedback_remediation |
Thumbs-down remediation | hybrid | Beta fail-open / stable fail-closed | Beta Mac. Stable off. Kill row missing | no | — | NegativeFeedbackRemediationFeature in desktop/macos/Desktop/Sources/Chat/NegativeFeedbackRemediationFeature.swift |
negative_feedback_remediation_kill |
Thumbs-down remediation kill | posthog | Beta fail-open (inverted) | nobody (row missing) | no | — | NegativeFeedbackRemediationFeature.killSwitchFlagName |
screen_activity_lossless_sync |
Lossless screen-activity sync | hybrid | Beta fail-open / stable fail-closed. Non-prod defaults on (OMI_FORCE_LOSSLESS_SCREEN_SYNC=0 off) |
Beta Mac + named/dev. Stable on the legacy cursor until the enable flag is true | no | — | ScreenActivityLosslessSyncFeature in desktop/macos/Desktop/Sources/ScreenActivitySyncService.swift |
screen_activity_lossless_sync_kill |
Lossless sync kill | posthog | Beta fail-open (inverted) | nobody (row missing) | no | — | ScreenActivityLosslessSyncFeature.killSwitchFlagName |
desktop_persistent_capture_stream |
Persistent window-capture stream | posthog | fail-closed for all production bundles including Beta. Missing ⇒ off for shipped users. Non-prod defaults on (OMI_PERSISTENT_CAPTURE_STREAM=0 off) |
named/dev only | no | — | ScreenCaptureStreamFeature in desktop/macos/Desktop/Sources/ScreenCaptureStreamFeature.swift |
desktop-rating-prompt-disabled |
Rating-prompt kill | posthog | inverted: missing ⇒ prompt stays on | nobody (row missing; prompt still shows) | no | — | RatingPromptPolicy.killSwitchFlag in desktop/macos/Desktop/Sources/RatingPrompt.swift |
jit-processing-v1 |
JIT processing admission | hybrid | non-allowlist fail-closed; allowlist still admits if PostHog is down | dual admission: PostHog 100% of cohort 529814 (2 UIDs) and hardcoded JIT_ADMISSION_ALLOWLIST (same 2 UIDs) |
yes | — | JIT_PROCESSING_FLAG_KEY / JIT_ADMISSION_ALLOWLIST / resolve_jit_rollout_sync in backend/utils/jit_rollout.py. See jit_rollout_authority.mdx |
jit-processing-kill-switch-v1 |
JIT kill | posthog | unknown/absent kill never blocks by itself | nobody at 0% rollout; only lever that can revoke the allowlist | yes (active, 0%) | — | JIT_KILL_SWITCH_FLAG_KEY |
daily-memory-sweep-v1 |
Daily memory sweep (decoy) | posthog | n/a — not admission | nobody. Prod job is env-off. Sweep cohort flag is not permits_work |
yes (active, 0%) | MEMORY_DAILY_MEMORY_SWEEP_* |
JIT_DAILY_SWEEP_FLAG_KEY (must not be read for admission). Job: daily_memory_sweep_authority_from_environment |
CONVERSATION_NOTES_V2_ENABLED |
Conversation notes v2 | env | closed (off) unless set | prod + dev (true since 2026-09-01). _base default is false |
no | CONVERSATION_NOTES_V2_ENABLED |
_flag_enabled / summary_pipeline_mode in backend/utils/conversations/process_conversation.py |
CONVERSATION_CALENDAR_CONTEXT_READ_ENABLED |
Calendar context read | env | closed (off) | false prod, true dev (Beta Mac talks to dev) | no | CONVERSATION_CALENDAR_CONTEXT_READ_ENABLED |
_calendar_context_read_enabled in process_conversation.py |
CONVERSATION_OCR_CONTEXT_ENABLED |
OCR meeting context | env | closed (off) | false prod, true dev | no | CONVERSATION_OCR_CONTEXT_ENABLED |
_ocr_meeting_context_enabled in process_conversation.py |
CONVERSATION_STORED_MEETING_CONTEXT_ENABLED |
Stored meeting lookup | env | fail-open (code default true) | everyone unless env-killed. Not declared in runtime_env |
no | unset (kill via env) | _stored_meeting_lookup_enabled in process_conversation.py |
WAKE_WORD_ADJUDICATION_ENABLED |
Wake-word LLM adjudication | env | fail-open (unset ⇒ on) | on (_base true) |
no | WAKE_WORD_ADJUDICATION_ENABLED |
wake_word_adjudication_enabled in backend/utils/task_intelligence/conversation_capture.py |
OMI_LLM_GATEWAY_FEATURE_MODE |
LLM gateway feature mode | env | closed (direct) unless gateway |
gateway in _base / prod / dev |
no | OMI_LLM_GATEWAY_FEATURE_MODE |
should_route_features_through_gateway in backend/utils/llm/gateway_client.py |
MEMORY_DAILY_MEMORY_SWEEP_* |
Daily memory sweep job | env | closed (off) | disabled in prod (MEMORY_DAILY_MEMORY_SWEEP_ENABLED=false and model/cohort off). Not admission |
no | MEMORY_DAILY_MEMORY_SWEEP_ENABLED and siblings on daily-memory-sweep-job |
daily_memory_sweep_authority_from_environment in backend/utils/memory/daily_memory_sweep.py |
DAY3_REENGAGEMENT_EMAIL_ENABLED |
Day-3 re-engagement email | env | closed (off) | false prod (and _base) |
no | DAY3_REENGAGEMENT_EMAIL_ENABLED |
authority_from_environment in backend/utils/email/day3_reengagement.py |
PUBLIC_SHARED_CONVERSATION_CHAT_MODE |
Public shared-conversation chat | env | closed (off) |
off | no | PUBLIC_SHARED_CONVERSATION_CHAT_MODE |
_gateway_mode_enabled in backend/routers/public_shared_conversation_chat.py |
ACCOUNT_CUTOVER_ENFORCEMENT |
Account cutover fence | env | closed (off) |
off | no | ACCOUNT_CUTOVER_ENFORCEMENT |
cutover_enforcement_enabled in backend/utils/account_cutover/access.py |
FAIR_USE_ENABLED |
Fair-use metering | env | closed (false) | unset in runtime_env; code default false |
no | unset | FAIR_USE_ENABLED in backend/utils/fair_use.py |
Do not list these as rollout flags:
- Flutter
OmiFeatureshardware capability bits. - Integration-nudge UserDefaults opt-out (per-user preference, not a remote gate).
- Local-only process overrides (
OMI_FORCE_*,OMI_PERSISTENT_CAPTURE_STREAM,OMI_FORCE_CONTEXT_BUCKETS,OMI_FORCE_LOSSLESS_SCREEN_SYNC, and the bucket-pipelineOMI_FORCE_BUCKET_*/OMI_FORCE_DWELL_REFRESH/OMI_FORCE_DEPARTURE_EVALUATION/OMI_FORCE_FACT_WRITE_POLICYknobs). They never ship as remote authority.
Do not re-read these for admission:
| Key | Why |
|---|---|
jit-processing-ledger-migration-v1 |
Retired. Kept as JIT_LEDGER_MIGRATION_FLAG_KEY so tests can prove it no longer authorizes work. See jit_rollout_authority.mdx. |
daily-memory-sweep-v1 |
Live PostHog row, but it is a decoy name on the sweep job, not permits_work. Listed in the table above so the dashboard is not mistaken for admission. |