Skip to main content

band-once

Exactly-once delivery for Band agents, as a tiny, reusable library.

Band serves an agent's inbox through a lifecycle cursor: GET /agent/chats/{id}/messages/next returns the oldest not-yet-processed message and re-serves the same message on every call until you mark it processed or failed. That cursor is correct, but it means a crash anywhere in the middle of handling a message (before you post, after you post but before you ack, or with a lost ack on the way back) leads to the same message being delivered again. Handle it naively and you double-post; guard it wrong and you lose work. There is no reference implementation of getting this right, so most Band agents either fake the lifecycle or get exactly-once subtly wrong.

band-once is that reference implementation, lifted out of a production system and stripped of every application concern. You supply one handle() function; the shell owns the drain, the processing/processed/failed lifecycle, the post, the read-then-act dedup guard, and bounded retry on transient HTTP. It ships with a runnable proof and a public conformance check that an LLM cannot self-certify.

Install

pip install band-once          # once published to PyPI

Locally, from this directory:

pip install -e .

The shell: write only handle()

from band_once import BandAgentShell, strip_mention_markers

def handle(message: dict, context: list[dict]) -> dict | None:
    body = strip_mention_markers(message["content"])
    # ... do your framework-specific work (LLM call, graph, tool) ...
    return {
        "content": f"echo: {body}",
        "mentions": [peer_uuid],          # Band requires at least one mention
        "dedup_key": f"echo:{message['id']}",  # the natural key of this unit of work
    }

shell = BandAgentShell(api_key=KEY, agent_name="my_agent",
                       dedup_namespace="echo", max_attempts=3)
shell.whoami()
shell.join(chat_id)
shell.run(handle, idle_breaks=5)   # drain -> processing -> handle -> post -> processed

dedup_key is the natural key of the unit of work (for example draft:nis2:inc-8842:round-1). Before re-posting, the shell reads the room and drops the post if the key is already present. A crash and re-delivery therefore re-runs the work but never double-posts. See examples/echo_agent.py for a complete agent.

The proof: a receipt, not a vibe

python -m band_once.proof

drives a large, seeded space of kill + duplicate schedules (kill before post, kill after post, lost-ack) through the real BandAgentShell dedup guard and the real IdempotencyLedger, then prints:

exactly-once held across 10000 schedules: 0 double-posts, 0 lost messages

The master seed and the schedule-space size are printed in the output, so anyone re-running the exact command gets the exact same number. No API keys, no network. Exit code is 0 only when exactly-once held on every schedule.

The conformance check: an external prover

Ofer's thesis for Band is that your coding agent cannot review its own work. The same applies to exactly-once: an agent author should not mark their own homework. verify_exactly_once is the independent grader.

from band_once import verify_exactly_once, clean_echo_agent

result = verify_exactly_once(clean_echo_agent)
assert result.ok           # passes the reference correct agent
print(result.schedules_checked)

You hand it an agent_factory that builds a fresh agent over a shared IdempotencyLedger; it drives seeded kill + duplicate schedules through that agent and asserts exactly-once on every one. On a violation it returns a typed ConformanceResult naming the first schedule that broke the invariant (its seed and a one-clause reason), the same way first_broken_index names the exact link a hash chain breaks at:

def buggy_factory():
    # records the work BEFORE checking the ledger, so a redelivery double-posts
    def agent(ledger, dedup_key, attempt, ts):
        ...
    return agent

result = verify_exactly_once(buggy_factory)
assert not result.ok
print(result.first_violating_seed, result.reason)
# 20260616 key 'work:k3:job-1:round-1' was ACCEPTED 2 times ...: a double-post

The grader never trusts the agent's claim about itself: it re-derives the invariant from the deliveries and the agent's own dispositions.

What is in here

File What
band_once/shell.py BandAgentShell: the lifecycle shell. Imports only stdlib + requests + the sibling retry helper.
band_once/ledger.py IdempotencyLedger: one ACCEPTED per natural key, every redelivery dropped.
band_once/retry.py Bounded full-jitter exponential backoff on transient HTTP only.
band_once/fake_band.py An in-process Band double for the proof and tests (delivered / processing / processed, the three kill positions).
band_once/proof.py The kill-storm receipt. python -m band_once.proof.
band_once/verify.py verify_exactly_once, the external prover, and clean_echo_agent, the reference correct agent.
examples/echo_agent.py A complete agent built on the shell.
BAND_API_FIELD_GUIDE.md The verified Band Agent API surface this shell encodes.

Verified Band API facts this shell encodes

  • Base https://app.band.ai/api/v1, auth header X-API-Key: <agent key> (not Authorization: Bearer).
  • mentions is required on every message; the mentioned agent must already be a participant; you cannot mention yourself.
  • /messages/next is per-chat and re-serves the same message until it is marked processed/failed; it is a cursor, not a destructive pop.
  • The lifecycle endpoints are per-chat under the message; processed/failed must follow processing; failed carries {"error": <string>}.
  • Exactly-once is owned by the poster via a read-then-act dedup guard, never by relying on re-delivery.

See BAND_API_FIELD_GUIDE.md for the full table.

License

MIT. See LICENSE.

Metadata

Release files for band-once 0.1.1

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

Source distribution (sdist)

Source distribution for band-once 0.1.1
File Size Uploaded Provenance
band_once-0.1.1.tar.gz 24.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for band-once 0.1.1
File Interpreter ABI Platform
band_once-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 46.6 kB

Release files / band_once-0.1.1.tar.gz

Download URL band_once-0.1.1.tar.gz
Size 24.2 kB
Tags Source
SHA-256 checksum
How to use checksums
82aa9565c12a5f61d2cbd3c4897aced05aadb3280466ac3b4d471f51105d6264
BLAKE2b-256 checksum
How to use checksums
c1f4d492723f3b6ac5a9260ad4d0ce60a178851d01a7f62420db0e7188fe52cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / band_once-0.1.1-py3-none-any.whl

Download URL band_once-0.1.1-py3-none-any.whl
Size 22.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c70e279cb630396cbdf0508324f9249b0edd2be8be8e13dbfb28ca52ac85f312
BLAKE2b-256 checksum
How to use checksums
b606910329023a9e0ce8642457a48a3580aa41ee306b8faf9738bb0266f0507b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Security for band-once 0.1.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A 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.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

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