Reference

CI Validation

Read-only CI gates for contract, readiness, and workspace validation.

referenceautomation buildersintermediatestable2026-05-30

Purpose

Hosted validation is the read-only CI path for ota.

Use it when a pull request or pipeline needs to verify a repo or workspace without mutating it, so reviewers get a gate instead of a surprise edit.

  • deterministic gates before merge
  • machine-readable readiness data for CI
  • repo and workspace findings without local mutation
  • annotations or check summaries derived from ota JSON

Repo gating

Use these when CI should judge one repo directly and stay read-only.

Use this surface for contract validation, readiness diagnosis, container-boundary diagnosis, and checks-only gates when the integration boundary is one repo.

Repo gatingbash
ota validate --jsonota doctor --jsonota doctor --container --persistent --jsonota check --json

Workspace gating

Use these when the orchestration layer is the thing being judged rather than one repo in isolation.

Use this surface for workspace validation, readiness diagnosis, checks-only gating, and ordered remediation when the integration boundary is the workspace orchestration layer.

Workspace gatingbash
ota workspace validate --jsonota workspace doctor --jsonota workspace check --jsonota workspace explain --json

Inventory and preflight

Use these when CI or a hosted validator needs inventory and roll-up data without acting like an execution wrapper.

Use this surface for runnable inventory and workspace roll-up context without mutating anything or pretending to execute work.

Inventory and preflightbash
ota workspace tasks --jsonota workspace list --json

Operational rule

  • use hosted validation when the repo should be judged, not changed, so CI stays read-only
  • keep the CI job thin and let ota own the repo-readiness logic, so the gate stays trustworthy
  • use JSON output as the source of truth for gates and annotations, so humans and automation read the same result

Example CI flow

CI and Pipelinesyaml
name: ci on:  pull_request: jobs:  validate:    runs-on: ubuntu-latest     steps:      - uses: actions/checkout@v5      - name: Install ota        run: curl -fsSL https://dist.ota.run/install.sh | sh      - name: Validate contract        run: ota validate --json | tee .ota-validate.json      - name: Diagnose readiness        run: ota doctor --json | tee .ota-doctor.json      - name: Render annotations        run: ota doctor --json | ota annotations --mode doctor --format github --input -

Official GitHub Action

Use ota-run/action@v1 when you want the GitHub-native wrapper instead of hand-written JSON glue.

It keeps the gate read-only while publishing the summary, annotations, pull-request comment, and receipt artifact from the ota JSON contract.

  • default command is receipt, which is the better CI default for archive-friendly read-only output
  • the action installs ota by default on Linux, macOS, and Windows runners
  • the canonical pull-request gate needs actions: read plus pull-requests: write permissions
GitHub Actionyaml
permissions:  actions: read  contents: read  pull-requests: write steps:  - uses: actions/checkout@v5  - name: Publish ota readiness    uses: ota-run/action@v1    with:      command: receipt      archive: true      github-token: ${{ github.token }}

Use cases

  • a pull request needs a blocking readiness check before merge
  • a CI pipeline wants annotations instead of raw JSON
  • a workspace gate needs to show which repo is blocking the roll-up
  • a platform team wants consistent validation results across repos
  • a repo owner wants a machine-readable summary without mutating local state

What to fail on

  • ok: false
  • summary.error_count > 0 for validation commands
  • any error or errors
  • any severity: error
  • non-zero exit when validation is expected to pass

Runner boundary

GitHub Actions or your CI runner can still provision infrastructure such as service containers.

ota removes duplicated repo logic above the runner by keeping validation, readiness, environment intent, and task execution in the contract.

  • ota can prepare declared repo services through ota up
  • ota does not replace the CI runner, OS package manager, or language installer on the host

Annotation mapping

Use the JSON payload as the source of truth and turn it into annotations or check-run summaries without re-parsing text output.

  • use summary.primary_blocker as the headline when present
  • emit one annotation per finding
  • finding_groups is additive and can be used for grouped summary lines; each entry includes a stable semantic action_key
  • treat severity: error as blocking
  • treat severity: warn as non-blocking unless policy says otherwise
  • use why as the annotation body and next as the suggested fix

Keep it read-only

  • do not run ota init
  • do not run ota detect --write
  • do not run ota workspace init --bootstrap
  • do not infer behavior from human text output

Portable CI adapter

ota annotations is the canonical JSON-to-CI adapter.

Use --format plain for provider-neutral log lines, --format github for GitHub-native annotations, or --format markdown when a step summary or pull-request comment should reuse ota’s own wording.

The renderer keeps the primary blocker singled out once, labels Provenance: plus Next: when those fields exist, and now covers receipt-diff baseline gates as well as doctor output.

Example adapterbash
ota doctor --json | ota annotations --mode doctor --format github --input -ota workspace doctor --json | ota annotations --mode workspace-doctor --format github --input -ota doctor --json | ota annotations --mode doctor --format markdown --input - >> "$GITHUB_STEP_SUMMARY"ota receipt --json --baseline .ota/receipts/latest.json .   | ota annotations --mode receipt-diff --format markdown --input - >> "$GITHUB_STEP_SUMMARY"