Skip to content

equivalence: CICS input channels and output containers compared (#4270) - #4647

Merged
squid-protocol merged 2 commits into
mainfrom
equiv/4270-cics-channels-containers
Oct 7, 2026
Merged

squid-protocol merged 2 commits into
mainfrom
equiv/4270-cics-channels-containers

Conversation

@squid-protocol

Copy link
Copy Markdown
Owner

Part of #4270. This PR merges after #4642. It is stacked on #4642 (base: its branch). Once #4642 merges, I will rebase it onto main.

This is part 2: CICS input channels and output containers.

What changed

Input channel (new oracle_assumptions.md X24). A scenario can state "channel": {"name", "containers": {NAME: {"text" | "hex", "datatype"}}}.

  • This is the channel a RUN TRANSID CHANNEL parent or a LINK CHANNEL caller passed: MYCHANNEL holding INPUTCONTAINER, the async credit-card services' input.
  • Text is encoded in the case's data page. The data type is BIT unless CHAR, as with PUT CONTAINER's default.
  • Both sides build the channel before the program runs and make it the first program's current channel:
    • stub: new GGCCHIN, reading channel.cfg;
    • Java side: CicsTask.withChannel with the new Channel.with.
  • Without a channel the task has no current channel, as before (GET CONTAINER is INVREQ RESP2 4).

Output containers compared. I followed the COMMAREA compare: at the task's end, the containers on that channel are compared as a last CONTAINERS event.

  • Every container is compared by name, byte for byte, along with the channel's name.
  • Sources: the stub's containers.out (written by GGCEND) and the Java test's task.currentChannel().
  • The event is dropped when the task abended, as a LINKed program's COMMAREA is, and for a task judged up to a refusal (X6, X23).
  • The data type is not compared: no conversion is modelled (X17).

RUN TRANSID CHILD. The COBOL side now reports it as CicsTask records it (TRANSID, RESP). Before, the Java side's RUN events had no COBOL counterpart, so the task differed. The child is not run in the one-task harness, which is sound for a parent that never FETCHes it (CSSTATS2). FETCH stays refused (X18).

"transactions" case key. It writes the stub's transactions.cfg and the Java side's Programs.transaction. CSSTATS2's case states the bundle's nine TRANSACTION definitions (GETP and SPND among them).

java-facade side for a channel program. The generator gives a channel program handleLink(XChannelIn). The det port's version throws "no task facade (a channel program)" (#4343). The facade side now runs such a program through runTask, and its entries say so ("runTask (a channel program: handleLink(...) is no task facade, #4343)"). Before, every scenario of these programs failed on the facade side. Owner: say if you'd rather keep that a failure.

Cases (async credit-card estate, burned; Apache-2.0, LICENSE + NOTICE):

  • asynccc-crdtchk, asynccc-getaddr, asynccc-getname.
  • asynccc-csstatus: LINKs GETPOL and GETSPND, run in the same task via programs.
  • asynccc-csstats2: RUN TRANSID GETP and SPND.
  • Each has account-0001 (the '0001' branch), other-account and no-channel (the GET CONTAINER INVREQ path).

Numbers, before -> after

case before after
asynccc-crdtchk not proven (facade refused), 1/2 branches, no container compared proven, 2/2 branches, CREDITCHECKCONT compared
asynccc-getaddr not proven (facade), 1/2 proven, 2/2, GETADDRCONTAINER + GETPOSTCODE
asynccc-getname not proven (facade), 1/2 proven, 2/2, GETNAMECONTAINER
asynccc-csstatus not proven (facade), 1/2 proven, 2/2, GETVIPSTATUS (+ the LINKs)
asynccc-csstats2 not proven (RUN events not compared), 1/2 proven, 2/2, GETVIPSTATUS (+ the RUNs)

proof_blockers (survey census-cache fc2ab73; sweeps: #4642's GenApp and Db2 re-proofs plus the five cases before / after):

  • Strict bar (--branches): proven 19 -> 24.
  • Paragraph bar: proven 31 -> 36.
  • The async credit-card estate is now 8/8 of its services proven. ASYNCPNT (FETCH CHILD / FETCH ANY) and SEQPNT have no case.

Gates

  • pr_gates.py --fast: 5/5 pass.
  • pr_gates.py --ratchets: 7/7 pass.
  • New tests in test_equivalence_cics:
    • channel validation;
    • containers.out -> CONTAINERS event, compare, drop on abend, drop when judged up to a refusal;
    • RUN events;
    • transactions;
    • the generated test;
    • the stub's GGCCHIN / GET / PUT / GGCEND, built with gcc.
  • The new tests failed without the change (4 failed). The suites run: 436 passed.
  • Coverage ledger: det_coverage_ledger.py update for the 5 new cases; check: as expected.
  • evidence_report.py --refresh committed. No evidence record or approval edited.

Also in #4642 (since its last review)

#4642 conflicted with main after #4636 (X22, READ GTEQ) and #4608. I merged origin/main into it (no force push) and resolved:

  • oracle_assumptions X22 / X23 both kept;
  • the harness hunks combined;
  • the ledger regenerated.

I re-proved on the merged tree: the three no-COMMAREA cases and genapp-lgacdb02 / lgdpdb01 (Db2) are all proven, with coverage unchanged. pr_gates --fast 5/5 and --ratchets 7/7 on it.

🤖 Generated with Claude Code

Base automatically changed from equiv/4270-cics-channels-nocommarea to main October 7, 2026 21:08
@squid-protocol
squid-protocol force-pushed the equiv/4270-cics-channels-containers branch from 1cfb24b to 6a47586 Compare October 7, 2026 21:16
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

🐦‍⬛ Muninn Security Scan

✅ No security issues found.

🐦‍⬛ Powered by Muninn · Skald Lab

squid-protocol and others added 2 commits October 7, 2026 17:58
- A scenario's "channel" (name + containers, text or hex, BIT unless CHAR) is the channel the task
  starts with: the stub's GGCCHIN (channel.cfg) and CicsTask.withChannel / Channel.with make it the
  first program's current channel (oracle_assumptions.md X24).
- At the task's end the containers on that channel are compared, byte for byte, as a last CONTAINERS
  event (the stub's containers.out from GGCEND; the Java test reads task.currentChannel()); dropped on
  an abend and for a task judged up to a refusal (X6, X23).
- RUN TRANSID CHILD is compared on the COBOL side as CicsTask records it (TRANSID, RESP); the child is
  not run. A case's "transactions" writes the stub's transactions.cfg and the Java side's
  Programs.transaction.
- The java-facade side runs a channel program (handleLink(XChannelIn), no task facade yet, #4343)
  through runTask, and its entries say so.
- Cases: asynccc-crdtchk, -getaddr, -getname, -csstatus (LINKs GETPOL / GETSPND), -csstats2 (RUN
  TRANSID GETP / SPND), each with its '0001' and other-account branches and a no-channel task.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@squid-protocol
squid-protocol force-pushed the equiv/4270-cics-channels-containers branch from 6a47586 to 71ccf76 Compare October 7, 2026 22:00
@squid-protocol
squid-protocol marked this pull request as ready for review October 7, 2026 22:17
@squid-protocol
squid-protocol merged commit 6d49963 into main Oct 7, 2026
37 checks passed
@squid-protocol
squid-protocol deleted the equiv/4270-cics-channels-containers branch October 7, 2026 22:17
squid-protocol added a commit that referenced this pull request Oct 8, 2026
…#4647 (#4270)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
squid-protocol added a commit that referenced this pull request Oct 8, 2026
…4653)

* equivalence: cases for GenApp's front-end and test programs (#4270)

Eleven GenApp programs whose only proof gap was 'no case':
- the front ends LGACUS01, LGAPOL01, LGDPOL01, LGICUS01, LGIPOL01, LGUCUS01,
  LGUPOL01, each running its whole back-end chain (Db2 service, VSAM
  service, LGSTSQ) in the task, with the back-end cases' inputs plus the
  front end's own paths (no COMMAREA, short COMMAREA, wrong request id);
- the BMS test transactions LGTESTP1-4 (SSMAP maps, twelve programs per
  task): inquire / add / delete / update, CLEAR, PF3, MAPFAIL, bad option.

Harness / translator fixes, each with a test:
- stage_copybooks no longer stages a .bms map source as <NAME>.cpy (it
  shadowed the generated symbolic map COPY SSMAP means);
- a program with no DFHCOMMAREA still gets EIBCALEN from the task's area
  (LGTESTP's IF EIBCALEN > 0 GO TO A-GAIN);
- an integer literal compared with an alphanumeric item keeps its digits
  as written (ENP4CNOO Not = 0000000000);
- each LINKed SQL program's GG-SQL-IDs start at the next free hundred
  (1000 x its place ran past PIC 9(4) at the tenth program);
- ggsql.c refuses a statement the CLI fails in the client (-99999, Q10).

LGTESTP4's successful add is left out: #4652 (C11).

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

* equivalence: coverage ledger and evidence report for the GenApp front-end cases (#4270)

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

* equivalence: refresh the det-sweep coverage ledger after rebasing onto #4647 (#4270)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
squid-protocol added a commit that referenced this pull request Oct 8, 2026
…inary item (#4652) (#4663)

* equivalence: cases for GenApp's front-end and test programs (#4270)

Eleven GenApp programs whose only proof gap was 'no case':
- the front ends LGACUS01, LGAPOL01, LGDPOL01, LGICUS01, LGIPOL01, LGUCUS01,
  LGUPOL01, each running its whole back-end chain (Db2 service, VSAM
  service, LGSTSQ) in the task, with the back-end cases' inputs plus the
  front end's own paths (no COMMAREA, short COMMAREA, wrong request id);
- the BMS test transactions LGTESTP1-4 (SSMAP maps, twelve programs per
  task): inquire / add / delete / update, CLEAR, PF3, MAPFAIL, bad option.

Harness / translator fixes, each with a test:
- stage_copybooks no longer stages a .bms map source as <NAME>.cpy (it
  shadowed the generated symbolic map COPY SSMAP means);
- a program with no DFHCOMMAREA still gets EIBCALEN from the task's area
  (LGTESTP's IF EIBCALEN > 0 GO TO A-GAIN);
- an integer literal compared with an alphanumeric item keeps its digits
  as written (ENP4CNOO Not = 0000000000);
- each LINKed SQL program's GG-SQL-IDs start at the next free hundred
  (1000 x its place ran past PIC 9(4) at the tenth program);
- ggsql.c refuses a statement the CLI fails in the client (-99999, Q10).

LGTESTP4's successful add is left out: #4652 (C11).

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

* equivalence: coverage ledger and evidence report for the GenApp front-end cases (#4270)

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

* equivalence: refresh the det-sweep coverage ledger after rebasing onto #4647 (#4270)

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

* equivalence: model the oracle's MOVE of a non-digit zoned item to a binary item (#4652)

GnuCOBOL 3.1.2 (cob_move_display_to_binary) counts each byte of a zoned
sender as its character minus '0' (a space -16) in a wrapping unsigned
64-bit integer, keeps the receiver's digits under TRUNC(STD), then applies
the sign. The det runtime read spaces as 0, so GenApp LGTESTP4's add
INSERTed BROKERID 0 where the oracle INSERTs 931773840. Cobol.move now
models it for a zoned sender holding a non-digit (digit-only data is
unchanged); a sign byte that is no digit, sign or space is refused by
name. IBM documents no result: register C11 updated.

genapp-lgtestp4 gains its successful add (PROVED, 25 scenarios); the 27
ports with a zoned-to-binary MOVE re-proved. Follow-up: #4662.

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

* evidence: refresh committed reports (#4652)

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

* equivalence: regenerate the det-sweep ledger and evidence reports after merging main (#4652)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
squid-protocol added a commit that referenced this pull request Oct 8, 2026
… the oracle's sign rewrite (#4662) (#4693)

* equivalence: cases for GenApp's front-end and test programs (#4270)

Eleven GenApp programs whose only proof gap was 'no case':
- the front ends LGACUS01, LGAPOL01, LGDPOL01, LGICUS01, LGIPOL01, LGUCUS01,
  LGUPOL01, each running its whole back-end chain (Db2 service, VSAM
  service, LGSTSQ) in the task, with the back-end cases' inputs plus the
  front end's own paths (no COMMAREA, short COMMAREA, wrong request id);
- the BMS test transactions LGTESTP1-4 (SSMAP maps, twelve programs per
  task): inquire / add / delete / update, CLEAR, PF3, MAPFAIL, bad option.

Harness / translator fixes, each with a test:
- stage_copybooks no longer stages a .bms map source as <NAME>.cpy (it
  shadowed the generated symbolic map COPY SSMAP means);
- a program with no DFHCOMMAREA still gets EIBCALEN from the task's area
  (LGTESTP's IF EIBCALEN > 0 GO TO A-GAIN);
- an integer literal compared with an alphanumeric item keeps its digits
  as written (ENP4CNOO Not = 0000000000);
- each LINKed SQL program's GG-SQL-IDs start at the next free hundred
  (1000 x its place ran past PIC 9(4) at the tenth program);
- ggsql.c refuses a statement the CLI fails in the client (-99999, Q10).

LGTESTP4's successful add is left out: #4652 (C11).

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

* equivalence: coverage ledger and evidence report for the GenApp front-end cases (#4270)

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

* equivalence: refresh the det-sweep coverage ledger after rebasing onto #4647 (#4270)

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

* equivalence: model the oracle's MOVE of a non-digit zoned item to a binary item (#4652)

GnuCOBOL 3.1.2 (cob_move_display_to_binary) counts each byte of a zoned
sender as its character minus '0' (a space -16) in a wrapping unsigned
64-bit integer, keeps the receiver's digits under TRUNC(STD), then applies
the sign. The det runtime read spaces as 0, so GenApp LGTESTP4's add
INSERTed BROKERID 0 where the oracle INSERTs 931773840. Cobol.move now
models it for a zoned sender holding a non-digit (digit-only data is
unchanged); a sign byte that is no digit, sign or space is refused by
name. IBM documents no result: register C11 updated.

genapp-lgtestp4 gains its successful add (PROVED, 25 scenarios); the 27
ports with a zoned-to-binary MOVE re-proved. Follow-up: #4662.

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

* evidence: refresh committed reports (#4652)

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

* equivalence: non-digit zoned data as a MOVE sender, operand and comparand, and the oracle's sign rewrite (#4662)

Models what GnuCOBOL 3.1.2 (-std=ibm) does with a zoned item holding spaces, letters, low-values or X'FF':
MOVE to zoned (byte copy), numeric-edited (only '0' suppressed), packed and binary; COMPUTE / ADD / SUBTRACT
operands (cob_decimal_set_display, cob_get_int for cob_add_int); comparisons (cob_cmp_numdisp / the decimal);
and the GET_SIGN / PUT_SIGN rewrite of a signed sender's sign byte, digit-only data included. New
cobolrt/Zoned.java; C11 lists each shape with its libcob function; tests per sender shape against cobc.

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

* test: numproc probe reads fresh items per pass and expects the oracle's unsigned-overpunch value (#4662)

The #4662 sign rewrite (PUT_SIGN) mutates a signed zoned item on read, so the probe's reused items changed between the NOPFD and PFD passes; items are now built per pass. An overpunch letter in an unsigned item is a C11 non-digit (12C = 139 under NOPFD); PFD still refuses it.

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

* equivalence: regenerate the det-sweep ledger and evidence reports after merging main (#4652)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D

* equivalence: regenerate the det-sweep ledger after merging main (#4662)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D

* equivalence: regenerate the det-sweep ledger after merging main again (#4662)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D

* Refresh det coverage ledger after merge of main (harness fingerprint)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D

* Refresh det coverage ledger after merge of main

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
squid-protocol added a commit that referenced this pull request Oct 9, 2026
…4810)

* equivalence: a CICS task's terminal and origin stated, SEND CONTROL compared, SQL after a SYNCPOINT ROLLBACK kept (#4270)

Harness fixes the CBSA BMS front-end cases need (Part of #4270):
- A case's or scenario's "termid" / "uctranst" / "origin": the task's terminal (EIBTRMID, $GGCICS_FACILITY and
  terminals.cfg / CicsTask.withTermid), its UCTRANST and its origin data, stated on both sides as the cics-crucible
  runner states them. Unstated, None: RETURN IMMEDIATE, INQUIRE TERMINAL UCTRANST and INQUIRE ASSOCIATION are refused
  by both runtimes, as before.
- SEND CONTROL: the stub's SEND-CONTROL line is now an event on the COBOL side (CicsTask already recorded one), its
  options and CURSOR compared. Before, a CLEAR key's SEND CONTROL ERASE FREEKB differed by a missing event.
- SYNCPOINT ROLLBACK rolls the task's Db2 connection back there and then; the SQL after it is a new unit of work
  committed with the task, as the COBOL side's Db2 does (CBSA INQACCCU's cursor failing inside CREACC's task).
  Before, the whole Db2 transaction was marked rollback-only and the caller's later INSERTs were lost on the Java
  side. oracle_assumptions.md Q3 says so; X27 names the cases.

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

* equivalence: cases for the CBSA programs made whole (Part of #4270)

Fifteen new CBSA cases, each proved in a local det sweep (Db2 local):
- BMS front ends, each with its LINKed back ends run in the task: cbsa-bnkmenu, cbsa-bnk1cac (CREACC, INQCUST,
  INQACCCU, ABNDPROC), cbsa-bnk1cra (DBCRFUN; INQUIRE ASSOCIATION from a stated origin), cbsa-bnk1dac (INQACC,
  DELACC), cbsa-bnk1dcs (INQCUST, UPDCUST; INQUIRE / SET TERMINAL UCTRANST from a stated terminal).
- LINKed services: cbsa-creacc, cbsa-acctctrl.
- From the paused equiv/4270-cbsa-cases branch (its channel prerequisite #4647 has merged), re-proved on main:
  cbsa-getcompy, cbsa-getscode, cbsa-inqcust, cbsa-crdtagy1..5.
- det_sweep_coverage.json re-measured by a full local det sweep (as expected; the harness fingerprints moved).
- Register: C12, X24, L3 (prior art), X26, X27, X29 and Q3 name the new proofs.

Not cased (refused by name): BNK1TFN, BNK1UAC, BNK1CCS (#4695: RETURN LENGTH past the DTO; BNK1UAC also
#4806), BNK1CCA (#4807: BMS OCCURS map).

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

* Merge origin/main into equiv/4270-cbsa-whole-cases; ledger re-applied from the 24-case sweep under the merged harness

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TBJdDBRtJis5hzE244NQKV

---------

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant