Gallatin AI

Frontend Engineer

Gallatin AI builds Navigator — a real-time command-and-control platform for military logistics, used to plan and track the movement of people, equipment and cargo. I work on the layers underneath: the data layer every feature is built on, the realtime path that has to survive a burst of edits, and the boundary an agent has to cross before it can write to a plan.

The device has to hold the truth

  • SWRV
  • → TanStack Query
  • → TanStack DB
  • → local-first

A boundary — and the truth is on the near side of it

Planneredits a loadThe device — everything in here works with the link downPlanLoadsMaplive queryOne normalized cacheeach record stored once — the device owns itmay be goneServernot the sourcereconcile when the link returns
The server is not the source of truth. Everything inside the frame keeps working with the link cut — which is why the boundary is drawn as a frame rather than as the arrow it would be in an ordinary client-server sketch.

Navigator runs where the network doesn’t. A planner opens a movement order on a machine that may not reach a server for hours, and the original data layer treated the server as the source of truth — so every screen was a cached opinion about a record it did not own, and going offline meant going blank.

I proposed the move off it and led it, through TanStack Query and onto TanStack DB. Every record now lives once in a normalized cache on the device, and every view that shows that record is a live query against it — so editing a load in one panel updates the six other places it appears, with no refetch and no network. When the link comes back, the local writes and the server’s reconcile.

The point isn’t offline as a feature. It’s that the screen stops lying: what you see is what the device knows, and it knows because it holds the data rather than because it just asked. Every feature built since is built on that layer.

One save became a storm

  • one owner
  • batched by tick
  • deduped by record
  • burst-safe

Two timelines — the same burst, before and after

Was — nothing owns the streamOne saveSametickScreen disagreesand shows no error at allone edit, many recordsthey land together; last one winsthe failure with no symptomIs — one place is responsibleOne saveOneownerA burst is a burstnot just its final framethe same editbatched by tick, deduped by recordthe server would recognise itSame four events on both tracks. The only difference is who is listening.
The failure had no symptom. Three of four events vanishing looks identical to nothing happening — which is why the drawing shows the dropped ones rather than describing them.

A save in Navigator doesn’t touch one record. Moving a departure time moves the loads on it, the equipment assigned to those loads and the people assigned to that equipment — so a single edit fanned out into a burst of requests, and the socket events came back together in the same tick.

Two things were wrong at once. Nothing owned the stream, so several components each subscribed and each reacted; and events arriving in the same tick overwrote one another, so the last one won and the rest were dropped on the floor. That is the worst failure a planning tool can have, because nothing about it looks like a failure — the screen disagreed with the server while telling the operator everything was fine.

I made one place responsible for the socket. Events are batched by tick and deduplicated by record, so the whole burst is applied instead of just its final frame. A plan on screen is now a plan the server would recognise.

An agent that has to ask

  • typed results
  • agent proposes
  • human approves
  • then it writes

A gate — drawn with the path that does not exist

Plannerapproves, or does notAgentproposes a changecallsTyped resultan object, not proseso the interface can render a diff instead of a paragraphThe gatewritesThe planthe instructionthere is no path from the agent to the plan that skips a person
The crossed-out line is the whole design. An invariant is usually an absence, and an absence is the one thing a paragraph states and a reader never quite believes.

I built the front end for the product’s first agent workflow. A movement plan is an instruction, not a document — by the time a wrong one is noticed, equipment has moved. So the design question was never how capable to make the agent. It was where to put the person.

Two decisions carry it. Tool results come back as typed objects rather than free text, so the interface can render a proposed change as a diff a planner reads, instead of a paragraph they have to take on trust. And every write the agent proposes stops at a gate: it proposes, a human approves, and only then does anything change.

The agent has no route to the plan that doesn’t pass through someone.

A red suite teaches you to ignore it

  • signal restored
  • bugs surfaced
  • design system
  • lead contributor

A signal, and the noise it was indistinguishable from

Was — every run redone is a real regressionand you cannot tell whichIs — green, so red means somethingthis one you act on
Both rows carry the same regression. The drawing is about what a reader can pick out, which is the only thing that changed — and the only honest way to show it without numbers.

The end-to-end suite had been failing long enough that a red run had stopped meaning anything. That is the real cost of a red suite, and it isn’t the broken tests: a genuine regression arrives looking exactly like the noise everyone has learned to scroll past.

I took it green, and the bugs it had been hiding came out with it — which is the part that makes the case. They had been reported the whole time. Nobody could see them.

I also created the shared design-system repository and remain its leading contributor. Neither of these is a feature anyone can point at in the product. Both are why features stopped costing what they used to.