Repository navigation
Fix #4266: Extract SYNC, JUSTIFIED, BLANK WHEN ZERO, RENAMES, and resolve qualified names in layout model - #4627
Merged
Conversation
Contributor
squid-protocol
force-pushed
the
fix/issue-4266-layout-model-sync-renames
branch
from
October 7, 2026 18:52
cdf78ff to
74906b5
Compare
…S in the layout model
- mainframe_boundary: the COBOL record extractor records `sync` ('SYNC' / 'SYNC LEFT' /
'SYNC RIGHT'), `justified`, `blank_when_zero` and a 66 entry's `renames` ('A [THRU B]',
qualifiers kept as `X OF Y`), presence-keyed like sign_separate, read from the entry's own
text with COBOL-name boundaries (`WS-SYNC-FLAG` is no clause; `Comp sync.` is).
- record_data gains the four columns (healed into old tables); the rehydrator and the
GalaxyIR loader restore them; an older DB still loads (no slack, no RENAMES ranges).
- GalaxyIR: a SYNC binary / COMP-1 / COMP-2 / pointer / INDEX item starts on its IBM
boundary (binary <=4 digits halfword, else fullword; COMP-2 doubleword), counted from the
record start, in both record_layout and the storage spans; slack between table occurrences
is not modelled. A 66 RENAMES entry is laid out as the byte range it names in the record it
follows, so a MOVE from / to it resolves in data_flows (qualified by its record too).
Replaces the earlier draft of this branch: RENAMES no longer rides in `redefines`, plain SYNC
(the common case) now aligns, the clauses reach the DB, and the unrelated Optional -> X | None
churn and the non-standard `A (I) OF B` operand form are dropped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
) COACTUPC.cbl:1933/1990/2039/2087 MOVE LIT-ALL-ALPHA[NUM]-FROM-X (66 RENAMES LIT-UPPER THRU LIT-LOWER / LIT-NUMBERS, 52 / 62 bytes of WS-LITERALS) TO the PIC X(52) / X(62) receivers. Data flows: Resolved 27040 -> 27044, unresolved operand 99 -> 95, Ratio 99.6% -> 99.7%. Regenerated with tests/tools/crucible_check.py --update --yes; scope_check shows only these three repo-wide rollup fields moved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…al_names) The SYNC / JUSTIFIED / BLANK WHEN ZERO / RENAMES patterns bounded the keyword with an ASCII-only [A-Z0-9-]; every mainframe letter class must splice in identifiers.NATIONAL (and #3991's wide digits / hyphens) so a name like #SYNC is not read as the clause. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
squid-protocol
force-pushed
the
fix/issue-4266-layout-model-sync-renames
branch
from
October 7, 2026 19:35
74906b5 to
a1fc34c
Compare
This was referenced Oct 7, 2026
squid-protocol
added a commit
that referenced
this pull request
Oct 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4266. Taken over from the first draft of this branch (Gemini) and reworked from a fresh rebase onto main. The first draft's 5 CI failures, and what it got wrong, are listed below.
What #4266 changes
Extractor (
core/mainframe_boundary.py): each COBOL record entry now recordssync(SYNC/SYNC LEFT/SYNC RIGHT),justified,blank_when_zero(BLANK [WHEN] ZERO[S|ES]) and, on a 66 entry,renames(A/A THRU B; qualifiers kept asX OF Y,INread asOF,THROUGHread asTHRU). These keys only appear on an entry that codes the clause, the same waysign_separateworks. Each clause is read from the entry's own text (stopping at its period, with literals blanked) and must sit on COBOL-name boundaries, soWS-SYNC-FLAGandVALUE 'SYNC'are not read as clauses, andComp sync.is.DB:
record_datagetssync TEXT, justified INTEGER, blank_when_zero INTEGER, renames TEXT, added to old tables by_ensure_columns.state_rehydratorand the GalaxyIR loader restore them. A DB written before these columns existed still loads, with no slack bytes and no RENAMES ranges (tested).GalaxyIR layout (
record_layoutand_storage_spans): a SYNCHRONIZED elementary item now starts on its IBM Enterprise COBOL boundary, counted from the start of the record (which IBM aligns on a doubleword):The slack bytes count toward the group that holds the item. Slack between the occurrences of a table is not modelled yet (noted in
_slack).RENAMES: a 66 entry is laid out as the byte range it names (
_renames_spans), from the first byte of A to the last byte of B, within the record it follows. Each operand must name exactly one placed item there, otherwise the entry is left unplaced._operand_spanresolves the entry by its name, or by its name qualified by the record, so aMOVEfrom or to it resolves indata_flows.Qualified / subscripted sources for data-move lineage: main already resolved these in
data_flows(engine MOVE truncation: a qualified source (X OF Y) is never flagged as truncating #4204 qualifiers matched against storage ancestors; a subscript is stripped andoccurrence_bytesrides along). The new test covers a qualified RENAMES operand (CUST-POSTAL OF CUSTOMER). Thecics_mainframe_facts.md§6 sentence the issue cites is about CICS name resolution: follow data-name MOVE chains (bounded), not one hop #3578's VALUE/MOVE name-resolution chain incore/cics_resources.py, which is a different reader. It is not changed here (see "Owner decisions").Tests:
tests/cobol_mainframe/test_sync_renames_4266.py(10 tests). They go through the full scan → DB → GalaxyIR path and include a SYNC record of 36 bytes against the same record unsynced at 30.The first draft's CI failures: cause and fix
test_renames:UnboundLocalError: key. The RENAMES loop in_storage_spansused a leftover loop variable. It also called_operand_spanbefore_span_placedexisted, which would raise KeyError on a qualified operand._renames_spans, run inside_storage_spansbefore the cache is published. It matches operands against the placements directly.redefines('Redefines': 'WS-TEN THRU WS-TEA'), which is semantically wrong and changed the Record Layout golden. (2)MISSING KEY: 7. Mainframe Skeleton Completeness: the branch was stale against main.renamesis its own field, andredefinesis untouched. Rebased onto main. The golden diff that remains is explained below.Optional[...] -> X | Nonesweep over two whole files. That sweep produced most of the draft's -306 lines; no working code was dropped.ruff format(0.16.0).ruff_audit.py --cipasses with no new findings, so the baseline is not regenerated. It reports 3 FYI "no longer flagged" UP045 entries in galaxy_ir that could be pruned later.The draft had three other problems: a plain
SYNC(the common case) stored"", which is falsy, so it never aligned;SYNC.(period right after the clause) did not match; and the clauses never reached the DB, so a real scan never saw them. It also looseneddata_moves.pyto acceptA (I) OF B, which is not standard COBOL. That change is dropped.What moved (golden masters)
Both golden masters (
7_mainframe_skeleton_completeness/channels.json) were regenerated withtests/tools/crucible_check.py --update --yes:The 4 newly resolved flows are all in CardDemo
COACTUPC.cbl, at lines 1933, 1990, 2039 and 2087:MOVE LIT-ALL-ALPHA-FROM-X TO LIT-ALL-ALPHA-FROM. The source is66 ... RENAMES LIT-UPPER THRU LIT-LOWER: 26 + 26 = 52 bytes at offset 172 of WS-LITERALS. The receiver isPIC X(52).MOVE LIT-ALL-ALPHANUM-FROM-X TO LIT-ALL-ALPHANUM-FROM. The source is... THRU LIT-NUMBERS: 62 bytes. The receiver isPIC X(62).All four report
truncates: false, so the computed widths agree with the receivers the program sized for them.scope_check.py --expect cobolreports exactly these three fields, as repo-wide rollup fields that it cannot attribute to a language, and nothing else. No Record Layout or per-file golden moved: the new keys are not rendered byaudit_recorder, and the crucible corpus's SYNC items (genapplgwebst5.cbl) are 01-levels, which need no slack.Ground-truth ledger, fact cross-check, estate gate and completeness pins: no movement.
Local gates
pr_gates.py --fast: 5/5 pass (lint, audits, secrets, xray, gauntlet).pr_gates.py --ratchets: 6/6 pass (ports, port-surface, estate, fact-crosscheck, completeness, ground-truth).Owner decisions / follow-ups
tests/tools/cross_verify_sections.pytells reviewers to "assume no slack bytes (ignore SYNCHRONIZED)". The engine now adds slack. No ledger entry moved today (the census SYNC items sit on aligned offsets or are 01s), but the zosconnectclaimreq.cpypattern (X(255)followed byCOMP-2 SYNC) would differ by 7 bytes if it were ever keyed.det/layout.py:223"RENAMES: not laid out"), left alone to avoid colliding with the sibling det work;cics_resources.py);🤖 Generated with Claude Code