# One folder shape for every course: a lifecycle monorepo convention

> Source: <https://dev.to/nasrulhazim/one-folder-shape-for-every-course-a-lifecycle-monorepo-convention-383f>
> Published: 2026-07-22 15:46:35+00:00

`00-planning → 04-post-training`

.`_TEMPLATE/`

you copy to start the next one, an `_ARCHIVED/`

you park old stuff in, and a `CLAUDE.md`

that makes the convention machine-readable.`<angle-bracket-slots>`

, and "done" is a `grep`

that returns nothing.I had course material scattered across repos — planning notes here, marketing copy there, facilitator run-sheets in a third place. Every new course started from a blank page, and I re-invented the folder layout each time. So I collapsed everything into one monorepo with a single rule: **every course has the identical shape.**

The insight isn't "use folders" — it's that a course has a *lifecycle*, and numbered folders make that lifecycle the primary axis instead of file type. Plan it, sell it, teach it, run it, follow up. Five stages, always in order:

| Folder | Stage | What lives here |
|---|---|---|
`00-planning/` |
Prepare | Syllabus (source of truth), specs |
`01-marketing/` |
Sell | Positioning master + channel assets |
`02-content/` |
Teach | Modules, one file each |
`03-delivery/` |
Run | Run-sheet, pre-flight checklist, fallback plan |
`04-post-training/` |
Follow up | Feedback form, follow-up email, post-mortem |

The numeric prefix isn't decoration. It forces sort order to match the actual workflow, so the folder listing reads like the process itself. Same reason migration files are timestamped — order is information.

``` php
<course>/
  00-planning/       -> derives everything below
  01-marketing/
  02-content/
  03-delivery/
  04-post-training/  --. post-mortem findings
                        |
     ^------------------'  feed back into 00..03
```

That loop at the end matters: the post-mortem doesn't sit in a graveyard folder. Its findings flow back into the syllabus, the run-sheet, the marketing. The structure runs the same feedback loop it's supposed to teach.

`_TEMPLATE/`

: a course starts as a copy
Starting a new course is one line:

```
cp -r _TEMPLATE my-new-course
```

The template is the full lifecycle skeleton with the writing already stubbed. What you must fill is marked as `<angle-bracket-slots>`

— `<course-name>`

, `<promise-one-liner>`

, and so on. Everything *not* in a slot is standing structure you keep.

The part I like most is the definition of done. A course is ready when this returns nothing:

```
grep -rn '<' --include='*.md' .
```

No slot hits = no unfilled blanks. It turns "is this finished?" from a judgment call into a command with an exit code — the same instinct as a failing test. If I were wiring this into CI, that grep becomes the assertion.

`_ARCHIVED/`

: park it, don't delete it
Retired formats and old campaigns go into `_ARCHIVED/`

, in dated subfolders with a note on *why* it was retired and what replaced it. One rule keeps it honest: **nothing live may reference anything in there.** If a live file still links to it, it isn't archived — it's just moved.

Why keep it at all? Because a retired price, a killed campaign style, or an abandoned format is a *recorded decision*. Deleting it loses the "we already tried that, here's why it didn't work." Git history technically has it, but nobody spelunks reflog for a pricing decision.

`CLAUDE.md`

: the convention, machine-readable
The last piece is a `CLAUDE.md`

at the root that spells out the layout, the naming rules, and the standing decisions. It's written for an AI coding agent, but the real value is broader: it's the one file where the convention lives as text instead of as tribal knowledge in my head. Any collaborator — human or agent — reads one file and knows where things go.

The pattern generalizes past courses. Any repeatable body of work with a lifecycle — client engagements, product launches, incident write-ups — benefits from the same three moves: **one fixed shape, a copy-to-start template with a grep-checkable done state, and a parking lot for retired decisions.** Consistency you can `grep`

beats consistency you have to remember.
