Skip to content

fix(as370): a discarded statement is an error, not a severity-4 warning - #84

Merged
mgrossmann merged 1 commit into
mainfrom
fix/eaten-card-is-an-error
Aug 28, 2026
Merged

fix(as370): a discarded statement is an error, not a severity-4 warning#84
mgrossmann merged 1 commit into
mainfrom
fix/eaten-card-is-an-error

Conversation

@mgrossmann

Copy link
Copy Markdown
Contributor

The nsf370 team found the hole, and they found it in the rule I proposed for mbt
(mvslovers/mbt#94, accept RC < 8). Re-lengthening the comment card that had
eaten their DCBD and sending it through exactly that rule:

make would see exit code: 0        <-- the build PASSES
CORRUPTED: 3 bytes differ from the intended code

The defect that turned their CI red at noon would have passed silently by
evening. They are right, and the fix belongs here rather than in a per-project
lint.

What IFOX00 conflates

Severity 4 covers two different things:

costs
a continued comment eats another comment nothing
a continued card eats a statement the statement — and the deck is punched anyway

Same message, same severity. On MVS that was survivable: COND=(8,LT) let RC 4
through and a test run would find the damage. In a host build, where the exit
status is the only channel, it is not.

The split

as370 keeps IFOX00's number, message and severity for the harmless case and
raises the one that loses a statement to 8. The bytes stay IFOX00's — only
the return code says a build must stop. There is precedent in the file: a
construct that is valid Assembler XF but unimplemented here already returns 8
with the note "not IFOX's error, but it must not pass silently".

The test is the consumed card, not the statement that ate it:

  • a comment card is never a loss — as a comment it generates nothing, and
    merged into an operand it only spoils a TITLE string. rexx370's
    trxldc.asm and tlnkterm.asm are that shape (a TITLE whose quoted text
    runs past column 71 eats the comment below it) and stay warnings. This is the
    case my first cut got wrong;
  • a card eaten by a continued comment is discarded whole → error, including
    when IFOX00 does not warn at all, which is what happens when the card's
    columns 1-15 are blank — a macro operand card vanishing without a word;
  • a card eaten by a continued statement keeps only columns 16-71, so a label
    or operation in 1-15 is thrown away → error. That is rs_goodidx.s losing its
    own END.

Measured

project RC 4 RC 8 decks
libc370 (743) 0 0 none moved
rexx370 (18) 3 1 — irxprobe.asm's pre-existing AMODE/RMODE gap, zero cards lost
nsf370 main (9) 7 2 — exactly the modules that lost a DCBD, two EQUs and an instruction
nsf370 PR branch (9) 0 0

tests/cont72.s now returns 8 where IFOX00 returns 4, deliberately and with the
reason in the fixture: its two eaten statements are errors, its three
comment-eats-comment cards and its IFO069 stay warnings, and the section is
still the oracle's eight bytes. The listing reference is unchanged and still
carries IFOX00's own verdict.

Order with mvslovers/mbt#94

This should land first. With the split in place, RC < 8 in the mbt rule
tolerates only what is genuinely harmless, and a build that drops a statement
still stops — for every project, without each one having to add a lint of its
own. The nsf370 team's check-card-columns.sh remains worth having: it catches
the card before the assembler runs, and it covers sources the assembler never
sees.

IFOX00 puts two very different things at severity 4. A continued comment that
eats another comment costs nothing. A continued card that eats a STATEMENT costs
the statement -- and the deck is punched anyway. IFO026 is the same message and
the same severity for both.

On MVS that blind spot was survivable: COND=(8,LT) let the ASM step's RC 4
through, and the module was wrong in ways a test run would find. In a host build
it is not survivable. The nsf370 team demonstrated it against the very rule
proposed for mbt (accept RC < 8): re-lengthening the comment card that had eaten
their DCBD, they got

    make would see exit code: 0
    CORRUPTED: 3 bytes differ from the intended code

-- the defect that turned their CI red at noon passing silently by evening.

So as370 keeps IFOX00's number, message and severity for the harmless case and
raises the one that loses a statement to 8. The bytes are IFOX00's either way;
only the return code says a build must stop. There is precedent in this file:
a construct that is valid Assembler XF but not implemented here also returns 8
with the comment "not IFOX's error, but it must not pass silently".

The rule is the consumed card, not the statement that ate it:

  * a COMMENT card is never a loss -- it generates nothing as a comment, and
    merged into an operand it only spoils a TITLE string. rexx370's trxldc.asm
    and tlnkterm.asm are exactly that (a TITLE whose quoted text runs past
    column 71 eats the comment below it) and stay warnings;
  * a card eaten by a continued COMMENT is discarded whole -> error, whether or
    not IFOX00 warns about it (it does not warn at all when the card's columns
    1-15 are blank, which is how a macro operand card disappears);
  * a card eaten by a continued STATEMENT keeps only columns 16-71, so a label
    or operation in 1-15 is thrown away -> error. That is rs_goodidx.s losing
    its END card.

Measured across the ecosystem: libc370 743 modules, no warning and no error, no
deck moved. rexx370 three warnings, no new error (its one RC 8 is irxprobe.asm's
pre-existing AMODE/RMODE gap, zero cards lost). nsf370 on main: two errors,
precisely the two modules that lost a DCBD, two EQUs and an instruction; on the
branch where those cards are trimmed, clean.

tests/cont72.s now returns 8 rather than 4, and says why: its two eaten
statements are errors, its three comment-eats-comment cards and its IFO069 stay
warnings, and the section is still the oracle's eight bytes.
@mgrossmann
mgrossmann merged commit fd1baa6 into main Aug 28, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant