exams/

.md
dirtopics/<slug>/exams/<exam>/

One folder per exam. The folder name is the exam's id: the unit number and title (01-methods-and-codes), or quiz for the level quiz. Attempts are named by the minute they were made.

tree
exams/01-methods-and-codes/
├── exam.json
├── draft.json                        # a sitting in progress, autosaved by the app
└── attempts/
    ├── 2026-09-24T1030.json          # your answers
    ├── 2026-09-24T1030-p3.webm       # oral answer to question 3
    └── 2026-09-24T1030.feedback.md   # feedback
written by
slp-exam and slp-quiz (the exam), the app (attempts), slp-grade (feedback)
pending
an attempt without its .feedback.md. draft.json is not an attempt: never graded, deleted on submit
second exam on a unit
01-methods-and-codes-b. An exam with attempts is never rewritten or reordered, since attempts point at questions by position
same minute
a second attempt in the same minute gets -2, -3…

exam.json

exam.json
{
  "title": "HTTP — 01: methods and codes",
  "questions": [
    { "type": "multiple_choice", "q": "Which method is idempotent?",
      "options": ["POST", "PATCH", "PUT", "CONNECT"],
      "answer": 2, "explanation": "..." },
    { "type": "open", "q": "When is 409 better than 400?",
      "rubric": ["...", "...", "..."] }
  ]
}
field meaning
title shown in the lists. Missing: the folder name
type multiple_choice (default when missing) · open · oral · practical
q the question
options multiple choice: exactly 4 statements
answer multiple choice: index of the right option, 0-based
explanation multiple choice: why, shown after grading. Required
rubric open, oral, practical: 3–5 checkable points. No answer

q, options and explanation can hold ```mermaid and ```math fences, written as \n inside the string, with LaTeX backslashes doubled.

Quiz

exams/quiz/exam.json is the level check slp-init runs first and slp-quiz runs again to compare. A normal exam with three more fields:

field meaning
kind top level, "quiz"
thread per question: the prerequisite line it tests, kebab-case (methods)
level per question: difficulty from 1 to 5

Questions are never edited or reordered: the bank grows by appending higher levels. The app sits it like any other exam.

Attempt

What you answered, nothing more. No score: multiple choice is scored on screen, the rest by slp-grade.

attempts/2026-09-24T1030.json
{
  "exam": "01-methods-and-codes",
  "answers": [
    { "i": 0, "type": "multiple_choice", "chosen": 2 },
    { "i": 1, "type": "open", "text": "..." },
    { "i": 3, "type": "oral", "audio": "2026-09-24T1030-p3.webm" }
  ]
}
field meaning
exam the exam folder name
i position of the question in exam.json, not the shuffled order you saw
type copied from the question
chosen multiple choice: the option index, null if skipped
text open, practical, or oral answered in writing
audio oral: file name of the recording next to the attempt (webm, ogg, mp4 or wav)
mode "chat" when the quiz was run in the chat and written by slp-quiz

Feedback

attempts/<date>.feedback.md, written by slp-grade, or by slp-quiz for a quiz run in the chat.

attempts/2026-09-24T1030.feedback.md
# Attempt — 01-methods-and-codes — 2026-09-24 10:30

**MC:** 3/4 · **Rubric points:** 2/3

## [03] Multiple choice — overloaded server
✗ Picked 404. … See *Methods and status codes › Status codes*.

## What to improve
- …
sections
[NN] is the question position plus one. Only missed and non-multiple-choice questions get one
✗
says what is missing and the note heading that covers it, or that no note covers it yet
quiz
the score line is a | Thread | Edge level | table

Markdown formats

The documentation is also available in llms.txt formats:

  • llms.txt lists every documentation page.
  • llms-full.txt contains the complete documentation in one file and may exceed some context windows.

Append .md to any documentation URL to retrieve that page as Markdown. For example, this page is available at https://selflearningplatform.github.io/docs/exams.md. You can also copy the current page as Markdown by pressing Cmd+C or Ctrl+C.