An agent harness with evals that grade the end state, not the output.
Most agent evals grade text: they ask a model whether the answer looks right. That is cheap to
build and easy to game. endstate throws away everything the agent said and asserts against what
it left behind — did the test suite go green, are the files where they should be, is there a
secret in the diff, did it refuse the destructive command, did it survive being killed halfway
through.
pip install endstate
Status: v0.0.1, in development. The harness and the eval runner work —
endstate eval --suite tasks/runs 12 tasks in disposable containers and grades what they left behind. The differentiating task categories and the published benchmark are next. Follow the build plan for what ships when.
Documentation → — including How agents actually work, a walk through the internals of agent design: the loop, the sandbox boundary, permissioning, context compaction, checkpoint durability, and why end-state grading beats grading text.
Results
Not yet published. The v0.2.0 benchmark runs the same 20-task suite across hosted and self-hosted
models and reports pass rate, tokens, cost per task and p95 latency. Method and raw traces will be
committed under benchmarks/.
Why the graders are boring on purpose
A grader is a Python function that receives a handle to the sandbox after the run and returns pass/fail plus a reason:
def grade(sandbox: Sandbox) -> Verdict:
if not sandbox.run("python -m unittest discover -s tests -t . -q").ok:
return Verdict.fail("test suite still red")
if sandbox.read_text("tests/test_chunk.py") != sandbox.fixture_text("tests/test_chunk.py"):
return Verdict.fail("the tests were edited")
return Verdict.ok()
No LLM judge in the primary path. It is slower to write and much harder to argue with.
Note what is not a parameter: there is no messages, no transcript. A grader cannot read what
the agent said because it was never given it — and that is enforced, not documented. Graders are
resolved by dotted path and the resolver inspects the signature, so a grader that takes a
transcript argument fails to load rather than quietly checking the wrong thing.
The end state can be gamed too, which is the half most write-ups skip. Editing the tests satisfies "the suite is green" completely. So every shipped task also pins its test files by hash, refuses new skip markers, confines changes to the paths the task permits, and runs held-out tests that were never in the sandbox.
The task categories that matter
| Category | What it proves | |
|---|---|---|
| Bug fix, feature, refactor | The agent can do the job at all | 12 shipped |
| Long-horizon / compaction | It still works when the task does not fit in the context window | next |
| Permissioning | It refuses. Pass means the destructive command did not run | next |
| Checkpoint recovery | Kill it mid-run, resume, and reach the same end state | next |
The last three are the ones that break real deployments, and almost nothing tests them.
How do you know the evals test anything?
Every task ships a reference solution that no agent ever sees, and the test suite asserts both directions for all twelve: the graders fail on the untouched fixture, and pass on the reference fix. A grader that passes either way is measuring nothing, and it is much easier to write one of those than most people expect — several in this suite did, before that check caught them.
Quickstart
export OPENAI_API_KEY=...
endstate run "make the failing test in pkg/ pass" --workdir ./sandbox --model gpt-4o-mini
Run the eval suite — one disposable container per task, no network inside:
endstate eval --suite tasks/ --model gpt-4o-mini --jobs 4 --out benchmarks/
Point it at anything OpenAI-compatible — vLLM, Ollama, a gateway:
endstate run "..." --base-url http://localhost:8000/v1 --model qwen-coder
Resume a killed run:
endstate sessions
endstate run "continue" --resume <session-id>
Design notes
Written from primitives, not on a framework. I have migrated a production coding agent from
Pydantic-AI to LangGraph and run it at billions of tokens a month. This one is deliberately built
from the provider SDKs up: the interesting parts of a harness — where the context budget is
enforced, what happens when a tool is denied, what is persisted before a step can fail — are exactly
the parts a framework hides. They are all visible in
agent/loop.py.
The token budget is an object, not an accident. Every compaction records tokens before and after, so "what did compaction cost you?" has a number rather than a shrug.
Prices are data. The cost table is a JSON file you supply. Unknown model prices raise instead of silently reporting zero — a wrong cost is worse than a missing one.
One disposable container per eval task. Deterministic, parallelisable, and the only reason it is sane to hand an agent a shell.
Development
uv sync --group dev
make check
Trunk-based: short-lived branches cut from main, linear history, no merge commits. Versions are
derived from Conventional Commits — feat: bumps the minor,
fix: the patch, and anything else lands without consuming a version. CI tags it, cuts the GitHub
Release and publishes to PyPI, so a merged feat: ships.
See CONTRIBUTING.md.
Licence
MIT — see LICENSE.
Metadata
Release files for endstate 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| endstate-0.1.0.tar.gz | 733.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| endstate-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 788.2 kB
Release files / endstate-0.1.0.tar.gz
| Download URL | endstate-0.1.0.tar.gz |
|---|---|
| Size | 733.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d4494f9e17fcd863b8f71ff2a50898fc5b02ff17807ae97ff826b370f91633c0
|
|
BLAKE2b-256 checksum How to use checksums |
8ef4f8d0f616f91789a4422e952faf53521f12b7ecf9db7c0b61d969e87af4dc
|
| 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 Aug 13, 2026.
Transparency logRelease files / endstate-0.1.0-py3-none-any.whl
| Download URL | endstate-0.1.0-py3-none-any.whl |
|---|---|
| Size | 54.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3dca396af47d52c95774a0cc36364ab3f1982e5deec67752f7ef9192603aa60c
|
|
BLAKE2b-256 checksum How to use checksums |
db266114e20b104311b8c267c010a8471131588ab9cc57030ec99a1118e6cb87
|
| 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 Aug 13, 2026.
Transparency logSecurity for endstate 0.1.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for endstate-0.1.0.tar.gz
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 Aug 13, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.