Skip to content

yaml: args matches only a with: block — inputs: declarations are invisible and a block counts as one argument #2753

Description

@squid-protocol

Found by the #2669 pass over every non-green cell in the keyword-rosetta bias report (2026-09-05, engine 0e521e8). yaml/args reads 0 against a median of 13 and avg_func_args 0.0 against 1.0; both are ledgered as args-no-parameter-surface-morphology because the rule "matches a with: block, which binds to uses: and never to the corpus's run: steps". The rule is narrower than the language on two axes.

1. with: is the call-site argument block; the declarations are inputs:

yaml.py's args matches only

r"^[ \t]*with:[ \t]*(?:#.*)?\n(?:[ \t]*(?:#.*)?\n){0,10}[ \t]+[a-zA-Z0-9_-]+:[ \t]*.*"

with: supplies arguments to an action. The parameter surface a YAML file declares — the thing every other language's args rule reads off the def/function/sub line — is inputs::

None of these match today. On language-crucible's yaml corpus (8 Ansible task files, 77bc85e) with: fires 0 times, so the rule is also unexercised by the golden master (the caveat #2646/#2647 recorded as language-crucible#23). Ansible's own parameter blocks — vars: on include_role/include_tasks (5 in crucible) and module args: — are likewise unseen.

2. It counts blocks, not parameters

The regex consumes the block header through its first key as one match, so with: carrying five inputs is args 1. yaml defines none of the _args_* capture helpers, so nothing splits the list. Every other language records one hit per parameter; a with: block with five keys is five arguments by the same definition.

Candidate shape

# Parameter surfaces: a declared inputs: block (workflow_dispatch / workflow_call /
# action.yml) or a supplied with: / args: block. One hit per key, not per block.
"args": re.compile(
    r"^[ \t]*(?:with|inputs|args):[ \t]*(?:#.*)?\n"
    r"(?:[ \t]*(?:#.*)?\n){0,10}[ \t]+([a-zA-Z0-9_-]+):",
    re.M,
),

plus an _args_pattern_list_groups-style helper (or an indentation walk) to count every key at the block's child indentation rather than the first. Whether Ansible vars: is a parameter block or a variable block is the design question — it is both, depending on the task.

Overlap, measured (screen_plant.py)

An inputs: block under the corpus's existing on: workflow_dispatch: fires nothing new (the api hit shown is the pre-existing trigger). The plant must use required:/default: only — a description: under an input is a doc hit (yaml's doc rule matches every description: line). A with: under a uses: step is the ledger's rejected form (it needs a uses: line = import + a DAG edge); an inputs: declaration needs neither.

Corpus pairing

a.yml already carries on: workflow_dispatch:; an inputs: block with one key per probe (12 keys) reads args 12 under a per-key count, or 1 under today's per-block count. Either ends the 0; the ledger entry narrows or retires for yaml.

Part of #2669 (rosetta[yaml] is #2606).


Filed together on 2026-09-05: jcl api #2748 · jcl cleanup #2749 · jcl globals #2750 · jcl high_risk_execution #2751 · css io #2752 · yaml args #2753. Corpus-side pairings: squid-protocol/keyword-rosetta#59.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    core-engineModifications to the central physics and parsing engineenhancementNew feature, sensor, or structural signaturemetricsHeuristics, risk exposures, and topological math updates

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions