CI Enforcement Status

May 1, 2026 · View on GitHub

Last updated: 2026-03-15

Enforcement Model

This project does not rely on post-hoc audits.

All security, correctness, and performance checks are enforced in CI. If a change violates any constraint, it is rejected automatically.

Commit → CI → Audit → PASS → Merge
                ↓
              FAIL → Block

Core Rule: If CI fails — the change does not exist.

This means:

  • A failing exploit test blocks the merge
  • A performance regression blocks the merge
  • A CT verification failure blocks the merge
  • A static analysis violation blocks the merge

Security is not reviewed after the fact — it is enforced at every commit.


Maps every CI workflow to its enforcement level: merge-blocking, advisory, or nightly-only.


Merge-Blocking Workflows

These workflows MUST pass before code merges to main or dev.

WorkflowTriggerEnforcement MechanismStatus
ci.ymlpush/PR main,devRequired status check (build, ci, test)ACTIVE
clang-tidy.ymlpush/PR (all paths)Required status check (clang-tidy) on devACTIVE
cppcheck.ymlpush/PR (all paths)Required status check (cppcheck) on devACTIVE
ct-verif.ymlpush/PR main,devRequired status check (ct-verif) on devACTIVE
security-audit.ymlpush/PR, weeklyRequired status check (asan+ubsan, werror) on devACTIVE
bench-regression.ymlpush main/dev, PR mainfail-on-alert: true (150% threshold)ACTIVE
codeql.ymlpush/PR, weeklyRequired status check (codeql) on devACTIVE

Enforcement Details

  • main branch: 2 required reviewers, signed commits, squash-only. Checks: build, ci, test.
  • dev branch: 8 required status checks: gcc-13, clang-17, asan+ubsan, codeql, ct-verif, werror, clang-tidy, cppcheck.
  • bench-regression: Not a required check (path-filtered, may not run on every PR), but fail-on-alert: true blocks PR when triggered.

Advisory Workflows

Run automatically but do not block merges. Failures are reviewed manually.

WorkflowTriggerWhat it checksFail behavior
audit-report.ymlWeekly + manual + release tags3-platform unified_audit_runnerVerdict job exits 1 on FAIL, but not a required check
sonarcloud.ymlpush/PRCode quality, coverageInformational
scorecard.ymlpush main, weeklyOpenSSF ScorecardInformational
dependency-review.ymlPRVulnerable dependenciesWarns, does not block

audit-report.yml Enforcement

The verdict job is fail-closed: it aggregates JSON reports from 3 platforms (Linux GCC, Linux Clang, Windows MSVC) and exits 1 if any verdict != PASS/AUDIT-READY. However, this workflow runs weekly/manually/on-release, not on every push/PR, so it cannot be a required merge check. The audit correctness gate for daily development is provided by the security-audit.yml workflow (ASan + UBSan + audit subset).


Nightly/Periodic Workflows

WorkflowSchedulePurpose
nightly.ymlDaily 03:00 UTCExtended differential + 30min dudect
ct-arm64.ymlPush, PR, daily 04:00Native M1 dudect timing
valgrind-ct.ymlpush main/devValgrind taint tracking
cflite.ymlpush, PR, nightlyClusterFuzzLite
mutation.ymlWeekly Sun 05:00Mutation testing

Release/Publishing Workflows

WorkflowTriggerPurpose
release.ymlTags, manualMulti-platform release artifacts
packaging.ymlRelease tags.deb/.rpm packaging
benchmark.ymlpushgh-pages performance tracking
docs.ymlpushDoxygen to GitHub Pages
bindings.ymlpush/PR12-language compile check
auditor-prep.ymlmanualAuditor-facing evidence bundle artifact

Local CI Enforcement

Local Docker CI (docker/run_ci.sh) mirrors the above tiers:

Local ModeMirrorsWhen to run
quickci.yml (gcc + clang Release)Before every commit
pre-pushci.yml + ASan + clang-tidyBefore every push
dev-gateAll 8 dev-protection checksBefore PR to dev
main-gateAll main-protection checksBefore PR to main
gh-parityFull GH Actions matrixBefore release

Local Fail-Open Patterns (Documented)

The following || true patterns exist in local scripts. They are mitigated by post-hoc verdict checking but not ideal:

FilePatternMitigation
docker/run_ci.sh:602,663unified_audit_runner ... || trueJSON verdict checked via jq afterward
ci/local-ci.sh:432unified_audit_runner ... || trueJSON verdict checked via grep afterward
ci/local-ci.sh:184ctest -T MemCheck || trueValgrind log content parsed afterward

These are acceptable for local development (the exit code swallowing prevents noisy false-fail on segfault during memcheck), but the verdict/log parsing afterward ensures real failures are caught.


Flaky Test Registry

Tests that may produce non-deterministic results on shared/virtualized CI runners:

TestCausePolicy
ct_sidechannelStatistical timing (dudect, 600s)Advisory on shared CI, strict on dedicated hardware
ct_sidechannel_smokeStatistical timing (120s, CI-safe subset)Advisory on shared CI
Benchmark regressionCPU frequency scaling, neighbor noise150% threshold (generous) on shared runners

Assurance Expansion In Progress

The following assurance-system hardening work is now tracked in-repo:

ArtifactPurpose
docs/ASSURANCE_LEDGER.mdCanonical claim-to-evidence map
docs/AI_AUDIT_PROTOCOL.mdGoverns AI-assisted adversarial review
docs/AI_REVIEW_EVENTS.jsonMachine-readable record of accepted/rejected AI review findings
docs/GPU_BACKEND_EVIDENCE.jsonMachine-readable GPU backend status, publishability, and artifact requirements
docs/FORTRESS_ROADMAP.mdTracks the remaining fortress-grade assurance gap
docs/SECURITY_AUTONOMY_PLAN.mdSecurity autonomy framework and 30-day phase plan
docs/FORMAL_INVARIANTS_SPEC.jsonMachine-readable formal invariant specifications
docs/AUDIT_SLA.jsonAudit SLA/SLO enforcement definitions
docs/SECURITY_AUTONOMY_KPI.jsonAuto-generated autonomy score and gate results

All other tests are deterministic and must always pass.

The AI review-event log is enforced locally through:

  • python3 ci/preflight.py --ai-review

and schema-validated through:

  • python3 ci/validate_assurance.py

GPU backend publishability is enforced locally through:

  • python3 ci/preflight.py --gpu-evidence

Security autonomy gates are enforced locally through:

  • python3 ci/preflight.py --autonomy
  • python3 ci/security_autonomy_check.py --json

and schema/policy-validated through:

  • python3 ci/validate_assurance.py