ci: check cohort counts against the roster - #40
Merged
Conversation
This repository has published a wrong cohort size twice. The Fall 2025 card read seven when the roster should have held eight, because Pegi Bracaj had never been added. The README read "eight applied researchers" against a Summer 2026 roster of seven. Neither was catchable. The head-count is written by hand in four places - the roster itself, team.researchersCount, the cohorts card, and the README - and nothing forced them to agree. Every wrong value is a valid string, so the build and the linter were always going to pass. Adds scripts/check-content-invariants.mjs, run in CI as `npm run check:content`. It imports the real site.ts exports rather than parsing text (Node 24 strips the types natively, and the module has no imports of its own) and asserts: - each cohort card's "N researchers" matches the roster for that term; - team.researchersCount matches the current cohort; - the README's prose count matches the current cohort; - no two people share a /team/[slug]. Verified against four seeded faults - a wrong README number word, a stale cohort card, a researcher moved between terms, and two people sharing a slug - each failing with a message naming the file and both numbers. The current tree passes. The CI job name is deliberately unchanged: it is the context the branch ruleset requires, so renaming it would silently detach the gate. Partially closes UPD-008. Route reachability, base-path asset references, and publication anchors are still uncovered. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Partially closes UPD-008.
Why
This repository has published a wrong cohort size twice:
Neither was catchable. The head-count is written by hand in four places — the roster itself, eam.researchersCount, the cohorts card, and README.md — and nothing forced them to agree. Every wrong value is a perfectly valid string, so the build and the linter were always going to pass.
That matters more than an off-by-one suggests. When prose and data disagree, there is no way to tell from inside the repository which one is wrong — whether someone typo'd the number, or whether a real person is missing from the roster. The two have opposite fixes, and one of them quietly erases a researcher from the public site.
What
scripts/check-content-invariants.mjs, run in CI asnpm run check:content. It imports the realsite.tsexports rather than parsing text — Node 24 strips the types natively, and the module has no imports of its own — and asserts:"N researchers"matches the roster for that term;team.researchersCountmatches the current cohort;/team/[slug].Verification
Seeded four faults; each fails with a message naming the file and both numbers:
researchersCountClean tree passes:
Content invariants OK (3 cohorts, 23 researcher records). Current counts audited and all correct — Summer 2026: 7, Fall 2025: 8, Spring 2025: 8.Also green on this branch:
eslint0,tsc --noEmit0,sync:staticleaves the snapshot in sync.One thing reviewers should know
The CI job name is deliberately unchanged.
Lint, typecheck, build, snapshotis the exact context the branch ruleset requires. Renaming it to mention the new step would silently detach the gate — the required check would never report, and merges would hang. The step was added inside the existing job instead.