# Complete Guide to Task Statuses in Paperclip: All 21 States Explained

> Explore all 21 Paperclip task statuses, from creation to archival. Understand the full task lifecycle and ensure smooth workflow management with this comprehensive guide.

- Repository: [Paperclip/paperclip](https://github.com/paperclipai/paperclip)
- Tags: deep-dive
- Published: 2026-08-14

---

**Paperclip defines 21 distinct task statuses as string-literal unions in TypeScript, covering the full lifecycle from creation through completion, error handling, and archival.**

Task statuses in Paperclip represent the execution state of work items (also called *issues* in the codebase). These statuses appear throughout the backend schema, shared type definitions, and UI components to track progress, blockers, and terminal states. According to the `paperclipai/paperclip` source code, the `Issue` type in [`packages/shared/src/types/issue.ts`](https://github.com/paperclipai/paperclip/blob/main/packages/shared/src/types/issue.ts) serves as the canonical definition for all valid status values.

## Core Task Status Values in Paperclip

The complete set of Paperclip task statuses falls into five functional categories:

### Initiation and Planning States

These statuses apply before active work begins:

- **`todo`** — The task has been created but work has not yet started.
- **`planned`** — The task is scheduled for future execution but not yet started.
- **`ready`** — All prerequisites are satisfied; the task can be picked up.
- **`pending`** — The task is queued awaiting resources or a prerequisite condition.

### Active Execution States

These statuses indicate work in progress:

- **`in_progress`** — Work on the task is currently underway.
- **`active`** — The task is live and can be acted upon; often used for recurring or long-running tasks.

### Suspension and Blocker States

These statuses indicate work cannot proceed:

- **`blocked`** — The task cannot proceed until an external dependency is resolved.
- **`paused`** — Execution is temporarily halted by a user or system action.
- **`warning`** — The task is running but has a non-critical issue requiring attention.

### Review and Approval States

These statuses apply to tasks requiring human validation:

- **`in_review`** — The task awaits review or approval before completion.
- **`revision_requested`** — Review has requested changes; must be updated before proceeding.
- **`approved`** — Review has approved the task and it can move forward.

### Terminal States

These statuses represent task completion, failure, or discontinuation:

- **`done`** — The task has been successfully completed.
- **`achieved`** — The goal associated with the task has been met (success state).
- **`cancelled`** — The task was intentionally aborted before completion.
- **`failed`** — The task ended with an error preventing successful completion.
- **`hard_stop`** — The task triggered a budget or runtime limit and was forcibly halted.
- **`stopped`** — The task was stopped by the system (distinct from user-initiated cancel).
- **`cleanup_failed`** — Post-run cleanup failed after main task logic finished.
- **`archived`** — The task is retained for historical reference but no longer active.
- **`disabled`** — The task is intentionally disabled and cannot be executed.

## TypeScript Implementation of Task Statuses

Paperclip enforces status safety through string-literal unions. In [`packages/shared/src/types/issue.ts`](https://github.com/paperclipai/paperclip/blob/main/packages/shared/src/types/issue.ts), the `Issue` type defines the `status` field using these exact literals:

```typescript
// packages/shared/src/types/issue.ts
// The Issue type (representing tasks) uses this status union
type IssueStatus = 
  | "todo"
  | "in_progress"
  | "blocked"
  | "done"
  | "cancelled"
  | "failed"
  | "paused"
  | "active"
  | "planned"
  | "achieved"
  | "in_review"
  | "revision_requested"
  | "approved"
  | "ready"
  | "warning"
  | "hard_stop"
  | "stopped"
  | "cleanup_failed"
  | "pending"
  | "archived"
  | "disabled";

```

This union type provides **compile-time safety** across the API, server, and UI layers. Any component consuming `Issue["status"]` will error if passed an invalid string.

## Practical Usage Examples

### Creating a Validated Task with Zod

The following schema validates task creation including the status field:

```typescript
import { z } from "zod";

const newTaskSchema = z.object({
  title: z.string(),
  description: z.string().optional(),
  status: z.enum([
    "todo",
    "in_progress",
    "blocked",
    "done",
    "cancelled",
    "failed",
    "paused",
    "active",
    "planned",
    "achieved",
    "in_review",
    "revision_requested",
    "approved",
    "ready",
    "warning",
    "hard_stop",
    "stopped",
    "cleanup_failed",
    "pending",
    "archived",
    "disabled",
  ]),
});

// Valid usage
const task = newTaskSchema.parse({
  title: "Create onboarding flow",
  status: "todo",
});

```

### Rendering Status Badges in React Components

UI components in [`ui/storybook/fixtures/paperclipData.ts`](https://github.com/paperclipai/paperclip/blob/main/ui/storybook/fixtures/paperclipData.ts) demonstrate mapping statuses to visual states:

```tsx
import { Badge } from "@/components/ui/badge";

type Issue = {
  status: "todo" | "in_progress" | "blocked" | "done" | // ... full union
};

type StatusBadgeProps = { status: Issue["status"] };

export const StatusBadge = ({ status }: StatusBadgeProps) => {
  const colorMap: Record<Issue["status"], string> = {
    todo: "gray",
    in_progress: "blue",
    blocked: "orange",
    done: "green",
    cancelled: "red",
    failed: "red",
    paused: "yellow",
    active: "blue",
    planned: "purple",
    achieved: "green",
    in_review: "indigo",
    revision_requested: "amber",
    approved: "emerald",
    ready: "cyan",
    warning: "yellow",
    hard_stop: "rose",
    stopped: "red",
    cleanup_failed: "orange",
    pending: "slate",
    archived: "zinc",
    disabled: "neutral",
  };

  return <Badge color={colorMap[status]}>{status}</Badge>;
};

```

## Runtime Status Distinction

Paperclip separates **task status** (the `Issue` lifecycle) from **runtime execution status**. The [`packages/shared/src/types/workspace-runtime.ts`](https://github.com/paperclipai/paperclip/blob/main/packages/shared/src/types/workspace-runtime.ts) file defines distinct states for actual task execution infrastructure:

```typescript
// packages/shared/src/types/workspace-runtime.ts
// Runtime states track infrastructure, not business logic
type RuntimeStatus = 
  | "provisioning"
  | "running"
  | "stopped";

```

This separation allows a task to be `in_progress` (business state) while its runtime is `provisioning` (infrastructure state).

## Key Source Files for Task Statuses

| File Path | Purpose |
|-----------|---------|
| [`packages/shared/src/types/issue.ts`](https://github.com/paperclipai/paperclip/blob/main/packages/shared/src/types/issue.ts) | Canonical TypeScript union type for all 21 task statuses |
| [`ui/storybook/fixtures/paperclipData.ts`](https://github.com/paperclipai/paperclip/blob/main/ui/storybook/fixtures/paperclipData.ts) | UI fixtures demonstrating status usage in components |
| [`packages/shared/src/types/workspace-runtime.ts`](https://github.com/paperclipai/paperclip/blob/main/packages/shared/src/types/workspace-runtime.ts) | Runtime execution states separate from task lifecycle |

## Summary

- **Paperclip defines 21 task statuses** as a TypeScript string-literal union in [`packages/shared/src/types/issue.ts`](https://github.com/paperclipai/paperclip/blob/main/packages/shared/src/types/issue.ts).
- **Statuses cluster into five phases**: initiation, active execution, suspension/blockers, review/approval, and terminal states.
- **Type safety is enforced at compile time** through the `Issue["status"]` union type, preventing invalid status values.
- **Runtime states are separate** from task statuses, tracked in [`workspace-runtime.ts`](https://github.com/paperclipai/paperclip/blob/main/workspace-runtime.ts) for infrastructure concerns.
- **UI fixtures in [`paperclipData.ts`](https://github.com/paperclipai/paperclip/blob/main/paperclipData.ts)** demonstrate practical status usage for component development and testing.

## Frequently Asked Questions

### What is the difference between `done` and `achieved` in Paperclip?

Both mark successful completion, but `done` indicates the task itself is finished while `achieved` emphasizes that the underlying goal has been met. Use `achieved` for milestone-oriented workflows where goal attainment matters distinctly from task execution.

### How does Paperclip handle invalid task statuses?

The TypeScript compiler rejects invalid status strings through the `Issue["status"]` union type. At runtime, Zod schemas (or similar validators) in the API layer enforce the same constraint, returning validation errors for unrecognized status values.

### What distinguishes `cancelled` from `stopped` in Paperclip?

`cancelled` represents a **user-initiated** abort decision, while `stopped` indicates **system-initiated** termination. This distinction matters for audit trails and retry logic—cancelled tasks typically require explicit user action to recreate, whereas stopped tasks may auto-retry depending on configuration.

### Can custom task statuses be added to Paperclip?

No. The `paperclipai/paperclip` source code uses a fixed union type without extension points. Adding statuses would require modifying [`packages/shared/src/types/issue.ts`](https://github.com/paperclipai/paperclip/blob/main/packages/shared/src/types/issue.ts) and updating all dependent schemas, UI mappings, and database constraints throughout the monorepo.