spec/fixtures/ and
reproduce the signature vectors in spec/signing.md, including the negative
cases. Both prove, by killing a real subprocess mid-poll, that a client can die
at any point without losing an answer.
Installation state, checked while writing this page — neither SDK is on a
public registry yet.
pip install handoff-human and
npm install @handoffproto/sdk do not resolve today; both installs below work
from a checkout of
github.com/OmegaAgent/handoff. When
the registry releases land, the package names will be the ones shown here.Python: handoff-human
Standard library only. Version 0.2.0 in the repository.
raise_request, resume, receive) is covered in
the quickstart. Two details
that matter in production:
receive()acks when its block completes. If the block raises, nothing is acked and the signal stays queued. Acking first and applying second would turn at-least-once delivery into at-most-once application, which is the exact bug the protocol exists to make impossible.- To record that a decision arrived and could not be acted on, call
received.unable("the refund API was down")inside the block. That is not an error; it is a fact worth keeping.
str is refused rather than
silently encoded. Receipt-chain verification (verify_receipt_chain,
verify_chain) needs nothing outside the standard library; only the optional
detached Ed25519 layer needs the cryptography package.
If you are coming from the 0.1.x hackathon package: the module is now
handoff, and import human still works in 0.2.x with a deprecation warning.
TypeScript: @handoffproto/sdk
Zero runtime dependencies, and no Node built-ins: hashing, HMAC and randomness
go through WebCrypto, so the same source runs on Node, Deno, Bun, and Workers.
The package ships TypeScript source, consumed directly by any runtime that
strips types (Node 22.18 or newer, Deno, Bun) or by any bundler.
verifyCallback, verifyChain, and digest
all return promises.
Shared error model
Every error carries a stablecode and raises or throws a class that mirrors
it: AlreadyAnswered (carrying the receipt id), RequesterMayNotAnswer,
InsufficientAuthority, AuthorizationSpent, AnswerValidationFailed (with
per-field detail), and the rest of the spec’s §13. A code the SDK version does
not recognize surfaces as HandoffProtocolError with the code intact. Never
branch on .message; it is written for people and may change at any time.