# 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.*
