Jerlshin's picture
refined progress and defect fix
761d149
Raw
History Blame Contribute Delete
2.59 kB
from __future__ import annotations
import hashlib
from dataclasses import dataclass
from datetime import date
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from redstack.config.schema import RedstackConfig
__all__: tuple[str, ...] = (
"RunContext",
"canonical_config_hash",
)
def canonical_config_hash(config: RedstackConfig) -> str:
"""Return a deterministic sha256 over the validated configuration.
The hash is taken over Pydantic's canonical JSON serialization with keys
sorted, so it is stable across process restarts and insertion order. Enum
values serialize by value (``StrEnum``), matching the determinism policy.
This feeds the run report's ``reproducible.config_hash`` (Ports §13) and the
offline staleness key's ``config_slice`` (Offline Pipeline Part 11).
"""
payload = config.model_dump_json(by_alias=False)
sorted_payload = _canonicalize_json(payload)
return hashlib.sha256(sorted_payload.encode("utf-8")).hexdigest()
def _canonicalize_json(payload: str) -> str:
"""Re-serialize a JSON string with sorted keys and no incidental whitespace."""
import json
parsed: object = json.loads(payload)
return json.dumps(parsed, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
@dataclass(frozen=True, slots=True, kw_only=True)
class RunContext:
"""Immutable base carrier: resolved config + reproducibility provenance.
Subclasses (``OfflinePipelineContext`` and the online ``OnlineRunContext``)
add their bound ports and output roots. The base owns only what both share
and what the run report's ``reproducible`` block requires.
Attributes:
config: The fully-composed, validated typed configuration. Raw ``dict``
config never crosses a module boundary (Architecture §20).
seed: The run seed sourced from ``config.determinism.seed`` (offline may
also override from ``config.offline.seed``); the single root of every
seeded substream. Online ranking has no legitimate RNG.
as_of: The injected reference date. No module reads the OS clock for
logic; recency math takes this value (Repository Layout §0).
code_version: The build's code provenance (e.g. ``git describe``),
recorded into the report so a submission is traceable to its source.
config_hash: Deterministic sha256 of ``config`` (see
:func:`canonical_config_hash`), pinned at construction.
"""
config: RedstackConfig
seed: int
as_of: date
code_version: str
config_hash: str