Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rullst CI/CD and Verification Contract

This document describes what the repository’s automation currently executes. It is not evidence that a workflow has passed for a particular commit. A green claim must always point to the GitHub Actions run, commit SHA, logs, and produced artifacts.

Last source-level review: 2026-09-11.

Status language

StatusMeaning
BlockingA failing command fails that workflow run. Branch protection still determines whether the check is required for merging.
Automated evidenceThe workflow runs automatically, but part of its result is external, uploaded, or deliberately non-blocking.
InformationalThe workflow is explicitly advisory and must not be described as a release gate. A manual trigger alone does not make a strict candidate check informational.
RoadmapThe idea is preserved, but this repository does not yet provide reproducible evidence for it.

The distinction matters: Kani, Miri, mutation testing, or a scanner can be very valuable without proving that the entire framework is panic-free, race-free, memory-safe, or compliant with a regulation.

Mainline execution model

The v12 dashboard and its automatic status badges are pinned to main. The continuous workflows accept pushes to main and pull requests targeting it, and expose workflow_dispatch where a safe rerun is useful. Superseded runs of these workflows are cancelled per workflow and ref so rapid development does not spend runner capacity proving an obsolete commit.

ci.yml deliberately treats the expensive operating-system matrix differently. Format and Clippy continue to give feedback on draft pull requests. The complete Linux/macOS/Windows test matrix, blocking line coverage, SemVer fan-out and CodeQL analysis start for a pull request only when it is ready for review, and it can always be requested manually. Each operating system executes eight parallel shards: the non-CLI workspace, ordinary CLI targets, the LMS contract, three public-profile groups and two generated-blueprint groups. The basic/relational/polyglot and foundation/product partitions retain every original case while bounding the longest Windows and macOS jobs. No test is omitted; this changes wall-clock scheduling rather than the assertions being executed. Hosted CI permits two nested compiler jobs for the otherwise serial generated profile/blueprint builds; constrained local runs retain their one-job default. Each CLI shard fetches the locked registry inventory before its generated applications prove that they compile without network access. After that reviewed commit is merged, the automatic main push repeats Linux rather than paying for the same macOS and Windows proof twice. A direct push to main therefore has Linux evidence only until a maintainer explicitly runs ci.yml; release candidates must use the manual full matrix when no successful ready-PR run points to the exact candidate tree.

The SHA-bound quality scorecard is generated only by a ready pull request or a manual full-matrix run. It is deliberately skipped on the Linux-only automatic main run, because that execution cannot honestly award cross-platform verification credit. Run ci.yml manually on a final main candidate to produce the exact-SHA release scorecard. Manual diagnostic runs may select one operating system and one test shard; those deliberately do not produce a full-matrix scorecard and do not replace final-candidate evidence.

GitHub executes schedule events from the repository’s default branch, so scheduled and continuous v12 evidence now share the active main source line. Tag publication remains deliberately unavailable through a manual button.

Manual and periodic execution map

Every verification workflow except the PR-context-only ai-sentinel-pr.yml and tag-only release.yml can now be started from Actions → select workflow → Run workflow. A manual run checks the selected branch’s current SHA; record that SHA and the run URL before treating it as release evidence. The release workflow intentionally has no button because its publication authority begins only with an exact version tag.

The workflows below run only when requested manually:

WorkflowEvidenceRC interpretation
dast-zap.ymlOWASP ZAP baseline against a release blog showcase plus fresh generated REST API and complete LMS applicationsREST/LMS warnings and failures block unless an exact rule ID is versioned as INFO with a local explanation in .zap/; those configs are passed explicitly to the pinned scanner and unlisted warnings remain live. The showcase is informational because it deliberately uses third-party presentation assets; reports and application logs are retained. This remains representative, not universal deployment coverage.
fuzzing.ymlAll 40 declared libFuzzer targets from the validated shared inventoryRequired v12 RC evidence: release mode first validates the ten package lockfiles and compiles every declared target in ten package-level preflight jobs, then every target must finish without a crash for the 5.5-hour budget; target-specific corpora are restored and saved, while failure reproducers are retained. Dependency-lock drift fails preflight, campaign and corpus jobs. The proc-macro parser uses strict processes of at most 30 minutes sharing one corpus, which bounds sanitizer RSS without weakening the total budget. A strict five-minute single-target diagnostic accelerates correction feedback but is explicitly ineligible as RC evidence. This is bounded evidence, not proof for every input.
kani.ymlTwenty named bounded formal harnesses in ten supported runtime/library packagesRequired v12 RC evidence for the declared harnesses: every proof has an isolated strict matrix job. Rullst itself stays on stable Rust 1.98.1 with a Rust 1.96 MSRV; only the separately built Kani verifier uses its pinned nightly-2026-08-01 compiler (rustc 1.99.0-nightly) because the latest stable Kani bundle’s Rust 1.93 compiler cannot compile the framework. The proc-macro-only rullst-macros target remains unsupported by Kani and is covered by compile-pass/fail and generated-project evidence instead.
miri.ymlRandomized-layout Miri execution over 15 named pure-Rust/default-feature scopesRequired v12 RC evidence for the declared scopes: every selected scope is strict. This nightly-only interpreter uses pinned nightly-2026-08-21 (rustc 1.100.0-nightly); it does not change the project’s stable toolchain or MSRV. Native FFI, OS syscall, network/provider, umbrella re-export, and example-application boundaries are excluded explicitly rather than emitted as tolerated errors.
mutants.ymlA fail-fast reviewed inventory, eighty lossless shards over the measured 14,380-mutant workspace scope, their artifacts and a strict aggregateInformational: a cheap all-feature --list --json preflight rejects inventory drift before runners start; every shard then uses that release surface, and aggregation requires every reviewed candidate to receive exactly one classification before reporting the conservative caught percentage. A targeted mode retests one validated production Rust file after a correction; it does not replace the complete campaign. Missed/time-out exit codes remain findings, while a broken baseline, incomplete artifact set, preflight/classification mismatch, invalid invocation or cargo-mutants internal failure fails the workflow. The 80-way split replaces an invalid 16-way attempt whose default-feature baseline omitted optional tests and whose slowest CLI/ORM jobs could not fit the 5h30 bound. “Pass” does not honestly mean every possible mutant was killed.

These workflows are periodic and manually runnable:

CadenceWorkflowsMode
Dailyaudit.yml, sanitizers.ymlCargo Audit is blocking; TSan/ASan are blocking when executed.
Weeklybench.yml, cargo-deny.yml, codeql.yml, corpus-sync.yml, coverage.yml, documentation.yml, pqc-compliance.yml, proptest.yml, scorecards.yml, security-audit.yml, trufflehog.yml, udeps.ymlThe inventory below identifies which results are blocking, automated evidence, or informational. Corpus sync warms and minimizes the same 40 validated target corpora with bounded parallelism.

All remaining test/build workflows run on the documented push, pull-request or path filters and also expose a manual rerun. For an RC checkpoint, first use the automatic mainline suite, then manually run the five manual-only workflows and any periodic/platform matrix whose latest successful run does not point to the same candidate SHA. Physical devices, store approval, live provider accounts, external security review and human release approval remain outside GitHub Actions.

Required local and release baseline

The contributor baseline from AGENTS.md is:

cargo test --workspace --all-features
cargo clippy --workspace --all-features -- -D warnings
cargo fmt --all

The main CI uses the stricter all-target Clippy form and checks formatting without modifying files:

cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-features

Rust CI disables Cargo incremental compilation and uses the pinned sccache Action and binary to store content-addressed compiler outputs in GitHub Actions cache. The current cc build dependency also honors the same Rust compiler wrapper, so compatible bundled DuckDB C++ objects can be reused. Same-repository pull requests can populate only their GitHub-isolated refs/pull/.../merge cache scope, making a failed-job rerun useful without modifying the trusted default-branch namespace. Fork pull requests remain read-only. Pushes and explicit manual runs on main populate entries reusable by later pull requests. Cache contents never substitute for a test result. The tag-only verifier uses the same namespace strictly read-only, so it can reuse an exact trusted compiler output but cannot alter the cache while creating release artifacts; every release command and assertion still runs.

The setup action’s job-scoped Cargo archive is disabled in these compiler-cache jobs, so neither the raw workspace target tree nor duplicate registry bundles compete with compiler objects. CLI integration tests create and remove nested Cargo targets, and archiving whole mutable trees previously produced false missing-directory annotations, duplicated roughly 9.56 GiB across twenty active main caches, and caused eviction churn at GitHub’s default 10 GiB repository limit. Cargo may redownload registry sources on a fresh runner; this small network cost is preferable to storing the same registry/target archive under many job-specific keys. A first run on a new cache namespace is still a cold build; evaluate acceleration using the reported cache hit ratio and a later compatible run, never by weakening or omitting assertions.

The same content-addressed approach accelerates LLVM coverage, benchmark, mutation/fuzz compilation and the scheduled release-mode regression suite. The weekly corpus workflow warms the same fuzz compiler namespace used by the manual campaign. Benchmarks remain sequential on one runner so comparisons do not mix host variance. Coverage deliberately remains one report job because splitting it without a reviewed profile-data merge could change the repository percentage. Its second default-feature pass is limited to ORM, Studio and the public facade: those are the packages with default-SQLite tests excluded by the mutually exclusive all-feature graph, so unrelated workspace tests are not repeated. The release-mode workspace is safe to split because every shard returns an ordinary test result, while the two source locations that actually use proptest! still receive their configured 10,000-case runs. SemVer checks fan out from the machine-readable release order and validate one published API per job, so adding or removing a release package cannot silently drift from the matrix.

The all-feature coverage pass uses pinned cargo-nextest to schedule the same discovered unit and integration tests concurrently. It performs no retry and a flaky retry could not be normalized into success. A repository profile fixes four global slots and permits at most two integration tests that launch nested generated-application Cargo builds, preventing compiler fan-out from trading latency for memory or disk exhaustion. The exact per-test JUnit result and duration record is retained for 30 days. This runner is a coverage scheduler, not a replacement for Rust CI: the required multi-platform shards continue to execute the complete inventory with ordinary cargo test, preserving both traditional libtest process semantics and the materialized-project gates.

CodeQL also remains one analysis job. Its Cargo target cache is disabled so the extractor observes compilation for the exact SHA instead of inheriting a fresh artifact from another run; the analysis database itself is not interchangeable with ordinary test shards. Rust CodeQL’s faster buildless mode is intentionally not used because manual compilation gives the extractor the stronger generated code boundary needed by this release.

ci.yml also compiles and exercises each ORM strict database feature in isolation (PostgreSQL, MySQL, and SQLite), exercises the runtime-only Core and all 45 public umbrella features in isolated additive graphs with automatic manifest-drift detection, runs the portable database matrix on Linux, and tests the complete all-feature workspace in eight parallel shards on Linux, macOS, and Windows. Feature-boundary rows and threat-model negative tests also fan out into four deterministic strict shards each; their matrix job remains a single blocking dependency for the quality scorecard. Each threat-model shard primes the reviewed lockfile before its deliberately offline generated-project checks, so it does not inherit a hidden source-cache dependency from another job. The umbrella’s cfg(doctest) aggregation reads all 52 public tutorial files directly, so that same command discovers the versioned Rust blocks, compiles or executes complete examples, and records explicitly contextual fragments as ignored instead of pretending they are standalone programs. Its pinned live Redis job also proves that scheduled Core jobs are not claimed early, that Core cache inspection returns bounded metadata without values, plus ORM cache hit/TTL/recovery, tenant/table invalidation, rollback preservation, process-local post-commit observers and Scout commit ordering. A separate SQLite outbox contract runs on all three operating systems and covers atomicity, conflicting idempotency keys, claim races, lease expiry, retry and dead-letter; the relational matrix repeats the core outbox lifecycle against PostgreSQL, MySQL, MariaDB and strict SQLite. A dedicated job checks the declared MSRV, Rust 1.96.0. The Linux provider matrix also runs the feature-gated Scout adapter against a digest-pinned Meilisearch image; Algolia and Elasticsearch use bounded local protocol fixtures because no hosted provider account is part of CI. The same matrix runs typed, parameterized L2 and cosine queries against a digest-pinned PostgreSQL + pgvector image. It also runs Nexus’s default Any/SQLite HTTP contract explicitly, because the global all-feature graph intentionally selects a strict database profile and excludes that materialized tenant/audit target. Coverage separately merges the default workspace pass, so those routes contribute real executed-line evidence.

After a ready-PR or manual full-matrix Rust CI run finishes, an observational job emits a SHA-bound per-crate quality scorecard into the workflow summary and a 90-day artifact. The score combines versioned expert-audit ceilings with the actual gate results; a failed/skipped/cancelled gate can remove the dimensions it was meant to prove, while a green gate cannot inflate a crate beyond its audited ceiling. This is engineering-evidence reporting, not capability completion or certification. See the scorecard methodology.

Rows with no feature selected compile every package target. Feature-selected rows compile the isolated library graph; feature-enabled tests, examples, and benchmarks remain covered by the workspace and specialist jobs. This avoids pulling unrelated development dependencies into every boundary while retaining real integration coverage.

The tag-only packaged-distribution gate reads the complete feature set from the extracted rullst package manifest and compiles that crates-only consumer with defaults disabled and every public feature enabled. A partial hand-maintained feature allowlist therefore cannot make a monorepo-only integration appear release-ready.

Require every job emitted by the following workflows before merging into main: Rust CI, GitHub Actions Lint, Documentation, End-to-End Smoke Tests, Cargo Audit, Security Audit, Cargo Deny, CodeQL, Test Coverage, Cargo Machete, SemVer Checks, Spellcheck, Crate Architecture Policy, TruffleHog, Unsafe Policy, WebAssembly Matrix, Zero Panics, no-std Build, IoT Integration, and PR Security Evidence.

Do not configure a path-filtered, scheduled, manual, deployment, or tag-only workflow as a universal required check: an intentionally skipped workflow may never create the check context. In particular, IoT Cryptography Containment is blocking when relevant paths change, and the Omni desktop, Android and iOS compile workflows are blocking only when the Omni generator boundary changes. Pages, benchmarks, fuzzing, sanitizers, Kani, Miri, mutation testing, udeps, ZAP, Scorecard, and release provenance belong to deeper evidence or release policy. GitHub repository rulesets remain the enforcement source; this document records the recommended profile and does not claim that the hosted setting is already enabled.

Phase 4 release-engineering status

Goal from gpt.mdCurrent statusAssessment
Trifecta with all featuresImplementedCI and tag release both run format, all-target/all-feature Clippy, and all-feature tests.
Strict DB features in isolationImplemented in workflowstrict-postgres, strict-mysql, and strict-sqlite compile independently and each runs a backend-specific CRUD test with only the selected strict feature enabled.
Honest blocking/informational labelsImplementedUnsafe and Wasm checks are blocking in continuous CI; the declared Kani, Miri and fuzzing scopes are strict v12 RC gates; mutation testing and udeps explicitly remain informational.
Cover every fuzz targetImplemented in workflow.github/fuzz-targets.json is the shared inventory for the manual campaign and corpus maintenance. A blocking validator compares it with all ten fuzz manifests and their 40 source files. This records configuration, not a successful six-hour run.
Package all crates before publishingImplemented in workflowThe tag-only release validates versions, packages all publishable workspace crates, hashes and attests the archives, then publishes in dependency order.
Unified evidence bundle per tagImplemented in workflowThe tag-scoped bundle contains Cargo.lock, Cargo metadata, CycloneDX 1.5 SBOM, Cargo Audit JSON, deny.toml, bounded compliance evidence, governed advisory exceptions, commit/tag context, and checksums. The bundle and .crate archives are included in build-provenance attestation.
Align manifest, changelog, tag, registry, and notesPartialThe release validates vMAJOR.MINOR.PATCH against publishable manifest versions. Changelog state and registry/release-note consistency are not automatically verified. Worth implementing before calling 12.0.0 released.

Important evidence boundaries

Zero-panics and unsafe Rust

zero-panics.yml denies Clippy’s unwrap, expect, panic, todo, and unimplemented lints for published runtime libraries, procedural-macro engines, CLI production targets, generated runtime templates, and the Wasm Core path. Tests are excluded where assertion panics are test semantics.

unsafe-policy.yml compiles production libraries and binaries with -Dunsafe-code. The only reviewed file-level exceptions are the Radar OS probe and dynamic-library loader, and the workflow fails if that allowlist changes. This is an enforced boundary, not a claim that all dependencies contain no unsafe Rust.

Coverage

coverage.yml runs LLVM coverage over workspace all-features and default profiles plus the live database matrix, then uploads LCOV to Codecov using GitHub OIDC rather than a long-lived upload secret. It also retains exact JSON and text line summaries for 30 days so a passing upload cannot be confused with the coverage percentage. The all-feature pass uses pinned cargo-nextest only to run the same discovered tests concurrently, with zero retries, bounded nested-Cargo concurrency and a retained JUnit execution record. Rust CI still runs ordinary cargo test across Linux, macOS and Windows. The default-profile pass explicitly includes ORM, Studio, Nexus and the umbrella facade so their real SQLite contracts are not hidden by mutually exclusive all-feature database profiles. Before upload, the workflow independently rejects an LLVM summary below 90% for either the whole repository or the governed framework-library paths. codecov.yml also requires at least 90%, with zero tolerance, for those views and changed lines; failure to upload LCOV also fails the workflow. The report filters examples, benchmarks, auxiliary test support, and separate test files. CLI and proc-macro code therefore remains part of the blocking repository aggregate and is additionally visible as informational components. Their stronger semantic evidence still comes from materialized scaffolds and compile-pass/compile-fail contracts. The README exposes both the public overall badge and the separate framework_libraries badge rather than substituting the higher component result for the repository total.

Formal, dynamic, and stress analysis

  • Kani and Miri are manual research evidence scoped to the harnesses/packages that actually execute. Rullst itself remains pinned to stable Rust 1.98.1 and keeps Rust 1.96 as its declared MSRV. Kani builds reviewed upstream revision 8fcd6d90ed07b559e553ca8a92b95f2db69b2c78 with the verifier’s own pinned nightly-2026-08-01 compiler (rustc 1.99.0-nightly) into a bundle and installer, then treats proof failures in twenty isolated harness jobs across ten supported packages as real matrix failures. That revision intentionally predates a compare_bytes compiler crash reproduced with Kani’s first rustc 1.100.0-nightly snapshot. The workflow does not patch manifests, bypass MSRV data, or change Rullst’s stable toolchain. Kani cannot verify the proc-macro-only rullst-macros target. Miri, which only runs on nightly Rust, pins nightly-2026-08-21 (rustc 1.100.0-nightly) and strictly executes 15 named pure-Rust/default-feature scopes. Its matrix excludes native ring, AWS-LC, SQLite, OS-syscall and network/provider execution that Miri cannot interpret; native CI, integration tests and sanitizers remain the applicable evidence for those paths. The rullst umbrella re-export facade and Blog example add no separate interpreter scope. A selected-scope failure fails the run. The Kani Security harnesses prove pure production decisions such as Vault key-ID character policy, DLP buffer admission, ASCII-folded RASP matching, SRI asset limits and bounded Login Guard delay; the IoT matrix also proves the complete CoAP option-component classification. They do not claim that Kani verifies zeroize’s unsupported inline assembly, cryptographic implementations or the entire concurrent middleware implementations.
  • Mutation testing is manual, split into 80 lossless shards over the measured 14,380-mutant inventory, and intentionally informational while results are uploaded. Before the expensive matrix starts, a fail-fast --list --json preflight verifies the exact unique candidate set; the final aggregate must match that reviewed list, not merely its count. The hosted command makes --all-features explicit and .cargo/mutants.toml applies the same feature policy locally; the ignored legacy root configuration and its exclusions were not silently activated. Targeted mode accepts exactly one tracked production .rs path so a correction can be retested without restarting the complete workspace campaign. Exit statuses for missed and timed-out mutants remain findings; baseline, usage and internal failures do not get normalized into green jobs. The aggregate also fails closed when an artifact is absent, a shard is incomplete or the reviewed full inventory drifts; its conservative percentage never treats a timeout as caught.
  • Fuzzing and corpus maintenance pin nightly-2026-08-21 instead of following a moving nightly alias. This verifier-only toolchain does not change the framework’s stable Rust 1.98.1 toolchain or its Rust 1.96 MSRV. Before a release campaign starts, ten strict preflight jobs compile every target so a stale import or broken fuzz manifest fails in minutes rather than alongside hours of valid campaigns. A five-minute one-target diagnostic is correction feedback only; the evidence-boundary job refuses to call it release evidence. Each of the ten fuzz packages has a checked-in dependency lock; inventory validation requires it, and locked metadata plus a post-command drift check prevents preflight, campaign or corpus maintenance from silently resolving a different dependency graph. The parser campaign restarts its ASan process every 30 minutes while retaining one corpus and the full 5.5-hour target budget, preventing instrumentation RSS accumulation from masquerading as a parser crash.
  • Branch coverage, cargo-udeps, TSan and ASan share the reviewed nightly-2026-08-21 analysis snapshot instead of following a moving nightly alias. The first two remain observational/informational; sanitizer failures remain blocking whenever their daily/manual matrix executes.
  • cargo-udeps is weekly/manual and explicitly non-blocking.
  • TSan and ASan run daily/manual across twelve runtime/domain packages; Messaging runs its integration contract so its concurrent state is actually exercised rather than reporting a zero-test library pass. There is no MSan job in the current sanitizer workflow.
  • The manual ZAP workflow materializes, release-builds and migrates a fresh REST API and complete LMS through the real CLI. Both baselines fail on any warning/failure, preserve INFO observations and use no ignored rules. The release blog showcase is scanned separately but remains informational because its documented presentation boundary deliberately uses a relaxed CSP and third-party assets. Its rules retain those external-asset findings for review and reduce only evidenced token/state signals or escaped showcase reflections to INFO; they do not hide findings with IGNORE. These three targets are representative evidence, not coverage of every blueprint, authenticated role, browser, proxy or deployment.
  • Property tests and benchmarks are scheduled/manual evidence. The property workflow preserves the complete all-feature release-mode regression suite in eight parallel shards and separately runs the ORM and Connect property contracts with 10,000 generated cases. The eight published benchmark groups, backed by nine Criterion binaries, emit non-blocking alerts at a 20% regression and feed the public benchmark hub; they are not a promise against every nanosecond-level regression.

Fuzzing and OSS-Fuzz

The manual fuzzing.yml matrix covers all 40 declared libFuzzer targets: Core 12, ORM 5, Security 7, Connect 3, Mail 4, AI 3, IoT 3, Capital 1, Nexus 1, and Studio 1. The checked-in .github/fuzz-targets.json is validated against every */fuzz/Cargo.toml, corresponding lockfile and source file before either the manual campaign or weekly corpus job can fan out. Release mode then compiles all targets in ten package-level preflight jobs before starting any long campaign. Both jobs use versioned per-target corpora and one content-addressed compiler-cache namespace; campaign failures retain their exact reproducer, and the weekly job performs a bounded warm-up before minimizing and uploading each actual corpus. A clean run remains evidence only for its exact SHA, target, corpus, toolchain and time budget. Diagnostic mode is limited to one exact inventory target for five minutes and is never counted as the forty-target RC gate.

The oss-fuzz/projects/rullst directory is a local integration draft. It is not proof of upstream acceptance, continuous ClusterFuzz execution, or coverage of all 40 targets; its helper build must be completed and validated against the official OSS-Fuzz repository before submission. The integration is worth finishing, but a “100% first-pass acceptance” promise is not meaningful and should not be made.

Supply chain and release provenance

All direct third-party GitHub Actions references in this repository’s workflow files are pinned to full commit SHAs. A pinned composite action can still carry its own transitive downloads or references, so blocking integrations must also be reviewed for that behavior. RustSec exceptions are limited by deny.toml and documented with owners, controls, and expiry dates in docs/src/security-advisory-exceptions.md.

scorecards.yml runs the pinned OpenSSF Scorecard action on main pushes and weekly, uploads SARIF to GitHub code scanning, and publishes OIDC-authenticated results to the public Scorecard API so the README badge follows the latest completed analysis. The numeric score is supply-chain evidence, not a security certification.

release.yml is tag-only. It verifies source, validates the exact semantic tag against every publishable crate, packages before the first publish, and creates a tag-bound evidence bundle containing the lockfile, Cargo metadata, CycloneDX 1.5, Cargo Audit JSON, dependency policy, bounded compliance evidence, advisory exceptions, commit context, and checksums. The .crate archives and evidence receive a GitHub build-provenance attestation, while the official generic SLSA generator produces release provenance. This does not by itself establish project-wide SLSA Level 3 certification, Sigstore Cosign binary signing, or regulatory compliance.

workflow-lint.yml validates all workflow syntax, GitHub expressions, and embedded shell with Actionlint 1.7.7. Its container is pinned to an immutable linux/amd64 digest, just like third-party GitHub Actions are pinned to full commit SHAs.

architecture.yml is repository-owned and deterministic. It rejects any internal dependency edge or optionality change that is not reflected in the reviewed crate-architecture-policy.json. The earlier TangleGuard integration was removed because its composite action downloaded an unversioned latest binary without a repository-pinned checksum, which was unsuitable for a blocking supply-chain gate.

Workflow inventory (37 definitions)

Durations are intentionally omitted because runner load, cache state, and the dependency graph make static estimates unreliable.

WorkflowTriggerModeActual scope
ai-sentinel-pr.ymlpull requestsAutomated evidenceGenerates bounded CLI audit, compliance report, and CycloneDX SBOM artifacts; no certification claim.
architecture.ymlmain push and PR, manualBlockingCompares Cargo’s publishable non-dev internal dependency graph with the reviewed crate-architecture-policy.json; unreviewed normal/build edges, removals, or optionality changes fail, while test-only dev-dependencies do not masquerade as production coupling.
audit.ymlmain push and PR, daily, manualBlockingCargo Audit over the production lock and all ten fuzz-package locks with one advisory-database fetch. The v12 candidate applies no advisory exceptions; future exceptions must pass the separate owner/expiry governance check.
bench.ymlmain push, weekly, manualAutomated evidenceEight published groups backed by nine Criterion binaries, with non-blocking 20% regression alerts and gh-pages data consumed by the benchmark hub. Scheduled runs use the repository default branch.
cargo-deny.ymlmain push and PR, weekly, manualBlockingAdvisory, license, ban, and source policy from deny.toml.
ci.ymlmain push and PR, manualBlocking plus observational reportFormat, all-target/all-feature Clippy, eight-shard multi-OS tests including Cargo-aware doctests sourced from all 52 tutorials, four-way feature/threat partitions, the SQLite transactional outbox contract and Messaging concurrency suite, relational/polyglot live matrices, isolated strict-DB/feature boundaries, MSRV, and a ready-PR/manual full-matrix SHA-bound per-crate quality scorecard artifact. A targeted manual OS/shard run is diagnostic and cannot emit the full scorecard.
codeql.ymlmain push and PR, weekly, manualBlocking runRust CodeQL after an all-target/all-feature workspace check.
corpus-sync.ymlweekly, manualInformationalValidates the shared 40-target inventory and ten package lockfiles, restores each real target corpus, performs a bounded warm-up, minimizes it, uploads the result and warms the campaign’s content-addressed compiler cache; individual target failures are retained but tolerated, while dependency-lock drift remains a hard failure.
coverage.ymlmain push and PR, weekly, manualBlocking plus observational jobLLVM LCOV generation with a pinned, zero-retry, bounded-concurrency nextest scheduler and retained JUnit inventory; a focused default-SQLite pass for ORM/Studio/Nexus/the facade; exact local 90% floors; and blocking OIDC-authenticated Codecov upload. Scheduled/manual branch instrumentation is non-blocking and uses the pinned verifier-only nightly.
dast-zap.ymlmanualBlocking generated targets plus informational showcasePins the ZAP image by digest, scans fresh release/migrated REST API and complete LMS surfaces as blocking gates, scans the CDN-backed blog showcase informationally, and uploads separate reports plus application logs.
documentation.ymlmain push and PR, weekly, manualBlocking plus informational external scanBuilds the mdBook; validates landing/benchmark templates, project identity, the README workflow count, local assets, pinned external chart scripts and all requested social links. Real Chromium checks desktop/390px/320px layout, keyboard/mobile navigation, clipboard success/denial, privacy disclosure, reduced motion, no-JS navigation, and absence of external landing requests/browser storage. This is a bounded browser contract, not WCAG certification. Also validates the 190-claim historical roadmap denominator and repository-local links. Scheduled/manual runs preserve an informational external-link report.
e2e-smoke.ymlmain push and PR, manualBlockingBoots the release Blog application and checks HTTP, headers, CSRF form flow, SQLite persistence, and the persisted page parsed by real headless Chromium.
fuzzing.ymlmanualBlocking v12 RC campaign or diagnosticRelease mode validates ten package lockfiles and compiles all targets in ten package preflights before forty 5.5-hour libFuzzer jobs, with per-target corpus caching and failure reproducers. Lock drift is always rejected. The parser restarts its ASan process at most every 30 minutes while preserving the budget. Single-target diagnostic mode runs for five minutes and the evidence boundary marks it ineligible for release.
iot-integration.ymlmain push and PR, manualBlockingHost IoT tests, signed OTA invariants, and one Cortex-M no-std build; no hardware claim.
kani.ymlmanualBlocking v12 RC scope; bounded evidenceBuilds an immutable reviewed Kani snapshot with the verifier-only nightly-2026-08-01 compiler, while Rullst stays on stable Rust 1.98.1 with a Rust 1.96 MSRV. It verifies twenty named bounded harnesses in isolated jobs across ten supported packages. Proof failures fail their matrix jobs; the proc-macro-only crate remains outside Kani’s supported targets.
machete.ymlmain push and PR, manualBlockingUnused dependency scan with configured exceptions.
miri.ymlmanualBlocking v12 RC scope; bounded evidencePinned nightly-only Miri executes 15 named pure-Rust/default-feature scopes with randomized layouts without changing Rullst’s stable toolchain or MSRV. Native FFI/syscall/network paths, the umbrella re-export facade, and the Blog example are explicit boundaries; selected-scope failures fail the workflow.
mutants.ymlmanualInformationalA fail-fast exact-inventory preflight followed by eighty lossless pinned cargo-mutants 27.1.0 shards over the measured 14,380-mutant all-feature workspace scope, or one validated production-file diagnostic, with uploaded results, compiler caching and a strict completeness aggregate bound to the preflight list. Findings stay informational, but baseline/tool/invocation failures, missing artifacts, incomplete classification and reviewed-inventory drift fail the run.
no_std-build.ymlmain push and PR, manualBlockingBuilds rullst-iot for three bare-metal targets; this is compile evidence, not hardware execution.
omni-android.ymlrelevant main changes and PRs, manualBlocking when triggeredGenerates a fresh deterministic Omni shell, initializes Android and compiles an unsigned aarch64 debug APK. It does not test a physical device, Play testing, signing, privacy declarations or store acceptance.
omni-desktop.ymlrelevant main changes and PRs, manualBlocking when triggeredGenerates a fresh deterministic HTTPS-backed shell and checks its Tauri crate on Linux, macOS and Windows. It does not build/sign every installer or exercise a GUI/WebView session.
omni-ios.ymlrelevant main changes, manualBlockingGenerates a fresh deterministic Omni iOS shell on macOS and compiles it for the runner’s simulator architecture. It does not test a physical device, signing, privacy declarations, TestFlight or App Store acceptance.
pages.ymlmain push, manualDeployValidates and deploys the unreleased v12 landing page, local visual assets, mdBook and benchmark hub/dashboards to GitHub Pages while preserving history data fetched from gh-pages.
pqc-compliance.ymlrelevant main changes, weekly, manualBlockingSigned OTA and Vault tests, RustSec audit, and simulator-boundary checks; explicitly no PQC/HSM certification.
proptest.ymlweekly, manualBlocking runEight parallel release-mode workspace shards plus dedicated ORM and Connect property contracts with configured case counts.
release.ymlexact-looking version tagsReleaseTag validation, full verification, package-all, evidence bundle, checksums, attestations, dependency-order publish, and release provenance.
sanitizers.ymldaily, manualBlocking runTSan and ASan library matrices on pinned nightly-2026-08-21; this verifier toolchain does not change Rullst’s stable compiler or MSRV.
scorecards.ymlmain push, weekly, manualAutomated evidenceOpenSSF Scorecard analysis and SARIF/artifact upload; not SLSA certification.
security-audit.ymlmain push and PR, weekly, manualBlockingCross-checks active advisory IDs and expiry metadata across the ledger, Cargo Deny, and scanner workflows, then independently reruns Cargo Audit.
semver.ymlmain push and PR, manualBlockingFans out one job per machine-readable release-order entry and compares each supported, already-published library API with its exact latest non-yanked crates.io baseline. Never-published packages and proc-macro/binary API surfaces unsupported by cargo-semver-checks are reported explicitly.
spellcheck.ymlmain push and PR, manualBlockingRepository typo scan.
trufflehog.ymlmain push and PR, weekly, manualBlockingVerified-secret scan over the configured Git history range.
udeps.ymlweekly, manualInformationalcargo-udeps signal on pinned nightly-2026-08-21; command failures are tolerated.
unsafe-policy.ymlmain push and PR, manualBlockingDenies new production unsafe code and validates the reviewed exception allowlist.
wasm-matrix.ymlmain push and PR, manualBlockingCompiles Core, the public rullst facade and macros for wasm32-unknown-unknown and wasm32-wasip1.
workflow-lint.ymlmain push and PR, manualBlockingValidates the shared fuzz inventory, then Actionlint checks workflow syntax, GitHub expressions and embedded shell using an immutable container digest.
zero-panics.ymlmain push and PR, manualBlockingPanic-family Clippy lints plus generated-code regression checks for published runtime targets.

Preserved next-generation roadmap

These ideas remain valuable, but are not current guarantees:

IdeaStatus and recommendation
Loom and Shuttle concurrency explorationNot implemented — worth implementing for the small shared-state primitives that have explicit concurrency invariants. Do not apply them indiscriminately to the whole workspace.
cargo-vet dependency reviewNot implemented — worth implementing once review ownership and audit criteria are defined; an empty policy file would add ceremony without assurance.
cargo-careful and zero-allocation assertionsNot implemented — worth targeted experiments. Allocation claims need stable benchmarks and explicit hot paths before becoming gates.
PGO and BOLTNot implemented — defer until production profiles exist. Fixed throughput-gain percentages must not be promised in advance.
Chaos testing with fail-rsNot implemented — worth implementing around queues, database retries, and provider timeouts after deterministic failure contracts exist.
AFL.rs/honggfuzz differential fuzzingNot implemented — valuable after the 40 libFuzzer targets have healthy corpora and triage ownership.
Sigstore Cosign signingNot implemented. Consider it for separately distributed binaries/containers; current .crate provenance and checksums should remain the immediate priority.
Absolute “100% pure Rustls” mandateNot established and not recommended as a marketing absolute. Enforce an audited TLS dependency policy based on supported platforms and threat model instead.
Complete upstream OSS-Fuzz integrationPartial draft — worth finishing. Validate every intended target with helper.py build_fuzzers and check_build, then submit upstream; do not imply acceptance before merge.

The goal of this roadmap is stronger, reproducible evidence—not a larger number of badges or absolute claims that no finite test suite can establish.