Portable records for consequential actions.
Create an ActionReceipt when your application buys work, calls a tool, or accepts a result. Keep it with the supporting evidence so another system can inspect the record later. Local receipt checks do not require the original agent or platform.
Bulla creates and verifies portable ActionReceipts, applies receiver-supplied policies, reconciles receipt sets with application records, and captures completed stdio MCP calls. The application retains the transaction record alongside its evidence, so it can inspect the delivery after the original process is gone.
Bulla 0.49.4 · Python 3.10+ · Apache-2.0
Bulla Labs maintains this software alongside its applied research. Use Bulla on its own; the laboratory’s research and intellectual foundations provide additional context.
MCP capture is included in Bulla 0.49.4. It emits ActionReceipt v0.4, an experimental draft format; v0.2 remains the normative default for the general receipt tools.
Application code creates the receipt around the consequential call, so the model never has to generate the JSON. The receiver retains the file and applies its own verification context and policy.
$ python -m pip install "bulla==0.49.4"
$ bulla demoThis local scenario uses wrap_action to emit one receipt, checks a changed copy, and compares the receipt set with two customer-log entries. No payment network is contacted.
Each run creates a fresh directory. Look for its path on the final line after artifacts, then set BULLA_DEMO_DIR to that path, as shown in the quickstart.
Open receipts/pay_demo_042.json from that directory in Inspect a receipt. The browser reads that exact file and checks its structure and integrity without uploading it. Signatures, supporting files, receiver policy, and coverage remain separate checks.
BULLA_DEMO_DIR="/paste/the/artifacts/path/here"$ bulla receipt drill "$BULLA_DEMO_DIR/receipts/pay_demo_042.json" --format jsonRun the drill to compare Bulla with the packaged standalone checker while network operations are denied. Output separates checks over saved files from questions that need another source.
Download the retained verification kit for offline command-line checking.
Verification kit details
Keep the archive and detached digest with the receipt set. Its manifest covers every member, and the signed release receipt authenticates the published archive.
Kit SHA-256: 8f2cdd16bcbd1a1121f49545b6a6512872b188221ca30ec054dfd6b2fb2142ab
Create a receipt around the consequential call
from bulla import wrap_action
with wrap_action(
"payments.charge",
{"event_id": "pay-1", "amount_minor": 12500},
) as action:
receiver.charge(amount_minor=12500)
receipt = action.receiptA receiver is the system inspecting a record. A supplier can receive an order or authorization; a purchaser can receive a delivery. Receipt checks alone establish neither authorization nor payment assurance. How local policy differs from agreed terms.
One transaction, three records
The provider reports the action, an ActionReceipt crosses the boundary, and the receiving system compares the receipt with its own record.
Provider record → ActionReceipt → Receiver record
Provider-side log
Internal operational log
Provider systems keep this log for their own operation.
not supplied to this check
Retained boundary artifact
ActionReceipt
- event
- pay_demo_042
- amount
- USD 125.00
- original integrity
- CHECKING
- changed copy
- CHECKING
Customer record
Observed actions
- actions
- —
- matching receipts
- —
- coverage
- CHECKING
Computing receipt integrity and coverage…
Integrity checks the receipt in hand. Reconciliation compares the receipt set with the customer’s supplied action record.
This control changes an amount without recomputing the stored commitments. It does not authenticate the issuer or prove that a payment occurred. Reconciliation can find only actions present in the supplied customer record.
Inspect the receipt computation
- Inputs
- Customer actions
pay_demo_042andpay_demo_043; one receipt forpay_demo_042. - Checks
- Recompute the stored commitments and compare bound action identifiers.
- Result
- Original record integrity
VERIFIEDto digest; coverage1/2; unmatchedpay_demo_043. - Boundary
- An action omitted from both supplied inputs remains invisible.
| Receiver supplies | Bulla computes | Never inferred |
|---|---|---|
| Receipt bytes | Record integrity and declared-convention checks | Worldly truth or occurrence |
| Trusted keys or roots | Supported signature and inclusion checks | Key custody or signer independence |
| Receiver action record | Actions without matching receipts | Completeness of that record |
| Pinned policy, time, and revocation context | RELY, REFUSE, or ESCALATE | Policy suitability, custody, or settlement |
Why not signed JSON?
Signed JSON can carry the same facts. In our scheduling experiment, matched signed records produced the same decisions as ActionReceipts. Bulla supplies a versioned record format, local verification tools, receiver-policy evaluation, and receipt reconciliation. The adoption question is whether a shared convention removes enough bespoke coordination to justify producing, retaining, checking, and maintaining it. A competent conventional arrangement may suffice. Reduced integration effort and interoperability between independently operated systems remain unmeasured.
Four tasks
- 01CreateEmit a portable transaction record where an application accepts or completes an external action.
- 02CheckRecompute a saved receipt locally without contacting the provider.
- 03DecideApply a supplied receiver policy before another consequential action.
- 04ReconcileCompare a receipt set with customer records and identify actions with no receipt.
What ships where
| Surface | Public state |
|---|---|
| Bulla | Published Python package 0.49.4 |
| ActionReceipt v0.2 | Normative stable format |
| ActionReceipt v0.3 | Non-normative released draft |
| ActionReceipt v0.4 | Opt-in experimental draft |
| Answerability profiles | Repository-source research profiles |
Reference
Beyond the released tools
These repository-source experiments study institutional arrangements around records. They are not services supplied by the installed package.