A repeatable test plan and dated evidence for transcripts, streamed answers and video citations.
Instructors need a transcript before learners can ask questions about a video. Study Buddy can now generate that transcript or accept an SRT or VTT file. Learners get answers tied to lesson evidence and can jump to the cited time. This report checks those actions on beta and keeps the remaining release checks visible.
Wait until processing completes.
Generate one, or upload an SRT or VTT file.
Read provisional text, then the validated answer.
Click a timestamp to seek in the video.
About 92 seconds, silent. The blue dot is the mouse. This is the deployed beta app with synthetic QA data. The synthetic video has a plain navy picture and spoken lesson audio.
All nine previously unrun cases were attempted. Pass, Partial and Fail remain separate. API checks used an isolated beta tenant; the original video and screenshots remain from the first QA course.
The threshold was set before transcription: normalized word error at most 15%, with nonempty cues inside the video duration. Word error counts substitutions, insertions and deletions against reference words. These scores do not replace an independent human review or prove absolute timing accuracy.
| Clip | Result | Word error | Cues | Video duration |
|---|---|---|---|---|
| vi-1 | Pass | 0.00% | 1 | 44 seconds |
| vi-2 | Fail | 18.75% | 1 | 41 seconds |
| vi-3 | Pass | 0.00% | 1 | 41 seconds |
| vi-noisy | Pass | 0.00% | 1 | 42 seconds |
| long-en | Pass | 14.19% | 668 | 2585 seconds |
The short Vietnamese videos include a still frame tail after the spoken reference audio. The noisy fixture adds deterministic white noise at about 10 dB signal-to-noise ratio. Sources: Google FLEURS, CC BY 4.0; MIT OpenCourseWare, Ana Bell, Fall 2016, CC BY-NC-SA. The site publishes scores only, with no full reference transcripts or source audio. Download scores.

Sign in as an instructor. Open a ready video lesson in an isolated course. Check that the card is off and no transcript exists. Do not use an existing customer lesson.

Use one toggle action. Expect the pending message, then a ready transcript. This run reached Ready at the 18.07-second polling observation and saved 17 cues in English. Exact job-count and billing reconciliation remain open.


Upload a valid SRT, then a valid VTT. Check the language, segment count and instructor origin. Reject invalid timing, a file over 2 MB, the wrong extension and cues past the video end. Confirm each rejection leaves the previous transcript unchanged.
The test upload reused the machine transcript text. Instructor origin confirms the upload path; it does not mean a human reviewed the wording.

Open the lesson in a separate learner session. Ask, “When should I review the five new words?” Confirm that partial text appears before final feedback and source controls.


The expected intervals are one, three and seven days. Check them against the source cue from 17.8 to 23.1 seconds. Click the timestamp and watch the real player time change.


Turn Study Buddy off and reload as the learner. The panel must disappear while the video remains playable. Turn it on again and confirm it reuses the saved transcript. Interrupt a reply, then retry the original question explicitly.

Change only the QA course language. The old transcript must stay unchanged and the instructor must see the language warning. Restore the course language after the check.

| State or control | What it means |
|---|---|
| Automatic | Machine-generated transcript. The learner sees that it is not yet reviewed by the instructor. |
| Uploaded by the instructor | A file was uploaded. This is a source label, not an independent quality score. |
| 17 segments | There are 17 timestamped cues in this QA transcript. |
| Provisional answer | Text is still arriving. It has not reached final validation. |
| Timestamp link | A validated source time. Clicking it seeks in the current video. |
| Language warning | Course language and existing transcript language differ. Changing the course does not regenerate the transcript. |
Known answer. The QA cue says to review after one, three and seven days. The observed answer gave those same intervals. Its first citation points to that cue.
Live streaming. The browser showed provisional text at 5.554 seconds and final controls at 6.349 seconds. Measured warm API stream: first text 7.2262s; final 8.405s. No five-second performance target is claimed. Browser sampling and screenshots add overhead. These are single warm observations, not percentile benchmarks.
Real access checks. Student management attempts and unenrolled chat requests were denied. An actual other-tenant hostname was also denied. That request stopped at the entitlement check; other tenant-boundary branches remain outside this smoke test.
Follow-up and refusal. A follow-up explained active recall using lesson cues. A stock-price question was refused because the lesson does not contain that information.
41 cases. P0 is a release gate. P1 covers edge cases and wider acceptance. Expand a case to compare its expected and observed behavior. Not run means no beta proof was collected.
| Case | Result | Steps, expected result and evidence |
|---|---|---|
| REL-01 P0 | Pass | Confirm merge and active beta deploymentExpected. PR 602 is merged; deployed frontend commit contains it. Observed. PR 602 merged 26 Oct 2026 at 16:11 UTC. DigitalOcean deployment ae248d2c is ACTIVE; frontend commit and backend image tag are f305ddf3. Git ancestry confirms that commit contains merge 67290b88. |
| CFG-01 P0 | Pass | Open a ready video lessonExpected. Study Buddy card shows off, no transcript, and an upload control. Observed. Beta lesson editor shows the off/empty card and upload control. |
| GEN-01 P0 | Partial | Turn on a ready video without a transcriptExpected. Pending state appears; exactly one job is requested. Observed. Real beta UI changed to generating after one switch action. Job-count accounting is not verified. One UI toggle request was sent. Exact job and billed-call counts were not read from the ledger. |
| GEN-02 P0 | Pass | Wait for real Gemini transcriptionExpected. Ready state shows machine origin, language and nonempty segments. Observed. Real transcription completed in 18.07s; origin=machine_generated, segments=17, language=en-US. |
| GEN-03 P0 | Pass | Enable again with a saved transcriptExpected. Existing transcript is reused; no new generation is pending. Observed. Repeated enable reuses transcript: HTTP 200 |
| UP-01 P0 | Pass | Upload a valid SRTExpected. Instructor origin replaces machine origin; timings and cue count match. Observed. SRT uploaded through the beta lesson editor; 17 cues, instructor origin, en-US. The file reuses machine text for format testing, not independent review. |
| UP-02 P1 | Pass | Upload a valid VTTExpected. VTT is parsed; instructor origin and cue count are correct. Observed. Valid VTT upload returned HTTP 200, 17 cues and instructor origin. |
| UP-03 P0 | Pass | Upload reversed cue timingExpected. 400 with a stable error; previous transcript stays available. Observed. Reverse cue: HTTP 400; saved transcript unchanged=True |
| UP-04 P1 | Pass | Upload a file over 2 MBExpected. 413; previous transcript stays available. Observed. Oversized file: HTTP 413; saved transcript unchanged=True |
| UP-05 P1 | Pass | Upload text with an unsupported extensionExpected. 400; previous transcript stays available. Observed. Unsupported extension: HTTP 400; saved transcript unchanged=True |
| UP-06 P1 | Pass | Upload a cue after the video endsExpected. 400; previous transcript stays available. Observed. Past video duration: HTTP 400; saved transcript unchanged=True |
| VIS-01 P0 | Pass | Open the lesson while enabled and readyExpected. Enrolled learner sees attribution, question input and suggestions. Observed. Enrolled synthetic learner sees input, scope and instructor attribution on beta. |
| VIS-02 P0 | Pass | Turn off, then reload as learnerExpected. Panel is hidden; video still plays; saved transcript remains. Observed. After disabling and reload, panel is absent, saved transcript remains, and Bunny video element remains. Playback decoding is checked separately. Panel hidden while actual HTML5 playback advanced 0.01s to 1.78s, readyState 4, no playback error. |
| VIS-03 P0 | Pass | Turn on again, then reloadExpected. Panel returns without regeneration. Observed. Panel returns after re-enable; saved transcript reused, generation state none. |
| ANS-01 P0 | Pass | Ask for the three review intervalsExpected. Answer includes one, three and seven days and a valid source. Observed. Answer checked against cue 5: review after one, three and seven days. |
| ANS-02 P0 | Pass | Ask a follow-up about active recallExpected. Answer uses earlier context and the correct lesson evidence. Observed. Follow-up returned a validated final answer about retrieval from memory with lesson citations. Manual spot check is recorded in the report. |
| ANS-03 P0 | Pass | Ask an unrelated questionExpected. Answer refuses or clearly says the lesson does not support it. Observed. Unrelated stock-price question received a lesson-scope refusal without a price. |
| STR-01 P0 | Pass | Observe the real beta reply streamExpected. Ordered version-1 start/status/text/final events arrive; text precedes final. Observed. Beta endpoint returned application/x-ndjson; 9 ordered events. First event 0.5533s, first text 7.2262s, final 8.405s. |
| STR-02 P0 | Pass | Observe learner answer during deliveryExpected. Provisional text is visible before final; final answer enables source controls. Observed. Provisional answer observed before final feedback controls. First observed text=5.554s; final=6.349s. Browser sampling includes screenshot overhead. |
| CIT-01 P0 | Pass | Click a timestamp in a validated answerExpected. Bunny player seeks to the cited time; evidence supports the answer. Observed. Clicked Jump to Spaced repetition and active recall at [00:17]; player time changed 14.75s → 19.93s; target 17s. |
| CAN-01 P1 | Pass | Leave the lesson during a replyExpected. Request cancels; no stale answer appears in the next lesson. Observed. Used the course sidebar to change lessons during an answer. Stream failure observed: ['net::ERR_ABORTED']; original question remains on destination=False. Backend provider cancellation was not traced. |
| REC-01 P1 | Partial | Interrupt the browser network during a replyExpected. Clear retry state; retry uses the original question; no automatic paid resend. Observed. Network interruption was injected; full retry check did not complete: TimeoutError |
| SEC-01 P0 | Fail | Read config without authenticationExpected. 401 before any sensitive config is returned. Observed. Anonymous config: HTTP 403 Access was safely denied with Not authenticated. The mismatch is 403 versus the planned 401, not an authentication bypass. |
| SEC-02 P0 | Pass | Read and change config as a studentExpected. 403; student cannot manage transcript or toggle. Observed. Student config: HTTP 403 Student toggle: HTTP 403 |
| SEC-03 P0 | Pass | Ask as a student without course enrolmentExpected. 403 before stream headers and provider work. Observed. Unenrolled student context: HTTP 403 Unenrolled student stream: HTTP 403 |
| SEC-04 P0 | Pass | Use the QA resource under another tenant hostExpected. Request fails and returns no QA lesson or transcript. Observed. Actual other-tenant hostname returned HTTP 403. Request was denied by the other tenant entitlement. This does not isolate every ownership or membership branch. A header-only probe on the default host was discarded because the actual Host takes precedence. |
| SEC-05 P1 | Pass | Request a nonexistent resourceExpected. 404 without leaking another resource. Observed. Unknown video: HTTP 404 |
| VAL-01 P1 | Pass | Send an empty questionExpected. 422 before a provider call. Observed. Blank question: HTTP 422 |
| SRC-01 P1 | Pass | Try JSON replacement after instructor uploadExpected. 409; instructor transcript remains the source. Observed. JSON/API transcript replacement after instructor upload returned HTTP 409. |
| CAP-01 P1 | Partial | Inspect Bunny captions after saving transcriptExpected. Caption track is attached in transcript language and selectable. Observed. Bunny exposes caption tracks [{'language': 'en', 'label': 'English'}]; HTML5 readiness=4, duration=75.264s. English caption file fetched with HTTP 200. Player caption-menu selection was not exercised. |
| LANG-01 P1 | Pass | Change course language after an uploadExpected. Existing transcript stays unchanged; instructor sees a mismatch warning. Observed. Changed only the QA course to Vietnamese. Existing en-US transcript and update timestamp stayed unchanged; beta instructor card displayed the language warning. Restored course language to en-US afterward. |
| LEC-01 P0 | Pass | Create a fresh lecture-video lesson in the QA courseExpected. Narration transcript is saved automatically with lecture_script origin. Observed. Fresh beta lecture job completed; origin=lecture_script, segments=7, generation_state=none. Uploaded XLSX/PPTX through presigned R2 URLs; no transcript was manually supplied. |
| ERR-01 P1 | Partial | Use a QA-only failed transcription fixture, then retryExpected. Readable error; Retry succeeds; video remains playable. Observed. Zero-credit toggle created a failed transcription with credit_used_up and a readable message. Restored QA allowance, called Retry, then real Gemini transcription became none, ready=True in 16.1s. This follow-up used API evidence; the failed-state UI was not captured. Readable failure and successful API retry are proven. Playback in the failed-state UI was not independently exercised. |
| QUO-01 P0 | Pass | Exhaust credit on a separate QA tenantExpected. 429 AI_ALLOWANCE_USED before stream headers; no provider work. Observed. Isolated tenant text allowance set to 0. Stream returned HTTP 429, application/json, AI_ALLOWANCE_USED; ledger rows 0 -> 0. No provider row created. |
| KEY-01 P1 | Pass | Use a separate own-key tenant without GeminiExpected. Upload remains available; automatic transcription explains the missing key. Observed. Isolated own-key OpenAI tenant reported no_gemini_key. A VTT upload succeeded. Provider ledger rows remained 1. The placeholder key was never used in an OpenAI call. |
| RATE-01 P1 | Pass | Reach the configured request rate on a separate QA tenantExpected. 429; no second billed request is started. Observed. 11 explicit QA requests in 6.7s. Statuses [504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 429]. Invalid QA Gemini credentials prevented successful provider calls; the final request was rate-limited. Ledger grew by 10 rows. |
| RACE-01 P1 | Pass | Upload while a QA transcription is pendingExpected. Instructor upload wins; late machine result cannot overwrite it. Observed. Fresh fixture upload raced with a provider ledger operation. Observed pending rows: 1; terminal statuses: ['completed']. Final origin: instructor_upload. All short quality jobs were already terminal; the long quality operation existed in the baseline. The only new transcription row belonged to this fresh fixture. Instructor source survived its completed late result. |
| PERF-01 P1 | Pass | Measure first event, first text and final completionExpected. Record actual timings; do not claim the deferred five-second target. Observed. Measured warm API stream: first text 7.2262s; final 8.405s. No five-second performance target is claimed. |
| BILL-01 P1 | Partial | Compare QA operation usage with ledger and provider invoiceExpected. Call count, token usage and charged amount reconcile. Observed. Inspected beta tenant ledger and signed-in AI Studio usage/spend/billing. Completed transcription and failed own-key attempts are recorded. AI Studio exposed aggregate Skill Pixel usage, but the accessible billing account linked a different project. No beta invoice or per-request provider reconciliation was available. Private financial values are excluded. |
| QUAL-01 P1 | Fail | Grade Vietnamese, noisy and long audio with an independent reviewerExpected. Use declared thresholds and report every failure; no broad quality claim from this short clip. Observed. Fresh beta transcription scored against licensed reference text: 4/5 clips passed the declared 15% normalized word-error threshold and timestamp bounds. Independent human review and absolute timestamp alignment remain unverified. |
| FB-01 P1 | Partial | Vote on one validated answer in a tagged QA sessionExpected. Expected rating/answer/lesson/request identifiers arrive; no conversation text. Observed. Clicked Helpful on a freshly validated beta answer in a QA browser session tagged is_test/test_run. The button became aria-pressed=true and a screenshot was saved. PostHog SDK/flags loaded successfully, but no matching event appeared in project 417708 after repeated queries. No synthetic analytics event was sent to replace the real UI action. Delivery, identifier payload and absence of conversation text remain unverified. |
| Question | Choice |
|---|---|
| Where to test? | An isolated beta QA course, public selling disabled. Existing customer lessons and shared credit settings were not changed. A separate QA tenant held the failure fixtures. |
| Where to publish? | Hoan’s Personal Cloudflare account, as requested. This site is separate from the earlier local LangGraph report. |
| What counts as a pass? | Dated live evidence for the stated case. Local automated checks, a merge and a deployed image alone do not prove a beta flow. |
| What remains after testing? | Original QA course, generated lecture, isolated QA tenant and courses, licensed reference videos, and synthetic learner enrollments. Private session files stay outside the report and repository. |