Skip to content
Davide Scuteri Moretti
Senior Data Architect
02
Essay

The Task as the Atomic Unit of Data Computation

*The task is often treated as an operational convenience: a box in an orchestrator, a scheduled job, a notebook, or a container invocation. This essay argues that the task should instead be understood as the atomic unit of accountable data computation. A task is not merely a step that runs; it is a typed transformation with declared inputs, outputs, preconditions, postconditions, quality obligations, provenance effects, and failure semantics. The essay formalises tasks as state transitions and morphisms over data contracts, distinguishes logical tasks from physical executions, examines composability in directed acyclic graphs, and relates task design to ideas from programming language semantics and the philosophy of action. The central claim is that a platform becomes intelligible when its smallest executable unit is also its smallest explainable unit. Granularity is therefore not only a performance concern. It determines whether lineage, replay, ownership, and change impact can be reasoned about without reconstructing intent from code after the fact.*

6 minute read·July 2026·Davide Scuteri Moretti
computational tasksDAGsatomicitypure functionsprovenanceorchestrationcomposabilityoperational semantics
Themes
  • Semantics

Abstract

The task is often treated as an operational convenience: a box in an orchestrator, a scheduled job, a notebook, or a container invocation. This essay argues that the task should instead be understood as the atomic unit of accountable data computation. A task is not merely a step that runs; it is a typed transformation with declared inputs, outputs, preconditions, postconditions, quality obligations, provenance effects, and failure semantics. The essay formalises tasks as state transitions and morphisms over data contracts, distinguishes logical tasks from physical executions, examines composability in directed acyclic graphs, and relates task design to ideas from programming language semantics and the philosophy of action. The central claim is that a platform becomes intelligible when its smallest executable unit is also its smallest explainable unit. Granularity is therefore not only a performance concern. It determines whether lineage, replay, ownership, and change impact can be reasoned about without reconstructing intent from code after the fact.

1. From job to accountable action

A scheduler sees a task as something with a start time, end time, status, and dependency set. This operational view is necessary but ontologically thin. Two tasks may both finish successfully while one produces a semantically valid object and the other merely writes bytes. The distinction lies in the relation between execution and declared purpose.

Let a logical task be represented as

where is the input contract, the execution context, the preconditions, the transformation, the output contract, the quality assertions, the metadata effects, and the recovery semantics. An execution instance of then produces

where is an execution status richer than success or failure. It may include partial success, quarantine, degraded output, skipped execution, compensating action, or policy denial.

This model separates the task’s identity from any single runtime. A Python function, SQL statement, distributed job, or API invocation can implement . The platform’s architectural knowledge resides in the contract around the implementation.

2. Preconditions and postconditions

Programming logic provides a useful vocabulary. A Hoare triple

states that if precondition holds, execution of establishes postcondition . Data tasks require an enriched version because execution may produce external effects, partial outputs, and metadata.

For a task , correctness can be expressed as

where asserts that provenance, metrics, version identifiers, and audit evidence have been emitted. A task that produces correct values without provenance may be computationally correct and platform-incomplete.

Preconditions should include more than file existence or table accessibility. They may require a contract version, watermark, reference-data snapshot, key uniqueness threshold, or policy decision. Postconditions may

include referential integrity, row-count bounds, monotonicity, conservation equations, or conformance to a Data Object.

Suppose a task maps source observations to a canonical object. A conservation check might assert

unless documented filtering semantics justify a difference. Such equations convert vague expectations into evidence. The task becomes a small theorem with an executable proof obligation.

3. Atomicity is relative

Calling the task “atomic” does not imply that it is indivisible at every level. A database transaction, distributed Spark stage, and orchestration node have different atomicity boundaries. The relevant question is: atomic with respect to which reasoning?

For lineage, a task should be small enough that one can state why each output attribute exists and from which inputs it derives. For recovery, it should be isolated enough to replay without repeating unrelated work. For ownership, it should correspond to a coherent responsibility. For performance, it should not be fragmented so finely that orchestration overhead dominates computation.

We can formulate a granularity objective. Let be a proposed decomposition of a process into tasks. Define

where the terms estimate reasoning complexity, replay cost, operational overhead, and change propagation. Overly coarse tasks increase the first, second, and fourth terms; overly fine tasks increase operational overhead and coordination cost. The optimal decomposition is domain- and platform-dependent.

Atomicity is therefore a design judgement, not a property conferred by drawing a rectangle in a DAG.

4. Tasks as morphisms between contracts

A clean way to understand composition is to treat Data Contracts as objects and tasks as morphisms. If task maps contract to , and maps to , then the composition

is valid only if the postconditions of satisfy the preconditions of . This is more demanding than file compatibility. The output may be parseable while semantically insufficient.

Associativity of composition allows processes to be reasoned about at several levels:

Operational execution may differ because of materialisation, caching, or parallelism, but the logical composition should preserve meaning. Identity tasks correspond to no-op transformations that preserve a contract while perhaps relocating or re-encoding data.

Category theory need not become implementation ceremony. Its value is conceptual: it directs attention from storage locations to lawful transformations. A platform is then not a pile of datasets but a network of typed computations.

5. Dependency graphs and causal discipline

Tasks are commonly arranged in a directed acyclic graph , where vertices are tasks and edges express precedence or data dependency. Acyclicity guarantees a topological order, but not semantic correctness. An edge can mean several things: consumes output, requires successful validation, waits for a watermark, shares a reference snapshot, or depends on a policy decision.

Edges should therefore be typed:

where is a set of dependency labels. This permits stronger analysis. A data dependency may trigger replay when upstream values change; a control dependency may not. A reference-data dependency may require restatement when the dictionary version changes even if source records do not.

The graph also encodes a causal story about production. It should not be confused with causality in the scientific sense. The fact that task precedes does not imply that the represented event causes another represented event. The platform graph describes how claims are manufactured, not necessarily how the world itself unfolds.

This distinction protects data culture from a subtle error: operational provenance is not causal explanation. A dashboard value may depend computationally on a transformation without that transformation explaining the phenomenon measured.

6. Purity, effects, and controlled impurity

Pure functions are attractive because they simplify reasoning:

with no hidden state and no externally visible effect. Real data tasks read clocks, consult reference data, write stores, emit messages, call services, and allocate identifiers. They are rarely pure in the strict sense.

The correct response is not to pretend purity but to isolate effects. We can decompose a task into a pure core and an effectful shell:

where materialises inputs and context, performs deterministic transformation, and commits outputs and evidence. Hidden dependencies should be promoted into explicit context : code version, configuration, time zone, reference snapshot, policy version, and random seed where applicable.

This pattern improves testability and reproducibility. It also clarifies responsibility. If a task fails because an external service is unavailable, the transformation may remain valid while the effect boundary fails. Recovery can then retry the shell without recomputing the core.

Controlled impurity is a more honest and useful goal than rhetorical purity.

7. Failure semantics and the intelligibility of error

A binary state space is insufficient for data computation. Consider records that violate a soft quality rule, arrive after a watermark, fail identity reconciliation, or are prohibited for a particular use. Treating all such conditions as technical failure obscures their nature.

Let task outcome be

Each state should have defined downstream semantics. A degraded output may be publishable with a warning for exploration but inadmissible for a regulated metric. A quarantined subset may permit the valid partition to continue. A blocked task may indicate policy, not malfunction.

Recovery semantics should specify replay scope, idempotency key, checkpoint, compensation, and whether downstream products require invalidation. Without this, orchestration records that a retry occurred but cannot explain what was logically restored.

The task is the right level at which error acquires meaning. A platform that records only stack traces knows that software failed; a platform with task semantics knows which promise was broken.

Continue reading