Freight cost intelligence · evidence-first

Catch freight cost creep before it becomes your new normal.

Ferro watches every lane week by week, flags cost rises that don't look justified, and explains each one in plain English, citing the exact evidence. It never guesses.

728route-weeks checked
16unexplained rises found
3justified, each with a cited note
0made-up reasons
Mumbai-Pune · cost per tonne-km
This week₹4.49
vs own 8-wk avg+5.7%
vs similar routes+38.9%
RouteOwn 8-wk avgSimilar routes
!
Unexplained riseMumbai-Pune · +38.9% vs similar routes
Note check
  • ✓Right route
  • ✗Right dates
  • ✗Describes a cost rise
  • ✗Big enough
No note passes → flagged for review
✓
Justified · N002Festival-week surcharge, Ahmedabad-Mumbai
Built forProcurementLogistics opsFinance & auditTransport managers Runs offline · Python + pandas · no lock-in
The problem

Freight costs rarely jump. They creep.

Companies pay transporters by distance and weight. Over months, the price on some lanes drifts up, sometimes for a real reason (fuel, tolls, floods, festivals) and sometimes for no good reason at all. By the time anyone notices, the higher rate is the new baseline.

Spikes hide in thousands of invoices

A +35% week on one lane is invisible in a monthly spend report, and nobody has time to read every shipment.

Slow creep hides inside averages

When a rate rises a little every week, its own recent average rises with it. Compared with itself, the lane always looks "normal".

Every rise comes with a story

"Fuel went up." "There was a flood." Some stories are true, some are true but for different weeks, and some are just stories.

Real example from the data

Mumbai-Pune got ~30% pricier in six months, and its own history barely noticed.

Against its own trailing 8-week average, the lane looked only +3–9% high each week. Against similar-length routes it was +20–39% high. Ferro compares every lane both ways, so creep can't hide.

Mumbai-PuneIts own 8-week averageSimilar routes
What Ferro gives you

One clear verdict per lane, per week. With the receipts.

The same four steps run for every route, every week. Every step is visible in the dashboard, so you can check the assistant's work instead of trusting it blindly.

01

Measure

Weekly cost per tonne-km for every lane: total freight bill ÷ (tonnes × km), Monday–Sunday.

02

Compare

Against the lane's own last 8 weeks and against similar-length lanes that same week.

03

Check the evidence

Searches the context notes (fuel, tolls, weather, festivals) and tests each one against four strict checks.

04

Explain

Plain-English reason with the cited note, or "unexplained, review it", plus a suggested next step.

▲
UnexplainedRose past a threshold and no note genuinely explains it → review.
✓
JustifiedA note covers this lane and these dates and describes a real cost rise → cited.
●
NormalWithin the expected range → nothing to do.
Why you can trust it

A true story is not a free pass.

In February 2025 floods hit the Chennai-Bangalore highway. The note says the disruption ran Feb 24 – Mar 8. Costs stayed high for four weeks.

  1. Week of Feb 24: flood note covers it → justified, cites N001
  2. Week of Mar 3: still inside the window → justified, cites N001
  3. Week of Mar 10: roads reopened Mar 9; the window has closed → unexplained
  4. Week of Mar 17: the only nearby note says conditions "returned to normal" → unexplained

Most tools would wave the whole spike through as "flood-related". Ferro only accepts a reason when the route, the dates, the cost effect and the size all match.

See it in the dashboard →

▲ unexplained · ✓ justified · click the chart to replay

Measured, not claimed

Checked against known answers before every release.

Run python -m ferro eval and you get the same numbers.

3/3official sample rows reproduced exactly
20/20hand-labeled weeks correct
18/18adversarial "fake reason" probes rejected
0fabricated justifications
3×identical output, byte for byte
$0per run by default (≈ $0.0004 with an LLM)
The difference

From spreadsheet archaeology to a weekly answer.

Without Ferro

  • Rate rises noticed at quarter-end, if at all
  • "Fuel went up" accepted for every lane, every week
  • Slow creep invisible against last month
  • No record of who checked what
  • AI summaries you can't verify

With Ferro

  • Every lane checked every week, both ways
  • A reason accepted only if route, dates, effect and size match
  • Creep caught by comparing with similar lanes
  • Review queue with statuses, notes and an export
  • Deterministic verdicts; AI only rewords, and is validated
FAQ

Questions people ask first.

Does it use AI? Can it make things up?

Retrieval (a small vector index over the context notes) finds candidate evidence. Deterministic code decides every verdict. An LLM is optional and only rewords explanations; a validator rejects any rewrite that adds a note id, a number, or flips the verdict. In tests a deliberately hallucinating model changed zero graded fields.

What data does it need?

A shipment file (origin, destination, route type, tonnes, km, cost, date) and a short list of context notes. Bad rows are quarantined with a reason, never silently dropped.

How much does it cost to run?

$0 by default: templates write the explanations. With an open-source model on Groq's free tier, a full run is about 19 calls and ≈ $0.0004, and repeat runs are served from cache for $0.

Will it give the same answer tomorrow?

Yes. Three untouched runs produce byte-identical output files. There's no randomness in the decision path, and the optional LLM runs at temperature 0 with a response cache.

Can we tune how sensitive it is?

Yes. Thresholds live in one config file, and the What-if lab shows exactly which weeks would change before you commit. The defaults (+15% vs own history, +20% vs similar routes) are stable across a wide band.

See this week's verdicts in under a minute.

Run it locally. No accounts, no cloud, no build step.

python -m ferro serve
Open the dashboard →