Lifecycle
The statuses an engagement moves through, and which of them are terminal.
An engagement has one status at a time, drawn from seven values: pending,
queued, running, completed, failed, cancelled, blocked. This page
lists the transitions that occur in the product, which is a smaller set than the
seven names suggest.
The transitions¶
| From | To | What causes it |
|---|---|---|
| — | pending |
the engagement is created, by the wizard, the API, or a schedule firing |
pending, blocked |
queued |
you submit it and every gated identifier clears the launch gate |
pending, blocked |
blocked |
you submit it and some gated identifier does not clear the launch gate; nothing is queued |
queued |
running |
the scheduler takes the job and starts the container |
running |
completed |
the container exits 0 and returns a results payload |
running |
failed |
the container exits non-zero, returns no payload, or the scheduler itself errors |
Submitting is the only operator action that changes a status, and it is accepted
only from pending and blocked. A request to submit an engagement in any other
status is refused with a 400 naming the current one. The scheduled path applies
the same two transitions to the engagement it creates from the schedule template.
Terminal and not¶
completed and failed are terminal. Nothing in the product moves an engagement
out of either, and submit refuses both. A run you want repeated is a new
engagement.
pending is where a created engagement waits. Creating an engagement and starting
it are two separate actions: Create engagement saves it at pending and
Start pentest on its detail page submits it. An engagement left at pending
stays there indefinitely and consumes nothing.
blocked is not terminal. It means the launch gate refused the run because an
identifier's ownership proof did not hold, and the response names each identifier
and the reason. Clearing the gate is not the same check for every asset: a
verified covering asset has its proof re-run over the network at each launch,
while an attested one is a human claim with nothing to re-run, so only its
expiry date is checked. Publish the missing record, or renew the attestation,
and submit the same engagement again with
POST /api/engagements/{id}/submit, or with an API key through
POST /api/v1/engagements/{id}/submit (Engagements).
The console shows Start pentest only on a pending engagement, so it has no
button for this. See
Ownership verification.
queued and running are the in-flight statuses, and they are the two the plan
cap counts. Neither can be interrupted: there is no cancel, pause or abort in the
console or the API.
cancelled is in the status vocabulary and the console knows how to display
it, but no code path assigns it. No engagement reaches that status.
What each status allows¶
- Report generation requires
completed. A request for any other status is refused with a 400. - Locker export requires a seal, which is written only when the container exits zero with a results payload — a weaker condition than finishing the work. An unsealed engagement is refused with a 409. See Sealing.
- The live progress stream is opened by the console only while the status is
queuedorrunning; once a run ends the console stops showing it. The trace is retained for 24 hours and stays fetchable fromGET /api/engagements/{id}/progress— see Running an engagement. - Findings are written when the run is marked
completed, in the same step. Afailedengagement has no findings rows.
Where the status is written¶
pending is set at creation. queued and blocked are set by the submit
endpoint, or by the campaign ticker on the scheduled path. running, completed
and failed are set by the scheduler as it processes the job — running before
the container starts, and one of the other two once it has exited.
A status write that fails is logged and swallowed rather than retried, so a
database fault during a run leaves the engagement on its previous status while the
run itself continues. An engagement stuck at queued or running long after its
trace ended is the shape that problem takes.
Last updated 2026-09-24