A signal-driven fill is easy to justify on the day it happens and very hard to justify eight months later. The person asking will not be the person who took it, the screen that produced it has refreshed several thousand times since, and the only artefact that survives by default is the fill itself. A fill says what you did. It says nothing about why, and why is the half the reviewer came for.
The fix is not a better memory or a longer trade note. It is deciding in advance which fields are written to durable storage at the instant the signal exists, and accepting a hard rule about everything else: anything you plan to look up later is not evidence.
What the feed hands you at signal time
The Market Reversal Engine presents each setup as a row with nine fields. Ticker, Price, TF, Signal, Side, Type, Read, Time, and an Action control. Eight of those are structured. One of them, Read, is prose, and the prose one is simultaneously the most valuable and the most fragile.
A representative Read string from the capture is "Confirmed 5-minute break-down and AMS M6 shows strength". That sentence names both the price-action condition that triggered and the engine leg standing behind it. It is the closest thing on the screen to a stated rationale, and it is the field an integration is most likely to drop, because integrations map typed columns and treat free text as decoration.
Store it verbatim as an unparsed string, in addition to whatever structure you extract from it. Any parser you write today will eventually meet a phrasing it does not recognise, and on that day you want the original sentence sitting next to the failed parse rather than a null.

Look at what that Action column implies. The path from signal to ticket runs through a control on a page. Whatever your integration is, the gap between the row and the order record is where provenance goes missing, and nothing in the vendor's display is obliged to close it for you. Closing it is your side of the boundary.
Freeze the inputs rather than planning to recompute them
MRE composes three scorecards. AMS combines 11 breadth and on-chain metrics. MMS is a momentum scorecard running across 6 timeframes. GLS tracks 8 central bank balance sheets. Each of those is a living object that will read differently tomorrow, and two of them will read differently by the end of the session.
This is the failure mode that ruins otherwise careful audit trails. Someone stores the ticker, the side and the timestamp, then assumes the engine state can be reconstructed on demand from the scorecards. It cannot. A scorecard recomputed in March is a March object wearing a January label, and a reviewer who understands that will discount everything you show them from it.
So capture the engine readings as of the signal bar, at the level of granularity you can actually get. If you can retrieve constituent metrics, store them. If you can only observe the composite state the platform displayed, store that, and store explicitly that it is what you had. A recorded limitation is defensible. A silently reconstructed number is not, and the difference costs nothing to establish at write time.
Three clocks, and the offset nobody wrote down
The Time column prints to the second. Aug 25, 2026, 08:09:05 on the SOL row, 21:11:04 and 05:30:06 on the two BTC rows. What the column does not print is a timezone. That is not a footnote, it is the first unresolved item in the specification, because every session mapping, every latency measurement and every sequencing argument you will later make depends on it.
Three timestamps belong on each stored row, and they are three different measurements rather than three copies of one.
- The vendor stamp, verbatim, exactly as rendered, plus a separately recorded determination of what clock that column runs on. Establish it once, document how you established it, and do not infer it row by row.
- Your receipt time, in UTC, from a synchronised clock on your own infrastructure. This is the only stamp you control and the only one you can defend the provenance of.
- The order ticket time from the OMS.
With all three you can demonstrate sequence: the signal existed, then a decision was made, then an order was created. Sequence is the specific thing a compliance review is testing when it asks about a signal-driven fill, because the alternative story it has to rule out is that the rationale was assembled after the position was on.
The confidence field you have to build yourself
If your routing rule contains a threshold, be precise about what it is thresholding. The MRE feed as captured exposes Signal state, Side, Type, timeframe and the Read sentence on each row. It does not print a per-row numeric confidence in that view, so any score your router compares against a cutoff is a score you computed.
That is a perfectly reasonable design, and it moves an obligation onto you. The scoring code is now part of the audit record. Persist its version identifier, the input vector it consumed, the output it produced and the threshold that was in force at that moment, on the row, at signal time. Not in a config file, not in a wiki page, on the row.
Threshold drift is the most common adverse finding in this whole area and it is almost never malicious. Someone loosens a cutoff during a quiet week, the change goes in without a dated record, and six months later a cluster of marginal trades has no explanation for why it was eligible. If the threshold lives on the stored row, that entire class of question answers itself and the reviewer moves on.
Detecting restatement before it becomes your problem
Vendor history is not immutable simply because it is historical. Feeds get corrected, backfilled, deduplicated and reindexed, all of which are legitimate engineering acts that quietly rewrite the record you cited in a memo.
The defence is cheap. Hash each row you ingest across its meaningful fields, store the hash, and diff the visible history on a schedule. When a row you have already acted on changes, you want an alert rather than a discovery. Keep your own copy as the record of what you saw, and treat the vendor's current view as a separate object that happens to overlap with it.
The header counters are worth reconciling on the same schedule, because they are the fastest way to spot that something upstream moved. At capture the archive counter read 100 of 3,022 while the setups tile showed 2 in the last 24 hours against a 7-day average of 30.3 per day, and tickers covered read 4 over the last 30 days against a stated coverage universe that includes three crypto assets, three equity indices and blue-chip names. Those numbers are not contradictory, they are measuring different windows and different things, but a desk that has never reconciled them once does not know that, and will find out at the worst possible time.
The questions the stored row has to answer alone
Test any implementation against a single standard. Hand the stored row to somebody with no access to the platform, no access to you, and no context, and see whether they can answer five things: what fired, on what instrument and timeframe, what the engine state was at that moment, when it happened on a clock you can defend, and what rule made it eligible to route.
If any of those requires opening the live product, that field is not in your audit trail yet. It is a lookup, and lookups expire.