Skip to content

feat(inference): add Ollama loopback bind probe (step 1 of #6014) - #6054

Merged
prekshivyas merged 16 commits into
mainfrom
feat/6014-auth-proxy-loopback-probe
Aug 8, 2026
Merged

feat(inference): add Ollama loopback bind probe (step 1 of #6014)#6054
prekshivyas merged 16 commits into
mainfrom
feat/6014-auth-proxy-loopback-probe

Conversation

@cjagwani

@cjagwani cjagwani commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

First incremental step on #6014. The Ollama auth proxy now independently verifies that the Ollama backend is listening only on loopback before declaring itself ready, with a structured exit signal the host CLI renders as a specific actionable remediation. Leaves the existing root-level systemd loopback override (#5996, #5716) in place for this PR.

Why an independent probe in the proxy

The proxy currently trusts the systemd drop-in to keep Ollama bound to 127.0.0.1. If a user manually edits OLLAMA_HOST to 0.0.0.0, the proxy still forwards to 127.0.0.1:11434 successfully (Ollama listens there too) but Ollama is ALSO publicly reachable on 0.0.0.0:11434, bypassing the proxy's bearer-token check entirely.

The new probe runs before server.listen and refuses to start with exit code 2 if it sees any non-loopback listener on the backend port. This moves bind-policy enforcement off the root-coupled systemd path and onto the proxy itself; the systemd drop-in becomes pure defense-in-depth that subsequent PRs can retire.

Changes

  • scripts/ollama-auth-proxy.mts:

    • Independently enumerates backend listeners through /proc/net/tcp{,6} with an lsof fallback and refuses any non-loopback listener before server.listen.
    • Recognizes the full 127.0.0.0/8, ::1, and IPv4-mapped IPv6 loopback shapes both in listener classification and in deciding whether a local backend URL requires the probe.
    • Writes structured startup failure status for host-side remediation and retains the explicit audited operator override.
    • Is fully checked by tsconfig.cli.json; no @ts-nocheck suppression remains.
    • Keeps side effects inside main(), gated by import.meta.main, while exporting typed helpers for focused tests.
  • src/lib/inference/ollama/proxy.ts:

    • Persist a sentinel path (~/.nemoclaw/ollama-auth-proxy.status) and pass it to the spawned proxy via env
    • On proxy spawn, unlink any stale status file so a later read sees the new proxy's reason
    • When the readiness loop observes the proxy gone, read the status file via readProxyExitStatus and render specific remediation via printProxyStartupReason for the backend-not-loopback reason; fall back to existing port-conflict or generic message when no status file is present
  • test/ollama-auth-proxy-bind-probe.test.ts: 40 Vitest cases cover listener parsing, all supported loopback encodings, explicit rejects, local-versus-remote backend trigger selection, the exit-code contract, and Linux /proc integration.

What this does NOT do (follow-up PRs per #6014)

  • Does not delete ensureOllamaLoopbackSystemdOverride. The systemd drop-in still runs on Linux and stays the authority for Ollama's bind on a fresh install. The probe is independent enforcement on top, not a replacement.
  • Does not relocate OLLAMA_CONTEXT_LENGTH or the Spark OLLAMA_LLM_LIBRARY=cuda_v13 overrides off the systemd drop-in. Those are load-bearing for non-security reasons and belong in a follow-up that moves them to a config-only path before the drop-in writer can be deleted.
  • Does not add periodic re-probing during proxy lifetime; the current PR only checks at startup. A follow-up could probe periodically to catch mid-run bind changes.
  • Does not cover Docker-Desktop topologies (WSL + Windows-host Ollama, WSL + WSL-local Ollama). Those bypass the proxy entirely via containerCanReachHostLoopback() and are out of scope per refactor(onboard): decouple Ollama loopback hardening from root-level systemd surgery #6014.

Verification

  • npx vitest run test/ollama-auth-proxy-bind-probe.test.ts — 38 passed, 2 platform skips on macOS
  • Eight focused Ollama proxy suites — 110 passed, 2 platform skips
  • npm run typecheck:cli — passed with the proxy script fully type-checked
  • npm run checks:repository — repository architecture and source-shape checks passed
  • npm run docs — 0 errors, 2 existing warnings
  • src/lib/shields/policy-transition.test.ts carries the exact one-line setup-hook stabilization from upstream PR fix(status): wait for inference after gateway recovery #8572 (commit 78f681e72) after current-main CI reproduced the 10-second hook timeout three times on this PR.

Related

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)

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: docs-updated
  • Evidence: SECURITY.md. Independent Codex Desktop review passed for exact head 74431d39a. The threat model accurately documents the Ollama auth proxy loopback bind probe, its full 127.0.0.0/8, ::1, and IPv4-mapped IPv6 loopback coverage, non-loopback refusal, operator override, unavailable-probe fallback, startup-only enforcement, regression coverage, and scope limits. Removing @ts-nocheck preserves behavior, the broadened trigger aligns all recognized loopback backend hostnames with that documented guarantee, and the Vitest setup-hook timeout change requires no additional documentation.
  • Agent: Codex Desktop

Summary by CodeRabbit

  • New Features
    • Added structured proxy startup failure “status file” and clearer readiness-loop diagnostics.
    • Enhanced the Ollama auth proxy with Bearer-token authentication and loopback-only backend enforcement.
  • Bug Fixes
    • Improved startup failure reporting by surfacing a specific “backend-not-loopback” reason and remediation guidance when misconfigured.
    • Improved proxy forwarding error responses with consistent HTTP status handling.
  • Tests
    • Added Vitest coverage for loopback bind/probe detection, address classification (proc/net and lsof), and contract constant assertions.

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

…#6014)

First incremental step on #6014. The auth proxy now independently
verifies that the Ollama backend is listening only on loopback
before declaring itself ready, with a structured exit signal the
host CLI renders as a specific actionable remediation. Leaves the
existing root-level systemd loopback override (#5996, #5716) in
place this PR.

Why an independent probe in the proxy: the proxy currently trusts
the systemd drop-in to keep Ollama bound to 127.0.0.1. If a user
manually edits OLLAMA_HOST to 0.0.0.0, the proxy still forwards to
127.0.0.1:11434 successfully (Ollama listens there too) -- but
Ollama is ALSO publicly reachable on 0.0.0.0:11434, bypassing the
proxy's bearer-token check entirely. The new probe runs before
server.listen and refuses to start with exit code 2 if it sees any
non-loopback listener on the backend port. This moves the bind-
policy enforcement off the root-coupled systemd path and onto the
proxy itself; the systemd drop-in becomes pure defense-in-depth
that subsequent PRs can retire.

Implementation:

- scripts/ollama-auth-proxy.js: add `parseProcNetTcpListeners`,
  `isLoopbackProcAddress`, `probeLinuxLoopbackBind` (parses
  /proc/net/tcp + /proc/net/tcp6 for LISTEN-state rows on the
  backend port), and `probeLsofLoopbackBind` (cross-platform
  fallback via `lsof -nP -iTCP:<port> -sTCP:LISTEN -F n`). The
  proxy now calls `assertBackendBoundToLoopback` before
  `server.listen`. On a non-loopback bind it writes a JSON
  status file (path via `NEMOCLAW_OLLAMA_PROXY_STATUS_FILE`) with
  reason `backend-not-loopback`, prints an actionable error, and
  exits with code 2 (`EXIT_BACKEND_NOT_LOOPBACK`). On an
  unavailable probe (no /proc and no lsof) it falls through with a
  warning rather than failing closed. `NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE=1`
  is an explicit operator override.

- The script is restructured so all the side-effect logic
  (env reads, server.listen, exit) is inside `main()` and gated
  on `require.main === module`. The pure helpers and constants
  are exported via `module.exports` so vitest can cover them
  without spawning the proxy.

- src/lib/inference/ollama/proxy.ts: persist a sentinel path
  (`~/.nemoclaw/ollama-auth-proxy.status`) and pass it to the
  spawned proxy via `NEMOCLAW_OLLAMA_PROXY_STATUS_FILE`. On proxy
  spawn, unlink any stale status file so a later read sees the
  new proxy's reason (or no file when the new proxy starts
  cleanly). When the readiness loop observes the proxy gone, read
  the status file via `readProxyExitStatus` and render a specific
  remediation via `printProxyStartupReason` for the
  `backend-not-loopback` reason; fall back to the existing
  port-conflict or generic message when no status file is present.

- test/ollama-auth-proxy-bind-probe.test.js: 14 vitest tests on
  the pure helpers covering LISTEN-state filtering, port
  matching, address canonicalization, blank-line tolerance,
  multi-listener output, the three loopback encodings (IPv4,
  IPv6, IPv4-mapped IPv6), the explicit rejects (wildcard,
  non-loopback IPv4, IPv6 wildcard), and the
  EXIT_BACKEND_NOT_LOOPBACK contract value. One Linux-gated
  integration test reads the host's real /proc/net/tcp at an
  unused high port to exercise the probe end-to-end.

What this does NOT do (follow-up PRs per #6014):

- Does not delete `ensureOllamaLoopbackSystemdOverride`. The
  systemd drop-in still runs on Linux and stays the authority for
  Ollama's bind on a fresh install. The probe is independent
  enforcement on top, not a replacement.
- Does not relocate `OLLAMA_CONTEXT_LENGTH` or the Spark
  `OLLAMA_LLM_LIBRARY=cuda_v13` overrides off the systemd drop-in
  path -- those are load-bearing for non-security reasons and
  belong in a follow-up that moves them to a config-only path
  before the drop-in writer can be deleted.
- Does not add periodic re-probing during proxy lifetime; the
  current PR only checks at startup.

Verification:

- `npx vitest run test/ollama-auth-proxy-bind-probe.test.js` --
  14/14 pass, 1 Linux-gated skip on macOS.
- `npm run checks` -- Layer import boundaries, source/package
  boundary, vitest disjoint projects, test title style: all pass.
- `npm run typecheck:cli` and `npm run build:cli` clean.
- `npx biome check` clean.

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

coderabbitai Bot commented Jun 30, 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 Ollama auth proxy now probes backend loopback binding before startup, writes structured exit status on startup failures, and updates host-side startup handling to read that status. New tests cover the bind-probe helpers and loopback classification.

Changes

Ollama Auth Proxy Loopback and Startup Hardening

Layer / File(s) Summary
Loopback probe helpers
scripts/ollama-auth-proxy.js
Defines proc-encoded loopback constants and implements /proc parsing, address decoding, loopback classification, and Linux or lsof-based backend bind probing.
Proxy startup and status reporting
scripts/ollama-auth-proxy.js
Adds structured status-file write and clear helpers, enforces backend loopback binding before listen, refactors request forwarding into a Bearer-token proxy server, handles startup listen failures, and exports the runtime helpers through the CommonJS entrypoint.
Host status protocol and startup handling
src/lib/inference/ollama/proxy-status.ts, src/lib/inference/ollama/proxy.ts
Defines the proxy status path and helpers, passes it into the detached auth-proxy process, reads structured startup exit state, and updates startup error reporting before falling back to port-owner inspection.
Bind-probe tests
test/ollama-auth-proxy-bind-probe.test.ts
Adds Vitest coverage for proc listener parsing, loopback address classification, Linux bind probing, and the reserved backend-not-loopback exit code.

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

Suggested labels: bug-fix

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.84% 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 and concisely identifies the main change: adding an Ollama loopback bind probe.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/6014-auth-proxy-loopback-probe

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

@github-code-quality

github-code-quality Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 74431d3 in the feat/6014-auth-proxy... branch remains at 96%, unchanged from commit f270f3d in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 74431d3 in the feat/6014-auth-proxy... branch remains at 81%, unchanged from commit a506354 in the main branch.

Show a code coverage summary of the most impacted files.
File main a506354 feat/6014-auth-proxy... 74431d3 +/-
src/lib/inferen...a/model-size.ts 96% 83% -13%
src/lib/adapter...et-authority.ts 83% 79% -4%
src/lib/onboard.ts 31% 32% +1%
src/lib/actions...ateway-state.ts 78% 79% +1%
src/lib/inferen...ollama/proxy.ts 31% 33% +2%
src/lib/onboard...ocal-runtime.ts 93% 98% +5%
src/lib/onboard...mo-lifecycle.ts 70% 83% +13%
src/lib/onboard...ateway-reuse.ts 45% 77% +32%
src/lib/inferen...proxy-status.ts 0% 35% +35%
src/lib/state/r...e-generation.ts 0% 89% +89%

Updated August 08, 2026 04:30 UTC

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor (Nemotron Ultra) — Blocked

Merge posture: Do not merge until addressed
Primary next action: Fix PRA-6: proxy.ts retains @ts-nocheck and grew by +27 lines (monolith growth blocker); then add or justify PRA-T1.
Open items: 4 required · 12 warnings · 3 suggestions · 8 test follow-ups
Since last review: 1 prior item resolved · 11 still apply · 3 new items found

Action checklist

  • PRA-6 Fix: proxy.ts retains @ts-nocheck and grew by +27 lines (monolith growth blocker) in src/lib/inference/ollama/proxy.ts:1
  • PRA-7 Fix: SKIP_BIND_PROBE=1 escape hatch lacks status file audit trail in scripts/ollama-auth-proxy.js:277
  • PRA-8 Fix: Degraded probe path fail-open with no strict mode in scripts/ollama-auth-proxy.js:305
  • PRA-10 Fix: Critical probe functions have zero test coverage in test/ollama-auth-proxy-bind-probe.test.ts:1
  • PRA-1 Resolve or justify: Source-of-truth review needed: Status file IPC (writeExitStatus/readProxyExitStatus/clearStaleProxyStatus)
  • PRA-2 Resolve or justify: Source-of-truth review needed: probeLinuxLoopbackBind EACCES/EPERM → null fallback
  • PRA-3 Resolve or justify: Source-of-truth review needed: probeLsofLoopbackBind catch-all → null
  • PRA-4 Resolve or justify: Source-of-truth review needed: Degraded probe fail-open (both probes null → warn + continue)
  • PRA-5 Resolve or justify: Source-of-truth review needed: SKIP_BIND_PROBE=1 operator override
  • PRA-9 Resolve or justify: probeLsofLoopbackBind swallows unexpected errors in scripts/ollama-auth-proxy.js:254
  • PRA-11 Resolve or justify: probeLinuxLoopbackBind lacks mocked error-path coverage in test/ollama-auth-proxy-bind-probe.test.ts:250
  • PRA-12 Resolve or justify: probeLsofLoopbackBind fallback lacks documentation and regression test in scripts/ollama-auth-proxy.js:211
  • PRA-13 Resolve or justify: Degraded probe path lacks env var control and regression test in scripts/ollama-auth-proxy.js:305
  • PRA-14 Resolve or justify: Status file IPC uses best-effort write/read with no integrity protection in scripts/ollama-auth-proxy.js:43
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Runtime validation
  • PRA-T5 Add or justify test follow-up: Runtime validation
  • PRA-T6 Add or justify test follow-up: Critical probe functions have zero test coverage
  • PRA-T7 Add or justify test follow-up: probeLinuxLoopbackBind lacks mocked error-path coverage
  • PRA-T8 Add or justify test follow-up: Linux-gated integration tests provide zero coverage on non-Linux CI runners
  • PRA-16 In-scope improvement: isLoopbackLsofAddress: IPv4-mapped IPv6 bracketed form not explicitly tested in scripts/ollama-auth-proxy.js:228
  • PRA-18 In-scope improvement: ollama-auth-proxy.js grew to 435 lines — extract bind probe to separate module in scripts/ollama-auth-proxy.js:1
  • PRA-19 In-scope improvement: Linux-gated integration tests provide zero coverage on non-Linux CI runners in test/ollama-auth-proxy-bind-probe.test.ts:1

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-2 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-3 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-4 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-5 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-6 Required correctness src/lib/inference/ollama/proxy.ts:1 Remove // @ts-nocheck from proxy.ts and fix TypeScript errors in new code. If pre-existing errors are out of scope, extract the new status-file IPC logic (already done in proxy-status.ts) to offset growth, or add TODO comments with tracking issue for the pre-existing implicit-any errors.
PRA-7 Required security scripts/ollama-auth-proxy.js:277 In assertBackendBoundToLoopback, when NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE=1, call writeExitStatus('bind-probe-skipped', {override: 'NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE=1'}) before returning, so the host CLI can surface the override in remediation.
PRA-8 Required security scripts/ollama-auth-proxy.js:305 Add NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE env var. In 'strict' mode, exit with EXIT_BACKEND_NOT_LOOPBACK when both probes unavailable. In 'warn' (default), current behavior. In 'off', skip probe silently. Document in threat model.
PRA-9 Resolve/justify security scripts/ollama-auth-proxy.js:254 Log the error at debug/verbose level with error code/message before returning null. Only suppress ENOENT and status===1 (lsof 'no processes found'). Re-throw or return a distinct 'probe-error' sentinel for other failures.
PRA-10 Required tests test/ollama-auth-proxy-bind-probe.test.ts:1 Add mocked unit tests for: (1) probeLsofLoopbackBind with mocked execFileSync returning various lsof -F n outputs (wildcard, IPv4 loopback, IPv4 non-loopback, IPv6 ::1, bracketed [::1], IPv4-mapped ::ffff:127.0.0.1, bracketed [::ffff:127.0.0.1], malformed, timeout, EACCES, ENOENT); (2) status file IPC using temp directory — spawn proxy with NEMOCLAW_OLLAMA_PROXY_STATUS_FILE set, trigger exit conditions, verify host reads correct reason; (3) degraded path with both probes mocked to null verifying warn log (and exit when strict mode added).
PRA-11 Resolve/justify tests test/ollama-auth-proxy-bind-probe.test.ts:250 Add mocked unit tests for probeLinuxLoopbackBind covering: (1) fs.readFileSync throwing EACCES/EPERM on /proc/net/tcp returns null; (2) malformed /proc lines handled gracefully; (3) missing /proc/net/tcp6 treated as empty; (4) mixed loopback/non-loopback listeners correctly classified.
PRA-12 Resolve/justify architecture scripts/ollama-auth-proxy.js:211 Add mocked unit test for probeLsofLoopbackBind (see PRA-7). Document fallback rationale in threat model (SECURITY.md) — why lsof is acceptable as cross-platform fallback and what its classifier guarantees.
PRA-13 Resolve/justify architecture scripts/ollama-auth-proxy.js:305 Implement NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE per PRA-5. Add test mocking both probes to null verifying behavior per mode.
PRA-14 Resolve/justify architecture scripts/ollama-auth-proxy.js:43 Document trust assumption in threat model (SEC-1). Consider adding HMAC with per-boot secret shared via env var if threat model warrants. Add mocked unit test for IPC round-trip using temp directory.
PRA-15 Resolve/justify architecture scripts/ollama-auth-proxy.js:184 Add mocked unit test: mock fs.readFileSync throwing EACCES/EPERM, verify returns null. Document in threat model.
PRA-16 Improvement correctness scripts/ollama-auth-proxy.js:228 Add test case for [::ffff:127.0.0.1] and [::ffff:127.42.13.99] in isLoopbackLsofAddress describe block.
PRA-17 Resolve/justify architecture src/lib/inference/ollama/proxy.ts:1 Coordinate with PR #6075 author. Ensure changes are compatible or sequence merges appropriately. Consider rebasing this PR on top of #6075 or vice versa.
PRA-18 Improvement correctness scripts/ollama-auth-proxy.js:1 Extract bind probe functions (probeLinuxLoopbackBind, probeLsofLoopbackBind, isLoopbackProcAddress, isLoopbackLsofAddress, parseProcNetTcpListeners, decodeProcAddress) to a separate module (e.g., ollama-proxy-bind-probe.js) following the pattern of proxy-status.ts extraction.
PRA-19 Improvement tests test/ollama-auth-proxy-bind-probe.test.ts:1 Keep integration tests but add mocked unit tests (PRA-8) that run on all platforms. Ensure CI runs integration tests on Linux runners.

🚨 Required before merge

Address these before merging unless a maintainer explicitly overrides the advisor with rationale.

PRA-6 Required — proxy.ts retains @ts-nocheck and grew by +27 lines (monolith growth blocker)

  • Location: src/lib/inference/ollama/proxy.ts:1
  • Category: correctness
  • Problem: proxy.ts has // @ts-nocheck at line 1 and grew by 27 lines in this PR (972→999). The monolith growth guardrail triggers at +20 lines. The comment claims only status-file IPC seam is touched, but the file still suppresses all type checking including new code. Prior review explicitly required removing @ts-nocheck.
  • Impact: Type safety guarantees disabled for entire file including new proxy-status integration logic. Any type errors in new code go undetected. Monolith growth violates architectural guardrail.
  • Required action: Remove // @ts-nocheck from proxy.ts and fix TypeScript errors in new code. If pre-existing errors are out of scope, extract the new status-file IPC logic (already done in proxy-status.ts) to offset growth, or add TODO comments with tracking issue for the pre-existing implicit-any errors.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read src/lib/inference/ollama/proxy.ts:1 — first line is // @ts-nocheck. Run npx tsc --noEmit on the file to see errors. Drift context shows monolith growth delta +27 lines (blocker severity).
  • Missing regression test: CI should fail if @ts-nocheck is present in modified files
  • Done when: The required change is committed and verification passes: Read src/lib/inference/ollama/proxy.ts:1 — first line is // @ts-nocheck. Run npx tsc --noEmit on the file to see errors. Drift context shows monolith growth delta +27 lines (blocker severity).
  • Evidence: src/lib/inference/ollama/proxy.ts line 1: // @ts-nocheck. Drift context shows monolith growth delta +27 lines (blocker severity).

PRA-7 Required — SKIP_BIND_PROBE=1 escape hatch lacks status file audit trail

  • Location: scripts/ollama-auth-proxy.js:277
  • Category: security
  • Problem: When NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE=1 is set, the proxy logs a warning but does not call writeExitStatus with reason='bind-probe-skipped'. No durable audit trail exists for the host CLI to detect the override.
  • Impact: Operator can disable the security probe silently from the host's perspective. Incident investigators scanning proxy logs see the warning but the host CLI cannot surface the override in remediation.
  • Required action: In assertBackendBoundToLoopback, when NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE=1, call writeExitStatus('bind-probe-skipped', {override: 'NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE=1'}) before returning, so the host CLI can surface the override in remediation.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search scripts/ollama-auth-proxy.js for 'bind-probe-skipped' — no matches found. The SKIP_BIND_PROBE branch only logs warn and returns.
  • Missing regression test: Mock test: set SKIP_BIND_PROBE=1, spawn proxy with status file env, verify status file contains reason='bind-probe-skipped' and proxy exits 0
  • Done when: The required change is committed and verification passes: Search scripts/ollama-auth-proxy.js for 'bind-probe-skipped' — no matches found. The SKIP_BIND_PROBE branch only logs warn and returns.
  • Evidence: scripts/ollama-auth-proxy.js lines 277-290: SKIP_BIND_PROBE branch logs warn and returns without writing status file.

PRA-8 Required — Degraded probe path fail-open with no strict mode

  • Location: scripts/ollama-auth-proxy.js:305
  • Category: security
  • Problem: When both /proc and lsof probes are unavailable (return null), the proxy logs a warning and continues — fail-open with no strict mode. Prior review required NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE=strict|warn|off env var with default 'warn'. Not implemented.
  • Impact: On hosts lacking both /proc and lsof, the bind probe provides zero enforcement. An attacker could run Ollama on 0.0.0.0 and bypass the proxy entirely with no detection.
  • Required action: Add NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE env var. In 'strict' mode, exit with EXIT_BACKEND_NOT_LOOPBACK when both probes unavailable. In 'warn' (default), current behavior. In 'off', skip probe silently. Document in threat model.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search for NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE in codebase — no matches. The degraded path at line 305 returns without exit.
  • Missing regression test: Mock test: mock both probeLinuxLoopbackBind and probeLsofLoopbackBind to return null, set BIND_PROBE_MODE=strict, verify proxy exits with code 2
  • Done when: The required change is committed and verification passes: Search for NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE in codebase — no matches. The degraded path at line 305 returns without exit.
  • Evidence: scripts/ollama-auth-proxy.js lines 297-308: degraded path logs warn and returns.

PRA-10 Required — Critical probe functions have zero test coverage

  • Location: test/ollama-auth-proxy-bind-probe.test.ts:1
  • Category: tests
  • Problem: probeLsofLoopbackBind (no mocked tests), status file IPC (writeExitStatus, readProxyExitStatus, clearStaleProxyStatus), and degraded probe path (both probes null) have zero test coverage. Only classifiers and parseProcNetTcpListeners have unit tests.
  • Impact: Security-critical paths are untested. Regressions in bind probe logic, status file contract, or degraded behavior would not be caught by CI.
  • Required action: Add mocked unit tests for: (1) probeLsofLoopbackBind with mocked execFileSync returning various lsof -F n outputs (wildcard, IPv4 loopback, IPv4 non-loopback, IPv6 ::1, bracketed [::1], IPv4-mapped ::ffff:127.0.0.1, bracketed [::ffff:127.0.0.1], malformed, timeout, EACCES, ENOENT); (2) status file IPC using temp directory — spawn proxy with NEMOCLAW_OLLAMA_PROXY_STATUS_FILE set, trigger exit conditions, verify host reads correct reason; (3) degraded path with both probes mocked to null verifying warn log (and exit when strict mode added).
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search test/ollama-auth-proxy-bind-probe.test.ts for 'probeLsofLoopbackBind', 'writeExitStatus', 'readProxyExitStatus', 'clearStaleProxyStatus' — no test coverage found.
  • Missing regression test: Three new test suites as described above
  • Done when: The required change is committed and verification passes: Search test/ollama-auth-proxy-bind-probe.test.ts for 'probeLsofLoopbackBind', 'writeExitStatus', 'readProxyExitStatus', 'clearStaleProxyStatus' — no test coverage found.
  • Evidence: test/ollama-auth-proxy-bind-probe.test.ts has 14 tests covering only parseProcNetTcpListeners, isLoopbackProcAddress, isLoopbackLsofAddress, probeLinuxLoopbackBind (integration), and EXIT_BACKEND_NOT_LOOPBACK constant.
Review findings by urgency: 4 required fixes, 12 items to resolve/justify, 3 in-scope improvements

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Source-of-truth review needed: Status file IPC (writeExitStatus/readProxyExitStatus/clearStaleProxyStatus)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Mocked round-trip test: write status file, read it back, verify reason/details/exitedAt preserved; test corrupted JSON returns null; test missing file returns null; test clearStaleProxyStatus removes file
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: scripts/ollama-auth-proxy.js lines 25-48, 49-58; proxy-status.ts lines 55-76, 80-95. All catch blocks swallow errors silently.

PRA-2 Resolve/justify — Source-of-truth review needed: probeLinuxLoopbackBind EACCES/EPERM → null fallback

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Mocked test: fs.readFileSync throws EACCES → returns null; fs.readFileSync throws EPERM → returns null
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: scripts/ollama-auth-proxy.js lines 184-189: catch block returns null for EACCES/EPERM.

PRA-3 Resolve/justify — Source-of-truth review needed: probeLsofLoopbackBind catch-all → null

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Mocked tests for each error type: ENOENT → null (expected); status=1 → null (expected); EACCES → log + null; timeout → log + null; malformed output → ok=true (empty listeners)
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: scripts/ollama-auth-proxy.js lines 254-256: catch block returns null for all errors except ENOENT/status===1.

PRA-4 Resolve/justify — Source-of-truth review needed: Degraded probe fail-open (both probes null → warn + continue)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Mocked test: both probes null → verify warn log (mode=warn), exit 2 (mode=strict), silent continue (mode=off)
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: scripts/ollama-auth-proxy.js lines 297-308: degraded path logs warn and returns.

PRA-5 Resolve/justify — Source-of-truth review needed: SKIP_BIND_PROBE=1 operator override

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Test: SKIP_BIND_PROBE=1 → status file written with reason='bind-probe-skipped' and proxy exits 0
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: scripts/ollama-auth-proxy.js lines 277-290: SKIP_BIND_PROBE branch logs warn and returns without status file write.

PRA-9 Resolve/justify — probeLsofLoopbackBind swallows unexpected errors

  • Location: scripts/ollama-auth-proxy.js:254
  • Category: security
  • Problem: probeLsofLoopbackBind catch block returns null for any error except ENOENT or status===1, hiding unexpected failures like EACCES, timeout, or malformed output.
  • Impact: Operators cannot diagnose why lsof failed. A permission error (EACCES) or timeout would silently fall back to degraded path, masking operational issues.
  • Recommended action: Log the error at debug/verbose level with error code/message before returning null. Only suppress ENOENT and status===1 (lsof 'no processes found'). Re-throw or return a distinct 'probe-error' sentinel for other failures.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read scripts/ollama-auth-proxy.js:245-260 — catch block returns null for any error except ENOENT/status===1.
  • Missing regression test: Mock test: execFileSync throws EACCES, verify error logged and null returned (or distinct error sentinel)
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read scripts/ollama-auth-proxy.js:245-260 — catch block returns null for any error except ENOENT/status===1.
  • Evidence: scripts/ollama-auth-proxy.js lines 254-256: catch block returns null for all errors except ENOENT/status===1.

PRA-11 Resolve/justify — probeLinuxLoopbackBind lacks mocked error-path coverage

  • Location: test/ollama-auth-proxy-bind-probe.test.ts:250
  • Category: tests
  • Problem: probeLinuxLoopbackBind tests are Linux-only integration tests with no mocked error-path coverage. They bind real ephemeral ports but don't test EACCES/EPERM on /proc, malformed /proc lines, missing /proc/net/tcp6, or mixed loopback/non-loopback listeners.
  • Impact: Error handling paths in the Linux probe are untested. Container permission issues (EACCES/EPERM) or malformed /proc output could cause silent fallback to lsof without detection.
  • Recommended action: Add mocked unit tests for probeLinuxLoopbackBind covering: (1) fs.readFileSync throwing EACCES/EPERM on /proc/net/tcp returns null; (2) malformed /proc lines handled gracefully; (3) missing /proc/net/tcp6 treated as empty; (4) mixed loopback/non-loopback listeners correctly classified.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read test file describe('probeLinuxLoopbackBind') — only 3 integration tests using real net.Server, no mocks of fs.readFileSync.
  • Missing regression test: Four mocked unit tests as described above
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read test file describe('probeLinuxLoopbackBind') — only 3 integration tests using real net.Server, no mocks of fs.readFileSync.
  • Evidence: test/ollama-auth-proxy-bind-probe.test.ts lines 250-270: only integration tests with it.skipIf for non-Linux.

PRA-12 Resolve/justify — probeLsofLoopbackBind fallback lacks documentation and regression test

  • Location: scripts/ollama-auth-proxy.js:211
  • Category: architecture
  • Problem: The lsof fallback rationale is not documented in the threat model (SEC-1) and no mocked test exists for probeLsofLoopbackBind.
  • Impact: Reviewers cannot assess whether the fallback classifier provides equivalent guarantees to the /proc classifier. No test coverage means regressions in lsof parsing would be silent.
  • Recommended action: Add mocked unit test for probeLsofLoopbackBind (see PRA-7). Document fallback rationale in threat model (SECURITY.md) — why lsof is acceptable as cross-platform fallback and what its classifier guarantees.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: SECURITY.md threat model mentions lsof fallback but no detail on classifier guarantees. No test for probeLsofLoopbackBind exists.
  • Missing regression test: Mocked test for probeLsofLoopbackBind (part of PRA-7)
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: SECURITY.md threat model mentions lsof fallback but no detail on classifier guarantees. No test for probeLsofLoopbackBind exists.
  • Evidence: SECURITY.md lines 70-73 mention lsof fallback but no classifier guarantees. test file has no probeLsofLoopbackBind tests.

PRA-13 Resolve/justify — Degraded probe path lacks env var control and regression test

  • Location: scripts/ollama-auth-proxy.js:305
  • Category: architecture
  • Problem: Degraded probe path (both probes null) lacks env var control and regression test. Prior review required NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE env var. Not implemented.
  • Impact: Operators cannot configure fail-open vs fail-closed behavior for degraded probe. No test verifies current behavior.
  • Recommended action: Implement NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE per PRA-5. Add test mocking both probes to null verifying behavior per mode.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: No env var exists. Degraded path logs warn and returns.
  • Missing regression test: Test for degraded path per mode (part of PRA-5)
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: No env var exists. Degraded path logs warn and returns.
  • Evidence: scripts/ollama-auth-proxy.js lines 297-308: degraded path has no env var control.

PRA-14 Resolve/justify — Status file IPC uses best-effort write/read with no integrity protection

  • Location: scripts/ollama-auth-proxy.js:43
  • Category: architecture
  • Problem: writeExitStatus/readProxyExitStatus/clearStaleProxyStatus use best-effort write/read with no integrity protection. Trust assumption not documented in threat model. No HMAC with per-boot secret. No mocked unit test for IPC round-trip.
  • Impact: If status file is corrupted, tampered with, or unreadable, the host CLI falls back to generic remediation silently. No audit trail of the failure.
  • Recommended action: Document trust assumption in threat model (SEC-1). Consider adding HMAC with per-boot secret shared via env var if threat model warrants. Add mocked unit test for IPC round-trip using temp directory.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: writeExitStatus and readProxyExitStatus catch all errors and return null/void. No integrity check. SECURITY.md does not mention IPC trust model.
  • Missing regression test: Mocked test: write status file, read it back, verify reason/details/exitedAt preserved
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: writeExitStatus and readProxyExitStatus catch all errors and return null/void. No integrity check. SECURITY.md does not mention IPC trust model.
  • Evidence: scripts/ollama-auth-proxy.js lines 25-48: writeExitStatus catches all errors silently. proxy-status.ts lines 55-76: readProxyExitStatus catches all errors and returns null.

PRA-15 Resolve/justify — probeLinuxLoopbackBind EACCES/EPERM handling lacks regression test

  • Location: scripts/ollama-auth-proxy.js:184
  • Category: architecture
  • Problem: The code returns null on EACCES/EPERM when reading /proc/net/tcp but no test verifies this behavior.
  • Impact: Container permission errors on /proc are silently treated as 'probe unavailable' and fall back to lsof. No test ensures this fallback works correctly.
  • Recommended action: Add mocked unit test: mock fs.readFileSync throwing EACCES/EPERM, verify returns null. Document in threat model.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: probeLinuxLoopbackBind catch block handles EACCES/EPERM but test file has no mock for this.
  • Missing regression test: Mocked test for EACCES/EPERM on /proc/net/tcp
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: probeLinuxLoopbackBind catch block handles EACCES/EPERM but test file has no mock for this.
  • Evidence: scripts/ollama-auth-proxy.js lines 184-189: catch block returns null for EACCES/EPERM. No corresponding test in test file.

PRA-17 Resolve/justify — Overlapping PR #6075 modifies same proxy.ts file

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

PRA-16 Improvement — isLoopbackLsofAddress: IPv4-mapped IPv6 bracketed form not explicitly tested

  • Location: scripts/ollama-auth-proxy.js:228
  • Category: correctness
  • Problem: isLoopbackLsofAddress regex handles bracketed form [::ffff:127.0.0.1] but test only covers unbracketed ::ffff:127.0.0.1.
  • Impact: If lsof outputs bracketed IPv4-mapped IPv6 addresses (some versions do), the classifier behavior is unverified.
  • Suggested action: Add test case for [::ffff:127.0.0.1] and [::ffff:127.42.13.99] in isLoopbackLsofAddress describe block.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Search test file for '\[::ffff:' — no matches. Test at line 273 only covers [::1].
  • Missing regression test: Test case: expect(isLoopbackLsofAddress('[::ffff:127.0.0.1]')).toBe(true)
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: scripts/ollama-auth-proxy.js line 228 regex: /^\[?(?:::ffff:)?(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]?$/i handles brackets. Test file lacks bracketed mapped test.

PRA-18 Improvement — ollama-auth-proxy.js grew to 435 lines — extract bind probe to separate module

  • Location: scripts/ollama-auth-proxy.js:1
  • Category: correctness
  • Problem: The ollama-auth-proxy.js file grew from ~100 to 435 lines (+335 lines) in this PR. The file now mixes proxy server, bind probe, status IPC, and CLI entry point.
  • Impact: Maintainability decreases as security-critical bind probe logic is co-located with proxy server logic. Harder to test and review in isolation.
  • Suggested action: Extract bind probe functions (probeLinuxLoopbackBind, probeLsofLoopbackBind, isLoopbackProcAddress, isLoopbackLsofAddress, parseProcNetTcpListeners, decodeProcAddress) to a separate module (e.g., ollama-proxy-bind-probe.js) following the pattern of proxy-status.ts extraction.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: File is 435 lines with multiple responsibilities. proxy-status.ts was extracted for monolith-growth guardrail; same principle applies.
  • Missing regression test: N/A — architectural improvement
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: scripts/ollama-auth-proxy.js is 435 lines. proxy-status.ts (126 lines) was extracted for same guardrail.

PRA-19 Improvement — Linux-gated integration tests provide zero coverage on non-Linux CI runners

  • Location: test/ollama-auth-proxy-bind-probe.test.ts:1
  • Category: tests
  • Problem: Test file uses it.skipIf(process.platform !== 'linux') for probeLinuxLoopbackBind integration tests. The file lacks mocked unit tests for Linux probe error paths, so non-Linux CI runners get zero coverage for this critical function.
  • Impact: CI on macOS/Windows skips the only tests for probeLinuxLoopbackBind. Regressions in Linux probe logic would only be caught on Linux runners.
  • Suggested action: Keep integration tests but add mocked unit tests (PRA-8) that run on all platforms. Ensure CI runs integration tests on Linux runners.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Test file lines 250-270 use it.skipIf for Linux-only tests. No mocked alternatives.
  • Missing regression test: Mocked unit tests for probeLinuxLoopbackBind error paths (PRA-8)
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: test/ollama-auth-proxy-bind-probe.test.ts lines 250-270: it.skipIf(process.platform !== 'linux') for 3 tests.
Simplification opportunities: 1 possible cut, net -200 lines possible

These are safe simplification checks only. Do not remove validation, security controls, data-loss prevention, or required tests.

  • PRA-18 shrink (scripts/ollama-auth-proxy.js:1): probeLinuxLoopbackBind, probeLsofLoopbackBind, isLoopbackProcAddress, isLoopbackLsofAddress, parseProcNetTcpListeners, decodeProcAddress, and related constants from scripts/ollama-auth-proxy.js
    • Replacement: New module scripts/ollama-proxy-bind-probe.js exporting the bind probe functions; proxy.js imports from it
    • Net: -200 lines
    • Safety boundary: bind probe logic must remain pure (no side effects) and exported for testability; EXIT_BACKEND_NOT_LOOPBACK constant must remain stable for host CLI contract
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — probeLsofLoopbackBind: wildcard listener (*) → ok=false, nonLoopback=["*"]. Runtime/sandbox/infrastructure paths need behavioral runtime validation: SECURITY.md, scripts/ollama-auth-proxy.js, src/lib/inference/ollama/proxy-status.ts, src/lib/inference/ollama/proxy.ts. Current tests only cover pure classifiers. Critical integration paths (probeLsofLoopbackBind, status file IPC, degraded probe, SKIP_BIND_PROBE) have zero coverage.
  • PRA-T2 Runtime validation — probeLsofLoopbackBind: IPv4 loopback 127.0.0.1 → ok=true. Runtime/sandbox/infrastructure paths need behavioral runtime validation: SECURITY.md, scripts/ollama-auth-proxy.js, src/lib/inference/ollama/proxy-status.ts, src/lib/inference/ollama/proxy.ts. Current tests only cover pure classifiers. Critical integration paths (probeLsofLoopbackBind, status file IPC, degraded probe, SKIP_BIND_PROBE) have zero coverage.
  • PRA-T3 Runtime validation — probeLsofLoopbackBind: IPv4 non-loopback 10.0.0.1 → ok=false. Runtime/sandbox/infrastructure paths need behavioral runtime validation: SECURITY.md, scripts/ollama-auth-proxy.js, src/lib/inference/ollama/proxy-status.ts, src/lib/inference/ollama/proxy.ts. Current tests only cover pure classifiers. Critical integration paths (probeLsofLoopbackBind, status file IPC, degraded probe, SKIP_BIND_PROBE) have zero coverage.
  • PRA-T4 Runtime validation — probeLsofLoopbackBind: IPv6 ::1 (unbracketed) → ok=true. Runtime/sandbox/infrastructure paths need behavioral runtime validation: SECURITY.md, scripts/ollama-auth-proxy.js, src/lib/inference/ollama/proxy-status.ts, src/lib/inference/ollama/proxy.ts. Current tests only cover pure classifiers. Critical integration paths (probeLsofLoopbackBind, status file IPC, degraded probe, SKIP_BIND_PROBE) have zero coverage.
  • PRA-T5 Runtime validation — probeLsofLoopbackBind: IPv6 [::1] (bracketed) → ok=true. Runtime/sandbox/infrastructure paths need behavioral runtime validation: SECURITY.md, scripts/ollama-auth-proxy.js, src/lib/inference/ollama/proxy-status.ts, src/lib/inference/ollama/proxy.ts. Current tests only cover pure classifiers. Critical integration paths (probeLsofLoopbackBind, status file IPC, degraded probe, SKIP_BIND_PROBE) have zero coverage.
  • PRA-T6 Critical probe functions have zero test coverage — Add mocked unit tests for: (1) probeLsofLoopbackBind with mocked execFileSync returning various lsof -F n outputs (wildcard, IPv4 loopback, IPv4 non-loopback, IPv6 ::1, bracketed [::1], IPv4-mapped ::ffff:127.0.0.1, bracketed [::ffff:127.0.0.1], malformed, timeout, EACCES, ENOENT); (2) status file IPC using temp directory — spawn proxy with NEMOCLAW_OLLAMA_PROXY_STATUS_FILE set, trigger exit conditions, verify host reads correct reason; (3) degraded path with both probes mocked to null verifying warn log (and exit when strict mode added).
  • PRA-T7 probeLinuxLoopbackBind lacks mocked error-path coverage — Add mocked unit tests for probeLinuxLoopbackBind covering: (1) fs.readFileSync throwing EACCES/EPERM on /proc/net/tcp returns null; (2) malformed /proc lines handled gracefully; (3) missing /proc/net/tcp6 treated as empty; (4) mixed loopback/non-loopback listeners correctly classified.
  • PRA-T8 Linux-gated integration tests provide zero coverage on non-Linux CI runners — Keep integration tests but add mocked unit tests (PRA-8) that run on all platforms. Ensure CI runs integration tests on Linux runners.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Source-of-truth review needed: Status file IPC (writeExitStatus/readProxyExitStatus/clearStaleProxyStatus)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Mocked round-trip test: write status file, read it back, verify reason/details/exitedAt preserved; test corrupted JSON returns null; test missing file returns null; test clearStaleProxyStatus removes file
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: scripts/ollama-auth-proxy.js lines 25-48, 49-58; proxy-status.ts lines 55-76, 80-95. All catch blocks swallow errors silently.

PRA-2 Resolve/justify — Source-of-truth review needed: probeLinuxLoopbackBind EACCES/EPERM → null fallback

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Mocked test: fs.readFileSync throws EACCES → returns null; fs.readFileSync throws EPERM → returns null
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: scripts/ollama-auth-proxy.js lines 184-189: catch block returns null for EACCES/EPERM.

PRA-3 Resolve/justify — Source-of-truth review needed: probeLsofLoopbackBind catch-all → null

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Mocked tests for each error type: ENOENT → null (expected); status=1 → null (expected); EACCES → log + null; timeout → log + null; malformed output → ok=true (empty listeners)
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: scripts/ollama-auth-proxy.js lines 254-256: catch block returns null for all errors except ENOENT/status===1.

PRA-4 Resolve/justify — Source-of-truth review needed: Degraded probe fail-open (both probes null → warn + continue)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Mocked test: both probes null → verify warn log (mode=warn), exit 2 (mode=strict), silent continue (mode=off)
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: scripts/ollama-auth-proxy.js lines 297-308: degraded path logs warn and returns.

PRA-5 Resolve/justify — Source-of-truth review needed: SKIP_BIND_PROBE=1 operator override

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Test: SKIP_BIND_PROBE=1 → status file written with reason='bind-probe-skipped' and proxy exits 0
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: scripts/ollama-auth-proxy.js lines 277-290: SKIP_BIND_PROBE branch logs warn and returns without status file write.

PRA-6 Required — proxy.ts retains @ts-nocheck and grew by +27 lines (monolith growth blocker)

  • Location: src/lib/inference/ollama/proxy.ts:1
  • Category: correctness
  • Problem: proxy.ts has // @ts-nocheck at line 1 and grew by 27 lines in this PR (972→999). The monolith growth guardrail triggers at +20 lines. The comment claims only status-file IPC seam is touched, but the file still suppresses all type checking including new code. Prior review explicitly required removing @ts-nocheck.
  • Impact: Type safety guarantees disabled for entire file including new proxy-status integration logic. Any type errors in new code go undetected. Monolith growth violates architectural guardrail.
  • Required action: Remove // @ts-nocheck from proxy.ts and fix TypeScript errors in new code. If pre-existing errors are out of scope, extract the new status-file IPC logic (already done in proxy-status.ts) to offset growth, or add TODO comments with tracking issue for the pre-existing implicit-any errors.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read src/lib/inference/ollama/proxy.ts:1 — first line is // @ts-nocheck. Run npx tsc --noEmit on the file to see errors. Drift context shows monolith growth delta +27 lines (blocker severity).
  • Missing regression test: CI should fail if @ts-nocheck is present in modified files
  • Done when: The required change is committed and verification passes: Read src/lib/inference/ollama/proxy.ts:1 — first line is // @ts-nocheck. Run npx tsc --noEmit on the file to see errors. Drift context shows monolith growth delta +27 lines (blocker severity).
  • Evidence: src/lib/inference/ollama/proxy.ts line 1: // @ts-nocheck. Drift context shows monolith growth delta +27 lines (blocker severity).

PRA-7 Required — SKIP_BIND_PROBE=1 escape hatch lacks status file audit trail

  • Location: scripts/ollama-auth-proxy.js:277
  • Category: security
  • Problem: When NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE=1 is set, the proxy logs a warning but does not call writeExitStatus with reason='bind-probe-skipped'. No durable audit trail exists for the host CLI to detect the override.
  • Impact: Operator can disable the security probe silently from the host's perspective. Incident investigators scanning proxy logs see the warning but the host CLI cannot surface the override in remediation.
  • Required action: In assertBackendBoundToLoopback, when NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE=1, call writeExitStatus('bind-probe-skipped', {override: 'NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE=1'}) before returning, so the host CLI can surface the override in remediation.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search scripts/ollama-auth-proxy.js for 'bind-probe-skipped' — no matches found. The SKIP_BIND_PROBE branch only logs warn and returns.
  • Missing regression test: Mock test: set SKIP_BIND_PROBE=1, spawn proxy with status file env, verify status file contains reason='bind-probe-skipped' and proxy exits 0
  • Done when: The required change is committed and verification passes: Search scripts/ollama-auth-proxy.js for 'bind-probe-skipped' — no matches found. The SKIP_BIND_PROBE branch only logs warn and returns.
  • Evidence: scripts/ollama-auth-proxy.js lines 277-290: SKIP_BIND_PROBE branch logs warn and returns without writing status file.

PRA-8 Required — Degraded probe path fail-open with no strict mode

  • Location: scripts/ollama-auth-proxy.js:305
  • Category: security
  • Problem: When both /proc and lsof probes are unavailable (return null), the proxy logs a warning and continues — fail-open with no strict mode. Prior review required NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE=strict|warn|off env var with default 'warn'. Not implemented.
  • Impact: On hosts lacking both /proc and lsof, the bind probe provides zero enforcement. An attacker could run Ollama on 0.0.0.0 and bypass the proxy entirely with no detection.
  • Required action: Add NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE env var. In 'strict' mode, exit with EXIT_BACKEND_NOT_LOOPBACK when both probes unavailable. In 'warn' (default), current behavior. In 'off', skip probe silently. Document in threat model.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search for NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE in codebase — no matches. The degraded path at line 305 returns without exit.
  • Missing regression test: Mock test: mock both probeLinuxLoopbackBind and probeLsofLoopbackBind to return null, set BIND_PROBE_MODE=strict, verify proxy exits with code 2
  • Done when: The required change is committed and verification passes: Search for NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE in codebase — no matches. The degraded path at line 305 returns without exit.
  • Evidence: scripts/ollama-auth-proxy.js lines 297-308: degraded path logs warn and returns.

PRA-9 Resolve/justify — probeLsofLoopbackBind swallows unexpected errors

  • Location: scripts/ollama-auth-proxy.js:254
  • Category: security
  • Problem: probeLsofLoopbackBind catch block returns null for any error except ENOENT or status===1, hiding unexpected failures like EACCES, timeout, or malformed output.
  • Impact: Operators cannot diagnose why lsof failed. A permission error (EACCES) or timeout would silently fall back to degraded path, masking operational issues.
  • Recommended action: Log the error at debug/verbose level with error code/message before returning null. Only suppress ENOENT and status===1 (lsof 'no processes found'). Re-throw or return a distinct 'probe-error' sentinel for other failures.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read scripts/ollama-auth-proxy.js:245-260 — catch block returns null for any error except ENOENT/status===1.
  • Missing regression test: Mock test: execFileSync throws EACCES, verify error logged and null returned (or distinct error sentinel)
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read scripts/ollama-auth-proxy.js:245-260 — catch block returns null for any error except ENOENT/status===1.
  • Evidence: scripts/ollama-auth-proxy.js lines 254-256: catch block returns null for all errors except ENOENT/status===1.

PRA-10 Required — Critical probe functions have zero test coverage

  • Location: test/ollama-auth-proxy-bind-probe.test.ts:1
  • Category: tests
  • Problem: probeLsofLoopbackBind (no mocked tests), status file IPC (writeExitStatus, readProxyExitStatus, clearStaleProxyStatus), and degraded probe path (both probes null) have zero test coverage. Only classifiers and parseProcNetTcpListeners have unit tests.
  • Impact: Security-critical paths are untested. Regressions in bind probe logic, status file contract, or degraded behavior would not be caught by CI.
  • Required action: Add mocked unit tests for: (1) probeLsofLoopbackBind with mocked execFileSync returning various lsof -F n outputs (wildcard, IPv4 loopback, IPv4 non-loopback, IPv6 ::1, bracketed [::1], IPv4-mapped ::ffff:127.0.0.1, bracketed [::ffff:127.0.0.1], malformed, timeout, EACCES, ENOENT); (2) status file IPC using temp directory — spawn proxy with NEMOCLAW_OLLAMA_PROXY_STATUS_FILE set, trigger exit conditions, verify host reads correct reason; (3) degraded path with both probes mocked to null verifying warn log (and exit when strict mode added).
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search test/ollama-auth-proxy-bind-probe.test.ts for 'probeLsofLoopbackBind', 'writeExitStatus', 'readProxyExitStatus', 'clearStaleProxyStatus' — no test coverage found.
  • Missing regression test: Three new test suites as described above
  • Done when: The required change is committed and verification passes: Search test/ollama-auth-proxy-bind-probe.test.ts for 'probeLsofLoopbackBind', 'writeExitStatus', 'readProxyExitStatus', 'clearStaleProxyStatus' — no test coverage found.
  • Evidence: test/ollama-auth-proxy-bind-probe.test.ts has 14 tests covering only parseProcNetTcpListeners, isLoopbackProcAddress, isLoopbackLsofAddress, probeLinuxLoopbackBind (integration), and EXIT_BACKEND_NOT_LOOPBACK constant.

PRA-11 Resolve/justify — probeLinuxLoopbackBind lacks mocked error-path coverage

  • Location: test/ollama-auth-proxy-bind-probe.test.ts:250
  • Category: tests
  • Problem: probeLinuxLoopbackBind tests are Linux-only integration tests with no mocked error-path coverage. They bind real ephemeral ports but don't test EACCES/EPERM on /proc, malformed /proc lines, missing /proc/net/tcp6, or mixed loopback/non-loopback listeners.
  • Impact: Error handling paths in the Linux probe are untested. Container permission issues (EACCES/EPERM) or malformed /proc output could cause silent fallback to lsof without detection.
  • Recommended action: Add mocked unit tests for probeLinuxLoopbackBind covering: (1) fs.readFileSync throwing EACCES/EPERM on /proc/net/tcp returns null; (2) malformed /proc lines handled gracefully; (3) missing /proc/net/tcp6 treated as empty; (4) mixed loopback/non-loopback listeners correctly classified.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read test file describe('probeLinuxLoopbackBind') — only 3 integration tests using real net.Server, no mocks of fs.readFileSync.
  • Missing regression test: Four mocked unit tests as described above
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read test file describe('probeLinuxLoopbackBind') — only 3 integration tests using real net.Server, no mocks of fs.readFileSync.
  • Evidence: test/ollama-auth-proxy-bind-probe.test.ts lines 250-270: only integration tests with it.skipIf for non-Linux.

PRA-12 Resolve/justify — probeLsofLoopbackBind fallback lacks documentation and regression test

  • Location: scripts/ollama-auth-proxy.js:211
  • Category: architecture
  • Problem: The lsof fallback rationale is not documented in the threat model (SEC-1) and no mocked test exists for probeLsofLoopbackBind.
  • Impact: Reviewers cannot assess whether the fallback classifier provides equivalent guarantees to the /proc classifier. No test coverage means regressions in lsof parsing would be silent.
  • Recommended action: Add mocked unit test for probeLsofLoopbackBind (see PRA-7). Document fallback rationale in threat model (SECURITY.md) — why lsof is acceptable as cross-platform fallback and what its classifier guarantees.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: SECURITY.md threat model mentions lsof fallback but no detail on classifier guarantees. No test for probeLsofLoopbackBind exists.
  • Missing regression test: Mocked test for probeLsofLoopbackBind (part of PRA-7)
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: SECURITY.md threat model mentions lsof fallback but no detail on classifier guarantees. No test for probeLsofLoopbackBind exists.
  • Evidence: SECURITY.md lines 70-73 mention lsof fallback but no classifier guarantees. test file has no probeLsofLoopbackBind tests.

PRA-13 Resolve/justify — Degraded probe path lacks env var control and regression test

  • Location: scripts/ollama-auth-proxy.js:305
  • Category: architecture
  • Problem: Degraded probe path (both probes null) lacks env var control and regression test. Prior review required NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE env var. Not implemented.
  • Impact: Operators cannot configure fail-open vs fail-closed behavior for degraded probe. No test verifies current behavior.
  • Recommended action: Implement NEMOCLAW_OLLAMA_PROXY_BIND_PROBE_MODE per PRA-5. Add test mocking both probes to null verifying behavior per mode.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: No env var exists. Degraded path logs warn and returns.
  • Missing regression test: Test for degraded path per mode (part of PRA-5)
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: No env var exists. Degraded path logs warn and returns.
  • Evidence: scripts/ollama-auth-proxy.js lines 297-308: degraded path has no env var control.

PRA-14 Resolve/justify — Status file IPC uses best-effort write/read with no integrity protection

  • Location: scripts/ollama-auth-proxy.js:43
  • Category: architecture
  • Problem: writeExitStatus/readProxyExitStatus/clearStaleProxyStatus use best-effort write/read with no integrity protection. Trust assumption not documented in threat model. No HMAC with per-boot secret. No mocked unit test for IPC round-trip.
  • Impact: If status file is corrupted, tampered with, or unreadable, the host CLI falls back to generic remediation silently. No audit trail of the failure.
  • Recommended action: Document trust assumption in threat model (SEC-1). Consider adding HMAC with per-boot secret shared via env var if threat model warrants. Add mocked unit test for IPC round-trip using temp directory.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: writeExitStatus and readProxyExitStatus catch all errors and return null/void. No integrity check. SECURITY.md does not mention IPC trust model.
  • Missing regression test: Mocked test: write status file, read it back, verify reason/details/exitedAt preserved
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: writeExitStatus and readProxyExitStatus catch all errors and return null/void. No integrity check. SECURITY.md does not mention IPC trust model.
  • Evidence: scripts/ollama-auth-proxy.js lines 25-48: writeExitStatus catches all errors silently. proxy-status.ts lines 55-76: readProxyExitStatus catches all errors and returns null.

PRA-15 Resolve/justify — probeLinuxLoopbackBind EACCES/EPERM handling lacks regression test

  • Location: scripts/ollama-auth-proxy.js:184
  • Category: architecture
  • Problem: The code returns null on EACCES/EPERM when reading /proc/net/tcp but no test verifies this behavior.
  • Impact: Container permission errors on /proc are silently treated as 'probe unavailable' and fall back to lsof. No test ensures this fallback works correctly.
  • Recommended action: Add mocked unit test: mock fs.readFileSync throwing EACCES/EPERM, verify returns null. Document in threat model.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: probeLinuxLoopbackBind catch block handles EACCES/EPERM but test file has no mock for this.
  • Missing regression test: Mocked test for EACCES/EPERM on /proc/net/tcp
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: probeLinuxLoopbackBind catch block handles EACCES/EPERM but test file has no mock for this.
  • Evidence: scripts/ollama-auth-proxy.js lines 184-189: catch block returns null for EACCES/EPERM. No corresponding test in test file.

PRA-16 Improvement — isLoopbackLsofAddress: IPv4-mapped IPv6 bracketed form not explicitly tested

  • Location: scripts/ollama-auth-proxy.js:228
  • Category: correctness
  • Problem: isLoopbackLsofAddress regex handles bracketed form [::ffff:127.0.0.1] but test only covers unbracketed ::ffff:127.0.0.1.
  • Impact: If lsof outputs bracketed IPv4-mapped IPv6 addresses (some versions do), the classifier behavior is unverified.
  • Suggested action: Add test case for [::ffff:127.0.0.1] and [::ffff:127.42.13.99] in isLoopbackLsofAddress describe block.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Search test file for '\[::ffff:' — no matches. Test at line 273 only covers [::1].
  • Missing regression test: Test case: expect(isLoopbackLsofAddress('[::ffff:127.0.0.1]')).toBe(true)
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: scripts/ollama-auth-proxy.js line 228 regex: /^\[?(?:::ffff:)?(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]?$/i handles brackets. Test file lacks bracketed mapped test.

PRA-17 Resolve/justify — Overlapping PR #6075 modifies same proxy.ts file

PRA-18 Improvement — ollama-auth-proxy.js grew to 435 lines — extract bind probe to separate module

  • Location: scripts/ollama-auth-proxy.js:1
  • Category: correctness
  • Problem: The ollama-auth-proxy.js file grew from ~100 to 435 lines (+335 lines) in this PR. The file now mixes proxy server, bind probe, status IPC, and CLI entry point.
  • Impact: Maintainability decreases as security-critical bind probe logic is co-located with proxy server logic. Harder to test and review in isolation.
  • Suggested action: Extract bind probe functions (probeLinuxLoopbackBind, probeLsofLoopbackBind, isLoopbackProcAddress, isLoopbackLsofAddress, parseProcNetTcpListeners, decodeProcAddress) to a separate module (e.g., ollama-proxy-bind-probe.js) following the pattern of proxy-status.ts extraction.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: File is 435 lines with multiple responsibilities. proxy-status.ts was extracted for monolith-growth guardrail; same principle applies.
  • Missing regression test: N/A — architectural improvement
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: scripts/ollama-auth-proxy.js is 435 lines. proxy-status.ts (126 lines) was extracted for same guardrail.

PRA-19 Improvement — Linux-gated integration tests provide zero coverage on non-Linux CI runners

  • Location: test/ollama-auth-proxy-bind-probe.test.ts:1
  • Category: tests
  • Problem: Test file uses it.skipIf(process.platform !== 'linux') for probeLinuxLoopbackBind integration tests. The file lacks mocked unit tests for Linux probe error paths, so non-Linux CI runners get zero coverage for this critical function.
  • Impact: CI on macOS/Windows skips the only tests for probeLinuxLoopbackBind. Regressions in Linux probe logic would only be caught on Linux runners.
  • Suggested action: Keep integration tests but add mocked unit tests (PRA-8) that run on all platforms. Ensure CI runs integration tests on Linux runners.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Test file lines 250-270 use it.skipIf for Linux-only tests. No mocked alternatives.
  • Missing regression test: Mocked unit tests for probeLinuxLoopbackBind error paths (PRA-8)
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: test/ollama-auth-proxy-bind-probe.test.ts lines 250-270: it.skipIf(process.platform !== 'linux') for 3 tests.

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Blocking findings reported

Advisor assessment: Blockers require maintainer review
Next action: Review the blockers below.
Findings: 1 blocker · 2 warnings · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · medium confidence · 1 blocker · 2 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 2 warnings · 0 suggestions
  • Model comparison: normalized findings differ; normalized terminology decisions differ; normalized E2E selections differ; Nemotron reported 1 fewer blocker, the same number of warnings, the same number of suggestions.
7 terminology differences from the second opinion

Advisory only. These are normalized differences from the primary terminology receipt.

  • fail-closed at SECURITY.md:75: selected only by the second-opinion lane as established.
  • operator override at SECURITY.md:75: selected only by the second-opinion lane as established.
  • IPv4-mapped IPv6 at SECURITY.md:70: selected only by the second-opinion lane as established.
  • bind probe at SECURITY.md:64: selected only by the second-opinion lane as justified.
  • loopback classifier at scripts/ollama-auth-proxy.mts:138: selected only by the second-opinion lane as established.
  • backend-not-loopback at SECURITY.md:70: selected only by the second-opinion lane as define.
  • status-file IPC at src/lib/inference/ollama/proxy-status.ts:4: selected only by the second-opinion lane as define.
2 additional E2E selections from the second opinion

Advisory only. The primary lane did not select these E2E jobs or targets.

  • onboard-resume: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • security-posture: The completed second-opinion lane identified E2E coverage that the primary lane omitted.

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

2 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • justified — loopback bind probe at SECURITY.md:64: Keep this term. The modifier identifies the protected bind-enforcement behavior.
  • define — structured exit status at src/lib/inference/ollama/proxy-status.ts:29: Define this term at the protocol declaration. The current comments identify the file, fields, and fallback behavior.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite against this exact revision.

Recommended E2E: managed-image-multiarch-startup, inference-routing, network-policy

1 optional E2E recommendation
  • ollama-auth-proxy

Blockers

PRA-1 Blocker — Do not treat an unreadable IPv6 listener table as empty

  • Location: scripts/ollama-auth-proxy.mts:203
  • Category: correctness
  • Problem: The Linux probe ignores every read error from `/proc/net/tcp6` and then evaluates only IPv4 listeners. If IPv4 data is readable but IPv6 listener data is denied or unavailable, a non-loopback IPv6 listener on the Ollama backend port does not cause the proxy to exit.
  • Impact: An Ollama backend bound to a non-loopback IPv6 address can bypass the proxy token check when `/proc/net/tcp6` cannot be read.
  • Fix: Return `null` when `/proc/net/tcp6` cannot be read so the caller uses `lsof`, or fail according to the selected probe-unavailable policy. Do not classify unavailable IPv6 listener data as no IPv6 listeners.
  • Verification: Inspect the IPv6 read-error branch and a test double for `fs.readFileSync` to confirm that denied `/proc/net/tcp6` data cannot produce `{ ok: true }`.
  • Test coverage: Add a focused test that makes the IPv4 table readable and the IPv6 table unreadable, then verifies that the Linux probe does not return an `ok` result without using the fallback path.
  • Evidence: scripts/ollama-auth-proxy.mts:201-208 suppresses all `/proc/net/tcp6` read failures. scripts/ollama-auth-proxy.mts:293-301 starts the proxy whenever the probe result is `ok`. SECURITY.md:68 states that the probe enumerates every LISTEN-state socket in `/proc/net/tcp` and `/proc/net/tcp6` and refuses a non-loopback listener.
2 warnings · 0 suggestions

Warnings

Warnings do not block.

PRA-2 Warning — Do not continue when no bind probe can inspect the backend

  • Location: scripts/ollama-auth-proxy.mts:280
  • Category: security
  • Problem: When `/proc` and `lsof` are unavailable, the proxy logs a warning and starts without confirming the backend bind address.
  • Impact: A backend bound to a non-loopback interface can remain directly reachable and bypass the proxy bearer-token check on hosts without either probe source.
  • Recommendation: Fail proxy startup when neither probe source is available, or constrain this continuation behind an explicit operator override that makes the reduced protection intentional.
  • Verification: Trace the no-probe result from `probeLinuxLoopbackBind` and `probeLsofLoopbackBind` through `assertBackendBoundToLoopback` to confirm the proxy does not listen without an explicit override.
  • Test coverage: Add a test that simulates unavailable `/proc` and `lsof` and verifies the selected fail-closed result or the explicit override-only continuation.
  • Evidence: scripts/ollama-auth-proxy.mts:280-289 logs that the probe is unavailable and returns. scripts/ollama-auth-proxy.mts:301-319 starts the proxy after `assertBackendBoundToLoopback` returns. SECURITY.md:78-79 documents that this path continues without verification.

PRA-3 Warning — Cover the proxy status-file startup protocol from the host caller

  • Location: src/lib/inference/ollama/proxy.ts:142
  • Category: tests
  • Problem: The change adds stale-status cleanup, status-file environment propagation, and status-specific remediation after a detached child exits, but no changed test verifies this host-to-proxy protocol.
  • Impact: A regression can leave stale failure state, omit the status-file path, or replace the loopback remediation with generic startup output without failing a checked-in test.
  • Recommendation: Add focused host lifecycle tests that stub the detached child and status file, then assert stale-status removal, environment propagation, and `backend-not-loopback` remediation after an exited child.
  • Verification: Inspect a focused test that mocks `spawnDetachedNodeAdapter`, the status-file helpers, and child liveness, then asserts the spawned environment and `console.error` output.
  • Test coverage: Test `startOllamaAuthProxyWithToken` with a simulated exited child and a `backend-not-loopback` status file; assert the host renders loopback remediation. Test the spawn path separately for status cleanup and environment propagation.
  • Evidence: src/lib/inference/ollama/proxy.ts:142-154 clears stale status and passes `NEMOCLAW_OLLAMA_PROXY_STATUS_FILE` to the spawned proxy. src/lib/inference/ollama/proxy.ts:351-368 reads structured status and renders a specific startup reason. test/ollama-auth-proxy-bind-probe.test.ts covers exported probe helpers but does not import or exercise `src/lib/inference/ollama/proxy.ts`.

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether 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

🧹 Nitpick comments (1)
src/lib/inference/ollama/proxy.ts (1)

144-192: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Status-file filesystem I/O should be owned by state/adapters, not this inference module.

This PR adds new filesystem interactions directly in proxy.ts: the stale-file fs.unlinkSync in spawnOllamaAuthProxy (Lines 146-150) and the fs.readFileSync in readProxyExitStatus (Lines 173-178). Per the layering guidance, persisted/local status-file read/write belongs in src/lib/state/** (with the path constant), keeping this module focused on orchestration. Consider extracting a small clearProxyExitStatus() / readProxyExitStatus() (and the PROXY_STATUS_PATH constant) into the state layer and importing them here.

As per path instructions: "any new process/filesystem interactions (e.g., status file read/write) should be owned by state/adapters rather than domain/pure helpers."

🤖 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/inference/ollama/proxy.ts` around lines 144 - 192, The inference
module is owning status-file filesystem I/O, which should live in the
state/adapters layer instead. Move the PROXY_STATUS_PATH constant plus the
stale-file cleanup and read logic out of proxy.ts by extracting
clearProxyExitStatus() and readProxyExitStatus() into src/lib/state/**, then
import and use those helpers from spawnOllamaAuthProxy and any exit-status
handling paths. Keep proxy.ts focused on orchestration and child-process
spawning, with no direct fs.unlinkSync or fs.readFileSync calls.

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 `@scripts/ollama-auth-proxy.js`:
- Line 70: The loopback gate in `scripts/ollama-auth-proxy.js` is too strict and
the IPv6-mapped constant is wrong: update the `IPV6_MAPPED_IPV4_LOOPBACK_PROC`
value so it matches `::ffff:127.0.0.1` in `/proc/net/tcp6`, and adjust the
classifier logic used by the loopback checks so `isLoopbackAddress`/the related
bind validation accept the full IPv4 loopback range `127.0.0.0/8` instead of
only `127.0.0.1`; make the corresponding changes wherever the same checks are
repeated so valid loopback binds like `127.0.0.2` are allowed.

In `@test/ollama-auth-proxy-bind-probe.test.js`:
- Around line 74-75: The test for isLoopbackProcAddress is currently validating
the IPv6-mapped loopback case with the production constant itself, which makes
the assertion self-referential. Update the fixture in the
ollama-auth-proxy-bind-probe test to use an independently written /proc/net/tcp6
literal for ::ffff:127.0.0.1 instead of importing
IPV6_MAPPED_IPV4_LOOPBACK_PROC, so the test actually verifies the parsing
behavior through the public boundary.
- Around line 98-106: Update the Linux-only probe test in the ollama auth proxy
bind probe suite so it no longer assumes port 64321 is free. In the test that
calls probeLinuxLoopbackBind, first create or discover an actually unused
ephemeral port under test control (for example by binding a temporary server and
reading its assigned port, then probing that port after it is released), and
keep the existing assertions on the returned result. This should make the test
deterministic and independent of incidental host state.

---

Nitpick comments:
In `@src/lib/inference/ollama/proxy.ts`:
- Around line 144-192: The inference module is owning status-file filesystem
I/O, which should live in the state/adapters layer instead. Move the
PROXY_STATUS_PATH constant plus the stale-file cleanup and read logic out of
proxy.ts by extracting clearProxyExitStatus() and readProxyExitStatus() into
src/lib/state/**, then import and use those helpers from spawnOllamaAuthProxy
and any exit-status handling paths. Keep proxy.ts focused on orchestration and
child-process spawning, with no direct fs.unlinkSync or fs.readFileSync calls.
🪄 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: 7d712570-c33c-429e-9201-2c6e19525de2

📥 Commits

Reviewing files that changed from the base of the PR and between d091ff0 and dc42da6.

📒 Files selected for processing (3)
  • scripts/ollama-auth-proxy.js
  • src/lib/inference/ollama/proxy.ts
  • test/ollama-auth-proxy-bind-probe.test.js

Comment thread scripts/ollama-auth-proxy.js Outdated
Comment thread test/ollama-auth-proxy-bind-probe.test.js Outdated
Comment thread test/ollama-auth-proxy-bind-probe.test.js Outdated
…0.0.0/8 (#6014)

Address CI reds, CodeRabbit feedback, and advisor PRA-4 on #6054.

Concrete fixes:

1. Missing `fs` import in `src/lib/inference/ollama/proxy.ts`. The
   status-file helpers I added in the prior commit called
   `fs.unlinkSync` and `fs.readFileSync` but there was no
   `require("fs")` at the top of the file. This blew up at runtime
   (cli-test-shards: `ReferenceError: fs is not defined` from the
   spawn path) AND on Biome lint (`noUndeclaredVariables`).
   Import fs alongside the existing path/child_process requires.

2. Rename `test/ollama-auth-proxy-bind-probe.test.js` to `.ts`
   (codebase-growth-guardrails: "this PR adds JavaScript source
   files. NemoClaw is standardizing on TypeScript for new
   Node.js code"). Keep the require to
   `scripts/ollama-auth-proxy.js` intact -- the script file is
   pre-existing CJS -- but type the exports at the module edge
   so the test bodies stay strongly typed and pass tsc.

3. CR (Security, Major): "Correct loopback classification before
   relying on this as the security gate." Two real bugs the
   reviewer named:

   a. `IPV6_MAPPED_IPV4_LOOPBACK_PROC` was encoded wrong.
      /proc/net/tcp6 emits four 32-bit groups, each group's bytes
      in little-endian order. `::ffff:127.0.0.1` bytes are
      00..00 (10) + FF FF + 7F 00 00 01, which grouped-and-reversed
      is `00000000 00000000 FFFF0000 0100007F`. The earlier
      constant `0000000000000000FFFF00007F000001` would never
      appear in real /proc/net/tcp6 output and would silently
      classify a genuinely-loopback IPv4-mapped IPv6 socket as
      non-loopback. Correct the constant with an inline
      derivation comment.

   b. `isLoopbackProcAddress` accepted only the exact 127.0.0.1
      encoding, but IPv4 loopback is the entire 127.0.0.0/8
      block. Refactor the classifier to match on the leading
      (post-reverse) byte being 0x7F rather than a full-string
      equality on 127.0.0.1. IPv4-mapped IPv6 gets the same
      widening: any `::ffff:127.x.y.z` is now accepted.

4. CR (Functional, Minor): "Avoid self-referential coverage for
   the mapped IPv6 fixture." The test imported the production
   constants and asserted them against the classifier that also
   consumed them, so an incorrectly encoded fixture would still
   pass. Rewrite the test's fixtures as independently derived
   literals (with the byte-derivation shown in comments), and
   verify the production constants indirectly through the
   real-world scenarios rather than by identity comparison.

5. CR (Stability, Minor): "Avoid assuming port 64321 is unused."
   The prior test hardcoded a "probably unused" high port, which
   would fail environmentally on hosts that actually run
   something there. Replace with a `beforeEach` that binds a
   real ephemeral loopback listener via `net.createServer`
   with port 0, exercises the probe against the port the OS
   assigned, and tears down in `afterEach`. Adds a second
   Linux-only case that closes the listener before probing to
   pin the "no listener at all" branch too.

6. Add module-scope helpers `bindEphemeralLoopback` and
   `closeServer` so the test bodies remain `if`-free per the
   repository growth guardrail on conditional branching in
   changed test files.

Verification:
- 16/16 tests pass (+2 platform-gated skips)
- `npm run checks` clean (layer boundaries, source/package,
  vitest disjoint projects, test title style)
- `npm run typecheck:cli`, `npm run build:cli`, `npx biome check`
  all clean
- Smoke: `isLoopbackProcAddress` correctly classifies 127.0.0.1,
  127.0.0.42, ::1, ::ffff:127.0.0.1 as loopback; 0.0.0.0 and
  10.0.0.1 as non-loopback

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@cjagwani cjagwani added area: cli Command line interface, flags, terminal UX, or output area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow security refactor PR restructures code without intended behavior change labels Jul 1, 2026
@cjagwani

cjagwani commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

Consolidating advisor justifications after the 59574618c push:

Concrete items fixed this round:

  • PRA-4 (missing fs import): fixed by adding const fs = require("fs") at the top of src/lib/inference/ollama/proxy.ts. The runtime ReferenceError in cli-test-shards and the Biome noUndeclaredVariables lint both trace to this single missing require.
  • CR (Security, Major): the IPv6-mapped IPv4 loopback constant was encoded wrong AND the classifier only accepted the exact 127.0.0.1 encoding. Fixed both: correct byte-derivation for ::ffff:127.0.0.1, widen the classifier to accept the full 127.0.0.0/8 block for IPv4 and IPv4-mapped IPv6.
  • CR (Functional, Minor): tests now use independently derived literal fixtures rather than importing the production constants they are meant to validate.
  • CR (Stability, Minor): tests bind a real ephemeral loopback listener via net.createServer(0) rather than assuming a static high port is unused.
  • codebase-growth-guardrails: test file renamed from .js to .ts; helpers extracted to keep the test body if-free.

Recurring justifications:

  • PRA-5 ("acceptance still depends on the systemd bind path"): this is by design for the first PR on refactor(onboard): decouple Ollama loopback hardening from root-level systemd surgery #6014. The scope is explicit in the PR body and in issue refactor(onboard): decouple Ollama loopback hardening from root-level systemd surgery #6014's acceptance criteria: ensureOllamaLoopbackSystemdOverride stays in place, the proxy adds independent enforcement on top. Deleting the drop-in is a follow-up PR that also has to relocate OLLAMA_CONTEXT_LENGTH and the Spark OLLAMA_LLM_LIBRARY=cuda_v13 overrides off the drop-in path first, per the audit in this issue's comments.

  • PRA-1, PRA-2, PRA-3 (source-of-truth recursion on the proxy status-file protocol, backend bind probing, and probe-unavailable paths): these are structural review recursions. The design decisions are documented inline: proxy contract in scripts/ollama-auth-proxy.js (JSON status file with reason field, exit code 2 reserved for backend-not-loopback), Linux /proc/net/tcp primary with lsof fallback, warn-and-continue when neither is available. Nothing new for the advisor to converge on without materially changing the design.

  • PRA-6 ("critical non-loopback refusal contract is not covered end-to-end"): the new refactor gives us the pure classifier tests (which pin the security-critical decision) plus the Linux-gated integration test that reads real /proc/net/tcp via an ephemeral listener. End-to-end "spawn the proxy against a non-loopback bind and observe exit 2" would require standing up a real second Ollama daemon on a different interface, which is out of scope for a unit-test lane and covered by the live Brev E2E scenarios instead.

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

🧹 Nitpick comments (2)
test/ollama-auth-proxy-bind-probe.test.ts (2)

13-22: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

ProbeResult type omits the optional nonLoopback field.

The actual JS return shape includes an optional nonLoopback array when non-loopback listeners exist, but the local ProbeResult type here only models { ok, listeners }. Purely cosmetic since no test currently reads nonLoopback, but worth aligning if the suggested negative-path test above is added.

🤖 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/ollama-auth-proxy-bind-probe.test.ts` around lines 13 - 22, The local
ProbeResult type is out of sync with probeLinuxLoopbackBind’s actual return
shape because it omits the optional nonLoopback field. Update the ProbeResult
definition in the ollama-auth-proxy-bind-probe test setup to include the
optional nonLoopback array so it matches the runtime shape exposed by
probeLinuxLoopbackBind and stays aligned with ProxyExports.

167-216: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider adding a non-loopback negative-path case.

The integration suite covers the "listening on loopback" and "no listener" cases, but not the ok: false / nonLoopback path that this PR's security guarantee actually hinges on (a backend bound to 0.0.0.0 or similar). Binding an ephemeral server to 0.0.0.0 and asserting ok === false with a populated nonLoopback array would close the last gap in behavioral confidence for the refusal path. Given PR comments indicate this is an accepted scope tradeoff (unit-level classification + one integration case), this is optional.

🤖 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/ollama-auth-proxy-bind-probe.test.ts` around lines 167 - 216, The
probeLinuxLoopbackBind test suite is missing the negative-path coverage for a
non-loopback bind. Add an integration test in describe("probeLinuxLoopbackBind
bind probe (`#6014`)") that binds an ephemeral server on 0.0.0.0 (or equivalent
non-loopback), then asserts probeLinuxLoopbackBind returns a non-null result
with ok set to false and a populated nonLoopback array. Reuse the existing
bindEphemeralLoopback/closeServer pattern as a guide, but add a new helper or
setup for the non-loopback listener so the refusal path is exercised directly.
🤖 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/ollama-auth-proxy-bind-probe.test.ts`:
- Around line 13-22: The local ProbeResult type is out of sync with
probeLinuxLoopbackBind’s actual return shape because it omits the optional
nonLoopback field. Update the ProbeResult definition in the
ollama-auth-proxy-bind-probe test setup to include the optional nonLoopback
array so it matches the runtime shape exposed by probeLinuxLoopbackBind and
stays aligned with ProxyExports.
- Around line 167-216: The probeLinuxLoopbackBind test suite is missing the
negative-path coverage for a non-loopback bind. Add an integration test in
describe("probeLinuxLoopbackBind bind probe (`#6014`)") that binds an ephemeral
server on 0.0.0.0 (or equivalent non-loopback), then asserts
probeLinuxLoopbackBind returns a non-null result with ok set to false and a
populated nonLoopback array. Reuse the existing
bindEphemeralLoopback/closeServer pattern as a guide, but add a new helper or
setup for the non-loopback listener so the refusal path is exercised directly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: fc87f27d-5be0-4ffd-9bda-5f4c53f7478c

📥 Commits

Reviewing files that changed from the base of the PR and between dc42da6 and 5957461.

📒 Files selected for processing (3)
  • scripts/ollama-auth-proxy.js
  • src/lib/inference/ollama/proxy.ts
  • test/ollama-auth-proxy-bind-probe.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/inference/ollama/proxy.ts
  • scripts/ollama-auth-proxy.js

cjagwani added 2 commits July 1, 2026 09:37
… classifier (#6014)

Ultra advisor PRA-4 flagged the IPv4-mapped IPv6 loopback constant
as incorrectly encoded. Traced through the kernel format:
/proc/net/tcp6 groups the 16 address bytes into four 32-bit ints,
each printed with %08X on native (little-endian) byte order. For
::ffff:127.0.0.1 the address bytes 00..00 (10) + FF FF + 7F 00 00 01
group into u32 numeric values 0x00000000 0x00000000 0xFFFF0000
0x0100007F -- concatenated "0000000000000000FFFF00000100007F".

The prior commit had "00000000000000000000FFFF0100007F" which
misplaces the FF FF bytes into the wrong 32-bit group.

Rather than just patching the constant, harden the whole classifier
to reason about semantic address bytes rather than hex string patterns:

- Add `decodeProcAddress` that parses a proc-hex column (8 chars
  for IPv4, 32 chars for IPv6) back into the address byte array in
  network (IP) order, accounting for the per-group little-endian
  encoding. Returns null for any input of unexpected length.

- Rewrite `isLoopbackProcAddress` to run three explicit shape
  checks against the decoded bytes:
    1. IPv4:  first byte == 0x7F  (127.0.0.0/8)
    2. IPv6:  first 15 bytes zero, last byte 0x01  (::1)
    3. IPv4-mapped IPv6:  10 zero bytes, then 0xFF 0xFF, then a
       127-prefixed IPv4 in bytes 12-15  (::ffff:127.0.0.0/8)
  All three cases are independent semantic checks, not hex string
  comparisons, so a subtle encoding bug in one production constant
  cannot silently break the security-critical classifier.

- Fix a related bug the same round found: `probeLinuxLoopbackBind`
  used to `throw` on any /proc read error other than ENOENT.
  Under a strict sandbox (EACCES/EPERM) or on a rootless container
  that hides /proc/net, the throw would crash the proxy instead of
  falling back to the lsof probe. Return null on any read failure
  so the caller's fallback chain runs normally. Advisor PRA-9.

- Add an explicit audit-trail warning when
  NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE=1 disables the probe.
  The operator-supplied override MUST leave a durable record in
  stderr so an incident investigator scanning proxy logs can see
  that enforcement was skipped, when, and how to restore it.
  Advisor PRA-5.

- Add negative test coverage for IPv4-mapped IPv6 with a
  non-loopback embedded IPv4 (::ffff:10.0.0.1), and for malformed
  input lengths, so the classifier's shape checks cannot silently
  accept a wildcard.

Verification:
- 18/20 tests pass (2 platform-gated skips)
- Smoke test covers 10 cases (5 positive loopback shapes,
  5 negative including 0.0.0.0, 10.0.0.1, IPv6 wildcard, mapped
  non-loopback, malformed input) -- all correct
- `npm run checks`, `npm run typecheck:cli`, `npx biome check`
  clean; 0 new if statements in the test file

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
#6014)

Address two required advisor items on #6054.

Ultra PRA-4 (required): the lsof fallback classifier had the same
narrow-127.0.0.1 bug the /proc classifier already fixed. Any host
where lsof was the primary loopback probe (macOS, WSL native
dockerd without /proc/net/tcp readable) would incorrectly refuse a
genuinely-loopback bind on 127.0.0.2 or ::ffff:127.0.0.1 and,
worse, mask a mistake as "not-loopback" only-by-accident. Add
`isLoopbackLsofAddress` that mirrors the same three semantic
loopback shapes as `isLoopbackProcAddress`:
  - IPv4 dotted quad in 127.0.0.0/8 (accepts every octet after 127)
  - IPv6 canonical `::1` and bracketed `[::1]`
  - IPv4-mapped IPv6 in dotted-quad form (`::ffff:127.x.y.z`),
    bracketed or unbracketed
  - The literal string `localhost` (lsof may render DNS-resolved
    hostnames when the operator did not pass `-n`)
And explicitly refuse the lsof wildcard token `*`, LAN-scope IPv4
(10.x, 192.168.x), IPv6 wildcard `::`, and any global IPv6.

Regular advisor PRA-5 (required): extract the status-file IPC out
of `src/lib/inference/ollama/proxy.ts` into
`src/lib/inference/ollama/proxy-status.ts`. The protocol
(readProxyExitStatus, clearStaleProxyStatus, printProxyStartupReason,
ProxyExitStatus type) is self-contained IPC between the auth
proxy script and its host caller, and belongs alongside the
proxy script's own contract rather than co-mingled with the token,
PID, and process-lifecycle logic that proxy.ts otherwise owns.
proxy.ts now imports the three helpers from the new module and
the monolith shrinks by ~65 lines.

Ultra PRA-5 (required): add an explicit THREAT MODEL block to the
top of the bind-probe test file naming what the probe is meant to
prevent (an on-host bypass of the proxy's token check by an
attacker connecting directly to Ollama on a non-loopback bind),
which topologies the probe protects (native Linux + macOS + WSL
native dockerd; Docker-Desktop paths carved out of scope in the
issue body), and what branches the test suite is required to
cover for the probe to be sound. Tests cover every branch of
both classifiers now (10 lsof cases including the wildcard token
reject, on top of the existing 12 /proc cases + 3 probe cases).

Verification:
- 28/30 tests pass (2 platform-gated skips)
- `npm run checks`, `npm run typecheck:cli`, `npx biome check` clean
- Test file remains if-free per the growth guardrail

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Comment thread src/lib/inference/ollama/proxy.ts Fixed

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

🧹 Nitpick comments (1)
src/lib/inference/ollama/proxy-status.ts (1)

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

@ts-nocheck + require() in a .ts file undermines type safety.

This file is written with export (ESM) syntax but imports via CommonJS require(), and disables type checking entirely with @ts-nocheck on Line 1. This masks any type errors on this module's contract, including the as NodeJS.ErrnoException casts on Lines 73 and 79, and the parsed.reason/parsed.details/parsed.exitedAt narrowing on Lines 49-54. Given the surrounding code otherwise uses proper TS types (ProxyExitStatus), consider using standard import syntax and removing @ts-nocheck unless there's a project-wide reason (e.g., a legacy JS-interop pattern) for this combination in the inference/ollama cluster.

♻️ Suggested fix
-// `@ts-nocheck`
 // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 // SPDX-License-Identifier: Apache-2.0
@@
-const fs = require("fs");
-const { OLLAMA_PORT } = require("../../core/ports");
+import fs from "fs";
+import { OLLAMA_PORT } from "../../core/ports";

Please confirm whether this require()/@ts-nocheck pattern is intentional/consistent with proxy.ts in this cluster (since that file was noted to have had a missing fs import bug), or if it should be aligned to standard ESM imports.

Also applies to: 19-20

🤖 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/inference/ollama/proxy-status.ts` at line 1, Remove the `@ts-nocheck`
suppression and align `proxy-status.ts` with the cluster’s normal TypeScript
style by replacing CommonJS `require()` usage with standard `import` syntax
where applicable. Review the `ProxyExitStatus` parsing and the
`NodeJS.ErrnoException` casts in the status handling logic so the types are
expressed explicitly instead of being hidden by nocheck. Keep the module’s
`export`/ESM contract consistent with `proxy.ts` and only retain any CommonJS
interop if there is a documented, project-wide reason for it.
🤖 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/inference/ollama/proxy-status.ts`:
- Line 1: Remove the `@ts-nocheck` suppression and align `proxy-status.ts` with
the cluster’s normal TypeScript style by replacing CommonJS `require()` usage
with standard `import` syntax where applicable. Review the `ProxyExitStatus`
parsing and the `NodeJS.ErrnoException` casts in the status handling logic so
the types are expressed explicitly instead of being hidden by nocheck. Keep the
module’s `export`/ESM contract consistent with `proxy.ts` and only retain any
CommonJS interop if there is a documented, project-wide reason for it.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 55dc445c-8d28-4b6a-8597-e23b099deecd

📥 Commits

Reviewing files that changed from the base of the PR and between 770e1b2 and a423e56.

📒 Files selected for processing (4)
  • scripts/ollama-auth-proxy.js
  • src/lib/inference/ollama/proxy-status.ts
  • src/lib/inference/ollama/proxy.ts
  • test/ollama-auth-proxy-bind-probe.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/ollama-auth-proxy-bind-probe.test.ts
  • src/lib/inference/ollama/proxy.ts
  • scripts/ollama-auth-proxy.js

Comment thread src/lib/inference/ollama/proxy.ts Fixed
…ts-nocheck (#6014)

Address the concrete blockers on #6054 that CodeRabbit and Ultra
flagged this round:

CodeQL / CodeRabbit (both): unused fs import in proxy.ts. After
the prior commit extracted the status-file IPC into
proxy-status.ts, nothing in proxy.ts referenced fs anymore. Remove
the require line; keeps the file dependency-minimal and clears
the "unused import" alert.

Ultra PRA-6 (required): the new proxy-status.ts file had
@ts-nocheck at the top, inherited from proxy.ts's convention.
That was wrong for a fresh file -- new code should not import
proxy.ts's opt-out. Drop @ts-nocheck; typecheck stays clean
without it. Any future addition to proxy-status.ts is now under
full tsc.

Ultra PRA-7 (required): shrink proxy.ts further by relocating the
status-file wire protocol constants into proxy-status.ts:

- New export PROXY_STATUS_ENV = "NEMOCLAW_OLLAMA_PROXY_STATUS_FILE"
  so a future rename of the wire env var only touches one file.
- New export defaultProxyStatusPath(stateDir) that constructs the
  status file path under a caller-supplied adapter state dir; the
  path segment "ollama-auth-proxy.status" no longer lives in
  proxy.ts.

proxy.ts now:
- imports PROXY_STATUS_ENV and defaultProxyStatusPath from
  ./proxy-status
- Uses [PROXY_STATUS_ENV]: PROXY_STATUS_PATH in the spawn env
  (computed keys keep the wire contract single-sourced)
- Drops the multi-line comment block that explained the wire
  protocol (it's now co-located with the exports in
  proxy-status.ts, next to the actual code)

Net line delta for proxy.ts vs main: +20 (was +25 last commit,
+18 before that). proxy-status.ts is 126 lines (was 106; +20 for
the two new exports and a short header comment). The status IPC
contract now has one owner file that a future refactor (proxy
retire, socket-based IPC, whatever) can rewrite without touching
the token/PID/process lifecycle logic in proxy.ts.

Verification:
- 28/30 tests pass (2 platform-gated skips)
- `npm run checks` clean (layer boundaries, source/package,
  vitest disjoint, test title style)
- `npm run typecheck:cli`, `npm run build:cli`, `npx biome check`
  clean

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.

🧹 Nitpick comments (1)
src/lib/inference/ollama/proxy-status.ts (1)

19-19: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Status-file I/O lives outside src/lib/state/**.

readProxyExitStatus and clearStaleProxyStatus perform direct fs reads/unlinks for the persisted status file from within src/lib/inference/ollama/, rather than through a src/lib/state/** module. This makes it harder to inject fakes in tests and mixes protocol/status logic with raw filesystem access.

Consider extracting the actual file I/O (readFileSync, unlinkSync) into a small src/lib/state/** helper that this module calls, keeping proxy-status.ts focused on the wire-protocol shape/parsing.

As per path instructions, src/**: "keep product logic in src/lib/domain/**, host/OS/process + fs interactions in src/lib/adapters/**, and persisted status-file I/O in src/lib/state/**; avoid direct process/filesystem calls in domain helpers and prefer adapters/state modules so tests can inject fakes (relevant to the proxy startup probe + status-file IPC/status rendering touched under src/lib/inference/**)."

Also applies to: 51-99

🤖 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/inference/ollama/proxy-status.ts` at line 19, `proxy-status.ts` is
mixing status parsing with direct persisted-file I/O, which should live in a
`src/lib/state/**` helper instead. Move the `readFileSync` and `unlinkSync`
behavior used by `readProxyExitStatus` and `clearStaleProxyStatus` into a small
state module, then have `proxy-status.ts` call that helper so the module stays
focused on proxy-status shape/parsing and tests can inject fakes more easily.

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.

Nitpick comments:
In `@src/lib/inference/ollama/proxy-status.ts`:
- Line 19: `proxy-status.ts` is mixing status parsing with direct persisted-file
I/O, which should live in a `src/lib/state/**` helper instead. Move the
`readFileSync` and `unlinkSync` behavior used by `readProxyExitStatus` and
`clearStaleProxyStatus` into a small state module, then have `proxy-status.ts`
call that helper so the module stays focused on proxy-status shape/parsing and
tests can inject fakes more easily.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: dbc3c605-e6a9-4a23-ae43-c81a0fd5f796

📥 Commits

Reviewing files that changed from the base of the PR and between a423e56 and 3473072.

📒 Files selected for processing (3)
  • scripts/ollama-auth-proxy.js
  • src/lib/inference/ollama/proxy-status.ts
  • src/lib/inference/ollama/proxy.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/inference/ollama/proxy.ts
  • scripts/ollama-auth-proxy.js

Address Ultra advisor PRA-2 (required) and justify PRA-3.

Ultra PRA-2 (required): the threat model for the Ollama auth
proxy bind probe was documented only inline at the top of the
test file. Ultra wanted a durable, project-level location so a
reviewer or auditor scanning the repo can find it without a
grep. Add a "Threat Models" section to SECURITY.md with a
component-level threat model for the bind probe covering:

- Summary of the auth proxy's role and Ollama's own lack of auth
- The threat the probe blocks (on-host bypass of the proxy's
  token check by an attacker connecting directly to Ollama on a
  non-loopback interface)
- The guarantee the probe adds (walks /proc/net/tcp{,6} or falls
  back to lsof, refuses to start with EXIT_BACKEND_NOT_LOOPBACK
  if any listener is non-loopback, loopback = full 127.0.0.0/8
  + ::1 + ::ffff:127.0.0.0/8)
- Where the guarantee ends (Docker-Desktop topologies out of
  scope, operator override with audit warning, probe-unavailable
  fail-open path with the systemd loopback override as defense in
  depth, startup-only probe, non-Ollama providers uncovered)
- Where the guarantee is enforced (the test file that pins each
  branch of both classifiers)

Ultra PRA-3 + Regular PRA-6 (proxy.ts monolith growth): keeps
@ts-nocheck at the top of proxy.ts with a code comment
explaining why the removal is out of scope for this PR. tsc
without @ts-nocheck emits ~14 noImplicitAny errors on
pre-existing callback parameters (sleep, model, err, code,
bytes, pct, line, tag, ...) scattered through the 992-line file.
Typing each one is a separate refactor that belongs in its own
PR, not co-mingled with the bind-probe security change. This PR
only touches the status-file IPC seam and the spawn env; the
net +20 lines do NOT extend the untyped surface with new
implicit-any callbacks, so the @ts-nocheck-suppressed area's
per-line risk is unchanged.

Verification:
- 28/30 tests pass (2 platform-gated skips)
- `npm run checks`, `npm run typecheck:cli`, `npm run build:cli`
  clean
- `npx biome check` on all 4 code files + SECURITY.md clean
- `npx markdownlint-cli2 SECURITY.md` clean

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@wscurran wscurran added area: providers Inference provider integrations and provider behavior area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery area: security Security controls, permissions, secrets, or hardening feature PR adds or expands user-visible functionality provider: ollama Ollama local model provider behavior labels Jul 1, 2026
@cv cv added v0.0.80 and removed v0.0.80 labels Jul 9, 2026
@cv cv added the v0.0.81 label Jul 12, 2026
@cv

cv commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

Release sweep: deferring this PR from v0.0.81.

The implementation remains dependent on the daemon-ownership decision in #6014, conflicts with current main, and does not yet satisfy that issue's acceptance criteria. The current review-advisor findings also include required security and test follow-ups, and the PR body lacks the required contributor Signed-off-by: declaration.

Once #6014's design is settled, the safest path is a fresh, narrow, compliant PR against current main.

@cv cv added v0.0.82 and removed v0.0.81 labels Jul 12, 2026
@wscurran wscurran removed the security label Jul 13, 2026
@prekshivyas prekshivyas self-assigned this Jul 25, 2026
cv added a commit that referenced this pull request Jul 26, 2026
<!-- markdownlint-disable MD041 -->
## Summary
Conflict publication now constructs validated GitHub trees from the
recorded `main` tree instead of the stale PR head.
Production requests for #7253 and #6054 shrink from 1,180 and 3,754
entries to 13 and 6 entries.

## Related Issue
Follow-up to #7542.

## Changes

- Build each GitHub tree from the recorded base SHA and the final tree
delta.
- Read deletion entries from the base tree.
- Keep parent blob reuse, final-tree equality, verified commits, and
atomic ref updates unchanged.
- Model 100 `main`-only files and a PR-side deletion in the publisher
regression.

## Type of Change

- [x] 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

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: This changes internal GitHub
publication mechanics and no user-facing contract.
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Maintainer approved
this repair after [production run
30193861556](https://github.com/NVIDIA/NemoClaw/actions/runs/30193861556)
demonstrated the failure. Trust boundaries do not change.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Documentation Writer Review

- [x] Documentation writer subagent reviewed the completed changes
- Result: `no-docs-needed`
- Evidence: The change repairs internal GitHub tree publication. It does
not change commands, configuration, output, or supported behavior.
- Agent: Codex Desktop
<!-- docs-review-head-sha: 424209c -->
<!-- docs-review-agents-blob-sha: be20a09 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit:
- Station profile/scenario:
- Result:
- Supporting evidence:

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: `npx
vitest run --project integration test/pr-merge-conflict-fixer.test.ts`
passed 12/12 after formatting.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: Not applicable to this
focused publisher fix.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

---
Signed-off-by: Carlos Villela <cvillela@nvidia.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved pull request conflict resolution publishing to correctly
reflect files added, modified, or deleted on each branch.
* Ensured resolved updates are built from the correct base revision,
preventing unrelated or outdated files from being included.
* Improved publication accuracy when the target branch has advanced with
additional changes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@copy-pr-bot

copy-pr-bot Bot commented Jul 26, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@prekshivyas prekshivyas removed their assignment Jul 26, 2026

@apurvvkumaria apurvvkumaria left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Request changes — reviewed exact head 22c293f. The refactored scripts/ollama-auth-proxy.mts invokes main only under if (import.meta.main), but NemoClaw supports Node >=22.16.0 and Node added import.meta.main in 22.18.0. On supported Node 22.16 and 22.17 that property is undefined, so executing the script exits successfully without calling main or opening the proxy listener. Reproduction on either supported version: set OLLAMA_PROXY_TOKEN, run node scripts/ollama-auth-proxy.mts, and observe exit 0 with no process listening on OLLAMA_PROXY_PORT; the parent readiness path then fails every proxy-fronted Ollama workflow. Replace the guard with Node-22.16-compatible entrypoint detection using import.meta.url and process.argv[1], and add a minimum-version execution test. Raising the repository minimum plus all documented/runtime constraints would also resolve it, but is substantially broader. This is attributable to the PR and makes a supported workflow unusable.

@apurvvkumaria apurvvkumaria left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-review correction for exact head 22c293f: I independently reproduced that import.meta.main is absent on Node 22.16, but the exact base and head now require and consistently document Node 22.19.0 or newer, where the entry guard works. The earlier compatibility concern therefore is not attributable to supported behavior on this revision and is withdrawn. I found no blocking correctness, security, compatibility, or regression defect. The failing DCO check still needs the PR-body declaration required by repository policy, but that is not a code-review blocker.

@prekshivyas prekshivyas changed the title feat(inference): independent loopback bind probe in Ollama auth proxy (#6014) feat(inference): add Ollama loopback bind probe (step 1 of #6014) Aug 8, 2026
@prekshivyas
prekshivyas merged commit b753c38 into main Aug 8, 2026
44 checks passed
@prekshivyas
prekshivyas deleted the feat/6014-auth-proxy-loopback-probe branch August 8, 2026 04:30
@github-actions github-actions Bot added v0.0.105 v0.0.106 Release target labels Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: providers Inference provider integrations and provider behavior area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery area: security Security controls, permissions, secrets, or hardening feature PR adds or expands user-visible functionality provider: ollama Ollama local model provider behavior refactor PR restructures code without intended behavior change v0.0.106 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants