Justin Smith

The operating platform

Adventure Idaho · 2026

Modern booking platforms can assign a guide and reserve a vehicle. That was never the hard part. The hard part is keeping the operation current as bookings, people, vehicles, geography, and field conditions change underneath it, all day. This is the layer I built to run at the speed the operation actually moves.

If you want to see what this looks like day to day rather than how it works underneath, start with the board that replaced the whiteboard.

Why off-the-shelf scheduling couldn't do it

Most scheduling products assume people and rooms. A person is busy or free, a room is booked or open, and the day is the unit. This operation schedules a dependent graph instead: a trip needs a crew, the crew needs qualifications specific to a river section, the trip needs boats and a vehicle and often a trailer, the vehicle needs a driver with the right license, and the whole thing has to be somewhere else the next morning. Change one assignment and the consequences ripple through shuttle logistics two days out.

The part that breaks every product I looked at is that resources here aren't consumed by the day. A guide can run a day trip in the morning and launch on a five-day expedition that afternoon. A trailer might serve three or four different trips in a single day, moving between put-ins and takeouts on different rivers. Booking software wants to pin one vehicle and one trailer to one trip for one day, which is tidy and wrong. What actually governs the schedule is drive time between points, how far one trip's window overlaps the next, and how long a rig takes to reset between uses. None of those are a calendar.

The constraints aren't static either. Trip types have different crew ratios, different rigs, different put-ins. Capacity is gated by permits. Off-the-shelf tools can express "this person is busy." They can't express "this trailer is committed until it clears the takeout and drives back," or "this guide isn't cleared to lead big water."

Where AI sits

Everything described above this is a real operational database: constraints, qualifications, capacities, and dependencies, codified. That is the part that makes what follows possible. The AI layer has read and write access to it and knows the operation's rules, so it isn't guessing at English, it's acting on a model of how this company actually works. That is the difference between a chatbot bolted onto a booking product and an operations layer. The booking system is the system of record. This is the system of action on top of it.

The booking connection is read-only: it pulls from the booking system but does not write back into it. Our own operational records are where the updates happen. The booking system records the transaction. The operation lives in the layer on top, where our own records are read and written in real time. It's also why none of this is tied to one booking platform: swap the connector and the model comes with you.

The obvious version of this is an AI that drives your booking software for you, clicking through the screens. I built that first. It's too slow and too brittle, because that software was never designed for a machine to operate at speed, even with an agent driving a browser. The bottleneck isn't the model, it's the data layer. So the real work was the database: 44 interconnected tables and 207,000 connected data points modeling guides, certifications, rigs, trailers, permits, movements, and compliance, with the operation's rules encoded as data the engine reads. That depth isn't vanity. It's the only shape that can hold an operation where a guide runs a morning day-trip and launches on a five-day that afternoon, and it took a full season of real edge cases to get right. The AI is the interface. The operating model is the moat. It gets deeper every season, because every operation and exception it survives is context no competitor and no foundation model starts with.

It's the interface, not the decision maker. The speed difference is the whole point: instead of opening records and hand-editing every name, contact, and field one at a time, I say what changed and the system works out what that touches. Updates get made by voice from a truck. Questions get asked in plain language against live operational data. Reports that used to take days get generated in minutes. When the schedule tightens, it helps me see moves that used to take an evening to work out, like when one rig can service two trips inside the same window instead of sending two. An operation moves faster than booking software was built to move, and typing was the bottleneck. A guide messages that a blinker is out, the VIN is already in the vehicles table, and a minute later the exact bulb part number and the steps to change it are posted to the channel and the repair is logged against that vehicle. Then the part lands on the shopping list, the same list the food run works from, so whoever is next in town picks up the bulb alongside the groceries and nobody has to remember to ask. That is the whole point of one model instead of four automations: a maintenance report in a channel turns into a purchasing task in a different workflow, because the system knows they are the same operation. No booking system is going to ship "which bulb fits this van," and it shouldn't have to. It took one sentence.

A spoken request being dictated into the operations system on a phone, waveform showing, asking it to check river miles per guide for the year, who is over and under utilized, who has not been on the bigger multi-day trips, and when vehicles could go to the shop. The same request transcribed in full, ending with an instruction to pull recent guide messages about scheduling conflicts, build them into the board, and return an overview layer for a person to verify.
A spoken request becomes real changes, with a human verifying. Note how it ends: build it into the board, then give me an overview layer I can check. The asking is the fast part. The verifying is the part that stays human.

The other half is reading what the team already says. Operations don't announce themselves as structured records. A guide mentions a doctor's appointment in a channel, a boat tube tears and that boat can't go out again until it's fixed, a group asks to be picked up an hour later than the booking says, a vehicle problem comes in on the ops issue form. Each is a future conflict wearing plain clothes, and on a whiteboard it stays invisible until the morning it isn't. Claude reads across the channels, updates the operational record or stages the change, and the conflict engine re-checks the schedule so the collision surfaces while there is still time to solve it. The alternative isn't a tidier database, it's endless texts and whoever happened to read them.

But anything touching money, compliance, or safety requires a human confirmation, and the system reports back exactly what it changed so a person can verify it. That constraint isn't a limitation, it's what makes the crew willing to use it.

Here is what the speed actually buys, and it is the part I did not expect. Planning used to be 20 to 40 hours a week of tracking every detail by hand. It is 2 to 4 now, and the hours did not disappear, they moved to the work I actually like: putting the right guides with the right guests, building the crews that make a trip click, finding the part-timers who are thrilled to be there and lift the culture, and hunting the next revenue line or the next thing to make more efficient. The manual labor was never the job. It was in the way of the job.

The conflict engine

The largest single component. It walks the schedule and flags three classes of problem: hard conflicts where a person or asset is committed in two places, soft conflicts that need a human look, and missing data where it can't judge safely. That third category matters more than it sounds. A system that silently passes incomplete records teaches people to distrust it.

It runs two ways: event-driven when a record changes, and on a schedule as a safety net, because event triggers eventually miss something. It went through 27 versions, and most of those versions exist because real operations kept producing edge cases the model hadn't imagined.

Configuration as data, not code

The single most useful architectural decision was pushing business rules out of the code and into tables: trip type rules, conflict rules, capacity tiers, and a config table of thresholds. Adding a trip type is a row, not a deploy.

That decision is what makes the system portable. The rules are the part that's specific to one company. The engine that reads them isn't.

A model of the river that gets better every week

Drive time on a river is not a constant, and it is not a road. How long a float takes changes with flow, wind, and the kind of crew, and the gap between two put-ins changes with it. So the system models it: a guide radios a launch time, and it pulls current flows, factors wind and trip type, and tells a driver when to leave to be at the takeout before the boats. Every timed run that gets logged tightens the estimates, and a guide's radioed ETA always overrides the model. The model of how this operation moves through time and geography gets more accurate the longer it runs. That is the part a foundation model doesn't bring with it: the accumulated truth of how this particular operation moves through time and geography. It doesn't know that this trailer needs forty minutes to reset, that this stretch runs slow in a headwind, or that this guide is cleared for this water and not that one. That accumulated operational truth is the application.

The team channel showing the timing model's output: paired messages telling a driver to leave in about ten minutes for a pickup roughly ten minutes away, each naming the group size in guests plus guides and the time the boats are expected to land, with a satellite text relayed in from a camp below them.
What the model puts out. Each ping carries the drive time, the group size in guests plus guides, and when the boats are expected to land, timed off the trip that is actually on the water rather than the one on the schedule. Names and numbers redacted.

The money the booking system can't see

The booking system knows the balance. What it doesn't do is turn that balance into an operating priority. The number sits in a record, correct and passive, and nobody is continuously asking the question that matters: what is launching soon, what is still owed on it, what changed since yesterday, and what does a person need to deal with today.

So the system reads the booking data every morning and posts what is still owed on trips going out in the next six days: which reservations changed, what is outstanding, and a link to contact the guest. It is a plain report with working links, which is the whole trick. Balances get handled before the trip launches, not chased after it. The daily digest is covered in detail here.

Collecting money you are already owed, before the guest is on the water, isn't new revenue. It's the same revenue arriving on time instead of late or never. That is the argument for an operations layer in one sentence: the booking platform isn't wrong, it just isn't looking.

The loop that closes

The system doesn't just flag problems, it carries them to done. Anyone reports an issue, by text or a form, and it becomes a tracked task with a category, a priority, a linked asset, and a named owner. If it needs buying, one checkbox puts it on the shopping list, so it rides to town on the same run as the groceries and comes back installed. So far it has carried 130 issues, closed 97, and put 69% of them on a specific person's row. Of the 14 items that have reached the shopping list, 9 were vehicle or trailer safety parts: a jack, a battery, wipers, a tire tool, the things that get forgotten until they strand a trip.

Here is one loop end to end. In June a rental went out with the wrong oar lengths, a guest complaint. It became a task: match every oar, buy tape and colored zip ties, assigned to a person. Eight weeks later a guide reported back, unprompted, that the shop now runs a blue-and-purple tape system that keeps every pair of oars together, and the counts landed in the inventory table the same night. A guest-facing failure became a purchase, became a physical system in the shop, became a row in the database, with a person doing the real work in the middle and nothing dropped across eight weeks. A booking system records the reservation. It has no concept of a bent oar, a shopping run, or who rigged the boat.

Integrations

Reservations sync from the booking platform through a purpose-built API adapter, hourly, with a nightly deep reconcile and a de-duplication pass. Cancellations cascade: cancel a reservation and the day's operation, its driving movements, and its trip log entries all stand down together. Alerts route to Slack. Texts from satellite messengers route through a company number into a team Slack channel, so a message from a canyon with no cell service reaches everyone who needs it rather than whoever happened to be holding the phone.

The adapter pattern is deliberate. Everything downstream of a standard intake table is portable; only the connector is vendor-specific.

The one direction that does not work yet is back. Reservations flow in, and nothing flows back to the booking platform, so capacity, availability and prices are still typed in by hand. What we need from booking software next is written up in Everything is connected except the booking software.

How it was built

I built it the way Build it centralized. Run it distributed. describes: one person who knew the operation, designing the model and directing AI coding tools, with nothing waiting on a handoff. I write the specification, review every change, test it against real days, and ship it. The code is the fast part now. The judgment is deciding what the model has to know, which rules are hard limits, and where a person stays in charge.

AI coding tools are confident on the easy cases and wrong on the edge cases an operation actually lives in. So the system is built to be corrected. Every change is checked, every override is logged, and each override becomes a new rule or a clarification. Most of the rules nobody had written down came out of that log. That loop, more than the code, is what kept it right while 44 people ran a season on it.

What made it possible is the operating experience behind it: guiding, hiring and training crews, sales, and running the day. More on that background. The wider argument is that booking software solved the transaction and left the operation unbuilt.