Skip to content

fix(multimodal): close post-merge review gaps (batch parity, pdf limits, url-secret redaction, supervisor identity) - #1211

Merged
murdore merged 1 commit into
releasefrom
fix/post-merge-review-gaps
Jul 20, 2026
Merged

murdore merged 1 commit into
releasefrom
fix/post-merge-review-gaps

Conversation

@murdore

@murdore murdore commented Jul 19, 2026 •

Copy link
Copy Markdown
Contributor

Summary

After the 13-PR multimodal/CLI/PDF/proxy batch merged into release, an audit of the review threads that were still unresolved at merge (re-review comments from Yama/CodeRabbit/Copilot on the rebased commits) surfaced 12 verified gaps still present in released code — adversarially verified against release, not just taken at face value. This PR closes all of them, plus the docs/nits, in one consolidated fix.

Fixes

Backward-compatibility (documented, not reverted) — 3 breaking changes shipped in 9.94.x–9.95.x are now documented in docs/MIGRATION.md with before/after + migration steps (see BREAKING CHANGE: footer):

  1. multimodal file/CSV processing is fail-loud (throws) instead of log-and-skip partial success;
  2. MessageContent dropped its open index signature (closed shape);
  3. BatchCommandArgs.file → .promptsFile.

CLI batch parity — neurolink batch previously dropped several inputs the generate/stream paths honor:

  • --pdf-password / NEUROLINK_PDF_PASSWORD was silently ignored → encrypted PDFs failed. Now wired via resolvePdfPassword.
  • --csv-max-rows wasn't fail-fast validated; --csv-encoding / --csv-sanitize-names / --csv-name-case / --csv-parse-timeout-ms were ignored → now built via the shared buildCsvOptionsFromArgv.
  • --pdf soft-warning fired at 100 MB while docs promise 50 MB → dedicated PDF_SOFT_MAX_MB = 50.

PDF hardening

  • Aggregate page-limit summed pageCount ?? 0, silently undercounting when a PDF's page count is unknown → now WARNs (enforcement still runs on the known sum; unknown-count PDFs aren't failed outright).
  • getAccuratePageCount never cleared its Promise.race timeout (dangling 5 s handle) and a throwing pdf.destroy() in finally discarded a valid count → timer is cleared/unref'd and destroy is guarded.

URL/secret handling

  • Cache-hit debug log leaked a raw presigned-URL prefix → uses redactUrlForError.
  • imageCache and fileDetector URL caches keyed on the full URL (secret query params persisted in in-memory Map keys) → a shared sensitive-param denylist strips them from cache keys.
  • URL pre-flight HEAD enforced maxSize without checking statusCode → non-2xx HEAD now falls through to the streaming GET guard.

Proxy — processLooksLikeProxySupervisor matched any process whose args merely contained neurolink → now requires both neurolink and the proxy subcommand before a stale/recycled pid could be signalled during uninstall.

Tests & validation

  • 8 new regression tests (batch pdf-password/csv validation/options, aggregate page-limit warn, HEAD non-2xx fall-through, page-count timer/destroy resilience, cache-key redaction, supervisor identity). Suite 225/225.
  • tsc --strict 0 errors · lint 0 errors · build:cli green · pre-commit gate (validate:all + full build) green.

Follow-up (out of scope, flagged)

pdf-parse (pinned pdfjs-dist@5.4.296) and pdf-to-img (pdfjs-dist@5.4.624) are separate installs; once PDFProcessor.convertToImages() runs in a process, subsequent real getAccuratePageCount() calls hit a pdfjs "API version does not match Worker version" error and degrade to null for the rest of the process. Pre-existing, not caused by these fixes — worth a follow-up ticket.

Summary by CodeRabbit

  • Bug Fixes

    • Improved PDF page-limit warnings when some page counts are unknown (now clearer about partial verification).
    • Hardened URL loading by ignoring oversized content-length from non-2xx HEAD responses.
    • Reduced proxy supervisor uninstall false positives with stricter PID identity/start-time checks.
    • Strengthened signed/presigned URL handling and cache-key behavior to avoid auth-context collisions and better redact sensitive query params in logs.
    • Improved batch CSV/PDF processing: CSV/PDF validation, PDF password reuse per batch, and a dedicated PDF soft warning threshold.
  • Documentation

    • Updated migration guidance for breaking changes (stricter CSV/file failures, closed message content shape, CLI batch args rename).
    • Clarified CSV encoding detection order/limitations and PDF conversion vs streaming behavior.

Copilot AI review requested due to automatic review settings July 19, 2026 20:12
@vercel

vercel Bot commented Jul 19, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
neurolink Ready Ready Preview, Comment Jul 19, 2026 10:54pm

@github-actions

github-actions Bot commented Jul 19, 2026 •

Copy link
Copy Markdown
Contributor

✅ Single Commit Policy - COMPLIANT

Status: Policy requirements met • 1 commit • Valid format • Ready for merge

📊 View validation details

📝 Commit Details

  • Hash: 72725352d0604bcd6cb0ef334639cbd588719ef9
  • Message: fix(multimodal): close post-merge review gaps (batch parity, pdf limits, url-secret redaction, supervisor identity)
  • Author: Sachin Sharma

✅ Validation Results

  • Single commit requirement met
  • No merge commits in branch
  • Semantic commit message format verified
  • Ready for squash merge to release branch

🤖 Automated validation by NeuroLink Single Commit Enforcement

@coderabbitai

coderabbitai Bot commented Jul 19, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR documents breaking API and CLI changes, strengthens batch and proxy validation, sanitizes URL-based cache keys, adjusts URL size preflight behavior, hardens PDF page counting, and adds regression tests covering these changes.

Changes

NeuroLink hardening and migration updates

Layer / File(s) Summary
Migration and feature documentation
docs/MIGRATION.md, docs/features/*
Documents fail-loud multimodal errors, the closed MessageContent shape, the promptsFile rename, CSV encoding detection, and PDF conversion behavior.
CLI option wiring and proxy detection
src/cli/commands/proxy.ts, src/cli/factories/commandFactory.ts, src/cli/utils/inputValidation.ts
Adds CSV row-limit validation, shared CSV/video option construction, reusable batch PDF passwords, a dedicated PDF warning threshold, and stricter proxy process matching with start-time validation.
URL cache and preflight hardening
src/lib/utils/logSanitize.ts, src/lib/utils/fileDetector.ts, src/lib/utils/imageCache.ts, src/lib/utils/imageProcessor.ts
Removes sensitive query parameters from cache keys while preserving auth-context separation, ignores non-2xx HEAD size metadata, and redacts cached-image URLs.
PDF page counting and aggregate validation
src/lib/utils/messageBuilder.ts, src/lib/utils/pdfProcessor.ts
Warns when aggregate PDF page counts are incomplete, clears page-count timers, and tolerates cleanup failures.
Regression coverage
test/continuous-test-suite-bugfixes.ts
Verifies CLI wiring, proxy identity checks, PDF behavior, URL preflight handling, and cache-key sanitization.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels: released

Suggested reviewers: tara-ag

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: batch parity, PDF limits, URL redaction, and supervisor identity hardening.
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.
✨ 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 fix/post-merge-review-gaps

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.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@github-actions

github-actions Bot commented Jul 19, 2026 •

Copy link
Copy Markdown
Contributor

Documentation Validation Results

🚀 Documentation validation passed!

Check Status Result
Frontmatter Validation ✅ Passed
TypeScript Check ✅ Passed
Build ✅ Passed
Link Validation ✅ Passed

📦 Build artifact uploaded successfully. Ready for deployment preview.

Commit: 5dcc1e41f53c1ef8e5a7efa9eeb3b566145916a5 | Workflow: View logs

Copilot AI 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.

Pull request overview

This PR addresses a set of post-merge audit gaps across multimodal handling, CLI batch parity, PDF hardening, and URL secret hygiene, and adds targeted regression tests plus documentation of recently shipped breaking changes.

Changes:

  • Aligns neurolink batch with generate/stream for CSV validation/options and PDF password wiring; adjusts PDF warning threshold to match docs.
  • Hardens PDF page counting (timer cleanup, destroy-guard) and adds an aggregate page-limit WARN when page counts are unknown.
  • Improves URL handling (redacted cached-image log; strips sensitive query params from URL cache keys) and tightens proxy supervisor process identification; adds migration/docs updates and regression tests.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/continuous-test-suite-bugfixes.ts Adds regression tests covering batch parity, URL cache key redaction, PDF page-limit/page-count edge cases, and proxy supervisor identity.
src/lib/utils/pdfProcessor.ts Fixes timer cleanup and makes destroy() cleanup non-fatal for accurate page counting; clarifies streaming conversion docs.
src/lib/utils/messageBuilder.ts WARNs when aggregate PDF page-limit verification is partial due to unknown page counts.
src/lib/utils/logSanitize.ts Introduces shared sensitive query-param denylist + helper to strip them from URL objects for long-lived cache keys.
src/lib/utils/imageProcessor.ts Redacts URL in cached-image debug log; expands minimum-valid-image-size documentation.
src/lib/utils/imageCache.ts Strips sensitive query params from URL-based cache keys to avoid persisting secrets in-memory.
src/lib/utils/fileDetector.ts Strips sensitive query params from URL content-type cache keys; avoids trusting content-length from non-2xx HEAD responses.
src/cli/utils/inputValidation.ts Adds PDF_SOFT_MAX_MB=50 and uses it for --pdf warning threshold.
src/cli/factories/commandFactory.ts Wires batch CSV max-rows validation, shared CSV options builder, and PDF password options into batch runs.
src/cli/commands/proxy.ts Tightens supervisor PID verification (requires neurolink and proxy in args) and exports helper for testing.
docs/MIGRATION.md Documents breaking changes shipped in 9.94.x–9.95.x with before/after and migration guidance.
docs/features/pdf-support.md Clarifies that convertToImages() is not a wrapper over convertToImagesStream().
docs/features/csv-support.md Clarifies encoding detection order and performance characteristics.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/continuous-test-suite-bugfixes.ts Outdated
Comment thread test/continuous-test-suite-bugfixes.ts Outdated
Comment thread src/lib/utils/logSanitize.ts
Comment thread src/lib/utils/imageCache.ts Outdated

@Tara-ag Tara-ag 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.

Review Summary

Files reviewed: 13
New issues raised: 3 (1 MAJOR, 2 MINOR)
Blocking issues: 0

Findings

  • MAJOR — docs/MIGRATION.md: The doc retroactively documents three breaking changes, which is helpful. However, CLAUDE.md Critical Rule 5 states the public SDK API must not break existing callers. Consider adding a policy note that future breaking changes require pre-shipping migration docs, and evaluate whether MessageContent should retain a deprecated index signature for one minor cycle to ease adoption.

  • MINOR — src/cli/factories/commandFactory.ts: executeBatch still constructs videoOptions inline rather than using a shared helper like buildCsvOptionsFromArgv/resolvePdfPassword. Extracting buildVideoOptionsFromArgv(argv) would reduce drift across generate/stream/batch.

  • MINOR — src/cli/commands/proxy.ts: processLooksLikeProxySupervisor is a meaningful hardening step, but remains regex-based over ps output. Consider a follow-up with a stronger identity signal (startTime cross-check against ProxySupervisorState.startTime, or a nonce verified via /proc/<pid>/environ / ps -o lstart=).

What looks good

  • Secret redaction is now applied to long-lived cache keys (ImageCache, FileDetector URL cache), not just logs.
  • URL pre-flight HEAD correctly ignores non-2xx content-length and falls through to the streaming GET guard.
  • getAccuratePageCount clears its race timer and guards a throwing pdf.destroy().
  • Batch parity fixes wire pdfOptions.password and the full csvOptions shape.
  • Eight focused regression tests cover the claimed gaps.

No hardcoded secrets, injection vectors, or other critical security issues were introduced. Approving with inline comments for the author to address at their discretion.

Comment thread docs/MIGRATION.md
Comment thread src/cli/factories/commandFactory.ts
Comment thread src/cli/commands/proxy.ts Outdated

@coderabbitai coderabbitai 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.

Caution

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

⚠️ Outside diff range comments (2)
src/lib/utils/fileDetector.ts (1)

1959-1969: 🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

Redact the URL and error message before logging.

The HEAD pre-flight error log currently surfaces the full, unredacted url, as well as a raw error message which may also embed the URL if thrown by the HTTP client. Based on learnings, full URL strings must never be logged or surfaced; they should be sanitized with redactUrlForError() to prevent leaking presigned authentication tokens. Additionally, you can use sanitizeErrorCause(error).message to safely extract the error text without leaking URLs.

🔒️ Proposed fix
       } catch (error) {
         if (error instanceof Error && /File too large/.test(error.message)) {
           throw error;
         }
         logger.debug(
-          `[FileDetector] HEAD pre-flight skipped for ${url}: ${
-            error instanceof Error ? error.message : String(error)
-          }`,
+          `[FileDetector] HEAD pre-flight skipped for ${redactUrlForError(url)}: ${
+            sanitizeErrorCause(error).message
+          }`,
         );
       }
🤖 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/utils/fileDetector.ts` around lines 1959 - 1969, Update the HEAD
pre-flight catch block in file detection to redact both logged values: pass url
through redactUrlForError() and derive the error text from
sanitizeErrorCause(error).message instead of directly using the raw error
message or String(error). Keep the existing File too large rethrow behavior
unchanged.

Source: Learnings

src/cli/factories/commandFactory.ts (1)

4711-4716: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Batch resolves --pdf-password once per prompt, not once per run.

batchPdfFiles (and images/csv/video) are resolved once before the loop, but resolvePdfPassword(argv) is called fresh inside runBatchGenerate on every iteration — so a multi-prompt batch with --pdf-password prints the "visible in shell history" stderr warning once per prompt instead of once for the whole run.

🔇 Proposed fix: hoist password resolution alongside the other batch file variables
       const batchVideoFiles = CLICommandFactory.processCliVideoFiles(
         argv.video as string | string[] | undefined,
       );
+      const batchPdfPassword = CLICommandFactory.resolvePdfPassword(argv);
               ...(batchPdfFiles?.length && {
                 pdfOptions: {
-                  password: CLICommandFactory.resolvePdfPassword(argv),
+                  password: batchPdfPassword,
                 },
               }),

Also applies to: 4866-4870

🤖 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/cli/factories/commandFactory.ts` around lines 4711 - 4716, Resolve the
PDF password once when initializing batch inputs alongside batchPdfFiles,
batchVideoFiles, and the other processed files. Update runBatchGenerate to
accept and reuse that resolved password for every prompt, removing the
per-iteration resolvePdfPassword(argv) call while preserving existing password
behavior.
🧹 Nitpick comments (1)
src/lib/utils/pdfProcessor.ts (1)

294-340: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the shared withTimeout helper here.
The manual Promise.race is fine, but src/lib/utils/async/withTimeout.ts already handles the timeout cleanup. Using it here would keep this pattern consistent and avoid reintroducing the same timer-leak bug later.

🤖 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/utils/pdfProcessor.ts` around lines 294 - 340, The manual
Promise.race timeout in getAccuratePageCount should be replaced with the shared
withTimeout helper from the async utilities. Reuse that helper around
pdf.getInfo(), remove the local timeoutHandle and related timer setup/cleanup,
and preserve the existing PDF destroy cleanup and page-count fallback behavior.

Source: Coding guidelines

🤖 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.

Outside diff comments:
In `@src/cli/factories/commandFactory.ts`:
- Around line 4711-4716: Resolve the PDF password once when initializing batch
inputs alongside batchPdfFiles, batchVideoFiles, and the other processed files.
Update runBatchGenerate to accept and reuse that resolved password for every
prompt, removing the per-iteration resolvePdfPassword(argv) call while
preserving existing password behavior.

In `@src/lib/utils/fileDetector.ts`:
- Around line 1959-1969: Update the HEAD pre-flight catch block in file
detection to redact both logged values: pass url through redactUrlForError() and
derive the error text from sanitizeErrorCause(error).message instead of directly
using the raw error message or String(error). Keep the existing File too large
rethrow behavior unchanged.

---

Nitpick comments:
In `@src/lib/utils/pdfProcessor.ts`:
- Around line 294-340: The manual Promise.race timeout in getAccuratePageCount
should be replaced with the shared withTimeout helper from the async utilities.
Reuse that helper around pdf.getInfo(), remove the local timeoutHandle and
related timer setup/cleanup, and preserve the existing PDF destroy cleanup and
page-count fallback behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 222c1419-96e6-449b-aad4-fec753fd29b9

📥 Commits

Reviewing files that changed from the base of the PR and between a7ec8c7 and 506fc3c.

📒 Files selected for processing (13)
  • docs/MIGRATION.md
  • docs/features/csv-support.md
  • docs/features/pdf-support.md
  • src/cli/commands/proxy.ts
  • src/cli/factories/commandFactory.ts
  • src/cli/utils/inputValidation.ts
  • src/lib/utils/fileDetector.ts
  • src/lib/utils/imageCache.ts
  • src/lib/utils/imageProcessor.ts
  • src/lib/utils/logSanitize.ts
  • src/lib/utils/messageBuilder.ts
  • src/lib/utils/pdfProcessor.ts
  • test/continuous-test-suite-bugfixes.ts

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@coderabbitai coderabbitai 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.

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 `@src/cli/factories/commandFactory.ts`:
- Around line 4876-4885: Hoist CLICommandFactory.resolvePdfPassword(argv) out of
the per-prompt loop in runBatchGenerate, storing its result in a batch-scoped
value before iteration. Update the batch pdfOptions construction to reuse that
cached password, ensuring the warning is emitted only once while preserving the
existing PDF option behavior.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b3da4697-c08e-4667-b54a-870a38c46061

📥 Commits

Reviewing files that changed from the base of the PR and between 506fc3c and da03092.

📒 Files selected for processing (13)
  • docs/MIGRATION.md
  • docs/features/csv-support.md
  • docs/features/pdf-support.md
  • src/cli/commands/proxy.ts
  • src/cli/factories/commandFactory.ts
  • src/cli/utils/inputValidation.ts
  • src/lib/utils/fileDetector.ts
  • src/lib/utils/imageCache.ts
  • src/lib/utils/imageProcessor.ts
  • src/lib/utils/logSanitize.ts
  • src/lib/utils/messageBuilder.ts
  • src/lib/utils/pdfProcessor.ts
  • test/continuous-test-suite-bugfixes.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • docs/features/pdf-support.md
  • src/cli/utils/inputValidation.ts
  • src/lib/utils/messageBuilder.ts
  • docs/MIGRATION.md
  • src/lib/utils/pdfProcessor.ts
  • docs/features/csv-support.md
  • src/lib/utils/imageCache.ts
  • src/lib/utils/fileDetector.ts
  • src/lib/utils/imageProcessor.ts

Comment thread src/cli/factories/commandFactory.ts
@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@Tara-ag Tara-ag 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.

Review Summary

Files reviewed: 13
New issues raised this run: 0 (one existing unresolved CRITICAL comment remains)
Blocking issues: 1

Blocking issue

  • 🔒 CRITICAL — src/lib/utils/fileDetector.ts:1961: The HEAD pre-flight catch block still logs the raw url, including presigned-URL query tokens/signatures. This contradicts the URL-secret hardening goal of this PR and violates the secret-exposure blocking criterion. The GET error path below already redacts correctly; the HEAD catch should use the same redactUrlForError(url) + sanitizeErrorCause(error).message pattern. This issue is already tracked in the pending inline comment and must be fixed before merge.

Previously raised issues

All other points from earlier review rounds ( brittle source-scan windows, GCS denylist, cache-key collision, retroactive migration docs, shared buildVideoOptionsFromArgv, proxy start-time cross-check, and per-prompt PDF-password resolution) have been addressed by the author.

What looks good

  • Batch parity fixes wire the full csvOptions shape, validate --csv-max-rows, and resolve the PDF password once per run.
  • URL cache keys now strip sensitive query params while keeping distinct auth contexts distinct via the hash suffix.
  • Non-2xx HEAD responses no longer trust misleading content-length.
  • PDF page-count race timer is cleared and destroy() failures are guarded.
  • Proxy supervisor identity is hardened with both arg matching and start-time cross-check.
  • Regression tests cover the claimed gaps.

Please redact the HEAD pre-flight debug log, then this is good to approve.

Comment thread src/lib/utils/fileDetector.ts
@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (2)
src/lib/utils/logSanitize.ts (1)

260-279: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider adding missing AWS SigV4 parameters to the denylist.

The denylist includes all auxiliary parameters for GCP V4 signatures (e.g., x-goog-algorithm, x-goog-date, x-goog-expires), but omits the corresponding AWS SigV4 auxiliary parameters. While these are not strictly sensitive secrets like the signature itself, adding them ensures consistency and prevents these variable, auth-related parameters from persisting in plaintext within the cache key.

💡 Proposed consistency improvement
 export const SENSITIVE_URL_QUERY_PARAM_DENYLIST: readonly string[] = [
   "token",
   "signature",
   "x-amz-signature",
   "x-amz-credential",
   "x-amz-security-token",
+  "x-amz-algorithm",
+  "x-amz-date",
+  "x-amz-expires",
+  "x-amz-signedheaders",
   "awsaccesskeyid",
   "expires",
   "sig",
🤖 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/utils/logSanitize.ts` around lines 260 - 279, Update
SENSITIVE_URL_QUERY_PARAM_DENYLIST to include the missing AWS SigV4 auxiliary
query parameters, specifically the X-Amz algorithm, date, expires, and signed
headers keys, matching the existing lowercase naming convention and the
corresponding GCP entries.
src/lib/utils/pdfProcessor.ts (1)

300-321: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add unref support to withTimeout, then use it here. This path needs the timer detached from process liveness; the shared helper currently clears it, but not unref().

🤖 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/utils/pdfProcessor.ts` around lines 300 - 321, Update the shared
withTimeout helper to call unref() on its timer when supported, then refactor
the page-count timeout flow around pdf.getInfo() to use withTimeout instead of
creating and clearing a local timer. Preserve the existing timeout duration,
error behavior, and total-value validation while removing the duplicated
timeoutHandle management.

Source: Coding guidelines

🤖 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.

Nitpick comments:
In `@src/lib/utils/logSanitize.ts`:
- Around line 260-279: Update SENSITIVE_URL_QUERY_PARAM_DENYLIST to include the
missing AWS SigV4 auxiliary query parameters, specifically the X-Amz algorithm,
date, expires, and signed headers keys, matching the existing lowercase naming
convention and the corresponding GCP entries.

In `@src/lib/utils/pdfProcessor.ts`:
- Around line 300-321: Update the shared withTimeout helper to call unref() on
its timer when supported, then refactor the page-count timeout flow around
pdf.getInfo() to use withTimeout instead of creating and clearing a local timer.
Preserve the existing timeout duration, error behavior, and total-value
validation while removing the duplicated timeoutHandle management.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 16e82ffa-376f-4256-b76b-c0f56720f15e

📥 Commits

Reviewing files that changed from the base of the PR and between da03092 and 3a4d17b.

📒 Files selected for processing (13)
  • docs/MIGRATION.md
  • docs/features/csv-support.md
  • docs/features/pdf-support.md
  • src/cli/commands/proxy.ts
  • src/cli/factories/commandFactory.ts
  • src/cli/utils/inputValidation.ts
  • src/lib/utils/fileDetector.ts
  • src/lib/utils/imageCache.ts
  • src/lib/utils/imageProcessor.ts
  • src/lib/utils/logSanitize.ts
  • src/lib/utils/messageBuilder.ts
  • src/lib/utils/pdfProcessor.ts
  • test/continuous-test-suite-bugfixes.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • docs/features/pdf-support.md
  • docs/MIGRATION.md
  • src/lib/utils/imageCache.ts
  • src/cli/utils/inputValidation.ts
  • src/lib/utils/imageProcessor.ts
  • src/lib/utils/fileDetector.ts
  • src/lib/utils/messageBuilder.ts
  • src/cli/commands/proxy.ts
  • docs/features/csv-support.md
  • src/cli/factories/commandFactory.ts

@Tara-ag Tara-ag 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.

Review Summary

Reviewed the 13 changed files in PR #1211. Loaded existing review comments first; no duplicate points were raised.

New issues found

Raised 6 inline comments across 6 files:

  • src/cli/commands/proxy.ts — getProcessStartTime uses execFileSync inside an async function, blocking the event loop during uninstall and lacking a timeout bound. Suggested switching to async execFile wrapped with withTimeout.
  • src/cli/factories/commandFactory.ts — Batch pdfOptions is constructed with a possibly-undefined password, creating a subtle inconsistency with generate/stream. Suggested aligning the conditional construction.
  • src/lib/utils/logSanitize.ts — The URL param denylist includes overly broad generic names (token, signature, expires) that are also common non-secret query params, risking incorrect cache-key normalization. Suggested narrowing to provider-specific/auth-shaped params.
  • src/lib/utils/fileDetector.ts — cacheKeyForUrl strips sensitive params but does not strip tracking params, so URLs differing only by tracking params get distinct cache keys unlike ImageCache.
  • src/lib/utils/imageCache.ts — The content-hash dedup index is overwritten to the newest URL, making the older mapping unreachable; suggested keeping the oldest/stablest mapping.
  • src/lib/utils/messageBuilder.ts — Aggregate PDF page-limit warning does not name which file(s) had unknown page counts, making the log less actionable.

Also left a confirmation note on src/lib/utils/pdfProcessor.ts that the race-timer/destroy fix is logically sound.

Blocking assessment

None of the newly raised issues meet the formal blocking criteria in the project standards: no hardcoded secrets, no critical security vulnerability, no new backward-compatibility break, no non-negotiable CLAUDE.md rule violation, and fewer than 3 MAJOR issues. The PR consolidates legitimate post-merge fixes and adds regression tests.

Recommendation

Approve. The two highest-impact items to address in a follow-up are the async ps call in proxy.ts and the breadth of the URL param denylist in logSanitize.ts.

Comment thread src/cli/commands/proxy.ts
Comment thread src/cli/factories/commandFactory.ts
Comment thread src/lib/utils/logSanitize.ts
Comment thread src/lib/utils/fileDetector.ts
Comment thread src/lib/utils/imageCache.ts Outdated
Comment thread src/lib/utils/messageBuilder.ts
Comment thread src/lib/utils/pdfProcessor.ts
@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
test/continuous-test-suite-bugfixes.ts (1)

8338-8374: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Reduce flakiness of the ps-based proxy-supervisor tests. Both tests spawn children, wait a fixed 300 ms, then rely on ps (readPsField/getProcessStartTime) to observe args and start time; under CI load the child args may not be visible within 300 ms, and on platforms lacking ps the assertions fail rather than skip.

  • test/continuous-test-suite-bugfixes.ts#L8338-L8374: replace the fixed 300 ms sleep with a bounded poll until readPsField(pid, "args") returns the expected args (or a timeout), and gate the test on ps availability.
  • test/continuous-test-suite-bugfixes.ts#L8375-L8427: apply the same readiness poll/ps gate, and confirm PROXY_SUPERVISOR_START_TIME_TOLERANCE_MS comfortably exceeds the drift between millisecond new Date().toISOString() and the second-granularity ps -o lstart= value so closeMatch cannot flake.
🤖 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 `@test/continuous-test-suite-bugfixes.ts` around lines 8338 - 8374, In
test/continuous-test-suite-bugfixes.ts:8338-8374, replace the fixed delay in the
processLooksLikeProxySupervisor test with a bounded readiness poll using
readPsField(pid, "args"), and skip or otherwise gate the test when ps is
unavailable. Apply the same poll and ps-availability gate to the test at
test/continuous-test-suite-bugfixes.ts:8375-8427, and ensure
PROXY_SUPERVISOR_START_TIME_TOLERANCE_MS is comfortably larger than the
millisecond-to-second timestamp precision drift so
getProcessStartTime/closeMatch remains stable.
🤖 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.

Nitpick comments:
In `@test/continuous-test-suite-bugfixes.ts`:
- Around line 8338-8374: In test/continuous-test-suite-bugfixes.ts:8338-8374,
replace the fixed delay in the processLooksLikeProxySupervisor test with a
bounded readiness poll using readPsField(pid, "args"), and skip or otherwise
gate the test when ps is unavailable. Apply the same poll and ps-availability
gate to the test at test/continuous-test-suite-bugfixes.ts:8375-8427, and ensure
PROXY_SUPERVISOR_START_TIME_TOLERANCE_MS is comfortably larger than the
millisecond-to-second timestamp precision drift so
getProcessStartTime/closeMatch remains stable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 51391caf-0cad-421e-88d1-f81ba4fd8d34

📥 Commits

Reviewing files that changed from the base of the PR and between 3a4d17b and dba96e3.

📒 Files selected for processing (13)
  • docs/MIGRATION.md
  • docs/features/csv-support.md
  • docs/features/pdf-support.md
  • src/cli/commands/proxy.ts
  • src/cli/factories/commandFactory.ts
  • src/cli/utils/inputValidation.ts
  • src/lib/utils/fileDetector.ts
  • src/lib/utils/imageCache.ts
  • src/lib/utils/imageProcessor.ts
  • src/lib/utils/logSanitize.ts
  • src/lib/utils/messageBuilder.ts
  • src/lib/utils/pdfProcessor.ts
  • test/continuous-test-suite-bugfixes.ts
🚧 Files skipped from review as they are similar to previous changes (12)
  • src/lib/utils/messageBuilder.ts
  • docs/MIGRATION.md
  • src/lib/utils/imageCache.ts
  • src/lib/utils/imageProcessor.ts
  • src/lib/utils/logSanitize.ts
  • docs/features/csv-support.md
  • docs/features/pdf-support.md
  • src/cli/utils/inputValidation.ts
  • src/lib/utils/pdfProcessor.ts
  • src/lib/utils/fileDetector.ts
  • src/cli/factories/commandFactory.ts
  • src/cli/commands/proxy.ts

@Tara-ag Tara-ag 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.

Review Summary

Files reviewed: 13
New issues raised this run: 0
Existing unresolved MAJOR issue: 1

Blocking issue

  • ⚠️ MAJOR — src/cli/commands/proxy.ts:256: getProcessStartTime parses ps -o lstart= output with new Date(out) without accounting for the system's local timezone. The lstart value is emitted in local time, while the persisted expectedStartTimeIso is an ISO 8601 UTC string. On any machine not running UTC, the two Date objects will differ by the timezone offset (e.g., 5.5 hours for IST), causing driftMs to exceed the 10 s tolerance and processLooksLikeProxySupervisor to return false for a legitimate supervisor. During uninstall this leaves the real supervisor running and orphans its socket.

    This issue is already tracked in the pending inline comment at src/cli/commands/proxy.ts:256. The fix is to append the current local timezone offset to the lstart output before parsing, so both timestamps resolve to the same absolute instant.

Previously addressed issues

All other review points from earlier rounds have been resolved by the author:

  • Batch parity: --pdf-password / NEUROLINK_PDF_PASSWORD is now resolved once per run and wired into pdfOptions; --csv-max-rows is validated; full csvOptions and videoOptions are built via shared helpers.
  • PDF hardening: aggregate page-limit warns when page counts are unknown; getAccuratePageCount clears its race timer and guards a throwing pdf.destroy().
  • URL/secret handling: cache-hit debug log is redacted; ImageCache and FileDetector URL caches strip sensitive query params and fold a hash of the stripped values into the key to avoid cross-auth-context collisions; non-2xx HEAD responses no longer trust misleading content-length.
  • Proxy supervisor identity now requires both "neurolink" and "proxy" in args and cross-checks OS-reported start time.
  • Breaking changes are documented in docs/MIGRATION.md with a policy note for future changes.
  • Eight focused regression tests cover the claimed gaps.

Recommendation

Please fix the getProcessStartTime timezone parsing issue, then this is good to approve.

Comment thread src/cli/commands/proxy.ts
@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@Tara-ag Tara-ag 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.

Review Summary

Reviewed all 13 changed files. The PR addresses real post-merge gaps and the test coverage is welcome, but two critical issues and three major issues remain that must be fixed before merge.

New blocking issues raised

CRITICAL (2)

  1. src/cli/commands/proxy.ts:256 — getProcessStartTime builds a local-time Date and compares it directly against a UTC ISO timestamp. On non-UTC hosts the drift will exceed the tolerance and uninstall will fail to stop a legitimate supervisor, orphaning its socket.
  2. src/lib/utils/fileDetector.ts:1966 — The HEAD pre-flight catch swallows all non-size errors at debug level, including TLS/DNS/network anomalies, allowing a malicious or misconfigured endpoint to force a full streaming GET and bypass the size guard.

MAJOR (3)

  1. src/cli/commands/proxy.ts:210 — readPsField re-imports node:child_process/node:util and re-promisifies execFile on every call; should be module-level and use ErrorFactory typed errors consistently.
  2. src/cli/commands/proxy.ts:310 — processLooksLikeProxySupervisor is exported solely for the regression test, exposing internal uninstall-path logic as public API.
  3. src/lib/utils/logSanitize.ts:278 — The sensitive-param denylist includes overly broad generic names (token, signature, expires) that are commonly ordinary content-varying query params, creating a semantic mismatch and unnecessary cache-key mutation.

MINOR (5)

  • src/lib/utils/logSanitize.ts:340 — case-insensitive stripping mutates original param casing without documenting it.
  • src/lib/utils/fileDetector.ts:86 — cacheKeyForUrl and ImageCache.normalizeUrl should share a single normalizeUrlForCache helper to prevent future drift.
  • src/cli/factories/commandFactory.ts:4885 — batch pdfOptions construction is inconsistent with generate/stream; consider a shared buildPdfOptionsFromArgv helper.
  • src/lib/utils/messageBuilder.ts:1326 — aggregate page-limit warning logs raw filenames (caller-controlled data); consider basenaming or documenting.
  • test/continuous-test-suite-bugfixes.ts:7780 — several new tests rely on source-code string matching, which is fragile; prefer behavioral assertions where feasible.

Decision

REQUEST_CHANGES — the two CRITICAL issues (supervisor identity timezone bug and silent HEAD failure bypass) and three MAJOR issues meet the blocking criteria. Once these are addressed, the remaining MINOR items can be handled at the author's discretion.

Comment thread src/cli/commands/proxy.ts
Comment thread src/cli/commands/proxy.ts
Comment thread src/cli/commands/proxy.ts
Comment thread src/lib/utils/logSanitize.ts
Comment thread src/lib/utils/logSanitize.ts
Comment thread src/lib/utils/fileDetector.ts
Comment thread src/lib/utils/fileDetector.ts
Comment thread src/cli/factories/commandFactory.ts
Comment thread src/lib/utils/messageBuilder.ts
Comment thread test/continuous-test-suite-bugfixes.ts
…ts, url-secret redaction, supervisor identity)

Closes 12 post-merge review gaps found across PRs #1191/#1195/#1201/#1202/#1203:

- imageProcessor.ts: redact URLs in cache-hit debug logs; document
  MIN_VALID_IMAGE_SIZE threshold derivation.
- logSanitize.ts: shared SENSITIVE_URL_QUERY_PARAM_DENYLIST +
  stripSensitiveUrlParams(), reused by imageCache.ts's normalizeUrl so
  cache keys (not just logs) don't retain signed-URL secrets.
- fileDetector.ts: dedicated cacheKeyForUrl() helper for the URL
  content-type cache; loadFromURL no longer trusts a non-2xx HEAD's
  Content-Length for the size gate, falling through to the GET guard
  instead of over-rejecting.
- commandFactory.ts: executeBatch now validates --csv-max-rows and wires
  csvOptions/pdfOptions.password into runBatchGenerate via the same
  buildCsvOptionsFromArgv/resolvePdfPassword helpers generate/stream use
  (previously silently dropped on batch).
- inputValidation.ts: added PDF_SOFT_MAX_MB soft-limit warning, separate
  from the existing PDF_MAX_MB hard limit.
- pdfProcessor.ts: getAccuratePageCount now clears its race-timer when
  getInfo() wins (was left dangling for PAGE_COUNT_TIMEOUT_MS every
  call), and a throwing pdf.destroy() no longer discards an
  already-obtained page count; convertToImagesStream's JSDoc no longer
  falsely claims to be a wrapper over convertToImages.
- messageBuilder.ts: the aggregate PDF page-limit check now warns when
  any attached file's page count is unknown instead of silently
  undercounting the combined total.
- proxy.ts: processLooksLikeProxySupervisor (exported for testability)
  now requires both 'neurolink' and 'proxy' in the process args, not
  'neurolink' alone, to identify the proxy supervisor process.
- docs/features/csv-support.md, docs/features/pdf-support.md: corrected
  encoding-detection ordering and the convertToImages batch-wrapper claim.
- docs/MIGRATION.md: new — documents the three breaking changes shipped
  in 9.94.x-9.95.x with before/after examples and adaptation guidance.

Adds 8 regression tests to test/continuous-test-suite-bugfixes.ts
covering all of the above (225/225 passing, up from 217).

BREAKING CHANGE: three breaking changes shipped earlier in 9.94.x-9.95.x
are now documented in docs/MIGRATION.md: (1) multimodal file/CSV
processing is fail-loud since v9.94.6 (throws ErrorFactory.fileProcessingFailed
/csvProcessingFailed instead of log-and-skip), (2) MessageContent
(src/lib/types/multimodal.ts) dropped its open index signature since
v9.94.6 (closed shape, TS2353 on unknown fields), (3) BatchCommandArgs.file
was renamed to .promptsFile since v9.95.1. No further behavior changes to
these three in this commit — this commit only adds the migration doc.
@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (3)
src/lib/utils/logSanitize.ts (3)

309-313: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Make tracking parameter removal case-insensitive.

URLSearchParams.delete() is strictly case-sensitive. Since tracking parameters in the wild can occasionally be mixed-case (e.g., ?UTM_SOURCE=...), consider making this removal case-insensitive to match the robust behavior of stripSensitiveUrlParamsForCacheKey.

💡 Proposed refactor
 export function stripTrackingParams(parsed: URL): void {
-  TRACKING_URL_QUERY_PARAMS.forEach((param) =>
-    parsed.searchParams.delete(param),
-  );
+  const keysToDelete: string[] = [];
+  for (const key of parsed.searchParams.keys()) {
+    if (TRACKING_URL_QUERY_PARAMS.includes(key.toLowerCase())) {
+      keysToDelete.push(key);
+    }
+  }
+  keysToDelete.forEach((key) => parsed.searchParams.delete(key));
 }
🤖 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/utils/logSanitize.ts` around lines 309 - 313, Update
stripTrackingParams to remove tracking query parameters case-insensitively,
rather than relying on URLSearchParams.delete with exact casing. Compare each
parsed parameter name against TRACKING_URL_QUERY_PARAMS using a case-insensitive
match, while preserving non-tracking parameters.

260-279: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider adding the remaining AWS SigV4 parameters for symmetry.

The list comprehensively covers GCS metadata parameters (e.g., x-goog-date, x-goog-algorithm, x-goog-expires), but omits the AWS equivalents. Consider adding them so that all non-content-varying AWS auth metadata is consistently stripped from the plaintext portion of the cache key.

💡 Proposed additions
   "x-amz-signature",
   "x-amz-credential",
   "x-amz-security-token",
+  "x-amz-date",
+  "x-amz-algorithm",
+  "x-amz-expires",
+  "x-amz-signedheaders",
   "awsaccesskeyid",
   "expires",
🤖 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/utils/logSanitize.ts` around lines 260 - 279, Extend
SENSITIVE_URL_QUERY_PARAM_DENYLIST with the remaining AWS SigV4 metadata query
parameters, matching the existing x-goog entries and excluding content-varying
parameters, so AWS authentication metadata is consistently removed from cache
keys.

373-376: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use JSON.stringify for mathematically collision-free hashing.

Using .join("&") could theoretically result in a hash collision if a decoded parameter value contains an & that perfectly mimics another parameter boundary (e.g., token=A and sig=B vs token=A&sig=B as a single parameter). While astronomically unlikely to occur naturally, using JSON.stringify guarantees boundary safety.

💡 Proposed tweak
   const hash = createHash("sha256")
-    .update(strippedPairs.join("&"))
+    .update(JSON.stringify(strippedPairs))
     .digest("hex")
     .slice(0, 16);
🤖 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/utils/logSanitize.ts` around lines 373 - 376, Update the hash input
construction in the log sanitization flow to serialize strippedPairs with
JSON.stringify instead of joining with "&". Keep the existing SHA-256 hashing
and 16-character hex truncation unchanged, ensuring parameter boundaries remain
unambiguous.
🤖 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.

Nitpick comments:
In `@src/lib/utils/logSanitize.ts`:
- Around line 309-313: Update stripTrackingParams to remove tracking query
parameters case-insensitively, rather than relying on URLSearchParams.delete
with exact casing. Compare each parsed parameter name against
TRACKING_URL_QUERY_PARAMS using a case-insensitive match, while preserving
non-tracking parameters.
- Around line 260-279: Extend SENSITIVE_URL_QUERY_PARAM_DENYLIST with the
remaining AWS SigV4 metadata query parameters, matching the existing x-goog
entries and excluding content-varying parameters, so AWS authentication metadata
is consistently removed from cache keys.
- Around line 373-376: Update the hash input construction in the log
sanitization flow to serialize strippedPairs with JSON.stringify instead of
joining with "&". Keep the existing SHA-256 hashing and 16-character hex
truncation unchanged, ensuring parameter boundaries remain unambiguous.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5ca0ec91-2122-4f6a-9ed5-d1ab048b4ebd

📥 Commits

Reviewing files that changed from the base of the PR and between dba96e3 and 7272535.

📒 Files selected for processing (13)
  • docs/MIGRATION.md
  • docs/features/csv-support.md
  • docs/features/pdf-support.md
  • src/cli/commands/proxy.ts
  • src/cli/factories/commandFactory.ts
  • src/cli/utils/inputValidation.ts
  • src/lib/utils/fileDetector.ts
  • src/lib/utils/imageCache.ts
  • src/lib/utils/imageProcessor.ts
  • src/lib/utils/logSanitize.ts
  • src/lib/utils/messageBuilder.ts
  • src/lib/utils/pdfProcessor.ts
  • test/continuous-test-suite-bugfixes.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/cli/utils/inputValidation.ts
  • docs/features/pdf-support.md
  • src/lib/utils/fileDetector.ts
  • src/lib/utils/imageProcessor.ts
  • src/lib/utils/pdfProcessor.ts
  • docs/features/csv-support.md
  • src/lib/utils/messageBuilder.ts
  • docs/MIGRATION.md
  • src/cli/commands/proxy.ts
  • src/cli/factories/commandFactory.ts

@Tara-ag Tara-ag 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.

Review Summary

Files reviewed: 13 changed files
New issues raised this run: 0 (none)
Existing review comments: Audited all 27 existing threads; each has been addressed or justified by the author.

I walked the diff file-by-file against the project standards (CLAUDE.md Critical Rules 1–6, focus areas, and blocking criteria) and against the existing review threads. No new blocking issues remain:

  • Security: Secrets are redacted before logging (imageProcessor.ts, fileDetector.ts); presigned-URL auth params are stripped and hash-suffixed for cache keys (logSanitize.ts, imageCache.ts, fileDetector.ts); HEAD pre-flight no longer trusts non-2xx content-length.
  • Architecture: CLI-only proxy hardening stays in src/cli/commands/proxy.ts; no SDK/CLI boundary leak. Dynamic imports in the CLI command are outside the provider-registry scope of CLAUDE.md Critical Rule 1.
  • Backward compatibility: The PR documents already-shipped breaking changes retroactively; it does not introduce new public-API breaks.
  • Correctness: Batch now wires pdfOptions, csvOptions, and videoOptions through the same shared helpers as generate/stream; PDF aggregate page-limit warns on unknown counts; getAccuratePageCount clears its race timer and guards a throwing destroy().
  • Tests: 8 new regression tests cover the claimed gaps.

All previously raised concerns (broad denylist entries, exported test seam, readPsField dynamic imports, source-string assertions, pdfOptions: { password: undefined } parity, timezone/start-time parsing) have either been fixed in subsequent commits or answered with a coherent justification in the thread. I am not re-raising them.

Decision: Approve.

@murdore
murdore merged commit 1956f4a into release Jul 20, 2026
19 checks passed
@murdore
murdore deleted the fix/post-merge-review-gaps branch July 20, 2026 09:13
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 10.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

This branch was successfully deployed

1 active deployment
Preview — 72725352 Deployed Jul 19, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants