Quality / tfl-engine

Engine

TFL Engine — evidence

The R package that turns ADaM into ARDs and ARDs into displays: data-prep, the analysis.yaml interpreter, the owned ard.json serialization, and the gt/tfrmt/r2rtf renderers.

88reviewed requirementstfl-engine.md
110test recordsjs-unit · r-unit
0failing110 passing
95%requirement coverage84/88 evidenced

Requirements

IDAreaRequirementEvidence typeResult
TFL-PREP-001prepare_data() excludes all screen-failure subjects (ARM == "Screen Failure") from ADSL and restricts every other prepared dataset to the surviving subjects.1 passing
TFL-PREP-002ITTFL is derived from randomisation (!is.na(RANDDT)); SAFFL is used as shipped with NA recoded to "N".1 passing
TFL-PREP-003COMPLFL and the derived DISCREAS reproduce EOSSTT exactly and partition the discontinued subjects.1 passing
TFL-PREP-004Baseline weight, height and BMI are merged onto ADSL from the ADVS records flagged ABLFL == "Y", so display code never joins subject-level data.1 passing
TFL-PREP-005Every prepared dataset is described in a manifest with row/column counts, a SHA-256 content hash, and the source package and version.1 passing
TFL-PREP-006The analysis-set registry maps analysis_set keys onto population flags and rejects unknown sets and datasets lacking the required flag.1 passing
TFL-PREP-007Treatment arms are ordered by dose, not alphabetically, in every prepared dataset.1 passing
TFL-PREP-008Every vendored PHUSE file — eleven ADaM datasets and the study's SDTM CM and DM domains — matches the SHA-256 and byte count recorded in PROVENANCE.json, which pins the upstream repository, commit, per-file git blob SHA-1 and MIT licence.1 passing
TFL-PREP-009prepare_data() exposes the whole CDISCPILOT01 ADaM package — the ten datasets the study's define.xml documents, plus PHUSE's added adcm — and rejects an unknown dataset name by listing the known ones.1 passing
TFL-PREP-010TRT01A on every non-ADSL dataset is taken from the prepared ADSL rather than the dataset's own TRTA/TRTP, so no display can group on an arm the subject-level table disagrees with.1 passing
TFL-PREP-011On the PHUSE source the study's own SAFFL/ITTFL/EFFFL and baseline vitals are used as stated rather than re-derived, screen-failure absence is asserted rather than assumed, and AGEGR1 carries the study's three age groups.1 passing
TFL-PREP-012ADCM's relabelling of even-numbered sites into a synthetic second study is reversed, and every remapped subject is proven to be the same subject by age, sex and actual treatment before the remap is accepted.1 passing
TFL-PREP-013The manifest records the upstream repository path and pinned commit for every PHUSE-sourced dataset, in the same source_pkg/source_version pair a package uses.1 passing
TFL-PREP-014The pharmaverse re-derivation remains readable wholesale as the alternate lane: its own derivations and age grouping hold, its arm labels reach every dataset it serves, and it is the lane on which twelve subjects sit on a different actual arm from the study's own package.1 passing
TFL-PREP-015The analysis-set registry resolves efficacy to EFFFL; a source that states no efficacy set fails by naming the missing flag rather than returning every subject.1 passing
TFL-PREP-016A display declaring a packaging in its sources: block is refused prepared data built from a different one, naming the datasets that disagree, rather than silently rendering against data its specification did not ask for.1 passing
TFL-PREP-017RACEOR, Race (Origin) as the 2006 report coded it, is derived on both lanes from ethnicity first and race second with the report's labels, so that Caucasian plus Hispanic equals White.1 passing
TFL-PREP-018The medication analysis dataset is derived from the study's own SDTM CM domain — every CM column as published, dates taken only where stated to the day, the safety flag and treatment columns joined from ADSL, CMFL on every record — and reproduces every one of the 414 statistics the medication table published from the relabelled PHUSE copy, which stays vendored for that check.1 passing
TFL-PREP-019DM, the study's SDTM demographics domain, is the screened population: prepare_data() keeps all 306 rows, including the 52 screen failures that never reached ADSL, and is the one dataset it does not restrict to ADSL's subjects.1 passing
TFL-SRC-001The two packagings of CDISCPILOT01 are measured against each other on the domains they share, and every divergence matches the record committed at quality/data/source-agreement.json; an unrecorded divergence fails the build.1 passing
TFL-SPEC-001An analysis method outside the documented vocabulary is rejected, naming the offending analysis and listing the known methods.1 passing
TFL-SPEC-002Missing required keys and missing per-method fields (variables, hierarchy, custom) are rejected before any {cards} call is attempted.2 passing
TFL-SPEC-003A display specification must carry a study identifier, a population label and a data cut-off — the ICH E3 header requirement — as non-empty strings.1 passing
TFL-SPEC-004Row-plan keys that YAML 1.1 silently coerces to booleans (bare n, y, no, on, off) are rejected with an explanation rather than rendered as FALSE.1 passing
TFL-SPEC-005A display row referencing an analysis the analysis spec does not define, or an id mismatch between the two specs, fails the build.1 passing
TFL-SPEC-006Every display committed to library/tfl/ validates, has matching ids, and declares a post_text variant.1 passing
TFL-SPEC-007Spec map KEYS that YAML 1.1 resolves to booleans are rejected naming the file and the path. A digit plan written N: 0 parses cleanly and means FALSE: 0, so the declared precision would never reach the renderer; the failure is loud instead.1 passing
TFL-ARD-001build_ard() emits one row per computed statistic, carrying the analyses[].name that produced it, and its continuous statistics equal a direct dplyr computation.2 passing
TFL-ARD-002subject_count counts distinct subjects over the analysis-set subject denominator, never over event records.1 passing
TFL-ARD-003hierarchical_count nests inner terms under their outer level, counts each subject once per level, and matches a direct dplyr computation.1 passing
TFL-ARD-004The total column is computed by the same code path as the treatment columns and is labelled with the grouping variable, not an internal constant.1 passing
TFL-ARD-005listing passes records through as one ARD row per record per listed variable, addressable by record index.1 passing
TFL-ARD-006An analysis may dispatch to a function in the display's custom.R; a missing custom function is a build failure, not a silent skip.1 passing
TFL-ARD-007An analysis filter restricts the records summarised, and a filter that is not one logical per row or references an unknown variable fails loudly.1 passing
TFL-ARD-008{cards}' per-statistic warning and error values are retained as ARD columns; statistics computed on empty groups are recorded, not dropped.1 passing
TFL-ARD-009A binding address resolves to exactly one ARD row; zero or multiple matches raise an error.1 passing
TFL-QNT-001Quartiles use the SAS-compatible type-2 quantile definition, not R's default type 7.1 passing
TFL-IO-001ard.json conforms to the owned schema: schema, display, created, provenance, rows, with the full thirteen-key row shape on every row.1 passing
TFL-IO-002The provenance envelope records spec and display hashes, per-dataset hashes and versions, the R and package environment, and the git commit.1 passing
STD-MODEL-003The treatment vocabulary (trt_levels()) and the analysis-set registry (analysis_set_flag()) resolve from library/study.yaml, not from code; a model that spells an arm twice or counts a set for the wrong arms is refused.1 passing
STD-MODEL-004Every per-arm count library/study.yaml declares for an analysis set is what the default lane's ADSL holds — measured from the vendored file with {haven} and again through prepare_data() on both treatment assignments.1 passing
STD-MODEL-005Every committed ARD carries a population record in its provenance — analysis set, grouping column, distinct subjects per arm — that agrees with the study model for its analysis set; a listing with no arm grouping says so rather than carrying counts.1 passing
STD-SRC-001The default source registry serves every dataset the CDISC pilot publishes from the pilot's own package; only ADEX and ADLB, which it does not publish, resolve to the pharmaverse re-derivation, and no committed display reads that lane. The alternate stays readable as a whole and per dataset.1 passing
STD-SRC-002The pilot's ADVS prepares on the default lane: with no derived-record column every record is observed, a blank timepoint keys the same series as a missing one, and baseline, change and end-of-treatment derive as on the alternate.1 passing
TFL-IO-003write_ard() / read_ard() round-trip an ARD without loss; numeric statistics stay numeric.1 passing
TFL-IO-004Reading refuses a document that is not an opencsr/ard/v1 ARD; writing refuses rows missing schema columns.1 passing
TFL-IO-005Every committed ARD is readable, names only analyses its spec defines, and carries no statistic-level errors.1 passing
TFL-FMT-001Rounding is half away from zero (SAS behaviour), not R's round-half-to-even, and is stable against binary representation error.3 passing
TFL-FMT-002Proportions are scaled to percent and every statistic is rendered at its declared precision, including trailing zeros.2 passing
TFL-FMT-003The digit plan is declarative: a display-level plan applies by default and a row-level plan overrides it for variables with different collected precision.2 passing
TFL-FMT-004A p-value too small or too large to print at its declared precision is reported at the boundary (<0.0001, >0.9999) rather than rounded to 0.0000 or 1.0000; the unrounded probability stays in the ARD, and proportions are unaffected.1 passing
TFL-RND-001Rendered HTML is a standalone document with inline CSS and no external stylesheet, script or CDN reference.1 passing
TFL-RND-002In-text and post-text variants render from one ARD; the in-text variant is a strict subset of the post-text variant and applies the declared percentage threshold exactly.2 passing
TFL-RND-003Columns follow the declared order, carry group headcounts (a p-value column heads none), and silently omit declared columns absent from the ARD.1 passing
TFL-RND-004Every rendered display states its study, its analysis set and its data cut-off, and carries a source line.1 passing
TFL-RND-005Rendering a variant the display does not declare is an error.1 passing
TFL-RND-006Section headings left without data rows are dropped, and indentation distinguishes headings from the rows beneath them.1 passing
TFL-RND-007A listing renders one column per listed variable with the label declared in the display spec.1 passing
TFL-RND-008A levels: all row prints each level under level_labels while the ARD keeps the data's level; p_from names a sibling analysis whose hypothesis-test rows fill a row's p-value column, placed by the test rows' variable_level so a sub-block's test sits on its first level only; format.zero_count prints a count of nobody as the declared string; with format.sub_one_pct, a percentage at zero decimals that is positive but rounds to zero prints <1 — both opt-in, because the same report prints 1 ( 0%) in one table and 1 ( <1%) in another.1 passing
TFL-RND-009A hierarchical row plan's sort orders the outer level by name or count and the inner level by name, by one named arm's subject count or by subjects summed across the arms, ties by name; format.zero_count applies to any pattern that prints a count.1 passing
TFL-RND-010A columns.order entry may be an object naming the column's label, group level, analysis and pattern, so one row reads a different analysis or statistic per column; a variant may declare its own rows, columns and format and is rendered from the same ARD as the display's full form; a hierarchical row may print its inner level flat and in title case.1 passing
TFL-FIG-001A display declaring a figure: block renders an inline, self-contained curve drawn only from the committed ARD — deterministic for a given ARD, absent when no figure is declared, and a build failure when the declared coordinate statistics are missing rather than an empty frame.1 passing
TFL-FIG-002A rendered figure keeps its appearance when the site embeds it by lifting the document body and discarding the head: every drawn element carries its colour and its fill as SVG presentation attributes, and the stylesheet holding the dark-scheme palette travels inside the <svg>. A figure styled only from the document head publishes as filled black shapes, and silently.1 passing
TFL-SPEC-008An analysis spec typed figure and a display spec's figure: block must both be present or both absent, the block must name an analysis the spec defines, and an axis key YAML 1.1 resolved to a boolean is refused. A type: figure display with no block renders as a table and publishes silently as one.1 passing
TFL-ITER-001regenerate() writes a complete iteration directory — spec snapshots, ard.json, rendered variants and a manifest — with spec snapshots byte-identical to the specs read.1 passing
TFL-ITER-002The iteration manifest records the actor, the change request, the regulatory identifier, the ARD hash, row counts, error counts, the rendered variants and the environment.1 passing
TFL-ITER-003A second regeneration — whether through regenerate() or regenerate_all() — allocates a new version and never overwrites an earlier one; current.json moves and the ledger grows.1 passing
TFL-ITER-004Version allocation takes the maximum of the filesystem and the ledger, so a partially written or partially deleted iteration cannot be silently overwritten.1 passing
TFL-ITER-005The committed t-ae-common ledger records a real two-iteration change-request story: differing spec and ARD hashes, a recorded request and actor, and unchanged values for the numbers the change did not touch.1 passing
TFL-ITER-006Regenerating a display whose spec id does not match its directory is an error.1 passing
TFL-ITER-007Every display in the library has a current iteration on disk, referenced by both current.json and the ledger.1 passing
TFL-RTF-001A rendered display encodes as a complete RTF document.1 passing
TFL-RTF-002Every cell of the rendered display appears in the RTF, and row labels arrive without the non-breaking-space indentation the HTML renderer uses.2 passing
TFL-RTF-003The display title, population label, footnotes, source line and column headers with their subject counts travel into the RTF.2 passing
TFL-RTF-004Listings and reduced in-text variants render as RTF as well as full summary tables do, each naming the variant it is.2 passing
TFL-RTF-005regenerate() writes an RTF beside every rendered variant and records its filename and sha256 in the iteration manifest.2 passing
TFL-RTF-006Every committed display has an RTF for each variant whose hash matches the manifest, so a hand-edited artifact fails the build.1 passing
TFL-VAL-001The values declaration validates: unique ids, a readable label on every value, and exactly one of an ARD source or a declared derivation.2 passing
TFL-VAL-002A malformed binding address or an operation outside the closed vocabulary is rejected with a message naming the value.1 passing
TFL-VAL-003Every ARD-sourced value equals its row in the committed ARD and carries that iteration's path and sha256.2 passing
TFL-VAL-004A derived value equals the arithmetic it declares over values defined before it; a forward reference is an error.2 passing
TFL-VAL-005A binding that resolves to no ARD row, or names a display with no committed iteration, fails the build rather than producing a blank value.1 passing
TFL-VAL-006Scaling and rounding are presentation only: the stored value stays the ARD's, and formatted carries the display format.1 passing
TFL-VAL-007The committed store matches a fresh build of the declaration, value for value.1 passing
TFL-QC-001Every testthat test name matches <REQ-ID>[, <REQ-ID>]: <description> (#<issue>).no test
TFL-QC-002Every requirement ID cited by a test exists in a matrix under quality/requirements/.no test
TFL-QC-003Every requirement in a matrix is cited by at least one test — no untested claims.no test
TFL-QC-004Requirement matrices use the five columns ID, Requirement, Type, Verification and Status, with five cells on every requirement row.no test

Test records

ResultSuiteTestRequirementsFile
passjs-unitGate: treatment consistency STD-GATE-001: a display whose arm counts differ from the study model fails the gate, and the error names the display, the arm and both numbers (#59)STD-GATE-001tests/unit/study-model.test.js
passjs-unitGate: treatment consistency STD-GATE-002: two displays reporting the same analysis set with different counts in one document is an error naming both, even when one of them matches the model (#59)STD-GATE-002tests/unit/study-model.test.js
passjs-unitGate: treatment consistency STD-GATE-003: a display with no population record is a named warning, never a silent pass; one with no arm grouping is warned and not counted as checked (#59)STD-GATE-003tests/unit/study-model.test.js
passjs-unitGate: treatment consistency STD-GATE-004: an analysis set the model does not declare is an error, not a skipped check (#59)STD-GATE-004tests/unit/study-model.test.js
passjs-unitGate: treatment consistency STD-GATE-005: the committed report assembles green on the gate, every placed display is gated by arm, and none of them read the alternate lane (#60)STD-GATE-005tests/unit/study-model.test.js
passjs-unitStudy model STD-MODEL-001: library/study.yaml loads with three arms in print order and every analysis set counted per arm (#59)STD-MODEL-001tests/unit/study-model.test.js
passjs-unitStudy model STD-MODEL-002: every assembly that declares treatment groups declares the model's arms, in the model's order (#59)STD-MODEL-002tests/unit/study-model.test.js
passr-unitDSP-ALL-001: every display renders a table that actually contains numbers (#1)DSP-ALL-001test-displays.R
passr-unitDSP-ALL-002: every display declares a regulatory identifier and a source line (#1)DSP-ALL-002test-displays.R
passr-unitDSP-INTXT-001: the in-text demographics redraw is the report's Table 11-1 — mean and range, percentages, race as White/Caucasian or other — from the same ARD as the full table (#63)DSP-INTXT-001test-displays.R
passr-unitDSP-INTXT-002: the in-text incidence redraw is the report's Table 12-1 — terms at 5% or more in any arm, flat, in title case, an asterisk where the placebo comparison has p < 0.15 (#63)DSP-INTXT-002test-displays.R
passr-unitDSP-INTXT-003: the in-text weight redraw is the report's Table 12-4 — n and mean per arm for baseline and the changes at Week 24 and end of treatment — from the weight table's own ARD (#63)DSP-INTXT-003test-displays.R
passr-unitSTD-MODEL-003: the treatment vocabulary and the analysis-set registry resolve from the study model, not from code (#59)STD-MODEL-003test-study-model.R
passr-unitSTD-MODEL-004: every count the model declares is what the default lane's ADSL holds, per arm and per set (#59)STD-MODEL-004test-study-model.R
passr-unitSTD-MODEL-005: every committed ARD carries a population record that agrees with the study model for its analysis set (#59)STD-MODEL-005test-study-model.R
passr-unitSTD-SRC-001: the default registry serves every pilot dataset from the study's own package, and only the two datasets it lacks come from the alternate (#60)STD-SRC-001test-study-model.R
passr-unitSTD-SRC-002: the pilot's ADVS prepares without derived-record or timepoint columns the alternate carries, and its series keys match (#60)STD-SRC-002test-study-model.R
passr-unitTFL-ARD-001: build_ard returns one row per computed statistic, tagged with its analysis (#1)TFL-ARD-001test-ard-build.R
passr-unitTFL-ARD-001: continuous statistics equal a direct dplyr computation (#1)TFL-ARD-001test-ard-build.R
passr-unitTFL-ARD-002: subject_count uses the analysis-set subject denominator (#1)TFL-ARD-002test-ard-build.R
passr-unitTFL-ARD-003: hierarchical_count nests preferred terms under their SOC (#1)TFL-ARD-003test-ard-build.R
passr-unitTFL-ARD-004: the total column is produced by the same code path as the arms (#1)TFL-ARD-004test-ard-build.R
passr-unitTFL-ARD-005: listing passes records through as one row per variable (#1)TFL-ARD-005test-ard-build.R
passr-unitTFL-ARD-006: an analysis may dispatch to a function in custom.R (#1)TFL-ARD-006test-ard-build.R
passr-unitTFL-ARD-007: an analysis filter restricts the records it summarises (#1)TFL-ARD-007test-ard-build.R
passr-unitTFL-ARD-008: cards' per-statistic warning and error columns survive into the ARD (#1)TFL-ARD-008test-ard-build.R
passr-unitTFL-ARD-009: a binding address must resolve to exactly one ARD row (#1)TFL-ARD-009test-ard-build.R
passr-unitTFL-FIG-001: a figure is drawn only from its ARD, and a missing series fails the build (#1)TFL-FIG-001test-displays-cibic.R
passr-unitTFL-FIG-002: a figure keeps its appearance when the site strips the document head (#1)TFL-FIG-002test-displays-cibic.R
passr-unitTFL-FMT-001: round_half_up preserves NA, Inf and vector length (#1)TFL-FMT-001test-formatting.R
passr-unitTFL-FMT-001: round_half_up rounds half away from zero, unlike base::round (#1)TFL-FMT-001test-formatting.R
passr-unitTFL-FMT-001: round_half_up survives binary representation error (#1)TFL-FMT-001test-formatting.R
passr-unitTFL-FMT-002: format_stat applies the collected-precision defaults (#1)TFL-FMT-002test-formatting.R
passr-unitTFL-FMT-002: format_stat scales proportions to percent and pads decimals (#1)TFL-FMT-002test-formatting.R
passr-unitTFL-FMT-003: format_stat honours an explicit digit plan (#1)TFL-FMT-003test-formatting.R
passr-unitTFL-FMT-003: the row-level digit plan overrides the display digit plan (#1)TFL-FMT-003test-formatting.R
passr-unitTFL-FMT-004: p-values are reported at the boundary of their declared precision (#1)TFL-FMT-004test-displays-cibic.R
passr-unitTFL-IO-001: ard.json matches the owned schema, top to bottom (#1)TFL-IO-001test-ard-io.R
passr-unitTFL-IO-002: the provenance envelope is complete and machine-checkable (#1)TFL-IO-002test-ard-io.R
passr-unitTFL-IO-003: write_ard / read_ard round-trip an ARD without loss (#1)TFL-IO-003test-ard-io.R
passr-unitTFL-IO-004: reading refuses a document that is not an opencsr ARD (#1)TFL-IO-004test-ard-io.R
passr-unitTFL-IO-005: every committed ARD is readable and internally consistent (#1)TFL-IO-005test-ard-io.R
passr-unitTFL-ITER-001: regenerate writes a complete, self-describing iteration (#1)TFL-ITER-001test-regenerate.R
passr-unitTFL-ITER-002: the manifest records who, why, from what and how many (#1)TFL-ITER-002test-regenerate.R
passr-unitTFL-ITER-003: a second regeneration never overwrites the first (#1)TFL-ITER-003test-regenerate.R
passr-unitTFL-ITER-004: version allocation is robust to ledger and filesystem drift (#1)TFL-ITER-004test-regenerate.R
passr-unitTFL-ITER-005: the committed t-ae-common ledger tells a two-iteration change-request story (#1)TFL-ITER-005test-regenerate.R
passr-unitTFL-ITER-006: regenerate refuses specs whose ids disagree with each other or the directory (#1)TFL-ITER-006test-regenerate.R
passr-unitTFL-ITER-007: every display in the library has a current iteration on disk (#1)TFL-ITER-007test-regenerate.R
passr-unitTFL-PREP-001: screen failures are excluded from every prepared dataset (#1)TFL-PREP-001test-data-prep.R
passr-unitTFL-PREP-002: ITTFL is derived from randomisation, SAFFL is used as shipped (#1)TFL-PREP-002test-data-prep.R
passr-unitTFL-PREP-003: COMPLFL and DISCREAS reconstruct EOSSTT exactly (#1)TFL-PREP-003test-data-prep.R
passr-unitTFL-PREP-004: baseline vitals are merged from ADVS onto ADSL (#1)TFL-PREP-004test-data-prep.R
passr-unitTFL-PREP-005: the manifest describes every prepared dataset with a sha256 hash (#1)TFL-PREP-005test-data-prep.R
passr-unitTFL-PREP-006: the analysis-set registry rejects unknown sets and applies flags (#1)TFL-PREP-006test-data-prep.R
passr-unitTFL-PREP-007: treatment arms are ordered by dose, not alphabetically (#1)TFL-PREP-007test-data-prep.R
passr-unitTFL-PREP-008: every vendored PHUSE file matches its recorded provenance (#39)TFL-PREP-008test-data-phuse.R
passr-unitTFL-PREP-009: the whole CDISCPILOT01 ADaM package is preparable (#39)TFL-PREP-009test-data-phuse.R
passr-unitTFL-PREP-010: TRT01A on every dataset comes from the prepared ADSL (#39)TFL-PREP-010test-data-phuse.R
passr-unitTFL-PREP-011: the PHUSE ADSL states its populations instead of deriving them (#39)TFL-PREP-011test-data-phuse.R
passr-unitTFL-PREP-012: ADCM's two-study relabelling is reversed, and proven (#39)TFL-PREP-012test-data-phuse.R
passr-unitTFL-PREP-013: the manifest names the upstream commit for PHUSE data (#39)TFL-PREP-013test-data-phuse.R
passr-unitTFL-PREP-014: the alternate lane still prepares whole, with its own derivations and arms (#39)TFL-PREP-014test-data-phuse.R
passr-unitTFL-PREP-015: the efficacy analysis set exists and fails loudly without EFFFL (#39)TFL-PREP-015test-data-phuse.R
passr-unitTFL-PREP-016: a display is refused data prepared from a packaging its spec did not ask for (#1)TFL-PREP-016test-displays-cibic.R
passr-unitTFL-PREP-017: Race (Origin) is derived on both lanes — ethnicity first, then race, with the report's labels (#61)TFL-PREP-017test-data-prep.R
passr-unitTFL-PREP-018: the medication analysis dataset is derived from the study's own SDTM CM domain and reproduces every statistic the remapped PHUSE copy gave the medication table (#65)TFL-PREP-018test-data-phuse.R
passr-unitTFL-PREP-019: DM is the screened population and is the one dataset prepare_data() does not restrict to the subjects in ADSL (#63)TFL-PREP-019test-data-phuse.R
passr-unitTFL-QNT-001: quartiles follow the SAS-compatible type-2 definition (#1)TFL-QNT-001test-ard-build.R
passr-unitTFL-RND-001: rendered HTML is standalone — no CDN, no script, no external asset (#1)TFL-RND-001test-render.R
passr-unitTFL-RND-002: the 5% threshold keeps exactly the terms that reach it (#1)TFL-RND-002test-render.R
passr-unitTFL-RND-002: the in-text variant is a strict subset of the post-text variant (#1)TFL-RND-002test-render.R
passr-unitTFL-RND-003: columns follow the declared order and carry group counts (#1)TFL-RND-003test-render.R
passr-unitTFL-RND-004: every display states study, analysis set and data cut-off (#1)TFL-RND-004test-render.R
passr-unitTFL-RND-005: rendering rejects a variant the display does not declare (#1)TFL-RND-005test-render.R
passr-unitTFL-RND-006: section headings without data rows are dropped, indentation is preserved (#1)TFL-RND-006test-render.R
passr-unitTFL-RND-007: a listing renders one column per listed variable with its label (#1)TFL-RND-007test-render.R
passr-unitTFL-RND-008: a level prints under its declared label, a sub-block's test comes from the sibling analysis `p_from` names and sits on its first level only, and the report's zero and sub-1% presentations are display options (#61)TFL-RND-008test-render.R
passr-unitTFL-RND-009: a hierarchical row plan can order its levels by name, by one arm's count, or by the subjects summed across arms, and a bare-zero option applies to any pattern that prints a count (#62)TFL-RND-009test-render.R
passr-unitTFL-RND-010: a column may name its group, its analysis and its pattern, and a variant may redraw the display with its own rows, columns and format over the same ARD (#63)TFL-RND-010test-render.R
passr-unitTFL-RTF-001: a rendered display encodes as a complete RTF document (#1)TFL-RTF-001test-rtf.R
passr-unitTFL-RTF-002: every cell of the rendered display survives into the RTF (#1)TFL-RTF-002test-rtf.R
passr-unitTFL-RTF-002: row labels arrive without the HTML indentation trick (#1)TFL-RTF-002test-rtf.R
passr-unitTFL-RTF-003: column headers carry the treatment arms and their subject counts (#1)TFL-RTF-003test-rtf.R
passr-unitTFL-RTF-003: the title, population, footnotes and source line travel with the table (#1)TFL-RTF-003test-rtf.R
passr-unitTFL-RTF-004: a listing renders as RTF as well as a summary table does (#1)TFL-RTF-004test-rtf.R
passr-unitTFL-RTF-004: the in-text variant renders its own, smaller RTF (#1)TFL-RTF-004test-rtf.R
passr-unitTFL-RTF-005: regenerate writes an RTF beside every rendered variant (#1)TFL-RTF-005test-rtf.R
passr-unitTFL-RTF-005: the manifest records each variant's RTF and its hash (#1)TFL-RTF-005test-rtf.R
passr-unitTFL-RTF-006: every committed display has an RTF whose hash matches its manifest (#1)TFL-RTF-006test-rtf.R
passr-unitTFL-SPEC-001: an unknown analysis method is rejected by name (#1)TFL-SPEC-001test-spec-validation.R
passr-unitTFL-SPEC-002: missing required analysis keys are reported together (#1)TFL-SPEC-002test-spec-validation.R
passr-unitTFL-SPEC-002: per-method required fields are enforced (#1)TFL-SPEC-002test-spec-validation.R
passr-unitTFL-SPEC-003: a display must identify its study, population and data cut-off (#1)TFL-SPEC-003test-spec-validation.R
passr-unitTFL-SPEC-004: bare YAML `n` read as a boolean is rejected with an explanation (#1)TFL-SPEC-004test-spec-validation.R
passr-unitTFL-SPEC-005: a display row naming an unknown analysis fails the build (#1)TFL-SPEC-005test-spec-validation.R
passr-unitTFL-SPEC-006: every committed display in the library validates (#1)TFL-SPEC-006test-spec-validation.R
passr-unitTFL-SPEC-007: a spec key YAML 1.1 resolved to a boolean is refused, not silently dropped (#1)TFL-SPEC-007test-displays-cibic.R
passr-unitTFL-SPEC-008: a figure display and its figure block must agree, or the build fails (#1)TFL-SPEC-008test-displays-cibic.R
passr-unitTFL-SRC-001: the two sources' overlap matches the committed record (#39)TFL-SRC-001test-data-phuse.R
passr-unitTFL-VAL-001: a declaration missing a label, an id or a source is rejected (#1)TFL-VAL-001test-values.R
passr-unitTFL-VAL-001: the committed declaration validates and every value is uniquely named (#1)TFL-VAL-001test-values.R
passr-unitTFL-VAL-002: a malformed binding address or unknown operation is rejected (#1)TFL-VAL-002test-values.R
passr-unitTFL-VAL-003: every ARD-sourced value equals its row in the committed ARD (#1)TFL-VAL-003test-values.R
passr-unitTFL-VAL-003: every value carries the iteration and hash of the ARD it came from (#1)TFL-VAL-003test-values.R
passr-unitTFL-VAL-004: a derivation naming a value declared after it is an error (#1)TFL-VAL-004test-values.R
passr-unitTFL-VAL-004: a derived value equals the arithmetic it declares (#1)TFL-VAL-004test-values.R
passr-unitTFL-VAL-005: an unresolvable binding fails the build rather than producing a blank value (#1)TFL-VAL-005test-values.R
passr-unitTFL-VAL-006: percentages are scaled and rounded at presentation, never in the store (#1)TFL-VAL-006test-values.R
passr-unitTFL-VAL-007: the committed store matches a fresh build of the declaration (#1)TFL-VAL-007test-values.R

Traceability

No generated output yet, so the data → ARD → display chain is empty.

Provenance

Generated
2026-09-02T23:26:54.745Z
Environment
os Darwin 23.6.0 · node v24.14.0 · r 4.3.3
CI run
Not recorded for this evidence set