Sigil Quickstart: Gate an Agent PR
At the end of this quickstart, Sigil will evaluate a PR ref against a baseline and emit an auditable ALLOW, REVIEW, or BLOCK decision. In GitHub Actions, the same loop posts a status check that can protect your merge queue.
Prerequisites
Section titled “Prerequisites”-
A
sigilbinary on yourPATH:Terminal window curl -fsSL https://runsigil.com/install.sh | sh -
Docker and Docker Compose.
-
A service with a
docker-compose.ymlthat Sigil can deploy. -
At least one LLM provider configured for judge scenarios: Ollama, OpenAI, Anthropic, or OpenRouter.
-
A PR ref or commit ref to evaluate, such as
pull/42/head.
1. Initialize a service
Section titled “1. Initialize a service”sigil init --service apiThis creates .sigil/sigil.toml, the .sigil/ state directory, and scenarios/api/.
2. Add a scenario
Section titled “2. Add a scenario”Scenario source lives at the project root under scenarios/<service>/, where it
is findable and editable like any other source. .sigil/ holds only tool state —
config, blobs, ledger, proofs.
mkdir -p scenarios/api/smoke$EDITOR scenarios/api/smoke/health.luaA minimal health-check scenario:
-- scenarios/api/smoke/health.luareturn { title = "Service responds to /health", priority = "P0", policy = { capabilities = {"http"} },
run = function() local res = sigil.get("/health") expect(res.status == 200) expect(res.json.ok == true) end,}For structured JSON assertions, sigil.json.decode(res.body) and the
capability-free sigil.data helpers
provide immutable typed values and bounded traversal without a shell process.
Ordinary res.json field assertions above remain valid.
3. Lint scenarios and generate editor types
Section titled “3. Lint scenarios and generate editor types”sigil scenario lintsigil generate-typesgenerate-types writes .sigil/types/sigil.lua for editor autocomplete and hover docs.
4. Evaluate a PR against a baseline
Section titled “4. Evaluate a PR against a baseline”sigil eval pull/42/head --service apiSigil deploys the PR and baseline side by side, decrypts the visible plus holdout scenario bundle, runs the scenarios against both environments, and writes eval.complete to the ledger.
Expected shape:
visible 1.00holdout 0.82overall 0.94ledger eval.complete eval_01HPXG5KQ7J9W45. Emit the merge decision
Section titled “5. Emit the merge decision”sigil decide pull/42/head --service apiExit codes:
| Decision | Exit | Meaning |
|---|---|---|
ALLOW | 0 | Policy and trust gates passed. |
REVIEW | 1 | Human review required. |
BLOCK | 2 | Regression or policy failure. |
A new service returns REVIEW at first, even for a clean eval. Only auto mode can ALLOW, and since 0.36.0 the service must also earn trust: set mode = "shadow" explicitly (sigil init leaves it unset, and an unset mode does not earn trust), let it collect clean evals, then move it to auto. See Trust Model.
GitHub status check path
Section titled “GitHub status check path”Once the local loop works, wire the same command sequence into GitHub Actions:
sigil ci owner/repo#42 --service api --comment --auto-mergeRead CI Integration for the full workflow, permissions, branch protection, and merge queue setup.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Check |
|---|---|
| Docker deploy fails | Confirm docker compose up works without Sigil. |
| Scenario lint fails | Check capability declarations and Lua syntax. |
| Judge scenario fails before running | Confirm your [judge] provider config and keys. |
REVIEW appears unexpectedly | Read the rationale codes in sigil decide --format json. A clean run in shadow or advisory is capped (shadow_mode_cap). In auto, trust_level_insufficient:none means the service has not earned trust yet: it starts at NONE and earns LOW after 20 clean evals in shadow mode. Any regression also REVIEWs (regression_detected). |
Holdout key unavailable (scenarios_not_loaded) | Expose the age identity as AGE_KEY or AGE_KEY_FILE. An eval whose holdouts did not load cannot ALLOW. |
| GitHub status does not post | Confirm token permissions include statuses: write and pull-requests: write. |
| No scenarios found, but the files are there | If they live under .sigil/scenarios/, this project predates 0.27. Run sigil migrate (dry-run by default; add --apply). |
Next steps
Section titled “Next steps”- Read Writing Scenarios for the Lua DSL.
- Read Using WebAssembly Plugins to add reproducible
require("wasm.name")dependencies. - Read CI Integration to post GitHub checks.
- Read Trust Model to configure earned-autonomy thresholds.
- Read Dark Factory to understand why the authoring agent never sees holdout scenarios.