0 / 91
Week 12 · Day 82 of 91

Build vertical slice 1 with Codex

AI-Assisted Capstone: Build Without Vibe Coding

Objective

Implement one thin end-to-end path rather than separate giant layers.

AI is an advanced instrument or junior collaborator: it expands throughput, but the engineer still defines requirements, verifies measurements, and signs off on safety.

  • vertical slicing
  • plan and diff review
  • manual explain-back

Why this matters

Today the project becomes real: one workflow, working end to end, from a row in the database to something a person can see. Not the whole database layer, not all the endpoints — one path through every layer, committed and demonstrable. A project built in vertical slices is usable at every point in its life; one built in horizontal layers is usable only at the end, if it arrives.

By the end of the hour you have one small workflow committed, and you can explain every line of it.

Vertical slicing

A vertical slice is a small feature that crosses every layer it needs — database, API, UI — end to end. Its opposite is horizontal work: build all the tables, then all the endpoints, then all the screens.

Horizontal looks efficient and is a trap. Three sessions in you have a schema, some routes, and no way to know whether any of it works together; the first real feedback arrives once everything is already built on the misunderstanding. You also cannot demonstrate anything, so you cannot tell whether you are ahead or behind.

A slice is thin, not short. SLICE 1 of the calibration tracker:

migration: calibrations table  ->  POST /api/instruments/:id/calibrations
                               ->  GET  /api/instruments/:id/calibrations
                               ->  CalibrationForm + history list

Four files, maybe five. It saves one record and shows it back. It does not edit, delete, paginate, or validate beyond the criteria you wrote for it.

Bring up one channel first

You do not populate an entire board and apply power hoping for the best. You bring up the supply, then one signal path — sensor, amplifier, converter, display — and confirm a real reading on one channel. Every remaining channel is then a repetition of a path you have already proven. A vertical slice is that first channel: the smallest complete path from input to visible output.

The slice plan

Before writing code, write the plan. One row per slice, and this template works for any project:

# Slice Table Endpoint Screen Done when
1 Record a calibration calibrations POST/GET /instruments/:id/calibrations form + history Story 1, criteria 1–4 pass on seeded data
2 Show overdue instruments none (derived) GET /instruments?status=overdue badge on list Story 2, criteria 1–3 pass
3 Edit a calibration none PATCH /calibrations/:id edit form Story 3 criteria pass

The rule that makes this a slice plan rather than a task list: after every row, the app still runs. If finishing a row leaves the app broken until the next row lands, the rows are horizontal layers wearing a costume. Reorder until each ends in something you could demonstrate.

Order by risk, not comfort: the slice you are least sure about goes early, while there is still time to change the design around it.

Plan and diff review

You are using an agent today in pair mode: it proposes, you verify. Two moments carry all the safety.

The plan, before any file changes. Ask for a plan and read it against your spec, checking four things: does it touch only the files you expected, does it satisfy the criteria you named, does it invent requirements, does it add dependencies. Correcting a wrong plan costs a sentence; correcting wrong code costs the hour.

The diff, before it is committed. A diff is the line-by-line difference between the last committed state and now. Start with size, then read every line:

git status
git diff --stat
 db/migrations/003_calibrations.sql       | 12 ++++++++
 src/routes/calibrations.ts               | 41 +++++++++++++++++++
 src/web/CalibrationForm.tsx              | 58 ++++++++++++++++++++++++
 3 files changed, 111 insertions(+)

Compare that against the Touches line in your issue. Three files, roughly as predicted — good. If it said eleven files and 900 lines, reject it before reading further: a diff too big to read is a diff you cannot own, and the fix is a smaller task, not more reading.

Then read it properly:

git diff

Read every changed line and ask three questions of each: what does this line do, why is it here, and what breaks if it is wrong? You need not have written the line, but you must be able to answer those three questions, and the rule from Day 34 is absolute: never accept code you cannot explain. Not "it passes the tests" — tests only check what someone thought to check.

Signing the inspection sheet

An inspector who signs without looking has not saved time; they have transferred the fault to their own name. The moment you commit generated code it is your code — defended by you in every review, debugged by you at midnight. Sign what you have read.

Checkpoints: commit known-good states

A checkpoint is a commit where the app worked and the checks were green — your undo button. The discipline is mechanical:

git switch -c slice-1-record-calibration   # start from a known-good main
# ... one scoped change ...
npm run check                              # must be green
git add -A
git commit -m "feat: record a calibration against an instrument"

Commit at every point where the app works, not at the end of the day. If the next attempt goes badly, you have somewhere to return to:

git restore .        # discard uncommitted changes, back to the last checkpoint

`git restore .` throws away uncommitted work permanently

Every change since the last commit is gone, with no recovery. That is why you commit known-good states first: with a checkpoint behind you this costs one experiment, without one it costs your afternoon. Run git status and read the list before you run it.

Manual explain-back

Before committing, close the tool and narrate the slice out loud, following the data:

  1. What the user types, and where the browser sends it.
  2. Where the server receives it, and what it validates.
  3. What SQL runs, and what changes in the database.
  4. What comes back, and what the screen shows.
  5. What happens on each failure case in your spec.

Any step where you say "and then somehow" is the step to go read. Finding that gap now, in a fifty-line slice, is the entire reason this checkpoint exists; finding it in a three-thousand-line app on Day 89 is a different experience.

When you get stuck

You will get stuck today, and recognising it early is a skill. The signal is concrete: twenty minutes with no new information. Not no progress — no information. Re-reading the same file or asking the agent to try again feels like work while telling you nothing new.

When that happens, use one of three moves:

  • Reduce scope. Cut the slice in half. Drop the form and prove POST works with a manual request; drop validation and save one hard-coded record. A smaller thing that works beats a bigger thing that might.
  • Reproduce smaller. Take the failure out of the app: one SQL statement in the database client, one curl to the endpoint, one function in a scratch script. Most bugs become obvious when nothing else is running.
  • Check the boundary. From Day 69: at each boundary, inspect what actually crossed it. What did the browser send, what did the server receive, what did the database get? The bug lives at the first boundary where reality stops matching what you expected.

Checkpoint

Say which of the three moves fits each case: the form submits but nothing appears in the list; the migration fails; the slice is becoming six files instead of three.

Walkthrough: the slice in one pass

git switch -c slice-1-record-calibration

Then the plan request, then the implementation request — separately, never in one message:

Pair mode — plan first, then implement

"Implement only this vertical slice after presenting the plan. Keep the diff small. Run checks and explain each changed file."

Paste the issue and its acceptance criteria underneath. Read the plan against your spec and reply with corrections before allowing any edit. Then verify in this order every time: inspect the diff, run npm run check, explain the behaviour in your own words. Any one failing means the change is not accepted.

Now verify by hand, because green checks are not proof that the feature works:

npm run db:seed
npm run dev

Walk your acceptance criteria one at a time in the browser: submit a valid calibration and confirm it appears at the top of the history, then submit with the date empty and confirm the exact message from criterion 2. Then commit:

npm run check
git add -A
git commit -m "feat: record a calibration against an instrument"
git log --oneline -1
a3f1c9d feat: record a calibration against an instrument

One slice, one commit, all criteria checked by hand.

Your turn

  1. Write your slice plan table in docs/backlog.md. Confirm the app still runs after every row.
  2. git switch -c a branch named for SLICE 1.
  3. Ask for the plan only. Check it against your spec: expected files, no invented requirements, no new dependencies. Correct it in writing before any edit happens.
  4. Let it implement, then run git diff --stat and compare with the issue's Touches line. If it is much larger, discard and ask for a smaller task.
  5. Read the whole diff. For each changed section, write one line in docs/slice-1-notes.md saying what it does and why.
  6. Run npm run check, then verify each acceptance criterion by hand, failure cases included.
  7. Do the explain-back out loud through all five steps. Read anything you cannot narrate.
  8. Commit the slice as one commit with a message describing the behaviour.

You are done when

One commit contains a workflow that works end to end, npm run check is green, and you can explain every changed line without opening the AI tool.

Common pitfalls

  • Letting the slice grow while inside it. "While I'm here" is how a three-file diff becomes eleven. Put the extra idea in the backlog and leave it.
  • Accepting a diff because the tests passed. Tests check what someone thought to check; reading catches the rest.
  • One giant commit at the end of the day. With no checkpoints, your only undo is "delete everything". Commit every time it works.
  • Asking for a retry instead of new information. If the second attempt fails the same way, you need a smaller reproduction.

Verify it yourself

Open today's reference, OpenAI's Codex CLI documentation.

  1. Find how the CLI shows what it changed and how you approve or reject changes. Compare with your git diff review — which shows you more, and what does each miss?
  2. Find whether it can be asked to plan without editing. Note the exact way to do that; a plan step you cannot enforce is one you will skip when tired.

Write both answers in docs/slice-1-notes.md. Making the tool stop before it edits is what keeps you the author of this project.

The hour

  1. 0–5 min Recall

    Without notes, state yesterday’s main idea and one unresolved question.

  2. 5–20 min Learn

    Read only the listed concept notes and official reference sections needed today.

  3. 20–48 min Build

    Have Codex plan and implement one flow from database to API to UI. Review every changed file and rerun checks.

  4. 48–55 min Explain and verify

    Run the result, inspect evidence, and explain the data/control flow in your own words.

  5. 55–60 min Quiz and commit

    Complete the quiz, record one lesson, and commit the verified change when applicable.

What to hand in

Deliverable

One complete, small workflow committed separately.

Working with AI today

AI as pair programmer

Define one small task, review the plan, inspect the diff, run checks, and explain every changed section.

Implement only this vertical slice after presenting the plan. Keep the diff small. Run checks and explain each changed file.

References

End-of-day quiz

Q1 What is a vertical slice?
Q2 Which result best proves today’s work is complete?
Q3 Before accepting an AI-generated code change, what should you do?

Explain-back gate

Pass the quiz above to unlock completion.

Quiz + explain-back checks required.