Milestone 6

Technical Specification (System Design Document)

Apologetic question: "What are you building on?"

Milestone 6 — Technical Specification (System Design Document)

“Everyone then who hears these words of mine and does them will be like a wise man who built his house on the rock.” — Matthew 7:24 (ESV)

Chapter: Chapter 6 — The Technical Specification Week: 6 of 16 · design phase · you are wearing the architect’s hat Due: End of Week 6, committed to your repository Submit: Commit and push to your default branch, then put the repository link and the commit hash in the Canvas dropbox Where it lands in the final package: docs/architecture.md, with diagram sources and rendered images under docs/diagrams/ and migration 0001 under migrations/. It feeds the design and architecture line of the Week-16 rubric, and in Week 13 you add a one-page overview to the front of this same file as a new §0 — Overview (a component diagram and five paragraphs) for the handoff package. Everything you write now stays underneath it — the Week-13 overview is an addition, never a replacement. AI policy: Open, with disclosure and verification. An assistant may draft interface contracts, enumerate error cases, and argue against your design. Every specific fact it produces — model identifier, endpoint path, header name, config key, limit, price — is verified against the vendor’s own documentation before it enters the document, with the date recorded. Substantive use is logged in docs/ai-usage.md per Appendix C. You sign this specification; sign only what you have read.

On weighting. Like every milestone in this course, this one is graded twice. It carries its own points in the 25% milestone bucket, and it is the deliverable — the Week-16 submission is 50% of your grade and it awards points for exactly the artifacts these milestones produce. Skipping this week does not save you the work; it forfeits the milestone and moves the work to a week that has none of the time and all of the panic.


The Setup

You have requirements a stranger could verify and a stack you chose on evidence. What you do not have is a design. Right now the only place your system exists as a system — as boundaries, contracts, and stored state rather than as intentions — is inside your head, and your head is not a deliverable. It is also, and this is the part students underestimate, not durable: the version of you that exists in Week 12 will not remember why expiry and notify are separate modules, and will merge them at 11pm because it seemed simpler at the time.

So this week you write it down. The document you produce is the thing a reviewer will attack in Week 8, the thing you will build from in Weeks 9 through 12, and the thing that tells whoever inherits this project why — the one question the source code will never answer.

The bar is the stranger test: a competent developer who has never spoken to you should be able to read this document, pick any Must-priority requirement, and start building it without asking you a single question. That is not a stylistic preference. It is exactly the situation you will be in during Week 12, when the stranger is you.

One thing to be clear about before you start, because it changes how you spend the fifteen hours. This document is not a description of your project. Descriptions are easy and worth nothing; you could write four pages describing PantryPilot without deciding anything at all. This document is a record of decisions — what “about to expire” means as an integer, which module owns the items table, what the timeout on the third-party call is, what a user sees when it fires. The grader will read your specification the way a builder would: by trying to build from it. Every place they have to guess is a place you left a decision on the floor for your future self to trip over.


Learning Targets

You will demonstrate that you can:

  • Decompose a system into containers and components, each with one responsibility and one owner.
  • Draw context and container diagrams whose boxes and arrows both carry information a builder can act on.
  • Specify an interface completely — inputs, outputs, errors, authorization, idempotency, side effects, and limits.
  • Design a data model with keys, types, nullability that means something, invariants, and a migration plan.
  • Sequence the critical paths, including what the system does when a boundary you do not control fails.
  • Decide error-handling policy and enumerate edge cases before they become defects.
  • Specify a nondeterministic dependency — an AI component or a third-party service — with a budget and a fallback.
  • Trace every Must requirement to a component and an interface, in both directions.
  • Distinguish a specification that decides things from one that merely describes them, and mark honestly what you have not decided yet.

Sizing This for Your Project Shape

This course is stack-agnostic, and “interface contract” does not mean the same artifact for every project. The seven parts of a specification do not change; what fills them does. Find your row, and if you are between two rows, do both.

Your project is…”Interfaces” means”Data model” meansThe risky path is usually
A web or mobile applicationHTTP endpoints, plus any webhook you receiveDatabase schema, entities, and relationshipsA third-party API, or auth
A command-line tool or libraryCommands, flags, exit codes, stdout/stderr contract; or public function signatures with pre- and post-conditionsOn-disk file formats and the in-memory structures the algorithm depends onMalformed input at scale, or a file system you did not create
A data or machine-learning pipelineStage boundaries: input schema, output schema, and the contract each stage promisesDataset schemas, intermediate artifacts, and the versioning of bothA data source that changes shape, or a model artifact you cannot reproduce
An embedded or hardware projectDevice protocols, message framing, and timing guaranteesPersisted state, buffer sizes, and what survives a power lossThe physical world: disconnection, noise, and power
A game or simulationThe system boundaries between engine subsystems, and any save-file formatEntity and world state, and what is authoritativeFrame budget, and state that must survive a save/load cycle

Whatever your row, the grading is the same, because the underlying question is the same: can a stranger act on this?


The weekly status block — paste this into your submission comment

Every milestone submission carries these five lines. It takes two minutes, it is the same five lines every week, and it is the difference between an instructor who can help you in Week 6 and one who finds out in Week 14. Copy it into the Canvas submission comment when you submit — not into a document.

Shipped:     what actually works this week, in one line
Cut:         what I dropped or deferred, and where it went (backlog / change request / gone)
Hours:       planned N / actual N        (from docs/hours-log.csv)
Blocked on:  the one thing in my way, or "nothing"
Ship confidence: green | amber | red — if amber or red, the one thing that would move it

Say red when it is red. A red in Week 6 is a conversation and a scope cut. A red discovered in Week 15 is a grade. Nobody has ever been penalised in this course for an honest amber; the only expensive answer is the green that was not true.


Normal Tier

Required deliverables

  1. docs/architecture.md, versioned v0.1 and dated, structured from code/tech-spec-template.md, containing items 2–9 below.
  2. Context and container diagrams — source and rendered image committed under docs/diagrams/. Every box labeled with a responsibility and a technology; every arrow labeled with payload and protocol; the trust boundary drawn; a legend, a version, and a date. One level-3 component diagram for the container where the hard part lives, or a sentence explaining why none is needed.
  3. A component responsibility table — component, one-sentence responsibility beginning with a verb, owned state, dependencies, and requirements served. No cycles in the dependency graph. No piece of state with two owners.
  4. Interface contracts for every interface that serves a Must-priority requirement, each with all eight facts from §6.4 of the chapter, plus one error envelope and one status-code policy for the whole system.
  5. A data model — every entity with purpose, primary key, attributes with types and nullability rules, invariants, relationships with cardinality, and a volume estimate — plus the migration decision (mechanism, forward-only or reversible, path and runner) and migration 0001 committed under migrations/.
  6. Three sequence flows — the money path, the risky path, and the failure path — each with numbered steps and a failure table giving system behavior and user-visible behavior per step.
  7. An error-handling policy covering the six failure categories, a timeout and retry rule for every call that leaves your process, and an edge-case register of at least twelve concrete entries.
  8. A dependency specification for your AI component (prompt contract, model identifier with verification date, output schema and validator, token/latency/cost budget with a hard cap, and a non-AI fallback) or, if you have none, for your riskiest third-party dependency.
  9. A traceability table and an open-questions list. Every Must requirement maps to at least one component and one interface; every component serves at least one requirement. Every open question carries what it blocks, an owner, and a date by which it will be decided.
  10. A clean run of code/spec-check.py against your specification and your requirements file, with the output pasted into your commit message or your hours log.

Normal-tier rubric (out of 100)

CriterionPoints
Context and container diagrams: labeled boxes, labeled arrows, trust boundary, legend, version, date10
Component responsibility table: one verb-led sentence each, single owner per piece of state, acyclic dependencies12
Interface contracts complete (all eight facts) for every Must-priority interface; one error envelope; one status-code policy16
Data model: keys, types, meaningful nullability, invariants, relationships, volume — plus the migration decision and migration 000116
Three sequence flows with numbered steps and a per-step failure table10
Error-handling policy across the six categories; timeout and retry rule per external call; edge-case register of 12+ entries10
Traceability both directions: every Must requirement served, every component justified10
Dependency specification: contract, budget, failure behavior, and a fallback that actually works without the dependency6
Open questions named with blocker, owner, and decide-by date5
Document quality: versioned, dated, committed, checker clean, and it survives the stranger test5
Total100

Medium Tier (+up to 25% extra credit)

Depth a reviewer will notice. Pick what fits your project:

  • A spike that de-risks the riskiest interface. Fifty lines of throwaway code that proves the third-party call actually returns what you specified — committed under spikes/, with a short note on what you learned and what changed in the specification because of it. This is the highest-value option on this list.
  • A performance budget traced through a flow. Take one non-functional requirement with a number in it and allocate that number across the steps of a sequence flow: this much for the database, this much for the network, this much left for your code. Then say which step you expect to violate it first.
  • Trust boundaries and a threat sketch. Annotate the container diagram with what crosses each boundary and who could be lying at each crossing, and name your three most likely abuse cases with a mitigation each.
  • An alternative design, considered and rejected. One full page: the design you did not choose, why it was attractive, and the specific requirement or constraint that ruled it out. If the decision is architecturally significant, promote it into a new architecture decision record extending your Milestone 5 set, using the next unused number in docs/adr/0005-....md if you wrote exactly the four that milestone required, higher if you wrote more. Never reuse a number that already exists; the numbers are permanent identifiers, and the ADR index you assemble in Milestone 13 assumes each one points at exactly one decision.
  • A defined interface versioning policy — what happens to callers when a contract changes, how you signal it, and what you promise not to break.
  • A machine-checkable interface definition — an OpenAPI document, a JSON Schema, a protocol buffer file, a typed function signature file, whatever your stack supports — committed alongside the prose contract and referenced from it. Prose and schema must agree; where they disagree, say which one wins.
  • A capacity sketch. Estimate the volume of each entity at the end of the semester and at ten times that, and name the first query that stops being fast. You do not have to fix it. You have to know it exists.

Hard Tier (+up to 25% additional extra credit)

Judgment, which is the thing no assistant can supply for you, because it requires owning a decision.

Write a two- to three-page Design Defense Memo, addressed to the reviewer who will run your Week-8 design review, that does four things:

  1. Argue against your own design. Name the weakest decision in the specification — the one you are least sure about — make the strongest case against it that you can, and then explain why you are proceeding anyway. “I could not find a weak point” is not an answer; it is evidence you did not look.
  2. Name the decision you would most regret, and the earliest signal that would tell you it was wrong. Be specific: not “if performance is bad,” but “if the expiry query exceeds 300ms on 2,000 rows in the Week 9 skeleton, this data model is wrong and I will normalize before Iteration One.”
  3. State your cut line. If you lost three weeks — illness, a failed integration, a job offer with a start date — which components come out, in what order, and what does the system still do afterward? A design that cannot degrade gracefully under a schedule shock is a design that will fail all at once.
  4. Make the AI honesty call. Exactly where an assistant contributed to this specification, what you verified and how, what it produced that you rejected and why, and the one design decision you are certain it could not have made for you. Reconcile it against docs/ai-usage.md.

Graded on honesty and self-awareness, not on polish. A memo that admits a real weakness and defends a real tradeoff scores far above one that quietly congratulates the design.


Submission

Commit to your default branch. The relevant part of your repository should look like this:

your-capstone/
├── docs/
│   ├── requirements.md          # Milestones 3 and 4
│   ├── architecture.md          # THIS milestone — v0.1, dated
│   ├── ai-usage.md              # updated with this week's sessions
│   ├── hours-log.csv            # updated with this week's hours
│   ├── adr/
│   │   ├── 0001-....md          # Milestone 5 — four or more, numbered from 0001
│   │   ├── ...                  #   (0002, 0003, 0004, ...)
│   │   └── 0005-....md          # Medium tier only — the next UNUSED number
│   └── diagrams/
│       ├── context.<src>        # diagram SOURCE (text, so it diffs)
│       ├── context.png
│       ├── containers.<src>
│       └── containers.png
├── migrations/
│   └── 0001-initial.sql
├── tools/
│   └── spec-check.py            # copied from this chapter's code/ directory
└── spikes/                      # Medium tier only

Then submit the repository link and the commit hash in the Canvas dropbox. The full submission conventions for the course are in Appendix C.


Hints

  • Start with Rep 1, the decision inventory. Everything else in the document is an answer to something on that list. Students who skip it write beautiful diagrams that answer no questions.
  • Write the data model before the interfaces. Interfaces move data around; if you do not know what the data is, the contracts will be wrong and you will rewrite them.
  • Specify the interface you understand least, first. The one you can already describe does not need your best hours.
  • Draw the failure branch before you finish the contract. It will change the contract. That is the whole reason to draw it.
  • One error envelope. One timestamp convention. One place local time is computed. Three sentences that will save you three bugs.
  • Mark what you do not know. An OPEN QUESTION with a blocker, an owner, and a date is a professional artifact. An unmarked hole is a landmine, and the person who steps on it is you.
  • Budget the hours as §6.13 of the chapter lays them out, and give the data model more than you think it needs. It is the one part you cannot cheaply fix later.
  • Read code/pantrypilot-spec-excerpt.md before you start writing, and Appendix B if you want more good-and-bad pairs. Seeing the difference is faster than being told about it.
  • Commit the diagram source, not just the picture. A .png in a repository is a fossil; nobody can update it, so nobody does, and by Week 14 your diagram is a lie. Text source diffs, and a diff is how a reviewer sees what changed between v0.1 and v0.2.
  • Do not specify what you are not going to build. A section describing a feature you have already cut is worse than no section: it makes the grader look for code that does not exist and makes your own traceability table wrong. If it is out of scope, say so once, in the scope section, and move on.
  • If you are stuck on a section, write the questions instead of the answers. Five sharp open questions beat one vague paragraph, they are honest, they carry partial credit, and they turn straight into your Week-8 review agenda.

What Happens to This Document Next

Write it knowing where it goes. Nothing you produce this week is thrown away.

WeekWhat happens to docs/architecture.md
8It is the artifact under review. A reviewer walks it section by section and logs defects against it, and then it is baselined — from that point, changes go through change control and into CHANGELOG.md
9The walking skeleton is built from the container diagram: the thinnest slice that touches every box
10–12The interface contracts and the data model are what you build against. Every one of the eleven decisions you made this week is a question you do not have to answer while tired
11The edge-case register and the acceptance criteria become test cases, largely verbatim
13A one-page §0 — Overview is added to the front of this file for the handoff package. The sections you write now are not condensed away — they stay underneath §0, updated as built, and they are what the Week-16 technical-specification line is graded against
16It is graded as part of the 50% final, and you present from its diagrams

What Mastery Looks Like

A masterful technical specification is boring to read and impossible to argue with. Every box has a job. Every arrow says what crosses it. Every interface tells you what happens when it fails, and the failure is a decision rather than an accident. The data model has invariants written in words, and the words are true. The three sequence flows include the one where the network dies, and that flow visibly changed something upstream — you can see the design being made on the page.

And it is honest. The open questions are listed, not hidden, each with an owner and a date. Nowhere does it say “handle errors appropriately,” because that sentence means “I have not decided,” and this document does not pretend. When a reviewer asks the hardest question in Week 8, the answer is already on page four — or it is on the open-questions list with a date next to it, which is the second-best answer and infinitely better than a confident guess.

There is one more mark of mastery, and it is the one that separates a good student specification from a professional one: it is proportionate. The data model and the risky interface get pages; the parts that are genuinely obvious get a sentence. A specification that spends equal ink on everything has not been thought about — it has been filled in. The author of a proportionate document has decided where the danger is, and the reviewer can see that decision from the table of contents.

Coach’s Note — You will be tempted, somewhere around hour nine of this week, to write a section that sounds complete instead of one that decides something. It happens right when you are tired and the deadline is close and the topic is the one you understand least — which is precisely the section that most needs a decision. When you catch yourself doing it, stop and mark it OPEN with a date. An admitted gap is a professional act. A disguised one is the thing that fails you in Week 12.

When You’re Done

  • docs/architecture.md exists, versioned v0.1 and dated
  • Context and container diagrams committed as source and image; every arrow labeled; trust boundary drawn
  • One level-3 diagram, or a written reason none is needed
  • Component responsibility table: verb-led sentences, single owner per piece of state, no cycles
  • Interface contracts complete for every Must-priority interface; one error envelope; one status-code policy
  • Data model with keys, types, nullability meanings, invariants, and volume estimates
  • Migration decision written down; migration 0001 committed and runnable by a stranger
  • Three sequence flows, each with a per-step failure table
  • Error-handling policy; timeout and retry rule for every external call; 12+ edge cases registered
  • AI or third-party dependency specified, with a budget and a working fallback
  • Traceability verified in both directions; open questions have blocker, owner, and date
  • spec-check.py runs clean against the specification and the requirements
  • Stranger test run on a live human; their questions written down for the Week-8 review
  • docs/ai-usage.md and docs/hours-log.csv updated honestly
  • Committed, pushed, and the link submitted

A theological footnote. “Everyone then who hears these words of mine and does them will be like a wise man who built his house on the rock” (Matthew 7:24, ESV). The parable turns on two things, and neither is the weather. The first is the foundation: both houses faced identical rain, floods, and wind, and only the footing differed. The second is quieter and sharper — both builders heard. The wise one is the one who heard and did. That is the whole difference between reading this chapter and writing this document. Your specification is not a foundation in the sense Jesus means; the rock is his word and the house is a life, and Paul is blunt that no one lays a foundation other than the one already laid (1 Corinthians 3:10–11). Your standing before God was settled outside of you and is not on this rubric. But the smaller work is still real work, done in a world God ordered so that things built on what is true tend to stand. Writing down what you will build, plainly enough that a stranger can check it, is an act of service toward the people who come after you — the reviewer, the roommate, the next engineer. Do it as unto the Lord, and then go build the house.