fix(rebuild): keep compatible-endpoint reasoning through recovered recreate (#7940) - #7991
Conversation
…create (#7940) A `rebuild` that must recover the recorded provider from the registered gateway credential replaced the sandbox with no reasoning configuration: the replacement recorded a `null` reasoning effort even though the authoritative resume configuration carried `high`. Three NemoClaw-owned gaps combined: - `toSessionUpdates()` never carried `compatibleEndpointReasoningEffort`, so the value its callers supply was dropped before the session, and therefore the registry entry, was written. A fresh compatible-endpoint onboard with `NEMOCLAW_REASONING_EFFORT=high` recorded `null` as well. - The recreate isolates the ambient onboard-selection env (#5735) but re-seeded only the policy tier, so the inner `onboard --resume` and the sandbox image patch that bakes `ARG NEMOCLAW_REASONING_EFFORT` ran with no reasoning inputs. - A recovered selection that reuses the registered gateway credential skips the custom-endpoint validation that configures the reasoning mode and effort, so it reported none and cleared the recorded values. The recreate now re-seeds `NEMOCLAW_REASONING` and `NEMOCLAW_REASONING_EFFORT` from the authoritative resume configuration inside the isolated window, the existing isolation restore returns the caller's ambient values on success and failure, the provider-inference handler replays the recorded configuration when a recovered selection reused the gateway credential, and the session normalizer carries the effort with its nullable contract. Fixes #7940 Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
|
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)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe change preserves compatible-endpoint reasoning effort across session updates, provider recovery, and sandbox recreation. It seeds isolated rebuild environments with recovered reasoning values and adds coverage for normalization, restoration, cleanup, and unsupported providers. ChangesCompatible-endpoint reasoning recovery
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant ProviderInference
participant RebuildPhase
participant SandboxImageBuild
ProviderInference->>RebuildPhase: Restore compatible-endpoint reasoning settings
RebuildPhase->>RebuildPhase: Set reasoning environment variables
RebuildPhase->>SandboxImageBuild: Pass seeded reasoning configuration
RebuildPhase->>RebuildPhase: Restore ambient environment values
Possibly related issues
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 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 ac9fba2 in the TypeScript / code-coverage/cliThe overall coverage in commit ac9fba2 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
Nemotron output stays in workflow artifacts and does not change the assessment above. E2E guidanceAdvisory only. E2E / PR Gate selects and runs jobs independently. Recommended E2E: This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lib/onboard/machine/handlers/provider-inference.ts`:
- Around line 646-665: In the credential-reuse recovery branch of the provider
inference handler, call describeIgnoredReasoningEnv and
describeIgnoredReasoningEffortEnv with the effective recorded reasoning and
effort values before invoking configureCompatibleEndpointReasoning and
configureCompatibleEndpointReasoningEffort. Preserve the existing fallback
selection and configuration behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: a80dc757-4242-4fbf-b266-908900c29cbd
📒 Files selected for processing (7)
src/lib/actions/sandbox/rebuild-recreate-phase.tssrc/lib/actions/sandbox/rebuild-recreate-reasoning.test.tssrc/lib/onboard/machine/handlers/provider-inference-authoritative-recovery.test.tssrc/lib/onboard/machine/handlers/provider-inference.tssrc/lib/onboard/session-updates.test.tssrc/lib/onboard/session-updates.tstest/helpers/rebuild-flow-lifecycle-cases.ts
The recovered compatible-endpoint replay applied the recorded reasoning mode and effort without naming them, so an exported `NEMOCLAW_REASONING` or `NEMOCLAW_REASONING_EFFORT` that disagreed with the recorded value was discarded with no output. That is the silent no-op #7462 removed from the resumed-selection path, which reports the ignored variable, the recorded value, and the recreate command before it configures. The replay now emits the same report through `describeIgnoredReasoningEnv()` and `describeIgnoredReasoningEffortEnv()` before configuring, and the recorded values it applies are read once. A rebuild recreate seeds the environment from the same recorded configuration, so it stays silent. Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/lib/onboard/machine/handlers/provider-inference-authoritative-recovery.test.ts`:
- Around line 196-198: Update the warning assertions in the provider-inference
recovery test to verify that each message includes both the ignored ambient
value and the recorded replacement value: `true` for reasoning mode and `high`
for reasoning effort. Keep the existing checks for the NEMOCLAW_REASONING and
NEMOCLAW_REASONING_EFFORT warnings while asserting their complete recorded-value
behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 88f43e00-6139-476f-9e5e-6b8c6b32b3a9
📒 Files selected for processing (2)
src/lib/onboard/machine/handlers/provider-inference-authoritative-recovery.test.tssrc/lib/onboard/machine/handlers/provider-inference.ts
) The replay-report case proved only that the ambient values were ignored. The point of #7462 is that the report names the recorded value the caller gets instead, so assert the recorded reasoning mode and effort appear in the message. Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
jyaunches
left a comment
There was a problem hiding this comment.
Approved after exact-revision merge gate: current head/base CI and selected E2E evidence pass, the linked supported regression is covered by tests, contributor requirements pass, and no unresolved correctness or security findings remain.
<!-- markdownlint-disable MD041 --> ## Summary Adds the canonical dated changelog entry for `v0.0.100` so the maintainer release plan can verify the pre-tag documentation prerequisite. The entry summarizes the user-facing changes merged since `v0.0.99` and links to the relevant guides. ## Changes - Add `docs/changelog/2026-07-31.mdx` with the exact `## v0.0.100` heading. - Cover restored OpenClaw pairing, transactional replacement, Deep Agents Code, onboarding recovery, lifecycle cleanup, Hermes builds, host provenance, documentation, and trusted E2E evidence. - Distinguish active Docker and Kubernetes runtime-bundle enforcement from the still-inactive managed shared-state transaction foundation. ## Source Coverage The release entry maps the doc-impacting merged PRs in the `v0.0.99..main` release range to `docs/changelog/2026-07-31.mdx`: #8021, #8024, #7973, #8028, #7947, #7788, #7884, #8023, #7969, #8020, #7989, #8000, #7907, #7942, #7567, #8013, #7955, #8017, #8014, #8015, #7629, #7644, #7821, #7971, and #7991. PR #7974 was reviewed after the final rebase and excluded because it changes internal maintainer-skill attribution policy and tests only; it does not change a user-facing product or documentation surface. ## 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: the changelog contract test validates the dated entry, version heading, SPDX form, and route constraints. - [ ] 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-07-31.mdx`; exact-head review passed for `6093f44f`; writing rules and documentation style reviewed; `npx vitest run test/changelog-docs.test.ts` passed 6/6; `npm run docs` passed with zero Fern errors and two generic Fern upgrade notices. - Agent: Codex Desktop <!-- docs-review-head-sha: 6093f44 --> <!-- docs-review-agents-blob-sha: 3dd7c24 --> ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: Not applicable; no DGX Station host 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 at `6093f44f`. - [ ] 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 dated prose-only release entry. - [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) — validation passed with zero errors; Fern emitted two generic upgrade notices. - [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 changelog entry has the required parser-safe MDX SPDX header; dated changelog entries intentionally do not use page frontmatter. --- Signed-off-by: Senthil Ravichandran <senthilr@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added release notes for v0.0.100. * Documented improvements to restore pairing, sandbox replacement, onboarding recovery, lifecycle cleanup, runtime handling, build support, host readiness, and end-to-end validation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Signed-off-by: Senthil Ravichandran <senthilr@nvidia.com>
Summary
A
rebuildthat has to recover the recorded provider from the registered gateway credential replaced the sandbox with no reasoning configuration: the replacement recordedcompatibleEndpointReasoningEffort = nulleven though the authoritative resume configuration carriedhigh, so the effort had to be restored by hand withinference set --reasoning-effort high. Three NemoClaw-owned gaps combined, and all three are fixed here. The documented contract indocs/inference/configure-model-capabilities.mdx— "a resumed onboard andnemoclaw <sandbox-name> rebuildboth replay those recorded values" — now holds on the recovered path too. No new flag, environment variable, or configuration surface: the reporter's command isrebuild --yes, and it works unchanged.Related Issue
Fixes #7940
Changes
src/lib/onboard/session-updates.ts:OnboardSessionUpdateInputandtoSessionUpdates()never carriedcompatibleEndpointReasoningEffort, so the value the callers inmachine/handlers/provider-inference.tssupply was dropped before the session was written — and therefore before the registry entry thatonboard/sandbox-registration.tswrites from that session.SessionUpdatesalready supported the field. The normalizer now maps it, keeping theundefinedleave-unchanged versus explicitnullclear semantics, and normalizing throughnormalizeReasoningEffortso an unrecognized value clears the recorded effort instead of persisting an effort the endpoint never received. This gap alone also made a fresh compatible-endpoint onboard withNEMOCLAW_REASONING_EFFORT=highrecordnull.src/lib/actions/sandbox/rebuild-recreate-phase.ts: the recreate isolates the ambient onboard-selection environment so an unrelated onboard cannot steer it ([Ubuntu][Upgrade] installer auto-rebuild destroys existing sandboxes then fails to recreate when ambient env/session does not match the original config #5735), but it re-seeded onlyNEMOCLAW_POLICY_TIER. Both the recovered provider selection andsrc/lib/onboard/dockerfile-patch.ts— which bakesARG NEMOCLAW_REASONING_EFFORTinto the sandbox image — read the value fromprocess.env, so the inneronboard --resumeran with no reasoning inputs. The recreate now re-seedsNEMOCLAW_REASONINGandNEMOCLAW_REASONING_EFFORTfrom the authoritativeresumeConfiginside the isolated window, only for thecompatible-endpointprovider that can use them. The existing isolation restore returns the caller's ambient values on success and on failure, so the seed stays scoped to the recreate.src/lib/onboard/machine/handlers/provider-inference.ts: the recovered branch reachesresolveRecoveredProviderCredentialReuse()(no host credential copy, validated gateway credential) and setsreuseGatewayCredentialWithoutLocalKey, which short-circuitsvalidateSelectedRemoteModel()— the only caller ofconfigureCompatibleEndpointReasoning[Effort]()for a custom endpoint. The selection therefore reported no reasoning at all and cleared the recorded values. The handler now replays the recorded mode and effort for that same route when the selection reused the gateway credential. This is the boundary that owns the recorded route, so the fix also covers a plain recoveredonboard --resume, not only a rebuild recreate.src/lib/actions/sandbox/rebuild-recreate-reasoning.test.ts(new): the recreate observes the recorded values, ambient values are restored on success and on a failed recreate, a resume configuration that no longer carries an effort clears it for the recreate, and a provider that cannot use reasoning still sees the isolated environment ([Ubuntu][Upgrade] installer auto-rebuild destroys existing sandboxes then fails to recreate when ambient env/session does not match the original config #5735 unchanged).src/lib/onboard/machine/handlers/provider-inference-authoritative-recovery.test.ts,src/lib/onboard/session-updates.test.ts,test/helpers/rebuild-flow-lifecycle-cases.ts: regression coverage for the recovered gateway-credential replay, the normalizer's nullable contract, and the rebuild lifecycle case that now asserts the effort survives.1b1bf3e39(CodeRabbit finding): the replay applied the recorded values without naming them, so an exportedNEMOCLAW_REASONING/NEMOCLAW_REASONING_EFFORTthat disagreed with the recorded value was discarded silently — the exact no-op No supported path to set NEMOCLAW_REASONING on an existing sandbox; local reasoning models stall the agent idle timeout #7462 removed from the sibling resumed-selection path. The replay now emits the samedescribeIgnoredReasoningEnv()/describeIgnoredReasoningEffortEnv()report before configuring, extracted intoreplayRecoveredCompatibleEndpointReasoning()to keephandleProviderInferenceStateunder the Biome cognitive-complexity budget. A rebuild recreate seeds the environment from the same recorded configuration, so it stays silent. Covered by a new case that fails without the source change, strengthened in2b0610047to assert that the report names the recorded values, not only the ignored ambient ones.Each new assertion was confirmed to fail without its corresponding source change.
Type of Change
Quality Gates
docs/inference/configure-model-capabilities.mdxalready documents the behavior this restores ("Onboarding records the reasoning flag and the reasoning effort in the sandbox's session and registry entry. A resumed onboard andnemoclaw <sandbox-name> rebuildboth replay those recorded values"), and theinference set --reasoning-effortcontract, the route rules, and the reasoning-effort inputs are all unchanged.validateSelectedRemoteModel(); this change only replays the already-recorded reasoning mode and effort for that selection, and no credential value is read, written, logged, or moved. The reseeded environment values are the two reasoning variables, taken from the authoritative resume configuration rather than the ambient environment, and they are restored by the existing#5735isolation restore on success and failure — so ambient-environment isolation is preserved, not weakened.codex review --base origin/mainreports no findings at head1b1bf3e39.Documentation Writer Review
docs-accurate-no-changedocs/inference/configure-model-capabilities.mdxalready states that a resumed onboard andnemoclaw <sandbox-name> rebuildreplay the recorded reasoning flag and reasoning effort, and that an exportedNEMOCLAW_REASONING/NEMOCLAW_REASONING_EFFORTdoes not change them; that is exactly the contract this change restores on the recovered path, so the page is accurate before and after.docs/reference/commands.mdxdocumentsinference set --reasoning-effort, which is unchanged. No new flag, environment variable, default, error message, or command output is introduced, so no page needs an edit and no changelog surface changes. Review performed by the primary agent in this session; no separate subagent surface was used. Re-reviewed at head1b1bf3e39after the CodeRabbit follow-up: that commit adds an operator-facing report that reuses the existingIgnoring NEMOCLAW_REASONING...message already documented on the same page, so no page needs an edit. Re-checked at head2b0610047: that commit strengthens a test assertion only, so no documentation change is needed. The governingAGENTS.mdblob remainsc052d60aa.Verification
PR description includes a
Signed-off-by:line and every commit appears asVerifiedin GitHubNormal
pre-commit,commit-msg, andpre-pushhooks passed, ornpm run validate:prpassed after refreshingorigin/mainwhen hooks were skipped or unavailable —npm run validate:praftergit fetch origin mainand a rebase ontoorigin/main387cb0864: all prek pre-commit hooks, commitlint, and pre-push hooks Passed (exit 0). commitlint reports 0 problems and 1footer-leading-blankwarning for theSigned-off-by:trailer that follows theFixesline.Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification:
npx vitest run --project cli src/lib/onboard/session-updates.test.ts src/lib/actions/sandbox/rebuild-recreate-reasoning.test.ts src/lib/onboard/machine/handlers/provider-inference-authoritative-recovery.test.ts src/lib/actions/sandbox/rebuild-env-isolation.test.ts src/lib/actions/sandbox/rebuild-flow.test.ts src/lib/onboard/setup-nim-flow.test.ts→ 6 files / 136 tests passed;npm run typecheck:cliandnpm run checks:repositorycleanApplicable broad gate passed —
npm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — command/result:npm testat head1b1bf3e39→ 23188 passed, 14 failed across 8 files, every one pre-existing or load-induced and unrelated to this change:test/install-station-dgx-os.test.ts(5),test/install-station-host-preparation.test.ts(3),test/install-station-package-transaction.test.ts(1): this host has a pending reboot (/var/run/reboot-required, dated 2026-07-28), sostation-preparerefuses withA reboot is pending on the Station factory image/An unrelated reboot is already pending. All 9 reproduce identically in a cleanorigin/mainworktree.test/issue-5667-hosted-inference-model-namespace.test.ts(1): reproduces identically in a cleanorigin/mainworktree, in isolation.test/package-contract/managed-image-registry-transport.test.ts(1): the packed-CLI--omit=devinstall fails registry resolution withnpm error notarget No matching version found for @aws-sdk/core@^3.977.3, an upstream dependency-resolution failure with no relation to this change.test/gateway-state-reconcile-2276.test.ts,test/rebuild-credential-preflight.test.ts,test/langchain-deepagents-code-image-credentials.test.ts(1 each): 15-60 s timeouts under full-suite parallel load. Re-running exactly those three files on this branch passes 143/143 in 80 s. The first two exercise the rebuild lifecycle this change touches, so they were re-run specifically to confirm the change is not the cause.Quality Gates section completed with required justifications or waivers
No secrets, API keys, or credentials committed
npm run docsbuilds without warnings (doc changes only)Doc pages follow the style guide (doc changes only)
New doc pages include SPDX header and frontmatter (new pages only)
Reporter-workflow E2E (Linux x86_64, real worktree CLI)
Every command below ran the worktree CLI (
./bin/nemoclaw.js), never a globalnemoclaw. Gateway port 8194 with an isolated state root (~/.nemoclaw/gateways/8194), sandboxe2e-7940-effort, a local OpenAI-compatible mock endpoint onhttp://127.0.0.1:8000/v1, a configured Telegram channel, and presetstelegram,local-inference. The reporter's step 3 is reproduced by leavingCOMPATIBLE_API_KEYout of the rebuild environment while the validated gateway credential stays registered, which is what forces the recovered-provider branch.Before the fix (
distbuilt fromorigin/main):The recorded effort survived that run only because the same normalizer defect also dropped the recovered
null; the reasoning mode, which the normalizer did carry, was cleared tonull— the reporter's defect.After the fix (
distbuilt from this branch, same commands):All three recording surfaces the issue names — onboard session, replacement registry row, and generated OpenClaw configuration — keep
highacross the recovered rebuild.Signed-off-by: Yimo Jiang yimoj@nvidia.com
Summary by CodeRabbit
New Features
Bug Fixes
Tests