Skip to main content

Add a ChangeOps Gate to CI

This guide wires the ChangeOps gate into a CI pipeline so every pull request produces a decision artifact before merge. The example uses GitHub Actions, but the same steps apply to any runner that can call the FleetForge CLI.

Prerequisites

  • FleetForge runtime accessible from CI (self-hosted runner or network tunnel).
  • Service account with writer access to the ChangeOps API.
  • fleetforge-ctl installed on the runner image.
  • Eval packs and replay workflows that generate the evidence referenced in the change bundle.

1. Collect change evidence

Produce a JSON bundle that captures the required inputs (diff summary, eval results, replay IDs, budget impact). Store it as change.json (or similar).

Example shell snippet:

cat <<'JSON' > change.json
{
"change_id": "${GITHUB_SHA}",
"diff": {
"files": $(git diff --name-only origin/main...HEAD | jq -R . | jq -s .),
"novelty_score": 0.82
},
"evals": {
"owasp_pack": $(cat artifacts/owasp-results.json)
},
"replays": [
{ "run_id": "replay-123", "parity": "match" }
],
"budget": {
"projected_delta_usd": 2.15
}
}
JSON

Adapt the payload to include the evidence your ChangeOps policies expect.

2. Call the gate from CI

Invoke fleetforge-ctl gates check with the bundle. The command returns a JSON decision (allow, follow_up, or deny) plus recommendations.

fleetforge-ctl gates check \
--endpoint "${FLEETFORGE_API_HTTP}" \
--token "${FLEETFORGE_API_TOKEN}" \
--input change.json \
--output gate-decision.json

Store the output file as a build artifact so reviewers can inspect it.

3. Enforce the decision

Add a step that fails the pipeline on deny, annotates follow_up, and allows merges on allow. Example (GitHub Actions):

decision=$(jq -r '.decision.effect' gate-decision.json)
case "$decision" in
allow)
echo "Gate passed."
;;
follow_up)
echo "::warning::ChangeOps follow-up required. See gate-decision.json for details."
exit 1
;;
deny)
echo "::error::ChangeOps gate denied the change."
cat gate-decision.json
exit 1
;;
*)
echo "::error::Unknown ChangeOps decision: $decision"
exit 1
;;
esac

Require the workflow to succeed before merging.

4. Record follow-ups

When the gate returns follow_up, approvers acknowledge the requirement via the CLI or API:

fleetforge-ctl gates followup \
--gate "$(jq -r '.decision.gate_id' gate-decision.json)" \
--note "Validated eval coverage for prompt pack XYZ."

The acknowledgement becomes part of the audit trail.

5. Publish the artifact

Upload both change.json and gate-decision.json as workflow artifacts (or store them with your release notes). This keeps the evidence accessible for audit and incident response.

Next steps