Skip to main content

agentltl-coding

AgentLTL rules for coding agents, whatever the harness: the AGENTLTL.yaml rule language, a library of tested rules, and a guard that decides each tool call before it runs.

  • Rules in plain YAML, compiled to AgentLTL formulas over the calls made so far:

    rules:
      - id: tests-before-push
        before: {first: pytest, then: git_push, since: [Edit, Write]}
        why: CI is slow; run the tests locally first.
        mode: warn
    use: [no-force-push, protect-secret-files]   # from the library
    
  • Shell commands are checked as the structured calls of their command line (cli-to-tools): git add . && git push -f is git_add, then git_push {force: true}, checked all or nothing, with redirections, paths after cd, and files only known at run time accounted for.

  • Modes map one to one onto AgentLTL severities: block, warn (the agent may insist), ask (you decide), retry (then you decide), stop, log.

  • Memory: each rule reads the calls of this session, or of the project across sessions.

Four harnesses are built on it: the Claude Code plugin, the GitHub Copilot CLI plugin, the Mistral Vibe plugin and the Codex plugin. The full rule reference is on agentltl.github.io.

Installation

Most people want a plugin for their agent, not this library: paste the prompt from the plugin's README into your agent (Claude Code, Codex, Copilot CLI, Mistral Vibe). To build a harness for another agent, paste this into your coding agent:

Install agentltl-coding (pip install "git+https://github.com/AgentLTL/agentltl-coding.git" in a virtual environment) and read its README at https://github.com/AgentLTL/agentltl-coding, then help me write a harness for my agent.

A harness in a few lines

from agentltl_coding import Harness, Session, configure

configure(Harness(name="my-agent", agent="the agent", user_dir="~/.my-agent",
                  shell_tools={"Bash": "command"},
                  tool_aliases={"shell": ("Bash", {"cmd": "command"}),
                                "write_file": ("Write", {"path": "file_path"})}))

s = Session(cwd, project_root, session_id)       # one per hook call; state is on disk
if s.files:                                      # an AGENTLTL.yaml applies here
    verdict = s.pre("shell", {"cmd": "git push --force"})      # before the call
    # verdict.action: "none" | "deny" | "ask" | "stop"; verdict.reason: the message
    ...
    s.post("shell", {"cmd": "pytest"}, call_id, output, status=0)   # after it ran
    s.finish()          # the agent wants to stop: "block" while a `finally` rule is unmet
    s.prompt()          # the user wrote: lift a `stop`

Harness says what differs between agents:

  • the agent's name in messages, and where the user's AGENTLTL.yaml lives;
  • tool_aliases: its tool names mapped onto the canonical ones rules use (Claude Code's Bash, Write, Edit, Read...), so the library works unchanged (Copilot's create {path, file_text} is Write {file_path, content});
  • which tools take shell command lines, and the permission modes in which nobody answers a prompt;
  • built-in rules of its own (memory-first), and where its memory lives, for agentltl memory scan (agentltl_coding.memory).

Session is what the hooks do: it keeps the session and project traces on disk, holds a stop until the user replies, logs interventions, and scans call output for credentials. Guard underneath decides one call. agentltl_coding.cli.main(argv, extend=...) is the agentltl command (validate, check, translate, tools, library, use, memory...), to which a harness can add commands. A library entry with harnesses: [claude-code] is for that agent only; elsewhere use: of it switches nothing on, so one project file serves every agent.

Testing a harness end to end

e2e/ lets a plugin test itself in the real agent, without a model or an account:

  • e2e/scripted_model.py SCRIPT.json serves the OpenAI chat-completions, OpenAI responses and Anthropic messages formats (Mistral Vibe, Copilot CLI with a custom provider, Codex with wire_api = "responses", Claude Code with ANTHROPIC_BASE_URL) and answers each request with the next step of a script: tool calls, then a final text.
  • e2e/check.py TRACE EXPECTED checks that agentltl trace shows the expected refusals, in order.
  • .github/workflows/agent-e2e.yml is a reusable workflow: it runs the plugin's docker/e2e.sh and, when that fails on a pull request (such as Dependabot's update of the agent's version), says so on the pull request and mentions who to notify.

Each plugin pins the agent version it tests in docker/ (a package.json or a requirements.txt), so Dependabot proposes every new release as a pull request.

Develop

pip install -e ".[dev]" "agentltl @ git+https://github.com/AgentLTL/AgentLTL.git" \
    "cli-to-tools @ git+https://github.com/AgentLTL/cli-to-tools.git"
pytest -q

tests/golden/verdicts.json records what every packaged rule, example file and formula rule decides, step by step; a change that alters a verdict regenerates it (AGENTLTL_GOLDEN_UPDATE=1 pytest tests/test_golden.py) and shows up as a reviewed diff.

Metadata

Release files for agentltl-coding 0.2.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agentltl-coding 0.2.4
File Size Uploaded
agentltl_coding-0.2.4.tar.gz 71.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for agentltl-coding 0.2.4
File Interpreter ABI Platform
agentltl_coding-0.2.4-py3-none-any.whl Python 3 none any Details

Total release size: 136.5 kB

Release files / agentltl_coding-0.2.4.tar.gz

Download URL agentltl_coding-0.2.4.tar.gz
Size 71.5 kB
Tags Source
SHA-256 checksum
How to use checksums
ba1e2148e3d4865a95602500c8b37ebda5d3c97c15746aab4141631be80dfba6
BLAKE2b-256 checksum
How to use checksums
529b5594c1a6991e4575451bb18aaaf470ce55f4e25a4560b686056ab1740bfb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release files / agentltl_coding-0.2.4-py3-none-any.whl

Download URL agentltl_coding-0.2.4-py3-none-any.whl
Size 65.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
28ba3f9c3ad97ad934b266a56c5690baa71f765b68017d477271ce5f936937f3
BLAKE2b-256 checksum
How to use checksums
9b1b3be190aba058711914bc39c25710af2096a99837f1d4e3da2aec68a33d94
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.4 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page