# 2nd Grade Math Curriculum β€” Comprehensive Audit, Weeks 1–32

**Date:** 2026-07-15
**Scope:** All 32 canonical generators + all 192 PDFs (6 per week). Read-only audit β€” no curriculum files modified.
**Method:** Automated signal scan (`/tmp/audit_full.py` β†’ `/tmp/audit_full.json`), py_compile syntax check on every generator, pdftotext content verification of every Monday PDF, normalized diffs for clone detection, MD5 comparison of PDFs, PNG rendering + ink-density analysis of 8 sample worksheets across all 5 phases.

---

## 1. Executive Summary

**Overall grade: C- (curriculum) / A- (layout & CSS) / A (weeks 1–15 pedagogy)**

The rewritten portion of the curriculum (Weeks 1–15, plus 17, 25, 31) is genuinely good: strong New Standard pedagogy, excellent writing space, correct standards alignment. But the audit uncovered a **catastrophic structural failure in the back half**:

### πŸ”΄ Finding #1 β€” 14 weeks are byte-identical clones of Week 3
Weeks **16, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 32** are verbatim copies of `generate_week3.py` ("Comparing & Ordering Numbers"). Evidence:
- Normalized diff of each vs. Week 3: only **4 lines differ** (the week-number token in the docstring/output path).
- Every `page()` call still passes week number `3` β€” the rendered PDFs say **"Week 3"** in the header.
- `md5sum Week_3_Monday.pdf == Week_16_Monday.pdf == Week_24_Monday.pdf` β€” **byte-identical**.

A child working through this curriculum would repeat the *same comparing-numbers worksheet 15 times* and **never see time-telling, money, graphs, geometry, area/perimeter, or multiplication facts**. This is not a quality issue β€” the content simply does not exist for 44% of the year.

### πŸ”΄ Finding #2 β€” Week 5 PDFs are mislabeled "Week 2"
`generate_week5_rewritten.py` has a copy-paste bug: all five `page(2, ...)` calls pass week number **2** instead of 5. Content is correct (Subtraction Facts to 20) but every Week 5 PDF header reads "Week 2". One-character fix Γ—5, then regenerate.

### πŸ”΄ Finding #3 β€” Week 15 PDFs are stale AND wrong
`generate_week15.py` (Length/Measurement, rewritten Jul 4) is good code, but the PDFs in `Week_15/` date from **Jun 18** and are actually **Week 3 clones** (header says "Week 3: Comparing & Ordering"). The generator was never re-run. Fix: run it.

### 🟑 Finding #4 β€” Week 9 canonical-file confusion
Current `Week_9/*.pdf` (Jul 4 18:13) contain "Estimate First!" boxes that exist **only** in `generate_week9_rewritten.py` (Jul 4 17:13), not in `generate_week9.py` (May 21). The rewritten file is the de-facto canonical; the tracking list says otherwise. Rename or update the record to avoid a future regeneration silently reverting Week 9 to the drill-heavy old version.

### βœ… What's working
- **Layout/writing space is excellent everywhere** (shared CSS): 14px/1.7lh body, blanks β‰₯8em, 80px draw boxes, 0.5in margins, single-page worksheets with content ending at 51–90% of page height (measured). No cramping anywhere.
- **Weeks 1–14 pedagogy is strong**: 5–7 of 7 New Standard principles per week; Weeks 4, 5, 10 hit all 7.
- All 32 generators compile cleanly; all import shared helpers/builders correctly.

---

## 2. Per-Week Breakdown

Legend for principles (7 max): E=Estimation, N=Number talk, M=Multiple strategies, W=Word-problem scaffold, O=Open-ended, S=Friday self-check, R=Reflection ("one thing I learned").

### Phase 1 β€” Number Sense (Weeks 1–6)

| Wk | Generator | Topic (actual) | Principles | Space | Standards | Issues |
|----|-----------|----------------|-----------|-------|-----------|--------|
| 1 | generate_week1.py | Counting & Number Sense to 100 | 5/7 (E N W S R) | A | 2.NBT.A.1–2 | Missing multi-strategy & open-ended; acceptable for intro week |
| 2 | generate_week2_rewritten.py | Place Value (Tens & Ones) | 6/7 (E N M W S R) | A | 2.NBT.A.1, A.3 | Missing open-ended only |
| 3 | generate_week3.py | Comparing & Ordering | 6/7 (E N M W S R) | A | 2.NBT.A.4 | Missing open-ended. Good week β€” pity it got cloned 14Γ— |
| 4 | generate_week4_rewritten.py | Addition Facts to 20 | **7/7** | A | 2.OA.A.2, 2.OA.B | Model week |
| 5 | generate_week5_rewritten.py | Subtraction Facts to 20 | **7/7** | A | 2.OA.A.2 | πŸ”΄ **All PDFs say "Week 2"** β€” `page(2,...)` bug on lines 83/135/185/239/300 |
| 6 | generate_week6.py | Phase 1 Review | 3/7 (N W S) | A | Review | Low signal count OK for a review/assessment week, but no reflection on a review week is odd |

### Phase 2 β€” Add/Sub to 100 (Weeks 7–14)

| Wk | Generator | Topic | Principles | Space | Standards | Issues |
|----|-----------|-------|-----------|-------|-----------|--------|
| 7 | generate_week7_rewritten.py | Adding Within 100 (no regroup) | 5/7 (E N W O S) | A | 2.NBT.B.5 | No Friday "one thing I learned" line |
| 8 | generate_week8_rewritten.py | Subtracting Within 100 (no regroup) | 5/7 (E N W O S) | A | 2.NBT.B.5 | Same reflection gap as W7 |
| 9 | generate_week9(_rewritten).py | Addition with Regrouping | rewritten: 6/7 | A | 2.NBT.B.5–6 | 🟑 Canonical-file ambiguity (see Finding #4). Old file only 3/7 |
| 10 | generate_week10.py | Subtraction with Regrouping | **7/7** | A | 2.NBT.B.5 | Model week. Fullest page in sample (content to 90%) but still fits well |
| 11 | generate_week11.py | Mixed 2-Digit Add/Sub | 6/7 | A | 2.NBT.B.5 | β€” |
| 12 | generate_week12.py | Adding 3 Numbers | 6/7 | A | 2.NBT.B.6 | β€” |
| 13 | generate_week13.py | 3-Digit Add/Sub | 5/7 | A | 2.NBT.B.7 | Missing multi-strategy & open-ended |
| 14 | generate_week14.py | Problem Solving Strategies | 4/7 (N O S R) | A | 2.OA.A.1 | No estimation boxes β€” surprising for a problem-solving week |

### Phase 3 β€” Measurement, Time & Money (Weeks 15–20)

| Wk | Generator | Actual content | Principles | Issues |
|----|-----------|----------------|-----------|--------|
| 15 | generate_week15.py | Length: Inches & Centimeters (good code) | 6/7 | πŸ”΄ **PDFs stale (Jun 18) and are Week 3 clones β€” generator never re-run after Jul 4 rewrite** |
| 16 | generate_week16.py | πŸ”΄ **Week 3 clone** (should be Telling Time) | n/a | Content missing entirely |
| 17 | generate_week17.py | Time Word Problems (genuine) | 4/7 (N W S R) | Real content βœ…, but old template: no estimation, no multi-strategy; drill-ish |
| 18 | generate_week18.py | πŸ”΄ **Week 3 clone** (should be Money: Coins & Bills) | n/a | Missing |
| 19 | generate_week19.py | πŸ”΄ **Week 3 clone** (should be Money: Adding & Change) | n/a | Missing |
| 20 | generate_week20.py | πŸ”΄ **Week 3 clone** (should be Picture & Bar Graphs) | n/a | Missing |

### Phase 4 β€” Geometry & Fractions (Weeks 21–26)

| Wk | Actual content | Issues |
|----|----------------|--------|
| 21 | πŸ”΄ **Week 3 clone** (should be 2D Shapes & Attributes) | Missing |
| 22 | πŸ”΄ **Week 3 clone** (should be 3D Shapes) | Missing |
| 23 | πŸ”΄ **Week 3 clone** (should be Lines, Angles & Symmetry) | Missing |
| 24 | πŸ”΄ **Week 3 clone** (should be Area & Perimeter) | Missing |
| 25 | Intro to Fractions (genuine) β€” 4/7 (W O S R) | Real content βœ…; no estimation/number-talk (estimation is arguably N/A for intro fractions, number talk is not) |
| 26 | πŸ”΄ **Week 3 clone** (should be Phase 4 Review) | Missing |

### Phase 5 β€” Multiplication & Division (Weeks 27–32)

| Wk | Actual content | Issues |
|----|----------------|--------|
| 27 | πŸ”΄ **Week 3 clone** (should be Equal Groups & Arrays) | Missing |
| 28 | πŸ”΄ **Week 3 clone** (should be Repeated Addition β†’ Γ—) | Missing |
| 29 | πŸ”΄ **Week 3 clone** (should be Γ— Facts 0–5) | Missing |
| 30 | πŸ”΄ **Week 3 clone** (should be Γ— Facts 6–10) | Missing |
| 31 | Division as Equal Sharing (genuine) β€” 5/7 (N M O S R) | Real content βœ…; old template but decent |
| 32 | πŸ”΄ **Week 3 clone** (should be Final Review & celebration) | Missing β€” the year currently ends on a repeat of a Week-3 worksheet |

---

## 3. Standards Coverage Matrix

| Standard | Description | Covered in | Status |
|----------|-------------|-----------|--------|
| 2.OA.A.1 | 2-step add/sub word problems ≀100 | W7–14 (esp. 14) | βœ… Strong |
| 2.OA.A.2 | Fluency within 20 | W4, W5 | βœ… |
| 2.OA.A.3 | Odd/even | β€” | πŸ”΄ **Gap** (nowhere explicit) |
| 2.OA.A.4 | Arrays / repeated addition | intended W27–28 | πŸ”΄ **Missing (clones)** |
| 2.NBT.A.1 | Place value hundreds/tens/ones | W1, W2, W13 | βœ… |
| 2.NBT.A.2 | Skip counting 5s/10s/100s | W1 | 🟑 Thin β€” only Week 1; W29–30 skip counting missing (clones) |
| 2.NBT.A.3 | Standard/word/expanded form | W2 | βœ… |
| 2.NBT.A.4 | Compare numbers | W3 (…and unintentionally Γ—15) | βœ… (over-covered!) |
| 2.NBT.B.5 | Fluency add/sub within 100 | W7–11 | βœ… Strong |
| 2.NBT.B.6 | Add up to 4 two-digit numbers | W12 | βœ… |
| 2.NBT.B.7 | Add/sub within 1000 | W13 | βœ… |
| 2.NBT.B.8 | Mentally Β±10/Β±100 | W9–10 warm-ups (Subtract 10 mental math) | 🟑 Partial β€” Β±100 not evidenced |
| 2.NBT.B.9 | Explain why strategies work | Number talks W2–13 | βœ… |
| 2.MD.A.1–4 | Measure/estimate lengths | W15 (code only β€” PDFs wrong) | 🟑 Code βœ…, output πŸ”΄ |
| 2.MD.B.5–6 | Length word problems, number lines | W15 partial | 🟑 |
| 2.MD.C.7 | Time to nearest 5 min | W17 (elapsed time βœ…); W16 telling-time **missing** | 🟑 W17 assumes clock-reading skills W16 never taught |
| 2.MD.C.8 | Money | intended W18–19 | πŸ”΄ **Missing entirely** |
| 2.MD.D.9–10 | Picture/bar graphs | intended W20 | πŸ”΄ **Missing entirely** |
| 2.G.A.1 | Shapes, angles, attributes | intended W21–23 | πŸ”΄ **Missing entirely** |
| 2.G.A.2 | Partition rectangles into squares (area) | intended W24 | πŸ”΄ **Missing entirely** |
| 2.G.A.3 | Partition into halves/thirds/fourths | W25 βœ… | βœ… |

**Bottom line:** All 2.OA (except A.3/A.4) and 2.NBT standards are well covered. **The entire 2.MD money/data cluster and nearly all of 2.G are absent** because the weeks that should teach them are Week-3 clones. Sequencing hazard: W17 (time word problems) exists but its prerequisite W16 (telling time) doesn't.

---

## 4. Writing Space Audit

Verified against `math_helpers.py` CSS + measured PNG renders (100 dpi, 850Γ—1100 px):

| Property | Value | Verdict for a 7-year-old |
|----------|-------|--------------------------|
| Body font / line-height | 14px / 1.7 | βœ… Good readability |
| Answer blanks `.b/.bw/.bl` | min-width 8em / 18em / 22em, 1.5px underline | βœ… Generous β€” 8em β‰ˆ 1.2" for single answers |
| Draw/dash boxes | min-height 80px (~0.83") | βœ… Adequate for drawings; could go 100px for base-10 block work (W9–10) |
| Number-bond circles | 38px | βœ… |
| Skip-count circles | 34px, 14px font | βœ… Just adequate β€” 2-digit numbers fit; 3-digit would be tight |
| Answer boxes `.obox` | min-width 2.2em, min-height 1.4em | 🟑 Smallest writing target on the page; fine for single digits, tight for 2-digit answers |
| Table cells | 5px 8px padding, 12px font | 🟑 If a child writes *in* a table cell, it's tight; mostly used for reference tables, so OK |
| Page | 8.5Γ—11in, 0.5in margins, 1 page per day | βœ… |

**Measured density (sample renders):** ink coverage 2.0–3.0% of page; content ends between 51% (W15/W17) and 90% (W10 Monday) of page height. No worksheet is cramped; several (W17, W25, W31 β€” the old-template genuine weeks) are actually *under-filled*, ending at ~51–57% with a large empty bottom half β€” space that could host a work area or "show your thinking" box.

**Per-week space grades:** every week **A or A-**. Only flags:
- W10 Monday is the densest page (90%) β€” fine now, but don't add sections.
- Old-template weeks (17, 25, 31) waste the bottom ~40% of the page.
- Recommend bumping `.dbox/.draw-box` min-height 80β†’100px for regrouping weeks (9–10) where kids draw base-10 blocks.

---

## 5. Priority Fixes (ranked)

### P0 β€” Critical (curriculum is unusable past Week 15 without these)
1. **Write real generators for the 14 clone weeks** (16, 18–24, 26–30, 32). This is ~44% of the year and covers all of money, data, geometry, area/perimeter, multiplication, and both Phase 4/Final reviews. Suggested order = chronological teaching order: 16 (time) β†’ 18–19 (money) β†’ 20 (graphs) β†’ 21–24 (geometry) β†’ 26 β†’ 27–30 (Γ—) β†’ 32.
2. **Regenerate Week 15 PDFs** β€” code is done; just run `generate_week15.py` in the venv. (5-minute fix.)
3. **Fix Week 5 label bug** β€” change `page(2,` β†’ `page(5,` on lines 83, 135, 185, 239, 300 of `generate_week5_rewritten.py`, regenerate. (5-minute fix.)

### P1 β€” Important
4. **Resolve Week 9 canonical file**: current PDFs come from `generate_week9_rewritten.py`; either promote it (rename over `generate_week9.py`) or update tracking docs so a future batch regeneration doesn't silently revert Week 9 to the 3/7-principle old version.
5. **Add 2.OA.A.3 (odd/even) coverage** β€” natural home: Week 6 review or the future Week 27 (equal groups).
6. **When writing W16, sequence before W17** β€” W17 already assumes clock-reading fluency that is currently never taught.

### P2 β€” Quality improvements
7. Bring old-template genuine weeks (17, 25, 31) up to New Standard: add estimation (where sensible), number talks (W25), multi-strategy sections, and use the empty bottom half of their pages for work areas.
8. Add "one thing I learned" reflection lines to W7 and W8 Fridays; add reflection to W6 review.
9. Add an estimation section to W14 (problem-solving week without estimation is a miss).
10. Strengthen skip counting (2.NBT.A.2): only W1 touches it; the future W29–30 rewrites should lean on it.
11. Extend 2.NBT.B.8 to Β±100 mentally (currently only Β±10 warm-ups).
12. Bump draw-box min-height to 100px for W9/W10.

---

## 6. Phase Comparison β€” Rewritten vs. Not

| Metric | Phase 1–2 (W1–14, rewritten) | Phase 3–5 (W15–32) |
|--------|------------------------------|---------------------|
| Genuine content | 14/14 weeks | **4/18 weeks** (15*, 17, 25, 31) |
| Avg New Standard principles | 5.6/7 (four weeks at 7/7 or 6/7) | 4.75/7 for the 4 genuine weeks; n/a for 14 clones |
| Estimation boxes | 12/14 weeks | 1/4 genuine (W15 only) |
| Number talks | 14/14 | 3/4 |
| Friday reflection | 12/14 | 4/4 |
| Drill reduction | Clear: activity counts trimmed, mental-math warm-ups replace drill pages (e.g., W10 has 8 computation items/day vs. traditional ~20+) | Old-template weeks (17, 25, 31) are lighter than traditional but lack the deliberate estimation/strategy scaffolds |
| Page fill | 55–90%, well-balanced | 51–57%, under-filled bottom halves |
| Code quality | All compile, correct imports, correct week numbers (except W5 label bug) | All compile, but 14 files are dead clones with `page(3,...)` |

*W15 code is rewritten-quality but its PDFs were never regenerated.

**Conclusion:** the Jul-4 rewrite effort produced a genuinely strong Phase 1–2. The rewrite evidently stopped at Week 15 (code) and the clone placeholders for the rest were never replaced. Until P0 items are done, this is a **15-week curriculum**, not a 32-week one.

---

*Audit artifacts: `/tmp/audit_full.py`, `/tmp/audit_full.json`, sample renders in `/tmp/audit_png/`. No curriculum files were modified.*