An analysis, written by this project
The annual town reports
The sixteen annual town reports, FY2011–FY2025, every one downloadable with the sha256 of the bytes we hold — and what we read out of them, by category. Says plainly which pages tie to a total the page itself prints and which carry figures nothing has ever checked, because those are not the same thing.
lunenburgbudgetproject.org — written by the Lunenburg Budget Project, an independent tool for residents. Not affiliated with the Town of Lunenburg, the School Committee or the school district. The document this page renders: /docs/analyses/annual-reports.md
What this report counts
One row per page of an annual town report that holds a financial table, and the datasets read out of those pages. A page is counted once per report; a figure is counted once per row.
All 477 pages holding a financial table have been read.
None is unread, so the work left is checking rather than reading.
Sixteen documents, opened page by page. A page counted here is one that holds a financial table, not every page of the book.
What it rests on `annual-report-pages.csv`, which is generated from what the extractors actually wrote and refuses to publish a count off a stale database.
What it does not show Whether a page holds a table we have not recognised as financial. The classifier reads headings, and the pages whose heading did not classify are filed as `unknown` rather than dropped.
208 of 477 pages tie to a total the page itself prints.
The other 269 carry real figures that no arithmetic has confirmed.
A page is PROVEN only where the table states an identity about itself -- parts summing to a printed total -- and the extract closes it. Most tables here print no total, so there is nothing to close.
What it rests on the `state` column of `annual-report-pages.csv`, set from the proof each extractor recorded rather than from whether it produced rows.
What it does not show That an UNPROVEN figure is wrong. It means nothing has checked it, which is a different claim and the reason the column exists.
Appropriations is the least checked: 77 of its 95 pages have no check at all.
It is also the category a resident is most likely to quote.
These pages print what Town Meeting voted, article by article. 17 of them do tie to a printed total; the rest are read and unconfirmed.
What it rests on `annual-report-pages.csv` grouped by subject and state.
What it does not show Which of those pages COULD be checked. A page printing no total can never reach PROVEN however good the extractor gets.
Those are the answers this report could reach from the documents behind it. If the one you came for is not among them, ask us — no name or email needed.
Sixteen documents, 477 pages of financial tables, 23,639 rows read out of them.
The sixteen reports
Every one is downloadable, and every one carries the sha256 of the bytes we hold, so a figure can be traced to the page it came from and the page to the file.
| fiscal year | document | size | download | sha256 |
|---|---|---|---|---|
| FY2011 | 4117-fy-2011-annual-town-report.pdf | 30.2 MB | download | 551f9edd75d051ae… |
| FY2012 | 4118-fy-2012-annual-town-report.pdf | 54.0 MB | download | 75d645ee7055f68c… |
| FY2013 | 4119-fy-2013-annual-town-report.pdf | 36.1 MB | download | 00670845b7d32216… |
| FY2014 | 4120-fy-2014-annual-town-report.pdf | 5.5 MB | download | f5ef6e9aec7866f7… |
| FY2015 | 4121-fy-2015-annual-town-report.pdf | 7.2 MB | download | 712afbb458b2a452… |
| FY2016 | 4123-fy-2016-annual-town-report.pdf | 5.2 MB | download | f13af7a7c78d4a14… |
| FY2016 addendum | 4122-fy-2016-annual-town-report-addendum.pdf | 2.1 MB | download | b354a3941e2451f7… |
| FY2017 | 4124-fy-2017-annual-town-report.pdf | 35.4 MB | download | 4c6fbf70d0aff247… |
| FY2018 | 4125-fy-2018-annual-town-report.pdf | 7.7 MB | download | 364a1138df754668… |
| FY2019 | 4126-fy-2019-annual-town-report.pdf | 8.9 MB | download | 220f1c778148feb9… |
| FY2020 | 4127-fy-2020-annual-town-report.pdf | 19.6 MB | download | c3bf67f1259a5c19… |
| FY2021 | 4128-fy-2021-annual-town-report.pdf | 78.8 MB | download | 7ec4740034a2b9bd… |
| FY2022 | 4129-fy-2022-annual-town-report.pdf | 16.1 MB | download | d1673d634dba15c2… |
| FY2023 | 4131-fy-2023-annual-town-report.pdf | 17.4 MB | download | d273ebb71360e30d… |
| FY2024 | 4132-fy-2024-annual-town-report.pdf | 49.8 MB | download | 46f14ff8459ec81f… |
| FY2025 | 4130-fy-2025-annual-town-report.pdf | 6.9 MB | download | a9ee7b51154d94fd… |
Read the rest of the analysisThe full version4 min
The other findings
17 of the 24 datasets are read by a generic extractor that cannot name its columns.
Read `column_meaning` before quoting a value from one of those.
The generic extractor records a column as `v1`, `v2`, `v3` -- an ORDINAL, the first column of THAT page that held figures. The ruler is rebuilt per page, so the same name means different columns on different pages.
What it rests on the dataset inventory in `scripts/build_archive_guide.py`, read here rather than restated, so the two cannot disagree.
What it does not show Which printed column a given `v1` is on any particular page, except where `column_meaning` names it from an identity the table states about itself.
What is in them, by category
proven means the rows tie to a total the page itself prints. unproven means the rows exist and nothing has checked them — not that they are wrong. refused means an extractor reached the page and wrote nothing.
| category | what it answers | pages | proven | unproven | refused |
|---|---|---|---|---|---|
| appropriations | what Town Meeting voted to spend, article by article | 95 | 17 | 77 | 1 |
| special revenue | the funds that sit outside the budget — grants, gifts, revolving | 68 | 53 | 15 | 0 |
| payroll | what the town paid its people, name by name | 65 | 5 | 59 | 1 |
| debt | what the town owes and when it falls due | 46 | 14 | 31 | 1 |
| trust and stabilization | the reserves, and how much is in each | 39 | 25 | 13 | 1 |
| receivables | what is owed TO the town, account by account | 28 | 18 | 7 | 3 |
| unknown | a financial table whose heading we could not classify | 27 | 12 | 15 | 0 |
| tax collection | what was committed, collected and abated | 21 | 9 | 11 | 1 |
| regional school | the assessment from the regional school district | 18 | 2 | 15 | 1 |
| balance sheet | what the town held and owed at year end | 17 | 16 | 1 | 0 |
| valuation | what the town is worth, by class of property | 16 | 8 | 8 | 0 |
| treasurers cash | the cash the Treasurer held | 15 | 14 | 0 | 1 |
| capital | the capital projects and what they cost | 13 | 10 | 3 | 0 |
| enrollment | how many children are in the schools | 6 | 4 | 2 | 0 |
| elections | how the town voted | 2 | 1 | 1 | 0 |
| cultural council | the grants the cultural council made | 1 | 0 | 1 | 0 |
| total | 477 | 208 | 259 | 10 |
By report
| fiscal year | pages | proven | unproven | refused |
|---|---|---|---|---|
| FY2011 | 28 | 10 | 17 | 1 |
| FY2012 | 27 | 10 | 16 | 1 |
| FY2013 | 29 | 8 | 20 | 1 |
| FY2014 | 27 | 14 | 13 | 0 |
| FY2015 | 31 | 13 | 18 | 0 |
| FY2016 | 41 | 12 | 29 | 0 |
| FY2017 | 33 | 14 | 16 | 3 |
| FY2018 | 35 | 17 | 18 | 0 |
| FY2019 | 38 | 11 | 26 | 1 |
| FY2020 | 39 | 16 | 22 | 1 |
| FY2021 | 37 | 16 | 21 | 0 |
| FY2022 | 33 | 18 | 15 | 0 |
| FY2023 | 34 | 15 | 17 | 2 |
| FY2024 | 22 | 11 | 11 | 0 |
| FY2025 | 23 | 23 | 0 | 0 |
The datasets read out of them
A dedicated extractor knows what its table means and can check it against a total the page prints. The generic one cannot: its v1…v8 are ORDINALS — the first, second, third column of that page that held figures — and the ruler is rebuilt per page. Read column_meaning before quoting one.
| dataset | rows | years | built by | checked | check failed | no check |
|---|---|---|---|---|---|---|
report-appropriations.csv | 5,345 | 2011–2025 | generic | 311 | 5034 | 0 |
staff-roster-entries.csv | 3,751 | 2011–2025 | dedicated | — | — | — |
report-gross-wages.csv | 3,547 | 2011–2025 | generic | 0 | 0 | 3547 |
special-revenue-funds.csv | 2,422 | 2011–2025 | dedicated | 172 | 2098 | 151 |
report-elections.csv | 2,012 | 2011–2025 | generic | 323 | 1688 | 1 |
annual-report-receipts.csv | 1,137 | 2011–2023 | dedicated | 504 | 85 | 548 |
staff-roster-counts.csv | 698 | 2011–2025 | dedicated | — | — | — |
report-index.csv | 652 | 2011–2025 | generic | — | — | — |
report-trust-funds.csv | 644 | 2011–2025 | generic | 12 | 418 | 214 |
report-capital-projects.csv | 618 | 2011–2025 | generic | 48 | 544 | 26 |
staff-position-map.csv | 525 | — | dedicated | — | — | — |
report-dept-activity.csv | 515 | 2011–2025 | generic | 0 | 0 | 515 |
report-debt.csv | 366 | 2011–2025 | generic | 75 | 99 | 192 |
report-enrollment-mcas.csv | 338 | 2011–2025 | generic | 0 | 0 | 338 |
report-valuation.csv | 321 | 2011–2019 | generic | 0 | 0 | 321 |
report-officials.csv | 237 | 2011–2024 | generic | 0 | 0 | 237 |
report-signatures.csv | 182 | 2013–2025 | generic | — | — | — |
report-filing.csv | 104 | — | generic | — | — | — |
report-vital-records.csv | 96 | 2011–2025 | generic | 0 | 0 | 96 |
report-monty-tech.csv | 70 | 2017–2017 | generic | 0 | 0 | 70 |
report-appropriations-supplement.csv | 32 | — | generic | — | — | — |
placement-counts.csv | 15 | 2011–2025 | dedicated | — | — | — |
ballot-questions.csv | 9 | 2012–2025 | dedicated | — | — | — |
report-appropriations-supplement-refused.csv | 3 | — | generic | — | — | — |
What this does not establish
- That an UNPROVEN figure is wrong. Nothing has checked it.
- What a generic
v1column is on any page wherecolumn_meaningsaysnot established. - Whether a page we filed as
unknownholds a table worth reading.
Limits that cannot be closed by better code are registered in sources/data/money-gaps.csv and published at /what-we-cannot-answer.
Where these figures come from
| what | where |
|---|---|
| The sixteen reports themselves | /docs/town-annual-reports/docs/, each with its sha256 in /data/archive-manifest.csv |
| What is on each page and what proved it | /data/annual-report-pages.csv |
| What a column means before you quote it | sources/data/PROVENANCE-report-tables.md and column_meaning |
Where this came from
Nothing on this page is an official document. It was written here, from documents the town and district published and from records obtained by request, and it has not been reviewed or endorsed by the Town of Lunenburg, the School Committee, the Finance Committee or Lunenburg Public Schools. The report index says the same thing at more length, and lists every analysis alongside the data underneath it.
This page renders the document itself, which is the source of truth: there is one copy of every sentence and every figure here, not a transcription of one.
Every other report
Every analysis this project has written, in one index, is at reports.