A support ticket says the assistant gave a customer bad pricing information yesterday afternoon. You have a name, an approximate time, and a screenshot. Whether that is a ten-minute investigation or an unanswerable question was decided months ago, by which columns you wrote.

Replayable is a property, not a feeling

Here is a definition worth holding yourself to: a request is replayable if you can reconstruct the exact bytes that were sent to the provider, without consulting anything that has since changed.

That last clause is the whole difficulty. Most systems can reconstruct most of a request — but they do it by re-running the code, which has been deployed twice, against the prompt template, which has been edited, using retrieval, which now returns different documents. What you replay is a request that resembles the original. If the bug was caused by any of the three things that changed, resemblance is exactly no help.

The property is testable, which is the nice part. Take a request from a week ago, reconstruct it from the log, hash it, and compare to the stored input_hash. If those match, your logging is complete. If they do not, the diff tells you which field is missing. Run that as a scheduled job over a handful of random rows and you have a continuous check on your own observability, which is otherwise the one system nobody tests until they need it.