Call Jacquard from your application
Jacquard Host lets Python, TypeScript and Go code call checked Jacquard functions. Jacquard owns the decision logic. Your application owns persistence, I/O and lifetimes, and implements each effect the logic declares with an ordinary service.
The effect row is the interface
This policy decides how many units to reorder. It cannot read stock levels
itself; it performs on-hand, an operation of a
Stock effect that the host must supply.
-- How many units to order. Stock levels come from the host.
once effect Stock where {
on-hand : (sku: Text) -> Int
}
reorder : (Text, Int) ->{Stock} Int
reorder(sku, target) = {
let have = on-hand(sku)
if lt(have, target) then sub(target, have) else 0
} $ jac check reorder.jac --print-sigs
reorder : (Text, Int) ->{Stock} Int
The signature ->{Stock} is everything the policy can ask its
host for. A reviewer reads one line to learn what the application has to
provide, and what the policy cannot reach.
Your service implements the effect
In Python, an object binds to an effect, and kebab-case operations select
snake_case methods. The SDK prepares and checks the program once, then each
call runs it in a fresh Core worker that asks the host for every
on-hand.
from jacquard_host import Runtime
class Warehouse:
def __init__(self, counts):
self.counts = counts
def on_hand(self, sku):
return self.counts.get(sku, 0)
program = Runtime().prepare("reorder.jac")
reorder = program.function("reorder", effects={"Stock": Warehouse({"bolt": 12})})
print(reorder("bolt", 40))
print(reorder("nut", 40)) $ python app.py
28
40 A missing service is refused before anything runs
Every operation of every effect in the function's checked row must be bound. Leave one out and the SDK refuses while binding, before a worker starts or any outside action happens.
from jacquard_host import BindingError, Runtime
program = Runtime().prepare("reorder.jac")
try:
program.function("reorder")
except BindingError as error:
print(error) $ python missing.py
reorder: missing handlers: stock.on_hand. Bind every operation in each declared effect before calling
Recorded with jacquard-host 48946f1 and Core
0.3.0, re-checked by scripts/verify_examples.sh.
Three SDKs, one protocol
- Python 3.11+ maps dataclasses, enums and optional fields, and binds synchronous services. See the SDK guide.
- TypeScript on Node.js 22+ supports async service methods. See the TypeScript walkthrough.
- Go 1.24+ maps native Go types and honours context cancellation. See the Go walkthrough.
None has third-party runtime dependencies. Each implements Core's
jacquard-host-v0 protocol independently and replays the same
pinned conformance kit. The adapters pin one Core release, 0.3.0,
in core-pin.json, and the
setup script installs it and verifies its checksum. Every invocation keeps
its raw protocol evidence, which you can render or save for inspection.
Get started
git clone https://github.com/jbwinters/jacquard-host
cd jacquard-host
python3 -m venv .venv && . .venv/bin/activate
python -m pip install .
eval "$(python3 scripts/core_pin.py install)"
python examples/quickstart/run.py The example projects go further, up to a fulfillment service with SQLite transactions, idempotency and explicit outbox recovery. Setup covers other platforms and building Core from source.
The boundary
Jacquard Host is experimental and for first-party programs on a trusted
host. Checked effects are an application boundary, not an
operating-system sandbox. The v0 process protocol may change,
each invocation runs one serial worker, and no outside action is retried
automatically.
Read the limits and authority model before connecting outside actions.