You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Deferred to R2 (need a compiler/tests to fix safely): S1874 (deprecated React.FormEvent/execCommand), remaining S4325, S3776 (cognitive complexity ×~29), S2004 (nesting).
CI + SonarCloud on this PR are the authoritative re-scan — I'll iterate R2 on whatever remains (and any regressions, e.g. the main.tsx!-removal under strict TS).
Summary by cubic
Quality-zero R1 expanded to lint-zero and coverage-100 across the monorepo, with safer parsing and a large test sweep to stabilize CI. Also forwarded CI visual/codex secrets and applied a non‑breaking web deps audit fix (no criticals) to keep gates green.
Refactors
Drove ruff/pylint/eslint to zero; added docstrings, constants, and clearer errors across API modules.
Hardened parsers and helpers: VTT/SRT timing, SRT translate/parse, subtitle grouping/shift, path guard, and lazy‑imported transcription/diarization backends with graceful fallbacks.
FFmpeg wrappers use named flags and better error handling; web code uses globalThis, fewer non‑null assertions, and readonly props.
services/worker Groq client finalized with offline gating; API client types tightened; minor UI/a11y polish continues (native <dialog>, button contrast).
Tests/CI
Added branch‑coverage suites for API (auth/identity, billing/Stripe, publish/collab, assets/jobs/usage), storage backends, media‑core (diarize/transcribe/translate/ffmpeg), and worker end‑to‑end helpers.
Isolated rate limiter state per test via new reset helpers to prevent sporadic 429s on fast CI runs.
Vitest setup now provides full localStorage/sessionStorage mocks; bumped vitest to 4.1.9 via audit fix to close criticals; web e2e and unit tests are stable.
Forwarded CHROMATIC_PROJECT_TOKEN, APPLITOOLS_API_KEY, and CODEX_AUTH_JSON to the quality‑zero workflow scanner matrix.
Cross‑platform fixes: SQLite URL building and Windows temp‑file handling in tests; shared worker fixtures. Coverage gates enabled (web at 100%); CI passes reliably.
Written for commit 8d3ce2e. Summary will update on new commits.
CodeAnt-AI Description
Improve auth, billing, uploads, and media tools across the app
What Changed
Login, SSO, invites, SCIM, and billing flows now return clearer “not found” and “authentication required” responses, with fewer broken edge cases during Okta, OAuth, and Stripe callbacks
Uploads, job retries, publish connections, and media exports now handle more cases reliably, including multipart uploads, share links, job bundles, and clip packages
Captions, subtitles, and shorts tools now parse and render more input formats, keep timing edits consistent, and surface better results when transcription or scoring falls back
Several screens and controls are now keyboard-accessible or more consistent to use, including dialogs, drop zones, media previews, and confirmation prompts
Impact
✅ Fewer failed sign-ins and invite acceptances ✅ Clearer billing and SSO error handling ✅ More reliable uploads and media exports
💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
@codeant-ai ask: Your question here
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
@codeant-ai ask: Can you suggest a safer alternative to storing this secret?
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
@codeant-ai: Your feedback here
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
@codeant-ai: Do not flag unused imports.
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
@codeant-ai: review
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.
Summary by CodeRabbit
Release Notes
New Features
Settings modal now uses a native HTML dialog for improved accessibility.
Improved keyboard support for upload dropzones.
Refactor
More consistent API error handling and response metadata across key endpoints.
Unified publish-provider typing in the web client.
Bug Fixes
Improved system status diagnostics rendering.
Safer cleanup for subtitle editor downloads and object URLs.
Style
Updated dark mode button background.
Tests
Added browser storage polyfills for more reliable test runs.
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bfff2562-48f0-4522-9b7e-f35716af1bae
📥 Commits
Reviewing files that changed from the base of the PR and between 8b9e74b and 8d3ce2e.
⛔ Files ignored due to path filters (1)
apps/web/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
.github/workflows/quality-zero-platform.yml
apps/api/app/rate_limit.py
apps/api/tests/conftest.py
apps/api/tests/test_rate_limit_policies.py
🚧 Files skipped from review as they are similar to previous changes (1)
apps/api/app/rate_limit.py
📝 Walkthrough
Walkthrough
Broad refactors added shared constants, helper functions, and typed route/query changes across API, worker, media-core, and web code. Test coverage and fixtures expanded around the updated flows, and several scripts and config files gained lint or formatting adjustments.
Changes
Cross-repo refactor and test coverage
Layer / File(s)
Summary
API core, auth, billing, and storage apps/api/app/*
API modules add shared constants, helper functions, and route metadata changes across auth, billing, collaboration, identity, publish, storage, and core app endpoints.
API models, config, database, and logging apps/api/app/*
API settings, database, error, share-token, and ORM model declarations are reformatted or centralized through new constants and docstrings, with no schema behavior changes beyond foreign-key constant use.
API tests and fixtures apps/api/tests/*
API test fixtures, route coverage, and branch tests expand around auth, billing, collaboration, identity, publish, rate limiting, storage, and helper utilities.
Web, desktop, and browser storage apps/web/src/*, apps/desktop/src/*
Web and desktop code switches to named provider types, globalThis, Readonly props, native dialog markup, and updated subtitle/media UI helpers and downloads.
Worker orchestration, media, and transcription services/worker/*
Worker execution paths add shared constants and helper functions for retries, usage, publish dispatch, transcription/captions, styled subtitles, shorts generation, and retention cleanup.
Media-core diarization, subtitles, transcription, and video tools packages/media-core/src/media_core/*
Media-core libraries refactor diarization, subtitle parsing, transcription backends, ffmpeg helpers, and shorts scoring into smaller internal helpers.
Scripts, workflow secrets, and lint markers scripts/*, .github/workflows/*, .gitignore
Scripts, workflow secrets, and .gitignore entries are updated with lint directives, secret forwarding, and ignore patterns for generated or local artifacts.
Estimated code review effort
🎯 5 (Critical) | ⏱️ ~120 minutes
Possibly related PRs
Prekzursil/Reframe#96: Overlaps directly on services/worker/worker.py publish-step dispatch and publish job execution logic, which this PR also significantly reorganizes with new helpers.
Prekzursil/Reframe#79: Shares the billing_api.py Stripe webhook seat-limit and checkout session handling, which this PR refactors into dedicated helper functions.
Poem
🐇 A rabbit hops through tangled strings,
Replacing every "not found" thing.
Constants bloom where literals lay, globalThis chases window away.
Each helper neatly cut and named—
The codebase tidied, refactor claimed! ✨
✨ Finishing Touches📝 Generate docstrings
Create stacked PR
Commit on current branch
🧪 Generate unit tests (beta)
Create PR with unit tests
Commit unit tests in branch chore/sonar-zero-remediation
We reviewed changes in df95284...8d3ce2e on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.
Some issues found as part of this review are outside of the diff in this pull request and aren't shown in the inline review comments due to GitHub's API limitations. You can see those issues on the DeepSource dashboard.
AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.
The reason will be displayed to describe this comment to others. Learn more.
Unexpected prompt
JavaScript's alert, confirm and prompt functions are widely considered to be obtrusive as UI elements and should be replaced by a more appropriate custom UI implementation. Furthermore, alert is often used while debugging code, which should be removed before deployment to production.
The reason will be displayed to describe this comment to others. Learn more.
Unexpected confirm
JavaScript's alert, confirm and prompt functions are widely considered to be obtrusive as UI elements and should be replaced by a more appropriate custom UI implementation. Furthermore, alert is often used while debugging code, which should be removed before deployment to production.
The reason will be displayed to describe this comment to others. Learn more.
Unexpected confirm
JavaScript's alert, confirm and prompt functions are widely considered to be obtrusive as UI elements and should be replaced by a more appropriate custom UI implementation. Furthermore, alert is often used while debugging code, which should be removed before deployment to production.
The reason will be displayed to describe this comment to others. Learn more.
Documentation comment not found for function declaration `CopyCommandButton`
It is recommended to have documentation comments above, or right inside a function/class declaration.
This helps developers, users and even the author understand the purpose of a code snippet or API function in the future.
NOTE: If you want to stop this issue from getting raised on certain constructs (arrow functions, class expressions, methods etc.), consider using the skip_doc_coverage option under the analyzers.meta property in your .deepsource.toml file.
For example, the following configuration will silence this issue for class expressions and method definitions:
The reason will be displayed to describe this comment to others. Learn more.
Documentation comment not found for arrow function `onCopy`
It is recommended to have documentation comments above, or right inside a function/class declaration.
This helps developers, users and even the author understand the purpose of a code snippet or API function in the future.
NOTE: If you want to stop this issue from getting raised on certain constructs (arrow functions, class expressions, methods etc.), consider using the skip_doc_coverage option under the analyzers.meta property in your .deepsource.toml file.
For example, the following configuration will silence this issue for class expressions and method definitions:
The reason will be displayed to describe this comment to others. Learn more.
Documentation comment not found for function declaration `parseTimingLine`
It is recommended to have documentation comments above, or right inside a function/class declaration.
This helps developers, users and even the author understand the purpose of a code snippet or API function in the future.
NOTE: If you want to stop this issue from getting raised on certain constructs (arrow functions, class expressions, methods etc.), consider using the skip_doc_coverage option under the analyzers.meta property in your .deepsource.toml file.
For example, the following configuration will silence this issue for class expressions and method definitions:
The reason will be displayed to describe this comment to others. Learn more.
Documentation comment not found for function declaration `subtitlesToCues`
It is recommended to have documentation comments above, or right inside a function/class declaration.
This helps developers, users and even the author understand the purpose of a code snippet or API function in the future.
NOTE: If you want to stop this issue from getting raised on certain constructs (arrow functions, class expressions, methods etc.), consider using the skip_doc_coverage option under the analyzers.meta property in your .deepsource.toml file.
For example, the following configuration will silence this issue for class expressions and method definitions:
The reason will be displayed to describe this comment to others. Learn more.
Documentation comment not found for function declaration `validateCues`
It is recommended to have documentation comments above, or right inside a function/class declaration.
This helps developers, users and even the author understand the purpose of a code snippet or API function in the future.
NOTE: If you want to stop this issue from getting raised on certain constructs (arrow functions, class expressions, methods etc.), consider using the skip_doc_coverage option under the analyzers.meta property in your .deepsource.toml file.
For example, the following configuration will silence this issue for class expressions and method definitions:
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: Avoid adding an extra remote API dependency for profile resolution; keep OAuth profile extraction local to the already-fetched user payload and fail fast when email is missing instead of calling another external endpoint. [custom_rule]
Severity Level: Minor ⚠️
Why it matters? 🤔
The final code introduces a network-dependent fallback to GitHub's /user/emails endpoint when the profile payload lacks an email address.
That matches the rule about replacing local-first/deterministic behavior with a remote API dependency, so the suggestion identifies a real violation.
This is a comment left during a code review.
**Path:** apps/api/app/auth_api.py
**Line:** 626:627
**Comment:***Custom Rule: Avoid adding an extra remote API dependency for profile resolution; keep OAuth profile extraction local to the already-fetched user payload and fail fast when email is missing instead of calling another external endpoint.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: Avoid automatic remote model downloads during diarization initialization by requiring pre-cached local models (or an explicit opt-in flag for network fetch), so default execution remains local-first and deterministic. [custom_rule]
Severity Level: Minor ⚠️
Why it matters? 🤔
This is a real violation of the local-first/deterministic rule: the diarization path now performs a remote Hugging Face download during initialization if the cache is missing. That makes default execution network-dependent rather than purely local.
This is a comment left during a code review.
**Path:** packages/media-core/src/media_core/diarize/__init__.py
**Line:** 184:184
**Comment:***Custom Rule: Avoid automatic remote model downloads during diarization initialization by requiring pre-cached local models (or an explicit opt-in flag for network fetch), so default execution remains local-first and deterministic.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: Avoid automatic cloud fallback when local translation initialization fails; keep execution local/deterministic by falling back to NoOpTranslator unless translator_backend is explicitly set to groq/cloud. [custom_rule]
Severity Level: Minor ⚠️
Why it matters? 🤔
The code falls back to a Groq/cloud translator when local translator initialization fails, which introduces a network-dependent path instead of staying local. That matches the rule against replacing local-first or deterministic behavior with remote-service fallback unless explicitly requested.
This is a comment left during a code review.
**Path:** services/worker/worker.py
**Line:** 1576:1578
**Comment:***Custom Rule: Avoid automatic cloud fallback when local translation initialization fails; keep execution local/deterministic by falling back to `NoOpTranslator` unless `translator_backend` is explicitly set to `groq`/`cloud`.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer TIP This summary will be updated as you push new changes.
The reason will be displayed to describe this comment to others. Learn more.
4 issues found across 30 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="packages/media-core/src/media_core/transcribe/backends/whisper_timestamped.py">
<violation number="1" location="packages/media-core/src/media_core/transcribe/backends/whisper_timestamped.py:33">
P2: `0.0 or w.get("score")` silently drops a valid 0.0 probability because `0.0` is falsy in Python. Use `w.get("probability") if w.get("probability") is not None else w.get("score")` instead.</violation>
</file>
<file name="apps/web/src/App.tsx">
<violation number="1" location="apps/web/src/App.tsx:3282">
P2: `<track kind="captions" />` is added without `src`, so captions never load and the element is invalid. This creates false a11y compliance while users still get no usable captions.</violation>
</file>
<file name="apps/web/src/components/SettingsModal.tsx">
<violation number="1" location="apps/web/src/components/SettingsModal.tsx:15">
P2: `aria-modal="true"` on `<dialog open>` (non-modal) misleads assistive technology — the element is announced as modal but focus can leave the dialog.</violation>
</file>
Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.
The reason will be displayed to describe this comment to others. Learn more.
P2: 0.0 or w.get("score") silently drops a valid 0.0 probability because 0.0 is falsy in Python. Use w.get("probability") if w.get("probability") is not None else w.get("score") instead.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/media-core/src/media_core/transcribe/backends/whisper_timestamped.py, line 33:
<comment>`0.0 or w.get("score")` silently drops a valid 0.0 probability because `0.0` is falsy in Python. Use `w.get("probability") if w.get("probability") is not None else w.get("score")` instead.</comment>
<file context>
@@ -11,6 +11,53 @@
+ except (KeyError, TypeError, ValueError) as exc:
+ logger.debug("Skipping malformed word payload: %s (%s)", w, exc)
+ return None
+ prob = w.get("probability") or w.get("score")
+ return Word(text=text, start=start, end=end, probability=_coerce_probability(prob))
+
</file context>
The reason will be displayed to describe this comment to others. Learn more.
P2: <track kind="captions" /> is added without src, so captions never load and the element is invalid. This creates false a11y compliance while users still get no usable captions.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/web/src/App.tsx, line 3282:
<comment>`<track kind="captions" />` is added without `src`, so captions never load and the element is invalid. This creates false a11y compliance while users still get no usable captions.</comment>
<file context>
@@ -3254,7 +3279,7 @@ function StyleEditor({
)}
{outputAssetUrl && outputAsset.mime_type?.includes("video") && (
- <video className="preview" controls src={outputAssetUrl} />
+ <video className="preview" controls src={outputAssetUrl}><track kind="captions" /></video>
)}
{outputAssetUrl && outputAsset.mime_type?.includes("text") && <TextPreview url={outputAssetUrl} title="Subtitle preview" />}
</file context>
The reason will be displayed to describe this comment to others. Learn more.
P2: aria-modal="true" on <dialog open> (non-modal) misleads assistive technology — the element is announced as modal but focus can leave the dialog.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/web/src/components/SettingsModal.tsx, line 15:
<comment>`aria-modal="true"` on `<dialog open>` (non-modal) misleads assistive technology — the element is announced as modal but focus can leave the dialog.</comment>
<file context>
@@ -12,7 +12,7 @@ export function SettingsModal({ onClose }: Props) {
return (
- <div className="modal-backdrop" role="dialog" aria-modal="true">
+ <dialog className="modal-backdrop" open aria-modal="true">
<div className="modal">
<header className="modal-head">
</file context>
… setup
jsdom under vitest 4 exposed an incomplete Storage (no removeItem), failing every
test that reset auth state in beforeEach (pre-existing on main, not from R1). With
a full in-memory Storage mock the web suite passes 47/47 and v8 coverage reports
100% line+branch+func+stmt — unblocking the Coverage 100 Gate for web.
The reason will be displayed to describe this comment to others. Learn more.
Bug: Creating an SSO connection with an invalid default_role errors, but updating one silently replaces the invalid role with "viewer" due to inconsistent validation logic. Severity: LOW
Suggested Fix
To ensure consistent behavior, add the same validation logic present in _apply_sso_connection_update to the _build_sso_connection function. This would involve checking if the provided default_role is in ROLE_VALUES and falling back to "viewer" if it is not, making the create and update paths behave identically.
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: apps/api/app/identity_api.py#L181
Potential issue: There is an inconsistency in how an invalid `default_role` is handled
for SSO connections. When creating a new connection, an invalid role is passed from
`_build_sso_connection` to `_upsert_sso_connection`, which then raises a 422 `ApiError`.
However, when updating an existing connection, `_apply_sso_connection_update` validates
the role and silently replaces an invalid one with "viewer". This results in different,
inconsistent behavior for create and update operations for the same invalid input.
Did we get this right? 👍 / 👎 to inform future reviews.
Temporary render/subtitle files are not cleaned up after asset persistence.
On Line 1928 and Line 2156, files created under tmp are uploaded but never unlinked (output_path, subtitle_file, styled_path). This will grow local disk unbounded on active workers.
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@services/worker/worker.py` around lines 1887 - 1929, Temporary files created
during the rendering process are not being deleted after they are used to create
assets, causing unbounded disk growth on active workers. In the
render_styled_subtitles function, after calling create_asset_for_existing_file
with output_path to persist the rendered subtitle file, add cleanup code to
delete the temporary output_path file using os.unlink() or Path.unlink(). Apply
the same cleanup pattern to other similar rendering functions that create
temporary files like subtitle_file and styled_path, ensuring files are deleted
after asset creation succeeds but before the function returns.
🧹 Nitpick comments (2)
apps/web/src/App.tsx (1)
21-24: ⚡ Quick win
Reuse the API client’s PublishProvider type here.
The PR adds PublishProvider to apps/web/src/api/client.ts, but this file still redeclares the same union locally. Importing the shared type keeps the UI state and apiClient method signatures from drifting when provider support changes.
♻️ Proposed alignment
type PublishConnectionView,
type PublishJobView,
+ type PublishProvider,
type PublishProviderView,
@@
const ORG_MANAGER_ROLES = new Set(["owner", "admin"]);
const PUBLISH_PROVIDERS = ["youtube", "tiktok", "instagram", "facebook"] as const;
-type PublishProvider = (typeof PUBLISH_PROVIDERS)[number];
Also applies to: 114-115
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/App.tsx` around lines 21 - 24, The App.tsx file redeclares the
PublishProvider type locally instead of importing it from the API client. Remove
the local PublishProvider type declaration from the import section around lines
21-24 and instead import PublishProvider directly from
apps/web/src/api/client.ts. Then update the other reference to the local
redeclaration at lines 114-115 to use the imported type instead. This ensures
the UI state and API client method signatures stay aligned when provider support
changes.
apps/api/app/billing_api.py (1)
433-434: 💤 Low value
Redundant metadata type check.
Line 434 re-checks isinstance(metadata, dict) immediately after line 433 already assigned metadata from the same conditional, making the second check always true.
♻️ Suggested simplification
- metadata = obj.get("metadata") if isinstance(obj.get("metadata"), dict) else {}- metadata = metadata if isinstance(metadata, dict) else {}+ metadata = obj.get("metadata") if isinstance(obj.get("metadata"), dict) else {}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/app/billing_api.py` around lines 433 - 434, The second metadata
assignment on line 434 is redundant because line 433 already guarantees that
metadata is a dict through its conditional expression. The ternary operator on
line 433 ensures metadata will be either the actual dict from
obj.get("metadata") or an empty dict, making the isinstance check on line 434
always true. Remove the redundant line 434 and keep only the conditional
assignment from line 433 that properly initializes metadata.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/api/app/api.py`:
- Around line 2436-2450: The validation checks for video and audio content types
at lines 2436 and 2444 now reject requests with missing or empty content_type
values, but the UploadInitRequest.mime_type field is optional in the schema
(line 942), breaking backward compatibility with clients that omit this field.
Modify the validation logic to only enforce the content type checks when a
mime_type is actually provided; if content_type is None or empty, either skip
the validation for that media kind or handle it gracefully without raising a 400
error, ensuring that clients can still proceed without providing an explicit
mime_type while maintaining security for requests that do provide one.
- Around line 2041-2044: The current exception handling around the UUID
conversion and add_asset_by_id call is too broad and suppresses real errors that
should surface for debugging. Narrow the exception handling to catch only the
UUID conversion failure by wrapping only the UUID(str(asset_id)) call in a
try-except block that catches ValueError, and move the add_asset_by_id function
call outside this try-except so that any genuine data-access or runtime failures
from that function are allowed to propagate rather than being silently
suppressed and returning None.
In `@apps/web/src/App.tsx`:
- Around line 593-595: The onDrop handler in AudioUploadPanel is missing a
preventDefault() call on the drop event, which allows the browser's default
file-drop behavior to still trigger and potentially navigate away or open the
file. In the onDrop event handler that calls handleFiles(e.dataTransfer.files),
add e.preventDefault() to ensure the browser's default drop action is fully
prevented and the upload flow completes uninterrupted.
- Line 3282: Remove or properly wire all empty caption track elements across
apps/web/src/App.tsx that lack src attributes, as they do not provide functional
captions. At apps/web/src/App.tsx line 3282, conditionally render the track
element only when a subtitle source URL exists for the output asset. At line
3300, add a real caption source URL to the track or remove it entirely. At line
3629, add a real caption source URL to the track or remove it. At line 3788,
wire a real subtitle source URL to the track. At line 3842, wire the generated
subtitle asset URL as the track src attribute. At line 3897, add a real caption
source URL or remove the track. At line 3903, remove the track element entirely
since captions do not apply to audio (use kind="descriptions" if audio
transcripts are needed instead). At lines 4150-4152, wire the transcript or
caption URL as the track src attribute for video accessibility. At line 4265,
add a real caption source URL to the track or omit it entirely.
In `@apps/web/src/components/SettingsModal.tsx`:
- Line 15: The dialog element at line 15 in SettingsModal.tsx uses the open
attribute which does not provide native modal behavior (focus trap and top
layer). To fix this, obtain a ref to the dialog element and replace the open
attribute with a useEffect hook that calls the dialog's showModal() method when
the component should be visible and the close() method when it should be hidden.
Additionally, wire up the dialog's native close and cancel events to trigger the
onClose callback, ensuring the parent's showSettings state stays in sync with
the actual dialog state and preventing desynchronization between the dialog's
internal state and the parent component's state management.
In `@apps/web/src/main.tsx`:
- Line 6: The call to ReactDOM.createRoot with document.getElementById("root")
lacks a guard for null, which violates the API contract since getElementById
returns HTMLElement | null while createRoot requires a non-null Element or
DocumentFragment. Add an explicit null check before passing the result of
document.getElementById("root") to ReactDOM.createRoot, and handle the case
where the root element is missing (either by throwing an informative error or
logging a warning) to ensure type safety and graceful failure.
In `@packages/media-core/src/media_core/transcribe/backends/whisper_cpp.py`:
- Around line 41-56: The issue is that in the _parse_token_word and
_parse_segment_word functions, the fallback argument tok.get(...) and
seg.get(...) are evaluated eagerly before getattr() is called, which fails
immediately for object-like tokens that don't have a .get() method. Fix this by
using conditional logic that only evaluates the fallback when needed—either
check if the attribute exists first using hasattr() before deciding which
approach to use, or restructure the code to attempt attribute access first and
catch AttributeError before falling back to dictionary-style access via .get().
Apply this fix to all three affected locations: lines 43-45 in
_parse_token_word, lines 54-56 in _parse_segment_word, and lines 72-75 (also
mentioned in "Also applies to").
- Around line 87-90: The `segments` parameter is being iterated twice - once in
the for loop that calls `_segment_words(seg)` and again when passed to
`_join_segment_text(segments)`. If `segments` is a generator or one-shot
iterator, it will be exhausted after the first iteration, causing
`_join_segment_text` to receive an empty iterable. Convert `segments` to a list
before the for loop to ensure it can be safely iterated multiple times by both
the loop and the subsequent `_join_segment_text` call.
---
Outside diff comments:
In `@services/worker/worker.py`:
- Around line 1887-1929: Temporary files created during the rendering process
are not being deleted after they are used to create assets, causing unbounded
disk growth on active workers. In the render_styled_subtitles function, after
calling create_asset_for_existing_file with output_path to persist the rendered
subtitle file, add cleanup code to delete the temporary output_path file using
os.unlink() or Path.unlink(). Apply the same cleanup pattern to other similar
rendering functions that create temporary files like subtitle_file and
styled_path, ensuring files are deleted after asset creation succeeds but before
the function returns.
---
Nitpick comments:
In `@apps/api/app/billing_api.py`:
- Around line 433-434: The second metadata assignment on line 434 is redundant
because line 433 already guarantees that metadata is a dict through its
conditional expression. The ternary operator on line 433 ensures metadata will
be either the actual dict from obj.get("metadata") or an empty dict, making the
isinstance check on line 434 always true. Remove the redundant line 434 and keep
only the conditional assignment from line 433 that properly initializes
metadata.
In `@apps/web/src/App.tsx`:
- Around line 21-24: The App.tsx file redeclares the PublishProvider type
locally instead of importing it from the API client. Remove the local
PublishProvider type declaration from the import section around lines 21-24 and
instead import PublishProvider directly from apps/web/src/api/client.ts. Then
update the other reference to the local redeclaration at lines 114-115 to use
the imported type instead. This ensures the UI state and API client method
signatures stay aligned when provider support changes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
Push a commit to this branch (recommended)
Create a new PR with the fixes
ℹ️ Review info⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 82659cea-5608-4ccc-aea7-cb4b44fcc2c3
📥 Commits
Reviewing files that changed from the base of the PR and between df95284 and b958f78.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
Narrow the exception handling in clip asset packaging.
Line 2043 catches Exception around both UUID parsing and asset loading. That suppresses unexpected runtime/data-access failures and can silently produce incomplete bundles. Catch only UUID-conversion failures and let real errors surface.
‼️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.
[warning] 2043-2043: Do not catch blind exception: Exception
(BLE001)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/app/api.py` around lines 2041 - 2044, The current exception handling
around the UUID conversion and add_asset_by_id call is too broad and suppresses
real errors that should surface for debugging. Narrow the exception handling to
catch only the UUID conversion failure by wrapping only the UUID(str(asset_id))
call in a try-except block that catches ValueError, and move the add_asset_by_id
function call outside this try-except so that any genuine data-access or runtime
failures from that function are allowed to propagate rather than being silently
suppressed and returning None.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟠 Major | ⚡ Quick win
Optional mime_type is now treated as required for video/audio uploads.
Line 2436 and Line 2444 reject empty content_type, but UploadInitRequest.mime_type is optional (Line 942). This introduces a request-contract break for clients that omit mime_type and now get 400.
💡 Proposed fix
- if normalized_kind == "video" and not ct.startswith("video/"):+ if normalized_kind == "video" and ct and not ct.startswith("video/"):
raise ApiError(
status_code=status.HTTP_400_BAD_REQUEST,
code=ErrorCode.VALIDATION_ERROR,
message="Invalid content type for video upload",
details={"content_type": content_type, "filename": filename},
)
- if normalized_kind == "audio" and not ct.startswith("audio/"):+ if normalized_kind == "audio" and ct and not ct.startswith("audio/"):
raise ApiError(
status_code=status.HTTP_400_BAD_REQUEST,
code=ErrorCode.VALIDATION_ERROR,
message="Invalid content type for audio upload",
details={"content_type": content_type, "filename": filename},
)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/app/api.py` around lines 2436 - 2450, The validation checks for
video and audio content types at lines 2436 and 2444 now reject requests with
missing or empty content_type values, but the UploadInitRequest.mime_type field
is optional in the schema (line 942), breaking backward compatibility with
clients that omit this field. Modify the validation logic to only enforce the
content type checks when a mime_type is actually provided; if content_type is
None or empty, either skip the validation for that media kind or handle it
gracefully without raising a 400 error, ensuring that clients can still proceed
without providing an explicit mime_type while maintaining security for requests
that do provide one.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
Prevent the browser’s default file-drop action.
AudioUploadPanel handles dataTransfer.files but does not cancel the drop event; some browsers can still navigate to/open the dropped file, interrupting the upload flow.
‼️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.
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/App.tsx` around lines 593 - 595, The onDrop handler in
AudioUploadPanel is missing a preventDefault() call on the drop event, which
allows the browser's default file-drop behavior to still trigger and potentially
navigate away or open the file. In the onDrop event handler that calls
handleFiles(e.dataTransfer.files), add e.preventDefault() to ensure the
browser's default drop action is fully prevented and the upload flow completes
uninterrupted.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟡 Minor
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash# Description: Verify all media track elements in App.tsx have a real caption source.# Expect: No matches for track elements that omit `src=`.
rg -nP '<track\b(?![^>]*\bsrc=)' -C2 -- 'apps/web/src/App.tsx'
Repository: Prekzursil/Reframe
Length of output: 3188
🏁 Script executed:
#!/bin/bash# Check context around the track elements to see if caption/subtitle sources are available# Focus on a few representative locations to understand the patternecho"=== Context around line 3282 (outputAsset) ==="
sed -n '3275,3285p' apps/web/src/App.tsx
echo -e "\n=== Context around line 3300 (safeUploadedPreview) ==="
sed -n '3295,3305p' apps/web/src/App.tsx
echo -e "\n=== Context around line 3903 (safeMergeAudioPreview) ==="
sed -n '3898,3908p' apps/web/src/App.tsx
echo -e "\n=== Context around line 4150-4152 (inputAsset) ==="
sed -n '4145,4155p' apps/web/src/App.tsx
# Also check if there are any track elements WITH src attributes in the fileecho -e "\n=== Check for track elements with src attributes ==="
rg '<track\b[^>]*\bsrc=' -C1 -- 'apps/web/src/App.tsx'| head -20
Repository: Prekzursil/Reframe
Length of output: 2600
Wire real caption tracks instead of empty placeholders.
The <track kind="captions" /> elements across the codebase do not provide captions without a src attribute. Either pass a real subtitle/caption URL to the track element or remove the empty track entirely.
Line 3282: render <track> only when a subtitle source exists for the output asset.
Line 3300: add a real caption source for the uploaded video preview or remove the track.
Line 3629: add a real caption source for the uploaded preview or remove the track.
Line 3788: add a real caption source for the subtitles video preview or remove the track.
Line 3842: wire the generated subtitle asset as the track source for styled output previews.
Line 3897: add a real caption source for the merge video preview or remove the track.
Line 3903: remove the track element (captions do not apply to audio; use kind="descriptions" if needed for audio transcripts).
Line 4150–4152: wire the transcript/caption URL as the track source for video accessibility.
Line 4265: add a real caption source for job output video previews or omit the track.
📍 Affects 1 file
apps/web/src/App.tsx#L3282-L3282 (this comment)
apps/web/src/App.tsx#L3300-L3300
apps/web/src/App.tsx#L3629-L3629
apps/web/src/App.tsx#L3788-L3788
apps/web/src/App.tsx#L3842-L3842
apps/web/src/App.tsx#L3897-L3897
apps/web/src/App.tsx#L3903-L3903
apps/web/src/App.tsx#L4150-L4152
apps/web/src/App.tsx#L4265-L4265
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/App.tsx` at line 3282, Remove or properly wire all empty caption
track elements across apps/web/src/App.tsx that lack src attributes, as they do
not provide functional captions. At apps/web/src/App.tsx line 3282,
conditionally render the track element only when a subtitle source URL exists
for the output asset. At line 3300, add a real caption source URL to the track
or remove it entirely. At line 3629, add a real caption source URL to the track
or remove it. At line 3788, wire a real subtitle source URL to the track. At
line 3842, wire the generated subtitle asset URL as the track src attribute. At
line 3897, add a real caption source URL or remove the track. At line 3903,
remove the track element entirely since captions do not apply to audio (use
kind="descriptions" if audio transcripts are needed instead). At lines
4150-4152, wire the transcript or caption URL as the track src attribute for
video accessibility. At line 4265, add a real caption source URL to the track or
omit it entirely.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟠 Major | ⚡ Quick win
<dialog open> is non-modal and can desynchronize close state.
At Line 15, using open directly does not provide native modal behavior (focus trap/top layer), and native close/cancel events are not wired back to onClose. Since apps/web/src/App.tsx:5526-5530 controls visibility via showSettings, this can leave parent/UI state out of sync.
Suggested fix
import { useState } from "react";
+import { useEffect, useRef, useState } from "react";
@@
export function SettingsModal({ onClose }: Props) {
+ const dialogRef = useRef<HTMLDialogElement>(null);
@@
+ useEffect(() => {+ const dialog = dialogRef.current;+ if (!dialog) return;+ if (!dialog.open) dialog.showModal();+ return () => {+ if (dialog.open) dialog.close();+ };+ }, []);+
return (
- <dialog className="modal-backdrop" open aria-modal="true">+ <dialog+ ref={dialogRef}+ className="modal-backdrop"+ onCancel={(e) => {+ e.preventDefault();+ onClose();+ }}+ onClose={onClose}+ >
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/components/SettingsModal.tsx` at line 15, The dialog element at
line 15 in SettingsModal.tsx uses the open attribute which does not provide
native modal behavior (focus trap and top layer). To fix this, obtain a ref to
the dialog element and replace the open attribute with a useEffect hook that
calls the dialog's showModal() method when the component should be visible and
the close() method when it should be hidden. Additionally, wire up the dialog's
native close and cancel events to trigger the onClose callback, ensuring the
parent's showSettings state stays in sync with the actual dialog state and
preventing desynchronization between the dialog's internal state and the parent
component's state management.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash# Read-only verification:# 1) Confirm web entrypoint defines `#root`.# 2) Confirm current mount call has no null guard.# 3) Enumerate other createRoot usages for consistency.set -euo pipefail
echo"== index.html root container =="
rg -n '<div id="root"></div>' apps/web/index.html
echoecho"== createRoot callsites =="
rg -n 'createRoot\s*\(' apps/web/src
echoecho"== getElementById root usage in main =="
rg -n 'getElementById\("root"\)' apps/web/src/main.tsx
Repository: Prekzursil/Reframe
Length of output: 339
Guard #root before createRoot to ensure type safety and handle missing element gracefully.
document.getElementById("root") returns HTMLElement | null, but ReactDOM.createRoot requires a non-null Element | DocumentFragment. Although #root exists in index.html, the unguarded call violates the API contract and could fail at runtime if the contract breaks. Add an explicit guard before mounting.
Suggested fix
-ReactDOM.createRoot(document.getElementById("root")).render(+const rootElement = document.getElementById("root");+if (!rootElement) {+ throw new Error('Missing root mount element: `#root`');+}++ReactDOM.createRoot(rootElement).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
📝 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.
thrownewError('Missing root mount element: `#root`');
}
ReactDOM.createRoot(rootElement).render(
<React.StrictMode>
<App/>
</React.StrictMode>
);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/main.tsx` at line 6, The call to ReactDOM.createRoot with
document.getElementById("root") lacks a guard for null, which violates the API
contract since getElementById returns HTMLElement | null while createRoot
requires a non-null Element or DocumentFragment. Add an explicit null check
before passing the result of document.getElementById("root") to
ReactDOM.createRoot, and handle the case where the root element is missing
(either by throwing an informative error or logging a warning) to ensure type
safety and graceful failure.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟠 Major | ⚡ Quick win
getattr(..., obj.get(...)) is unsafe here and breaks object-based whispercpp payloads.
On Line 43/44/45 and Line 54/55/56/74, the fallback obj.get(...) is evaluated before getattr(...) runs. For object-like tokens/segments without .get, this raises immediately and can force fallback stub behavior.
✅ Suggested fix
+def _field(obj: Any, key: str, default: Any = None) -> Any:+ if isinstance(obj, dict):+ return obj.get(key, default)+ return getattr(obj, key, default)
@@
def _parse_token_word(tok: Any) -> Word | None:
try:
- start = float(getattr(tok, "t_start", tok.get("t_start")))- end = float(getattr(tok, "t_end", tok.get("t_end")))- text = str(getattr(tok, "text", tok.get("text"))).strip()+ start = float(_field(tok, "t_start"))+ end = float(_field(tok, "t_end"))+ text = str(_field(tok, "text", "")).strip()
@@
def _parse_segment_word(seg: Any) -> Word | None:
try:
- start = float(getattr(seg, "t_start", seg.get("t_start")))- end = float(getattr(seg, "t_end", seg.get("t_end")))- text = str(getattr(seg, "text", seg.get("text"))).strip()+ start = float(_field(seg, "t_start"))+ end = float(_field(seg, "t_end"))+ text = str(_field(seg, "text", "")).strip()
@@
def _join_segment_text(segments: Iterable[Any]) -> Optional[str]:
try:
- return " ".join(getattr(s, "text", s.get("text", "")).strip() for s in segments) or None+ return " ".join(str(_field(s, "text", "")).strip() for s in segments) or None
Also applies to: 72-75
🧰 Tools🪛 Ruff (0.15.15)
[warning] 46-46: Do not catch blind exception: Exception
(BLE001)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/media-core/src/media_core/transcribe/backends/whisper_cpp.py` around
lines 41 - 56, The issue is that in the _parse_token_word and
_parse_segment_word functions, the fallback argument tok.get(...) and
seg.get(...) are evaluated eagerly before getattr() is called, which fails
immediately for object-like tokens that don't have a .get() method. Fix this by
using conditional logic that only evaluates the fallback when needed—either
check if the attribute exists first using hasattr() before deciding which
approach to use, or restructure the code to attempt attribute access first and
catch AttributeError before falling back to dictionary-style access via .get().
Apply this fix to all three affected locations: lines 43-45 in
_parse_token_word, lines 54-56 in _parse_segment_word, and lines 72-75 (also
mentioned in "Also applies to").
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
segments is consumed before text_field is built for one-shot iterables.
Line 87 iterates segments, then Line 90 iterates it again. If segments is a generator/iterator, text_field becomes empty unexpectedly.
✅ Suggested fix
def normalize_whisper_cpp(
@@
- words: list[Word] = []- for seg in segments:+ segments_list = list(segments)+ words: list[Word] = []+ for seg in segments_list:
words.extend(_segment_words(seg))
- text_field = _join_segment_text(segments)+ text_field = _join_segment_text(segments_list)
📝 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.
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/media-core/src/media_core/transcribe/backends/whisper_cpp.py` around
lines 87 - 90, The `segments` parameter is being iterated twice - once in the
for loop that calls `_segment_words(seg)` and again when passed to
`_join_segment_text(segments)`. If `segments` is a generator or one-shot
iterator, it will be exhausted after the first iteration, causing
`_join_segment_text` to receive an empty iterable. Convert `segments` to a list
before the for loop to ensure it can be safely iterated multiple times by both
the loop and the subsequent `_join_segment_text` call.
… + ruff clean
Captures the all-fix workflow's progress before it was halted (it conflicted with
the local ruff PostToolUse hook on every concurrent edit). All changed Python is
ruff-clean (E402 sys.path-bootstrap noqa, E741 noqa, F841 fixed) and compiles.
Pylint-zero / coverage-100 NOT yet complete — to be finished once the hook/workflow
conflict is resolved.
Keep Word(...) construction inside guarded parsing path.
On Line 98, Word(...) is outside the try, so validation failures (for malformed-but-coercible timestamps) can bubble out and fail the whole transcription normalize path instead of skipping just the bad word.
Suggested fix
def _parse_word(w: _WordLike | dict[str, Any]) -> Optional[Word]:
"""Parse a single word payload into a Word, or None when malformed."""
try:
if isinstance(w, dict):
start = float(w.get("start"))
end = float(w.get("end"))
text = str(w.get("word", "")).strip()
prob = w.get("probability")
else:
start = float(getattr(w, "start"))
end = float(getattr(w, "end"))
text = str(getattr(w, "word", "")).strip()
prob = getattr(w, "probability", None)
+ return Word(text=text, start=start, end=end, probability=_coerce_probability(prob))
except Exception as exc: # pragma: no cover - defensive # pylint: disable=broad-exception-caught
logger.debug("Skipping malformed word payload: %s (%s)", w, exc)
return None
- return Word(text=text, start=start, end=end, probability=_coerce_probability(prob))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/media-core/src/media_core/transcribe/backends/faster_whisper.py`
around lines 82 - 99, The Word(...) constructor call on the return statement is
located outside the try-except block in the _parse_word function, which means
validation failures during Word construction will bubble up and crash the
transcription process instead of being gracefully handled. Move the return
statement containing the Word(...) construction inside the try block so that any
exceptions raised during Word object creation are also caught and result in
returning None, allowing the transcription to continue by skipping just that
malformed word entry.
Enforce media-root containment in local write paths.
At Line 89 and Line 102, rel_dir/filename are joined and written directly. Inputs containing .. can escape media_root and write outside the storage root. Apply the same containment approach used in resolve_local_path before directory creation/write operations.
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/app/storage.py` around lines 84 - 107, The write_bytes and
write_file methods lack path containment validation, allowing relative path
traversal via filenames or rel_dir parameters containing ".." to escape the
media_root directory. Before calling mkdir on target_dir in both methods, add
validation to ensure the resolved target_path remains within media_root
boundaries, applying the same containment approach used in resolve_local_path.
This prevents path traversal attacks by validating that the final resolved path
is still a child of the media_root before performing any write operations.
Sync SCIM group identities when displayName changes.
The rename branch updates RoleMapping.external_value but does not update matching ScimIdentity.group_name. This can leave stale identities and cause downstream mismatches (e.g., deactivation lookup by group name during delete).
Suggested fix
def _apply_scim_group_operation(
session: Session, org_id: UUID, mapping: RoleMapping, operation: dict[str, Any]
) -> None:
path = str(operation.get("path") or "").strip().lower()
value = operation.get("value")
if path in {"displayname", "displayName".lower()}:
+ old_name = mapping.external_value
display_name = (str(value or "")).strip()
- if display_name:+ if display_name:
mapping.external_value = display_name
+ if display_name != old_name:+ identities = session.exec(+ select(ScimIdentity).where(+ (ScimIdentity.org_id == org_id)+ & (ScimIdentity.provider == "okta")+ & (ScimIdentity.resource_type == "group")+ & (ScimIdentity.group_name == old_name)+ )+ ).all()+ for identity in identities:+ identity.group_name = display_name+ identity.updated_at = _now()+ session.add(identity)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/app/identity_api.py` around lines 1083 - 1092, When the displayName
path is processed and mapping.external_value is updated with the new
display_name value, also synchronize all related ScimIdentity records by
updating their group_name field to match the new display_name. Query the
ScimIdentity records associated with this mapping using the session and org_id,
then update their group_name to keep them in sync with the
RoleMapping.external_value change to prevent downstream mismatches during
operations like deactivation lookup.
Do not silently coerce invalid default_role on update.
Line 220–221 converts unknown roles to "viewer", while the create path can return 422. This makes update behavior inconsistent and can hide bad client payloads.
Suggested fix
- role = (payload.default_role or "viewer").strip().lower()- connection.default_role = role if role in ROLE_VALUES else "viewer"+ role = (payload.default_role or "viewer").strip().lower()+ connection.default_role = role
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/app/identity_api.py` around lines 220 - 221, The code at lines
220-221 silently converts invalid default_role values to "viewer" instead of
raising a validation error, which is inconsistent with the create path that
returns a 422 error for invalid roles. Remove the conditional coercion logic and
instead validate that the normalized role is in ROLE_VALUES, raising an
appropriate validation error (matching the behavior of the create endpoint) if
it is invalid. Only assign the valid role to connection.default_role after
successful validation.
Materialize segments once before dual consumption.
On Line 88-91, segments is consumed once to build words and then reused for text_field; generator inputs can yield empty/partial text unexpectedly on second pass.
Suggested fix
def normalize_whisper_cpp(
@@
- words: list[Word] = []- for seg in segments:+ segments_list = list(segments)+ words: list[Word] = []+ for seg in segments_list:
words.extend(_segment_words(seg))
- text_field = _join_segment_text(segments)+ text_field = _join_segment_text(segments_list)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/media-core/src/media_core/transcribe/backends/whisper_cpp.py` around
lines 87 - 92, The variable `segments` is being consumed twice: first in the
loop that calls `_segment_words(seg)` and then again in the call to
`_join_segment_text(segments)`. If `segments` is a generator, it will be
exhausted after the first iteration, causing the second call to receive an empty
generator. Materialize `segments` by converting it to a list immediately before
the loop so that both `_segment_words()` and `_join_segment_text()` can safely
consume the complete data.
42-47: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win
Avoid eager .get(...) fallback evaluation in object/dict dual-access parsing.
Line 44/45/46 (and similarly Line 55/56/57, Line 75) still evaluate .get(...) eagerly inside getattr(...). For object-like payloads without .get, parsing fails and words/text are dropped.
Suggested fix
+def _field(obj: Any, key: str, default: Any = None) -> Any:+ if isinstance(obj, dict):+ return obj.get(key, default)+ return getattr(obj, key, default)+
def _parse_token_word(tok: Any) -> Word | None:
try:
- start = float(getattr(tok, "t_start", tok.get("t_start")))- end = float(getattr(tok, "t_end", tok.get("t_end")))- text = str(getattr(tok, "text", tok.get("text"))).strip()+ start = float(_field(tok, "t_start"))+ end = float(_field(tok, "t_end"))+ text = str(_field(tok, "text", "")).strip()
@@
def _parse_segment_word(seg: Any) -> Word | None:
try:
- start = float(getattr(seg, "t_start", seg.get("t_start")))- end = float(getattr(seg, "t_end", seg.get("t_end")))- text = str(getattr(seg, "text", seg.get("text"))).strip()+ start = float(_field(seg, "t_start"))+ end = float(_field(seg, "t_end"))+ text = str(_field(seg, "text", "")).strip()
@@
def _join_segment_text(segments: Iterable[Any]) -> Optional[str]:
try:
- return " ".join(getattr(s, "text", s.get("text", "")).strip() for s in segments) or None+ return " ".join(str(_field(s, "text", "")).strip() for s in segments) or None
Also applies to: 53-58, 73-76
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/media-core/src/media_core/transcribe/backends/whisper_cpp.py` around
lines 42 - 47, The _parse_token_word function uses eager evaluation of
`.get(...)` inside the `getattr(...)` calls on lines 44-46 for start, end, and
text attributes. This causes failures for object-like payloads that don't have a
`.get()` method, resulting in dropped words. Replace the pattern that calls
`getattr(tok, "attribute_name", tok.get("attribute_name"))` with a safe
dual-access approach: first try to get the attribute from the object, and only
if that fails and the object is dict-like, then try the `.get()` method as a
fallback. This same pattern issue appears at other locations in the same file
(around lines 53-58 and 73-76) and should be fixed using the same approach
throughout.
🧹 Nitpick comments (2)
apps/api/tests/test_api_helpers_coverage2.py (1)
206-206: 💤 Low value
Remove redundant import.
Path is already imported at the module level (line 6), so this local import is unnecessary.
♻️ Proposed fix
- from pathlib import Path-
target_dir = Path(media_root) / "out"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/tests/test_api_helpers_coverage2.py` at line 206, The import
statement for Path is duplicated in the file. The Path class is already imported
at the module level (line 6), so the redundant local import of Path from pathlib
at line 206 should be removed entirely. Simply delete this duplicate import
statement to clean up the code and avoid unnecessary redundancy.
apps/api/tests/test_identity_api_coverage.py (1)
28-34: 💤 Low value
Consider adding a None check for better test diagnostics.
If the organization doesn't exist, session.get returns None and line 32 will raise AttributeError: 'NoneType' object has no attribute 'seat_limit'. While current usage is safe (always called with freshly created orgs), adding a None check would provide clearer error messages if the helper is misused in future tests.
♻️ Proposed fix
def _set_seat_limit(org_id: str, seat_limit: int) -> None:
engine = get_engine()
with Session(engine) as session:
org = session.get(Organization, UUID(org_id))
+ if org is None:+ raise ValueError(f"Organization {org_id} not found")
org.seat_limit = seat_limit
session.add(org)
session.commit()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/tests/test_identity_api_coverage.py` around lines 28 - 34, In the
_set_seat_limit function, add a None check after the session.get call that
retrieves the Organization object. If the org variable is None (meaning the
organization doesn't exist), raise an informative error with a clear message
indicating that the organization with the provided org_id was not found. This
will prevent the AttributeError that would occur on the next line when trying to
access org.seat_limit, providing better debugging information if the helper is
misused in future tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/api/app/api.py`:
- Around line 2312-2320: The _bundle_resolve_asset_path function joins
ctx.media_root with URI-derived path segments without validating that the
resulting path stays within the media root directory, allowing path traversal
attacks via ".." sequences to escape the intended directory. After constructing
the final path by joining ctx.media_root with uri_path, resolve both paths to
their absolute forms and verify that the resolved asset path is contained within
the resolved media root directory. If the asset path escapes the media root
boundary, raise an appropriate exception to reject the unsafe path. This
containment check must be performed before the path is returned and subsequently
used for file operations.
In `@apps/api/app/identity_api.py`:
- Line 718: The parameter `filter` is shadowing the Python builtin and
triggering the A002 ruff error. Rename the parameter from `filter` to `filter_`
in the function signature, then add `alias="filter"` as an argument to the
Query() call to maintain backward compatibility with the API contract. Finally,
update all usages of the `filter` variable within the function body (at lines
728 and 729) to use `filter_` instead.
In `@apps/api/tests/test_api_routes_sweep.py`:
- Around line 309-346: The test creates three pending upload entries in the
global _pending_uploads dictionary (sess-ok, sess-exp, and sess-mm) but only
removes sess-mm at the end. To maintain proper test isolation and prevent state
leakage to other tests, remove all three session entries after the test
completes. Add cleanup calls to pop both sess-ok and sess-exp from
api_module._pending_uploads in addition to the existing cleanup of sess-mm.
In `@apps/api/tests/test_auth_identity_tail_coverage.py`:
- Around line 129-133: The membership creation setup calls using client.post for
creating members are not being asserted for success, which allows the test to
pass even if the setup fails by accidentally testing a different unauthorized
path. Add assertions to verify that the client.post responses for membership
creation return successful status codes (e.g., assert response.status_code in
[200, 201]) at both the initial member creation and the second member creation
location to ensure the test is validating the intended authorization path.
In `@apps/api/tests/test_small_modules_coverage.py`:
- Around line 573-580: The test function
test_setup_logging_returns_early_when_already_configured sets the
_reframe_configured attribute on the logger but never restores it, causing the
modified state to persist across test runs and pollute the global logger state
for subsequent tests. Save the original state of the logger's
_reframe_configured attribute (or check if it exists) before modifying it, then
restore it to its original state after the test completes using a try/finally
block or pytest fixture with cleanup. This ensures each test starts with a clean
logger state independent of test execution order.
In `@packages/media-core/src/media_core/diarize/__init__.py`:
- Around line 321-324: The current code in the embedding normalization section
only handles 2D tensors with the ndim == 2 check, but SpeechBrain's encode_batch
method returns 3D tensors with shape [1, 1, N]. This causes
functional.normalize() to keep the tensor at 3D, which then breaks
functional.cosine_similarity() and its subsequent .item() call. Replace the ndim
== 2 check with a .squeeze() call that removes all dimensions of size 1,
handling both 2D [1, N] and 3D [1, 1, N] cases and reducing the embedding to 1D
before passing it to functional.normalize(). This ensures the normalized
embedding is always 1D, allowing functional.cosine_similarity() to return a
scalar that .item() can properly process.
In `@packages/media-core/src/media_core/segment/shorts.py`:
- Around line 109-114: The _stable_scores function in
packages/media-core/src/media_core/segment/shorts.py (lines 109-114) corrupts
the DP objective by modifying raw scores with time/index offsets to break ties.
Remove the score modification logic and instead implement deterministic
tie-breaking in the control flow by using >= comparisons during DP and
backtracking operations. This same issue also affects the code at lines 134-141
and 156-160 in the same file, so apply the same fix approach there as well: stop
distorting scores and move tie-breaking logic into the comparison operators used
during optimization.
---
Outside diff comments:
In `@apps/api/app/identity_api.py`:
- Around line 1083-1092: When the displayName path is processed and
mapping.external_value is updated with the new display_name value, also
synchronize all related ScimIdentity records by updating their group_name field
to match the new display_name. Query the ScimIdentity records associated with
this mapping using the session and org_id, then update their group_name to keep
them in sync with the RoleMapping.external_value change to prevent downstream
mismatches during operations like deactivation lookup.
- Around line 220-221: The code at lines 220-221 silently converts invalid
default_role values to "viewer" instead of raising a validation error, which is
inconsistent with the create path that returns a 422 error for invalid roles.
Remove the conditional coercion logic and instead validate that the normalized
role is in ROLE_VALUES, raising an appropriate validation error (matching the
behavior of the create endpoint) if it is invalid. Only assign the valid role to
connection.default_role after successful validation.
In `@apps/api/app/storage.py`:
- Around line 84-107: The write_bytes and write_file methods lack path
containment validation, allowing relative path traversal via filenames or
rel_dir parameters containing ".." to escape the media_root directory. Before
calling mkdir on target_dir in both methods, add validation to ensure the
resolved target_path remains within media_root boundaries, applying the same
containment approach used in resolve_local_path. This prevents path traversal
attacks by validating that the final resolved path is still a child of the
media_root before performing any write operations.
In `@packages/media-core/src/media_core/transcribe/backends/faster_whisper.py`:
- Around line 82-99: The Word(...) constructor call on the return statement is
located outside the try-except block in the _parse_word function, which means
validation failures during Word construction will bubble up and crash the
transcription process instead of being gracefully handled. Move the return
statement containing the Word(...) construction inside the try block so that any
exceptions raised during Word object creation are also caught and result in
returning None, allowing the transcription to continue by skipping just that
malformed word entry.
---
Duplicate comments:
In `@packages/media-core/src/media_core/transcribe/backends/whisper_cpp.py`:
- Around line 87-92: The variable `segments` is being consumed twice: first in
the loop that calls `_segment_words(seg)` and then again in the call to
`_join_segment_text(segments)`. If `segments` is a generator, it will be
exhausted after the first iteration, causing the second call to receive an empty
generator. Materialize `segments` by converting it to a list immediately before
the loop so that both `_segment_words()` and `_join_segment_text()` can safely
consume the complete data.
- Around line 42-47: The _parse_token_word function uses eager evaluation of
`.get(...)` inside the `getattr(...)` calls on lines 44-46 for start, end, and
text attributes. This causes failures for object-like payloads that don't have a
`.get()` method, resulting in dropped words. Replace the pattern that calls
`getattr(tok, "attribute_name", tok.get("attribute_name"))` with a safe
dual-access approach: first try to get the attribute from the object, and only
if that fails and the object is dict-like, then try the `.get()` method as a
fallback. This same pattern issue appears at other locations in the same file
(around lines 53-58 and 73-76) and should be fixed using the same approach
throughout.
---
Nitpick comments:
In `@apps/api/tests/test_api_helpers_coverage2.py`:
- Line 206: The import statement for Path is duplicated in the file. The Path
class is already imported at the module level (line 6), so the redundant local
import of Path from pathlib at line 206 should be removed entirely. Simply
delete this duplicate import statement to clean up the code and avoid
unnecessary redundancy.
In `@apps/api/tests/test_identity_api_coverage.py`:
- Around line 28-34: In the _set_seat_limit function, add a None check after the
session.get call that retrieves the Organization object. If the org variable is
None (meaning the organization doesn't exist), raise an informative error with a
clear message indicating that the organization with the provided org_id was not
found. This will prevent the AttributeError that would occur on the next line
when trying to access org.seat_limit, providing better debugging information if
the helper is misused in future tests.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
Push a commit to this branch (recommended)
Create a new PR with the fixes
ℹ️ Review info⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d65e324c-070b-4502-a66d-8ffce3bef03d
📥 Commits
Reviewing files that changed from the base of the PR and between b958f78 and 8b9e74b.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟠 Major | ⚡ Quick win
Constrain bundle asset paths to the media root before reading files.
On Line 2319, _bundle_resolve_asset_path joins ctx.media_root with URI-derived path segments without a containment check. A ..-style URI can escape the media root and then be read on Line 2341 during bundle creation.
🔧 Proposed fix
def _bundle_resolve_asset_path(ctx: _BundleContext, asset: MediaAsset) -> Path:
uri = asset.uri or ""
if is_remote_uri(uri):
return Path(uri)
uri_path = Path(uri.lstrip("/"))
if uri_path.parts and uri_path.parts[0] == "media":
uri_path = Path(*uri_path.parts[1:])
- return ctx.media_root / uri_path+ candidate = (ctx.media_root / uri_path).resolve(strict=False)+ try:+ candidate.relative_to(ctx.media_root.resolve())+ except ValueError as exc:+ raise ApiError(+ status_code=status.HTTP_403_FORBIDDEN,+ code=ErrorCode.PERMISSION_DENIED,+ message="Asset path escapes media root",+ details={"uri": uri},+ ) from exc+ return candidate
Also applies to: 2340-2345
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/app/api.py` around lines 2312 - 2320, The _bundle_resolve_asset_path
function joins ctx.media_root with URI-derived path segments without validating
that the resulting path stays within the media root directory, allowing path
traversal attacks via ".." sequences to escape the intended directory. After
constructing the final path by joining ctx.media_root with uri_path, resolve
both paths to their absolute forms and verify that the resolved asset path is
contained within the resolved media root directory. If the asset path escapes
the media root boundary, raise an appropriate exception to reject the unsafe
path. This containment check must be performed before the path is returned and
subsequently used for file operations.
Rename filter argument to filter_ with query alias to resolve A002 builtin shadowing.
The parameter filter at line 718 triggers the A002 ruff error (builtin shadowing). Rename to filter_ and add alias="filter" to the Query() call to maintain the API contract. Update the two usages in the function body (lines 728–729) to use filter_ instead.
- if filter and "userName eq" in filter:- needle = filter.split("userName eq", 1)[1].strip().strip('"').strip("'")+ if filter_ and "userName eq" in filter_:+ needle = filter_.split("userName eq", 1)[1].strip().strip('"').strip("'")
🧰 Tools🪛 Ruff (0.15.15)
[error] 718-718: Function argument filter is shadowing a Python builtin
(A002)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/app/identity_api.py` at line 718, The parameter `filter` is
shadowing the Python builtin and triggering the A002 ruff error. Rename the
parameter from `filter` to `filter_` in the function signature, then add
`alias="filter"` as an argument to the Query() call to maintain backward
compatibility with the API contract. Finally, update all usages of the `filter`
variable within the function body (at lines 728 and 729) to use `filter_`
instead.
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/tests/test_api_routes_sweep.py` around lines 309 - 346, The test
creates three pending upload entries in the global _pending_uploads dictionary
(sess-ok, sess-exp, and sess-mm) but only removes sess-mm at the end. To
maintain proper test isolation and prevent state leakage to other tests, remove
all three session entries after the test completes. Add cleanup calls to pop
both sess-ok and sess-exp from api_module._pending_uploads in addition to the
existing cleanup of sess-mm.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
Assert membership setup responses to prevent false-positive auth-path tests.
Both setup calls proceed without checking success. If membership creation fails, the test can still pass via a different unauthorized path than the one intended.
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/tests/test_auth_identity_tail_coverage.py` around lines 129 - 133,
The membership creation setup calls using client.post for creating members are
not being asserted for success, which allows the test to pass even if the setup
fails by accidentally testing a different unauthorized path. Add assertions to
verify that the client.post responses for membership creation return successful
status codes (e.g., assert response.status_code in [200, 201]) at both the
initial member creation and the second member creation location to ensure the
test is validating the intended authorization path.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
Restore logger state in this test to avoid cross-test pollution.
Line 575 forces _reframe_configured = True and never restores prior state. That can leak global logger state into later tests and make outcomes order-dependent.
Suggested fix
def test_setup_logging_returns_early_when_already_configured():
logger = logging.getLogger("reframe")
- setattr(logger, "_reframe_configured", True)- before = list(logger.handlers)- logging_config.setup_logging(log_format="json")- # No new handler added because it short-circuits.- assert logger.handlers == before+ prev_configured = hasattr(logger, "_reframe_configured")+ prev_value = getattr(logger, "_reframe_configured", None)+ before = list(logger.handlers)+ try:+ logger._reframe_configured = True+ logging_config.setup_logging(log_format="json")+ # No new handler added because it short-circuits.+ assert logger.handlers == before+ finally:+ if prev_configured:+ logger._reframe_configured = prev_value+ elif hasattr(logger, "_reframe_configured"):+ delattr(logger, "_reframe_configured")
📝 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.
[warning] 575-575: Do not call setattr with a constant attribute value. It is not any safer than normal property access.
Replace setattr with assignment
(B010)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/tests/test_small_modules_coverage.py` around lines 573 - 580, The
test function test_setup_logging_returns_early_when_already_configured sets the
_reframe_configured attribute on the logger but never restores it, causing the
modified state to persist across test runs and pollute the global logger state
for subsequent tests. Save the original state of the logger's
_reframe_configured attribute (or check if it exists) before modifying it, then
restore it to its original state after the test completes using a try/finally
block or pytest fixture with cleanup. This ensures each test starts with a clean
logger state independent of test execution order.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟠 Major
🧩 Analysis chain
🌐 Web query:
For speechbrain (SpeakerRecognition.encode_batch), what tensor shape is returned for a single audio segment, and what is the recommended way to reduce it to a 1D embedding vector for cosine similarity?
💡 Result:
When using SpeechBrain's encode_batch method (available in classes like SpeakerRecognition or EncoderClassifier), the returned tensor for a single audio segment (or a batch of size 1) typically has the shape [1, 1, N], where N is the embedding dimension (e.g., 192 for ECAPA-TDNN models) [1]. To reduce this to a 1D embedding vector of shape [N] for use in cosine similarity or other vector operations, the recommended approach is to use the.squeeze method [2][3]. Calling.squeeze on the [1, 1, N] tensor will remove the singleton dimensions, resulting in the desired [N] shape [2]. Example implementation: embeddings = classifier.encode_batch(signal) # Returns [4] embedding_1d = embeddings.squeeze # Returns
cd packages/media-core && head -n 330 src/media_core/diarize/__init__.py | tail -n +260
Repository: Prekzursil/Reframe
Length of output: 2436
Handle 3D embeddings from SpeechBrain's encode_batch method.
The current code at line 321 only checks for 2D embeddings, but SpeechBrain's encode_batch returns tensors with shape [1, 1, N] (3D) for single audio segments. When this 3D tensor is passed to functional.normalize(emb, dim=0), the result remains 3D, causing functional.cosine_similarity() at line 266 to return a non-scalar tensor. This makes the subsequent .item() call fail at runtime.
Use .squeeze() to reduce the embedding to 1D before normalization, handling both 2D and 3D cases:
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/media-core/src/media_core/diarize/__init__.py` around lines 321 -
324, The current code in the embedding normalization section only handles 2D
tensors with the ndim == 2 check, but SpeechBrain's encode_batch method returns
3D tensors with shape [1, 1, N]. This causes functional.normalize() to keep the
tensor at 3D, which then breaks functional.cosine_similarity() and its
subsequent .item() call. Replace the ndim == 2 check with a .squeeze() call that
removes all dimensions of size 1, handling both 2D [1, N] and 3D [1, 1, N] cases
and reducing the embedding to 1D before passing it to functional.normalize().
This ensures the normalized embedding is always 1D, allowing
functional.cosine_similarity() to return a scalar that .item() can properly
process.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Potential issue | 🟠 Major | ⚡ Quick win
Don’t modify real candidate scores just to break ties.
Line 112 subtracts time/index offsets from actual scores, which changes the DP objective and can flip valid near-equal selections. Keep raw scores for optimization and resolve ties in control flow (e.g., deterministic >= choice in DP/backtrack), not by score distortion.
Suggested fix
def _stable_scores(intervals: List[SegmentCandidate]) -> list[float]:
- """Compute tie-broken scores so selection is deterministic for equal scores."""- return [- float(item.score) - (float(item.start) * 1e-6) - (idx * 1e-9)- for idx, item in enumerate(intervals)- ]+ """Return raw scores; tie-breaking is handled by deterministic traversal."""+ return [float(item.score) for item in intervals]
- dp[i][k] = take if take > skip else skip+ dp[i][k] = take if take >= skip else skip
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/media-core/src/media_core/segment/shorts.py` around lines 109 - 114,
The _stable_scores function in
packages/media-core/src/media_core/segment/shorts.py (lines 109-114) corrupts
the DP objective by modifying raw scores with time/index offsets to break ties.
Remove the score modification logic and instead implement deterministic
tie-breaking in the control flow by using >= comparisons during DP and
backtracking operations. This same issue also affects the code at lines 134-141
and 156-160 in the same file, so apply the same fix approach there as well: stop
distorting scores and move tie-breaking logic into the comparison operators used
during optimization.
The reason will be displayed to describe this comment to others. Learn more.
2 issues found across 102 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="apps/api/app/api.py">
<violation number="1">
P0: Validate resolved bundle asset paths stay under `media_root` before reading files; without a containment check, `..` segments can traverse outside the media directory and include unintended files in the job bundle.</violation>
</file>
<file name="apps/api/app/identity_api.py">
<violation number="1" location="apps/api/app/identity_api.py:718">
P3: Avoid shadowing the Python builtin `filter` in this endpoint parameter; rename it to `filter_` and keep the public query key via `Query(alias="filter")`.</violation>
</file>
Note: This PR contains a large number of files. cubic only reviews up to 100 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
On a pro plan you can use ultrareview for larger PRs. Tip: Review your code locally with the cubic CLI to iterate faster.
The reason will be displayed to describe this comment to others. Learn more.
P3: Avoid shadowing the Python builtin filter in this endpoint parameter; rename it to filter_ and keep the public query key via Query(alias="filter").
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/api/app/identity_api.py, line 718:
<comment>Avoid shadowing the Python builtin `filter` in this endpoint parameter; rename it to `filter_` and keep the public query key via `Query(alias="filter")`.</comment>
<file context>
@@ -632,10 +715,13 @@ def okta_sso_callback(
session: SessionDep,
authorization: Annotated[str | None, Header(alias="Authorization")] = None,
- filter: Annotated[str | None, Query()] = None,
+ filter: Annotated[str | None, Query()] = None, # pylint: disable=redefined-builtin
) -> dict[str, Any]:
+ """List SCIM users for the token's org, optionally filtered by userName."""
</file context>
The module-level policy_limiters singleton accumulated hits across the
entire pytest session, keyed by testclient:/api/v1/assets/upload. On fast
CI runs many upload tests clustered within the 60s window and exhausted the
uploads limiter (30/60s), so later asset upload/download tests received
429 RATE_LIMITED instead of 201/400/413 (4 failures on CI, ordering/timing
dependent — not reproducible on the slower local run).
Add RateLimiter.reset() + reset_all_policy_limiters() and an autouse
conftest fixture that clears limiter state before each test. Test-only
isolation; no runtime behavior change.
Skipping CodeAnt AI review — this PR changes more than 100 files, which usually means a migration, codemod, or vendored drop. Line-level review on diffs this large produces duplicate findings on the same rewrite pattern and drowns out anything that actually matters.
If you still want a review, comment @codeant-ai : review. For better signal, consider splitting the PR into smaller chunks.
Resolves 24 advisories within existing semver ranges (package.json
unchanged). Closes all 4 criticals incl. the Vitest UI-server arbitrary
file read/exec (GHSA-5xrq-8626-4rwp) by bumping vitest 4.0->4.1.9.
Remaining 21 (6 low / 7 moderate / 8 high) require SemVer-major bumps
in the visual-testing/E2E dev stack (Applitools, Chromatic/Storybook,
BrowserStack, vite 7->8) and are handled separately. Web suite: 47/47.
…trix
The reusable scanner matrix declares and consumes CHROMATIC_PROJECT_TOKEN,
APPLITOOLS_API_KEY and CODEX_AUTH_JSON, and all three are set as repo
secrets, but the caller only forwarded SONAR/CODACY/CODECOV/SENTRY/DEEPSCAN.
The unforwarded secrets arrived empty, so Quality Secrets Preflight flagged
them missing. Forward the three so Preflight (and the visual/codex lanes)
receive them. Config-only; no secret values handled.
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/@emnapi/runtime@1.11.1. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm @google-cloud/compute is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/@google-cloud/compute@5.3.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm @google-cloud/compute is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/@google-cloud/compute@5.3.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm @google-cloud/compute is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/@google-cloud/compute@5.3.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm @zip.js/zip.js is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/@zip.js/zip.js@2.8.26. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm browserstack-node-sdk is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/browserstack-node-sdk@1.57.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
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
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.
User description
First remediation pass toward
quality-zeroSonar true-zero (329 → ?). Mechanical/pattern fixes across 29 files; complexity/compiler-dependent issues deferred to R2.Fixed: S8409 (FastAPI response_model dupes), S8410 (Annotated DI), S1192 (duplicate-literal constants), S6535/S4325/S6759/S7764 (TS escape/assertion/readonly/globalThis), S3358/S4624 (ternary/template), S4084 (media
<track>), S6853 (label a11y), + a cross-file fix (worker.pyprovider=dropped to matchscore_segments_llm).Deferred to R2 (need a compiler/tests to fix safely): S1874 (deprecated React.FormEvent/execCommand), remaining S4325, S3776 (cognitive complexity ×~29), S2004 (nesting).
CI + SonarCloud on this PR are the authoritative re-scan — I'll iterate R2 on whatever remains (and any regressions, e.g. the
main.tsx!-removal under strict TS).Summary by cubic
Quality-zero R1 expanded to lint-zero and coverage-100 across the monorepo, with safer parsing and a large test sweep to stabilize CI. Also forwarded CI visual/codex secrets and applied a non‑breaking web deps audit fix (no criticals) to keep gates green.
Refactors
ruff/pylint/eslintto zero; added docstrings, constants, and clearer errors across API modules.globalThis, fewer non‑null assertions, and readonly props.services/workerGroq client finalized with offline gating; API client types tightened; minor UI/a11y polish continues (native<dialog>, button contrast).Tests/CI
localStorage/sessionStoragemocks; bumpedvitestto 4.1.9 via audit fix to close criticals; web e2e and unit tests are stable.CHROMATIC_PROJECT_TOKEN,APPLITOOLS_API_KEY, andCODEX_AUTH_JSONto the quality‑zero workflow scanner matrix.Written for commit 8d3ce2e. Summary will update on new commits.
CodeAnt-AI Description
Improve auth, billing, uploads, and media tools across the app
What Changed
Impact
✅ Fewer failed sign-ins and invite acceptances✅ Clearer billing and SSO error handling✅ More reliable uploads and media exports💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.
Summary by CodeRabbit
Release Notes