Skip to main content

loom compile

Compile a Loom workflow into Graph IR v1 JSON or project a GitLab workflow into a value-safe plan report, without executing jobs.

Canonical command usage

Use the generated core CLI command reference for the exact loom compile synopsis, flags, and displayed defaults.

Workflow source and context

Default discovery selects .loom/workflow.yml before the repository root .gitlab-ci.yml. --format loom|gitlab selects exactly one parser. An explicit .gitlab-ci.yml basename is recognized as GitLab at any trusted project path; other custom GitLab filenames need --format gitlab. Parser and read failures do not cause fallback.

Use --context with GitLab sources to load a strict loom.gitlab-pipeline-context.v1 JSON document. The file is project-relative, limited to 1 MiB, and keeps variables, changes, and runner_tags separate. Ambient CI variables and runtime settings do not affect selection.

Workflow path trust boundary

--workflow paths are resolved relative to the repository root. Absolute paths, paths containing .., and paths that resolve through escaping or dangling symlinks are rejected with WF_TRUSTED_PATH before workflow content is read. The same boundary applies to include.local.

Use cases

  • Diff compiled plans across branches or commits to spot unexpected job changes
  • Verify include/template resolution — confirm extends and include.local merge correctly
  • Inspect the job graph (nodes + needs edges) before running
  • Feed Graph IR to external tools for visualization or analysis

Exit codes

CodeMeaning
0Loom compilation succeeded, or GitLab plan is executable or skipped
1Source is invalid, GitLab plan is non-executable, or the command fails

Output streams

StreamContent
stdoutGraph IR v1 JSON, or a GitLab plan report once a plan exists
stderrWarnings, diagnostics, and fatal errors

For GitLab, stdout uses loom.gitlab-plan-report.v1. It contains the plan schema and state, selection identity, selection records, requirements, diagnostics, and executable job topology. It excludes scripts, variables, and resolved context values. source_invalid and non_executable still write this report before returning nonzero; workflow_skipped writes a skipped report and returns 0.

Compile reports privileged-service requirements but cannot grant consent. It also exposes unsupported hosted macOS, OIDC token, Pages, and environment requirements; optional manual jobs remain visible but are not executed. Report processing and artifact expiry are diagnostic limitations.

Graph IR output format

loom compile outputs a JSON object with these top-level keys:

KeyTypeDescription
schemastringIR schema identifier — currently loom.graph-ir.v1
stagesstring[]Ordered list of stage names
nodesobject[]Executable jobs (template-only jobs are excluded)
edgesobject[]Dependency edges (currently: needs relationships)

Example output

{
"schema": "loom.graph-ir.v1",
"stages": ["ci"],
"nodes": [
{
"id": "check",
"stage": "ci",
"target": "linux",
"image": "alpine:3.20",
"script": ["pnpm i --frozen-lockfile", "task check"],
"allow_failure": false,
"variables": [{ "key": "PNPM_STORE_DIR", "value": ".pnpm-store" }],
"cache": {
"paths": [".pnpm-store", ".nx/cache"],
"policy": "pull-push",
"when": "always",
"key": { "prefix": "loom-cache", "files": ["pnpm-lock.yaml"] }
}
}
],
"edges": []
}

Notes on node fields:

  • image, variables, and cache are omitted when not present or not effective for a node.
  • cache can be a single object or a list, matching the workflow's single-cache vs. multi-cache shape.
  • allow_failure is always a boolean and defaults to false. When true, only an ordinary nonzero exit from the main script may satisfy dependency ordering. The command result keeps its actual status, exit code, and reason. Setup, cancellation, timeout, provider, publication, finalization, and cleanup errors remain fatal.
  • Workflow source may declare allow_failure on jobs and template jobs. Resolved template values are emitted in Graph IR, and an explicit child value overrides its template.

Warnings

Warnings are non-fatal. They are written to stderr in this format:

warning: <code> <path> <message>

Known warning codes

CodeMeaning
WF_PLANNER_VARIABLE_NON_SCALARA variable value was not a scalar; it was ignored while building the Graph IR

Invalid needs targets, self-dependencies, and dependency cycles are compilation errors. They are reported at the offending needs source path and exit with code 1.

This list may grow. If you see an unknown warning code, include it when reporting issues.

Examples

Compile the default workflow

loom compile

Compile a workflow at a custom path

loom compile --workflow ci/staging-workflow.yml

Pipe Graph IR to jq for inspection

loom compile | jq '.nodes[] | {id, stage, image}'

Diff compiled plans between branches

diff <(git stash && loom compile) <(git stash pop && loom compile)

Reporting issues

When loom compile fails or emits unexpected warnings, include:

  1. The command you ran (including --workflow if used)
  2. Warning or error lines from stderr
  3. The first ~20 lines of JSON output (redacted if needed)

See What to share for the full checklist.

  • loom check — validate schema without compiling
  • loom run — execute the compiled workflow