Skip to content

xichia/course-notes

Repository files navigation

Course Notes

A Markdown-first system for durable learning notes, selective LLM retrieval, review queues, and study workflows. Markdown files under courses/ are the source of truth; the manifest and review queue are generated views.

One repository, one working copy. Tracked content (courses/ plus the framework) is the public-safe surface pushed to the GitHub remote; raw or source-risky material lives under a Git-ignored private/ directory and is never committed.

License: MIT. See LICENSE. The scripts, templates, prompts, and documentation are MIT licensed. Real course-derived notes should not be published through this repository unless separately cleared.

Quickstart

For a human overview, open INDEX.md. For an LLM session, provide LLM_GUIDE.md and manifest.json first. For today's study priorities, open REVIEW_QUEUE.md.

After adding or changing notes, run the normal workflow:

make all

This validates notes, rebuilds generated files, and runs tests. For the complete one-folder workflow (including private-study commands and the pre-commit safety gate), see docs/operating-checklist.md. If Make is unavailable, use the direct commands:

python3 validate_notes.py
python3 build_manifest.py
python3 build_review_queue.py
python3 -m unittest discover -s tests

Individual Make targets are also available:

make validate
make manifest
make review
make test
make all

Make is only a convenience; the scripts require Python 3, use only the standard library, and remain directly runnable.

Public/private content policy

The publishable work in this repository is original study material, not reproduced lecture material. Both public and private material live in this single repository, separated by directory and Git tracking rather than by repository:

Public Course Notes material (tracked, pushed) Private by default (private/, Git-ignored)
Templates, scripts, prompts, docs, metadata schemas, validation logic, generated-file conventions, and synthetic examples Real lecture-derived notes, problem sheets, exam maps/questions, lecturer hints, LMS material, assessment material, personal study evidence, and course-specific examples
  • courses/ holds only public-safe, polished notes. It is tracked by Git and must pass make validate-public. This is the only course tree the GitHub remote ever sees.
  • private/ holds everything source-risky or not yet cleared: private course notes under private/courses/, raw source material under private/raw/, drafts under private/drafts/, and private/framework-feedback.md. The whole private/ tree is ignored by Git (see .gitignore) and is never committed or pushed. It stays local to your working copy.

AI summarizing or paraphrasing alone does not make protected course material safe to publish. Keeping a file under private/ is not sanitization; promoting a private note into courses/ requires a separate sanitization and review step.

Read docs/publication-policy.md before changing visibility or preparing a release, and use docs/public-release-checklist.md before promoting any private note into courses/.

make validate-public applies the same conservative gate as before: it scans only courses/ and fails on visibility: private, course-derived or unknown source-risk, missing publication classifications, and local paths. The gate is not weakened by the private/ directory — private/ is simply outside its scan scope.

Public vs private notes

This repository is both the study workspace and the public Course Notes release. Tooling, templates, prompts, documentation, validation logic, and synthetic/demo content are tracked; real course notes and raw source material are kept under the Git-ignored private/ directory.

A note is private by default (visibility: private). A private note may live under private/courses/ and intentionally fail make validate-public, because that gate only ever runs against courses/. A note may move into courses/ only after it has been sanitized to public-framework / public-original / public-open-licensed with an allowed source-risk and has passed make pre-release.

Repository Structure

course-notes/
├── courses/                        tracked, public-safe polished notes only
│   └── <course-code>/
│       ├── course.md          course metadata, resources, and priorities
│       ├── syllabus.md        official outcomes and confirmed coverage
│       ├── concepts/          durable, one-concept-per-file notes
│       ├── lectures/          chronological lecture records
│       ├── problem-sheets/    attempts, corrections, and reflections
│       ├── exam/              exam maps and revision summaries
│       └── glossary.md        course terminology
├── private/                        Git-ignored; never committed or pushed
│   ├── courses/               private/source-risky notes (mirror the courses/ layout)
│   ├── raw/                   raw source material
│   ├── drafts/                 work in progress
│   └── framework-feedback.md  scratch notes about the framework itself
├── docs/                           onboarding and friction-test checklists
├── prompts/                        reusable LLM study workflows
├── templates/                      course, syllabus, and raw lecture templates
├── Makefile                        optional command shortcuts
├── TEMPLATE.md                     canonical concept-note template
├── LLM_GUIDE.md                    LLM navigation and editing protocol
├── INDEX.md                        maintained human navigation
├── manifest.json                   generated machine-readable index
└── REVIEW_QUEUE.md                 generated ranked review list

The included courses/demo-course/ tree is fictional and exists only to demonstrate the system; replace it with other synthetic material—not real course notes—when preparing a public variant. The private/ directory is ignored by Git: it exists for your local working material and is not part of the public release.

Source of Truth and Generated Files

  • Markdown under courses/ is the source of truth for course knowledge, evidence, and review metadata.
  • manifest.json is a generated retrieval index. Its top-level _generated field says how to rebuild it.
  • REVIEW_QUEUE.md is a generated study-priority view and begins with a generated-file warning.
  • INDEX.md and course README.md files are maintained human navigation.
  • Files under prompts/ are reusable instructions, not course facts.

Never edit manifest.json or REVIEW_QUEUE.md manually. Update source Markdown and run make manifest, make review, or make all.

Determinism: Generated files use a date-only generated-at field (no time). Running make all multiple times on the same day produces no diff when notes are unchanged. For fully reproducible builds, set the SOURCE_DATE_EPOCH environment variable (Unix timestamp) or pass --today to build_review_queue.py.

Command Reference

| Command | Purpose | |---|---|---| | make validate | Check metadata, IDs, dates, links, required sections, and mistake structure | | make validate-public | Apply the stricter public-release gate to courses/ only; private notes under private/ are outside its scope. Loads .public-release-blocklist if present (see below) | | make manifest | Validate and rebuild manifest.json | | make review | Validate and rebuild REVIEW_QUEUE.md for today; set DATE=YYYY-MM-DD for a reproducible date | | make test | Run the dependency-free regression suite | | make pre-release | Run the public-release gate, regenerate all files, and run tests (for release readiness) | | make all | Run normal validation, both generators, and all tests | | make reviewed NOTE=layered-recall | Update last-reviewed and review-after for a note by ID (see below) | | make reviewed NOTE=layered-recall DATE=2026-07-15 | As above, using a specific review date | | python3 build_review_queue.py --today YYYY-MM-DD | Generate the review queue for a specific date | | make study-validate | Validate notes under private/courses/ | | make study-manifest | Build private/manifest.json from study notes | | make study-review | Build private/REVIEW_QUEUE.md from study notes | | make study-all | Run study-validate, study-manifest, and study-review | | make study-reviewed NOTE=<id> | Mark a study note under private/courses/ as reviewed | | make public-safety | Validate the public tree and run all tests |

The equivalent direct Python commands are shown in Quickstart. Append --study to any tool to target private/courses/ instead of courses/.

CI runs on every push and pull request: make all, make validate-public, make pre-release, and a generated-file staleness check. See ci.yml.

Optional blocklist

Create .public-release-blocklist in the repository root with one term per line to extend make validate-public. Lines starting with # and blank lines are ignored. Matching is case-insensitive.

# Lines starting with # are comments.
Example University
PROFESSOR NAME
canvas.example.edu
MATH123

When present, make validate-public scans all Markdown files for these terms and reports each match as an error. This is a safety smoke alarm — it does not replace manual review. Remove or replace any blocked terms before publishing.

Mark a note as reviewed

After studying a note, update its review metadata with:

make reviewed NOTE=layered-recall

Or with a specific date:

make reviewed NOTE=layered-recall DATE=2026-07-15

The script updates only last-reviewed and review-after. It does not change status, visibility, source-risk, or any other frontmatter. The next review date is chosen from the current status:

Status Next review
new +1 day
shaky +2 days
learning +7 days
solid +30 days
mastered +60 days
reference / archived blank

Run make all after the update to regenerate the manifest and review queue.

Adding a new course

The full copy-and-check workflow is in docs/course-onboarding.md. In short:

  1. Create courses/<course-code>/ with concepts/, lectures/, problem-sheets/, and exam/.
  2. Copy templates/course.md to courses/<course-code>/course.md and replace every placeholder.
  3. Copy templates/syllabus.md to courses/<course-code>/syllabus.md; add only official or explicitly sourced material.
  4. Copy templates/lecture.md into lectures/ for each raw chronological lecture record.
  5. Use prompts/import-lecture.md to propose durable concept extraction, then create approved concepts from TEMPLATE.md.
  6. Put attempts, corrections, and evidenced mistakes under problem-sheets/.
  7. Put confirmed exam information and outcome maps under exam/.
  8. Run make validate.
  9. Run make manifest, make review, and make test (or simply make all).

Set every document's course field to the exact directory name. Keep raw lecture notes intact, preserve source paths, and keep missing official information visibly unknown.

After the first import, run the ten-minute course import friction test.

Add a Concept Note

  1. Copy TEMPLATE.md to courses/<course-code>/concepts/readable-filename.md.
  2. Give it a repository-unique, permanent id. For new notes, <course-code>-<concept-slug> is a useful convention.
  3. Fill in every metadata field and write the note in your own words.
  4. Use note IDs, not filenames, in prerequisites and related.
  5. Validate, then regenerate the manifest and review queue.

Keep filenames readable and stable. A concept note should grow as understanding improves instead of being replaced by dated copies.

Daily Study

  1. Run make review (or python3 build_review_queue.py).
  2. Open REVIEW_QUEUE.md, or give prompts/daily-study.md to an LLM with repository access.
  3. Study the highest-priority item through active recall before rereading it.
  4. Update review dates and Mistake Log items only after checking your performance. Use make reviewed NOTE=<id> to update dates quickly.
  5. Run make all after changing source notes.

For a weekly planning session, run make all, then use prompts/weekly-review.md with the refreshed manifest and queue.

Metadata Contract

Every study document under courses/ (except navigational README.md files) uses the same frontmatter keys:

Field Meaning
id Permanent, repository-unique identifier; lowercase letters, numbers, dots, and hyphens
title Human title, matching the document's # heading
course Course directory name
type concept, lecture, problem-sheet, exam-map, glossary, or reference
topic Stable topic slug within the course
aliases Alternative search terms as an inline list
prerequisites Note IDs needed first
related Other relevant note IDs
exam-weight none, low, medium, or high
status new, learning, shaky, solid, mastered, reference, or archived
last-reviewed Last active-recall date as YYYY-MM-DD, or blank
review-after Next review date as YYYY-MM-DD, or blank
source Lecture, text, problem sheet, URL, or an honest note that the source is unknown
visibility Optional publication classification: private, public-framework, public-original, or public-open-licensed
source-risk Optional provenance risk: lecture-derived, problem-sheet-derived, exam-derived, lms-derived, open-licensed, original, or unknown

Lists use the simple inline form [first-id, second-id]. This constrained frontmatter format keeps the scripts dependency-free and the files easy to inspect.

Status and Review Workflow

Use status as a judgment about recall, not note polish:

  • new: captured but not learned
  • learning: partly understood; cannot yet reproduce reliably
  • shaky: previously learned but errors or gaps remain
  • solid: can explain and solve representative problems
  • mastered: reliable after repeated delayed review
  • reference: useful navigation material, not a review item
  • archived: retained but excluded from active review

After an active review:

  1. Update last-reviewed.
  2. Set review-after to the next useful date. A practical starting cadence is 1–3 days for new/shaky, 7–14 days for learning, 30 days for solid, and 60–90 days for mastered.
  3. Propose a status change separately from making it. Upgrade only after repeated recall or application evidence; downgrade when repeated mistakes demonstrate a real gap.
  4. Record any evidenced error with the structured Mistake Log convention below.
  5. Regenerate manifest.json and REVIEW_QUEUE.md.

Use prompts/update-status.md after a quiz, problem sheet, or timed recall session. One good answer, confidence alone, or improved prose is not enough to upgrade status. A useful upgrade normally needs successful evidence from at least two attempts separated by time or using different task types.

Recording Mistakes

Mistakes are immutable evidence, not a to-do list. Add one five-field block under ## Mistake Log only when an actual quiz, problem sheet, exam, or recall attempt exposed the error:

- date: 2026-06-30
  source: problem-sheet-01
  mistake: Describe what went wrong.
  correction: Record the action or idea to apply next time.
  tags: [exam-trap, procedure]

Use one line per field and inline slug-style tags. date: unknown is allowed only when migrating a genuine older mistake whose date was never recorded. Do not delete old entries when they improve; their recent-priority effect expires automatically after 30 days, while the history remains useful.

Practice Questions

Every concept note has ## Practice Questions with ### Easy, ### Medium, and ### Exam-style groups. Questions are ordinary Markdown bullets. Empty groups use _No practice questions recorded yet._; never create filler questions merely to satisfy validation.

The manifest records counts by difficulty plus has-practice-questions. It also records whether the note has a substantive worked example, allowing weekly review to expose thin notes.

Review Priority

The generated queue documents the same additive formula beside its results:

  • status: shaky +40, new +32, learning +26, solid +8, mastered +0;
  • exam weight: high +25, medium +14, low +5, none +0;
  • review timing: +30 when due, plus up to +30 for overdue days; missing review-after +10;
  • review age: never reviewed +20, otherwise up to +20 after the first seven days;
  • mistakes: +5 each up to +20, plus +12 for each dated mistake in the last 30 days up to +36;
  • missing practice questions on a concept: +10;
  • high exam weight combined with shaky status: +15.

The score ranks attention; it is not a grade or automatic status decision. Use python3 build_review_queue.py --today YYYY-MM-DD for a reproducible queue on a specified date.

Manifest-First LLM Use

manifest.json contains metadata, publication classifications, short summaries, headings, mistake counts/dates/tags, worked-example coverage, and practice-question counts for every study document. An LLM should:

  1. Read the manifest first.
  2. Filter to relevant course, topic, type, status, aliases, or exam weight.
  3. Open only the selected files listed in file.
  4. Follow prerequisite and related IDs only when needed.
  5. Treat the Markdown notes as authoritative and generated files as disposable indexes.

See LLM_GUIDE.md for the full protocol and prompts/README.md for ready-to-use study workflows.

LLM Workflow Reference

Workflow Prompt
Import a rough lecture safely prompts/import-lecture.md
Run today's study session prompts/daily-study.md
Quiz one topic interactively prompts/quiz-me.md
Explain a selected concept prompts/explain-a-concept.md
Improve or extract a durable note prompts/improve-this-note.md
Generate source-backed flashcards prompts/generate-flashcards.md
Prepare for an exam prompts/prepare-for-an-exam.md
Plan the next week prompts/weekly-review.md
Evaluate a status change from evidence prompts/update-status.md

Every workflow must distinguish repository evidence from external explanation, preserve uncertainty, and avoid inventing course content.

Validation and Generated Files

validate_notes.py catches missing fields, malformed dates/lists, malformed structured mistakes, invalid status/weight/visibility/source-risk values, duplicate IDs, broken ID and Markdown links, absolute machine-specific links anywhere in repository Markdown, type/course-directory mismatches, title mismatches, and missing concept sections such as Practice Questions. Errors name the affected file and field or section, show the bad value when useful, and suggest a repair. The command exits non-zero on errors.

python3 validate_notes.py --public-release (or make validate-public) adds a conservative publication gate. It fails on private visibility, course-derived or unknown source risk, missing publication classifications, and local paths. Do not weaken this check to make a real private repository pass.

build_manifest.py and build_review_queue.py validate before writing. They will not replace their outputs when notes are malformed. manifest.json carries a top-level _generated warning; REVIEW_QUEUE.md begins with a generated-file HTML comment. Never edit either file manually: change the source Markdown and rebuild it.

For documentation navigation and repository-maintenance checks, see docs/README.md.

About

Markdown-first system for LLM-friendly university notes and study workflows.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors