# Immutable chat history without copying content

[Journal](/journal/)

August 2, 2026 · [guides](/journal/#guides)



Ordered snapshots preserve the exact messages behind an assistant result while database checks keep lineage immutable and scoped.

![Five message records feed an ordered verdigris snapshot rail linked to a user message and assistant result.](/_astro/immutable-chat-history-without-duplicating-content.DtZm7qzv_18uPk1.avif)

An assistant result needs the identity of its input history, not another copy of every message. Muniment Cloud now records that lineage as ordered membership in an immutable snapshot.

Our implementation links each newly persisted assistant result to two records. One link identifies its producing user message. The other identifies the ordered history snapshot used for that result.

## A snapshot records order without copying content

The snapshot holds ordered references to existing message rows. It does not copy their content into the assistant result.

That distinction preserves the input identity as a database relationship. A mutable pointer to the thread would only identify whatever the thread contains later.

Each new assistant result can carry lineage. Existing results keep null lineage because no trustworthy backfill can recover their exact input history.

## The database checks the complete boundary

Application code alone does not define a durable lineage contract. The database checks four membership rules:

1.  A snapshot contains no more than 256 messages.
2.  Its ordinals form one contiguous sequence.
3.  Every member belongs to the snapshot’s organization.
4.  Every member belongs to the snapshot’s thread.

The database also restricts lineage to assistant results. Each producing source must be a user message from the same organization and thread.

Together, those checks reject gaps, oversized histories, mixed organizations, mixed threads, cross-thread sources, and cross-organization sources.

## Deferred checks make the transaction the unit

A snapshot and its members enter the database within one transaction. The database defers completeness checks until commit, after the transaction has inserted every member.

This timing permits a valid multi-row write without accepting a partial snapshot. If the final membership remains incomplete or contradictory, the commit fails.

## Immutability has a concurrency test

A direct edit to a snapshot fails. Membership deletion and source relinking fail too.

Concurrent writes need a stronger test because two valid checks can still race. The schema tests hold one transaction open while another connection tries to update or delete a newly referenced message.

Per-thread transaction locks make the competing write wait. After the lineage transaction commits, the competing change fails against the immutable reference.

Whole-thread deletion remains distinct from editing lineage inside a retained thread. Deleting the thread cascades through its messages, snapshots, memberships, and results.

## Input identity is not output reproducibility

This evidence proves the schema behavior and concurrency contract. It does not prove generation reproducibility across changing models or providers.

No benchmark ran. The evidence proves no latency or storage-efficiency result.

The evidence comes from our Muniment Cloud note pinned to commit `f72da4da8da69bb5ddd81d1b4e53385f96949cfb`.

The result now points to the ordered records that produced it. Those original messages remain the only copy of their content.
