Skip to content

Core

Shared domain models, base types, and enums used across the framework.

Types

types

Reusable Pydantic type annotations and validators.

CurrencyCode intentionally lives in synthorg.budget.currency next to the ISO 4217 allowlist data. Importing it here would force core to depend on budget, introducing a circular import via the many budget modules that already import from core.types. Consumers who need the validated currency type import it from synthorg.budget.currency.

ModelTier module-attribute

ModelTier = Literal['large', 'medium', 'small']

Model capability tier: large (most capable), medium, small (cheapest).

AutonomyDetailLevel module-attribute

AutonomyDetailLevel = Literal['full', 'summary', 'minimal']

Level of autonomy instruction detail in prompt profiles.

PersonalityMode module-attribute

PersonalityMode = Literal['full', 'condensed', 'minimal']

Personality section verbosity in prompt profiles.

NotBlankStr module-attribute

NotBlankStr = Annotated[
    str, StringConstraints(min_length=1), AfterValidator(_check_not_whitespace)
]

A string that must be non-empty and not consist solely of whitespace.

PersonaLabelStr module-attribute

PersonaLabelStr = Annotated[
    str,
    BeforeValidator(flatten_label),
    StringConstraints(min_length=1),
    AfterValidator(_check_not_whitespace),
]

A persona-bound label (role / department / name): flattened to a single line with angle brackets stripped at construction, then required non-blank. Source-side defence-in-depth for prompt-injection (the render sites also flatten); a value that is empty after flattening is rejected.

require_not_blank

require_not_blank(value, field)

Validate a plain string arg is non-blank at runtime.

A NotBlankStr annotation only runs inside a Pydantic model, so a domain-exception __init__ typed execution_id: NotBlankStr would still accept "". Call this in such constructors to enforce the contract and name the offending field.

Returns:

Type Description
str

The unchanged value once confirmed non-blank.

Raises:

Type Description
ValueError

If value is empty or whitespace-only.

Source code in src/synthorg/core/types.py
def require_not_blank(value: str, field: str) -> str:
    """Validate a plain string arg is non-blank at runtime.

    A ``NotBlankStr`` annotation only runs inside a Pydantic model, so a
    domain-exception ``__init__`` typed ``execution_id: NotBlankStr`` would
    still accept ``""``. Call this in such constructors to enforce the
    contract and name the offending field.

    Returns:
        The unchanged *value* once confirmed non-blank.

    Raises:
        ValueError: If *value* is empty or whitespace-only.
    """
    if not value.strip():
        msg = f"{field} must not be blank"
        raise ValueError(msg)
    return value

flatten_label

flatten_label(value)

Flatten a semi-trusted label for safe interpolation into a prompt.

Collapses all whitespace (newlines included) onto one line and drops angle brackets so a crafted value cannot forge an untrusted-content fence or inject a fresh instruction line into a SYSTEM prompt. Shared by the persona renderer, the chief-of-staff router, and the PersonaLabelStr field type so the sanitisation cannot drift between sink and source.

Returns:

Type Description
str

The single-line, angle-bracket-free label.

Source code in src/synthorg/core/types.py
def flatten_label(value: str) -> str:
    """Flatten a semi-trusted label for safe interpolation into a prompt.

    Collapses all whitespace (newlines included) onto one line and drops
    angle brackets so a crafted value cannot forge an untrusted-content
    fence or inject a fresh instruction line into a SYSTEM prompt. Shared
    by the persona renderer, the chief-of-staff router, and the
    ``PersonaLabelStr`` field type so the sanitisation cannot drift
    between sink and source.

    Returns:
        The single-line, angle-bracket-free label.
    """
    collapsed = " ".join(value.split())
    return collapsed.replace("<", "").replace(">", "")

stable_agent_id

stable_agent_id(name)

Derive a deterministic agent id from an agent name.

The config-sourced agent roster and the runtime registry both derive identity from the agent name without coordinating, so a config agent and its registered AgentIdentity resolve to the same id and the dashboard can address either by one stable UUID.

Parameters:

Name Type Description Default
name str

Agent display name (unique across the company config).

required

Returns:

Type Description
UUID

The deterministic uuid5 agent id for name.

Source code in src/synthorg/core/types.py
def stable_agent_id(name: str) -> UUID:
    """Derive a deterministic agent id from an agent *name*.

    The config-sourced agent roster and the runtime registry both derive
    identity from the agent name without coordinating, so a config agent
    and its registered ``AgentIdentity`` resolve to the same id and the
    dashboard can address either by one stable UUID.

    Args:
        name: Agent display name (unique across the company config).

    Returns:
        The deterministic ``uuid5`` agent id for *name*.
    """
    return uuid5(_AGENT_ID_NAMESPACE, name)

validate_unique_strings

validate_unique_strings(values, field_name)

Validate that every string in values is unique.

Raises:

Type Description
ValueError

If duplicates are present.

Source code in src/synthorg/core/types.py
def validate_unique_strings(
    values: tuple[str, ...],
    field_name: str,
) -> None:
    """Validate that every string in *values* is unique.

    Raises:
        ValueError: If duplicates are present.
    """
    if len(values) != len(set(values)):
        dupes = sorted(v for v, c in Counter(values).items() if c > 1)
        msg = f"Duplicate entries in {field_name}: {dupes}"
        raise ValueError(msg)

Enums

Domain enums co-locate with the package that owns them. Foundation enums that core models depend on stay core-local: the task family (status, type, priority, complexity, stakes, structure, topology, source) plus stakes ordering in synthorg.core.task_enums; project status and the git-backend / environment discriminators in synthorg.core.project_enums; autonomy level and ordering in synthorg.core.autonomy_enums; tool access level in synthorg.core.tool_constraints; agent memory level and category in synthorg.core.memory_enums; the model completion-outcome (finish reason) in synthorg.core.completion_enums; and artifact type in synthorg.core.artifact (all below). The cross-cutting value objects EffectiveAutonomy (resolved autonomy) and RedTeamReviewInput (red-team gate input) also live core-local, in synthorg.core.effective_autonomy and synthorg.core.redteam_review_input, so engine, security, and tools consumers reference them without dragging a heavy hub at import time. Every other domain enum lives with its owning package: agent status, the personality traits (risk tolerance, creativity, decision style, collaboration preference, communication verbosity, conflict approach), cost tier, seniority, and strategic output mode under HR; company type and department name under Organisation; the skill-pattern taxonomy under Templates; memory consolidation interval and org-fact category under Memory; knowledge source type, content kind, and source status under Knowledge; research source type, claim type, and run status under Research; living-document type under Docs Engine; the workflow enums, workspace merge enums (order, escalation, conflict type), operator intervention kind, and the agent-runtime execution, recovery, and decision enums under Engine; the conversation turn, status, and proposal enums under Communication; the charter status enum under Meta; approval status, risk level, and source in synthorg.approval.enums (below); and the security action-type taxonomy, tool category, autonomy-downgrade reason, and timeout-action type under Security.

Task Enums

task_enums

Task-family enumerations and stakes ordering.

TaskStatus

Bases: StrEnum

Lifecycle status of a task.

The authoritative transition map lives in synthorg.core.task_transitions.VALID_TRANSITIONS. Summary for quick reference:

CREATED -> ASSIGNED | REJECTED
ASSIGNED -> IN_PROGRESS | AUTH_REQUIRED | BLOCKED | CANCELLED
            | FAILED | INTERRUPTED | SUSPENDED
IN_PROGRESS -> IN_REVIEW | AUTH_REQUIRED | BLOCKED | CANCELLED
               | FAILED | INTERRUPTED | SUSPENDED
IN_REVIEW -> COMPLETED | IN_PROGRESS (rework) | BLOCKED | CANCELLED
AUTH_REQUIRED -> ASSIGNED (approved) | CANCELLED (denied/timeout)
BLOCKED -> ASSIGNED (unblocked)
FAILED -> ASSIGNED (reassignment for retry)
INTERRUPTED -> ASSIGNED (reassignment on restart)
SUSPENDED -> ASSIGNED (resume from checkpoint)
COMPLETED, CANCELLED, and REJECTED are terminal states.
FAILED, INTERRUPTED, and SUSPENDED are non-terminal (can be reassigned).
AUTH_REQUIRED is non-terminal (waiting for authorization).

TaskType

Bases: StrEnum

Classification of the kind of work a task represents.

Priority

Bases: StrEnum

Task urgency and importance level.

Complexity

Bases: StrEnum

Estimated task complexity.

Stakes

Bases: StrEnum

How consequential a subtask or task is for stakes-aware routing.

Distinct from :class:Priority (urgency/importance) and :class:Complexity (effort): stakes captures the cost of being wrong. Low-stakes work tolerates a cheap model; high-stakes work (architecture, irreversible decisions) warrants a strong model and an adversarial red-team review. The authoritative ordering lives in _STAKES_ORDER below.

TaskStructure

Bases: StrEnum

Classification of how a task's subtasks relate to each other.

Used by the decomposition engine to determine coordination topology and execution ordering. See the Engine design page.

CoordinationTopology

Bases: StrEnum

Coordination topology for multi-agent task execution.

Determines how agents coordinate when executing decomposed subtasks. See the Engine design page.

TaskSource

Bases: StrEnum

Origin of a task within the system.

Distinguishes tasks created internally by agents from those originating from client simulation or external API calls.

compare_stakes

compare_stakes(a, b)

Compare two stakes levels.

Returns negative if a is lower-stakes than b, zero if equal, positive if a is higher-stakes than b.

Parameters:

Name Type Description Default
a Stakes

First stakes level.

required
b Stakes

Second stakes level.

required

Returns:

Type Description
int

Integer indicating relative stakes.

Source code in src/synthorg/core/task_enums.py
def compare_stakes(a: Stakes, b: Stakes) -> int:
    """Compare two stakes levels.

    Returns negative if *a* is lower-stakes than *b*, zero if equal,
    positive if *a* is higher-stakes than *b*.

    Args:
        a: First stakes level.
        b: Second stakes level.

    Returns:
        Integer indicating relative stakes.
    """
    return _STAKES_RANK[a] - _STAKES_RANK[b]

Project Enums

project_enums

Project-family enumerations.

ProjectStatus

Bases: StrEnum

Lifecycle status of a project.

GitBackendType

Bases: StrEnum

Discriminator selecting how a project's git repository is stored.

EMBEDDED is the safe default: the product self-hosts a bare repo on the persistent volume, with no external dependency. LOCAL_PATH targets a caller-supplied repository on disk. EXTERNAL_REMOTE delegates to an external forge remote resolved via the connection catalogue.

EnvironmentType

Bases: StrEnum

Discriminator selecting how a project declares its dev environment.

MANIFEST is the safe default: a backend-agnostic bootstrap manifest (committed lockfiles plus ordered setup commands) that provisions into the mounted workspace and runs in both the subprocess and Docker sandboxes, and emits a stock bootstrap.sh so a fresh clone is reproducible without the product present. DEVCONTAINER builds a sealed Docker image from .devcontainer/devcontainer.json (Docker backend only). NIX provisions a hermetic environment from a flake.nix via nix develop.

Autonomy Enums

autonomy_enums

Autonomy levels and autonomy comparison.

AutonomyLevel

Bases: StrEnum

Autonomy level controlling approval routing for agents.

Determines which actions an agent can execute autonomously vs. which require human or security-agent approval (see Operations design page).

compare_autonomy

compare_autonomy(a, b)

Compare two autonomy levels.

Returns negative if a is more restrictive than b, zero if equal, positive if a is less restrictive than b.

Parameters:

Name Type Description Default
a AutonomyLevel

First autonomy level.

required
b AutonomyLevel

Second autonomy level.

required

Returns:

Type Description
int

Integer indicating relative autonomy.

Source code in src/synthorg/core/autonomy_enums.py
def compare_autonomy(a: AutonomyLevel, b: AutonomyLevel) -> int:
    """Compare two autonomy levels.

    Returns negative if *a* is more restrictive than *b*, zero if equal,
    positive if *a* is less restrictive than *b*.

    Args:
        a: First autonomy level.
        b: Second autonomy level.

    Returns:
        Integer indicating relative autonomy.
    """
    return _AUTONOMY_RANK[a] - _AUTONOMY_RANK[b]

step_down_autonomy

step_down_autonomy(level)

Return the next-more-restrictive autonomy level (one step down).

LOCKED is the floor: stepping down from LOCKED returns LOCKED.

Parameters:

Name Type Description Default
level AutonomyLevel

The current autonomy level.

required

Returns:

Type Description
AutonomyLevel

The autonomy level one rank more restrictive, or LOCKED when

AutonomyLevel

already at the floor.

Source code in src/synthorg/core/autonomy_enums.py
def step_down_autonomy(level: AutonomyLevel) -> AutonomyLevel:
    """Return the next-more-restrictive autonomy level (one step down).

    LOCKED is the floor: stepping down from LOCKED returns LOCKED.

    Args:
        level: The current autonomy level.

    Returns:
        The autonomy level one rank more restrictive, or LOCKED when
        already at the floor.
    """
    rank = _AUTONOMY_RANK[level]
    if rank == 0:
        return level
    return _RANK_TO_AUTONOMY[rank - 1]

Tool Constraints

tool_constraints

Sub-constraint models for granular tool access control.

Defines per-dimension constraint enums and a ToolSubConstraints model that captures file system scope, network mode, git access, code execution isolation, and terminal access. Each ToolAccessLevel maps to a default set of sub-constraints matching the design spec (operations.md, section 11.2).

get_sub_constraints resolves the effective constraints for an access level, optionally overriding with per-agent custom constraints.

Lives in core (the foundation layer) so leaf domain models such as core.agent.AgentIdentity can reference ToolSubConstraints without importing the tools package, whose __init__ eagerly pulls the provider/engine stack and would re-introduce a cold-import cycle.

ToolAccessLevel

Bases: StrEnum

Access level for tool permissions.

Determines which tool categories an agent can use. Levels SANDBOXED through ELEVATED form a hierarchy where each includes all categories from lower levels. CUSTOM uses only explicit allow/deny lists, ignoring the hierarchy.

The concrete category sets for each level are defined in ToolPermissionChecker._LEVEL_CATEGORIES.

FileSystemScope

Bases: StrEnum

File system access scope.

Attributes:

Name Type Description
WORKSPACE_ONLY

Restrict to the agent's workspace directory.

PROJECT_DIRECTORY

Access within the project directory tree.

FULL

Unrestricted file system access.

NetworkMode

Bases: StrEnum

Network access mode.

Attributes:

Name Type Description
NONE

No network access permitted.

ALLOWLIST_ONLY

Only configured host:port pairs allowed.

OPEN

Unrestricted outbound network access.

GitAccess

Bases: StrEnum

Git access level.

Attributes:

Name Type Description
LOCAL_ONLY

Git operations only within the workspace.

READ_AND_BRANCH

Read operations plus branch creation (no push).

FULL

All git operations including push.

CodeExecutionIsolation

Bases: StrEnum

Code execution isolation level.

Attributes:

Name Type Description
CONTAINERIZED

Run in a container (Docker/K8s sandbox).

PROCESS

Run as a sandboxed subprocess (lighter isolation).

TerminalAccess

Bases: StrEnum

Terminal command access level.

Attributes:

Name Type Description
NONE

No terminal access.

RESTRICTED_COMMANDS

Only allow/blocklist-filtered commands.

FULL

Unrestricted command execution.

ToolSubConstraints pydantic-model

Bases: BaseModel

Per-level sub-constraints for tool access control.

Each dimension restricts a specific aspect of tool behavior. The requires_approval tuple lists action type prefixes that require human approval before execution.

Attributes:

Name Type Description
file_system FileSystemScope

File system access scope.

network NetworkMode

Network access mode.

git GitAccess

Git access level.

code_execution CodeExecutionIsolation

Code execution isolation level.

terminal TerminalAccess

Terminal command access level.

requires_approval tuple[NotBlankStr, ...]

Action type prefixes requiring approval.

network_allowlist tuple[NotBlankStr, ...]

Allowed host:port pairs when network mode is ALLOWLIST_ONLY.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

file_system pydantic-field

file_system = FileSystemScope.PROJECT_DIRECTORY

File system access scope

network pydantic-field

network = NetworkMode.OPEN

Network access mode

git pydantic-field

git = GitAccess.FULL

Git access level

code_execution pydantic-field

code_execution = CodeExecutionIsolation.CONTAINERIZED

Code execution isolation level

terminal pydantic-field

terminal = TerminalAccess.RESTRICTED_COMMANDS

Terminal command access level

requires_approval pydantic-field

requires_approval = ()

Action type prefixes requiring human approval

network_allowlist pydantic-field

network_allowlist = ()

Allowed host:port pairs for allowlist_only network mode

get_sub_constraints

get_sub_constraints(access_level, custom_constraints=None)

Resolve effective sub-constraints for an access level.

For CUSTOM access level, custom_constraints is required. For built-in levels, returns the spec-defined defaults unless custom_constraints overrides them.

Parameters:

Name Type Description Default
access_level ToolAccessLevel

The agent's tool access level.

required
custom_constraints ToolSubConstraints | None

Optional per-agent overrides. For CUSTOM level, used as-is (full specification required). For built-in levels, explicitly set fields override the level defaults while unset fields inherit the secure baseline (overlay merge via model_dump(exclude_unset)).

None

Returns:

Type Description
ToolSubConstraints

The resolved ToolSubConstraints.

Raises:

Type Description
ValueError

If CUSTOM level is used without providing custom_constraints.

Source code in src/synthorg/core/tool_constraints.py
def get_sub_constraints(
    access_level: ToolAccessLevel,
    custom_constraints: ToolSubConstraints | None = None,
) -> ToolSubConstraints:
    """Resolve effective sub-constraints for an access level.

    For ``CUSTOM`` access level, ``custom_constraints`` is required.
    For built-in levels, returns the spec-defined defaults unless
    ``custom_constraints`` overrides them.

    Args:
        access_level: The agent's tool access level.
        custom_constraints: Optional per-agent overrides. For
            ``CUSTOM`` level, used as-is (full specification required).
            For built-in levels, explicitly set fields override the
            level defaults while unset fields inherit the secure
            baseline (overlay merge via ``model_dump(exclude_unset)``).

    Returns:
        The resolved ``ToolSubConstraints``.

    Raises:
        ValueError: If ``CUSTOM`` level is used without providing
            ``custom_constraints``.
    """
    if custom_constraints is not None:
        if access_level == ToolAccessLevel.CUSTOM:
            logger.debug(
                SUB_CONSTRAINT_RESOLVED,
                access_level=access_level.value,
                source="custom",
            )
            return custom_constraints
        # Non-CUSTOM with overrides: merge into level defaults so
        # unset fields retain the secure baseline.
        base = _LEVEL_SUB_CONSTRAINTS.get(access_level, ToolSubConstraints())
        merged = {
            **base.model_dump(),
            **custom_constraints.model_dump(exclude_unset=True),
        }
        logger.debug(
            SUB_CONSTRAINT_RESOLVED,
            access_level=access_level.value,
            source="merged",
        )
        return ToolSubConstraints(**merged)

    if access_level == ToolAccessLevel.CUSTOM:
        msg = (
            "CUSTOM access level requires explicit sub_constraints; none were provided"
        )
        logger.warning(
            SUB_CONSTRAINT_RESOLVED,
            access_level=access_level.value,
            source="error",
            error=msg,
        )
        raise ValueError(msg)

    constraints = _LEVEL_SUB_CONSTRAINTS.get(access_level)
    if constraints is None:
        msg = f"No default sub-constraints for access level: {access_level.value}"
        logger.warning(
            SUB_CONSTRAINT_RESOLVED,
            access_level=access_level.value,
            source="error",
            error=msg,
        )
        raise ValueError(msg)
    logger.debug(
        SUB_CONSTRAINT_RESOLVED,
        access_level=access_level.value,
        source="level_default",
    )
    return constraints

Memory Enums

memory_enums

Memory persistence and category enumerations.

Core-local leaf: synthorg.core.agent (a cold-import leaf) imports MemoryLevel and MemoryCategory, and core may not import the heavy synthorg.memory hub, so these two live here rather than in synthorg.memory.enums.

MemoryLevel

Bases: StrEnum

Memory persistence level for an agent (§7.3).

MemoryCategory

Bases: StrEnum

Memory type categories for agent memory (§7.2).

PROJECT_DOC is a project-scoped (not agent-scoped) category used by the living-documentation engine: entries stored under a system docs agent_id, scoped via the project:<id> tag, surfaced via ProjectAwareMemoryFacade. KNOWLEDGE is the corpus-scoped knowledge + provenance substrate (ingested external sources, scoped via tags, carrying provenance). PROJECT_BRAIN is the project-scoped structured-state store: brain entries under a system brain agent_id, scoped via project:<id>, surfaced via the same facade.

Completion Enums

completion_enums

Provider-agnostic completion-outcome vocabulary.

FinishReason describes why a model stopped generating. It is shared vocabulary consumed across the engine, execution-trace, budget, and provider layers, so it lives in a dependency-free core leaf rather than the heavy providers hub: a foundation leaf any consumer can import at module level without dragging the provider package (whose eager init otherwise re-enters budget.cost_record mid-initialisation).

FinishReason

Bases: StrEnum

Reason the model stopped generating tokens.

Agent

agent

Agent identity and configuration models.

PersonalityConfig pydantic-model

Bases: BaseModel

Personality traits and communication style for an agent.

Big Five (OCEAN) floats (0.0-1.0) are internal scoring dimensions used for compatibility calculations. Behavioral enums produce natural-language labels injected into system prompts that LLMs respond to effectively.

Attributes:

Name Type Description
traits tuple[NotBlankStr, ...]

Personality trait keywords.

communication_style NotBlankStr

Free-text style description.

risk_tolerance RiskTolerance

Risk tolerance level.

creativity CreativityLevel

Creativity level.

description str

Extended personality description.

openness float

Big Five openness (curiosity, creativity). 0.0-1.0.

conscientiousness float

Big Five conscientiousness (thoroughness). 0.0-1.0.

extraversion float

Big Five extraversion (assertiveness). 0.0-1.0.

agreeableness float

Big Five agreeableness (cooperation). 0.0-1.0.

stress_response float

Emotional stability (1.0 = very calm). 0.0-1.0.

decision_making DecisionMakingStyle

Decision-making approach.

collaboration CollaborationPreference

Preferred collaboration mode.

verbosity CommunicationVerbosity

Communication verbosity level.

conflict_approach ConflictApproach

Conflict resolution approach.

Config:

  • frozen: True
  • extra: forbid
  • allow_inf_nan: False

Fields:

traits pydantic-field

traits = ()

Personality traits

communication_style pydantic-field

communication_style = 'neutral'

Communication style description

risk_tolerance pydantic-field

risk_tolerance = RiskTolerance.MEDIUM

Risk tolerance level

creativity pydantic-field

creativity = CreativityLevel.MEDIUM

Creativity level

description pydantic-field

description = ''

Extended personality description

openness pydantic-field

openness = 0.5

Big Five openness (curiosity, creativity)

conscientiousness pydantic-field

conscientiousness = 0.5

Big Five conscientiousness (thoroughness, reliability)

extraversion pydantic-field

extraversion = 0.5

Big Five extraversion (assertiveness, sociability)

agreeableness pydantic-field

agreeableness = 0.5

Big Five agreeableness (cooperation, empathy)

stress_response pydantic-field

stress_response = 0.5

Emotional stability (1.0 = very calm)

decision_making pydantic-field

decision_making = DecisionMakingStyle.CONSULTATIVE

Decision-making approach

collaboration pydantic-field

collaboration = CollaborationPreference.TEAM

Preferred collaboration mode

verbosity pydantic-field

verbosity = CommunicationVerbosity.BALANCED

Communication verbosity level

conflict_approach pydantic-field

conflict_approach = ConflictApproach.COLLABORATE

Conflict resolution approach

SkillSet pydantic-model

Bases: BaseModel

Primary and secondary skills for an agent.

Attributes:

Name Type Description
primary tuple[Skill, ...]

Core competency skills.

secondary tuple[Skill, ...]

Supporting skills.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_unique_ids

primary pydantic-field

primary = ()

Primary skills

secondary pydantic-field

secondary = ()

Secondary skills

ModelConfig pydantic-model

Bases: BaseModel

LLM model configuration for an agent.

Attributes:

Name Type Description
provider NotBlankStr

LLM provider name (e.g. "example-provider").

model_id NotBlankStr

Model identifier (e.g. "example-medium-001").

temperature float

Sampling temperature (0.0 to 2.0).

max_tokens int

Maximum output tokens.

fallback_model NotBlankStr | None

Optional fallback model identifier.

model_tier ModelTier | None

Capability tier ("large"/"medium"/"small") set during model matching and updated by budget auto-downgrade. Controls prompt profile selection.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

provider pydantic-field

provider

LLM provider name

model_id pydantic-field

model_id

Model identifier

temperature pydantic-field

temperature = 0.7

Sampling temperature

max_tokens pydantic-field

max_tokens = 4096

Maximum output tokens

fallback_model pydantic-field

fallback_model = None

Fallback model identifier

model_tier pydantic-field

model_tier = None

Model capability tier (large/medium/small)

AgentRetentionRule pydantic-model

Bases: BaseModel

Per-category retention override for an agent.

Structurally identical to :class:~synthorg.memory.consolidation.models.RetentionRule but defined in core to avoid a core -> memory import dependency.

Attributes:

Name Type Description
category MemoryCategory

Memory category this override applies to.

retention_days int

Number of days to retain memories in this category.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

category pydantic-field

category

Memory category this override applies to

retention_days pydantic-field

retention_days

Number of days to retain memories

MemoryConfig pydantic-model

Bases: BaseModel

Memory configuration for an agent.

Attributes:

Name Type Description
type MemoryLevel

Memory persistence type.

retention_days int | None

Days to retain memories (None means forever). Also serves as the agent-level global default for retention when per-category overrides are not specified.

retention_overrides tuple[AgentRetentionRule, ...]

Per-category retention overrides for this agent. These take priority over company-level per-category rules during retention enforcement.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_retention_consistency
  • _validate_unique_override_categories

type pydantic-field

type = MemoryLevel.SESSION

Memory persistence type

retention_days pydantic-field

retention_days = None

Days to retain memories (None = forever)

retention_overrides pydantic-field

retention_overrides = ()

Per-category retention overrides for this agent

ToolPermissions pydantic-model

Bases: BaseModel

Tool access permissions for an agent.

Attributes:

Name Type Description
access_level ToolAccessLevel

Tool access level controlling which categories are available.

allowed tuple[NotBlankStr, ...]

Explicitly allowed tool names.

denied tuple[NotBlankStr, ...]

Explicitly denied tool names.

mcp_capabilities tuple[NotBlankStr, ...]

MCP capability patterns controlling which internal MCP tools the agent can see. Supports wildcards (e.g. "tasks:*", "*:read", "*").

sub_constraints ToolSubConstraints | None

Optional per-agent sub-constraints overriding the access level defaults. When None, the checker resolves defaults from the access level.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_no_overlap
  • _validate_mcp_capability_format

access_level pydantic-field

access_level = ToolAccessLevel.STANDARD

Tool access level

allowed pydantic-field

allowed = ()

Explicitly allowed tools

denied pydantic-field

denied = ()

Explicitly denied tools

mcp_capabilities pydantic-field

mcp_capabilities = ()

MCP capability patterns (e.g. 'tasks:read', 'agents:*')

sub_constraints pydantic-field

sub_constraints = None

Per-agent sub-constraint overrides

AgentIdentity pydantic-model

Bases: BaseModel

Complete agent identity card.

Every agent in the company is represented by an AgentIdentity containing its role, personality, model backend, memory settings, tool permissions, and authority configuration.

Attributes:

Name Type Description
id UUID

Unique agent identifier.

name NotBlankStr

Agent display name.

role NotBlankStr

Role name (string reference to :class:~synthorg.core.role.Role).

department NotBlankStr

Department name (string reference).

level SeniorityLevel

Seniority level.

personality PersonalityConfig

Personality configuration.

skills SkillSet

Primary and secondary skill set.

model ModelConfig

LLM model configuration.

memory MemoryConfig

Memory configuration.

tools ToolPermissions

Tool permissions.

authority Authority

Authority configuration for this agent.

autonomy_level AutonomyLevel | None

Per-agent autonomy level override (None uses department/company default).

strategic_output_mode StrategicOutputMode | None

Per-agent strategic output mode override (None inherits company strategy config default).

hiring_date date

Date the agent was hired.

status AgentStatus

Current lifecycle status.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_seniority_autonomy

id pydantic-field

id

Unique agent identifier

name pydantic-field

name

Agent display name

role pydantic-field

role

Role name

department pydantic-field

department

Department name

level pydantic-field

level = SeniorityLevel.MID

Seniority level

personality pydantic-field

personality

Personality configuration

skills pydantic-field

skills

Skill set

model pydantic-field

model

LLM model configuration

memory pydantic-field

memory

Memory configuration

tools pydantic-field

tools

Tool permissions

authority pydantic-field

authority

Authority scope

autonomy_level pydantic-field

autonomy_level = None

Per-agent autonomy level override (D6)

strategic_output_mode pydantic-field

strategic_output_mode = None

Per-agent strategic output mode override. None inherits the company strategy config default.

hiring_date pydantic-field

hiring_date

Date the agent was hired

status pydantic-field

status = AgentStatus.ACTIVE

Current lifecycle status

Company

company

Company structure and configuration models.

Department-internal structure models live in :mod:synthorg.core.company_departments; cross-department handoff and escalation models live in :mod:synthorg.core.company_handoffs.

CompanyConfig pydantic-model

Bases: BaseModel

Company-wide configuration settings.

Attributes:

Name Type Description
autonomy AutonomyConfig

Autonomy configuration (level + presets).

approval_timeout ApprovalTimeoutConfig

Timeout policy for pending approval items.

budget_monthly float

Monthly budget in the configured currency.

communication_pattern NotBlankStr

Default communication pattern name.

tool_access_default tuple[NotBlankStr, ...]

Default tool access for all agents.

middleware MiddlewareConfig

Agent and coordination middleware configuration.

session_replay_on_start bool

When True, replay the previous session from the event log on agent start (requires an EventReader and resume_execution_id).

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

autonomy pydantic-field

autonomy

Autonomy configuration (level + presets)

approval_timeout pydantic-field

approval_timeout

Timeout policy for pending approval items

budget_monthly pydantic-field

budget_monthly = 100.0

Monthly budget in the configured currency

communication_pattern pydantic-field

communication_pattern = 'hybrid'

Default communication pattern

tool_access_default pydantic-field

tool_access_default = ()

Default tool access for all agents

middleware pydantic-field

middleware

Agent and coordination middleware configuration

session_replay_on_start pydantic-field

session_replay_on_start = False

Replay session from event log on agent start

HRRegistry pydantic-model

Bases: BaseModel

Human resources registry for the company.

available_roles and hiring_queue intentionally allow duplicate entries to represent multiple openings for the same role or position.

Attributes:

Name Type Description
active_agents tuple[NotBlankStr, ...]

Currently active agent names (must be unique).

available_roles tuple[NotBlankStr, ...]

Roles available for hiring (duplicates allowed).

hiring_queue tuple[NotBlankStr, ...]

Roles in the hiring pipeline (duplicates allowed).

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_no_duplicate_active_agents

active_agents pydantic-field

active_agents = ()

Currently active agent names

available_roles pydantic-field

available_roles = ()

Roles available for hiring

hiring_queue pydantic-field

hiring_queue = ()

Roles in the hiring pipeline

Company pydantic-model

Bases: BaseModel

Top-level company entity.

Validates that department names are unique and that budget allocations do not exceed 100%. The sum may be less than 100% to allow for an unallocated reserve.

Attributes:

Name Type Description
id UUID

Company identifier.

name NotBlankStr

Company name.

type CompanyType

Company template type.

departments tuple[Department, ...]

Company departments.

config CompanyConfig

Company-wide configuration.

hr_registry HRRegistry

HR registry.

workflow_handoffs tuple[WorkflowHandoff, ...]

Cross-department workflow handoffs.

escalation_paths tuple[EscalationPath, ...]

Cross-department escalation paths.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_departments

id pydantic-field

id

Company identifier

name pydantic-field

name

Company name

type pydantic-field

type = CompanyType.CUSTOM

Company template type

departments pydantic-field

departments = ()

Company departments

config pydantic-field

config

Company-wide configuration

hr_registry pydantic-field

hr_registry

HR registry

workflow_handoffs pydantic-field

workflow_handoffs = ()

Cross-department workflow handoffs

escalation_paths pydantic-field

escalation_paths = ()

Cross-department escalation paths

Role

role

Role and skill domain models.

Skill pydantic-model

Bases: BaseModel

Structured capability description, A2A AgentSkill-aligned.

Mirrors the A2A protocol AgentSkill shape so projection to A2AAgentSkill is lossless. proficiency is the SynthOrg-specific addition used for quality-aware routing ("route to the agent with the highest Python proficiency").

Attributes:

Name Type Description
id NotBlankStr

Unique skill identifier (e.g. "code-review").

name NotBlankStr

Human-readable display name (e.g. "Code Review").

description str

Capability description for semantic matching.

tags tuple[NotBlankStr, ...]

Searchable tags for multi-faceted routing.

input_modes tuple[NotBlankStr, ...]

MIME types the agent accepts for this skill.

output_modes tuple[NotBlankStr, ...]

MIME types the agent produces for this skill.

proficiency float

Proficiency level in [0.0, 1.0]. Default 1.0 preserves legacy boolean-match scoring when proficiency is unspecified.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

id pydantic-field

id

Unique skill identifier

name pydantic-field

name

Human-readable display name

description pydantic-field

description = ''

Capability description for semantic matching

tags pydantic-field

tags = ()

Searchable tags for multi-faceted routing

input_modes pydantic-field

input_modes = ('text/plain',)

MIME types the agent accepts for this skill

output_modes pydantic-field

output_modes = ('text/plain',)

MIME types the agent produces for this skill

proficiency pydantic-field

proficiency = 1.0

Proficiency level in [0.0, 1.0]

Authority pydantic-model

Bases: BaseModel

Authority scope for an agent or role.

Attributes:

Name Type Description
can_approve tuple[NotBlankStr, ...]

Task types this role can approve.

reports_to NotBlankStr | None

Role this position reports to.

can_delegate_to tuple[NotBlankStr, ...]

Roles this position can delegate tasks to.

budget_limit float

Maximum spend per task in base currency units.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

can_approve pydantic-field

can_approve = ()

Task types this role can approve

reports_to pydantic-field

reports_to = None

Role this position reports to

can_delegate_to pydantic-field

can_delegate_to = ()

Roles this position can delegate tasks to

budget_limit pydantic-field

budget_limit = 0.0

Maximum spend per task in base currency units

SeniorityInfo pydantic-model

Bases: BaseModel

Mapping from seniority level to authority and model configuration.

Attributes:

Name Type Description
level SeniorityLevel

The seniority level.

authority_scope NotBlankStr

Description of authority at this level.

typical_model_tier ModelTier

Recommended model tier (e.g. "large").

cost_tier NotBlankStr

Cost tier identifier (built-in CostTier or user-defined string).

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

level pydantic-field

level

Seniority level

authority_scope pydantic-field

authority_scope

Description of authority at this level

typical_model_tier pydantic-field

typical_model_tier

Recommended model tier

cost_tier pydantic-field

cost_tier

Cost tier identifier (built-in or user-defined)

Role pydantic-model

Bases: BaseModel

A job definition within the organization.

Attributes:

Name Type Description
name NotBlankStr

Role name (e.g. "Backend Developer").

department DepartmentName

Department this role belongs to.

required_skills tuple[NotBlankStr, ...]

Skills required for this role.

authority_level SeniorityLevel

Default seniority level.

tool_access tuple[NotBlankStr, ...]

Tools available to this role.

system_prompt_template NotBlankStr | None

Template file for system prompt.

description str

Human-readable description.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

name pydantic-field

name

Role name

department pydantic-field

department

Department this role belongs to

required_skills pydantic-field

required_skills = ()

Skills required for this role

authority_level pydantic-field

authority_level = SeniorityLevel.MID

Default seniority level for this role

tool_access pydantic-field

tool_access = ()

Tools available to this role

system_prompt_template pydantic-field

system_prompt_template = None

Template file for system prompt

description pydantic-field

description = ''

Human-readable description

CustomRole pydantic-model

Bases: BaseModel

User-defined custom role via configuration.

Unlike :class:Role, the department field accepts arbitrary strings in addition to :class:~synthorg.organization.enums.DepartmentName values, allowing users to define roles in non-standard departments.

Attributes:

Name Type Description
name NotBlankStr

Custom role name.

department DepartmentName | str

Department (standard or custom name).

required_skills tuple[NotBlankStr, ...]

Required skills for this role.

system_prompt_template NotBlankStr | None

Template file for system prompt.

authority_level SeniorityLevel

Default seniority level.

suggested_model NotBlankStr | None

Suggested model tier.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

name pydantic-field

name

Custom role name

department pydantic-field

department

Department (standard or custom name)

required_skills pydantic-field

required_skills = ()

Required skills for this role

system_prompt_template pydantic-field

system_prompt_template = None

Template file for system prompt

authority_level pydantic-field

authority_level = SeniorityLevel.MID

Default seniority level

suggested_model pydantic-field

suggested_model = None

Suggested model tier

Role Catalog

role_catalog

Built-in role catalog and seniority information.

Provides the canonical set of built-in roles from the Agents design page (Role Catalog) and the seniority mapping (Seniority & Authority Levels).

RED_TEAM_ROLE_NAME module-attribute

RED_TEAM_ROLE_NAME = _RED_TEAM.name

Canonical name of the built-in Red Team role.

Exposed so other modules (the red-team subsystem, tests) reference a single string constant instead of duplicating the literal.

get_builtin_role

get_builtin_role(name)

Look up a built-in role by name (case-insensitive, whitespace-stripped).

Parameters:

Name Type Description Default
name str

Role name to search for.

required

Returns:

Type Description
Role | None

The matching Role, or None if not found.

Source code in src/synthorg/core/role_catalog.py
def get_builtin_role(name: str) -> Role | None:
    """Look up a built-in role by name (case-insensitive, whitespace-stripped).

    Args:
        name: Role name to search for.

    Returns:
        The matching Role, or ``None`` if not found.
    """
    result = _BUILTIN_ROLES_BY_NAME.get(normalize_identifier(name))
    if result is None:
        logger.debug(ROLE_LOOKUP_MISS, role_name=name)
    return result

get_seniority_info

get_seniority_info(level)

Look up seniority info by level.

Parameters:

Name Type Description Default
level SeniorityLevel

The seniority level to look up.

required

Returns:

Type Description
SeniorityInfo

The matching SeniorityInfo.

Raises:

Type Description
LookupError

If no entry exists for the given level.

Source code in src/synthorg/core/role_catalog.py
def get_seniority_info(level: SeniorityLevel) -> SeniorityInfo:
    """Look up seniority info by level.

    Args:
        level: The seniority level to look up.

    Returns:
        The matching SeniorityInfo.

    Raises:
        LookupError: If no entry exists for the given level.
    """
    info = _SENIORITY_INFO_BY_LEVEL.get(level)
    if info is None:
        logger.warning(
            ROLE_LOOKUP_MISS,
            level=level.value,
            reason="no seniority info in catalog",
        )
        msg = f"No seniority info for level {level!r}; catalog may be incomplete"
        raise LookupError(msg)
    return info

Task

task

Task domain model and acceptance criteria.

AcceptanceCriterion pydantic-model

Bases: BaseModel

A single acceptance criterion for a task.

Attributes:

Name Type Description
description NotBlankStr

The criterion text.

met bool

Whether this criterion has been satisfied.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

description pydantic-field

description

Criterion text

met pydantic-field

met = False

Whether this criterion has been satisfied

Task pydantic-model

Bases: BaseModel

A unit of work within the company.

Represents a task from creation through completion, with full lifecycle tracking, dependency modeling, and acceptance criteria. Field schema matches the Engine design page.

Attributes:

Name Type Description
id UUID

Unique task identifier (auto-generated UUID).

title NotBlankStr

Short task title.

description NotBlankStr

Detailed task description.

type TaskType

Classification of the task's work type.

priority Priority

Task urgency and importance level.

project NotBlankStr

Project ID this task belongs to.

created_by NotBlankStr

Agent name of the task creator.

requested_by_user_id NotBlankStr | None

User id of the human who filed the task via the API (None for agent-internal tasks); gates SSE event-stream session ownership.

assigned_to NotBlankStr | None

Agent ID of the assignee (None if unassigned).

reviewers tuple[NotBlankStr, ...]

Agent IDs of designated reviewers.

dependencies tuple[NotBlankStr, ...]

IDs of tasks this task depends on.

artifacts_expected tuple[ExpectedArtifact, ...]

Artifacts expected to be produced.

acceptance_criteria tuple[AcceptanceCriterion, ...]

Structured acceptance criteria.

estimated_complexity Complexity

Task complexity estimate.

budget_limit float

Maximum spend for this task in the configured currency.

deadline str | None

Optional deadline (ISO 8601 string or None).

max_retries int

Max reassignment attempts after failure (default 1).

status TaskStatus

Current lifecycle status.

parent_task_id NotBlankStr | None

Parent task ID when created via delegation (None for root tasks).

delegation_chain tuple[NotBlankStr, ...]

Ordered agent names of delegators (root first).

task_structure TaskStructure | None

Classification of how subtasks relate to each other (None when not yet classified).

coordination_topology CoordinationTopology

Coordination topology for multi-agent execution (defaults to AUTO).

middleware_override tuple[NotBlankStr, ...] | None

Per-task middleware chain override (None uses company default chain).

metadata dict[str, object]

Arbitrary key-value metadata for pipeline tracking, labels, and operator-defined context. Deep-copied at construction to prevent external mutation.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _deepcopy_metadata
  • _validate_deadline_format
  • _validate_collections
  • _validate_delegation_fields
  • _validate_assignment_consistency

id pydantic-field

id

Unique task identifier

title pydantic-field

title

Short task title

description pydantic-field

description

Detailed task description

type pydantic-field

type

Task work type

priority pydantic-field

priority = Priority.MEDIUM

Task priority

project pydantic-field

project

Project ID this task belongs to

created_by pydantic-field

created_by

Agent name of the task creator

requested_by_user_id pydantic-field

requested_by_user_id = None

User id of the human who filed this task via the API (distinct from created_by, which is the agent name). Drives SSE event-stream session ownership: only the requester (or a CEO) may subscribe to a session keyed by this task's id. None for agent-internal tasks.

assigned_to pydantic-field

assigned_to = None

Agent ID of the assignee

reviewers pydantic-field

reviewers = ()

Agent IDs of designated reviewers

dependencies pydantic-field

dependencies = ()

IDs of tasks this task depends on

artifacts_expected pydantic-field

artifacts_expected = ()

Artifacts expected to be produced

acceptance_criteria pydantic-field

acceptance_criteria = ()

Structured acceptance criteria

estimated_complexity pydantic-field

estimated_complexity = Complexity.MEDIUM

Task complexity estimate

stakes pydantic-field

stakes = Stakes.NORMAL

How consequential this task is, driving stakes-aware model routing (cheap model for low stakes, strong model plus red-team for high/critical stakes)

budget_limit pydantic-field

budget_limit = 0.0

Maximum spend for this task in the configured currency

deadline pydantic-field

deadline = None

Optional deadline (ISO 8601 string)

max_retries pydantic-field

max_retries = 1

Max reassignment attempts after failure

status pydantic-field

status = TaskStatus.CREATED

Current lifecycle status

parent_task_id pydantic-field

parent_task_id = None

Parent task ID when created via delegation

delegation_chain pydantic-field

delegation_chain = ()

Ordered agent names of delegators (root first)

task_structure pydantic-field

task_structure = None

Classification of subtask relationships (None = not classified)

coordination_topology pydantic-field

coordination_topology = CoordinationTopology.AUTO

Coordination topology for multi-agent execution

source pydantic-field

source = None

Origin of this task (internal, client, or simulation)

middleware_override pydantic-field

middleware_override = None

Per-task middleware chain override (None = use company default)

metadata pydantic-field

metadata

Arbitrary key-value metadata for pipeline tracking and labels

hard_ceiling pydantic-field

hard_ceiling = None

Per-run hard real-money ceiling in the configured currency. When the in-loop BudgetChecker observes accumulated_cost >= hard_ceiling it raises RunHardCeilingExceededError and the engine parks the context via ApprovalGate so the operator can raise the ceiling and resume. None falls back to the global budget.run_hard_ceiling setting.

forecast_id pydantic-field

forecast_id = None

Identifier of the pre-flight cost Forecast row this task was dispatched against. The work-entry adapter sets this after the operator approves the forecast; the engine plumbs it onto the parked-context payload when a ceiling halt occurs so the resume UI can show the original estimate alongside the accumulated cost.

with_transition

with_transition(target, **overrides)

Create a new Task with a validated status transition.

Calls :func:~synthorg.core.task_transitions.validate_transition before producing the new instance, ensuring the state machine is enforced. Uses model_validate so all validators run on the new instance.

Parameters:

Name Type Description Default
target TaskStatus

The desired target status.

required
**overrides object

Additional field overrides for the new task.

{}

Returns:

Type Description
Task

A new Task with the target status.

Raises:

Type Description
ValueError

If the transition is not valid or overrides contain status.

Source code in src/synthorg/core/task.py
def with_transition(self, target: TaskStatus, **overrides: object) -> Task:
    """Create a new Task with a validated status transition.

    Calls :func:`~synthorg.core.task_transitions.validate_transition`
    before producing the new instance, ensuring the state machine is
    enforced.  Uses ``model_validate`` so all validators run on the
    new instance.

    Args:
        target: The desired target status.
        **overrides: Additional field overrides for the new task.

    Returns:
        A new Task with the target status.

    Raises:
        ValueError: If the transition is not valid or overrides
            contain ``status``.
    """
    if "status" in overrides:
        msg = "status override is not allowed; pass transition target explicitly"
        raise ValueError(msg)
    validate_transition(self.status, target)
    payload = self.model_dump()
    payload.update(overrides)
    payload["status"] = target
    result = Task.model_validate(payload)
    logger.info(
        TASK_STATUS_CHANGED,
        task_id=self.id,
        from_status=self.status.value,
        to_status=target.value,
    )
    return result

Task Transitions

task_transitions

Task lifecycle state machine transitions.

Defines the valid state transitions for the task lifecycle, based on the Engine design page, extended with BLOCKED, CANCELLED, FAILED, INTERRUPTED, SUSPENDED, REJECTED, and AUTH_REQUIRED transitions for completeness::

CREATED -> ASSIGNED | REJECTED
ASSIGNED -> IN_PROGRESS | AUTH_REQUIRED | BLOCKED | CANCELLED
           | FAILED | INTERRUPTED | SUSPENDED
IN_PROGRESS -> IN_REVIEW | AUTH_REQUIRED | BLOCKED | CANCELLED
               | FAILED | INTERRUPTED | SUSPENDED
IN_REVIEW -> COMPLETED | IN_PROGRESS (rework) | BLOCKED | CANCELLED
AUTH_REQUIRED -> ASSIGNED (approved) | CANCELLED (denied/timeout)
BLOCKED -> ASSIGNED (unblocked)
FAILED -> ASSIGNED (reassignment for retry)
INTERRUPTED -> ASSIGNED (reassignment on restart)
SUSPENDED -> ASSIGNED (resume from checkpoint)

COMPLETED, CANCELLED, and REJECTED are terminal states with no outgoing transitions. FAILED, INTERRUPTED, and SUSPENDED are non-terminal (can be reassigned). AUTH_REQUIRED is non-terminal (waiting for authorization).

validate_transition

validate_transition(current, target)

Validate that a state transition is allowed.

Parameters:

Name Type Description Default
current TaskStatus

The current task status.

required
target TaskStatus

The desired target status.

required

Raises:

Type Description
ValueError

If the transition from current to target is not in :data:VALID_TRANSITIONS.

Source code in src/synthorg/core/task_transitions.py
def validate_transition(current: TaskStatus, target: TaskStatus) -> None:
    """Validate that a state transition is allowed.

    Args:
        current: The current task status.
        target: The desired target status.

    Raises:
        ValueError: If the transition from *current* to *target*
            is not in :data:`VALID_TRANSITIONS`.
    """
    _MACHINE.validate(current, target)

transition_path

transition_path(current, target)

Return the shortest valid hop sequence from current to target.

Parameters:

Name Type Description Default
current TaskStatus

The current task status.

required
target TaskStatus

The desired task status.

required

Returns:

Type Description
tuple[TaskStatus, ...] | None

() when already at target; a tuple of intermediate

tuple[TaskStatus, ...] | None

statuses ending in target (each hop individually valid) when

tuple[TaskStatus, ...] | None

a lifecycle path exists; or None when target is

tuple[TaskStatus, ...] | None

unreachable from current (e.g. current is terminal).

Source code in src/synthorg/core/task_transitions.py
def transition_path(
    current: TaskStatus,
    target: TaskStatus,
) -> tuple[TaskStatus, ...] | None:
    """Return the shortest valid hop sequence from *current* to *target*.

    Args:
        current: The current task status.
        target: The desired task status.

    Returns:
        ``()`` when already at *target*; a tuple of intermediate
        statuses ending in *target* (each hop individually valid) when
        a lifecycle path exists; or ``None`` when *target* is
        unreachable from *current* (e.g. *current* is terminal).
    """
    return _MACHINE.path_to(current, target)

Project

project

Project domain model for task collection management.

Project pydantic-model

Bases: BaseModel

A collection of related tasks with a shared goal, team, and deadline.

Projects organize tasks into a coherent unit of work with budget tracking and team assignment. Per the Design Overview glossary and entity relationship tree.

Attributes:

Name Type Description
id UUID

Unique project identifier (auto-generated UUID).

name NotBlankStr

Project display name.

description str

Detailed project description.

team tuple[NotBlankStr, ...]

Agent IDs assigned to this project.

lead NotBlankStr | None

Agent ID of the project lead.

task_ids tuple[NotBlankStr, ...]

IDs of tasks belonging to this project.

deadline str | None

Optional deadline (ISO 8601 string or None).

budget float

Total budget in base currency (configurable, defaults to EUR).

status ProjectStatus

Current project status.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_deadline_format
  • _validate_collections

id pydantic-field

id

Unique project identifier

name pydantic-field

name

Project display name

description pydantic-field

description = ''

Detailed project description

team pydantic-field

team = ()

Agent IDs assigned to this project

lead pydantic-field

lead = None

Agent ID of the project lead

task_ids pydantic-field

task_ids = ()

IDs of tasks belonging to this project

deadline pydantic-field

deadline = None

Optional deadline (ISO 8601 string)

budget pydantic-field

budget = 0.0

Total budget in base currency (configurable, defaults to EUR)

status pydantic-field

status = ProjectStatus.PLANNING

Current project status

Approval

enums

Approval workflow enumerations.

ApprovalStatus

Bases: StrEnum

Status of a human approval item.

ApprovalRiskLevel

Bases: StrEnum

Risk level assigned to an approval item.

ApprovalSource

Bases: StrEnum

Origin of an approval item, fixed at creation.

Routing of a decided approval (mid-execution resume vs. review gate) keys off this persisted discriminator rather than a live parked-context probe, keeping the flow deterministic.

Attributes:

Name Type Description
PARKED_CONTEXT

Backs a parked agent execution context (SecOps escalation or request_human_approval); resumes the run.

REVIEW_GATE

Any other approval (autonomy, hiring, promotion, scaling, ...); drives the review-gate transition. Default.

CONVERSATIONAL_INTAKE

A work item proposed via the conversational interface; approval rebuilds the WorkItem and runs it through the pipeline, rejection declines it.

CONVERSATIONAL_INVITE

An agent's request to add another agent to a group conversation; approval adds the participant + hands over the transcript, rejection leaves membership.

approval

Human approval item domain model.

Represents an action that requires human approval before proceeding. Used by the approval queue API and referenced by engine and security subsystems.

ApprovalItem pydantic-model

Bases: BaseModel

A single item in the human approval queue.

Attributes:

Name Type Description
id UUID

Unique approval identifier.

action_type NotBlankStr

What kind of action requires approval.

title NotBlankStr

Short summary of the approval request.

description NotBlankStr

Detailed explanation.

requested_by NotBlankStr

Agent or system that requested approval.

risk_level ApprovalRiskLevel

Assessed risk level.

status ApprovalStatus

Current approval status.

created_at AwareDatetime

When the item was created.

expires_at AwareDatetime | None

Optional expiration time for auto-expiry.

decided_at AwareDatetime | None

When the decision was made (set on approve/reject).

decided_by NotBlankStr | None

Who made the decision (set on approve/reject).

decision_reason NotBlankStr | None

Reason for the decision (required on reject).

task_id NotBlankStr | None

Optional associated task identifier.

source ApprovalSource

Origin discriminator fixed at creation. Routes a decided approval deterministically (parked-context resume vs. review gate) without a live parked-context probe. Defaults to REVIEW_GATE; the two park producers (SecOps escalation and the request_human_approval tool) set PARKED_CONTEXT.

consumed_at AwareDatetime | None

When an APPROVED one-shot grant was spent. None until consumed. The governed external-access tool sets this via an atomic compare-and-set (consume_if_approved) before egress so the same approval cannot authorise a second call; the approval keeps status == APPROVED because consumption is orthogonal to the decision lifecycle.

metadata dict[str, str]

Additional key-value metadata.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _deep_copy_metadata
  • _validate_decision_fields
  • _validate_expiry
  • _validate_consumption

evidence_package pydantic-field

evidence_package = None

Structured evidence for HITL approval

Effective Autonomy

effective_autonomy

Resolved-autonomy value object.

EffectiveAutonomy is the expanded, resolved autonomy an agent runs under, produced by :class:~synthorg.security.autonomy.resolver.AutonomyResolver. It is shared vocabulary the engine, workers, tools, and meta layers annotate against, so it lives in a dependency-free core leaf (it needs only the autonomy-level enum) rather than the heavy security package, which any consumer would otherwise have to drag in to reference the type at module level.

EffectiveAutonomy pydantic-model

Bases: BaseModel

Resolved, expanded autonomy for an agent's execution run.

Produced by :class:~synthorg.security.autonomy.resolver.AutonomyResolver by resolving the three-level chain (agent, department, company) and expanding category shortcuts into concrete action types.

Attributes:

Name Type Description
level AutonomyLevel

Resolved autonomy level.

auto_approve_actions frozenset[str]

Concrete action types that are auto-approved.

human_approval_actions frozenset[str]

Concrete action types requiring human approval.

security_agent bool

Whether the security agent reviews escalations.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_disjoint

level pydantic-field

level

Resolved autonomy level

auto_approve_actions pydantic-field

auto_approve_actions

Expanded auto-approve action types

human_approval_actions pydantic-field

human_approval_actions

Expanded human-approval action types

security_agent pydantic-field

security_agent

Whether security agent reviews escalations

Red-Team Review Input

redteam_review_input

Red-team gate input value object.

RedTeamReviewInput is what the adversarial review gate sees on entry: a deliverable plus the context the gate needs to attack it. It is assembled in the engine and consumed by the security red-team subsystem, so it lives in a dependency-free core leaf (it needs only the string and autonomy-level primitives) rather than the heavy security.redteam package, letting either side annotate against it at module level without a cross-package cycle.

RedTeamReviewInput pydantic-model

Bases: BaseModel

What the gate sees on entry: the deliverable plus its context.

The gate's evaluation surface. Lives here (not on Task directly) so the red-team subsystem can be exercised without dragging the full Task model and its dependencies into every test.

Attributes:

Name Type Description
task_id NotBlankStr

The deliverable's owning task.

execution_id NotBlankStr

The execution that produced the deliverable.

deliverable_content NotBlankStr

The artifact text the red-team attacks.

acceptance_criteria tuple[NotBlankStr, ...]

The brief's acceptance criteria, used by the agent prompt; a dedicated requirements-coverage checker (not yet built) would also consume it.

assigned_agent_id NotBlankStr

The agent that produced the deliverable (forbidden as red-team reviewer; enforced one layer up by the review-gate's self-review guard).

autonomy AutonomyLevel

Effective autonomy level governing severity-tiered routing in :mod:synthorg.security.redteam.routing.

project_id NotBlankStr | None

Owning project of the deliverable, when known. The substrate-backed grounding checker scopes its corpus search to it; None falls back to a global-only search.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Artifact

artifact

Artifact domain models for task outputs and expected deliverables.

ArtifactType

Bases: StrEnum

Type of produced artifact.

ExpectedArtifact pydantic-model

Bases: BaseModel

An artifact expected to be produced by a task.

Used within task definitions to declare what outputs are expected.

Attributes:

Name Type Description
type ArtifactType

The type of artifact expected.

path NotBlankStr

File or directory path where the artifact should be produced.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

type pydantic-field

type

Type of artifact expected

path pydantic-field

path

File or directory path for the artifact

Artifact pydantic-model

Bases: BaseModel

A concrete artifact produced by an agent during task execution.

Artifacts track the actual work output, linking it back to the originating task and the agent who produced it.

Attributes:

Name Type Description
id NotBlankStr

Unique artifact identifier (e.g. "artifact-abc123").

type ArtifactType

The type of artifact.

path NotBlankStr

File or directory path of the artifact.

task_id NotBlankStr

ID of the task that produced this artifact.

created_by NotBlankStr

Agent ID of the creator.

description str

Human-readable description of the artifact.

content_type str

MIME content type (empty when no content stored).

size_bytes int

Content size in bytes (zero when no content stored).

project_id NotBlankStr | None

ID of the project this artifact belongs to.

created_at AwareDatetime | None

Timestamp when the artifact was created.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

id pydantic-field

id

Unique artifact identifier

type pydantic-field

type

Artifact type

path pydantic-field

path

File or directory path of the artifact

task_id pydantic-field

task_id

ID of the task that produced this artifact

created_by pydantic-field

created_by

Agent ID of the creator

description pydantic-field

description = ''

Human-readable description of the artifact

project_id pydantic-field

project_id = None

ID of the project this artifact belongs to

content_type pydantic-field

content_type = ''

MIME content type (empty when no content stored)

size_bytes pydantic-field

size_bytes = 0

Content size in bytes (zero when no content stored)

created_at pydantic-field

created_at = None

UTC timestamp when the artifact was created

Personality

personality

Personality compatibility scoring.

Computes pairwise and team-level compatibility scores from :class:~synthorg.core.agent.PersonalityConfig profiles.

compute_compatibility

compute_compatibility(a, b)

Compute pairwise compatibility score between two personality profiles.

Parameters:

Name Type Description Default
a PersonalityConfig

First personality profile.

required
b PersonalityConfig

Second personality profile.

required

Returns:

Type Description
float

Score between 0.0 (incompatible) and 1.0 (highly compatible).

Source code in src/synthorg/core/personality.py
def compute_compatibility(a: PersonalityConfig, b: PersonalityConfig) -> float:
    """Compute pairwise compatibility score between two personality profiles.

    Args:
        a: First personality profile.
        b: Second personality profile.

    Returns:
        Score between 0.0 (incompatible) and 1.0 (highly compatible).
    """
    bf_score = _big_five_score(a, b)
    collab_score = _collaboration_score(a.collaboration, b.collaboration)
    conflict_score = _conflict_score(a.conflict_approach, b.conflict_approach)

    result = (
        _WEIGHT_BIG_FIVE * bf_score
        + _WEIGHT_COLLABORATION * collab_score
        + _WEIGHT_CONFLICT * conflict_score
    )
    # Clamp to [0.0, 1.0] for safety.
    result = max(0.0, min(1.0, result))

    logger.debug(
        PERSONALITY_COMPATIBILITY_COMPUTED,
        score=result,
        big_five=bf_score,
        collaboration=collab_score,
        conflict=conflict_score,
    )
    return result

compute_team_compatibility

compute_team_compatibility(members)

Compute average pairwise compatibility for a team.

Parameters:

Name Type Description Default
members tuple[PersonalityConfig, ...]

Tuple of personality profiles for team members.

required

Returns:

Type Description
float

Average pairwise score (1.0 for teams with fewer than 2 members).

Source code in src/synthorg/core/personality.py
def compute_team_compatibility(
    members: tuple[PersonalityConfig, ...],
) -> float:
    """Compute average pairwise compatibility for a team.

    Args:
        members: Tuple of personality profiles for team members.

    Returns:
        Average pairwise score (1.0 for teams with fewer than 2 members).
    """
    team_size = len(members)
    if team_size <= 1:
        logger.debug(
            PERSONALITY_TEAM_SCORE_COMPUTED,
            team_size=team_size,
            score=1.0,
        )
        return 1.0

    pair_count = team_size * (team_size - 1) // 2
    total = sum(
        compute_compatibility(a, b) for a, b in itertools.combinations(members, 2)
    )
    result = total / pair_count

    logger.debug(
        PERSONALITY_TEAM_SCORE_COMPUTED,
        team_size=team_size,
        pair_count=pair_count,
        score=result,
    )
    return result

Resilience Config

resilience_config

Resilience configuration models (retry + rate limiting).

Defined in core/ to avoid circular imports between config.schema and providers.resilience. Both modules import from here.

RetryConfig pydantic-model

Bases: BaseModel

Configuration for automatic retry of transient provider errors.

Attributes:

Name Type Description
max_retries int

Maximum number of retry attempts (0 disables retries).

base_delay float

Initial delay in seconds before the first retry.

max_delay float

Upper bound on computed delay in seconds.

exponential_base float

Multiplier for exponential backoff.

jitter bool

Whether to add random jitter to delay.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_delay_ordering

max_retries pydantic-field

max_retries = 3

Maximum number of retry attempts (0 disables retries)

base_delay pydantic-field

base_delay = 1.0

Initial delay in seconds before the first retry

max_delay pydantic-field

max_delay = 60.0

Upper bound on computed delay in seconds

exponential_base pydantic-field

exponential_base = 2.0

Multiplier for exponential backoff

jitter pydantic-field

jitter = True

Whether to add random jitter to delay

RateLimiterConfig pydantic-model

Bases: BaseModel

Configuration for client-side rate limiting.

Attributes:

Name Type Description
max_requests_per_minute int

Maximum requests per minute (0 means unlimited).

max_concurrent int

Maximum concurrent in-flight requests (0 means unlimited).

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

max_requests_per_minute pydantic-field

max_requests_per_minute = 0

Maximum requests per minute (0 = unlimited)

max_concurrent pydantic-field

max_concurrent = 0

Maximum concurrent in-flight requests (0 = unlimited)

Auth

The auth domain types live in synthorg.core.auth (not synthorg.api.auth) so persistence repositories and engine modules can reference user / session / refresh-record / role models without crossing a layer boundary into the HTTP-coupled API package. The AuthService, controllers, and middleware that bind to Litestar / JWT issuer-audience constants stay under synthorg.api.auth.

config

Authentication configuration.

AuthConfig pydantic-model

Bases: BaseModel

JWT and authentication configuration.

The jwt_secret is resolved at application startup via a priority chain:

  1. SYNTHORG_JWT_SECRET environment variable (for multi-instance deployments sharing a common secret).
  2. Previously persisted secret in the settings table.
  3. Auto-generate a new secret and persist it for future runs.

At construction time the secret may be empty -- it is populated before the first request is served.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _apply_mirrors
  • _validate_secret_length
  • _validate_refresh_expiry
  • _validate_cookie_settings

jwt_secret pydantic-field

jwt_secret = ''

JWT signing secret (resolved at startup). Also used as the HMAC key for API key hash computation -- rotating this secret invalidates all stored API key hashes.

jwt_algorithm pydantic-field

jwt_algorithm = 'HS256'

JWT signing algorithm (HMAC family). HS256 is the default and is correctly keyed at the enforced MIN_SECRET_LENGTH (32 bytes); HS384/HS512 are accepted but RFC 7518 wants a >=48/64-byte key for full strength, so operators selecting them should provision a correspondingly longer jwt_secret.

jwt_expiry_minutes pydantic-field

jwt_expiry_minutes = 60

Access-token lifetime in minutes (default 1h). Short by design: refresh-token rotation keeps sessions alive without long-lived bearer tokens.

min_password_length pydantic-field

min_password_length = 12

Minimum password length for setup and password change

exclude_paths pydantic-field

exclude_paths = None

Regex patterns for paths excluded from authentication. When None (default), paths are auto-derived from the API prefix (health, auth/setup, auth/login, docs, scalar UI). Use ^ to anchor at the start of the path and add $ when an exact match (rather than a prefix match) is required.

dev_auth_bypass pydantic-field

dev_auth_bypass = False

DEV ONLY. When True, the gated POST /auth/dev-login endpoint is live: it mints a real session for the existing admin with no password so local dev work skips the login screen. Resolved at startup from SYNTHORG_DEV_AUTH_BYPASS; defaults False and MUST never be enabled in production -- it lets anyone who can reach the API obtain an admin session. Auth enforcement is otherwise unchanged: only this one endpoint is gated on the flag.

cookie_name pydantic-field

cookie_name = DEFAULT_COOKIE_NAME

Session cookie name

cookie_secure pydantic-field

cookie_secure = True

Secure flag on session cookies (HTTPS-only)

cookie_samesite pydantic-field

cookie_samesite = 'strict'

SameSite attribute for session cookies

cookie_path pydantic-field

cookie_path = '/api'

Path scope for the session cookie (HttpOnly)

csrf_cookie_path = '/'

Path scope for the CSRF cookie (non-HttpOnly). Defaults to / so document.cookie in JavaScript can read it from any SPA route; scoping it under /api (like the session cookie) would hide it from code running on application pages, breaking the double-submit pattern.

cookie_domain pydantic-field

cookie_domain = None

Domain for session cookies (None = current host)

csrf_cookie_name = DEFAULT_CSRF_COOKIE_NAME

CSRF token cookie name (non-HttpOnly, JS-readable)

csrf_header_name pydantic-field

csrf_header_name = DEFAULT_CSRF_HEADER_NAME

Header name for CSRF token submission

max_concurrent_sessions pydantic-field

max_concurrent_sessions = 5

Max concurrent sessions per user (0 = unlimited)

jwt_refresh_enabled pydantic-field

jwt_refresh_enabled = True

Enable refresh token rotation

jwt_refresh_expiry_minutes pydantic-field

jwt_refresh_expiry_minutes = 10080

Refresh token lifetime in minutes (default 7 days)

refresh_cookie_name = DEFAULT_REFRESH_COOKIE_NAME

Refresh token cookie name

refresh_cookie_path = DEFAULT_REFRESH_COOKIE_PATH

Path scope for refresh token cookie (narrow)

lockout_threshold pydantic-field

lockout_threshold = 10

Failed login attempts before account lockout

lockout_window_minutes pydantic-field

lockout_window_minutes = 15

Sliding window for counting failed attempts

lockout_duration_minutes pydantic-field

lockout_duration_minutes = 15

Auto-unlock duration after lockout

with_secret

with_secret(secret)

Return a copy with the JWT secret set.

Parameters:

Name Type Description Default
secret str

Resolved JWT signing secret.

required

Returns:

Type Description
AuthConfig

New AuthConfig with the secret populated.

Raises:

Type Description
ValueError

If the secret is too short for the configured JWT algorithm.

Source code in src/synthorg/core/auth/config.py
def with_secret(self, secret: str) -> AuthConfig:
    """Return a copy with the JWT secret set.

    Args:
        secret: Resolved JWT signing secret.

    Returns:
        New ``AuthConfig`` with the secret populated.

    Raises:
        ValueError: If the secret is too short for the configured
            JWT algorithm.
    """
    min_length = _MIN_SECRET_LENGTH_BY_ALG.get(
        self.jwt_algorithm, MIN_SECRET_LENGTH
    )
    _require_valid_secret(secret, min_length)
    return self.model_copy(update={"jwt_secret": secret})

models

Authentication domain models.

AuthMethod

Bases: StrEnum

Authentication method used for a request.

OrgRole

Bases: StrEnum

Permission-level role for org configuration access.

Orthogonal to HumanRole (operational persona). HumanRole controls who you are in the org simulation; OrgRole controls what you can do to the org config.

User pydantic-model

Bases: BaseModel

Persisted user account.

Attributes:

Name Type Description
id NotBlankStr

Unique user identifier.

username NotBlankStr

Login username.

password_hash str

Argon2id hash (excluded from repr).

role HumanRole

Access control role.

must_change_password bool

Whether the user must change password.

org_roles tuple[OrgRole, ...]

Permission-level roles for org config access.

scoped_departments tuple[NotBlankStr, ...]

Departments accessible to dept admins.

created_at AwareDatetime

Account creation timestamp.

updated_at AwareDatetime

Last modification timestamp.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_scoped_departments

ApiKey pydantic-model

Bases: BaseModel

Persisted API key (hash-only storage).

Attributes:

Name Type Description
id NotBlankStr

Unique key identifier (UUID).

key_hash NotBlankStr

HMAC-SHA256 hex digest of the raw key.

name NotBlankStr

Human-readable label.

role HumanRole

Access control role.

user_id NotBlankStr

Owner user ID.

created_at AwareDatetime

Key creation timestamp (timezone-aware).

expires_at AwareDatetime | None

Optional expiry timestamp (timezone-aware).

revoked bool

Whether the key has been revoked.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

AuthenticatedUser pydantic-model

Bases: BaseModel

Lightweight identity attached to connection.user.

Populated by the auth middleware after successful authentication.

Attributes:

Name Type Description
user_id NotBlankStr

User's unique identifier.

username NotBlankStr

User's login name.

role HumanRole

Access control role.

auth_method AuthMethod

How the user authenticated.

must_change_password bool

Whether forced password change is pending.

org_roles tuple[OrgRole, ...]

Permission-level roles for org config access.

scoped_departments tuple[NotBlankStr, ...]

Departments accessible to dept admins.

session_id NotBlankStr | None

JWT jti (or None for non-JWT methods). Long-lived connections (WS, SSE) consult session_store.is_revoked(session_id) periodically so an admin revocation kicks the connection out instead of waiting for the access token to expire.

api_key_id NotBlankStr | None

Id of the API key that authenticated the request (or None for non-API-key methods). Long-lived API-key streams (SSE) have no JWT jti, so the revalidation tick re-fetches this key by id to honour revocation / expiry.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_api_key_binding
  • _validate_scoped_departments

session

Session domain model for JWT session tracking.

Session pydantic-model

Bases: BaseModel

An active JWT session.

Each JWT token issued at login/setup creates a Session record. The session_id corresponds to the JWT jti claim, enabling per-token revocation.

Attributes:

Name Type Description
session_id NotBlankStr

JWT jti claim (unique token identifier).

user_id NotBlankStr

Owner's user ID.

username NotBlankStr

Owner's login name (denormalized for display).

role HumanRole

Owner's role at session creation time.

ip_address str

Client IP at login time.

user_agent str

Client User-Agent header at login time (capped at 512 characters).

created_at AwareDatetime

Session creation timestamp.

last_active_at AwareDatetime

Last request timestamp.

expires_at AwareDatetime

JWT expiry timestamp.

revoked bool

Whether the session has been revoked.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

  • session_id (NotBlankStr)
  • user_id (NotBlankStr)
  • username (NotBlankStr)
  • role (HumanRole)
  • ip_address (str)
  • user_agent (str)
  • created_at (AwareDatetime)
  • last_active_at (AwareDatetime)
  • expires_at (AwareDatetime)
  • revoked (bool)

Validators:

  • _validate_temporal_ordering

refresh_record

Refresh-token record model.

Lives outside the persistence layer so protocol modules can depend on the model without importing a backend implementation.

RefreshRejectReason

Bases: StrEnum

Why a consume() call refused to mint a new lease.

The repository captures the reason as a typed enum so the auth service / controller can emit SECURITY_AUTH_REFRESH_REJECTED with the correct reason field instead of folding every miss into a single bucket.

RefreshConsumeOutcome pydantic-model

Bases: BaseModel

Result of a refresh-token consume attempt.

Exactly one of record and reject_reason is populated. The model validator below keeps the discriminator honest.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_discriminator

RefreshRecord pydantic-model

Bases: BaseModel

A stored refresh token record.

Attributes:

Name Type Description
token_hash NotBlankStr

HMAC-SHA256 hash of the opaque token.

session_id NotBlankStr

Associated JWT session (jti).

user_id NotBlankStr

Token owner's user ID.

expires_at AwareDatetime

Expiry timestamp.

used bool

Whether the token has been consumed.

created_at AwareDatetime

Creation timestamp.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_temporal_order

roles

Recognised human roles for access control.

HumanRole

Bases: StrEnum

Recognised human roles for access control.