Update mainframe Prethink context
io.moderne.mainframe.prethink.UpdateMainframePrethinkContextio.moderne.recipe:recipes-mainframeDefinition
Recipes44
- Analyze the mainframe architecture
- Analyze the relationships of a load module
- Analyze the mainframe a Java source reaches
- List relationship kinds
- Analyze the business rules a portfolio applies
- Measure each program and its control flow
- Analyze the mainframe migration blockers
- Analyze the portfolio's copybooks
- Analyze how the portfolio reaches its data
- List each job step and the data sets it allocates
- List how far each job step can be read
- Say what each control card deck is and what it defines
- Join each load module to the programs bound into it
- Join each plan to the packages and programs bound under it
- Read the schema the DDL creates, and who reaches each table
- List the Db2 unloads and what each would cost to move
- Say when each job runs, what has to end first, and on which days
- Say which build orders the scheduler does not enforce, and which jobs nobody orders
- Join each IMS transaction and job step to the segments behind it
- Join every screen field to the COBOL behind it
- Compare each record with the other language that describes it
- Analyze what the run books document
- Compare the copies of a member across environments
- Find column lineage
- Generate mainframe [CALM](https://calm.finos.org/) architecture
- Generate the mainframe findings report
- Generate [OpenLineage](https://openlineage.io/) column lineage
- Export context files
- Export context files
- Export context files
- Export context files
- Export context files
- Export context files
- Export context files
- Export context files
- Export context files
- Export context files
- Export context files
- Export context files
- Export context files
- Export context files
- Export context files
- Update agent configuration files
- Update .gitignore for Prethink context
Options
Usage
Run this recipe
This recipe has no required configuration options. Users of Moderne can run it via the Moderne CLI.
You will need to have configured the Moderne CLI on your machine before you can run the following command.
mod run . --recipe UpdateMainframePrethinkContext
To also set the recipe's optional settings, add them to the command. The values below are examples, not recommendations; see Options for what each one does.
mod run . --recipe UpdateMainframePrethinkContext \
--recipe-option "targetConfigFiles=CLAUDE.md" \
--recipe-option "views=true"
If the recipe is not available locally, then you can install it using:
RELEASE resolves to the newest release and LATEST to the newest build of any kind, including snapshots. Either one lets mod config recipes upgrade pull in later versions without editing this command; a pinned version stays where you put it.
- RELEASE
- LATEST
- Pinned version
mod config recipes jar install io.moderne.recipe:recipes-mainframe:RELEASE
mod config recipes jar install io.moderne.recipe:recipes-mainframe:LATEST
mod config recipes jar install io.moderne.recipe:recipes-mainframe:0.1.0
Data tables
COBOL relationships
org.openrewrite.mainframe.cobol.table.CobolRelationshipsRelationships between different COBOL resources.
mod study . --last-recipe-run \
--data-table org.openrewrite.mainframe.cobol.table.CobolRelationships
| Column | Description |
|---|---|
| Dependent | The resource that defines the relationship. |
| Dependent type | The resource type of the resource that defines the relationship. |
| Action | The action that links the dependent and dependency. |
| Dependency | The resource that is exercised or linked to. |
| Dependency type | The resource type of the resource that is exercised or linked to. |
| Dependency missing | Indicates whether the dependency is a known resource. |
| Action metadata | Additional data about the action. |
| Dependent path | The source file the dependent's statement was written in, or null when the dependent is a name that has no source here. |
| Dependent line | The one-based line the dependent's statement was written on, or null when it has no source here. |
| Dependency path | The source file the dependency was written in, or null when the dependency is a name that has no source here, such as a vendor copybook. |
| Dependency line | The one-based line the dependency's statement was written on, or null when the dependency is a whole file rather than a statement within one. |
Relationship kinds
io.moderne.mainframe.analysis.table.RelationshipKindsEvery relationship a resource of each type can have, both ways round. This is the schema the relationship rows are read against, so a view of one component can show each relationship it is capable of even when it has none — an empty section says "nothing calls this", where a missing section says nothing at all.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.RelationshipKinds
| Column | Description |
|---|---|
| Resource type | The type this relationship is expected of. |
| Direction | OUTBOUND where the resource is the dependent of the edge, INBOUND where it is the dependency. Every kind has a row each way, which is what makes the inverse renderable. |
| Verb | What to call this relationship on a view of the resource: Calls outbound, Called by inbound. |
| Action | The action a relationship row carries for this kind. |
| Related type | The type at the other end. |
| Inverse verb | What the same relationship is called on a view of the related type. |
Business rules
io.moderne.mainframe.analysis.table.BusinessRulesOne row per decision: a condition a program tests, and everything that follows from it. A record copied field by field is one decision here, not one per field — the individual assignments are in the rule actions table.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.BusinessRules
| Column | Description |
|---|---|
| Program | The COBOL program. |
| Paragraph | The paragraph or section the actions are written in. The same test made in two places is two decisions, however alike they read. |
| When | The conditions that must all hold, normalised: condition names expanded to the test they stand for, negation folded into the operator, and each field named where its value came from rather than where it was copied to. |
| Then | What the program does, short enough to read. Fields copied unchanged are counted rather than listed, since a record copied field by field is one act however many statements it takes. |
| Decides | Every field assigned and resource acted on, in source order. |
| Actions | How many statements the decision covers. |
| Kinds | What sorts of thing it does: COPY, CONSTANT, COMPUTE, CALL, WRITE. A decision that only copies is plumbing; one that computes or writes is where the business is. |
| Conditions | The fields the condition tests. |
| Inherited from | Fields tested under a name other than the one the source wrote, because the value was traced back through a MOVE to where it came from. |
| Anomaly | CONTRADICTORY, UNREACHABLE or SUBSUMED where the decision cannot do what it appears to; empty otherwise. |
Rule actions
io.moderne.mainframe.analysis.table.RuleActionsOne row per statement a rule decides, which is the grain impact analysis and lineage want: every field the program assigns under a condition, and the condition. Rows sharing a subject are the rows of one decision table; rows sharing a condition are one row of the business rules table.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.RuleActions
| Column | Description |
|---|---|
| Program | The COBOL program. |
| Paragraph | The paragraph or section the action is written in. |
| Subject | What the action decides: the field it assigns, or the resource it acts on. Every row sharing this value belongs to one decision table. |
| Rule | The rule's position in its decision table, in source order. Where two rules cover the same case, the later one is the one that runs. |
| When | The conditions that must all hold, normalised. |
| Then | What happens: the value assigned, or the operation performed. |
| Kind | COPY for a field given another field's value unchanged, CONSTANT for a literal, COMPUTE for arithmetic or an expression, CALL for work handed to another program, WRITE for something written where the outside can see it. |
| Conditions | The fields this rule tests, which are the columns of its decision table. |
| Inherited from | Fields the rule tests under a name other than the one the source wrote, because the value was traced back through a MOVE to where it came from. |
| Anomaly | CONTRADICTORY, UNREACHABLE or SUBSUMED where the rule cannot do what it appears to; empty otherwise. |
Decision table anomalies
io.moderne.mainframe.analysis.table.DecisionTableAnomaliesRules that cannot do what they appear to, found by checking the normalised table rather than by reading the code.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.DecisionTableAnomalies
| Column | Description |
|---|---|
| Program | The COBOL program. |
| Subject | The field or resource the rule decides, which is the decision table it belongs to. |
| Kind | CONTRADICTORY for conditions that exclude each other, so the rule never fires; UNREACHABLE for a rule in a paragraph nothing reaches; SUBSUMED for a rule an earlier one has already decided. |
| Rule | The rule, as WHEN conditions THEN outcome. |
| Paragraph | The paragraph or section the rule is written in. |
| Detail | Why the rule cannot fire, or which earlier rule already covers it. |
Findings
io.moderne.mainframe.analysis.table.FindingsEverything the mainframe analyses found wrong, ranked, with the evidence for each and the line it is on. Sort on priority.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.Findings
| Column | Description |
|---|---|
| Priority | 1 for CRITICAL down to 4 for LOW, so the table sorts. |
| Severity | CRITICAL for code that cannot do what it was written to do, HIGH for what will break a migration if not decided deliberately, MEDIUM for what is worth knowing first, LOW for cleanup. |
| Category | What kind of problem it is, which is what groups the report into sections: DEAD_RULE, UNREACHABLE_CODE, COPYBOOK_DRIFT, MIGRATION_BLOCKER, RANGE_PATHOLOGY, DEAD_DATA, COMPLEXITY, LAYOUT_DRIFT, IMS_PCB_MISMATCH, IMS_SEGMENT_NOT_SENSITIVE, IMS_IO_AREA_MISMATCH, MFS_MESSAGE_LENGTH, SCREEN_ITEM_UNREACHED, SCREEN_FIELD_UNREACHED, PARSE_FAILURE, UNDOCUMENTED, STALE_DOCUMENTATION, STALE_REFERENCE, UNENFORCED_BUILD_ORDER, UNSCHEDULED_JOB, AUTOCALL_RESOLVED_REFERENCE, UNRESOLVED_EXECUTION_PATH, INHERITED_SETTING, UNLOAD_NEEDS_REDESIGN, UNLOAD_ACCESS_MODE, UNLOAD_CONSISTENCY, UNLOAD_OUTPUT_WIRING, MIXED_SUBSTITUTION. |
| Program | The COBOL program, or the copybook where the finding is about one. |
| Summary | The finding in one sentence, written to be read on its own. |
| Evidence | Why this is claimed — the conditions that conflict, the two declarations that differ, the caller that made the paragraph unreachable. A finding nobody can check is a finding nobody will act on. |
| Where | The paragraph, section or data item the finding is in. |
| Source path | The file, so the finding can be opened. |
Program complexity
io.moderne.mainframe.analysis.table.ProgramComplexitySize and complexity per program, for ranking a portfolio by risk and effort.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ProgramComplexity
| Column | Description |
|---|---|
| Program | The COBOL program. |
| Cyclomatic complexity | McCabe: one plus every decision the program can take, counting each operand of a compound condition separately. |
| Statements | Procedure division statements. |
| Source lines | Lines of the program as written. |
| Comment lines | Source lines that are comments: an asterisk or slash in the indicator column. |
| Expanded lines | Lines with every copybook inlined where it is copied, which is what the compiler reads. A copybook that was not found adds nothing. |
| Expanded comment lines | Comment lines with every copybook inlined. |
| Paragraphs | Paragraphs declared. |
| Sections | Sections declared. |
| Data items | Data items declared, including those copied in. |
| Copybooks | Distinct copybooks copied in. More than twenty marks a program that is expensive to change, because its shape is set by files it does not own. |
| Calls | Distinct programs called. |
| Halstead volume | Volume over COBOL operators and operands. The absolute value means little; the spread across a portfolio is what ranks programs. |
| Maintainability index | The conventional 171-based index. Below about 65 reads as hard to maintain, below 20 as effectively unmaintainable. |
| Flags | Thresholds crossed, from published operating experience rather than invented: more than 20 copybooks, more than 100 statements per paragraph on average, cyclomatic complexity over 50, or a maintainability index under 65. |
Dead data
io.moderne.mainframe.analysis.table.DeadDataDeclared fields that nothing reads, and fields written but never read back.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.DeadData
| Column | Description |
|---|---|
| Program | The COBOL program. |
| Field | The field, qualified by the records containing it. |
| Section | Where it is declared. LINKAGE and FILE items are read and written by something outside this program, so they are reported separately rather than treated as unused. |
| Verdict | UNUSED for a field neither read nor written; DEAD_STORE for one written but never read back. |
| Picture | The declared picture, for sizing what would be saved by dropping it. |
| Copybook | The copybook the field came from, where it came from one. A field dead in this program may well be live in another that copies the same book, so a copybook field is only safe to drop once every program is checked. |
Unreachable procedures
io.moderne.mainframe.analysis.table.UnreachableProceduresParagraphs and sections that no path from the program's entry point reaches.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.UnreachableProcedures
| Column | Description |
|---|---|
| Program | The COBOL program. |
| Procedure | The unreachable paragraph or section. |
| Kind | Whether it is a paragraph or a section. |
| Position | Its position in source order, counting from zero. |
| Reachable procedures | How many procedures the program does reach, for comparison against its total. |
| Total procedures | How many procedures the program declares. |
PERFORM THRU range pathology
io.moderne.mainframe.analysis.table.ProcedureRangePathologyRanges that overlap without nesting, and jumps that leave a range part-way through.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ProcedureRangePathology
| Column | Description |
|---|---|
| Program | The COBOL program. |
| Kind | OVERLAPPING_RANGE for two ranges that partly overlap; RANGE_JUMP for a GO TO that leaves a performed range before its exit. |
| Range | The range concerned, as START THRU END. |
| Conflicts with | For an overlap, the other range. For a jump, the procedure jumped to. |
| Detail | Why it matters for anyone trying to restructure or extract the code. |
Mainframe migration blockers
io.moderne.mainframe.analysis.table.MainframeMigrationBlockersCICS and IMS constructs that need a design decision before a program can be moved.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.MainframeMigrationBlockers
| Column | Description |
|---|---|
| Program | The COBOL program. |
| Paragraph | The paragraph or section containing the construct. |
| Category | The kind of problem the construct poses. |
| Construct | The command or call that raised it. |
| Detail | What has to be decided, and why the construct does not carry over on its own. |
CICS command usages
io.moderne.mainframe.analysis.table.CicsCommandUsagesEvery EXEC CICS command, with the options it was given.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.CicsCommandUsages
| Column | Description |
|---|---|
| Program | The COBOL program containing the command. |
| Paragraph | The paragraph or section containing the command. |
| Command | The CICS command, including its qualifier where it has one, such as SEND MAP. |
| API group | The CICS API the command belongs to, which is the unit a Java replacement is chosen for. |
| Options | The command's options and operands as written. |
Copybook source information
org.openrewrite.mainframe.cobol.table.CopybookSourceInformation about copybook references in a COBOL source.
mod study . --last-recipe-run \
--data-table org.openrewrite.mainframe.cobol.table.CopybookSource
| Column | Description |
|---|---|
| Source path | The source path of the file that contains the copy statement. |
| Copybook name | The copybook name from a copy statement in a COBOL source. |
| Copybook source path | The source path of the copybook that was resolved during resolution of copybooks. |
| Resolution status | The status of the resolved copybook in a copy statement. |
| Marked word | The current word being visited from the post-processed LST. |
Copybook drift
io.moderne.mainframe.analysis.table.CopybookDriftFields that a copybook declares differently, or not at all, in different programs.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.CopybookDrift
| Column | Description |
|---|---|
| Copybook | The copybook whose copies disagree. |
| Field | The field the copies disagree about. |
| Variant | The picture this group of programs sees, GROUP for a field with no picture of its own, or ABSENT for programs whose copy does not declare the field at all. |
| Programs | The programs seeing this variant. |
| Program count | How many programs see it. A variant held by one program against twenty is a different problem from an even split. |
Copybook impact
io.moderne.mainframe.analysis.table.CopybookImpactEvery program that copies a copybook, what it does with each field, and what those fields reach there.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.CopybookImpact
| Column | Description |
|---|---|
| Copybook | The copybook the field is declared in. |
| Field | The field, qualified by the records containing it. |
| Picture | The picture as written in this program. A field whose picture differs between programs is not one field, whatever the copybook says. |
| Program | A program that copies the copybook. |
| Usage | READ, WRITTEN, BOTH, or UNUSED where the program copies the field and never touches it. Unused is the common case and the useful one: it is what makes a copybook change smaller than it looks. |
| Endpoints | What the field reaches in this program — the files, queues, maps and IMS segments a change to it would be visible at. |
Resource CRUD matrix
io.moderne.mainframe.analysis.table.ResourceCrudWhich programs create, read, update and delete which files, queues, DB2 tables and IMS segments, across CICS, DL/I, SQL and native file I/O.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ResourceCrud
| Column | Description |
|---|---|
| Program | The COBOL program. |
| Paragraph | The paragraph or section containing the statement. |
| Resource kind | Whether the store is a file, a temporary storage or transient data queue, a DB2 table or an IMS segment. |
| Resource | The resource as the program names it. |
| External name | What the resource is called outside the program — the ASSIGN name for a native file. This is the column two programs have to agree on before they can be said to share a store. |
| CRUD | CREATE, READ, UPDATE or DELETE. |
| Operation | The statement as written. Two accesses that agree on CRUD can still differ in ways worth seeing. |
| Dynamic | Whether the resource name came from a data item rather than a literal. |
Batch CRUD matrix
io.moderne.mainframe.analysis.table.BatchCrudWhich job step runs which program against which data set, and what the program does with it.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.BatchCrud
| Column | Description |
|---|---|
| Job | The job name, empty for a member with no JOB card. |
| Member | The JCL member. |
| Step | The step name. An unnamed step is empty, and cannot be referred to by a later step or by a scheduler. |
| Step program | The program the step names on PGM=. |
| Program | The program that names the file. Not always the step's program: a subprogram opens the DDs of the step that runs its caller. |
| DD name | The DD name, which is the only word the JCL and the program both contain. |
| File | The file as the program names it, from SELECT. |
| Written in | The member that asked for the DD, where the program's own text does not — a SAS %INCLUDE reads another member in where the statement stands, so what that member needs the step has to allocate. Empty for a DD the program names itself. |
| Data set | The data set as the installation knows it, with any member. |
| Data set kind | Whether the DD names a catalogued data set, a generation, a library member, something temporary, in-stream data, DUMMY, SYSOUT, or a data set passed by an earlier step. |
| Disposition | The DISP operand as written. The status is what says whether the step expects the data set to exist. |
| CRUD | CREATE, READ, UPDATE or DELETE, empty where nothing is bound. |
| Operations | The statements the CRUD was read from. |
| Binding | How far the DD name and the ASSIGN clause got towards meeting. Anything other than BOUND is a gap between the JCL and the program, or a limit of what the sources read can say. |
CICS resource usages
io.moderne.mainframe.analysis.table.CicsResourceUsagesWhich CICS resources each program touches, and how.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.CicsResourceUsages
| Column | Description |
|---|---|
| Program | The COBOL program touching the resource. |
| Paragraph | The paragraph or section containing the command. |
| Resource kind | Whether the resource is a file, a queue, a program, a transaction or a map. |
| Resource | The resource name. For a dynamic reference this is the resolved name where one literal reaches the operand, and otherwise the data name supplying it. |
| Access | What the command does to the resource. |
| Dynamic | Whether the resource name came from a data item rather than a literal. Dynamic references are the ones an automated migration has to leave to a person. |
| Command | The CICS command that produced this access. |
IMS DL/I calls
io.moderne.mainframe.analysis.table.ImsDliCallsEvery DL/I database and message call, however it was written.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ImsDliCalls
| Column | Description |
|---|---|
| Program | The COBOL program making the call. |
| Paragraph | The paragraph or section containing the call. |
| Interface | The DL/I language interface: CBLTDLI, AIBTDLI, CEETDLI, PLITDLI, or EXEC DLI. |
| Function | The DL/I function, such as GU, GN, ISRT, REPL or DLET. Empty when the function code is supplied by a data item that more than one literal reaches. |
| Function operand | The argument the function code was passed in, whether or not it resolved. |
| PCB | The PCB the call was issued against. |
| PCB position | The PCB's position in the PSB, counting from zero, or -1 when the program does not declare it at its entry point. The PSB has to be joined on this position to name the database, because nothing in the COBOL does. |
| Message call | Whether the call is against the I/O PCB, making it a message queue read or write rather than a database call. |
| Access | What the call does: READ, CREATE, UPDATE, DELETE, CHECKPOINT or SYSTEM. |
| Segments | Segment names the call is qualified by, where they could be resolved. |
JCL step detail
io.moderne.mainframe.analysis.table.JclStepDetailEvery data set each job step allocates, with the procedure the step came from and the attributes the data set is allocated with.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.JclStepDetail
| Column | Description |
|---|---|
| Job | The job name, empty for a member with no JOB card. |
| Member | The JCL member the job was read from. |
| Source path | The file the job was read from, which is the file to open at the line below. |
| Line | The one-based line the step's EXEC card is on. A step a procedure supplies is written in that procedure and has no line in the job, so it is the calling EXEC card that is given — the line the job's reader has. The procedure is read on its own as well, and its steps carry their own lines there. |
| Step number | Where the step falls in the job as it runs, procedures expanded, counting from one. Ordering by it is what makes the rows a step-by-step listing rather than a pile. |
| Procedure | The procedure the step is written in. Empty for a step written in the job itself; filled in with the procedure it calls when that procedure was not supplied, which is the one case where the step below it cannot be read. |
| Step | The step name, qualified by the step that called its procedure — EXTRACT.RUN — which is how a listing names it and how a DD override refers to it. |
| Program | The program the step loads, symbols filled in. A DL/I or BMP region names itself on PGM= and the program it loads in its PARM, and it is that program which is reported. |
| PSB | The PSB an IMS region step runs under, from its PARM. Empty for anything that is not one. |
| DD name | The DD name, which is the only word the JCL and the program both contain. |
| Data set | The data set as the installation knows it, with any member. A DD that concatenates several is one row each, because only the data set name joins one job to another. |
| Data set kind | Whether the DD names a catalogued data set, a generation, a library member, something temporary, in-stream data, DUMMY, SYSOUT, or a data set passed by an earlier step. |
| Generation | The relative generation of a generation data group, +1 for the one this step creates and 0 or -1 for one it reads. Empty for everything else. |
| Disposition | The DISP operand as written. The status is what says whether the step expects the data set to exist. |
| Record format | RECFM, from the keyword or from within DCB. |
| Record length | LRECL, from the keyword or from within DCB. 0 is written on purpose and is not the same as absent, so an omitted one is left empty. |
| Block size | BLKSIZE, from the keyword or from within DCB. 0 asks the system to choose one. |
| Space | The SPACE operand without its outer parentheses, CYL,(10,5),RLSE. Only a step that creates a data set writes one. |
| Unit | The UNIT operand, the device or esoteric group the data set is allocated on. |
| CRUD | The letters of everything the step's programs do to the data set — C, R, U, D, in that order. Empty where nothing in the run unit assigns the DD, or where the program was not among the sources read. |
Execution paths
io.moderne.mainframe.analysis.table.ExecutionPathsEvery job step with the program it runs, the procedure it came through, what its PARM passes, where its control cards are written, and the verdict on whether all of that could be read from the source supplied.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ExecutionPaths
| Column | Description |
|---|---|
| Job | The job name, empty for a member with no JOB card. |
| Member | The JCL member the job was read from. |
| Source path | The file the job was read from, which is the file to open at the line below. |
| Line | The one-based line of the EXEC card the path starts at. A step a procedure supplies is written in that procedure and has no line in the job, so it is the calling EXEC card that is given — the line the job's reader has, and the card a transformation would be applied to. |
| Step number | Where the step falls in the job as it runs, procedures expanded, counting from one. |
| Procedure | The procedure the step is written in. Empty for a step written in the job itself; filled in with the procedure it calls when that procedure was not supplied, which is the case where nothing below can be read. |
| Step | The step name, qualified by the step that called its procedure — UNLHST.UNL. This is the name the reasons below are written against. |
| Program | The program the step names on PGM=, with its symbols filled in. What that program then loads is its own business and is usually in the PARM beside it: an IMS region names itself here, and a utility names an engine that reads its real instructions off the control cards. |
| PARM | What PARM= passes the program, symbols filled in and the apostrophes that carried it taken off. Empty where the step passes none. |
| PARM positions | The same PARM split into the positions the program reads it as, separated by | , with a group left whole — ssid,uid,HIDDEN(user,pswd) is three positions and not four. A utility reads its parameters by position, so this is where the subsystem a step runs against is written. |
| DD name | The DD that hands the step a deck of control cards. Empty for a step handed none; a step handed several has a row each, since the cards rather than the JCL are what such a step really runs. |
| Cards | Where those cards are written: IN_STREAM in this member's own job stream, PROCEDURE in the stream of the procedure the step calls, MEMBER in the library member the DD names. Empty where the step is handed no cards. |
| Cards member | The data set and member the DD names, CLM.PROD.CTLCARD(UNLCLM01). Empty for cards written in a stream. Where the member name is itself a symbol the job passed, this is what it resolved to — which for a job whose deck is named only on DECK= is the one line that says what the job does. |
| Verdict | RESOLVED where every name was followed and everything the step does is written in what was read, INHERITED where every name was followed and part of what it does is a setting written outside the application libraries, UNRESOLVED where a name was not followed at all. Only RESOLVED is safe to rewrite without asking anyone anything. The verdict is the whole path's, so the rows of one path all carry it. |
| Reasons | Every reason the verdict is not RESOLVED, separated by ; , each written as the kind, the step and DD it was found under, and its subject — KEYWORD_INHERITED UNLPOL.UNL.SYSIN FORMAT. Empty for a resolved path. One row per reason, with the kinds counted, is ExecutionPathGaps. |
Execution path gaps
io.moderne.mainframe.analysis.table.ExecutionPathGapsOne row per reason a job step's execution path is not fully determined by the source supplied: the kind of gap, the step and DD it was found under, and what it is about.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ExecutionPathGaps
| Column | Description |
|---|---|
| Job | The job name, empty for a member with no JOB card. |
| Member | The JCL member the job was read from. |
| Source path | The file the job was read from. |
| Line | The one-based line of the EXEC card whose path this reason belongs to, which is the line of this file a reader opens. With the member it is the key back to the ExecutionPaths rows of the same path. |
| Step | The step the reason was found in, qualified by the step that called its procedure — a keyword left uncoded in a deck the procedure's SYSIN names is found in UNLHST.UNL and belongs to the path of UNLHST. |
| Kind | PROCEDURE_MISSING for a procedure that was not in the library supplied, SYMBOL_UNDEFINED for a symbol nothing sets, MEMBER_MISSING for a library member a DD names and nobody supplied, CARDS_NOT_READ for a deck that opens a statement of a language read here and could not be read as one, KEYWORD_INHERITED for a keyword a deck leaves to a setting written outside the application libraries. |
| DD name | The DD the reason was found under. Empty where it was not found under one — a missing procedure, or a symbol on the EXEC card itself. |
| Name | What the reason is about: the procedure, the symbol without its &, the member, or the keyword. Empty for CARDS_NOT_READ, where the DD is itself the subject. |
| Verdict | The verdict this kind of reason carries a path to: UNRESOLVED for a name that was not followed, INHERITED for behaviour that is a site setting. A path's own verdict is the worst its reasons carry. |
Control card kinds
io.moderne.mainframe.analysis.table.ControlCardKindWhat each control card deck is, and which steps read it. A control card library holds sort cards, IDCAMS cards, DSN command decks and parm cards side by side, and nothing in a member's name says which is which — the kind here is read off the deck's first statement. A deck written in a job stream is here too, under the job it is written in, where what it says types it.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ControlCardKind
| Column | Description |
|---|---|
| Member | The control card member, or the job a deck written in the stream is written in. A member two libraries hold has a row for each, which is how an environment's copy is told from the application's own. |
| Source path | The file the cards are in. |
| DD | The DD a deck written in the stream arrives on, empty for a member of its own. Which DD it is depends on the utility: DFSORT reads SYSIN, DFSPARM or a xxxxCNTL an ICETOOL USING names. |
| Line | The one-based line of that file the deck begins on, which is 1 for a member of its own. |
| Kind | DFSORT, IDCAMS, DSN, DB2_UTILITY or PLAIN, judged by the first statement the deck writes. A member is not typed by its name: the shops that call them SRTxxxxx and DEFxxxxx are following a convention, not a rule. |
| Statements | How many control statements the deck holds. 0 where no grammar has read it: a PLAIN or DSN deck, and a deck that reached the analysis as plain text because the ingestion did not run the parser that types it. |
| References | How many job steps read this member. 0 for a member nothing supplied here reads, which is either a deck run by hand or a job that was not supplied; 1 for a deck written in the stream, which is read by the step it is written in. |
| Referenced by | The steps that read it, as JOB.STEP(DD), joined with commas. A step reaching the deck through a procedure names the DD as it was written on the override, RUN.SYSTSIN. |
Load module composition
io.moderne.mainframe.analysis.table.LoadModuleCompositionWhat each load module is built from, one row per program, map set or external routine bound into it, read from the link-edit deck that declares the module and from the listing that reports the module as built. Neither the COBOL nor the JCL says which programs share a module: a step names a module and runs whatever the binder last put in it, so a change to a statically bound subroutine is felt by every module holding a copy and by nothing else.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.LoadModuleComposition
| Column | Description |
|---|---|
| Module | The load module, which is the name a step, a CALL or a CICS program definition asks for. |
| Library | The load library the module is written to, from the SYSLMOD of the step that links it or from the listing. Which library a module is in is what tells a batch module from a CICS one where both carry the program's name. |
| Part | A program, map set or external routine the module holds. Every module holds the program of its own name; a statically called subroutine is a second part of every module that includes it. |
| Part kind | PROGRAM, ASSEMBLER or MAPSET where the part was read, STUB for a language interface known by name, EXTERNAL for an object nobody supplied. Runtime sections the binder's autocall pulls in are not parts and get no row. |
| Part path | The part's file, empty for a stub or an external routine. A module built from a program no ingestion holds is how a gap shows. |
| Reconciliation | BOTH where the deck declares the part and the listing reports it, DECLARED_ONLY where the module has not been listed since the deck was written, OBSERVED_ONLY where the module holds something no deck asked for — the module in the library and the deck in the library have drifted apart — and BUILT_ONLY where a job writes the module and neither describes it. |
| Inferred | True where no card names the part. The compile hands the binder its object on SYSLIN without naming it, so the program a module is named for is a part of it that the deck does not write down; every other part is on a card of its own. |
| Entry point | Where control enters the module: the program's own section, or a label in it such as the DLITCBL a DL/I batch program declares. |
| Aliases | The module's other directory entries, space separated. An alias is a second name the same module answers to, which is how a renamed program goes on being called by its old name. |
| Deck | The link-edit deck that declares the module, empty where none was read. A deck written in a job stream is that job. |
| Deck line | The line of the deck the part's INCLUDE card is on, or of the NAME card for the program the module is named for. Zero where no deck declares the part. |
| Listing | The listing the module was read from, empty where none covers it. A listing is what was printed on the day it last ran, so a module built since is missing from it rather than absent from the library. |
| Listing line | The line of the listing the part's control section is reported on. Zero where no listing covers the module. |
| Linked by job | The job whose step reads the deck, empty where no job read here does. |
| Linked by step | The step of that job, which is what has to be rerun to rebuild the module. |
| Loaded by job | A job whose step runs this module, empty where none does. Four cards say so: PGM=, the PARM an IMS region takes its program in, the RUN PROGRAM of a DSN deck the step reads, and the APPLCTN of a stage 1 deck — which is not a job at all, and names the stage 1 member instead. A module several steps run has a row for each. |
| Loaded by step | The step that runs it, named as the job writes it rather than as the procedure does, or APPLCTN for a module the IMS message region loads. |
DB2 bind chain
io.moderne.mainframe.analysis.table.Db2BindChainWhat each bind card declares, one row per plan or package it names: the deck it is written in, the job that runs that deck, the collection the package lands in, the DBRM it is bound from and the program that DBRM was precompiled from. The deck is the only place the chain from a plan to the program that runs under it is written down — neither the COBOL nor the JCL says any of it.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.Db2BindChain
| Column | Description |
|---|---|
| Deck | The member the deck is: a bind library member under its own name, or the job the deck is written in the stream of. |
| Deck path | The file the card was written in. |
| Line | The one-based line of that file the subcommand begins on, counting from the top of the job for a deck written in-stream. |
| Command | BIND where the card makes the object, REBIND where it names one that already exists. Only a BIND says what an object is bound from. |
| Binds | Whether the card binds a PLAN or a PACKAGE. |
| Plan | The plan, empty for a package bind. A plan is what a batch step names in RUN PROGRAM(...) PLAN(...) and what the CICS resource definition names. |
| Collection | The collection the packages are bound into, empty for a plan bind. This is the name an environment varies: the same deck binds into another collection on another subsystem. |
| Package | The package, empty for a plan bind. * where a REBIND names every package of the collection rather than one. |
| DBRM | The DBRM member the package is bound from, from MEMBER. Empty for a plan bind and for a REBIND, which is bound from whatever it was bound from before. |
| Program | The program the DBRM was precompiled from. A DB2 precompile writes the DBRM under the program's own name, so the DBRM member, the package and the program are the same word — this is the join from a plan to the code that runs under it. |
| Program path | The program's file, empty where no program of that name was read. A bind for a program nobody supplied is how a gap in an ingestion shows. |
| Package list | The packages a plan may run, from PKLIST, as written: an entry names a collection and either one package or * for all of them. Empty for a package bind. |
| Qualifier | What unqualified table names in the package resolve to. This is the schema the SQL in the program actually reads, which the program never names. |
| Owner | The authorization identifier the object is owned by. |
| Job | The job whose step runs this deck, empty where no job read here does. A deck run by two jobs has a row for each. |
| Step | The step of that job, which is where the bind is placed among the compiles. |
DB2 package plans
io.moderne.mainframe.analysis.table.Db2PackagePlansThe bind chain read from the package's side: which plans may run each package, and so which plans a change to the program behind it is felt under. A plan lists either the package outright or the whole collection with *, so the plans a package runs under are written down nowhere one name at a time.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.Db2PackagePlans
| Column | Description |
|---|---|
| Collection | The collection the package is bound into. |
| Package | The package. |
| Program | The program the package is bound from, which is the DBRM member of the same name. Empty where no bind read here says what the package holds. |
| Plan | A plan that may run the package. Empty where none read here lists it. |
| Listed as | PACKAGE where the plan's PKLIST names the package outright, COLLECTION where it names the collection with * and so picks up every package bound into it, NOT_LISTED where no plan reaches it. |
| Package deck | The deck the package is bound in. |
| Plan deck | The deck the plan is bound in, which is often not the one the package is bound in. |
DB2 tables
io.moderne.mainframe.analysis.table.Db2TablesOne row per table the DDL creates: where it is defined, what it is made of, and who reaches it. This is the summary a person opens a table on — the columns, the primary key, the foreign keys either way and the indexes, with the programs, packages and plans that use it — so the question "what is this table and what would a change to it break" is one row rather than a search.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.Db2Tables
| Column | Description |
|---|---|
| Table | The table, qualified as the DDL wrote it. This is the name the SQL in a program has to resolve to, and the one an unqualified name is resolved against the bind qualifier to reach. |
| Schema | The qualifier the table was created under, empty for a table created unqualified — which leaves it to whatever SET CURRENT SQLID was in force. |
| Name | The table's own name, without its schema. |
| Table space | The table space the table lives in, empty where the DDL leaves it to DB2. This is what a RUNSTATS or a REORG card names, so it is the join from a table to the utility jobs that maintain it. |
| Member | The DDL member the table is created in, or the job that creates it in its own stream. |
| Source path | The file the CREATE TABLE was read from, which is the file to open at the line below. |
| Line | The one-based line of that file the CREATE TABLE begins on, counting from the top of the job for DDL written in a stream. |
| Written | Whether the DDL is a member of a library or written in a job's stream. A table created in a stream exists nowhere else, so the job is its definition and not just the thing that ran it. |
| Columns | How many columns the table has. |
| Primary key | The primary key's columns in key order, empty for a table declaring none — which happens, and is then enforced by a unique index instead. |
| Foreign keys | How many foreign keys this table declares, which is how many parents it has. |
| Referenced by | How many foreign keys point at this table, which is how many children it has. A table with children cannot have a row deleted without deciding what happens to them. |
| Indexes | How many indexes are defined on the table. |
| Programs | How many programs name the table in an EXEC SQL statement, unqualified names resolved against the qualifier their package was bound with. |
| Packages | How many DB2 packages reach the table, which is the programs above joined to the bind decks that bind them. |
| Plans | How many plans reach the table through those packages, a PKLIST naming a whole collection expanded. Every plan counted here has to be rebound when the table changes. |
DB2 columns
io.moderne.mainframe.analysis.table.Db2ColumnsEvery column of every table the DDL creates, in the order a SELECT * and a host structure both take: what it holds, whether it may be absent, where it sits in the primary key, the table it points at through a foreign key, and the indexes it is a key of. The last is what says whether a predicate written on the column has an access path or a table space scan behind it.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.Db2Columns
| Column | Description |
|---|---|
| Table | The table the column belongs to, qualified as the DDL wrote it. |
| Ordinal | Where the column sits in the table, counting from one. This is the order a SELECT * and a host structure both take, so it is what aligns a column with the COBOL field receiving it. |
| Column | The column name. |
| Type | The type as the DDL writes it, length and scale included: CHAR(12), DECIMAL(9, 2), DATE. |
| Nullable | Whether the column may hold no value. A primary key column may not, whether or not the DDL says NOT NULL — DB2 requires it and supplies it when it is left out. A nullable column is the one a program has to fetch with an indicator variable. |
| Key sequence | Where the column sits in the primary key, counting from one, or 0 for a column that is not part of it. |
| Foreign key to | The table this column points at through a foreign key, empty where it points at none. A column carrying two foreign keys names both. |
| Indexes | The indexes the column is a key of, each with its position in that key and the direction it is held in — CLM.XPOLICY1(2 ASC). A column with none is a column no predicate can be selective on. |
| Member | The DDL member the column is declared in, or the job that declares it in its own stream. |
| Source path | The file the column was read from, which is the file to open at the line below. |
| Line | The one-based line of that file the column is declared on. |
DB2 primary keys
io.moderne.mainframe.analysis.table.Db2KeysThe primary key of each table, one row per key column in key order, with the unique index that enforces it. DB2 will not accept a primary key without one, so a key whose index is missing here is DDL that would not run — and the index is also the access path every foreign key check and every keyed read goes through.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.Db2Keys
| Column | Description |
|---|---|
| Table | The table the key belongs to, qualified as the DDL wrote it. |
| Constraint | The name the DDL gives the constraint, empty where it names none — which is usual for a primary key, and leaves DB2 to name it after the index. |
| Column | The key column. |
| Key sequence | Where the column sits in the key, counting from one. A composite key is only usable left to right, so the order is the whole of what it is good for. |
| Enforced by | The unique index whose key is exactly these columns, empty where the DDL read here declares none. DB2 requires one and creates it implicitly when a shop lets it, so an empty value means the index was not supplied rather than that there is none. |
| Member | The DDL member the key is declared in, or the job that declares it in its own stream. |
| Source path | The file the key was read from, which is the file to open at the line below. |
| Line | The one-based line of that file the PRIMARY KEY is written on. |
DB2 indexes
io.moderne.mainframe.analysis.table.Db2IndexesEvery index the DDL creates, with the table it is on and the key it holds. An index is how a batch job reaches a table cheaply, so which columns it is keyed on is which predicates the schema was designed to answer — and an index no program writes a predicate for is maintenance nothing collects on.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.Db2Indexes
| Column | Description |
|---|---|
| Index | The index, qualified as the DDL wrote it. |
| Table | The table the index is on, qualified as the DDL wrote it. |
| Unique | Whether the index enforces uniqueness, which is what a primary key needs and what a shop with no primary key uses instead of one. |
| Key columns | The key in order, each column with the direction it is held in — STATUS_CODE ASC, POLICY_NO ASC. A composite key is only usable left to right. |
| Enforces the primary key | Whether this is the unique index whose key is exactly the table's primary key, which is the index DB2 requires a primary key to have. |
| Member | The DDL member the index is created in, or the job that creates it in its own stream. An index added to a live table years after its table is routinely in a job of its own, and that job is the only place it exists. |
| Source path | The file the CREATE INDEX was read from, which is the file to open at the line below. |
| Line | The one-based line of that file the CREATE INDEX begins on, counting from the top of the job for DDL written in a stream. |
DB2 foreign keys
io.moderne.mainframe.analysis.table.Db2ForeignKeysOne table pointing at another, which is the referential arrow of the model diagram and the one relationship between two tables that can be read without reading a program. A key is written either in the CREATE TABLE or in an ALTER TABLE afterwards, and both are read here.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.Db2ForeignKeys
| Column | Description |
|---|---|
| Constraint | The name the DDL gives the relationship, empty where it names none. This is the name a -904 or a load utility message reports, so it is worth carrying even though nothing joins on it. |
| Table | The child table, the one holding the key, as the CREATE TABLE that creates it names it — or as the key names it where nothing here creates one. |
| Columns | The child's columns, in key order. |
| Referenced table | The parent table the key points at. |
| Referenced columns | The parent's columns, in key order. The DDL usually leaves these out and means the parent's primary key, and that key is filled in here — a row with a parent and no columns would say less than the DDL does. |
| Delete rule | What DB2 does to the child's rows when a parent row goes away: RESTRICT, CASCADE, SET NULL or NO ACTION. Empty where the DDL leaves it to the default of NO ACTION. |
| Member | The DDL member the key is declared in, or the job that declares it in its own stream. |
| Source path | The file the key was read from, which is the file to open at the line below. |
| Line | The one-based line of that file the FOREIGN KEY is written on. |
Db2 unloads
io.moderne.mainframe.analysis.table.Db2UnloadsEvery unload a job runs, the dialect its control cards are written in, what it unloads and where it writes it, and what it would take to run the same unload on the base Db2 utility.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.Db2Unloads
| Column | Description |
|---|---|
| Job | The job name, empty for a member with no JOB card. |
| Member | The JCL member the job was read from. |
| Source path | The file the job was read from, which is the file to open at the line below. |
| Line | The one-based line of the EXEC card written in that member. A step a procedure supplies has no line in the job, so it is the calling card that is given — the card a transformation would be applied to. |
| Step | The step name, qualified by the step that called its procedure — UNLHST.UNL. |
| Program | The program the step names on PGM=, with its symbols filled in. It does not say which engine runs: the unload product reads three vendors' dialects through one program name of its own, and a shop may alias the base utility's program to the product's compatibility entry point. |
| Dialect | The language the control cards are written in: HIGH_PERFORMANCE_UNLOAD for the unload product's own, BASE_UTILITY for the one the Db2 utilities read. This, and not the program name, is what says which engine runs. |
| Proven by | What in the deck settled the dialect — the SELECT and OUTDDN of the product, the FROM TABLE or SHRLEVEL of the base utility — and, where the program name says otherwise, that it does. |
| Deck | The control card member the cards are written in, or the JCL member for a deck written in the job stream. |
| Deck path | The file that member was read from, empty where the member was named but not supplied. |
| Deck line | The one-based line of that file the UNLOAD statement is written on. |
| Cards | Where the cards are written: IN_STREAM in this member's own job stream, PROCEDURE in the stream of the procedure the step calls, MEMBER in the library member the DD names. |
| Table space | The table space unloaded, empty where the deck leaves it to be worked out from the tables the SELECTs name — which an image copy unload does. |
| Tables | The tables the rows come from, separated by , : one per SELECT in the product's dialect, one per FROM TABLE in the base utility's. |
| Selects | How many SELECT or FROM TABLE blocks the unload writes. More than one is one pass over the table space fanned out to several files, and the base utility needs a statement and a pass each. |
| Output DDs | Every DD the rows are written to. The product has no default and every deck names its own; the base utility defaults to SYSREC, so these names are written twice — once here and once in the JCL — and a change to either has to be a change to both. |
| Load card DDs | Every DD the generated LOAD cards are written to. The base utility defaults this one to SYSPUNCH. A name here may be a TEMPLATE of the deck rather than a DD of the job. |
| Copy DD | The DD an image copy is read from instead of the table space, empty where the unload reads the table space. LAST_IC or a negative number is a catalog search the base utility does not do. |
| Formats | The layout each SELECT writes. A SELECT that codes none is not listed, because what it writes is then a site setting rather than something the deck says. |
| Access | How the rows are read: NO off the data sets outside Db2, FORCE through a dynamic cursor, YES for either as the SQL allows. The bytes written are not the same across the three. Empty where the deck leaves it to the site parmlib. |
| Consistency | What the deck says about reading a table space somebody else may be writing — LOCK YES QUIESCE YES in the product's dialect, SHRLEVEL REFERENCE in the base utility's. The two are not one for one: only LOCK YES QUIESCE YES, and LOCK YES under DB2 FORCE, are documented as ensuring consistency. |
| Verdict | How far the step reads, from FindExecutionPaths: RESOLVED, INHERITED where a keyword comes from the site parmlib, UNRESOLVED where a name was not followed at all. |
| Migration | What it would take to run this unload on the base utility: ALREADY_THE_TARGET for a deck already written in its language, MAPS_KEYWORD_FOR_KEYWORD where IBM's own option table covers every keyword, NEEDS_REDESIGN where it does not, NOT_DECIDABLE where the source does not say enough to judge. |
| Evidence | Why that verdict, separated by ; — the keywords the mapping covers, the constructs it does not, or the reasons the path could not be read. A verdict nobody can check is a verdict nobody will act on. |
Control-M schedule
io.moderne.mainframe.analysis.table.ControlMScheduleEvery job the scheduler runs, with the JCL member it submits. A JCL member says what a job does and nothing anywhere else says when it runs, out of which library the member is taken, or under which table and application it is ordered — so this is the far end of the batch estate, and the row carries the definition as written for the Scheduler Info report.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ControlMSchedule
| Column | Description |
|---|---|
| Job | The name the scheduler knows the job by. A table is a job too, and carries its own scheduling days and conditions. |
| Table | The table the job is ordered in, which is the folder it is written under in an export and the panel's GROUP field otherwise. A table names itself. |
| SMART table | Whether that table is a SMART table — one ordered, held and rerun as a unit, and so worth a containment edge — rather than a plain folder. Two folders of the same name, one of each kind, is a real export; nothing but this tells their jobs apart. A panel says which table a job is in but not what kind, so a job read from one always answers false, and so does a table itself. |
| Group | The group the definition names for itself: the panel's GROUP, the export's SUB_APPLICATION. The panel writes one field where the export writes two, so on a panel this is the table again. |
| Member name | The JCL member submitted, from MEMNAME. Empty for a table, which runs the jobs under it rather than a member of its own. |
| Member library | The library the member is taken from, from MEMLIB. Two applications routinely schedule a member of the same name out of different libraries. |
| Application | The application the job is ordered under. |
| Task type | Job for a member submitted to JES, SMART Table for a table, and a dozen others for the work the scheduler does itself. |
| Calendars | The calendars the scheduling days are validated against, each as the kind of decision it makes and the calendar name: CONFIRMATION says which days the job may run on at all, DAYS and WEEK which of the days written apply. |
| JCL path | The file the member was read from, empty where no member of that name was read. A schedule for a member nobody supplied is how a gap in an ingestion shows. |
| Definition path | The file the definition was written in: the export, or the member holding the one panel. |
| Definition line | The one-based line of that file the definition begins on. |
| Definition | The definition as written, which is what the Scheduler Info report shows. A table carries its jobs inside it, so a table's own definition is its opening tag. |
Control-M dependencies
io.moderne.mainframe.analysis.table.ControlMDependenciesWhich job the scheduler runs before which, one row per pair. Nothing in a schedule names another job: a job adds a condition when it ends and another job waits for that name, so the order the night runs in is only readable by joining the two — and the join holds across tables and across applications without either side saying so.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ControlMDependencies
| Column | Description |
|---|---|
| Predecessor | The job that adds the condition, which is the one that has to end first. |
| Predecessor table | The table the predecessor is ordered in. |
| Predecessor path | The file the predecessor's definition was written in. |
| Predecessor line | The one-based line of that file the predecessor's definition begins on. |
| Successor | The job that waits for the condition. |
| Successor table | The table the successor is ordered in. |
| Successor path | The file the successor's definition was written in. |
| Successor line | The one-based line of that file the successor's definition begins on. |
| Condition | The name both jobs write and neither explains. Shops name it after the predecessor, which is convention rather than syntax — a chain whose names do not follow it still runs in this order. |
| Order date | The run the successor asks for the condition on: ODAT for today's, PREV for the one before, which is how a job waits on the work of the night before rather than on tonight's. |
| Across tables | Whether the two jobs are ordered in different tables. A chain inside one table is what an operator sees on one screen; one that leaves it is the dependency nobody remembers is there. |
Control-M calendars
io.moderne.mainframe.analysis.table.ControlMCalendarsThe days each calendar has, a row per year it carries. A schedule writes the days a job is a candidate to run on and the calendar decides which of those the shop is open for, so the days a job really runs are only readable by decoding the year as exported: twelve months of thirty-one positions, Y or N, a position past the end of a month being N.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ControlMCalendars
| Column | Description |
|---|---|
| Calendar | The name the schedules refer to it by. |
| Type | Regular for a calendar of dates, Periodic for one whose days are named periods, Rule Based for one generated from a rule. |
| Data center | The Control-M data center the calendar is defined in. The same name is routinely defined in several, with different days in each. |
| Year | The year these days are in, or 0 for a calendar carrying no year — which is either a rule-based one or, where no file defines it at all, a gap in what was supplied. |
| Days | How many days of that year the calendar has. |
| Dates | Every day the calendar has, in order, as ISO dates. This is what turns "runs on CLMWORK" into the year calendar of execution days. |
| Definition path | The file the calendar was defined in, empty where a schedule names one no export defines. |
| Definition line | The one-based line of that file the definition begins on. |
Build order
io.moderne.mainframe.analysis.table.BuildOrderEvery order the build requires between two jobs, with what the scheduler does about it. A link-edit deck that includes an object binds whatever the object library held when the binder ran, so the job that compiles the object has to have run first — and no one file says so: the deck names a member, the JCL names the library it is written to and read from, and only the scheduler can make one job wait for another.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.BuildOrder
| Column | Description |
|---|---|
| Module | The load module whose deck requires the order. |
| Deck | The link-edit deck that includes the object. A deck written in a job stream is that job. |
| Deck line | The one-based line of the deck the INCLUDE card is on. |
| Object | The member the card includes, which is the compiled subroutine, map set or assembler object bound into the module. |
| Object data set | The library member the include resolves to, from the DD the card names as the linking step allocates it. This is what joins the deck to the job that writes the object. |
| Producer job | The job that writes the object, which is the one that has to run first. |
| Producer step | The step of that job, on whose SYSLIN or SYSLMOD the object is written. |
| Producer schedules | The scheduler's jobs that submit the producing member, comma separated. Empty where nothing schedules it. |
| Consumer job | The job that link-edits the module, which is the one that has to run second. |
| Consumer step | The step of that job that reads the deck. |
| Consumer schedules | The scheduler's jobs that submit the consuming member, comma separated. Empty where nothing schedules it. |
| Enforcement | ENFORCED where the consumer waits on a condition the producer adds, ENFORCED_THROUGH where the conditions in between impose the order anyway, MISSING where both are scheduled and neither waits for the other, UNSCHEDULED where one of them has no schedule at all, and SAME_JOB where one job does both and its own step order decides it. |
| Enforced through | The jobs the order runs through where no condition joins the two directly, producer first: CLMASMB > CLMCMPC > CLMCMPI. Empty for every other verdict. |
Schedule coverage
io.moderne.mainframe.analysis.table.ScheduleCoverageEvery job of the JCL library with the schedules that order it. A JCL member says what a job does and never says when it runs, so a member with no schedule is one somebody submits by hand, or one nothing runs at all — and either way it is outside everything the operations side of the estate is documented and monitored by.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ScheduleCoverage
| Column | Description |
|---|---|
| Job | The JCL member, which is the name a schedule's MEMNAME writes. |
| Source path | The file the job was read from. |
| Schedules | The scheduler's jobs that submit this member, comma separated. A member two applications order is submitted by a job of each. |
| Tables | The tables those jobs are ordered in, comma separated, which is where an operator looks for them. |
| Definitions | The files the schedules were read from, comma separated. A shop that supplies both the panel and the export supplies each job twice. |
| Verdict | ORDERED, or UNSCHEDULED for a job no schedule submits. |
IMS segment access
io.moderne.mainframe.analysis.table.ImsSegmentAccessEvery DL/I call with the database it reaches, which the COBOL never names: the call gives a PCB and the PSB turns that into a database, and only then does the segment name mean something.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ImsSegmentAccess
| Column | Description |
|---|---|
| Program | The program making the call. |
| Paragraph | The paragraph or section the call is in. |
| Interface | CBLTDLI, AIBTDLI, CEETDLI, PLITDLI or EXEC DLI. Which one it is decides how the PCB is named: by position in the entry list, by PCBNAME in the AIB, or by number among the database PCBs. |
| Function | The DL/I function, such as GU, GN, ISRT, REPL or DLET. |
| CRUD | CREATE, READ, UPDATE, DELETE, CHECKPOINT or SYSTEM, from the function. |
| PSB | The PSB the program runs under, empty where nothing says which one. A batch program's PSB is on the PARM of the region step; a message driven program's is the APPLCTN macro of the stage 1 deck. |
| PCB | The PCB as the PSB names it — its PCBNAME, else the PSB and the position, written CLMPSB02(3). |
| PCB position | The PCB's one-based position among the PSB's PCB statements, or zero where it did not resolve. This is not the mask: an I/O PCB is a mask and not a PCB statement. |
| Mask | The one-based position of the PCB in the program's entry list, or zero for a call that names its PCB rather than counting to it. |
| Reaches | SEGMENT for a database call, MESSAGE_QUEUE for the queue or the scratchpad, LOG for a checkpoint or restart, SEQUENTIAL for a GSAM record, UNRESOLVED where no PSB answered for the PCB. |
| Database | The IMS database the PCB opens, empty where the PCB is not a database one or did not resolve. This is the column nothing in the COBOL carries. |
| Index database | The secondary index the PCB's PROCSEQ walks the roots in, empty where it has none. A call through such a PCB reaches the database through the index. |
| Segments | The segments the call's search arguments name, space separated. A path call names several and reaches them all in the one call. |
| Source path | The program's file. |
| Line | The one-based line the call is written on. |
IMS chain
io.moderne.mainframe.analysis.table.ImsChainOne row per path from something that starts a program to a database it may reach: a transaction code or a job step, the program, the PSB it runs under, one PCB of that PSB, and the database and segments behind it.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ImsChain
| Column | Description |
|---|---|
| Start kind | TRANSACTION where a message schedules the PSB, JOB_STEP where a region step runs it. |
| Start | The transaction code, or the job. |
| Step | The job step, empty for a transaction. |
| Program | The program the region loads, empty where nothing in the estate says which one. A batch region takes it on the PARM beside the PSB; a message region loads the module named for the PSB, so which program that module holds is the link-edit deck's to say. |
| Program path | The program's file, empty where it was not read here. |
| PSB | The PSB, which is what turns a PCB position into a database. |
| PSB path | The PSB's file, empty where no gen source for it was read. |
| PCB | The PCB as the PSB names it — its PCBNAME, else the PSB and the position. |
| PCB position | The PCB's one-based position among the PSB's PCB statements. |
| PCB type | DB for a database PCB and GSAM for a sequential one. Message PCBs get no row: they reach the terminal network rather than a database. |
| Processing options | The PROCOPT the PCB opens the database with, which is what says whether the path is a read or a write. |
| Database | The IMS database the PCB opens. |
| Database path | The DBD's file, empty where no gen source for it was read. |
| Index database | The secondary index named on PROCSEQ, empty where the PCB has none. |
| Sensitive segments | The segments the PSB lets the program see through this PCB, space separated. GSAM has none. |
| Segments | The segments the program's calls through this PCB actually name, space separated. Narrower than the sensitive list wherever a program is given more than it uses, and empty where the program was not read. |
IMS databases
io.moderne.mainframe.analysis.table.ImsDatabasesOne row per DBD: how it is organised, the DD names a job has to supply for it, and what it holds.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ImsDatabases
| Column | Description |
|---|---|
| Database | The DBD name, which is what a PCB's DBDNAME and a stage 1 DATABASE macro name it by. |
| Organization | HDAM, HIDAM, HISAM, INDEX, GSAM or LOGICAL — the first operand of ACCESS, which says how a segment is found. |
| Access method | The operating system access method under it, VSAM or BSAM, from the second operand of ACCESS. |
| Randomizer | The RMNAME module an HDAM database hashes its root keys with, empty for every other organization. |
| DD names | The DD names the DATASET statements ask for, space separated. This is also an edge to every job step that runs against the database, since the step has to supply them. |
| Root segment | The segment with no parent, empty for GSAM, which has no segments at all. |
| Segments | How many segments the DBD defines. |
| Fields | How many FIELD statements it defines across those segments. |
| Record lengths | The RECORD lengths of a GSAM or HISAM data set group, space separated, empty where none is written. |
| References | The other databases this one names and why, written LOGICAL_PARENT CLMDBD02.POLROOT, space separated. A logical relationship and a secondary index are the only ways one DBD names another. |
| Source path | The gen source the DBD is written in. |
| Line | The one-based line of the DBD statement. |
IMS segments
io.moderne.mainframe.analysis.table.ImsSegmentsThe segment hierarchy of each DBD: the parent, the length, the sequence field and the fields with their offsets, which is the layout the copybook a program reads it into has to agree with.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ImsSegments
| Column | Description |
|---|---|
| Database | The DBD the segment belongs to. |
| Segment | The segment name, which is what a search argument's first eight bytes carry. |
| Parent | The physical parent, empty for the root. |
| Level | How far down the hierarchy the segment sits, 1 for the root. |
| Bytes | The BYTES length, which is the length of the I/O area a program reads it into — unless the PCB is field sensitive, in which case the SENFLD list is. |
| Sequence field | The field the segment is keyed on, empty where it has none. |
| Sequence start | The one-based byte the sequence field starts at, zero where there is none. |
| Sequence length | How many bytes the sequence field is, zero where there is none. |
| Unique | Whether the sequence field is unique, which is what decides whether two occurrences can share a key. |
| Fields | Every FIELD of the segment, written CLMKEY 1(10) with a type where one is given, space separated and in source order. |
| Logical parent | The segment in another database this one is the logical child of, written CLMDBD02.POLROOT, empty where it is not one. |
| Logical children | The logical children pointed at from here, space separated. Written on the parent's side, which is the side a reader of the DBD sees first. |
| Secondary indexes | The indexes built over this segment, written CLMDBX01.CLMXSEG on CLMXADJ, space separated. The XDFLD says which field is indexed and the LCHILD says which database holds the index. |
| Source path | The gen source the segment is written in. |
| Line | The one-based line of the SEGM statement. |
IMS field-sensitive I/O areas
io.moderne.mainframe.analysis.table.ImsFieldSensitiveAreasWhat a field-sensitive PCB hands a program, against the copybook the program reads it with. Where a PCB carries SENFLDs the I/O area is not the segment: it holds those fields, at those offsets, and a program using the whole segment's layout reads every field after the first omission out of the wrong bytes.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ImsFieldSensitiveAreas
| Column | Description |
|---|---|
| Program | The program making the call. |
| PSB | The PSB the program runs under. |
| PCB | The PCB as the PSB names it — its PCBNAME, else the PSB and the position, written CLMPSB02(2). |
| Segment | The segment the SENSEG names, which is the one the call asks for. |
| Sensitive fields | The SENFLDs in the order they build the area, each with the byte it starts at: CLMKEY 1 CLMPOL 11. A field of the segment that is not here is not in the area. |
| Expected bytes | How long the area is: the last SENFLD's start plus the length the DBD gives that field. Zero where a SENFLD names a field the DBD does not. |
| I/O area | The data item the call moves the segment into. |
| Copybook | The copybook that declares the I/O area, empty where the program declares it itself. |
| Copybook bytes | How many bytes that declaration describes, zero where it cannot be laid out. |
| Verdict | MATCH where the copybook is the length the SENFLDs build, DIFFERENT_LENGTH where it is not, UNKNOWN where one of the two lengths could not be worked out. |
| Source path | The program's file. |
| Line | The one-based line the call is written on. |
Screen fields
io.moderne.mainframe.analysis.table.ScreenFieldsEvery field of every screen, where it is drawn and which COBOL data item reaches it. CICS generates a symbolic map the program moves values into, and IMS supplies an area the program lays a copybook over, so the two halves are joined differently and both are here.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ScreenFields
| Column | Description |
|---|---|
| Technology | BMS for a CICS map set, MFS for an IMS format set. |
| Map set or format set | The DFHMSD for BMS, the FMT for MFS. |
| Map or page | The DFHMDI for BMS, the DPAGE for MFS. A format set with two device pages carries the same labels twice at different positions, which is why the page is part of what names a field. |
| Message or record | For MFS, the MSG that carries the field — the MID it arrives on or the MOD it goes out on. For BMS, the symbolic map record the program's item is declared in. Empty for a field no message and no program reaches. |
| Field | The label the map set or format set gives the field. Empty for a literal written straight onto the screen, which no program can name. |
| Row | The line the field starts on, counted from one. Zero where the definition gives no position, which is what a message field carrying a literal does. |
| Column | The column the field starts at, counted from one. BMS counts the attribute byte here and paints the data from the next column; MFS counts the first byte of the data itself. |
| Length | How many characters the field occupies on the screen, or how many bytes it occupies in the message where it is only in the message. |
| Attributes | How the field is drawn and whether it can be typed into, space separated and as the definition writes them: ASKIP NORM for BMS, PROT HI for MFS. |
| Initial value or literal | The text the field is drawn with whatever the program does, from BMS INITIAL= or the MFS literal. Padding is kept, because it is what decides how wide the field is. |
| Program | The COBOL program that reaches the field. Empty where nothing analysed does, which for a labelled field is worth reading twice. |
| Data item | What the program calls the field. For BMS this is the generated item the program names — TITLEO and TITLEL are the same field. For MFS the program names nothing, so this is the copybook item lying at the field's displacement, matched by order and length and never by name. |
| Subfield or offset | For BMS which part of the field the item is: OUTPUT carries the value, LENGTH says how much the operator typed, COLOR how it is drawn. For MFS the field's displacement in the message area, counted from zero and past the four byte prefix IMS supplies and no MFLD describes. |
| Source path | The map set or format set the field is defined in. |
| Line | The one-based line of the DFHMDF or DFLD. |
Screen lines
io.moderne.mainframe.analysis.table.ScreenLinesEach screen as the terminal paints it, one row per line: the literals where they are written and an underscore for every character the program supplies. This is what a green screen viewer draws, and what makes a map set readable without a terminal.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ScreenLines
| Column | Description |
|---|---|
| Technology | BMS for a CICS map set, MFS for an IMS format set. |
| Map set or format set | The DFHMSD for BMS, the FMT for MFS. |
| Map or page | The DFHMDI for BMS, the DPAGE for MFS. |
| Device | What the screen is drawn on: the BMS TERM=, or the MFS DEV TYPE= with its model. A printer is laid out the same way and is not a screen anybody types into. |
| Rows | How many lines the screen holds: 12 for a model 1, 24 for a model 2, or the BMS SIZE=. Where the device says nothing, the last line a field is on. |
| Columns | How many characters wide the screen is, which is what a BMS POS=n displacement is counted against. |
| Row | Which line of the screen this is, counted from one. |
| Text | The line as it is painted: literals in place, an underscore for every character a field supplies, and a blank everywhere the map writes nothing. Trailing blanks are kept so the columns line up. |
| Source path | The map set or format set the screen is defined in. |
Record layouts
io.moderne.mainframe.analysis.table.RecordLayoutsThe same record described in two languages, field by field, with where the two descriptions disagree.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.RecordLayouts
| Column | Description |
|---|---|
| Record | The layout being compared: the control section of an assembler DSECT, or the member whose INPUT statement reads the record for SAS. |
| Language | ASSEMBLER or SAS: which language wrote the description being compared with the COBOL one. |
| Source path | The file the description is in. |
| Line | The line the description starts on. |
| Compared with | The COBOL record: the copybook that declares it, or the program where it is declared in an FD and in no copybook at all. |
| Compared path | The file the COBOL record is declared in. |
| Offset | Where the field starts, counted from zero at the start of the record. |
| Field | The field as the other language names it, empty where it describes nothing at this offset. |
| Bytes | How many bytes the other language gives the field, 0 where it describes none. |
| COBOL field | The field the COBOL record has at that offset, empty where it has none. |
| COBOL bytes | How many bytes the COBOL record gives it, 0 where it has no field there. |
| Agreement | MATCH where both put a field of the same length at the same byte, DIFFERENT_LENGTH where they start one at the same byte and disagree about its length, MISSING where the COBOL record does not describe the bytes, and NOT_READ where it describes bytes the other language leaves alone. |
Run book coverage
io.moderne.mainframe.analysis.table.RunBookCoverageEvery program and job of the portfolio with the run book member that documents it, and every run book with the component it is about.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.RunBookCoverage
| Column | Description |
|---|---|
| Component | The program, job or data set: the PROGRAM-ID, the JCL member name, or the data set name a DOCFICH carries on its FILE line. |
| Component type | What the component is, in the relationship model's vocabulary: COBOL, ASSEMBLER, SAS, JCL or DATA_SET. |
| Source path | The file the component is in, or empty where nothing in the portfolio answers to the name. |
| Run book | The documentation member, or empty where none documents the component. |
| Shape | Which kind of run book it is, from its own first word: DOCJOB, DOCPGM, DOCFICH, DOCAPPL or DOCOPER. |
| Run book path | The file the run book is in. |
| Verdict | DOCUMENTED, UNDOCUMENTED for a component no run book is about, or SUBJECT_MISSING for a run book whose subject nothing answers to. |
| Names resolved | How many of the names the run book writes down are components of the portfolio. A run book is prose, so what it mentions over-answers until it is looked up; this is what survived the lookup. |
Environment copies
io.moderne.mainframe.analysis.table.EnvironmentCopiesThe same member held in more than one environment's libraries, and whether the copies still agree. Read from one copy's side, so a member promoted through three environments has a row from each of the three to each of the other two.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.EnvironmentCopies
| Column | Description |
|---|---|
| Member | The member name both copies answer to. |
| Component type | What the member is, in the types of ComponentIndex. Empty for a plain text member no DD names, which the portfolio has no type for. |
| Environment | The environment this copy is held in, as the segment of its path that names one: SLPROD, PREPROD, PROD. |
| Source path | This copy's file. |
| Owning application | The application whose library this is, where the layout says which segment names it. Empty where an environment holds one library for the whole site, which is what the default layout reads. |
| Other environment | The environment the copy this row compares against is held in. |
| Other source path | That copy's file. |
| Comparison | IDENTICAL where the two are the same line for line, ENVIRONMENT_NAMES where a bind deck differs only in the subsystem, collection and DBRM library it binds on, and DIVERGED where they differ anywhere else. Only the last is drift somebody has to answer for. |
| Differing lines | How many of this copy's lines the other copy has not. Lines are matched wherever they sit, so a card moved is not a difference and a card changed is one on each side. Counted as written, so a bind deck bound on another subsystem has differing lines and no drift. |
Column lineage
io.moderne.mainframe.analysis.table.ColumnLineageWhich input field feeds each field the program writes out, in the shape OpenLineage's column lineage facet asks for, with the statement that did it.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.ColumnLineage
| Column | Description |
|---|---|
| Program | The PROGRAM-ID, which is the job the lineage belongs to. |
| Source path | The program's file, which the offsets below index into. |
| Input namespace | The technology the value came in through, as a scheme: cics://file, ims://segment, sql://table, file://record and so on. The kind is in the namespace rather than the name because a CICS file and a CICS queue can share one. Empty when nothing outside the program feeds the field. |
| Input dataset | The resource the value came from, or the kind of endpoint where the statement names none. A screen is named mapset.map, which is what identifies it across an estate; a program that decides at run time which map it sends still gets the map it sent, read off the record BMS generated. |
| Input field | The field the value landed in when it entered the program, qualified by the records containing it — or, where the resource has its own name for it, that name: the column a SELECT read, or the screen field an operator typed into. |
| Output namespace | The technology the value goes out through, in the same scheme form as the input. |
| Output dataset | The resource written, named the same way as the input. |
| Output field | The field whose value crossed the boundary. A row about a screen names the field the mapset declares rather than the data item BMS generated from it, so TRNNAMEO reads as TRNNAME. The length, flag and attribute bytes of a screen field drive the terminal rather than carrying a value, and are not rows. |
| Transformation type | Always DIRECT. A field only tested in a condition moves no value and is never an edge, so this analysis never has the INDIRECT kind to report. |
| Transformation subtype | IDENTITY when every step along the route only copies the value, TRANSFORMATION when arithmetic, STRING or UNSTRING changed it. |
| Steps | How many statements the value passes through, counting the one that brought it in and the one that wrote it out. One means it was read and written by a single statement. |
| Path | The route the value takes, statement by statement. This is what makes the answer reviewable rather than something to be taken on trust. |
| Output line | Where the statement that wrote the value out begins, one-based. |
| Output column | The column that statement begins at, one-based. Sequence numbers and the identification area are not part of it. |
| Output start offset | The statement's first character, as an index into the source file. This is what a catalog that highlights the code it is describing asks for. |
| Output end offset | One past the statement's last character. Zero, with the offset and line, when a copybook wrote the statement and it has no position in this program. |
| Input line | Where the statement that brought the value in begins, one-based. A program often reads the same table twice, and without this the two rows differ in nothing a reader can see. |
| Input start offset | That statement's first character, as an index into the source file. |
| Input end offset | One past that statement's last character. Zero when the value came from nowhere outside the program, or the statement was written by a copybook. |
Context registry
org.openrewrite.prethink.table.ContextRegistryRegistry of available context files for coding agents.
mod study . --last-recipe-run \
--data-table org.openrewrite.prethink.table.ContextRegistry
| Column | Description |
|---|---|
| Display name | The display name of the context. |
| Short description | A brief description of what context this provides. |
| Context file | Path to the markdown file describing this context. |
Source files that had results
org.openrewrite.table.SourcesFileResultsSource files that were modified by the recipe run.
mod study . --last-recipe-run \
--data-table org.openrewrite.table.SourcesFileResults
| Column | Description |
|---|---|
| Source path before the run | The source path of the file before the run. null when a source file was created during the run. |
| Source path after the run | A recipe may modify the source path. This is the path after the run. null when a source file was deleted during the run. |
| Parent of the recipe that made changes | In a hierarchical recipe, the parent of the recipe that made a change. Empty if this is the root of a hierarchy or if the recipe is not hierarchical at all. |
| Recipe that made changes | The specific recipe that made a change. |
| Estimated time saving | An estimated effort that a developer to fix manually instead of using this recipe, in unit of seconds. |
| Cycle | The recipe cycle in which the change was made. |
Source files that had search results
org.openrewrite.table.SearchResultsSearch results that were found during the recipe run.
mod study . --last-recipe-run \
--data-table org.openrewrite.table.SearchResults
| Column | Description |
|---|---|
| Source path of search result before the run | The source path of the file with the search result markers present. |
| Source path of search result after run the run | A recipe may modify the source path. This is the path after the run. null when a source file was deleted during the run. |
| Result | The trimmed printed tree of the LST element that the marker is attached to. |
| Description | The content of the description of the marker. |
| Recipe that added the search marker | The specific recipe that added the Search marker. |
Source files that errored on a recipe
org.openrewrite.table.SourcesFileErrorsThe details of all errors produced by a recipe run.
mod study . --last-recipe-run \
--data-table org.openrewrite.table.SourcesFileErrors
| Column | Description |
|---|---|
| Source path | The file that failed to parse. |
| Recipe that made changes | The specific recipe that made a change. |
| Stack trace | The stack trace of the failure. |
Recipe performance
org.openrewrite.table.RecipeRunStatsStatistics used in analyzing the performance of recipes.
mod study . --last-recipe-run \
--data-table org.openrewrite.table.RecipeRunStats
| Column | Description |
|---|---|
| The recipe | The recipe whose stats are being measured both individually and cumulatively. |
| Source file count | The number of source files the recipe ran over. |
| Source file changed count | The number of source files which were changed in the recipe run. Includes files created, deleted, and edited. |
| Cumulative scanning time (ns) | The total time spent across the scanning phase of this recipe. |
| Max scanning time (ns) | The max time scanning any one source file. |
| Cumulative edit time (ns) | The total time spent across the editing phase of this recipe. |
| Max edit time (ns) | The max time editing any one source file. |