RDK0004 — Undocumented transitive pin
Severity: warning · Command: redecker check
A package is given a version that no project references directly, and nothing records why.
The situation
Transitive dependencies are an implementation detail of the packages you actually chose. They normally have no business appearing in Directory.Packages.props at all — you did not pick them, and next year you may not have them.
They appear anyway, for one recurring reason: a package you do reference drags in something with an advisory against it, and the parent has not raised its own floor yet. So you float it yourself:
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />That is a correct fix. The problem is what it looks like six months later.
Why it is worth a rule
The entry is indistinguishable from an ordinary dependency. Nothing in the file says it exists to dodge an advisory, so nobody can tell whether deleting it tidies up or quietly reintroduces a CVE. The safe move is always to leave it, so it stays — and the day the parent raises its own floor and the entry becomes redundant passes without anyone noticing.
The cost is not the stale line. It is that the entry keeps constraining resolution for everything else, permanently, for a reason nobody can name.
What it checks
redecker check compares what is declared against what is referenced: every PackageVersion that no PackageReference anywhere names.
$ redecker check .
warning RDK0004: System.Text.RegularExpressions is given a version but no project references itSilence is the goal, not removal
A pin carrying a hint produces no finding. The rule asks for a reason, and both available answers are good ones:
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1"
Label="security-floor: #:package System.Text.RegularExpressions@4.3.1;
until: transitive-floor(Serilog) >= 4.3.1;
note: floated above the advisory until Serilog raises its own floor" />Now the entry explains itself and names the condition under which it goes away — which is the whole reason the hint system exists. This rule is what makes writing one worthwhile.
When it does not run
If the scan finds no PackageReference at all, the rule is skipped and says so. Pointing check at a lone Directory.Packages.props would otherwise report every entry in it, since nothing in that file references anything:
$ redecker check Directory.Packages.props
2 declaration(s) across 1 file(s); 0 direct reference(s).
note: no PackageReference was found, so RDK0004 was skipped. Point check at a directory
containing the projects, not only at Directory.Packages.props.Point it at the repository root instead.
Why a warning
Because both readings are legitimate. A floated floor is correct engineering, and a stale entry is untidy rather than broken. Neither should fail a build on its own — but neither should be invisible.