feature: Phase 0 Java foundation for the COBOL translation (copybook models, subroutine contracts, test harness) - #256
Conversation
…pybook models, subroutine contracts, test harness) Co-Authored-By: Gael Kekatos <gael.kekatos@cognition.ai>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…st; document G9/G10 Co-Authored-By: Gael Kekatos <gael.kekatos@cognition.ai>
Phase 0 — independent test results, and three fixes on topVerified on JDK 11 / Maven 3.6.3 / GnuCOBOL 3.1.2: clean-state build plus an adversarial review of the translation against the COBOL source. The copybook translation came back field-by-field correct — every width, scale, group length and level-88 set matches the Fixed:
|
…est; note ERR-SEVERITY is unclamped Co-Authored-By: Gael Kekatos <gael.kekatos@cognition.ai>
Summary
Phase 0 of the COBOL-to-Java translation: the shared foundation every later slice (PORTTRAN, portfolio CRUD, batch, reporting) builds on. Nothing from
src/programs/is translated yet — this is the five shared copybooks, the two subroutine contractsPORTTRANcalls, and the harness that stands in for the z/OS runtime the original was never run on.New tree under
modernized/java/(67 tests,mvn -f modernized/java/pom.xml test):Three decisions drive everything else:
Packed decimals are
BigDecimalat the picture's scale, truncated not rounded. No statement in the slice saysROUNDEDorON SIZE ERROR, so storage drops excess decimals toward zero and silently loses high-order digits:Coded fields keep their raw bytes next to the enum.
2120-CHECK-TRANSACTION-TYPEexists becauseTRN-TYPEcan hold something no level-88 covers, and its message echoes it — sogetTrnType()returns"XX"whilegetTransactionType()returnsnull. Same split for every other coded field.PIC X(n)is stored space-padded.ERR-TEXTisPORTTRAN's error flag (IF ERR-TEXT = SPACES), not just a message, so it is an 80-char buffer withisErrTextSpaces()/clearErrText().CobolText.isSpacescompares against the space character only, since COBOL testsX'40'and a tab is data.Discrepancies handled explicitly, not fixed
All are written up as
G1–G10inmodernized/java/TRANSLATION-NOTES.md, each with a test:COPY PORTRECnames a copybook that does not exist, andPORTTRANupdatesPORT-TOTAL-UNITS/PORT-TOTAL-COST, whichPORTFLIO.cpydoes not define (it hasPORT-TOTAL-VALUE/PORT-CASH-BALANCE).PortfolioRecordtranslatesPORTFLIOfaithfully and adds two clearly-marked synthetic fields typed from their nearest documented equivalents inPOSREC.cpy:portTotalUnitsasPOS-QUANTITYS9(11)V9(4),portTotalCostasPOS-COST-BASISS9(13)V9(2). They are excluded fromtoRecordImage()so the audit before-image stays a faithfulPORTFLIOpicture. ReusingPORT-TOTAL-VALUEfor cost was rejected — market value and cost basis are different quantities.2200-UPDATE-POSITIONSsubtree and the unimplemented transfer are documented here and are Child 1's to reproduce.AUDPROCexpectsLS-AUDIT-REQUEST(starts atLS-SYSTEM-INFO, ends with a return code) but is handedAUDIT-RECORD(starts with a 26-byte timestamp, no return code);ERRPROCis offset byERR-MESSAGE's 18-byte timestamp. The interfaces pass the typed record and return the status instead of reproducing a storage overlay that would corrupt data. Also:PORTTRANtestsRETURN-CODE, whichAUDPROCnever sets.PORT00001intoPIC X(8), documented typesB/SvsBU/SL/TR/FE, documented statusIvs level-88A/C/S— are each pinned by a test inDocumentedRulesTest.PORTTRANnever setsERR-CODE/ERR-SEVERITY, soERRPROCreports severity 0 ("success") for every error. Reproduced; the documented catalogue lives separately asErrorCodefor the oracle.SUCC/FAILis decided by a possibly-staleWS-PORT-STATUS, and2300-UPDATE-AUDIT-TRAILSTRINGsCOMP-3senders, which Enterprise COBOL rejects — more evidence the source was never compiled. Note that GnuCOBOL accepts the latter even under-std=ibm, socobccannot corroborate G8; it is verified against the Enterprise COBOL V6.4 language reference instead.REWRITE PORTFOLIO-RECORDin three paragraphs butMOVE PORT-RECORDin a fourth (so one of the two names is undefined — a second symptom of G1), andMOVE FUNCTION USER-ID TO AUD-USER-IDuses an intrinsic Enterprise COBOL does not have, leaving the audit user with no defined source.Section 7 of the notes is the contract for the parallel slices: consume these types, never redefine them, one file set per slice, methods named after paragraphs, error strings byte-for-byte.
Review pass
An adversarial verification pass over the first commit found the models field-by-field correct against the copybooks, and one real bug:
CobolDecimal'sStringfactories didnew BigDecimal(value)while theBigDecimalones mappednullto zero, so ten setters across all five models threw or didn't purely by the argument's static type. Fixed, along withisSpacestreating tabs as blank, andCopybookFidelityTestis now in the suite so a later slice that widens a field or relaxes a scale fails immediately. Details in the comment below.Link to Devin session: https://app.devin.ai/sessions/c6183caec9fa435aaa59c67158c189f8
Requested by: @gaelkekatos-jpg
Devin Review