# 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 = "The record runs twenty-seven editions and breaks three times inside it, so no series may be drawn straight across it and an empty-looking demographic cell is almost always an exact published zero rather than a suppression."
status = "live"
confidence = "A"
updated = "2026-08-03"
implementation = "https://github.com/lavallee/njschooldata"

[dataset.coverage]
years = "1999-2000 through 2025-26"
grain = "school year x district x certificated role x metric"
entities = "27 editions; 17,773 district-year rows and 51,773 district-year-role rows across the whole record, plus 16,044 district-role rows and 320,880 district composition cells in the six modern-vocabulary editions; 661 of 738 rendered district profiles carry the published record"

[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 recovery through retained pins.

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 the certificated, non-certificated, and
archive pins before it builds a fresh staffing-family candidate. It projects
the owned modern marts and full history, validates the complete artifact
populations and exact owned-table set, and atomically replaces the family file.

| 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 `njschooldata_web/profile_domain.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"]
```

```toml ergo
[change]
date = "2026-08-01"
note = "Moved the certificated pin to nj-certificated-staff-aq060-2019-20-move and added a second exact pin on nj-certificated-staff-archive-2019-20-move, widening the consumer record from six editions to the whole published twenty-seven, 1999-2000 through 2025-26. Projected an edition register carrying each edition's counting unit, race vocabulary, total basis and role-split state, plus a per-district series and a per-district-role series; the four pre-existing marts and their receipts are byte-identical, and the two certificated ones are deliberately still scoped to 2020-21 onward because that is where the column vocabulary breaks. Shipped the twenty-seven-year band on district profiles with the total drawn in three stretches, the race composition drawn in three different stretches, and the role mix stated as not renderable rather than drawn. Registered the seven issues the whole record needs."
issues = ["headcount-becomes-fte", "race-vocabulary-changes-three-times", "role-split-is-absent-from-2016-17", "2005-06-position-split", "identity-spine-is-a-current-snapshot", "staff-counted-on-one-october-day", "special-services-is-spelled-two-ways"]
```
