Skip to content

shell: reflection_metaprogramming matches plain ${var} expansion (indirection marker is optional) and every $(...) -- 1,019 hits in 2,823 LOC on configure-helper.sh #2722

Closed

Description

@squid-protocol

Found while attributing #2719's golden-master diff: with per-file dynamism (reflection_metaprogramming) feeding documentation risk, 15 of the crucible's 46 shell files jump ≥ 25 points, to ~99% -- configure-helper.sh reads 1,019 reflection hits in 2,823 coding lines, ansible-galaxy__runme.sh 149 in 333, xcrun_cache.sh 122 in 225.

The shell rule (gitgalaxy/standards/language_standards/languages/shell.py):

\$\((?:[^()]|\([^()]*\))+\)|`[^`]+`|\b(?:awk|sed|perl|python[23]?|ruby)\s+['"][^'"]{0,500}|\beval\s+\$|\$\{!?[a-zA-Z0-9_]+\}

Two of its alternatives count ordinary shell as metaprogramming:

  1. \$\{!?[a-zA-Z0-9_]+\} -- the !? makes the indirection marker optional, so plain ${var} matches. ${!var} (indirect expansion) is reflection; ${var} is a variable. This looks like a typo for \$\{![a-zA-Z0-9_]+\}.
  2. \$\((?:...)\) and backticks -- every command substitution. test_shell_strict.py L105 pins output=$(date) as a positive, so this one is a deliberate decision by the rule's author; whether "runs a command" is the same thing as "dynamic dispatch a reader can't follow" is the question. On real shell it is one hit per ~3 lines, which is the language's vocabulary, not its dynamism -- the same shape as the control_flow_ratio vocabulary leak in length leaks: func_internal_density, avg_func_loc and control_flow_ratio read file length with content and tier held equal (rosetta F.1 design pass) #2705.

Suggested fix: (1) is a one-character change (!? → !) and should be uncontroversial; for (2), keep eval, ${!var}, declare -n, source/. of a computed path, and the inline awk|sed|perl|python programs, and drop bare $(...)/backticks -- or move them to a signal that means "runs a command". reflection_metaprogramming is unplanted in keyword-rosetta, so the change is not gate-visible there; it is golden-master-visible (documentation and cognitive load on shell).

Related: #2716 (three-input model), #2719 (per-file dynamism), #2705 (vocabulary leaks).

Activity

  1. added
    bugUnintended behavior or logic failure in the engine
    metricsHeuristics, risk exposures, and topological math updates
    core-engineModifications to the central physics and parsing engine
    on Sep 4, 2026
  2. squid-protocol commented on Sep 4, 2026

    @squid-protocol
    OwnerAuthor

    Fixed in #2725 (branch fix/2722-shell-reflection, off 4c283edf).

    Measured before touching anything, over the crucible's 255 shell files / 26,274 coding LOC, each alternative counted independently:

    alternative hits share
    ${var} 4,117 84.7%
    $(...) 789 16.2%
    `...` 164 3.4%
    awk|sed|perl|python|ruby '...' 152 3.1%
    eval $ 5 0.1%
    ${!var} 0 0.0%

    So (1) is even more lopsided than it looked: ${!var}, the construct the alternative exists for, does not occur in the corpus at all -- every one of those 4,117 hits was a plain variable.

    On (2) the registry settles it rather than the test pin. Every other language's rule counts name-based dynamic dispatch and introspection -- python getattr/setattr/inspect., go reflect./unsafe./cgo, ruby method_missing/define_method, js Reflect/Proxy/__proto__. None counts invoking another program; python's does not fire on subprocess.run. $(date) is that same call and its result is data, not code. test_shell_strict.py L105 now pins it as the NEGATIVE half of the pair, with eval "\$cmd" as the positive.

    Took the suggested fix in full: dropped $(...)/backticks and the !?, kept the inline sub-language programs and ${!var}, added eval unanchored (the old \\beval\\s+\$ missed eval "\$cmd"), namerefs declare/typeset/local -n, and source/. of a computed path. 4,863 -> 227 hits, 73 of 255 files still carrying one; configure-helper.sh 1,019 -> 15.

    Golden master re-blessed both venvs: 508 diffs, 0 topological, all shell files (the shell/ tree plus wrf's .csh/.ksh scripts and tigerbeetle/download.sh), every other language zero, and 20 files' Documentation Exposure falls by >=25 -- the reversal of the jumps #2719 flagged. Exactly one value in the corpus rises: sqlite/tclConfigShToMake.sh gains a hit for . "\$1", in a file whose header comment calls itself "a level of indirection".

    Considered and left out: trap '...' SIG (code in a string, but owned by cleanup) and a "runs a command" home for $(...), which would be a new signal rather than this fix.

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

    bugUnintended behavior or logic failure in the enginecore-engineModifications to the central physics and parsing enginemetricsHeuristics, risk exposures, and topological math updates

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions