Repository navigation
LINK / XCTL / CALL -> service-to-service calls; CSD decks are not program declarers (#3616) - #3640
Merged
Merged
Conversation
…gram declarers (#3616) Generator (cobol_to_java_call_forge.py). From the verified skeleton, each program's @service gains: - link<T> / xctl<T> for a resolved LINK / XCTL, calling T's handleLink (the #3615 contract); - call<T>(...) for a resolved CALL, typed by T's PROCEDURE DIVISION USING items, calling T's new handleCall; - dispatch<Operand>L<line>(String program, ...) for a data-driven site: a switch over the candidates the engine found; any other name throws; - for a LINK the CSD routes to another region (REMOTESYSTEM / SYSID), a call through a <Region>RemoteClient (RestTemplate, the URL a property). New config `integration.remote_calls: http | local` (default http). Targets are injected as ObjectProvider<...>: CICS screens XCTL to each other in cycles, which plain constructor injection cannot start. When a site passes a record other than the one the target receives, a TODO says so. The program-contract DTOs move to dto.contract, named after the declaring program. /link now also counts data-driven LINK / XCTL arriving through navigation. Engine (galaxy_ir). CSD, BMS, JCL and DDL files carry class_data names that are not programs. dynamic_call_targets indexed them, so the CSD deck became the file of every program it DEFINEs: 88 of 89 CardDemo candidates resolved to CARDDEMO.CSD. And _program_file saw two declarers and answered None. All program-ID indexes now use executable declarers only. A program declared twice resolves to the declarer nearest the caller (zOE: COBOL/ SAM1 -> COBOL/SAM2), or None on a tie. program_interfaces() also returns each program's USING parameters with their layouts. Verification: - 6 corpora x 13 configs compile via --scan. - The refraction snapshot shows 0 differ. - 521 mainframe tests pass with the corpora (ledger unchanged: the key compares candidate names, not their files). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ZsVaAkb86P5r5JXDC2Y9g
An engine attribute defect on CardDemo, found by the Java generator and fixed in this PR. It does not reset `dynamic call targets`: the keyed candidate names were right, the resolved file was not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ZsVaAkb86P5r5JXDC2Y9g
Contributor
_mismatch binds the target's COMMAREA once, and merge_extras keeps its filtered parts in a list[dict] instead of reassigning the Optional parameter tuple. No behavior change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ZsVaAkb86P5r5JXDC2Y9g
This was referenced Sep 25, 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.
Closes #3616 (epic #3625). It builds on #3615: every call becomes a call to the target's
handleLink/handleCall.What each call becomes
@ServiceEXEC CICS LINK/XCTL(calls)link<T>(req)/xctl<T>(req)→tService.getObject().handleLink(req), typed by T's COMMAREA DTOCALL 'T' USING a b(calls+ T'sinterface.parameters)call<T>(A a, B b)→handleCall(a, b). T gainshandleCall, typed by itsPROCEDURE DIVISION USINGitems: an elementary item maps to its Java type, a group to a DTOXCTL PROGRAM(WS-X)/CALL WS-X(dynamic_call_targets)dispatch<WsX>L<line>(String program, ...): aswitchover the candidates the engine found (VALUE, table, MOVEd literals). Any other name throws, naming the siteLINKthe CSD routes to another region (remote_calls:REMOTESYSTEM/SYSID)integration.remote_calls: http(new, default), a<Region>RemoteClient(RestTemplate,gitgalaxy.remote.<region>.url) posting to that program's/link; withlocal, the in-process beanObjectProvider<TService>. CICS screens XCTL to each other in cycles (menu ↔ detail), which plain constructor injection cannot start.casecarries// TODO: this site passes X; T receives Y (file) -- map one layout onto the other. The generator never casts silently.dto.cicstodto.contract, since they now hold CALL USING records too. A program's own record is named after the program that declares it (MenuWsComm), whichever program receives it.Example: CardDemo's menu option table:
And GENAPP's DPL:
Engine defect found and fixed (field-testing log D022)
CSD, BMS, JCL and DDL files carry
class_datanames that are not programs: a CSD deck'sDEFINE PROGRAM(...), a mapset, a job name, a table. Two lookups treated them as declarers:dynamic_call_targetsmade the CSD deck the file of every program it DEFINEs: 88 of 89 CardDemo candidates resolved toCARDDEMO.CSD._program_filesaw two declarers for each program and answeredNone, which quietly weakened the channel-handoff joins.All program-ID indexes now consider executable declarers only. When a program is declared twice, the lookup takes the declarer nearest the caller (zOE:
COBOL/SAM1→COBOL/SAM2, notmultiroot/sam/SAM2) and answersNoneon a tie.Blast radius, diffing every IR join on the 6 corpora (main vs this PR):
dynamic_call_targetsandnavigationchange on CardDemo, zECS (ZECS002exists only as a CSD definition: nowNone, correctly) and zOE.The ledger is unchanged because the answer key compares candidate names, not their files. So this is logged as an
attributedefect: it does not resetdynamic call targets.Verified
java_target_matrix.py --scan, with JDK 17/21, Maven and Gradle; CI runs both paths.refraction_snapshot.py checkshows 0 differ on 6 corpora.test_service_calls.py, a real scan): the CSD is no longer a declarer; the nearest-declarer rule and its tie; USING parameters; static LINK / CALL, data-driven dispatch with the mismatch TODO, and the remote client;localmode and plain constructors; config validation.Not in this PR
START TRANSIDasync children stay in the transaction map.🤖 Generated with Claude Code
https://claude.ai/code/session_017ZsVaAkb86P5r5JXDC2Y9g