Reference

release.yaml, and every rule it is checked against

One file in your repository describes the pipeline. Credentials, store accounts, distribution targets and approval policies are deliberately not in it — they live in the platform, which is what makes moving a project between store accounts possible.

A complete file

version: 1
framework: flutter
mode: native

apps:
  ios:
    bundle_id: com.example.app
  android:
    package: com.example.app

workflows:
  pr:
    triggers:
      pull_request:
        branches: [main]
    priority: pr-check
    jobs:
      test:
        steps:
          - uses: core/checkout
          - uses: flutter/bootstrap
          - uses: flutter/test
      build-ios:
        needs: [test]
        app: ios
        runs_on: { os: darwin }
        steps:
          - uses: core/checkout
          - uses: flutter/build
            with:
              platform: ios
              signed: false      # unsigned: no credential is resolved at all
              archive: false

That pull-request workflow is fork-safe, and not because anything says so. signed: false means the iOS build resolves no signing credential, no step in the job distributes, and so allowed_on_untrusted derives true. The step library shows that derivation for all forty-two steps.

19 errors

A file with any of these does not run.

  • E001

    The document does not match the schema

    Structural: a wrong type, an unknown key, a value outside an enum. Reported before any semantic rule runs, because running semantics over a malformed document produces cascading nonsense.

  • E010

    needs names a job that does not exist

    Usually a rename that missed one reference. The graph is built from these names, so an unresolvable one is a job that can never start.

  • E011

    The job graph has a cycle

    Two or more jobs waiting on each other. The engine would never schedule any of them, and it would look like a queue problem rather than a config one.

  • E012

    A job depends on itself

    The degenerate cycle, called out separately because the fix is obvious once named.

  • E013

    Two steps in one job share an id

    Step ids are how one step references another's output. Two steps with one id makes that reference ambiguous.

  • E014

    An expression references a step id that does not exist

    Checked at validation so it fails in half a second rather than mid-build.

  • E015

    An expression references a job that is not in needs

    A job's outputs are only available to jobs that declared they depend on it. Otherwise the value read depends on scheduling order, which is not a thing to build on.

  • E020

    uses names a step that is not in the registry

    The registry is the whole step library, so this is a typo or a version of Conductor older than the step. The diagnostic suggests the nearest name.

  • E021

    The step exists; that major version does not

    Steps are versioned per major. Pinning one that was never published fails here rather than at dispatch.

  • E022

    `with` violates the step's input schema

    Each step declares a JSON Schema for its inputs, and it is checked here rather than by the step failing on the machine.

  • E023

    A required input is absent

    Separated from the schema error above because “you forgot one” and “this value is wrong” are different problems with different fixes.

  • E030

    A distribution step is in a pull-request workflow

    A pull request must not be able to ship anything. This is an error rather than a warning because the failure mode is a build reaching testers from an unreviewed branch.

  • E031

    core/shell is in a job that also distributes

    A shell step in a job holding store credentials is the shape of an incident: arbitrary commands beside standing, high-privilege material. Split the shell work into a job the distribution job depends on.

  • E032

    A step needing a sensitive credential is on the untrusted pool

    The untrusted pool is where a fork's pull request runs, and it never receives standing credentials. A clone token is not sensitive and does not trip this — a fork may check out the code it is testing.

  • E033

    A fastlane lane needing credentials is reachable from a fork

    An adopted Fastfile is arbitrary Ruby holding injected credentials. Running it credential-free on a fork fails in a way that looks like Conductor broke it, so it is refused instead.

  • E034

    A job resolves credentials and does not say which app it targets

    Which credential satisfies a purpose is resolved per app. Without `app: ios` or `app: android` there is nothing to resolve against, and the build would have to guess.

  • E035

    One job mixes runner steps with control-plane ones

    A job runs entirely on one side. Mixing them would mean a workspace that exists for half the steps in it.

  • E040

    A store-account identifier appears in the config

    No Apple Team ID and no Play developer id may appear in release.yaml. That rule is the entire reason a project can be moved to a different store account as a configuration change rather than a rewrite.

  • E050

    A fastlane step is used while mode is native

    Native mode means typed steps only. Set `mode: hybrid` if you want both, which is a deliberate choice rather than an accident.

8 warnings

The pipeline runs. Each one is something that will cost you later, said now.

  • E051

    mode is adopt and no fastlane step is used

    Adopt mode exists to run your existing lanes. If none are called, `mode: native` describes what is actually happening.

  • W060

    No current runner matches runs_on

    The job would queue indefinitely. A warning rather than an error because a fleet changes — enrolling the right machine fixes it without touching the file.

  • W061

    The matrix expands beyond what this fleet can run

    On a small fleet a wide matrix is not parallelism, it is a queue. Learning that from a warning beats learning it from a dashboard.

  • W062

    An `on:` key was parsed as the boolean true

    Under YAML 1.1 an unquoted `on` is a boolean. Conductor's parser is 1.2 and keeps it a string, but other tooling may not — `triggers:` is the spelling immune to it.

  • W063

    The declared framework differs from what was detected

    A warning, never a silent switch. A build that quietly changed how it was produced is worse than one that stopped.

  • W064

    paths and paths_ignore overlap

    The overlap is silently excluded, which is rarely what somebody meant to write.

  • W065

    An expensive darwin job has no path filter

    macOS capacity is the scarce resource. A job that rebuilds an iOS app because a README changed is spending the thing you have least of.

  • W066

    A pull-request workflow asks for a signed build

    Signing a PR build costs a credential and an archive, and produces something nobody installs. It also puts the job out of reach of any fork.

Codes are stable and never reused

A diagnostic code is an identifier you can search for, link a colleague to, and grep a build log for. So they are append-only: a rule that is removed leaves its number retired rather than handing it to the next rule, because a search result explaining E032 should not one day explain something else.