OpenHuman Two-Lane CI Model: Understanding CI Lite vs CI Full and the 80% Coverage Gate
OpenHuman uses a dual-track continuous integration system where CI Lite enforces an 80% diff-coverage gate on every pull request to main using targeted test runs, while CI Full executes the complete test suite—including Playwright and cross-platform desktop E2E tests—on the release branch before production deployment.
The tinyhumansai/openhuman repository implements a sophisticated CI strategy that balances rapid developer feedback with rigorous release quality. By splitting validation into two distinct lanes, the project ensures that daily development moves quickly while guaranteeing that every release candidate undergoes comprehensive testing. This architecture centers on a strict diff-coverage gate that requires all new code to be sufficiently exercised by tests before merging.
The Two-Lane CI Architecture
OpenHuman’s pipeline is explicitly divided into CI Lite and CI Full, each defined in separate workflow files and triggered by different branch events.
CI Lite: Fast Feedback for Development
CI Lite is defined in .github/workflows/ci-lite.yml and runs on every push to main and every pull request targeting main or release. This lane prioritizes speed by testing only what changed:
- Frontend testing – Vitest executes only tests importing files modified under
app/src/using the--changedflag. - Rust testing –
cargo llvm-covruns with a libtest filter derived from changed source directories (src/<a>/<b>/…). - Quality checks – Lint, format, and static analysis run in parallel.
- Coverage enforcement – The 80% diff-coverage gate blocks merges if changed lines lack sufficient test coverage.
CI Full: Comprehensive Release Validation
CI Full is defined in .github/workflows/ci-full.yml and triggers only on pushes to the long-lived release branch and PRs targeting release. This lane executes the exhaustive test matrix:
- Complete Vitest and Rust unit test suites.
- Rust mock-backend E2E tests.
- Playwright UI tests (run as a non-blocking signal; flaky tests do not block merge).
- Full desktop-E2E matrix across Linux, macOS, and Windows.
Results aggregate behind the CI Full Gate check, which must pass before a release is cut.
How the 80% Diff-Coverage Gate Works
The coverage gate is enforced exclusively in the CI Lite lane to ensure all new code entering main meets quality standards. The implementation relies on a four-step process coordinated by shell scripts in the repository.
Step 1: Identify Changed Lines
GitHub Actions provides the list of files modified in a pull request. The system uses this list to scope all subsequent operations, ensuring the pipeline ignores unchanged legacy code when calculating coverage percentages.
Step 2: Execute Targeted Tests
The scripts scripts/ci/vitest-changed-coverage.sh (frontend) and scripts/ci/rust-coverage-changed.sh (backend) invoke the appropriate test runners with change-aware filters:
- Frontend: Vitest runs with
--changedto select only relevant tests. - Rust:
cargo llvm-covreceives flags limiting execution to test targets matching the changed source directories.
Step 3: Calculate and Enforce Coverage
Both scripts generate LCOV reports. The diff-cover utility then calculates the percentage of changed lines covered by tests. If this percentage falls below 80%, the script exits with a non-zero status, failing the CI Lite job and preventing the pull request from merging.
Fallback for Configuration Changes
When changes touch configuration files (e.g., Cargo.toml, lockfiles, or Vitest config), the changed-file strategy becomes insufficient. In these cases, the scripts automatically fallback to running the full test suite to guarantee coverage on the broader impact of these modifications.
Promotion Flow from Main to Release
Code moves from development to production through a structured promotion process:
- Developers merge feature branches into
mainafter passing the CI Lite diff-coverage gate. - Maintainers trigger the promotion workflow (
promote-main-to-release.yml), creating a merge commit frommainintorelease. - The CI Full lane runs on this commit, providing the final safety net with complete UI and desktop E2E validation.
- Only after CI Full passes is a production release cut from the
releasebranch.
Running Coverage Checks Locally
Developers can verify diff-coverage locally before submitting a pull request using the same scripts invoked in CI:
# Install required tooling
cargo install cargo-llvm-cov diff-cover
npm install -g vitest
# Execute the coverage scripts
./scripts/ci/vitest-changed-coverage.sh
./scripts/ci/rust-coverage-changed.sh
Both commands print the percentage coverage of changed lines and abort with exit code 1 if the result falls below the 80% threshold, mirroring the behavior of the CI Lite gate.
Key Implementation Files
The two-lane CI model and coverage gate rely on these specific files in the tinyhumansai/openhuman repository:
.github/workflows/ci-lite.yml– Defines the fast CI lane formainbranch pushes and pull requests..github/workflows/ci-full.yml– Defines the comprehensive CI lane forreleasebranch validation.scripts/ci/vitest-changed-coverage.sh– Runs Vitest on changed files and computes frontend diff coverage.scripts/ci/rust-coverage-changed.sh– Runscargo llvm-covon changed Rust modules and enforces the 80% threshold.AGENTS.md(line 66) – Documents the high-level CI architecture for contributor reference.
Summary
- CI Lite provides rapid feedback on every PR to
mainby running scoped tests and enforcing an 80% diff-coverage gate via.github/workflows/ci-lite.yml. - CI Full runs the exhaustive test suite—including Playwright and desktop E2E tests—only on the
releasebranch via.github/workflows/ci-full.yml. - The coverage gate uses
diff-coveron LCOV reports generated byscripts/ci/vitest-changed-coverage.shandscripts/ci/rust-coverage-changed.sh. - Configuration changes trigger a fallback to full-suite testing to ensure accurate coverage metrics.
- Code promotes from
maintoreleasethrough a manual workflow that triggers the CI Full gate as the final quality checkpoint.
Frequently Asked Questions
What is the 80% diff-coverage gate in OpenHuman?
The 80% diff-coverage gate is a quality checkpoint enforced in the CI Lite lane that requires at least 80% of lines modified in a pull request to be covered by tests. It is implemented using the diff-cover utility on LCOV reports generated by targeted Vitest and cargo llvm-cov runs.
When does CI Full run instead of CI Lite?
CI Full runs on every push to the release branch and on pull requests targeting release, whereas CI Lite runs on pushes to main and PRs targeting main or release. CI Full executes the complete test matrix including cross-platform desktop E2E tests, while CI Lite runs only tests relevant to changed files.
How can I check if my changes meet the coverage requirement before opening a PR?
Run the scripts/ci/vitest-changed-coverage.sh and scripts/ci/rust-coverage-changed.sh scripts locally after installing cargo-llvm-cov, diff-cover, and Vitest. These scripts calculate coverage only on your changed lines and exit with an error if the result is below 80%, identical to the CI Lite behavior.
What happens if I modify configuration files like Cargo.toml?
If your changes touch configuration files (lockfiles, Cargo.toml, Vitest config), the CI Lite scripts detect this and fallback to running the full test suite rather than the scoped changed-file tests. This ensures that broad configuration changes are validated against the entire codebase to prevent coverage gaps.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →