Industries

Firmware rollouts for agricultural robots.

Machines that work under canopy, at the far end of a paddock, and only see real bandwidth when they come back to the shed. Temper stages releases against operating hours and lets each machine prove itself before the fleet follows.

What breaks in agriculture, specifically

The generic version of this problem is well understood. These three are the ones that make a datacentre-shaped rollout tool useless on a farm.

The calendar is agronomic

Harvest and the spray window are the weeks the farm earns its year. A regression there is not a bad sprint, it is a season. Rollouts have to know about blackout windows and refuse to start inside one, no matter what the release train says.

Bandwidth lives at the shed

Under canopy and at the back of a paddock, LTE is marginal and satellite is blocked by the same trees you are working through. The reliable uplink is the yard, and it might be tomorrow, or next fortnight.

Every farm is a different fleet

Machine generations, implements from three vendors, and a customer still on last season's build because it is the one their planter agrees with. Uniform firmware was never the goal, but nobody can say what is where.

What a health gate looks like on a farm machine

Signals worth gating a row-guidance release on
SignalWhy it gates here
row_follow_error_cm.p95Drift is crop damage, not a log line. Anything past a few centimetres puts the implement into the row you were paid to protect.
rtk_reacquire_secondsA unit that takes ninety seconds to re-fix after boot is unusable at the start of a run, and the operator will switch it off rather than wait.
spray_rate_deviationOver-application is a chemical cost and a compliance event. Under-application is a re-spray. Both show up before any service crashes.
implement_can_uptimeA new build that silently drops the implement bus looks perfectly healthy from the control plane. The machine still knows.
hours_to_first_safe_stopOperator trust is the real adoption metric. A machine that stops twice a shift gets parked, and the firmware never gets blamed.
uplink_interval vs baselineThe dark-rate signal, computed per farm. A shed with no coverage is normal; that same shed going quieter than its own fortnightly baseline is not.

The same rollout, written for a paddock

rollout.yamlagriculture
# Rings follow the season, not the sprint.
release: row-guidance@2.4.1
rollback_to: 2.3.0            # pinned known-good slot

blackout:                     # never roll inside the window that pays for the farm
  - { window: harvest, sites: broadacre }
  - { window: spray, sites: orchard }

verify:                       # runs ON the machine, offline
  trial_boot: 3 attempts
  confirm_within: 2 operating_hours
  checks:
    - service: row-guidance healthy
    - metric: row_follow_error_cm.p95 < 4
    - metric: rtk_reacquire_seconds < 25
    - link: implement_can up
    - reachable: control-plane   # killed the modem? revert
  on_failure: revert_and_report

rings:
  - name: canary
    match: { fleet: internal }
    soak: 40 operating_hours     # engine hours, not wall clock
  - name: home-farm
    match: { site_type: controlled }
    soak: 120 operating_hours
  - name: early-customers
    match: { tier: design_partner }
    max_concurrent: 4            # one machine per farm at a time
  - name: fleet
    match: { all: true }
    requires_approval: true

ring_gate:                    # gates on evidence, never on silence
  min_confirmed: 12 units     # or 60% of ring, whichever is lower
  max_self_reverts: 0
  checkin_regression: 1.5x    # vs this ring's 14d dark-rate baseline
  stale_after: 14d            # a machine can sit in a shed for a fortnight
  on_timeout: escalate

on_gate_failure: halt_and_rollback

Two things in that file do not appear in a datacentre rollout. Soak is counted in operating hours, not wall clock, because a machine parked in a shed for two days has proved nothing and should not be allowed to advance a ring. And stale_after is set to fourteen days rather than seventy-two hours, because a fortnight of silence is a normal off-season for a header, not evidence of a problem. A stale unit drops out of the denominator. It never counts as a pass.

The blackout block is the piece most teams end up building by hand, usually as a shared calendar and a rule that everyone remembers until the one Friday they do not.

How Temper handles it

01Queue now, apply at the shed

The agent pulls when it has signal and stages to the inactive slot, resuming a part-finished download rather than restarting it. Nothing switches over until the machine has a full, signature-checked image. See offline updates.

02The machine decides

The new image boots on trial and runs the checks above against its own telemetry, with no round trip. Clearing the boot counter takes a positive result, so failure is the default. See automatic rollback.

03Rings that match how farms work

One machine per farm at a time, so a bad release cannot take out a customer's whole run. Gates count confirmed units, and a shed full of dark machines neither passes nor blocks. See staged rollouts.

04Deliberate drift, tracked

A customer pinned to last season's build is a supported state with an expiry, not a spreadsheet row someone forgot. See fleet configuration.

Early access

Running machines across paddocks?

We are taking on a handful of fleets this year. If your rollout plan currently depends on a laptop, a ute and a spare afternoon, we should talk.

Founding customers get direct engineering time and a permanent founding rate.