Skip to content

CICS: container code-page conversion -- FROMCCSID / INTOCCSID / CONVERTST / CCSID on both runtimes (Part of #4270) - #5227

Merged
squid-protocol merged 5 commits into
mainfrom
churn/4270-20261016T0730Z
Oct 16, 2026
Merged

squid-protocol merged 5 commits into
mainfrom
churn/4270-20261016T0730Z

Conversation

@squid-protocol

@squid-protocol squid-protocol commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

Part of #4270 (slice: container code-page conversion). Not Closes: the issue's other acceptance boxes are open.

What

PUT CONTAINER FROMCCSID and GET CONTAINER INTOCCSID / CONVERTST(NOCONVERT) / CCSID were refused whole ("code-page conversion of a CHAR container is not modelled"). They are now modelled on BOTH runtimes (CicsTask and the stub ggcics.c) and in the det translator, for the CCSIDs 037, 500, 1140 and 1208 (ASCII bytes only; multibyte refused). The nightly blocker ranking named GET CONTAINER SET INTOCCSID and PUT CONTAINER FROMCCSID (dbb-mortgage epscsmrd).

IBM semantics (CICS TS 6.x PUT / GET CONTAINER (CHANNEL), quoted in docs/language_status/register/X17.md): FROMCCSID implies CHAR (BIT with it: INVREQ RESP2 34); a container's CCSID is its first PUT's, else the region's 037; a later PUT is "converted (if required)"; GET converts to INTOCCSID, else to the region's CCSID; CONVERTST(NOCONVERT) + CCSID(area) read the container's own CCSID (0 for BIT); INTOCCSID / FROMCCSID with no channel is INVREQ RESP2 2; INTOCCSID on a BIT container is CCSIDERR RESP2 3 with the data returned unconverted.

Design decision

A container holds the program's storage bytes plus a CCSID tag. A conversion is the character-to-character map between the two pages, with a program's bytes read as the region's page 037 (the port's convention, #4528), so a TS write of a converted area logs the real converted bytes. The stub implements it as a small permutation (500 reads seven characters of 037 differently; 1140 swaps the currency sign for the euro; 1208 is ASCII one byte a character); CicsTask uses the JDK's Cp037/Cp500/Cp1140. Nothing in the expected values comes from either runtime (see Evidence).

Class and siblings (class table)

Class: code-page conversion of a CHAR container.

member status
PUT FROMCCSID this PR
GET INTOCCSID (INTO, NODATA, SET) this PR
GET CONVERTST(NOCONVERT) + CCSID this PR
MOVE CONTAINER onto a container of another CCSID, WEB SEND of a non-region CCSID container refused by name (this PR)
FROMCODEPAGE / INTOCODEPAGE refused: raise CODEPAGEERR (own RESP2 list), no corpus program uses them
any CCSID beyond 037/500/1140/1208, 1208 beyond ASCII, a character the target lacks (CCSIDERR RESP2 4) refused at run time, register X17
PREPEND, BYTEOFFSET different mechanism, refused as before (BYTEOFFSET/PREPEND have a crucible case ca-container-byteoffset)

Evidence

  • tests/cics_crucible/test_container_ccsid_4270.py (20 tests): one list of steps run on the stub and on CicsTask that must print the same lines; the expected bytes are computed from Python's cp037/cp500/cp1140/ascii codecs, not from either runtime; 9 refusals on both sides.
  • Existing cics-crucible case ca-container-ccsid (hand-traced from IBM; companion PR, see Cross-repo): bit-container passes on cobol-stub and java-ported only with cics-crucible#36 (see "Status of the crucible cells") (INVREQ 34, CCSIDERR 3, unconverted data); convert: events 1-10 match (INVREQ 2, FROMCCSID 037 -> INTOCCSID 1208 / 037 / default) and both sides stop at event 11 identically: the case's container TWO is ASCII data built from a hex literal X'414243313233', which the port (and GnuCOBOL's ASCII storage) reads as the characters 'ABC123' and a TS write encodes to X'C1C2C3F1F2F3'. That is the hex-literal / TS-page convention of det ports on the CICS crucible decode TS/COMMAREA bytes in the wrong charset (and det/cics.py reads DTO copybooks as latin-1) #4528, not a container defect; listed under sibling gaps.
  • cics_case_ports.py on the case: 2 programs, 0 holes. cics_crucible.py --update-baseline against the PINNED v0.8.0: ca-container-ccsid/bit-container/cobol-stub unsupported -> fail (the pinned CACCBIT logs FLENGTH 0 where its log says 6: the companion fix), convert/cobol-stub stays unsupported on the pinned DATATYPE(CHAR); CACCBIT enters the coverage ledger; pin untouched. (The same regeneration also rewrote three ca-address-commarea reasons from ADDRESS to ADDRESS COMMAREA: drift already on main, committed as the tool wrote it.)
  • Survey (cics_census.py survey --no-census --corpus dbb-mortgage-application --verb "GET CONTAINER" "PUT CONTAINER"): no hole naming GET / PUT CONTAINER is left in dbb-mortgage; before (nightly 0a6f3c6): GET CONTAINER SET INTOCCSID and PUT CONTAINER FROMCCSID, 1 program each (epscsmrd, which stays refused on SOAPFAULT, the EPSCSMR* CALLs and CEEHDLR/CEEHDLU). No burned program becomes whole from this slice alone; 0 non-burned counted.
  • Gates: pr_gates --fast 6/6; pr_gates --ratchets 8/8 (cics-spec, ports, port-surface, estate, fact-crosscheck, completeness, ground-truth, time); python -m gitgalaxy.standards.cics regen --check up to date; 1399 tests of tests/cics_crucible + det_translate + equivalence_cics + pointer lane + spec equality pass locally (javac, cc, JDK 17 present: nothing skipped in the new file). Full suite and the OS grid are CI's.

Status of the crucible cells (plain statement)

ca-container-ccsid/bit-container passes on cobol-stub and java-ported ONLY with the program fixes of cics-crucible#36. At the pinned v0.8.0 sources this PR's ledger records bit-container/cobol-stub as fail (data byte 14: the pinned CACCBIT logs FLENGTH 0 where its log says 6) and convert/cobol-stub as unsupported (pinned DATATYPE(CHAR)); both stay ledgered that way until #36 is released and the pin bumped. convert fails at event 11 on both sides even with #36 (hex-literal ASCII data).

Cross-repo

Companion cics-crucible PR (program-source fixes, expected logs unchanged): CACCSID wrote DATATYPE(CHAR) (DATATYPE takes a CVDA: DATATYPE(DFHVALUE(CHAR))) and CACCBIT did not log FLENGTH for GET2 although its expected log does. Merge order: either; the ledger here is measured on the PINNED v0.8.0 sources, so after the crucible PR is released and the pin bumped, cics_crucible.py --update-baseline moves the bit-container cells to pass (that bump is not part of this PR).

Lessons for agents

  • cat > file with no heredoc in a compound command hangs the shell until the 2-minute timeout: write scripts with the Write tool or a quoted heredoc. And /tmp/gitgalaxy-scratch/claude/ is shared by every agent: use a churn-<issue>/ subdirectory (an old edit1.py of another run was sitting there).
  • A hex literal (X'41') in a ported program is stored as that byte but a TS write re-encodes it as the region page (037), so any crucible case that observes ASCII bytes built from a hex literal through TS fails on both the stub and the port alike; check for that before blaming the container runtime.

🤖 Generated with Claude Code

squid-protocol and others added 5 commits October 16, 2026 03:43
…VERTST / CCSID) (Part of #4270)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…Task conversion test (Part of #4270)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…r CCSID slice (pin unchanged, v0.8.0) (Part of #4270)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… (Part of #4270)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…modelled, cite IBM's conversion CCSID tables (Part of #4270)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@squid-protocol squid-protocol added the shepherd:merge Maintainer: merge when green (auto-merge, squash). Guide: docs/ci.md label Oct 16, 2026
@squid-protocol

Copy link
Copy Markdown
Owner Author

No description provided.

@squid-protocol
squid-protocol marked this pull request as ready for review October 16, 2026 08:19
@squid-protocol
squid-protocol enabled auto-merge (squash) October 16, 2026 08:20
@squid-protocol

Copy link
Copy Markdown
Owner Author

No description provided.

Comment on lines +237 to +238
"java.util.function.Function<byte[], String> hex = d -> { StringBuilder b = new StringBuilder(); "
'for (byte x : d) b.append(String.format("%02X", x & 0xFF)); return b.toString(); };',
@github-actions

Copy link
Copy Markdown
Contributor

🐦‍⬛ Muninn Security Scan

✅ No security issues found.

🐦‍⬛ Powered by Muninn · Skald Lab

@squid-protocol
squid-protocol merged commit 6d28038 into main Oct 16, 2026
89 checks passed
@squid-protocol
squid-protocol deleted the churn/4270-20261016T0730Z branch October 16, 2026 08:52
squid-protocol added a commit that referenced this pull request Oct 16, 2026
…er brief Running)

Merge the #5227 citation into the existing sentence instead.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
squid-protocol added a commit that referenced this pull request Oct 16, 2026
* Promote 12 agent lessons from the inbox into .claude (rules, worker brief, skills)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop duplicate 'cat > file without a heredoc' lesson (already in worker brief Running)

Merge the #5227 citation into the existing sentence instead.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

shepherd:merge Maintainer: merge when green (auto-merge, squash). Guide: docs/ci.md

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants