Operator UAT 2026-05-20 rejected the build because the OS notification fired
on `chrome.runtime.onStartup` ("Recording started. I'm watching the last 30
seconds.") implied recording had auto-started when in fact recording was
not running. Per Phase 1 always-on charter recording does NOT auto-start;
the notification is the gesture surface that invites the operator to start
one (notifications.onClicked → startVideoCapture, src/background/index.ts:1038).
Root cause: a single i18n key `notifStartup` conflated the pre-recording
CTA-with-gesture path (the only path actually wired today) and a future
post-manual-start confirmation path. The key's own `.description` field
acknowledged the conflation. Operator-facing text leaned toward the
confirmation phrasing.
Fix (key split, no behavior change):
- `notifStartupCta` — EN: "Mokosh ready. Click to start a recording." /
RU: "Mokosh готов. Нажмите, чтобы начать запись." — wired into the
onStartup handler.
- `notifRecordingStarted` — preserves the original text ("Recording
started. I'm watching the last 30 seconds." / "Запись запущена…") for
a future post-manual-start confirmation flow.
- Fallback constant renamed `NOTIF_STARTUP_FALLBACK` →
`NOTIF_STARTUP_CTA_FALLBACK`; value updated to match the new CTA text.
- Inline test comment in tests/background/onstartup-notification.test.ts
refreshed to reference the new key + fallback. Assertion regex
/recording|recor|click/i covers both fallback + resolved locale variants,
no logic change.
Notification behavior preserved: same id prefix `mokosh-startup-`, same
priority, same icon, same onClicked → startVideoCapture wiring. No new
test-mode symbols (FORBIDDEN_HOOK_STRINGS inventory stays at 12).
Files modified:
- _locales/en/messages.json
- _locales/ru/messages.json
- src/background/index.ts
- tests/background/onstartup-notification.test.ts
Verification:
- npx vitest run --exclude tests/build/** --exclude tests/background/no-test-hooks-in-prod-bundle.test.ts: 104/104 GREEN
- npx vitest run tests/i18n/ tests/background/onstartup-notification.test.ts: 18/18 GREEN (locale-parity 4/4 + onstartup-notification 14/14)
- npx tsc --noEmit clean on src/background/index.ts
The 2 build-dependent vitest gates (tests/build/no-remote-fonts.test.ts +
tests/background/no-test-hooks-in-prod-bundle.test.ts) and npm run test:uat
are deferred to orchestrator-level re-verification after the parallel
Plan 01-10 mark-bundling fix also lands (operator-UAT re-spawn coordinated
by orchestrator).
Debug record: .planning/debug/resolved/01-09-startup-notification-misleading-text.md
Operator UAT rejection event: 2026-05-20
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
manifest.json migrated to chrome i18n placeholders:
- name: 'AI Call Recorder' → '__MSG_extName__'
- description: 'Запись сессий операторов для диагностики ошибок' → '__MSG_extDesc__'
- default_locale: 'en' (new field per RESEARCH §11 + Pitfall 4 fallback chain)
- action.default_title: '__MSG_tooltipOff__' (new field per Brief §02 string #1)
_locales/en/messages.json + _locales/ru/messages.json each carry the
same 16-key matrix per RESEARCH §10 + Brief §02 verbatim + D-07 user
override + D-08 tagline:
extName, extDesc, tooltipOff, tooltipRecPrefix, tooltipErr,
popupSavePrompt, popupSaveCta, popupSaveDone, popupSaving,
popupSaveDoneShort, popupEmptyState, popupInfoText,
notifStartup, notifRecovery, welcomeHeroRu, welcomeHeroEn
Canonical values (per brand-decisions-v1.md + RESEARCH §10 Brief §02):
- EN extName = 'Mokosh — Session Capture' (D-07 user override of A)
- EN extDesc = 'Thirty seconds ago, always at hand.' (D-08 tagline)
- RU extName = 'Mokosh — Запись сессии'
- RU extDesc = 'Тридцать секунд назад, всегда под рукой.'
NB on key count: the artifact-table 12-key baseline excluded the three
Wave-4 deltas (popupSaving, popupSaveDoneShort, popupEmptyState) which
are introduced now to avoid a re-locale-parity flap when Wave 4 lands.
popupInfoText is present in BOTH locales (the plan-checker flag 1
informational scope-slip is corrected here — see deviation block below).
Plan success-criteria reading: ≥12 keys with Wave 4 additive deltas
accounted for.
Each key carries both `message` and `description` per Chrome i18n
schema. EN descriptions are translator-facing; RU descriptions are
plain-Russian context for native operators.
npm run build emits:
- dist/manifest.json carries the i18n shape verbatim (crxjs preserves
__MSG_* placeholders; Chrome's manifest loader resolves them at install)
- dist/_locales/en/messages.json (3.30 KB)
- dist/_locales/ru/messages.json (3.81 KB)
Verification:
- tests/i18n/manifest-i18n.test.ts: 10/10 GREEN
- tests/i18n/locale-parity.test.ts: 4/4 GREEN (en↔ru parity, non-empty
messages, 16 keys each)
- tests/build/no-remote-fonts.test.ts: 4/4 GREEN (post-build dist/ has
zero remote font URLs)
- Full vitest sweep: 145/147 GREEN (2 RED remaining are popup/style.css
tokens-adopted cases — Wave 4 work)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>