cadrumo.core.observability.fingerprint module

Deterministic SHA-256 fingerprints of corpus, db, and certificate state.

Used by run_context() to stamp a recorded RunTrace with the configuration, application-state, and certificate identity observed at the time of the run.

db_sha256 fingerprints cadrumo_local_storage_root — the single canonical application data root every persisted category (encrypted state, caches, durable generated outputs) derives from, per Settings and cadrumo.core.config_state_root. This is deliberate: on an installed distribution the historical REPO_ROOT / "var" location resolves inside the virtualenv or the packaging tool’s ephemeral cache and typically does not exist, which previously made db_sha256 degrade to the constant empty-tree digest for every installed operator and permanently defeat drift detection rather than merely reporting “no state yet” once.

compute_corpus_sha256(settings)[source]

Compute a deterministic fingerprint of the effective configuration.

Hashes settings.model_dump_json() — the currently-loaded Settings snapshot, which already folds every environment-variable-sourced override. Production Settings carries no dotenv source of its own (see Settings.settings_customise_sources): an operator’s env/.env is development/test-only configuration bridged into the process environment before Settings resolves, so its values are already reflected in the snapshot hashed here and it needs no separate hashing channel.

Parameters:

settings (Settings) – Active Settings instance to fingerprint.

Return type:

str

Returns:

SHA-256 hex digest of the Settings snapshot.

compute_db_sha256(root, *, excluded_dirs=frozenset({}))[source]

Compute a deterministic fingerprint of a directory tree.

A generic, domain-agnostic content-addressed directory hash. Two callers use it for different purposes: compute_data_root_sha256() fingerprints the live application data root with the exclusion set data_root_cache_exclusions() computes from Settings, and a determinism-conformance test fingerprints an arbitrary snapshot directory of committed database files with no exclusions at all. This function itself knows nothing about Settings or the storage-root taxonomy.

Parameters:
  • root (Path) – Directory to walk.

  • excluded_dirs (frozenset[Path]) – Absolute or relative paths whose entire subtree is skipped; resolved internally before comparison so callers may pass either form.

Return type:

str

Returns:

SHA-256 hex digest of the curated tree.

data_root_cache_exclusions(settings)[source]

Return the regenerable/self-referential directories under the data root.

Which directories those are is declared, not decided here. Each member of the storage taxonomy carries a fingerprint_participation axis, and this reads the excluded set from it. That axis is independent and never derived: measured against every candidate, no expression over lifecycle or grouping reproduces the intended set, and three candidates differ in both directions at once — omitting members that are excluded while adding members that are not. So “exclude everything under cache/” or “exclude everything with a time-to-live” are both wrong, and wrong invisibly.

The value is still read from settings itself — the same instance whose cadrumo_local_storage_root compute_data_root_sha256() hashes — so an operator override of any one of these directories (a redirected LLM cache, say) is still excluded correctly regardless of where it actually resolves. A field that resolves to None is an opt-in location the operator never asked for; there is no directory to exclude.

What stays in matters as much as what comes out. Core state — the encrypted profile and bucket database, the filing artefacts, the financial catalogues — is deliberately fingerprinted, because a change there is real state drift. Excluding too much walks the digest toward the empty-tree constant that once defeated drift detection for every installed operator; excluding too little churns it on each cache write until the refusal stops being believed.

Return type:

frozenset[Path]

Parameters:

settings (Settings)

compute_data_root_sha256(settings)[source]

Compute compute_db_sha256() over the canonical application data root.

Hashes settings.cadrumo_local_storage_root — the single root every persisted category (encrypted state, caches, durable generated outputs) derives from in both a source checkout (REPO_ROOT/var/storage) and an installed distribution (the platform user-data directory) — excluding the regenerable caches and observability’s own output via data_root_cache_exclusions().

A data root that does not exist yet (a pristine install with no profile created) hashes to the same digest as an empty tree: this is a legitimate, expected, self-resolving state (it disappears the moment any state is written) rather than the historical defect, where a wrong root was hashed unconditionally on every installed run and every operator’s db_sha256 stayed the empty-tree constant forever, permanently defeating drift detection. A missing root is logged at debug level so the condition remains traceable without being disruptive on an otherwise-successful first invocation.

Parameters:

settings (Settings) – Active Settings instance supplying both the root to hash and the exclusions to apply.

Return type:

str

Returns:

SHA-256 hex digest of the curated application data root.

read_cert_fingerprint()[source]

Return the SHA-256 fingerprint of the active certificate, or "".

The empty string is the canonical “no certificate bound” sentinel — most CLI paths run without a cert (lookups and planning) and must still produce a valid RunTrace.

Reading the certificate without unlocking it is intentional: the observability layer never asks the operator for a passphrase, so we hash whatever DER bytes are visible on disk. When no path is configured we return "".

Return type:

str