Skip to content

chore(deps): durable qs override — close the per-regen audit re-float loop (queue #94)#103

Merged
Goosterhof merged 3 commits into
mainfrom
medic/queue-94-durable-qs-override
Jun 2, 2026
Merged

chore(deps): durable qs override — close the per-regen audit re-float loop (queue #94)#103
Goosterhof merged 3 commits into
mainfrom
medic/queue-94-durable-qs-override

Conversation

@Goosterhof
Copy link
Copy Markdown
Contributor

Summary

Closes enforcement queue #94. Makes the qs / typed-rest-client audit curation durable by replacing the per-regen lockfile patch with a regen-invariant overrides block in root package.json.

The problem — a lockfile pin is not a constraint

Stryker's transitive typed-rest-client@2.3.1 exact-pins vulnerable qs@6.15.1 (GHSA-q8mj-m7cp-5q26, moderate DoS — qs.stringify crashes on null/undefined entries in comma-format arrays). typed-rest-client@2.3.0 declares qs@^6.14.1 → resolves to patched 6.15.2.

The fix has been applied lockfile-only three times and lost twice, because a lockfile entry is not a constraint — any clean regen re-floats the tree:

When Action Outcome
2026-05-26 Supply Corps sweep flagged out-of-scope, not fixed
2026-05-29 PR #100 lockfile npm audit fix — held until next regen
2026-06-01 PR #102 (vue regen) clobbered #100's curation, re-fixed lockfile-only

main itself was one npm install away from a red audit. Verified directly: a clean regen on current main re-floats typed-rest-client to >=2.3.1 and reintroduces qs@6.15.1

qs  6.11.1 - 6.15.1   Severity: moderate
GHSA-q8mj-m7cp-5q26
  typed-rest-client  >=2.3.1  Depends on vulnerable versions of qs
2 moderate severity vulnerabilities

The fix — regen-invariant override

"overrides": {
    "typed-rest-client": {
        "qs": "^6.15.2"
    }
}

Scoped to the offending subtree, version-agnostic on the parent — forces qs to the patched line regardless of which typed-rest-client version floats. (oxfmt reorders overrides above engines; left as formatted.) The nested form took effect on first clean install — no top-level fallback needed.

After the override, the lockfile resolves typed-rest-client@2.3.1 (the version that exact-pins vulnerable qs) with qs@6.15.2 — proving the override holds even at the parent version that previously poisoned the tree.

Durability proof — TWO clean-from-scratch regens

Each is rm -rf node_modules package-lock.json && npm install && npm audit:

Regen typed-rest-client qs npm audit
pre-override (proof of re-float) 2.3.1 6.15.1 2 moderate (GHSA-q8mj-m7cp-5q26)
#1 with override 2.3.1 6.15.2 0 vulnerabilities
#2 with override 2.3.1 6.15.2 0 vulnerabilities

No manual npm audit fix between regens — which the lockfile-only approach structurally could not achieve.

qs grep (post-fix): single hoisted copy node_modules/qs @ 6.15.2, no nested vulnerable copy under typed-rest-client.

Gate matrix

Gate Result
npm audit 0 vulnerabilities (load-bearing)
npm run format:check PASS (oxfmt applied)
npm run lint PASS
npm run build PASS
npm run typecheck PASS
npm run test:coverage PASS — 520/520, runtime unaffected
npm run lint:pkg PRE-EXISTING baseline — publint "Suggestions" (sideEffects) ×11, exit 0; unrelated to this change (PR #101 fixes, Commander-pending)
Stryker mutation (optional) PASS — all packages above 90% threshold; mutation surface unmoved

All 11 @script-development/fs-* workspace packages still link to packages/* (link: true), no nested registry copies. The large package-lock.json diff is benign full-tree reordering from the clean regen.

Scope

Root package.json (overrides block) + package-lock.json only. No other manifest edits, no range widening, no version bumps beyond the qs override.

🤖 Generated with Claude Code

…durable GHSA-q8mj-m7cp-5q26 curation (queue #94)

Stryker's transitive typed-rest-client@2.3.1 exact-pins vulnerable
qs@6.15.1 (GHSA-q8mj-m7cp-5q26 DoS). A lockfile-only pin does not
survive clean regens — applied and lost twice before. This adds a
regen-invariant overrides block forcing qs>=6.15.2 within the
typed-rest-client subtree, so curation holds across any future
npm install from scratch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Goosterhof Goosterhof added the Agent Review Requested Requesting review of specialized AI review agents. label Jun 1, 2026
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Jun 1, 2026

Deploying fs-packages with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8829d12
Status: ✅  Deploy successful!
Preview URL: https://fb7b550c.fs-packages.pages.dev
Branch Preview URL: https://medic-queue-94-durable-qs-ov.fs-packages.pages.dev

View logs

jasperboerhof
jasperboerhof previously approved these changes Jun 1, 2026
Copy link
Copy Markdown
Contributor

@jasperboerhof jasperboerhof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — reviewed, no blockers.

…e-qs-override

# Conflicts:
#	package-lock.json
@Goosterhof
Copy link
Copy Markdown
Contributor Author

Rebased onto current main to clear a package-lock.json conflict introduced by the #102 vue-family bump (merged ahead of this in the same wave). Resolution: took main's lockfile and regenerated with npm install --package-lock-only — since #100's qs audit fix already landed on main (qs@6.15.2), this PR now reduces to the durable overrides block in package.json; the lockfile already complies (npm ci in-sync, 0 vulnerabilities). CI is green (check + Cloudflare Pages).

The manual rebase push dismissed the prior approval — re-approval needed before merge. The other five PRs in this wave (#94, #102, #77, #99, #101) are merged; fs-http@0.4.1 published from #77.

@Goosterhof
Copy link
Copy Markdown
Contributor Author

Branch freshened to current main (the rest of the wave — #94/#102/#77/#99/#101 — has since merged, which left this BEHIND). update-branch clean; CI re-confirmed green (check pass 2m29s, Cloudflare Pages pass). Diff is unchanged: the single durable overrides block in package.json. Still REVIEW_REQUIRED — re-approval is the only thing between this and merge. queue #94 strikes Enforced the moment it lands.

Copy link
Copy Markdown
Contributor Author

@Goosterhof Goosterhof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers, no concerns, one nit. This is the right shape of fix for the failure mode it documents.

Praise

The diagnosis is correct and the fix matches it. A lockfile entry is a resolution snapshot, not a constraint — any clean regen re-floats the tree, which is exactly why the lockfile-only approach lost the curation twice (PR #100, then PR #102's vue regen). A scoped overrides block in package.json:40-44 is the regen-invariant form: it constrains typed-rest-client's qs to ^6.15.2 regardless of which typed-rest-client version floats up. Verified against origin/main:package.json — no overrides block there, engines follows devDependencies directly, so this genuinely closes the per-regen re-float loop rather than re-applying a transient patch.

The durability evidence is the load-bearing part, not the five-line diff. Two rm -rf node_modules package-lock.json && npm install && npm audit cycles landing typed-rest-client@2.3.1 with qs@6.15.2 and 0 vulnerabilities is the right proof — it demonstrates the override holds at the exact parent version (2.3.1) that previously exact-pinned the vulnerable qs@6.15.1, which is the only version that matters here. The lockfile-only approach structurally could not produce that proof.

Nit

The scoped-nested override form ("typed-rest-client": { "qs": "^6.15.2" }) is correct and minimal, but it's silent about intent — six months from now a typed-rest-client bump that re-vendors qs cleanly leaves a dangling override with no breadcrumb. The PR body carries the GHSA reference and the rationale; the manifest does not. Not blocking — npm overrides doesn't take comments and a parallel // _comment key would trip oxfmt/lint. Worth a one-line note in enforcement/queue.md #94's closeout so the override has a documented expiry condition (drop it once typed-rest-client no longer pins a vulnerable qs range).

Scope is honest: root package.json override + package-lock.json regen only, no range widening, no unrelated bumps. The lint:pkg publint baseline is correctly declared pre-existing and out of scope (PR #101). COMMENT — merge-worthy as-is.

@jasperboerhof
Copy link
Copy Markdown
Contributor

PR Reviewer · claimed

@jasperboerhof
Copy link
Copy Markdown
Contributor

PR Reviewer · 8/10 · PASS

Findings

  • MINOR · package.json:40 — Row 6 (enforcement ladder): the PR's own thesis is that the qs/typed-rest-client pin must survive clean regens because the lockfile-only form (L4-equivalent) was re-floated and lost twice. The overrides block is the right durable fix — it's a resolution-time (npm-enforced, ~L3) constraint, a genuine escalation over the lockfile pin, and two clean-from-scratch regens in the PR body confirm it holds. The residual gap: no CI-time npm audit gate fails the build if this override is later deleted or a different advisory re-reds the tree, so durability still rests on the override staying in the manifest + a human noticing. Adding npm audit (or --audit-level=moderate) to CI would close the ladder; arguably out of scope for a single-advisory curation PR. Not a blocker — the override durably fixes GHSA-q8mj-m7cp-5q26 as scoped.

Action

merge-ready

Copy link
Copy Markdown
Contributor

@jasperboerhof jasperboerhof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-approved by /review-open-prs — review verdict is PASS. See the verdict comment for the per-reviewer breakdown.

@Goosterhof Goosterhof merged commit f6ced8f into main Jun 2, 2026
2 checks passed
@Goosterhof Goosterhof deleted the medic/queue-94-durable-qs-override branch June 2, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Agent Review Requested Requesting review of specialized AI review agents.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants