Skip to content

feat(ux): synthesis log export, UI context, and edge error hardening - #80

Merged
TechHypeXP merged 16 commits into
mainfrom
feature/synthesis-log-ux
Jun 15, 2026
Merged

feat(ux): synthesis log export, UI context, and edge error hardening#80
TechHypeXP merged 16 commits into
mainfrom
feature/synthesis-log-ux

Conversation

@TechHypeXP

@TechHypeXP TechHypeXP commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Implements UX upgrades (log export, UI state management) and stabilizes the edge ingestion pipeline with improved error handling.

Summary by Sourcery

Refine the Atlas and console UX while hardening graph and synthesis handling across the web app and edge worker.

New Features:

  • Add export and copy actions for synthesis processing logs, including markdown and JSON download formats.
  • Introduce a UI state context for toggling visibility of Atlas, synthesis log, and video player panes.
  • Wire the Atlas page hero to the real analysis SSE pipeline and dashboard navigation.

Bug Fixes:

  • Ensure video seek actions clear after applying to prevent repeated jumps in the video player.
  • Prevent dashboard crashes from global graph API failures or unauthorized access by returning empty graph data instead of errors.

Enhancements:

  • Replace the root page with a static marketing landing component and mark it as force-dynamic while decoupling it from the Atlas app layer.
  • Improve Atlas hero background loading with a reusable skeleton component that accepts custom styling.
  • Show placeholder dimension cards in the dashboard while analysis is running even before a projection is available.
  • Align global graph API paths and logging with the Atlas naming across hooks and routes.
  • Soften edge worker error responses for missing transcripts and adjust status codes to avoid exposing internal ingestion details.

Documentation:

  • Add 10X audit master checklist and preflight report documents summarizing recent reliability, security, and performance findings and fixes.

Summary by cubic

Adds synthesis log export, a small UI state context, and safer Atlas/global graph and edge error handling. Restores the public landing page, moves Atlas behind auth, and hardens OAuth with server-side cookie exchange, strict same-origin redirect sanitization, and robust exception handling with path persistence.

  • New Features

    • Export processing logs: copy or download as md or json.
    • UI state context to toggle Atlas, Synthesis Log, and Video Player panes.
    • Atlas hero wired to SSE; background map lazy-loads with Skeleton and shows 11-dimension placeholders during analysis.
  • Bug Fixes

    • Global graph API moved to /api/atlas/global-graph; returns {nodes:[],edges:[]} on 401/500 to avoid crashes; useGlobalGraph updated.
    • Clear one-time video seeks after applying to prevent repeated jumps.
    • Edge worker returns 400 (ERR_EDGE_EMPTY_SOURCE) with "Transcript unavailable" when transcript is missing.
    • OAuth: sets Supabase cookies on the redirect response, propagates next from sign-in, strictly sanitizes to same-origin paths (incl. encoded forms), and handles exchange exceptions; added vitest unit tests.

Written for commit e69675f. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

Release Notes

  • New Features

    • Added “Copy logs” and “Download” actions for processing logs (Markdown and JSON).
    • Introduced UI visibility controls for Atlas, Synthesis Log, and Video Player.
    • Added ability to clear the video player’s pending seek state.
  • Improvements

    • Simplified the landing page to always render the landing view.
    • Standardized global graph API error responses to return { nodes: [], edges: [] }.
    • Updated global graph fetching to use the new API path.
  • Documentation

    • Added an intelligent PR review workflow guide.

@supabase

supabase Bot commented Jun 14, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project adnmbikaqnxivalqoild because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@sourcery-ai

sourcery-ai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds synthesis log export UX, centralizes root landing page into a static marketing component, introduces UI state context and Atlas ingestion flow via SSE, and hardens edge/global graph behavior to avoid crashes while improving video player seek handling and skeleton/loading behavior.

Sequence diagram for Atlas SSE ingestion flow from AtlasPage

sequenceDiagram
  actor User
  participant AtlasPage
  participant useSSEStream
  participant EdgeWorker as analyze-llm-stream
  participant Router

  User->>AtlasPage: submit form
  AtlasPage->>AtlasPage: handleAnalyze
  AtlasPage->>AtlasPage: setIsSubmitting(true)
  alt videoUrl empty
    AtlasPage-->>User: return (no-op)
  else videoUrl present
    AtlasPage->>useSSEStream: startAnalysis(videoUrl, timeZone)
    useSSEStream->>EdgeWorker: POST /analyze-llm-stream
    EdgeWorker-->>useSSEStream: SSE synthesis stream
    useSSEStream-->>AtlasPage: resolve startAnalysis
    AtlasPage->>Router: push(/dashboard)
  end
  opt error during startAnalysis
    useSSEStream-->>AtlasPage: throw error
    AtlasPage->>AtlasPage: console.error
    AtlasPage->>AtlasPage: setIsSubmitting(false)
  end
Loading

Sequence diagram for useGlobalGraph fetching hardened atlas global graph

sequenceDiagram
  participant Dashboard as DashboardContainer
  participant useGlobalGraph
  participant API as /api/atlas/global-graph

  Dashboard->>useGlobalGraph: mount hook
  useGlobalGraph->>API: GET
  alt auth success and graph ok
    API-->>useGlobalGraph: {nodes, edges}
    useGlobalGraph-->>Dashboard: set graph data
  else unauthorized
    API-->>useGlobalGraph: [] status 401
    useGlobalGraph-->>Dashboard: error Failed to fetch global knowledge graph
  else processing error
    API-->>useGlobalGraph: {nodes: [], edges: []}
    useGlobalGraph-->>Dashboard: set empty graph
  end
Loading

File-Level Changes

Change Details Files
Replace Atlas root hero logic with an authenticated Atlas ingestion hero page and decouple the public landing page into a dedicated component.
  • Transform atlas/page.tsx into an Atlas-specific hero screen that overlays GlobalKnowledgeMap as a background, accepts a YouTube URL, and triggers analysis via useSSEStream before routing to /dashboard.
  • Wire atlas/page.tsx to Next.js router and add submit handling with in-flight state and basic error logging.
  • Update the root app page (app/page.tsx) to delegate to a new LandingPage component, marking the route as force-dynamic and documenting that it is decoupled from Atlas application logic.
web/app/atlas/page.tsx
web/app/page.tsx
Enhance processing log UX with copy/download export utilities for synthesis logs.
  • Add clipboard copy handler that flattens terminalLines into timestamped text and writes to navigator.clipboard.
  • Add markdown and JSON download handlers that create blobs, generate object URLs, and programmatically trigger downloads for synthesis-log.md or synthesis-log.json.
  • Replace the collapsed-line-count display with copy and download icon buttons while preserving existing header controls.
web/components/templates/console/ProcessingLog.tsx
Improve dashboard robustness and loading behavior around global graph and nucleus dimensions.
  • Adjust dimension computation in DashboardContainer to synthesize 11 placeholder dimensions with streaming/idle statuses when projection data is unavailable but analysis is in progress, falling back to an empty list only when truly absent.
  • Change the atlas global graph API route to live under /api/atlas/global-graph, returning an empty array on 401 and an empty nodes/edges graph on errors to avoid consumer crashes while updating log prefixes.
  • Update the useGlobalGraph hook to call the new /api/atlas/global-graph path.
web/components/containers/DashboardContainer.tsx
web/app/api/wiki/global-graph/route.ts
web/hooks/useGlobalGraph.ts
Tighten video player seek behavior via the video store and consumer.
  • Extend useVideoStore with a clearSeek action to reset seekTo to null.
  • Switch VideoPlayerCard to use clearSeek instead of jumpToTimestamp when reacting to seekTo, eliminating the previous timestamp reset semantics.
  • Update VideoPlayerCard hook destructuring and effect dependencies to align with the new store API.
web/components/templates/console/VideoPlayerCard.tsx
web/store/useVideoStore.ts
Make skeleton component more reusable to support full-bleed loading states.
  • Allow Skeleton to accept an optional className and merge it into the root div, preserving existing structural styling.
  • Update GlobalKnowledgeMap loader usage to pass an absolute inset-0 class for full-screen skeleton coverage.
web/components/ui/skeleton.tsx
web/app/atlas/page.tsx
Adjust edge worker error handling for empty transcript scenarios.
  • Change the analyze-llm-stream handler to return a generalized 'Transcript unavailable' message and switch the HTTP status from 400 to 500 for empty transcripts while keeping the edge error code constant.
worker/src/worker.ts
Introduce a UI state context to manage visibility of primary console/Atlas panes.
  • Create a React context and provider that tracks visibility flags for Atlas, synthesis log, and video player panes with corresponding toggle functions.
  • Export a typed useUIState hook that enforces provider usage and exposes the state and toggles.
web/lib/stores/ui-state-context.tsx
Add audit documentation capturing 10X checklist and preflight state for recent work.
  • Add a master audit checklist markdown document enumerating critical, high, medium, low, and new findings with status and side effects.
  • Add a preflight report markdown documenting reconciliation against the prior full-spectrum audit, recent work items, and identified risks/blindspots.
docs/audit/10X_AUDIT_MASTER_CHECKLIST_2026_06_14.md
docs/audit/10X_PREFLIGHT_REPORT_2026_06_14.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@vercel

vercel Bot commented Jun 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hex-yt-intel Ready Ready Preview, Comment Jun 15, 2026 7:21am

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Simplifies page.tsx to always render LandingPage, fixes global-graph API response shapes to { nodes: [], edges: [] }, renames the fetch endpoint to /api/atlas/global-graph, shortens a worker error string, rewrites OAuth callback with destination routing, hardens bearer token validation in middleware, adds session logging to atlas page, introduces UIStateProvider context for three panel visibility toggles, extends the video store with clearSeek, and adds clipboard copy and file download controls to ProcessingLog.

Changes

Console UI, Authentication, and API Improvements

Layer / File(s) Summary
Root page simplification and global-graph API contract fixes
web/app/page.tsx, web/app/api/atlas/global-graph/route.ts, web/hooks/useGlobalGraph.ts, worker/src/worker.ts
Strips auth/routing logic from page.tsx so RootPage always renders LandingPage. Corrects global-graph 401 and 500 error responses from [] and { error: 'Internal server error' } to { nodes: [], edges: [] }. Updates useGlobalGraph to fetch from /api/atlas/global-graph. Shortens the worker's empty-transcript error string to 'Transcript unavailable'.
OAuth callback simplification and signin destination routing
web/app/auth/callback/route.ts, web/app/auth/signin/form.tsx
Rewrites callback route to extract only code and next from URL, default next to /atlas, and create redirect response before Supabase client creation so cookies write directly via cookies.setAll. Removes prior OAuth error handling, pendingTokens staging, try/catch, and data.session validation. Updates signin form to compute callbackUrl from origin, /auth/callback path, and next query parameter from current pathname.
Middleware bearer token validation hardening
web/middleware.ts
Removes dev-only test-token bypass (test-token-, user- prefixes). Removes bearer token success/failure logging and diag writes on bearer success. Now calls client.auth.getUser(token) and returns false only on missing user or error; true on success. Preserves non-bearer getUser() path with diag.outcome and diag.supabaseError tracking.
Atlas page session logging
web/app/atlas/page.tsx
Destructures both session and sessionError from getSession(). Logs authentication check result with session presence and error details. Adds console log before unauthenticated redirect.
UIStateProvider context for panel visibility
web/lib/stores/ui-state-context.tsx
Introduces UIStateContext with TypeScript interfaces for combined UI state and context API. UIStateProvider stores three visibility booleans (Atlas, Synthesis Log, Video Player) all defaulting to true, exposes toggle callbacks, and memoizes the context value. useUIState hook throws when called outside provider.
Video store clearSeek and VideoPlayerCard integration
web/store/useVideoStore.ts, web/components/templates/console/VideoPlayerCard.tsx
Extends VideoState with clearSeek(): void method. Implements clearSeek in Zustand store by setting seekTo to null. Updates VideoPlayerCard to call clearSeek after seeking the ReactPlayer, ensuring pending seek targets are consumed atomically.
ProcessingLog copy and download controls
web/components/templates/console/ProcessingLog.tsx
Adds handleCopy (writes newline-delimited timestamped lines to clipboard) and handleDownload(format) (creates Blob-based file download as Markdown or JSON with filename synthesis-log.<format>). Replaces collapsed-state line-count display with Copy logs and Download MD icon buttons. Removes inline section comments.
Skeleton component className fallback
web/components/ui/skeleton.tsx
Updates Skeleton parameter to default className to empty string. Changes rendered class expression to use `className
PR review workflow documentation
docs/reference/PR_REVIEW_WORKFLOW_V2.md
Adds new documentation file defining an "Intelligent 6-phase" PR review workflow with mandatory trigger, environment detection and effort evaluation, local isolation and AST/type safety gates, automated tool discovery with review matrix, sequential feedback resolution with continuous re-verification, quota/self-improvement steps, final sign-off checklist requirements, merge authority constraints, and post-merge stewardship and documentation updates.

Sequence Diagram

sequenceDiagram
  participant User
  participant SigninForm as signin/form.tsx
  participant AuthCallback as auth/callback
  participant Supabase as Supabase Auth
  participant AtlasPage as atlas/page.tsx

  User->>SigninForm: Click Sign In
  SigninForm->>SigninForm: Compute callbackUrl<br/>(origin + /auth/callback<br/>+ next=pathname)
  SigninForm->>Supabase: signInWithOAuth(redirectTo: callbackUrl)
  Supabase-->>User: Redirect to provider
  User->>AuthCallback: OAuth callback<br/>(code + next params)
  AuthCallback->>AuthCallback: Create redirect response early
  AuthCallback->>Supabase: exchangeCodeForSession(code)
  Supabase-->>AuthCallback: Auth cookies
  AuthCallback->>AuthCallback: cookies.setAll<br/>(writes to response)
  AuthCallback-->>User: Redirect to next<br/>(default /atlas)
  User->>AtlasPage: Load /atlas
  AtlasPage->>Supabase: getSession()
  Supabase-->>AtlasPage: session + sessionError
  AtlasPage->>AtlasPage: Log session status
  alt Has Session
    AtlasPage-->>User: Render Atlas
  else No Session
    AtlasPage->>AtlasPage: Log redirect
    AtlasPage-->>User: Redirect to /auth/signin
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Hex-Tech-Lab/hex-yt-intel#25: Both PRs directly modify the Supabase auth middleware (web/middleware.ts) and auth flow by changing bearer token validation logic and cookie/session handling approaches.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main features and changes: synthesis log export, UI context management, and error handling improvements across the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 feature/synthesis-log-ux
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feature/synthesis-log-ux

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • In analyze-llm-stream the empty-transcript case was changed from a 400 to a 500 while still representing a client-side issue; consider keeping this as a 4xx (or otherwise aligning with existing retry/alerting semantics) so monitoring and clients don’t treat it as a transient server failure.
  • The /api/atlas/global-graph route now returns [] with a 401, but useGlobalGraph still treats any non-OK response as an error; either return a 200 with an empty graph for unauthenticated users or update the hook to handle 401 specifically and surface an empty graph without throwing.
  • The updated Skeleton component always interpolates className into a template literal, which will render the string "undefined" when no className is passed; consider defaulting className to an empty string or conditionally concatenating it.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `analyze-llm-stream` the empty-transcript case was changed from a 400 to a 500 while still representing a client-side issue; consider keeping this as a 4xx (or otherwise aligning with existing retry/alerting semantics) so monitoring and clients don’t treat it as a transient server failure.
- The `/api/atlas/global-graph` route now returns `[]` with a 401, but `useGlobalGraph` still treats any non-OK response as an error; either return a 200 with an empty graph for unauthenticated users or update the hook to handle 401 specifically and surface an empty graph without throwing.
- The updated `Skeleton` component always interpolates `className` into a template literal, which will render the string "undefined" when no className is passed; consider defaulting `className` to an empty string or conditionally concatenating it.

## Individual Comments

### Comment 1
<location path="web/components/ui/skeleton.tsx" line_range="1-3" />
<code_context>
-export function Skeleton() {
+export function Skeleton({ className }: { className?: string }) {
   return (
-    <div className="animate-pulse space-y-4 p-4 border border-gray-700 rounded-lg">
+    <div className={`animate-pulse space-y-4 p-4 border border-gray-700 rounded-lg ${className}`}>
       <div className="h-4 bg-gray-700 rounded w-3/4"></div>
       <div className="h-64 bg-gray-700 rounded w-full"></div>
</code_context>
<issue_to_address>
**nitpick (bug_risk):** Passing an undefined `className` will render the literal string "undefined" in the class list.

Since `className` is optional, omitting it will produce `"... rounded-lg undefined"` in the DOM. Consider defaulting it to an empty string or guarding it in the template literal, e.g. `export function Skeleton({ className = '' } ...)` or `className={`... rounded-lg ${className ?? ''}`}`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread web/components/ui/skeleton.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
worker/src/worker.ts (1)

418-425: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

HTTP 500 is semantically incorrect for empty transcript — this is a client input error.

An empty or missing transcript is a validation failure of the client-provided payload, not an internal server error. HTTP 400 (Bad Request) correctly signals that the request cannot be processed due to invalid input, while 500 implies a server-side failure that may be retryable.

This change will:

  1. Trigger server-error monitoring alerts for what is actually a client-side issue
  2. Potentially cause clients to retry requests that will never succeed
  3. Obscure actual server failures in error metrics
Recommended: keep 400 status, improve message if needed
   if (!req.transcript || req.transcript.trim().length === 0) {
     console.error('[analyze-llm-stream] Empty transcript received at edge');
     return c.json({ 
-      error: 'Transcript unavailable',
+      error: 'Transcript unavailable. The video may lack captions or transcript extraction failed.',
       code: 'ERR_EDGE_EMPTY_SOURCE' 
-    }, 500);
+    }, 400);
   }
🤖 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 `@worker/src/worker.ts` around lines 418 - 425, The empty transcript validation
check in the analyze-llm-stream handler is returning HTTP status code 500, which
incorrectly signals an internal server error when the actual issue is a
client-side validation failure. Change the status code from 500 to 400 (Bad
Request) in the json response for the empty transcript check, as HTTP 400 is the
semantically correct status for invalid client input rather than server
failures, which will prevent false server-error alerts and avoid triggering
unnecessary client retries.
🤖 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 `@web/app/api/atlas/global-graph/route.ts`:
- Around line 11-13: The 401 response when authError or !user is true returns an
empty array [] instead of the expected KnowledgeGraph object shape. Change the
return statement in the authError/!user check block to return { nodes: [],
edges: [] } to match the shape returned by the successful response path and
error fallback, ensuring downstream code like the useGlobalGraph hook and
GlobalKnowledgeMap component can properly access the nodes and edges properties
without encountering undefined errors.

In `@web/app/atlas/page.tsx`:
- Around line 22-37: In the handleAnalyze function, setIsSubmitting(false) is
only called in the catch block. If router.push throws an error or navigation is
cancelled, the form will remain permanently disabled. Add a finally block to the
try-catch statement in handleAnalyze and move the setIsSubmitting(false) call
there to ensure the form state is always reset regardless of whether the
operation succeeds or fails.

In `@web/app/page.tsx`:
- Around line 3-13: The RootPage component has `export const dynamic =
'force-dynamic'` which forces server-side rendering on every request, but the
page has no dynamic data dependencies (no API calls, cookies, or
request-specific data). Either remove the dynamic export statement to allow
Next.js static optimization since the landing page should be static, or if
dynamic behavior is actually required, update the comment block above RootPage
to clearly document what dynamic requirements justify this setting.

In `@web/components/templates/console/ProcessingLog.tsx`:
- Around line 27-30: The handleCopy function doesn't handle the Promise returned
by navigator.clipboard.writeText(), which can reject due to permissions or
browser support issues. Make the handleCopy function async, await the
navigator.clipboard.writeText call, and wrap it in a try-catch block to
gracefully handle any failures (such as logging an error message or showing user
feedback when the clipboard write fails).
- Around line 98-99: The copy and download buttons in the ProcessingLog
component lack aria-label attributes, which reduces accessibility for screen
reader users. Although these buttons have title attributes for tooltips, screen
readers need explicit aria-label attributes. Add aria-label="Copy logs" to the
button with handleCopy onClick handler and aria-label="Download MD" to the
button with handleDownload('md') onClick handler to match the accessibility
pattern already used on the collapse button elsewhere in the component.
- Around line 32-46: The handleDownload function has a race condition where
URL.revokeObjectURL is called immediately after a.click(), but since a.click()
can be asynchronous in some browsers, the URL may be revoked before the browser
finishes fetching the Blob, causing silent download failures. Defer the
URL.revokeObjectURL(url) call to execute after a delay (e.g., using setTimeout
with a small timeout value like 100ms) to ensure the browser has sufficient time
to read the Blob before the object URL is revoked.

In `@web/components/ui/skeleton.tsx`:
- Line 3: The className concatenation in the Skeleton component at
web/components/ui/skeleton.tsx line 3 renders the string "undefined" as a CSS
class when the className prop is not provided. To fix this, replace the direct
template literal concatenation of the className prop with the cn utility
function (the standard shadcn/ui pattern for merging class names), which will
safely handle undefined values and prevent semantic noise in the rendered class
attribute.

In `@web/lib/stores/ui-state-context.tsx`:
- Line 1: The file ui-state-context.tsx uses client-side React APIs (useState,
useContext, createContext) but lacks the required 'use client' directive for
Next.js App Router. Add 'use client'; as the very first line of the file, before
any imports, to explicitly mark this as a Client Component and ensure it runs in
the browser environment.

---

Outside diff comments:
In `@worker/src/worker.ts`:
- Around line 418-425: The empty transcript validation check in the
analyze-llm-stream handler is returning HTTP status code 500, which incorrectly
signals an internal server error when the actual issue is a client-side
validation failure. Change the status code from 500 to 400 (Bad Request) in the
json response for the empty transcript check, as HTTP 400 is the semantically
correct status for invalid client input rather than server failures, which will
prevent false server-error alerts and avoid triggering unnecessary client
retries.
🪄 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

Run ID: 4fc5270a-7008-44b4-b30d-9fdf28369499

📥 Commits

Reviewing files that changed from the base of the PR and between 2cca14e and 33bc127.

📒 Files selected for processing (13)
  • docs/audit/10X_AUDIT_MASTER_CHECKLIST_2026_06_14.md
  • docs/audit/10X_PREFLIGHT_REPORT_2026_06_14.md
  • web/app/api/atlas/global-graph/route.ts
  • web/app/atlas/page.tsx
  • web/app/page.tsx
  • web/components/containers/DashboardContainer.tsx
  • web/components/templates/console/ProcessingLog.tsx
  • web/components/templates/console/VideoPlayerCard.tsx
  • web/components/ui/skeleton.tsx
  • web/hooks/useGlobalGraph.ts
  • web/lib/stores/ui-state-context.tsx
  • web/store/useVideoStore.ts
  • worker/src/worker.ts

Comment thread web/app/api/atlas/global-graph/route.ts
Comment thread web/app/atlas/page.tsx Outdated
Comment thread web/app/page.tsx Outdated
Comment thread web/components/templates/console/ProcessingLog.tsx Outdated
Comment thread web/components/templates/console/ProcessingLog.tsx
Comment thread web/components/templates/console/ProcessingLog.tsx Outdated
Comment thread web/components/ui/skeleton.tsx Outdated
Comment thread web/lib/stores/ui-state-context.tsx Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

16 issues found across 13 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="web/components/containers/DashboardContainer.tsx">

<violation number="1" location="web/components/containers/DashboardContainer.tsx:306">
P2: Skeleton dimension keys are not compatible with final dimension keys. After projection loads, persisted selection can point to a non-existent key and the detail panel loses auto-selection.</violation>
</file>

<file name="web/components/templates/console/ProcessingLog.tsx">

<violation number="1" location="web/components/templates/console/ProcessingLog.tsx:29">
P2: `navigator.clipboard.writeText()` returns a Promise that can reject (permissions denied, non-HTTPS, browser support). Without awaiting or catching it, failures are completely silent with no user feedback.</violation>

<violation number="2" location="web/components/templates/console/ProcessingLog.tsx:45">
P2: `URL.revokeObjectURL(url)` is called synchronously after `a.click()`. Since the browser reads the blob asynchronously, immediate revocation can race with the download fetch, causing silent failures in some browsers. Defer revocation with `setTimeout(() => URL.revokeObjectURL(url), 100)`.</violation>

<violation number="3" location="web/components/templates/console/ProcessingLog.tsx:98">
P2: New icon buttons miss `type="button"` and explicit accessible labels, causing possible accidental form submits and weaker accessibility.</violation>
</file>

<file name="web/app/page.tsx">

<violation number="1" location="web/app/page.tsx:3">
P2: `/` is forced to dynamic rendering despite being a static landing page. This adds avoidable per-request render overhead and prevents static cache optimization.</violation>
</file>

<file name="web/app/atlas/page.tsx">

<violation number="1" location="web/app/atlas/page.tsx:29">
P2: Navigation is blocked by awaiting a long-running stream operation. This keeps users on Atlas until analysis fully settles instead of moving to dashboard when analysis is initiated.</violation>
</file>

<file name="docs/audit/10X_PREFLIGHT_REPORT_2026_06_14.md">

<violation number="1" location="docs/audit/10X_PREFLIGHT_REPORT_2026_06_14.md:5">
P3: Recorded HEAD commit is not resolvable from the repository state. This weakens audit traceability for the report.</violation>
</file>

<file name="web/components/templates/console/VideoPlayerCard.tsx">

<violation number="1" location="web/components/templates/console/VideoPlayerCard.tsx:14">
P3: This change removes the last usage of `jumpToTimestamp`, leaving an unused store action. Dead store APIs add maintenance noise and can mislead future callers.</violation>
</file>

<file name="web/app/api/atlas/global-graph/route.ts">

<violation number="1" location="web/app/api/atlas/global-graph/route.ts:12">
P3: 401 now returns an array instead of the standard `{ error: ... }` object. This creates an inconsistent API contract for unauthorized errors.</violation>

<violation number="2" location="web/app/api/atlas/global-graph/route.ts:12">
P1: Inconsistent response shape on 401: returns `[]` instead of `{ nodes: [], edges: [] }`. The successful path and error fallback both return the `{ nodes, edges }` shape, but the 401 path returns a bare array. If the hook's error handling changes or another consumer reads this response, accessing `.nodes` on `[]` will be `undefined`, breaking downstream components.</violation>

<violation number="3" location="web/app/api/atlas/global-graph/route.ts:25">
P1: Catch path now returns 200, so fetch treats real server failures as successful "no data". This hides production errors and breaks client error handling based on response status.</violation>
</file>

<file name="web/lib/stores/ui-state-context.tsx">

<violation number="1" location="web/lib/stores/ui-state-context.tsx:18">
P2: New UI state context is never consumed, so the feature is effectively inactive dead code in this PR.</violation>

<violation number="2" location="web/lib/stores/ui-state-context.tsx:30">
P2: Provider `value` is not memoized, causing avoidable context-wide rerenders on parent/provider rerenders.</violation>
</file>

<file name="docs/audit/10X_AUDIT_MASTER_CHECKLIST_2026_06_14.md">

<violation number="1" location="docs/audit/10X_AUDIT_MASTER_CHECKLIST_2026_06_14.md:33">
P2: N18 row is factually outdated: no API GET `route.ts` currently uses `await import()` for Supabase. This can misdirect audit follow-up to the wrong file/status.</violation>

<violation number="2" location="docs/audit/10X_AUDIT_MASTER_CHECKLIST_2026_06_14.md:34">
P3: N19 row overstates current risk; tracing include is narrowly scoped in `next.config.ts`. Keeping it red as “broad includes” makes the audit status inaccurate.</violation>
</file>

<file name="web/components/ui/skeleton.tsx">

<violation number="1" location="web/components/ui/skeleton.tsx:3">
P2: When `className` is omitted, the template literal evaluates to `"...rounded-lg undefined"`, rendering the literal string "undefined" as a CSS class in the DOM. Use a fallback like `${className || ''}` or the `cn` utility for safe className merging.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread web/app/api/atlas/global-graph/route.ts Outdated
Comment thread web/app/api/atlas/global-graph/route.ts Outdated
// If projection isn't ready but we're analyzing, show all 11 as idle/streaming skeletons
if (!nucleus.projection && (status === 'analyzing' || status === 'downloading')) {
return Array.from({ length: 11 }, (_, i) => ({
key: `dim-skeleton-${i + 1}`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Skeleton dimension keys are not compatible with final dimension keys. After projection loads, persisted selection can point to a non-existent key and the detail panel loses auto-selection.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At web/components/containers/DashboardContainer.tsx, line 306:

<comment>Skeleton dimension keys are not compatible with final dimension keys. After projection loads, persisted selection can point to a non-existent key and the detail panel loses auto-selection.</comment>

<file context>
@@ -302,6 +300,20 @@ export function DashboardContainer({ profile }: DashboardContainerProps) {
+    // If projection isn't ready but we're analyzing, show all 11 as idle/streaming skeletons
+    if (!nucleus.projection && (status === 'analyzing' || status === 'downloading')) {
+      return Array.from({ length: 11 }, (_, i) => ({
+        key: `dim-skeleton-${i + 1}`,
+        label: DIMENSION_LABELS[i + 1] || `Dimension ${i + 1}`,
+        icon: DIMENSION_ICONS[i + 1] || "solar:bolt-linear",
</file context>
Suggested change
key: `dim-skeleton-${i + 1}`,
key: `dim-${i + 1}`,

Comment thread web/components/templates/console/ProcessingLog.tsx Outdated
Comment thread web/app/page.tsx Outdated
Comment thread web/components/ui/skeleton.tsx Outdated
Comment thread docs/audit/10X_PREFLIGHT_REPORT_2026_06_14.md
export function VideoPlayerCard() {
const playerRef = useRef<any>(null);
const { isPlaying, setPlaying, seekTo, jumpToTimestamp } = useVideoStore();
const { isPlaying, setPlaying, seekTo, clearSeek } = useVideoStore();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This change removes the last usage of jumpToTimestamp, leaving an unused store action. Dead store APIs add maintenance noise and can mislead future callers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At web/components/templates/console/VideoPlayerCard.tsx, line 14:

<comment>This change removes the last usage of `jumpToTimestamp`, leaving an unused store action. Dead store APIs add maintenance noise and can mislead future callers.</comment>

<file context>
@@ -11,7 +11,7 @@ const Player = dynamic(() => import('react-player'), { ssr: false }) as any;
 export function VideoPlayerCard() {
   const playerRef = useRef<any>(null);
-  const { isPlaying, setPlaying, seekTo, jumpToTimestamp } = useVideoStore();
+  const { isPlaying, setPlaying, seekTo, clearSeek } = useVideoStore();
   const videoMetadata = useAnalysisStore((s) => s.videoMetadata);
   const nucleusVideoId = useSynthesisNucleus((s) => s.analysis?.videoId);
</file context>

Comment thread web/app/api/atlas/global-graph/route.ts Outdated

if (authError || !user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
return NextResponse.json([], { status: 401 });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: 401 now returns an array instead of the standard { error: ... } object. This creates an inconsistent API contract for unauthorized errors.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At web/app/api/atlas/global-graph/route.ts, line 12:

<comment>401 now returns an array instead of the standard `{ error: ... }` object. This creates an inconsistent API contract for unauthorized errors.</comment>

<file context>
@@ -9,7 +9,7 @@ export async function GET() {
 
     if (authError || !user) {
-      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
+      return NextResponse.json([], { status: 401 });
     }
 
</file context>
Suggested change
return NextResponse.json([], { status: 401 });
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });

| **L2** | Snyk scans stale | Monorepo | ✅ | Resolved via package upgrades (June 10). |
| **L4** | Fragmented prompts | Monorepo | 🟡 | Centralization started in `cascade.ts`. |
| **N18**| Dynamic import in GET | `route.ts` | 🔴 | Still using `await import()` for Supabase. |
| **N19**| broad tracing includes | `next.config.ts` | 🔴 | Potentially bloating bundle. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: N19 row overstates current risk; tracing include is narrowly scoped in next.config.ts. Keeping it red as “broad includes” makes the audit status inaccurate.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/audit/10X_AUDIT_MASTER_CHECKLIST_2026_06_14.md, line 34:

<comment>N19 row overstates current risk; tracing include is narrowly scoped in `next.config.ts`. Keeping it red as “broad includes” makes the audit status inaccurate.</comment>

<file context>
@@ -0,0 +1,44 @@
+| **L2** | Snyk scans stale | Monorepo | ✅ | Resolved via package upgrades (June 10). |
+| **L4** | Fragmented prompts | Monorepo | 🟡 | Centralization started in `cascade.ts`. |
+| **N18**| Dynamic import in GET | `route.ts` | 🔴 | Still using `await import()` for Supabase. |
+| **N19**| broad tracing includes | `next.config.ts` | 🔴 | Potentially bloating bundle. |
+
+## NEW FINDINGS (FROM RECENT WORK)
</file context>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="web/components/templates/console/VideoPlayerCard.tsx">

<violation number="1" location="web/components/templates/console/VideoPlayerCard.tsx:14">
P3: This change removes the last usage of `jumpToTimestamp`, leaving an unused store action. Dead store APIs add maintenance noise and can mislead future callers.</violation>
</file>

<file name="web/lib/stores/ui-state-context.tsx">

<violation number="1" location="web/lib/stores/ui-state-context.tsx:18">
P2: New UI state context is never consumed, so the feature is effectively inactive dead code in this PR.</violation>
</file>

<file name="docs/audit/10X_AUDIT_MASTER_CHECKLIST_2026_06_14.md">

<violation number="1" location="docs/audit/10X_AUDIT_MASTER_CHECKLIST_2026_06_14.md:33">
P2: N18 row is factually outdated: no API GET `route.ts` currently uses `await import()` for Supabase. This can misdirect audit follow-up to the wrong file/status.</violation>

<violation number="2" location="docs/audit/10X_AUDIT_MASTER_CHECKLIST_2026_06_14.md:34">
P3: N19 row overstates current risk; tracing include is narrowly scoped in `next.config.ts`. Keeping it red as “broad includes” makes the audit status inaccurate.</violation>
</file>

<file name="web/components/containers/DashboardContainer.tsx">

<violation number="1" location="web/components/containers/DashboardContainer.tsx:306">
P2: Skeleton dimension keys are not compatible with final dimension keys. After projection loads, persisted selection can point to a non-existent key and the detail panel loses auto-selection.</violation>
</file>

<file name="web/app/api/atlas/global-graph/route.ts">

<violation number="1" location="web/app/api/atlas/global-graph/route.ts:12">
P3: 401 now returns an array instead of the standard `{ error: ... }` object. This creates an inconsistent API contract for unauthorized errors.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread web/app/atlas/page.tsx Outdated
@github-actions

Copy link
Copy Markdown

Pipeline Status: All checks passed. Ready to merge.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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 `@web/app/api/atlas/global-graph/route.ts`:
- Around line 22-26: The catch block in the error handling for the global graph
API endpoint is returning an inconsistent response shape. Instead of returning
`{ error: 'Internal server error' }`, it should return `{ nodes: [], edges: []
}` to match the 401 error response shape and align with PR objectives of
preventing dashboard crashes by returning empty graph data. Update the
NextResponse.json call in the catch block to return the empty graph structure
with empty nodes and edges arrays, maintaining consistency with the 401 error
handling path and ensuring the frontend can safely access the graph.nodes
property without encountering undefined.
🪄 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

Run ID: a85df1cb-f4ec-4dbb-9957-4e8e01ff2732

📥 Commits

Reviewing files that changed from the base of the PR and between 33bc127 and c9f6e0d.

📒 Files selected for processing (4)
  • web/app/api/atlas/global-graph/route.ts
  • web/app/page.tsx
  • web/components/templates/console/ProcessingLog.tsx
  • worker/src/worker.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🤖 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 `@web/app/api/atlas/global-graph/route.ts`:
- Around line 22-26: The catch block in the error handling for the global graph
API endpoint is returning an inconsistent response shape. Instead of returning
`{ error: 'Internal server error' }`, it should return `{ nodes: [], edges: []
}` to match the 401 error response shape and align with PR objectives of
preventing dashboard crashes by returning empty graph data. Update the
NextResponse.json call in the catch block to return the empty graph structure
with empty nodes and edges arrays, maintaining consistency with the 401 error
handling path and ensuring the frontend can safely access the graph.nodes
property without encountering undefined.
🪄 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

Run ID: a85df1cb-f4ec-4dbb-9957-4e8e01ff2732

📥 Commits

Reviewing files that changed from the base of the PR and between 33bc127 and c9f6e0d.

📒 Files selected for processing (4)
  • web/app/api/atlas/global-graph/route.ts
  • web/app/page.tsx
  • web/components/templates/console/ProcessingLog.tsx
  • worker/src/worker.ts
🛑 Comments failed to post (1)
web/app/api/atlas/global-graph/route.ts (1)

22-26: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

500 response shape inconsistent with PR objectives and 401 fix.

The PR objectives state the goal is to "prevent dashboard crashes when global graph API returns 401 or 500 errors by returning empty graph data instead of errors." The 401 path correctly returns { nodes: [], edges: [] }, but the 500 path returns { error: 'Internal server error' } which lacks nodes and edges properties. When useGlobalGraph receives this response, accessing graph.nodes will be undefined, causing the same crash pattern the 401 fix addresses.

Proposed fix
   } catch (error) {
     console.error('[atlas/global-graph] Processing error:', error);
-    // Return error status to allow telemetry to capture the failure
-    return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
+    // Return empty graph to prevent dashboard crashes; status 500 still signals failure for telemetry
+    return NextResponse.json({ nodes: [], edges: [] }, { status: 500 });
   }
🤖 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 `@web/app/api/atlas/global-graph/route.ts` around lines 22 - 26, The catch
block in the error handling for the global graph API endpoint is returning an
inconsistent response shape. Instead of returning `{ error: 'Internal server
error' }`, it should return `{ nodes: [], edges: [] }` to match the 401 error
response shape and align with PR objectives of preventing dashboard crashes by
returning empty graph data. Update the NextResponse.json call in the catch block
to return the empty graph structure with empty nodes and edges arrays,
maintaining consistency with the 401 error handling path and ensuring the
frontend can safely access the graph.nodes property without encountering
undefined.

@github-actions

Copy link
Copy Markdown

Pipeline Status: All checks passed. Ready to merge.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 5 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="docs/reference/PR_REVIEW_WORKFLOW_V2.md">

<violation number="1" location="docs/reference/PR_REVIEW_WORKFLOW_V2.md:93">
P2: Mandatory trigger line conflicts with ledger-first startup protocol; required order should be explicit.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

---

## ⚠️ MANDATORY TRIGGER
Invoke `/pr_review_workflow` (which points to this V2 spec) at the start of every session.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Mandatory trigger line conflicts with ledger-first startup protocol; required order should be explicit.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/reference/PR_REVIEW_WORKFLOW_V2.md, line 93:

<comment>Mandatory trigger line conflicts with ledger-first startup protocol; required order should be explicit.</comment>

<file context>
@@ -0,0 +1,93 @@
+---
+
+## ⚠️ MANDATORY TRIGGER
+Invoke `/pr_review_workflow` (which points to this V2 spec) at the start of every session.
</file context>
Suggested change
Invoke `/pr_review_workflow` (which points to this V2 spec) at the start of every session.
Invoke `/pr_review_workflow` (which points to this V2 spec) after reading/updating `.memory/AGENT_LEDGER.md` at the start of every session.

@github-actions

Copy link
Copy Markdown

Pipeline Status: All checks passed. Ready to merge.

@github-actions

Copy link
Copy Markdown

Pipeline Status: All checks passed. Ready to merge.

@github-actions

Copy link
Copy Markdown

Pipeline Status: All checks passed. Ready to merge.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 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="web/app/auth/signin/form.tsx">

<violation number="1" location="web/app/auth/signin/form.tsx:15">
P1: OAuth `next` param captures sign-in page path instead of the original referrer, causing post-auth redirect back to `/auth/signin`</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread web/app/auth/signin/form.tsx Outdated
@github-actions

Copy link
Copy Markdown

Pipeline Status: All checks passed. Ready to merge.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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 `@web/app/auth/callback/route.ts`:
- Around line 8-9: The `next` parameter in the callback route is user-controlled
and needs validation to prevent open redirect attacks. Remove the redundant
decodeURIComponent call since searchParams.get() already returns the decoded
value. Instead, validate that the next parameter is a safe relative path
(starting with / and not containing protocol characters like :) before using it
in the redirect. This prevents attackers from redirecting users to arbitrary
external domains after authentication. Apply this validation logic wherever the
next parameter is processed in the callback handler.

In `@web/app/auth/signin/form.tsx`:
- Line 15: The callbackUrl construction is missing URL encoding for the pathname
parameter. When window.location.pathname contains special characters like
spaces, ampersands, equals signs, or other URL-reserved characters, they will
not be properly escaped in the query string, causing malformed URLs or parameter
truncation. Wrap window.location.pathname with encodeURIComponent() before
inserting it into the next query parameter to ensure special characters are
properly encoded.

In `@web/components/templates/console/ProcessingLog.tsx`:
- Around line 100-101: The handleCopy button (line 100) and handleDownload
button (line 101) in ProcessingLog.tsx are using inline style props which
violates the repo's styling policy. Remove the style prop from both buttons and
replace the inline styles with equivalent Tailwind CSS classes: the transparent
background becomes bg-transparent, the removed border becomes border-none, the
muted text color becomes text-[var(--ink-muted)], and the pointer cursor becomes
cursor-pointer. Alternatively, consider using shadcn/ui Button components with
appropriate variants if they better align with the component library's design
patterns.
🪄 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

Run ID: e4919097-1372-4c34-851c-5d5a058cc623

📥 Commits

Reviewing files that changed from the base of the PR and between c9f6e0d and 689da6a.

📒 Files selected for processing (9)
  • docs/reference/PR_REVIEW_WORKFLOW_V2.md
  • web/app/api/atlas/global-graph/route.ts
  • web/app/atlas/page.tsx
  • web/app/auth/callback/route.ts
  • web/app/auth/signin/form.tsx
  • web/components/templates/console/ProcessingLog.tsx
  • web/components/ui/skeleton.tsx
  • web/lib/stores/ui-state-context.tsx
  • web/middleware.ts
💤 Files with no reviewable changes (1)
  • web/middleware.ts

Comment thread web/app/auth/callback/route.ts Outdated
Comment thread web/app/auth/signin/form.tsx Outdated
Comment thread web/components/templates/console/ProcessingLog.tsx Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="web/components/templates/console/VideoPlayerCard.tsx">

<violation number="1" location="web/components/templates/console/VideoPlayerCard.tsx:14">
P3: This change removes the last usage of `jumpToTimestamp`, leaving an unused store action. Dead store APIs add maintenance noise and can mislead future callers.</violation>
</file>

<file name="web/lib/stores/ui-state-context.tsx">

<violation number="1" location="web/lib/stores/ui-state-context.tsx:18">
P2: New UI state context is never consumed, so the feature is effectively inactive dead code in this PR.</violation>
</file>

<file name="docs/audit/10X_AUDIT_MASTER_CHECKLIST_2026_06_14.md">

<violation number="1" location="docs/audit/10X_AUDIT_MASTER_CHECKLIST_2026_06_14.md:33">
P2: N18 row is factually outdated: no API GET `route.ts` currently uses `await import()` for Supabase. This can misdirect audit follow-up to the wrong file/status.</violation>

<violation number="2" location="docs/audit/10X_AUDIT_MASTER_CHECKLIST_2026_06_14.md:34">
P3: N19 row overstates current risk; tracing include is narrowly scoped in `next.config.ts`. Keeping it red as “broad includes” makes the audit status inaccurate.</violation>
</file>

<file name="web/components/containers/DashboardContainer.tsx">

<violation number="1" location="web/components/containers/DashboardContainer.tsx:306">
P2: Skeleton dimension keys are not compatible with final dimension keys. After projection loads, persisted selection can point to a non-existent key and the detail panel loses auto-selection.</violation>
</file>

<file name="web/app/api/atlas/global-graph/route.ts">

<violation number="1" location="web/app/api/atlas/global-graph/route.ts:12">
P3: 401 now returns an array instead of the standard `{ error: ... }` object. This creates an inconsistent API contract for unauthorized errors.</violation>
</file>

<file name="docs/reference/PR_REVIEW_WORKFLOW_V2.md">

<violation number="1" location="docs/reference/PR_REVIEW_WORKFLOW_V2.md:93">
P2: Mandatory trigger line conflicts with ledger-first startup protocol; required order should be explicit.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread web/app/auth/callback/route.ts Outdated
Comment thread web/app/auth/callback/route.ts Outdated
Comment thread web/app/auth/callback/route.ts Outdated
@github-actions

Copy link
Copy Markdown

Pipeline Status: All checks passed. Ready to merge.

@github-actions

Copy link
Copy Markdown

Pipeline Status: All checks passed. Ready to merge.

@TechHypeXP
TechHypeXP merged commit 6addcb5 into main Jun 15, 2026
22 checks passed
@TechHypeXP
TechHypeXP deleted the feature/synthesis-log-ux branch June 15, 2026 07:33
TechHypeXP added a commit that referenced this pull request Jul 31, 2026
…80)

* fix: restore landing page and move atlas to authenticated route

* fix(ui): restore public landing page, isolate atlas, improve API resilience

* feat(ui): implement 11-dimension skeleton loaders and refine markdown streaming to prevent CLS

* fix(remediation): fix atlas API route, auth guard, and searchParams typing

* fix(ui): hard de-couple root route and restore public landing page

* feat(ux): implement synthesis log export, UI state context, and edge error hardening

* fix(atlas): remove unused store import

* fix(atlas): remove unused analysis store import

* fix: zero-trust manual override of P1/P2 violations

* fix: zero-trust manual override

* chore: add auth debugging

* fix(auth): preserve redirect path in oauth callback

* fix(auth): enforce strict server-side cookie exchange and path persistence

* fix(auth): implement strict same-origin sanitizer for oauth callback

* fix(auth): capture correct referrer and handle exchange exceptions

---------

Co-authored-by: Kelly Bakri <noreply@github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants