Chapter 10 · Week 10

Iteration One: Building the Core

Whose work is it when a machine helps you?

Chapter 10 — Iteration One: Building the Core

“Working software is the primary measure of progress.” — Principles behind the Agile Manifesto (2001)

“Whatever you do, work heartily, as for the Lord and not for men,” — Colossians 3:23 (ESV)


Why This Matters

Last week the skeleton walked. One request went in the front door, touched every layer, and came back out — thin, ugly, and alive. This week you put muscle on it.

The hat is the developer’s, and for the first time all semester it is the only hat that matters most hours of the day. You are in construction. Everything you built in Weeks 1 through 8 — the charter, the requirements specification, the non-functional targets, the architecture decision records, the technical specification, the work breakdown — exists so that this week you can sit down and not have to decide anything except how to make the code work. That is the payoff. A student with a real specification writes code. A student without one spends this week re-litigating the design and calls it “building.”

But there is a trap sitting in the middle of Week 10, and almost every capstone student steps in it. Construction is the phase where the process quietly dies. The board stops getting updated because updating it feels like overhead. The hours log goes unlogged because you are busy, and you will “catch up Sunday.” Commits turn into one enormous dump at midnight with the message stuff. The definition of done you wrote in Week 4 gets silently downgraded to “it ran once on my laptop.” None of these feel like decisions. They feel like moving fast. In Week 16 they will read, to a grader, exactly like what they are: a project that had no process from Week 10 onward.

The AI thread runs hard through this chapter, from both directions. As a tool, an assistant is genuinely good at construction — scaffolding a module, drafting a client for an API you have not used, writing the boring half of a form handler. Used well, it buys you hours. As a workload you are accountable for, it hands you code you did not write and may not understand, and understanding it is not free. There is a real debugging tax: heavy assistant use often moves your hours out of the “writing” column and into the “figuring out what this actually does” column rather than removing them. And when the grader asks in Week 16 why line 78 catches that exception, “the assistant put it there” is not an answer. The spine rule of this course holds all semester: the assistant accelerates, you decide, you verify, and you are accountable.

Which brings up the apologetic question for the week, and it is not an abstract one for your generation: whose work is it when a machine helps you? You will graduate into an industry where a meaningful fraction of the code in every repository was drafted by a model. Is that code yours? Is the project yours? Is there any honest sense in which you can say “I built this” — and if so, what exactly makes it true? Push that question away and you will end up either paralyzed with guilt or shameless, and both are worse than the answer.

Fifteen hours. Three to five real slices, each one traceable to a requirement, each one demoable. A log you can defend. A five-minute demo of working software. Let’s build.


10.1 — Vertical Slices: One Requirement, All the Way Through

A vertical slice is a unit of work that cuts through every layer of your system to deliver one observable behavior. It touches the interface, the logic, the storage, and whatever integration is involved. When it is finished, a human being can see the software do something it could not do yesterday.

The alternative — the way most students naturally work — is horizontal: build the whole data layer this week, the whole API next week, the whole UI the week after. It feels efficient. It is a trap, for three reasons. Nothing is demoable until the last layer lands, so you get no feedback for weeks. All the integration risk piles up at the end, in the exact week you have no slack. And if you run out of time you have three-quarters of a system that does nothing, which is worth precisely zero on a rubric that grades working software. Here is the difference, on the running example.

PantryPilot — a household pantry tracker: what food you have, what is about to expire, what you can cook tonight. It has a real user group (a roommate house), one third-party integration (a barcode/product lookup service), and an optional AI feature. We use it for worked examples all term. Your project will look different. The shape of the work will not.

HORIZONTAL (bad) — a week of tasks that demo nothing:
  [ ] Create all six database tables and migrations
  [ ] Write model classes for all six entities
  [ ] Write repository/DAO layer for all six entities
  [ ] Stub all fourteen API endpoints

VERTICAL (good) — the same week, sliced by behavior:
  [ ] FR-04  Add a pantry item by hand (name, quantity, expiration)
             → form → validation → items table → list view shows it
  [ ] FR-12  Add a pantry item by scanning a barcode
             → scan input → barcode client → product lookup → same add path
  [ ] FR-18  Highlight items expiring within three days
             → query → date rule → list view badge

Each of those three, finished, is a thing you can put on a screen and show a human. Together they are the core of PantryPilot: an item goes in, and the system tells you when it is about to go bad. Everything else in the backlog — recipes, sharing, notifications — is decoration on that core. TraceLens, our contrast example, is a command-line log analyzer with no UI at all, and its slices work identically: tracelens scan <file> reads a file, parses lines, runs one detector, writes one report, exits with a meaningful status code. The observable behavior is a report on stdout and an exit code, not a screen — but it is still a vertical slice.

How to choose this week’s slices. Take your prioritized requirements — the Must-haves from your MoSCoW pass — and order them by this rule: the slice that would hurt most if it turned out to be impossible goes first. For PantryPilot that is FR-12, the barcode integration, because it depends on somebody else’s service and somebody else’s uptime. Discovering in Week 14 that the barcode service rate-limits you to a handful of requests an hour is a catastrophe. Discovering it in Week 10 is a Tuesday. Each slice retires a different risk:

SliceRequirementLayers touchedRisk retired
Add item by handFR-04form · validation · DB · listthe core write path works at all
Add item by barcodeFR-12scan · third-party client · mapping · DBthe integration is real, not assumed
Expiring-soon highlightFR-18query · date logic · viewthe whole point of the product exists

Three to five slices is the right ambition for a fifteen-hour week in which you also have to review, test, log, and demo. Not eight. If your list has eight, you are estimating like someone who has never been interrupted.

Coach’s Note — A slice is not finished when the code exists. It is finished when you can show it. If you cannot describe how you would demo a task in one sentence, it is not a slice — it is a chore, and chores belong inside slices, not on the board as work of their own.


10.2 — A Definition of Done, Applied Without Mercy

You wrote a definition of done in Week 4. This is the week it stops being a document and becomes a gate.

The purpose of a definition of done is to make “done” mean the same thing on Tuesday at 10 a.m. and on Saturday at 11 p.m. when you are tired and the deadline is Sunday. Without it, “done” drifts — always in the same direction, always toward “it worked when I tried it.” Here is what most students write, and what it costs.

The bad definition of done:

Definition of Done
- Code is written
- It works
- Committed to GitHub

Every line of that is unfalsifiable. “Code is written” — of course it is; that is what makes it a task. “It works” — under what input, on whose machine, against which acceptance criterion? “Committed” — a commit is evidence that a file changed, not that anything is finished. A grader in Week 16 cannot check a single one of those lines, which means they contribute nothing to your 50%.

The good definition of done — copy it from code/definition-of-done.md and adapt it to your stack:

A task is DONE when all of the following are true:
 1. The acceptance criteria on its requirement are met, verbatim.
 2. At least one automated test exercises the new behavior and passes.
 3. The full test suite passes locally AND in CI on the pushed branch.
 4. Errors and edge cases named in the technical specification are handled.
 5. The four-pass self-review is complete and its findings are resolved or logged.
 6. No secrets, credentials, or personal data are in the diff.
 7. Any assistant contribution is recorded in `docs/ai-usage.md`.
 8. The issue links to its requirement id and is moved on the board.
 9. Docs touched: README, runbook, or ADR updated if this changed how it runs.
10. Hours are logged for the session, with a real description.

Ten checks, and every one of them is verifiable by someone who is not you — that is the test of a good definition of done. If a line cannot be checked by a stranger with your repository open, rewrite it or delete it. Now the part that matters more than the list: apply it without mercy. A definition of done only works if it is allowed to say no. The first time you finish a slice at 11 p.m. and realize check 2 is missing, you have a decision to make, and it is a decision about what kind of engineer you are becoming. Write the test. It is twenty minutes. The alternative is a project where “done” is a mood.

Coach’s Note — Put the definition of done where you cannot avoid it: a pull-request template, a pinned issue, a comment at the top of your board. Discipline that depends on remembering is not discipline; it is luck with good branding.


10.3 — Reviewing Your Own Code: The Techniques That Actually Work

In industry, someone else reads your code before it merges. You do not have that. You have you, and you already believe your code is correct — you wrote it fifteen minutes ago on exactly that belief. Reading your own work honestly is a real skill with real techniques: four passes, in this order, on every slice. They take about twenty minutes for a normal-sized diff, and they routinely find things that testing does not.

Pass 1 — The diff pass (mechanical). Do not read the files. Read the diff:

git add -A
git diff --staged            # every line you are about to commit
git diff --staged --stat     # and the shape of it

You are looking for the accidents: the debug print you left in, the commented-out block, the file you did not mean to stage, the hard-coded localhost, the TODO you wrote three hours ago and forgot. This pass catches roughly half of everything you will find, and it costs five minutes.

Pass 2 — The stranger pass (comprehension). Read the changed code as if you had never seen it, starting from the entry point. The question is not “is this right?” — it is “could someone who has never met me follow this?” Name the things that make you hesitate. Ambiguous variable names, a function doing three jobs, a magic number, a nesting depth of four. If you have to reconstruct your own reasoning to read it, so will your Week-14 self.

Pass 3 — The adversary pass (destruction). Now attack it. Walk the diff asking, for each input: what is the worst thing a user, a network, or a clock could hand this?

InputThe hostile version
A text fieldempty, 10,000 characters, emoji, '; DROP TABLE, leading/trailing spaces
A numberzero, negative, 0.1 + 0.2, the maximum your type holds
A datetoday, a leap day, a date in 1900, a date in a different time zone
A network callslow, timed out, 500, 429, valid HTTP with a garbage body
A collectionempty, one element, one million elements, duplicates

You are not fixing everything you find. You are deciding — fix now, handle later with a logged defect, or accept with a written reason. All three are legitimate. Silence is not.

Pass 4 — The contract pass (traceability). Open the requirement. Read its acceptance criteria out loud. Then point, in the code, at the line that satisfies each one. If you cannot point at a line, the criterion is not met — no matter how good the feature feels.

Two amplifiers make all four passes sharper. Sleep on it: a twelve-hour gap between writing and reviewing is worth more than any tool, because you cannot see your own assumptions while you are still inside them. And open a pull request to yourself — even solo, branch → PR → review in the web interface → merge. The web diff view is unfamiliar enough to feel like someone else’s code, CI runs on the branch, and the PR becomes a permanent record of what you reviewed and why you merged it.

The four passes and the hostile-input table are also in code/definition-of-done.md, so you can copy them into your repository.

Coach’s Note — The bug you cannot find is almost always in the code you are proudest of, because pride is where you stop reading carefully. When a section of your diff makes you feel clever, slow down there.


10.4 — AI-Assisted Implementation, and the Line Between Using and Submitting

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you’re as clever as you can be when you write it, how will you ever debug it?” — Brian W. Kernighan and P. J. Plauger, The Elements of Programming Style, 2nd ed. (1978)

Kernighan wrote that about human cleverness. It applies with double force to code you did not write at all. An assistant will hand you a compact, confident, idiomatic function in four seconds. Your ability to debug that function at 2 a.m. in Week 14 is exactly your ability to understand it — and understanding was the part you skipped.

This course permits and expects assistant use. The authoritative statement is in Appendix C; the practical version is one sentence: you may use any tool to help you build, and you must be able to defend every line you ship as your own decision. So where is the line? Not at how many characters the model typed. At judgment and accountability — and that is testable.

Using (this is your work)Submitting (this is not)
The designYou chose it; the assistant filled it inThe assistant chose it; you accepted it
ComprehensionYou can explain every line without lookingYou would have to re-read it to explain it
VerificationYou tested it against your acceptance criteriaIt compiled, so you moved on
ModificationYou changed it — naming, structure, error handlingIt arrived as-is and merged as-is
FailureYou know what breaks it and what happens thenYou would be surprised by any failure
RecordIt is in docs/ai-usage.mdNobody knows it happened

The three tests. Before assistant-drafted code merges, put it through all three. They take about ten minutes and they are the whole difference.

  1. Explain it. Out loud, line by line, without re-reading. If you stall on a line, you do not own that line yet. Read it, look up what it does, or delete it.
  2. Break it. Deliberately feed it the hostile inputs from the adversary pass. Assistant code is famously optimistic: it assumes the network works, the field is populated, the list is non-empty, the date parses. Find the assumption. This is where the real bugs are.
  3. Rewrite it. Take the hardest function and retype it from memory, in your own naming, in your project’s style. If you cannot, you have found the piece you do not understand — and now you know exactly what to study. This one test is worth more than the other two combined.

Write a prompt contract, not a wish. The quality of what comes back tracks the specificity of what you asked, and a specific ask is also a record of the judgment you exercised.

Bad prompt — the wish:

write me the barcode scanning feature

You will get a plausible file that assumes a library you are not using, a framework version you do not have, an API shape you did not design, and error handling you never specified. Then you will spend two hours reconciling it with your actual system — the debugging tax, paid in full.

Good prompt — the contract:

Context: <language/framework and version>, existing module `pantry/items` with
an addItem(name, qty, expiresOn) function I already wrote and tested.
Task: write a client for the product-lookup HTTP API below. Do NOT change
addItem; the client returns a product name or null and the caller decides.
Contract:
  - lookupProduct(barcode: string) -> {name: string} | null
  - timeout 3 seconds, at most 1 retry on a 5xx, no retry on 4xx
  - a 404 means "unknown product" and returns null, not an error
  - never throws; on any other failure return null and log at warn
  - the API key comes from an env var, never a literal; no new dependencies
Constraints: match the error-handling style in `pantry/items` (attached).
Then list every assumption you made that I did not state.

That last line is the highest-leverage sentence you can put in a prompt to a coding assistant: the assumptions it lists are the bugs it was about to hand you.

The debugging tax, honestly. Assistant use does not automatically make you faster, and you should not plan as if it does. A 2025 randomized trial by METR found that experienced open-source developers working in codebases they knew well took roughly 19% longer on tasks when allowed to use early-2025 AI tools — while believing they had gone faster. It was a small study (sixteen developers, mature repositories) and it does not settle the question for every setting, least of all a greenfield student project where scaffolding is a genuine win. But it should make you suspicious of your own sense of speed. Your hours log knows the truth and your feelings do not.

Where assistant help reliably pays for a capstone: boilerplate you have written before, a client for an API whose docs you have read, test scaffolding, unfamiliar syntax, and explaining an error message. Where it reliably costs: anything touching your architecture, anything where the requirement is subtle, and anything you would not be able to fix yourself.

Coach’s Note — The rule I would tattoo on a capstone student’s wrist: never merge code you could not have written, only code you did not have to. The gap between those two sentences is the entire ethics of this chapter.


10.5 — The ai-usage Log: What to Record, and Why It Protects You

Your final package includes docs/ai-usage.md. It is required, it is graded in Week 16, and it is the most misunderstood artifact in this course. Students treat it as a confession. It is not. It is your defense. Think about what happens without it. In Week 16 a grader reads a file that does not sound like the rest of your repository. They have two hypotheses: you learned something and grew, or you pasted something you do not understand. With no log, the burden is on you to prove the first one, live, under pressure. With a log — dated, specific, showing what you asked, what you took, what you changed, and how you checked it — you have already answered the question, in writing, before it was asked. Documented use is use. Undocumented use looks like concealment, and that is an integrity matter.

Log at the level of a session or a contribution, not a keystroke. If an assistant drafted something that survived into your repository, or materially shaped a decision, it gets an entry with five fields: the date; the tool and, if you know it, the model or version; what you asked for, in one line, naming the actual task and not “help with code”; what you accepted, meaning the file or function and roughly how much of it survived; and what you changed and how you verified it — the edits you made and the test or check that proved it works.

Bad entry — useless to you and to the grader:

3/19 - used AI for the barcode stuff

Which assistant? Which file? What did it write? Did any of it survive? Did anyone test it? A grader learns nothing except that you know the word “AI.” A hostile reading is available, and you handed it to them.

Good entry — same session, honestly recorded:

### 2026-03-19 — barcode lookup client
Tool: <assistant name>, <model/version if known>
Asked for: an HTTP client `lookupProduct(barcode)` for the product API, with a
  3s timeout, one retry on 5xx only, 404 => null, never throws. Full contract
  in prompts/2026-03-19-lookup.txt.
Accepted: `pantry/barcode/client.*` — roughly the retry loop and the response
  mapping, about 40 of 95 lines survived.
Changed: rewrote error handling to match `pantry/items` (it swallowed timeouts
  silently); replaced the hard-coded key with PANTRY_API_KEY; renamed three
  variables; deleted a caching layer I did not ask for and do not need yet.
Verified: 4 unit tests with a stubbed HTTP layer (200 / 404 / 500-then-200 /
  timeout), all green in CI on branch feat/fr-12-barcode. Confirmed against
  FR-12 acceptance criteria 1 and 3. DEF-014 filed for the retry-count edge case.

Read those two again. The second is not a longer confession — it is a portrait of an engineer at work. It shows judgment (deleted a caching layer I did not ask for), verification (four named cases), traceability (FR-12, DEF-014), and honesty about proportion (40 of 95 lines). That entry earns points. The first one loses them. Start from code/ai-usage-log-template.md, commit it as docs/ai-usage.md, and write the entry in the same session as the work. Reconstructing an ai-usage log in Week 15 is impossible; you will not remember which of forty files the assistant touched, and the guessing will show.

One more thing this log does for you, quietly. Reading back six weeks of entries tells you something no rubric can: which parts of your own system you actually understand. Where the entries are thin and honest, you built it. Where they say “accepted mostly as-is” and the “changed” column is empty, you have found the module that will humiliate you in the Week-16 question period. Go read it now, while there is time.


10.6 — Commit Hygiene Under Deadline Pressure

Your commit history is a graded artifact. It is also, in Week 14 when something breaks, the only tool that can tell you when the system last worked. Both facts are invisible in Week 10 and decisive later. Deadline pressure produces one particular failure: the midnight dump — forty-one files, one commit, message iteration 1. It costs you nothing tonight and everything later, because git bisect is useless, git revert is all-or-nothing, and a grader cannot see a single decision you made across four days of work.

The discipline is small. One commit per coherent change, staged deliberately:

git add -p                     # stage hunk by hunk; you will see what you wrote
git status                     # what is staged, what is not, what is untracked
git diff --staged              # pass 1 of the self-review, for free
git commit                     # write a real message in an editor, not with -m

git add -p is the highest-value five minutes in this chapter. It forces you to look at every hunk before it becomes history, and it will catch the debug print and the stray key more reliably than any checklist.

Messages that explain themselves. The subject line says what; the body says why. Why is the part that is unrecoverable later — the code always shows what.

BadWhy it failsGood
fixFixes what?fix(items): reject expiration dates in the past (FR-04 AC-3)
updatesNothing is recoverablefeat(barcode): add product lookup client for FR-12
wip × 9Nine commits, zero informationsquash before merge; one message per behavior
changed the thing josh mentionedJosh is not in the repositoryfix(list): sort expiring items ascending; roommate feedback 3/18
iteration 1 on 41 filesNo bisect, no revert, no storyone commit per slice, each linked to its issue

A full message, for the record:

feat(barcode): add product lookup client for FR-12

Adds lookupProduct(barcode): 3s timeout, one retry on 5xx only. A 404 maps
to null ("unknown product") rather than an error, because FR-12 AC-2 requires
an unknown barcode to fall through to manual entry instead of failing the add.

Rejected an in-memory cache for now: NFR-03 does not require it and it would
need an invalidation story we have not designed. Revisit if the API rate limit
bites in iteration two.

Closes #34. Refs FR-12.

Two paragraphs of why, one deferred decision recorded, one issue closed, one requirement referenced — ninety seconds of typing. Many teams format subjects with the type(scope): summary convention documented at https://www.conventionalcommits.org/; adopt it or do not, but pick one shape and hold it for six weeks.

The commit you cannot take back. Under pressure this is when secrets get committed — the barcode API key, a database URL with a password, a .env you meant to ignore. Two facts you must internalize: deleting it in a later commit does not remove it from history, and a key pushed to a public repository should be treated as compromised the moment it lands, because automated scrapers find them fast. So the fix is not a follow-up commit — it is rotate the credential immediately, then clean the history. GitHub also runs secret scanning and can block pushes containing recognizable credential formats, but that is a backstop, not a strategy, and coverage varies by credential type. Check the diff yourself.

Coach’s Note — At the end of every working session, run git log --oneline -10 and read it as a stranger. If those ten lines do not tell the story of what you built this week, the history is already failing at its job — and it only gets harder to fix.


10.7 — Keeping the Hours Log Honest When You Are Busy

Here is the week the hours log dies. Not Week 3, when logging felt novel. Week 10, when you are actually working and stopping to type a line into a spreadsheet feels like theft from the work. So let us be blunt about what the log is for, because “the rubric says so” will not survive a hard week.

  1. It is your only calibration instrument. In Week 7 you estimated these tasks. This week you find out what they really cost. That comparison — estimate versus actual — is the most valuable professional habit this course can hand you, and it is unavailable without the log. Engineers who can estimate get trusted with schedules. Engineers who cannot spend their careers apologizing.
  2. It is the early-warning system for scope. Six weeks remain. If the log says you have spent 148 hours and the burn-down says half the features are left, you have a scope conversation to have this week, while cutting is still cheap.
  3. It is evidence. In Week 16 the log is part of what earns your 50%. A log that reads as if it was kept is worth points; a log that reads as if it was invented is worth less than nothing, because it puts everything else you claim under suspicion.

Log at the end of each session, in under thirty seconds. Not at the end of the week. The format has not changed since Week 1 and it still lives at docs/hours-log.csv — the columns from Appendix B, section B.11, plus the ai_assisted column you added in Week 7:

date,start,end,hours,phase,hat,task,estimate_hours,blocked_hours,notes,ai_assisted
2026-03-19,18:30,22:15,3.75,construction,developer,FR-12 barcode slice,2.50,0.00,assistant draft rewritten twice,yes
2026-03-19,22:15,23:15,1.00,construction,developer,FR-12 barcode client timeout,0.50,0.00,debugging the timeout the assistant hid,yes

Note the second row. That is the debugging tax, visible, in your own data. Do not fold it into the first row — separating “writing” from “understanding what I was handed” is exactly the measurement that makes the log worth keeping.

Whatever else you shorten this week, do not shorten the schema. estimate_hours above all. It is the only value in the file that cannot be recovered afterward, it is what makes the log a calibration instrument instead of a diary, and the Week-16 estimate-versus-actual analysis is computed straight out of it. A blank estimate on a row you genuinely forgot to estimate is honest and costs you one number. A log with no estimate column at all is a Week-16 deliverable you have already thrown away, six weeks before you find out.

A realistic sample log for the running example, covering Weeks 1 through 10, is in code/hours-log.csv. Run code/hours_report.py over it — python3 tools/hours_report.py docs/hours-log.csv — and it prints the weekly rollup, the phase distribution, the cumulative burn against 240 hours with your pace, and the pattern checks a grader runs. It needs only date, hours, and phase, and reads the work description from whichever of task, notes, or description your file has, so it runs on the Week-1 template unchanged. Point it at your own log once a week. It takes two seconds and it will tell you things about your semester you cannot feel.

What a dishonest log looks like — and why it is obvious. Backfilled logs have tells, and every one of them is a statistical fingerprint of reconstruction rather than recording:

2026-03-16,,,3,construction,developer,worked on project,,,,
2026-03-17,,,3,construction,developer,worked on project,,,,
2026-03-18,,,3,construction,developer,worked on project,,,,
2026-03-19,,,3,construction,developer,worked on project,,,,
2026-03-20,,,3,construction,developer,worked on project,,,,

Five identical durations. Every value a whole number. One task description repeated verbatim. Start, end, and estimate_hours blank on every row, which is what happens when rows are typed all at once from memory. No debugging, no reading, no dead ends, no interruptions — which is to say, no life. Real work is 1.25 hours here and 3.75 there, with a session that produced nothing but a fixed environment variable. Compare that block against the commit timestamps for the same days and the story falls apart in thirty seconds; graders check. Then there is the other classic, the fourteen-hour Sunday — one entry, 2026-03-22, 14.0, "caught up". Nobody does focused engineering for fourteen consecutive hours. What that row really records is a student reconstructing a week from memory, and it converts a required artifact into evidence against you.

Reconstructing honestly, when you have genuinely fallen behind. This is allowed, and it is far better than inventing. Rebuild from evidence — git log --since=... --date=short --pretty='%ad %s', your browser history, your editor’s recent files, your board — estimate in quarter hours, and mark the row as reconstructed:

2026-03-18,,,2.50,construction,developer,FR-04 validation and list view,,,[reconstructed from commits],no

A logged estimate labeled as an estimate is honest. An unlabeled guess is not. That bracket costs you nothing and buys you your credibility. And leave estimate_hours blank on a reconstructed row rather than back-filling it: a number invented after the session is not an estimate, and one empty cell costs you far less than a calibration factor built on fiction.

Coach’s Note — Thirty seconds at the end of a session. That is the whole practice. If you cannot spare thirty seconds, you were not going to spare the four hours it takes to fake it convincingly in Week 15 either.


10.8 — The Demo: Showing Working Software, Not Slides

Milestone 10 ends with a five-minute demo. It is small on purpose — it is the rehearsal for the thirty minutes in Week 16 that carry 10% of your grade, and rehearsal is cheaper now. The rule is absolute: a demo shows software running. Not a diagram of the architecture. Not a slide that says “implemented barcode scanning.” The software, on a screen, doing the thing. Five minutes, three acts:

ActTimeWhat happens
1. The claim45 secOne sentence: which requirements you closed and what a user can now do
2. The software3 minThe system doing it, live, with seeded data, following a written script
3. The evidence and the gap75 secTests passing, the acceptance criteria checked off, and what is not done

Act 2 is where students improvise and die. Do not. Write the script — the literal clicks or commands, in order, with the exact input values — and rehearse it once end to end. Then: seed your data (never demo on an empty database and never type a dataset live — commit a seed script; typing “asdf” into a form in front of a grader makes real software look like a toy); record a fallback before the live run, because Wi-Fi fails and third-party services go down, and “here is the recording I made this morning” reads as prepared where “it worked earlier” reads as every student who ever said it; cut the setup, so nothing installs on camera; and show one failure path — an unknown barcode, a past date — because handled errors impress more than happy paths, everyone’s happy path works.

The opening line. Compare:

Bad: “So, um, this is my project, I’ve been working on the pantry thing, let me just find the — okay, so there’s a lot still to do but basically you can add items, hold on, let me restart the server…”

Good: “PantryPilot now closes FR-04, FR-12, and FR-18: a household member can add an item by hand or by scanning a barcode, and the list flags anything expiring within three days. Here it is. I’m starting from the seeded pantry.”

Same project, same code. One of those students sounds like an engineer. And Act 3 is the one that earns points, and the one students skip. Say plainly what is not done and what it will take. “Recipe suggestion is not started. It is two slices, I have estimated eight hours, and it is scheduled for Week 12. If the barcode rate limit becomes a problem, recipe suggestion is the first thing I cut, and the requirements specification already marks it Should-have.” That paragraph demonstrates project management, honesty, and a plan — and it is impossible to fake. Compare it with “yeah, there’s some stuff left.” One of those is a status report; the other is a shrug.


10.9 — Where Your Hours Went This Week

The budget is roughly fifteen hours. A realistic Week 10, for a student who is on pace:

ActivityHours
Chapter, reps, weekly quiz1.5
Planning the increment: choosing slices, writing task cards, definition of done1.0
Implementation — the actual writing6.0
Debugging, including reconciling assistant-drafted code2.0
Self-review and the rework it produces1.5
Tests written alongside the slices1.5
Logs, commits, board, ai-usage entries0.5
Demo: script, seed data, rehearsal, recording1.0
Total15.0

Two things to notice. Implementation is under half the week — it always is, and students who plan for fifteen hours of typing finish Sunday with untested code and no demo. And debugging gets two hours by default, not “whatever is left over.” If your own log shows debugging routinely eating four, that is not a personal failing, it is data: feed it back into your Week 7 estimates for iteration two, and notice whether the four hours cluster around the code you wrote or the code you accepted.


10.10 — Interactive Lab: The Honest Hours Log

Below this chapter on the website is The Honest Hours Log. Do this lab before you touch your own log this week. Add entries the way you would after a real session: date, duration, work package, SDLC phase, and one line about what you actually did — a deliberately trimmed subset of your real columns, because the lab is about the shape of the data, not the schema of your file. The widget builds the weekly rollup, the phase distribution, and the cumulative burn against the 240-hour budget as you type, so you can see immediately whether you are on pace or quietly drifting.

Then open the “what your grader sees” panel. It runs the same pattern checks a grader runs: identical durations repeated, round numbers everywhere, a single implausible fourteen-hour Sunday, long silences in weeks your commit history says you were working. Deliberately feed it a backfilled week and watch every flag light up. Then fix the entries into something that resembles a real week — a 1.25, a 3.75, a session that produced nothing but a fixed environment variable — and watch the flags clear. What it teaches is not “how to avoid getting caught.” It is what an honest record looks like from the outside — and, more usefully, what your own distribution of hours has been telling you all semester while you were too busy to read it.


10.11 — Whose Work Is It When a Machine Helps You?

“Whatever you do, work heartily, as for the Lord and not for men.” (Colossians 3:23, ESV)

This is the honest version of a question your generation cannot avoid, and I want to give you a better answer than the two cheap ones on offer. The first cheap answer is “none of it is mine.” It sounds humble. It is actually a way of putting down responsibility: if the machine wrote it, the machine is answerable for it, and I am off the hook when it fails. That is not humility; it is abdication wearing humility’s coat. The second cheap answer is “all of it is mine, and I don’t have to say anything.” That is not confidence; it is concealment, and it is the thing academic-integrity policies exist to name.

Christian thinking has a durable category that cuts between them, and it is older than software: stewardship. “Moreover, it is required of stewards that they be found trustworthy” (1 Corinthians 4:2, ESV). A steward does not own the materials. A steward is answerable for what is done with them. The tools, the languages, the libraries, the machine on your desk, the intelligence you are using to read this sentence — none of it originated with you. Every engineer who has ever worked has worked with borrowed materials, and no engineer has ever been less accountable for the building because the timber grew somewhere else.

So “is this code mine?” is the wrong question, because it is a question about origin, and craft has never been settled by origin. The right question is the steward’s question: am I answerable for it? And that one has a hard, checkable answer.

You are answerable for code when you chose the design it implements. When you can explain it without re-reading it. When you tested it against a requirement you wrote. When you know what breaks it. When you changed it because your judgment differed from what you were handed. When your name is on the commit and you would defend it in a room. Every one of those is a judgment a model cannot make for you, because judgment requires someone who can be held to it — and a tool cannot be held to anything. That is not a limitation of current models; it is what accountability means.

Notice, too, that Scripture is comfortable with skill in a way our culture often is not. Exodus 31 tells of Bezalel, the craftsman for the tabernacle, described as filled by God with ability and intelligence and knowledge and craftsmanship — a passage that treats technical skill as a gift and as a genuine human accomplishment at once, with no embarrassment about either. Gift and work are not competitors. The craftsman is fully the craftsman even though nothing he used began with him.

And notice what Colossians 3:23 actually changes about this week. “Work heartily, as for the Lord and not for men” moves the audience. If you are working for men, the only thing that matters is what can be seen — the demo runs, the feature looks done, nobody knows which lines you accepted at 1 a.m. without reading. If you are working for the Lord, the unseen parts are the same work as the seen parts: the test you wrote when nobody would have checked, the entry in the log for a session you could have skipped, the function you rewrote because you could not explain it. Verse 24 follows on with the reason — the reward comes from the Lord, and it is the Lord Christ you serve. That is a strange and freeing thing to believe on a Thursday night in Week 10, because it means the honest log matters even in the universe where no grader ever opens it.

“One who is faithful in a very little is also faithful in much, and one who is dishonest in a very little is also dishonest in much” (Luke 16:10, ESV). This week the “very little” is a spreadsheet row and a five-line entry in docs/ai-usage.md. Nobody is watching. That is exactly what makes it a test worth passing.

Here is the practical landing: use the tool, log the use, own the result. Three clauses, and the middle one is what makes the other two honest. A student who does all three can say “I built this” with a completely straight back — not because no machine helped, but because at every point where judgment was required, a person exercised it, and that person’s name is on the repository.


10.12 — Common Pitfalls

Pitfall: Slicing horizontally — a week spent on “the data layer.” Example: Six tables, six model classes, six repositories, fourteen endpoint stubs. Nothing a human can look at. In Week 15 the UI is still missing and none of it is worth points. Fix: Every task on this week’s board must end in observable behavior. If you cannot say in one sentence how you would demo it, it is not a slice — fold it into one.


Pitfall: Letting “done” drift to “it ran on my machine.” Example: FR-04 is moved to Done on Thursday. No test, no CI run, the past-date edge case unhandled. In Week 13 it breaks and you no longer remember the code. Fix: The ten-line definition of done in code/definition-of-done.md, applied as a gate. If a check fails, the task is not done — it is nearly done, which is a different column.


Pitfall: Merging assistant-drafted code you cannot explain. Example: A retry loop with an exponential backoff you did not ask for and a swallowed timeout you did not notice. It works in the demo and fails silently in Week 14, and you have no idea where to start. Fix: Explain it, break it, rewrite it — all three, before merge. Ask the assistant to list every assumption it made that you did not state, then check each one.


Pitfall: The midnight commit dump. Example: 41 files, one commit, message iteration 1. git bisect is useless, the revert is all-or-nothing, and the history shows a grader four days of invisible work. Fix: git add -p, one commit per coherent change, a subject that says what and a body that says why, with the issue and requirement id referenced.


Pitfall: Backfilling the hours log on Sunday night. Example: Five rows of exactly 3.0 hours, all described “worked on project,” on days your commit history is empty. Fix: Thirty seconds at the end of each session. If you genuinely fall behind, reconstruct from commits and browser history, estimate in quarter hours, and label the row [reconstructed from commits].


Pitfall: Committing a secret and “fixing” it with a later commit. Example: The barcode API key lands in config.js on Tuesday and is deleted on Wednesday. It is still in the history, still public, and by then possibly already scraped. Fix: Rotate the credential first — treat it as compromised the moment it is pushed — then clean the history. Read every diff before staging; keep keys in environment variables from the first line of code.


Pitfall: Demoing slides, or demoing without seeded data. Example: A slide reading ”✅ Barcode scanning implemented,” or a live demo that begins with an empty database and a student typing test test test into a form. Fix: Working software only, from a committed seed fixture, following a written script, with a screen recording made in advance as the fallback. Close by naming what is not done and when it is scheduled.


10.13 — Reps

The reps are in the exercises. They are not warmups beside the milestone — they are the increment, built in order. Preview:

  • Rep 1 — cut this week’s slices from your Must-have requirements and write a slice card for each.
  • Rep 3 — adapt the ten-line definition of done, then apply it to a task you already called “done” and find the gap.
  • Rep 4 — run all four self-review passes on your ugliest file and log what you find.
  • Reps 6–7 — write a prompt contract instead of a wish, then put the result through explain / break / rewrite.
  • Rep 9 — rewrite five bad commit messages from your own history into messages that explain why.
  • Rep 10 — reconstruct one honest day from git log, then run code/hours_report.py over your real log.

Do the on-page Check Your Reps quiz when you finish the chapter — it is the ungraded rehearsal for Week 10 Quiz in Canvas, and the early-warning system that tells you whether this week actually landed.


10.14 — This Week’s Milestone

Milestone 10Milestone 10: Core Increment & Demo. Three to five vertical slices closed against their acceptance criteria, a definition of done that was actually applied, a self-review record, an honest docs/ai-usage.md, a commit history that tells the story, a current hours log, and a five-minute demo of working software with a recorded fallback. Remember the shape of this course: the milestones are graded twice, and that is not mercy. They carry 25% together, and the Week-16 submission — worth 50% — awards points for exactly these artifacts again. What you skip this week is not forgiven; it is charged once now and deferred again to a week that has six other things in it and no room. Build it now, once, while it is cheap.


10.15 — Coach’s Final Word

This is the week the course stops being about documents and starts being about whether you can build the thing you described. That transition breaks a lot of students, and almost never because they cannot code. It breaks them because construction feels like permission to abandon everything that got them here — the slices, the gate, the log, the history, the review. Do not take that permission. The process is not a tax on the building; it is what makes the building survive contact with Week 14, when you are tired and something is broken and the only thing that can save you is a history you can read and a log you can trust.

Three to five slices. Each one demoable. Each one you can explain, line by line, including the lines a machine drafted — especially those. A log that reads as if a person kept it, because a person did. And a five-minute demo where the software runs and you say plainly what is not finished yet.

Work heartily. The unseen parts count.

See you on Monday.


Up next: the exercises builds the increment rep by rep · Milestone 10 is Milestone 10 · then Chapter 11 — where verification stops being something you do at the end and becomes a phase with a plan. Reference appendices: Appendix B (templates and worked examples), Appendix C (the grading contract and the AI-use policy), Appendix E (glossary). Previous: Chapter 9.

Interactive Lab — Week 10
The Honest Hours Log

Log a few real sessions below — date, duration, work package, phase, and one checkable line about what you did. Everything recalculates as you type: the weekly rollup, the phase mix, and your burn against the 240-hour term budget. The panel at the bottom runs the pattern checks a grader runs; load either sample log to watch the flags flip.

Cumulative burn against the 240-hour term budget0 / 240 h

Weekly rollup

Phase distribution

Entries

DateHrsWork packagePhaseDescriptionRemove

What your grader sees

Pattern checks, not accusations — every threshold below is a rule of thumb. Clearing all six is not proof you did the work; it just means the log agrees with your commits, your issues, and your memory.

    Add an entry to generate your status line.

    Try: load the backfilled sample, then repair it one entry at a time — split the fourteen-hour Sunday across the days you were actually committing, replace “worked on project” with something a grader could check against the repo, and watch the flags clear. That is the whole discipline: log it the day it happens, in the words you would use to defend it.

    Check Your Reps

    Week 10 Knowledge Check

    Question 1 of 5
    Chapter 10 shows the same week planned two ways. Why does it call the first plan a trap?
    HORIZONTAL (bad) — a week of tasks that demo nothing:
      [ ] Create all six database tables and migrations
      [ ] Write model classes for all six entities
      [ ] Write repository/DAO layer for all six entities
      [ ] Stub all fourteen API endpoints
    
    VERTICAL (good) — the same week, sliced by behavior:
      [ ] FR-04  Add a pantry item by hand (name, quantity, expiration)
                 form -> validation -> items table -> list view shows it
      [ ] FR-12  Add a pantry item by scanning a barcode
                 scan input -> barcode client -> product lookup -> same add path
      [ ] FR-18  Highlight items expiring within three days
                 query -> date rule -> list view badge
    Why: Horizontal slicing feels efficient — finish the whole data layer, then the whole API — and it fails for three specific reasons the chapter names. A vertical slice cuts through interface, logic, storage, and any integration to deliver one behavior a human can watch working. Rep 2 makes you mark every task on your board V or H and fold the H tasks into V slices. Horizontal tasks are not evil — a migration is a migration — but a board that is mostly H cannot demo anything in Week 15. And notice the ordering rule inside the good list: FR-12 is first because it depends on somebody else's service, and discovering a rate limit in Week 14 is a catastrophe while discovering it in Week 10 is a Tuesday.
    Question 2 of 5
    This is the definition of done a student committed. Chapter 10's objection is one sentence long. What is it?
    Definition of Done
    - Code is written
    - It works
    - Committed to GitHub
    Why: Every line is unfalsifiable. 'Code is written' is what makes it a task in the first place. 'It works' — under what input, on whose machine, against which acceptance criterion? 'Committed' is evidence that a file changed, not that anything is finished. The test of a good definition of done is blunt: if a line cannot be checked by a stranger with your repository open, rewrite it or delete it. The ten-line version in the chapter passes that test — acceptance criteria met verbatim, an automated test exercising the new behavior, the suite green locally and in CI on the pushed branch, the four-pass self-review complete, no secrets in the diff, the ai-usage entry written, hours logged. And the part that matters more than the list: apply it without mercy. A gate that is never allowed to say no is decoration.
    Question 3 of 5
    Before assistant-drafted code merges, Chapter 10 requires three tests — explain it, break it, rewrite it. Which one does the chapter say is worth more than the other two combined, and why?
    Why: The rewrite test is the one that cannot be faked, because it converts a vague feeling of comprehension into a hard pass or fail — and when it fails, it tells you precisely what to study. The other two still matter: explaining out loud surfaces the lines you stall on, and breaking it finds the assistant's famous optimism (it assumes the network works, the field is populated, the list is non-empty, the date parses). The chapter's whole line between using and submitting is judgment and accountability, not how many characters the model typed: did you choose the design, can you explain it, did you verify it against your acceptance criteria, did you change it, do you know what breaks it, and is it in docs/ai-usage.md? The Coach's Note is the version to memorize: never merge code you could not have written, only code you did not have to.
    Question 4 of 5
    A grader opens docs/hours-log.csv and finds this block. What is the tell, and what is the honest repair?
    date,hours,work_package,phase,description
    2026-03-16,3,WP-8,Construction,worked on project
    2026-03-17,3,WP-8,Construction,worked on project
    2026-03-18,3,WP-8,Construction,worked on project
    2026-03-19,3,WP-8,Construction,worked on project
    2026-03-20,3,WP-8,Construction,worked on project
    Why: Those are the statistical fingerprints of a log written from memory: no debugging, no reading, no dead ends, no interruptions — which is to say, no life. Real work is 1.25 hours here and 3.75 there, with a session that produced nothing but a fixed environment variable. Compare a block like this against the commit timestamps for the same days and the story collapses in thirty seconds, and graders check. The sibling failure is the fourteen-hour Sunday labeled 'caught up.' Reconstructing honestly is explicitly allowed and far better than inventing — a logged estimate labeled as an estimate is honest; an unlabeled guess is not — and that bracket costs you nothing while buying your credibility. Better still: thirty seconds at the end of every session. That is the whole practice.
    Question 5 of 5
    It is Friday of Week 10. You can merge five slices with no self-review record, no docs/ai-usage.md entries, and an hours log you plan to backfill on Sunday — or three slices with all of that evidence in place. What does Milestone 10's rubric reward?
    Why: Milestone 10 says it outright: when you are behind, cut scope, not process. Three slices done properly beats five slices done invisibly, and the rubric agrees — twenty points for the slices, forty-two for the record of how they were built. Medium tier's sixth and seventh slices count only if the first five actually met the standard; quantity that skips the gate scores nothing. And the record is not equally recoverable: a commit history can never be manufactured afterward, and an ai-usage log reconstructed in Week 15 is impossible — you will not remember which of forty files the assistant touched, and the guessing will show. This is also the arithmetic of the whole course. The milestones are graded twice, so nothing you skip this week is forgiven — you lose the milestone score now, and the rest is deferred to a week that already contains a presentation, a final rubric audit, and a clean-machine test.
    YOU FINISHED. NICE WORK.