Daily listening lessons: verbatim evidence, one prepared lesson a day, and honest unknowns
Language: English | 简体中文
FLH started from questions I typed. The listening work adds a second source: French videos with my own transcripts, turned into exam-style listening exercises, then pulled from a playlist each day with at most one prepared lesson and an optional Telegram notice. It shipped as two changes, over two days.
My engineering contribution: separating source material from generated exercises, requiring every cited line to be verbatim, capping automatic spending at one attempt per day, and treating a timed-out or lost call as unknown rather than failed.
Published: 2026-11-09
Part 1: a lesson grounded in the transcript
A Listening view stores a video link, a title and an optional transcript I supply. Materials, transcripts and exercises are separate append-only tables. A link without a transcript waits; Prepare exercise is refused with 409 and no provider call.
The model must ground its output in the transcript. Every cited excerpt has to match a line verbatim, every segment must exist, and no timestamp may appear that the source does not have. An out-of-range segment, an invented time, a paraphrased excerpt or a provider error each store a failed exercise with its reason, and the transcript stays byte-identical.
Answers, reasons in English and Chinese, cited lines and notes stay hidden until Reveal. A cited 0:16 links to the video at &t=16s. A missed point becomes a normal learning record only after Save learning record, through the existing capture endpoint, so it enters the same traceable pipeline as typed questions.
Part 2: pull daily, prepare at most once
The daily pull reads a YouTube playlist through the official Data API, bounded to 1–200 items, 50 per request and 1 MiB per response, with the key in a header. Videos are deduplicated by ID, including ones I saved by hand, and new videos wait for a transcript. There is no speech recognition and no scraping.
With LISTENING_AUTO_PREPARE=daily, preparation runs at most once per local day in LISTENING_TIMEZONE, enforced by a partial unique index rather than application logic alone. The Pull now button and the scheduled command use the same service, so they share the cap and a run lease: an overlapping run gets 409 busy, and the command exits 4. A notification goes out only for the lesson that pull prepared, and contains only the title.
Unknown is not failed
Every outside call (OpenAI or Telegram) inserts its attempt row before the call and finishes it once. If the request was written and the response never came, the outcome is unknown, decided by httptrace.WroteRequest, not failed.
Nothing retries an unknown automatically, because it may already have been billed or delivered. Later pulls skip it. An explicit retry needs confirm_unknown_retry, and the button says may be billed again. Lost responses are looked up by key first, and only the same key is resent. The handlers detach the work from the client’s cancellation, so a closed tab does not abandon a completed result.
Verification
Both parts ran against local fakes of YouTube, OpenAI and Telegram with real SQLite, real handlers and real binaries. No real key, token or notification was used. The daily pull’s real-binary smoke passed 20 checks, 0 failures. All 13 backend and 6 frontend mutations were caught. One was missed at first, an unknown attempt on an older transcript, and the test was extended to cover it. make verify passed with 344 frontend tests at that snapshot.
Limits
- Real YouTube, OpenAI and Telegram responses were reproduced by fakes, not checked against the services. Exercise quality with a real model is untested.
- The transcript is mine and is not checked against the video.
- The daily cap counts attempts, so a failed or unknown attempt uses the day.
- The systemd timer was verified offline only, not installed.
- Listening is private: every route is refused by the public demo.
Implementation used Claude Code and Codex under my direction, task definitions and review.
Listening lesson validation · Daily listening validation · PR #130 · PR #131 · About me
- Title: Daily listening lessons: verbatim evidence, one prepared lesson a day, and honest unknowns
- Author: Sirui Liu
- Created at : 2026-11-09 12:00:00
- Updated at : 2026-11-09 12:00:00
- Link: https://vanquisher.world/2026/11/09/flh-listening/
- License: This work is licensed under CC BY-NC-SA 4.0.