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.",
) Belief
Fields
- id
- UUID
- statement
- str (1–500)
- confidence
- float [0, 1]
- domain
- str
- evidence
- list[Evidence]
- source_values
- list[UUID]
- last_evaluated
- datetime | None
- active
- bool
Relations
- Desire.aligned_beliefs references Belief.id
Example
await beliefs.add(
statement="users prefer up-front disclosure",
confidence=0.7,
domain="user_behaviour",
) Purpose
Fields
- id
- UUID
- statement
- str (1–500)
- role
- str
- scope
- PurposeScope (primary/secondary/contextual)
- grounded_in_values
- list[UUID]
- informed_by_beliefs
- list[UUID]
- active
- bool
Relations
- Desire.source_purpose references Purpose.id
Example
await purpose.set_primary(
"Help operators ship reliably without surprising them.",
role="autonomous_assistant",
grounded_in_values=[integrity.id, care.id],
) Desire
Fields
- id
- UUID
- statement
- str (1–500)
- intensity
- float [0, 1]
- intensity_label
- DesireIntensity enum
- priority
- int
- source_purpose
- UUID | None
- aligned_values
- list[UUID]
- aligned_beliefs
- list[UUID]
- active
- bool
Relations
- Goal.parent_desire references Desire.id
Example
await desires.add(
"Improve the proportion of tasks completed without rework.",
intensity=0.7,
source_purpose=primary.id,
) Goal
Fields
- id
- UUID
- title
- str (1–200)
- description
- str (≤2000)
- metric
- str
- target
- float
- current
- float
- deadline
- datetime | None
- status
- GoalStatus enum
- progress
- float [0, 1]
- parent_desire
- UUID | None
- parent_goal
- UUID | None
- sub_goals
- list[UUID]
Relations
- Goal.sub_goals references Goal.id (self-reference)
Example
await goals.create(
title="Cut rework rate to under 10%",
metric="rework_rate",
target=0.10,
parent_desire=quality.id,
) AlignmentReport
Fields
- aligned
- bool
- confidence
- float [0, 1]
- severity
- ConflictSeverity enum
- value_conflicts
- list[Conflict]
- belief_conflicts
- list[Conflict]
- purpose_match
- bool
- goal_relevance
- list[Goal]
- rationale
- str
- recommendation
- str
Relations
- Returned by AlignmentEngine.check_alignment
Example
report = await alignment.check_alignment(
{"description": "...", "tags": ["..."]},
)
if not report.aligned:
return refuse(reason=report.recommendation) 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 viautcnow_aware(). - Soft-delete via
active: boolrather than physical delete; engines filter onactive=Trueby 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 | None→Purpose.idDesire.aligned_values: list[UUID]→Value.idDesire.aligned_beliefs: list[UUID]→Belief.idGoal.parent_desire: UUID | None→Desire.idGoal.parent_goal: UUID | None→Goal.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.