bayesmithDocumentation0.10.0 source

bayesmith.artifacts.gates

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

Module contract
Quality gates: several reports in, one status and one verdict out (§0.6).

Two rulings do all the work here.

**§0 ruling 7: status and verdict are different axes.** ``BLOCKED``,
``INVALIDATED`` and ``ERROR`` mean the gate never got to judge and carry no
verdict at all; only ``EVALUATED`` carries ``PASS``, ``FAIL`` or ``ABSTAIN``.
Flattening the two would make "we could not check" indistinguishable from "we
checked and it failed", and those have different remedies.

**The answer may not depend on the order the slots arrived in.** So
:func:``aggregate_gate`` builds a mapping from requirement name to slot,
verifies it against the schema, and then walks the DEFINITION's requirements --
never the caller's list. The bug this shape exists to prevent is the loop that
keeps the last verdict it saw, which is correct exactly when the inputs happen
to arrive in a helpful order and silently wrong otherwise. Findings and report
references come out in definition order for the same reason: a result that
compares unequal to itself under a permutation is not a record.

The priority is §0.6's, in order: a missing prerequisite blocks; a stale input
or a stale report invalidates; an attempted required error, or an optional
error the schema says blocks, is an error; and only then is a verdict computed
-- FAIL if any required applicable report failed, ABSTAIN if any required
report is missing, inapplicable, unverifiable or undecided, and PASS only when
every required applicable report passed.

Layering: ``base``, ``refusal`` and ``reports`` (§0.1).

OperationalStatus

Defined in bayesmith.artifacts.gates, line 73.

class OperationalStatus(StrEnum)
Whether the gate got to judge at all (§0 ruling 7).

Three of the four say it did not, and each names a different thing to fix:
a missing prerequisite is upstream work, an invalidated input is a re-run,
an error is a failure to investigate. Only ``EVALUATED`` carries a verdict.
BLOCKED = 'blocked'
INVALIDATED = 'invalidated'
ERROR = 'error'
EVALUATED = 'evaluated'

AttemptStatus

Defined in bayesmith.artifacts.gates, line 88.

class AttemptStatus(StrEnum)
Whether anybody tried to produce this report.

The distinction the truth table turns on: a required report that was never
attempted leaves the gate undecided (ABSTAIN), while one that was attempted
and errored is an ERROR. Without this field the two look identical -- no
report either way -- and the milder answer would win.
NOT_ATTEMPTED = 'not_attempted'
ATTEMPTED = 'attempted'

ReportRequirement

Defined in bayesmith.artifacts.gates, line 103.

class ReportRequirement
name: str
required: bool = True
optional_error_blocks: bool = False
One check a gate asks for, and how much it matters.

``optional_error_blocks`` answers a question only an OPTIONAL requirement
has: a required check that errored always blocks. Declaring it on a
required requirement is refused rather than ignored -- a field that is
silently ignored somewhere is a field somebody will set and rely on.

ReportSlot

Defined in bayesmith.artifacts.gates, line 130.

class ReportSlot
requirement: ReportRequirement
report: EvaluationReport | None = None
attempt_status: AttemptStatus = AttemptStatus.NOT_ATTEMPTED
invalidated: bool = False
error: ErrorRecord | None = None
What became of one requirement on one subject.

Exactly one outcome at a time: not attempted, a report, or an error. §0.6
refuses a slot holding a report AND an error at the boundary, because an
aggregator reading whichever it checks first would produce a defensible
answer from an impossible input.

GateDefinition

Defined in bayesmith.artifacts.gates, line 179.

class GateDefinition
name: str
version: int
requirements: tuple[ReportRequirement, ...]
blocked_actions: tuple[str, ...] = ()
remedies: tuple[Remedy, ...] = ()
The schema of a gate: what it asks for, and what it governs.

``blocked_actions`` and ``remedies`` belong to the DEFINITION, not to any
one run of it, which is why :func:``aggregate_gate`` copies them into the
result unedited.

GateDefinition.identity

identity(self) -> str
``name@version``: the spelling a task's ``quality_gate`` carries.

One spelling, because a task asks for a gate by string and a result
must be checkable against the gate that was asked for.

GateDefinition.requirement

requirement(self, name: str) -> ReportRequirement
The declared requirement called ``name``, or a refusal naming it.

GateResult

Defined in bayesmith.artifacts.gates, line 238.

class GateResult
meta: ArtifactMeta
definition: GateDefinition
status: OperationalStatus
verdict: Conclusion | None = None
report_refs: tuple[ArtifactRef, ...] = ()
findings: tuple[Finding, ...] = ()
blocked_actions: tuple[str, ...] = ()
remedies: tuple[Remedy, ...] = ()
One gate's answer: a status always, a verdict only when it judged.

aggregate_gate

Defined in bayesmith.artifacts.gates, line 292.

aggregate_gate(definition: GateDefinition, *, meta: ArtifactMeta, prerequisites_ready: bool, inputs_current: bool, slots: tuple[ReportSlot, ...]) -> GateResult
§0.6's priority, applied to a schema-checked mapping of slots.

The slots are indexed by requirement name and then read in the order the
DEFINITION declares, so the caller's ordering reaches nothing: not the
status, not the verdict, not the findings, not the report references.

Type a concept or API name.