# Jobs and steps (https://www.shipfox.io/docs/understand/jobs-and-steps)

Description: Understand how the split into jobs affects shared files, parallel work, runner placement, and results.

A **job** is the unit that Shipfox places on a runner. A **step** is one ordered
action inside that job. A step is a run step, an agent step, or a tool step.

The main design choice is where one job ends and the next begins. That choice
decides which steps share a checkout, what can run at the same time, and which
results must pass from one job to another.

## Three kinds of step [#three-kinds-of-step]

Each kind of step performs a different kind of work.

| Step       | Performs                                                     | Runs on                                             |
| ---------- | ------------------------------------------------------------ | --------------------------------------------------- |
| Run step   | A shell command in the job's checkout.                       | The runner.                                         |
| Agent step | A goal that an agent pursues in the checkout.                | The runner.                                         |
| Tool step  | One integration operation with inputs the workflow supplies. | The Shipfox API, through an integration connection. |

A tool step has no working tree. It can't read files, set `env`, or use
`secrets`. Its inputs come from run data, and its result becomes step outputs
for later steps. Shipfox makes the call, so the provider credential never
reaches the runner.

The job still holds its runner while a tool step runs. The runner waits for
the call to finish and then continues with the next step. A job made only of
tool steps still needs a runner. [Integrations, integration connections, and
tools](https://www.shipfox.io/docs/understand/integrations-connections-and-tools) explains when a tool
step fits better than an agent with tools.

## When to keep steps in one job [#when-to-keep-steps-in-one-job]

Steps in one job run in order and use the same checkout. A later step can read
files that an earlier step changed. It can also use packages that an earlier
step installed.

Steps don't share one long-lived shell process. A shell variable set in one run
step doesn't reach the next. Save a file in the checkout when the next step
needs it. Publish an output when the value must become workflow data.

One job is usually the right choice when steps must:

* Edit and check the same files.
* Reuse an expensive local setup.
* Repeat together in a feedback loop.
* Use the same runner capabilities and repository permission.

The tradeoff is less parallelism. One slow step holds the job's runner and
delays every later step.

## When to split work into jobs [#when-to-split-work-into-jobs]

Each job gets a fresh checkout. It can use a different runner or repository
permission. Jobs without dependencies can start at the same time when capacity
is free.

Separate jobs fit work that must:

* Run in parallel.
* Fail or skip on its own.
* Use a different execution environment.
* Expose a small, named result to later work.

The cost is extra setup. Two jobs that both need Node.js packages each
install them again. Their files, process environment, and logs stay separate.

This complete workflow shows the split:

```yaml title=".shipfox/workflows/check-and-review.yml"
# yaml-language-server: $schema=https://www.shipfox.io/docs/workflow.schema.json
name: Check and review a change
runner: shipfox

triggers:
  manual:
    source: manual

jobs:
  lint:
    steps:
      - run: npm ci && npm run lint

  test:
    steps:
      - run: npm ci && npm test

  review:
    needs: [lint, test]
    steps:
      - prompt: Review the repository for likely bugs and missing tests.
```

`lint` and `test` can run in parallel. Each installs its own dependencies.
`review` waits for both, but receives neither job's files nor logs. It reviews
its own fresh checkout.

The `shipfox` label selects the default hosted runner. The [Runner labels
reference](https://www.shipfox.io/docs/reference/runner-labels) lists the other hosted sizes.

The [parallel CI
recipe](https://www.shipfox.io/docs/how-to/recipes/parallel-ci-agent-review) applies this shape to a GitHub
push. The [job fields
reference](https://www.shipfox.io/docs/reference/workflow-schema#job-fields) defines the dependency syntax.

## How results move between jobs [#how-results-move-between-jobs]

A job output passes a small value to later jobs. It fits a version, a decision,
an identifier, or a URL.

An artifact is a file or a directory. One job's checkout isn't available to
another job. Put large reports and build products in an external store. Pass
only their location as an output.

This explicit hand-off means a later job can't depend on a file that another
job left behind by accident. It also makes reruns and runner placement easier
to predict.

A named [agent session](https://www.shipfox.io/docs/understand/agent-sessions) is a third way to pass
context. It gives one agent's conversation to a later agent step in the same
run. It doesn't pass files either.

## A job also chooses its runner and its access [#a-job-also-chooses-its-runner-and-its-access]

A job selects its runner labels as a whole. Split work when one part needs a
private network, special hardware, or another operating system. Keep it
together when every step needs the same environment.

Repository checkout permission also applies to the whole job. Each agent step
selects its own integration tools, and each tool step names one operation.
Both are separate from Git access. This matters when an agent reads code but
only one later step must write to an external system.

[Runners and execution
environments](https://www.shipfox.io/docs/understand/runners-and-execution-environments) explains
placement. [Agent access](https://www.shipfox.io/docs/how-to/author-workflows/use-integration-tools) shows
the separate repository and integration controls. [Call an integration
tool](https://www.shipfox.io/docs/how-to/author-workflows/call-integration-tool) shows a tool step.

## Retries and later events stay inside the job [#retries-and-later-events-stay-inside-the-job]

A feedback loop repeats steps inside one job execution, so the repeated work
keeps the same checkout. A listening job creates a new job execution for each
later event or event batch. It can run its steps several times in one run.

Choose the job boundary before you add either kind of repetition. A job that
mixes unrelated writes makes retries and later events harder to handle safely.