I have written twice about a fireball solver: once about the geometry that makes it possible, and once about three occasions when the physics contradicted what I was building. Both were about pieces. This is the whole thing, what it does, what it refuses to do, and what is next.
The tool is called rainshower. It is not public. Everything below is a screenshot of it running on a worked example whose answer the test suite independently pins, so the numbers on screen are numbers the code actually produced rather than mockups.
The chain
Two people see a fireball. Each reports four angles: where it appeared and where it vanished, in azimuth and elevation. That is all.
From there:
two sightlines -> the trajectory
+ how long it was lit -> the entry speed, as a bracket
+ a date -> the orbit it arrived on
+ a light curve -> how much rock there was
+ a sounding -> where the pieces landed
+ honest error bars -> which squares to walk, in what order
Each arrow is established physics. None of it is mine. What I think is worth showing is not the chain but what happens at the joints, because that is where a tool like this either earns trust or quietly stops deserving it.
It tells you whether to bother
The first genuinely useful thing is not where the rock is. It is whether there is a rock.
Run the orbit backwards from the entry velocity and you get the path it was on before Earth caught it. That path tells you what kind of body it was. An asteroidal orbit means a dense, coherent thing, most likely an ordinary chondrite, and those survive the fall. A cometary orbit usually means a fragile aggregate that turned entirely into dust somewhere above 30 km. A perfect trajectory solution for a cometary fireball is a correct answer to a search that will find nothing.
Here is that panel on the worked example.

Look at what it does there. It does not answer.
The entry speed is not a number, it is a range, because timing a fireball gives you the mean speed over its whole luminous path and one number cannot separate the speed at the top from the speed at the bottom. So the tool runs the entire backtrack twice, once at each end of that range, and issues a verdict only where both ends agree. Here they do not. The slow end says Jupiter-family comet. The fast end is not bound to the Sun at all, which is the signature of an entry speed that is too high rather than of an interstellar visitor.
So it says it is not settled, and it says what would settle it: a tighter duration. That is more useful than a confident label, because a confident label sends somebody out for a weekend and a stated gap sends them back to the video timestamps.
The dash in the Tisserand column is the same instinct. The formula that computes it happily returns a real number for an unbound orbit, because the two negative terms cancel under a square root, and that number means nothing. It used to be printed. Now it is a dash.
Then it tells you where
Given a strength, the tool finds where ram pressure exceeded it and the body came apart, then flies each fragment down through a real wind column and bins the impacts into 500 metre squares.

Those coordinates are the output. Not a heat map to interpret, not an ellipse to eyeball. Six squares, heaviest first, each with the coordinates to walk to and the biggest piece to expect when you get there.
Two things in that panel are there because the physics insisted.
The first is the breakup altitude being a range, 40 to 43 km, for the same reason the orbit is a range. The second is quieter. The note says separation at breakup is 17 m/s and then immediately says that barely matters, because a transverse speed one part in a thousand of the forward speed spreads a field by a few hundred metres, while the wind moves it by kilometres. I built that whole fragmentation model to replace an assumed search width with a derived one. It cannot. The assumed width was closer to right, and the model's real contribution turned out to be the along-track structure instead. Leaving that sentence in the interface rather than in a commit message is deliberate.
And then it tells you how wrong it is
This is the part I would keep if I had to throw the rest away.

Every number in the panels above is a single answer. A single answer with no error bar tells you where to stand, not where to walk. So the tool samples every input together, runs the whole chain a few hundred times, and reports two things.
The first is the search itself: 24.8 square kilometres to cover half the probability, 65 to cover ninety. That is what you actually plan around.
The second is the column headed fix this, and it is the part that changes behaviour. Each input is varied alone, everything else held exact, and the resulting spread on the ground is ranked. On this example, with a careful eyewitness reporting angles to about a degree, the angles are 54 percent of the total error. The advice is not to go and get a better wind forecast. The advice is to go and get a calibrated camera.
Feed the same fireball in with camera-grade angles and those two rows drop by a factor of twenty, and the ranking inverts. Now wind direction leads and surviving mass is second. A tool that always named the same culprit would be decoration. The reason to compute this per case is that the answer moves.
Two rows look like bugs and are not. Timing contributes nothing at all, because how long the fireball was lit sets the entry speed, and the entry speed decides what the object was and whether it is worth searching for, but it does not move the terminal point or the dark flight. A stopwatch buys you an orbit, not a smaller search. And if you enter no wind, the wind direction row reads zero while wind speed does not, because a wind of zero has no direction to be uncertain about.
What it cannot do
This is the half that matters more, and I would rather write it myself than have somebody find it.
It has never been checked against a recovered meteorite. Everything in it is validated against physics: closed forms, conservation laws, two independent methods agreeing to under a metre, scaling laws varied one input at a time. Seven hundred and thirty two assertions. Not one of them compares a prediction against a rock somebody actually picked up off the ground. A pipeline can satisfy every conservation law in it and still point at the wrong field, because the errors that matter live in the modelling choices rather than in the arithmetic.
The harness for that validation is built. It scores two things that fail in opposite directions: containment, was the recovery inside the predicted 90 percent region, and efficiency, how much ground that region covered. Either alone is worthless, because predicting the whole county contains every recovery.
Its case registry is deliberately empty. A validation case is worth exactly what its inputs are worth, and those inputs are somebody else's published reduction of a real fall. Filling them in from memory would compute a figure of merit from invented numbers, which would look precisely like a validation and be worse than having none. So the harness refuses to mark any case as evidence without a source, and stamps everything else with a note saying not to cite it.
What it can do meanwhile is close the loop synthetically: forward model where a fragment really lands, feed only the observations back in, and check the prediction contains it. It does, 290 metres from the centre of the cloud. That tests the frames, the sampling and the scoring all at once. It cannot test whether the model matches reality, because the truth it scores against came out of the same model. I am working on sourcing real falls. Until then the right description is physically sound and empirically untested, and that is what the repository says.
Everything is two-body. Run an orbit backwards past a close encounter with a planet and it stops meaning anything. The code says so in a comment and nothing enforces it.
It needs two observers. That is a geometric limit rather than a software one, and no amount of processing recovers the missing dimension from a single view. It also degrades smoothly rather than failing, so the solver refuses below five degrees of convergence instead of returning a confident wrong answer.
The surviving mass is the weakest link. The light curve now derives it rather than asking you to type it, and doing that honestly made the search area larger, not smaller. On the example above the entry mass comes out tight, 268 to 461 kg, because that is essentially the square of the entry speed bracket. What survives to the ground does not: 0.9 to 38 kg, a factor of forty, because most of a fireball never reaches the ground and how much does is barely constrained. A typed estimate assumes a factor of three. The narrower figure was never real.
What is next
Validation, first and above everything. One sourced fall would be worth more than another month of features. Five would make the containment rate an actual measurement rather than a coin flip, since a well calibrated 90 percent model misses one in ten by construction.
The solar system. The eight planets are already in, with their elements checked against Kepler's third law rather than against the page they were copied from, because re-reading a transcription proves nothing. What is missing is a view. The tool currently has two camera scales, one for the event and one for the globe, and a solar system needs a third that is four orders of magnitude further out.
Other bodies. The propagation machinery handles any conic already, including the hyperbolic ones this app produces routinely, so tracking known asteroids is a data problem rather than a physics one.
Light curves from video instead of typed samples, which is an image processing build rather than an evening of physics.
More than two observers. The error budget is unambiguous that angles dominate for eyewitness data. A calibrated camera is one answer. More stations is the other, and a least squares fit over several would also produce a real residual, which is a measurement of how well the observations agree rather than an assumption about it.
The thread running through all of this is the same one running through everything else I write here: a system that returns a well formed answer that happens to be false is more dangerous than one that crashes. A crash gets fixed. A plausible number gets acted on.
So the interface says not settled when it is not settled, prints a dash where a formula would happily print a meaningless real number, tells you its search area grew when it learned something, and refuses to call one test case a calibration. None of that makes the tool look better. It makes it worth using.