[quality] data/community-people.json has no validator and no contract test, so a scheduled refresh can silently empty the Community page
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 88/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- javascript, node.js
- Domain
- testing-qa
Research direction
Start with tests/.test.mjs and the existing npm run test:unit command, then inspect data/community-people.json, data/community-roster.json, docs/**/.md, and src/components/CommunityPeople/index.js to align the contract with its consumers. Done means tests/community-people-data.test.mjs validates the listed shape, sections, fields, handles, URLs, and uniqueness, and the existing unit suite passes.
Written by the indexing model from the issue text.
Description
Finding
data/community-people.json is the only generated data file in the repository with neither a validator script nor a test.
It is regenerated on a schedule by .github/workflows/refresh-community-people.yml (scripts/fetch-community-people.mjs) from data/community-roster.json plus live api.github.com responses, and is then read directly by src/components/CommunityPeople/index.js, which docs/community/end-user-community.md renders twice:
<CommunityPeople section="tab" />
<CommunityPeople section="staff" />
The component does peopleData.people[section] || [], so a section that is renamed, dropped, or emptied by a bad refresh renders an empty grid with no build error and no warning — the Community page just loses its people.
Other unguarded couplings between the generated file and the component:
imageis rendered straight into<img src={image}>. The generator falls back to''when there is no avatar and nofallbackImagesentry, which yields a broken image.github,linkedinandtwitterare interpolated unescaped intohttps://github.com/${value},https://www.linkedin.com/in/${value}andhttps://twitter.com/${value}. A handle containing/,?,#or..— these values come fromdata/community-roster.jsonand are never sanitised — produces a link to a different destination than the one it claims.blogis normalised asblog.startsWith('http') ? blog : 'https://' + blog, so a non-URL value becomes a nonsense link.key={person.name}requires names to be unique within a section.publicRepos/followersare rendered as counts and must be non-negative integers.
By contrast metrics.json, awards.json and data/architectures/ each have a scripts/validate-*.mjs run in CI, and the remaining data/*.json files have contract tests open (#234, #238, #240-cluster, #252).
Recommendation
Add a test-only contract suite, tests/community-people-data.test.mjs, asserting the committed data/community-people.json against exactly the shape its consumers rely on:
-
fetchedAtis a parseable date;peopleis a plain object - the section keys equal the section keys of
data/community-roster.json(the generator's own invariant) - every
section="..."referenced bydocs/**/*.mdexists and is non-empty, discovered by scanning the docs rather than hard-coded - per person:
namenon-empty and unique within its section;imagea non-emptyhttps://URL;bio/location/blogstrings;role/linkedin/twitter/profileUpdatedAtstring-or-null;publicRepos/followersnon-negative integers;profileUpdatedAtparseable when present -
github/linkedin/twittermatch a conservative handle pattern, so they cannot change the destination of the URLs the component builds from them -
blogis either empty or normalises to anhttp/httpsURL under the component's own rule
This needs no new production code and no workflow change — npm run test:unit (node --test) already picks up tests/*.test.mjs, and CI already runs it.
Coverage evidence
- Unit:
node --test --experimental-test-coverage, local clone ofcncf/endusersat00b44dfafternpm ci, 2026-09-17 — 55 tests pass, 0 fail. The coverage report lists onlyscripts/**andtests/helpers.mjs; no test loadsdata/community-people.json. - End-to-end: the repository defines no end-to-end or browser suite — no
playwright/cypress/puppeteer/seleniumdependency or script inpackage.json, and no such job in any of the six workflows in.github/workflows/(grep at00b44df). It also publishes no coverage artifact from any suite, tracked separately in #186, so no cross-suite coverage merge was possible. - Per the coverage-priority rule this is covered by neither unit nor end-to-end tests.
Scope
This issue claims data/community-people.json and one new file, tests/community-people-data.test.mjs. It is disjoint from #213/#214 (which cover scripts/fetch-community-people.mjs behaviour with an offline fetch stub, not the committed output) and from the data/community-roster.json contract in #240/#241 — this suite reads the roster only to compare section keys and asserts nothing about the roster's own internal shape.
Priority
- Impact: medium — a silent content regression on a published page, on an automated schedule
- Effort: low — one test-only file, no new dependency, no workflow change
Filed by quality agent (hold-gated mode)
— hive: agent=quality backend=copilot model=claude-opus-5
- Dominant language
- JavaScript
- Stars
- 0
- Forks
- 2
- Avg merge
- 2d 22h
- Merged PRs (30d)
- 12
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from cncf/endusers
-
agent/security hive/hosted-available-lke648397-260827-5n31 security
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
[scanner] PR #178 has zero linked issues — implements gov.yaml TAB integration requested by #163 Openagent/scanner bug hive/hosted-available-lke648397-260827-5n31
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
agent/scanner bug hive/hosted-available-lke648397-260827-5n31
Difficulty 1/5 Under an hour Newbie friendliness 88/100
-
agent/scanner bug hive/hosted-available-lke648397-260827-5n31
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
agent/quality hive/hosted-available-lke648397-260827-5n31 quality testing
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
HarperFast/skills#96 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
sugarlabs/musicblocks#8847 ·
-
client-controller-update ta-bot-triage team-money-movement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
MetaMask/metamask-mobile#36594 ·