bayesmithDocumentation0.10.0 source

bayesmith.artifacts.base

Source-derived signatures and contracts. See the reference index for coverage and conventions.

Module contract
The artifact envelope: what every artifact carries, and how it retires.

Plan §0.2's frozen envelope, plus the small value objects a run record is made
of. Three rulings shape nearly every line here.

**An artifact is data, and data does not change under you.** Everything is a
frozen dataclass; :class:``NamedArray`` copies its input into a C-contiguous
read-only array, so a caller who keeps a reference to the array they passed
cannot edit an artifact that has already been fingerprinted. The copy and the
read-only flag close different holes -- one from outside the artifact, one
from inside -- and neither substitutes for the other.

**Identity and content are different axes.** ``artifact_id`` and ``run_id`` are
UUID4s minted once and preserved across round trips; they say WHICH artifact.
What it was made OF is the fingerprint bundle, and that is what caching and
invalidation read. The version identity is ``(artifact_id, revision)``:
:func:``invalidate_meta`` APPENDS revision ``n + 1`` marked INVALIDATED, carrying
the changed input kinds and the time, and leaves revision ``n`` exactly as it
was. Provenance that can be rewritten is not provenance, and a verdict that
can be deleted is not a record of having judged.

**Refusals happen at construction, in the smallest type that can see the
problem.** A budget refuses a negative count, a timestamp refuses a naive or
offset time, a lifecycle refuses "invalidated, but nothing changed". The
alternative is a validator somewhere upstream that a second caller does not
know to run.

**Which exception a refusal raises is a contract, not a mood.** A ``TypeError``
means "that is the wrong kind of thing" -- a bare string where an enum member
belongs, a list where a tuple of refs belongs. A ``ValueError`` means "right kind
of thing, malformed or out of range" -- a negative count, a non-UTC timestamp,
a UUID that is not version 4. The split is worth stating because most fields
here can fail either way, and a caller sanitising input needs to know which
question it just got an answer to.

Two details that look like fussiness and are not. Times are UTC RFC 3339 and
are NORMALISED to the ``Z`` spelling: ``+00:00`` is the same instant, and two
spellings of one instant are two byte strings for one artifact. And the enums
are checked with ``isinstance`` rather than by string value, because a
:class:``enum.StrEnum`` member IS its value -- ``ApproximationClass.EXACT`` and
``TargetFidelity.EXACT`` are equal strings answering different questions, and a
string check would let them be swapped.

Layering: ``_codec ← identity ← base``. NumPy and the standard library, and
nothing of the Graph, the dispatch layer or JAX (§0 ruling 5).

SCHEMA_VERSION

Defined in bayesmith.artifacts.base, line 102.

SCHEMA_VERSION = 1

CanonicalScalar

Defined in bayesmith.artifacts.base, line 107.

CanonicalScalar = bool | int | float | str | None

CanonicalValue

Defined in bayesmith.artifacts.base, line 108.

CanonicalValue = CanonicalScalar | tuple['CanonicalValue', ...]

canonical_scalar_options

Defined in bayesmith.artifacts.base, line 281.

canonical_scalar_options(label: str, pairs: object) -> tuple[tuple[str, CanonicalScalar], ...]
Sorted, key-unique options whose values are :data:``CanonicalScalar``.

canonical_value_options

Defined in bayesmith.artifacts.base, line 288.

canonical_value_options(label: str, pairs: object) -> tuple[tuple[str, CanonicalValue], ...]
Sorted, key-unique options whose values are :data:``CanonicalValue``.

utc_timestamp

Defined in bayesmith.artifacts.base, line 197.

utc_timestamp(moment: _dt.datetime | None=None) -> str
``moment`` (default: now) as an RFC 3339 UTC string in the ``Z`` spelling.

NamedArray

Defined in bayesmith.artifacts.base, line 300.

class NamedArray
name: str
value: np.ndarray
dims: tuple[str, ...]
The one public container for an array in an artifact (§0.5).

The value is copied in and handed back read-only, and ``dims`` names one axis
each. A repeated dim name is allowed on purpose: a covariance matrix is
indexed by the same parameter axis twice, and refusing that would push
every covariance into an unnamed array.

Equality is over NAME, DIMS and BYTES rather than by ``==`` on the arrays.
Element-wise comparison would make ``artifact == artifact`` raise for any
array of more than one element, and byte equality is what a fingerprint
already means -- which is also why two NaNs with one bit pattern compare
equal here, while ``np.array_equal`` would call them different.

RunWarning

Defined in bayesmith.artifacts.base, line 375.

class RunWarning
code: str
message: str
scope: str | None = None
Something a run noticed and did not fail over.

``scope`` is a plain string here. Task 4 introduces the structured
``ScopeRef`` that the Refusal family uses, and borrowing it before it
exists would make this module depend on a type nobody has designed yet.

ErrorRecord

Defined in bayesmith.artifacts.base, line 395.

class ErrorRecord
code: str
message: str
exception_type: str
traceback_ref: str | None = None
A serialisable summary of a failure -- never the exception object.

``traceback_ref`` is an opaque external reference (§0.6): a traceback is not
one of the three :class:``ArtifactKind`` the invalidation matrix reasons
about, so it is stored beside the artifacts rather than as one.

ComputeBudget

Defined in bayesmith.artifacts.base, line 417.

class ComputeBudget
draws: int | None = None
warmup: int | None = None
chains: int | None = None
max_iterations: int | None = None
max_wall_clock_seconds: float | None = None
What a run was allowed to spend. ``None`` where a count does not apply.

``None`` and ``0`` are different answers -- "this task has no such knob"
against "you may take none" -- so the field is kept and left empty rather
than filled with a stand-in.

SeedRecord

Defined in bayesmith.artifacts.base, line 443.

class SeedRecord
seed: int
key_algorithm: str
The entropy a run started from, and the key algorithm it was fed to.

DeviceRecord

Defined in bayesmith.artifacts.base, line 456.

class DeviceRecord
platform: str
device_kind: str
device_id: int
One device a run used, described the way a backend describes it.

BackendRef

Defined in bayesmith.artifacts.base, line 471.

class BackendRef
name: str
version: str | None = None
The backend that RAN, which is never the policy value ``"auto"``.

A task may ask for ``"auto"`` (§0.4); a run record answering ``"auto"`` would
be provenance that forgot which backend produced the numbers.

TerminationReason

Defined in bayesmith.artifacts.base, line 492.

class TerminationReason(StrEnum)
Why a run stopped, which is not the same question as whether it worked.
COMPLETED = 'completed'
CONVERGED = 'converged'
BUDGET_EXHAUSTED = 'budget_exhausted'
TOLERANCE_UNMET = 'tolerance_unmet'
DIVERGED = 'diverged'
INTERRUPTED = 'interrupted'

TerminationRecord

Defined in bayesmith.artifacts.base, line 505.

class TerminationRecord
reason: TerminationReason
iterations: int | None = None
message: str = ''
No additional source docstring. Read the signature and owning module contract above.

TimingRecord

Defined in bayesmith.artifacts.base, line 519.

class TimingRecord
started_at: str
finished_at: str
wall_clock_seconds: float
compile_seconds: float | None = None
When a run ran and how long it took. Wall clock only -- §0.3 keeps
timing out of every fingerprint, so nothing here can change an identity.

ApproximationClass

Defined in bayesmith.artifacts.base, line 550.

class ApproximationClass(StrEnum)
How the representation was PRODUCED (§0.2).
EXACT = 'exact'
CERTIFIED_DETERMINISTIC = 'certified_deterministic'
MONTE_CARLO = 'monte_carlo'
HEURISTIC = 'heuristic'

TargetFidelity

Defined in bayesmith.artifacts.base, line 560.

class TargetFidelity(StrEnum)
Whether the TARGET is the intended one, or an approximation of it.
EXACT = 'exact'
APPROXIMATE = 'approximate'

ApproximationRecord

Defined in bayesmith.artifacts.base, line 569.

class ApproximationRecord
representation_class: ApproximationClass
target_fidelity: TargetFidelity
details: tuple[tuple[str, CanonicalScalar], ...] = ()
Two orthogonal answers, kept apart (§0.2).

iid exact-linear draws are ``MONTE_CARLO`` and ``EXACT``: sampled, but from the
posterior itself. NUTS is ``MONTE_CARLO`` and, with no target approximation,
also ``EXACT``; an amortized posterior is ``HEURISTIC``/``APPROXIMATE``. One
enum would have to call the first case something, and every available
something is a lie about one of the two axes.

ProducerRef

Defined in bayesmith.artifacts.base, line 593.

class ProducerRef
package: str
version: str
The package and version that wrote an artifact.

ArtifactStatus

Defined in bayesmith.artifacts.base, line 605.

class ArtifactStatus(StrEnum)
No additional source docstring. Read the signature and owning module contract above.
CURRENT = 'current'
INVALIDATED = 'invalidated'

ArtifactRef

Defined in bayesmith.artifacts.base, line 612.

class ArtifactRef
artifact_id: str
revision: int
artifact_type: ArtifactKind
A reference to one VERSION of one artifact.

The revision and the kind travel with the id because ``(artifact_id,
revision)`` is the version identity: a reference carrying only an id would
be silently satisfied by a later, invalidated revision of the same
artifact, which is exactly the impersonation §0.2 rules out.

LifecycleRecord

Defined in bayesmith.artifacts.base, line 633.

class LifecycleRecord
status: ArtifactStatus
invalidated_at: str | None = None
changed_inputs: tuple[FingerprintKind, ...] = ()
Current, or invalidated with the reason and the time recorded.

ArtifactMeta

Defined in bayesmith.artifacts.base, line 681.

class ArtifactMeta
artifact_type: ArtifactKind
schema_version: int
artifact_id: str
revision: int
created_at: str
producer: ProducerRef
parent_refs: tuple[ArtifactRef, ...]
fingerprints: FingerprintBundle
lifecycle: LifecycleRecord
warnings: tuple[RunWarning, ...]
summary: str
The §0.2 envelope every artifact carries.

RunRecord

Defined in bayesmith.artifacts.base, line 732.

class RunRecord
run_id: str
plan_ref: ArtifactRef
fingerprints: FingerprintBundle
seed: SeedRecord | None
dtype: str
devices: tuple[DeviceRecord, ...]
jax_config: tuple[tuple[str, CanonicalScalar], ...]
backend: BackendRef
budget: ComputeBudget
termination: TerminationRecord
timing: TimingRecord
approximation: ApproximationRecord
warnings: tuple[RunWarning, ...]
initial_values: tuple[NamedArray, ...] = ()
sampling_details: tuple[tuple[str, CanonicalValue], ...] = ()
What one execution of a plan actually did (§0.2).

new_artifact_meta

Defined in bayesmith.artifacts.base, line 783.

new_artifact_meta(*, artifact_type: ArtifactKind, fingerprints: FingerprintBundle, producer: ProducerRef, summary: str='', parent_refs: tuple[ArtifactRef, ...]=(), warnings: tuple[RunWarning, ...]=(), schema_version: int=SCHEMA_VERSION, artifact_id: str | None=None, created_at: str | None=None) -> ArtifactMeta
A CURRENT envelope at revision 0, with a freshly minted UUID4.

``artifact_id`` and ``created_at`` are arguments so that a caller restoring an
artifact keeps its identity; left out, they are minted here. They are not
derived from the content: two artifacts with identical fingerprints are
still two artifacts, with separate lineage and separate verdicts.

invalidate_meta

Defined in bayesmith.artifacts.base, line 817.

invalidate_meta(meta: ArtifactMeta, *, before: FingerprintBundle, after: FingerprintBundle, policy: InvalidationPolicy, at: str | None=None) -> ArtifactMeta
The INVALIDATED copy of ``meta`` at ``revision + 1`` (§0.2, §0.3).

Same ``artifact_id``, same fingerprints -- the retired revision records what
it was MADE from, not what replaced it -- with the changed input kinds and
the time written into its lifecycle. ``meta`` itself is untouched, because
the point of a revision is that the earlier one survives.

Refused, loudly, in four cases: ``before`` is not this artifact's own bundle
(so the comparison would be about some other artifact), nothing changed,
the policy says this artifact kind does not depend on what changed, and the
artifact was already invalidated. Each of these is a caller error that
would otherwise produce a plausible-looking revision recording a judgement
nobody made.

Type a concept or API name.