|
| 1 | +# PR_26177_BRAVO_001 Audit: Text To Speech Profiles And Emotions |
| 2 | + |
| 3 | +## Scope |
| 4 | + |
| 5 | +Audit-only review of Team Bravo Text To Speech, including TTS Profiles, Emotion Profiles, Messages integration, DB/API contracts, existing tests, Playwright coverage, and remaining production-readiness gaps. |
| 6 | + |
| 7 | +No implementation changes were made. |
| 8 | + |
| 9 | +Repo-structured ZIP path: `tmp/PR_26177_BRAVO_001-audit-text-to-speech-profiles-emotions_delta.zip` |
| 10 | + |
| 11 | +## Branch Validation |
| 12 | + |
| 13 | +| Check | Result | Evidence | |
| 14 | +| --- | --- | --- | |
| 15 | +| Current branch must be `main` | PASS | `git branch --show-current` returned `main`. | |
| 16 | +| Hard stop if branch is not `main` | PASS | Branch was validated before report edits. | |
| 17 | + |
| 18 | +## Audit Checklist |
| 19 | + |
| 20 | +| Area | Status | Notes | |
| 21 | +| --- | --- | --- | |
| 22 | +| 1. Text To Speech creator page/workflow | PASS | `toolbox/text-to-speech/index.html` uses Theme V2 shell, external assets, TTS Profiles table, per-profile Emotion rows, and Local Preview playback. | |
| 23 | +| 2. TTS Profile management | PARTIAL | Browser UI supports add/edit/delete and persistence, but source of truth is browser storage and reference blocking is based on stored counters rather than live Messages usage. | |
| 24 | +| 3. Emotion Profile management | PARTIAL | Text To Speech has per-profile Emotion rows with pitch/rate/volume, but Local API/DB has global `messages_emotion_profiles` and no TTS Profile to Emotion settings join table. | |
| 25 | +| 4. Messages integration with TTS Profiles and Emotion Profiles | PARTIAL | Messages loads saved active TTS Profiles, syncs names to Local API rows, filters sentence emotions by selected TTS Profile, and plays through browser speech. The sync is opportunistic and browser-storage-driven. | |
| 26 | +| 5. DB tables/migrations/seeds | PARTIAL | Runtime service DDL contains TTS profile references, but static `docs_build/database/ddl/messages.sql` is stale and lacks `voiceProfileKey` columns/indexes and `messages_event_actions`. | |
| 27 | +| 6. Local API/service contracts | PARTIAL | Local API exposes list/create/update for TTS and Emotion Profiles plus Messages/Sentences. TTS Profile usage/reference counts and deactivation protection are missing. | |
| 28 | +| 7. Reference protection/delete blocking | PARTIAL | Message delete is blocked when sentences exist; Emotion deactivation is blocked when referenced. TTS Profile deactivation is not blocked server-side, and Text To Speech delete blocking depends on stale/local counters. | |
| 29 | +| 8. Usage counts/used-by visibility | PARTIAL | Messages shows selected message sentence usage and reference list. Emotion Profile API exposes usage/references. TTS Profile API does not expose usage/references, and Text To Speech has no live used-by view. | |
| 30 | +| 9. Preview playback | PASS | Text To Speech preview uses Web Speech API through `TextToSpeechEngine`; Messages playback uses selected parent TTS Profile and sentence Emotion settings. | |
| 31 | +| 10. Validation and error handling | PARTIAL | Required-field and uniqueness checks exist in UI/service, plus publish validation. Gaps remain around inactive profile publish checks, TTS Profile reference protection, and creator-facing API terminology. | |
| 32 | +| 11. Theme V2 compliance | PASS | Target HTML uses `base href="/"`, Theme V2 CSS, partials, `tool-workspace`, `tool-column`, data-tool-display-mode, and no inline style/script handlers in inspected pages. | |
| 33 | +| 12. Existing unit/API tests | PASS | Targeted Node tests pass: 10 tests across Text To Speech shell/store, Messages playback source checks, and Messages publish validation. | |
| 34 | +| 13. Existing Playwright coverage | FAIL | Coverage files exist, but impacted Playwright lane is not currently runnable: Messages spec imports a removed store path, and standalone Text To Speech spec cannot launch because Chromium is not installed. | |
| 35 | +| 14. Remaining production-readiness gaps | PASS | Exact implementation PR recommendations are listed below. | |
| 36 | + |
| 37 | +## File Inventory |
| 38 | + |
| 39 | +| Surface | Files | |
| 40 | +| --- | --- | |
| 41 | +| Text To Speech page/workflow | `toolbox/text-to-speech/index.html`; `assets/toolbox/text-to-speech/js/index.js`; `assets/js/shared/tts-profile-store.js`; `src/engine/audio/TextToSpeechEngine.js`; `src/engine/audio/TextToSpeechDefaults.js`; `src/shared/contracts/tools/textToSpeechContract.js` | |
| 42 | +| Messages integration | `toolbox/messages/index.html`; `toolbox/messages/messages.js`; `toolbox/messages/messages-api-client.js`; `toolbox/messages/message-tts-service-registry.js`; `src/api/server-api-client.js` | |
| 43 | +| Local API/service | `src/dev-runtime/messages/messages-postgres-service.mjs`; `src/dev-runtime/server/local-api-router.mjs`; `src/dev-runtime/server/local-api-server.mjs` | |
| 44 | +| DB contract/seed | `docs_build/database/ddl/messages.sql`; `docs_build/database/dml/messages.sql`; `docs_build/database/seed/messages.json` | |
| 45 | +| Unit/API tests | `tests/tools/Text2SpeechShell.test.mjs`; `tests/tools/MessagesPlaybackSource.test.mjs`; `tests/dev-runtime/MessagesPublishValidation.test.mjs`; `tests/helpers/messagesPostgresClientStub.mjs` | |
| 46 | +| Playwright tests | `tests/playwright/tools/TextToSpeechFunctional.spec.mjs`; `tests/playwright/tools/MessagesTool.spec.mjs`; `tests/playwright/tools/EventsTool.spec.mjs` | |
| 47 | + |
| 48 | +## DB/API Inventory |
| 49 | + |
| 50 | +### Runtime Service Tables |
| 51 | + |
| 52 | +`src/dev-runtime/messages/messages-postgres-service.mjs` creates or patches: |
| 53 | + |
| 54 | +- `messages_categories` |
| 55 | +- `messages_emotion_profiles` |
| 56 | +- `messages_tts_profiles` |
| 57 | +- `messages_records` |
| 58 | +- `messages_segments` |
| 59 | +- `messages_event_actions` |
| 60 | +- `messages_records."voiceProfileKey"` references `messages_tts_profiles(key)` |
| 61 | +- `messages_segments."voiceProfileKey"` references `messages_tts_profiles(key)` |
| 62 | +- indexes for emotion, voice profile, message, event action, creator, and updater lookups |
| 63 | + |
| 64 | +### Static DB Files |
| 65 | + |
| 66 | +- `docs_build/database/ddl/messages.sql` includes categories, emotion profiles, TTS profiles, records, and segments. |
| 67 | +- Static DDL currently omits `messages_records."voiceProfileKey"`, `messages_segments."voiceProfileKey"`, the voice-profile indexes on records/segments, and `messages_event_actions`. |
| 68 | +- `docs_build/database/dml/messages.sql` intentionally has no direct inserts and delegates setup to server-side seed/API. |
| 69 | +- `docs_build/database/seed/messages.json` seeds names for categories, emotion profiles, and TTS profiles. It explicitly says browser pages must not seed authoritative records. |
| 70 | + |
| 71 | +### Local API Endpoints |
| 72 | + |
| 73 | +Browser client `toolbox/messages/messages-api-client.js` wraps: |
| 74 | + |
| 75 | +- `GET/POST /api/messages/emotion-profiles` |
| 76 | +- `GET/POST /api/messages/emotion-profiles/:key` |
| 77 | +- `GET/POST /api/messages/tts-profiles` |
| 78 | +- `GET/POST /api/messages/tts-profiles/:key` |
| 79 | +- `GET/POST /api/messages/messages` |
| 80 | +- `GET/POST /api/messages/messages/:key` |
| 81 | +- `POST /api/messages/messages/:key/delete` |
| 82 | +- `GET/POST /api/messages/segments` |
| 83 | +- `GET/POST /api/messages/segments/:key` |
| 84 | +- `POST /api/messages/segments/:key/delete` |
| 85 | +- `GET /api/messages/publish-validation` |
| 86 | + |
| 87 | +### Contract Gaps |
| 88 | + |
| 89 | +- `messages_tts_profiles` has no usage count or references projection. |
| 90 | +- `messages_tts_profiles` update allows active TTS Profiles to be deactivated even when Messages or Sentences reference them. |
| 91 | +- Local API uses user-facing "Voice profile" wording in errors and publish issues where creator-facing UI says "TTS Profile". |
| 92 | +- DB/API does not model per-TTS-Profile Emotion Settings. The runtime maps every active global Emotion Profile into every TTS Profile unless the browser-local Text To Speech store overrides it. |
| 93 | + |
| 94 | +## Test Inventory |
| 95 | + |
| 96 | +### Validation Performed |
| 97 | + |
| 98 | +| Command | Result | |
| 99 | +| --- | --- | |
| 100 | +| `node --check assets/toolbox/text-to-speech/js/index.js` | PASS | |
| 101 | +| `node --check assets/js/shared/tts-profile-store.js` | PASS | |
| 102 | +| `node --check toolbox/messages/messages.js` | PASS | |
| 103 | +| `node --check toolbox/messages/messages-api-client.js` | PASS | |
| 104 | +| `node --check toolbox/messages/message-tts-service-registry.js` | PASS | |
| 105 | +| `node --check src/dev-runtime/messages/messages-postgres-service.mjs` | PASS | |
| 106 | +| `node --test tests/tools/Text2SpeechShell.test.mjs tests/tools/MessagesPlaybackSource.test.mjs tests/dev-runtime/MessagesPublishValidation.test.mjs` | PASS, 10/10 tests | |
| 107 | +| `rg -n "imageDataUrl" ...target files...` | PASS, no matches | |
| 108 | +| `rg -n --pcre2 "<style|style=| on[a-z]+\\s*=|<script(?![^>]*\\bsrc=)" toolbox/text-to-speech/index.html toolbox/messages/index.html` | PASS, no matches | |
| 109 | +| `npx playwright test tests/playwright/tools/TextToSpeechFunctional.spec.mjs tests/playwright/tools/MessagesTool.spec.mjs --project=playwright` | FAIL/BLOCKED, stale Messages spec import to `../../../toolbox/text-to-speech/tts-profile-store.js` | |
| 110 | +| `npx playwright test tests/playwright/tools/TextToSpeechFunctional.spec.mjs --project=playwright` | FAIL/BLOCKED, Chromium executable missing at `C:\Users\davidq\AppData\Local\ms-playwright\chromium-1217\chrome-win64\chrome.exe` | |
| 111 | + |
| 112 | +### Existing Test Coverage |
| 113 | + |
| 114 | +- `tests/tools/Text2SpeechShell.test.mjs` covers message model ownership, browser preview request shaping, provider adapter status, saved profile store export to Messages, default profile names, emotion labels, and default usage counters. |
| 115 | +- `tests/tools/MessagesPlaybackSource.test.mjs` statically guards against old preview wording, global emotion fallbacks, Text To Speech UI module imports, and stale profile builders. |
| 116 | +- `tests/dev-runtime/MessagesPublishValidation.test.mjs` covers publish-ready messages and broken/missing TTS reference validation. |
| 117 | +- `tests/playwright/tools/TextToSpeechFunctional.spec.mjs` is intended to cover TTS page load, profile/emotion workflow, preview playback, toolbox registration, and browser speech unavailable state. |
| 118 | +- `tests/playwright/tools/MessagesTool.spec.mjs` is intended to cover Messages CRUD, profile filtering, playback through saved TTS Profiles, reference/delete blocking, and creator-safe load failures, but currently imports a removed file path. |
| 119 | + |
| 120 | +## Playwright Impacted Assessment |
| 121 | + |
| 122 | +Impacted specs: |
| 123 | + |
| 124 | +- `tests/playwright/tools/TextToSpeechFunctional.spec.mjs` |
| 125 | +- `tests/playwright/tools/MessagesTool.spec.mjs` |
| 126 | +- `tests/playwright/tools/EventsTool.spec.mjs` indirectly reads Messages API TTS/Emotion profile rows. |
| 127 | + |
| 128 | +Current assessment: |
| 129 | + |
| 130 | +- Playwright coverage exists and is relevant. |
| 131 | +- The impacted Messages spec must be repaired before it can run because it imports `../../../toolbox/text-to-speech/tts-profile-store.js`; the active store is `assets/js/shared/tts-profile-store.js`. |
| 132 | +- The local machine also needs the configured Chromium browser installed before browser-backed validation can execute. |
| 133 | +- Once unblocked, the impacted Playwright lane should be rerun with Text To Speech and Messages together because the critical workflow crosses localStorage, Local API sync, profile selection, emotion filtering, and playback. |
| 134 | + |
| 135 | +## Exact Remaining Implementation PR Recommendations |
| 136 | + |
| 137 | +1. `PR_26177_BRAVO_002-messages-ddl-runtime-contract-alignment` |
| 138 | + - Update `docs_build/database/ddl/messages.sql` to match runtime service DDL. |
| 139 | + - Include `voiceProfileKey` columns, voice-profile indexes, `messages_event_actions`, and any needed migration/backfill notes. |
| 140 | + - Add a test comparing static Messages DDL inventory to `MESSAGES_SCHEMA_SQL` coverage. |
| 141 | + |
| 142 | +2. `PR_26177_BRAVO_003-tts-profile-usage-reference-protection` |
| 143 | + - Add TTS Profile usage counts and reference lists to Local API responses. |
| 144 | + - Block deactivation of referenced TTS Profiles the same way Emotion Profile deactivation is blocked. |
| 145 | + - Surface used-by visibility in Text To Speech for profiles referenced by Messages/Sentences. |
| 146 | + |
| 147 | +3. `PR_26177_BRAVO_004-profile-scoped-emotion-settings-contract` |
| 148 | + - Add an explicit DB/API model for TTS Profile to Emotion settings. |
| 149 | + - Store pitch/rate/volume per TTS Profile emotion instead of depending on browser-local profile JSON. |
| 150 | + - Keep Messages sentence emotion dropdowns sourced from the selected TTS Profile only. |
| 151 | + |
| 152 | +4. `PR_26177_BRAVO_005-server-owned-tts-profile-source-of-truth` |
| 153 | + - Move active TTS Profiles out of browser-local storage as the production source of truth. |
| 154 | + - Keep any local storage use limited to explicit drafts/cache if approved. |
| 155 | + - Do not introduce silent defaults; default profiles should be seeded server-side and visible. |
| 156 | + |
| 157 | +5. `PR_26177_BRAVO_006-playwright-tts-messages-lane-repair` |
| 158 | + - Fix `tests/playwright/tools/MessagesTool.spec.mjs` to import `TEXT_TO_SPEECH_PROFILE_STORAGE_KEY` from `assets/js/shared/tts-profile-store.js`. |
| 159 | + - Ensure Playwright Chromium is installed or provide a zero-browser gate for import/static checks. |
| 160 | + - Rerun `TextToSpeechFunctional.spec.mjs` and `MessagesTool.spec.mjs` together. |
| 161 | + |
| 162 | +6. `PR_26177_BRAVO_007-creator-facing-tts-terminology` |
| 163 | + - Normalize user-visible API and validation wording from "Voice Profile" to "TTS Profile". |
| 164 | + - Normalize "Message Part" wording to "Sentence" where surfaced in creator-facing Messages UI/errors. |
| 165 | + |
| 166 | +7. `PR_26177_BRAVO_008-publish-validation-profile-active-state` |
| 167 | + - Extend publish validation to reject inactive Emotion Profiles and inactive TTS Profiles already referenced by saved Messages/Sentences. |
| 168 | + - Add tests for deactivation-after-save publish blocking. |
| 169 | + |
| 170 | +## Manual Validation Notes |
| 171 | + |
| 172 | +- Manual browser validation was not completed because Playwright browser validation is blocked by missing Chromium. |
| 173 | +- Source inspection confirmed both target HTML pages use external Theme V2 assets and no inline style/script handlers. |
| 174 | +- Source inspection confirmed Text To Speech local preview blocks empty text and missing selected browser voice. |
| 175 | +- Source inspection confirmed Messages playback uses the parent Message TTS Profile for sentence playback and does not call Text To Speech Local Preview. |
| 176 | +- Source inspection confirmed no `imageDataUrl` usage in the audited target files. |
| 177 | + |
| 178 | +## Known Issues |
| 179 | + |
| 180 | +- `tests/playwright/tools/MessagesTool.spec.mjs` imports a removed store path: `../../../toolbox/text-to-speech/tts-profile-store.js`. |
| 181 | +- Playwright Chromium is not installed at the configured local path, so browser specs cannot launch. |
| 182 | +- Static Messages DDL is behind runtime service DDL for `voiceProfileKey` and event action tables. |
| 183 | +- TTS Profile usage counts and references are missing from the Local API. |
| 184 | +- TTS Profile deactivation is not server-blocked when referenced. |
| 185 | +- Text To Speech delete blocking relies on profile/emotion usage counters embedded in browser-local profile JSON. |
| 186 | +- Local API still exposes "Voice profile" terminology in user-visible messages. |
| 187 | +- Production TTS Profile source of truth is not yet server-owned. |
| 188 | + |
| 189 | +## Output Files |
| 190 | + |
| 191 | +- `docs_build/dev/reports/codex_review.diff` |
| 192 | +- `docs_build/dev/reports/codex_changed_files.txt` |
| 193 | +- `docs_build/dev/reports/PR_26177_BRAVO_001-audit-text-to-speech-profiles-emotions.md` |
| 194 | +- `tmp/PR_26177_BRAVO_001-audit-text-to-speech-profiles-emotions_delta.zip` |
0 commit comments