Originally created by: fu351
models.py declares ALGEBRA_VERSION = 1 and the docs describe the action algebra as a versioned vocabulary. Nothing enforces it: Algebra has no version field, no code reads the constant, no test covers it. The 2026-08-19 subjective-layer hardening audit flagged this as a claim with no enforcement behind it.
It is harmless today only because an Algebra never leaves the process — inference builds it, the engine scores it, and it is gone. The day one is persisted or exchanged, the failure mode is silent: pydantic drops an unknown field from a newer writer, so an old reader scores the action missing a dimension with no signal that anything was lost. In a risk engine, that is a silent under-classification channel.
Versioning only means something once an algebra crosses a writer/reader boundary, so this issue builds that boundary and the enforcement together:
classification_confidence and version — classes and floats only, never raw targets or payloads, same redaction discipline as every other column. Independent value: the decision log becomes replayable (feed real recorded traffic back through the benchmark harness, analyze classification drift across releases).version: int = ALGEBRA_VERSION to Algebra so every serialized copy carries its vocabulary version.ALGEBRA_VERSION bumps are documented in the constant's docstring (when to bump, what a reader must do).Additive only — no existing classification changes (that would be level-8). The read-side conservative rule reuses the existing is_unclassified / UNCLASSIFIED_SENSITIVITY_FLOOR machinery in subjective/infer.py rather than inventing a new path.