You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
data/members.json is the largest committed data file (17 organisations, ~21 KB) and the sole input to src/components/MemberDirectory/index.js, but nothing validates it: there is no validate:members script in package.json and no test file references it.
MemberDirectory dereferences the entry arrays with no guards:
The file is generated by scripts/generate-members.mjs from data/architectures/catalog.json and data/awards.json. If a regeneration drops one of those arrays from an entry, the Docusaurus production build crashes; if it emits a logo path with no file behind it, the member directory renders a broken image. Neither failure is caught before deploy.
Sibling data files already have (or are getting) contract tests — data/milestones.json (#234), data/projects-born.json (#238), data/community-roster.json (#240). data/members.json is the remaining unvalidated one.
Coverage evidence
Unit: node --test --experimental-test-coverage at main00b44df — 55 tests pass. The coverage table lists only scripts/lib/validate-utils.mjs, scripts/validate-{architecture-assets,architectures,awards,button-contrast,metrics}.mjs and tests/helpers.mjs. data/members.json appears in no test. Zero unit coverage.
End-to-end: the repository has no end-to-end or browser suite — no Playwright/Cypress config, dependency or job (matches in package-lock.json are transitive only), and none of the six workflows in .github/workflows/ runs one. No end-to-end coverage exists to measure.
Limitation: the two sources cannot be merged at statement granularity because only one exists. The closest end-to-end signal is the Docusaurus production build in deploy-gh-pages.yml, which would fail on a crash-inducing entry but is not a test and emits no coverage data — tracked separately by [quality] CI publishes no coverage evidence, so coverage findings cannot be verified #186.
Recommendation
Add tests/members-data.test.mjs asserting the contract that MemberDirectory and the generator depend on:
Envelope keys (description, generatedFrom, schema) present, and generatedFrom still names data/architectures/catalog.json and data/awards.json
Every member carries industries, projects, architectures, awards and sourceAttribution as arrays (the unguarded dereferences above)
id/slug are unique kebab-case and equal to each other, so profile links resolve
Members stay sorted by display name, matching generator output
Every logo, when set, is a /img/ path whose file exists under static/ (the check validate-awards.mjs already performs for awards.json)
Nested architecture entries carry id, title, an https sourceUrl and a 40-hex sourceCommit
Nested award entries carry year, award, awardLabel, citation, event, with https URLs where present
Cross-file parity: every awards.json winner slug has a matching member id, and every member award matches an awards.json entry
Note that parity must key on slug, not display name: awards.json lists Mercedes-Benz Tech Innovation while the member entry's display name is Mercedes-Benz, and both share the slug mercedes-benz-tech-innovation.
Priority
Impact: high — an unguarded regeneration breaks the production build or ships broken logos
Effort: low — data-only assertions, no new test infrastructure
Finding
data/members.jsonis the largest committed data file (17 organisations, ~21 KB) and the sole input tosrc/components/MemberDirectory/index.js, but nothing validates it: there is novalidate:membersscript inpackage.jsonand no test file references it.MemberDirectorydereferences the entry arrays with no guards:The file is generated by
scripts/generate-members.mjsfromdata/architectures/catalog.jsonanddata/awards.json. If a regeneration drops one of those arrays from an entry, the Docusaurus production build crashes; if it emits a logo path with no file behind it, the member directory renders a broken image. Neither failure is caught before deploy.Sibling data files already have (or are getting) contract tests —
data/milestones.json(#234),data/projects-born.json(#238),data/community-roster.json(#240).data/members.jsonis the remaining unvalidated one.Coverage evidence
node --test --experimental-test-coverageatmain00b44df— 55 tests pass. The coverage table lists onlyscripts/lib/validate-utils.mjs,scripts/validate-{architecture-assets,architectures,awards,button-contrast,metrics}.mjsandtests/helpers.mjs.data/members.jsonappears in no test. Zero unit coverage.package-lock.jsonare transitive only), and none of the six workflows in.github/workflows/runs one. No end-to-end coverage exists to measure.deploy-gh-pages.yml, which would fail on a crash-inducing entry but is not a test and emits no coverage data — tracked separately by [quality] CI publishes no coverage evidence, so coverage findings cannot be verified #186.Recommendation
Add
tests/members-data.test.mjsasserting the contract thatMemberDirectoryand the generator depend on:description,generatedFrom,schema) present, andgeneratedFromstill namesdata/architectures/catalog.jsonanddata/awards.jsonindustries,projects,architectures,awardsandsourceAttributionas arrays (the unguarded dereferences above)id/slugare unique kebab-case and equal to each other, so profile links resolvelogo, when set, is a/img/path whose file exists understatic/(the checkvalidate-awards.mjsalready performs forawards.json)id,title, an httpssourceUrland a 40-hexsourceCommityear,award,awardLabel,citation,event, with https URLs where presentawards.jsonwinner slug has a matching memberid, and every member award matches anawards.jsonentryNote that parity must key on slug, not display name:
awards.jsonlistsMercedes-Benz Tech Innovationwhile the member entry's display name isMercedes-Benz, and both share the slugmercedes-benz-tech-innovation.Priority
Filed by quality agent (hold-gated mode)
— hive: agent=quality backend=copilot model=claude-opus-5