Build and CI

Core jobs run on every applicable non-draft pull request, every push to main, and manual dispatch. The table also names the path-triggered Signal Atlas gate and the manual-only external link check. These jobs test software and packaging contracts; they do not establish scientific validity or require hosted-model text to be deterministic.

What runs where

A workflow is the GitHub Actions file that is triggered by a pull request, a push, or a manual run. A job is an independently run set of steps inside that workflow. RFGen’s topology is deliberately small:

Workflow

Job

Purpose

Implementation CI

implementation

Fast source-tree regression, static analysis, and distribution build.

Implementation CI

installed-wheel e2e

Full local user-journey regression against a wheel in a fresh environment. This is the required PR quality gate.

Implementation CI

provisioned Sionna RT contract

Required real-solver unit and OpenGERT/Munich integration contracts.

Use-case Qualification

signal-atlas/pnt-v1 (one per migrated variant), Every use-case package is gated or excluded with a reason, Use-case qualification

Runs every migrated use-case variant’s own test suite (currently signal-atlas/pnt-v1), plus a drift check that every use_cases/ package is either in that matrix or a named, reasoned exclusion. Use-case qualification is the fixed-name required job — the other two names are per-job display names, not what a required-check list should reference.

Documentation CI

documentation

Documentation inventory checks, strict rendering, and the installed-wheel documentation journey.

Documentation External Link Check

link-check

Manually dispatched strict external-link validation.

The jobs intentionally answer different questions. A unit test that imports from the checkout cannot prove that a released wheel contains every required module or that a documented command works in an isolated environment. That is why installed-wheel e2e is a separate job instead of an extra step in implementation. Contributors can perform the focused package-artifact check described in Build and verify a release wheel.

Implementation CI

The implementation job verifies the maintained implementation in the source tree on Python 3.11. It installs the development and supported local-test extras, then runs:

  • all unit tests in tests/unit;

  • Ruff against src, ci, and the maintained unit, integration, manual, qualification, Golden Path, fixture, and test-configuration directories;

  • MyPy against src/rfgen;

  • python -m build, producing a wheel and source distribution.

This job is the implementation-regression gate. Package-boundary and entry-point coverage belongs to the broader fresh installed-wheel E2E job.

Installed-wheel E2E CI

The installed-wheel e2e job is the end-to-end gate. Here local means a test supplies no credential and makes no network call to an external model provider. The workflow environment uses uv to install the test runner and local extras. The session fixture then builds the repository wheel and creates a second, fresh Python 3.11 environment containing that wheel. It runs the complete installed-wheel suite named in the executable test map, with PYTHONPATH removed, and asserts that rfgen resolves from the second environment’s site-packages directory. Each journey has an isolated temporary workspace. This two-environment design prevents the checkout or test-runner environment from masking a missing wheel file or undeclared dependency.

Before pytest starts, ci/integration/validate_coverage_manifest.py checks ci/integration/coverage_manifest.json. The manifest assigns every declared local public command, entry point, store, and optional extra a specific disposition: an exercised E2E scenario or a documented reason for its declared boundary or exclusion.

Complete E2E contract inventory

The table below is the complete reader-facing inventory: 12 contracts that cover 35 pytest invocations in seven source modules. The executable test map names every pytest node and parameter expansion. The source links below take a maintainer to the relevant test module.

Contract family

Test source

What CI proves

Narrowband Golden Path

Golden Path tests

Uses Sionna UMi propagation; validates, generates, inspects, and reopens 100 records with RX-profile and Sionna provenance, finite IQ, labels, storage, and repeats whose ground truth is exact and whose IQ is equal within the tolerance the path declares.

Chirp-radar Golden Path

Golden Path tests

Uses Sionna TDL propagation; validates, generates, inspects, reopens, and repeats 24 chirps with finite IQ, labels, storage, Sionna provenance, RX profile, and output whose ground truth is exact and whose IQ is equal within the tolerance the path declares.

CLI and configuration

Installed-wheel Golden Paths

Installed initialization, generation, inspection, and deterministic reopen work.

Retained stores

Entry-point checks

Retained fixed-IQ store plugins load from installed distribution metadata.

Native records and receiver axes

Signal Dataset unit contracts

Native publication, ordinal access, metadata-only access, and per-receiver projection remain deterministic.

Built-in entry points and declared boundaries

Entry-point tests

Applicable local entry-point contracts are exercised from installed metadata. The ADS-B and TorchSig-impairments intentional stub/failure boundaries are tested without claiming runnable signal generation.

External plug-in wheel

Fixture plug-in tests

A separately built wheel is selected through installed rfgen generate configuration, then consumed through the public dataset and collator; invalid selection fails clearly.

Local annotation lifecycle

Annotation lifecycle test

A deterministic local client appends, reads, and resumes an annotation overlay without a second request.

Coverage manifest and exclusions

Manifest validator and manifest tests

The validator implements missing, stale, duplicate, ambiguous, and unknown-entry checks. The tests directly exercise a valid checked-in manifest, a missing declared identifier, a stale scenario node, and a newly unmapped public CLI command; duplicate, ambiguous, and unknown-identifier rules do not yet have separate injected negative test cases.

Sanitized failure diagnostics

Diagnostic tests and wheel-fixture tests

The CI upload is limited to redacted structural summaries; raw streams, credentials, IQ, stored payloads, and hosted responses are excluded.

For the local command, prerequisites, artifact policy, and rules for extending this inventory, see Installed-wheel E2E quality gate.

The ordinary E2E suite deliberately excludes live Gemini and other hosted-model calls, GPU, GNU Radio/OOT and other non-PyPI runtimes, hardware, and scientific validation. It installs Sionna PHY once to qualify the UMi and TDL Golden Paths and the compact UMa/RMa/CDL smoke set. Hosted annotation qualification is manual because it requires credentials and can incur cost; see Annotate an existing dataset.

Sionna RT CI

Sionna RT is a required core gate on every applicable non-draft pull request and push to main, without path filtering. The self-hosted superpose-arc runner preflights Sionna RT, Mitsuba, and Dr.Jit, then runs the seven marked real-solver contracts in tests/unit/test_propagation.py and the five OpenGERT/Munich journeys in tests/integration/sionna_rt/.

Signal Atlas comms-v1 Qualification

This workflow contains one job. It runs for changes to core source, root dependency metadata, the comms-v1 package, or the workflow itself, and supports a no-input manual dispatch. It is not a global repository gate.

The reason is the shape of that suite’s coverage. Signal Atlas comms-v1 shipped with several disclosed, deliberately-unfixed corpus defects, and each one is pinned by at least one pytest.mark.xfail(strict=True) test. A strict xfail fails the build when the test unexpectedly passes, so whoever fixes a defect has to remove its marker in the same change; the fix cannot be silently absorbed. That guarantee only exists while something runs the pins, which is what this job is for.

Two details of the job are load-bearing:

  • It checks out full history (fetch-depth: 0). Two byte-identity tests in the suite invoke git show against a specific pre-Phase-2 commit, which a depth-1 checkout cannot resolve.

  • It installs the framework and the use-case package from the checkout instead of running an out-of-tree wheel. Those same two tests resolve rfgen.planning.joint_sampling.__file__ relative to the repository root, so rfgen has to be imported from the checkout.

RadioML and Drone tests remain in the repository for focused development, but no Actions job qualifies them and they are not CI-backed compatibility promises.

Documentation CI

The documentation job independently verifies that the docs remain truthful, linkable, and usable. On Python 3.11 it installs RFGen plus documentation dependencies and runs, in order:

  • the documentation-inventory unit test;

  • the code-example inventory and API-coverage checkers;

  • sphinx-build -E -W -b html docs /tmp/rfgen-docs-html; and

  • the fresh installed-wheel documentation journey.

Documentation CI does not replace implementation or E2E CI: it checks that the documented public surface remains synchronized with the installed package. The inventory and classification check examines every documented code block; the installed-wheel journey executes only the blocks classified as runnable bindings. Static configuration, API-signature, and transcript examples are checked for their declared non-runnable classification rather than executed as programs. Run the same checks locally from Documentation Quality Checks. Live Gemini and other billed provider calls remain deliberately outside this job. The three manually gated unified Spark qualifications are documented in Generate, then annotate. External link checking is a separate manual workflow on superpose-arc; it retains strict sphinx-build -E -W -b linkcheck behavior.