Building Your Capstone Workbench
Getting a repository, a board, an hours log, and a place to run code — including on a locked-down laptop with no administrator rights
Appendix A — Building Your Capstone Workbench
“For which of you, desiring to build a tower, does not first sit down and count the cost, whether he has enough to complete it?” — Luke 14:28 (ESV)
A carpenter does not choose a bench by how expensive it is. He chooses it by whether it holds the work. This appendix builds yours, and the first thing I want you to know is how small it actually is.
This course’s infrastructure footprint is tiny. Five pieces, and four of them are free forever: a GitHub account, a place to edit and run code, a project board, an hours log, and a diagramming tool whose output you can commit. That is the whole backbone. Every milestone before Week 9 is a document you write in a web browser — with one wrinkle worth knowing up front: four of those weeks (1, 4, 5 and 6) also ask you to run a small Python checker against the document you just wrote, and a browser editor cannot run anything. That costs you a couple of free minutes in a cloud environment, or eight lines of GitHub Actions configuration you write once — both are in A.6, and neither requires installing a thing. Construction of your own system does not start until Week 9. If you are reading this in Week 1 and bracing to spend a weekend and two hundred dollars getting set up, relax — you will spend about three hours, and you can spend zero dollars.
Your own project may need more than the backbone: a database, a host, an API key, occasionally a piece of hardware. Section A.8 tells you how to get each of those cheaply, and — more importantly — when. The answer is almost never Week 1.
There are two paths through this appendix. Path A installs nothing, requires no administrator rights, and works from a locked-down school or work laptop, a Chromebook, or a library computer. It is the default, and it is not a lesser option — in Week 9 you will find that a browser-only student’s environment is more reproducible than a local one, because the environment definition lives in the repository where a grader can use it too. Path B is a local toolchain on a machine you control: faster, offline-capable, and it needs rights you may not have. Read A.1, pick your path, build it, then run the verification pass in A.12 before Week 1 ends.
Two honest caveats, and they run through every section.
Every price, version, free-tier limit, and allowance in this appendix is approximate and dated to 2026. Vendors change them without warning and without apology. Treat every number here as a snapshot that tells you the shape of the thing, then verify the current terms on the vendor’s own page before you commit money or a deadline to it. Writing down the number with the date you checked it is a professional habit you will need again in Week 5 and Week 14.
Do the work yourself. You may absolutely ask an assistant how to create a repository. What you may not do is paste a setup script you do not understand into a terminal and call the bench built. When your first push is rejected, read the error. That fifteen minutes is not lost time — it is the reason you will not lose an hour to the same error in Week 12, at midnight, with a milestone due.
A.1 — Choose Your Environment
Start by being honest about your machine and your permissions. Nothing in this decision is about ambition; it is about what you can actually run on the computer you actually have.
| Your situation | Take this path |
|---|---|
| Locked-down school or work laptop, no administrator rights, a Chromebook, a borrowed or shared machine, a low-RAM machine, or you simply want the cheapest path that works | Path A — browser-only (A.2). Nothing installed, no admin, free tiers. |
| You have admin rights on a machine you own, enough disk for a toolchain, and you want speed and offline work | Path B — local (A.3). Free, fast, fully yours. |
| Admin rights at home, none on the campus machine you use between classes | Hybrid. Build Path B at home and commit the Path A environment definition so you can work anywhere. This is the strongest setup in the course and costs about twenty extra minutes. |
What every path must give you by the end of Week 1, regardless of which you pick:
- A repository on GitHub with the canonical structure from Chapter 1 §1.5.
- A place to edit files, plus some way to run a Python script — needed in Weeks 1, 4, 5 and 6 for the milestone checkers (A.6), and needed continuously from Week 9 for your own code. Browser or local.
- A project board with columns and a work-in-progress limit.
- An hours log in the repository, in version control, not in your downloads folder.
- A diagramming tool whose source is a text file you can commit.
That is it. Five things. Now the table that stops you from over-provisioning.
Milestone → minimum environment
The left column is what the course asks of you; the right column is the smallest environment that can deliver it. Read down the right column and notice how far you get on a browser plus a few borrowed minutes of free compute. Where a row says a checker run, it means one of the course’s small Python scripts, which are stdlib-only and take seconds — see A.6 for the two free ways to run one without installing anything.
| Wk | Milestone | Minimum environment | Costs money? |
|---|---|---|---|
| 1 | Project Charter & Engineering System | Browser: GitHub + a text editor in the browser, plus a checker run — hours_report.py must run against your log (A.6) | No |
| 2 | Idea Portfolio & Scoping Decision | Browser | No |
| 3 | Software Requirements Specification v1 | Browser | No |
| 4 | Non-Functional Requirements, Constraints & Definition of Done | Browser, plus a checker run — check-traceability.py against your matrix (A.6) | No |
| 5 | Technology Evaluation & Architecture Decision Records | Browser, plus a checker run — score-stack.py must exit 0 (A.6) — plus vendor pricing and license pages you read yourself | No |
| 6 | Technical Specification | Browser + a diagram tool (A.7), plus a checker run — spec-check.py against your specification (A.6) | No |
| 7 | Work Breakdown, Schedule & Risk Register | Browser + a spreadsheet or CSV | No |
| 8 | Design Review & midterm checkpoint — no milestone | Browser | No |
| 9 | Walking Skeleton & Continuous Integration | First week you run your own code: a cloud development environment or a local toolchain, plus CI on GitHub | No |
| 10 | Core Increment & Demo | Same as Week 9 | Only if your project calls a paid API |
| 11 | Test Plan, Test Suite & Defect Log | Same as Week 9 | No — stub paid calls in tests |
| 12 | Integrated Release Candidate & Change Log | Same, plus whatever third-party services your design named | Maybe |
| 13 | Documentation Set & the Clean-Machine Test | Same, plus a second, genuinely clean environment (A.11) | No |
| 14 | Deployable Release v1.0 & Handoff Package | Same, plus a host — or a written, defended constraint if you cannot host | Possibly. The only week that reliably might. |
| 15 | Presentation Deck, Demo Script & Rehearsal | Browser + a screen recorder for the fallback recording | No |
| 16 | The Final Submission | Browser + a clean machine for the last acceptance test | No |
What you do not need for this course. No GPU. No expensive laptop. No paid editor. No paid diagramming tool. No domain name. No paid continuous-integration plan. No Docker Desktop licence. If somebody tells you a senior capstone requires you to buy hardware, hand them this table.
Coach’s Note — The most expensive mistake in Week 1 is provisioning for Week 14. Students spin up a database, a hosting account, and an API key in the first week — before they have an idea, let alone a design — and by Week 12 two of the three have lapsed, changed terms, or quietly started billing. Provision the backbone now and add each service the week the milestone actually needs it. That is not procrastination; it is the same discipline that makes you write non-goals in your charter.
A.2 — Path A: The Browser-Only, No-Admin Path (the default)
Nothing installed. No administrator rights. No BIOS setting, no toolchain, no sudo. Everything below runs in a web browser on a machine you do not own.
Step 1 — A GitHub account (the backbone of every submission)
Sign up free at https://github.com. Use an email address that will still work after you graduate — your capstone repository is a thing you will link to in an interview eighteen months from now, and a dead school email is a locked account.
A free personal account has historically included unlimited public and private repositories, the built-in Projects boards, and Actions minutes for public repositories, with a monthly included allowance for private ones. That has been stable for years, but tiers change — confirm the current terms at https://docs.github.com before you depend on any of it. If your institution provides GitHub accounts or a GitHub Classroom organization, prefer it, and ask one question up front: does the account survive graduation, and can you transfer the repository out? If the answer is no, keep your capstone on a personal account and add your instructor as a collaborator.
Then, before you write anything: verify your student status at https://education.github.com/pack. The Student Developer Pack bundles free and discounted offers from a rotating set of vendors — the contents change constantly, so I will not tell you what is in it, only that it takes ten minutes and is the single highest-return ten minutes in this appendix. Several of the things Section A.8 tells you to pay for may be free to you.
Step 2 — A place to edit files in the browser (free, instant, no compute)
For Weeks 1–8 you are mostly writing documents rather than building software. You need a text editor, and GitHub has one built in.
Open any repository you own and press the . key. GitHub opens a full editor in the browser tab — file tree, search, multi-file editing, commit and push from the sidebar. Nothing installs. It works on a Chromebook, a library computer, and a laptop whose IT department has locked everything down. This is where you will write docs/charter.md, docs/requirements.md, and every other document through Week 8.
Know its one limitation before it surprises you: it is an editor, not a computer. There is no terminal and nothing runs.
That is fine for prose, and it is not enough for four milestones you will hit long before Week 9. Weeks 1, 4, 5 and 6 each grade a run of a small Python checker against the document you wrote — the hours report in Week 1, the traceability checker in Week 4, the stack scorer in Week 5, the specification linter in Week 6. You do not need a laptop, admin rights, or a dollar to satisfy any of them; you need one of the two free routes in A.6, which you can set up in Week 1 and then stop thinking about. And from Week 9, when you are running code you wrote yourself, the editor stops being enough at all — which is why there is a Step 3.
Step 3 — A cloud development environment (minutes at a time from Week 1, continuously from Week 9)
From Week 9 you need something that can actually execute your code, install dependencies, and run a test suite — and before then you need it in short bursts, a few minutes per milestone, to run the checkers named in Step 2. The default recommendation is GitHub Codespaces: a Linux container running a full editor in your browser, with a real terminal, launched from your repository in about a minute. You are root inside it. No admin rights on your laptop are involved at any point.
As of 2026 a free personal account has included a monthly allowance on the order of 120 core-hours and 15 GB of storage — roughly 60 hours a month on a 2-core machine. Treat that number as approximate, verify it in GitHub’s current billing documentation, and understand the two things that actually bite students:
- Storage is billed on stopped codespaces, not just running ones. Delete codespaces you are done with; do not merely stop them. A forgotten codespace quietly eats the allowance you wanted in Week 13.
- A codespace’s disk is not backup. Anything not committed and pushed can vanish. Commit at the end of every session — which you should be doing anyway, because Milestone 1 grades your commit history.
The piece that makes this a better setup than a local one: commit a .devcontainer/devcontainer.json to your repository describing the environment — base image, language version, extensions, and a postCreateCommand that runs your setup script. Now the environment is a versioned artifact of the project rather than a private fact about your laptop. A grader, a classmate, or your Week-14 successor gets the identical machine by opening the repository. The specification lives at https://containers.dev. Write the file in Week 9 when you know your stack; do not guess at it now.
If your institution disables Codespaces, or you burn the allowance, you have three fallbacks, in order of how much I recommend them: a browser IDE (Replit and StackBlitz both run real code in a browser tab; free tiers vary and change, so read the current terms), a hosted notebook such as Google Colab if your project is Python and notebook-shaped, or a small cloud virtual machine you reach from a browser shell — see A.8, where it costs a few dollars a month or nothing at all.
Step 4 — The board, the log, the diagrams
All three are browser-native, and they get their own sections because they are course requirements rather than environment choices: the board is A.5, the hours log is A.6, diagramming is A.7. Every one of them works with nothing installed.
Step 5 — Prove Path A works
Do this now, in about ten minutes. If all five steps pass, you have a working capstone workbench and you never touched your laptop’s settings.
- Create a repository on GitHub (private is fine; you can open it later).
- Press
.in that repository. The browser editor opens. - Create
README.mdwith one real sentence about what this repository is. Commit it from the sidebar with the messageM1: repository created. - Confirm the commit appears on the repository’s main page, with today’s date.
- Open the repository’s Actions tab and confirm it is available to you. You will need it in Week 9; better to learn now if your institution has disabled it.
A.3 — Path B: The Local Path (needs admin rights and your own machine)
If you own the machine and can install software, a local toolchain is faster, works on a plane, and does not consume anybody’s monthly allowance. It requires rights that a school laptop very often does not grant. If you cannot get administrator rights, use Path A and do not fight it — you lose nothing that is graded.
Five pieces:
| Piece | Purpose | Notes |
|---|---|---|
| Git | Version control, the whole course | Ships with macOS developer tools; install from https://git-scm.com on Windows |
| An editor | Where you write everything | Any editor with Git integration and a Markdown preview. Free ones are entirely sufficient. |
| Your language toolchain | Running the code, from Week 9 | You do not know which one yet — you pick your stack in Week 5. Do not install it in Week 1. |
| Python 3 | The four milestone checkers in Weeks 1, 4, 5 and 6 (A.6) | Present on most Linux systems, and on macOS once the developer tools are installed — the same install that gives you Git. On Windows, install it from https://python.org in Week 1. This is not your project’s stack; it is only what the course’s checkers happen to be written in, and they need no packages. |
| A terminal | Commands, scripts, CI parity | Built into macOS and Linux; Windows Terminal ships with Windows 10/11 |
Set your Git identity once, before your first commit, or your history will be attributed to someone who is not you:
git config --global user.name "Your Name"
git config --global user.email "you@example.edu"
git config --global init.defaultBranch main
Authenticate your pushes. Pick one and stop thinking about it:
- A personal access token. In GitHub, under Settings → Developer settings → Personal access tokens → Fine-grained tokens, create one scoped to your capstone repository with contents read/write. Use it as the password when Git prompts. Cache it with
git config --global credential.helper store— note that this writes the token to a file in your home directory in plain text, which is fine on a machine only you use and not fine on a shared one. - An SSH key.
ssh-keygen -t ed25519 -C "capstone", then paste the contents of the public file (~/.ssh/id_ed25519.pub) into GitHub → Settings → SSH and GPG keys. Never paste the private one anywhere, ever, including into an assistant.
On version pinning, one rule that saves Week 13: whatever toolchain you install in Week 5, pin its version in a file in the repository — a version file, a lock file, a container definition, whatever your ecosystem uses. Then write the version in your README.md prerequisites. The single most common clean-machine failure is a project that runs on the author’s minor version and nowhere else.
The hybrid setup, if you can manage it: work locally, but keep the .devcontainer definition current so you can open the same project in a browser from a locked-down campus machine. Twenty minutes of work in Week 9 buys you the ability to make progress from any computer for the remaining seven weeks — and it is exactly the reproducibility Week 13 grades.
A.4 — The Repository and Its Structure
The repository is not storage. It is the deliverable. Seventy-five percent of your grade — the 50 percent final plus the 25 percent of milestones that build it — is a link to it, and every milestone lands in a named slot inside it. Create the whole tree in Week 1 with placeholders, so that every later week is a matter of filling a slot rather than deciding where something goes.
The canonical layout is in Chapter 1 §1.5 and is repeated on Milestone 1. Here is how to create it.
In the browser (Path A). GitHub’s web editor will create a directory when you type a path with slashes in it. Create each file with a one-line placeholder saying what it is and which week fills it — an empty file is invisible in a diff, and a placeholder is a to-do list you cannot lose. The one exception is docs/hours-log.csv: it is a data file, not a document, so give it the header row from A.6 instead of a Markdown placeholder — the report script in A.6 and A.12 reads that file by name and will fail on anything else. Git does not track empty directories, so src/, tests/, docs/adr/, and .github/workflows/ each need a .gitkeep file (an empty file whose only job is to exist).
From a terminal (Path B, or inside a cloud development environment):
mkdir -p docs/adr docs/diagrams src tests tools .github/workflows
touch docs/adr/.gitkeep docs/diagrams/.gitkeep src/.gitkeep tests/.gitkeep .github/workflows/.gitkeep
for f in charter ai-usage scoping-decision requirements \
definition-of-done architecture plan risk-register \
test-plan defect-log runbook handoff; do
[ -e "docs/$f.md" ] || printf '# %s\n\n_Placeholder — filled in its week. See the course plan._\n' "$f" > "docs/$f.md"
done
# The hours log is a CSV, not a document — seed it with its header row, not a placeholder.
[ -e docs/hours-log.csv ] || printf 'date,start,end,hours,phase,hat,task,estimate_hours,blocked_hours,notes\n' > docs/hours-log.csv
git add -A && git commit -m "M1: canonical repository structure"
Then, before you push anything else, do the two things that are cheap now and expensive later.
Write the .gitignore first — before there is anything worth ignoring. A starter that covers the usual offenders regardless of stack is provided with Chapter 9 in that chapter’s companion files, and the mechanics of secrets are in A.9 below. The rule to internalize today: .env never enters the repository, and Git history is permanent memory.
Decide the licence, or defer it with a date. Read the actual text at https://spdx.org/licenses/ or use https://choosealicense.com/, and check whether your institution claims any rights in student work — many do, and it is a five-minute question now and an ugly one in Week 14. If you are not ready, commit a LICENSE file containing a dated line saying the decision is deferred to Week 5 and why. A dated deferral is a decision. An empty file is a hole.
One warning about the history itself: do not delete and re-create the repository in Week 6 because the early commits embarrass you. The history is evidence, it is graded, and a repository whose first commit is dated in Week 6 tells a story you do not want told.
A.5 — The Board, Wired to Requirement Identifiers
A board is a queue with a limit. Without the limit it is a list, and a list of forty things is a mood.
GitHub Projects is the default recommendation, because it lives beside the repository and can link a card to an issue, an issue to a branch, and a branch to the commits that closed it. That chain is what lets you answer, in Week 11, “which commits implemented FR-014?” — with a query instead of an archaeology expedition. Create one from your repository’s Projects tab, in the browser, free.
Set it up once, this way:
- Five columns: Backlog, This Week, In Progress, Blocked, Done.
- A work-in-progress limit of two in the In Progress column. If your board tool does not enforce a limit for you, enforce it yourself by naming the column
In Progress (max 2)and honoring it. The limit is not decoration; it is the entire value of the board. - Three custom fields on every card:
Estimate(hours, a number),Hat(which of the seven you are wearing), andRequirement(the identifier from your requirements specification — empty until Week 3, mandatory after).
That third field is the wiring. From Week 3 onward, every card carries a requirement identifier, every branch is named for one (fr-014-expiry-warning), and every commit subject begins with one (FR-014: warn when an item expires within 3 days). Three weeks of tiny discipline, and then Week 11’s traceability matrix and Week 12’s change log write themselves out of git log.
Cards are verifiable work items, not nouns. Compare:
Build the backend
against
FR-014 — Warn on items expiring within 3 days
Estimate: 3h Hat: developer Branch: fr-014-expiry-warning
Done when: FR-014's acceptance criteria pass and CI is green on main.
The first cannot be finished, estimated, or moved to Done without an argument with yourself. The second has a size, a home, and a stopping condition.
If you would genuinely rather use a different tool — a Kanban service, a spreadsheet, index cards on a wall — use it, on one condition: it must survive to Week 16. A board abandoned in Week 6 is worse than no board, because it makes you feel tracked while telling you nothing. Whatever you choose, put a link to it in your README.md so a grader can see it.
A.6 — The Hours Log
docs/hours-log.csv, in the repository, in version control, from Week 1. Not a spreadsheet in your downloads folder, not an app on your phone, not your memory.
The template and the report script both ship with Chapter 1 — hours-log.csv and hours_report.py, in that chapter’s companion files. Copy both into your repository; the script goes in tools/. The columns:
date,start,end,hours,phase,hat,task,estimate_hours,blocked_hours,notes
Path A students: you can maintain this entirely in the browser. Edit the CSV in GitHub’s web editor and commit — sixty seconds at the end of a session, and the commit timestamp is itself a small piece of evidence. To run the report without a local Python installation, you have two options. Open a cloud development environment for two minutes and run it:
python3 tools/hours_report.py docs/hours-log.csv
Or — better, and it doubles as continuous-integration practice before Week 9 — add a workflow that runs the same command on every push and prints the report in the Actions log. Then your weekly total is a click away from any browser, on any machine, forever.
Running any of the course’s checkers without a computer
This is the section to come back to whenever a milestone says “and the checker must run clean.” It is not only the hours report: four milestones before Week 9 grade a checker run — hours_report.py against your log in Week 1, check-traceability.py against your matrix in Week 4, score-stack.py against your evaluation matrix in Week 5, and spec-check.py against your specification in Week 6. Each one ships with its own chapter’s companion files, and every one of them is a single Python 3 file that imports nothing but the standard library. That matters: there is no install step, no dependency file, and no version negotiation. If a machine has Python 3, it can run all four.
So you have two free routes, and Path A students should pick one in Week 1 rather than discovering the problem on a Thursday night.
Route one — borrow a machine for two minutes. Open a cloud development environment from your repository (A.2 Step 3), run the command, read the output, and delete the environment when you are done. Best while you are iterating, when you want to fix a finding and immediately re-run.
Route two — let a workflow run it, and never think about it again. Copy each checker into tools/ as its milestone arrives, then keep one workflow file at .github/workflows/checks.yml. Every push runs it, and the output waits for you in the repository’s Actions tab, readable from any browser on any machine you can sign in from. The whole job is eight lines:
name: checks
on: [push]
jobs:
run-checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # confirm the current major version
- run: python3 tools/hours_report.py docs/hours-log.csv
Add one - run: line per checker as the weeks bring them, pointed at the real file each one grades:
- run: python3 tools/check-traceability.py docs/traceability.csv
- run: python3 tools/score-stack.py docs/tech-evaluation.csv
- run: python3 tools/spec-check.py docs/architecture.md --requirements docs/requirements.md
A checker that exits non-zero fails the job and marks the commit with a red X on github.com. That is the feature, not the annoyance — it is the same red X that Week 9’s continuous integration will start giving you, arriving eight weeks early while the stakes are a CSV file instead of a release candidate. As of 2026, Actions minutes have been free for public repositories and metered by a monthly allowance on private ones; verify the current terms before you set anything to run on a schedule.
The rules that make the number mean something are in Chapter 1 §1.6, and I will repeat only the one that this appendix can enforce: log at the end of the session, not the end of the week. A retro-filled log is fiction with a file extension. Put the log in whatever place you will actually reach — a browser tab pinned all semester, a terminal alias, a phone bookmark to the file on github.com, which is editable from a phone if that is what it takes.
Coach’s Note — “A false balance is an abomination to the LORD, but a just weight is his delight” (Proverbs 11:1, ESV). Nobody audits this file. No grader can prove your 2.5 was really a 2.0. That is precisely why it measures you rather than your project — and why it is the one artifact in your repository that is worth more to you than it is to me.
A.7 — A Diagramming Tool Whose Source You Can Commit
Week 6 requires context and container diagrams. Week 13 requires an architecture overview with a diagram in it. Both are graded, and both have one requirement that eliminates most of the tools students reach for first:
If you cannot commit the source, it is not a tool you can use in this course. A photograph of a whiteboard does not diff. A drawing locked inside a web application you will stop paying for does not survive the handoff. Your successor needs to edit the diagram, not admire it.
Three options, all free, all browser-capable, in the order I recommend them.
| Tool | Source you commit | Renders where | Best for |
|---|---|---|---|
| Mermaid (https://mermaid.js.org) | A fenced code block inside a Markdown file — the diagram is text in your document | GitHub renders it directly in the browser; the live editor at https://mermaid.live previews it | The default. Architecture, sequence, and entity diagrams that live next to the prose they explain and update in the same commit. |
| PlantUML (https://plantuml.com) | A .puml text file | Editor plugins, a local renderer, or a public server | Richer UML when you need it. Do not paste anything sensitive into a public rendering server. |
| A drawing editor — Excalidraw (https://excalidraw.com) or diagrams.net (https://app.diagrams.net) | The tool’s own file format, which is text and diffs badly but is committable | Export a PNG or SVG alongside the source | Sketchy, hand-drawn context diagrams and anything a text syntax fights you on. |
The house convention, matching Chapter 6: commit both the source and the rendered image, under docs/diagrams/. The source so it can be edited; the image so it displays anywhere, including in a presentation slide in Week 15 and in a PDF nobody can regenerate. Name files for what they show — context.mmd and context.svg, not diagram2-final-FINAL.
Start with Mermaid unless you have a specific reason not to. It requires nothing installed, it renders in your repository where a grader is already looking, and — the property that actually matters — when you change the architecture in Week 12, the diagram shows up in the same pull request as the change. Diagrams that live outside version control go stale silently, and a stale architecture diagram is worse than none, because it is confidently wrong.
A.8 — What Your Own Project Might Add
The backbone above is free and universal. Your project may need one or more of the following. Read this section when the milestone that needs it arrives — Week 5 for the decision, Week 9 for the database, Week 14 for the host — and not before.
A database. Start by asking whether you need a server at all. For a single-user or small-household capstone, an embedded database in a file — SQLite is the usual answer — costs nothing, installs nothing, needs no account, no host, and no credentials, and it survives the handoff perfectly because it is a file in the repository’s ignore list with a schema in migrations/. Most capstones that provision a managed database in Week 5 did not need one, and paid for it with a Week-12 outage. If you genuinely need a client-server database (multiple concurrent writers, a hosted deployment, a data type your embedded option cannot express), free tiers of managed Postgres and MySQL exist from several vendors, and the Student Developer Pack often includes credits. Whatever you choose: read the current free-tier terms yourself, write down what happens when they end, and put it on the watch list in A.10.
A place to host it. Chapter 14 covers what “deployed” honestly means for each shape of project, and the short version is that not every project needs a server. A static site or client-only application deploys to free static hosting wired to your repository — GitHub Pages is free for public repositories, though terms change; verify. A command-line tool “deploys” as a tagged release with a built artifact attached, and hosting one to look impressive is a waste of a week. A web application with a database is the one shape that reliably costs something, and the cheapest paths that work are a small platform-as-a-service hobby plan or one small virtual machine. As a rough shape, as of 2026: a small virtual machine from a budget provider runs about $4–6 a month (Hetzner has been around €4, DigitalOcean, Linode, and Vultr in the same neighborhood), and Oracle Cloud has offered an Always Free ARM instance — approximately 2 cores and 12 GB of memory in mid-2026, after a cut from a more generous earlier allotment — which is free for as long as you stay inside the limits. If you are a verified student, Azure for Students has offered around $100 of credit with no credit card required, renewable while you remain enrolled. Every one of those numbers is a snapshot. Check the vendor, write the number and the date in docs/handoff.md, and never quote a free tier from memory in a document that gets graded.
An AI API, if your project has an AI feature. Model prices, free allowances, rate limits, and context windows change more often than anything else in this appendix, and they vary by vendor and region — so this book will not give you a number. Look it up on the vendor’s own pricing page, write it into your requirements or assumptions section with the date you checked it, and re-check before Week 14. Four cost controls that hold regardless of vendor: develop against the smallest model that exhibits the behavior you are testing; cache responses during development so you are not paying to re-run the same prompt forty times; stub the client in your automated tests and put real-provider tests behind a flag you run by hand, or CI will bill you on every push; and set a spending limit on the account if the vendor offers one. If you have a machine you control with reasonable memory, running a small model locally is a legitimate zero-marginal-cost path for development — but note that a hosted CI runner cannot reach a model running on your laptop, so anything CI must exercise needs to be stubbed or pointed at a hosted endpoint.
Anything else — hardware, a paid data set, a device to test on. Two rules. Do not buy it before Week 5, when your technology evaluation has actually justified it in writing. And if it costs money you do not want to spend, that is a constraint, which goes in your requirements document as a constraint and is graded as one. A capstone shaped honestly around a real limitation earns more than a capstone that pretended the limitation away and ran out of money in Week 13.
Coach’s Note — The sentence I want you to be able to say in Week 15 is: “Here is what this system costs to run, per month, and here is what happens when the free tier ends.” Every student who can say that has a project somebody could actually take over. Every student who cannot has a demo. The difference is about thirty minutes of reading vendor pages, done in the right week.
A.9 — Secrets and Keys: The Mechanics
The rule is simple and the mechanics are worth learning once: no credential ever enters the repository. Not in a config file, not in an architecture decision record, not “temporarily,” not in a commit you plan to amend. Git history is permanent, public memory, and a key pushed at 1 a.m. is a key that is scraped by breakfast.
Where the secret actually lives, by path:
| Where you are working | Where the key goes | How your code reads it |
|---|---|---|
| Local machine (Path B) | A .env file in the project root, listed in .gitignore before you create it | Environment variable |
| Cloud development environment (Path A) | The platform’s own secret store — in Codespaces, GitHub → Settings → Codespaces → Codespaces secrets, scoped to your repository | Environment variable, injected for you |
| Continuous integration | Repository secrets — repository Settings → Secrets and variables → Actions | ${{ secrets.NAME }}, referenced by name only |
| A deployed host | The host’s secret store or injected environment variables | Environment variable |
In all four the code reads an environment variable and never knows the difference. That is the point: one code path, four storage locations, no if statements about where you are running.
Commit a .env.example listing every variable your application reads, each with a placeholder value. It doubles as documentation — a stranger can see what the application needs — and it is what makes the clean-machine test in Week 13 possible. The rule that goes with it: your application must start with only .env.example values plus a local database. If it cannot, your README’s promise is a lie and a grader will find out.
Two things students get wrong, both expensive:
- Never echo a secret in a CI step, never dump the whole environment, and never turn on shell tracing in a step that touches one. Providers mask registered secret values in logs on a best-effort basis, and that masking does not survive you transforming the value.
- If a secret is already committed, rotate first, clean second. Revoke the credential at the provider and issue a new one before you touch the history. Rewriting history does not reach forks, clones, caches, or anybody’s terminal scrollback. Rotation is the fix; cleaning the history is the tidy-up.
The full checklist — including the audit commands that find a key already sitting in your history — ships with Chapter 9 as its secrets-and-config checklist. Run it before your first push, and again before every push for the rest of the term.
A.10 — The Free-Tier Watch List and the Teardown Checklist
Free tiers end. They sleep after inactivity, they expire on a date, they get cut in half in a quiet blog post, they convert to paid when you cross a threshold nobody told you about. The failure this produces is always the same and always at the worst time: it is Week 12, your integration works on your machine, and the service your project depends on stopped answering.
The fix is a table, started the day you create your first account. Keep it in docs/handoff.md — it is a required section there in Week 14 anyway, so starting it now costs you nothing and saves you the archaeology.
| Service | What it gives me | Plan | Free until / limit | Date checked | Whose card is on file | What breaks when it ends |
|---|---|---|---|---|---|---|
| GitHub | Repository, board, Actions, Codespaces | Free personal | Monthly Actions and Codespaces allowance | 2026-09-08 | None | CI stops; browser environment stops |
| your database | Managed Postgres | Free tier | what the vendor’s page says today | Mine | The application cannot start | |
| your host | Public URL | Hobby | sleeps after N minutes idle? | Mine | The grader’s link 404s | |
| your model API | Recipe suggestions | Pay-as-you-go | rate limit; balance | Mine | One feature degrades — is that handled? |
Fill in the real numbers from the vendor’s page, not from a blog post and not from an assistant, which will state expired limits with total confidence. Then set two calendar reminders: one in Week 8, where the design review’s environment audit asks whether your workbench still works and when your free tiers end, and one in Week 14, before you write the handoff.
Notice the last column. It is the one that turns a billing detail into a design requirement: if the answer to “what breaks” is “the whole system, silently,” you have found a non-functional requirement and a risk-register row, and you found them in Week 5 instead of Week 12.
The teardown checklist
Anything you provisioned gets torn down when you are done with it. Run this every time — after a rented machine, after a spike, after the semester:
- Pull off anything you need first. Data, logs, the final database dump, screenshots for the presentation. Once it is deleted it is gone.
- Delete, do not merely stop. A stopped virtual machine can still bill for its disk; a stopped cloud development environment still bills for storage. Delete the resource.
- Revoke the keys that belonged to it, at the provider. A live key for a dead service is pure liability.
- Check the billing dashboard the next morning and confirm the spend actually stopped. Not the same day — the next day, when the meter has caught up.
- Update the watch list so the row reflects reality. A handoff document that lists a service you deleted is a landmine for your successor.
- If you set a budget alert, leave it on. It costs nothing and it is the only thing standing between you and a surprise.
Coach’s Note — Set a spending alert on every account that can charge you, on the day you create it, at a number that would genuinely upset you — twenty dollars, five, whatever is real for your life. It takes ninety seconds. The students who get a shocking bill are never the ones who were reckless; they are the ones who provisioned something in Week 5, forgot it existed, and found out in January.
A.11 — A Clean Machine, When You Need One
Weeks 13 and 16 both require you to prove that your project runs somewhere that is not your development environment. “Clean” means specifically this: nothing your project installed is already there. Your laptop is not clean. It has never been clean. It has three years of accumulated toolchains, environment variables you set in 2024, and a global package that your project silently depends on.
Four ways to get a genuinely clean environment, all free:
| Option | How clean | Path A friendly? |
|---|---|---|
| A brand-new cloud development environment created from the repository, with no cached image | Very — it is a fresh container | Yes. The easiest option in the course. |
| A fresh container built from your own definition, on a machine with a container runtime | Very | Only if you have a runtime, so Path B or a cloud machine |
| A classmate’s laptop, following only your README, with you not touching the keyboard | Brutally honest, and the most instructive | Yes |
| A brand-new user account on your own machine | Partially — it catches per-user configuration, not system-wide installs | Path B |
The protocol is the same in all four, and it is the one that ships with Chapter 13: start a timer, open only your README.md, follow it literally, type nothing it does not tell you to type, and write down every place you had to improvise. Each improvisation is a defect in your documentation, and each one is worth points in Week 16.
The rule that makes this test real: you may not fix the environment. You may only fix the README. The moment you reach past the document to make something work, you have stopped testing and started rehearsing.
A.12 — Verify the Whole Workbench Before Week 1 Ends
This is the acceptance test for your bench. Run it before Friday of Week 1. It takes about fifteen minutes, and it is the cheapest version of a test you will run three more times this semester in far more expensive weeks.
Every path — the eight checks that must pass:
- The repository exists on GitHub and you can reach it from a browser you are not signed into as yourself (if it is private, confirm your instructor’s access instead).
- The canonical tree is committed. From the repository’s file view, or from a terminal:
ls -R docsshows every slot from Chapter 1 §1.5, each with a placeholder. - You can commit from where you actually work. Change one line in
README.md, commit, and see it on github.com within a minute. Path A: do this from the browser editor. Path B: do it withgit push. - The history has more than one day in it. Milestone 1 requires work across at least three distinct days; confirm the commit dates are real, and if today is your first day, this check is a reminder rather than a failure.
- The board is live and linked. Five columns, a stated work-in-progress limit, at least six cards with an estimate, a hat, and a stopping condition — and a link to it in your
README.md. - The hours log has real rows, with
estimate_hoursfilled in before each session, and the report runs and agrees with the file:python3 tools/hours_report.py docs/hours-log.csv - A diagram renders. Put a three-box Mermaid diagram in any Markdown file and confirm GitHub displays it as a picture rather than as code. You are not designing anything yet; you are proving the tool works before Week 6 depends on it.
- The clean-clone smoke test passes. This is the one that matters most.
git clone <your-repo-url> /tmp/capstone-check && cd /tmp/capstone-check
ls -R docs # the whole tree is really there
python3 tools/hours_report.py docs/hours-log.csv # the report runs from a clone
Then read your own README.md as if you had never seen the project. Can you tell what this is, who owns it, what state it is in, and where to look next? If not, fix the README, not your memory. Delete /tmp/capstone-check when you are done.
Path A students, do the equivalent: create a new cloud development environment from the repository — not the one you have been working in — and confirm the tree, the log, and the report are all there. That is the same test, and it is closer to what Week 13 will do to you.
Two additional checks if you are on Path B:
git --version && git config --get user.name && git config --get user.email
git log --oneline -n 5 # your commits, attributed to you, with real dates
If every check that applies to you passes, your workbench is real, and you can stop thinking about tooling until Week 5. That is the actual goal: a bench you never have to think about again. Write down, in your charter’s capacity section, which path you took and whether you have administrator rights — Week 9 and Week 14 will both ask.
A.13 — Counting the Cost, Applied to Your Own Bench
“For which of you, desiring to build a tower, does not first sit down and count the cost, whether he has enough to complete it?” — Luke 14:28 (ESV)
That verse opens Chapter 1, and Chapter 1 is careful to say what it is actually about: Jesus is telling a crowd that following him is not a casual affiliation, and the half-built tower is a picture of someone who signed up without understanding the price. It is not a project-management proverb. But it works as a picture precisely because his hearers already knew something true about human labor — that a wise builder sits down first, and that the shame lands not on the one who could not, but on the one who began without knowing.
Apply that here, to the smallest possible thing: a bench.
Counting the cost of a workbench means refusing two opposite temptations. The first is over-provisioning — the database, the host, the paid plan, the machine you buy in Week 1 for a project you have not designed. That is not diligence. It is anxiety wearing diligence’s clothes, and it produces exactly the Week-12 failure it was meant to prevent, because half of it lapses while you are not looking. The second is pretending the constraint away — working on a locked-down laptop and telling yourself you will “figure out the environment later,” which reliably means the Thursday night of a week whose milestone ends in “and the checker must run clean,” with no way to run anything.
Between them sits the honest middle: name what you actually have — this machine, these permissions, this budget, these hours — and build the smallest bench that holds the work. Then tear down what you are done with. Every teardown checklist in this appendix, every “the cheapest path that works,” every “do not buy this,” is the same discipline applied to resources you were entrusted with rather than resources you earned. Paul makes exactly that the standard for stewards in 1 Corinthians 4:2, and Jesus puts it in the smallest possible terms: “One who is faithful in a very little is also faithful in much” (Luke 16:10, ESV). A forgotten cloud instance billing quietly through Christmas is a very little. So is a five-dollar-a-month virtual machine you kept because deleting it felt like admitting the semester was over. They are still yours to account for.
And there is a specific comfort here for the student reading this on a borrowed Chromebook in a library, worrying that everyone else has better equipment. They do not have a better capstone. The grade in this course is carried by requirements a stranger can verify, decisions you can defend, tests that trace to promises, documentation that gets somebody running, and a repository somebody else can take over. Not one of those costs a dollar. The most impressive capstone I can imagine — the one a hiring manager would remember — could be built end to end from the free tier described in this appendix, and the student who builds it will have learned something the student with the expensive laptop did not: how to size the work to the resources, which is most of what engineering actually is.
So sit down. Count what you have. Build the bench that fits it. Then get to work — the tower is the point, not the scaffolding.
See you on Monday.
Up next: Return to the course overview and begin Chapter 1, whose milestone is the workbench you just built. The templates and worked good-versus-bad examples for every artifact are in Appendix B; the grading contract, full rubric, and submission checklist are in Appendix C; fifty sized project ideas are in Appendix D; the vocabulary is in Appendix E.