"""Versioned identities used across the SciMesh workload SDK. The module-level constants ``SDK_API_VERSION``, ``MANIFEST_SCHEMA_VERSION``, ``WORKFLOW_SCHEMA_VERSION``, ``TASK_SCHEMA_VERSION``, and ``OUTPUT_SCHEMA_VERSION`` pin the current wire/schema versions; manifests declare explicit compatibility ranges against them. """ from __future__ import annotations from dataclasses import dataclass from typing import Mapping from ._validation import ( require_exact_keys, require_identifier, require_semver, require_string, require_workload_name, validate_version_range, version_in_range, ) SDK_API_VERSION = "1.0.0" MANIFEST_SCHEMA_VERSION = 1 WORKFLOW_SCHEMA_VERSION = 1 TASK_SCHEMA_VERSION = 1 OUTPUT_SCHEMA_VERSION = 1 @dataclass(frozen=True, slots=True) class VersionRange: """A deliberately small, explicit compatibility range. The v1 SDK accepts comma-separated comparisons such as ``>=1.0,<2.0``. Wildcards and an omitted operator are rejected so a missing version can never be interpreted as "latest". """ expression: str def __post_init__(self) -> None: object.__setattr__( self, "expression", validate_version_range(self.expression, "version range") ) def contains(self, version: str) -> bool: return version_in_range(version, self.expression) def to_dict(self) -> str: return self.expression @classmethod def from_dict(cls, value: object) -> "VersionRange": return cls(value) # type: ignore[arg-type] @dataclass(frozen=True, slots=True) class WorkloadId: """The exact identity of a workload: canonical hyphenated name and semantic version.""" name: str version: str def __post_init__(self) -> None: object.__setattr__(self, "name", require_workload_name(self.name)) object.__setattr__( self, "version", require_semver(self.version, "workload.version") ) def to_dict(self) -> dict[str, str]: return {"name": self.name, "version": self.version} @classmethod def from_dict(cls, value: object) -> "WorkloadId": if not isinstance(value, Mapping): raise ValueError("workload identity must be an object") require_exact_keys(value, {"name", "version"}, "workload identity") return cls(name=value["name"], version=value["version"]) # type: ignore[arg-type] @dataclass(frozen=True, slots=True) class SchemaRef: """A versioned artifact schema identity (``name@version``). Schemas are content contracts: two artifacts share a schema only when their ``SchemaRef`` values are equal. """ name: str version: int def __post_init__(self) -> None: object.__setattr__(self, "name", require_identifier(self.name, "schema.name")) if ( isinstance(self.version, bool) or not isinstance(self.version, int) or self.version < 1 ): raise ValueError("schema.version must be a positive integer") @property def canonical(self) -> str: return f"{self.name}@{self.version}" def to_dict(self) -> dict[str, object]: return {"name": self.name, "version": self.version} @classmethod def parse(cls, value: object, field: str = "schema") -> "SchemaRef": text = require_string(value, field, max_length=160) name, separator, raw_version = text.rpartition("@") if not separator or not raw_version.isdigit(): raise ValueError(f"{field} must use the name@version form") return cls(name=name, version=int(raw_version)) @classmethod def from_dict(cls, value: object) -> "SchemaRef": if isinstance(value, str): return cls.parse(value) if not isinstance(value, Mapping): raise ValueError("schema reference must be a name@version string or object") require_exact_keys(value, {"name", "version"}, "schema reference") return cls(name=value["name"], version=value["version"]) # type: ignore[arg-type] @dataclass(frozen=True, slots=True) class ComponentRef: """Versioned, package-owned planner/runner/reducer/verifier identity.""" name: str version: int def __post_init__(self) -> None: object.__setattr__( self, "name", require_identifier(self.name, "component.name") ) if ( isinstance(self.version, bool) or not isinstance(self.version, int) or self.version < 1 ): raise ValueError("component.version must be a positive integer") @property def canonical(self) -> str: return f"{self.name}@{self.version}" def to_dict(self) -> dict[str, object]: return {"name": self.name, "version": self.version} @classmethod def from_dict(cls, value: object) -> "ComponentRef": if isinstance(value, str): parsed = SchemaRef.parse(value, "component") return cls(parsed.name, parsed.version) if not isinstance(value, Mapping): raise ValueError("component reference must be an object") require_exact_keys(value, {"name", "version"}, "component reference") return cls(name=value["name"], version=value["version"]) # type: ignore[arg-type] @dataclass(frozen=True, slots=True) class FeatureRequirement: """A versioned feature a workload requires or optionally selects. Optional features may declare a fallback that negotiation records when the runtime does not provide the feature. """ name: str versions: VersionRange fallback: str | None = None def __post_init__(self) -> None: object.__setattr__(self, "name", require_identifier(self.name, "feature.name")) if not isinstance(self.versions, VersionRange): raise ValueError("feature.versions must be a VersionRange") if self.fallback is not None: object.__setattr__( self, "fallback", require_identifier(self.fallback, "feature.fallback") ) def to_dict(self) -> dict[str, object]: result: dict[str, object] = { "name": self.name, "versions": self.versions.expression, } if self.fallback is not None: result["fallback"] = self.fallback return result @classmethod def from_dict(cls, value: object) -> "FeatureRequirement": if not isinstance(value, Mapping): raise ValueError("feature requirement must be an object") require_exact_keys( value, {"name", "versions"}, "feature requirement", optional={"fallback"}, ) return cls( name=value["name"], # type: ignore[arg-type] versions=VersionRange.from_dict(value["versions"]), fallback=value.get("fallback"), # type: ignore[arg-type] )