Guides
Gate CI on a verdict
Generate an artifact in CI and fail the build unless it comes back valid.
If an artifact your build ships is made from an intent, make it in CI through
Forma and let the verdict decide: valid writes the artifact and its citation,
anything else fails the build. Forma does not check an artifact you already have
— it checks the one it returns.
The script
#!/usr/bin/env bash
set -euo pipefail
answer=$(curl -sS --fail-with-body \
"https://api.formalogic.io/v1/oracles/chart/ask" \
-H "Authorization: Bearer $FORMA_API_KEY" \
-H "Content-Type: application/json" \
-d @intent.json)
status=$(jq -r .status <<<"$answer")
case "$status" in
valid)
jq -r .result <<<"$answer" > artifact.json
echo "checked against $(jq -r .verified_by <<<"$answer")"
;;
invalid)
echo "::error::the check refused it: $(jq -r .detail <<<"$answer")"
exit 1
;;
error)
echo "::warning::the oracle could not answer; nothing was billed"
exit 75 # EX_TEMPFAIL — retry the job, do not fail the branch
;;
*)
echo "::error::unexpected answer: $status"
exit 1
;;
esac--fail-with-body matters: without it curl exits 0 on a 401 and the script
parses an error envelope as a verdict.
Distinguish "refused" from "unavailable"
invalid means the artifact is wrong — fail the build; a human should look.
error means we were unavailable — that is not the branch's fault. Exiting 75
rather than 1 lets a retry policy pick it up without a red mark against someone's
commit.
Keep the citation
Write verified_by into the build output next to the artifact. It is what tells
a reader six months later which version of the rules the file in the repository passed.
Budget
Every gated build spends credits. On a busy repository, gate on merge rather than on every push. Usage shows what this period has spent and Credits your balance — check both before turning it on across many pipelines.