The engine

A payment is a record that moves through states.

Not a single irreversible transfer. Both products, delivery escrow and compliance bonds, run on the same core engine: funds lock at authorization into a neutral pending account, then either release to the payee on a verified claim or return to the payer on a cancellation.

Authorized
Pendingneutral · belongs to no one
Released · claim event
Refunded · cancel event

every transition → a distinct, auditable snapshot

Architecture-first, rail-agnostic

Five decisions that make settlement enforceable

Immutable records, not transfers

A payment is an immutable record that moves through a defined lifecycle of states, never a single irreversible transfer that can't be reasoned about after the fact.

A neutral pending account

Funds lock at authorization into a neutral pending account. They belong to neither party until terms are met, then move on a verified event.

Per-counterparty behavior

Immediate payment versus held-in-escrow is selected per counterparty, not hardcoded. A trusted supplier and an unknown new hauler transact through the same system under different rules.

Events, not commands

Claims and cancellations are events submitted by authorized parties. An inspector, terminal operator, or safety officer triggers an outcome within their authority, the payment layer never evaluates correctness itself.

Exactly one outcome

Concurrency is handled with per-transaction row locking. A claim and a cancellation racing toward the same load resolve safely to exactly one outcome, never both.

A clean trust boundary

The settlement layer records the delivery-confirmation reference without adjudicating it, keeping a clear line between what the system enforces and what an authorized inspector attests.

The model

One primitive, two products

LIFECYCLE

Lock at authorization

A hold is created in the pending state. The mode, escrow, immediate, or bond, is resolved from the counterparty's policy, not baked into the call site.

hold.ts
const hold = await sentinel.holds.create({
  load:  "0x8d90",
  payer: buyer.id,
  payee: refiner.id,
  mode:  policyFor(buyer),  // per-counterparty
  terms: ["on_time", "full_qty", "on_spec"]
})
// hold.state === "pending"
EVENTS

Claim or cancel, both are events

An authorized party submits a claim (release) or a cancellation (refund). The engine records the reference and transitions the record; it never judges whether the attestation is correct.

events.ts
// release, submitted by an inspector
await sentinel.events.claim(hold.id, {
  by: inspector.id, ref: "terminal-3/att-5521"
})

// refund, submitted on timeout / dispute
await sentinel.events.cancel(hold.id, {
  by: "reconciler", reason: "late"
})
CONCURRENCY

The race resolves to one outcome

If a claim and a cancellation arrive at once, per-transaction row locking serializes them. The first to commit wins the transition; the second sees a settled record and is rejected cleanly.

load 0x8d90 · concurrent
claim · terminal-3 commit
cancel · reconciler rejected
final state: released once

Why it matters

Caught before the funds move

Sentinel takes the silent assumptions of fuel logistics and attaches money and verification to them. Counterparties who perform well get paid faster; the ones who don't are caught before the funds move. For a refiner whose investment case rests on dependable feedstock in and product out, that's the difference between a promise and a guarantee.

audit · load 0x8d90
06:02 · authorized → pending snapshot
07:28 · claim · terminal-3 snapshot
07:28 · pending → released snapshot
ref recorded · not adjudicated boundary

Build settlement that enforces what was agreed.

Rail-agnostic, architecture-first, and modeled around the way fuel logistics actually moves. Start building against the Sentinel engine.