How the work gets done

Autopilot

Advances routine entries within broker-set guardrails — and stops for review when unsure.

5 min readUpdated Aug 6, 2026

Deterministic state machine. The orchestrator that decides when to run the other agents, what the entry's next legal action is, and when the broker must take the wheel. Single source of truth for entry state.

What it does

Walks every entry through its lifecycle: draft → ai_review → ready → filed → cleared (or → exam, → hold, → released). At each transition it decides:

  1. Which agents to run at this state (classifier? screener? duty calc?)
  2. Whether the entry can advance autonomously or needs broker review
  3. What the next legal action is (classify / approve / transmit / release …)
  4. What gets logged to the activity stream for the audit trail

AI auto-approval is currently suspended. Every AI classification routes to broker review — no line and no entry auto-approves today (a calibration hold; re-enabled only when a measured confidence + corroboration gate replaces the old threshold). The "Autopilot on / auto ≥ 92%" toggle in the top bar is display-only: it drives cosmetic dashboard buckets, not any server-side gating.

This is not an LLM agent. State transitions in customs work must be deterministic, reproducible, and challenge-able in a CBP audit. Every state change is logged with the action that caused it, the agent (system / broker / state-machine / autopilot), and a timestamp.

Inputs

// applyAction(from, action) — the state machine is a pure (status, action) map.
{
  from: ShipmentStatus,             // current state
  action: 'classify' | 'approve' | 'hold' | 'transmit'
        | 'release' | 'exam' | 'reject' | 'clear',
}

Outputs

{
  from: 'ai_review',
  to: 'ready',
  action: 'approve',
  progress: 4,                      // 0..6 progress-bar position
  legalActions: ['transmit'],       // what can come next from the new state
}

An illegal transition is not a soft failure — applyAction throws, and the /advance endpoint returns HTTP 409 with the current state:

{ error: "Illegal transition: cannot 'transmit' from 'ai_review'. Legal actions: approve, hold.", current: 'ai_review' }

For the canonical reference of every status (what it means, what moves it forward, how Dashboard filters map to it), see Entry statuses, explained. The visual workflow this state machine implements is the visual workflow.

State diagram

                    ┌──────────────────────────┐
                    │       draft              │   created from a doc / PO / manual
                    └─────────────┬────────────┘
                                  │ classify + screen (auto)
                                  ▼
                    ┌──────────────────────────┐
                    │      ai_review           │   agents have run, broker assessing
                    └──────┬───────────────────┘
                           │
                ┌──────────┴──────────┐
                ▼                     ▼
  Autopilot auto-approve    Broker approves
   (SUSPENDED today —         (the only path today)
    every line → review)
                │                     │
                └──────────┬──────────┘
                           ▼
                    ┌──────────────────────────┐
                    │       ready              │   ready to file (transmit ABI)
                    └─────────────┬────────────┘
                                  │ transmit
                                  ▼
                    ┌──────────────────────────┐
                    │       filed              │   CBP has the entry summary
                    └────┬────────────────┬────┘
                         │                │
                         ▼                ▼
                ┌────────────┐    ┌────────────┐
                │   exam     │    │   hold     │   CBP escalation
                └────┬───────┘    └────┬───────┘
                     │ release         │ (broker resolves —
                     ▼                 │  no coded exit from hold)
                ┌──────────────┐       ▼
                │   released   │ ─ clear ─▶  cleared   (only 'cleared' is terminal)
                └──────────────┘

When it runs

  • On every action taken against an entry — by a broker (drawer button), by a service (extractor finishes), by a scheduler (timeout escalation), or by an upstream event (CBP CSMS message — planned).
  • At ingest time — when a new shipment is ingested via the shipments/ingest endpoint or the document inbox.

How advancing actually works

advance is a broker-triggered, unconditional state-machine step: the endpoint takes the entry's current status and the requested action and applies the matching transition (or 409s if the action is illegal from that state). There is no confidence gate, no PGA gate, and no duty-cap gate in the transition logic — the state machine is a pure map of (status, action) → next status.

The one automated guard lives upstream, at classification time: if denied-party screening surfaces a block-band hit, the entry is routed to hold instead of ai_review, so a broker must clear it explicitly before anything moves forward. Low-confidence lines don't block the transition — they're flagged for broker review (see the 70% HTS review floor below), and every AI classification currently routes to review regardless (auto-approval suspended).

Canonical Stage vocabulary

The eight raw statuses above feed deriveShipmentStage (shipment-stage.ts), which derives the canonical 9-stage pipeline (PO & Shipment → ISF → Documents → HTS Classification → Duty Calc → PGA / UFLPA → ACE Filing → CBP → Post-Entry) plus an honest "next action" and health dot. That derived Stage — not the raw status — is what the Shipments table and the drawer stepper render, so the two can never disagree. A line below the 70% HTS review floor (HTS_REVIEW_THRESHOLD) parks the entry at HTS Classification for broker review; this floor is separate from (and lower than) the display-only 92% Autopilot toggle.

Dependencies

What success looks like

MetricBarToday
State transitions are reproducible100%✓ — pure function of (status, action, context)
Every transition logged with agent + reason100%
Cannot skip statesEnforced✓ — legalActions() is the only path
Screening block routes to hold before it can advanceEnforced✓ — a block-band screening hit sends the entry to hold at classification time; a broker must clear it
AI auto-approvalSuspended (calibration hold)Every classification routes to broker review; no line/entry auto-advances today
Blocking errors caught before transmit100%✓ — Screening blocks prevent ready → filed

What it does NOT do

  • Does NOT decide what to classify or how to screen — it just calls the right agents at the right transition.
  • Does NOT transmit to CBP today. The transmit action moves the entry to filed and produces the ACE message envelope, but doesn't yet POST to CBP's network. Planned.
  • Does NOT auto-respond to CBP exams or holds — those always require a broker. The state machine surfaces the legal next action; the broker takes it.
  • Does NOT roll back transitions. Once filed, the way out is forward (cleared / released / exam / hold) — undo would require a Post Entry Amendment, which is a separate workflow.

Roadmap

  • Planned — Wire transmit to actually POST the ACE message envelope to CBP's network. Requires bond + carrier code.
  • Q4 2026 — CBP CSMS message ingestion → automatic state transition when a hold is released or an exam is scheduled.
  • Q4 2026 — Org-level Autopilot policy (different thresholds for different importers, different duty caps, different chapter rules).
  • Q1 2027 — Org-level auto-approve caps by duty exposure (e.g. "auto-approve only when total duty ≤ $50K"). Not yet built — the state machine carries no duty or confidence logic today.
Ready to see it live?

Put your own book of entries through Aduaria.