Plans and results¶
Use FlowPlan before execution and RunResult after a normally completed run. See
Plan, result, and events for their roles and
portable projection boundary.
FlowPlan¶
FlowPlan
dataclass
¶
A deterministic, inspectable description of selected flow work.
FlowPlan.partition_groups lists the selected immutable PartitionGroup
declarations in deterministic plan order. Planning validates group membership and
linear dependencies before execution and does not invoke assets or adapters. The
group limit governs active selected keys; global concurrency and resource policies
continue to govern invocations separately. See partition groups.
RunResult¶
RunResult
dataclass
¶
circuit_skipped_partition_keys(task_name)
¶
Return original keys skipped by an open circuit in attempt order.
Dependency skips and cancellations are excluded. Keys retain their live object identity. Lookup errors match failed_partition_keys.
failed_partition_keys(task_name)
¶
Return original keys of terminal failures in attempt order.
Recovered retries, skips and cancellations are excluded. Keys are live, application-owned objects; portable records cannot reconstruct them. Raises TypeError for non-string names, KeyError for missing tasks and ValueError for unpartitioned tasks.
resource_statistics(name)
¶
Return the live statistics snapshot for an exact resource name.
Manually constructed and historical results have no inferred statistics. Raises TypeError for non-string names and KeyError when no snapshot exists.
RunResult.resources contains immutable ResourceStatistics snapshots for the
named resources selected by this plan, in plan order. Use
result.resource_statistics(name) for exact lookup. A non-string name raises
TypeError; an unknown or empty name raises KeyError. Historical or manually
constructed results without live summaries do not invent statistics.
invocations counts actual starts of an asset body-plus-commit operation.
succeeded and failed count its completed outcome, and invocation_duration
adds monotonic elapsed time through commit. retries counts a subsequent body
invocation only when it actually starts. Preparation failures, materialization
reuse, skips, and retry decisions that never start another body do not add an
invocation or retry. Selected resources with no body starts still appear with
zero counters. Counters belong to one run and are not process-wide totals.
wait_count and wait_duration describe observed resource-admission episodes.
An episode starts when otherwise eligible body work is checked and denied by
resource concurrency, rolling rate limit, retry delay, or resource cooldown. It
ends at body start or terminal skip; repeated checks during one episode count
once. Dependency and preparation waits, and global-only queue time before
resource admission is examined, are not measured. Once an episode starts, its
duration may include later scheduler or global delay. Durations are summed across
operations, may overlap, and do not measure exclusive time for one cause or total
flow wall-clock time.
These summaries exist only on the live RunResult. They do not change record
versions 1–4, event projections, CLI or SQLite schemas. A historical record cannot
reconstruct statistics that were not recorded. See the
resource statistics example.
InvocationResult¶
InvocationResult
dataclass
¶
One numbered body-plus-commit operation within a logical attempt.
AttemptResult.invocations records body/commit operations only when retry behavior
is enabled for the resource. The logical partition attempt remains one result with
one terminal status. RunResult.to_record() defaults to record schema v1 for Python
compatibility; pass schema_version=2 to include invocation history, 3 to include
resource circuit skip reasons, or 4 to include successful materialization
provenance. Circuit skips retain the originating failed attempt in blocked_by.
Portable references intentionally retain only the task name and whether a partition
key was present; they do not serialize the raw key, so different partitions of one
task may not be distinguishable in a portable record.
Record v4 adds resolution and materialization_id to each attempt. A successful
ordinary execution reports executed with a null ID; a successful committed
execution reports executed with its committed ID; a reuse reports materialized
with its ID. Failed, skipped, and cancelled attempts report null for both fields.
Hand-built successful results may leave both unknown. Versions 1–3 keep their
existing shape, and the zero-argument projection remains v1. Materialization IDs
are opaque, adapter-defined diagnostic strings. They are not interpreted as keys,
automatically redacted, or used to load artifacts during inspection.
For a live RunResult, failed_partition_keys(task_name) returns the original keys
for terminal failed attempts, and circuit_skipped_partition_keys(task_name) returns
the original keys for attempts skipped because a resource circuit opened. Both return
tuples in attempt order. They include falsey keys such as 0, "", and False, and
they do not treat a failed retry invocation as a failed logical attempt if that
attempt later succeeded. A skipped attempt is selected only when its terminal reason
is resource_circuit_open.
Each method raises TypeError when task_name is not a string, KeyError when the
task is absent, and ValueError when the task exists but is not partitioned. A
partitioned task with no matching outcomes returns (). The tuple is immutable, but
its keys are the original application objects; mutable keys remain owned by the
application. These helpers inspect only the live result. Portable records omit raw
keys, so a record loaded from storage cannot reconstruct or provide these queries.
To run selected outcomes again, pass the returned keys explicitly in a new run's
partition_keys configuration. kazeflow does not resume a prior run automatically.
See the partition outcome example.