Skip to content

Anatomy of a flight

A flight is one piece of requested work. This page follows a flight from the moment it opens to the moment it ends. Along the way it covers where the organisation’s rules are checked, and what each status means.

When a flight opens, Good Grief determines its rules once, by combining three layers:

the rules for one flight = root + work kind + narrowings

  • Root is the organisation’s base rules. It alone decides which repositories and environments flights may use.
  • The work kind describes one kind of work, such as an investigation, a review or a change. It decides how that work is done and where it lands.
  • Narrowings are additional approvals a repository requires for itself.

The combined result is the flight’s envelope. The envelope describes what each layer contributes, field by field.

Created → Ready → Leased → Worked → Evaluated → Ended
Stage What happens
Created The flight has been opened and its rules determined.
Ready Everything the flight needs before it can start is in place. It is waiting for a machine.
Leased A runner has claimed the flight, and no other machine can take it.
Worked The agent has run.
Evaluated Good Grief has checked the agent’s work against the rules, including which files changed and what requires approval.
Ended The flight has its final outcome.

These are stages, not statuses. A flight can remain in a stage for some time, waiting for a machine or a person, without anything being wrong.

Not every flight passes through all six stages:

  • Rejected when opened. The request to open the flight fails, and no flight is created. This happens when a request names an environment that does not exist or a repository that was never registered, or when the rules contradict each other. gg states which.
  • Halted. Good Grief found a rule it cannot evaluate as yes or no, so it stops and reports the rule rather than guessing. The flight is still open: once the rule is fixed, it can continue.
  • Sent back. The work is attempted again, because a reviewer rejected it or it ran out of time. Each retry is a new attempt. When retries happen automatically after the time runs out, the envelope’s attempt limit decides when to stop and wait for a person.

A flight can stop because no machine is free, because a person has not answered yet, because time ran out, or because a rule could not be checked. None of these ends the flight. Until something ends it, the flight is open, which is what allows it to be picked up again later.

A flight ends in exactly one of four ways:

Ending Meaning
landed The work was accepted somewhere.
grounded A person stopped it.
withdrawn The question stopped mattering.
failed The work finished, but nowhere accepted it.

Two other words can appear, and neither is an ending:

  • open: nothing has ended the flight yet, and something still can.
  • unknown: Good Grief cannot account for the flight’s state. Run gg bundle and send the result to the Good Grief team.

What a runner reports, and what it means for the flight

Section titled “What a runner reports, and what it means for the flight”

A runner never decides how a flight ended. It reports only what happened to its own turn at the work, and Good Grief decides what that means for the flight. This keeps a machine reporting on its own work from being the one that declares the work accepted.

Runner reports Meaning The flight Offered to another machine?
completed The runner finished, and the work was accepted somewhere. landed No. It is done.
failed The runner finished, and nowhere accepted the work. failed No. It is done.
outstanding The runner has stopped for now. Nothing was accepted, and a person needs to answer something. stays open No. It is waiting on a person.
abandoned The runner gave up, but the work remains available. stays open Yes.
expired Reported by Good Grief, not the runner: the machine stopped checking in while it held the flight. stays open Yes.

Only two of these end the flight. The other three leave it open, and one question separates them: should another machine pick it up?

A runner cannot report grounded or withdrawn. Those endings belong to people, and only people record them.

Consider an agent that stops to ask a question. Without outstanding, the runner would have had two options, and neither would be accurate:

  • completed would record the work as accepted, which it was not.
  • abandoned would return the flight to the queue. The next machine would run the same agent into the same question and ask it again.

outstanding states what actually happened: the work is waiting on a person, so it should not go to another machine.

completed means different things at two levels:

  • When the agent’s run ends completed, the agent stopped of its own accord.
  • When the runner reports completed, the work was accepted somewhere.

An agent’s run can therefore finish while the flight is still waiting on a person:

the agent's run ended blocked
→ the runner reports outstanding
→ the flight is open

The envelope is not checked all at once at the end. Each field is checked at a particular stage, so when a flight stops or is rejected, the stage points to the field responsible.

Field Checked at Set by In short
repositories: Created Root Which repositories a flight may concern.
environments: Created, then Ready → Leased Root Where the work may run, and so which machines may take it.
loops: Leased → Worked Work kind Which agent runs, what it may do, and for how long.
context.scope: Evaluated Root and work kind together Which files the agent may change.
obligations: Evaluated Every layer What must be true, and what a person must approve.
produces: Evaluated Work kind What the work yields, which decides which obligations can apply.
destinations: Evaluated → Ended Work kind Where finished work goes, and what it requires first.

The envelope describes each field in detail, with examples.

While a flight waits at a gate, the runner still pushes the branch, so there is real code to review. It does not open the pull request until the gate is answered. For example, a work kind that requires a person to approve a running preview before its pull request opens lists that approval in the destination’s requires:. The branch exists for review, and the pull request follows the approval.