Versioning
Kanoniv tracks changes across four layers — specs, rules, entities, and time. Together they give you a complete audit trail from "who changed the matching logic" to "what happened to this specific customer record."
The Four Versioning Layers
| Layer | What It Tracks | Identifier | Granularity |
|---|---|---|---|
| Spec | Identity resolution logic (rules, thresholds, survivorship) | identity_version (user-defined) + plan_hash (SHA-256) | Per spec upload |
| Rule | Individual matching rule changes | Auto-incrementing version integer per rule name | Per rule creation |
| Entity | Changes to canonical (golden) records | AuditEvent with before_state / after_state JSONB | Per entity mutation |
| Temporal | Time-validity of source records | valid_from / valid_to fields | Per source record |
How They Work Together
A typical change flows through all four layers:
- You update the spec YAML (e.g., lower
match_thresholdfrom 0.85 to 0.75) - Upload via
POST /v1/identity/specswithcompile: true— newplan_hashis generated - Re-reconciliation runs, applying the new logic
- Entities that now match differently get updated — each change is recorded as an
AuditEventwith before/after state - If temporal matching is enabled, the engine considers record validity windows when scoring
The plan_hash connects spec changes to their downstream effects. By recording which hash produced a given set of golden records, you can always trace back to the exact logic that generated them.
Quick Start
python
from kanoniv import Spec, plan, diff
# Load two spec versions
old = Spec.from_file("spec-v1.yaml")
new = Spec.from_file("spec-v2.yaml")
# Compare plan hashes
old_plan = plan(old)
new_plan = plan(new)
print(f"Hash changed: {old_plan.plan_hash != new_plan.plan_hash}")
# Get a structured diff
changes = diff(old, new)
print(changes.summary)
if changes.rules_added:
print(f"New rules: {changes.rules_added}")
if changes.thresholds_changed:
print("Thresholds were modified")bash
# View rule history via API
curl "https://api.kanoniv.com/v1/rules/email_exact/history" \
-H "X-API-Key: kn_..."
# View entity audit trail
curl "https://api.kanoniv.com/v1/canonical/{entity_id}/history" \
-H "X-API-Key: kn_..."When to Use What
| Question | Use This |
|---|---|
| "Did the matching logic change?" | Compare plan_hash values — different hash means different behavior |
| "What specifically changed in the spec?" | diff(old_spec, new_spec) — returns structured change details |
| "How did this rule evolve over time?" | GET /v1/rules/:name/history — full version history |
| "What happened to this entity?" | GET /v1/canonical/:id/history — audit events with before/after state |
| "Can I undo a bad merge?" | Lock the entity, then revert to a historical state |
| "Which records were valid at a specific time?" | Configure temporal matching with valid_from / valid_to |
| "Which spec version produced my training data?" | Record plan_hash alongside your dataset — see ML Training Data |
Next Steps
- Spec Versioning —
identity_version,plan_hash, and thediff()API - Rule Versioning — Auto-incrementing rule versions, testing before activating, rollback
- Entity History & Audit — Audit events, entity locking, reverting, temporal matching
- ML Training Data — Pinning training datasets to spec versions for reproducible ML
