Repository navigation
Bug sweep (COBOL engine): #4204 #4205 #4203 - #4227
Merged
Merged
Conversation
The ALL branch of the data-move operand reader only accepted a token starting with a quote, so ALL + a prefixed literal (X'00', N'..') fell through as an item named ALL and the statement produced no row. Both literal tests now share _is_literal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013sNMtAg6s9dyyjNgnjRHi8
…wice (#4204) IBM DBB EPSCMORT moves EPSPCOM-ERRMSG OF W-COMMUNICATION-AREA. The item lives in EPSMTOUT, nested in EPSMTCOM, which the program COPYs under both W-COMMUNICATION-AREA and DFHCOMMAREA. The storage walk lays the same copybook item objects out twice, but spans/paths were keyed by id(item), so the second placement (DFHCOMMAREA) overwrote the first and the qualifier never matched; the qualified lookup also searched only direct copybooks. The source stayed unresolved and the truncation was never flagged. _storage_spans now records every placement of an item, and a qualified operand is resolved against those placements. On the corpus 17 qualified data flows newly resolve, and L231 is flagged as truncating (80 > 40 bytes). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013sNMtAg6s9dyyjNgnjRHi8
func_start's optional 6-column sequence-area slot swallowed a free-format indent plus the level number (` 01 VALUE-BYTES.`), stepping past the regex's level-number shield, so data entries read as paragraph headers: 143 phantom units on CobolCraft, every unit of coordinates.cob/decode.cob. The cobol_sentence_start scope filter now refuses a header on a line with no fixed-format sequence area (the existing _COBOL_SEQUENCE_AREA test) that opens with a level number or FD/SD/RD/CD. Fixed-format source is unchanged. PROGRAM-ID-as-unit is left for a design decision (see the PR). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013sNMtAg6s9dyyjNgnjRHi8
…4205, #4203) Ledger: 3 dbb-mortgage-application mismatches no longer reproduce (MOVE truncation L231, MOVE ALL X'00' / X'FF'); their two defect causes are retired. Completeness pin: data flows 124/566 -> 141/568 (+17 qualified operands resolved, #4204; +2 ALL X'..' rows, #4205). Field testing: D038's root cause recorded, D040 (#4203, CobolCraft, unkeyed) logged; report regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013sNMtAg6s9dyyjNgnjRHi8
Contributor
Owner
Author
|
Correction: the 3 |
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.
Three COBOL engine bugs from the bug sweep, each fixed in its own commit with a test that fails on
mainand passes here.#4204: MOVE truncation was never flagged for a qualified source
Root cause. IBM DBB EPSCMORT L231 is
MOVE EPSPCOM-ERRMSG OF W-COMMUNICATION-AREA TO MSGERRO. The item comes from a nested copybook: it lives in EPSMTOUT, which EPSMTCOM COPYs, and the program COPYs EPSMTCOM twice, once underW-COMMUNICATION-AREAand once underDFHCOMMAREA.GalaxyIR._storage_spanslays the same copybook item objects out once per COPY, but it keyed spans and ancestor paths byid(item). The second placement (DFHCOMMAREA) overwrote the first, so the qualifierOF W-COMMUNICATION-AREAnever matched. The qualified lookup also searched only direct copybooks, not nested ones. The source stayedsource_unresolvedandtruncateswas None.Fix.
_storage_spansnow records every placement of an item (_span_placed)._operand_spanresolves a qualified operand against those placements, so the qualifier picks the right one. Unqualified lookups are unchanged.Test.
test_a_qualified_source_in_a_nested_copybook_copied_twice_resolves_and_truncatesintests/cobol_mainframe/test_galaxy_ir.py. Its fixture has the same nested-COPY, copied-twice shape.Corpus effect. 17 qualified data flows on dbb-mortgage-application now resolve, and L231 is flagged as truncating (80 bytes into 40). The
test_completenesspin for data flows moves from 124/566 to 141/568: +17 resolved here, plus 2 new rows from #4205.#4205: MOVE ALL X'..' was not recorded
Root cause. In
core/data_moves.py, theALLoperand branch only accepted a next token that starts with a quote.X'00'starts withX, so the statement produced no row.Fix. One shared
_is_literalhelper (quoted, or an X/N/G/Z-prefixed literal) is now used by both the literal branch and theALLbranch.Test.
test_move_all_of_a_prefixed_literal_is_a_figurative_moveintests/core_engine/test_data_moves.py, coveringALL X'00',ALL x'FF'andALL N'A'.#4203: free-format data entries were read as paragraphs
Root cause.
func_starthas an optional 6-column sequence-area slot. In free-format source that slot swallows the indent plus the level number (01of01 VALUE-BYTES.), which steps past the regex's level-number shield, so the data name was captured as a paragraph header. On CobolCraft @ e8c420df this produced 143 phantom units, including every unit incoordinates.cobanddecode.cob.Fix. The existing
cobol_sentence_startscope filter (#3197) now refuses a header on a line that has no fixed-format sequence area (the existing_COBOL_SEQUENCE_AREAtest: six digits or six blanks) and that opens with a level number or FD/SD/RD/CD. Fixed-format source is untouched.I checked this against all of CobolCraft: 419 units before, 276 after. All 143 removed units are data-entry lines, and no real paragraph was lost.
Test.
tests/core_engine/test_cobol_free_format_data_entries_4203.pyhas CobolCraft-shaped valid and invalid fixtures (sibling programs, free-format paragraphs with FD/01/77 entries, a fixed-format control) plus a check that the func_start count and the unit list agree.Left for a design call. The issue also proposes counting
PROGRAM-IDunits as function boundaries. Today each PROGRAM-ID is already counted inclass_count(3 and 13 on the two files above). Making them units as well would changefunction_countand function-level metrics for every COBOL file in every corpus, and would need a decision on how the key models them (see #4206). This PR keeps to the false-positive fix and leaves #4203 open for that half.Mainframe ground truth and field testing
MOVE ALL X'00'L1457,MOVE ALL X'FF'L3452), and their two defect causes are retired.ground_truth_ledger.py checkpasses with 0 new mismatches. Scoreboard: MOVE truncation is now 4/4 and data moves 578/578.field_testing.json: D038 (engine MOVE truncation: a qualified source (X OF Y) is never flagged as truncating #4204) now records its real root cause. D040 (cobol func_start: free-format source reads data items as paragraphs and misses PROGRAM-ID units (CobolCraft) #4203) is new, logged against CobolCraft (an unkeyed estate, after round 7). D039 (engine data moves: MOVE ALL X'..' (hex figurative) is not recorded #4205) was already logged. The report is regenerated; theunitsclean-fresh streak resets, as the protocol requires.Golden masters: no drift
Neither fixture changes in this PR.
tests/golden_master_auditat HEAD (bless_scope.py: newly parsed none, newly excluded none).galaxy_zero_venv(PyYAML only) gives 0 differences againsttests/golden_master_zero_dep_auditat HEAD (newly parsed none, newly excluded none).fastapi/tests/test_include_router_defaults_overrides.py) hitting a regex timeout under load. An origin/main scan run at the same time showed the same timeout. I discarded that bless.Sibling bug-sweep PRs also re-bless golden masters, so a golden conflict after one of them merges is expected. Re-bless after merging main (
crucible_check.py --update --yesorrebase_rebless.py); never hand-merge golden files.pr_gates
python tests/tools/pr_gates.py(full): lint, audits, secrets, xray, gauntlet and golden all PASS. suite: 13,937 passed, 3 failed. All 3 failures are pre-existing, listed below.Failing on
origin/maintoo, so not caused by this branch:tests/cobol_mainframe/test_det_programs.py::{test_typed_lifts_only_what_every_use_allows, test_a_move_that_can_leave_negative_zero_keeps_the_item_bytes, test_typed_groups_sync_a_groups_bytes_around_its_whole_uses}.Related
excluded_programs(from Estate 4: IBM DBB MortgageApplication -- EPSNBRVL and EPSCMORT proven; group USING items across CALL, nested COPY, CBL from column 1 #4216). answer key: model multi-program sources (sibling programs / END PROGRAM) #4206 (PR fix(answer-key): model multi-program sources (sibling / nested programs) (#4206) #4226, merged) made the answer key able to hold multi-program sources, but onboarding EPSCSMRD needs the forge to read multi-program sources per program first (about 1,000 ledger mismatches otherwise). That is follow-up work, not this PR.Closes #4204
Closes #4205
Part of #4203 (the false-positive half; PROGRAM-ID-as-unit is left open for a design call, see above)
🤖 Generated with Claude Code
https://claude.ai/code/session_013sNMtAg6s9dyyjNgnjRHi8