Skill: course-build → write-like-james @ 84b31cb
Grade 3 Science on TimeBack Scroll: the course, its shape, and the ledger you will receive
_For the TimeBack Scroll team, from James Moore. 30 September 2026. A ten-minute read; the machine-facing detail is folded away at the bottom._
The takeaways
- What the course is. Grade 3 Science: 4 strands, 42 topics, 198 lessons, self-paced. Every lesson is a 40 to 75 second video or a short illustrated article, the student's choice, then its questions.
- What you receive. One activity ledger CSV (your v3 schema, 58 columns, one row per thing a student meets, in course order) and one PP100 bank CSV (your v1 schema) per topic. Pictures as PNG. Nothing hand-typed: a script builds both files from the course's own content and runs your schema check before anything is sent.
- The one format point that matters most. Scroll has no in-video questions. So the one easy question that closes each video becomes the first post-lesson question, and the lesson's quiz follows it. Same row, same id, just no longer inside the video.
- Placeholders. A video not yet made is a lesson row in
text_onlymode with the narration already inscriptand the video columns empty. When the video lands, that row flips tolearner_choiceand gets its file name. The row's id never changes, so nothing a student has done is lost. - Where we are today. All 42 topics are written. 151 of 282 videos are delivered (all of Physics and all of Matter), 131 are not yet briefed (Earth & Space and Life; their scripts are written and being skimmed by James now). Four topics have their full test bank; the other 38 have a sample of each question type and get their banks once James approves the sample.
- Students never see the word 'strand'; in student-facing titles the four are named by subject (Physics, Matter, Earth and Space, Living things). "Strand" stays an internal word in this document and the ledger's ids. (James, 30 Sep 2026.)
- What is still coming. Four strand intro videos (scripts written), four end-of-strand tests (format going to Alpha's assessment lead for validation before anything is authored; static form plus a bank for retests), and revision resources. The end-of-grade test is Alpha's existing Grade 3 standardised science test (ten live forms), not something this course builds. Formats for each are stated below; the ledger you get today carries a marked placeholder row where each will sit.
The problem this document solves
You need to build the player and the upload path before the course is finished. So this tells you the shape now, with placeholders where content is still coming, and promises that the shape will not change under you.
How a student moves through the course
Course order is strand by strand. Physics first, then Matter, then Earth & Space, then Life.
Each layer has a fixed pattern. Read the tree top-down.
Grade 3 Science
- Strand (4 of them)
- Strand intro video. Short, teaches nothing, ends with a ready poll. Video or article toggle.
- Topic (3 to 15 per strand; 42 in all)
- Topic intro. Video or article toggle, then a ready poll (no right answer).
- Lesson (3 to 9 per topic; 198 in all), each one register atom:
- The lesson: video or article, student's choice (
learner_choice). - Question 1: the question that used to close the video. Easy, one step, needs the lesson.
- The quiz: about ten items, mixed formats (pick one, pick one of two, type a word or number).
- Mixed mastery practice: items from every lesson in the topic, key terms typed from memory.
- Topic summary video (video or article toggle), then three check questions.
- PP100: the topic mastery test, drawn at random from a protected bank of at least 50 items. First answer final.
- End-of-strand test: a static form (multiple choice plus some typed short answers, graded), drawn from a bank large enough for retests. Placeholder today.
- End-of-grade test: Alpha's existing Grade 3 standardised science test (ten live forms, built by David's team). The course does not build one; the placeholder row marks where it sits in the sequence.
Two things the tree hides:
- Some articles carry several drawings. Your schema allows one image per row, so those articles are split at their subtitles into two to six readings (
-p1,-p2, …). The video attaches to reading 1. Readings 2 onward are text only. - Nothing in a topic is skippable except the two polls (
required_for_atom=false).
What one lesson looks like in the ledger
Take Topic 21, lesson 1 (Melting). Its rows, in order, all under atom_id = MAT3-040:
| element_id | element_type | What it is | Delivery |
|---|---|---|---|
g3t21-l01-lesson-p1 | lesson | Reading 1 of the article, plus the whole video narration in script | learner_choice, video_source_ref = G3T21-L01.mp4 |
g3t21-l01-lesson-p2 … -p5 | lesson | Readings 2 to 5 | text_only |
g3t21-l01-vq1 | cloze | Question 1: the former in-video question, two answers, tap one | associated_lesson_id = g3t21-l01-lesson-p1 |
g3t21-l01-q01 … -q12 | mcq / cloze / frq | The quiz | same link |
The ids follow one pattern for every lesson in the course: g3t<topic>-l<lesson>-lesson, -vq1, -q01. Topic-level rows are g3t21-intro-lesson, g3t21-intro-poll, g3t21-pr-q01 (practice), g3t21-summary-lesson, g3t21-summary-q1. Strand-level rows are g3-physics-intro-lesson, g3-physics-intro-poll, g3-physics-test-placeholder. The end-of-grade row is g3-grade-test-placeholder.
How the four question shapes are expressed
- Pick one of three or four →
mcq. The key is alwaysmcq_a(your positional rule; the app shuffles).feedback_aopens "Correct:". Every option has its own feedback line. - Pick one of two (yes or no; this object or that one) →
cloze. Your MCQ needs three options and we will not invent a third answer for a grade-3 reader. The stem sits incloze_textending "Answer: {{the key}}", the two answers are thecloze_word_bank. The explanation goes inactivity_feedback. Please confirm this renders as tap-one-of-two. - Type a word or a number →
frq.accepted_answersis a JSON list of every string we accept (for "melting":["melting", "melt", "melts", "melted", …]).ai_grading_instructionssays, in plain words, exact match only, case and articles ignored, no synonyms, a number with or without its unit. Please confirm the grader can be held to the list. - The ready poll (no right answer) →
mcqwith the first reply "Yes, let's go!" in the key slot,required_for_atom=false,exclude_from_retrieval=true, three friendly feedback lines and no "Correct:". If the player must show right or wrong on it, tell us and James may drop the row.
How a video placeholder works, and how it fills in
Three states, all on the same row, same element_id:
| State | lesson_delivery_mode | video_source_type | video_source_ref | script |
|---|---|---|---|---|
| Video not made yet | text_only | empty | empty | the full narration |
| Video delivered (today: 148 rows) | learner_choice | uploaded_file | the MP4 file name, e.g. G3T21-L01.mp4 | the full narration |
| Video hosted by you | learner_choice | matt_asset_id or external_url | your asset id or URL | unchanged |
- The schema has no status column, so an empty
video_source_refon a lesson row is the placeholder mark. There is nothing else to look for. - Every video is generated by David through the Peps pipeline and edited by its Peps id. That id is not in the ledger; it lives in the course repo's
handoff/VIDEO_IDS.md, one line per video. David uploads the MP4 and fills the row. - A topic intro, a topic summary and a strand intro are
lessonrows too, so the same three states apply to them.
The two placeholder rows that are not videos
The end-of-strand tests and the end-of-grade test do not exist yet. Each is marked in the ledger by one lesson row whose element_title begins PLACEHOLDER:, text_only, with a body that says what will replace it. They hold the place in the course order and must be removed or replaced before an upload. There are five: g3-physics-test-placeholder, g3-matter-test-placeholder, g3-earth-space-test-placeholder, g3-life-test-placeholder, g3-grade-test-placeholder.
How the two CSVs relate
- The ledger is everything a student meets in order: intros, lessons, Question 1s, quizzes, practice, summaries, polls, placeholders.
- The bank is the PP100 items only, one row per item, in your protected format:
chapter_id= the topic (g3t21),atom_idandassociated_lesson_idpoint back at a ledger row,correct_answeris a letter,difficultyeasy / medium / hard anddok_level1 / 2 / 3 from the same tag,family_id= the question type (type-3). Items are served singly at random, so each one stands alone. item_idis a hash of the wording (g3t21-pp-ed69d6b2): stable when the bank is re-sorted, changed only if the item is reworded.- Ids are unique across the whole course, so the 42 topic pairs can be uploaded one at a time or as the single course-wide pair described below.
What is ready today
Counted from the course repo on 30 September. "Videos" counts one per lesson plus the topic intro and summary. "Delivered" means David's videos file says done and the MP4 exists.
| Strand | Topics | Lessons | Videos wanted | Delivered | With the pipeline | Not yet briefed | Full PP100 banks (50 or more items) |
|---|---|---|---|---|---|---|---|
| Physics | 15 | 74 | 104 | 104 | 0 | 0 | 4 of 15 |
| Matter | 6 | 35 | 47 | 47 | 0 | 0 | 0 of 6 |
| Earth & Space | 10 | 45 | 65 | 0 | 0 | 65 | 0 of 10 |
| Life | 11 | 44 | 66 | 0 | 0 | 66 | 0 of 11 |
| Whole course | 42 | 198 | 282 | 151 | 0 | 131 | 4 of 42 |
- Written content: all 42 topics have their intro, lessons, quizzes, practice and summary written. Earth & Space and Life are in James's review now.
- Videos: Physics and Matter are delivered except the Sound summary and one added lesson in Measuring tools (both with the pipeline) and one added lesson in Heating and cooling (briefed, not yet in the videos file). Earth & Space and Life videos are not yet briefed; their narration is in every row's
script. - Strand intros: four scripts written, none rendered yet; four
text_onlyrows in the ledger. - PP100 banks: Topics 1 to 4 have 50 to 54 items each. The other 38 topics carry 6 to 14 items: one worked example per question type, which James approves before the full bank is generated. So today's bank file has 556 items and will grow to at least 2,100.
- The course-wide ledger with placeholders is built and passes your schema check:
handoff/COURSE_LEDGER/g3-science.activity-ledger-v3.csv(4,294 rows) andg3-science.pp100-bank-v1.csv(556 items), with 1,735 images. It is a format sample, not an upload: it contains the five test placeholders and four strand intros with no video.
What will change, and in what format
- Strand intro videos (4). Same kind of row as a topic intro. Today
text_onlywith the script; they flip tolearner_choicewhen rendered. Ids:g3-physics-intro-lesson,g3-matter-intro-lesson,g3-earth-space-intro-lesson,g3-life-intro-lesson, each with a-pollrow after it. - End-of-strand tests (4). Static forms plus a bank for retests; the format (about 30 items, phenomenon clusters, numeric entry, matching, two-part evidence, a 90% bar) follows Alpha's own Grade 3 test blueprint and goes to Alpha's assessment lead for validation before anything is authored. The end-of-grade test is Alpha's existing Grade 3 form family. Proposed format: a pp100-bank-v1 file per test with
chapter_id= the placeholder's id (g3-physics-test), item typesmcqandfrq, and a short form list naming which items make the static form. Length, item count and pass mark are James's to rule; the placeholder row goes when the bank arrives. If your protected-bank type cannot hold a static form, tell us now. - End-of-strand practice test and revision resources. Being proposed to James separately. They would be ordinary ledger rows (a
lessonrow for a revision page, question rows for a practice set), so no new format. - PP100 banks grow from a sample to 50 or more items per topic as James approves each type sheet. Item ids of existing items do not change.
- Two-lesson atoms. Three lessons revisit an atom taught earlier in the same topic. Where the two lessons are consecutive they share the atom. Where they are not (Topic 3,
FOR3-021), the second lesson's rows carryFOR3-021--l06until James rules whether to merge or register a new atom.
What we need from you
- Does a two-answer
clozerender as tap-one-of-two for a grade-3 reader? If you can take a two-optionmcq, say so and the exporter emits that instead. - Can the FRQ grader be held to an exact accept list? Every typed item depends on it (413 in the ledger today, 17 of them in Topic 21 alone).
- Does a split article work as a toggle? The video sits on reading 1; readings 2 onward are text only. Does the student who chose the video still see readings 2 onward, or should we put the whole article on one row and the video on another?
- Can the poll row be shown without right or wrong?
- Can a static test form live in the protected bank format, or do you need a different file?
Validation and contact
- Rule: nothing is sent until
validate_export.pyprints PASS. The validator ships in every package folder beside the CSVs. It runs your two JSON schemas and the cross-checks the schemas cannot express (unique ids, every question after its lesson, every bank atom real, every image present). Today's course-wide ledger: PASS, 0 schema errors, 0 cross-check errors. - Route: James Moore owns the content and the format. David uploads the packages and the videos and edits videos by Peps id. Questions about a row go to James; questions about an upload go to David.
Depth: the 58 ledger columns, column by column
Column names are verbatim from your v3 template, in template order.
| Column | What we put in it |
|---|---|
course_id, course_title, grade | g3-science, Grade 3 Science, 3 on every row |
domain_id, domain_title, domain_order | The strand: physics / matter / earth-space / life, its title, 1 to 4 |
unit_id, unit_title, unit_order | Physics has three units (g3-motion, g3-forces, g3-energy); the other strands have one unit named after the strand. Strand intro and test rows use the strand as unit |
topic_id, topic_title, topic_order | g3t21, Heating and cooling, 21. Strand intros use g3-<strand>-intro, order 0; tests use g3-<strand>-test, order 99 |
standard_id | The atom's first standards code (TEKS-G3-6C); blank on intro, practice, summary and placeholder atoms |
atom_id | The register atom (MAT3-040) for a lesson; g3t21-intro, g3t21-practice, g3t21-summary for the topic-level atoms |
atom_title, atom_objective, atom_order | The register's title and behaviour, repeated on every row of the atom; order within the topic |
element_id, element_type, element_title, element_order | Course-unique id; lesson / mcq / cloze / frq; a human label ("L01 quiz 3 of 12"); position within the atom |
required_for_atom | true everywhere except the two polls |
exclude_from_retrieval | true for lessons, polls, Question 1s, summary checks and scaffold items; false for quiz and practice items, which are eligible for spaced retrieval |
prompt | The question text (for cloze: "Pick the answer from the word bank.") |
script | The full narration of the lesson's video, on reading 1 only. Present whether or not the video exists |
speaker_description, background_description, b_roll_guidance | Blank. These belong to your legacy generated video type, which we do not use |
image_url, image_description | /course-assets/g3-science/images/g3t21_<key>.png and the drawing's alt text; one image per row at most |
dok_level | 1 to 3, metadata only |
passage_dependent | false |
ai_grading_instructions, accepted_answers | frq rows only: the exact-match rule in plain words (80 characters minimum) and the JSON list of accepted strings |
mcq_a … mcq_e, feedback_a … feedback_e | mcq rows: options with the key first, feedback per option, feedback_a opening "Correct:" (not on polls) |
match_pairs, sequence_items, sort_categories | Blank. Not used yet; a reorder item type waits on your confirmation of sequence |
cloze_text, cloze_word_bank | cloze rows: stem ending "Answer: {{key}}" and the JSON list of the two answers |
lesson_delivery_mode | lesson rows only: text_only (no video yet, or a later reading) or learner_choice (video delivered) |
lesson_body_markdown | The article as safe markdown: # title, ## subtitles, paragraphs, rule, Drawing: caption where a figure sits |
video_source_type, video_source_ref, video_aspect_ratio, caption_source_ref | Empty until the video exists; then uploaded_file, the MP4 name, auto, empty |
associated_lesson_id | Every question points at its lesson's reading-1 row; practice items point at a lesson only where the source names one |
activity_feedback | The explanation for cloze and typed items (MCQs carry it per option instead) |
supporting_kc_ids | JSON list of the atom's other standards codes (["SC.3.P.9.1"]), [] when none |
Depth: the 34 bank columns and the id rules
course_id, chapter_id (= topic id), chapter_title, atom_id, associated_lesson_id, item_id, family_id (question type, type-N), item_type (mcq or frq), primary_kc_id (= atom), supporting_kc_ids, dok_level (easy 1, medium 2, hard 3), difficulty, prompt, image_url, image_description, activity_feedback, option_a … option_e, correct_answer (a letter), feedback_a … feedback_e (key line opens "Correct:", others "Not this one."), accepted_answers, ai_grading_instructions, match_pairs, cloze_text, cloze_word_bank, sequence_items, sort_categories.
Id rules: item_id = g3t<topic>-pp- + 8 hex characters of a hash of stem and options. Reordering the bank does not change ids; rewording an item does. Multi-select items are exported as their pair MCQ until you confirm a select-all type; reorder items are held back until you confirm sequence.
Depth: the files and tools behind this document
- Per-topic exporter:
build_tools_export_timeback.py <topic module> <out folder>; writes the two CSVs,images/,contract/(your schemas and templates),validate_export.py, a preview of the course's own page,README_for_David.mdand an export report. Worked example:handoff/G3T21/package/. - Course-wide ledger with placeholders:
build_tools_course_ledger.py [--reuse]; runs the exporter for all 42 topics, stitches them in strand order, adds the strand intro rows and the five test placeholders, reads video state from each topic'shandoff/<CODE>/videos.json, prefixes every image with its topic code (two topics can reuse a figure key), validates, writeshandoff/COURSE_LEDGER/BUILD_REPORT.md. - Validator:
python3 validate_export.py <ledger.csv> <bank.csv> [images_dir] [contract_dir]; inside a package folder the arguments default to the files beside it. - Video ids:
handoff/VIDEO_IDS.md(rebuilt bybuild_tools_video_ledger.pyfrom each topic'svideos/*.beats.json). - The Student view that mimics your player during review:
build_tools_timeback_mimic.py, video card first, Question 1 straight after it, then the article cards, then the quiz. - Contract source: the TimeBack Scroll authoring package (v3 ledger, v1 bank), copied into every package's
contract/folder.