Skip to main content
Every write in SenseLab creates a new version of an entry. The previous version is preserved as superseded. Nothing an agent learned is ever overwritten. This is what the rest of the loop stands on. A decision trace can cite the exact version an agent read, so an outcome is credited to what the agent actually saw rather than to whatever the entry says today. A fix that makes things worse can be rolled back to the version before it. And two agents that disagree both keep their position, with their names on it, instead of one silently winning.

How It Works

When you write to a key that already exists:
  1. The current version is marked as superseded
  2. A new version is created with an incremented version number
  3. The new version becomes the current version
Reading always returns the current (latest) version:

Viewing History

history() returns every version of one key, oldest first. Each version is a full snapshot, not a delta, so you can read any past state directly:
It also takes since and until, which is how you reconstruct what an agent knew at the moment it decided something. To see all versions across an entity rather than one key, use list():
On the dashboard, the same history is the Event Log of the agent’s Git Repository section — see Learning as Git.

Comparing Versions

Because every version is kept, SenseLab can show exactly which fields changed rather than just that something did. diff() returns structural, field-level changes addressed by RFC 6901 JSON Pointer paths:
Each change carries a path, an operation of add, remove, or replace, and the old and new values. The surrounding result also reports diff_type (added, modified, or deleted) and the two versions’ confidence. This works on nested dicts, lists, and scalars, so a change buried deep in a config object is reported at its exact path instead of as a wholesale replacement of the value.

Version Retention

Every version is kept. Superseding a key never overwrites the previous value — it marks it as no longer current and stores the new one alongside it, so the full chain stays queryable through history() for as long as the entry exists. Outcomes are versions too: when a committed outcome moves an entry’s confidence, the entry gets a new version with the new confidence and the old one is superseded, so the trust an entry has earned over time is as traceable as its value.

Conflict Handling

When two agents write to the same key concurrently, the conflict_policy determines behavior:
You can also provide a custom conflict resolver:
For changes that need review before they reach everyone, write them on a branch and open a pull request instead of resolving the conflict at write time.

Why copy-on-write

  • Attribution — An outcome is credited to the version the agent read, so trust moves on the right thing.
  • Reversibility — A fix, a merge or a bad write can be undone by rolling back; nothing has to be reconstructed.
  • Audit — Months later, history() and the decision trace still answer who believed what, at what confidence, and what followed.
  • Training data — The record of what was known at each decision, as it was then, is what a model can be trained on. See ML Layer.