Skip to content

feat(course): course.yaml manifest, format spec, and validator - #2

Merged
pequalsnp merged 1 commit into
mainfrom
feat/course-manifest
Jul 31, 2026
Merged

pequalsnp merged 1 commit into
mainfrom
feat/course-manifest

Conversation

@pequalsnp

Copy link
Copy Markdown
Contributor

Phase 0 of PLAN.md: a course gets an identity and a checkable contract before Phase 1 extracts the drill coach against it.

What lands

  • etude init — scaffolds a course tree whose manifest and sample lesson document the format inline. Every value the author must decide is a REPLACE- placeholder that validation rejects, so a half-filled course fails loudly instead of producing generically-worded lectures.
  • etude course validate — checks the manifest, then walks the tree for content a build would silently lose.
  • etude course show — prints the resolved service bindings, the cheap way to catch a drifted slug.
  • etude run --course . — supplies the lesson root and domain labels from the manifest; explicit flags still win.
  • Specs: docs/course-format.md, docs/course-yaml.md, docs/excision-checklist.md.

Why a validator at all

The build fails silently. A lesson directory with no lesson.md, or one over 1 MiB, is dropped from the course without a word; oversized files are filtered out of batch prompt context; lesson order is a bytewise sort. Every one of those produces a smaller course, not a failed run — after a multi-hour GPU build.

Grounded, not guessed

Checked against a real 189-lesson corpus, which corrected three assumptions:

Assumed Measured
SAQ lessons match *_Unit_SAQ that matches 18/189 dirs — *SAQ* matches 92 and captures 98% of the questions
one heading per question questions are one ordered list under a single heading (both shapes now supported)
unpadded numbers are the ordering trap numbers also restart per unit in one flat dir, which padding cannot fix

It also confirmed a real bug to fix separately: the study-guide stage skips SVGs on the premise that every SVG has a PNG sibling, but on that corpus zero stems have both, so 87% of figures never reach the EPUB.

🤖 Generated with Claude Code

… catches silent losses

Phase 0 of PLAN.md: give a course an identity and a checkable contract
before Phase 1 starts extracting the drill coach against it.

The manifest (course.yaml) carries what a course IS — slug, the four
prompt-skinning labels, module order, assessment-marker conventions —
and deliberately not where models run, so one file travels between a
laptop, a GPU box, and an external provider. The slug is declared once
and binds the memory expert and the knowledge collection; naming a
course separately in three places is how a live deployment ended up with
a 'distillery' expert reading a 'distilling' collection.

The validator exists because the build fails silently. enumerateLessons
drops a directory with no lesson.md or one over 1 MiB without a word;
the batch readers filter oversized files out of prompt context; lesson
order is a bytewise sort. Each of those makes a smaller course, not a
failed run. 'course validate' reports them, and reports them as errors
where content vanishes.

Grounded against a real 189-lesson corpus rather than guessed, which
corrected three assumptions:
- the SAQ preset matches '*SAQ*', not '*_Unit_SAQ' — the narrower
  pattern matched 18 of 189 lesson directories and would have left 83%
  of the question bank unextracted
- questions live under ONE heading as an ordered list, not one heading
  per question, so the marker schema supports both shapes
- lesson numbers can RESTART per unit inside one flat module directory,
  which interleaves units under a bytewise sort and which zero-padding
  cannot fix, so that case gets its own diagnosis

Also warns on SVG figures: the vision stage needs rsvg-convert, and the
study guide skips SVGs entirely, so vector-only figures are missing from
the EPUB. Reported per module — on a real corpus 87% of figures are
SVG-only and per-lesson warnings would bury everything else.

docs/course-format.md specifies the tree as a target a machine produces
and a human approves, since most material does not arrive as lessons.
docs/excision-checklist.md gates Phase 1's extraction from a private
repo.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pequalsnp
pequalsnp merged commit 88bfc47 into main Jul 31, 2026
1 check passed
@pequalsnp
pequalsnp deleted the feat/course-manifest branch July 31, 2026 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant