Left is what the app did before today, read out of the code. Right is what shipped. Real tokens, real fonts, real strings — the failure text on the left is copied verbatim from app.js and server.py, not imagined. Six surfaces, ending with the one that makes the compression thesis observable.
The app rejects on exactly three conditions: over 40 MB, not a PDF, no file. All three currently print the server's own words into a red box with one button that throws the upload away.
One lecture. About four minutes.
Slides are fine. Scans are fine.
In PowerPoint: File → Export → PDF, then drop it here. Nothing else changes.
Ten stages. Two are essential and kill the run if they throw — upload and graph extraction ("no graph = no lecture"). Everything else is wrapped in _try, so one artifact failing degrades that artifact and the rest still ships. The screen doesn't distinguish those two cases at all.
ResourceExhausted: 429 Quota exceeded for quota metric 'Generate requests per model per day' and limit 'GenerateRequests per day per model per project'
Shipped without the Ref a4f21 code — that has to be generated where the exception is caught, server-side. Logged. The raw exception is kept behind the disclosure instead of thrown away.
…and the SBAs tab looks identical to a lecture that simply has none.
The lecture itself came through — this is one output missing, not a failed run.
Not shipped: a scoped retry needs a per-artifact entry point on the server. Logged, not built — a button that silently re-ran the whole four-minute pipeline would be a worse lie than no button.
There is no success state. #dl is a bare <a href="/download/{jobId}"> — the file downloads and the screen does nothing. This is the moment the product actually delivered, and it is the only moment with no design on it.
↓ click, and this screen is unchanged
no valid cards to export
server.py:215 · shown only if you reach the URL; the button is simply hidden
Every card this lecture produced failed cloze validation, so there was nothing to pack.
A render error is caught and written into the panel as a raw exception message inside a <pre>. Same pattern on the Mindmap tab (app.js:252), which additionally dumps the whole mermaid source underneath it.
flowchart render error: Cannot read properties of undefined (reading 'nodes')
All three are _try-wrapped with [] as the default. When one fails you get an empty array, and an empty array renders exactly like a lecture that legitimately produced none. Absence and failure are the same picture.
It is not that the lecture had none — the step failed, and everything else is unaffected.
When a lecture genuinely has none, the same panel reads "Nothing here for this lecture." on the plain ground — different sentence, different colour, every time.
Shipped without a retry button, for the same reason as above.
The triage's own top pick — "if you build one thing from this document, build this." LAW 13 says review load falls as knowledge rises. A claim you have to take on trust is marketing; the same claim as a number you watch yourself is the product. The app was keeping no history at all, so there was nothing to compare against — that snapshot is now written at the end of every session, in localStorage, where the review state already lives.
Stop — sleep consolidates it. Come back for the next pass.
Stop — sleep consolidates it. Come back for the next pass.
17 cards have dropped out of rotation since your last session. That is the whole point — the load is meant to fall as the knowledge rises.
The part that took the thinking: the pile legitimately GROWS at a pass boundary, because starting a pass reactivates every card you have rested. A screen that said "it's getting smaller" there would be a false claim at the exact moment you can see it is false.
First time through, so there is nothing to compare it to yet. From here you watch this number, not the calendar.
Pass 3 reopened cards you had already rested — that is the design, not a setback. The count falls again as you clear them.