Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ env:
value: "0"
- name: BATCH_PIPELINE_PERCENT
value: "0"
- name: SERVER_BATCH_ONLY_MOBILE_PERCENT
value: "0"
- name: BATCH_PIPELINE_SERVING_ENABLED
value: "false"
- name: BATCH_PIPELINE_WORKER_ENABLED
Expand Down
3 changes: 1 addition & 2 deletions backend/docs/feature-flag-registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ and an explicit empty literal renders as `''`.
| `PLAYBACK_ON_DEMAND_ENABLED` | Build playback only on open/play; stable generation/checksum source IDs; existing task/run-lock coalescing | backend | env | closed | {value: 'false', category: rollout} | false (backend-listen (chart), pusher (chart)); {value: 'false', category: rollout} (cloud_run/backend, cloud_run/backend-integration, cloud_run/backend-sync, cloud_run/backend-sync-backfill, gke/backend-listen, gke/pusher) | false (backend-listen (chart), pusher (chart)); {value: 'false', category: rollout} (cloud_run/backend, cloud_run/backend-integration, cloud_run/backend-sync, cloud_run/backend-sync-backfill, gke/backend-listen, gke/pusher) | — | graduate | on | 2026-11-15 | dazheng |
| `REPEAT_WORK_REVISION_ENABLED` | Reuse existing sync outbox with 60min ceiling and exact successful snapshot-based notes/L1 dedupe; content-free call/final joins | backend | env | closed | {value: 'false', category: rollout} | false (backend-listen (chart), pusher (chart)); {value: 'false', category: rollout} (cloud_run/backend, cloud_run/backend-integration, cloud_run/backend-sync, cloud_run/backend-sync-backfill, gke/backend-listen, gke/pusher) | false (backend-listen (chart), cloud_run/backend, cloud_run/backend-integration, cloud_run/backend-sync, cloud_run/backend-sync-backfill, pusher (chart)); {value: 'false', category: rollout} (gke/backend-listen, gke/pusher) | — | pending | undecided | 2026-11-04 | dazheng |
| `REVIEW_SURFACE_MODE` | Review queue, reversible agent changes and entity pages; off by default, on enables authenticated routes | backend | env | closed | on | on (backend-listen (chart), cloud_run/backend, gke/backend-listen) | on (backend-listen (chart), cloud_run/backend, cloud_run/backend-sync, gke/backend-listen) | — | pending | undecided | 2026-11-07 | dazheng |
| `SERVER_BATCH_ONLY_MOBILE_PERCENT` | Default 0; iOS/Android unsalted owner-hash cohort nested in existing batch admission, with the same custody and language gates | backend | env | closed | — | — | — | — | pending | on | 2026-10-31 | dazheng |
| `SERVER_BATCH_ONLY_MOBILE_PERCENT` | Default 0; iOS/Android unsalted owner-hash cohort nested in existing batch admission, with the same custody and language gates | backend | env | closed | — | — | 0 (backend-listen (chart)) | — | pending | on | 2026-10-31 | dazheng |
| `SONIOX_CAPTURE_AXIS_DIAGNOSTICS` | Measure raw Soniox token clocks against wire PCM and the managed send ledger; default off, no placement changes | backend | env | closed | declared (gke/backend-listen, gke/pusher); false (cloud_run/backend, cloud_run/backend-integration, cloud_run/backend-sync, cloud_run/backend-sync-backfill) | false (backend-listen (chart), cloud_run/backend, cloud_run/backend-integration, cloud_run/backend-sync, cloud_run/backend-sync-backfill, gke/backend-listen, gke/pusher, pusher (chart)) | false (cloud_run/backend, cloud_run/backend-integration, cloud_run/backend-sync, cloud_run/backend-sync-backfill); true (backend-listen (chart), gke/backend-listen, gke/pusher, pusher (chart)) | — | pending | undecided | 2026-11-04 | dazheng |
| `SONIOX_ELAPSED_AXIS` | Measure Soniox elapsed timestamps before enabling speaker windows | backend | env | closed | — | — | — | — | kill | off | 2026-11-04 | dazheng |
| `SONIOX_IDLE_COHORT_CLOSE_SECONDS` | Treatment-arm close seconds for the uid-hash idle cohort; unset/off keeps the global value; floored at 20 s | backend | env | open | — | — | — | — | pending | undecided | 2026-11-21 | backend |
Expand Down Expand Up @@ -942,7 +942,6 @@ their code default (`fail` tells you which way a missing value resolves).
- `SCREEN_TASK_STOP` — Stop screen-task gate and flagged extraction admission; default false; clients poll every 30 seconds with a 55-second lease (fail: inverted)
- `SELFHEAL_MODE` — Conversation self-heal sweeper mode: off/detect-only/nudge/heal (fail: closed)
- `SERVER_BATCH_ONLY_ENABLED` — Default on; consented supported-language platform sessions reserve durable batch ownership and open no managed live STT (fail: open)
- `SERVER_BATCH_ONLY_MOBILE_PERCENT` — Default 0; iOS/Android unsalted owner-hash cohort nested in existing batch admission, with the same custody and language gates (fail: closed)
- `SERVER_BATCH_ONLY_PLATFORMS` — Default macos,windows; comma-separated desktop platforms admitted to server batch-only capture; linux supported explicitly (fail: closed)
- `SONIOX_ELAPSED_AXIS` — Measure Soniox elapsed timestamps before enabling speaker windows (fail: closed)
- `SONIOX_IDLE_CLOSE_SECONDS` — Default on at 45 s; close paid Soniox transports after continuous active-VAD silence or 60 s with no client frames; 0 or off is the kill switch (fail: open)
Expand Down
4 changes: 4 additions & 0 deletions backend/scripts/verify_pusher_cohost_env_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@
"MOBILE_STANDARD_BATCH_ENABLED",
"MOBILE_STANDARD_BATCH_PERCENT",
"MOBILE_STANDARD_BATCH_UIDS",
# Only listen reads the mobile server-batch-only cohort: server_batch.selected via
# request_eligible and via eligible <- create_in_progress_conversation, both called only
# from routers/listen. Pusher's finalizer uses owned/has_audio and never admits capture.
"SERVER_BATCH_ONLY_MOBILE_PERCENT",
# Managed listen-only STT rollout; pusher is not a live audio receiver.
"PARAKEET_BATCH_PRESSURE_MIN_REPLICAS",
"PARAKEET_BATCH_PRESSURE_POOL_HOST",
Expand Down
31 changes: 31 additions & 0 deletions backend/tests/unit/test_backend_listen_helm_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,37 @@ def test_backend_listen_helm_template_uses_runtime_project_for_google_cloud_proj
assert 'name: TRANSLATION_NEGATIVE_CACHE_TTL\n value: "21600"' in rendered


def test_prod_listen_carries_an_explicit_zero_mobile_batch_only_percent():
"""Ruling 73b217: the mobile batch-only cohort is a reviewed listen value, explicit 0 until a ramp PR changes it.

The value must reach the rendered container env (not only the values file), so a listen roll applies it.
"""
values = _load_values(ENV_IDENTITY_DEFAULTS["prod"]["values_file"])
assert _env_value(values, "SERVER_BATCH_ONLY_MOBILE_PERCENT") == "0"
names = [entry.get("name") for entry in values.get("env", []) or [] if isinstance(entry, dict)]
assert names.count("SERVER_BATCH_ONLY_MOBILE_PERCENT") == 1

helm = shutil.which("helm")
if helm is None:
pytest.skip("helm is not installed")
rendered = subprocess.run(
[
helm,
"template",
"backend-listen",
str(CHART_DIR),
"-f",
str(ENV_IDENTITY_DEFAULTS["prod"]["values_file"]),
"--set-string",
"image.tag=abc1234",
],
check=True,
capture_output=True,
text=True,
).stdout
assert 'name: SERVER_BATCH_ONLY_MOBILE_PERCENT\n value: "0"' in rendered


def test_backend_listen_helm_template_requires_image_tag():
helm = shutil.which("helm")
if helm is None:
Expand Down
1 change: 1 addition & 0 deletions config/deployment-setting-classification.json
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@
"STT_LIVE_DEMAND_MIN_DWELL_SECONDS",
"MOBILE_STANDARD_BATCH_ENABLED",
"MOBILE_STANDARD_BATCH_PERCENT",
"SERVER_BATCH_ONLY_MOBILE_PERCENT",
"MOBILE_STANDARD_BATCH_UIDS",
"OWNER_IDENTITY_RETRY_COALESCE_ENABLED",
"SPEAKER_GROUPING_CROSS_SCOPE_THRESHOLD",
Expand Down
Loading