What is a Task?
A task is an event that changes the state of something. That is the entire definition. Everything else is detail.
"Write the email" changes a draft from empty to written. "Deploy the server" changes the system from local to live. "Buy groceries" changes the fridge from empty to full. Each task takes a system in one state and moves it to another. The before-state is the precondition. The after-state is the postcondition. The task is the bridge.
Most people think of tasks as items on a list. That framing is useful for remembering what to do, but it misses the deeper structure: tasks are transitions in a state machine. Understanding them that way changes how you plan, execute, and automate work.
The Anatomy of a Task
Every task, no matter how simple or complex, has the same internal structure:
Precondition
The state the world must be in before the task can begin. "Deploy the server" requires the code to be committed, tests to be passing, and a target environment to exist. If the precondition is not met, the task is blocked — not failed, blocked. Understanding the difference prevents wasted effort.
Input
The information or resources the task consumes. A "write the report" task needs data, context, and a template. A "cook dinner" task needs ingredients and a recipe. Missing inputs are the most common reason tasks stall — not difficulty, not motivation, but missing inputs.
Transformation
The actual work — the thing that changes state. This is what most people think of when they think of a task. It is important, but it is only one of five parts.
Output
The artifact or state change the task produces. A written email, a deployed server, a cooked meal. The output of one task is often the input or precondition of the next task. This is how tasks compose.
Postcondition
The state the world is in after the task completes. This is the definition of "done." Without an explicit postcondition, you do not know when to stop. Tasks without clear postconditions expand indefinitely — this is what scope creep actually is at the atomic level.
Task States
Tasks themselves have states — and understanding these states is the key to both execution and automation.
Blocked
Preconditions are not met. The task cannot start. The correct response is not to force it — it is to identify and resolve the blocker. Forcing a blocked task produces garbage output.
Ready
Preconditions are met, inputs are available. The task can begin. This is the moment of decision: is this the highest-value ready task? If yes, start. If no, leave it ready and work on what matters more.
In Progress
Transformation is happening. The task is consuming time and attention. The risk here is not failure — it is drift. A task that stays in progress too long without producing output is either too large (decompose it) or stuck (identify the sub-blocker).
In Review
Transformation is complete, output exists, but postcondition has not been verified. This is the quality gate. Code review, proofreading, testing, tasting the soup. Skipping review is skipping the postcondition check — you are declaring done without confirming done.
Done
Postcondition is met. The state change has occurred. The task is complete. The output is available as input to downstream tasks.
Failed
The transformation could not produce the required output. This is different from blocked (cannot start) — failed means started and could not finish. The correct response is diagnosis: why did it fail? Missing input? Wrong approach? Impossible postcondition?
Stale
The task was relevant when it was created but the context has changed. The precondition no longer matters, the output is no longer needed, or the world moved on. Stale tasks should be closed, not completed. Completing a stale task is waste.
How to Get Better at Tasks
Define done before you start. The single most effective habit for task execution is writing the postcondition before beginning the work. "The email is sent to the client with the Q2 numbers attached" is a postcondition. "Work on the email" is not. If you cannot define done, you are not ready to start.
Decompose until each task is one sitting. If a task takes more than one focused session (60-90 minutes), it is not a task — it is a project disguised as a task. Break it down until each piece can be started and finished in a single sit-down. Small tasks complete. Large tasks linger.
Identify blockers before they block you. Before starting a task, scan its preconditions. Do you have the inputs? Is the upstream work done? Are you waiting on someone? Discovering a blocker mid-task is more expensive than discovering it during planning. A 10-second precondition check saves hours of wasted starts.
Batch similar tasks. Context switching is the enemy of task throughput. Writing five emails is faster than writing one email, doing something else, and writing another email. Batching preserves the mental context — the vocabulary, the focus, the flow state. Group similar tasks and execute them in a single session.
Close stale tasks ruthlessly. Every stale task on your list is cognitive weight — a tiny background process consuming attention. If a task has been sitting for weeks and the context has changed, close it. You can always recreate it if the need returns. A clean task list with 5 items is more useful than a comprehensive list with 50.
Reflect on failed tasks. Failure is diagnostic. When a task fails, the question is not "how do I try harder?" — it is "what was wrong with the task definition?" Was the postcondition impossible? Was an input missing? Was the decomposition wrong? Failed tasks teach you more about task design than completed tasks ever will.
How LLMs Approach Tasks
Large language models approach tasks differently than humans, and understanding the difference makes you better at both directing AI and doing your own work.
Decomposition is explicit. When an LLM receives a complex task, it decomposes it into subtasks — but unlike a human who might hold the decomposition in their head, the LLM writes it out. This forced explicitness is actually a strength: the decomposition is visible, auditable, and correctable before execution begins. Humans should steal this habit. Write down your subtask decomposition. If it looks wrong on paper, it is wrong in execution.
Precondition checking is tool-based. An LLM checks preconditions by reading files, running commands, and searching for information. It does not guess whether a file exists — it checks. It does not assume the tests pass — it runs them. This discipline (verify before acting) is something humans skip constantly, usually to their detriment.
State tracking is context-dependent. An LLM tracks task state through its context window — a finite memory that can be overwhelmed. When context is lost, the LLM may re-do work, forget constraints, or drift from the original goal. This is analogous to a human who does not write things down: the mind drifts, the details fade, the task mutates. External state tracking (written notes, task boards, checklists) solves this for both humans and AI.
Failure handling is iterative. When an LLM\'s approach fails (a command errors, a test fails, a file is not where it expected), it does not panic or give up — it tries an alternative approach. This is the correct failure response: diagnose, adjust, retry with new information. Humans often respond to failure with emotion (frustration, self-doubt) before responding with logic. The LLM skips the emotion. The logic is the same.
The output is only as good as the task definition. A vague prompt produces a vague response. A precise prompt with clear preconditions, inputs, and postconditions produces a precise result. This is not an AI limitation — it is a task definition truth that applies to all executors, human or machine. The quality of the output is bounded by the quality of the task specification.
From Tasks to Automations
The bridge from tasks to automations is this: any task you can define precisely enough to explain to another person, you can define precisely enough to automate.
Automations are tasks with triggers instead of humans. A human decides to start a task. An automation is triggered by an event — a file is uploaded, a form is submitted, a time is reached, a threshold is crossed. The transformation is the same. The initiator is different.
Task states inform automation design. A well-designed automation handles every state a task can be in: it checks preconditions before executing (if the input file does not exist, do not process it), it handles failure gracefully (retry, notify, or escalate), it detects stale conditions (if the upstream data is older than 24 hours, do not proceed — something is wrong), and it verifies postconditions before declaring success (did the output actually arrive where it was supposed to?).
Automations that trigger when tasks go off the rails are the most valuable kind. A task that fails silently is worse than a task that fails loudly. An automation that monitors for failure states — a deploy that does not complete, a report that does not generate, a backup that does not run — and alerts a human is not doing the task. It is supervising the task. Most production systems need both: automations that do the work AND automations that watch the work.
The automation progression: (1) Do the task manually and document every step. (2) Script the steps. (3) Add triggers so the script runs without you. (4) Add monitoring so you know when it fails. (5) Add recovery so it fixes itself. Each level adds autonomy. Most useful automations live at level 3 or 4. Level 5 is the goal but rarely achieved for complex tasks.
Not every task should be automated. Automate tasks that are: frequent (daily or more), deterministic (same input → same output), low-judgment (no subjective decision required), and high-cost-of-error-is-low (a mistake is annoying, not catastrophic). Tasks that are infrequent, require judgment, or have high stakes should be human-executed with automated assistance (checklists, pre-checks, monitoring) — not fully automated.
The Reflection
Tasks are so fundamental that we rarely examine them. We just do them. But the developers and operators who excel are the ones who think about tasks as a system — not just "what do I need to do?" but "what state is this task in? What are its preconditions? What does done look like? Could this be automated? Should it be?"
The invitation is to look at your current task list — whatever form it takes — and ask these questions of each item. You will find blocked tasks pretending to be ready. You will find tasks without postconditions that have been "in progress" for weeks. You will find stale tasks consuming mental bandwidth. And you will find at least one task that you have done manually a dozen times that is begging to be automated.
That last one is the beginning. Automate it, and the time you save becomes a new task: find the next thing to automate.