Your agent already writes policies.Give it the Tirith vocabulary.
Ask any agent for a guardrail and it writes plausible JSON against a schema it is guessing at. The Tirith skills give it the actual condition list, the argument key each provider reads, and the commands to check its own work before handing anything back.
Install them in your client
One command, and the file is self-contained: copy it into any repository and your agent picks it up.
- Claude Code · Claude Desktop
Drop the folder into your repository. It is picked up automatically: no config file, no restart. Works in any project, not just this one.
curl -fsSL https://stackguardian.github.io/tirith/skill.sh | sh - Cursor
A single rule file scoped with globs, so it attaches by itself the moment a policy file is open and stays out of the way otherwise. Self-contained: it needs nothing else.
curl -fsSL https://stackguardian.github.io/tirith/skill.sh | sh -s -- --cursor - Codex · Zed · anything reading AGENTS.md
Fetch the pack, then point AGENTS.md at it. One file at the repository root is read by a growing number of clients, and the pack beside it keeps the references resolvable.
curl -fsSL https://stackguardian.github.io/tirith/skill.sh | sh printf '\n## Tirith policies\nSee %s/SKILL.md\n' .claude/skills/tirith-policies >> AGENTS.md
Check it workedAsk for a policy in plain words: every bucket needs an Owner tag. With the pack loaded your agent names a real condition type and the argument key that provider actually takes. Without it, it invents one that reads perfectly and gates nothing.
Working in VS Code? The editor setup wires lint and evaluate to one keystroke, so the policy your agent just wrote is proved before you read it. The skills teach your agent the vocabulary. To let it run a policy as well, install Tirith so the command is on PATH. one pip command, and the skill's own install reference covers pinning a version.
Add Tirith to any pipeline
Ask your agent for a policy gate and, with the pack loaded, it knows the install is a git URL rather than PyPI, which plan document each provider reads, and that exit 3 and exit 1 have to reach the job differently.
“Add a Tirith policy gate to our pipeline”
One sentence, and no need to name your CI: the pack covers GitHub Actions, GitLab, Bitbucket, Jenkins, Azure DevOps, CircleCI and any container runner, so the agent writes for whichever one it finds in the repository. What comes back is that pipeline file, a policy under .tirith/policies, and a job that fails on exit 3 and reports a tooling problem on exit 1 instead of confusing the two.
curl -fsSL https://stackguardian.github.io/tirith/skill.sh | shpip install "git+https://github.com/StackGuardian/tirith.git@1.2.1"
tirith -policy-path .tirith/policies -input-path plan.json --fail-on-errorreference/pipelines.mdGitHub Actions, GitLab, Bitbucket, Jenkins, Azure DevOps, CircleCI, any container runner, and the pre-commit hooks.reference/install.mdInstall from git, because the name on PyPI belongs to something else. Pinning a tag, the optional interface, the Python floors.reference/debug-ci.mdStart from a red build and end at the rule and the resource, ordered by what is most often the answer.
What it covers
Fifteen references across three skills, each a file in the skills folder. Your agent loads the entry skill and pulls the rest in as the task needs them.
- Add it to a pipeline
reference/pipelines.mdGitHub Actions, GitLab, Bitbucket, Jenkins, Azure DevOps and CircleCI: the plan step, the install, the pre-commit hooks, and making each exit code do the right thing to the job. - Install Tirith
reference/install.mdInstall from git, because it is not on PyPI, and the name there belongs to something else. Pinning a tag, the optional interface, and the Python floors. - Debug a red build
reference/debug-ci.mdStart from a failed job and end at the rule and the resource, ordered by what is most often the answer.
- Generate a standards set
SKILL.mdRead the Terraform or OpenTofu you already run, propose the standards it would support, and write one policy per rule. Includes the guard every type-scoped rule needs to stay green on unrelated changes. - The standards catalogue
reference/standards.mdRequired tags, tag value shape, naming per resource type, allowed regions, forbidden types, size ceilings, encryption, version pinning, and the trap attached to each.
- Author a policy
SKILL.mdTurn an intent, “every resource needs an owner tag”, into valid policy JSON: the provider, the operation, the condition and the expression that ties them together. - The schema
reference/schema.mdThe closed vocabulary. Thirteen condition types, each provider’s operations, and the argument key that differs per provider, which is the one an agent otherwise invents. - Validate it
reference/validate.mdThe trap classes that produce a policy which looks right and gates nothing, and why a clean shape is not a working rule. tirith lint runs that same check from the command line, and tirith ui runs it as you type. - Run it and read the verdict
reference/verdicts.mdExit 0, 1 and 3 and what each should do to a job, why final_result: null is not a pass, and how to find the resource behind a failure. - Prove it works
examples/required-tags/A policy, a plan that fails it and a plan that passes it. The agent runs both before it hands anything back, because a rule only ever seen passing is untested.
- OpenTofu and Terraform plans
reference/terraform-plan.mdThe seven operations, why attribute cannot see a destroy, replacement ordering, and why count measures the module rather than the change. - Kubernetes, Infracost, JSON
reference/other-providers.mdattribute_path with kubernetes_kind, cost ceilings and the misspelled type that sums to zero and passes, and get_value wildcards for any other document. - One policy, many environments
reference/variables.mdParameterise with -var and -var-path, and the var. prefix that is silently required.
- Organization policies
reference/platform.mdtirith platform check: central policy across many repositories, what is masked on your runner before anything is uploaded, and which flags are required.
How a policy gets written
Their one standing instruction is never to hand back a policy it has not run. A policy that matches nothing looks identical to one that works.
- 01
Ask
Describe the guardrail in a sentence. The skill supplies the schema, so the agent picks a real provider, operation and condition instead of guessing.
- 02
Check the shape
Check the condition type and every argument key against the closed vocabulary. An invented one is ignored rather than rejected, so the check reads nothing and passes.
- 03
Check the meaning
Only evaluation proves a policy matches anything. Run it against a document that should fail it.
- 04
Ship it
Commit the policy, add the gate to the pipeline, and let the exit code decide.
What it does not do
- Nothing here changes your infrastructure.
- The commands read documents and return verdicts. An agent may propose a code change; a human reviews and merges it, as before.
- A drafted policy is a draft.
- Generated JSON is worth no more than the evaluation that follows it.
- The engine decides, not the model.
- Every verdict comes from the same evaluator your pipeline runs.
- Evaluation stays on your machine.
- Your agent may be a hosted model, which is between you and your agent. Tirith itself makes no network call unless you use organization mode.
Across every repository, not just this one.
An agent with the skill can write and prove a policy in the repository in front of it. What it cannot see is which of your two hundred repositories have no gate at all.