Skip to content

Mainframe fact channel: CICS task control and the async task graph (#3449) - #3459

Merged
squid-protocol merged 2 commits into
feat/sql-statement-channel-3446from
feat/cics-async-channel-3449
Sep 24, 2026
Merged

squid-protocol merged 2 commits into
feat/sql-statement-channel-3446from
feat/cics-async-channel-3449

Conversation

@squid-protocol

Copy link
Copy Markdown
Owner

Closes #3449. Part of #3445. Stacked on #3458 (base is its branch; GitHub retargets to main when #3458 merges).

What

New fact channel cics_task_data: one row for each CICS task-control command.

  • Commands covered: RUN, START, START ATTACH, FETCH CHILD, FETCH ANY, FREE CHILD, RETRIEVE, CANCEL, DELAY, POST, WAIT EVENT, WAIT EXTERNAL, WAITCICS, ENQ and DEQ.
  • Fields on each row: the TRANSID or RESOURCE target, the CHANNEL, the CHILD / ANY / REQID token, the FROM/INTO record, the timing, and any remaining options.

A new join, GalaxyIR.async_tasks(), connects each RUN or START to:

  • the CSD transactions and programs it can reach;
  • the containers the parent PUTs on the channel it passes;
  • the FETCH ANY, FETCH CHILD or FREE CHILD that collects it (matched by token);
  • the RETRIEVE in the child, for a START.

The dynamic-transid part

CBSA's CRECUST builds its child transaction id at run time:

STRING 'OCR' DELIMITED BY SIZE, WS-CC-CNT DELIMITED BY SIZE INTO WS-RUN-TRANSID   (WS-CC-CNT PIC 9)
EXEC CICS RUN TRANSID(WS-RUN-TRANSID) CHANNEL(WS-CHANNEL-NAME) CHILD(WS-ANY-CHILD-TKN)

Resolution adds one reading after literal, VALUE and MOVE: a STRING-built id becomes an fnmatch pattern.

  • Each STRING source contributes either its literal text or its PIC width: [0-9] for each digit, ? for each character.
  • This id becomes OCR[0-9]. It reaches OCR1..OCR5, and deliberately not OCRA, a different transaction in the same deck. A naive OCR* pattern would have matched it.
  • The reader expands the pattern against the CSD. The extractor never guesses.

Result on CBSA: CRECUST RUNs OCR1..OCR5, which reach CRDTAGY1..5 (all resolved to files). It passes containers CIPA..CIPI on CIPCREDCHANN, and FETCH ANY at line 639 collects the children.

Ground truth

  • Independent reader: cobol_answer_key.py add-cics-tasks, with its own STRING/PIC reading and its own CSD expansion.
  • New scored fields: CICS task control and async children. Both are drafted, with sign-off flag cics_tasks_validated.

The engine matches the key exactly:

corpus CICS task control async children
CBSA 24/24 5/5
CardDemo 3/3 (its MQ-triggered RETRIEVE INTO(MQTM)) 0/0
zopeneditor none none

No pinned corpus contains a START TRANSID, so START / CANCEL / POST / WAIT are covered by unit tests only. A blind census of the new section is still owed before cics_tasks_validated can be set.

Checks

  • Golden masters re-blessed. The only change is a new cics_tasks.json in each fixture (CBSA and genapp COBOL files); no existing golden file moved.
  • Tests: full suite passes locally (11,141 passed). The ruff and mypy audits show no new findings.
  • Dead-key audit: "CHANNEL" is allowlisted, because it's an EXEC CICS option word parsed from source.

🤖 Generated with Claude Code

https://claude.ai/code/session_017ZsVaAkb86P5r5JXDC2Y9g

squid-protocol and others added 2 commits September 23, 2026 23:46
…3449)

Only RUN TRANSID reached call_site_data, as a routing verb whose target never
resolved; the async API's join points, START/RETRIEVE data passing and
DELAY/POST/WAIT/ENQ were not modelled, so CBSA's credit-agency fan-out/fan-in
read as one unconnected child start.

New channel cics_task_data: one row per CICS task-control command -- RUN,
START, START ATTACH, FETCH CHILD / FETCH ANY, FREE CHILD, RETRIEVE, CANCEL,
DELAY, POST, WAIT EVENT / WAIT EXTERNAL / WAITCICS, ENQ, DEQ -- with the TRANSID
or RESOURCE target, the CHANNEL, the CHILD / ANY / REQID token, the FROM/INTO
record, the timing and the remaining options.

Target resolution adds one reading to literal / VALUE / MOVE: a transaction id
BUILT by STRING becomes an fnmatch pattern, each source contributing its
literal text or its PIC width (`[0-9]` per digit, `?` per character). CRECUST's
`STRING 'OCR' ..., WS-CC-CNT (PIC 9) ... INTO WS-RUN-TRANSID` is `OCR[0-9]`:
it reaches OCR1..OCR5 and deliberately not OCRA, another transaction in the
same deck. A STRING also assigns the name, so it joins any MOVEd literals as
candidates rather than losing to a sole MOVE.

Spine per how_to_add_a_fact_channel.md:
- core/cics_tasks.py: bounded extractor reusing cics_resources' block and
  option walker; STRING reader bounded by _STRING_LIMIT and the sentence end.
- extract_boundary (cobol + pli), galaxyscope payload, record_keeper table +
  indexes, state_rehydrator byte-identical delta restore, audit block, LLM
  brief summary and per-file line.
- galaxy_ir: EngineCicsTask, EngineFile.cics_tasks, and GalaxyIR.async_tasks():
  each RUN/START joined to the CSD transactions and programs it can reach, the
  containers the parent PUTs on the passed channel, the FETCH ANY / FETCH CHILD
  / FREE CHILD that collect it (by token), and a START's child RETRIEVEs.
  CBSA: CRECUST RUN -> OCR1..OCR5 -> CRDTAGY1..5, containers CIPA..CIPI on
  CIPCREDCHANN, collected by FETCH ANY at line 639.

Ground truth: an independent reader in cobol_answer_key.py (add-cics-tasks)
with its own STRING/PIC reading and CSD expansion; two new scored fields,
"CICS task control" and "async children" (TRUTH_FLAGS cics_tasks_validated,
drafted). The engine matches the key exactly: CBSA 24/24 commands and 5/5
children, CardDemo 3/3 (its MQ-triggered RETRIEVEs), zopeneditor none. No
START TRANSID exists in any pinned corpus; START is covered by unit tests.

Golden masters re-blessed: the only change is a new cics_tasks.json in each
fixture (CBSA + genapp COBOL files); no existing golden file moved.
dead_key_audit: "CHANNEL" allowlisted -- it is a parsed EXEC CICS option word.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ZsVaAkb86P5r5JXDC2Y9g
@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 2a03edd into feat/sql-statement-channel-3446 Sep 24, 2026
2 checks passed
@squid-protocol
squid-protocol deleted the feat/cics-async-channel-3449 branch September 24, 2026 08:53
squid-protocol added a commit that referenced this pull request Sep 24, 2026
* Mainframe fact channel: embedded SQL table access (#3446)

sql_table_data (#3344) held DB2 table SHAPES; nothing said which programs use
which table, or how. New channel sql_statement_data: every embedded SQL
statement (EXEC SQL ... END-EXEC in COBOL, ... ; in PL/I), one row per
(statement, table), with the verb, access (read / insert / update / delete /
merge / lock), cursor and host variables. A statement naming no table (OPEN /
FETCH / CLOSE, COMMIT, CALL) keeps one row, so the cursor lifecycle and
unit-of-work points survive. INCLUDE, DECLARE ... TABLE and WHENEVER are not
statements; dynamic SQL names no table.

Spine per how_to_add_a_fact_channel.md:
- core/db2_sql_statements.py: bounded extractor reusing db2_declare_table's
  sequence-field, literal and comment helpers.
- Wired through extract_boundary, galaxyscope, record_keeper (+ indexes),
  state_rehydrator (byte-identical delta restore) and the audit block and
  LLM brief.
- galaxy_ir: EngineSqlStatement, EngineFile.sql_statements, and the join
  GalaxyIR.sql_table_access(), a program x table matrix where OPEN / FETCH
  reach the cursor's DECLAREd SELECT.

Ground truth: an independent token-walk reader in cobol_answer_key.py
(add-sql-access), a new "DB2 table access" field (TRUTH_FLAGS
sql_access_validated, drafted), and every key drafted. The engine matches
the independent reader exactly: CardDemo 13/13, CBSA 24/24 (zopeneditor has
no SQL). Every non-comment EXEC SQL in the corpora is accounted for.

Golden masters re-blessed: 23 differences, all new `SQL Statements` blocks on
COBOL files, no other movement. keyword-rosetta identical.

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

* test_galaxy_ir: drop redundant local shutil/sqlite3 imports (CodeQL)

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

* Mainframe fact channel: CICS task control and the async task graph (#3449) (#3459)

Only RUN TRANSID reached call_site_data, as a routing verb whose target never
resolved; the async API's join points, START/RETRIEVE data passing and
DELAY/POST/WAIT/ENQ were not modelled, so CBSA's credit-agency fan-out/fan-in
read as one unconnected child start.

New channel cics_task_data: one row per CICS task-control command -- RUN,
START, START ATTACH, FETCH CHILD / FETCH ANY, FREE CHILD, RETRIEVE, CANCEL,
DELAY, POST, WAIT EVENT / WAIT EXTERNAL / WAITCICS, ENQ, DEQ -- with the TRANSID
or RESOURCE target, the CHANNEL, the CHILD / ANY / REQID token, the FROM/INTO
record, the timing and the remaining options.

Target resolution adds one reading to literal / VALUE / MOVE: a transaction id
BUILT by STRING becomes an fnmatch pattern, each source contributing its
literal text or its PIC width (`[0-9]` per digit, `?` per character). CRECUST's
`STRING 'OCR' ..., WS-CC-CNT (PIC 9) ... INTO WS-RUN-TRANSID` is `OCR[0-9]`:
it reaches OCR1..OCR5 and deliberately not OCRA, another transaction in the
same deck. A STRING also assigns the name, so it joins any MOVEd literals as
candidates rather than losing to a sole MOVE.

Spine per how_to_add_a_fact_channel.md:
- core/cics_tasks.py: bounded extractor reusing cics_resources' block and
  option walker; STRING reader bounded by _STRING_LIMIT and the sentence end.
- extract_boundary (cobol + pli), galaxyscope payload, record_keeper table +
  indexes, state_rehydrator byte-identical delta restore, audit block, LLM
  brief summary and per-file line.
- galaxy_ir: EngineCicsTask, EngineFile.cics_tasks, and GalaxyIR.async_tasks():
  each RUN/START joined to the CSD transactions and programs it can reach, the
  containers the parent PUTs on the passed channel, the FETCH ANY / FETCH CHILD
  / FREE CHILD that collect it (by token), and a START's child RETRIEVEs.
  CBSA: CRECUST RUN -> OCR1..OCR5 -> CRDTAGY1..5, containers CIPA..CIPI on
  CIPCREDCHANN, collected by FETCH ANY at line 639.

Ground truth: an independent reader in cobol_answer_key.py (add-cics-tasks)
with its own STRING/PIC reading and CSD expansion; two new scored fields,
"CICS task control" and "async children" (TRUTH_FLAGS cics_tasks_validated,
drafted). The engine matches the key exactly: CBSA 24/24 commands and 5/5
children, CardDemo 3/3 (its MQ-triggered RETRIEVEs), zopeneditor none. No
START TRANSID exists in any pinned corpus; START is covered by unit tests.

Golden masters re-blessed: the only change is a new cics_tasks.json in each
fixture (CBSA + genapp COBOL files); no existing golden file moved.
dead_key_audit: "CHANNEL" allowlisted -- it is a parsed EXEC CICS option word.


Claude-Session: https://claude.ai/code/session_017ZsVaAkb86P5r5JXDC2Y9g

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* db2_sql_statements: build long regexes from named pieces (X-Ray entropy)

The X-Ray entropy scan flagged three long regex literals. Build them from
named parts (_S, _ALIAS_STOP, _FETCH_ORIENTATION, _HOST_NAME) instead; every
compiled pattern is byte-identical to before.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
squid-protocol added a commit that referenced this pull request Sep 24, 2026
…3448) (#3460)

* Mainframe fact channel: embedded SQL table access (#3446)

sql_table_data (#3344) held DB2 table SHAPES; nothing said which programs use
which table, or how. New channel sql_statement_data: every embedded SQL
statement (EXEC SQL ... END-EXEC in COBOL, ... ; in PL/I), one row per
(statement, table), with the verb, access (read / insert / update / delete /
merge / lock), cursor and host variables. A statement naming no table (OPEN /
FETCH / CLOSE, COMMIT, CALL) keeps one row, so the cursor lifecycle and
unit-of-work points survive. INCLUDE, DECLARE ... TABLE and WHENEVER are not
statements; dynamic SQL names no table.

Spine per how_to_add_a_fact_channel.md:
- core/db2_sql_statements.py: bounded extractor reusing db2_declare_table's
  sequence-field, literal and comment helpers.
- Wired through extract_boundary, galaxyscope, record_keeper (+ indexes),
  state_rehydrator (byte-identical delta restore) and the audit block and
  LLM brief.
- galaxy_ir: EngineSqlStatement, EngineFile.sql_statements, and the join
  GalaxyIR.sql_table_access(), a program x table matrix where OPEN / FETCH
  reach the cursor's DECLAREd SELECT.

Ground truth: an independent token-walk reader in cobol_answer_key.py
(add-sql-access), a new "DB2 table access" field (TRUTH_FLAGS
sql_access_validated, drafted), and every key drafted. The engine matches
the independent reader exactly: CardDemo 13/13, CBSA 24/24 (zopeneditor has
no SQL). Every non-comment EXEC SQL in the corpora is accounted for.

Golden masters re-blessed: 23 differences, all new `SQL Statements` blocks on
COBOL files, no other movement. keyword-rosetta identical.

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

* test_galaxy_ir: drop redundant local shutil/sqlite3 imports (CodeQL)

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

* Mainframe fact channel: CICS task control and the async task graph (#3449)

Only RUN TRANSID reached call_site_data, as a routing verb whose target never
resolved; the async API's join points, START/RETRIEVE data passing and
DELAY/POST/WAIT/ENQ were not modelled, so CBSA's credit-agency fan-out/fan-in
read as one unconnected child start.

New channel cics_task_data: one row per CICS task-control command -- RUN,
START, START ATTACH, FETCH CHILD / FETCH ANY, FREE CHILD, RETRIEVE, CANCEL,
DELAY, POST, WAIT EVENT / WAIT EXTERNAL / WAITCICS, ENQ, DEQ -- with the TRANSID
or RESOURCE target, the CHANNEL, the CHILD / ANY / REQID token, the FROM/INTO
record, the timing and the remaining options.

Target resolution adds one reading to literal / VALUE / MOVE: a transaction id
BUILT by STRING becomes an fnmatch pattern, each source contributing its
literal text or its PIC width (`[0-9]` per digit, `?` per character). CRECUST's
`STRING 'OCR' ..., WS-CC-CNT (PIC 9) ... INTO WS-RUN-TRANSID` is `OCR[0-9]`:
it reaches OCR1..OCR5 and deliberately not OCRA, another transaction in the
same deck. A STRING also assigns the name, so it joins any MOVEd literals as
candidates rather than losing to a sole MOVE.

Spine per how_to_add_a_fact_channel.md:
- core/cics_tasks.py: bounded extractor reusing cics_resources' block and
  option walker; STRING reader bounded by _STRING_LIMIT and the sentence end.
- extract_boundary (cobol + pli), galaxyscope payload, record_keeper table +
  indexes, state_rehydrator byte-identical delta restore, audit block, LLM
  brief summary and per-file line.
- galaxy_ir: EngineCicsTask, EngineFile.cics_tasks, and GalaxyIR.async_tasks():
  each RUN/START joined to the CSD transactions and programs it can reach, the
  containers the parent PUTs on the passed channel, the FETCH ANY / FETCH CHILD
  / FREE CHILD that collect it (by token), and a START's child RETRIEVEs.
  CBSA: CRECUST RUN -> OCR1..OCR5 -> CRDTAGY1..5, containers CIPA..CIPI on
  CIPCREDCHANN, collected by FETCH ANY at line 639.

Ground truth: an independent reader in cobol_answer_key.py (add-cics-tasks)
with its own STRING/PIC reading and CSD expansion; two new scored fields,
"CICS task control" and "async children" (TRUTH_FLAGS cics_tasks_validated,
drafted). The engine matches the key exactly: CBSA 24/24 commands and 5/5
children, CardDemo 3/3 (its MQ-triggered RETRIEVEs), zopeneditor none. No
START TRANSID exists in any pinned corpus; START is covered by unit tests.

Golden masters re-blessed: the only change is a new cics_tasks.json in each
fixture (CBSA + genapp COBOL files); no existing golden file moved.
dead_key_audit: "CHANNEL" allowlisted -- it is a parsed EXEC CICS option word.

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

* Mainframe fact channel: job submission through the internal reader (#3448)

The engine recorded both halves of an online->batch submission -- the CICS
WRITEQ TD (cics_resource_data) and the extrapartition TDQUEUE (csd_resource_data)
-- but not the edge "transaction X submits job Y", and nothing of the batch case,
a step whose DD is SYSOUT=(A,INTRDR).

New channel job_submit_data (core/job_submits.py):
- COBOL: the JCL cards a program holds as literals -- `//NAME JOB` (the job
  name) and `//STEP EXEC PROC=|PGM=|P` -- kept only when a JOB card is among
  them, so a DISPLAY '//...' is never JCL. One bounded literal regex, shielded.
- JCL: every DD routed to the internal reader, with the step's SYSUT1 DSN
  (what IEBGENER copies there), read from the existing _jcl_statements parse.

galaxy_ir: EngineJobSubmit, EngineFile.job_submits, and
GalaxyIR.job_submissions():
- online (`tdq`): WRITEQ TD to an extrapartition TDQUEUE, when some JCL routes
  its DDNAME to SYSOUT=(x,INTRDR) (`region_jcl`) or the writer embeds a job
  card (`job_card`); with the transactions that enter the writer, the job
  names and each EXEC target resolved to its JCL member (a PROC prefers the
  procedure member: TRANREPT.prc over TRANREPT.jcl).
- batch (`intrdr_dd`): the SYSUT1 library member resolved to its JCL file.
CardDemo: CR00 -> CORPT00C -> TDQ JOBS (INREADER) -> job TRNRPT00 ->
PROC TRANREPT = app/proc/TRANREPT.prc; INTRDRJ1 -> INTRDRJ2.

Ground truth: an independent join in cobol_answer_key.py (add-job-submissions)
with its own line-by-line JCL read, job-card scan and CSD / WRITEQ readers; new
scored field "job submissions" (TRUTH_FLAGS submissions_validated, drafted).
Engine matches the key exactly: CardDemo 3/3; CBSA and zopeneditor submit
nothing.

Golden masters re-blessed: one new Job Submission block (CORPT00C), nothing
else moved.

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

* Mainframe fact channel: CICS task control and the async task graph (#3449) (#3459)

Only RUN TRANSID reached call_site_data, as a routing verb whose target never
resolved; the async API's join points, START/RETRIEVE data passing and
DELAY/POST/WAIT/ENQ were not modelled, so CBSA's credit-agency fan-out/fan-in
read as one unconnected child start.

New channel cics_task_data: one row per CICS task-control command -- RUN,
START, START ATTACH, FETCH CHILD / FETCH ANY, FREE CHILD, RETRIEVE, CANCEL,
DELAY, POST, WAIT EVENT / WAIT EXTERNAL / WAITCICS, ENQ, DEQ -- with the TRANSID
or RESOURCE target, the CHANNEL, the CHILD / ANY / REQID token, the FROM/INTO
record, the timing and the remaining options.

Target resolution adds one reading to literal / VALUE / MOVE: a transaction id
BUILT by STRING becomes an fnmatch pattern, each source contributing its
literal text or its PIC width (`[0-9]` per digit, `?` per character). CRECUST's
`STRING 'OCR' ..., WS-CC-CNT (PIC 9) ... INTO WS-RUN-TRANSID` is `OCR[0-9]`:
it reaches OCR1..OCR5 and deliberately not OCRA, another transaction in the
same deck. A STRING also assigns the name, so it joins any MOVEd literals as
candidates rather than losing to a sole MOVE.

Spine per how_to_add_a_fact_channel.md:
- core/cics_tasks.py: bounded extractor reusing cics_resources' block and
  option walker; STRING reader bounded by _STRING_LIMIT and the sentence end.
- extract_boundary (cobol + pli), galaxyscope payload, record_keeper table +
  indexes, state_rehydrator byte-identical delta restore, audit block, LLM
  brief summary and per-file line.
- galaxy_ir: EngineCicsTask, EngineFile.cics_tasks, and GalaxyIR.async_tasks():
  each RUN/START joined to the CSD transactions and programs it can reach, the
  containers the parent PUTs on the passed channel, the FETCH ANY / FETCH CHILD
  / FREE CHILD that collect it (by token), and a START's child RETRIEVEs.
  CBSA: CRECUST RUN -> OCR1..OCR5 -> CRDTAGY1..5, containers CIPA..CIPI on
  CIPCREDCHANN, collected by FETCH ANY at line 639.

Ground truth: an independent reader in cobol_answer_key.py (add-cics-tasks)
with its own STRING/PIC reading and CSD expansion; two new scored fields,
"CICS task control" and "async children" (TRUTH_FLAGS cics_tasks_validated,
drafted). The engine matches the key exactly: CBSA 24/24 commands and 5/5
children, CardDemo 3/3 (its MQ-triggered RETRIEVEs), zopeneditor none. No
START TRANSID exists in any pinned corpus; START is covered by unit tests.

Golden masters re-blessed: the only change is a new cics_tasks.json in each
fixture (CBSA + genapp COBOL files); no existing golden file moved.
dead_key_audit: "CHANNEL" allowlisted -- it is a parsed EXEC CICS option word.


Claude-Session: https://claude.ai/code/session_017ZsVaAkb86P5r5JXDC2Y9g

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* Mainframe fact channel: IBM MQ calls -- queues, direction, handles (#3447) (#3461)

CALL 'MQOPEN' / 'MQPUT' / 'MQGET' reached call_site_data as external calls
only; nothing said which program puts to or gets from which queue.

New channel mq_call_data (core/mq_calls.py): one row per MQI call with the
verb, direction (MQOO-* open options; PUT put, GET get), the queue, the handle
and the option words in effect.
- The queue of an MQOPEN / MQPUT1 is the operand last MOVEd to its descriptor's
  OBJECTNAME (qualified `OF <od>` or not), read as a literal / VALUE / MOVEd
  literals, following name-to-name MOVEs (depth 3). Two runtime sources are
  named, never guessed: `trigger` (MQTM-QNAME, the queue whose trigger started
  the transaction) and `reply_to` (MQMD-REPLYTOQ).
- A PUT / GET / CLOSE is matched to its MQOPEN by handle: the one it passes,
  or the one MOVEd into its handle operand just before it, with the copies an
  open's handle gets before the next MQ call (`MOVE MQ-HOBJ TO
  INPUT-QUEUE-HANDLE`) -- so CardDemo's shared MQ-HOBJ still resolves.
- Fixed-format sequence fields are blanked first: in numbered source the
  cols 73-80 tag used to end a CALL's operand list. The ground-truth ledger
  caught this on the real scan (COACCT01/CODATE01 4/22 -> 22/22).

Spine per how_to_add_a_fact_channel.md: extract_boundary (cobol), payload,
record_keeper table + indexes, byte-identical delta restore, audit block, LLM
per-file queue line; galaxy_ir EngineMqCall / EngineFile.mq_calls,
GalaxyIR.mq_queues (per-program endpoints, runtime queues named) and mq_flows
(producer -> consumer through a named queue).

Ground truth: an independent token-walk reader (add-mq) with its own MOVE,
COMPUTE and handle tracking; new scored field "MQ calls" (mq_validated,
drafted). Engine matches the key exactly: CardDemo 22/22; CBSA and zopeneditor
make no MQ calls. CardDemo's MQ programs are request/reply services whose
requesters are outside the repo, so no in-repo producer->consumer pair exists.

Golden masters unchanged (no MQ program in the crucible corpus).


Claude-Session: https://claude.ai/code/session_017ZsVaAkb86P5r5JXDC2Y9g

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* db2_sql_statements: build long regexes from named pieces (X-Ray entropy)

The X-Ray entropy scan flagged three long regex literals. Build them from
named parts (_S, _ALIAS_STOP, _FETCH_ORIENTATION, _HOST_NAME) instead; every
compiled pattern is byte-identical to before.

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

* job_submits: build the JCL card regex from a named piece (X-Ray entropy)

Same fix as db2_sql_statements in #3458: the compiled pattern is
byte-identical; the literal no longer reads as a dense string.

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

---------

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