There's a little buglet in #85387 (which was the PR that closed #84046), specifically, it doesn't account for the possibility that there's both a default/request **and** and a final pipeline, and that they can both touch the `@timestamp` field.

`IngestService#postIngest` was added in #85387, and it's intended that the logic there only runs **once**, after all the pipelines associated with the request have been executed. But as it's currently written, the logic actually runs after each individual pipeline runs.

The consequence of that is that if there's a default/request and a final pipeline in use for a document, and the final pipeline changes the timestamp field, the `rawTimestamp` recorded for the `IndexRequest` associated with the document will mistakenly use the value it sees after the default/request pipeline runs, and **not** the most correct one (from after when the final pipeline runs).

/cc @martijnvg 
server/src/main/java/org/elasticsearch/ingest/IngestDocument.java
private final IngestCtxMap ctxMap;
    private final Map<String, Object> ingestMetadata;
    /**
     * Shallowly read-only, very limited, map-like view of the ctxMap and ingestMetadata,
     * for providing as a model to TemplateScript and ValueSource instances. This avoids the cost of
     * constructing a purpose-built map on each template evaluation.
     */
    private final DelegatingMapView templateModel;
    
    private final Set<String> executedPipelines = new LinkedHashSet<>();
    private boolean doNoSelfReferencesCheck = false;
    public IngestDocument(String index, String id, long version, String routing, VersionType versionType, Map<String, Object> source) {
        this.ctxMap = new IngestCtxMap(index, id, version, routing, versionType, ZonedDateTime.now(ZoneOffset.UTC), source);
        this.ingestMetadata = new HashMap<>();
        this.ingestMetadata.put(TIMESTAMP, ctxMap.getMetadata().getNow());
        this.templateModel = initializeTemplateModel();
    }
    /**
     * Copy constructor that creates a new {@link IngestDocument} which has exactly the same properties as the one provided as argument
     */
    public IngestDocument(IngestDocument other) {
        this(
            new IngestCtxMap(deepCopyMap(other.ctxMap.getSource()), other.ctxMap.getMetadata().clone()),
            deepCopyMap(other.ingestMetadata)
        );
    }
    /**
     * Constructor to create an IngestDocument from its constituent maps.  The maps are shallow copied.
     */
    public IngestDocument(Map<String, Object> sourceAndMetadata, Map<String, Object> ingestMetadata) {