Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Ledvar Diff — Companion Standard

  • Version: 0.1.0 (DRAFT)
  • Companion to: the Ledvar Protocol, MAJOR 0 (SPEC.md)
  • Status: Draft. Optional.

1. What this is — and what it is not

This is an optional, open standard for representing the comparison of two Ledvar snapshots. It is a companion to the core protocol, not a part of it — the way JSON Patch (RFC 6902) is a separate standard from JSON itself.

The core protocol (SPEC.md) standardizes how state is represented and hashed, and nothing more. Comparing two snapshots is a forced consequence of that — any correct implementation reaches the same answer. So this document does not add new truth; it only fixes a shared vocabulary for a computed comparison, so that one component can produce a result and another can read it without guessing.

You MAY:

  • adopt this standard, so your comparison results interoperate with anyone else who adopts it;
  • define your own representation;
  • store nothing and recompute comparisons on demand (the way git diff derives a diff from stored objects).

The core protocol requires none of this. Conformance to SPEC.md does not depend on this document.

2. The comparison

Given a previous snapshot and a current snapshot, match their nodes by identity_key (SPEC.md §5). Each node receives exactly one StateStatus:

StateStatusCondition
Baselinethere is no previous snapshot (cold start) — every node is Baseline
Addedin current, not in previous
Removedin previous, not in current
Unchangedin both, equal content_hash
Modifiedin both, different content_hash

These outcomes are exhaustive and mutually exclusive: every node is exactly one, and there is no sixth case. This is not a design choice — it is what comparing two sets yields. Added, Modified and Removed are collectively drift.

Baseline means there is no previous snapshot at all — a cold start. This is intentionally distinct from a previous snapshot whose tree is empty: comparing against an empty previous is a normal comparison and yields every current node as Added, not Baseline. “No comparand” and “an empty comparand” are different states.

Whether a node changed is settled here by arithmetic. What the change means — whether it matters, whether it is allowed — is not. That is meaning, and meaning lives in higher layers (see the Manifesto, “context lives elsewhere”).

3. Result representation

A DiffNode is one node of a comparison result:

FieldTypeMeaning
nodeNodethe node as it appears in current (or, for Removed, as carried from previous)
identity_keystringfrom SPEC.md §5
content_hashstringfrom SPEC.md §5
state_statusStateStatus§2

A DiffResult carries the current snapshot’s metadata (protocol_version, origin_id, provider_name, timestamp, fingerprint, parent_origin_id, labels) plus a list of DiffNodes. It MAY also carry an optional previous reference (the previous snapshot’s timestamp and/or fingerprint) so a reader knows what current was compared against — otherwise that comparand is lost once the result is serialized. This reference is a convenience only: whether a result is a Baseline is already evident without it, since every node’s state_status is then Baseline.

This vocabulary is deliberately fact-only: a DiffNode says what changed, and nothing about whether a change is acknowledged, silenced, severe, or allowed. Those are opinions a consumer layers on top — they live in the consumer’s own representation, in its own layer, and are never standardized here (see §2, and the core SPEC.md §4.4). A consumer that wants to carry, say, a suppression flag or a severity does so in its own envelope around a DiffNode; because such judgements are policy-specific (one system’s “silenced” is another’s “acknowledged”), standardizing them would hurt interoperability, not help it.

4. Conformance (for adopters)

An implementation of this companion standard conforms iff, for the example snapshots examples/snapshot-a.json (previous) and examples/snapshot-b.json (current), it assigns the state_status below to each node. (The hashes are the core protocol’s; see examples/CONFORMANCE.md.)

node (path)in Ain BStateStatus
mydb / user:appMedium, {SELECT,INSERT}High, {SELECT,INSERT,DROP}Modified
mydb / config:max_connections{200}{200}Unchanged
mydb / user:backup{SELECT,LOCK TABLES}Added
mydb / user:readonly{SELECT}Removed

5. Status

Draft, optional companion to MAJOR 0. Like the core, once a non-zero MAJOR of this companion is published its result vocabulary is stable for that MAJOR.