You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Found by the #2669 pass over every non-green cell in the keyword-rosetta bias report (2026-09-05, engine 0e521e8). jcl/globals is n/a (jcl.py L151 "globals": None), ledgered under jcl-2610-rebaseline-residual-morphology as "no scoped-vs-global distinction (JOBLIB/STEPLIB plants would inflate io + dependency_links)". JCL has that distinction in three places, and the overlap the entry feared is one the engine already accepts for dockerfile.
The morphology is real
job-scoped (global)
step/proc-scoped (local)
language-crucible (186 files)
//JOBLIB DD — program search library for every step of the job
//STEPLIB DD — the same, for one step
JOBLIB 32 files · STEPLIB 70 lines in 59 files
// SET SYM=value — a symbol every later statement in the job can read
//name PROC SYM= — a symbolic parameter scoped to the procedure
SET 39 lines in 12 files
// EXPORT SYMLIST=(…) — makes symbols visible inside in-stream data
(none)
2
That is precisely the global-vs-scoped pair globals measures elsewhere: python's module-level name vs a def-local, dockerfile's ENV (image-wide) vs a RUN-local export, yaml's ${{ env.X }}. The engine reads jcl's SET today, but only as state_mutation.
Candidate shape
# Job-scoped declarations: JOBLIB (job-wide search library, vs the step-scoped# STEPLIB), a job-level SET symbol (vs a PROC parameter), and EXPORT SYMLIST."globals": re.compile(
r"^[ \t]*//JOBLIB[ \t]+DD\b"r"|^[ \t]*//[A-Za-z0-9_#$@]*[ \t]+(?:SET[ \t]+[A-Za-z0-9_#$@]+=|EXPORT[ \t]+SYMLIST\b)",
re.M|re.I,
),
Overlap, measured (screen_plant.py)
//SET1 SET COUNTER=1 → state_mutation 1. This is dockerfile's ENV shape exactly — ENV is dual globals + state_mutation in the engine and ledgered as such (batch4-dual-keyword-overlaps). A declaration that creates a job-wide symbol is both the creation of global state and a mutation of it.
//JOBLIB DD DSN=X,DISP=SHR → io 2 (DSN, DISP=SHR) and a _dependency_capture edge on the DSN. The edge is correct — a JOBLIB is a dependency of every step — and the io reading is the same accepted overlap feat(core-engine): jcl sync_locks counts the exclusive-ENQ dispositions (#2733) #2742 took for sync_locks. If the double count is unwanted, the JOBLIB alternative can be dropped and SET/EXPORT alone carry the rule.
// EXPORT SYMLIST=(COUNTER) → clean.
Corpus pairing
keyword-rosetta's b.jcl already carries //SET1 SET COUNTER=1 and //SET2 SET NOTE=GO (its state_mutation plant), so with the SET alternative the corpus reads globals 2 with no new plant — exactly the median. The cell goes from n/a to green in the same re-bless; only b.jcl's manifest row changes (globals 0 → 2). The SPEC puts globals in probe_globals (a.jcl), so the corpus may prefer to move the plant; either way nothing manufactures a red cell.
Part of #2669 (rosetta[jcl] was #2581). Siblings from the same pass: jcl api, jcl cleanup, jcl high_risk_execution.
Found by the #2669 pass over every non-green cell in the keyword-rosetta bias report (2026-09-05, engine 0e521e8).
jcl/globalsis n/a (jcl.pyL151"globals": None), ledgered underjcl-2610-rebaseline-residual-morphologyas "no scoped-vs-global distinction (JOBLIB/STEPLIB plants would inflate io + dependency_links)". JCL has that distinction in three places, and the overlap the entry feared is one the engine already accepts for dockerfile.The morphology is real
//JOBLIB DD— program search library for every step of the job//STEPLIB DD— the same, for one step// SET SYM=value— a symbol every later statement in the job can read//name PROC SYM=— a symbolic parameter scoped to the procedure// EXPORT SYMLIST=(…)— makes symbols visible inside in-stream dataThat is precisely the global-vs-scoped pair
globalsmeasures elsewhere: python's module-level name vs adef-local, dockerfile'sENV(image-wide) vs aRUN-localexport, yaml's${{ env.X }}. The engine reads jcl'sSETtoday, but only asstate_mutation.Candidate shape
Overlap, measured (
screen_plant.py)//SET1 SET COUNTER=1→state_mutation1. This is dockerfile'sENVshape exactly —ENVis dualglobals+state_mutationin the engine and ledgered as such (batch4-dual-keyword-overlaps). A declaration that creates a job-wide symbol is both the creation of global state and a mutation of it.//JOBLIB DD DSN=X,DISP=SHR→io2 (DSN,DISP=SHR) and a_dependency_captureedge on the DSN. The edge is correct — a JOBLIB is a dependency of every step — and the io reading is the same accepted overlap feat(core-engine): jcl sync_locks counts the exclusive-ENQ dispositions (#2733) #2742 took forsync_locks. If the double count is unwanted, the JOBLIB alternative can be dropped and SET/EXPORT alone carry the rule.// EXPORT SYMLIST=(COUNTER)→ clean.Corpus pairing
keyword-rosetta's
b.jclalready carries//SET1 SET COUNTER=1and//SET2 SET NOTE=GO(itsstate_mutationplant), so with the SET alternative the corpus readsglobals2 with no new plant — exactly the median. The cell goes from n/a to green in the same re-bless; onlyb.jcl's manifest row changes (globals 0 → 2). The SPEC putsglobalsinprobe_globals(a.jcl), so the corpus may prefer to move the plant; either way nothing manufactures a red cell.Part of #2669 (rosetta[jcl] was #2581). Siblings from the same pass: jcl
api, jclcleanup, jclhigh_risk_execution.Filed together on 2026-09-05: jcl
api#2748 · jclcleanup#2749 · jclglobals#2750 · jclhigh_risk_execution#2751 · cssio#2752 · yamlargs#2753. Corpus-side pairings: squid-protocol/keyword-rosetta#59.