Repository navigation
cobol args −92%: the overlap-cost rejection was priced before #2729 planted ENTRY on every paragraph — the api cost it avoids is already paid #2804
Description
args cobol 1, median 13, −92% — the worst gated cell in the language, and avg_func_args 0 (−100%) follows it. The ledger declines the plant on an overlap-cost argument that #2729 has since made obsolete.
Measured 2026-09-06 on engine main a59ecf6b / corpus main 2038a86. Ledger: cobol-args-clause-match-morphology, args-no-parameter-surface-morphology.
The standing verdict, and why it no longer holds
cobol-args-clause-match-morphology rejects a per-probe args plant on two grounds:
(2) the file-level
argsmetric counts rule MATCHES, not captured names — verified empirically … a modified shell whosePROCEDURE DIVISION USINGcarried 13 parameter names still recordsstruct_args1. (3) Every construct that would add per-probeUSING/RETURNINGmatches (CALL … USING,ENTRY … USING,INVOKE … RETURNING) is ALSO an api-rule keyword, so planting 12 of them would trade one red for api distortion — overlap-cost rejection.
Ground (3) was priced in August. #2729 then planted ENTRY 'PROBE-X'. on all nine copybook paragraphs anyway, for the api rule — data/cobol/a.cpy L11/L15/L19, and the same in b.cpy/c.cpy. The api cost the rejection was avoiding is already on the books.
Screened against the live compiled rules (tools/screen_plant.py, engine a59ecf6b):
[CLEAN] ENTRY 'PROBE-GLOBALS'. api=1 (nothing else) <- planted today
[COLLATERAL] ENTRY 'PROBE-GLOBALS' USING ARGS-ITEM. args=1 also fires: api=1 <- the same api=1
Appending USING <item> to nine lines that already exist is args +9 at zero marginal collateral. args goes 1 → 10 against the 13 median: −23%, green, from −92% red.
It stops at 10, not 13, and that is deliberate: main.cbl's four paragraphs have no ENTRY, and giving them one would take main's raw_arch_api 1 → 5 and break the file-level api plant api-non-function-surfaces depends on. Ten is the honest ceiling for the plant alone.
Ground (2) is a real engine gap, and it is the other half
ENTRY … USING A, B, C and PROCEDURE DIVISION USING A, B, C both read 1, because the file-level signal count is len(finditer(...)) and cobol's args rule captures the whole comma list in one group:
"args": re.compile(
r"\b(?:USING|RETURNING)\s+((?:(?:BY\s+(?:REFERENCE|CONTENT|VALUE)\s+)?(?!RETURNING\b)[A-Z0-9_-]+\s*,?){0,20})",
re.I,
),The engine already has the mechanism for exactly this: args_count_override, which turns one match into a real operand count via _count_agc_register_args and _count_assembly_register_args. detector.py L3040 names the languages that never get one:
for the 4 Mode A languages that never get a dedicated
args_count_overrideat all (cobol, fortran, dockerfile, jcl), the generic args-count derivation … defaults to searching the WHOLE greedyblock
so cobol falls to the generic bounded-window path and counts clauses, not names.
Why this is worth reopening rather than leaving ledgered
args-no-parameter-surface-morphology has already been falsified twice, and the entry says so itself:
- agc_assembly left it by authoring —
#2669 A.3plantedCA Aat each probe entry,args2 → 13,avg_func_args0.167 → 1.0. The entry notes its own item list "was written against the pre-A bias_data cache and still named it." - yaml left it via yaml: args matches only a with: block — inputs: declarations are invisible and a block counts as one argument #2753 / engine PR fix(core-engine): yaml args reads declared inputs: and counts parameters, not blocks (#2753) #2759 — and the entry's own words are that the original reasoning "is correct about
with:and was written before anyone checked the OTHER half of yaml's parameter surface." yaml now readsargs13, green.
cobol is the third language whose "no parameter surface" verdict was written before someone checked the other half. COBOL alternate entry points genuinely take USING; that is the language's per-paragraph parameter surface, and the corpus already declares one on every paragraph.
Candidate shapes
(a) Corpus-only. Append USING <item> to the nine existing ENTRY lines. args 1 → 10 (green). No engine change. Cheapest, and it lands independently of (b).
(b) Engine: give cobol an args_count_override. Split the captured USING/RETURNING operand list on commas, the way _count_agc_register_args splits register operands. This is what makes a single PROCEDURE DIVISION USING A, B, C read 3, and it is the fix that generalises to real COBOL — a production program's linkage section routinely passes several operands and currently scores 1.
(c) Both. (a) moves the cell; (b) makes the number mean parameters rather than clauses. They are independent and neither blocks the other.
Open question I could not settle from a regex screen
Whether avg_func_args follows. cobol is in the _mode_a_args_window_end bounded set, which limits the per-function search to "the label's own statement span" — and in COBOL the paragraph name (PROBE-GLOBALS.) is terminated by its own period, so the ENTRY line on the next line is a separate statement and may fall outside the window. If it does, file-level args reaches 10 (it is a plain finditer over the file) while avg_func_args stays 0. That needs a real galaxyscope --db-only run, not a screen. If it holds, (b) or a window adjustment is required to move avg_func_args at all.
Corpus pairing
data/cobol/{a,b,c}.cpy — nine lines gain USING <item>; expected_signals.json re-blesses args 1 → 10 and, if the window question resolves favourably, avg_func_args. No other gated signal moves (api is unchanged, screened above). cobol-args-clause-match-morphology closes; args-no-parameter-surface-morphology loses cobol for args and keeps it for avg_func_args only if the window blocks it — the same split the entry already applies to yaml. rosetta:rebless-owed.
Part of #2669. Related: #2729, #2753, #2759 (all closed), #2567.
Activity
test(golden-crucible): re-bless cobol baselines for #2805 globals + #…
test(golden-crucible): re-bless cobol baselines on merged main (#2805, …
fix(cobol): globals drops WORKING-STORAGE header (#2805); args counts…
squid-protocol commentedon Sep 6, 2026
Engine half merged in #2830 (with #2805): COBOL
argsnow counts declared operands, not USING/RETURNING clauses. The rule captures the full operand list (comma/space/newline-separated, bounded so it can't over-read past a period-less statement or into fixed-format cols 73–80), and_count_cobol_using_operandsturns each clause into a real parameter count (dropping BY REFERENCE/CONTENT/VALUE). Verified on the crucible corpus: e.g. CSUTLDPY.cpy 1→3, IC2014 11→44, IC2244 12→48. Golden masters re-blessed.This is the general-correctness half (issue shape (b)); it's invisible on the single-operand rosetta shell, so the chart cell is not yet moved. Remaining to close: the optional corpus shape (a) — append
USING <item>to the nineENTRYlines indata/cobol/{a,b,c}.cpy(args 1→10), plus the openavg_func_argswindow question this issue flagged. Leaving open for that corpus follow-up.squid-protocol commentedon Sep 7, 2026
Corpus half (shape (a)) is up as keyword-rosetta#97, and the open
avg_func_argsquestion this issue flagged is answered.The plant. The nine
ENTRY 'PROBE-X'.lines indata/cobol/{a,b,c}.cpyeach gainUSING ARGV-BLOCK— main.cbl'sLINKAGE SECTIONitem, which is what a real COBOLENTRY … USINGoperand must be.args1 → 10 against the 13 median: −92% → −23%, in band. Screened end-to-end on engine main2655985:argsis the only column that moves, in any file —apistays 1/3/3/3,api_orphan_creditstays 3 in a/b/c, exactly as the issue predicted. It stops at 10 for the reason given here: main.cbl's four paragraphs carry noENTRY, and giving them one would take main'sraw_arch_api1 → 5.The open question resolves as feared, and the cause is pinned.
avg_func_argsstays 0.0. The sharp form: the engine's own function record disagrees with itself —hit_vectorattributes theUSINGto the paragraph correctly; the function'sargsfield, whichavg_func_argsaverages, reads 0 because it is computed off_mode_a_args_window_end— "A language with no continuation marker (cobol) never extends past its own first line." A paragraph label ends at its own period, so theENTRYstatement one line down is outside the window while still inside the block.Micro-repro, one variable (the
ENTRYstatement's line position, legal COBOL either way): as plantedargs=0; folded onto the label lineargs=1; folded withUSING A, B, Cargs=3. So the window is the sole blocker, and #2830's operand counting already reaches the per-function path. Filed as #2863.Folding
ENTRYonto the label line would turn the cell green and is deliberately not done — real Enterprise COBOL writesENTRYon its own line, so it would buy a green rosetta cell while every real COBOL program kept reading 0, the opposite of what #2830 landed for.Ledger.
cobol-args-clause-match-morphologyis retired (ground (2) fixed by #2830, ground (3) screened away by this plant, ground (1) — "paragraphs declare no parameters in COBOL" — simply wrong). cobol is removed fromargs-no-parameter-surface-morphologyentirely, the third language to falsify it after agc_assembly and yaml;avg_func_argsgets its own entry pointing at #2863 rather than staying on a premise that is now false.One number moves the "wrong" way and should: open-defect share 25 → 26 of 2645 (0.9% → 1.0%),
inherency77 → 75,extraction19 → 20. That isavg_func_argsreclassified from "the language cannot express this" to "an engine gap somebody owes". The cell was never inherency.Ready to close once keyword-rosetta#97 merges; #2863 carries the remainder and owes no re-bless.
fix(detector): a COBOL paragraph's ENTRY ... USING is its parameter d…
squid-protocol commentedon Sep 8, 2026
All three shapes are landed and verified on the current bias data (corpus main, engine main
9f5d57c6):argscounts declared operands, not clauses (_count_cobol_using_operands).USING ARGV-BLOCKon the nineENTRYlines.argscobol reads 10 vs median 13 (−23%), in band, from 1 (−92%).ENTRY ... USINGnow counts inside its paragraph's args window.avg_func_argscobol reads 0.75 vs median 1 (−25%), in band, from 0.0 (−100%).Ledger:
cobol-args-clause-match-morphologyretired and cobol removed fromargs-no-parameter-surface-morphologyin keyword-rosetta#97 as planned. Neither cobol args cell is an open defect in the current report's cause table. Closing.The remaining args-contract residue is abap's call-site counting (#2824), which has its own fix in flight.