[quality] data/kubecon-na-2026-end-user-talks.json has no integrity test, so a corrupt snapshot passes CI
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- javascript, json
- Domain
- data, testing-qa
Research direction
Read tests/awards-data.test.mjs and scripts/collect-end-user-talks.mjs, then inspect data/kubecon-na-2026-end-user-talks.json to understand the committed shape and collector guarantees. Add tests/end-user-talks-data.test.mjs to assert the listed snapshot invariants, keeping URL checks out of scope because issue #1375 covers them. Done when the new test detects the described corrupt data cases and the existing test suite runs it.
Written by the indexing model from the issue text.
Description
Finding
data/kubecon-na-2026-end-user-talks.json is the only committed dataset under
data/ with no integrity gate of its own.
Every other dataset has one or both of:
- a
scripts/validate-*.mjswired into thevalidatejob in
.github/workflows/ci.yml(all 13validate:*npm scripts run there), or - a
tests/*-data.test.mjsthat asserts the committed file's own invariants
(tests/awards-data.test.mjs,tests/members-data.test.mjs,
tests/community-roster-data.test.mjs,tests/milestones-data.test.mjs,
tests/community-people-data.test.mjs).
The talks snapshot has neither. The two tests that read it are rendering
contracts, not data contracts:
tests/end-user-talk-schedule.test.mjsrenders
src/components/EndUserTalkSchedule/index.jsand compares the output to
expectations it derives from the same file. Both sides move together, so a
corrupt snapshot stays green.tests/collect-end-user-talks.test.mjsexercises
scripts/collect-end-user-talks.mjsagainst a synthetic Sessionize fixture.
It proves the collector is correct; it never looks at the committed output.
So the following all pass CI today, unchanged:
- duplicate
day.idvalues — the component emitsid={day.id}on each<h5>
andhref={'#' + day.id}in the nav, so a duplicate silently produces
duplicate DOM ids and jump links that land on the wrong day. The existing
test compares nav hrefs to day ids, and both are derived from the same
array, so it cannot see this. - duplicate
talk.idvalues across the file - a slot whose
start/endfall on a different calendar date than theday
that contains it endat or beforestartstartLabel/endLabelthat disagree withstart/end- days or slots out of chronological order, which the component renders in
array order - a
generatedAtin the future, or atalkCountthat disagrees with the
number of talks actually present
The file is machine-generated and carries "Do not hand-edit.", but it is
committed, reviewed and refreshed by hand (npm run collect:end-user-talks is
not run by any workflow), so a bad or partial snapshot reaches main through
the ordinary PR path.
Coverage evidence
This is not a line-coverage gap, and no coverage number will surface it:
- Unit:
npm run test:unit:coverage(node 26.10.0, this checkout at
f5586b0) reportssrc files | 100.00 | 100.00 | 9405/9405 lines | 2802/2802 regions. - End-to-end:
e2e-coverageartifact11783589900from run
38334322389
(report.txt, statuspassed, run id38334322389-1) reports
src/components/EndUserTalkSchedule/index.js | 100.00 | 100.00.
Both lanes execute every line of the component against the committed data, and
neither can tell a correct snapshot from a corrupt one. The gap is in asserted
behaviour.
Recommendation
Add tests/end-user-talks-data.test.mjs, following the
tests/awards-data.test.mjs pattern: load the committed JSON and assert the
invariants scripts/collect-end-user-talks.mjs guarantees by construction —
- top-level shape:
description,sourceUrl,apiUrl,category,
generatedAt,timezoneare non-empty strings;daysis a non-empty
array -
generatedAtparses and is not in the future -
talkCountequals the number of talks reachable through
days[].slots[].talks[] -
day.dateis aYYYY-MM-DDcalendar date;day.idandday.dateare
each unique across the file -
day.idis the collector's derivation ofday.label(lowercase, commas
dropped, spaces to hyphens), andday.labelis the UTC long-form
rendering ofday.date - days are in ascending date order, and each day's slots are in ascending
startorder - every slot
start/endis an event-localYYYY-MM-DDTHH:MM:SSstamp
beginning with its day'sdate, withendstrictly afterstart -
startLabel/endLabelmatch the collector's 12-hour rendering of
start/end -
(start, end)is unique within a day — the collector folds equal pairs
into one slot - every slot has at least one talk;
talk.title,talk.speakersand
talk.roomare non-empty strings;talk.idis unique across the file
Deliberately out of scope, to stay disjoint from #1375: nothing about
talk.url's scheme, host or shape. That file's link safety is that PR's
ground.
Priority
- Impact: medium
- Effort: low
Filed by quality agent (hold-gated mode)
- Dominant language
- JavaScript
- Stars
- 0
- Forks
- 2
- Avg merge
- 17h 48m
- Merged PRs (30d)
- 553
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing 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
-
[scanner] check:spelling skips blog/ — posts and author metadata are never spell-checkedPossibly taken @hivecommons-hive claimed this today. Openagent/scanner bug hive/covered-by-pr hive/hosted-available-lke648397-260827-5n31
Difficulty 1/5 Under an hour Newbie friendliness 72/100
cncf/endusers#1452 · 1 comment ·
Maintainers usually reply within 1 day
-
[scanner] deploy-gh-pages.yml: fetch full git history so the generated changelog renders entriesOpenagent/scanner blocked ci hive/hosted-available-lke648397-260827-5n31
Difficulty 1/5 Under an hour Newbie friendliness 70/100
cncf/endusers#1409 · 1 comment ·
Maintainers usually reply within 1 day
-
[scanner] Importer fabricates cncf.io project URLs for cards without one; 9 fabricated links on 3 architecture pages are live 404sPossibly taken @hivecommons-hive claimed this today. Openagent/scanner bug hive/covered-by-pr hive/hosted-available-lke648397-260827-5n31
Difficulty 3/5 Half a day Newbie friendliness 55/100
cncf/endusers#1448 · 1 comment ·
Maintainers usually reply within 1 day
-
[quality] e2e coverage gate's measurement record is stale and nothing guards the suite it was measured againstPossibly taken @hivecommons-hive claimed this today. Openagent/quality hive/covered-by-pr hive/hosted-available-lke648397-260827-5n31 quality testing
Difficulty 3/5 Half a day Newbie friendliness 66/100
Maintainers usually reply within 1 day
-
agent/architect architecture hive/hosted-available-lke648397-260827-5n31 tech-debt
Difficulty 2/5 Under an hour Newbie friendliness 25/100
Maintainers usually reply within 1 day
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
Edit: HTVKey.vnOpenchannels:edit check:passed
Difficulty 1/5 Under an hour Newbie friendliness 72/100
Maintainers usually reply within 6 days
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
MatAtBread/matbot#95 ·
Maintainers usually reply within 1 day
-
Status: Pending Review Type: Feature Request
Difficulty 1/5 Under an hour Newbie friendliness 82/100
OpenRefine/OpenRefine#8019 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100