# Context and templating (https://www.shipfox.io/docs/understand/data-and-templating)

Description: Understand when run data becomes available, how outputs move it between jobs, and how workflows use it safely.

**Context** is the data a workflow can read while it runs. It starts with the
event or the manual inputs. It grows as jobs and steps produce results.

Timing matters. A workflow can't read a result before the work that creates it
has finished. Shipfox resolves each value once enough context exists. A value
that depends on later work waits for that work to finish.

## When each kind of data becomes available [#when-each-kind-of-data-becomes-available]

Context is a flow, not one global object. Data joins it at five points:

1. **Run creation** adds the run identity, the trigger, the event, and the
   inputs.
2. **Job readiness** adds the outputs of upstream jobs that have finished.
3. **Listening execution** adds the event batch that started that execution.
4. **Step dispatch** adds earlier step outputs and retry context.
5. **Runner execution** resolves secret bindings for the command that needs
   them. The secret value never enters the run plan.

A tool step adds one short-lived value. Its provider response is readable as
`result` only while that step maps its outputs, right after the call returns.
Later steps read the stored value as `steps.<key>.outputs.result`.

Workspace variables and project settings hold long-lived configuration. Events
and outputs describe this run. Secrets grant access and follow a stricter path.

The [Contexts reference](https://www.shipfox.io/docs/reference/contexts#context-availability) is the
canonical table of which contexts each field can read.

## Two kinds of expression: templates and predicates [#two-kinds-of-expression-templates-and-predicates]

A `${{ }}` template puts a value into text or into a setting. It can put an
issue title in a prompt. It can also bind a job output to an environment
variable.

A predicate returns true or false. Filters, conditions, gates, and job success
rules use predicates. They decide whether work starts, continues, or passes.

The two roles stay separate, which makes policy easier to inspect. A template
never decides control flow. A predicate can't run a command or change outside
state. The same saved context therefore always produces the same decision.

Use a template to move a known value. Use a predicate when the workflow needs a
yes-or-no rule. The [Expressions
reference](https://www.shipfox.io/docs/reference/expressions) defines the exact syntax and the available
fields.

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

Steps in one job can share files, but files don't cross a job boundary. An
output turns a result into named workflow data that later work can read.

This complete workflow moves a version between two isolated jobs:

```yaml title=".shipfox/workflows/pass-version-between-jobs.yml"
# yaml-language-server: $schema=https://www.shipfox.io/docs/workflow.schema.json
name: Pass a version between jobs
runner: shipfox

triggers:
  manual:
    source: manual

jobs:
  package:
    outputs:
      version: ${{ steps.read_version.outputs.version }}
    steps:
      - key: read_version
        run: echo "version=$(git describe --tags --always)" >> "$SHIPFOX_OUTPUT"
        outputs:
          version: string

  publish:
    needs: package
    steps:
      - run: printf 'Publishing version %s\n' "${{ jobs.package.outputs.version }}"
```

The step creates `version`. The `package` job publishes it. The `publish` job
declares the dependency and puts the value in its command.

When a step declares a JSON array or object, a job output that maps exactly one
expression keeps that structure for later jobs. A later expression such as
`jobs.review.outputs.findings[0].severity` can then read a nested field. A
template that mixes text and expressions still produces a string.

Outputs fit small facts. Files and build products belong in external artifact
storage, with an output that carries their location. [Step
outputs](https://www.shipfox.io/docs/reference/workflow-schema#step-outputs) defines declaration types and
encoding. [Job outputs](https://www.shipfox.io/docs/reference/limits#job-outputs) lists the limits for job
outputs.

## Treat outside data as text, not as instructions [#treat-outside-data-as-text-not-as-instructions]

Events, inputs, and step outputs carry data that the workflow didn't write. A
shell step reads that data as text, so it can't run as a command. [A few shell
constructs](https://www.shipfox.io/docs/reference/workflow-schema#run-step-fields) read their own arguments
again and break that protection.

Nothing protects a prompt or a job setting this way. An event can contain
instructions for an agent. It can also choose the runner a job uses. Keep event
data out of any choice you wouldn't let a stranger make.

[Secrets and variables](https://www.shipfox.io/docs/reference/secrets-variables) describes storage,
masking, and binding. [Integrations, integration connections, and
tools](https://www.shipfox.io/docs/understand/integrations-connections-and-tools) explains the external
credential boundary.