Skip to work

ledgerloop

An agent reads a company's HRIS and derives the whole approval workflow. Then invoices route through it.

A procure-to-pay product in two halves that form one loop: onboarding derives the approval workflow from the org chart, operations routes real invoices through it.

ledgerloop live demo: an invoice run traversing a derived approval workflow, with the execution trace panel open
fig. 01 · derived approval DAG · ledgerloop

Nobody draws the workflow canvas

Ramp, Zip, and every workflow builder make you draw the approval graph by hand. Here the agent reads the client's HRIS (a real BambooHR pull, captured and replayed), derives who signs off on what, resolves each gate to a real person from the org chart, and flags the dirty data (a terminated manager, two people who look like the CEO, junk records) for a human to fix first.

You then maintain the workflow conversationally: "above $25k also require the CFO" produces a previewed diff you approve or revert. Nothing applies until you do.

AI only where it earns its keep

Three AI touchpoints, no more. Extraction reads the messy vendor PDF (vision to schema-validated JSON). Onboarding discovery maps org titles to signing authority, genuinely fuzzy judgement. The investigator agent judges a flagged exception against deliberately unstructured records (price history, PO notes), chooses its own tools, and recommends legitimate, overcharge, or unclear. It decides nothing about the money.

Everything else is pure unit-tested code: 2/3-way matching against open POs pulled from a live QuickBooks org, master-data controls (inactive vendor, off-catalog SKU, already-posted duplicate), the conditional-approval DAG engine, reconciliation. An LLM never decides a payment amount, and nothing posts before a human approves.

The engineering that holds up under scrutiny

Every run lands as an append-only audit row, replayable with zero tokens: the audit trail an AP buyer asks for first. Human-in-the-loop is stateless and replay-based: Approve or Reject recomputes the deterministic prefix, no persisted run snapshots, so a saved run can never change a future verdict.

The HRIS and ERP adapters are real, captured, and replayed: committed fixtures are actual BambooHR and QuickBooks output, so the demo and CI run with zero API keys. One factory picks live versus recorded; swap QuickBooks for NetSuite behind the same adapter interface and nothing downstream changes. Zod is the single source of truth: it constrains the model, validates every boundary, and its types flow to Drizzle, the stream, and the UI.