Rules that connect calls¶
A per-call checker can say "never run terraform apply". It can't say "apply only the plan
that was reviewed": that depends on an earlier call, and on what its arguments were.
AgentLTL can. A $variable in a before rule must take the same value in both calls.
Promote only what staging ran¶
- id: promote-what-staging-ran
before:
first: {tool: helm_upgrade, with: {chart: $chart, version: $v, namespace: staging}}
then: {tool: helm_upgrade, with: {chart: $chart, version: $v, namespace: prod}}
scope: project # the staging deploy may have been yesterday, in another session
Staging on 1.5.2 doesn't let 1.6.0 into prod, and neither does another chart on 1.6.0: the
two variables must match together. Under the hood this is: for every chart c and version
v, every helm_upgrade(c, v, prod) comes after a helm_upgrade(c, v, staging).
Apply exactly the reviewed plan¶
- id: apply-the-reviewed-plan
before:
first: {tool: terraform_plan, with: {out: $plan}}
then: {tool: terraform_apply, with: {plan: $plan}}
- id: apply-a-saved-plan
require: {tool: terraform_apply, where: {plan: "?*"}}
The second rule closes the gap the first leaves: terraform apply with no plan file at all
computes a fresh plan on the spot.
Delete only what the agent wrote¶
- id: delete-only-what-you-wrote
before:
first: {tool: Write, with: {file_path: $f}}
then: {tool: rm, with: {paths: $f}}
Bash rm scratch.txt README.md
✗ Rule 'delete-only-what-you-wrote' blocked this call. Nothing was executed.
Problem: for f='/repo/README.md': no earlier Write call had file_path='/repo/README.md'.
Every value is checked: rm a b needs both files to have been written.
Read before you run¶
- id: read-sql-before-running-it
before:
first: {tool: Read, with: {file_path: $f}}
then: {tool: psql, with: {file: $f}}
Paths are compared in one form: Read migrations/007.sql and
psql -f ./migrations/007.sql name the same file, and so does
cd migrations && psql -f 007.sql.
Read before you overwrite¶
- id: read-before-overwrite
before:
first: {tool: Read, with: {file_path: $f}}
then:
- {tool: Write, with: {file_path: $f}, exists: true}
- {tool: [sed, perl], with: {in_place: true, paths: $f}, exists: true}
- {tool: "*", with: {overwrite_to: $f}, exists: true} # echo … > f
exists: true limits it to files that are already there: creating a new file is fine.
overwrite_to covers truncating redirections (>), not appending ones (>>). This one
is in the library.
More¶
The example rule files have deploy, git, research-hygiene and
prompt-injection-tripwire rules, each tested with agentltl check.