120 hours to overqualified

Ten days. One topic per day, fully immersed — then that topic comes back, smaller and harder, until you can produce it cold. Built against the StudyFix codebase and against the learning science in your own strategy folder.

120h
12h × 10 days
1
Topic per day, blocked
3–4×
Returns per topic, spaced
20h
Pipeline engineering

How this course is built — and what the evidence actually says

Every structural decision below comes from the research in business/strategy/ and business/engineering-plans/research/. Tiers are quoted as your own corpus tiers them. Inflating a tier is the one thing Howard is instructed to treat as a firing offence, so nothing is inflated here.

The two that carry the weight — HIGH utility, meta-analytic

PrincipleWhat it forces in this course
Retrieval practice
g ≈ 0.50. Dunlosky et al. 2013 HIGH utility. PubMed 26173288
Every block ends by producing from blank, never by reading. Watching and reading are capped. You do not "review" anything in these ten days — you re-retrieve it.
Distributed practice (spacing)
d ≈ 0.54. HIGH utility. Optimal gap ≈ 10–20% of time-to-test (Cepeda).
10-day horizon × 10–20% = 1–2 day gaps. So every topic returns on roughly a 2-day cadence. This is the one thing the original 100-hours plan gets structurally wrong: it teaches JavaScript on day 1 and never returns to it.

Immersion is correct — and so is the return

The one-line system

The five jobs — each return does a different one

Your 5-pass engine (§3.5, LOCKED) says: "Each pass does a different cognitive job. That is the entire point. A pass that repeats the previous pass's job is a wasted pass." Mapped to code:

PassThe jobWhat it looks like for code
1 · ORIENTBuild the container before anything goes in it See the shape. Skim the whole topic's map with nothing memorised. Done when you can name the parts and say what each one breaks if removed.
2 · ENCODEBind facts into the slots Type it with the reference open. This is the immersion block.
3 · MECHANISMStop storing, start deriving Reference closed. Produce the code from the principle. "The pass almost everyone skips, and the reason week-2 facts are gone by the exam."
4 · TRIAGEBreak your own schema and log where it cracks Not a learning pass — an audit. Deliberately break it, read the error, log every hesitation.
5 · INTEGRATERebuild the whole thing from the name alone Blank file, blank editor, no AI. Free recall at structure level.

The five jobs in this order are Tier 3 — coherent design inside a supported principle, not a tested protocol. The retrieval and spacing underneath them are Tier 1.

Run warm. This is the rule most self-taught plans break.

The cue ladder — pre-committed, because you can't judge your own level

LAW 7 (expertise reversal, Sweller): "The fade is automatic because the student cannot judge their own expertise level — that judgement is exactly what the fluency illusion corrupts." So the rungs are set in advance, on the calendar, not by how you feel on the day:

RUNG 4  full worked example open beside you, type it       ← immersion block, hour 1
RUNG 3  file skeleton + comments, you fill the bodies      ← immersion block, later hours
RUNG 2  function signatures only, no bodies                ← first return (+2 days)
RUNG 1  one-line description of what it should do          ← second return (+4 days)
RUNG 0  the name of the feature. Blank file.               ← final return (+7 days)

If you get less than half at any rung, step DOWN one rung. Do not grind.

Generation without correction is theatre

Close the reference before you explain

Koh, Lee & Lim 2018 (Appl Cogn Psychol 32:401–410): teaching without notes ≈ retrieval practice; teaching with notes ≈ control, at one week. Your own ELI5 doc puts it as "a ward round with the notes in your hand" versus one where "someone took the notes away." Same four minutes, all of the benefit in one of them.

So: when you explain what a piece of code does, the file is closed and the AI chat is closed. Out loud, not typed — oral explanation shows the benefit, written repeatedly doesn't. Hoogerheide et al. 2016; Lachner et al. 2020 — the latter is flagged in your own corpus as "could not verify", so treat the oral-vs-written margin as directional.

The five prompts — and the two that are banned

Bisra et al. 2018 (Educ Psychol Rev 30:703–725, g=.55 overall) ranks prompt types: conceptualize g=.87 · explain g=.68 · justify g=.42 · metacognitive g=.19 (n.s.). Use the top of that list. Ask yourself these five, out loud, after every feature:

  1. What does this do, to someone who has never seen a browser?
  2. What breaks if I delete it — and what breaks because of that?
  3. Why does it work that way rather than the obvious other way?
  4. How is this different from [the sibling API], in one sentence?
  5. Say it again in plain English. (Re-probe yourself on any vague sentence — that's the Chi 1994 mechanism: keep talking, don't let vagueness pass.)

Banned: "How confident am I?" — metacognitive prompts are the one category with no detectable effect, and LAW 10 says the answer is worthless anyway. Multiple-choice self-quizzing — g=.24, not different from zero. Never pick from a menu. Always produce.

Nail the rule, then immediately hunt the exception

Explain correct code, not your own untested reasoning

Constraint #2 of the same paper: explaining your own reasoning is weaker than explaining known-correct information, and can be neutral-to-negative when your reasoning is often wrong. So: self-explain working, tested code and real docs. Do not spend an hour explaining your own untested architecture decision to yourself — you'll cement whatever's wrong in it.

The objective signal overrides the self-mark

LAW 10: "Fluent material feels learned; ease of processing is mistaken for strength of memory." And it's worse for beginners — poor performers are more overconfident (PMC6775028). So every day below ends with an objective check: a thing that runs or doesn't, on a live URL. "I feel like I got it" is not admissible evidence and does not close a day.

The honest problem with a 120-hour fortnight

The shape — one topic per day, four returns each

Read down a column to see a day. Read across a row to see a topic's life. Colours are cue rungs: encode (reference open) · derive (reference closed) · blank file.

TopicD1D2D3D4D5D6D7D8D9D10
JavaScript & async·····
Terminal & git·······
React······
Next.js & routing······
Data, SQL, auth, RLS·······
The AI layer······
Pipeline engineering······
Security······

Every day has the same two-part shape:

Breaks: 15–20 min every ~90 min. Your own research calls incubation productive — "stepping away lets stuck problems resolve" — and says to build breaks in rather than grinding to exhaustion. The 12 hours below are work hours; breaks sit on top.

Five rules that keep this from collapsing

01
Commit after every working state. Git is your undo button. Working feature → commit. Vibe coding without git is building on sand.
02
One feature at a time. Build → test in the browser → commit. Never stack three untested changes.
03
Never accept code you can't summarise. One sentence per file, out loud, reference closed. This rule is the entire product of these 120 hours — your ledger already contains agents reporting GREEN on something that doesn't work.
04
Keep SPEC.md. Purpose, data model, conventions. Pasted into every session. It is what stops an AI-built codebase drifting into incoherence.
05
Three-strike rule. Same bug fails three times? Stop. Revert. Describe it differently. Looping past three makes it strictly worse.

The architecture call

The ten days

D1

JavaScript, all of it

Immersion: the language. By tonight you can read a page of JS and say what it does, and you own a live URL you deployed yourself.
12h
Immersion — JavaScript12h
1h
Toolchain and accounts, done once, done properly
Node LTS → VS Code → Git → Claude Code, in that order (Claude Code needs Node). Then GitHub, Vercel, Supabase, Anthropic Console. This is LAW 12 in action — a broken environment on day 5 is extraneous load wearing a costume, so it gets pre-solved now, outside the learning hours.
0.5h
Lock the accounts before you build on themSecurity
2FA everywhere with an authenticator app, not SMS. Repo private. GitHub secret scanning with push protection ON. .env.local in .gitignore before your first commit. Not theoretical for you — this repo has leaked-key history.
1.5h
Deploy a blank app to a real URL
npx create-next-app@latest → push to GitHub → import into Vercel. Customise nothing. The point is to hit every deployment problem now, on day 1, instead of on day 10.
4h
Eloquent JavaScript, chapters 1–4 — typed, not read
Values & types → program structure → functions → data structures. Type every example into a file and run it. This is the one place you can't shortcut: reading without producing is the fluency illusion in its purest form.
1.5h
Objects, arrays, destructuring, the methods you'll see every day
map filter reduce find, spread, optional chaining, template literals, arrow functions, modules (import/export). This is 80% of what Claude will hand you. Work through javascript.info's fundamentals for anything Eloquent JS left thin.
1.5h
Discrimination pairs — the exception huntLAW 8
Not more material — pairs that differ on one axis, which is what builds discrimination rather than recall. For each, write the one-sentence difference from memory, then check: let vs const in a closure · == vs === · null vs undefined · map vs forEach · slice vs splice · value vs reference for objects. That last one is the rule whose exception will bite you — hunt it now.
1.5h
Read your own repo coldPipeline
Open studyfix/apps/web/server.py and studyfix/apps/worker/service.py. Don't try to understand them. Write down every line you can't explain. That list is your syllabus and you'll clear it by day 10 — it also gives you an honest day-1 baseline that isn't a feeling.
0.5h
Write DIRECTING.md
One page. What a good instruction to Claude contains: the observable behaviour, the acceptance check, the file if you know it. And the three phrases you will never accept again without running it yourself — "it works", "tests pass", "done".
Objective check — not a feelingBlank file, no AI, no docs: write a function that takes an array of objects and returns those where a property exceeds a threshold, then one that does the same asynchronously over an array of URLs. If the first fails, add an hour tomorrow. Don't advance broken.
D2

Async, the network, the terminal, git

Immersion: how code waits, and how you undo your own mistakes.
12h
Return — JavaScript · rung 31h
1h
Yesterday, from a skeleton
Take six things you typed yesterday. Keep only the function signatures and a one-line comment inside each; delete the bodies. Fill them back in with the docs closed, then open the originals and read the diff line by line. The diff is the mechanism, not the score. Anything you got wrong stays on the list by default — removing it is a deliberate act. Kornell & Bjork 2008: letting yourself drop items has "small but consistently negative effects on learning."
Immersion — async, HTTP, terminal, git11h
3.5h
Async JavaScript
Promises, async/await, try/catch, error propagation, Promise.all. Eloquent JS ch.11 plus javascript.info's async section. This is the concept that unlocks everything else — every database query and every model call is asynchronous.
2h
HTTP, fetch, JSON
Request and response, headers, API keys, and what JSON actually is. Status codes: 200 · 401 · 403 · 429 · 500. 429 is the one that's been sitting on your Gemini key since 19 June — by tonight you'll know exactly what it means, who emits it, and how you'd have caught it from a log.
2h
The terminal and how a computer is organised
MIT's Missing Semester, lectures 1–2. Paths, directories, environment variables, what PATH is. Most "it doesn't work" on day 5 is a path problem. Note: the 2026 iteration reorders things — lecture 2 is now Command-line Environment, not the 2020 "Shell Tools and Scripting".
2h
Git, properly
commit, push, branch, and above all git revert and git checkout. Learn Git Branching is visual and takes about an hour. This is rule 01 — the skill that makes reckless building safe.
1.5h
Read a diff and judge it — on real stakes
git diff, git log -p, git status. Then go clear the 1,336 uncommitted paths sitting in your repo from the 08-14 cleanup. Real material, real consequences, and it needs doing anyway. git add -A stays banned — stage explicitly.
Objective checkBlank file, no AI: a script that calls a public API, pulls three fields, prints them, and handles the failure case. Then break your own repo and recover it with git. Both must actually run.
D3

React

Immersion: how screens get built — enough to read any component Claude hands you and say what it does.
12h
Return — JavaScript & async · rung 21h
1h
Async from signatures only
Reference closed. Given only the signatures — firstSuccessful(urls), withRetry(fn, attempts, baseDelay) — write the bodies: fetch three URLs in parallel and return the first that succeeds; retry with backoff. Then diff against a correct version. Say out loud why await exists before you look anything up — a wrong effortful attempt beats reading a correct one, provided you then read the correct one.
Immersion — React11h
5h
react.dev — Describing the UI, then Adding Interactivity
Genuinely the best documentation on the web; don't substitute a video course. Skip Escape Hatches. Managing State is reference for now, not reading.
2.5h
Build tic-tac-toe
React's own guided project. Small, but it's where state clicks — and it's a worked example with the scaffold still on, which is exactly right for hour six of a new topic.
1.5h
Discrimination pairsLAW 8
One-sentence difference from memory, then check: useState vs useRef · props vs state · controlled vs uncontrolled input · key in a list vs array index · re-render vs re-mount. Then the exception hunt: name one case where the obvious rule about re-rendering is wrong.
2h
Structured output — the most important pipeline ideaPipeline
Placed today deliberately, three days before you use it, so it gets a spacing gap. A schema turns a model's paragraph into data your program can use. Zod and Pydantic side by side. Then open packages/schema/kg.py and work out why extra="forbid" is there and what breaks without it. That file is the spine of your entire product.
Objective checkBlank file, no AI, 25 minutes: a counter and a to-do list that both work in the browser. Then, docs closed and out loud: "props flow down, state lives in one place, changing state re-renders" — and point at each in code you didn't write.
D4

Next.js — and StudyFix v2's skeleton

Immersion: routing, layouts, server vs client. By tonight v2 exists as pages you can click between on a live URL.
12h
Return — React · rung 2  ·  git · rung 11.5h
1h
React from signatures only
Component signatures given, bodies blank, docs closed. Fill them. Diff. Under half? Step down a rung — reopen the tutorial and type it again rather than grinding.
0.5h
Git, derived
Deliberately break your repo three different ways and recover each without looking up the command. Log which one you had to look up — that's tomorrow's rung.
Immersion — Next.js10.5h
1.5h
React Foundations
Vercel's bridge from plain JS → React → Next.js. Fast, and it fills gaps you don't know you have.
4h
Next.js Learn — the dashboard app
The canonical course, written by the people who build the framework. File-based routing, layouts, server vs client components, data fetching, streaming. Server-vs-client is the one that decides where your API key lives — do not skim it.
2h
Write SPEC.md for StudyFix v2
Before any real code. One sentence on what it does, the stack, the data model, conventions, and what's explicitly out of scope. Pull the locked decisions out of MANIFESTO.md and the approved structure out of DESIGN.md — this is where they become machine-readable. Pasted into every session from here on.
3h
Scaffold the real app
Fresh Next.js project. Every page the approved structure needs — sign-in, subject home, lecture surface (Encode · Retrieval · Practice) — navigation between them, hardcoded placeholder content. Deploy it. Commit after each page.
Objective checkA live URL where you click through StudyFix's real structure. Nothing works yet and that is correct. Plus, docs closed, out loud: what a server component is, what a client component is, and which one your API key is allowed to touch.
D5

Data — the day that makes it usable

Immersion: SQL, Supabase, auth, RLS. This kills the single biggest reason the current app is unusable.
12h
Return — JavaScript & async · rung 11h
1h
From a one-line description
"A function that fetches a lecture, validates the shape, retries twice on 429, and throws a typed error otherwise." Blank file, no signature given. Then diff. This is the third touch on async — day 2, day 3, day 5 — which is your 1–2 day gap holding.
Immersion — data, auth, RLS11h
1.5h
SQL and schema basics
Tables, rows, columns, primary and foreign keys, SELECT/INSERT/UPDATE/DELETE. You need to read SQL, not write it fluently — Claude writes it, you check it.
2h
Wire Supabase into Next.js
Follow the official quickstart exactly once on a scratch project before touching v2. Worked example first, then the real thing — that's the CLT ordering, and skipping it is how you spend four hours debugging your own app instead of learning the pattern.
2.5h
Auth, Row Level Security, default-denySecurity
Sign-up, log-in, sessions. Then RLS on every table, written default-deny — no policy means no access — with narrow policies scoped to auth.uid(). Two hard rules: the service_role key bypasses RLS entirely and must never appear in client code, and hiding a button in the UI is not access control. Current docs point at getClaims(), not getSession(), for protecting pages — older tutorials teaching getSession() for authorization are giving unsafe advice.
1h
Environment variables and secrets
.env.local, what NEXT_PUBLIC_ means (it means the browser can see it — never a secret), and setting the same variables in Vercel's dashboard.
4h
StudyFix's real schema — the migration off localStorage
Design and create the tables: lectures, graph, cards, review state, mastery, pass state, exam dates. Wire one page end to end — form → database → display. Everything that lives in localStorage today and dies on a cache clear now lives in Postgres. Deploy and confirm on the live URL, not locally.
Objective checkData you typed on the live site appears in the Supabase dashboard, RLS is on for every table, the Supabase linter shows zero unprotected tables, and you can sign in on your phone and see your own row.
D6

The AI layer

Immersion: one model call, done properly — server-side, schema'd, saved, rendered.
12h
Return — React + routing · rung 1  ·  RLS · rung 31.5h
1h
React from a description
"A page at /lectures/[id] that fetches one lecture server-side, lists its cards, shows a loading state, and filters by pass." Blank file — this covers the React and the routing return in one rep. Diff after.
0.5h
Write an RLS policy from memorySecurity
Default-deny, scoped to auth.uid(), for the cards table. Then check it against the docs. Getting this one wrong is how apps leak every user's data — so it recurs three times before day 10.
Immersion — the AI layer10.5h
1.5h
What a model is, as a component
A stateless function: text in, text out, no memory between calls. Tokens, context window, temperature, system vs user vs assistant roles.
2h
Generating text and structured output
You did the theory on day 3 — this is the implementation, and the gap between them is the point. Note the v7 API change: structured data now uses Output.object() / Output.array().
1.5h
Tool calling and streaming
The model never runs anything — it requests, your code executes, you hand back the result. Streaming, and what it does to your UI.
1.5h
Prompt injectionSecurity
Anything a user types reaches the model as instructions, and the model cannot tell your instructions from theirs. Treat model output as untrusted input — never execute it, never build SQL with it, never render it as raw HTML. For you specifically: a lecture PDF is user input, and a PDF can contain instructions.
4h
Wire one real call into v2, end to end
Route → auth check → validate input → model call → structured result → saved to Postgres → rendered on screen. The model call happens on the server only; your key never goes near the browser. Deploy. Commit.
Objective checkThe live site does one AI-powered thing, and — reference closed, out loud — you can name every step between the click and the result, and say which parts run on the server and why.
D7

Pipelines and guards — your moat

Immersion: one call becomes ten stages, and you build the thing that makes the output defensible.
12h
Return — JS · rung 0  ·  git · rung 0  ·  routing · rung 31.5h
1.5h
Blank file, no cue, no AI
From the feature name alone: an async fetch-with-retry module; a Next.js route that validates a body and writes a row. Plus recover a broken repo with no lookup. This is the derivation test — hide it, can you reproduce it? Anything you can now regenerate from the principle comes off the practice list. Anything you can't stays on, by default.
Immersion — pipeline engineering10.5h
3h
Multi-stage pipelinesPipeline
The jump from one call to ten. Prompt chaining, routing, parallelisation, orchestrator-workers, evaluator-optimizer. Why an intermediate representation beats chaining strings — your graph IR is exactly this, and it's why every surface (doc, index, flowchart, cards, SBAs, Anki) is a render of one extraction rather than nine separate prompts. Then map your own: read service.py's process_lecture() top to bottom and write out the ten stages in order, with what each takes in and puts out. This is the contract v2 calls, and it's what you reproduce from memory on day 9 and day 10.
2h
When the model returns garbagePipeline
Validation failure, partial JSON, hallucinated fields, refusals, truncation at the context limit. Repair vs retry vs fail loud. Your pipeline has MAX_REEXTRACT_PASSES = 2 and MAX_FIX_VERIFY_PASSES = 1 — by the end of this block you can say why those are bounded and exactly what happens at the bound.
4h
Deterministic guards — build one by handPipeline
This is your moat and you should be able to write one. A guard is plain code, no LLM, that set-diffs output against input and forces a bounded retry on anything missed — never a model checking its own work. Write one from scratch, then read coverage_guard.py, doc_coverage.py, edge_label_guard.py and source_coverage.py's number_misses(), and say what each one's denominator is. Graph-as-denominator vs source-PDF-as-denominator is the difference between your honest claim and a false one.
1.5h
Grade the agentRule 03
Take five files Claude wrote for you this week. Grade each against a rubric you write first: does it validate input? does it re-check the session? can I summarise it in one sentence? You acquire the eye by judging, not by reading a spec — this is Module 3 of your own course architecture, turned on yourself.
Expect the wallDay 7 or 8 is usually the day nothing works and the AI confidently breaks things. It's structural, not failure. Revert to the last good commit, take the break, come back and describe the problem differently. Objective check: a guard you wrote, running, that catches a deliberately dropped fact.
D8

Evals — the biggest hole in your company

Immersion: stop arguing about prompt quality and start measuring it. Plus the core loop finishes.
12h
Return — React · rung 0  ·  structured output · rung 31.5h
1.5h
Blank file: a review screen
From the name alone, no AI: a component that shows one card, flips on space, and grades on two keys. Then a Pydantic schema for a lecture graph, from memory. Diff both.
Immersion — evals and the core loop10.5h
5h
Build the eval harnessPipeline
You have a year of intuition about what makes a good card and zero mechanical way to prove a prompt change improved anything. Build: a golden set (10 lectures you know cold, with the cards you'd accept), a scoring function, a regression run, and a number that moves. Then a prompt change becomes a measurement instead of an argument. Your EVAL_HARNESS.md specifies the wrong stack — this replaces it. Start with error analysis on real output, not with a metric.
3.5h
Finish the core loop
Upload a lecture → pipeline runs → cards land in Postgres → review queue reads from Postgres. One feature at a time, ~45 min per cycle. Past 90 minutes means you bit off too much: revert and split.
2h
Loading and error states
A full lecture run takes minutes and sometimes fails. Every stage needs a visible state and a message that says what went wrong. This is the line between prototype and testable — and it's one of the two backlogs you logged on 08-10 and never dispatched.
Objective checkChange one line of a prompt, run the eval, and state whether it got better with a number. That's the capability; the number is the evidence.
D9

Attack it, and price it

Immersion: security and cost. You attack your own app before a stranger does, and you learn what one lecture actually costs you.
12h
Return — RLS · rung 0  ·  pipeline stages · rung 31.5h
1.5h
Blank file, blank page
Write the full RLS policy set for v2 from the table names alone. Then, on paper, the ten stages of process_lecture() with inputs and outputs. Diff both against the real thing. Whatever's still wrong on the fourth touch is what you genuinely don't own — write it down for the re-entry schedule.
Immersion — security and cost10.5h
3h
Attack your own app with two accountsSecurity
Create user A and user B. Logged in as A, try to reach B's data: edit IDs in the URL, call your API routes directly with curl, replay A's requests with B's record IDs swapped in. Every leak is a missing RLS policy or a missing server-side check. The highest-value hours in the ten days.
2h
Secrets sweep, dependencies, backupsSecurity
Search the whole repo — and git history, not just current files. A key committed on day 4 and deleted on day 6 is still public. This repo has known leaked-key history, so this block is not optional for you. Rotate anything exposed, npm audit, Dependabot, Supabase point-in-time recovery, security headers.
3h
Cost, limits and abusePipeline
Your unit is a whole lecture, not a chat message. Token maths on a real 40-slide deck through ten stages — Gemini charges ~258 tokens per PDF page, capped at 50 MB / 1000 pages, and on Gemini 3 native embedded PDF text is extracted free while image-based pages count as IMAGE tokens. Caching, batching, and which stages can drop to a cheaper model without touching fidelity. Then: hard spend limit on the key, per-user rate limit, input length cap. By the end you can say what one lecture costs and what you'd have to charge — a number missing from every pricing conversation you've had.
1.5h
Long documents and image-only slidesPipeline
Chunking, context limits, why a 90-slide lecture isn't one call. Your vision_text() is a stub returning an empty string, so every diagram-only slide is invisible to your source-coverage denominator right now. Decide and spec the fix.
1h
Read your own codebase
Every file you shipped this week, one sentence each, out loud, file closed. Rule 03 applied retroactively. Anything you can't explain, ask now — not during a demo.
Objective checkA cannot reach B's data by any route you tried. Zero secrets in git history. And you can state the cost of one lecture in dollars.
D10

Ship it, then study from it

Real URL, your own real lectures, and a Step 1 session inside the thing you built.
12h
Return — everything · rung 02h
2h
The integrate pass
Blank page, nothing open, no AI. Draw the whole of StudyFix v2 from the name alone: every page, every route, every table, every pipeline stage, where the key lives, where the auth check happens, what each guard's denominator is. Free recall at structure level — the highest-value retrieval act available, and the only measurement that distinguishes owning the mechanism from having memorised the outputs. Then open the repo and diff.
Immersion — ship10h
2h
Production deploy, properly
Every environment variable set in Vercel. Confirm every feature on the live URL, not locally — this catches the classic works-on-my-machine gap.
1.5h
Logging you can actually readPipeline
Per stage: what the model was sent, what came back, how long, what it cost, which guard fired, how many retries. Without it a bad card is unexplainable; with it every complaint is traceable to a stage. Logs must not contain full prompts with personal data, or keys.
3h
Five of your own real lectures
Not the Aortic Stenosis fixture. Five real Step 1 lectures you know cold, so you can judge the output as an expert. Write down every wrong card and which stage produced it. This is your own course architecture's rule — the exercise always runs on the learner's own real material, never a toy example.
2h
Cross-model auditPipeline
A model auditing its own output is the weakest possible floor — self-reflection fails systematically. Wire a genuinely different model family as the auditor. Your AUDIT_PROVIDER currently falls back to a Gemini self-audit when nothing is configured, silently — that fallback is exactly the kind of quiet downgrade your own honesty rules exist to prevent.
1.5h
Study from it, for real
One full Step 1 session, in the app, on the live URL, on your own material. This is the acceptance test for the entire 120 hours. If you don't want to use it, it isn't done — and now you know enough to say precisely why.
The barYou've shipped it and you've studied from it. For all ten pipeline stages you can name what goes in, what comes out, what it costs, and how you'd know if it got worse. And no one can tell you it's green when it isn't.

The security six — read now, and again on day 9

Almost every breach of a small app is one of six mistakes, none of them exotic. An AI will happily write code containing all six, because the code works — insecure code is not broken code, which is exactly why testing won't catch it.

MistakeWhat happensFix
Secret in the browserAnyone opens dev tools and takes your key. You find out from the bill.Keys server-side only. NEXT_PUBLIC_ means public. service_role never in client code.
No Row Level SecurityUser A reads everyone's rows by changing a number in a URL. RLS on every table, default-deny, scoped to auth.uid(). Verify with two accounts, not by reading the policy.
Auth checked in the UI onlyThe button is hidden; the endpoint isn't. One curl walks past it.Every route re-checks the session server-side. Hiding UI is cosmetics.
Trusting the request bodySomeone sends userId: "not-mine" and your app obeys.A schema on every endpoint. Identity comes from the session, never from the request.
Unlimited AI endpointOne person loops it overnight; you wake to a four-figure bill. Per-user rate limits, input length caps, hard spend limit on the key.
Trusting model outputUser text becomes instructions; the model is talked into a tool call it shouldn't make.Model output is untrusted input. Validate and scope every tool call server-side before it runs.

The security prompt — run before every commit

Review this code as a security auditor. For each issue give the
severity and the exact fix. Check specifically:
1. Any secret reachable from the browser
2. Any database access not protected by RLS
3. Any endpoint that doesn't re-verify the session server-side
4. Any user input used without schema validation
5. Any user identity taken from the request instead of the session
6. Any model output that gets executed, rendered as HTML,
   or used to build a query
7. Any AI endpoint without a rate limit or input size cap

Do not tell me it looks fine. Assume there is at least one issue
and find the most serious one.

When you're stuck

TypeLooks likeWhat to do
Environment"command not found", "module not found", works for everyone else Versions, reinstall, right folder. Search the exact error plus your OS.
Syntax / type"undefined is not a function", "cannot read property of undefined" Something is a different shape than you assumed. Print the variable. Nine times in ten it's null, or an array where you expected an object.
LogicRuns fine, wrong answer, no error at all The hardest kind. Print values at each step until reality diverges from what you expected. That line is the bug.
Integration401, 403, 429, 500, CORS, timeouts, "it works locally" Your code is probably fine. Keys, environment variables, permissions, RLS policies, quota.

Read the stack trace bottom-up: the last line is the error, the lines above are the path that got there. Ask by pasting the entire trace, not your summary of it — say what you expected, what happened, and what you already tried. Never "it doesn't work"; that sentence contains no information.

What you are deliberately not learning

All real, all useful, none load-bearing for shipping this. LAW 9 is the justification: far transfer is mostly a myth, so there is no general-thinking module to take — judgment falls out of a large store of concrete, stack-specific patterns plus reps at telling them apart.

And three study techniques your own research rules out: highlighting, rereading and summarisation are LOW utility (Dunlosky). Mnemonics are a last resort for genuinely underivable facts, then tested — never the default. Multiple-choice self-quizzing is g=.24, statistically indistinguishable from zero. Produce; never pick.

After day 10 — the re-entry schedule

Honest evidence status — what I am and am not claiming

Built 2026-08-15. Course structure derived from business/strategy/COURSE_ARCHITECTURE.md, MANIFESTO.md §3.5 / LAWs 1–13, RECALL_MECHANISM_howard_2026-07-29.md, ELI5_ENCODING_howard_2026-08-01.md, engineering-plans/research/pedagogy_{foundation,evidence_pubmed}, learning_books_synthesis, make_it_stick_audit, STUDY_SYSTEM_research_based, STUDYFIX_MASTER_LESSONS.md. Technical content re-cut from Downloads/100-hours-1.html against studyfix/README.md, service.py, DECISIONS.md and JOBS.md. Every external link verified live on 2026-08-15. Supersedes LEARNING_APPS.md.