# NJDOE Certificated Staff

```toml ergo
[dataset]
ergo = "0.4"
slug = "certificated-staff"
title = "NJDOE Certificated Staff"
publisher = "New Jersey Department of Education"
subject = "https://www.nj.gov/education/doedata/cs/index.shtml"
source_url = "https://www.nj.gov/education/doedata/cs/index.shtml"
pitfall = "District certificated FTE is published as four separate role rows, not an authoritative district total or a count of employees, payroll, cost, effectiveness, quality, or need — and an empty-looking demographic cell is almost always an exact published zero, not a suppression."
status = "live"
confidence = "A"
updated = "2026-07-30"
implementation = "https://github.com/lavallee/njschooldata"

[dataset.coverage]
years = "2020-21 through 2025-26"
grain = "school year x district x certificated role x metric"
entities = "16,044 district-role rows and 320,880 district composition cells across 679 districts; 582 of 587 rendered budget districts have both staffing families"

[dataset.access]
keys = ["school_year", "district_code", "staff_role", "metric_id"]
```

## Consumer question and boundary

AQ-060 answers one product-owned question before the existing UFB salary and
benefit context:

> What district-level certificated role FTE and non-certificated support-role
> FTE did NJDOE report for 2020-21 through 2025-26, especially the latest
> 2025-26 year, before a reader treats UFB salary or benefit rows as staffing
> evidence?

Aquifer owns official-file custody, source literals and row locators, value
states, complete source validation, quarantines, immutable releases, and
offline snapshots. This repo owns the bounded question, exact mart selection,
district/year join, derived certificated total, wording, placement, static UAT,
and rollback.

The product keeps this release independent from non-certificated staffing. It
never publishes a combined workforce total, joins names, or treats the shared
`2025-26` label as a bridge to UFB payroll or budget dollars.

## Exact offline pin and mart

The committed pin is `contracts/aquifer/nj-certificated-staff.lock.json`:

- release `nj-certificated-staff-aq060-refresh2-v2`;
- manifest SHA-256
  `14a41b615ca52098fc1f959106b683c6e7d0e5cd4653d2dc6359bca1fffae4f0`;
- SQLite SHA-256
  `63277c64418eb8ad2129d3ac7f2c7035322b48db43c4cd52bc69abeaef98a8b8`;
- 1,120,714,752 bytes, 76,218 source rows, and 1,524,240 canonical values.

The consumer resolves and hashes this pin and the independent
non-certificated pin before it clones the warehouse. It projects only the
district `staff.certificated.total-fte` role values, validates all six annual
source files and the complete artifact population, hashes every unmanaged
consumer table, and atomically replaces the isolated candidate.

| Consumer table | Rows | Deterministic row SHA-256 |
| --- | ---: | --- |
| `staffing_certificated_district_composition` | 320,880 | `6e4d5d4f0f7e8fdd7b39cb7546e72ac2525ca576d292bab795085a016b3e513f` |
| `staffing_certificated_district_role` | 16,044 | `54bd0d86f40564aec6fa35f9337ee1932fcbbae2666aeda6c8fc803b14f451c2` |

The district projection contains 15,022 reported values and 1,022 exact
reported zeroes. Its four roles are Administrators, Special Service,
Supervisors/Coordinators, and Teacher. Annual district-role counts are 2,688,
2,680, 2,676, 2,676, 2,672, and 2,652.

### The widened composition mart

`staffing_certificated_district_role` projects one measure and one dimension:
`staff.certificated.total-fte` by role. It cannot answer a question about who
those staff are, because it carries no race column and no sex column.

`staffing_certificated_district_composition`, added 2026-07-30, is the whole
district slice at the grain the question needs — 16,044 role cells x 20 metric
definitions = **320,880 cells**, keyed
`(school_year, district_code, staff_role, metric_id)`. The three pre-existing
tables and their receipts are byte-identical after the change; the role table's
row SHA-256 is unmoved.

`numeric_value` is **nullable** in the composition mart and not in the role
mart. That is deliberate: the publisher's withheld cells have a literal and no
number, and collapsing them to `0.0` would turn *withheld* into *none*.

Per-metric reported rates at district level, all six years, 16,044 cells each:

| metric | reported | published zero | withheld |
| --- | ---: | ---: | ---: |
| `race.white.fte` | 14,666 | 1,378 | 0 |
| `gender.female.fte` | 14,567 | 1,477 | 0 |
| `gender.male.fte` | 12,179 | 3,865 | 0 |
| `race.hispanic.fte` | 7,057 | 8,987 | 0 |
| `race.black.fte` | 6,023 | 10,021 | 0 |
| `race.asian.fte` | 4,283 | 11,761 | 0 |
| `race.two-or-more-races.fte` | 1,131 | 14,913 | 0 |
| `race.hawaiian-native.fte` | 856 | 15,188 | 0 |
| `race.american-indian.fte` | 648 | 15,396 | 0 |
| `gender.nonbinary.percent` | **0** | **0** | **16,044** |

Nothing in this release is withheld except the non-binary percentage, and all of
it is. Every other empty-looking cell is an exact `0`.

## Issues

### FTE is workload, not people or money

```toml ergo
[issue]
id = "fte-is-not-headcount-or-payroll"
title = "Certificated FTE is fractional reported workload, not employee headcount, payroll, salary cost, effectiveness, quality, or need"
effect = "misleads"
type = "definitional"
status = "open"
detection = "The publisher reports numeric FTE by role; no person identifier, employee count, salary, payroll, cost, quality, or need field is present in the district role projection."
misuse = "Calling 730.2 FTE 730 employees, adding it to UFB salary dollars as a payroll rate, or treating a change as evidence of service quality or staffing adequacy."

[issue.scope]
all = true
```

The budget panel labels every number `FTE` and places the staffing table before
the separate UFB labor-cost context. Its caption blocks headcount, payroll,
cost, effectiveness, quality, and need readings.

### The district total is derived from four role rows

```toml ergo
[issue]
id = "district-total-is-derived"
title = "The district release has four certificated role rows but no authoritative district-total row"
effect = "misleads"
core = true
type = "measurement"
status = "mitigated"
detection = "District source rows contain exactly Administrators, Special Service, Supervisors/Coordinators, and Teacher; there is no district value with a separate total role."
misuse = "Presenting the four-role sum as a separately published NJDOE district total or combining it with the independent non-certificated reported total."

[issue.scope]
years = "2020-21 through 2025-26"
tables = ["staffing_certificated_district_role"]
```

The renderer sums the four reported role values only after exact district-code
and year selection and labels the result `derived sum of four reported role
rows`. The two staffing families are never added.

### An empty-looking cell is almost always an exact published zero

```toml ergo
[issue]
id = "published-zero-is-not-a-suppression"
title = "A blank-looking demographic cell is an exact published zero (literal 0), not a withheld value; the only withheld cells in the release carry the literal <.1"
effect = "corrupts"
core = true
type = "suppression"
status = "mitigated"
detection = "Release-wide, 909,830 of 1,524,240 values are value_state exact-reconciliation-zero with reported_literal '0' and 76,212 are value_state suppressed with reported_literal '<.1'; there is no third empty state. At district level 15,396 of the 16,044 american-indian FTE cells are an exact 0."
misuse = "Rendering an exact 0 as 'not reported' or 'no data', which reverses the finding: the district reported no staff FTE in that group and role. Or the mirror error, rendering a withheld <.1 as a zero."
instead = "Carry numeric_value as NULL only where the publisher withheld the value, keep the reported_literal beside it, and give the two states different words on the page."

[issue.scope]
years = "2020-21 through 2025-26"
tables = ["staffing_certificated_district_composition"]
```

The composition mart keeps `numeric_value` nullable and stores every
`reported_literal` and `value_state` verbatim. The profile module prints a
published zero as `0.0` in the ordinary text colour and a withheld cell as the
publisher's own literal in a muted monospace, and its notes say in words that a
`0.0` is a number New Jersey published.

### New Jersey has never published a non-binary value

```toml ergo
[issue]
id = "nonbinary-is-never-published"
title = "staff.certificated.gender.nonbinary.percent is a percentage with no count metric behind it, and it is withheld in every district, every role and every year"
effect = "misleads"
type = "coverage"
status = "mitigated"
detection = "The release has 20 metric definitions: seven race categories and two gender categories each carry a .fte and a .percent, and gender.nonbinary carries a .percent alone. All 76,212 of its cells across all reporting levels — 16,044 at district level — are value_state suppressed with reported_literal '<.1' and a NULL numeric value. Not one district, role or year has a published value."
misuse = "Dropping the category from a rendering because it is empty, which reads as 'there are none'; or reconstructing a value from total-fte minus female-fte minus male-fte and presenting the residual as a non-binary count."
instead = "Show the category, say that New Jersey published no value for it in any district, any role, or any year, and do not derive one."

[issue.scope]
years = "2020-21 through 2025-26"
columns = ["staff.certificated.gender.nonbinary.percent"]
tables = ["staffing_certificated_district_composition"]
```

The adapter fails closed on `EXPECTED_NONBINARY` — 16,044 cells, 16,044
withheld, 0 published, one distinct literal — so the module's sentence stops
being true the moment the state publishes anything. The module renders a
non-binary row on every role table with `not published` in the count column and
the publisher's `<.1` in the share column.

### Female plus male FTE does not add to the published total

```toml ergo
[issue]
id = "sex-fte-does-not-reconcile-to-total"
title = "The two published sex FTE values do not sum to the published total FTE in 421 of 16,044 district-role cells, and the residual is not a recoverable non-binary count"
effect = "misleads"
type = "measurement"
status = "mitigated"
detection = "Grouping the composition mart by (school_year, district_code, staff_role): the seven race FTE values sum to total-fte in all but 108 cells, off by at most 0.1. The two sex FTE values leave a non-zero residual in 421 cells. 295 of those residuals are +/-0.1; 181 are NEGATIVE, meaning female plus male exceeds the publisher's own total; the largest absolute residual is -54.0 against a published total of 1.0 (district 4270, Teacher, 2022-23)."
misuse = "Publishing total-fte minus female-fte minus male-fte as a non-binary count, an 'other' category, or an 'unreported' band. The residual is a mixture of publisher rounding and at least one gross publisher inconsistency, and in a small district a derived whole-number residual would identify individuals the publisher chose to withhold."
instead = "Show the two published sex values and their shares of the published role total, say that they do not always add to it, and derive nothing from the gap."

[issue.scope]
years = "2020-21 through 2025-26"
tables = ["staffing_certificated_district_composition"]
```

The adapter pins the residual population (421 cells, 181 negative, 54.0 maximum)
so this cannot drift silently. The module's `disclosure_gate` in
`aquifer_staffing_metadata` states the rule in the warehouse itself: no withheld
value is reconstructed by subtraction.

### The percent column rounds a reported FTE down to zero

```toml ergo
[issue]
id = "percent-column-rounds-a-reported-fte-to-zero"
title = "Eight district cells carry a reported non-zero FTE and a percent the publisher rounded to an exact 0.0, so the two columns disagree about whether anyone is there"
effect = "misleads"
type = "coding"
status = "mitigated"
detection = "At district level, race.american-indian.fte has 648 reported values but race.american-indian.percent only 642; race.two-or-more-races.fte has 1,131 against 1,129. The six and two extra cells are published zeros in the percent column standing over a reported non-zero FTE."
misuse = "Building a composition from the publisher's own .percent metrics, which silently drops the smallest reported groups to zero and leaves the shares not summing to 100."
instead = "Compute every share from the .fte metrics, which are additive: the seven race FTE values sum to the role's total FTE within 0.1 in all 16,044 district-role cells."

[issue.scope]
years = "2020-21 through 2025-26"
columns = ["staff.certificated.race.american-indian.percent", "staff.certificated.race.two-or-more-races.percent"]
tables = ["staffing_certificated_district_composition"]
```

Every share the profile module prints is computed from the FTE metrics. The
publisher's `.percent` metrics are projected and stored, and are not used to
build a distribution.

### Non-certificated staff have no race or sex at all

```toml ergo
[issue]
id = "noncertificated-has-no-race-or-sex"
title = "The non-certificated release carries no demographic metric, so paraprofessionals, aides, clerical and service staff are absent from any staff-composition reading"
effect = "misleads"
type = "coverage"
status = "mitigated"
detection = "nj-noncertificated-staff.sqlite has exactly two metric definitions, staff.noncertificated.role-fte and staff.noncertificated.total-fte. There is no race, ethnicity or sex metric at any reporting level or in any year."
misuse = "Presenting certificated staff composition as 'the district's staff', which excludes a large share of the adults a child encounters and does so invisibly."
instead = "Name the exclusion on the surface: this is the certificated part of the staff, and New Jersey collects no demographics for the rest."

[issue.scope]
all = true
```

The profile module says so in its own notes rather than in distant methodology
text, in the same paragraph block as the published-zero and non-binary notes.

### Shares on a small FTE base are arithmetic, not findings

```toml ergo
[issue]
id = "small-denominator-share-floor"
title = "Half of all district-role cells report 10.8 FTE or less, where a single hire moves a share by ten points or more"
effect = "misleads"
type = "measurement"
status = "mitigated"
detection = "Across the 16,044 district-role cells the median total FTE is 10.8; 5,848 are at or below 5.0 and 1,022 are an exact zero. In 2025-26 only 17 of 663 districts report 20 or more Supervisors/Coordinators FTE, and 37 districts report under 20 FTE of certificated staff in total."
misuse = "Printing '33% of Supervisors/Coordinators FTE' where the role is 3.0 FTE, which is one person-equivalent rendered as a statistic and, in a small district, an identification."
instead = "State an FTE floor, print the reported counts below it and no share, and say which rows were floored and why."

[issue.scope]
years = "2020-21 through 2025-26"
tables = ["staffing_certificated_district_composition"]
```

`STAFF_SHARE_FLOOR_FTE` in `tools/build_profiles.py` is that floor, in one
place. It is set to **20.0 FTE**, the level at which one full-time equivalent
moves a share by five points. It is an editorial threshold, not a publisher
rule: NJDOE publishes every one of these values, and moving the constant changes
only how much of the state gets a percentage printed beside its counts.

## Static rendering and omissions

The canonical build writes 587 district budget reports. Exactly 582 render
both staffing families; none render only one. Bass River, Chesilhurst, Sea
Isle, Seaside Park, and Washington Township (Burlington) omit the panel because
neither release has an exact district-code match. Names never provide a
fallback.

South Orange-Maplewood renders a derived certificated total of 730.2 FTE for
2025-26: 588.2 Teacher, 97.0 Special Service, 35.0 Administrators, and 10.0
Supervisors/Coordinators. It also renders the 2020-21 role rows and a +2.8 FTE
derived change. Every row links the official workbook and preserves all four
publisher row locators.

```toml ergo
[validation]
date = "2026-07-22"
method = "exact offline pin adoption, complete mart validation, statewide static build, SOMSD value UAT, and isolated rollback/reinstall"
result = "16,044 district-role rows with deterministic SHA-256 54bd0d86f40564aec6fa35f9337ee1932fcbbae2666aeda6c8fc803b14f451c2; 582 of 587 budget reports render both families and the exact five-page omission set is regression-tested"
```

## Changelog

```toml ergo
[change]
date = "2026-07-22"
note = "AQ-060 consumer page created with the exact refresh-2 pin, district-role mart receipt, two independent staffing-family boundary, exact served coverage, and issues for FTE semantics and the derived certificated district total."
issues = ["fte-is-not-headcount-or-payroll", "district-total-is-derived"]
```

```toml ergo
[change]
date = "2026-07-30"
note = "Widened the district projection from one metric to the whole district slice (16,044 to 320,880 cells) so the race and sex composition behind a district's certificated staff reaches the consumer warehouse; the three pre-existing tables and their receipts are byte-identical. Added fail-closed expectations on per-metric value states, the non-binary disclosure, and the race/sex reconciliation. Shipped the district-profile module and served this page at /data/certificated-staff/, and registered the six issues a representation surface has to get right."
issues = ["published-zero-is-not-a-suppression", "nonbinary-is-never-published", "sex-fte-does-not-reconcile-to-total", "percent-column-rounds-a-reported-fte-to-zero", "noncertificated-has-no-race-or-sex", "small-denominator-share-floor"]
```
