phenotypic.sdk_.RunIdentity#

class phenotypic.sdk_.RunIdentity(processing_generation: str, restart_epoch: int, scheduler_epoch: str | None, owner_generation: str | None, inventory_digest: str, scientific_config_digest: str, finalization_input_digest: str)[source]#

Bases: object

The run-level identity of one run configuration (spec §5.1, §5.3).

Carries four of §5.1’s five identity tokens – the fifth, work_id, is per-image and lives on ImageState – plus §5.3’s three digests.

processing_generation is content-derived (from P2 onward), so resume and fencing are emergent rather than bookkeeping: two invocations with the same inputs mint the same identity without either having read the other’s state.

Note the count: spec §5.1 is headed “the six tokens” and its own amendment U-4 cuts publication_id, leaving five, of which work_id and processing_generation are the content-derived pair. Anything still saying “six tokens, three content-derived” predates U-4.

Methods

__init__

digest

Return a stable digest of the fencing-relevant tokens.

Attributes

Parameters:
  • processing_generation (str)

  • restart_epoch (int)

  • scheduler_epoch (str | None)

  • owner_generation (str | None)

  • inventory_digest (str)

  • scientific_config_digest (str)

  • finalization_input_digest (str)

processing_generation: str#
restart_epoch: int#
scheduler_epoch: str | None#
owner_generation: str | None#
inventory_digest: str#
scientific_config_digest: str#
finalization_input_digest: str#
digest() str[source]#

Return a stable digest of the fencing-relevant tokens.

scheduler_epoch and owner_generation are excluded: they are liveness facts, not configuration, and folding them in would discard the verification cache every time a job is submitted against unchanged work.

Derived from IDENTITY_DIGEST_FIELDS, not from a second hand-written list (F6). The set was enumerated twice – here and in _run_state’s comparison – with nothing keeping them in step, so a sixth field added to one would have silently not been fenced by the other.

Uses canonical_digest() rather than a local ``json.dumps`` (F5). The hand-rolled copy matched on sort_keys and separators and differed on ensure_ascii, which is the one flag _digests calls load-bearing: every proof on disk was written with ensure_ascii=False. A dataset directory containing a non-ASCII character – plaque-café/ – was enough to make this digest disagree with the canonical spelling of the same value.

Return type:

str