Chapter 7 — Reps
These reps are not warm-ups around the milestone. They are the milestone, built one piece at a time. Work them in order and by the end you will be holding a work breakdown, a schedule, a burn-down baseline, a risk register, and a scope decision you can defend.
Ground rules
- Work on YOUR project. Every rep operates on your real specification, your real requirement identifiers, your real hours. PantryPilot is an illustration, not a substitute.
- Estimate before you look. Write your number, then run the script or open the widget. An estimate you produced after seeing the answer teaches you nothing.
- The assistant proposes tasks; you propose durations. Every hour figure in your plan is yours. Strike anything a model wrote in the estimate column.
- Everything lands in the repository.
docs/plan.mdanddocs/risk-register.mdgrow rep by rep, with dated commits. If it is not committed, it did not happen. - Write the reflection. A rep is not done until you have written the two to four sentences it asks for. Keep them in the milestone document; the reflections are where the grader sees you thinking.
Group A — Getting the work on the table
Rep 1 — Inventory the invisible work
Before you decompose anything, list the work packages you had not planned to write down. Use §7.2 as a prompt list, then add three that are specific to your project.
Invisible work package In my WBS already? Rough hours
-------------------------------- ------------------- -----------
Repository scaffold + CI [ ] yes [ ] no ____
Seed / fixture data [ ] yes [ ] no ____
Error handling + edge cases [ ] yes [ ] no ____
Accessibility pass [ ] yes [ ] no ____
Secrets, config, deployment [ ] yes [ ] no ____
Reviewing AI-generated code [ ] yes [ ] no ____
README / runbook / handoff [ ] yes [ ] no ____
<yours> [ ] yes [ ] no ____
Reflect: How many boxes came back “no”? Add those hours up. That number is how wrong your plan was ten minutes ago — write it down before you fix it, because you will want the humility later.
Rep 2 — Decompose one work package properly
Take the single work package you understand least well and decompose it to the 1–6 hour rule, using the layout in code/wbs-template.md. Every task gets an identifier, a requirement trace, a done-when, and a dependency.
| Task | Name | Reqs | O | M | P | E | Done when | Depends on |
Reflect: Which task did you want to leave at eight hours because splitting it felt fussy? Split it anyway and say what the split revealed — a decision you had not made, or a step you did not know how to do.
Rep 3 — The bad-WBS autopsy
Here is a real one, of the kind that gets submitted every semester:
1. Set up project (1 week)
2. Build backend (3 weeks)
3. Build frontend (3 weeks)
4. Add AI features (1 week)
5. Test and deploy (1 week)
Name five distinct defects. Then rewrite item 2 as a proper work package with at least four tasks, estimates, traces, and done-whens.
Reflect: Which of the five defects is the most expensive, and in which week does the bill arrive? Be specific about the week — that is the skill.
Group B — Estimating like a professional
Rep 4 — Three-point estimate everything
Give every remaining task an O, an M, and a P, and compute E = (O + 4M + P) / 6. Do the arithmetic by hand for the first five so the weighting stops being magic, then let the spreadsheet or code/plan-check.py do the rest.
Reflect: For your first five, how did E compare to the single number you would have written before this chapter? Report the average difference as a percentage. That gap is the planning fallacy, measured on yourself.
Rep 5 — The spread test
Compute P / O for every task. Every task above 4 gets one of two treatments: split it into pieces you understand, or convert it into a timeboxed spike with a hard cap and a written deliverable.
| Task | O | P | P/O | Verdict (split / spike) | Spike cap | Spike deliverable |
Reflect: How many tasks failed the spread test? Where do the spikes have to sit in your schedule for their answers to arrive in time to matter?
Rep 6 — Compute your calibration factor
Open docs/hours-log.csv. For every task you both estimated and finished, compute the ratio of actual hours to expected hours. Then multiply every remaining estimate by that factor.
calibration factor = (hours actually spent) / (hours expected)
Reflect: What is your factor, and how many tasks is it built on? If it is fewer than eight, say so in one sentence and state how you will strengthen the sample by Week 10. Then answer the uncomfortable question: are you slower than you thought, or were your done-whens too vague to fail?
Rep 7 — Run the checker
Export your WBS in the column layout of code/wbs-sample.csv. Run the sample first, so you know what good output looks like, then run your own:
python3 plan-check.py wbs-sample.csv
python3 plan-check.py my-wbs.csv --capacity 4,12,12,12,12,12,12,6,5 --buffer 0.25
Reflect: What is your verdict line, verbatim? If you are over budget, by how many hours — and which week does the script say the plan first exceeds remaining capacity? Copy that sentence into your milestone document; it is the sentence the whole week turns on.
Group C — Schedule, buffer, and risk
Rep 8 — Build the capacity table you will actually live in
Do not copy §7.1’s table. Build yours. Start from 15 hours a week, subtract the course overhead honestly, and then subtract the weeks you know you will lose — the exam week in another course, the trip, the shift you cannot move.
| Week | Course overhead | Known losses | Available for the project |
Reflect: What is your real total, and how far is it from 87? If your number is higher than 87, name the specific thing that makes you faster than the model. “I’ll just work more” is not a thing.
Rep 9 — Declare the buffer and find the gap
Compute plannable effort: available hours × (1 − buffer). Use 25% unless you can argue otherwise in one sentence. Put your calibrated WBS total next to it.
Available ______ h · Buffer ______ h · Plannable ______ h
Calibrated WBS total ______ h · Gap ______ h
Reflect: Was your first instinct to lower the buffer or to cut scope? Both close the gap on paper. Only one of them still closes it in Week 13.
Rep 10 — Twelve risks, culled to eight, with triggers that can fire
Write twelve candidate risks, at least two in each of the five categories in §7.6, each phrased cause → uncertain event → consequence. Score likelihood and impact (impact in hours lost), compute exposure, sort, and keep the top eight. Give every survivor an owner and a response using code/risk-register-template.md.
Then do the part everybody skips. For each of your top five, write the trigger as something you could observe this week without thinking about it — a number in a log, a count on a dashboard, a date on a calendar, a line in your hours log.
| Risk | Trigger (observable) | Where I will see it | Checked how often |
Reflect: Which of your responses is not yet a task in your WBS with hours attached? Add it now and note what it did to your total — a response with no hours is a hope. And which risk could not be given an observable trigger? That is either a badly written risk or a genuinely unobservable one; say which, and either rewrite it until it can be seen or accept it and write the contingency.
Group D — AI, honestly
Rep 11 — The breadth pass, and its price
Give an assistant your technical specification for one work package and ask: “List every task required to deliver this, including setup, error handling, tests, and documentation. Do not estimate anything.” Then, separately: “Name fifteen risks for a solo nine-week build with a third-party API dependency. Give each a cause, an event, and a consequence.”
Harvest what is genuinely new. Discard the rest. Then run the same prompts with estimates requested, and audit the numbers.
Tasks proposed: ____ kept: ____ genuinely new to me: ____
Risks proposed: ____ kept: ____ genuinely new to me: ____
Of the durations it produced: how many were identical? ____ spread given? ____
Reflect: Where was it worth the fifteen minutes, and where was it confidently wrong? Name one task it proposed that you would not have thought of, and one duration that would have hurt you if you had believed it. Log the session in docs/ai-usage.md.
Rep 12 — Budget what AI costs you
Add an ai_assisted column to docs/hours-log.csv and start filling it today. Then estimate one upcoming task twice: once assuming you write it yourself, once assuming you generate and review it.
T-___ by hand: O __ M __ P __ -> E ____
T-___ generated: generation ____ + review ____ + debugging ____ = ____
Reflect: Which is smaller, and by how much? Say plainly how confident you are in the second number, and what evidence would change your mind. In Week 11 you will have real data on this; today you have a hypothesis, and it should be labeled as one.
Done? One Last Thing.
Make the cut, and write it down.
This is the rep that separates a plan from a wish. Your calibrated total is bigger than your plannable hours. Fix it — for real, in the document, today.
- Sort your work packages by MoSCoW priority (Chapter 3). Coulds at the bottom.
- Cut from the bottom until the calibrated total fits inside plannable. Use
--excludeto model each candidate cut before you commit to it, and watch the burn-down move. - Re-estimate only with evidence. A spike result, a framework feature you confirmed, a library that does more than you thought. Never because you disliked the number.
- Write the scope decision table in
docs/plan.md: what was cut or deferred, its requirement identifiers, hours recovered, MoSCoW before and after, and one honest sentence of why. - Update
docs/requirements.mdso every cut requirement’s priority now reads Won’t — and flag it for change control in next week’s design review. - Commit with the message
plan: baseline WBS, schedule, risk register, and scope decision.
Then read your scope decision out loud. If any line makes you wince, that is the line you will be tempted to quietly un-cut in Week 11. Name it now, in writing, so future-you has to argue with past-you in public.
Up next: Milestone 7