fix(arena): olive-output scan routes and AbortError body-read handling - #79
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe PR adds secure Olive output scanning, opaque-ID listing and download routes, and expanded Arena upstream error handling. It also adds path, filesystem, response, middleware, disconnect, and property-based tests, updates specifications, and adjusts dependency versions. ChangesOlive output security and route handling
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 8✅ Passed checks (8 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
Warning Review ran into problems🔥 ProblemsLinked repositories: Public OSS repositories can only analyze public repositories installed in this organization. Analyzed Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Sorry @tonythethompson, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
PR Summary by QodoArena: secure Olive-output list/download routes + AbortError-safe proxy reads
AI Description
Diagram
High-Level Assessment
Files changed (10)
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5975bbaaad
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
This PR hardens the Arena “Olive outputs” workflow by adding server-side scanning + opaque ID download endpoints, and improves cloud-inference proxy behavior when upstream body reads abort (timeouts/client disconnect).
Changes:
- Add a server-only Olive output scanner/registry that lists artifacts from server-owned roots and resolves opaque IDs for sandboxed downloads.
- Add new Arena routes for listing/download, reject path-like query params with empty bodies, and stream downloads with validation.
- Improve cloud proxy AbortError handling (rethrow aborts from
text()/json()and avoid writing after disconnect).
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/server/services/playground/oliveOutputScan.ts |
Implements server-side scan + opaque ID registry + download revalidation. |
src/server/routes/arena.ts |
Adds olive-output list/download routes and improves cloud-inference abort/disconnect handling. |
src/server/routes/arenaOliveOutputs.test.ts |
Adds route-level tests for list/download behavior and abort regressions. |
src/server/routes/arena.test.ts |
Minor import cleanup. |
src/lib/arenaOliveOutputs.ts |
Adds shared types/helpers for Olive output roots/sandbox checks. |
src/lib/__tests__/arenaOliveOutputs.test.ts |
Unit tests for the new helper functions. |
.kiro/specs/playground-tab/* |
Updates spec docs to reflect the new rejection behavior and task completion status. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Code Review by Qodo
Context used✅ Compliance rules (platform):
170 rules✅ Skills:
|
Greptile SummaryThis PR completes the Olive output scan routes (list + download) for the Arena playground tab, and hardens the cloud-inference proxy's body-read abort handling. All three findings flagged in prior review threads have been addressed:
Confidence Score: 5/5Safe to merge. The new scan and download routes have defense-in-depth path containment, the cloud proxy abort handling is correct, and all three previously flagged defects are resolved. The olive-output routes resolve symlinks before registering IDs and again before streaming, so traversal escapes are blocked at two independent points. The cloud-inference proxy now correctly propagates both AbortError and UpstreamBodyTooLargeError to the outer catch, and client-disconnect checks bracket every body read. No new logic defects were found. Files Needing Attention: No files require special attention. The two P2 observations (loose PBT status assertion in arenaOliveOutputs.test.ts and no explicit res.off cleanup in the download error path) are both harmless at runtime.
|
| Filename | Overview |
|---|---|
| src/server/routes/arena.ts | Cloud inference AbortError and body-size fixes; new olive-output list/download routes with correct 400/403 gating and Content-Length omission. Previous review concerns (stale Content-Length header, BodyTooLarge unreachable in outer catch, redundant ternary) all resolved. |
| src/server/services/playground/oliveOutputScan.ts | New server-only scan module: iterative DFS with depth/visit/entry caps, realpathSync containment at walk time, opaque SHA-256 ID registry cleared and rebuilt on each list, revalidated on each download. Defense-in-depth looks solid. |
| src/lib/arenaOliveOutputs.ts | Pure-logic path helpers (resolveOliveOutputRoots, isPathInsideRoots, hasAllowedOliveOutputExtension) with Windows/UNC prefix preservation; well-tested including edge cases. |
| src/server/services/arena/ssrfGuard.ts | Adds UpstreamBodyTooLargeError and sized readBody helper with abort-signal support. Redirect refusal and IP-blocking logic unchanged. |
| src/server/routes/arenaOliveOutputs.test.ts | Comprehensive route tests covering list/download happy paths, symlink escape, zero-byte rejection, Content-Disposition sanitization, and fast-check PBT for Properties 20/20b; disconnect-during-json-read regression test added. |
| src/lib/tests/arenaOliveOutputs.test.ts | Unit tests for path helpers: dedup, Windows/UNC prefix preservation, root containment. All cases look well-exercised. |
| package.json | Adds fast-check devDependency; downgrades @openai/codex-sdk 0.146 to 0.145, @playwright/test 1.62.1 to 1.61.1, @types/react 19.2.18 to 19.2.17, @types/react-dom 19.2.4 to 19.2.3 — looks like a sync revert of unrelated bumps. |
| src/server/routes/arena.test.ts | Existing cloud-inference tests retain coverage; UpstreamBodyTooLargeError now importable from ssrfGuard mock, no regressions. |
Reviews (10): Last reviewed commit: "test(arena): make Content-Disposition ba..." | Re-trigger Greptile
There was a problem hiding this comment.
Actionable comments posted: 15
🤖 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 @.kiro/specs/playground-tab/tasks.md:
- Around line 341-348: The Task 19.5 criteria for Properties 20 and 20b must
align with the download handler’s finalized status-code contract. After
reviewing the resolver and oliveOutputScan.ts behavior, either constrain the
implementation to return only the documented 403/400 responses or update the
task and Property 20 assertions to explicitly permit 404; ensure the fast-check
tests validate the complete actual status-code set before marking the task
complete.
In `@src/lib/__tests__/arenaOliveOutputs.test.ts`:
- Around line 10-34: Add tests for resolveOliveOutputRoots covering a non-empty
relative cacheDir resolved against cwd, alongside outputDir, and a Windows-style
C:\... cacheDir/outputDir/cwd/homedir combination. Assert the expected
normalized absolute roots and deduplication behavior so resolvePath and
resolveOliveOutputRoots handle both path-base asymmetry and drive-letter paths.
In `@src/lib/arenaOliveOutputs.ts`:
- Around line 43-68: Update resolveOliveOutputRoots so non-empty relative
cacheDir values are resolved against cwd, matching the existing outputDir
behavior; preserve the homedir-based fallback for an empty cacheDir. Add a test
covering a relative cacheDir and assert it resolves beneath the configured cwd.
- Around line 6-16: Update resolvePath to preserve Windows drive-letter and UNC
roots instead of converting them to slash-prefixed paths or duplicating the
drive when combining with a base; resolve relative OLIVE_CACHE_DIR values
against cwd before invoking the helper in oliveOutputScan.ts. Keep the
implementation browser-safe and add coverage for drive-letter, UNC, and
relative-path resolution, including the existing absolute and dot-segment
behavior.
In `@src/server/routes/arena.test.ts`:
- Around line 204-208: Update the timeout assertion in the test loop around the
exact-preservation cases to compare body.error with the complete expected
timeout message, including the expected millisecond value, rather than using a
substring check. Preserve the existing expectedMs test data and ensure values
such as 1_001 cannot match larger incorrect numbers.
In `@src/server/routes/arena.ts`:
- Around line 214-216: In the error branch of the arena route, simplify the
emptyReject call to pass resolved.status directly instead of using the
tautological ternary. Preserve the existing !resolved.ok condition and response
behavior.
- Around line 28-37: Update armCloudAbort to use a single setTimeout with the
clamped ms delay, invoke abort when it fires, and return the timeout handle.
Ensure the corresponding cleanup in the caller’s finally block uses clearTimeout
rather than clearInterval, while preserving the existing abort behavior.
- Around line 225-232: Update the stream error handler in the arena route’s
createReadStream flow to remove the previously set Content-Length header before
calling emptyReject(res, 404) when headers have not been sent. Preserve the
existing response destruction behavior after headers are sent.
In `@src/server/routes/arenaOliveOutputs.test.ts`:
- Around line 139-140: Extend the GET /api/arena/olive-outputs tests with five
fast-check property tests covering the Olive-output security contract: rejected
query keys return an empty 400 response, unregistered opaque IDs return 400, and
generated basenames produce Content-Disposition values without raw control
characters, quotes, or backslashes. Use the existing route test setup and mark
Task 19.5 complete only after all five properties are implemented.
- Around line 143-153: Strengthen the no-filesystem-path assertion in the
response-body checks around the `body` object: inspect the serialized response
across `roots`, `entries`, and `recent`, asserting that filesystem paths such as
`tmpRoot` are absent from every field and that no unexpected
`absolutePath`-style data is present. Preserve the existing entry ID and
recent-count assertions.
- Around line 186-218: Add coverage in the olive-output download tests for
response headers: use a fixture with a non-ASCII or quote-bearing filename, then
assert the expected Content-Type and sanitized Content-Disposition, including
its ASCII fallback and filename* value. Also add requests that exercise
resolveOliveOutputForDownload’s disallowed-extension and out-of-root cases,
asserting both return status 403 and the route’s expected empty-body behavior.
- Around line 302-370: Strengthen the disconnect test around the request
callback so it actually records whether any response bytes or timeout/error
payload are received before the client is destroyed, and assert that none were
produced instead of only checking mockedPinnedFetch. Remove the inert
gate/release scaffolding from the mocked json implementation, and replace the
uncancelled 2000 ms timeout with a timer that is cleared when the request
promise settles.
- Around line 222-257: Update the test comment for the middleware-order test to
state that mocked passthrough middleware only verifies registration order, not
loopback enforcement or rate limiting. Document that inspecting router.stack,
route.stack, and handle relies on Express 5.2.1 internal APIs and may be
version-sensitive, or replace these assertions with a behavioral test if
practical.
In `@src/server/services/arena/ssrfGuard.ts`:
- Around line 265-271: Expose the default message used by
UpstreamBodyTooLargeError as a shared exported constant, then update the arena
route’s three duplicate literals to reference that constant or use the caught
error’s message. Keep UpstreamBodyTooLargeError’s default message aligned with
the shared value so future changes cannot drift.
In `@src/server/services/playground/oliveOutputScan.ts`:
- Around line 199-251: Align the download failure contract to 400/403 only: in
src/server/services/playground/oliveOutputScan.ts#L199-L251, change both 404
returns in resolveOliveOutputForDownload to 403 and narrow
OliveOutputResolveErr.status to 400 | 403. In
.kiro/specs/playground-tab/design.md#L2053-L2059, change Property 20 to require
a 403 (or 400) status; .kiro/specs/playground-tab/requirements.md#L407-L410 and
.kiro/specs/playground-tab/tasks.md#L320-L325 require no direct changes because
they already define the matching contract.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 8182f37c-b3b7-4166-94b7-445d0b21a263
📒 Files selected for processing (11)
.kiro/specs/playground-tab/HANDOFF.md.kiro/specs/playground-tab/design.md.kiro/specs/playground-tab/requirements.md.kiro/specs/playground-tab/tasks.mdsrc/lib/__tests__/arenaOliveOutputs.test.tssrc/lib/arenaOliveOutputs.tssrc/server/routes/arena.test.tssrc/server/routes/arena.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/services/arena/ssrfGuard.tssrc/server/services/playground/oliveOutputScan.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
Trackdubllc/Trackdub(manual)tonythethompson/QuickShell(manual)tonythethompson/numan(manual)tonythethompson/dependency-chain-substrate(manual)
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (8)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
src/**/*.{ts,tsx}: Match existing naming, file layout, and TypeScript patterns insrc/.
Put shared recipe logic insrc/lib/, especiallypipelineValidation.ts,oliveRecipeBuilder.ts, andrecipePipeline.ts.
src/**/*.{ts,tsx}: Follow the React performance guidance in docs/REACT_BEST_PRACTICES.md, especially eliminating request waterfalls, avoiding barrel imports, and deferring non-critical third-party libraries.
Do not implement the listed backburner AI providers unless explicitly requested; prefer Custom or openai-compat for OpenAI-shaped hosts.
src/**/*.{ts,tsx}: Keep validation logic in shared libraries rather than duplicating it in UI cell helpers or inspectors.
Split theInputEnvironmentPanel,IHVIntegrationPanel, andExecutionWorkspacemega-panels into feature folders with colocated hooks and tests.
Keep server and UI AI provider catalogs synchronized, preferably through a shared provider ID list or synchronization test; register new providers in both catalogs.
Add test coverage forrecipe-graph/,passCatalog,oliveRecipeHub,jobHistoryStore, andvramEstimate, and strengthen component tests for the large panels.
Files:
src/server/routes/arena.test.tssrc/server/services/arena/ssrfGuard.tssrc/lib/arenaOliveOutputs.tssrc/lib/__tests__/arenaOliveOutputs.test.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.tssrc/server/services/playground/oliveOutputScan.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.{ts,tsx,js,jsx}: Place imports at the top of modules; use inline imports only for a documented circular dependency.
Run linting and ensure typecheck-related CI checks pass before submitting changes.
For UI or server changes, manually smoke-test development startup, recipe loading/building, validation banners, and live execution when execution behavior is touched.
Files:
src/server/routes/arena.test.tssrc/server/services/arena/ssrfGuard.tssrc/lib/arenaOliveOutputs.tssrc/lib/__tests__/arenaOliveOutputs.test.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.tssrc/server/services/playground/oliveOutputScan.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use the project’s React 19, Vite, Express, and Tauri 2 conventions when modifying TypeScript or TSX application code.
Treat ESLint warnings as acceptable up to the configured limit; only lint errors or a non-zero lint exit indicate failure.
Files:
src/server/routes/arena.test.tssrc/server/services/arena/ssrfGuard.tssrc/lib/arenaOliveOutputs.tssrc/lib/__tests__/arenaOliveOutputs.test.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.tssrc/server/services/playground/oliveOutputScan.ts
src/server/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use the server-test configuration and
pnpm test:serverfor server unit tests.
Files:
src/server/routes/arena.test.tssrc/server/routes/arenaOliveOutputs.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Do not trigger real Olive optimization or batch runs in CI or VM tests; use CPU-only recipe building, JSON export, and validation flows instead.
Files:
src/server/routes/arena.test.tssrc/lib/__tests__/arenaOliveOutputs.test.tssrc/server/routes/arenaOliveOutputs.test.ts
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use the repository’s prescribed validation commands and preserve the CI order: lint, unit tests, server tests, integration tests, component tests, recipe validation, build, artifact assertion, production smoke testing, and CodeQL.
Files:
src/server/routes/arena.test.tssrc/server/services/arena/ssrfGuard.tssrc/lib/arenaOliveOutputs.tssrc/lib/__tests__/arenaOliveOutputs.test.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.tssrc/server/services/playground/oliveOutputScan.ts
src/server/routes/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Keep server functionality organized in the modular route structure under src/server/routes/ rather than bypassing the established Express route organization.
Files:
src/server/routes/arena.test.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.ts
src/lib/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use the unit-test configuration and
pnpm testfor src/lib unit tests.
Files:
src/lib/__tests__/arenaOliveOutputs.test.ts
🪛 ast-grep (0.45.0)
src/server/routes/arenaOliveOutputs.test.ts
[warning] 44-44: Express application should use Helmet
Context: express()
Note: [CWE-693] Protection Mechanism Failure (Express app without Helmet security headers).
(missing-helmet-typescript)
[warning] 72-72: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(path.join(cache, "a.onnx"), Buffer.alloc(16, 1))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
[warning] 73-73: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(path.join(output, "b.ort"), Buffer.alloc(32, 2))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
[warning] 74-74: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(path.join(output, "skip.bin"), Buffer.alloc(8, 3))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
src/server/routes/arena.ts
[warning] 225-225: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.createReadStream(resolved.absolutePath)
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
[warning] 212-212: Untrusted request input flows into a filesystem path
Context: resolveOliveOutputForDownload(req.query.id)
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(path-traversal-typescript)
🔍 Remote MCP DeepWiki, GitHub Copilot
Review-relevant context
- PR
#79is open againstfeat/playground-tab; it adds Olive-output list/download routes and cloud body-read handling. Task 19.1 and the required Task 19.5 property tests remain incomplete. - The underlying architecture comes from PR
#77:mountArenaRoutesserves Arena cloud inference, while Playground/Arena state and UI live in the existing TypeScript modules. PR#32supplied related server hardening patterns. - Olive scanning is bounded to depth 4, 200 matched entries, and 2,000 visited filesystem nodes. IDs are SHA-256 hashes of canonical paths; downloads revalidate containment, extension, regular-file status, and the 512 MiB size limit before streaming.
- Route tests cover opaque-ID refreshes, rejected path query parameters, download bytes, middleware order, body-size failures, timeout handling, and disconnect behavior. However, the five required fast-check properties are specified but not implemented.
- Current checks show CodeQL, security, validation, Docker build, and deployment succeeded; Python tests and Greptile review were still in progress, while the CodeRabbit status remained pending.
- DeepWiki could not provide repository context because
tonythethompson/Olive-Studiois not indexed.
🔇 Additional comments (17)
src/server/routes/arena.ts (3)
96-112: LGTM!
129-190: LGTM!
193-203: 🗄️ Data Integrity & IntegrationDo not raise a missing
Cache-Controlheader for these routes.Requirement 18 requires
Cache-Control: no-store, privatefor the Assistant snapshot endpoint, not the Olive output endpoints. Olive output IDs are deterministic hashes of canonical paths, so registry refreshes do not invalidate IDs while files remain available.> Likely an incorrect or invalid review comment.src/server/routes/arenaOliveOutputs.test.ts (3)
11-38: LGTM!
44-85: LGTM!
95-137: LGTM!src/server/services/arena/ssrfGuard.ts (1)
301-301: LGTM!src/server/routes/arena.test.ts (3)
8-8: LGTM!Also applies to: 33-33
227-265: LGTM!
267-285: LGTM!.kiro/specs/playground-tab/design.md (3)
2085-2093: 🎯 Functional CorrectnessSame contract already flagged at lines 2053-2059.
This section's 403/400-only wording is the stricter version of the same Property 20 contract discussed above. No separate action needed here beyond the consolidated fix.
2071-2071: LGTM!
2108-2108: LGTM!.kiro/specs/playground-tab/tasks.md (1)
357-357: LGTM!.kiro/specs/playground-tab/HANDOFF.md (1)
60-60: LGTM!src/lib/arenaOliveOutputs.ts (1)
70-89: LGTM!src/server/services/playground/oliveOutputScan.ts (1)
61-142: LGTM!
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 7 file(s) based on 13 unresolved review comments. Files modified:
Commit: The changes have been pushed to the Time taken: |
Dismissed because a newer commit was pushed; Greptile will re-review the current head.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
src/lib/arenaOliveOutputs.ts (1)
24-35: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winPreserve the Windows base prefix for relative Olive roots.
resolvePathdetects drive and UNC prefixes before it combines a relativevaluewithbase. Therefore, a default such asresolvePath("models/optimized", "C:\\workspace")returns/C:/workspace/models/optimized. The scanner then uses an invalid root on Windows.
src/lib/arenaOliveOutputs.ts#L24-L35: detect the drive or UNC prefix after combining a relative value withbase, or recursively normalize the combined path.src/lib/__tests__/arenaOliveOutputs.test.ts#L48-L60: add assertions for relative cache/output paths with aC:\\...base and for a\\\\server\\share\\...base.🤖 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 `@src/lib/arenaOliveOutputs.ts` around lines 24 - 35, Update resolvePath in src/lib/arenaOliveOutputs.ts so drive and UNC prefixes are detected after relative values are combined with base, preserving Windows prefixes for relative paths; add assertions in src/lib/__tests__/arenaOliveOutputs.test.ts at lines 48-60 covering relative cache/output paths with C:\... and \\server\share\... bases.src/server/routes/arena.ts (1)
216-233: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winThe Content-Length TOCTOU gap from the earlier review is only half-fixed.
resolved.sizeBytesis captured beforefs.createReadStream(resolved.absolutePath)opens the file. If the file shrinks or is replaced between resolve-time stat and stream completion,stream.pipe(res)ends normally with fewer bytes than the declaredContent-Length. Node does not raiseERR_HTTP_CONTENT_LENGTH_MISMATCHunlessresponse.strictContentLengthis set, so this path never reaches thestream.on("error", ...)handler you just fixed. The client silently receives a truncated file with a200status.This case is not hypothetical here: the app's own output directories are the ones an in-progress Olive optimization job can still be writing to.
Two low-effort options:
- Drop the
Content-Lengthheader and let the response use chunked transfer encoding. This removes the byte-count contract entirely and eliminates the mismatch class, at the cost of an inaccurate browser progress indicator.- Re-stat the file right after
createReadStreamopens (on the stream's'open'event) and setContent-Lengthfrom that fresh stat instead of the pre-fetchedresolved.sizeBytes.🐛 Proposed fix (Option 1: drop the pre-declared length)
res.setHeader("Content-Type", "application/octet-stream"); const safeBasename = resolved.basename.replace(/[\u0000-\u001f\u007f"\\]/g, "_"); const asciiFallback = safeBasename.replace(/[^\x20-\x7e]/g, "_"); res.setHeader( "Content-Disposition", `attachment; filename="${asciiFallback}"; filename*=UTF-8''${encodeURIComponent(safeBasename)}`, ); - res.setHeader("Content-Length", String(resolved.sizeBytes)); const stream = fs.createReadStream(resolved.absolutePath);🤖 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 `@src/server/routes/arena.ts` around lines 216 - 233, Remove the pre-declared Content-Length header based on resolved.sizeBytes in the download response so the stream uses chunked transfer encoding and cannot advertise a stale byte count. Keep the existing createReadStream, close cleanup, and error handling behavior unchanged.
🤖 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 @.kiro/specs/playground-tab/design.md:
- Around line 2085-2092: Complete Task 19.5 by implementing the missing route
property tests for Properties 21, 21b, and 22, and enable the two currently
skipped required properties. Cover the documented Olive-output security
behaviors, including snapshot eligibility and failure-shape assertions. Update
the oversized-file case to require an empty response with status 400 or 403,
rather than accepting any 4xx status.
In `@src/server/routes/arenaOliveOutputs.test.ts`:
- Around line 263-277: Rename the test to describe only the listing filter and
unknown-ID behavior, or replace that portion with coverage for the download
route; in particular, create a registered output that resolves to a disallowed
extension or an out-of-root symlink, request it through the file-download
endpoint, and assert status 403 with an empty body. Use the existing setup and
registration symbols plus resolveOliveOutputForDownload’s validation path, while
keeping the separate unknown-ID test non-duplicated.
---
Duplicate comments:
In `@src/lib/arenaOliveOutputs.ts`:
- Around line 24-35: Update resolvePath in src/lib/arenaOliveOutputs.ts so drive
and UNC prefixes are detected after relative values are combined with base,
preserving Windows prefixes for relative paths; add assertions in
src/lib/__tests__/arenaOliveOutputs.test.ts at lines 48-60 covering relative
cache/output paths with C:\... and \\server\share\... bases.
In `@src/server/routes/arena.ts`:
- Around line 216-233: Remove the pre-declared Content-Length header based on
resolved.sizeBytes in the download response so the stream uses chunked transfer
encoding and cannot advertise a stale byte count. Keep the existing
createReadStream, close cleanup, and error handling behavior unchanged.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 3f68e315-8a44-4047-80c8-d9a02dfa1ed3
📒 Files selected for processing (7)
.kiro/specs/playground-tab/design.mdsrc/lib/__tests__/arenaOliveOutputs.test.tssrc/lib/arenaOliveOutputs.tssrc/server/routes/arena.test.tssrc/server/routes/arena.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/services/playground/oliveOutputScan.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
Trackdubllc/Trackdub(manual)tonythethompson/QuickShell(manual)tonythethompson/numan(manual)tonythethompson/dependency-chain-substrate(manual)
📜 Review details
⏰ Context from checks skipped due to timeout. (6)
- GitHub Check: CodeQL
- GitHub Check: Greptile Review
- GitHub Check: docker-build
- GitHub Check: validate
- GitHub Check: python-tests
- GitHub Check: security
🧰 Additional context used
📓 Path-based instructions (8)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
src/**/*.{ts,tsx}: Match existing naming, file layout, and TypeScript patterns insrc/.
Put shared recipe logic insrc/lib/, especiallypipelineValidation.ts,oliveRecipeBuilder.ts, andrecipePipeline.ts.
src/**/*.{ts,tsx}: Follow the React performance guidance in docs/REACT_BEST_PRACTICES.md, especially eliminating request waterfalls, avoiding barrel imports, and deferring non-critical third-party libraries.
Do not implement the listed backburner AI providers unless explicitly requested; prefer Custom or openai-compat for OpenAI-shaped hosts.
src/**/*.{ts,tsx}: Keep validation logic in shared libraries rather than duplicating it in UI cell helpers or inspectors.
Split theInputEnvironmentPanel,IHVIntegrationPanel, andExecutionWorkspacemega-panels into feature folders with colocated hooks and tests.
Keep server and UI AI provider catalogs synchronized, preferably through a shared provider ID list or synchronization test; register new providers in both catalogs.
Add test coverage forrecipe-graph/,passCatalog,oliveRecipeHub,jobHistoryStore, andvramEstimate, and strengthen component tests for the large panels.
Files:
src/lib/__tests__/arenaOliveOutputs.test.tssrc/lib/arenaOliveOutputs.tssrc/server/routes/arena.test.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.tssrc/server/services/playground/oliveOutputScan.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.{ts,tsx,js,jsx}: Place imports at the top of modules; use inline imports only for a documented circular dependency.
Run linting and ensure typecheck-related CI checks pass before submitting changes.
For UI or server changes, manually smoke-test development startup, recipe loading/building, validation banners, and live execution when execution behavior is touched.
Files:
src/lib/__tests__/arenaOliveOutputs.test.tssrc/lib/arenaOliveOutputs.tssrc/server/routes/arena.test.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.tssrc/server/services/playground/oliveOutputScan.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use the project’s React 19, Vite, Express, and Tauri 2 conventions when modifying TypeScript or TSX application code.
Treat ESLint warnings as acceptable up to the configured limit; only lint errors or a non-zero lint exit indicate failure.
Files:
src/lib/__tests__/arenaOliveOutputs.test.tssrc/lib/arenaOliveOutputs.tssrc/server/routes/arena.test.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.tssrc/server/services/playground/oliveOutputScan.ts
src/lib/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use the unit-test configuration and
pnpm testfor src/lib unit tests.
Files:
src/lib/__tests__/arenaOliveOutputs.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Do not trigger real Olive optimization or batch runs in CI or VM tests; use CPU-only recipe building, JSON export, and validation flows instead.
Files:
src/lib/__tests__/arenaOliveOutputs.test.tssrc/server/routes/arena.test.tssrc/server/routes/arenaOliveOutputs.test.ts
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use the repository’s prescribed validation commands and preserve the CI order: lint, unit tests, server tests, integration tests, component tests, recipe validation, build, artifact assertion, production smoke testing, and CodeQL.
Files:
src/lib/__tests__/arenaOliveOutputs.test.tssrc/lib/arenaOliveOutputs.tssrc/server/routes/arena.test.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.tssrc/server/services/playground/oliveOutputScan.ts
src/server/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use the server-test configuration and
pnpm test:serverfor server unit tests.
Files:
src/server/routes/arena.test.tssrc/server/routes/arenaOliveOutputs.test.ts
src/server/routes/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Keep server functionality organized in the modular route structure under src/server/routes/ rather than bypassing the established Express route organization.
Files:
src/server/routes/arena.test.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.ts
🪛 ast-grep (0.45.0)
src/server/routes/arenaOliveOutputs.test.ts
[warning] 239-239: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(unicodePath, Buffer.alloc(24, 5))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
[warning] 477-477: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(evilPath, Buffer.alloc(8, 42))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
🔍 Remote MCP DeepWiki, GitHub Copilot
Additional review context
- PR
#79’s implementation is concentrated inmountArenaRoutes, the new server-onlyoliveOutputScanservice, and shared path helpers. Listing rebuilds a process-local ID registry; downloads re-canonicalize the registered path and revalidate containment, extension, regular-file status, and the 512 MiB limit before creating a stream. - The route tests explicitly state that middleware behavior is mocked as passthrough; they verify registration order only. Thus, actual non-loopback rejection and rate-limit throttling for the new Olive routes are not covered by these tests.
- The two required property tests currently remain
it.skipplaceholders, and the other three required properties (21, 21b, 22) are absent from the added test file. This confirms the documented Task 19.5 completion gate is unmet. - The test suite’s “out-of-root” case does not exercise traversal or symlink escape; it only sends an unknown hash and asserts
400. The actual symlink/path revalidation behavior therefore lacks direct route-test coverage. - DeepWiki could not provide architectural context because
tonythethompson/Olive-Studiois not indexed.
🔇 Additional comments (5)
src/server/services/playground/oliveOutputScan.ts (1)
199-251: LGTM!src/server/routes/arena.ts (2)
43-55: LGTM!Also applies to: 98-106, 144-146, 162-164
211-214: 🗄️ Data Integrity & IntegrationNo change required.
OliveOutputResolveErr.statusis typed as400 | 403, soresolved.statussatisfiesemptyRejectwithout a cast.> Likely an incorrect or invalid review comment.src/server/routes/arenaOliveOutputs.test.ts (1)
144-169: LGTM!Also applies to: 236-261, 279-287, 367-448, 472-502
src/server/routes/arena.test.ts (1)
8-8: LGTM!Also applies to: 33-33, 204-212, 227-227, 231-269, 271-289, 367-425
53995b7 to
51e0036
Compare
e8a7bd0 to
179406d
Compare
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/server/routes/arena.ts (1)
142-143: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove the supported
req.on("aborted")listener.This route runs under Express 5 and Node 22, where this handling path is not appropriate for abort detection. The
res.on("close")listener handles client disconnects for this block.♻️ Proposed refactor
- req.on("aborted", onClientGone); res.on("close", onClientGone);Update the matching cleanup at
req.off("aborted", onClientGone)to remove the dead registration.🤖 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 `@src/server/routes/arena.ts` around lines 142 - 143, Remove the req.on("aborted", onClientGone) registration from this route and retain res.on("close", onClientGone) as the client-disconnect handler. Update the corresponding cleanup to remove req.off("aborted", onClientGone), leaving only cleanup for the remaining response listener.
🤖 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 @.kiro/specs/playground-tab/design.md:
- Around line 2090-2092: Update the “Size limit” bullet in the design document
to require an oversized model file to return a 400 or 403 response with an empty
body, matching Property 20 and the behavior of resolveOliveOutputForDownload; do
not leave the wording as a generic 4xx response.
In `@src/lib/__tests__/arenaOliveOutputs.test.ts`:
- Around line 11-21: Update the assertions in the empty-cache and missing-output
test cases for resolveOliveOutputRoots to use literal forward-slash expected
strings instead of platform-dependent path.resolve calls. Preserve the expected
paths and follow the literal-string pattern used by the existing Windows and UNC
cases.
In `@src/server/routes/arena.ts`:
- Around line 251-267: Update the stream error handler associated with the
createReadStream flow to remove the previously set Content-Type and
Content-Disposition headers before calling emptyReject(res, 403) when headers
have not been sent. Leave the res.destroy() path unchanged once headers are
sent.
- Around line 55-59: Update isBodyTooLarge to recognize only
UpstreamBodyTooLargeError and remove the error-message substring fallback. In
the legacy stubs covered by the arena tests, replace the generic errors with
UpstreamBodyTooLargeError so those cases continue exercising the intended
size-limit path.
In `@src/server/routes/arenaOliveOutputs.test.ts`:
- Around line 669-675: Export the production Content-Disposition sanitizer from
arena.ts, using its existing sanitizer symbol, and reuse it in the route body
instead of duplicating the logic. Update the test’s “Content-Disposition
sanitization replaces quotes, backslashes, and controls” assertion to import and
call that production sanitizer, removing the local two-replace implementation.
- Around line 440-474: Update the promise in the HTTP request test around
req.on("error") to use reject for unexpected or watchdog failures, eliminating
the unused parameter. Restore a timeout watchdog that rejects when req.destroy()
does not settle the request, and clear that timeout whenever the promise
resolves or rejects so the test cannot hang.
- Around line 629-660: Update the download Content-Disposition construction to
percent-encode apostrophes in the encoded basename used by filename*, applying
the replacement after encodeURIComponent. Extend the property-based coverage
around basenameArb and the download response to extract filename* and verify it
round-trips to the original basename, including names containing apostrophes.
In `@src/server/services/arena/ssrfGuard.ts`:
- Around line 318-322: In the response-size limit branch, call finish with
UpstreamBodyTooLargeError before destroying res so the typed rejection is
settled first; then invoke res.destroy with the existing error and return,
preserving the current oversized-response behavior.
In `@src/server/services/playground/oliveOutputScan.ts`:
- Around line 105-119: Update walkRoot and its callers in listOliveOutputs so
maxEntries is enforced per root rather than against the shared out.length; track
each root’s number of emitted entries independently while preserving the global
maxVisited limit. Ensure every configured root can contribute entries, and keep
recent’s final mtime ordering and cap unchanged.
---
Outside diff comments:
In `@src/server/routes/arena.ts`:
- Around line 142-143: Remove the req.on("aborted", onClientGone) registration
from this route and retain res.on("close", onClientGone) as the
client-disconnect handler. Update the corresponding cleanup to remove
req.off("aborted", onClientGone), leaving only cleanup for the remaining
response listener.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: b8e7db5f-ff6b-48cd-836a-27948595e2b0
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (10)
.kiro/specs/playground-tab/design.md.kiro/specs/playground-tab/tasks.mdpackage.jsonsrc/lib/__tests__/arenaOliveOutputs.test.tssrc/lib/arenaOliveOutputs.tssrc/server/routes/arena.test.tssrc/server/routes/arena.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/services/arena/ssrfGuard.tssrc/server/services/playground/oliveOutputScan.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
tonythethompson/QuickShell(manual)tonythethompson/numan(manual)tonythethompson/dependency-chain-substrate(manual)
📜 Review details
⏰ Context from checks skipped due to timeout. (4)
- GitHub Check: Greptile Review
- GitHub Check: python-tests
- GitHub Check: validate
- GitHub Check: docker-build
🧰 Additional context used
📓 Path-based instructions (9)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
src/**/*.{ts,tsx}: Match existing naming, file layout, and TypeScript patterns insrc/.
Put shared recipe logic insrc/lib/, especiallypipelineValidation.ts,oliveRecipeBuilder.ts, andrecipePipeline.ts.
src/**/*.{ts,tsx}: Follow the React performance guidance in docs/REACT_BEST_PRACTICES.md, especially eliminating request waterfalls, avoiding barrel imports, and deferring non-critical third-party libraries.
Do not implement the listed backburner AI providers unless explicitly requested; prefer Custom or openai-compat for OpenAI-shaped hosts.
src/**/*.{ts,tsx}: Keep validation logic in shared libraries rather than duplicating it in UI cell helpers or inspectors.
Split theInputEnvironmentPanel,IHVIntegrationPanel, andExecutionWorkspacemega-panels into feature folders with colocated hooks and tests.
Keep server and UI AI provider catalogs synchronized, preferably through a shared provider ID list or synchronization test; register new providers in both catalogs.
Add test coverage forrecipe-graph/,passCatalog,oliveRecipeHub,jobHistoryStore, andvramEstimate, and strengthen component tests for the large panels.
Files:
src/lib/__tests__/arenaOliveOutputs.test.tssrc/server/services/arena/ssrfGuard.tssrc/server/routes/arena.test.tssrc/lib/arenaOliveOutputs.tssrc/server/services/playground/oliveOutputScan.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.{ts,tsx,js,jsx}: Place imports at the top of modules; use inline imports only for a documented circular dependency.
Run linting and ensure typecheck-related CI checks pass before submitting changes.
For UI or server changes, manually smoke-test development startup, recipe loading/building, validation banners, and live execution when execution behavior is touched.
Files:
src/lib/__tests__/arenaOliveOutputs.test.tssrc/server/services/arena/ssrfGuard.tssrc/server/routes/arena.test.tssrc/lib/arenaOliveOutputs.tssrc/server/services/playground/oliveOutputScan.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use the project’s React 19, Vite, Express, and Tauri 2 conventions when modifying TypeScript or TSX application code.
Treat ESLint warnings as acceptable up to the configured limit; only lint errors or a non-zero lint exit indicate failure.
Files:
src/lib/__tests__/arenaOliveOutputs.test.tssrc/server/services/arena/ssrfGuard.tssrc/server/routes/arena.test.tssrc/lib/arenaOliveOutputs.tssrc/server/services/playground/oliveOutputScan.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.ts
src/lib/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use the unit-test configuration and
pnpm testfor src/lib unit tests.
Files:
src/lib/__tests__/arenaOliveOutputs.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Do not trigger real Olive optimization or batch runs in CI or VM tests; use CPU-only recipe building, JSON export, and validation flows instead.
Files:
src/lib/__tests__/arenaOliveOutputs.test.tssrc/server/routes/arena.test.tssrc/server/routes/arenaOliveOutputs.test.ts
**/*
📄 CodeRabbit inference engine (AGENTS.md)
Use the repository’s prescribed validation commands and preserve the CI order: lint, unit tests, server tests, integration tests, component tests, recipe validation, build, artifact assertion, production smoke testing, and CodeQL.
Files:
src/lib/__tests__/arenaOliveOutputs.test.tssrc/server/services/arena/ssrfGuard.tspackage.jsonsrc/server/routes/arena.test.tssrc/lib/arenaOliveOutputs.tssrc/server/services/playground/oliveOutputScan.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.ts
package.json
📄 CodeRabbit inference engine (AGENTS.md)
Use pnpm 11.17 as the package manager; do not use npm install because the preinstall guard blocks it.
Files:
package.json
src/server/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use the server-test configuration and
pnpm test:serverfor server unit tests.
Files:
src/server/routes/arena.test.tssrc/server/routes/arenaOliveOutputs.test.ts
src/server/routes/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Keep server functionality organized in the modular route structure under src/server/routes/ rather than bypassing the established Express route organization.
Files:
src/server/routes/arena.test.tssrc/server/routes/arenaOliveOutputs.test.tssrc/server/routes/arena.ts
🪛 ast-grep (0.45.0)
src/server/routes/arenaOliveOutputs.test.ts
[warning] 45-45: Express application should use Helmet
Context: express()
Note: [CWE-693] Protection Mechanism Failure (Express app without Helmet security headers).
(missing-helmet-typescript)
[warning] 73-73: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(path.join(cache, "a.onnx"), Buffer.alloc(16, 1))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
[warning] 74-74: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(path.join(output, "b.ort"), Buffer.alloc(32, 2))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
[warning] 75-75: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(path.join(output, "skip.bin"), Buffer.alloc(8, 3))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
[warning] 240-240: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(unicodePath, Buffer.alloc(24, 5))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
[warning] 291-291: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(outside, Buffer.alloc(8, 9))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
[warning] 302-302: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(emptyPath, Buffer.alloc(0))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
[warning] 639-639: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(filePath, Buffer.alloc(8, 42))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
src/server/routes/arena.ts
[warning] 240-240: Untrusted request input flows into a filesystem path
Context: resolveOliveOutputForDownload(req.query.id)
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(path-traversal-typescript)
[warning] 259-259: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.createReadStream(resolved.absolutePath)
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
🪛 GitHub Check: CodeFactor
src/server/services/playground/oliveOutputScan.ts
[notice] 105-173: src/server/services/playground/oliveOutputScan.ts#L105-L173
Complex Method
src/server/routes/arenaOliveOutputs.test.ts
[notice] 440-440: src/server/routes/arenaOliveOutputs.test.ts#L440
'reject' is defined but never used. Allowed unused args must match /^_/u. (@typescript-eslint/no-unused-vars)
🪛 OpenGrep (1.26.0)
src/server/routes/arenaOliveOutputs.test.ts
[ERROR] 658-658: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.
(coderabbit.command-injection.exec-js)
🔍 Remote MCP DeepWiki, GitHub Copilot
Additional review context
- Related PR
#77is now merged intomain(2ee6dd4), not open or blocked. It introduced the Arena boundary:ArenaPanel → POST /api/arena/cloud-inference, mounted under/api, with shared timeout handling and local-first access control. - PR
#77’s design explicitly requires Olive-output routes to use server-owned roots and opaque IDs, reject client-supplied filesystem parameters, revalidate containment/symlinks/extensions/size before downloads, and prevent credential leakage from Assistant snapshots. - The same design states that Requirement 18 is incomplete until fast-check properties 20, 20b, 21, 21b, and 22 each pass with at least 100 iterations. This aligns with the supplied summary that Task 19.5 remains incomplete.
- DeepWiki could not provide architectural context because
tonythethompson/Olive-Studiois not indexed.,
🔇 Additional comments (32)
.kiro/specs/playground-tab/design.md (1)
2093-2098: Properties 21, 21b, and 22 still have no implementations.Property 20 and 20b now exist as
fast-checkproperties insrc/server/routes/arenaOliveOutputs.test.ts. Properties 21, 21b, and 22 do not appear in the supplied files. Requirement 18 stays incomplete until all five properties pass at 100 iterations. Do not mark Task 19.5 complete before that.src/server/routes/arena.ts (5)
28-37:armCloudAbortstill polls every 25 ms.The implementation retains the
setIntervaldeadline poll. This was raised in a previous round. The comment at Lines 124-126 documents the CodeQL motivation, so the polling is now a deliberate, documented choice.
5-19: LGTM!Also applies to: 61-79
129-141: LGTM!Also applies to: 160-213
216-229: LGTM!
231-250: LGTM!Also applies to: 268-270
src/server/services/arena/ssrfGuard.ts (2)
277-283: The default message is still duplicated in the route layer.Line 279 hardcodes
"Upstream response exceeded maximum allowed size", andsrc/server/routes/arena.tsLine 206 repeats the same literal. This was raised in a previous round. Export the message as a constant, or have the route useerr.messagefrom the caughtUpstreamBodyTooLargeError.
285-291: LGTM!src/server/routes/arena.test.ts (4)
402-431: These two tests now duplicate the typed-error tests above.Lines 402-431 throw a plain
Errorwith the size message. Lines 262-301 cover the same two scenarios withUpstreamBodyTooLargeError. The plain-Errorvariants pass only because of the message-substring fallback inisBodyTooLarge. Remove the fallback and these two stubs together, as described in the comment onsrc/server/routes/arena.tsLines 55-59.
34-34: LGTM!Also applies to: 108-125, 235-240, 258-260
262-322: LGTM!
362-371: LGTM!Also applies to: 385-391, 444-451, 464-540
.kiro/specs/playground-tab/tasks.md (1)
344-353: LGTM!src/lib/arenaOliveOutputs.ts (4)
8-58: LGTM!
66-84: LGTM!
96-121: LGTM!
124-148: LGTM!src/server/services/playground/oliveOutputScan.ts (5)
1-74: LGTM!
82-85: LGTM!
120-173: LGTM!
234-311: LGTM!
186-216: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winClearing
idRegistryin place opens a window where valid downloads return 400.Line 187 empties the registry, then the scan and the
mapat Lines 202-216 refill it. A download request that arrives during that window finds no entry and gets400fromresolveOliveOutputForDownload, even though the ID is valid before and after the refresh. The list route is rate-limited but not serialized, so a UI refresh concurrent with a download can hit this.IDs are already stable per canonical path, so build a new map and swap it at the end.
🔧 Proposed fix
export function listOliveOutputs(): OliveOutputsListResult { - idRegistry.clear(); const roots = getOliveOutputRoots(); @@ + const nextRegistry = new Map<string, RegistryEntry>(); const entries: OliveOutputEntry[] = scanned.map((file) => { const id = mintOpaqueId(file.absolutePath); - idRegistry.set(id, { + nextRegistry.set(id, { absolutePath: file.absolutePath, rootLabel: file.rootLabel, displayPath: file.displayPath, }); @@ }); + // Swap atomically so concurrent downloads never observe an empty registry. + idRegistry.clear(); + for (const [id, entry] of nextRegistry) idRegistry.set(id, entry);> Likely an incorrect or invalid review comment.src/lib/__tests__/arenaOliveOutputs.test.ts (1)
48-84: LGTM!Also applies to: 87-108
src/server/routes/arenaOliveOutputs.test.ts (8)
1-138: LGTM!
140-200: LGTM!
202-316: LGTM!
318-363: LGTM!
366-404: LGTM!
406-439: LGTM!Also applies to: 475-487
521-622: LGTM!
489-519: LGTM!Also applies to: 624-628, 661-668
package.json (1)
102-102: Confirm the unrelated dependency downgrades before merge.
fast-check^3.23.2supports the newfc.stringMatchingusage. Confirm the adjacent downgrades are intentional:@openai/codex-sdk^0.145.0,@playwright/test^1.61.1,@types/react^19.2.17, and@types/react-dom^19.2.3. The React type change can affect UI type resolution.
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 6 file(s) based on 6 unresolved review comments. Files modified:
Commit: The changes have been pushed to the Time taken: |
Dismissed because a newer commit was pushed; Greptile will re-review the current head.
…erge Replay the olive-output list/download stack onto current main as a single commit, keep cloud AbortError/size-limit handling, and avoid Windows-illegal basename generators in Content-Disposition PBTs. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep filesystem round-trips to path-legal characters and cover quote/backslash/control sanitization with a focused unit assertion. Co-authored-by: Cursor <cursoragent@cursor.com>
1d748ef to
abdcd90
Compare
Dismissed because a newer commit was pushed; Greptile will re-review the current head.
Summary
Addresses still-valid review findings on the playground-tab Arena work:
GET /api/arena/olive-outputs) scans server-owned roots without requiring an opaque id; download (/file?id=) resolves the id and revalidates containment, regular file, extension, and size. Path-related query params are rejected with empty 400/403 bodies.cacheDir/outputDir/path/absolutePath.upstream.text()/json()is rethrown;clientDisconnected/writableEnded/destroyedchecked after body reads.Validation
pnpm exec tsc --noEmitpnpm test:server(190 passed)pnpm test(570 passed)pnpm lint(exit 0, existing warnings only)Notes
Summary by cubic
Adds secure Olive output list/download routes with opaque IDs and stricter cloud proxy body-read handling. Improves Windows handling (drive/UNC prefixes, Content‑Disposition tests) and keeps failures to 400/403 per spec.
New Features
GET /api/arena/olive-outputs: scans server-owned roots with depth/count/visit caps; returns{ roots, recent≤10, entries }with stable opaque IDs anddisplayPathonly (no absolute paths).GET /api/arena/olive-outputs/file?id=<id>: re-validates in-root containment, regular file,.onnx/.ort, and size in(0, 512 MiB]; streams bytes with sanitizedContent-Disposition; omitsContent-Length; stops on client disconnect.path,absolutePath,cacheDir,outputDirwith empty 400; protected byarenaLocalOnlyandarenaProxyRateLimit.Bug Fixes
UpstreamBodyTooLargeErrorto 502; treatsAbortErrorfromtext()/json()as a timeout (504); passes through non‑2xx; aborts upstream and avoids writes after disconnects.Written for commit abdcd90. Summary will update on new commits.