Test evidence

Stratified survival

Every requirement of this module, the tests named for it, and what each test recorded the last time the evidence was rebuilt.

Summary

Requirements
38
Tests named for them
38 (14 unit, 24 browser)
Result
pass every test passing
Screenshots
7
Recorded
2026-10-04 19:02 UTC
Environment
linux 6.17.0-1022-azure · node v22.23.3 · playwright 1.61.1 · chromium 149.0.7827.55
Test run
Continuous-integration run 37226711557

The requirements are the rows of the module’s requirement matrix. A test is named for a requirement by starting its name with the requirement’s ID. The results are read from the committed evidence set; continuous integration reruns every test and fails when the committed set no longer matches.

Requirements and their tests

  1. SS-KIT-001 pass

    The chart is built from safety.viz's kit on the page: its curves are the kit's kmEstimate, the descriptive product-limit estimate, drawn with the kit's Chart.js, bundling neither; without safety.viz on the page it is refused with a message saying what is missing.

    • pass browser SS-KIT-001: the chart is built from safety.viz’s kit on the page, its curves the kit’s kmEstimate drawn with the kit’s Chart.js; without safety.viz it says what is missing (#61)
  2. SS-KIT-002 pass

    The chart reads no band of the kit's estimate: nothing of its source reads the lower or upper bound or the standard error that kmEstimate also returns.

    • pass unit stratified survival: what the chart reads of the kit SS-KIT-002: the chart reads no band of the kit’s estimate: nothing of its source reads the lower or upper bound or the standard error that kmEstimate also returns (#61)
  3. SS-CFG-001 pass

    Every setting has a default; the outcomes table is read by its endpoint, time and one flag, censored (ADaM's CNSR) or event, exactly one named; the groups are a column or a cut variable; a setting that is not known, or a value it cannot take, is refused with a sentence naming it.

    • pass unit stratified survival: settings SS-CFG-001: every setting has a default; the outcomes table is read by its time and one flag, censored or event, never both; the groups are a column or a cut variable (#61)
  4. SS-DATA-001 pass

    Each participant drawn is in desktop R's group, with R's time and event, for every case: the study by CRP cut at its median, at 4, at its tertiles and at 10, by arm, the women alone, a table flagged by event, and one where an arm has no event.

    • pass unit stratified survival: who is drawn, and each curve SS-DATA-001: each participant drawn is in desktop R’s group, with R’s time and event, for every case (#61)
  5. SS-DATA-002 pass

    The outcomes table is read either way round: a flag of events gives the same participants, groups and curves as ADaM's CNSR, and the flag goes to R as the table gives it.

    • pass unit stratified survival: who is drawn, and each curve SS-DATA-002: the outcomes table is read either way round: a flag of events gives the same participants, groups and curves as ADaM’s CNSR (#61)
  6. SS-DATA-003 pass

    A participant with a group and no usable outcome is left out and counted by reason: no row for the endpoint, more than one, a time or flag missing or not a number, a flag that is not 0 or 1, a time below 0; a logical flag is read as R reads one; an outcome row for no such participant is not used, and counted.

    • pass unit stratified survival: who is drawn, and each curve SS-DATA-003: a participant with a group and no usable outcome is left out and counted by reason: no row, more than one, a time or flag that is missing or not a number, a flag that is not 0 or 1, a time below 0 (#61)
  7. SS-CURVE-001 pass

    Each group's curve is the kit's kmEstimate, and its steps are R's survfit() estimate: the same event times, numbers at risk, events and survival (to 12 decimal places), and the same censored times.

    • pass unit stratified survival: who is drawn, and each curve SS-CURVE-001: each group’s curve is safety.viz’s kmEstimate, and its steps are R’s survfit() estimate: the same event times, numbers at risk, events and survival, and the same censored times (#61)
  8. SS-RISK-001 pass

    The at-risk strip counts, at each time of the axis, the participants of a group whose time is at or after it, and a cell lists those participants, the ones R's data hold there.

    • pass unit stratified survival: who is drawn, and each curve SS-RISK-001: the at-risk strip counts, at each time of the axis, the participants of a group whose time is at or after it, and those are the ones a cell lists (#61)
  9. SS-RISK-002 pass

    On the page, the at-risk strip's counts at each time are R's numbers at risk for each group.

    • pass browser SS-RISK-002: the at-risk strip counts, at each time of the axis, the participants of each group whose time is at or after it, as R’s survfit() counts them at risk (#61)
  10. SS-CUT-001 pass

    For a cut variable the histogram holds every value the points were worked out on, and a cut line dropped becomes a typed point as its label writes it, four significant digits; a line cannot pass its neighbour, stop where two points are written alike, or leave the values it cuts.

    • pass unit stratified survival: who is drawn, and each curve SS-CUT-001: for a cut variable the histogram holds every value the points were worked out on, and a cut line dropped becomes a typed point as its label writes it (#61)
  11. SS-HIST-001 pass

    On the page, the histogram shows the values the cut points were worked out on, with a line at each point and how many values fall in each group.

    • pass browser SS-HIST-001: for a cut biomarker the histogram shows the values the points were worked out on, with a line at each point and how many values fall in each group (#61)
  12. SS-DRAW-001 pass

    Event-free survival by CRP at Baseline cut at its median: each group's curve is R's survfit() estimate step for step with its censored times marked, the legend gives each group's count, and high CRP has the worse survival, as the study was planted.

    • pass browser SS-DRAW-001: event-free survival by CRP at Baseline cut at its median: each group’s curve is R’s survfit() estimate, step for step, with its censored times marked, and high CRP has the worse survival, as the study was planted (#61)
    Screenshot captured by a test of SS-DRAW-001: as the gallery shows itScreenshot captured by a test of SS-DRAW-001: crp median
  13. SS-DRAW-002 pass

    Groups from a column are drawn by name and a cut at its tertiles makes three curves, low to high, each R's; a column has no histogram.

    • pass browser SS-DRAW-002: groups from a column are drawn by name, and a cut at its tertiles makes three curves, low to high, each R’s; a column has no histogram (#61)
  14. SS-DRAG-001 pass

    Dragging the cut line moves the curves at once and asks R nothing, and the line says R is asked when it is let go; letting it go makes the cut a typed point as its label writes it, held by the Groups control, and asks R once.

    • pass browser SS-DRAG-001: dragging the cut line moves the curves at once and asks R nothing; letting it go makes the cut a typed point, as its label writes it, held by the Groups control, and asks R once (#61)
  15. SS-DRAG-002 pass

    Dropped at 4, R's stored answer for the cut at 4 is found and printed, and the curves are R's for that cut; the left and right arrow keys move the line too.

    • pass browser SS-DRAG-002: dropped at 4, R’s stored answer for the cut at 4 is found and printed: its log-rank test, its medians and its hazard ratio; the arrow keys move the line too (#61)
  16. SS-DRAG-003 pass

    An answer asked for before the line was taken hold of is never shown: the line waits for the answer to the cut it is let go at.

    • pass browser SS-DRAG-003: an answer asked for before the line was taken hold of is never shown: the line waits for the cut it is let go at (#61)
  17. SS-DRAG-004 pass

    A click on a cut line, with no drag, leaves it where it is and asks R nothing; a drag moves it by as much as the pointer moves, from where it took hold.

    • pass browser SS-DRAG-004: a click on a cut line, with no drag, leaves it where it is and asks R nothing; a drag moves it by as much as the pointer moves, from where it took hold (#61)
  18. SS-DRAG-005 pass

    Each cut line is a slider of its own, with its value and how far it can go; its arrow keys move it, the curves at once and R once the keys rest; it stops at its neighbours and inside the values.

    • pass browser SS-DRAG-005: each cut line is a slider of its own: at the tertiles the second line takes the focus and its arrows move it, the curves at once, R once the keys rest; it stops at its neighbours and inside the values (#61)
  19. SS-STAT-001 pass

    R is asked once per view, with one row per participant drawn, and the function, the arguments, the identity and the row count that desktop R's recipe writes; a cut's groups go high to low, so the hazard ratio is the higher group's over the lower's, and a column's by code point; the flag goes under the name the table reads it by.

    • pass unit stratified survival: what R is asked, and what the line says SS-STAT-001: R is asked once per view, with one row per participant drawn, and the function, the arguments, the identity and the row count desktop R’s recipe writes; the flag goes under the name the table reads it by (#61)
  20. SS-STAT-002 pass

    Handed to a connection as stored results, each of R's answers is found by the chart's request for its view.

    • pass unit stratified survival: what R is asked, and what the line says SS-STAT-002: handed to a connection as stored results, each of R’s answers is found by the chart’s request for its view (#61)
  21. SS-STAT-003 pass

    R's log-rank test is printed with its method and counts, labelled exploratory and unadjusted; each group's median with its log-log interval, in the legend's order, a median or bound R did not reach reading not reached; and, for two groups, the hazard ratio with its interval, a cut's named high over low.

    • pass unit stratified survival: what R is asked, and what the line says SS-STAT-003: R’s log-rank test is printed with its method and counts, each group’s median with its log-log interval, a median R did not reach as not reached, and, for two groups, the hazard ratio with its interval (#61)
  22. SS-STAT-004 pass

    A hazard ratio R does not estimate is not printed, and R's note says why, as R wrote it (gsm.bio#26).

    • pass unit stratified survival: what R is asked, and what the line says SS-STAT-004: a hazard ratio R does not estimate is not printed, and R’s note says why, as R wrote it (#61)
  23. SS-STAT-005 pass

    A group below R's minimum size prints R's reason and counts, and no number.

    • pass unit stratified survival: what R is asked, and what the line says SS-STAT-005: a group below R’s minimum size prints R’s reason and counts, and no number (#61)
  24. SS-STAT-006 pass

    With no R attached the line says statistics are unavailable, the curves are still drawn, and nothing is fetched.

    • pass browser SS-STAT-006: with no R attached the line says statistics are unavailable, the curves are still drawn, and nothing is fetched (#61)
  25. SS-STAT-007 pass

    R's answers stored in the page are found and printed for the women alone, with the filter said, and for a column; a group below R's minimum size prints R's reason.

    • pass browser SS-STAT-007: R’s answers stored in the page are found for the women alone and for a column, and a group below R’s minimum size prints R’s reason (#61)
  26. SS-STAT-008 pass

    On the page, where R does not estimate the hazard ratio it is not printed, and R's note says why.

    • pass browser SS-STAT-008: where R does not estimate the hazard ratio, it is not printed, and R’s note says why (#61)
    Screenshot captured by a test of SS-STAT-008: hazard ratio not estimable
  27. SS-STAT-009 pass

    Once the connection is replaced, a late answer from the old one changes neither the line nor what chart.statistics() reports.

    • pass browser SS-STAT-009: once the connection is replaced, a late answer from the old one changes neither the line nor what chart.statistics() reports (#61)
  28. SS-STAT-010 pass

    Where some participants have a value and no outcome, a cut's points are worked out on those drawn, as R's Analyze_Screen takes its median: the cut, each group's count and R's answer are desktop R's, and the footnote says who is cut.

    • pass browser SS-STAT-010: where some participants have a value and no outcome, the median is the median of those drawn, as R’s Analyze_Screen takes it: the cut, each group’s count and R’s answer are the ones desktop R gives (#61)
  29. SS-NEED-001 pass

    Loaded without an outcomes table, the chart says it needs one, draws nothing and keeps its controls; given one, it draws; an outcomes table without a column a setting names is refused by name.

    • pass browser SS-NEED-001: loaded without an outcomes table, the chart says it needs one, draws nothing and keeps its controls (#61)
  30. SS-EVENT-001 pass

    An outcomes table flagged by event is read the other way round on the page: the same curves, and R is asked with strEventCol and finds its answer; event_col named alone later, through setSettings or setData, reads it so too.

    • pass browser SS-EVENT-001: an outcomes table flagged by event, 1 for an event, is read the other way round: the same curves, and R is asked with strEventCol and finds its answer (#61)
  31. SS-LIST-001 pass

    A click on a curve lists its group's participants, and a count of the at-risk strip those it counts, the ones R puts there; a click away from every curve lists nothing, and the legend hides nothing; a row opens safety.viz's participant profile of that participant.

    • pass browser SS-LIST-001: a click on a curve lists its group’s participants, and a count of the at-risk strip those it counts, the ones R puts there; a row opens that participant’s profile (#61)
    Screenshot captured by a test of SS-LIST-001: participants at risk
  32. SS-FAIL-001 pass

    When drawing fails the chart says so in its element and keeps its controls, leaving nothing half drawn, and draws again once it can.

    • pass browser SS-FAIL-001: when drawing fails the chart says so in its element and keeps its controls, leaving nothing half drawn, and draws again once it can (#61)
  33. SS-MOBILE-001 pass

    At 390 pixels the controls are folded away, the at-risk strip fits or scrolls inside its own box, and the page does not scroll sideways.

    • pass browser SS-MOBILE-001: at 390px the controls are folded away, the at-risk strip fits or scrolls inside its own box, and the page does not scroll sideways (#61)
    Screenshot captured by a test of SS-MOBILE-001: the curves on a phone
  34. SS-SITE-001 pass

    The live demo holds at a 390-pixel-wide viewport with no horizontal scroll, with the controls open; each count of the at-risk strip stays on one line, the strip scrolling in its own box.

    • pass browser SS-SITE-001: the live demo holds at a 390px-wide viewport with no horizontal scroll, with the controls open (#61)
    Screenshot captured by a test of SS-SITE-001: demo on a phone
  35. SS-SITE-002 pass

    The gallery lists the chart with links to its live demo, its evidence page and its API reference; the demo opens on event-free survival by CRP at Baseline cut at its median, and draws the curves where R cannot be reached and says so.

    • pass browser SS-SITE-002: the gallery lists the chart with links to its live demo, its evidence page and its API reference, and the demo opens on event-free survival by CRP at Baseline cut at its median (#61)
  36. SS-SITE-003 pass

    The API reference has a table row for every setting the chart has, with the default the code has; the site build fails when one is missing.

    • pass unit stratified survival: the API reference SS-SITE-003: the reference names every setting the chart has, with its default, and a setting it leaves out is a problem (#61)
  37. SS-LIVE-001 pass

    Against R and the survival package started in the browser on the demo: the log-rank p, each median with its interval and the hazard ratio with its interval equal desktop R's within 1 part in 10^8, before and after the cut line is moved to 4.

    • pass browser SS-LIVE-001: with R and the survival package started in this browser, the log-rank p, each median with its interval and the hazard ratio with its interval are desktop R’s, before and after the cut line is moved to 4 (#61)
    Screenshot captured by a test of SS-LIVE-001: r in the browser
  38. SS-LIVE-002 pass

    Against R in the browser: by arm, a column, equals desktop R's.

    • pass browser SS-LIVE-002: by arm, a column, R in the browser is desktop R’s (#61)

Tests run with every module

92 tests of the site, the evidence pipeline and the repository’s own checks

These are recorded in every module’s evidence set. A requirement ID one of them carries belongs to another module’s page.

  • pass browser CORE-SITE-001: the home page names the library and its version, and shows the version its bundle reports (#1)
  • pass browser CORE-SITE-002: the home page holds at a 390px-wide viewport with no horizontal scroll (#1)
  • pass browser CORE-SITE-003: the gallery is reached from the home page and lists the published charts, or says that none is published yet (#7)
  • pass browser CORE-SITE-004: the gallery lists each shared part, and its two links lead to that module’s evidence page and API reference (#7)
  • pass browser CORE-SITE-006: every module has an evidence page that lists each requirement of its matrix (#7)
  • pass browser CORE-SITE-006: the connection to R’s evidence page lists every RCON- and PVAL- requirement with the tests that prove it (#7)
  • pass browser CORE-SITE-007: a screenshot a test captured is shown under its requirement on the evidence page (#7)
  • pass browser CORE-SITE-009: every module has an API reference page that documents each name it exports (#7)
  • pass browser CORE-SITE-009: the connection to R’s API reference documents createConnection and formatStatistic (#7)
  • pass browser CORE-SITE-012: the gallery holds at a 390px-wide viewport with no horizontal scroll (#7)
  • pass browser CORE-SITE-013: each module’s evidence page holds at a 390px-wide viewport with no horizontal scroll (#7)
  • pass browser CORE-SITE-014: each module’s API reference holds at a 390px-wide viewport, with its tables restacked (#7)
  • pass browser CORE-SITE-015: the site serves the synthetic study, and the gallery gives its row counts and the commit it was copied from (#7)
  • pass unit API reference page CORE-SITE-009: a link to another reference file goes to that module’s page, and the page names the file it was rendered from (#7)
  • pass unit API reference page CORE-SITE-009: the page is the reference file, rendered: its title, sections, tables and code (#7)
  • pass unit API reference page CORE-SITE-009: the sections are listed at the top, each linked to its place on the page (#7)
  • pass unit API reference: held to the code CORE-MAN-006: an export listed as data is documented as one, under one heading, and its fields are not held one by one (#32)
  • pass unit API reference: held to the code CORE-SITE-010: a constant whose value the reference does not give is a problem (#7)
  • pass unit API reference: held to the code CORE-SITE-010: a function the reference documents that the bundle does not export is a problem (#7)
  • pass unit API reference: held to the code CORE-SITE-010: a namespace in the surface stands for each of its members, and a constant carries its value (#7)
  • pass unit API reference: held to the code CORE-SITE-010: a parameter the source documents and the reference leaves out is a problem (#7)
  • pass unit API reference: held to the code CORE-SITE-010: a reference that documents every export, parameter and constant has no problems (#7)
  • pass unit API reference: held to the code CORE-SITE-010: an export no module claims, a surface the bundle lacks and an empty surface are each a problem (#7)
  • pass unit API reference: held to the code CORE-SITE-010: an export with no heading in the reference is a problem (#7)
  • pass unit API reference: held to the code CORE-SITE-010: the committed references document everything the committed bundle exports (#7)
  • pass unit API reference: held to the code CORE-SITE-010: the connection’s reference is held to the parameters its source documents (#7)
  • pass unit API reference: held to the code GC-SITE-004: a chart’s reference names every setting the chart has, and a setting it leaves out is a problem (#9)
  • pass unit evidence normalizer buildEvidenceSets splits records per module and duplicates shared scaffold records (#1)
  • pass unit evidence normalizer buildRun builds GitHub Actions run provenance from the environment (#1)
  • pass unit evidence normalizer compareEvidence flags status drift and test-set changes, ignoring screenshots (#1)
  • pass unit evidence normalizer compareEvidence ignores provenance so --check never drifts on generatedAt/environment/run (#1)
  • pass unit evidence normalizer CORE-SITE-011: a requirement row with no test named for it is reported (#7)
  • pass unit evidence normalizer CORE-SITE-011: a test that names a requirement in no matrix is reported with the test (#7)
  • pass unit evidence normalizer moduleForFile routes test files to modules by path (#1)
  • pass unit evidence normalizer normalizePlaywright walks nested suites into browser-suite records (#1)
  • pass unit evidence normalizer normalizeVitest maps assertion results to unit-suite records (#1)
  • pass unit evidence normalizer parseTestName extracts requirement IDs and issue refs (#1)
  • pass unit evidence normalizer parseTestName recognizes any requirement-ID prefix, not just SH (#1)
  • pass unit evidence normalizer provenance lives in dedicated top-level keys; the records array stays timestamp-free (#1)
  • pass unit evidence page CORE-SITE-006: a requirement with no test says so, and the summary counts it (#7)
  • pass unit evidence page CORE-SITE-006: each requirement shows the tests named for it, unit or browser, with the result each recorded (#7)
  • pass unit evidence page CORE-SITE-006: every requirement is listed in the matrix’s order with its text (#7)
  • pass unit evidence page CORE-SITE-006: tests that carry none of the module’s requirements are listed apart, as run with every module (#7)
  • pass unit evidence page CORE-SITE-006: with every requirement tested and passing the summary says every test is passing (#7)
  • pass unit evidence page CORE-SITE-007: a screenshot is shown under the requirement it was captured for, and only there (#7)
  • pass unit evidence page CORE-SITE-007: the build is told of a screenshot the evidence names that is not committed (#7)
  • pass unit evidence page CORE-SITE-008: results recorded on a developer’s machine say so, and absent provenance is not invented (#7)
  • pass unit evidence page CORE-SITE-008: the page says when and where the results were recorded and links the run (#7)
  • pass unit evidence page the page links the module’s requirement matrix and its committed evidence set (#7)
  • pass unit gallery CORE-SITE-003: a chart that is registered but not yet available is not listed as published (#7)
  • pass unit gallery CORE-SITE-003: a chart’s card shows its picture once that screenshot is committed, and no picture before (#9)
  • pass unit gallery CORE-SITE-003: a registered chart is listed under Charts with links to its evidence page and API reference (#7)
  • pass unit gallery CORE-SITE-003: with no chart registered the gallery says that no chart is published yet (#7)
  • pass unit gallery CORE-SITE-004: each shared part is listed with links to its evidence page and API reference (#7)
  • pass unit gallery CORE-SITE-004: the registry as committed lists the core and the connection to R as shared parts (#7)
  • pass unit gallery CORE-SITE-015: the gallery says what each table of the synthetic study holds, its rows, and the commit it was copied from (#7)
  • pass unit gallery the home page heads its callout for one chart and for several (#26)
  • pass unit gallery the home page links each module’s evidence page and API reference, and the gallery (#7)
  • pass unit gallery the home page says there are no charts yet only while none is published (#9)
  • pass unit markdown: blocks a relative link points at the repository, and a link to another reference file at its page (#7)
  • pass unit markdown: blocks CORE-SITE-009: a fenced block is code, escaped and left as written, and a # inside it is not a heading (#7)
  • pass unit markdown: blocks CORE-SITE-009: a table keeps each column heading on every cell, so it can restack on a narrow screen (#7)
  • pass unit markdown: blocks CORE-SITE-009: headings get the anchors GitHub gives them, repeated ones numbered (#7)
  • pass unit markdown: blocks CORE-SITE-009: paragraphs join their lines, and bullet and numbered lists keep theirs apart (#7)
  • pass unit markdown: inline keeps a code span inside a link label, and links a bare address in angle brackets (#7)
  • pass unit markdown: inline mdText strips the marks and keeps the words (#7)
  • pass unit markdown: inline reads nothing inside a code span as a link or as emphasis (#7)
  • pass unit markdown: inline renders code, links, bold and italic, and escapes everything else (#7)
  • pass unit module registry CORE-SITE-005: an entry that does not say whether it is a chart or a shared part is refused (#7)
  • pass unit module registry CORE-SITE-005: an entry without its matrix or its API reference is refused, as is a name registered twice (#7)
  • pass unit module registry CORE-SITE-005: the registry as committed is well formed (#7)
  • pass unit R check page RCON-PAGE-001: the page has a button that starts R, the stated tolerance and the versions desktop R used (#3)
  • pass unit R check page RCON-PAGE-002: the recorded megabytes, requests and seconds are shown for cold, reload and warm, with how they were measured (#3)
  • pass unit R check page RCON-PAGE-003: with no recorded measurement the page says so and prints no number in its place (#3)
  • pass unit repo hygiene no source or test file carries a machine-specific absolute path (#1)
  • pass unit requirements-lib: freshness guard flags added and removed requirement IDs (#1)
  • pass unit requirements-lib: freshness guard flags changed requirement text (#1)
  • pass unit requirements-lib: freshness guard reports fresh when the committed set matches a fresh extraction (#1)
  • pass unit requirements-lib: matrix parsing ignores the header, separator, and non-requirement content (#1)
  • pass unit requirements-lib: matrix parsing keeps an escaped pipe inside a requirement cell as a single row (#1)
  • pass unit requirements-lib: matrix parsing maps each requirement ID to its reviewed text (#1)
  • pass unit requirements-lib: requirement set wraps the parsed map with module + matrix provenance (#1)
  • pass unit requirements-lib: unregistered matrices passes when every matrix file is registered, ignoring the README and non-markdown files (#1)
  • pass unit requirements-lib: unregistered matrices reports a matrix file no module in site/config.json names (#1)
  • pass unit site pages CORE-SITE-001: the home page names the library and its version (#1)
  • pass unit site pages escapeHtml escapes the five HTML-significant characters (#1)
  • pass unit site pages renderShell fills title, description, version and root, and leaves no token behind (#1)
  • pass unit site pages summarizeModule counts requirement rows and passing test records (#1)
  • pass unit site pages the home page links to the R check page (#3)
  • pass unit site pages the home page lists each registered module with its counts and a link to its matrix (#1)
  • pass unit site validation: internal links flags internal links and asset references that do not resolve (#1)
  • pass unit site validation: internal links passes a site whose internal links all resolve, ignoring external and fragment links (#1)

Checking this page

npm ci
npm run evidence:check   # rerun every test and compare with the committed evidence set
npm run evidence         # rebuild docs/evidence/stratified-survival/evidence.json