The test of an audit trail is not whether it exists. It is whether a competent person who was not in the building can take one order out of the middle of last year and reconstruct why it was sent, using only what you stored, without asking anyone. Almost every trail I have seen fails that test in the same place. It records what happened to the order and says nothing about the state of the world that produced it.
Autopilot describes itself as keeping a full audit trail, and the History and Analytics tabs are where the execution record accumulates. Treat that as the floor rather than the ceiling. An execution record tells you an order existed, at what price it filled, on which venue. The question you will actually be asked is upstream of all of that.
The question, and when it arrives
It arrives in one of four situations and the timing is what makes this hard. A client or an allocator reviewing performance wants to understand a specific loss. Compliance is testing whether the strategy did what the disclosure says it does. A regulator or auditor samples orders and asks for the basis of each. Or, most commonly and least formally, the strategy stops working and you are trying to establish when the behaviour changed and whether anything on your side changed with it.
All four arrive months after the fact, by which time the signal source has been revised, the profile has been edited a dozen times, the person who configured it has moved teams, and the market data vendor has quietly restated a week of history. Narration will not survive that. "The momentum signal fired" is not a record. It is a description of a category of event.
Inputs as of decision time, not as of now
This is the single most common structural defect, and it is worth being precise about the failure. If your record stores a pointer to an input rather than the value of that input, you have not recorded the decision. You have recorded a lookup instruction that will return a different answer later.
Consider a profile that follows a momentum feed on a daily timeframe. A year on, you go back to work out why it entered. You query the signal source for that date and get a value. That value has been through vendor price corrections, a backfill when a data gap was repaired, possibly a change in how the indicator itself is computed, and a survivorship adjustment on the universe. It may not be the number the engine saw. Sometimes it is not even the same sign.
So store the value, not the reference. At minimum, for every order: the signal identifier and its numeric value at decision time, the reference price the engine used, the timestamp of the input as distinct from the timestamp of the decision, and the source that supplied it. If the input arrived as a message, store the message. Storage is the cheapest thing on this list by a wide margin and it is the only part that cannot be reconstructed afterwards.

The four fields that do the reconstruction
Beyond the inputs, four things turn a log line into a defensible record. They are cheap to add at the point of writing and impossible to add later.
The rule version. Not the profile name, the version. The names on my own overview describe what a profile follows and say nothing about which iteration of the configuration was live. Attach an immutable version identifier to every order, derived from the actual configuration rather than typed by a human, and keep the configuration itself addressable by that identifier. The test is simple: given an order from last March, can you retrieve the exact parameter set that was live when it was sent? If retrieval requires reading a change log and inferring, the answer is no.
The guardrail state at the moment of the decision. The module offers risk guards, trailing stops and partial take profits. Whatever values were in force need to be on the order record, because the most interesting question about a bad trade is often whether the protection you believe was in place was actually in place. A record showing the trailing stop was configured at three percent at 14:22 on the day answers that in one line. Reconstructing it from a change history and a memory does not.
The authorising human. Every automated order traces back to a person who authorised the configuration to act, and to a supervisor who was responsible for it that day. Both names belong on the order, denormalised, not joined at query time to a table that will have been updated since. When the person changes, old orders keep the old name, which is the entire point.
The alternative that was not taken. Where the engine chose between candidates, or sized down, or picked one venue over another, record the losing option and the reason. This is the field people consider excessive until the first time someone asks why a smaller size was used, and the record can say that the exposure guard was at eighty percent utilisation rather than leaving you to argue that it probably was.
The orders that were never sent
A trail made only of executed orders describes a strategy that never declined anything, and every real strategy declines constantly. The negative record is at least as valuable as the positive one and it is almost always missing.
Log the signal that arrived and was not acted on, with the reason. Concurrency ceiling reached. Exposure cap binding. Instrument outside the permitted universe. Profile disabled. Venue unavailable. Each of these is a decision your controls made on your behalf, and each one is invisible in an execution log.
Two things depend on having it. The first is attribution. When the profile's realised results diverge from the signal source's published results, the decline log is the only evidence that distinguishes "our guardrails cost us four hundred basis points" from "the signal stopped working", and those two conclusions lead to opposite actions. The second is control testing. A guardrail that has never fired has never been demonstrated to work, and a compliance function asked to evidence that a limit is effective will want to see it binding, with timestamps, rather than a screenshot of the setting.
Four clocks, and where the record has to live
There are at least four timestamps around every automated order and they are not the same: when the input was generated at source, when the engine made the decision, when the order was transmitted, and when the venue acknowledged or filled it. Store all four in UTC, with the offset preserved if anything upstream reports local time. The gaps between them are diagnostic. A widening gap between input generation and decision is a data latency problem showing up before it becomes a performance problem, and you will only see it if the two are separate fields.
As for where it lives, the requirement is that the record cannot be revised by the system that produced it. Append only, retained on the schedule your regulator or your fund documents require rather than on the platform's, and held somewhere you would still have access to it if you stopped being a customer tomorrow. A trail that lives only inside the execution engine is a trail whose integrity rests entirely on that engine, which is the thing under examination.
The operational shape that works is a nightly export of the day's decision records into your own append only store, reconciled by count and by checksum, with the reconciliation result itself logged. That last part sounds like bureaucracy until the morning the export silently produces zero rows and nobody notices for five weeks.