fix: KaTeX LaTeX leak (#194), image recognition (#192), ARM64 silent exit (#190), + 1000 Genomes skill docs (#191)#201
Open
KB (KB-syntheticsciences) wants to merge 7 commits into
Open
Conversation
#194) DOMPurify's mathMl profile disallows <semantics>/<annotation>, and its default KEEP_CONTENT strips the tags but keeps their text — so the raw TeX source inside KaTeX's MathML annotation survived as a bare text node and rendered visibly next to the typeset formula. Add ADD_TAGS/ ADD_ATTR to the sanitize config to allowlist the annotation wrapper tags, and export sanitize so it's directly testable. Adds a jsdom-based DOM test harness for frontend/ui (bunfig preload + jsdom.ts), which currently has no DOM test environment. Uses jsdom rather than the @happy-dom/global-registrator pattern used in frontend/workspace: happy-dom's NodeIterator doesn't implement the DOM spec's live-mutation adjustment, so once DOMPurify removes the first disallowed node mid-walk, iteration silently stops and everything after goes unsanitized — verified directly, and confirmed jsdom does not have this problem.
…lity (#192) unsupportedParts() gated image/pdf parts solely on the fine-grained capabilities.input.image/pdf flag, which is absent or wrong for models outside the local models.dev catalog. The synthetic OpenRouter model in particular hardcoded attachment:false + input.image:false for any whitelisted-but-uncataloged model, so vision-capable models silently had their images swapped for an ERROR text part that the model then paraphrased as "this model doesn't support image input". Fall back to the coarse attachment capability for image/pdf only when the finer modality flag is missing (audio/video untouched), and make the synthetic model's placeholder capabilities permissive for image/pdf so a genuinely-unsupported attachment surfaces a real provider error instead of a fabricated one.
…tly (#190) On some ARM64 hosts (e.g. 64KB page-size kernels) the prebuilt native binary is killed by a signal (SIGSEGV/SIGILL) rather than exiting with a status code. spawnSync then returns status: null, signal: "SIG...", and the launcher's tail (`code = status ?? 0`) silently exited 0 with no output — the reporter's "exits silently." Add a signal branch in run() that prints an actionable diagnostic (signal name, host platform/arch, remediation steps) and exits 1. The existing result.error branch and numeric-status exit path are unchanged.
Make the dnaerys/onekgpd-skill (1000 Genomes individual-genotype queries, MIT) discoverable via the existing `skill add` flow rather than bundling a third-party skill that depends on an external endpoint the maintainers don't control.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…tion tests (#202) Audit for #202 found no DOMPurify-based tests in frontend/workspace (the only DOMPurify test, frontend/ui markdown.test.ts, is already on jsdom). Add a guard comment on the happy-dom registrator so future sanitizer tests aren't written against it and silently pass with a broken sanitizer.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Batch of four independent issue fixes, each as its own commit.
Closes #194
Closes #192
Closes #190
Closes #191
Closes #202
#194 — KaTeX shows raw LaTeX beside rendered math
Root cause: KaTeX's default
htmlAndMathmloutput emits<math><semantics>…<annotation encoding="application/x-tex">RAW TEX</annotation></semantics></math>. The DOMPurify config infrontend/ui/src/components/markdown.tsxhad noADD_TAGS, so<semantics>/<annotation>were stripped; with DOMPurify's defaultKEEP_CONTENT: true, the raw TeX survived as a bare text node in<math>and rendered visibly.Fix:
ADD_TAGS: ["semantics","annotation","annotation-xml"]+ADD_ATTR: ["encoding"]. The annotation stays nested (non-rendered metadata).FORBID_TAGS/FORBID_CONTENTSunchanged — no XSS widening (verified:annotation-xml encoding="text/html"mXSS payloads are still stripped, with a committed test asserting it).Test harness note: the behavioral test uses jsdom, not happy-dom (see #202).
#192 — Uploaded images rejected as "this model doesn't support image input"
Root cause: the image gate in
backend/cli/src/provider/transform.tskeys onmodel.capabilities.input.image, which defaults tofalsein paths users hit — notably_syntheticOpenRouterModel(provider.ts) hardcodesimage:falsefor managed/OpenRouter models missing from the local catalog. Vision-capable models had their image swapped for a harness-injected "does not support image input" note, which the model then paraphrases.Fix: (a) the gate falls back to the coarser
attachmentcapability for image/pdf only (audio/video unchanged); (b)_syntheticOpenRouterModeldefaults to permissiveattachment:true+input.image/pdf:truefor synthesized unknown models — a real provider error beats a fabricated one.#190 — ARM64 hosts: launcher exits silently with no output
Root cause:
backend/cli/bin/opensciencerun()computedcode = typeof result.status === "number" ? result.status : 0, so a binary killed by a signal (status: null— e.g. SIGILL/SIGSEGV on 64KB-page ARM64 hosts) was treated as exit0and exited silently.Fix: a
result.signalbranch prints an actionable diagnostic (signal, platform/arch, the 64KB-page ARM64 hint, recovery/report links) and exits non-zero. The normal numeric-exit path is unchanged. (Native arm64 binaries are already built + published — this is only the silent-signal bug.)#191 — 1000 Genomes individual-genotype skill
Made the community skill discoverable via the existing
openscience skill addflow (docs entry inskills.mdx) rather than bundling a third-party skill that depends on an external endpoint (db.dnaerys.org) the maintainers don't control. Verified the install command works end-to-end (skill add gh:dnaerys/onekgpd-skill→ fetch → safety review pass → installed).#202 — happy-dom unsound as a DOMPurify test harness
Audit folded in: DOMPurify is used in exactly one place (
markdown.tsx), and the only test exercising it (frontend/ui/markdown.test.ts) is already on jsdom here. Nofrontend/workspacetest does DOMPurify / mid-walk DOM mutation, so nothing needed migrating. Added a guard comment onfrontend/workspace/happydom.tsso future sanitizer tests aren't written against happy-dom — itsNodeIteratorlacks the DOM spec's live-mutation adjustment, so it silently under-sanitizes and a broken sanitizer can false-pass under it.Verification (local)
frontend/uisuite: 18 pass / 0 fail (incl. jsdom sanitizer tests + mXSS guards)CI caveat
The
Test(bun test) check will be red for an unrelated external reason — the currentubuntu-latest/ubuntu-24.04runner image (≥20260714.240, azure kernel-1020) breaks Bun's test runner repo-wide (see closed PR #200). Everything here passes locally. Merging relies on admin override past that known-bad check.