Skip to content

ci(advisor): run PR Review Advisor in OpenShell#7600

Open
cjagwani wants to merge 12 commits into
mainfrom
codex/pr-advisor-openshell
Open

ci(advisor): run PR Review Advisor in OpenShell#7600
cjagwani wants to merge 12 commits into
mainfrom
codex/pr-advisor-openshell

Conversation

@cjagwani

@cjagwani cjagwani commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

The PR Review Advisor currently runs directly on the Actions host with the model credential in its process. This change reuses the conflict fixer's OpenShell lifecycle so both advisor lanes run through inference.local.

The Advisor opts into four read-only Docker bind mounts for its trusted code, PR data, prepared GitHub context, and verified search tools. Those mounts and the final hard-Landlock policy exist before the first sandbox process starts. Application writes are confined to a capped runtime tmpfs.

Changes

  • Extract the conflict fixer's OpenShell lifecycle into tools/openshell-agent/runtime.mts for the conflict fixer and PR Review Advisor. The shared helper now supports opt-in bind mounts and driver configuration while preserving the conflict fixer's upload behavior.
  • Add the Advisor sandbox policy, host orchestration, unavailable-result fallback, and isolated GitHub context preparation. Canonical trusted host paths become four read-only mounts outside /sandbox; a 512 MiB tmpfs is the only application-data write subtree.
  • Add a startup proof with cross-UID writable canaries. It reads every canary, resolves the canonical PR worktree and commit-form HEAD, rejects chmod, overwrite, rename, and creation in every input, and exercises the complete create/overwrite/chmod/rename/delete lifecycle in the runtime.
  • Pin the sandbox to GIT_DIR=/pr-workdir/.git and GIT_WORK_TREE=/pr-workdir. This narrowly trusts the immutable metadata created by the trusted prepare helper without using a broad safe.directory=* exception.
  • Give the embedded Pi SDK the same pinned, proxy-aware Undici transport as the Pi CLI. OpenShell exposes hosted inference only through the sandbox proxy.
  • Update the Advisor README, workflow-boundary checks, source-shape contract, and watch-trigger mappings for the immutable runtime boundary.

Regression Fix

  • Root cause: the upload-and-seal implementation relied on Unix mode bits and a runtime policy transition that OpenShell v0.0.85 cannot use to narrow a running sandbox safely.
  • Detection gap: owner-only canaries could fail from ordinary host DAC when the runner and sandbox UIDs differed, even if the intended immutable boundary was absent.
  • Prevention: the final Landlock policy and four read-only bind mounts are applied before sandbox startup. Deliberately cross-UID-writable canaries prove effective mutation denial, while a sticky tmpfs root permits only the private 0700 application directories created at startup.
  • Live-run follow-up: the runner-owned read-only worktree crossed into the sandbox under a different UID. Git 2.43 treated implicit repository discovery as untrusted, so both Advisor lanes failed before turn 1 even though the mounts were present. Fixed trusted GIT_DIR and GIT_WORK_TREE values bypass only discovery for the already-immutable checkout. The startup proof now fails closed unless that checkout and HEAD are readable.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification:
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: Independent security and regression re-reviews passed at 8fa580d2b; the test-only runner-config isolation was revalidated at 82e56aad1. The final local regression passed 19 files / 263 tests, including the exact different-owner Git path.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: docs-updated
  • Evidence: tools/pr-review-advisor/README.md accurately documents four pre-start read-only mounts, one final hard-Landlock policy, the bounded runtime tmpfs, the mutation proof, and credential boundaries. No Fern documentation, changelog, or skill update is needed because this is internal review automation.
  • Agent: Codex Desktop

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit: Not applicable
  • Station profile/scenario: Not applicable
  • Result: scripts/prepare-dgx-station-host.sh is unchanged.
  • Supporting evidence: Not applicable

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — The Advisor and conflict-fixer regression passed 19 files / 263 tests. At 82e56aad1, the isolated different-owner Advisor test passed 18/18. CLI type-check, Biome, source-shape, test-size, normal pre-commit, commit-msg, and pre-push checks passed. The pinned Pi image reproduced implicit Git rejection and passed the explicit worktree proof as its real sandbox user.
  • Applicable broad gate passed — Exact-head CI and live E2E are pending.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

GitHub Actions E2E

  • Targeted fallback run: both lanes passed isolated PR preparation and unavailable-artifact validation.
  • Initial targeted live run: GPT-5.6 Terra and Nemotron each completed all 14 turns inside OpenShell on production SHA 792f1cfab. Artifact schema, SHA binding, cleanup, and outcome checks passed.
  • Context-read hardening run: GPT-5.6 Terra and Nemotron each completed all 14 turns inside OpenShell on production SHA ac4154daf. Exact analyzer/target SHA binding, artifact schema parity, credential scans, and sandbox cleanup passed.
  • Functional live run before the immutable-bind fix: GPT-5.6 Terra and Nemotron each completed all 14 turns inside OpenShell on production SHA 8f9c52f79. Exact analyzer/target SHA binding, artifact schema parity, credential scans, inference routing, and sandbox cleanup passed.
  • Exact-head immutable-bind run for 5327f5ff6: both lanes proved four immutable inputs and one writable runtime, then failed before turn 1 because Git rejected implicit discovery of the runner-owned worktree. Both sandboxes were deleted and no credentials leaked.
  • Cross-UID Git validation for 8fa580d2b: both lanes passed the strengthened immutable-input/Git proof, completed 14/14 turns, downloaded valid artifacts, deleted their sandboxes, and returned merge_as_is with high confidence and zero findings.
  • Final exact-head validation for 82e56aad1: both lanes passed the strengthened immutable-input/Git proof, completed 14/14 turns, downloaded valid artifacts, and deleted their sandboxes. Terra returned merge_as_is with high confidence and zero findings. Nemotron completed with one non-actionable documentation suggestion whose requested sandbox lifecycle, credential separation, no-egress/Landlock policy, runtime tmpfs, and unavailable-artifact fallback are already explicit in tools/pr-review-advisor/README.md.

Signed-off-by: Charan Jagwani cjagwani@nvidia.com

Summary by CodeRabbit

  • New Features

    • PR review analysis now executes inside a tighter, isolated sandbox with credential-free stages and policy enforcement.
    • Added stronger prepared review-context handling with bounded/truncated inputs and improved “unavailable” artifact fallback behavior.
    • Improved inference endpoint selection and proxy-aware HTTP dispatching.
  • Bug Fixes

    • Strengthened workflow and runtime boundary checks, including stricter path/workspace/artifact validation and safer cleanup semantics.
    • Hardened sandbox lifecycle so unauthorized or misconfigured runs fail closed.
  • Tests

    • Added/expanded security, workflow-boundary, and HTTP dispatcher tests to cover the sandbox behavior.
  • Documentation

    • Updated PR Review Advisor documentation to reflect the new execution model and safety boundaries.

cjagwani added 3 commits July 26, 2026 14:03
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@cjagwani cjagwani added the area: security Security controls, permissions, secrets, or hardening label Jul 27, 2026
@cjagwani cjagwani self-assigned this Jul 27, 2026
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

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 replaces direct advisor execution with a staged OpenShell sandbox workflow, adds prepared GitHub context and credential separation, centralizes runtime and transport helpers, introduces restrictive policy validation, and expands workflow, integration, security, and boundary tests.

Changes

OpenShell advisor integration

Layer / File(s) Summary
Shared runtime and advisor transport
tools/openshell-agent/runtime.mts, tools/advisors/*, tools/pr-merge-conflict-fixer/resolve.mts, package.json, test/advisor-*
Adds shared OpenShell lifecycle helpers, approved inference endpoint selection, proxy-aware Undici transport, pinned dependency configuration, and merge-conflict-fixer delegation.
Prepared review context and target workspace
tools/pr-review-advisor/github-context.mts, tools/pr-review-advisor/analyze.mts, tools/pr-review-advisor/prepare-target-pr.mts, related tests
Extracts bounded GitHub context collection and validation, supports prepared credential-free context loading, validates dedicated pr-workdir targets, and probes model support from centralized constants.
Advisor sandbox lifecycle and policy
tools/pr-review-advisor/openshell.mts, tools/pr-review-advisor/*policy.yaml, tools/pr-review-advisor/README.md, test/pr-review-advisor-openshell.test.ts
Prepares sandbox inputs, configures inference, creates and seals the sandbox, runs analysis, downloads artifacts, deletes the sandbox, validates runtime confinement, and documents the execution model.
Workflow integration and boundary validation
.github/workflows/pr-review-advisor.yaml, tools/pr-review-advisor/workflow-boundary.mts, boundary/watch tests, ci/source-shape-test-budget.json
Replaces direct analysis with staged OpenShell commands and outcome handling; validates identity bindings, credential isolation, ordering, pinned configuration, artifact paths, policy restrictions, and watch-trigger mappings.

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

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant AdvisorWrapper
  participant OpenShellGateway
  participant AdvisorSandbox
  participant ArtifactStore
  GitHubActions->>AdvisorWrapper: prepare GitHub context and sandbox inputs
  AdvisorWrapper->>OpenShellGateway: configure provider and inference model
  GitHubActions->>AdvisorWrapper: create and run sandbox analysis
  AdvisorWrapper->>AdvisorSandbox: execute advisor analysis
  AdvisorSandbox-->>AdvisorWrapper: produce review artifacts
  AdvisorWrapper->>ArtifactStore: download artifacts
  GitHubActions->>AdvisorWrapper: delete sandbox and verify outcomes
Loading

Possibly related PRs

  • NVIDIA/NemoClaw#7556: The shared OpenShell runtime refactor is directly coupled to the merge-conflict-fixer tooling and workflow.

Suggested labels: area: ci, area: inference, area: sandbox, feature, v0.0.96

Suggested reviewers: cv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.08% 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
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.
Title check ✅ Passed The title clearly matches the main change: moving PR Review Advisor execution into OpenShell sandboxes.
✨ 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 codex/pr-advisor-openshell

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

@github-code-quality

github-code-quality Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 82e56aa in the codex/pr-advisor-ope... branch remains at 96%, unchanged from commit fdf14f5 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 82e56aa in the codex/pr-advisor-ope... branch remains at 81%, unchanged from commit a02a3b9 in the main branch.

Show a code coverage summary of the most impacted files.
File main a02a3b9 codex/pr-advisor-ope... 82e56aa +/-
src/lib/onboard...ndbox-create.ts 83% 33% -50%
src/lib/onboard...-create-plan.ts 88% 75% -13%
src/lib/onboard...ndbox-create.ts 91% 83% -8%
src/lib/domain/.../connect-env.ts 97% 89% -8%
src/lib/onboard/tracing.ts 85% 80% -5%
src/lib/actions...x/mcp-bridge.ts 43% 41% -2%
src/lib/shields/index.ts 71% 72% +1%
src/lib/actions...lution-probe.ts 93% 95% +2%
src/lib/actions...ol-discovery.ts 0% 82% +82%
src/lib/actions...time-command.ts 0% 100% +100%

Updated July 27, 2026 03:47 UTC

@github-actions

Copy link
Copy Markdown
Contributor

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized E2E selections differ; severity counts match.

Nemotron output stays in workflow artifacts and does not change the assessment above.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: cloud-onboard, credential-sanitization, security-posture

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

Comment thread test/pr-review-advisor-openshell.test.ts Fixed
Comment thread tools/pr-review-advisor/github-context.mts Fixed
0o600,
);
try {
fs.writeFileSync(fd, content);
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>

@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

🧹 Nitpick comments (6)
tools/pr-review-advisor/prepare-target-pr.mts (1)

76-96: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider requiring an absolute path.

A relative TARGET_DIR such as pr-workdir resolves under the current working directory, passes every guard (basename matches, cwd isn't contained), and is then rmSync(..., { recursive: true, force: true })'d — deleting a directory inside the trusted checkout. Rejecting non-absolute input closes that path.

🛡️ Proposed guard
   if (!value || value.includes("\0")) {
     fail("target directory must be a non-empty filesystem path");
   }
+  if (!path.isAbsolute(value)) {
+    fail("target directory must be an absolute filesystem path");
+  }
   const resolved = path.resolve(value);
🤖 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 `@tools/pr-review-advisor/prepare-target-pr.mts` around lines 76 - 96, Update
validatePrepareTargetDirectory to reject non-absolute value inputs before path
resolution, while preserving the existing non-empty, NUL-byte, root, basename,
and current-directory containment checks for accepted paths.
tools/openshell-agent/runtime.mts (2)

276-304: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider a default timeoutSeconds for sandbox exec.

execOpenShellSandbox omits --timeout entirely when timeoutSeconds is unset (e.g. the patch-export path), so a wedged sandbox command blocks until the job-level timeout. A conservative default bounds the failure.

🤖 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 `@tools/openshell-agent/runtime.mts` around lines 276 - 304, Update
execOpenShellSandbox to apply a conservative default timeout when
input.timeoutSeconds is unset, while preserving explicitly provided timeout
values. Ensure timeoutArgs always includes the resulting --timeout argument
before invoking tools.run.

251-254: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Unvalidated : in upload paths silently mis-splits the mapping.

--upload ${source}:${destination} is ambiguous if either path contains a colon. Callers pass env-derived directories (RESOLUTION_WORKDIR, RESOLVER_CONFIG_DIR), so a guard here keeps the failure explicit rather than uploading to a wrong destination.

🛡️ Proposed guard
   const uploadArgs = input.uploads.flatMap(({ source, destination }) => [
     "--upload",
-    `${source}:${destination}`,
+    ((): string => {
+      if (source.includes(":") || destination.includes(":")) {
+        throw new OpenShellAgentError("Sandbox upload paths must not contain ':'");
+      }
+      return `${source}:${destination}`;
+    })(),
   ]);
🤖 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 `@tools/openshell-agent/runtime.mts` around lines 251 - 254, Validate each
source and destination path in the uploadArgs construction before forming the
mapping, rejecting any path containing “:” with a clear error. Keep the existing
--upload argument format for valid paths and ensure env-derived directories such
as RESOLUTION_WORKDIR and RESOLVER_CONFIG_DIR fail explicitly rather than being
mis-split.
tools/pr-review-advisor/github-context.mts (1)

102-107: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Identity binding is skipped when the expected repo/PR are absent.

readPreparedGitHubContext only compares repo/prNumber when the caller supplies them, and collectGitHubReviewContext passes undefined whenever TARGET_REPO/GITHUB_REPOSITORY or PR_NUMBER are unset. Since this is the boundary that binds sandbox-supplied context to the workflow target, consider requiring both when preparedPath is set.

🛡️ Proposed tightening
   if (preparedPath) {
+    if (!repo || !Number.isFinite(prNumber) || prNumber <= 0) {
+      throw new Error("Prepared GitHub context requires a known repository and pull request");
+    }
     return readPreparedGitHubContext(preparedPath, {
       repo,
-      prNumber: Number.isFinite(prNumber) && prNumber > 0 ? prNumber : undefined,
+      prNumber,
     });
   }

Also applies to: 120-126

🤖 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 `@tools/pr-review-advisor/github-context.mts` around lines 102 - 107, Update
readPreparedGitHubContext and its collectGitHubReviewContext call path so that
when preparedPath is set, both the expected repository and pull request number
are required and validated; do not skip identity checks merely because
TARGET_REPO/GITHUB_REPOSITORY or PR_NUMBER are unset. Preserve the existing
mismatch errors and normal behavior when no prepared context is used.
tools/pr-review-advisor/workflow-boundary.mts (1)

443-447: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Share the artifact-directory pattern with the runtime validator.

^[a-z0-9][a-z0-9-]*$ is now defined here and independently in tools/pr-review-advisor/openshell.mts (Line 248). If one side loosens, the other silently stops matching and the boundary claim no longer reflects runtime behavior. Export the pattern from one module and import it here.

As per path instructions, "Derive inventories and limits from a canonical source where possible; flag duplicated lists that can silently drift."

🤖 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 `@tools/pr-review-advisor/workflow-boundary.mts` around lines 443 - 447,
Centralize the artifact-directory validation pattern currently duplicated in the
workflow-boundary loop and the runtime validator in openshell.mts. Export the
canonical pattern from openshell.mts, import and reuse it in the entries
validation, and preserve the existing validation behavior.

Source: Path instructions

test/pr-review-advisor-openshell-workflow-boundary.test.ts (1)

353-397: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Policy invariants without negative coverage.

version, filesystem_policy.include_workdir, and process.run_as_user/run_as_group are enforced in checkOpenShellPolicy but never exercised by a mutation here, so a regression that drops those branches would go unnoticed. validatePolicyMutation makes each addition a two-line case.

🤖 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/pr-review-advisor-openshell-workflow-boundary.test.ts` around lines 353
- 397, Extend the test in “fails closed around the credential-free OpenShell
filesystem and network boundary” with mutation cases for version,
filesystem_policy.include_workdir, and process.run_as_user/run_as_group. Use
validatePolicyMutation for each mutation and assert the corresponding
checkOpenShellPolicy invariant message, ensuring regressions in each enforced
branch are covered.

Source: Path instructions

🤖 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 `@test/advisor-http-dispatcher.test.ts`:
- Around line 80-84: Guard child.stderr before registering the "data" listener
in the child-process test setup, using optional chaining or an explicit null
check so the code handles the declared Readable | null type while preserving
stderr collection when available.

---

Nitpick comments:
In `@test/pr-review-advisor-openshell-workflow-boundary.test.ts`:
- Around line 353-397: Extend the test in “fails closed around the
credential-free OpenShell filesystem and network boundary” with mutation cases
for version, filesystem_policy.include_workdir, and
process.run_as_user/run_as_group. Use validatePolicyMutation for each mutation
and assert the corresponding checkOpenShellPolicy invariant message, ensuring
regressions in each enforced branch are covered.

In `@tools/openshell-agent/runtime.mts`:
- Around line 276-304: Update execOpenShellSandbox to apply a conservative
default timeout when input.timeoutSeconds is unset, while preserving explicitly
provided timeout values. Ensure timeoutArgs always includes the resulting
--timeout argument before invoking tools.run.
- Around line 251-254: Validate each source and destination path in the
uploadArgs construction before forming the mapping, rejecting any path
containing “:” with a clear error. Keep the existing --upload argument format
for valid paths and ensure env-derived directories such as RESOLUTION_WORKDIR
and RESOLVER_CONFIG_DIR fail explicitly rather than being mis-split.

In `@tools/pr-review-advisor/github-context.mts`:
- Around line 102-107: Update readPreparedGitHubContext and its
collectGitHubReviewContext call path so that when preparedPath is set, both the
expected repository and pull request number are required and validated; do not
skip identity checks merely because TARGET_REPO/GITHUB_REPOSITORY or PR_NUMBER
are unset. Preserve the existing mismatch errors and normal behavior when no
prepared context is used.

In `@tools/pr-review-advisor/prepare-target-pr.mts`:
- Around line 76-96: Update validatePrepareTargetDirectory to reject
non-absolute value inputs before path resolution, while preserving the existing
non-empty, NUL-byte, root, basename, and current-directory containment checks
for accepted paths.

In `@tools/pr-review-advisor/workflow-boundary.mts`:
- Around line 443-447: Centralize the artifact-directory validation pattern
currently duplicated in the workflow-boundary loop and the runtime validator in
openshell.mts. Export the canonical pattern from openshell.mts, import and reuse
it in the entries validation, and preserve the existing validation 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: Enterprise

Run ID: a5ec61e6-d1db-4cae-a1c2-bacff6b56c88

📥 Commits

Reviewing files that changed from the base of the PR and between 2f66902 and e293f0a.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (24)
  • .github/workflows/pr-review-advisor.yaml
  • ci/source-shape-test-budget.json
  • package.json
  • test/advisor-http-dispatcher.test.ts
  • test/advisor-session-runner.test.ts
  • test/helpers/vitest-watch-triggers.ts
  • test/pr-review-advisor-openshell-workflow-boundary.test.ts
  • test/pr-review-advisor-openshell.test.ts
  • test/pr-review-advisor-prepare-target-pr.test.ts
  • test/pr-review-advisor-workflow-boundary.test.ts
  • test/vitest-watch-triggers.test.ts
  • tools/advisors/http-dispatcher.mts
  • tools/advisors/provider-constants.mts
  • tools/advisors/session.mts
  • tools/openshell-agent/runtime.mts
  • tools/pr-merge-conflict-fixer/resolve.mts
  • tools/pr-review-advisor/README.md
  • tools/pr-review-advisor/analyze.mts
  • tools/pr-review-advisor/github-context.mts
  • tools/pr-review-advisor/openshell-policy.yaml
  • tools/pr-review-advisor/openshell.mts
  • tools/pr-review-advisor/prepare-target-pr.mts
  • tools/pr-review-advisor/run-analysis.mts
  • tools/pr-review-advisor/workflow-boundary.mts

Comment thread test/advisor-http-dispatcher.test.ts
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>

@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 `@test/pr-review-advisor-openshell.test.ts`:
- Around line 311-316: Update the skipIf platform guard for the “rejects a
prepared-context FIFO without blocking” test to also require
fs.constants.O_NOFOLLOW, while preserving the existing win32 and O_NONBLOCK
checks.
🪄 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: Enterprise

Run ID: 8d448c74-f301-428d-a3dd-29ed8ca59907

📥 Commits

Reviewing files that changed from the base of the PR and between ac4154d and 8f9c52f.

📒 Files selected for processing (5)
  • test/advisor-http-dispatcher.test.ts
  • test/pr-review-advisor-openshell.test.ts
  • tools/advisors/http-dispatcher.mts
  • tools/pr-review-advisor/github-context.mts
  • tools/pr-review-advisor/openshell.mts
🚧 Files skipped from review as they are similar to previous changes (4)
  • tools/advisors/http-dispatcher.mts
  • test/advisor-http-dispatcher.test.ts
  • tools/pr-review-advisor/github-context.mts
  • tools/pr-review-advisor/openshell.mts

Comment thread test/pr-review-advisor-openshell.test.ts Outdated
cjagwani and others added 3 commits July 26, 2026 18:23
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>

@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 `@tools/pr-review-advisor/workflow-boundary.mts`:
- Around line 1130-1146: Extract the duplicated OS baseline paths into a shared
constant near the two policy checks, then spread that constant into the readOnly
arrays passed to both checkOpenShellPolicy calls. Keep each policy’s additional
paths unchanged, including the runtime-only sandbox paths and the upload-policy
readWrite paths.
🪄 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: Enterprise

Run ID: 282adb05-b09f-4a82-8403-b84b316c5642

📥 Commits

Reviewing files that changed from the base of the PR and between 7e321f1 and 52dcfd2.

📒 Files selected for processing (11)
  • test/advisor-http-dispatcher.test.ts
  • test/helpers/vitest-watch-triggers.ts
  • test/pr-review-advisor-openshell-workflow-boundary.test.ts
  • test/pr-review-advisor-openshell.test.ts
  • test/vitest-watch-triggers.test.ts
  • tools/openshell-agent/runtime.mts
  • tools/pr-review-advisor/README.md
  • tools/pr-review-advisor/openshell-policy.yaml
  • tools/pr-review-advisor/openshell-upload-policy.yaml
  • tools/pr-review-advisor/openshell.mts
  • tools/pr-review-advisor/workflow-boundary.mts
🚧 Files skipped from review as they are similar to previous changes (7)
  • test/helpers/vitest-watch-triggers.ts
  • tools/pr-review-advisor/openshell-policy.yaml
  • test/advisor-http-dispatcher.test.ts
  • tools/openshell-agent/runtime.mts
  • tools/pr-review-advisor/README.md
  • tools/pr-review-advisor/openshell.mts
  • test/pr-review-advisor-openshell.test.ts

Comment thread tools/pr-review-advisor/workflow-boundary.mts Outdated
cjagwani added 3 commits July 26, 2026 19:54
Mount trusted Advisor inputs read-only before the first sandbox process.

Confine application writes to a capped tmpfs and prove the boundary with cross-UID canaries.

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Pin the sandbox to its immutable Git directory and worktree so Git does not reject
the runner-owned bind mount across the sandbox UID boundary.

Require readable boundary canaries and a canonical commit-form HEAD before analysis
starts. Cover the exact different-owner failure and ambient Git environment overrides.

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Ignore runner-level Git safety configuration while exercising the different-owner
control so hosted Git installations reproduce the intended rejection consistently.

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: security Security controls, permissions, secrets, or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants