Skip to content

sei.lock — drift state

✅ Stable

sei.lock is the freshness anchor file the engine writes to the repository root after every sei run. It holds the digests of pipeline inputs at the time of the last recompute. sei status reads it without running any script to determine which sections have become stale.


The core of the file is the anchored triple (triple), which deterministically identifies the state of the repository at the time of recompute:

triple fieldWhat it measuresHow it is computed
codeCode versionSHA-1 of HEAD (via gix, in-process)
model(reserved)Empty in GitDvcVersionResolver (model: String::new()); the model version is anchored indirectly via pipeline_lock_digest (dvc.lock/metrics)
datasetDataset versionComposed SHA-256 of DVC hashes from data/*.dvc

In addition to the triple, the pipeline_lock_digest field anchors the state of the reproducible pipeline:

  • DVC backend (cat. 1): SHA-256 of dvc.lock after dvc repro — anchors deps + params + outs of the recompute.
  • MLflow (cat. 2): Canonical SHA-256 of the run metrics (content-addressed).
  • Dagster (cat. 3): SHA-256 of the metrics file after asset materialisation.

The pipeline_lock_digest is included in the signed evidence bundle (EvidenceBundle.pipeline_lock_digest) as provenance of the recompute (Annex IV §1).


The schema lives in seigarrena-core/src/lock.rs. The following is an illustrative shape of a real sei.lock (hash values are fictitious):

sei.lock (illustrative shape)
{
"schema_version": "seigarrena.dev/v1alpha1",
"program_uid": "550e8400-e29b-41d4-a716-446655440000",
"triple": {
"code": "4280c0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7",
"model": "",
"dataset": "dvc:a1b2c3d4e5f6..."
},
"sections": {
"classification": {
"status": "valid",
"input_hash": "sha256:abc123...",
"edge_type": "scope"
},
"measurement_data": {
"status": "valid",
"input_hash": "sha256:def456...",
"edge_type": "data"
},
"measurement_model": {
"status": "valid",
"input_hash": "sha256:789abc...",
"edge_type": "impl"
}
},
"signed_bundle_digest": "sha256:deadbeef..."
}
FieldTypeDescription
schema_versionstringLock schema version (seigarrena.dev/v1alpha1).
program_uidstringUUID of the risk programme (the risk section of sei.yaml) at run time, derived from the system name (anchors the normative context).
tripleobjectAnchored triple (code, model, dataset) — see table above.
sectionsmapTyped dependency graph: each section has its input_hash, status, and edge_type.
signed_bundle_digeststringSHA-256 of the signed evidence bundle emitted by this run (None on the pipeline-less path).

Each entry in the sections map has three fields:

FieldTypeValuesDescription
statusstring"valid"Section status at run time.
input_hashstringsha256:…Hash of this section’s inputs. When it changes, the section becomes stale.
edge_typestring"scope", "impl", "data"Edge type in the dependency graph (see below).

The edge_type field determines which changes trigger recomputation of each section:

edge_typeRust valueWhat triggers recomputation
scopeEdgeType::ScopeChange to system purpose or risk triage (Drift A). Risk classification must be redone.
implEdgeType::ImplChange to the evaluation script or model (Drift B). Re-measure only; no re-triage if purpose is unchanged.
dataEdgeType::DataChange to the dataset (Drift C, EU AI Act Art. 10). Only data-dependent measurements are recomputed.

This typology maps directly to drift classes A, B and C. See Typed drift for the full model description.


How sei status detects drift without recomputing

Section titled “How sei status detects drift without recomputing”

sei status compares current hashes against those stored in sei.lock without running any script:

  1. Resolves the current repository triple (git HEAD + DVC hashes; the model field stays reserved/empty — the model version is reflected in pipeline_lock_digest).
  2. Compares each input_hash in sections against the current hash of the corresponding input.
  3. Sections whose hash has changed are marked Stale { reason, change_class } with the corresponding drift class.
  4. Unchanged sections are marked Reused.

The result is a per-section drift report with its class (A, B or C) and the reason for the change. sei status returns exit ≠ 0 if any section is stale (freshness gate) or if any blocking control in the last bundle fails (risk gate).

Ventana de terminal
# Detect drift without recomputing — useful in CI/CD as a fast gate
sei status

Staleness is selective: if only the dataset changes (edge_type: data), only data-measurement sections are recomputed on the next sei run; system classification and dataset-independent measurements are reused.


sei.lock uses an ordered BTreeMap and deterministic serialisation: the same repository state always produces the same bytes. This ensures that signed digests are reproducible across machines.


sei.lock and .sei/bundle.json are complementary:

  • sei.lock is the freshness anchor: it tells you when to re-run.
  • .sei/bundle.json is the signed evidence: it contains the results of the last run, control verdicts, and the pipeline_lock_digest.

The signed_bundle_digest field in sei.lock links the two artefacts: it is the SHA-256 of the bundle written during the same sei run.

See also: sei CLI Reference, The .sei/* artefacts.