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
{{ message }}
Repository navigation
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
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):
Two of its alternatives count ordinary shell as metaprogramming:
\$\{!?[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_]+\}.
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).
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.
Activity
feat(core-engine): per-file dynamism replaces the flat language irc i…
squid-protocol commentedon Sep 4, 2026
Fixed in #2725 (branch
fix/2722-shell-reflection, off4c283edf).Measured before touching anything, over the crucible's 255 shell files / 26,274 coding LOC, each alternative counted independently:
${var}$(...)`...`awk|sed|perl|python|ruby '...'eval $${!var}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., goreflect./unsafe./cgo, rubymethod_missing/define_method, jsReflect/Proxy/__proto__. None counts invoking another program; python's does not fire onsubprocess.run.$(date)is that same call and its result is data, not code.test_shell_strict.pyL105 now pins it as the NEGATIVE half of the pair, witheval "\$cmd"as the positive.Took the suggested fix in full: dropped
$(...)/backticks and the!?, kept the inline sub-language programs and${!var}, addedevalunanchored (the old\\beval\\s+\$missedeval "\$cmd"), namerefsdeclare/typeset/local -n, andsource/.of a computed path. 4,863 -> 227 hits, 73 of 255 files still carrying one;configure-helper.sh1,019 -> 15.Golden master re-blessed both venvs: 508 diffs, 0 topological, all shell files (the
shell/tree plus wrf's.csh/.kshscripts andtigerbeetle/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.shgains 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 bycleanup) and a "runs a command" home for$(...), which would be a new signal rather than this fix.fix(core-engine): shell reflection counts dispatch, not command subst…