Part 3 · Topic 4 of 11
Knowledge products
Knowledge products and their contracts
1 min read
The unit of ownership in this model is a knowledge product: a defined set of source content, owned by a domain team, processed into the standard representations, registered in the catalog, published through the standard retrieval API, with a stated freshness commitment and measured quality. The term is borrowed from data mesh, and the adaptation to unstructured content is mostly about what the contract covers.
A knowledge product contract states: what content is in scope and where it comes from; who owns it and who to contact; which representations are published (not every product needs every one); the metadata fields it guarantees to populate beyond the required set; its freshness window and how supersession is handled; its sensitivity classification and the access labels a consumer needs; its measured quality — the evaluation set it is scored against and the current numbers; and its version history.
Here is the shape of it as a schema. The specific fields matter less than the fact that they are required, validated at registration, and visible to every consumer.
from __future__ import annotations
from datetime import datetime, timedelta
from enum import Enum
from typing import Literal
from pydantic import BaseModel, Field, HttpUrl
class Representation(str, Enum):
RAW = "raw"
CANONICAL = "canonical"
SECTIONS = "sections"
CHUNKS = "chunks"
SUMMARIES = "summaries"
ENTITIES = "entities"
RELATIONSHIPS = "relationships"
EMBEDDINGS = "embeddings"
class Maturity(str, Enum):
MINIMUM_VIABLE = "minimum_viable" # ingested, canonical, chunked, registered
ENRICHED = "enriched" # + summaries, entities, full context
GOVERNED = "governed" # + review workflow, freshness SLO, eval set, audit
REUSABLE = "reusable" # + consumed by 2+ domains, stable contract, agent-ready
class FreshnessCommitment(BaseModel):
content_class: str
max_lag: timedelta # source change → retrievable update
review_cycle: timedelta | None = None # periodic human review, if any
class QualityReport(BaseModel):
eval_set_id: str
measured_at: datetime
recall_at_10: float = Field(ge=0, le=1)
grounding_rate: float = Field(ge=0, le=1)
freshness_compliance: float = Field(ge=0, le=1)
class KnowledgeProduct(BaseModel):
"""The contract a domain team publishes when they register a knowledge
product. Validated at registration; visible to every consumer."""
product_id: str
name: str
owning_domain: str
owner_contact: str
description: str
scope: str # what content is in, what is out
source_systems: list[str]
representations: set[Representation]
required_metadata: list[str] # platform-required, always present
additional_metadata: list[str] = [] # domain guarantees beyond required
sensitivity: Literal["public", "internal", "confidential", "restricted"]
access_labels: list[str] # labels a consumer must hold
freshness: list[FreshnessCommitment]
source_of_truth_rank: int # relative authority when scopes overlap
supersedes: list[str] = [] # prior product ids, if any
maturity: Maturity
quality: QualityReport | None = None # required at GOVERNED and above
retrieval_endpoint: HttpUrl
contract_version: str
registered_at: datetime
def is_agent_ready(self) -> bool:
# An agent can only use what it can trust and discover: measured
# quality, explicit freshness, and a stable contract.
return (
self.maturity in (Maturity.GOVERNED, Maturity.REUSABLE)
and self.quality is not None
and Representation.SUMMARIES in self.representations
and Representation.CHUNKS in self.representations
)The maturity field is worth dwelling on. Not every knowledge product needs to be fully governed on day one, and demanding it is how you get no knowledge products at all. The levels give a domain team a path: get the content in, canonical, chunked, and registered, and it is already useful. Add summaries, entities, and full context, and it is enriched. Add a review workflow, a freshness commitment, an evaluation set, and audit logging, and it is governed. When two or more other domains consume it through a stable contract, and it exposes agent-usable interfaces, it is reusable. Each level is an increment a team can reach in weeks, and each delivers value before the next.