rembg 2.0.75 requires a numpy incompatible with the pinned numpy==1.26.4
that the rest of the ML stack (onnxruntime etc.) depends on, making
pip-audit's resolution impossible. The rembg <2.0.75 advisory (medium) is
accepted as a residual: it only affects the on-demand background-removal AI
bundle (publishing currently paused) and can't be patched without a numpy
2.x migration across the whole Python sidecar.
jsdom@29.1.1 imports undici's internal lib/handler/wrap-handler.js, removed
in 8.5.0 -- so forcing undici>=8.5.0 broke ~27 jsdom unit files. Removing the
override lets pnpm resolve undici to the latest patched in-range versions
(6.27.0/7.28.0/8.5.0, all above the vulnerable ranges) while jsdom keeps
working. Unit suite restored to 188 files / 4908 tests.
The 2.0 API routes changed from /api/v1/tools/<toolId> to
/api/v1/tools/<section>/<toolId>. Updated all bench script call sites
to pass section-prefixed tool IDs (e.g. "image/resize" instead of
"resize"), matching the authoritative toolSection() mapping.
The Astro Dev Toolbar (enabled by default in dev mode) injects h1
elements ("No islands detected", "Audit", "Settings") and a
"Community" link inside its shadow DOM. Playwright CSS selectors
pierce shadow DOM, causing 6 test failures:
- 5 heading-hierarchy tests saw extra h1 elements from the toolbar
- footer "Community" column title resolved to 2 elements (footer h4
plus toolbar's Astro community chat link)
Root-cause fix: set PLAYWRIGHT=1 env var in the Playwright webServer
command; Astro config conditionally disables devToolbar when set.
Normal development retains the toolbar.
All /api/ routes are already covered by the global @fastify/rate-limit
(index.ts:283), but CodeQL doesn't model the global registration and flagged
every route without an explicit per-route limit. Added tuned config.rateLimit
to 45 routes: stricter on auth/credential routes (mfa/saml/oidc/api-keys,
15-30/min), moderate on writes (60/min), generous on reads/polls (300/min =
the global default). Real defense-in-depth on sensitive routes. 3 alerts on
non-route code (a preHandler hook, the rate-limiter's own DB lookup, a test
helper) are documented false-positives covered by the global limiter.
- file-preview.ts: validate the :id URL param against a safe charset and
restrict the original-name extension to alphanumerics before they feed
filesystem paths (closes 9 CodeQL js/path-injection; defense-in-depth on
top of the existing DB lookup).
- media-input.ts: require the SRT/VTT timecode structure to detect a subtitle
rather than a bare '-->' (closes CodeQL js/bad-tag-filter; also rejects
non-subtitle files that merely contain '-->').
- tests/e2e/helpers.ts: build the sharp script path via JSON.stringify
instead of single-quote-only replace (CodeQL js/incomplete-sanitization,
high: backslashes were not escaped). Proper fix, no suppression.
- landing CategoryCards: rename the file-modality marketing card to
"File Tools" (matches the Image/Video/Audio Tools siblings and is
unique vs the 23 "Files" tool pills, which broke the e2e locator).
Modality label stays "Files" everywhere it is the actual modality.
#280 left 10 section-prefixed custom-route files mis-indented and one
unsorted import block in the new landing section-index page. Fixed via
biome formatter (api) and manual import sort (landing). No config change
(biome.json is hook-protected); no suppression. pnpm lint + typecheck
now exit 0.
The fifth user-facing group is now Image, Video, Audio, PDF, Files
(internal modality id stays "file"; section.ts "files" was already
"Files"). Updates modality.ts label + comment, all 21 i18n locales
(categories.data "Data Files"->"Files", modalities.documentsAndFiles
"PDF & Data"->"PDF & Files", dead homePage.data), landing cards/hero
search/tools filter, docs headings, and e2e modality-tab assertions
(/^Data/ -> /^Files/, which had been failing).
#276's overhauled integration tests + QA sweep scripts hit the old
sectionless /api/v1/tools/<id> routes, which 404 after #280 made routes
section-prefixed. Ran scripts/rewrite-tool-paths.ts for literal URLs and
converted dynamic /api/v1/tools/${id} constructions to apiToolPath().
Negative-test paths (nonexistent/fake tools) intentionally left raw.
- Add || true after inference commands so set -e doesn't kill the
script before we reach the meaningful error message (exit code 3)
- Fix colorize settings: use "model" not "method" (matching colorize.py)
- Use larger font (size=40) and image (400x100) for OCR test so
PaddleOCR reliably recognizes the text
- Add || result="" fallback for stdout-capture smoke tests (OCR,
transcription) to prevent set -e on command substitution failure
The verify job runs between build and publish, gating HuggingFace
upload on per-bundle smoke tests. Each of the 14 bundle variants
(7 bundles x 2 arches) is verified independently: SHA256 checksum,
tarball extraction, Python import checks, and functional inference.
- validate models field in bundle.json
- pipe JSON via stdin instead of triple-quote embedding (injection safety)
- add PNG magic byte validation for background-removal output
- add dimension assertion for upscale-enhance output
- add fixture existence guards before smoke tests
- use --no-index for offline fixup wheel install
Verifies bundle tarballs in 4 phases: SHA256 integrity, extraction
and install into the base venv, Python import checks per bundle,
and a functional inference smoke test per bundle.
- fixture-integrity: probe media via media-engine probeMedia (resolves the
bundled static ffmpeg) instead of bare system ffprobe, which is ENOENT in CI;
gate on ffmpegAvailable() like the other media tests
- a11y: regenerate a11y-baseline.json to include the mobile device keys (the
baseline only had desktop keys, so the mobile a11y scan saw them as new)
- device-visual: tag @visual and exclude it from the PR mobile-smoke gate
(darwin-only screenshots cannot pass on linux; nightly + update-visual-baselines
still run it to seed linux goldens)
- Remove media-30s.mp4 and media-30s.wav from gen-synthetic-content.mjs
(these are committed real heroes, not synthetics to regenerate)
- Add skip-if-exists guards to all generators to prevent manifest hash
breakage from encoder-version differences
- Add --force flag to gen-synthetic-content.mjs for deliberate overwrite
- Fix generate-test-fixtures.mjs to skip encrypted.pdf if it exists
(qpdf AES encryption uses random IVs, non-deterministic)
- Fill provenance for 14 newly-scanned manifest entries after Phase 6b moves
- Verify all three generators produce expected output against new layout
Move all fixture files from flat/mixed dirs (content/, media/, documents/,
formats/, hostile/, root loose) into the modality-first hierarchy:
image/{valid,formats,edge,hostile}, video/{valid,formats,hostile},
audio/{valid,formats,hostile}, document/{valid,formats,edge,hostile},
data/valid/, security/. Update index.ts paths, fixtureDir aliases,
all literal refs in 17 e2e/qa/script files, manifest.json, and the
three generator scripts. 163 files moved, 0 dropped, 100 new tests
from expanded document scan.