Skip to main content

Mainframe Migration Toolkit - COBOL/JCL -> Python/SQL

A VS Code extension + language server + CLI toolkit that gives an AI coding agent (GitHub Copilot in agent mode) deterministic navigation of a legacy COBOL/JCL codebase's dependencies (CALL/COPY/EXEC), and a set of scripts that automate the mechanical, low-risk parts of migrating that codebase to Python and SQL.

This project intentionally does not try to auto-translate COBOL business logic into Python - see docs/RESEARCH.md for why that approach is unsafe for financial-grade code, and what large migration programs do instead.

Why "deterministic"?

LLMs are good at reading and writing code, but bad at reliably tracing "what calls what" across thousands of files inside a limited context window - and a hallucinated dependency edge in a mainframe migration can mean a silent production regression. Every tool here is a plain parser or graph traversal: same input always produces the same output, with no model involved. The AI agent's job is to call these tools and reason over their output, not to re-derive the graph itself.

How edge cases are handled

No regex-based parser can understand 100% of real-world COBOL/JCL. When a tool hits something it can't safely resolve - an unresolved CALL/COPY target, a dynamic CALL WS-VAR, EXEC CICS/IMS blocks, OCCURS ... DEPENDING ON variable-length tables, an unterminated EXEC SQL block, a missing PROGRAM-ID, GO TO control flow, an edited/floating-point PIC clause, a qualified/indicator SQL host variable, a JCL backward reference to a nonexistent step, etc. - it never guesses. Instead it emits a structured warning (code, severity, message, suggested_action, file, line, snippet) defined once in scripts/common/warnings_model.py / server/src/warningsModel.ts, and every tool surfaces it:

  • Immediately supplyable missing prerequisites produce BLOCK and stop the affected file generation before outputs are written. Semantic decisions produce configurable code-local TODO(mainframe-migration): [CODE] explanation / required decision markers while unaffected units continue.
  • The language server reports the same facts as editor diagnostics on the offending line, and via the mainframe/warnings custom LSP request (also folded into mainframe/dependencyGraph and mainframe/impactAnalysis results).
  • Known IBM/vendor utility programs (IEFBR14, SORT, IDCAMS, ...) and system copybooks (SQLCA, DFHCOMMAREA, ...) are allowlisted so real findings aren't buried in expected noise.

See test-fixtures/edge-cases/ for a fixture per edge case, used to regression-test this behavior.

Repository layout

extension/        VS Code extension: starts the language server and
                   registers 5 vscode.lm Language Model Tools for Copilot
                   agent mode (see extension/package.json
                   "languageModelTools").
server/           Deterministic COBOL/JCL language server
                   (vscode-languageserver, TypeScript). Provides go-to-
                   definition & hover for CALL/COPY/EXEC PGM=, diagnostics
                   for unresolved targets, and custom LSP requests
                   (mainframe/dependencyGraph, mainframe/impactAnalysis,
                   mainframe/callers, mainframe/resolveCopybook) that back
                   the extension's LM tools.
scripts/          17 standalone Python CLI tools for migration planning and
                   scaffolding (see below). No dependencies beyond the
                   Python 3 standard library.
scripts/common/   Shared deterministic COBOL/JCL parsing + workspace
                   indexing code used by every script (and conceptually
                   mirrored in server/src/*.ts for the LSP).
test-fixtures/    An original, small "bank batch" COBOL/JCL system used to
                   exercise every tool end-to-end (see
                   test-fixtures/README.md for its call/copy graph).
docs/RESEARCH.md  Research on migration strategies used by large players,
                   and which tool here implements each one.

Configuration and preflight

Use a workspace-relative mainframe-migration.json to define ordered primary/fallback COBOL, copybook, and JCL libraries. The schema is mainframe-migration.schema.json, and test-fixtures/mainframe-migration.json is a complete example that intentionally includes edge-cases/ as a fallback library.

mainframe-migration.json is authoritative for paths, ordered primary and fallback libraries, source encoding, extensions, external registries, the generated TODO prefix, and optional named transportProfiles. A transport profile defines fixed-width text charset, line separator, trim policy, and the representation of DISPLAY, COMP-3, BINARY/COMP-4, COMP-1, and COMP-2 fields. Old configs remain valid, but contract/fixture generation requires an explicit profile or defaultTransportProfile.

Physical copybook layout and transported text layout are separate contracts. For example, a six-byte packed COMP-3 value can become 13 text characters (precision digits, decimal point, and sign) without changing its source offset or physical length. Expanded decimal width is precision plus an explicit decimal point when scale is non-zero plus one sign character when signed; expanded integer width is precision plus one sign character when signed.

Run mandatory phase-zero preflight before generating migration output:

python3 scripts/migration_preflight.py test-fixtures --jcl BANKRUN --format text
python3 scripts/migration_preflight.py test-fixtures --format json

Preflight exits 0 when there are no BLOCK findings and 2 when a human-suppliable fact is missing or ambiguous. Dynamic calls, transaction dialects, ODO, REDEFINES, edited PICs, and qualified SQL hosts become explicit TODO findings and do not stop unrelated analysis. Generate a starter file with --write-template. Present the initial report grouped by user_can_supply=true and then false. Resolution order is fixed: current LSP facts, configured primary libraries, configured fallback libraries, then verified known externals; exhaustion blocks and requires user input. Automated migration repair is capped at 50 total failed attempts.

Configuration-aware CLIs accept --config. For single-file CLIs, the selected file must exist, match its configured kind, and belong to the selected inventory. Omitting config retains legacy behavior.

Pinned CardDemo validation

Run the parsed phase-3 scenarios against the exact pinned AWS CardDemo revision with one command (the runner clones/caches and verifies the detached commit):

python3 tests/run_carddemo_scenarios.py

The assertions, observed results, known fixes, and residual TODOs are recorded in docs/research-carddemo-validation.md.

The 17 tools

Tool What it answers
scripts/migration_preflight.py Validates configured source inventory, precedence, static dependencies, and migration blockers before generation
scripts/dependency_graph.py "What calls/copies/executes what across the whole codebase?" (JSON/DOT/text)
scripts/impact_analysis.py "If I change X, what breaks?" (transitive upstream/downstream + risk)
scripts/dead_code_finder.py "Which programs/copybooks are never referenced?"
scripts/sql_extractor.py Pulls embedded EXEC SQL out of COBOL into standalone, bind-parameterized .sql files
scripts/business_rule_extractor.py Mines IF/EVALUATE decision logic (+ preceding comments) into a reviewable rule list
scripts/copybook_to_dataclass.py Copybook PIC layout -> Python @dataclass and/or SQL CREATE TABLE
scripts/copybook_to_contract.py Copybook physical offsets + selected transport profile -> canonical language-neutral JSON record contract with digest, provenance, and structured TODO/BLOCK findings
scripts/generate_copybook_fixtures.py Canonical contract or configured copybook -> deterministic seeded fixed-width input, decoded JSONL, invalid decode cases, and a non-authoritative manifest for ingestion testing only
scripts/generate_file_readers.py FILE-CONTROL/FD/COPY -> standalone domain/model dataclasses and binary-safe fixed-width readers; missing copybooks block writes while semantic layout decisions remain explicit TODO stubs
scripts/cobol_to_python_skeleton.py COBOL paragraph structure -> Python class skeleton (structure preserved, logic left as TODOs)
scripts/jcl_flow_extractor.py JCL step/COND flow -> explicit orchestration description or Python skeleton
scripts/migration_complexity_report.py Ranks every program by migration effort/risk into a wave plan
scripts/characterization_test_scaffolder.py Generates a golden-master pytest harness from a program's LINKAGE SECTION contract
scripts/generate_program_capsule.py Runs selected-JCL preflight, then creates per-program/utility PARTIAL capsules with deterministic DD/I/O evidence, contract copies, explicit semantic TODO IR, placeholder source/tests, and exact paths/commands; any preflight BLOCK writes nothing
scripts/validate_relational_ir.py Pure-stdlib typed validation for relational IR v1; exits 0 only for executable reviewed plans, 2 for BLOCK, and 3 for TODO/non-executable
scripts/ir_to_pyspark.py Deterministically compiles validated executable IR to native PySpark source with run(inputs, outputs, spark) and refuses BLOCK/TODO plans before writing

Every script is runnable standalone:

python3 scripts/dependency_graph.py test-fixtures --format text
python3 scripts/copybook_to_contract.py test-fixtures/copybooks/TRANREC.cpy --config test-fixtures/mainframe-migration.json --out TRANREC.contract.json
python3 scripts/generate_copybook_fixtures.py TRANREC.contract.json --out-dir synthetic/TRANREC --count 6 --seed 41 --include-invalid
python3 scripts/generate_file_readers.py test-fixtures --out-dir domain
python3 scripts/generate_program_capsule.py test-fixtures --jcl BANKRUN --out-dir migration/BANKRUN/capsules --format text
python3 scripts/validate_relational_ir.py migration/BANKRUN/capsules/mainpgm/ir/plan.scaffold.json --format text

relational-ir.schema.json defines the portable relational plan format. An AI may author the semantic operations only after the program semantic brief and target design review are approved. The validator and PySpark compiler are deterministic; they do not infer missing types or business rules. A generated program capsule is intentionally PARTIAL, contains an explicit semantic TODO, and is not a translated or equivalent implementation.

The generated readers open files in binary mode so COMP-3, COMP-4/ BINARY, and DISPLAY fields retain their physical COBOL representation. Each malformed line yields a structured RecordParseError by default; valid records continue streaming. Missing copybooks block before package creation; semantic or unsafe layout decisions generate an empty dataclass and reader stub with a standardized TODO instead of a guessed layout.

Synthetic fixture output never contains authoritative expected program output. Its manifest says synthetic=true, authoritative=false, and purpose=ingestion_validation_only. Raw binary fields are not written into a fixed_width_text artifact; a source_bytes representation requires an explicit binary-capable output mode and otherwise blocks generation.

Copilot migration workflow

Use the workspace-scoped mainframe JCL migration skill directly, or select the Mainframe JCL Migrator agent for the phase-gated workflow. Example invocation:

/mainframe-jcl-migration /path/to/mainframe-workspace BANKRUN migration/BANKRUN

The first argument is the workspace root, the second is a JCL job name or path, and the optional third argument is the target directory.

The 5 Language Model Tools (for Copilot agent mode)

Registered in extension/package.json under contributes.languageModelTools and implemented in extension/src/extension.ts:

  1. mainframe_getDependencyGraph - whole-graph or scoped CALL/COPY/EXEC graph.
  2. mainframe_getCallers - who calls a given program, including JCL EXEC PGM=.
  3. mainframe_resolveCopybook - resolve a COPY target to its file + users.
  4. mainframe_impactAnalysis - transitive blast-radius + risk rating before any change.
  5. mainframe_runMigrationScript - runs any of the 17 scripts above, workspace-sandboxed.

These are backed by the same language server used for interactive go-to-definition/hover, so an agent and a human developer see identical dependency information.

Building

cd server && npm install && npm run compile
cd ../extension && npm install && npm run compile

Then press F5 in VS Code (or use the "Run Extension" launch configuration in .vscode/launch.json) to try it against test-fixtures/.

A standalone smoke test for the language server (no VS Code required) is at server/scripts/smoke_test.js:

node server/scripts/smoke_test.js test-fixtures
node server/scripts/config_parity_test.js test-fixtures

Installing the release artifacts

Build the wheel, source distribution, and bundled VSIX without publishing:

python tools/build_release.py
python -m pip install dist/mainframe_modernization_toolkit-0.1.0-py3-none-any.whl
mainframe-toolkit --version

The wheel contains the standalone VS Code extension, including the bundled dist/server.js. Export and verify the exact embedded bytes before installing the VSIX manually:

mainframe-toolkit vsix export --output mainframe-migration-toolkit-0.1.0.vsix
mainframe-toolkit vsix verify mainframe-migration-toolkit-0.1.0.vsix
code --install-extension mainframe-migration-toolkit-0.1.0.vsix

The extension invokes mainframe-toolkit by default. Set mainframeMigration.executablePath to the installed executable's absolute path when it is not on the VS Code extension host's PATH. Run mainframe-toolkit workspace init <workspace> or the Mainframe Migration: Initialize Workspace command to add the packaged configuration, schemas, skill, and agent without overwriting existing files.

Source extensions referenced

This project was built with the two extensions supplied in the task as primary references for real-world COBOL/JCL LSP feature scope:

  • eclipse-che4z/che-che4z-lsp-for-cobol - full COBOL LSP (ANTLR-based, JVM). Studied for how it models copybook resolution, dialects, and CALL/COPY dependency nodes; not vendored directly (JVM/Maven toolchain would be heavy for an agent-facing tool - see docs/RESEARCH.md for the tradeoff rationale).
  • BroadcomMFD/jcl-language-support - JCL syntax highlighting/snippets/Zowe integration. Studied for JCL file detection conventions (.jcl/.cntl, jobcard sniffing) and DD/DSN navigation patterns.
  • Their Marketplace listings (broadcomMFD.jcl-language-support, broadcomMFD.cobol-language-support) were fetched for feature summaries.

All COBOL/JCL fixtures under test-fixtures/ are original, written for this project (not copied from any repository).

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mainframe_modernization_toolkit-0.1.0.tar.gz (378.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mainframe_modernization_toolkit-0.1.0-py3-none-any.whl (399.6 kB view details)

Uploaded Python 3

File details

Details for the file mainframe_modernization_toolkit-0.1.0.tar.gz.

File metadata

File hashes

Hashes for mainframe_modernization_toolkit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5182f49fac2ca92f42f640216b319be37547139634006cdee7677172684ed8a6
MD5 09c659026dc214e7c6e62e95367f3cc3
BLAKE2b-256 e6952a2b928835c1fe9fe10ae6610f9f486ba0f4e96b5201368ac32ced152b1f

See more details on using hashes here.

File details

Details for the file mainframe_modernization_toolkit-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for mainframe_modernization_toolkit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 573d4d449f2b2e5e6f49b98ea7d6a06009a305710018c41f044ffdc7ba8b9a63
MD5 1502a1fc739edf8f07c8b9feb18b9c10
BLAKE2b-256 e37c75734c29d96256928b0b1c4614100b6448a2dd6a14fd29e05d9885aafe9c

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.19

2 files

0.1.18

2 files

0.1.17

2 files

0.1.16

2 files

0.1.15

2 files

0.1.14

2 files

0.1.13

2 files

0.1.12

2 files

0.1.11

2 files

0.1.10

2 files

0.1.9

2 files

0.1.8

2 files

0.1.7

2 files

0.1.6

2 files

0.1.4

2 files

0.1.3

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page