Skip to content

damage-control batch 4: computed verbs resolved or fail closed; unread piped programs - #1147

Merged
dotdevdotdev merged 3 commits into
mainfrom
dc-batch4
Oct 19, 2026
Merged

dotdevdotdev merged 3 commits into
mainfrom
dc-batch4

Conversation

@dotdevdotdev

Copy link
Copy Markdown
Owner

Batch 4 of the damage-control residuals (rows 11, 12 of the inventory): computed verbs and programs piped from producers the scanner can't read.

What changed

  • Resolve (_indirect_verbs → _hidden_commands): same-command literal scalars/exports, literal arrays, for/select lists, aliases, functions (call args substituted for $1/"$@"/$#), and concatenation (x=ev;y=al; $x$y). Each resolved command is judged by the same engine, also inside sh -c/ssh payloads.
  • Unresolvable → core.indirect-verb (unverifiable ask): variable filled by a substitution/read/computed loop list; a head that glues expansions (e${x}val); any unresolved expansion in a command that names a control-plane path. Bare env names ($CC -o x, $EDITOR f, $VENV/bin/python, "$@") pass.
  • Unread producers: curl|wget|… | sh|bash|python3 - → block (core.fetched-program-pipe); cat f | sh and other producers → unverifiable ask. -c, script operands, curl | jq, echo|sh (already read) unaffected.

Measurement (audit-log replay, 6,563 distinct Bash commands, 9 days)

  • $VAR in command position: ~230 commands, 222 same-command literals (now resolved), 8 truly unresolved. $CC/$EDITOR/"$@" as verb: 0. alias-as-verb: 1. curl|sh / cat|sh executions: 0.
  • Before/after: 2 diffs, both ask → ask (already-asking PY=$(…); $PY commands, now unverifiable instead of bypass-demotable). 0 allow→ask, 0 →block. Log is dominated by this fleet's own DC work: a floor on benign shapes, not a census.
  • Tier choice: curl|sh block because measured use is zero and the safe rewrite (download, read, run file) is untouched; cat|sh ask because it is rephraseable to bash file.

Verification

  • New tests/unit/test_damage_control_indirect_verbs.py: differential (decision behind every indirection == decision alone, absolute too), wrappers, controls for everyday shapes. Mutation-checked: dropping the resolved rescan, the unresolved ask, the fetch block, the pipe ask, and the pure-head carve-out each turn a distinct test red.
  • Full fast suite (-m "not requires_tmux and not slow"): green. One pin in test_path_resolution_lane.py used ls … | sh as a "harmless" control; that is now (by design) an ask, so the control became echo ls | sh.
  • No rule YAML change, so no baseline/count change and no hook-deploy skew (hooks regenerated).

Docs: docs/wiki/internals/damage-control.md — new section, closed residuals removed.

Built by dotdev.dev

…d piped programs (#1065)

Resolve same-command scalars/arrays/for-lists/aliases/functions and rescan with all rules;
unresolvable shapes ask unverifiably (env names pass); curl|sh blocks, cat|sh asks.

Built by dotdev.dev
…sition assigns, wrongful-ask carve-outs

Built by dotdev.dev
…ed fetch consumers and substitution-wrapped pipes

Built by dotdev.dev
@dotdevdotdev
dotdevdotdev marked this pull request as ready for review October 19, 2026 13:03
@dotdevdotdev
dotdevdotdev merged commit 404f916 into main Oct 19, 2026
5 checks passed
@dotdevdotdev
dotdevdotdev deleted the dc-batch4 branch October 19, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant