docs: archive the finished backlogs (RD-30)
Two backlog trees are complete: `docs/project/backlog/` (75 files, every WP done) and `docs/project/refactor-backlog-setup/` (the arc before it). Move both under `docs/project/archive/` with `git mv`, so history stays intact through `git log --follow`. `SHOWCASE-ROADMAP.md` moves with them, because it points at the now-archived backlog README. Add `docs/project/archive/README.md`. It states that these trees are historical and names the two directories that are still live. Repoint every inbound reference named in RD-30's Files table: CLAUDE.md, the root README, both backend READMEs, `LetterHtml.cs`, `a11y.mdx`, the `document-feature` and `new-ssp` skills, and the readable-codebase PLAN, README, and RD-19 ticket. Fix two upward-relative links inside the moved WP files (WP-68, WP-69) that gained a directory level and would otherwise break. Repoint `.prettierignore`'s two agent-prompt exclusions to their new path, so prettier keeps leaving those files' exact wording alone. Mark RD-30 done and check off its acceptance criteria; flip its README row to done. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# RB-14 — scan the .NET dependency tree for known advisories
|
||||
|
||||
Status: **implemented** · 2026-08-27 · Source findings: `07-bio2-compliance.md` BIO-016 · `99-backlog.md` RB-14
|
||||
|
||||
## What was wrong
|
||||
|
||||
`npm audit --omit=dev` gates the shipped frontend bundle. Nothing equivalent existed for the
|
||||
backend, so **the entire .NET dependency tree — direct and transitive — was unscanned.** BIO-016
|
||||
lists it first under "Absent".
|
||||
|
||||
## The trap the ticket walked into
|
||||
|
||||
The backlog row says: `dotnet list package --vulnerable --include-transitive` **as a failing
|
||||
step**. Implemented literally, that step cannot fail. `dotnet list package --vulnerable` is a
|
||||
_reporting_ command: it prints the advisory table and exits 0 regardless.
|
||||
|
||||
Verified rather than assumed — a throwaway project with `System.Net.Http 4.3.0`:
|
||||
|
||||
```
|
||||
Project `vulntest` has the following vulnerable packages
|
||||
> System.Net.Http 4.3.0 4.3.0 High https://github.com/advisories/GHSA-7jgj-8wvc-jh57
|
||||
EXITCODE=0
|
||||
```
|
||||
|
||||
A **High** severity advisory, exit code **0**. A bare `- run: dotnet list package --vulnerable`
|
||||
would have added a line to `ci.yml` that reads like coverage in a compliance review and enforces
|
||||
nothing — which is worse than leaving the gap visible.
|
||||
|
||||
## What changed
|
||||
|
||||
| File | Change |
|
||||
| -------------------------- | -------------------------------------------------------------------------- |
|
||||
| `scripts/dotnet-audit.sh` | **new** — runs the scan, matches its output, exits 1 on a hit |
|
||||
| `.github/workflows/ci.yml` | new backend step calling the script (same `changes.outputs.backend` guard) |
|
||||
| `scripts/ci-local.sh` | new `backend dependency audit` step calling the same script |
|
||||
|
||||
**One script, two callers**, rather than the same four lines pasted into a workflow and a shell
|
||||
script that would then drift. The guard matches `has the following vulnerable packages` — the
|
||||
exact sentence `dotnet list` prints per project on a hit; the clean case prints
|
||||
`has no vulnerable packages given the current sources` instead.
|
||||
|
||||
## Verification
|
||||
|
||||
- Against the real solution: passes, both projects clean (exit 0).
|
||||
- Against the marker sentence `dotnet list` actually emits: the guard fires and exits 1.
|
||||
- The exit-0-on-High behaviour that motivates the whole script is reproduced above.
|
||||
|
||||
## Residual
|
||||
|
||||
`--include-transitive` means a vulnerable package pulled in by a dependency turns CI red with no
|
||||
direct upgrade available. The fix in that case is a direct `PackageReference` pinning a patched
|
||||
version; the script's failure message says so. There is deliberately **no severity threshold and
|
||||
no suppression list** — adding one before a real advisory forces the question would be guessing
|
||||
at a policy nobody has needed yet.
|
||||
|
||||
Secret scanning (gitleaks/trufflehog), BIO-016's other named absence, is **not** in this ticket
|
||||
and remains on the pre-production checklist.
|
||||
Reference in New Issue
Block a user