QA Evidence Workflow¶
Use this page when you need to move from individual run evidence to a bundled artifact you can bring to a release review or attach to a QA record.
BenchCI produces structured verification evidence for each hardware test run. Workspaces can package multiple runs into a release evidence bundle — a self-contained ZIP with per-run evidence, a requirement coverage matrix, review history, LCOV summaries, and a hash manifest.
What BenchCI does not do: The bundle is a structured record. It is not a product certification and it does not replace your company’s sign-off procedure. Whether a bundle meets a specific customer or release requirement is a judgment call made by your team and your QA process.
What is a release evidence bundle?¶
A release evidence bundle packages the runs you choose into a single ZIP file. It includes:
release-evidence-v1.2.3.zip
release-summary.json ← bundle metadata and coverage counts
release-summary.html ← human-readable bundle summary report
coverage-matrix.json ← full per-run requirement/test rows
coverage-matrix-latest.json
← latest result per requirement/test pair
coverage-matrix.csv ← full matrix, spreadsheet-friendly
coverage-matrix.html ← standalone full coverage table
HASHES.txt ← SHA256 of every file in the bundle
runs/
<run_id>/
evidence.json
evidence.html
manifest.json
external-artifacts/
...
Inline artifacts imported from external JUnit/CTRF workflows are included under
the corresponding run when present. release-summary.json and
release-summary.html also include the review state, lock timestamp,
hash-linked review events, included-run DUT identity, fault summary counts, and
LCOV coverage summary.
Each bundle is workspace-permissioned. Only members of your workspace can list, download, or view bundles.
How to create a bundle (CLI)¶
The benchci releases command group manages bundles.
1. Find the run IDs you want to include¶
benchci runs list
Run IDs appear in the RUN ID column. You can also copy run IDs from the dashboard Runs page.
Only terminal runs (status done or failed) can be included. Up to 100 runs per bundle.
2. Create the bundle¶
benchci releases create "Firmware v1.2.3 Release" \
--version "1.2.3" \
--runs 4c1e9b7a2fd3,7b3fa1c8e921 \
--description "Pre-release validation runs against REQ-BOOT and REQ-COMM"
--version and --description are optional. The bundle name is required (positional) and --runs is required.
The CLI prints the bundle ID on success:
Bundle created: bnd_a3f9c2e1b047
Status: ready
Bundle generation is synchronous and completes before the command returns. For typical release bundles (2–20 runs) this takes a few seconds.
3. Download the bundle¶
benchci releases download bnd_a3f9c2e1b047
The ZIP is written to the current directory as
benchci_release_bnd_a3f9c2e1b047.zip unless --out is provided.
Other CLI commands¶
benchci releases list # list all bundles in your workspace
benchci releases show bnd_a3f9c2e1b047 # show bundle metadata
benchci releases report bnd_a3f9c2e1b047 --format html
benchci releases report bnd_a3f9c2e1b047 --template iec-62304-style --format pdf
How to create a bundle (Dashboard)¶
Open the Releases view in the BenchCI dashboard.
Click Create bundle.
Enter the bundle name, optional version and description, and paste or type the run IDs to include.
Click Create. The bundle appears in the list with status
readywhen generation completes.Click Download to save the ZIP.
The Releases view also shows the coverage summary, included runs, DUT and LCOV context, review state/history, and report downloads.
Review and sign-off¶
New bundles start in draft.
The dashboard supports this review flow:
draft or rejected
↓ submit with comment
under_review
↓ approve or reject with comment
approved or rejected
Workspace developers, admins, and owners can submit a bundle for review. Workspace owners and admins can approve or reject it. Each action requires a comment and creates a hash-linked review event. The bundle ZIP is regenerated after review changes so the downloaded package contains the current review history.
Approved bundles are locked and cannot be removed through the normal dashboard or API delete path. Owners and admins may remove non-approved bundles. A run included in any release bundle cannot be removed until that bundle is removed.
Human-readable release reports¶
Generate HTML or PDF reports from the same evidence used by the bundle:
benchci releases report bnd_a3f9c2e1b047 \
--template generic-qa \
--format html \
--out release-report.html
benchci releases report bnd_a3f9c2e1b047 \
--template iso-26262-style \
--format pdf \
--out release-report.pdf
Available templates are:
generic-qaiec-62304-styleiso-26262-style
Reports include release metadata, review state/comments, run summaries, DUT identity, firmware hashes, LCOV summaries, traceability rows, fault summaries, and external-result source labels. A draft, under-review, or rejected report is labeled with that state.
These reports are evidence review aids. They are not official assessments, certification, or regulatory approval.
How requirement coverage works¶
The coverage matrix is built from traceability metadata in your suite.yaml.
Connect tests to requirements¶
Add requirement_ids to each test case:
tests:
- name: boot_ok
test_case_id: TC-BOOT-001
requirement_ids:
- REQ-BOOT-001
- REQ-BOOT-002
steps:
- expect_uart:
node: dut
transport: console
contains: "[BOOT] OK"
within_ms: 3000
- name: comm_latency
test_case_id: TC-COMM-001
requirement_ids:
- REQ-COMM-001
steps:
- send_uart:
node: dut
transport: console
data: "PING\n"
- expect_uart:
node: dut
transport: console
contains: "PONG"
within_ms: 1000
test_case_id and requirement_ids are optional at the test level. You can also set requirement_ids at the suite level to apply to all tests in the suite.
See Suite Configuration for the full traceability field reference.
How the matrix is built¶
When you create a bundle, BenchCI parses the evidence from each selected run and writes two machine-readable views:
coverage-matrix.jsoncontains the full per-run matrix: one row per(run_id, requirement_id, test_case_id).coverage-matrix-latest.jsoncontains the latest result per(requirement_id, test_case_id)pair. This is the default view used by the dashboard and/coverageAPI.Result states are
pass,fail, ornot_run.If a requirement appears in multiple runs, the most recently created run wins.
not_run means the traceability record exists but the test did not produce a
passing or failing result, for example because it was skipped or interrupted by
an infrastructure failure. Requirements that never appear in the selected
runs’ evidence are absent from the matrix; BenchCI does not infer a master
requirement list from source files that were not part of the indexed evidence.
Coverage rows include:
requirement_idtest_case_idtest_nameresultandlatest_result(pass / fail / not_run). For full rows,resultis the per-run result;latest_resultis kept for backward compatibility.run_idandrun_statusof the run that produced the rowDUT identity fields and attached LCOV summary when available
firmware_sha256andsuite_versionfrom that runlast_run_attimestamp
Coverage is bundle-scoped¶
The matrix reflects only the runs you included in the bundle. It is a snapshot, not a live cross-run view.
If a traced test is present but was skipped or did not reach a valid test
result, its requirement/test pair can show as not_run. If a requirement is
missing entirely, confirm that it was included in the submitted suite and
preserved in the selected runs’ traceability evidence.
Workflow example¶
A typical pre-release validation workflow:
# Trigger CI validation runs across your suite
benchci run --cloud --bench-id dut-stm32 \
--suite suite.yaml --artifact build/v1.2.3.elf
# Run finishes: get the run ID from output or dashboard
benchci runs list
# Create the release bundle
benchci releases create "STM32 v1.2.3 pre-release" \
--version "1.2.3" \
--runs 4c1e9b7a2fd3,7b3fa1c8e921,9d2ae3f01b44
# Download the ZIP
benchci releases download bnd_a3f9c2e1b047
# Generate a human-readable review report
benchci releases report bnd_a3f9c2e1b047 \
--template generic-qa \
--format pdf \
--out stm32-v1.2.3-review.pdf
What to do when coverage is incomplete¶
If the matrix shows not_run for requirements you expected to cover:
Confirm the suite ran those tests. Check
results.jsonin the per-run evidence — are the test cases present?Confirm
requirement_idsis set on those tests. Open theinputs/suite.yamlfrom a run’s evidence ZIP to see what was actually submitted.Check if the run failed early. If a run failed before a test executed, that test will not appear in the coverage data.
Add a run that covers the missing requirement. Create a new bundle that includes that run.
Coverage data is only as complete as the traceability metadata in your suite.yaml files.