Fix CI unit test failures and optimize PerformanceOptimizer#73
Fix CI unit test failures and optimize PerformanceOptimizer#73daggerstuff wants to merge 29 commits intostagingfrom
Conversation
- Added HTML escaping to simpleMarkdownToHtml to prevent raw HTML injection. - Added URL protocol validation to prevent javascript: link exploitation. - Added unit tests to verify the security fix. - Added security journal entry in .jules/sentinel.md. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
…I failure - Added HTML escaping to simpleMarkdownToHtml to prevent raw HTML injection. - Added URL protocol validation to prevent javascript: link exploitation. - Added unit tests to verify the security fix. - Fixed CI failure by removing invalid 'suites' definition in CodeQL custom queries qlpack.yml. - Added security journal entry in .jules/sentinel.md. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
- Implemented HTML escaping and URL validation in simpleMarkdownToHtml to prevent XSS. - Fixed CodeQL CI by properly defining the hipaa-compliance suite in a .qls file. - Aligned PNPM_VERSION across all GitHub Action workflows to 10.30.1. - Added comprehensive XSS unit tests and security journal entry. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
… CodeQL queries - Implemented HTML escaping and URL validation in simpleMarkdownToHtml to prevent XSS. - Restructured custom CodeQL queries into separate files to resolve CI conflicts. - Fixed CodeQL configuration to use a properly defined hipaa-compliance.qls suite. - Aligned PNPM_VERSION across GitHub Action workflows to 10.30.1. - Added XSS unit tests and updated Sentinel journal. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
- Implemented HTML escaping and URL protocol whitelisting in simpleMarkdownToHtml. - Restructured custom CodeQL queries into focused files to resolve CI conflicts. - Corrected CodeQL config and qlpack.yml to use the restored hipaa-compliance suite. - Unified PNPM version across all CI workflows. - Added comprehensive unit tests and Sentinel journal entry. - Applied formatting to modified files. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
…nment - Implemented HTML escaping and URL protocol whitelisting in simpleMarkdownToHtml. - Restructured custom CodeQL queries into focused files to resolve CI conflicts. - Corrected CodeQL config and qlpack.yml to use the restored hipaa-compliance suite. - Unified PNPM version across all CI workflows. - Moved XSS unit tests to src/lib/ to match project patterns and ensured environment compatibility. - Added missing vitest.setup.ts to resolve global test configuration errors. - Applied formatting to all modified files. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
- Implemented HTML escaping and URL protocol whitelisting in simpleMarkdownToHtml. - Restructured custom CodeQL queries into focused files to resolve CI conflicts. - Corrected CodeQL config and qlpack.yml to use the restored hipaa-compliance suite. - Unified PNPM version across all CI workflows. - Added comprehensive unit tests and Sentinel journal entry. - Applied formatting to modified files. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
…nment (Final) - Implemented HTML escaping and URL protocol whitelisting in simpleMarkdownToHtml. - Restructured custom CodeQL queries into focused files to resolve CI conflicts. - Corrected CodeQL config and qlpack.yml to use the restored hipaa-compliance suite. - Unified PNPM version across all CI workflows. - Moved XSS unit tests to src/lib/ to match project patterns and ensured environment compatibility. - Created vitest.setup.ts with required polyfills (TextEncoder/TextDecoder) to resolve global test configuration errors. - Applied formatting to all modified files. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
…nment (Final Fix) - Implemented HTML escaping and URL protocol whitelisting in simpleMarkdownToHtml. - Restructured custom CodeQL queries into focused files to resolve CI conflicts. - Corrected CodeQL config and qlpack.yml to use the restored hipaa-compliance suite. - Unified PNPM version across all CI workflows. - Moved XSS unit tests to src/lib/ and created vitest.setup.ts with polyfills. - Ensured all modified files pass oxfmt formatting checks. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
…nment (Verified) - Implemented HTML escaping and URL protocol whitelisting in simpleMarkdownToHtml to prevent XSS. - Restructured custom CodeQL queries into focused files to resolve CI 'conflicting select clause' errors. - Corrected CodeQL config and qlpack.yml to use the restored hipaa-compliance suite. - Unified PNPM version across all CI workflows to 10.30.1. - Moved XSS unit tests to src/lib/ to match project patterns and ensured environment compatibility. - Created vitest.setup.ts with required polyfills (TextEncoder/TextDecoder) to resolve global test configuration errors. - Applied oxfmt formatting to all modified files. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
…dated) - Implemented HTML escaping and URL protocol whitelisting in simpleMarkdownToHtml to prevent XSS. - Restructured custom CodeQL queries into focused files to resolve CI conflicts. - Corrected CodeQL config and qlpack.yml to use the restored hipaa-compliance suite. - Unified PNPM version across all CI workflows to 10.30.1. - Added XSS unit tests and ensured environment compatibility with vitest.setup.ts. - Applied formatting to all modified files. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
…l Verified) - Implemented HTML escaping and URL protocol whitelisting in simpleMarkdownToHtml to prevent XSS. - Restructured custom CodeQL queries into focused files to resolve CI conflicts. - Corrected CodeQL config and qlpack.yml to use the restored hipaa-compliance suite. - Unified PNPM version across all CI workflows to 10.30.1. - Moved XSS unit tests to src/lib/ and created vitest.setup.ts with polyfills. - Applied formatting to all modified files to ensure 100% oxfmt compliance. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
…l Verified v7) - Implemented HTML escaping and URL protocol whitelisting in simpleMarkdownToHtml to prevent XSS. - Restructured custom CodeQL queries into focused files to resolve CI 'conflicting select clause' errors. - Corrected CodeQL config and qlpack.yml to use the restored hipaa-compliance suite. - Unified PNPM version across all CI workflows to 10.30.1. - Moved XSS unit tests to src/lib/ and created vitest.setup.ts with polyfills. - Ensured all modified files pass oxfmt formatting checks and oxlint. - Removed redundant/conflicting legacy query files. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
…dated Final) - Implemented HTML escaping and URL protocol whitelisting in simpleMarkdownToHtml to prevent XSS. - Restructured custom CodeQL queries into focused files to resolve CI 'conflicting select clause' errors. - Corrected CodeQL config and qlpack.yml to use the restored hipaa-compliance suite. - Unified PNPM version across all CI workflows to 10.30.1. - Moved XSS unit tests to src/lib/ and created vitest.setup.ts with polyfills. - Applied oxfmt formatting to all modified files. - Removed redundant/conflicting legacy query files. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
… test environment - Implemented HTML escaping and URL protocol whitelisting in simpleMarkdownToHtml to prevent XSS. - Restructured custom CodeQL queries into focused files to resolve CI 'conflicting select clause' errors. - Corrected CodeQL config and qlpack.yml to use the restored hipaa-compliance suite. - Unified PNPM version across all CI workflows to 10.30.1. - Added XSS unit tests in src/lib/ and created vitest.setup.ts with necessary polyfills. - Applied formatting to all modified files. - Removed redundant query files. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
…nerability-11500473593375101206 🛡️ Sentinel: [HIGH] Fix XSS vulnerability in Markdown rendering
- Corrected relative paths in config/vitest.config.ts for aliases and setup files. - Fixed error handling logic in health-monitor.ts (typos in catch blocks). - Optimized PerformanceOptimizer cache eviction from O(n) to O(1). - Updated PatientResponseService.test.ts to correctly await async methods and match output formats. - Fixed ambiguous selectors and ensured proper cleanup in WebSocketProgressBar.test.tsx. - Added missing react-dom/test-utils mock for React 19 compatibility. - Updated package.json scripts and .python-version for environment consistency. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Reviewer's GuideRefactors the PerformanceOptimizer cache to track hits/accesses and use O(1) eviction for LRU/FIFO, fixes HealthMonitor error handling, updates Vitest config paths and test runner scripts for CI, stabilizes React component tests and PatientResponseService async tests, and adds global cleanup in test setup plus a React 19 test-utils mock. Class diagram for updated PerformanceOptimizer cache behaviorclassDiagram
class PerformanceOptimizer {
- OptimizationConfig config
- PerformanceMetrics metrics
- Map~string, unknown[]~ connectionPool
- Map~string, CacheEntry~ cache
- Map~string, number~ activeCounts
- number totalCacheAccesses
- number cacheHitsCount
+ PerformanceOptimizer(config PartialOptimizationConfig)
+ set(key string, value unknown) void
+ get(key string) unknown
+ evictExpired() void
+ evictByStrategy() void
- findLFUKey() string
+ updateMetrics() void
+ reset() void
}
class CacheEntry {
unknown value
number timestamp
number accessCount
}
class OptimizationConfig {
CacheConfig cache
ConnectionPoolConfig connectionPool
}
class CacheConfig {
number maxSize
string strategy
number ttl
}
class PerformanceMetrics {
number cacheHitRate
number activeConnections
}
PerformanceOptimizer o--> CacheEntry : uses
PerformanceOptimizer o--> OptimizationConfig : has
PerformanceOptimizer o--> PerformanceMetrics : updates
OptimizationConfig o--> CacheConfig : has
OptimizationConfig o--> ConnectionPoolConfig : has
Class diagram for updated HealthMonitor error handlingclassDiagram
class HealthMonitor {
+ checkDependencies() Promise~HealthCheckResult[]~
+ checkSystem() Promise~HealthCheckResult~
+ checkMemory() Promise~HealthCheckResult~
+ checkDisk() Promise~HealthCheckResult~
}
class HealthCheckResult {
string name
string status
string message
number responseTime
}
HealthMonitor o--> HealthCheckResult : returns
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
📝 WalkthroughWalkthroughUpdates runtime/tooling and test configuration; adds a React 19 test-utils mock and global test cleanup; converts several tests to async and tightens assertions; refactors health-monitor catch messages; changes PerformanceOptimizer cache internals and metrics; and converts CodeQL EHR queries to path-based analysis. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In
HealthMonitor, thecatchblocks now referenceerrorinstead of_error, which will result inReferenceError; theinstanceofchecks andString(...)calls should consistently use the caught variable name.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `HealthMonitor`, the `catch` blocks now reference `error` instead of `_error`, which will result in `ReferenceError`; the `instanceof` checks and `String(...)` calls should consistently use the caught variable name.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| globals: true, | ||
| environment: 'jsdom', | ||
| setupFiles: ['./src/test/setup.ts', './vitest.setup.ts'], | ||
| setupFiles: ['../src/test/setup.ts', '../vitest.setup.ts'], |
There was a problem hiding this comment.
Bug: The setupFiles paths are now relative (../), but Vitest resolves them from the project root. This will prevent the test setup files from being found and loaded.
Severity: CRITICAL
Suggested Fix
Revert the setupFiles paths to their original values: ['./src/test/setup.ts', './vitest.setup.ts']. These paths correctly resolve from the project root where the test command is executed. Alternatively, use absolute paths via path.resolve() to avoid ambiguity.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: config/vitest.config.ts#L42
Potential issue: The `setupFiles` configuration in `config/vitest.config.ts` has been
changed to `['../src/test/setup.ts', '../vitest.setup.ts']`. Vitest resolves these paths
from the project root, not from the directory containing the configuration file. As a
result, the paths incorrectly point to a directory above the project root, and the setup
files will not be loaded. These files contain critical test infrastructure, including
DOM mocks (`@testing-library/jest-dom`, `window.matchMedia`) and global polyfills
(`TextEncoder`). Their absence will cause widespread test failures in the CI
environment.
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
1 issue found across 9 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="package.json">
<violation number="1" location="package.json:32">
P1: `oxfmt` has no `format` subcommand — the stale subcommand from `oxc` will be treated as a nonexistent path argument, breaking the format scripts. Use `oxfmt --write .` directly.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| "format": "oxfmt format --write . && prettier --write \"**/*.{astro,mdx}\"", | ||
| "format:check": "oxfmt format --check . && prettier --check \"**/*.{astro,mdx}\"", |
There was a problem hiding this comment.
P1: oxfmt has no format subcommand — the stale subcommand from oxc will be treated as a nonexistent path argument, breaking the format scripts. Use oxfmt --write . directly.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At package.json, line 32:
<comment>`oxfmt` has no `format` subcommand — the stale subcommand from `oxc` will be treated as a nonexistent path argument, breaking the format scripts. Use `oxfmt --write .` directly.</comment>
<file context>
@@ -29,8 +29,8 @@
"analyze:bundle": "npx astro-bundle-analyzer dist",
- "format": "oxc format --write . && prettier --write \"**/*.{astro,mdx}\"",
- "format:check": "oxc format --check . && prettier --check \"**/*.{astro,mdx}\"",
+ "format": "oxfmt format --write . && prettier --write \"**/*.{astro,mdx}\"",
+ "format:check": "oxfmt format --check . && prettier --check \"**/*.{astro,mdx}\"",
"lint": "oxlint .",
</file context>
| "format": "oxfmt format --write . && prettier --write \"**/*.{astro,mdx}\"", | |
| "format:check": "oxfmt format --check . && prettier --check \"**/*.{astro,mdx}\"", | |
| "format": "oxfmt --write . && prettier --write \"**/*.{astro,mdx}\"", | |
| "format:check": "oxfmt --check . && prettier --check \"**/*.{astro,mdx}\"", |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/lib/services/health-monitor.ts (1)
63-79:⚠️ Potential issue | 🟡 MinorUse per-check timing in the failure path too.
This catch still reports
performance.now() - startTime, which includes time spent in earlier checks. A late failure will overstate that check’sresponseTimeand skew the health metrics. LiftcheckStartout of thetryand use it in both paths.Suggested fix
const checkPromises = Array.from(this.checks.entries()).map( async ([name, checkFn]) => { + const checkStart = performance.now() try { - const checkStart = performance.now() const result = await Promise.race([ checkFn(), this.timeoutPromise(5000, name), // 5 second timeout ]) result.responseTime = performance.now() - checkStart @@ } catch (error) { return { name, status: 'unhealthy' as const, message: error instanceof Error ? String(error) : 'Unknown error', - responseTime: performance.now() - startTime, + responseTime: performance.now() - checkStart, } } }, )As per coding guidelines, "Build applications with observability in mind, including structured logging, metrics exposition, and distributed tracing instrumentation."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/services/health-monitor.ts` around lines 63 - 79, The catch block uses performance.now() - startTime which measures from the overall health run, not the individual check; move the declaration const checkStart = performance.now() so it is created before the try (i.e. immediately inside the map callback before invoking checkFn/this.timeoutPromise) and then in both the success path (where you currently set result.responseTime) and the catch path set responseTime = performance.now() - checkStart; update references to startTime in this callback to use checkStart for per-check timing (symbols: this.checks, checkFn, checkStart, timeoutPromise, responseTime).
🧹 Nitpick comments (2)
src/components/pipeline/__tests__/WebSocketProgressBar.test.tsx (1)
243-243: AvoidgetAllByText(...)[0]for these assertions.Picking the first match just bakes current DOM order into the tests, so another
"connecting","sent", or"received"label will make them flaky again. Scope the assertion withwithin(...), or target a role/test id for the specific element under test instead.As per coding guidelines, "Test component behavior, not implementation details" and "Use
@testing-library/reactfor component testing with screen queries and accessibility queries."Also applies to: 732-733
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/pipeline/__tests__/WebSocketProgressBar.test.tsx` at line 243, The test in WebSocketProgressBar.test.tsx uses expect(screen.getAllByText(/connecting/i)[0]) which relies on DOM order and is flaky; update the assertion to scope the query to the specific element (use within(...) on the component/container or target an accessible role/testid) instead of getAllByText(...)[0]; replace similar occurrences around lines 732-733 as well and use functions like within(renderedContainer).getByText(...) or screen.getByRole/getByTestId for the specific progress-label element so the test asserts the intended element reliably.src/lib/services/performance-optimizer.ts (1)
63-64: Redundant counter initialization.The counters are initialized at declaration (lines 63-64) and again in the constructor (lines 85-86). The field initializers are sufficient; the constructor assignments can be removed.
♻️ Suggested cleanup
constructor(config: Partial<OptimizationConfig> = {}) { - this.totalCacheAccesses = 0 - this.cacheHitsCount = 0 this.config = {Also applies to: 85-86
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/services/performance-optimizer.ts` around lines 63 - 64, Remove the redundant re-initialization of the counters in the constructor: the fields totalCacheAccesses and cacheHitsCount are already initialized at declaration, so delete their assignments inside the constructor (look for the constructor method in performance-optimizer.ts that sets totalCacheAccesses = 0 and cacheHitsCount = 0) and leave the field initializers as the single source of initialization.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@__mocks__/react-dom/test-utils.js`:
- Around line 2-8: The mock currently implements a no-op act which bypasses
React's real flushing/batching; replace the shim by importing and re-exporting
React's real act from the 'react' package (use the exported symbol act) and
ensure the default export still exposes act so any imports from this module
continue to work; this preserves React 19 async batching/flush semantics used by
await act(...) in tests.
In @.python-version:
- Line 1: The repo Python pin in .python-version (3.12.3) is inconsistent with
the package.json script that calls "uv run --python 3.11" (used by the "bias:py"
npm script); change the package.json script to use the same interpreter version
as .python-version (update "--python 3.11" to "--python 3.12" or to "3.12.3" to
exactly match) so pnpm run bias:py and CI will use the pinned Python; ensure you
update the exact string in the "bias:py" script entry in package.json and run a
quick local test to confirm it launches with Python 3.12.3.
In `@config/vitest.config.ts`:
- Line 42: The setupFiles entries currently use ../ prefixes and will resolve
outside the repo; update the setupFiles array so entries are root-relative
(e.g., replace '../src/test/setup.ts' and '../vitest.setup.ts' with
'src/test/setup.ts' and 'vitest.setup.ts' respectively) so Vitest resolves them
from the project root; locate the setupFiles setting in the vitest config and
change those paths accordingly.
In `@src/test/setup.ts`:
- Around line 97-99: afterEach currently only calls cleanup() which unmounts DOM
nodes but leaves the singleton test spies intact; update the global teardown in
afterEach to also reset the singleton localStorageMock (e.g. call
localStorageMock.clear() or the appropriate reset method) and clear/restore the
console spies created in beforeEach (use mockClear()/mockRestore() or
jest.clearAllMocks() as appropriate) so that localStorageMock and console spy
call histories do not leak between tests.
---
Outside diff comments:
In `@src/lib/services/health-monitor.ts`:
- Around line 63-79: The catch block uses performance.now() - startTime which
measures from the overall health run, not the individual check; move the
declaration const checkStart = performance.now() so it is created before the try
(i.e. immediately inside the map callback before invoking
checkFn/this.timeoutPromise) and then in both the success path (where you
currently set result.responseTime) and the catch path set responseTime =
performance.now() - checkStart; update references to startTime in this callback
to use checkStart for per-check timing (symbols: this.checks, checkFn,
checkStart, timeoutPromise, responseTime).
---
Nitpick comments:
In `@src/components/pipeline/__tests__/WebSocketProgressBar.test.tsx`:
- Line 243: The test in WebSocketProgressBar.test.tsx uses
expect(screen.getAllByText(/connecting/i)[0]) which relies on DOM order and is
flaky; update the assertion to scope the query to the specific element (use
within(...) on the component/container or target an accessible role/testid)
instead of getAllByText(...)[0]; replace similar occurrences around lines
732-733 as well and use functions like within(renderedContainer).getByText(...)
or screen.getByRole/getByTestId for the specific progress-label element so the
test asserts the intended element reliably.
In `@src/lib/services/performance-optimizer.ts`:
- Around line 63-64: Remove the redundant re-initialization of the counters in
the constructor: the fields totalCacheAccesses and cacheHitsCount are already
initialized at declaration, so delete their assignments inside the constructor
(look for the constructor method in performance-optimizer.ts that sets
totalCacheAccesses = 0 and cacheHitsCount = 0) and leave the field initializers
as the single source of initialization.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ba07a227-aec3-463b-a50e-5f840ed4243e
📒 Files selected for processing (9)
.python-version__mocks__/react-dom/test-utils.jsconfig/vitest.config.tspackage.jsonsrc/components/pipeline/__tests__/WebSocketProgressBar.test.tsxsrc/lib/ai/services/PatientResponseService.test.tssrc/lib/services/health-monitor.tssrc/lib/services/performance-optimizer.tssrc/test/setup.ts
| export const act = (callback) => { | ||
| return callback(); | ||
| }; | ||
|
|
||
| export default { | ||
| act, | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In React 19, should compatibility shims for react-dom/test-utilsre-exportactfromreact, and does act need to preserve async callback semantics and queued update flushing?
💡 Result:
Yes.
-
React 19 moved
actintoreactand deprecated/removed thereact-dom/test-utilsentry point. So a compatibility shim forreact-dom/test-utilsshould re-exportactfromreact(and ideally nothing else), becausereact-dom/test-utils’s other APIs are gone andReactDOMTestUtils.actis deprecated in favor ofReact.act. [1], [2] -
actshould preserve the async semantics and flushing behavior. React’s documentedactusage isawait act(async () => { ... }), where updates triggered inside the callback are queued in an internal “act queue” and then flushed together, including work that crosses async boundaries; React also recommends the async/awaitform because the sync form is not reliable and is planned for deprecation/removal. [3]
Sources:
[1] React warning page: react-dom/test-utils deprecation and “import { act } from 'react'” guidance. (react.dev)
[2] React changelog excerpt noting removal/move of react-dom/test-utils and act moved to react. (collected.press)
[3] React act API reference describing async actFn, internal act queue, and flushing across async boundaries; sync version slated for deprecation/removal. (react.dev)
Citations:
- 1: https://react.dev/warnings/react-dom-test-utils?utm_source=openai
- 2: https://collected.press/github/facebook/react/CHANGELOG.md?utm_source=openai
- 3: https://react.dev/reference/react/act
Re-export React's real act from react instead of providing a no-op shim.
In React 19, react-dom/test-utils is deprecated and act moved to the react package. This mock drops React's critical flush and batching behavior—await act(async () => ...) relies on internal queuing and flushing of state updates across async boundaries. The current implementation simply invokes the callback, which can mask state-update bugs and make async tests flaky.
Suggested fix
-export const act = (callback) => {
- return callback();
-};
+export { act } from 'react';
export default {
act,
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const act = (callback) => { | |
| return callback(); | |
| }; | |
| export default { | |
| act, | |
| }; | |
| export { act } from 'react'; | |
| export default { | |
| act, | |
| }; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@__mocks__/react-dom/test-utils.js` around lines 2 - 8, The mock currently
implements a no-op act which bypasses React's real flushing/batching; replace
the shim by importing and re-exporting React's real act from the 'react' package
(use the exported symbol act) and ensure the default export still exposes act so
any imports from this module continue to work; this preserves React 19 async
batching/flush semantics used by await act(...) in tests.
| @@ -1 +1 @@ | |||
| 3.11.13 | |||
| 3.12.3 | |||
There was a problem hiding this comment.
Align the repo Python pin with bias:py.
.python-version now selects 3.12.3, but package.json Line 8 still forces uv run --python 3.11. On a fresh dev/CI machine that only has the pinned interpreter installed, pnpm bias:py will still fail, so the environment is not actually consistent yet.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.python-version at line 1, The repo Python pin in .python-version (3.12.3)
is inconsistent with the package.json script that calls "uv run --python 3.11"
(used by the "bias:py" npm script); change the package.json script to use the
same interpreter version as .python-version (update "--python 3.11" to "--python
3.12" or to "3.12.3" to exactly match) so pnpm run bias:py and CI will use the
pinned Python; ensure you update the exact string in the "bias:py" script entry
in package.json and run a quick local test to confirm it launches with Python
3.12.3.
| globals: true, | ||
| environment: 'jsdom', | ||
| setupFiles: ['./src/test/setup.ts', './vitest.setup.ts'], | ||
| setupFiles: ['../src/test/setup.ts', '../vitest.setup.ts'], |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In Vitest 4, are test.setupFilespaths resolved from the project root or from the directory containingvitest.config.ts?
💡 Result:
In Vitest 4, test.setupFiles paths are resolved relative to Vitest’s root (the project root)—not relative to the directory that contains vitest.config.ts. [1][2]
🏁 Script executed:
# Find vitest.config.ts and setup files
fd -t f 'vitest\.(config|setup)' -o 'setup\.ts'
# List project structure to understand directory layout
ls -la config/ 2>/dev/null | head -20
ls -la src/test/ 2>/dev/null | head -20
ls -la . | grep -E '^-.*vitest|^-.*setup|^d' | head -20Repository: daggerstuff/pixelated
Length of output: 2243
🏁 Script executed:
# Read the vitest.config.ts file
cat -n config/vitest.config.ts
# Check if vitest.setup.ts exists in the project root
ls -la vitest.setup.ts 2>&1
fd -t f 'vitest\.setup\.ts'Repository: daggerstuff/pixelated
Length of output: 4577
setupFiles paths must be root-relative; current ../ prefixes will escape the repository.
Vitest 4 resolves test.setupFiles from the project root, not from the config file's directory. The paths ../src/test/setup.ts and ../vitest.setup.ts will resolve to project_root/../src/test/setup.ts and project_root/../vitest.setup.ts, causing setup hooks to fail to load. This breaks test initialization in CI. The include globs (lines 48–51) are already root-relative, confirming the correct pattern.
Suggested fix
- setupFiles: ['../src/test/setup.ts', '../vitest.setup.ts'],
+ setupFiles: ['./src/test/setup.ts', './vitest.setup.ts'],🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@config/vitest.config.ts` at line 42, The setupFiles entries currently use ../
prefixes and will resolve outside the repo; update the setupFiles array so
entries are root-relative (e.g., replace '../src/test/setup.ts' and
'../vitest.setup.ts' with 'src/test/setup.ts' and 'vitest.setup.ts'
respectively) so Vitest resolves them from the project root; locate the
setupFiles setting in the vitest config and change those paths accordingly.
| afterEach(() => { | ||
| cleanup() | ||
| }) |
There was a problem hiding this comment.
Reset global mocks here too.
cleanup() only unmounts DOM nodes. The singleton localStorageMock spies in this file and the console spies installed in beforeEach() keep their call history unless each test remembers to clear them manually, so state can still leak between suites. This global teardown is the right place to restore/clear them centrally.
Suggested fix
afterEach(() => {
cleanup()
+ vi.restoreAllMocks()
+ vi.clearAllMocks()
})🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/test/setup.ts` around lines 97 - 99, afterEach currently only calls
cleanup() which unmounts DOM nodes but leaves the singleton test spies intact;
update the global teardown in afterEach to also reset the singleton
localStorageMock (e.g. call localStorageMock.clear() or the appropriate reset
method) and clear/restore the console spies created in beforeEach (use
mockClear()/mockRestore() or jest.clearAllMocks() as appropriate) so that
localStorageMock and console spy call histories do not leak between tests.
- Corrected relative paths in config/vitest.config.ts for aliases and setup files. - Fixed error handling logic in health-monitor.ts (typos in catch blocks). - Optimized PerformanceOptimizer cache eviction from O(n) to O(1). - Updated PatientResponseService.test.ts to correctly await async methods and match output formats. - Fixed ambiguous selectors and ensured proper cleanup in WebSocketProgressBar.test.tsx. - Added missing react-dom/test-utils mock for React 19 compatibility. - Modernized CodeQL custom queries in .github/codeql/custom-queries/ to use TaintTracking::Global and flowsTo API. - Removed deprecated setup-python-dependencies from CodeQL workflow. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
.github/codeql/custom-queries/ehr/unencrypted-ehr-data.ql (1)
42-51: Pre-existing gap: no flow check betweendataand the transmissioncall.The query checks that
isDataTransmissionCall(call)andisEHRData(data)hold independently, but there's no constraint ensuringdataactually flows into arguments ofcall. This could produce false positives where an unrelated EHR variable exists in the same file as a transmission call.Consider adding a flow check, for example:
from CallExpr call, DataFlow::Node data where isDataTransmissionCall(call) and isEHRData(data) and + data.flowsTo(DataFlow::exprNode(call.getAnArgument())) and not exists(CallExpr encryptCall | encryptCall.getCalleeName().matches("%encrypt%") and data.flowsTo(DataFlow::exprNode(encryptCall.getAnArgument())) )This is a pre-existing issue unrelated to the current change—flagging for awareness.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/codeql/custom-queries/ehr/unencrypted-ehr-data.ql around lines 42 - 51, The query currently treats isDataTransmissionCall(call) and isEHRData(data) independently, causing false positives because it doesn't ensure the EHR data actually flows into the transmission call; modify the where-clause to require a data flow from data into an argument of the transmission call (e.g., add a condition using data.flowsTo(DataFlow::exprNode(call.getAnArgument())) or equivalent to assert data flows to one of call's argument nodes), keeping the existing encryptCall exclusion logic intact (references: CallExpr call, DataFlow::Node data, isDataTransmissionCall, isEHRData, encryptCall)..github/codeql/custom-queries/ehr/ehr-security-patterns.ql (1)
17-46: Design trade-off: merged configuration reduces precision.Combining the two original configurations (
InsecureEHRConfigandUnsafeEHRAccess) into a singleEHRConfigSigmodule means all sources can flow to all sinks:
EHRCredentialSource→ EHR request arguments (could be legitimate credential usage)RemoteFlowSource→ logging calls (could be intentional request logging)This may increase false positives compared to the original separate configurations. If this is intentional for simplicity, consider documenting the trade-off. If high precision is needed, you could use separate configuration modules or add additional constraints in
isSinkto filter source types.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/codeql/custom-queries/ehr/ehr-security-patterns.ql around lines 17 - 46, The merged EHRConfigSig loses precision by allowing both EHRCredentialSource and RemoteFlowSource to match all sinks; split the config back into two modules (InsecureEHRConfig and UnsafeEHRAccess) or tighten EHRConfigSig.isSink to check source type before matching sinks (e.g., only allow EHRCredentialSource to match logging/URL sinks and only allow RemoteFlowSource to match remote-request sinks), using the existing symbols isSource, isSink, EHRCredentialSource, RemoteFlowSource, and EHREndpoint to implement the source-specific constraints.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/codeql/custom-queries/ehr/ehr-security-patterns.ql:
- Around line 36-44: The sink pattern currently requires the EHREndpoint to flow
to the same argument as the tainted sink; instead, update the condition so the
EHREndpoint can flow to any argument of the same DataFlow::CallNode (call) while
the sink remains any argument of that call. Concretely, replace the check using
endpoint.flowsTo(sink) with a check that there exists a DataFlow::Node (e.g.,
urlArg) such that call.getAnArgument(urlArg) and endpoint.flowsTo(urlArg),
keeping the existing DataFlow::CallNode call, sink, and EHREndpoint endpoint
symbols to locate and wire the logic together.
- Line 15: The import of PathGraph is currently from DataFlow::PathGraph; change
it to import PathGraph from the instantiated flow module by replacing that
import with an import of EHRFlow::PathGraph and move this import so it appears
after the EHRFlow module definition (i.e., after the EHRFlow instantiation that
uses DataFlow::ConfigSig) so path explanations are generated using your taint
configuration (refer to PathGraph, EHRFlow, and DataFlow::ConfigSig to locate
the relevant code).
---
Nitpick comments:
In @.github/codeql/custom-queries/ehr/ehr-security-patterns.ql:
- Around line 17-46: The merged EHRConfigSig loses precision by allowing both
EHRCredentialSource and RemoteFlowSource to match all sinks; split the config
back into two modules (InsecureEHRConfig and UnsafeEHRAccess) or tighten
EHRConfigSig.isSink to check source type before matching sinks (e.g., only allow
EHRCredentialSource to match logging/URL sinks and only allow RemoteFlowSource
to match remote-request sinks), using the existing symbols isSource, isSink,
EHRCredentialSource, RemoteFlowSource, and EHREndpoint to implement the
source-specific constraints.
In @.github/codeql/custom-queries/ehr/unencrypted-ehr-data.ql:
- Around line 42-51: The query currently treats isDataTransmissionCall(call) and
isEHRData(data) independently, causing false positives because it doesn't ensure
the EHR data actually flows into the transmission call; modify the where-clause
to require a data flow from data into an argument of the transmission call
(e.g., add a condition using
data.flowsTo(DataFlow::exprNode(call.getAnArgument())) or equivalent to assert
data flows to one of call's argument nodes), keeping the existing encryptCall
exclusion logic intact (references: CallExpr call, DataFlow::Node data,
isDataTransmissionCall, isEHRData, encryptCall).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: db689ab3-15c7-4479-b7a4-bacc0f087f7b
📒 Files selected for processing (3)
.github/codeql/custom-queries/ehr/ehr-security-patterns.ql.github/codeql/custom-queries/ehr/unencrypted-ehr-data.ql.github/workflows/codeql.yml
💤 Files with no reviewable changes (1)
- .github/workflows/codeql.yml
- Corrected relative paths in config/vitest.config.ts for aliases and setup files. - Fixed error handling logic in health-monitor.ts (typos in catch blocks). - Optimized PerformanceOptimizer cache eviction from O(n) to O(1). - Updated PatientResponseService.test.ts to correctly await async methods and match output formats. - Fixed ambiguous selectors and ensured proper cleanup in WebSocketProgressBar.test.tsx. - Added missing react-dom/test-utils mock for React 19 compatibility. - Modernized CodeQL custom queries in .github/codeql/custom-queries/ to use TaintTracking::Global and flowsTo API. - Fixed EHREndpoint type and hasFlowPath resolution in ehr-security-patterns.ql. - Removed deprecated setup-python-dependencies from CodeQL workflow. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
.github/codeql/custom-queries/ehr/ehr-security-patterns.ql (1)
74-82:⚠️ Potential issue | 🟠 MajorLogic flaw in EHR request sink pattern remains unaddressed.
The condition
endpoint.flowsTo(sink)requires the EHR endpoint URL to flow to the same argument that is the taint sink. This misses the primary attack vector: tainted remote data flowing to a different argument (e.g., request body) of a call targeting an EHR endpoint.Example not detected:
const url = "https://example.com/fhir/Patient"; // EHREndpoint const userInput = req.body.data; // RemoteFlowSource (tainted) fetch(url, { body: userInput }); // userInput in body, url in first argProposed fix
// Sinks for unsafe access: remote data used in requests to EHR endpoints exists(DataFlow::CallNode call | ( call.getCalleeName().matches("%request%") or call.getCalleeName().matches("%fetch%") or call.getCalleeName().matches("%axios%") ) and sink = call.getAnArgument() and - exists(EHREndpoint endpoint | endpoint.flowsTo(sink)) + exists(EHREndpoint endpoint | endpoint.flowsTo(call.getAnArgument())) )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/codeql/custom-queries/ehr/ehr-security-patterns.ql around lines 74 - 82, The current pattern only matches when the EHREndpoint URL flows into the exact same call argument identified as sink; update the predicate so we require the EHREndpoint to flow to some call argument (e.g., introduce an argument variable endpointArg via call.getAnArgument()/call.getArgument(i)) and allow the tainted sink to be a different argument (sink = call.getAnArgument()) by replacing endpoint.flowsTo(sink) with an exists(endpointArg | call.getAnArgument() = endpointArg and endpoint.flowsTo(endpointArg) and not endpointArg.equals(sink)) so the rule detects cases where the URL is one argument and tainted remote data flows into another (body/header) argument.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In @.github/codeql/custom-queries/ehr/ehr-security-patterns.ql:
- Around line 74-82: The current pattern only matches when the EHREndpoint URL
flows into the exact same call argument identified as sink; update the predicate
so we require the EHREndpoint to flow to some call argument (e.g., introduce an
argument variable endpointArg via call.getAnArgument()/call.getArgument(i)) and
allow the tainted sink to be a different argument (sink = call.getAnArgument())
by replacing endpoint.flowsTo(sink) with an exists(endpointArg |
call.getAnArgument() = endpointArg and endpoint.flowsTo(endpointArg) and not
endpointArg.equals(sink)) so the rule detects cases where the URL is one
argument and tainted remote data flows into another (body/header) argument.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6023d2f9-b297-4c73-9cee-1d952ff69015
📒 Files selected for processing (1)
.github/codeql/custom-queries/ehr/ehr-security-patterns.ql
- Corrected relative paths in config/vitest.config.ts for aliases and setup files. - Fixed error handling logic in health-monitor.ts (typos in catch blocks). - Optimized PerformanceOptimizer cache eviction from O(n) to O(1). - Updated PatientResponseService.test.ts to correctly await async methods and match output formats. - Fixed ambiguous selectors and ensured proper cleanup in WebSocketProgressBar.test.tsx. - Added missing react-dom/test-utils mock for React 19 compatibility. - Modernized CodeQL custom queries in .github/codeql/custom-queries/ to use TaintTracking::Global and fixed resolution errors by moving logic into ConfigSig. - Removed deprecated setup-python-dependencies from CodeQL workflow. Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
There was a problem hiding this comment.
🧹 Nitpick comments (3)
.github/codeql/custom-queries/ehr/ehr-security-patterns.ql (2)
25-29: Log sink pattern is overly broad.The regex
(?i).*log.*matches any function containing "log" anywhere in the name, including unrelated functions likecatalog,dialogue,analog, orprologue. This will cause false positives.🔧 Suggested improvement with word boundary matching
predicate isSink(DataFlow::Node sink) { exists(DataFlow::CallNode call | - call.getCalleeName().regexpMatch("(?i).*log.*") and + call.getCalleeName().regexpMatch("(?i).*(\\blog\\b|logger|logging|console).*") and sink = call.getAnArgument() ) orAlternatively, match specific known logging patterns:
call.getCalleeName().regexpMatch("(?i)(log|warn|error|info|debug|trace|console)")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/codeql/custom-queries/ehr/ehr-security-patterns.ql around lines 25 - 29, The isSink predicate is too broad because call.getCalleeName().regexpMatch("(?i).*log.*") will match any name containing "log"; narrow this by changing the regexp in isSink (the DataFlow::CallNode / call.getCalleeName() check) to either use word-boundary matching or enumerate common logging identifiers (e.g., use a pattern like (?i)\b(log|warn|error|info|debug|trace|console)\b or an explicit alternation of known logging functions) so only actual logging calls are treated as sinks.
34-39: EHR endpoint sink only matches literal URL strings.
call.getAnArgument().getStringValue()only returns non-null for string literals, so dynamically constructed URLs won't be detected:const baseUrl = config.ehrEndpoint; // Won't match fetch(baseUrl + "/fhir/Patient", data);This is an acceptable precision trade-off, but consider adding a supplementary pattern for well-known URL variables/properties if broader coverage is needed.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/codeql/custom-queries/ehr/ehr-security-patterns.ql around lines 34 - 39, The current DataFlow::CallNode sink logic relies on call.getAnArgument().getStringValue(), which only matches string literals and misses dynamically constructed URLs; update the query to add a supplementary pattern that matches well-known EHR URL variables/properties and non-literal argument sources (e.g., check the argument's value/source rather than only getStringValue()), for example add an alternative exists branch that inspects call.getAnArgument().getAValue()/getAnArgument().getASource() or matches identifier/property names like "ehrEndpoint", "baseUrl", "config.*" and still applies the same url.regexpMatch and callee regexpMatch checks so dynamically-built endpoints (config.ehrEndpoint + "/fhir") are flagged..github/codeql/custom-queries/ehr/unencrypted-ehr-data.ql (1)
17-22: Source detection usingtoString()is unreliable for taint tracking.Using
source.asExpr().toString().toLowerCase()matches based on source code representation (variable names, string literals), which is fragile:
- False positives: Variables like
catalogItemmatch due to containing "clinical" substring patterns- False negatives: Aliased or renamed EHR data won't be detected
Consider using semantic patterns like property accesses on known EHR objects or API return values instead.
🔧 Suggested improvement using semantic sources
predicate isSource(DataFlow::Node source) { - exists(string s | - s = source.asExpr().toString().toLowerCase() and - s.regexpMatch(".*(patient|health|record|ehr|fhir|clinical).*") - ) + // Match property reads from EHR/FHIR objects + exists(DataFlow::PropRead read | + read = source and + read.getPropertyName().regexpMatch("(?i).*(patient|health|record|ehr|fhir|clinical).*") + ) + or + // Match return values from EHR API calls + exists(DataFlow::CallNode call | + call = source and + call.getCalleeName().regexpMatch("(?i).*(getPatient|fetchRecord|readEHR|getFHIR).*") + ) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/codeql/custom-queries/ehr/unencrypted-ehr-data.ql around lines 17 - 22, The predicate isSource currently relies on source.asExpr().toString().toLowerCase() and regexpMatch which is fragile; replace this string-based detection with semantic source patterns by matching expression/flow node kinds (e.g., DataFlow::ExprSource, FieldAccess, MemberAccess, MethodCall) and known EHR API identifiers or property names (for example check receiver and field names like "patient", "ehr", "fhir" on MemberAccess/FieldAccess nodes or known API call targets) so taint sources are identified by AST/semantic node types rather than textual toString() values; update the isSource predicate to inspect source.asExpr() node kind and its resolved member/identifier names instead of using toString()/regexpMatch.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.github/codeql/custom-queries/ehr/ehr-security-patterns.ql:
- Around line 25-29: The isSink predicate is too broad because
call.getCalleeName().regexpMatch("(?i).*log.*") will match any name containing
"log"; narrow this by changing the regexp in isSink (the DataFlow::CallNode /
call.getCalleeName() check) to either use word-boundary matching or enumerate
common logging identifiers (e.g., use a pattern like
(?i)\b(log|warn|error|info|debug|trace|console)\b or an explicit alternation of
known logging functions) so only actual logging calls are treated as sinks.
- Around line 34-39: The current DataFlow::CallNode sink logic relies on
call.getAnArgument().getStringValue(), which only matches string literals and
misses dynamically constructed URLs; update the query to add a supplementary
pattern that matches well-known EHR URL variables/properties and non-literal
argument sources (e.g., check the argument's value/source rather than only
getStringValue()), for example add an alternative exists branch that inspects
call.getAnArgument().getAValue()/getAnArgument().getASource() or matches
identifier/property names like "ehrEndpoint", "baseUrl", "config.*" and still
applies the same url.regexpMatch and callee regexpMatch checks so
dynamically-built endpoints (config.ehrEndpoint + "/fhir") are flagged.
In @.github/codeql/custom-queries/ehr/unencrypted-ehr-data.ql:
- Around line 17-22: The predicate isSource currently relies on
source.asExpr().toString().toLowerCase() and regexpMatch which is fragile;
replace this string-based detection with semantic source patterns by matching
expression/flow node kinds (e.g., DataFlow::ExprSource, FieldAccess,
MemberAccess, MethodCall) and known EHR API identifiers or property names (for
example check receiver and field names like "patient", "ehr", "fhir" on
MemberAccess/FieldAccess nodes or known API call targets) so taint sources are
identified by AST/semantic node types rather than textual toString() values;
update the isSource predicate to inspect source.asExpr() node kind and its
resolved member/identifier names instead of using toString()/regexpMatch.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: fcf1a0dc-4df6-41aa-9f89-2f4d3252662a
📒 Files selected for processing (2)
.github/codeql/custom-queries/ehr/ehr-security-patterns.ql.github/codeql/custom-queries/ehr/unencrypted-ehr-data.ql
There was a problem hiding this comment.
2 issues found across 2 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".github/codeql/custom-queries/ehr/ehr-security-patterns.ql">
<violation number="1" location=".github/codeql/custom-queries/ehr/ehr-security-patterns.ql:31">
P2: Exact-match `= "url"` is a regression from the previous `matches("%url%")`. Properties like `baseUrl`, `apiUrl`, `requestUrl`, and `redirectUrl` are no longer considered sinks, so credentials written to those properties won't be detected.</violation>
<violation number="2" location=".github/codeql/custom-queries/ehr/ehr-security-patterns.ql:36">
P1: `getStringValue()` only resolves constant string literals, so EHR URLs stored in variables or constructed dynamically won't be detected. The previous implementation used `EHREndpoint` as a `SourceNode` with `flowsTo`, which tracked the URL through data flow. Consider restoring `EHREndpoint` as a source node and using `flowsTo` to preserve that coverage.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| ) or | ||
| exists(DataFlow::CallNode call, string url | | ||
| call.getCalleeName().regexpMatch("(?i).*(request|fetch|axios).*") and | ||
| url = call.getAnArgument().getStringValue() and |
There was a problem hiding this comment.
P1: getStringValue() only resolves constant string literals, so EHR URLs stored in variables or constructed dynamically won't be detected. The previous implementation used EHREndpoint as a SourceNode with flowsTo, which tracked the URL through data flow. Consider restoring EHREndpoint as a source node and using flowsTo to preserve that coverage.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/codeql/custom-queries/ehr/ehr-security-patterns.ql, line 36:
<comment>`getStringValue()` only resolves constant string literals, so EHR URLs stored in variables or constructed dynamically won't be detected. The previous implementation used `EHREndpoint` as a `SourceNode` with `flowsTo`, which tracked the URL through data flow. Consider restoring `EHREndpoint` as a source node and using `flowsTo` to preserve that coverage.</comment>
<file context>
@@ -13,80 +13,36 @@
+ ) or
+ exists(DataFlow::CallNode call, string url |
+ call.getCalleeName().regexpMatch("(?i).*(request|fetch|axios).*") and
+ url = call.getAnArgument().getStringValue() and
+ url.regexpMatch(".*(/fhir/|/ehr/|/api/v|/epic/|/cerner/|/allscripts/).*") and
+ sink = call.getAnArgument()
</file context>
| ) or | ||
| exists(DataFlow::PropWrite write | | ||
| write.getPropertyName().matches("%url%") and | ||
| write.getPropertyName() = "url" and |
There was a problem hiding this comment.
P2: Exact-match = "url" is a regression from the previous matches("%url%"). Properties like baseUrl, apiUrl, requestUrl, and redirectUrl are no longer considered sinks, so credentials written to those properties won't be detected.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/codeql/custom-queries/ehr/ehr-security-patterns.ql, line 31:
<comment>Exact-match `= "url"` is a regression from the previous `matches("%url%")`. Properties like `baseUrl`, `apiUrl`, `requestUrl`, and `redirectUrl` are no longer considered sinks, so credentials written to those properties won't be detected.</comment>
<file context>
@@ -13,80 +13,36 @@
+ ) or
exists(DataFlow::PropWrite write |
- write.getPropertyName().matches("%url%") and
+ write.getPropertyName() = "url" and
sink = write.getRhs()
- )
</file context>
| write.getPropertyName() = "url" and | |
| write.getPropertyName().regexpMatch("(?i).*url.*") and |
This PR addresses critical issues preventing unit tests from executing correctly in the CI environment. Key fixes include path resolution in Vitest configuration, error handling in the HealthMonitor service, and updating stale tests to match the current async implementation of the PatientResponseService. Additionally, performance was significantly improved in the PerformanceOptimizer service by transitioning cache eviction from O(n) to O(1). Overall test stability was enhanced by adding global cleanup and fixing ambiguous selectors in frontend component tests.
PR created automatically by Jules for task 14363552755739880997 started by @daggerstuff
Summary by Sourcery
Fix test configuration and error handling while optimizing cache performance metrics.
Bug Fixes:
Enhancements:
Build:
oxctooxfmtand adjust the main test script path to the new testing runner location.Tests:
Summary by cubic
Fixes CI unit tests, modernizes CodeQL security queries, and speeds up the
PerformanceOptimizercache. Tests now run reliably in CI, and cache eviction is O(1) with accurate hit-rate metrics.Bug Fixes
vitestalias/setup paths; added React 19react-dom/test-utilsmock and global cleanup; stabilized WebSocket tests; awaited async prompt generation in AI tests.HealthMonitorerror handling usingString(error).path-problemwithTaintTracking::Global,ConfigSig, andPathGraph; added encryption sanitizer; removed deprecated workflow option; updated scripts/env (test runner path, formatter tooxfmt,.python-versionto 3.12.3).Refactors
totalCacheAccessesandcacheHitsCountfor precise hit rate; counters reset onreset().Written for commit db6a3c4. Summary will update on new commits.
Summary by CodeRabbit
Bug Fixes
Performance
Tests
Security
Chores