Chapter 5 — Reps
Twelve reps that build Milestone 5 piece by piece. Do them in order; each one feeds the next.
Ground rules
- Everything here is about your project. PantryPilot appears only as a worked shape. If you catch yourself doing these reps for PantryPilot, stop and reopen
docs/requirements.md. - Every artifact you produce this week gets committed. Not a scratch file, not a note in your head. Committed, in the repository, with a date.
- Every time-varying claim carries a source and a date. Versions, prices, free-tier limits, rate limits, license terms. If you cannot cite where you read it and when, it does not go in the document. This is the strictest rule in the course and it applies to claims from documentation, from a classmate, and from an assistant equally.
- Log your hours as you go, in the same
docs/hours-log.csvyou started in Week 1. Round to the quarter hour. Log the hour you wasted too — that one is the most useful number in the file. - An assistant is allowed everywhere in these reps unless a rep says otherwise. It expands the option space; you verify the facts; you own the decision. Record substantive use in
docs/ai-usage.md. - Time box everything. If a rep runs 50% over its estimate, stop, write down where the time went, and move on. That overrun is data for your Week 7 estimates.
Group A — Reading your requirements as an architect
Rep 1 — Extract your architectural drivers
Open docs/requirements.md and docs/nfr.md (or whatever you named your non-functional section in Week 4). Go through every requirement and ask one question: would my technology choice change if this requirement changed?
Produce a table in a scratch file, then paste it into the top of docs/tech-evaluation.md:
| Driver | Requirement id | Why it constrains the stack |
|---|---|---|
| Three-way join on the main screen | FR-011 | Rules out stores where I would hand-join in app code |
| 500 ms at 1,000 records | NFR-P-02 | Rules out anything I cannot measure locally |
| Must run where my grader can reach it | CON-02 | Rules out campus-only hosting |
Target: four to eight rows. Fewer than four means you have not read your NFRs. More than eight usually means you are listing features, not drivers.
Write: one paragraph. If your list came out at zero or one driver, say so plainly — “my project is stack-indifferent” — and name the stack you already know best. That is a legitimate and strong finding, and it changes how you spend the rest of the week.
Rep 2 — The job-board test
Ten minutes, honest, alone.
Write down every technology you want to use in this project, before any evaluation. Next to each, write the real reason in one sentence. Then label the reason driver (it serves a requirement) or résumé (it serves you).
| Technology | The real reason | Driver or résumé? |
|---|---|---|
There is nothing wrong with a résumé motive. It is only dangerous when it is disguised. Compare:
- Disguised: “I chose Rust because performance is critical for this application.” (Is it? Which requirement says so, with a number?)
- Honest: “I want Rust on my résumé. It is not a driver for this project. It costs me a novelty load of 1 and roughly 15 hours of learning, which I have budgeted. If it loses the matrix, I will use it on a side project instead.”
Write: the honest version of your own sentence. Keep it — the Hard tier of the milestone asks you to defend exactly this.
Group B — Building and scoring the matrix
Rep 3 — Generate the option space, then prune it
Pick your single most consequential decision (usually the data store, the framework, or the host). Ask an assistant to widen the field:
For a solo developer building [one sentence about your project] over about
200 remaining hours, list eight options for [the decision]. Include at least
two that are unfashionable. For each: one sentence on what it is best at,
and one sentence on its most common failure mode. Do not recommend one.
Now prune to three, on paper, by hand. Keep at least one option you did not previously want. Delete anything with a novelty load you cannot afford.
Write: the eight, the three that survived, and one sentence per deletion. If you kept exactly the three you walked in with, say so — that is a finding, not a failure, but it is worth noticing.
Rep 4 — Weights before scores
Copy code/tech-evaluation-matrix.csv into your repository as docs/tech-evaluation.csv. Delete every PantryPilot row.
Now, before you look at any option, write the criteria and their weights for your three decisions. Every criterion must trace to a driver from Rep 1. Weights within a decision sum to 1.00.
Bad and good, so you can see the difference in your own file:
| Bad | Good |
|---|---|
data-store,modern,0.2,... | data-store,supports FR-011 join in one query,0.30,... |
hosting,easy,0.4,... | hosting,grader can open it with no account (CON-02),0.25,... |
auth,secure,0.3,... | auth,session expiry configurable per NFR-S-03,0.20,... |
Commit the file with the weights and no scores at all. The commit is the point: it timestamps that you weighted before you scored, and you can show it in the Week 8 design review.
Write: one sentence per decision naming the criterion you weighted highest, and why that weight is defensible.
Rep 5 — Score with evidence, then run the checker
Now score, 0–5, and fill the evidence column for every single cell. Evidence is a fact, a measurement, or a cited source — never an adjective.
python3 score-stack.py docs/tech-evaluation.csv
Fix everything it complains about. It will complain, and its complaints are all the same complaint: you skipped a cell you did not want to fill in.
Write: the ranking for each decision, and — if the top two are within 0.25 — which option is easier to reverse, and why that is the tiebreaker.
Rep 6 — The sensitivity pass
Take the criterion you weighted highest. Halve its weight, redistribute the difference evenly, rerun:
python3 score-stack.py docs/tech-evaluation.csv --decision <your-decision>
Write: did the winner change? If yes, your decision rests on one number. Name the number, say how confident you are in it, and either go get better evidence or record the fragility in the ADR’s Context section. If no, say so — a decision that survives its own sensitivity test is worth one sentence of confidence.
Restore the original weights before you commit.
Group C — Seams, novelty, and spikes
Rep 7 — The seam inventory
List every boundary in your chosen stack where two pieces have to talk. Aim for six to ten rows. For each: what has to work across it, whether you have crossed that exact seam before, a risk rating, and a spike id if the risk is High.
| Seam | What has to work | Crossed before? | Risk | Spike |
|---|---|---|---|---|
| app ↔ database | driver + migrations against the deployed DB version | no | High | SP-01 |
| CI ↔ tests | integration tests need a live database in the runner | no | Medium | SP-02 |
Write: which seam scares you most, and the honest reason. “Because I have never done it” is a perfectly good reason and the whole point of the column.
Rep 8 — Count your novelty load
One number. Count the pieces of your stack you have never shipped with — built, deployed, and debugged. Tutorials do not count. Coursework where someone else set up the environment does not count.
Write:
- The number.
- If it is 0–1: what you will do with the surplus hours.
- If it is 2: which two, whether they touch the same seam, and when each gets spiked.
- If it is 3 or more: which one you are demoting, and to what. Not “I’ll be careful.” A named substitution, or a named requirement you are cutting to remove the need. Then rerun Rep 5 with the substituted option in the matrix.
Then name your one innovation token — the single new thing you are deliberately keeping — and the requirement it serves.
Rep 9 — Run one real spike
Not a plan. A spike, actually run, on your highest-risk seam from Rep 7.
Copy code/spike-plan-template.md to docs/spikes/SP-01-<slug>.md. Fill in the question, the smallest build, the success criterion, the failure criterion, and the Plan B — all five before you write a line of code. Then set a 90-minute timer and go.
When the timer rings, stop. Even if you are close. Especially if you are close — “I was almost there” is exactly the state in which spikes turn into projects.
Write: the Result and Decision sections, with numbers. Include what surprised you; the surprise is usually the real finding. Log the time in docs/hours-log.csv.
Group D — Money, licenses, and the AI vendor
Rep 10 — The cost sheet and the free-tier watch list
Build both in docs/tech-evaluation.md. Cost sheet at your scale — you, your grader, five friends — with a line per service and a total you can say out loud. Then the watch list: one row per free service, with what is free, where you read it, the date you read it, the risk, and what you do if it ends.
Write: your monthly total, and the single line most likely to surprise you. Then answer the question that catches people: if this service ended in Week 12, how many hours would it cost me to move? If the answer is more than eight, that dependency needs a Plan B written now, not discovered then.
Rep 11 — The license inventory
List every dependency you have already added or intend to add, plus every asset — fonts, icons, images, datasets. For each: the SPDX identifier from the project’s own LICENSE file (not from memory, not from a search summary), whether it is permissive, copyleft, or source-available, the obligation it puts on you, and a ship/no-ship call.
Then choose your own project’s license and put the file at LICENSE in the repository root.
Write: the one dependency in your list whose license you were wrong about, or would have been wrong about. If every single one matched your assumption, say so — and note that you checked, because next semester one of them will not match.
Rep 12 — Verify five claims, and record your hit rate
Take five factual claims an assistant gave you this week — a version, a price, a free-tier limit, a license, a compatibility claim. Verify each against the vendor’s own documentation.
| Claim as stated | Verdict | Source (vendor URL) | Checked |
|---|---|---|---|
| "<claim>" | correct / stale / wrong / unverifiable | <url> | YYYY-MM-DD |
Write: your hit rate as a fraction, in docs/ai-usage.md, with the date. Then one sentence on which category of claim it got wrong. That category is the one you will check first for the rest of your career, and you now have your own evidence for it rather than mine.
Done? One Last Thing.
Write ADR 0001 for real.
Copy code/adr-template.md to docs/adr/0001-<kebab-title>.md and fill in every section for your most consequential decision. Status Accepted, dated today, your name on it, requirement identifiers from your own specification, the weighted scores from Rep 5, and — this is the one that matters — negative consequences with the hours you have budgeted for each mitigation, plus a revisit trigger with a number in it.
Then hand it to somebody who is not in this course and ask them a single question: “Can you tell me why I chose this?” If they can restate your reasoning without you talking, the Context section is doing its job. If they cannot, the Context is thin — and thin Context is the most common reason an ADR is worthless six months later.
Then delete every template comment, commit, and go write the other three.
Up next: Milestone 5