Mission lifecycle
A mission document has two overlapping notions of “state” in ARGUS:
mission.status— a named phase set by the commander in the create/edit form:planning | ready | active | completed | aborted.- Timestamp-derived status — used by the operations list to
show a coloured chip without requiring the commander to bump the status field:
planned(startOn in the future),active(startOn ≤ now, no finishedOn),finished(finishedOn ≤ now).
They rarely diverge, but the list uses the timestamp-derived version so unfinished,
unpromoted ops don’t appear “active” just because someone set status: 'active' while
still planning.
For documentation and UI clarity, think of a mission as moving through five phases:
planning → ready → active → completed ↘ abortedPlus archived as a separate, aspirational soft-delete state (see below).
planning
Default on create. The startOn date may be today or any later day. The mission is
fully editable via /operations/{id}/edit. No side-services are dispatched. Members of
the organisation are notified that the operation was created (operation_created
notification), but nothing is “live”.
ready
A human promotion used when briefings are done and the team is at stations. No code
paths currently react differently to ready vs planning — the flag is operator
reference and future workflow gating.
active
The op is live. Participants with operations.join can click LAUNCH LIVE OPS on the
detail page to route into /ops/{id}/live — the live console. Once at least one
participant is in the console:
- A TACLINK room is provisioned for the op. All realtime audio, video, joystick inputs, and data-channel traffic (flags, telemetry, alerts) flow through it.
- DJI docks assigned to the op start auto-streaming to the console’s WHIP ingress. See DJI auto-stream.
- If AI detection is enabled per stream, a YOLO11 / detection worker is dispatched onto each stream tile.
- CAS evaluates proximity between all tracked aircraft at the interval set in the
mission’s
casConfig. - Workflows subscribed to this operation’s events fire on their triggers.
Transition back out of active is controlled by the commander (via the edit form’s
Status dropdown) or by admins.
completed
Terminal success state. Promoted by the commander when objectives are met. When the
status flips to completed:
- The live console’s LAUNCH LIVE OPS button still routes, but late joiners enter a read-only room.
- The AI after-action report becomes useful to generate
(mission report). Before
completedyou can still generate one — it simply has less data. - Recordings flagged for privacy blur begin post-processing.
- Flight logs, comms, flags, and tasks remain queryable at
missions/{id}/*.
aborted
Terminal failure state. Use for operations that ended without meeting objectives (e.g.
stood down due to weather, mission cancelled by higher HQ, safety abort). No side-effect
cleanup beyond what completed does — the distinction is operational, for the
after-action record.
Archived / soft-delete — aspirational
An archived state with a 30-day restore window appears in roadmap discussions but is
not implemented today. Deletion from the row menu is a hard
deleteDoc(missions/{id}) — document and subcollections go immediately, with no
recovery. Treat any archive / restore docs as aspirational.
Who can change state
- Commander (or any user with
operations.editand document ownership) — can changemission.statusby picking a new value in the edit form and saving. There is no dedicated “Start” / “Stop” button; it’s all through the Status dropdown. - Org admins — same editability, scoped by
operationOwnerGuard. - Workflow engine — workflows can patch
mission.statuswhen configured to. This is how auto-complete-on-empty or auto-abort-on-HMS-critical patterns are built.
What doesn’t change state automatically
Reaching startOn or finishedOn does not auto-promote mission.status. The
commander (or a workflow) must do it. The list view’s timestamp chip will show the new
phase at that moment, but the stored status field is unchanged.
Timeline and audit
Every time mission.status changes, the update is reflected in mission.updatedOn on
the document. There is no dedicated status-change log in a subcollection — Firestore’s
document history is the audit trail.