CI/CD Integration
Gate your PRs on semantic proofs, not just green tests.
Overview
Tests prove that code runs. aura prove proves that code does the thing you said it would do. aura pr-review proves that the code change matches its stated intent. Running both in CI raises your merge gate from "tests pass" to "tests pass and the change is semantically consistent with its intent."
Aura runs in any CI:
- GitHub Actions (covered in GitHub integration)
- GitLab CI (covered in GitLab integration)
- CircleCI
- Jenkins
- Buildkite
- Drone
- self-hosted TeamCity, Bamboo, Azure Pipelines
This page covers generic CI patterns: exit codes, caching, containerization, and how to make Aura a hard gate without slowing the pipeline.
Setup
Binary distribution
A single static binary. Install in any Linux/macOS container:
curl -fsSL https://aura.build/install.sh | sh
Or pin a version:
curl -fsSL https://aura.build/install.sh | sh -s -- --version 0.14.1
Or use the official image:
ghcr.io/naridon-inc/aura:0.14.1
ghcr.io/naridon-inc/aura:latest
The image is ~40 MB, Alpine-based, and contains aura + git. It is designed as a CI image, not a dev image.
Shadow branches
CI needs shadow branches to compute semantic diffs. Fetch them before running Aura:
git fetch origin '+refs/heads/aura/*:refs/remotes/origin/aura/*'
If shadow branches don't exist yet, aura prove degrades gracefully — it computes what it can from the current working tree and warns about missing history.
Exit Codes
Every Aura CI-relevant command returns deterministic exit codes so pipelines can branch on them.
aura prove
| Code | Meaning | Typical action | |------|---------|----------------| | 0 | All goals proved. | Pass. | | 1 | Some goals failed. | Fail the build. | | 2 | No goals logged for this branch. | Warn or pass (configurable). | | 3 | Engine error (missing shadow, corrupt index). | Fail with alert to platform team. | | 4 | Timeout. | Retry once, then fail. |
aura pr-review
| Code | Meaning |
|------|---------|
| 0 | No violations at or above fail_on threshold. |
| 1 | Violations found. |
| 2 | Intent not logged. |
| 3 | Engine error. |
aura doctor
| Code | Meaning | |------|---------| | 0 | Healthy. | | 1 | Warnings (missing hooks, stale snapshots). | | 2 | Errors (corrupt DB, orphaned sessions). |
Exit codes are stable across versions. CI scripts can rely on them.
Configuration
CircleCI
.circleci/config.yml:
version: 2.1
jobs:
aura:
docker:
- image: ghcr.io/naridon-inc/aura:latest
steps:
- checkout
- run:
name: Fetch shadow branches
command: git fetch origin '+refs/heads/aura/*:refs/remotes/origin/aura/*'
- run:
name: aura prove
command: aura prove --base origin/main
- run:
name: aura pr-review
command: aura pr-review --base origin/main --format markdown --output review.md
- store_artifacts:
path: review.md
workflows:
review:
jobs:
- aura:
filters:
branches:
ignore: main
Jenkins
pipeline {
agent {
docker { image 'ghcr.io/naridon-inc/aura:latest' }
}
stages {
stage('Shadow') {
steps {
sh "git fetch origin '+refs/heads/aura/*:refs/remotes/origin/aura/*'"
}
}
stage('Prove') {
steps {
sh 'aura prove --base origin/main'
}
}
stage('Review') {
steps {
sh 'aura pr-review --base origin/main --format markdown --output review.md'
archiveArtifacts artifacts: 'review.md'
}
}
}
post {
failure {
script {
def review = readFile 'review.md'
// Post to Slack / PR / etc.
}
}
}
}
Buildkite
steps:
- label: "aura"
command:
- git fetch origin '+refs/heads/aura/*:refs/remotes/origin/aura/*'
- aura prove --base origin/$BUILDKITE_PULL_REQUEST_BASE_BRANCH
- aura pr-review --base origin/$BUILDKITE_PULL_REQUEST_BASE_BRANCH
plugins:
- docker#v5.0.0:
image: "ghcr.io/naridon-inc/aura:latest"
if: build.pull_request.id != null
Azure Pipelines
steps:
- task: Docker@2
inputs:
command: run
arguments: >
-v $(Build.SourcesDirectory):/src -w /src
ghcr.io/naridon-inc/aura:latest
sh -c "git fetch origin '+refs/heads/aura/*:refs/remotes/origin/aura/*' &&
aura prove --base origin/$(System.PullRequest.TargetBranch) &&
aura pr-review --base origin/$(System.PullRequest.TargetBranch)"
Caching
Aura's AST index is deterministic given the commit SHA. Cache it between pipeline runs for a 5–10x speedup on large repos:
# GitHub Actions example, reusable pattern
- uses: actions/cache@v4
with:
path: .aura/index
key: aura-index-${{ hashFiles('**/*.rs', '**/*.ts', '**/*.py') }}
restore-keys: aura-index-
Cache keys should include every source-file extension Aura indexes. The cache is invalidated on any source change, which is correct — the index must match the tree.
Examples
Hard gate
Fail the build if aura prove fails or if PR review finds error-level violations. This is the recommended baseline:
aura prove --base origin/main || exit 1
aura pr-review --base origin/main --fail-on error || exit 1
Soft gate (advisory mode)
For teams rolling out Aura incrementally:
aura prove --base origin/main || echo "::warning::aura prove failed (advisory)"
aura pr-review --base origin/main --fail-on never
This runs the checks and posts the report, but never fails the build.
Parallel pipelines
aura prove and aura pr-review share an AST parse step. Run them in the same job to reuse it. If you must split them across jobs, share the cached index:
# Job 1
aura index --output .aura/index.bin
# Job 2 (depends on Job 1)
aura prove --index .aura/index.bin
# Job 3 (depends on Job 1)
aura pr-review --index .aura/index.bin
Gating on a specific goal
aura prove "Checkout flow redirects to success page on completed payment"
Useful for "I care about this one behavior this PR must preserve" gates. Multiple --goal flags are allowed.
Intent-required enforcement
Reject PRs that never called aura_log_intent:
aura pr-review --require-intent --fail-on error
Exit code 2 is returned if no intent exists; turn it into a failure with --require-intent.
Troubleshooting
Pipeline is slow. Enable caching of .aura/index. Expect 30s–2m parse time without cache on mid-sized (~100K LOC) repos; <10s with cache.
aura prove returns 2 for every PR. No intents are being logged. The pre-commit hook isn't firing locally. See pre-commit hook. As an interim, enable --require-intent only for main merges, not every PR.
Shadow branch fetch fails. The CI bot user lacks read access to aura/* refs. Either widen the token scope or push shadow branches to a mirror repo.
Different results on CI vs local. Almost always a version mismatch. Pin aura in CI (--version 0.14.1) and locally.
Timeouts on very large repos. Set AURA_PARSE_TIMEOUT=300 (seconds) and consider partitioning: aura prove --scope apps/web. Aura supports scope-restricted runs that parse only a subtree.
Running Aura in Matrix Jobs
If your CI runs a matrix (multiple OSes, multiple language versions), avoid running Aura once per matrix cell. Semantic analysis is platform-independent — running it N times wastes N-1 runs and risks races on shadow-branch pushes. Run Aura in a single dedicated job, gated on the matrix jobs' success:
jobs:
test:
strategy:
matrix: { os: [ubuntu-latest, macos-latest, windows-latest] }
steps: [ ... your tests ... ]
aura:
needs: test
runs-on: ubuntu-latest
steps: [ ... aura commands ... ]
This pattern keeps the semantic gate deterministic and fast.
Reporting and Metrics in CI
Every aura prove and aura pr-review run emits a machine-readable summary to .aura/ci-summary.json. Archive it as an artifact to build dashboards:
{
"run_id": "run_01HW3K...",
"branch": "feat/login",
"base": "main",
"timestamp": "2026-04-21T14:23:09Z",
"prove": { "goals": 4, "passed": 4, "failed": 0, "duration_ms": 1823 },
"review": {
"findings": { "error": 0, "warning": 2, "info": 5 },
"nodes_changed": 12,
"duration_ms": 2410
}
}
Feed this into your observability stack (Datadog, Grafana) to track CI-side semantic health over time: average Prove duration, error-finding rate per team, node churn.
Authoring a Minimal CI Wrapper
If your CI isn't covered above, the generic pattern is three commands:
git fetch origin '+refs/heads/aura/*:refs/remotes/origin/aura/*'
aura prove --base origin/main
aura pr-review --base origin/main --format markdown --output review.md
Whatever CI you are on, reproduce those three lines in its syntax. Every other integration detail — annotations, artifacts, merge gates — is a nice-to-have on top of this minimum.
Self-Hosted Runners
For self-hosted GitHub Actions or GitLab runners, pre-install Aura in the base AMI/image. This saves the install step on every job and makes the runner's version stable. The official image ghcr.io/naridon-inc/aura is built reproducibly and has SBOM attestations published to the same registry.
If your org policy forbids pulling images from public registries, mirror the release tarball internally:
curl -fsSLO https://aura.build/releases/0.14.1/aura-x86_64-linux.tar.gz
sha256sum -c aura-x86_64-linux.tar.gz.sha256
All releases are published with Sigstore-signed SHA256 manifests.
Security Considerations in CI
A few practices worth enforcing:
- Scope the CI token.
AURA_TOKENin CI should haveread_intents,write_impacts, andread_snapshots— nothing broader. Avoid giving CIwrite_messagesunless you intentionally want CI to post into team chats. - Redact in logs. Set
AURA_LOG_REDACT=trueto strip sensitive fields from daemon logs written to CI artifacts. - Don't cache secrets in
.aura/. The cache directory is for the AST index only. Aura never writes tokens there, but a misconfigured hook could; a.gitignoreentry of.aura/secrets*belongs in every repo.
Monorepo Strategies
Large monorepos benefit from two patterns:
- Scoped Prove runs. Run
aura prove --scope apps/webin each app's pipeline rather than one mega-run. Each team owns its Prove goals and sees only its failures. - Shared index cache. One cache key per language —
aura-index-rust-${hashFiles('**/*.rs')}— so the Rust app's cache doesn't invalidate when TS changes.
See Also
- GitHub integration
- GitLab integration
- Pre-commit hook
- Semantic diff
- Custom plugins — drive your own CI steps through the plugin API.