Seven reported defects, six of them false positives or negatives in the same
family: dcg was judging the text of a command rather than what the command
would actually do. A SQL keyword that was only ever a filename, a POSIX
end-of-options marker, a variable dcg had already proven elsewhere in the same
command, a German commit message -- each was read as evidence of something it
was not.
Fixed
-
A SQL keyword used as an ordinary filename no longer denies (#394).
cat truncate x,sort truncate bandwc -l truncate xwere denied as
database.mysql:truncate-table, because the rule matched the bare word
TRUNCATEfollowed by an identifier with no SQL execution context at all.
Both the MySQL and PostgreSQL TRUNCATE rules now require the statement to
start in statement position under a SQL client, somysql -eandpsql -c
forms still deny while file readers pass. -
The POSIX end-of-options marker keeps the literal temp exemption (#395).
rm -rf -- /tmp/foois what a careful script writes so an operand beginning
with-cannot be parsed as a flag -- strictly safer than the spelling dcg
already allowed, and it was denied bycore.filesystem:rm-rf-general. Every
temp-dir rm safe pattern now admits an optional bare--. It widens the
accepted syntax, not the eligible operands: a home-directory operand and a
traversal out of/tmpstill deny, and--no-preserve-rootis not a bare
--. -
A proven
$VARrm operand gets the same exemption its literal value gets
(#396). dcg has folded a single literal assignment for the redirect rule
since #275, so a redirect into"$D/f"was allowed while a recursive delete
of the same proven path was denied -- the same value, proven by the same
machinery, judged differently. That inversion rewarded hard-coding a temp
path overmktemp -d, which is backwards. The proven value is now spliced
into the segment and the real rm classifier is asked again, so only a command
that would independently be allowed is allowed: a non-temp value, traversal
past it, a second non-temp operand, a re-bound or subshell-bound name, a
value carrying a space or a glob, and the ambient$TMPDIRall still deny. -
bun -e,bun -p,deno -eandbun execpayloads are extracted like
node -e(#397). An identical inline payload was denied undernodeand
allowed underbun;bun exechands its argument to a shell and was not
modeled as an inline payload at all. -
Dashed
git-<sub>executables are treated as git (#400).git-reset --hard,git-clean -fdxandgit-checkoutare the real dashed builtins and
bypassed thecore.gitrules that their spaced spellings hit. -
Duplicate snake_case and camelCase keys in hook input no longer fail open
(#410). A payload carrying bothtool_inputandtoolInputfailed
deserialization, and the failure defaulted to allow. Conflicting spellings
are now reconciled and evaluated; genuinely malformed input still takes the
documented default, and says so. -
dcg explainreports the resolved outcome, not the rule default (#417).
explainanddcg test -vvvskipped policy resolution, so a rule overridden
towarn,askorlogwas still reported asDENY-- the one command
whose job is to tell you what will happen disagreed with what happened.
Partially fixed
- A quoted heredoc body is no longer read as PowerShell shape (#412). An
ordinary hyphenated word at the start of a line in a commit message
(Read-only) looked like a verb-noun cmdlet and down-trusted aBash-labeled
command toUnknown, where the fail-closed union denied it. The shape test
now runs on the heredoc-masked view. The reported command remains denied: it
embeds the heredoc in"$(...)"and its body carries an unbalanced",
which defeats the trigger scanner behind the mask, so the body is never
delimited. #412 stays open with the root cause recorded.
Internal
cargo clippy --all-targets -- -D warningsandcargo fmt --checkare clean
again; both are release gates and both were failing on main.