Data model

Pydantic v2 models for every layer plus the alignment surface — fields, constraints, and example payloads.

Browse the models

Click a model on the left to see its fields, relations to other models, and an example payload. Source of truth is src/<layer>/models.py in the repository.

Models

Value

Fields

id
UUID
name
str (1–100)
description
str (1–500)
weight
float [0, 1]
category
ValueCategory enum (13 members)
aligned_keywords
list[str]
conflict_keywords
list[str]
context_tags
list[str]
active
bool

Relations

  • Desire.aligned_values references Value.id

Example

await values.add(
  "integrity", weight=0.95,
  category=ValueCategory.INTEGRITY,
  description="Be truthful and transparent.",
)

Key shapes

Every layer model has the same hygiene contract:

  • UUID-keyed (id: UUID = Field(default_factory=uuid4)).
  • Timestamps where it matters (created_at, updated_at) — always timezone-aware via utcnow_aware().
  • Soft-delete via active: bool rather than physical delete; engines filter on active=True by default.
  • Free-form metadata: dict[str, str] escape-hatch for integrators.

IDs and relations

Cross-layer references are UUID-typed and named after the target layer:

  • Desire.source_purpose: UUID | NonePurpose.id
  • Desire.aligned_values: list[UUID]Value.id
  • Desire.aligned_beliefs: list[UUID]Belief.id
  • Goal.parent_desire: UUID | NoneDesire.id
  • Goal.parent_goal: UUID | NoneGoal.id (self-reference)
  • Goal.sub_goals: list[UUID]Goal.id

There are no foreign-key constraints. AlignmentEngine.full_audit surfaces dangling references as orphan_desires / orphan_goals so an integrator can reconcile or sweep them on a schedule.

Serialisation

Every model round-trips through Pydantic v2's model_dump(mode="json") and model_validate(data). The framework persists the mode="json" form (UUIDs and datetimes become strings) so all three shipped backends share the same on-the-wire shape.

For backups and migrations, ValuesEngine.export_values() returns a versioned ValueExport; import_values accepts the same shape with merge_strategy chosen by the integrator ("replace" | "merge" | "skip-existing"). Other layers do not yet have a dedicated exporter — for now, dump the storage backend directly.