Skip to content
PYD ENTERPRISES

Migration guide

JCL to cloud batch orchestration: translate COND codes, GDGs and PROCs into a job graph

JCL is a dependency graph written in negative logic. This guide shows how to read COND, IF/THEN, GDGs and utility control cards as a specification for Airflow, Argo, Step Functions or any other orchestrator.

JCLCloud batch orchestration
DIFFICULTY
Moderate
OUTPUT
OpenAPI / YAML
SYNTAX TRAPS
6 covered
WORKFLOW
6 steps

By Pranav Kulkarni, Head of Language Engineering · Updated 15 Oct 2026

Technical syntax challenges

Where JCL migrations go wrong.

01

COND is a bypass test, not a run test

COND=(4,LT,STEP010) reads "bypass this step if 4 is less than STEP010's return code". The step runs only when STEP010 ended with RC 4 or lower. Engineers translating it by eye invert it often enough that every condition should be machine translated and reviewed.

02

Abends, bypassed steps and EVEN or ONLY

After an abend, steps without COND=EVEN or COND=ONLY are skipped. A COND test that names a step which was itself bypassed is ignored. Orchestrator conditions need explicit states for succeeded, failed with RC, abended and skipped to reproduce this.

03

GDG relative generations

PRD.LN.EXTRACT(+1) creates a new generation, (0) reads the latest and (-1) the one before. Within one job, (+1) keeps pointing at the generation created earlier in that job. In object storage this becomes dated or run-id keyed paths plus a retention rule matching the GDG LIMIT.

04

Utility control cards are business logic

INCLUDE COND=(11,1,CH,EQ,C'A') in a DFSORT step filters active records by byte position. Those cards, plus IDCAMS REPRO and IEBGENER steps, encode selection rules that must be mapped to field names through the record layout.

05

PROCs, symbolics and overrides

Cataloged PROCs with &ENV symbolics and //STEP020.SYSIN DD overrides mean the job that runs is not the job you read. Expansion has to happen before any dependency analysis.

06

DISP and temporary datasets

DISP=(NEW,CATLG,DELETE) deletes the dataset if the step abends; &&SORTED with PASS lives only for the job. These are cleanup and atomicity rules the cloud pipeline needs as explicit failure handlers.

Extraction workflow

6 steps from source to signed-off spec.

The sequence a PYD ENTERPRISES Discovery Scan runs for this stack. Every output links back to source file and line range.

  1. 1

    Collect JCL, PROCLIBs and scheduler definitions

    Export job JCL, every PROCLIB in search order, INCLUDE members, SYSIN control card members and the scheduler's job dependency definitions.

  2. 2

    Expand PROCs and resolve symbolics

    PYD ENTERPRISES expands each job as the converter would, applying symbolic parameters and DD overrides, so the analyzed job is the executed job.

  3. 3

    Translate COND and IF/THEN into positive conditions

    Every COND parameter and IF/THEN/ELSE construct becomes an explicit run condition over named step outcomes, with the original text kept for review.

  4. 4

    Build dataset lineage across steps and jobs

    DD statements link producers and consumers of each dataset, including GDG generations, so cross-job dependencies the scheduler enforces appear in one graph.

  5. 5

    Map utility control cards to field-level rules

    SORT, INCLUDE, OMIT and OUTREC cards are resolved against copybook layouts, turning byte offsets into named-field filters and transformations.

  6. 6

    Export the job graph and step contracts

    The result is a job graph with conditions, dataset contracts as JSON Schema and links into the program-level rules each step executes, ready for the orchestration team.

Legacy in, specification out

The source, and what PYD ENTERPRISES extracts from it.

Left: the JCL construct as it sits in production. Right: the reviewed artifact your Cloud batch orchestration engineers build against. PYD ENTERPRISES produces the spec and the tests; your team writes the service.

LEGACY SOURCE

LNDLY01.jclJCL
1//LNDLY01 JOB (ACCT),'LOAN DAILY',CLASS=A,MSGCLASS=X
2//STEP010 EXEC PGM=LNEXTR01
3//LNMAST DD DSN=PRD.LN.MASTER,DISP=SHR
4//EXTRACT DD DSN=PRD.LN.EXTRACT(+1),
5// DISP=(NEW,CATLG,DELETE),
6// SPACE=(CYL,(50,10),RLSE)
7//STEP020 EXEC PGM=SORT,COND=(4,LT,STEP010)
8//SORTIN DD DSN=PRD.LN.EXTRACT(+1),DISP=SHR
9//SORTOUT DD DSN=&&SORTED,DISP=(NEW,PASS),
10// SPACE=(CYL,(20,5))
11//SYSIN DD *
12 SORT FIELDS=(1,10,CH,A)
13 INCLUDE COND=(11,1,CH,EQ,C'A')
14/*
15//STEP030 EXEC PGM=LNACCR02,
16// COND=((4,LT,STEP010),(0,NE,STEP020))
17//INFILE DD DSN=&&SORTED,DISP=(OLD,DELETE)

EXTRACTED ARTIFACT

LNDLY01.jobgraph.yamlYAML
1job: LNDLY01
2x-pyd-source: LNDLY01.jcl:1-17
3steps:
4 - id: STEP010
5 program: LNEXTR01
6 reads: [PRD.LN.MASTER]
7 writes: [{ dataset: PRD.LN.EXTRACT, generation: "+1", onAbend: delete }]
8 - id: STEP020
9 utility: SORT
10 runIf: "STEP010.rc <= 4"
11 rules:
12 sortKey: "LN-ACCT-ID ascending (bytes 1-10)"
13 filter: "LN-STATUS = 'A' (byte 11)"
14 - id: STEP030
15 program: LNACCR02
16 runIf: "STEP010.rc <= 4 and STEP020.rc == 0"
17 note: "a test against a bypassed step is ignored"
18 reads: [{ temp: SORTED, deleteAfter: true }]
19onAbend: "skip remaining steps (no EVEN or ONLY)"

Architectural best practices

Build the Cloud batch orchestration side to the spec, not to the old shape.

  • Translate every COND into a positive run condition automatically and have an operator who knows the job confirm it.
  • Give each step four explicit outcomes (succeeded, return code, abended, skipped) so orchestrator conditions can express JCL semantics exactly.
  • Replace GDGs with immutable, run-keyed object paths and a retention policy equal to the GDG limit.
  • Rename byte-offset filters to field names from the copybook before anyone reimplements them.
  • Keep restart points: JCL RESTART and checkpoint behavior should become idempotent, resumable tasks in the new pipeline.

The scheduler is half the graph

JCL describes the steps inside a job. Which job runs after which, at what time and on which calendar is defined in the enterprise scheduler (Control-M, CA 7, IBM Workload Scheduler and similar). PYD ENTERPRISES ingests exported job and dependency definitions alongside JCL so dataset lineage and scheduler dependencies appear in one graph. Where the scheduler enforces an order that no dataset explains, the edge is flagged: it is either a hidden data dependency (a DB2 table, a VSAM file opened by both) or an operational habit that can be dropped.

What PYD ENTERPRISES hands the orchestration team

The output is a specification, not generated DAG code. It contains the job graph with positive conditions, dataset contracts with JSON Schema derived from copybooks, utility steps rewritten as named-field rules, and links into the business rules extracted from each program. Your platform team builds the pipeline in the orchestrator they chose, and the generated fixtures (input datasets and expected outputs per step) confirm each rebuilt step matches the mainframe run.

FAQ

JCL to Cloud batch orchestration questions

Does PYD ENTERPRISES generate Airflow DAGs or Step Functions definitions?

No. It exports an orchestrator-neutral job graph with conditions, dataset contracts and rules. Teams translate it into their orchestrator of choice, which keeps the design decisions with the platform team.

How are IF/THEN/ELSE constructs handled compared with COND?

Both are translated into the same positive condition language over step outcomes, including ABEND, RUN and return code tests, so mixed jobs read consistently.

Can it read DFSORT and SyncSort control cards?

Yes for the common statements: SORT, MERGE, INCLUDE, OMIT, INREC, OUTREC and SUM. Byte positions are mapped to field names through the copybook of the input dataset.

Get the spec for your JCL estate.

Request a codebase scan and review extracted rules, contracts and fixtures for your own JCL estate, inside your VPC.