﻿# Terminal request records: reconcile stream, usage and logs

Build one terminal inference request record, reconcile stream completion and usage, and avoid duplicate outcomes when telemetry events are redelivered.

Author: Retrivium team
Updated: 2026-11-01
Canonical URL: https://retrivium.ai/journal/provider-terminal-request-record-consistency/
Language: en

## Why records disagree

A proxy observes a connection closing, an engine reports generation completion, and the collector receives usage later. If each component independently increments a successful request counter, one user call becomes several outcomes. The opposite happens when the last event is lost: the text has arrived, but the log still considers the request active. A terminal record should therefore describe the lifecycle of a specific attempt, rather than count received messages. Store a logical request identifier, an attempt identifier and the observation source separately. Retrying through another engine creates another attempt even when the external operation remains the same.

## Assign the transition owner

A useful internal model contains accepted, running and terminal states, with completed, failed or cancelled outcomes. This is a proposed service model, rather than a universal OpenRouter schema. One component owns the final transition; other components supply facts. [Prometheus instrumentation guidance](https://prometheus.io/docs/practices/instrumentation/) distinguishes completion counters from measurements of work currently in progress. In practice, increment the outcome counter only after successfully committing the transition. Redelivery with the same event key must not repeat that change. Events arriving after terminal may enrich the record, but should not return it to running without an explicitly documented correction.

## Separate outcome from accounting completeness

A minimal record includes outcome, classification evidence, acceptance and completion times, whether content was forwarded, usage completeness and contract versions. Missing usage must not silently become zero. In [OpenRouter streaming documentation](https://openrouter.ai/docs/api_reference/streaming), accounting information arrives in a separate final frame; processing it should enrich accounting rather than finish generation again. A completeness field distinguishes an observed zero from an unknown value. Keeping original supplier values separately from normalized values also makes later discrepancies explainable without reconstructing user prompt content from logs. Completeness is its own dimension, rather than an additional request outcome.

## Exercise the completion and cancellation race

A diagnostic scenario reproduces this order: the client disconnects, the engine finishes, then usage arrives. First define what cancelled means: client intent, engine acknowledgement or absence of a result on the client side. These are different observations. [OpenRouter generation metadata](https://openrouter.ai/docs/api/api-reference/generations/get-generation) provides an external example with additional signals, but does not define internal transitions for an arbitrary provider. Repeat the test with reordered events and deliver the terminal message twice. The attempt should retain one outcome, an explainable classification basis and a separate indication when the user experience and server outcome disagree. Such a disagreement is evidence to preserve, not an event to discard.

## Reconcile records with aggregates

A periodic reconciliation compares accepted attempts with active and terminal records over an agreed window. Allow a defined delay for late messages; otherwise ordinary transport lag resembles data loss. Put discrepancies into a separate identifier list rather than high cardinality metric labels. See [usage accounting](/journal/openrouter-usage-accounting/) and the [token accounting model](/journal/router-billing-token-accounting/). This reconciliation checks the consistency of a particular ledger. It does not establish delivery to the client, correctness of another platform's charges or error free tokenization. Each of those claims requires its own source of truth and a separate validation procedure.
