Local evals with your IDE agent are the starting point. CI integration is the next step: it makes regression detection automatic, gates merges on passing checks, and creates an audit trail for every prompt change.Documentation Index
Fetch the complete documentation index at: https://bintzgavin-apastra-14.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
When to upgrade from local to CI
| Signal | What it means |
|---|---|
| More than one engineer edits prompts | You need merge gates — local evals don’t protect the shared branch |
| Prompt changes ship without review | You need a required status check that blocks merge |
| You want an audit trail | CI creates a durable record of every eval run tied to a commit SHA |
| Baselines need to be shared | CI writes baselines to the promptops-artifacts branch so everyone uses the same reference |
Basic CI: two workflows
For most teams, two workflows cover the full loop — eval on pull requests, release on tag push.- prompt-eval.yml
- prompt-release.yml
Trigger: Pull requests with changes to This workflow delegates to
promptops/**What it does: Runs the regression gate on every PR that touches prompt specs, datasets, evaluators, or policies. Blocks merge if a regression is detected.regression-gate.yml (the reusable workflow), which:- Detects changed files in
promptops/harnesses/**,promptops/prompts/**,promptops/datasets/**, andpromptops/policies/*.yaml - Skips if no evaluable files changed
- Fetches the latest regression report from the
promptops-artifactsbranch - Evaluates the report status and posts a step summary with per-metric evidence
- Checks cost budgets against suite
budgets.cost_budgetlimits - Exits non-zero (blocking merge) if the report status is not
pass
Full CI: six workflows
For enterprise teams needing fine-grained control, apastra ships six individual workflows. Each has a distinct responsibility:| Workflow | Trigger | What it does |
|---|---|---|
regression-gate.yml | Pull requests to main; also callable via workflow_call | Detects changed files, fetches the regression report from artifacts branch, evaluates pass/fail, checks cost budgets, posts step summary, blocks merge on failure |
promote.yml | Manual dispatch (workflow_dispatch) or release publish | Verifies an approval state record exists for the digest, generates an append-only promotion record, commits it to the promptops-artifacts branch, then calls deliver.yml |
deliver.yml | Called by promote.yml via workflow_call | Reads the promotion record, resolves the channel and digest, iterates over promptops/delivery/*.yaml targets, and executes the sync for each matching target |
immutable-release.yml | Tag push (*); also callable via workflow_call | Packages promptops/, computes digest, attests build provenance, creates an immutable GitHub Release with the bundle and digest |
auto-merge.yml | Pull request opened, reopened, or synchronized | Resolves PROGRESS.md merge conflicts automatically, then enables squash auto-merge for PRs that pass all required checks |
prompt-eval.yml | Pull requests touching promptops/** | Entry point for the basic CI setup — delegates to regression-gate.yml |
regression-gate.yml, immutable-release.yml, and deliver.yml are reusable workflows (they declare workflow_call as a trigger). This means you can call them from other workflows in the same repo or from workflows in other repos, which lets a platform team standardize PromptOps across many repositories.What the regression gate does in detail
The regression gate is the most important workflow for day-to-day governance. Here is what happens step by step when a PR is opened:Detect changed files
The workflow uses
tj-actions/changed-files to detect whether any of the following changed:promptops/harnesses/**promptops/prompts/**promptops/datasets/**promptops/policies/*.yaml
Fetch the artifacts branch
When evaluable files changed, the workflow fetches
reports/regression_report.json and reports/run_manifest.json from the promptops-artifacts branch. These were written by the most recent eval run.Evaluate the regression report
The workflow reads the report and posts a step summary table with columns: Metric, Status, Candidate, Baseline, Delta, Message. Any failing metrics are annotated as errors in the PR.
Check cost budgets
If a
run_manifest.json includes a total_cost field, the workflow compares it against the budgets.cost_budget declared in each suite file. A cost overrun fails the gate.CODEOWNERS for prompt governance
Use aCODEOWNERS file to require human review of any prompt, policy, or evaluator change:
- Any PR that modifies a file in
promptops/prompts/requires at least one approved review from@your-org/ai-qualitybefore merge. - This is enforced by GitHub branch protection rules — not just convention.
Branch protection: required status checks
Configure branch protection onmain to require the regression gate before merge:
- Go to Settings → Branches → Branch protection rules.
- Add a rule for
main. - Enable Require status checks to pass before merging.
- Add
gate(the job name fromregression-gate.yml) as a required check. - Optionally enable Require a pull request before merging and Require review from Code Owners.
main unless:
- The regression gate job passed (no regression detected, no cost budget exceeded)
- At least one CODEOWNERS reviewer approved (if CODEOWNERS is configured)
Auto-merge for passing PRs
Theauto-merge.yml workflow enables squash auto-merge for PRs that pass all required checks. It fires on pull_request events (opened, reopened, synchronized) and:
- Resolves any
PROGRESS.mdmerge conflicts automatically using a union merge strategy. - Calls
gh pr merge --auto --squashto enable auto-merge once all required checks are green.
In the apastra repo, auto-merge is scoped to PRs from
google-labs-jules and BintzGavin. For your own repo, update the if: conditions to match your autonomous agent’s login or a specific label.Artifacts branch: keeping derived data out of main
Regression reports, run manifests, promotion records, and baselines are derived data — they should not live onmain alongside your source files. Apastra uses a separate promptops-artifacts branch as an append-only store: