Skip to content

project_model

project_model

Project and preset data models — DDD Value Objects.

Pure data types with no filesystem or subprocess I/O. These are the value objects in the domain model: they carry configuration data but have no behavior beyond computed paths.

ProjectConfig is loaded from project.yml by the companion projects module and wrapped by the rich Project aggregate to provide behavior.

ProjectConfig

Bases: BaseModel

Resolved project configuration loaded from project.yml.

Pure value object — holds configuration fields with no behavior beyond computed paths. The rich domain object Project wraps this and provides behavior.

model_config = ConfigDict(frozen=True) class-attribute instance-attribute

id instance-attribute

security_class instance-attribute

isolation = 'shared' class-attribute instance-attribute

upstream_url instance-attribute

default_branch instance-attribute

root instance-attribute

tasks_root instance-attribute

gate_path instance-attribute

gate_enabled = True class-attribute instance-attribute

staging_root instance-attribute

ssh_use_personal = False class-attribute instance-attribute

Opt in to the user's ~/.ssh keys for host-side gate-sync (default off).

expose_external_remote = False class-attribute instance-attribute

human_name = None class-attribute instance-attribute

human_email = None class-attribute instance-attribute

git_authorship = 'agent-human' class-attribute instance-attribute

upstream_polling_enabled = True class-attribute instance-attribute

upstream_polling_interval_minutes = 5 class-attribute instance-attribute

auto_sync_enabled = False class-attribute instance-attribute

auto_sync_branches = Field(default_factory=list) class-attribute instance-attribute

default_agent = None class-attribute instance-attribute

default_login = None class-attribute instance-attribute

agent_config = Field(default_factory=dict) class-attribute instance-attribute

shutdown_timeout = 10 class-attribute instance-attribute

memory = None class-attribute instance-attribute

Podman --memory value from run.memory in project.yml.

cpus = None class-attribute instance-attribute

Podman --cpus value from run.cpus in project.yml.

nested_containers = False class-attribute instance-attribute

Project runs podman/docker inside its container (see run.nested_containers).

runtime = None class-attribute instance-attribute

OCI runtime selector from run.runtime.

None (default) means "use the global default", which itself falls through to "crun" — the OCI runtime podman drives by default on every supported distro. "krun" selects KVM-microVM isolation; gated on the global experimental: true flag at runtime selection time so a typo never silently boots the experimental backend.

Sizing reuses the standard memory / cpus knobs — podman writes them into the OCI spec and the runtime reads them there; no krun-specific knob.

timezone = None class-attribute instance-attribute

IANA timezone for task containers (from run.timezone).

None lets terok-executor fall back to the host's timezone; pass an explicit string ("UTC", "Europe/Prague") to override — including to pin containers to UTC for reproducible runs.

task_name_categories = None class-attribute instance-attribute

shield_drop_on_task_run = True class-attribute instance-attribute

shield_on_task_restart = 'retain' class-attribute instance-attribute

hook_pre_start = None class-attribute instance-attribute

hook_post_start = None class-attribute instance-attribute

hook_post_ready = None class-attribute instance-attribute

hook_post_stop = None class-attribute instance-attribute

base_image = 'ubuntu:24.04' class-attribute instance-attribute

family = None class-attribute instance-attribute

Package family override for L0/L1 builds.

None lets terok-executor auto-detect from base_image; set explicitly when the auto-detect allowlist doesn't recognise the image (rocky, alma, suse, …).

agents = 'all' class-attribute instance-attribute

Comma-separated roster entries to install in L1 (or "all").

snippet_inline = None class-attribute instance-attribute

snippet_file = None class-attribute instance-attribute

shared_dir = None class-attribute instance-attribute

is_sealed property

Whether this project uses sealed isolation (zero bind mounts).

presets_dir property

Directory for preset config files for this project.

PresetInfo(name, source, path) dataclass

Metadata about a discovered preset.

name instance-attribute

source instance-attribute

path instance-attribute

is_valid_project_id(project_id)

Return whether project_id matches the [a-z0-9][a-z0-9_-]* contract.

Source code in src/terok/lib/core/project_model.py
def is_valid_project_id(project_id: str) -> bool:
    """Return whether *project_id* matches the ``[a-z0-9][a-z0-9_-]*`` contract."""
    return bool(project_id) and _PROJECT_ID_RE.fullmatch(project_id) is not None

validate_project_id(project_id)

Ensure a project ID is safe for use as a directory and OCI image name.

Raises SystemExit if the ID is empty, contains uppercase letters, path separators or traversal sequences, or uses characters outside [a-z0-9_-].

Source code in src/terok/lib/core/project_model.py
def validate_project_id(project_id: str) -> None:
    """Ensure a project ID is safe for use as a directory and OCI image name.

    Raises SystemExit if the ID is empty, contains uppercase letters, path
    separators or traversal sequences, or uses characters outside
    ``[a-z0-9_-]``.
    """
    if not is_valid_project_id(project_id):
        raise SystemExit(
            f"Invalid project ID '{project_id}': "
            "must start with a lowercase letter or digit, followed by lowercase letters, "
            "digits, hyphens, or underscores"
        )