Back to Feed
article 4m read

Replay Retained Inventory Bytes Without Turning Them into Business Records

Retained raw inventory evidence can be replayed safely when the runtime proves replay stays in memory, avoids upstream fetches, and creates no durable business records.

Article DepthPractice

Flow

Replay Decision Loop

Any uncertainty about identity, mode, or side effects terminates before candidate analysis.

  1. 1Validate flags

    Require replay permission, metadata-only behavior, and no persistence.

  2. 2Check retention state

    Reject missing, expired, or inaccessible artifacts.

  3. 3Bind expected identity

    Compare stored bytes with the caller’s exact hash.

  4. 4Prepare isolated reader

    Disable upstream clients and write-capable dependencies.

  5. 5Parse bounded input

    Enforce byte, row, depth, and time limits.

  6. 6Reduce candidates

    Produce stable counts and validation issues only.

  7. 7Assert no effects

    Verify database, queue, and network mutation counters remain zero.

  8. 8Store attempt receipt

    Record the replay outcome without raw identifiers.

Replay is one of those backend features that sounds harmless until its boundaries blur.

A team retains raw inventory payloads because those payloads are useful later. They can explain why a candidate count changed. They can help reproduce a parser issue. They can support a regression test. They can show whether a normalization rule behaved the same way against the same input.

Retention gives the system a stable piece of evidence:

Illustrative anonymized example
These are the bytes that arrived.

But replaying those bytes should not be the same thing as importing them.

That distinction is the center of the design.

A raw inventory payload is evidence, not accepted inventory state. It may include product identifiers, package identifiers, quantities, timestamps, source-specific fields, and other values that look operational.

But until they pass a separate review or promotion path, they remain source-dependent candidates.

Replay should not:

  • turn candidates into source observations
  • turn candidates into canonical facts
  • update production inventory records
  • fetch the upstream system again

The safer design is a read-only replay boundary.

The replay request starts with a retained payload reference and an expected hash. The runtime resolves the artifact, verifies that the artifact hash matches the request, and only then parses the raw bytes in memory.

If parsing succeeds, the reducer emits a summary. That summary may contain row counts, candidate observation counts, and validation issue counts. It may also emit a replay event with a trace ID, payload hash status, byte size, and side-effect flags.

But the replay path ends there.

The system should be able to produce a statement like this:

Illustrative anonymized example
I replayed retained inventory evidence in memory.
I verified the expected payload hash.
I produced a candidate summary.
I did not fetch the upstream gateway.
I did not persist records.
I did not write to the database.
I did not call core mutation commands.
I did not create source observations.
I did not create canonical facts.
I did not print raw values.

Those "did not" statements are part of the feature. They are how the replay path proves that it stayed diagnostic.

This is why a replay result should carry explicit false side-effect fields.

Illustrative anonymized example
{
  "outcome": "replayed_and_normalized_in_memory",
  "payloadHashVerified": true,
  "rowCount": 100,
  "candidateObservationCount": 98,
  "validationIssueCount": 2,
  "gatewayFetched": false,
  "persisted": false,
  "dbWrites": false,
  "coreCommandsCalled": false,
  "sourceObservationsCreated": false,
  "canonicalFactsCreated": false,
  "rawValuesPrinted": false
}

The counts are useful, but they should be understood carefully.

Candidate counts are not business records. They are regression evidence.

If the same retained payload produced 100 candidates yesterday and 97 candidates today, something changed in parsing, normalization, validation, or configuration. That may be important. But it still does not mean the candidates are accepted inventory truth.

Hash gate before parse

The hash gate is the most important early boundary.

If the retained artifact hash does not match the expected hash, replay should stop before parse.

That means no decoded JSON, no row count, no candidate count, and no raw values in the result.

That behavior is conservative, but it is the correct default. When the hash does not match, the system has lost the link between the replay request and the intended evidence.

Continuing to parse would create a privacy and audit problem. The system might accidentally summarize or expose a payload that the caller did not mean to inspect.

Safe replay events

A safe replay event should be designed for audit rather than curiosity.

It can include:

  • event name
  • trace ID
  • retained artifact reference
  • whether the expected hash was verified
  • byte size
  • candidate counts
  • validation issue counts
  • false side-effect fields

It should not include:

  • raw payload bodies
  • raw inventory identifiers
  • store identifiers
  • private paths
  • deployment routes
  • live operational counts

That event can help someone answer:

  • Which retained artifact was replayed?
  • Was the expected hash verified?
  • Was the replay in-memory only?
  • Were candidate counts produced?
  • Did any write path run?
  • Were raw values kept private?

The point is not to make replay clever. The point is to make replay boring and auditable.

A replay path should inspect the same retained bytes again, summarize them in memory, and stop before any durable mutation.

That is the useful system property:

replay without hidden import.

// Illustrative anonymized example
function verifyBeforeParse(actualHash, expectedHash) {
  if (!expectedHash) throw new Error("expected digest is required")
  if (actualHash !== expectedHash) throw new Error("digest mismatch")
  return true
}

Keep reading

Pick up a connected idea or branch into a nearby one.

5 paths forward