Chapter 10 — Reps
These reps are not warmups beside the milestone. Done in order, they are the increment: by Rep 11 the slices are merged, the logs are current, and the demo is recorded.
Ground rules
- Work on YOUR project. Every rep operates on your own repository, your own requirement ids, your own stack. PantryPilot and TraceLens are examples in the chapter; they are not the assignment.
- Log the hours as you go. Every rep in this file is real work. Thirty seconds at the end of each session, in
docs/hours-log.csv. This is the week that discipline dies if you let it. - Log the assistant, in the same session. Anything drafted by an assistant that survives into the repository gets an entry in
docs/ai-usage.mdbefore you close the laptop. - Nothing merges that fails the definition of done. The gate has to be allowed to say no or it is decoration.
- Write the reflections in plain prose. A rep is not finished until you have written the two to four sentences it asks for. The writing is where the learning lands.
Slicing the work
Rep 1 — Cut this week’s slices
Open your requirements specification and take only the Must-have functional requirements that are not yet built. Choose three to five that can each go end to end this week, ordered so the riskiest one is first. Write a slice card for each:
SLICE: FR-__ <one sentence a user would recognize>
Layers: <interface> → <logic> → <storage> → <integration, if any>
Demo in one sentence: ____________________________________________
Acceptance criteria to satisfy: AC-__, AC-__
Estimate (three-point): optimistic __ h | likely __ h | pessimistic __ h
Riskiest unknown: _______________________________________________
Reflect: Which slice did you put first, and is it first because it is the riskiest or because it is the most fun? If those are different slices, say why you are overruling the rule — or reorder.
Rep 2 — Find the horizontal task hiding on your board
Read every open task on your board and mark each one V (ends in observable behavior) or H (ends in a layer). For every H, either fold it into a V slice or write one sentence explaining why it must exist alone.
Reflect: How many H tasks did you have? Horizontal tasks are not evil — a migration is a migration — but a board that is mostly H is a board that cannot demo anything in Week 15. What is your V-to-H ratio?
The gate
Rep 3 — Adapt the definition of done, then use it as a weapon
Copy code/definition-of-done.md into your repository as docs/definition-of-done.md and adapt the bracketed parts to your stack. Then take a task you already moved to Done last week and run all ten checks against it, honestly.
Task: ______________ Checks passed: __/10 Checks that fail: __________
What I am doing about it: fix now / log a defect / accept with reason
Reflect: Which check failed first? Almost every student fails on the same one — the test, the docs update, or the log entry. That is your personal weak point for the next six weeks; name it out loud.
Rep 4 — The four passes on your ugliest file
Pick the file in your repository you least want someone else to read. Run all four self-review passes from code/definition-of-done.md on it — diff, stranger, adversary, contract — and record what each pass found:
| Pass | Findings | Fixed / logged / accepted |
|---|---|---|
| 1 Diff | ||
| 2 Stranger | ||
| 3 Adversary | ||
| 4 Contract |
Reflect: Which pass found the most? Pass 3 usually wins, and pass 4 usually finds the one that matters. If pass 4 found an acceptance criterion with no line of code behind it, you just caught a requirement you were about to claim falsely in Week 16.
Rep 5 — Open a pull request to yourself
Branch, push, open a pull request in the web interface, review your own diff there, leave at least two review comments on your own code, then merge. Confirm CI ran on the branch before the merge.
Reflect: Did the web diff view show you anything the editor did not? Most students find at least one thing — unfamiliar presentation is a cheap substitute for a second pair of eyes.
Working with the assistant
Rep 6 — A prompt contract, not a wish
Take one non-trivial piece of this week’s work. Write the wish version of the prompt first (one line, the way you would naturally type it). Then write the contract version: context, task, explicit function signature, behavior on every failure mode, constraints, and the closing instruction “then list every assumption you made that I did not state.”
Run both. Save both outputs.
Wish prompt: ______________________________________________
Contract prompt: saved at prompts/YYYY-MM-DD-____.txt
Assumptions the model listed that I had not stated: ____________
Reflect: Compare the two outputs. What did the wish version assume about your project that is not true? Those assumptions are the two hours of reconciliation you just avoided.
Rep 7 — Explain it, break it, rewrite it
Take the assistant-drafted code from Rep 6 and put it through all three tests before it merges.
- Explain it out loud, line by line, without re-reading. Note every line you stall on.
- Break it with the hostile inputs from the adversary table — empty, huge, malformed, timed out, 429.
- Rewrite the hardest function from memory in your own naming and your project’s style.
Lines I stalled on: ______________________________________
What broke it: ______________________________________
Could I rewrite it? yes / no — and what I had to look up: ______
Reflect: If you could not rewrite it, you have found the module you do not own yet. What are you going to do about that this week — study it, or replace it?
Rep 8 — Write both ai-usage entries
Using code/ai-usage-log-template.md, write the entry for the Rep 6/7 session twice: once badly (one line, the way you would if you were rushing) and once properly (tool, ask, accepted, changed, verified, requirement id). Commit only the good one to docs/ai-usage.md.
Reflect: Read the bad one as if you were a grader who has never met you. What would you assume about the student who wrote it? That assumption is exactly what a thin log buys you.
The record
Rep 9 — Rewrite five bad commit messages
Run git log --oneline -20 on your own repository. Find the five worst messages and rewrite them as they should have been — subject line saying what, body saying why, with the issue and requirement id.
| Actual message | What it should have said |
|---|---|
Then, for the rest of this week, commit with git add -p and write every message in an editor rather than with -m.
Reflect: How much of why is recoverable from your history right now — say, three weeks from now, when you need to know why you chose the retry count you chose? Be honest.
Rep 10 — Reconstruct one honest day, then run the report
Pick a day in the last two weeks you did not log properly. Rebuild it from evidence only:
git log --since=2026-03-17 --until=2026-03-19 --date=short --pretty='%ad %h %s'
Add browser history, editor recents, and your board. Estimate in quarter hours, and label the row [reconstructed from commits]. Then run the report over your real log:
python3 tools/hours_report.py docs/hours-log.csv
Compare its output against the sample in code/hours-log.csv — that log covers Weeks 1 through 10 of the running example and clears every pattern check. Copy code/hours_report.py over the Week-1 script at tools/hours_report.py — same columns and same command, now with the weekly rollup, phase mix, burn-down, and honesty checks — and run it on your own file weekly from here to Week 16.
Reflect: What did the report flag? And separately: what does your phase distribution say about where the semester actually went? If Construction is 15% of your hours in Week 10, that is not a scandal — it is a fact you now have to plan around.
Rep 11 — The secret you almost committed
Search your own history for credentials, then fix your process so it cannot happen again.
# 1. did an env file ever get committed?
git log --all --oneline -- '*.env' '*.env.*' '*credentials*' '*secrets*'
# 2. anything that looks like a literal credential in the working tree
git grep -nEI "(api[_-]?key|secret|password|token)[\"']?\s*[=:]\s*[\"'][^\"']{8,}"
# 3. same pattern across history (slow on a large repo — let it run)
git grep -nEI "(api[_-]?key|secret|password|token)[\"']?\s*[=:]\s*[\"'][^\"']{8,}" \
$(git rev-list --all) | head -20
Whatever you find, decide in writing: rotate now, or confirm it was always a placeholder. Then verify your ignore file covers the real config file, and confirm every credential your project needs is read from an environment variable and documented — by name only — in README.md.
Credentials my project uses: _______________________________
Read from: env var / secret store / (be honest) a literal
In history? yes -> rotated on ____ | no
Ignore file covers: ______________________________
Reflect: If a real key were in your history right now, what would your next four steps be, in order? Write them down. The reason to write them today is that the day you need them you will be panicking.
Rep 12 — The five-minute demo, rehearsed and recorded
Write the demo script — literal clicks or commands, in order, with the exact input values — commit your seed data, and rehearse the three acts on a timer: the claim (45 s), the software (3 min), the evidence and the gap (75 s). Then record it.
Act 1 opening line (write it verbatim): ________________________
Act 2 script steps: 1. ______ 2. ______ 3. ______ 4. ______
Act 2 failure path shown: ______________________________________
Act 3 what is NOT done, and when it is scheduled: ______________
Recorded fallback saved at: ____________________________________
Reflect: Time the first run. Where did you go over? The overrun is almost always in Act 2, and almost always because you improvised instead of following the script. What are you cutting?
Done? One Last Thing.
The full-week dress rehearsal. Run the whole loop end to end, in one sitting, as if the milestone were due tonight:
- Every slice from Rep 1 is merged, and every merged task passes all ten checks in
docs/definition-of-done.md. Any that does not gets moved back off Done — publicly, on the board, where your own board can embarrass you. git log --oneline -15reads as a story a stranger could follow. Nowip, nofix, no forty-one-file dumps.docs/ai-usage.mdhas an entry for every assistant contribution that survived into the repository, each one naming what you changed and how you verified it.python3 tools/hours_report.py docs/hours-log.csvruns clean: no pattern flags, and the cumulative burn is a number you can defend out loud.- The five-minute demo runs from the script, on seeded data, with the recording saved as the fallback — and it ends with you naming what is not done.
- Everything is committed and pushed, and CI is green on the default branch.
If that loop runs clean tonight, Milestone 10 is already finished and you spent the week building instead of assembling. If it does not, you have just found out on a Wednesday instead of a Sunday, which is the entire point of a dress rehearsal.
Up next: Milestone 10