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.
3–4×
Returns per topic, spaced
The bar. By day 10 you can spec any StudyFix feature, direct an agent to build it, and
independently verify the result — including catching an agent that reports green on something
broken. You will not be typing production code. You will be the person no one can bluff.
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
| Principle | What 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
LAW 8, verbatim: "Block briefly to acquire, then interleave to make it stick."
Spacing is not fragmenting. Day 1 is all JavaScript, uninterrupted, because acquisition
wants a single deep block and because splitting a new topic across days raises extraneous load for
nothing. What spacing demands is that the topic comes back — not as new material, as a short
harder retrieval on material you already met.
Returns are cheap because of the between-pass rule: "aggressively drop
what you already own, so each pass is only the un-owned material." A return is 45–60 minutes, not
a slice of the day.
The one-line system
The topic comes back. Each time it's smaller, and the
task is harder.
MANIFESTO §3.8.1. Marked as a design rule, not an
empirical finding — but it is the correct organising slogan and it's downstream of LAW 5 and LAW 13.
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:
| Pass | The job | What it looks like for code |
| 1 · ORIENT | Build 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 · ENCODE | Bind facts into the slots |
Type it with the reference open. This is the immersion block. |
| 3 · MECHANISM | Stop 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 · TRIAGE | Break your own schema and log where it cracks |
Not a learning pass — an audit. Deliberately break it, read the error, log every hesitation. |
| 5 · INTEGRATE | Rebuild 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.
A failed cold retrieval confers almost no benefit. From STUDYFIX_MASTER_LESSONS
§4: "when initial retrievability is under 50% with no feedback, standard cold testing does
essentially nothing, while fading cues restore a substantial benefit."
Operating rule, verbatim: "start a card on Names; if you produce
less than ~half the points, step down a rung rather than grinding a blank page. Sit where recall is
effortful but you still get most of it." Staring at an empty file for forty minutes is not
desirable difficulty — it is a wasted forty minutes.
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
LAW 6: "The act of constructing the 'why' is what encodes — a wrong effortful attempt
beats reading a correct one." And the hard constraint: "Effortful wrong answers only help when
they get corrected. No generation-only cards."
Make It Stick ch.4 says the same. So: every blank-file attempt is followed
by opening the real version and reading the diff line by line. Metcalfe's 2017 hypercorrection
review is explicit that the learner must attend to and process the correct answer, not merely
be shown it. Skipping the diff turns the whole rep into a performance.
Metcalfe J. Learning from errors. Annu Rev Psychol 2017;68:465–489.
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:
- What does this do, to someone who has never seen a browser?
- What breaks if I delete it — and what breaks because of that?
- Why does it work that way rather than the obvious other way?
- How is this different from [the sibling API], in one sentence?
- 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
Self-explanation makes you better at rules and worse at exceptions.
Rittle-Johnson & Loehr 2016, constraint #1: it "reduces memory for details and promotes
overgeneralization — least suited to domains with important exceptions." Your own doc calls
shipping compression and self-explanation together without an exception register "the single most
dangerous combination in the product." The moment you've beautifully explained a general rule
("everything in JS is pass-by-reference for objects"), go find the exception — because the model you
just built is specifically the one that will fail you confidently.
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
By LAW 3's own definition this is a cram, and you should know what you're buying.
"Cramming spikes retrieval strength and builds far less storage strength per hour spent... cramming
buys the exam and nothing past it." Ten days of immersion will make you competent to direct and
verify this month. It will not by itself make that durable.
Two mitigations, both built in below: (1) the return blocks are precisely the spacing that converts
some of it to storage, and (2) there is a re-entry schedule at the end of this document. Do not
skip it — without it, a chunk of this decays by October.
And sleep is not slack. Carey: "sleep is learning — it improves
retention of what you studied the day before." Dehaene's fourth pillar is consolidation:
"practice every day, take advantage of every night." 12 hours of work + 8 hours of sleep + 4
for everything else is the actual budget. The 12 hours come out of everything except sleep. An
all-nighter in this fortnight destroys more than it buys.
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.
| Topic | D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9 | D10 |
| 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:
- Return block — 60–90 min, first thing. Yesterday-and-before, at a harder rung, reference
closed. It's first because retrieval before new material also acts as pretesting, and because it's
the block you'll skip if you leave it till you're tired.
- Immersion block — 10–11 hours. One topic, uninterrupted. Reference open, worked examples
open, AI on. This is where you learn.
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
Keep the Python pipeline. Rebuild the shell in Next.js + Supabase.
Your prompts, the knowledge-graph IR and the four deterministic guards are the moat and they're in
Python — rewriting them in TypeScript burns ten days on a translation that buys nothing. The
shell is what's broken: loopback-only, localStorage, launched from a terminal,
dies on a cache clear. Supabase is auth and a real database; Vercel is a URL. Days 4–8 build v2's
shell, calling your existing pipeline as a service.
Push back if you disagree — but decide before day 4, because SPEC.md
depends on it.
The ten days
D1JavaScript, 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.
D2Async, 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.
D3React
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.
D4Next.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.
D5Data — 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.
D6The 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.
D7Pipelines 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.
D8Evals — 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.
D9Attack 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.
D10Ship 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.
| Mistake | What happens | Fix |
| Secret in the browser | Anyone 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 Security | User 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 only | The 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 body | Someone sends userId: "not-mine" and your app
obeys. | A schema on every endpoint. Identity comes from the session, never from the request. |
| Unlimited AI endpoint | One 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 output | User 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. |
Before you take money or health data. Your users are medical students and
your inputs are lecture PDFs, so you are close to this line without crossing it. The moment there's
payment, or anything about identified patients, the bar goes from good practice to legal obligation —
GDPR, and a data-processing agreement with whichever model provider you use. That is not a ten-day
project and no checklist substitutes for advice from someone qualified in your jurisdiction. Build and
test on your own lectures until you've had that conversation.
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
| Type | Looks like | What 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. |
| Logic | Runs 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. |
| Integration | 401, 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.
- Linear algebra, calculus, statistics for ML
- PyTorch, TensorFlow, training or fine-tuning models
- Transformer internals, attention, backpropagation
- Data structures & algorithms interview prep
- CSS from scratch — Tailwind plus AI covers it, and your structure is already approved
- Docker, Kubernetes, AWS, CI/CD pipelines
- TypeScript generics, design patterns, testing frameworks as a subject
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
This is the part that decides whether the 120 hours survives to October. A ten-day block is
a cram by LAW 3's definition; the returns inside it convert some of that to storage, but not all.
Spacing scales with the retention interval, so past day 10 the gaps stretch.
Four re-entries, each one a rung-0 rebuild of one thing, gated on succeeding rather than on
being done — successive relearning (Rawson & Dunlosky) runs ~3–4 spaced sessions
each to criterion, and what predicts durability is not the count but whether each visit ended in a
successful retrieval:
| When | ~Date | The rep, 60–90 min |
| +3 days | 28 Aug | Blank file: the auth flow and one RLS policy set. Then
ship one small feature to v2 alone. |
| +1 week | 4 Sep | Blank page: all ten pipeline stages, plus write one new
guard from scratch. |
| +3 weeks | 18 Sep | Run the eval, change one prompt, defend the delta with
a number. |
| +6 weeks | 9 Oct | Full integrate pass — redraw the whole system from the
name alone, then ship a feature end to end. |
Anything you still can't produce at the fourth re-entry is the thing you
never actually learned, whatever day 10 felt like. That is LAW 10 doing its job.
Honest evidence status — what I am and am not claiming
- Tier 1, safe to lean on: retrieval practice (g≈0.50) and spacing (d≈0.54). The whole
return-block structure rests on these two and nothing else needs to hold for it to be worth doing.
- Tier 2, strong: transfer-appropriate processing, cognitive load theory and faded
scaffolding, expertise reversal, hypercorrection, the closed-book explanation finding.
- Moderate — real but not proven: self-explanation (g≈.55 vs passive, but only g≈.30
against another active strategy, which is the number that applies here since you're already
building), elaborative interrogation (d=0.46 immediate, 0.28 delayed — it fades), interleaving
("ultimate effectiveness currently unknown" — Dunlosky).
- Design, not evidence: the specific five passes in that order at those intervals are Tier 3
in your own corpus — "coherent design inside a supported principle". The "smaller and harder"
slogan is a design rule.
- Withdrawn, do not repeat: the "five passes because the forgetting curve reaches its
asymptote" justification was retracted on 2026-08-01 as folklore. Five is arithmetic — horizon ÷ gap.
For a 10-day horizon that arithmetic gives 5–7 touches, which is what the matrix above uses.
- Banned figures: the dual-coding "~65%" number (traced to a weak source, cut by your own
2026-07-13 audit) and the "Daley et al. 2014, d≈0.7–0.9" citation (Howard could not locate a matching
paper, flagged three times). Neither appears here.
- Not in your corpus: "learning styles" is neither endorsed nor rejected anywhere in these
files — it isn't mentioned. Worked examples exist only as Berthold's "faded, partially-completed
prompts". Analogy and concreteness are demonstrated in Howard's prose but never stated as rules. I
haven't attributed any of these to your research.
- LAW 13 (compression) is unbuilt and uncited — the manifesto itself calls it a representation
argument, not a memory finding, and names its own falsifier. The drop-what-you-own rule in the return
blocks uses it lightly; nothing here depends on it.