fix(llama-cpp): accept public /v1/models with protected /props - #8322
Conversation
…tive server (#8302) Real llama.cpp started with --api-key serves /v1/models publicly (HTTP 200) while gating /props, /metrics, and /v1/chat/completions behind authentication. The probe incorrectly required 401/403 from the anonymous catalog request, blocking legitimate server attachment. Accept 200 as a valid anonymous status; native-server fingerprinting via the authenticated /props and /metrics responses still distinguishes llama.cpp from other OpenAI-compatible servers. Return not-llama-cpp instead of authentication-required for unrecognized anonymous status codes. Verified on DGX Spark (aarch64): onboarding step [3/8] now attaches and reports "Attached Local llama.cpp with served model alias" instead of the previous error. Fixes #8302
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe llama.cpp attachment probe now accepts public HTTP 200 Changesllama.cpp detection
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested labels: Sequence Diagram(s)sequenceDiagram
participant probeLlamaCppAttachment
participant v1_models
participant props
probeLlamaCppAttachment->>v1_models: Anonymous GET /v1/models
v1_models-->>probeLlamaCppAttachment: HTTP 200 model catalog
probeLlamaCppAttachment->>props: Anonymous GET /props
props-->>probeLlamaCppAttachment: HTTP 401/403
probeLlamaCppAttachment-->>probeLlamaCppAttachment: Accept native llama.cpp attachment
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage in commit 6321b7f in the TypeScript / code-coverage/cliThe overall coverage in commit 6321b7f in the Show a code coverage summary of the most impacted files.
Updated |
PR Review Advisor — No blocking findings reportedAdvisor assessment: No blocking advisor findings reported Model lanes
3 terminology differences from the second opinionAdvisory only. These are normalized differences from the primary terminology receipt.
1 additional E2E selection from the second opinionAdvisory only. The primary lane did not select these E2E jobs or targets.
Second-opinion terminology and E2E selections are advisory. They do not change the primary assessment or E2E / PR Gate. 2 semantic terminology decisionsTerminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.
E2E guidanceAdvisory only. E2E / PR Gate selects and runs jobs independently. Recommended E2E: 1 warning · 0 suggestionsWarningsWarnings do not block.
|
The createPackageFixture call in openshell-policy-boundary.test.ts only copied ["dist", "schemas"] into the fixture, so dist/lib/policy/merge.js could not resolve its relative require for nemoclaw/dist/shared/openshell-policy-boundary.cjs in the extracted package. Add "nemoclaw/dist" to the entries so the boundary file is available in the fixture and the out-of-tree validator probe succeeds. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…els' into fix/8302-llama-cpp-public-v1-models
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Maintainer security review — PASS\n\nReviewed revision 47bdfc0 with the repository security-review checklist. PRA-1 is addressed: when the model catalog is public, attachment now requires an anonymous /props request to return 401 or 403 before any credential-bearing request is made. A server that leaves /props unprotected is rejected, and focused regression coverage passes 29/29.\n\nNo open security findings remain.\n\n1. Secrets and credentials — PASS: no secrets were added; the credential remains in the protected curl configuration and is not sent during either anonymous probe.\n2. Input validation — PASS: the fixed loopback and port restriction, bounded responses, and safe served-alias validation remain intact.\n3. Authentication and authorization — PASS: the public-catalog path now proves that a protected llama.cpp endpoint enforces the supplied key.\n4. Dependencies — PASS: no dependency changes.\n5. Error handling and logging — PASS: failures are explicit and do not include credential material.\n6. Cryptography and data protection — PASS: no cryptographic behavior changed.\n7. Configuration and security headers — PASS: attachment remains restricted to loopback port 8081.\n8. Security testing — PASS: the new negative test rejects a native-looking server whose protected endpoint is publicly accessible.\n9. Holistic posture — PASS: the supported stock llama.cpp flow is restored without weakening the existing-server authentication guarantee.\n\nFiles reviewed: src/lib/inference/llama-cpp/index.ts and src/lib/inference/llama-cpp/index.test.ts. Commit hooks, pre-push type checking, focused tests, and the documentation build passed. Documentation writer result: no docs needed because no command, setting, credential lifecycle, or user procedure changed. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lib/inference/llama-cpp/index.ts`:
- Around line 252-257: Update the `/props` status handling around the
anonymousProps check to return `not-llama-cpp` for every unrecognized status,
including 404, 405, and 500; only the specific public-success status should
produce `authentication-required`. Add a regression test covering `200
/v1/models` followed by `404 /props` and assert the `not-llama-cpp` result.
- Around line 242-258: Update the authenticated probe flow around
resolveFixedLoopbackBaseUrl and the trusted curl configuration so the bearer
token is never sent over HTTP. Use a protected transport or equivalent local
credential channel for the llama.cpp authentication probe, while preserving the
existing protected-endpoint validation and failure behavior.
🪄 Autofix
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: 24b82f99-31fc-4110-858d-09c6872c9ef9
📒 Files selected for processing (2)
src/lib/inference/llama-cpp/index.test.tssrc/lib/inference/llama-cpp/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/lib/inference/llama-cpp/index.test.ts
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
|
Maintainer follow-up:\n\n- The previous cli-test-shards (4) failure was limited to test/mcp-lifecycle-lock.test.ts: the test expected containment-active but observed a mutation-lock timeout. This branch does not change that subsystem, and the focused integration file passes 38/38 locally. The run was superseded by the current revision, so I did not rerun that old workflow.\n- The actionable CodeRabbit classification finding is fixed in 2506429: a missing or otherwise unsuccessful anonymous /props endpoint now returns not-llama-cpp, while a successful public response still returns authentication-required. The new regression is included and the llama.cpp suite passes 30/30.\n- The loopback-transport finding was reviewed and dispositioned in its thread. This PR preserves the established local port 8081 contract, does not follow redirects, keeps the bearer value in an owner-readable temporary curl configuration, and now proves the protected endpoint rejects anonymous access before sending the credential.\n\nBoth review threads are resolved. The follow-up commit is signed and GitHub-verified, pre-push type checking passed, and the documentation writer revalidated the revision as no-docs-needed. |
|
Advisor classification for the current branch revision: the Terra lane stopped during its terminology-analysis turn because it produced no required analysis result. The Nemotron lane completed successfully, and the publisher completed normally. This failure occurred inside the advisor workflow and is not associated with the llama.cpp code or regression tests. I classified it as a transient advisor-runtime failure and restarted only the failed Terra job once. The remaining CI and protected E2E checks are still running. No merge will occur without all required gates and independent approval. |
|
E2E failure classification: infrastructure, not caused by this PR. Both selected targets stopped before their test bodies while restoring the validated CLI artifact. The restored package is missing This is the shared artifact-boundary defect being repaired by #8333. I am not rerunning the unchanged workflow because it would reproduce the same missing-module failure. Once that repair lands, I will refresh this PR’s protected E2E gate and continue monitoring it. |
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
|
CI classification: the required CLI shard timed out after 15 seconds in test/langchain-deepagents-code-nemotron-profile-plugin.test.ts while building an unrelated plugin wheel. This PR changes only the llama.cpp inference implementation and its focused tests, and the other seven CLI shards passed. The failure is outside the changed code and is consistent with a timing-sensitive test under runner load. I am using the single bounded failed-job rerun for this classification and will continue monitoring. If it repeats, I will stop retrying and document it as a reproducible blocker. |
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
|
The bounded retry passed: the previously timed-out CLI shard is green, the aggregate CLI coverage and required checks are green, and the repository has started a fresh E2E gate evaluation. This confirms the earlier failure was transient and not caused by the llama.cpp change. I am continuing to monitor E2E and review readiness. |
|
Protected E2E failure classification: infrastructure, not caused by this PR. The selected network-policy test reached phase 3, then ClawHub returned HTTP 503 with “Rate limit temporarily unavailable” while installing the pinned OpenClaw plugin. This PR changes only the llama.cpp attachment probe and its unit tests; the selected inference-routing lane passed. I restarted only the failed trusted E2E job once and will not waive the gate or retry again without new evidence. |
|
E2E classification for the current branch: external service failure, not caused by this PR. The selected The protected E2E rollup has not accepted a passing result. I am not manually restarting the controller-owned child run. This revision remains blocked on a fresh repository-authorized E2E result and an independent approval; it will not be merged before both gates pass. |
|
Advisor classification for the current branch: transient advisor-runtime failure, not a code finding. The primary Terra lane completed with no blockers, warnings, or suggestions. The Nemotron lane preserved zero findings but failed its outcome check because the model omitted a required terminology-tool result and emitted text before that tool completed. This occurred inside the advisor protocol after the repository analysis ran; it is unrelated to the llama.cpp implementation or tests. I am using the single bounded failed-job retry for this advisor run. If the failure repeats, I will stop retrying and document it as an external blocker. |
|
The failed-job rerun stopped at the artifact identity check. The provenance record names workflow attempt 1, but the rerun used attempt 2. The check rejected that mismatch before it downloaded or executed PR code. I will not rerun the child workflow or bypass this trust boundary. The repository must dispatch E2E for a new PR commit after the branch is updated from current main. The previously reported application failure remains the external ClawHub HTTP 503. |
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
|
The bounded advisor retry passed. Both advisor lanes and the publisher are green, with no blocking findings reported. No further advisor retry will be used for this revision. The PR remains blocked by the required E2E rollup after the unrelated ClawHub HTTP 503 and by the lack of an independent approval. All other reviewed gates remain green. |
|
Current branch revalidation after the new test-only commit:
The repository merge-gate checker still fails closed on advisor provenance because its validator currently requires a |
|
Priority follow-up: the current branch revision is fully green across required CI, protected E2E, code scanning, both review-advisor lanes, documentation review, DCO, commit verification, and the independent sensitive-path review. Both prior review threads are resolved. No PR-related technical blocker remains. The remaining gates are independent repository approval and the active merge freeze; no merge will be attempted until the freeze is explicitly lifted. |
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
|
Refreshed this branch onto current Validation completed before push:
The PR description now records the current documentation and security review receipts. Fresh CI and automated review checks are running; no check is waived. |
|
Priority revalidation is complete for this branch revision. Ordinary CI and code scanning are green; the protected inference-routing and network-policy E2E checks passed; the bounded advisor retry completed with both model lanes green and zero findings; documentation, sensitive-path review, DCO, and GitHub verification are current. The remaining gates are independent approval, reconciliation after the release cut stabilizes |
|
Release status update: v0.0.103 has been cut and the merge freeze is lifted. The completed technical, documentation, security, and review-thread evidence remains current. The remaining gate is independent approval; once approved, I will reconcile the branch with current main, run the fresh repository-controlled gates, and use the normal protected merge path. |
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
cv
left a comment
There was a problem hiding this comment.
Approved for PR commit 6321b7fbb292986d2bc82772a55260ddcb49a92d against base SHA 422fe9545ed35dbf7d7976bd719239b5430346aa.
- Accepted issue #8161 and RFC #7636 establish the product scope.
- The correctness review and all nine security categories passed.
- The documentation writer review concluded
no-docs-needed. - All 46 current checks, including
E2E / PR Gate, passed without a waiver. - The DCO declaration is present, and all 19 commits appear as
Verified. - Both review threads are resolved.
<!-- markdownlint-disable MD041 --> ## Summary Adds the canonical dated changelog entry required before cutting `v0.0.104`. The entry reconciles user-facing changes merged from `v0.0.103` through `8d2b86aaf44968b4f7bc3b714222a73bd28e0403` while excluding hidden and experimental product surfaces. ## Changes - Added `docs/changelog/2026-08-06.mdx` with the exact `## v0.0.104` heading and release themes for local inference, private endpoints, network policy, state authority, lifecycle recovery, uninstall, Hermes, MCP diagnostics, credential safety, and installation guidance. - Source summary links: - [#8399](#8399) -> `docs/changelog/2026-08-06.mdx`: fixed DGX Spark local serving profiles. - [#8418](#8418) -> `docs/changelog/2026-08-06.mdx`: durable llama.cpp lifecycle management. - [#8422](#8422) -> `docs/changelog/2026-08-06.mdx`: recoverable llama.cpp receipt publication. - [#8402](#8402) -> `docs/changelog/2026-08-06.mdx`: remediable DGX Spark storage admission. - [#8391](#8391) -> `docs/changelog/2026-08-06.mdx`: host-local serving recipe contracts. - [#8401](#8401) -> `docs/changelog/2026-08-06.mdx`: serving profile lifecycle provenance. - [#8322](#8322) -> `docs/changelog/2026-08-06.mdx`: guarded llama.cpp route compatibility. - [#8272](#8272) -> `docs/changelog/2026-08-06.mdx`: explicitly trusted private endpoints with stable policy pins and CA trust. - [#8431](#8431) -> `docs/changelog/2026-08-06.mdx`: Personal onboarding policy tier and its trust boundary. - [#8143](#8143) -> `docs/changelog/2026-08-06.mdx`: manifest-derived state authority. - [#7859](#7859) -> `docs/changelog/2026-08-06.mdx`: side-effect-free lifecycle lock timeouts. - [#8262](#8262) -> `docs/changelog/2026-08-06.mdx`: managed gateway lease waiting. - [#8339](#8339) -> `docs/changelog/2026-08-06.mdx`: continued journaled rebuild recreation. - [#8373](#8373) -> `docs/changelog/2026-08-06.mdx`: restore readiness after compatibility decisions. - [#8443](#8443) -> `docs/changelog/2026-08-06.mdx`: fail-closed malformed registry handling. - [#8419](#8419) -> `docs/changelog/2026-08-06.mdx`: bounded recovery for a gateway that never served. - [#8486](#8486) -> `docs/changelog/2026-08-06.mdx`: target-scoped registry recovery. - [#8259](#8259) -> `docs/changelog/2026-08-06.mdx`: scoped uninstall ordering and retry safety. - [#8457](#8457) -> `docs/changelog/2026-08-06.mdx`: desktop metadata exclusion during uninstall. - [#8026](#8026) -> `docs/changelog/2026-08-06.mdx`: typed Hermes configuration policy. - [#8242](#8242) -> `docs/changelog/2026-08-06.mdx`: Hermes WhatsApp session diagnostics. - [#8344](#8344) -> `docs/changelog/2026-08-06.mdx`: patched Hermes image and dependency checks. - [#8491](#8491) -> `docs/changelog/2026-08-06.mdx`: bounded MCP discovery timeout. - [#8490](#8490) -> `docs/changelog/2026-08-06.mdx`: MCP shadow diagnostics. - [#7619](#7619) -> `docs/changelog/2026-08-06.mdx`: web-search credential isolation. - [#8476](#8476) -> `docs/changelog/2026-08-06.mdx`: stable preflight advisory identifiers. - [#8452](#8452) -> `docs/changelog/2026-08-06.mdx`: user-local CLI resolution. - [#8481](#8481) -> `docs/changelog/2026-08-06.mdx`: remote network-policy terminal guidance. - Product-scope exclusions: [#8429](#8429) remains experimental; [#8261](#8261) remains feature-gated; and portable-profile changes [#8408](#8408), [#8415](#8415), [#8446](#8446), [#8458](#8458), [#8462](#8462), and [#8506](#8506) are not promoted as supported product surfaces. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [ ] Tests added or updated for changed behavior - [x] Existing tests cover changed behavior — justification: `npx vitest run test/changelog-docs.test.ts` passed 6/6 and validates dated changelog structure and published links. - [ ] Tests not applicable — justification: - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [ ] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: - [ ] 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: `docs-updated` - Evidence: `docs/changelog/2026-08-06.mdx`; release-range scope, writing rules, documentation style, skip terms, exact names, threat-boundary wording, and published routes reviewed; changelog tests and docs build passed. - Agent: Codex Desktop <!-- docs-review-head-sha: 02b51ae --> <!-- docs-review-agents-blob-sha: c69aad4 --> ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: Not applicable; no DGX Station host preparation script changed. - Station profile/scenario: Not applicable. - Result: Not applicable. - Supporting evidence: Not applicable. ## 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 validate:pr` passed after refreshing `origin/main` 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 test/changelog-docs.test.ts` passed 6/6. - [ ] 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 a single changelog entry. - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [x] `npm run docs` builds without warnings (doc changes only) - [x] 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) The new dated changelog file includes the required parser-safe SPDX header and intentionally has no frontmatter, matching the changelog contract and existing entries. --- Signed-off-by: Charan Jagwani <cjagwani@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added release notes for v0.0.104. * Documented fixes for local model runtimes, private endpoints, network policies, state recovery, uninstall behavior, safety updates, MCP diagnostics, credential isolation, and installation guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
NemoClaw now accepts a public llama.cpp
/v1/modelscatalog only when anonymous/propsremains protected.This corrects attachment for API-key-protected llama.cpp servers without changing the fixed loopback or native server fingerprint requirements.
Related Issue
Fixes #8302.
The accepted scope comes from #8161 and RFC #7636.
Changes
200from the anonymous/v1/modelsprobe./propsto return HTTP401or403before creating the authenticated request./propsresponse without sending the credential.8081, response bounds, model-alias validation, and authenticated native server fingerprint checks./v1/models.Type of Change
Quality Gates
8081, bounded probes, consistent native server evidence, and generic-endpoint fallback. Commands, settings, credential lifecycle, ownership, and procedures do not change.6321b7fbb292986d2bc82772a55260ddcb49a92dagainst base SHA422fe9545ed35dbf7d7976bd719239b5430346aa.Documentation Writer Review
no-docs-needed6321b7fbb292986d2bc82772a55260ddcb49a92dagainst base SHA422fe9545ed35dbf7d7976bd719239b5430346aa. Existing documentation remains accurate because API-key authentication, loopback port8081, bounded probes, native fingerprint evidence, and generic-endpoint fallback remain required. The change does not alter commands, configuration, credential lifecycle, ownership, or procedures.DGX Station Hardware Evidence
scripts/prepare-dgx-station-host.shdoes not change.Verification
Signed-off-by:line and every commit appears asVerifiedin GitHub — all 19 commits appear asVerified.pre-commit,commit-msg, andpre-pushhooks passed, ornpm run validate:prpassed after refreshingorigin/mainwhen hooks were skipped or unavailable — normal hooks passed for the change set and current merge commits.E2E / PR Gate, passed for the current PR commit.npm run docsbuilds without warnings (doc changes only) — not applicable; no documentation changes.Sensitive-Path Security Review
Independent review found no security finding for PR commit
6321b7fbb292986d2bc82772a55260ddcb49a92dagainst base SHA422fe9545ed35dbf7d7976bd719239b5430346aa.finallycleanup./propsmust show authentication enforcement before credential use./props, timeout, oversized responses, and stopping after anonymous probes.Required checks and maintainer approval remain separate merge requirements.
GitHub Actions
GitHub Actions is authoritative for PR commit
6321b7fbb292986d2bc82772a55260ddcb49a92dagainst base SHA422fe9545ed35dbf7d7976bd719239b5430346aa.All 46 checks in the current GitHub snapshot are successful, skipped as designed, or neutral. The required checks and
E2E / PR Gatepassed.No check waiver is recorded.
Signed-off-by: Yang Liu yanyunl@nvidia.com