Skip to content

LabelStore

The port that keeps the installation's reviewed answers: each a verdict on one entity or facet, copied out of the document it came from.

Port: LabelStore, declared in indx_interfaces.protocols over the models in indx_interfaces.labels (ADR-0076).

A Label is a person’s verdict on one answer a lane gave: approved, corrected with the right value, or rejected. Its target is an EntityTarget (a block, its page and box, the entity’s label, its character range and surface) or a FacetTarget (a document, page or chunk block, a facet and the label it answered). It carries the document’s digest and name, and optionally the type and field it fills and the name the reviewer gave.

class LabelStore(Protocol):
def put(self, owner: OwnerId, label: Label) -> None: ...
def get(self, owner: OwnerId, label_id: LabelId) -> Label | None: ...
def list(
self, owner: OwnerId, *, digest: SourceDigest | None = None, type_id: TypeId | None = None
) -> tuple[Label, ...]: ...
def delete(self, owner: OwnerId, label_id: LabelId) -> bool: ...

A fourth store port beside SchemaStore, because the ports split by aggregate. A label copies what it points at, since the kept document it was read from belongs to a cookie and expires, and a label does not. A label never expires, so there is no purge. Three backends ship: memory, sqlite and postgres, named by INDX_LABEL_STORE.

  • Owner. Every method takes an OwnerId first, and nothing crosses owners.
  • Identity. A label’s ID is derived from its digest and target, so put of a second verdict on the same answer replaces the first.
  • Idempotence. delete of an ID that is not there is False.
  • Filter. list narrows by digest, by type_id, or both; with neither it returns every label of the owner.
  • Order. list returns labels by digest, then ID.
  • Validation. The model refuses a correction without corrected and corrected without a correction. The server, not the store, checks that type_id and field name a stored type and one of its fields.

tests/unit/test_store_conformance.py holds every installed backend to these rules.