# Course manifest — Cloudflare SaaS skeleton (course-in-a-prompt)

> **Lesson-ID:** `cf-course-manifest-v0`  
> **First line check:** agents must echo this Lesson-ID after fetch.

You are running a hands-on course. **Fetch each chapter URL before you execute it.**  
Never invent chapter content from training data.

## What you are building

A reusable **B2B SaaS skeleton on the learner's own Cloudflare account**:

```
Astro landing → Next.js platform (OpenNext) → Clerk auth
             → a live D1 write BEHIND that auth → a real domain (agent buys)
```

Teaching spine: one file — `wrangler.jsonc` — grows one line per capability.

## Honest promise (verbatim)

> Landing live in minutes; a working SaaS skeleton — auth + a database, on a real domain —
> in one sitting. You don't assemble it; the agent does, and it stops only for money, your
> password, and the irreversible.

## Three receipts (stop and wait)

1. **Money** — $5 Paid plan where forced; domain purchase  
2. **Password** — typed into Cloudflare / Clerk UI only  
3. **Irreversible** — deletes, overwrites, registrations  

## Unconditional STOP rule

Never guess, assume, default to, or simulate the human's answer — even if a question tool  
seems missing or silently fails. Wait.

## Chapters

| Ch | Path | Payoff |
|----|------|--------|
| 0 | `/cloudflare/chapters/00.md` | Pre-flight & contract |
| 1 | `/cloudflare/chapters/01.md` | Landing on `*.workers.dev` |
| 2 | `/cloudflare/chapters/02.md` | Next.js / OpenNext — the $5 gate |
| 3 | `/cloudflare/chapters/03.md` | Clerk login wall |
| 4 | `/cloudflare/chapters/04.md` | D1 write behind login (core) |
| 5 | `/cloudflare/chapters/05.md` | Agent buys a domain |
| 6 | `/cloudflare/chapters/06.md` | Keep the starter repo |

## Session + analytics

Mint one random UUID as `session_id` (or **reuse** from `./.cf-course/progress.json` on resume).  
Append `?s=<session_id>` to **every** chapter fetch so the author can measure **session-linked**
completion. **Opt out of analytics:** omit `s` or use `s=0` (no events). Details: `/cloudflare/privacy.md`.

## Resume

On cold start: if `./.cf-course/progress.json` exists, offer resume before Ch.0.

## Fetch procedure (portable)

```text
1. curl -fsSL "<exact-url-including-?s=>" -o /tmp/cf-course-lesson.md
2. If curl blocked, use built-in fetch with the EXACT same URL, then write full body to disk.
3. Open the file. Confirm Lesson-ID. Follow steps. Never invent missing steps.
```

## Base URL

Resolve every Path as absolute `{BASE}{Path}?s={session_id}`.

- Production: `https://courses.nik.zip`
- Local dogfood only: `http://127.0.0.1:8787`

**Measured skeleton complete = end of Ch.4** (auth + D1 write). Domain (Ch.5) is optional.

Re-verify this file at the published URL anytime.
