Pairs with: Lecture 06 — Why Initialization Needs Its Own Phase. Time: ~60 min. Difficulty: Intermediate. Prerequisites: Module 05 checkpoint.
Module 06. Bootstrap Phase
Why this module
A fresh clone of noted-cli today needs you to remember the exact dance: pnpm install, then pnpm test, then ./bin/noted --help. Skip a step and the agent's first verification fails for the wrong reason. Lecture 06 calls the failure mode initialization-as-implementation: agents try to write feature code before the environment is even green, and waste their first hour debugging setup. The fix is to separate initialization into its own phase, codified in a single bootstrap script that ends with a passing baseline.
Concepts
- Bootstrap contract — four properties a freshly-cloned repo must satisfy after running its bootstrap script:
- can start — the binary runs.
- can test —
pnpm test(or equivalent) passes at least one test. - can see progress —
PROGRESS.mdis readable and points at a Next Action. - can pick next steps — there is a non-empty list of things to do.
- Initialization phase — the period from
git cloneto "bootstrap contract holds." No feature code is written during this phase, by anyone, ever. - Idempotent bootstrap —
./init.shrun twice on the same repo produces the same end state. No surprises if a learner re-runs it. - Baseline verification — the smoke test the bootstrap runs at the end. Must be fast (< 30s) and load-bearing (a regression here aborts the session).
→ Read Lecture 06 for the long-form treatment, including the bootstrap contract origin and the cost of skipping initialization.
Lab
Step 1 — Copy the template init.sh
Copy ../../resources/templates/init.sh into your repo root, then make exactly two substitutions:
sh
INSTALL_CMD=(pnpm install)
VERIFY_CMD=(pnpm test)
START_CMD=(node bin/noted --help)Make it executable:
sh
chmod +x init.shStep 2 — Add a bootstrap-contract probe
init.sh only runs the install + test today. We want it to prove the four-part bootstrap contract. Append the following block to init.sh after the existing baseline verification:
sh
echo "==> Verifying bootstrap contract"
if ! ./bin/noted --help >/dev/null 2>&1; then
echo "FAIL: can-start (./bin/noted --help)"; exit 11
fi
if ! pnpm test >/dev/null 2>&1; then
echo "FAIL: can-test (pnpm test)"; exit 12
fi
if [ ! -f PROGRESS.md ] || ! grep -q "## Next Action" PROGRESS.md; then
echo "FAIL: can-see-progress (PROGRESS.md missing or no Next Action)"; exit 13
fi
if [ ! -f AGENTS.md ]; then
echo "FAIL: can-pick-next-steps (AGENTS.md missing)"; exit 14
fi
echo "OK: bootstrap contract holds"
echo " can-start PASS"
echo " can-test PASS"
echo " can-see-progress PASS"
echo " can-pick-next-steps PASS"
echo
echo "Next action (from PROGRESS.md):"
awk '/^## Next Action/{flag=1; next} flag{print " " $0}' PROGRESS.md | head -3Step 3 — Test the bootstrap on a fresh clone
This is the high-leverage part of Module 06. Do not skip it.
sh
git push # if you have a remote; otherwise commit and continue
cd /tmp && rm -rf bootstrap-test
git clone <your-repo-path> bootstrap-test
cd bootstrap-test
./init.shTime it. The whole script should finish in well under three minutes on a normal machine. The last lines you see should be the bootstrap-contract block. If any of them fail, the script tells you which.
If you do not have a remote, simulate with a local copy:
sh
cd .. && cp -R noted-cli /tmp/bootstrap-test && cd /tmp/bootstrap-test
rm -rf node_modules .noted
./init.shStep 4 — Make the bootstrap idempotent
Run ./init.sh again in the same directory. Output must be identical. If pnpm install re-installs everything from scratch, your lockfile is missing — git status should show pnpm-lock.yaml clean.
Step 5 — Document the bootstrap contract
Add docs/BOOTSTRAP.md:
md
# Bootstrap
`./init.sh` is the only supported way to bring a fresh clone to a verified
start. It is idempotent. It must finish in under three minutes on a
machine with Node 20 and `pnpm` installed.
## Contract
After `./init.sh` exits 0, the repository satisfies all four:
| Property | Probe |
|-----------------------|-------------------------------------|
| can-start | `./bin/noted --help` exits 0 |
| can-test | `pnpm test` exits 0 |
| can-see-progress | `PROGRESS.md` exists with `## Next Action` |
| can-pick-next-steps | `AGENTS.md` exists |
Failure exit codes: 11 = can-start, 12 = can-test, 13 = can-see-progress,
14 = can-pick-next-steps.
## Updating
When you add a new initialization step (e.g., creating a logs directory in
Module 10), add it to `init.sh` and update this contract table if a new
property is introduced.Add a line to AGENTS.md's workflow section so agents always run ./init.sh first:
md
## Workflow
1. **`./init.sh`** — must exit 0 before any work.
2. Read `PROGRESS.md`.
3. Pick the next item from `feature_list.json` (added M08).
4. Work.
5. `./verify.sh` (added M09).
6. Update `PROGRESS.md`, commit.Step 6 — Update continuity artifacts
PROGRESS.md:
md
## Current State
- Last verified: Module 06 checkpoint (`./init.sh` exits 0; bootstrap contract green).
- Last command run: `./init.sh`DECISIONS.md:
md
## D-003 — `./init.sh` is the only supported entry path
- Date: 2025-MM-DD (Module 06)
- Context: Agents otherwise run `pnpm test` directly and skip the contract probe.
- Consequence: Anything that breaks `./init.sh` blocks every session. The
failure exit codes (11–14) are stable and referenced from `docs/BOOTSTRAP.md`.Step 7 — Commit
sh
git add .
git commit -q -m "module-06: init.sh + bootstrap contract"Verification
sh
chmod +x init.sh && \
./init.sh >/tmp/m06.log 2>&1 && \
grep -q "OK: bootstrap contract holds" /tmp/m06.log && \
echo "M06 OK"Expected:
M06 OKIf ./init.sh exits non-zero, read the last line — it tells you which contract property failed.
Common pitfalls
- Skipping the fresh-clone test. Running
./init.shin your existing repo withnode_modules/already populated tells you nothing. The point is the fresh state. - Adding feature work to
init.sh. Bootstrap is a separate phase. If you find yourself addingnoted importcalls to it, you are blurring the boundary; move that work to a script underscripts/. - Letting the contract probe drift. When you add
feature_list.jsonin Module 08, add a fifth contract probe and bump the failure exit codes table indocs/BOOTSTRAP.md. - Treating non-deterministic test failures as "flaky." Module 09 is going to fail loudly on the first flaky test; do not paper over them now with retries.
Next
Module 07 — Scope Boundaries (WIP=1). You can bootstrap reliably; the agent can still try to do five things at once. Module 07 enforces one active feature at a time.
