> ## Documentation Index
> Fetch the complete documentation index at: https://docs.withmithras.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Process Lifecycle

> Public statuses, idempotency rules, timestamp semantics, and partial progress behavior.

# Process Lifecycle

Phonefarm exposes a normalized process model so callers do not need to reason about every internal queue state.

## Public Status Enum

These are the public statuses returned by `GET /processes/{process_id}`:

| Status            | Meaning                                                   |
| ----------------- | --------------------------------------------------------- |
| `queued`          | The request is accepted and not yet terminal.             |
| `executing`       | Work is currently executing.                              |
| `retrying`        | Work is waiting for a retry attempt.                      |
| `completed`       | All work completed successfully.                          |
| `failed_terminal` | Execution ended in a terminal failure or partial failure. |
| `cancelled`       | The process was cancelled.                                |

## Internal to Public Mapping

Internally, Phonefarm uses richer request and queue states. The current mapping is:

| Internal status | Public status     |
| --------------- | ----------------- |
| `QUEUED`        | `queued`          |
| `PLANNED`       | `queued`          |
| `CLAIMED`       | `queued`          |
| `EXECUTING`     | `executing`       |
| `RETRYABLE`     | `retrying`        |
| `DONE`          | `completed`       |
| `PARTIAL`       | `failed_terminal` |
| `DEAD_LETTER`   | `failed_terminal` |
| `CANCELLED`     | `cancelled`       |

## Idempotency

Phonefarm uses different idempotency keys depending on endpoint family.

### Process APIs

* `POST /capability-requests/enqueue`
* `POST /maintenance/requests`

Idempotency key:

```text theme={null}
(platform, process_type, requested_by.system, request_id)
```

Duplicate requests return the existing process instead of creating a new one.

### Legacy Queue APIs

* `POST /ingest`

Idempotency key:

```text theme={null}
(account_id, content_id)
```

## Partial Progress

A public process can represent fanout or multi-step work. That means binary success and failure is not always enough.

When a process ends in partial completion:

* public status becomes `failed_terminal`
* `partial_progress` remains available for consumers
* `linked_ids` shows queue-item relationships

If your system needs exact operator-facing messaging, use `status`, `error`, `partial_progress`, and `linked_ids` together.

## Timestamp Semantics

The `timestamps` object is milestone-derived.

| Field                 | Meaning                                   |
| --------------------- | ----------------------------------------- |
| `created_at`          | The row creation time.                    |
| `accepted_at`         | The accepted milestone time.              |
| `queued_at`           | The planned milestone time.               |
| `executing_at`        | The queue-materialization milestone time. |
| `retrying_at`         | Retry timestamp when present.             |
| `cancel_requested_at` | Time cancel was requested.                |
| `finished_at`         | Derived from terminal row update time.    |

Important: `executing_at` is not guaranteed to be the exact time of first device interaction.

## Terminal Behavior

Terminal outcomes are:

* `completed`
* `failed_terminal`
* `cancelled`

Process-aware cancellation may first enter a non-terminal `cancel_requested` path internally before settling into a final public status.

## Read Next

* [Get Process](../api/processes-get)
* [Cancel Process](../api/processes-cancel)
* [Errors and Idempotency](../reference/errors-and-idempotency)
