Skip to main content

Taskbundle

Author, validate, and run SWE-bench-style coding tasks in reproducible containers.

A task is a bundle: a directory with a repo at a commit, a problem statement, a golden patch, and hidden pass2pass / fail2pass tests. Taskbundle packages it into a Docker image and runs those hidden tests before and after a solver (an LLM agent, a script, anything that edits files), so you know exactly which tests it fixed and which it broke.

The loop: init (build the image) → validate (assert the baseline guardrail) → run (solve in isolation, then score) → query (inspect any past run).

Full documentation, design rationale, and examples live in the GitHub repo: https://github.com/yatharthk2/taskbundle

How it works

   ┌────────────────────────────────────────┐
   │                 BUNDLE                 │
   │     repo · problem · patch · tests     │
   └────────────────────────────────────────┘
                       │  init
                       ▼
   ┌────────────────────────────────────────┐
   │              Docker image              │
   └────────────────────────────────────────┘
                       │  run
                       ▼
   ┌────────────────────────────────────────┐
   │              1) SOLVE box              │
   │          sees repo + problem           │
   │      NEVER sees the hidden tests       │
   └────────────────────────────────────────┘
                       │  captured patch (git diff)
                       ▼
   ┌────────────────────────────────────────┐        ┌──────────────┐
   │              2) SCORE box              │        │ hidden tests │
   │         apply patch, run tests         │ ◀───── │  p2p / f2p   │
   │          hermetic, no network          │  only  └──────────────┘
   └────────────────────────────────────────┘  here
                       │
                       ▼
                   resolved?

Two isolated containers: SOLVE edits the repo but never sees the hidden tests; they're injected only into the separate, hermetic SCORE box that grades the captured patch, so a solver can't peek at or game them.

Install

Python ≥ 3.9. Built with Typer; everything else is stdlib.

pip install taskbundle
task --help

Docker (or Podman / colima / nerdctl) is needed to build & run images. task query and task init --no-build work without it.

Quickstart

The whole loop on a tiny, self-contained bundle (hello-task, no external repo, ~1 min):

task init     cli/examples/hello-task                 # build the image + smoke-check
task validate cli/examples/hello-task --check-patch   # baseline: p2p pass / f2p fail; golden flips f2p
task run      cli/examples/hello-task                 # golden solver → RESOLVED (exit 0)
task run      cli/examples/hello-task --solver noop   # makes no edits → not resolved (exit 9)
task query                                            # the ledger, every run newest first
task query 1                                          # full detail for command #1

(Clone the repo to get the example bundles.)

Commands

Command What it does Exit
init Resolve a Dockerfile + build the image (clone/copy the repo at the commit) + smoke-check 0 ok · 3/4/5/6/11 setup
validate Run the hidden buckets on the baseline → assert p2p pass, f2p fail 0 holds · 7 violated · 8 no tests
run Run a solver (it never sees the buckets), capture its diff, score it in a hermetic box 0 resolved · 9 not · 8/12 setup
query Read-only ledger inspection: by id, filtered list, or --stats scoreboard 0 · 10 unknown id

Any unexpected error is caught, logged to the ledger, and shown as one line with exit 70 (TASKBUNDLE_DEBUG=1 for the traceback). Step-by-step docs: init · validate · run · query.

Bundle layout

my-task/
  task.json       # which code: repo, commit, id  (+ optional install/build/test/smoke overrides)
  description.md  # the problem statement shown to the solver
  patch.diff      # golden solution (unified diff)
  Dockerfile      # OPTIONAL — owns the environment; auto-generated if absent
  tests/
    pass2pass/    # must pass before AND after the golden patch
    fail2pass/    # must fail on baseline, pass after the golden patch

task.json says which code; the Dockerfile owns the environment (base image included). Its optional test_cmd sets how the buckets run — any framework that writes JUnit to $TASKBUNDLE_JUNIT (tests at $TASKBUNDLE_BUCKET), default pytest — so non-Python tasks run too.

Use an LLM as the solver

--solver is just a command that edits files, so an LLM agent is one too. The repo ships a stdlib-only OpenAI agent (openai_agent.py); the openai-demo bundle vendors it and COPYs it into the image, so you run it as an ordinary solver command:

export OPENAI_API_KEY=sk-...           # in your shell, never an arg, never committed
task run cli/examples/openai-demo \
  --solver 'python /opt/openai_agent.py' \
  --solver-env OPENAI_API_KEY           # forward the key BY NAME (-e NAME)

The key is forwarded by name: its value never hits the argv, a log, or the ledger. Isolation is unchanged — it runs in the same solve box and never sees the hidden buckets.

References

The task structure and evaluation methodology (hidden fail2pass / pass2pass tests, golden patches, containerized per-instance environments) take inspiration from:

  • Jimenez et al., "SWE-bench: Can Language Models Resolve Real-World GitHub Issues?" ICLR 2024 — arXiv:2310.06770.
  • Deng et al. (Scale AI), "SWE-Bench Pro: Can AI Agents Solve Long-Horizon Software Engineering Tasks?" — arXiv:2509.16941.

License

MIT © Yatharth Kapadia

Metadata

Release files for taskbundle 0.1.0

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

Source distribution (sdist)

Source distribution for taskbundle 0.1.0
File Size Uploaded
taskbundle-0.1.0.tar.gz 44.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for taskbundle 0.1.0
File Interpreter ABI Platform
taskbundle-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 78.8 kB

Release files / taskbundle-0.1.0.tar.gz

Download URL taskbundle-0.1.0.tar.gz
Size 44.6 kB
Tags Source
SHA-256 checksum
How to use checksums
f987c4611b5ea34e97eafa830aa673550c057481fedb8bbddc3c7fe34412f19c
BLAKE2b-256 checksum
How to use checksums
2345ba289b19854a6da247829aed0382934e2b5d95484d85fa9f3c2bee7dfe8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 20, 2026.

Transparency log

Release files / taskbundle-0.1.0-py3-none-any.whl

Download URL taskbundle-0.1.0-py3-none-any.whl
Size 34.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d5a864a60770dbf62638948d94aaadfd8e8dcf39b25f2c29f7699243a9d187bc
BLAKE2b-256 checksum
How to use checksums
9f32686d159ac346b92cd4c1ef143779c712cb5f862e8b216b0c6e23f722341c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 20, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 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