Use cases · Logistics & dispatch

Courier & last-mile delivery

A local courier running its own fleet. An order comes in, gets checked against the service area, holds until it's paid, then drops onto a driver's route as a pickup and a dropoff. The customer watches the driver move on a map. The day it grows past its own vans, it should be able to hand a job to DoorDash or Uber without rewriting anything.

The shape

This is Elliot in its own-fleet flavor: one Shipment model and one mode-agnostic carrier-driver seam, with a ZoneResolver gating the service area and a Driver working Stops. Dispatch is gated on payment through the Daneel needs ledger, and the live map rides Palver.

  • Elliot owns the delivery. The own-fleet driver assigns a Driver a pickup and dropoff Stop; a ZoneResolver rejects anything outside the coverage map. Because every flavor sits behind one carrier-driver contract (quote / book / cancel), swapping to a DoorDash Drive or Uber Direct driver is a configuration change, not a rewrite.
  • Daneel's needs ledger gates dispatch on payment: a Need holds the Shipment in a pending state until the charge clears, and an event→outcome capability binding releases it to a driver the moment it does (payment-to-dispatch).
  • Hober is the order being fulfilled; an order.closed auto-drafts a Shipment with the ship-to address and one parcel per line.
  • Payments takes the charge that must clear before a van is committed; a failure leaves the Need unmet and nothing dispatches.
  • Palver streams the driver's status and location to the customer's "where's my order" view in real time, off the same audit outbox the rest of the platform publishes to.
  • Seldon handles scheduled deliveries as a range Availability with a travel buffer (travelBufferSec), so a promised window accounts for the drive between stops.

Walk-through

Order in, coverage check

A customer places a same-day delivery order. Hober closes the order and auto-drafts an Elliot Shipment; Elliot's ZoneResolver checks the dropoff against the coverage map. Out of area, it's rejected before anyone is dispatched; in area, it advances to pending.

Hold for payment

Rather than dispatch on faith, the flow records a Need in the Daneel needs ledger: payment-to-dispatch. The Shipment sits pending. Payments charges the customer; on success the Need is satisfied, and a capability binding fires the dispatch outcome. On failure the Need stays open, nothing leaves the depot, and the obligation surfaces in the operator's needs-ledger view.

Onto a route

Dispatch assigns the Shipment to a driver as two Stops — pickup, then dropoff. The driver works the route in the field app; each status change (picked up, en route, delivered) streams through the audit outbox.

Live tracking

The customer opens the tracking link and Palver subscribes them to the Shipment's channel — the driver's progress and ETA update live, on the same Centrifugo socket the operator dashboard uses.

Overflow to a third-party carrier

On a slammed Friday the own fleet is full. The dispatcher flips the Shipment's carrier configuration to DoorDash Drive; Elliot quotes and books it through the on-demand-courier driver behind the identical contract. The needs-ledger gate, the tracking stream, and the Mallow posting are untouched — only the driver changed.

Why this is hard without LatticeKit

Most delivery operations bolt a dispatch tool onto a separate payments flow and a separate tracking widget, and "don't dispatch until it's paid" becomes a fragile bit of glue that fails open under load. Here that rule is a first-class Need in a durable ledger: the Shipment cannot leave until the obligation clears, the release is an auditable capability firing, and an abandoned order unwinds through saga compensation. And because Elliot's carrier seam is mode-agnostic, the choice between your own van and a gig courier is a config flag rather than a second integration project.