fix(onboard): reject malformed Ollama model entries - #9518
Conversation
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Documentation Writer Review: PASSNo documentation change is needed. This follow-up tightens validation of malformed No documentation blocker found. |
Security Review: PASSI reviewed the complete two-file change.
No security blocker found. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 12 included reviews per hour; 3 remain after this review. 📝 WalkthroughWalkthroughThe local response parser now uses ChangesOllama validation
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to The change rejects malformed Ollama model entries while preserving valid empty lists, with no actionable merge-blocking risk remaining after normal checks and review. Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
jyaunches
left a comment
There was a problem hiding this comment.
LOC Reduction / Codebase Simplicity Review
Why changes are requested
The validator change belongs in the existing Ollama response boundary, but the commit under review adds avoidable duplicate code in both changed files.
src/lib/onboard/provider-host-state.test.tsadds a 21-line table test that repeats the complete fixture and the same three assertions from the immediately preceding non-Ollama-body test. Only the captured response body differs.src/lib/inference/local.tsspells out the same non-null object and non-array check for the response and each model entry.src/lib/core/json-types.tsalready providesisObjectRecordfor this boundary check.
Refactor direction
- Convert the existing non-Ollama-body test into one
it.eachtable. Include the HTML body,nullentry, primitive entry, and nested-array entry. Keep onebuildDepsblock and one assertion block. - Import
isObjectRecordand use it for the parsed response and eachmodelsentry. Use the same helper for the adjacentmodelInventoryentry guard if that guard changes. - Keep
isValidOllamaTagsResponseBodyas the shared Ollama health-shape owner. PR #9483 already has a separate request to reuse this validator with the existing inventory and matcher path, so this PR does not need a second inventory abstraction.
Expected result
The same malformed responses fail closed, valid empty model lists remain accepted, and the test adds roughly six lines instead of 21. The production change can be neutral or negative instead of adding two lines.
PR Review Advisor — No blocking findings reportedAdvisor assessment: No blocking advisor findings reported Model lanes
3 additional E2E selections from the second opinionAdvisory only. The primary lane did not select these E2E jobs or targets.
Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests. 2 semantic terminology decisionsTerminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.
E2E guidanceAdvisory only. A maintainer can dispatch the default E2E suite for the commit under review. Recommended E2E: Manual-only E2E: This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge. |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage in commit 338ffb0 in the TypeScript / code-coverage/cliThe overall coverage in commit 338ffb0 in the Show a code coverage summary of the most impacted files.
Updated |
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
|
Addressed the test-duplication portion of the change request in the current branch revision. One table now owns the HTML, null-entry, primitive-entry, and nested-array cases with one fixture and one assertion block. The requested direct Validation:
Maintainer decision needed for the remaining request: accept the existing local boundary check in this PR, or approve a separately scoped dependency refactor that provides a sanctioned shared path. |
Partially addressed by 1958ade: the duplicate malformed-body test setup was consolidated, but the canonical production record predicate remains unresolved. Superseded by the refreshed review at the current head.
jyaunches
left a comment
There was a problem hiding this comment.
LOC Reduction / Codebase Simplicity Review
What this update resolved
The duplicate test setup is resolved at 1958adea0cf36174a13f111d3d247d7f27a603ed. The HTML response and the three malformed model-entry bodies now share one it.each table, one dependency fixture, and one assertion block. The exact response removes 18 net test lines.
Why changes are still requested
The production half of the prior finding is unchanged. src/lib/inference/local.ts:365-372 still implements the same object-record predicate twice: once for the parsed response and once for each models entry. The repository already owns that boundary rule as isObjectRecord in src/lib/core/json-types.ts.
This leaves the production diff at +10/-8 even though the validation can reuse the canonical predicate directly. Keeping a second spelling makes null/array handling easier to drift from the adjacent JSON boundaries and adds lines without a new contract.
Refactor direction
Import isObjectRecord from ../core/json-types and express the validator with the existing owner:
return (
isObjectRecord(parsed) &&
Array.isArray(parsed.models) &&
parsed.models.every(isObjectRecord)
);Keep isValidOllamaTagsResponseBody as the shared Ollama health-shape boundary. No new inventory helper or abstraction is needed.
Expected result
The same malformed entries fail closed and valid empty model lists remain accepted, while the production response becomes neutral or negative and the repository has one definition of an object record.
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
|
Addressed the remaining requested change and the current CI failure through Requested canonical boundary (
CI repair (
Validation on the exact pushed head:
Fresh exact-head checks are starting. The changes-requested review remains intact for reviewer re-evaluation. |
Resolved at f0967c6. The validator now imports and reuses the canonical isObjectRecord predicate. The consolidated malformed-response table remains in place.
jyaunches
left a comment
There was a problem hiding this comment.
LOC Reduction / Codebase Simplicity Review
What this update resolved
Commit f0967c694792f9de0a8b865949df6416ef12aa9e resolves the remaining simplicity request.
src/lib/inference/local.ts now imports isObjectRecord from core/json-types. The Ollama validator uses it for the parsed response and every models entry. The adjacent modelInventory path also reuses the same predicate.
The consolidated it.each test remains unchanged. One fixture and one assertion block cover the HTML response and all malformed model-entry cases.
The production file is now net negative relative to the PR base. The architecture-budget changes record the direct dependency without adding a wrapper or hidden re-export.
Scope of this resolution
This comment resolves only the LOC-reduction and codebase-simplicity blocker. It is not an approval and does not assess other review requirements.
Documentation Writer Review: PASSNo documentation change is required. The PR tightens validation of malformed Ollama responses and reuses an existing internal JSON boundary. It adds no user command, configuration, supported integration, or operator action. Security Review: PASSNo findings. The parser now requires the response and each model entry to be plain object records, rejects malformed JSON and invalid entries, and keeps the existing empty-array behavior. It adds no credential handling, authorization path, dependency, remote execution, cryptography, security-header change, or new system privilege. Error handling remains fail closed. The changed 19-test suite, the full 79-test installer file that failed in CI, and the source architecture check pass on the current branch revision. |
|
Outside contributor here, not a maintainer — offering evidence rather than a decision. I read this diff against What holds upI executed the pre-change and post-change versions of
Three of the four table rows genuinely flip, so the added cases cannot pass without the production change, and the empty-model-list case stays valid. The HTML row was already rejected before — that is the case the table grew out of, so no surprise there. I also re-derived the import graph that To be clear about the limits: I did not run the repository test suite, type-check, or build. The table above is a hand-executed comparison of the two versions of the predicate only. One thing worth catching: this overlaps #9483#9483 rewrites the same block of The two also draw the boundary in different places. Executed against both heads: That is a real judgement call about how much of an
The summary describes the Windows-host probe, which is the case the new tests cover; the other two consumers are easy to miss when reading the change. Smaller noteAfter this change the file carries two different answers for a partly-malformed list. Thanks for the change either way — the tightening itself reads correctly to me, and the consolidated table is easy to follow. |
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
|
Addressed the remaining advisor coverage warning in signed, GitHub-Verified commit
Validation on the pushed commit:
Fresh exact-head CI is now running. |
prekshivyas
left a comment
There was a problem hiding this comment.
Approved exact head 338ffb0. The shared Ollama tags boundary rejects null, primitive, array, and malformed object entries while preserving valid empty inventories; the direct backend and auth-proxy probes now cover the same malformed shapes. All six commits are verified, review threads are resolved, local focused/repository/type/full validation passed, and all current CI, advisory, CodeRabbit, security, and managed-runtime checks are green.
<!-- markdownlint-disable MD041 --> ## Summary The exact candidate documentation review rejected the v0.0.111 release entry because it omitted three merged product fixes. This PR records the missing Ollama validation, Deep Agents Code OpenRouter identity validation, and dashboard port reservation behavior. ## Changes - Record that Windows-host Ollama discovery rejects non-object model entries from PR #9518. - Record that Deep Agents Code onboarding accepts OpenRouter's native provider and model identity from PR #9561. - Record that onboarding releases its temporary dashboard port reservation before the host forward starts from PR #9569. ## 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 - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: The change updates changelog prose only and does not change product behavior. - [ ] 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: ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: Not applicable. `scripts/prepare-dgx-station-host.sh` is unchanged. - 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 — tests are not applicable to changelog prose. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: - [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) — 0 errors and 2 unrelated warnings: unauthenticated redirect checking and existing light-mode accent contrast. - [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) --- Signed-off-by: San Dang <sdang@nvidia.com> Signed-off-by: San Dang <sdang@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary This pull request (PR) fixes portable rootless onboarding after the host gateway address blocked Podman network creation. Portable host preparation now creates or validates the network before it adds the overlapping loopback address. ## Related Issue Fixes #9577. ## E2E Root Cause - E2E root cause: `portable host preparation / rootless Podman network creation / host loopback address reserves the portable network subnet` - Source run: [automatic run 32220977895](https://github.com/NVIDIA/NemoClaw/actions/runs/32220977895) (run 32220977895, attempt 1) - Failed jobs: [rootless-linux 95971243086](https://github.com/NVIDIA/NemoClaw/actions/runs/32220977895/job/95971243086) and [portable-launch 95971243205](https://github.com/NVIDIA/NemoClaw/actions/runs/32220977895/job/95971243205) - Signature: `Creating the portable sandbox network failed: subnet 169.254.1.0/24 is already used on the host` - Scope: one root cause ## Base SHA Reconciliation Latest PR commit `c85831dce4cd5b1e1d5c218aa1d90c6f6309dab3` is an ordinary signed merge with ordered parents [`c9499420d566ef4ff0c1fcc4654d1cd3f5456b0a`, `0ac5a7cd0565ca8aac32fab1a22603da459a4158`]. PR base SHA `0ac5a7cd0565ca8aac32fab1a22603da459a4158` adds #9493 after previous base SHA `2c74cbb87c35d1ec8700c0c4264a0fcc03c715c2`. #9493 changes only the live registry-target test and its E2E-support registry-discovery test. It does not change the two files in this PR or the portable-host preparation boundary. The net PR diff remains the production portable-host preparation file and its focused test. Automatic exact-base [E2E run 32262846265](https://github.com/NVIDIA/NemoClaw/actions/runs/32262846265) completed with 11 passed and 27 expected skipped jobs. Its substantive failure is the separate, already owned and decision-blocked #9280 launch-readiness publication contract; the Relevant E2E job failed downstream. ## Changes - Add a stateful host-command regression test that models the rootless Podman subnet conflict. - Separate portable network preparation from registry-container preparation. - Order portable host effects as network preparation, host gateway configuration, then registry-container preparation. ## 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: - [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: independent exact-`c85831dce4cd5b1e1d5c218aa1d90c6f6309dab3` correctness, nine-category security, and documentation reviews passed; automated and maintainer review remain pending - [x] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: automatic exact-base [E2E run 32262846265](https://github.com/NVIDIA/NemoClaw/actions/runs/32262846265) failed the separate #9280 launch-readiness publication contract; this reconciliation authorization accepts that owned failure as unrelated to #9578 ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: - Station profile/scenario: - Result: - Supporting evidence: ## Security and Documentation Review - The network name, subnet, registry address, Podman socket authority, privileged command, and fail-closed error paths are unchanged. - A network-creation failure stops before the host address or registry container changes. A host-address failure stops before registry-container mutation. - No credential, workflow, dependency, cryptography, redaction, cleanup, or authorization path changes. - No documentation change is required. Existing documentation already describes the final portable gateway and registry topology; this PR changes only the internal order that reaches it. ## Additional Local Evidence - Before the production fix, the new regression test failed 1/1 with `Creating the portable sandbox network failed: subnet 169.254.1.0/24 is already used on the host`. - A four-file topology command also ran `src/lib/onboard/docker-driver-gateway-env.test.ts`. Two unrelated tests encountered durable `/tmp/nemoclaw-gateway` state from another process and stopped at the existing generated-gateway identity gate. The shared network-authority test passed separately, and this PR does not change that gateway state or identity path. ## Credential-Free Live Evidence - Latest PR commit c85831d preserves the portable-host blobs from credential-free live commit 7d94953, which created the openshell-docker network with subnet 169.254.1.0/24 before it added host loopback address 169.254.1.2/32. - The live run did not reproduce the #9577 subnet collision. Rootless Podman remained the lifecycle authority, and Docker state did not change. - A later Hermes probe exposed a separate address-authority defect tracked by #9587. This PR does not include that defect or its remediation. ## 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: `npm exec -- vitest run --project cli src/lib/onboard/experimental/portable-host-preparation.test.ts src/lib/onboard/gateway-sandbox-reachability.test.ts src/lib/onboard/host-service-reachability.test.ts` passed 106/106 on latest PR commit `c85831dce4cd5b1e1d5c218aa1d90c6f6309dab3`; the isolated network-order regression passed 1/1; the #9579 installer fixture passed 3/3; the #9518 provider/local-inference and #9507 Dockerfile-patch compatibility suite passed 153/153; the #9493 E2E-support registry-discovery suite passed 11/11; the #9561 DCode compatibility suites passed 53/53 and 139/139; the #9512 shared-state compatibility suite passed 74/74 - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: `npm run test:changed` passed growth guardrails 32/32 and found no additional changed-project test files beyond the explicit focused suites; `npm run typecheck:cli`, `git diff --check`, and `npm run validate:pr` passed; the net change remains one onboarding order and its regression test, so `npm test` was not run locally - [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: Julie Yaunches <jyaunches@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved portable host preparation by creating and validating the sandbox network before configuring the host gateway. * Ensured registry setup occurs only after network and gateway preparation is complete. * **Tests** * Added regression coverage verifying the correct order of network creation, gateway configuration, and registry operations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Julie Yaunches <jyaunches@nvidia.com> Signed-off-by: Senthil Ravichandran <senthilr@nvidia.com> Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Summary
The Windows-host Ollama probe introduced in #9482 accepted a
modelsarray even when its entries werenull, primitive values, or nested arrays. The shared response validator now requires every model entry to be a non-null, non-array object while preserving valid empty model lists.Related Issue
Refs #9348. Follow-up to #9482.
Changes
isValidOllamaTagsResponseBodyso malformed model entries fail closed.null, primitive, and array entries.This change adds no abstraction, configuration, fallback, migration, or compatibility path. It tightens the response contract already used by the Windows-host reachability probe.
Type of Change
Quality Gates
DGX Station Hardware Evidence
Not applicable.
scripts/prepare-dgx-station-host.shis unchanged.Verification
Signed-off-by:line and every commit appears asVerifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run validate:prpassed after refreshingorigin/mainwhen hooks were skipped or unavailablenpx vitest run --project cli src/lib/onboard/provider-host-state.test.ts src/lib/inference/local.test.ts: 110 passed;npx vitest run --project integration test/growth-guardrails.test.ts: 32 passed;npm run typecheck:cli: passed.npm run docsbuilds without warnings (doc changes only)Signed-off-by: Apurv Kumaria akumaria@nvidia.com
Summary by CodeRabbit
Bug Fixes
Tests