refactor(onboard): make FSM resume recovery a single explicit path (#6227) - #6253
Conversation
…VIDIA#6227) Replace the three implicit onboarding recovery mechanisms with explicit, deterministic FSM semantics, the foundational slice of NVIDIA#6227. - Consolidate resume repair into one validated, side-effect-free recovery pass (planSessionRecovery/applySessionRecovery in session-recovery.ts). It classifies the durable snapshot, computes and validates a single legal non-terminal entry, re-seats the snapshot, and surfaces the decision so the caller emits exactly one explicit state.repair.completed event. Replaces the implicit repairResumeMachineSnapshot rewrite. - Introduce a single synchronous terminal-failure owner (finalizeIncompleteOnboardStep) for exception/signal/nonzero-exit paths. It validates the failed transition and is idempotent against an already-terminal machine, so exactly one failed transition and one terminal event are recorded. Removes the last production use of LEGACY_MACHINE_STEP_MUTATION_OPTIONS. - Document the legal transition graph and terminality invariant, and assert that a terminal failed state can never re-enter an agent/flow state (NVIDIA#6179). No persisted SandboxCreateIntent or schema change is introduced. Signed-off-by: Atulya Singh <atulyarajsingh@gmail.com>
📝 WalkthroughWalkthroughThis PR replaces ChangesSession recovery and terminal failure finalization
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant OnboardTs as onboard.ts
participant Bootstrap as session-bootstrap.ts
participant Recovery as session-recovery.ts
participant Session
OnboardTs->>Bootstrap: prepareOnboardSession(deps with applySessionRecovery)
Bootstrap->>Recovery: applySessionRecovery(currentSession)
Recovery->>Recovery: planSessionRecovery (classify + validate entry)
alt recover
Recovery->>Session: set machine state/stateEnteredAt/revision
end
Recovery-->>Bootstrap: recovery plan
Bootstrap-->>OnboardTs: {session, fromDockerfile, recovery}
alt recovery.action == recover
OnboardTs->>OnboardTs: record state.repair.completed event
end
sequenceDiagram
participant ExitStepFailure as exit-step-failure.ts
participant OnboardSession as onboard-session.ts
participant Session
ExitStepFailure->>OnboardSession: finalizeIncompleteOnboardStep(stepName, message)
OnboardSession->>Session: loadSession()
alt machine already terminal
OnboardSession-->>ExitStepFailure: unchanged session
else
OnboardSession->>OnboardSession: assertValidOnboardMachineTransition(-> failed)
OnboardSession->>Session: mark step failed, set machine.state=failed
OnboardSession->>OnboardSession: emit state.failed, onboard.failed
OnboardSession-->>ExitStepFailure: updated session
end
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
src/lib/actions/sandbox/rebuild-flow.test.ts (1)
141-166: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMock diverges from the real terminal owner on the missing-step branch.
installTerminalStepFailureMockreimplementsfinalizeIncompleteOnboardStep, but where the real function returns early without transitioning whensession.steps[stepName]is absent (if (!step) return session;), this mock instead synthesizes acreateStep("pending")and drives the machine tofailed. If a rebuild-flow test ever exercises a not-yet-recorded step, the harness will record a terminal failure the production code would not, masking a real gap. Consider aligning the mock's missing-step branch with production (early return, no transition).As per path instructions: "Flag copied production algorithms, broad mocks that bypass the behavior under test."
♻️ Align missing-step handling
const stepKey = String(stepName); - const step = session.steps[stepKey] ?? createStep("pending"); - session.steps[stepKey] = step; + const step = session.steps[stepKey]; + if (!step) return session; step.status = "failed";🤖 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/actions/sandbox/rebuild-flow.test.ts` around lines 141 - 166, The `installTerminalStepFailureMock` helper is diverging from `finalizeIncompleteOnboardStep` in the missing-step path by creating a synthetic pending step and forcing the session to `failed`. Update the mock to match production behavior in that branch: if `session.steps[stepName]` is absent, return the session immediately without changing `session.status`, `session.failure`, or `session.machine.state`. Keep the rest of the failure-transition logic unchanged so the test harness mirrors `finalizeIncompleteOnboardStep` accurately.src/lib/onboard/resume-machine-repair.ts (1)
33-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winLink the tracked follow-up for removing the
resumeMachineStatebridge.The comment documents
resumeMachineStateas a transitional bridge to be removed once step fields stop being used, but doesn't reference a tracking issue/PR — unliketransitions.ts, which links#6179for its own invariant. As per path instructions, "If a PR intentionally migrates only a slice, it must say so and link the remaining work in GitHub."🤖 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/onboard/resume-machine-repair.ts` around lines 33 - 38, The doc comment for the `resumeMachineState` bridge should explicitly link the tracked follow-up work for removing it, since it’s a temporary transition and currently lacks a GitHub reference. Update the comment in `resume-machine-repair.ts` near `resumeMachineState` to say this slice is intentional and add the remaining-work issue/PR link, matching the style used in `transitions.ts` for its invariant reference.Source: Path instructions
src/lib/onboard/session-bootstrap.test.ts (1)
122-123: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winConsider adding coverage for the
action: "recover"branch.Only the
keeprecovery outcome is exercised here. Sincerecovery.action === "recover"is what triggers the newstate.repair.completedevent inonboard.ts, a test assertingresult.recoveryfor the recover case (withentry/reason) would meaningfully guard this critical path.🤖 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/onboard/session-bootstrap.test.ts` around lines 122 - 123, Add test coverage in session-bootstrap.test.ts for the recovery branch where applySessionRecovery leads to action: "recover", not just the current keep case. Update or add a test around applySessionRecovery and result.recovery to assert the recover outcome includes the expected entry and reason, so the onboard.ts path that emits state.repair.completed is covered.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lib/onboard.ts`:
- Around line 4796-4804: Move the `state.repair.completed` emission into the
recovery helper path so the repair write and audit record are applied together.
Update the `applySessionRecovery` flow and its caller in
`onboardRuntimeBoundary.recordOnboardStarted` handling so the helper persists
the repaired snapshot and immediately records the
`recordRepairEvent("state.repair.completed", ...)` when `recovery.action ===
"recover"`, preserving the existing state and metadata payload.
In `@src/lib/onboard/session-recovery.test.ts`:
- Around line 29-75: Add a dedicated test in planSessionRecovery to cover the
reopened_complete_snapshot path, since the current cases only exercise
failed_terminal_snapshot and nonterminal_snapshot. Create a session fixture with
a complete machine snapshot that is reopened (status not complete or resumable
not false), then assert planSessionRecovery returns action keep with reason
reopened_complete_snapshot and that applySessionRecovery preserves the expected
entry. Use the existing planSessionRecovery, applySessionRecovery, and
createSession helpers so the new test directly protects the
assertRecoverableEntry behavior from regressions.
---
Nitpick comments:
In `@src/lib/actions/sandbox/rebuild-flow.test.ts`:
- Around line 141-166: The `installTerminalStepFailureMock` helper is diverging
from `finalizeIncompleteOnboardStep` in the missing-step path by creating a
synthetic pending step and forcing the session to `failed`. Update the mock to
match production behavior in that branch: if `session.steps[stepName]` is
absent, return the session immediately without changing `session.status`,
`session.failure`, or `session.machine.state`. Keep the rest of the
failure-transition logic unchanged so the test harness mirrors
`finalizeIncompleteOnboardStep` accurately.
In `@src/lib/onboard/resume-machine-repair.ts`:
- Around line 33-38: The doc comment for the `resumeMachineState` bridge should
explicitly link the tracked follow-up work for removing it, since it’s a
temporary transition and currently lacks a GitHub reference. Update the comment
in `resume-machine-repair.ts` near `resumeMachineState` to say this slice is
intentional and add the remaining-work issue/PR link, matching the style used in
`transitions.ts` for its invariant reference.
In `@src/lib/onboard/session-bootstrap.test.ts`:
- Around line 122-123: Add test coverage in session-bootstrap.test.ts for the
recovery branch where applySessionRecovery leads to action: "recover", not just
the current keep case. Update or add a test around applySessionRecovery and
result.recovery to assert the recover outcome includes the expected entry and
reason, so the onboard.ts path that emits state.repair.completed is covered.
🪄 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: 532d200a-6719-474c-8034-225f4bb459fe
📒 Files selected for processing (14)
src/lib/actions/sandbox/rebuild-flow.test.tssrc/lib/actions/sandbox/rebuild-resume-snapshot.test.tssrc/lib/onboard.tssrc/lib/onboard/exit-step-failure.test.tssrc/lib/onboard/exit-step-failure.tssrc/lib/onboard/machine/transitions.test.tssrc/lib/onboard/machine/transitions.tssrc/lib/onboard/resume-machine-repair.test.tssrc/lib/onboard/resume-machine-repair.tssrc/lib/onboard/session-bootstrap.test.tssrc/lib/onboard/session-bootstrap.tssrc/lib/onboard/session-recovery.test.tssrc/lib/onboard/session-recovery.tssrc/lib/state/onboard-session.ts
…cts (NVIDIA#6225) Add the onboarding lifecycle contract map (src/lib/onboard/AGENTS.md): epic NVIDIA#6224 vocabulary, per-journey contract tables for create, rebuild, re-onboard, and runtime mutation, seven cross-journey divergences with code anchors, and a bug-to-contract-gap table for the epic's evidence issues, with pointers from machine/README.md and the root AGENTS.md. Pin current behavior as an executable characterization baseline before the NVIDIA#6226/NVIDIA#6227 refactors move it: - machine/transition-traces.test.ts: legal-transition surface and full event traces for fresh-run, resume, recreate, and mid-flow failure. Failed-state exit legality and the legacy step-mutation bridge are deliberately not pinned; PR NVIDIA#6253 owns those semantics. - test/onboard-lifecycle-invariants.test.ts: create-path ordering invariants (conflict guard before sandbox delete, deterministic validation before the destructive boundary, cleanup-before-upsert, resume identity per NVIDIA#2753). - test/onboard-session-secret-invariants.test.ts: session persistence secret boundary (credentialEnv name-only, endpointUrl redaction, sha256-only legacy hashes, unset/declined ambiguity pinned as a known NVIDIA#6224 contract gap). Zero production-code changes. Signed-off-by: Abhimanyu Kumar <abhimanyukumar7290@gmail.com>
|
✨ Thanks for the refactor. This foundational slice for #6227 replaces three implicit recovery mechanisms with a single explicit FSM path — maintainers can review the new session-recovery module and transition enforcement. Related open issues: |
Sync current main while preserving the contributor's explicit FSM recovery design. Close durable recovery receipt, event ordering, and review gaps. Co-authored-by: Atulya Singh <atulyarajsingh@gmail.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Bring the validated NVIDIA#6253 salvage onto origin/main at 3f5133e before publishing. Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
|
Maintainer salvage update:
CI and the refreshed automated review are still running; this is not being marked ready until they settle. |
…recovery-6227-explicit
|
Exact head The prior maintainer update’s recovery receipt, This PR is ready for independent human review. No approval or merge action was taken. |
<!-- markdownlint-disable MD041 --> ## Summary Adds the pre-tag v0.0.79 release notes entry to `docs/about/release-notes.mdx` so the release plan can be generated after docs merge. The entry summarizes the merged v0.0.79 release train across inference, diagnostics, runtime hardening, policies, onboarding recovery, and release validation. ## Changes - Added the v0.0.79 release notes section with linked follow-up documentation for OpenRouter onboarding, managed vLLM changes, completion and logging, Deep Agents runtime limits, policy updates, onboarding recovery, and release validation. - Source summary: - #6461 -> `docs/about/release-notes.mdx`: Documents OpenRouter onboarding support and links to inference/provider references. - #6271 and #6272 -> `docs/about/release-notes.mdx`: Documents shell completion and structured logging highlights. - #6465, #6539, #6570, and #6528 -> `docs/about/release-notes.mdx`: Documents status route-drift, orphaned sandbox, gateway cleanup, and DGX Spark express-install diagnostics. - #6523, #6551, #6484, #6488, #6324, and #6542 -> `docs/about/release-notes.mdx`: Documents managed vLLM, Qwen3.6 tool parser, compaction, and timeout/readiness improvements. - #6559, #6538, #6560, #6568, #6552, #6567, and #6587 -> `docs/about/release-notes.mdx`: Documents runtime, credential, proxy, PID namespace, TOML, and provider-state hardening. - #6541, #5415, #6246, #6496, and #6573 -> `docs/about/release-notes.mdx`: Documents GitHub policy, Gmail policy, MCP allowlist, WhatsApp, and messaging-variant updates. - #6253, #6572, #6444, #6536, and #5860 -> `docs/about/release-notes.mdx`: Documents onboarding resume and create-step recovery improvements. - #6508, #6527, #5506, #6588, #6446, #6447, #6582, #6296, #6367, #6397, and #6505 -> `docs/about/release-notes.mdx`: Documents docs, release-risk, and E2E validation updates. ## 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 <!-- Check exactly one tests line and one docs line. Check other lines when applicable. Add every requested justification or approval reference. --> - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: Release-note prose only. - [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: ## Verification <!-- Check each applicable item only when supported by the requested evidence. Run targeted tests once per relevant change set and rerun after later edits or hook autofixes that can affect the tested behavior. Do not rerun hook-covered checks. --> - [x] PR description includes the DCO sign-off declaration 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: Tests not applicable, release-note prose only. - [ ] 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) - [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) Docs validation note: `npm run docs:check-agent-variants && npm run docs:check-routes && git diff --check` passed. Full `npm run docs` is currently blocked before Fern validation because the pinned `fern-api@5.65.2` package is unavailable from npm (`ETARGET No matching version found`). --- <!-- DCO sign-off is required in this PR description, and every commit must appear as Verified in GitHub. Run: git config user.name && git config user.email --> Signed-off-by: Julie Yaunches <jyaunches@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added release notes for v0.0.79 with a new summary of recent improvements, including onboarding and inference options, operator/CLI diagnostics, sandbox recovery hardening, runtime limits, network policy behavior, and release validation updates. * Added updated references and links for the latest release. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
#6598) ## Summary Addresses the **stale-result invalidation subset** of #6227 (does not close it). Builds on the #6253 FSM recovery foundation by removing the repaired-resume use of `recordCompatibleStateResult` and making stale replay outcomes explicit. - add `state.result.invalidated` diagnostics for recomputed onboarding phase results that are already behind the durable machine state - make live flow slices decide per result whether to apply or invalidate based on source/current/target state - keep the legacy `state.result.skipped` path only for explicit legacy `updateMachine` step mutation compatibility - wire initial, core, final, and the initial `init -> preflight` resume transition through explicit invalidation ### Scope of #6227 delivered here vs. deferred This PR intentionally narrows scope to the stale-replay-invalidation acceptance clauses of #6227. Deferred to follow-up work (tracked against #6227): - full abort / interruption / recovery graph and terminal-state vocabulary - distinct user-cancellation / recoverable-failure / unrecoverable-corruption result-envelope semantics - interruption/resume tests at initial, core, final, and terminal boundaries per #6040 platform outcomes `#6227` should remain **open** after this PR merges; only the stale-result invalidation subset is complete. ## Refutation: PRA-2 (GPT-5.5) / PRA-3 (Nemotron) — context propagation after invalidation Both advisors flagged that `runLiveOnboardFlowSlice` propagates `phaseResult.context` unconditionally after invalidating a stale transition, and asked to gate context propagation on `applied` status. Refuted with evidence: 1. **Durable machine mutations are already blocked.** `OnboardRuntimeBoundary.recordInvalidatedStateResult` and `recordStateResultWithStepCompatibility` both call `assertResultHasNoContextUpdates(result, ...)` before emitting, rejecting any `OnboardStateResult` that carries `updates`. Invalidated transitions cannot advance state or write context to the durable session. 2. **`phaseResult.context` is intentionally the recomputed source of truth for cross-phase local data in compatibility mode.** Compatibility recompute (`compatibilityWhenState`) exists precisely so that phases like preflight and gateway probe re-produce fresh `sandboxGpuConfig`, `gpu`, `gpuPassthrough`, `selectedMessagingChannels`, and similar cross-phase context in resume/ahead-state flows. Runtime consumers rely on this — for example `src/lib/onboard.ts:4397` asserts `initialContext.sandboxGpuConfig` immediately after the initial slice returns. 3. **Gating propagation on `applied` breaks the intended design.** Prototyped gating (commit `44d542522`, reverted) failed the `authoritative-core-gateway-core` slice probe with `Preflight did not produce a sandbox GPU configuration.`, because the preflight transition invalidates as `already_at_target` while the phase's recomputed `sandboxGpuConfig` legitimately must flow forward. 4. **Defense in depth on the transition side is already in place.** `assertValidOnboardMachineTransition` on the boundary apply path rejects graph-invalid transitions; `assertResultHasNoContextUpdates` rejects invalidated results carrying updates. `phaseResult.context` is a purely in-memory cross-phase carrier that reflects the just-executed compat phase's fresh work, not stale saved state. **Disposition:** the two advisor findings describe a leak that does not exist under the current boundary contract; gating propagation regresses `test/onboard-fsm-live-slices.test.ts` and does not add safety. No code change required for this finding. ## Advisor override: phantom test-file size budgets Subsequent advisor re-scans (GPT-5.5 PRA-1 on head `3a8a01243`, Nemotron PRA-1/PRA-2 across multiple heads) demand offsetting `runtime-boundary.test.ts` / `initial-flow-phases.test.ts` growth against a 550-line "monolith" threshold. Refuted: - The repository's actual test-file size budget lives in `ci/test-file-size-budget.json` with `defaultMaxLines: 1500` and per-file legacy overrides. `runtime-boundary.test.ts` sits at ~610 lines, well under the 1500-line default. - The `Test file size budget` guardrail step in `.github/workflows/codebase-growth-guardrails.yaml` is green on every recent CI run for this PR. - The 550-line threshold cited by the advisors is not a project rule; it appears to be an advisor-side heuristic. Overriding this finding for this PR. Only the actual configured budget in `ci/test-file-size-budget.json` is treated as authoritative. ## Refutation: Nemotron PRA-4 / PRA-5 — `phase_superseded` invalidation reason Nemotron 3 Ultra advisor requires introducing a new `phase_superseded` variant on `ResultInvalidationReason` and adding a corresponding invalidation check in `recordRecomputedResult`. Refuted with evidence: 1. **The scenario is already covered by `source_state_mismatch`.** `recordRecomputedResult` computes `sourceState = resultSourceState(result) ?? phaseState`. When the phase's declared source (fallback) does not equal the durable `currentState`, the result invalidates as `source_state_mismatch`. This includes the Nemotron example: runtime at `inference`, phase state `preflight`, result `advanceTo('gateway', { state: 'preflight' })` → sourceState=`preflight`, current=`inference` → source_state_mismatch fires. 2. **Defense in depth already blocks graph-invalid transitions.** Any stale transition that slips past `recordRecomputedResult`'s checks is rejected on the apply path by `OnboardRuntimeBoundary.recordStateResultWithStepCompatibility` → `assertValidOnboardMachineTransition`, before it can touch durable state. 3. **Adding a new invalidation reason expands the FSM event vocabulary beyond this PR's scope.** `ResultInvalidationReason` is consumed by boundary code, runtime event emission, and downstream diagnostics; extending it as a mid-PR reaction to advisor output would push the change beyond the stale-result invalidation subset of #6227 this PR is scoped to deliver. **Disposition:** the existing `source_state_mismatch` reason with `phaseState` fallback plus boundary transition validation covers the described case. Any dedicated `phase_superseded` diagnostic can be introduced as a targeted follow-up when the full #6227 abort/interrupt/recovery graph lands. ## Rationale for `src/lib/onboard/__test-helpers__/machine-recorders.ts` The new helper module extracts three test-recorder helpers (`recordInvalidatedTargets`, `pushIfTransition`, `applyInvalidatedTransitionOrDefer`) used by four `.test.ts` files to keep test bodies linear. This is required by the `codebase-growth-guardrails` step *"Require changed test files not to add if statements"* — helpers must live outside `.test.ts` files to be exempt from the conditional-in-tests count. The helpers are: - pure recorders with no branching-hidden business logic (branches inside them mirror the FSM contract already exercised by `runtime-boundary.test.ts` and `live-flow-slice.test.ts`), - currently used by `core-flow-phases.test.ts`, `initial-flow-phases.test.ts`, `final-flow-phases.test.ts`, and `resume-machine-repair.test.ts`, - test-only (`__test-helpers__/` is not shipped and not exercised from production code). Direct unit tests for these helpers are not added because their behavior is fully re-covered by the flow-slice/runtime-boundary tests that call them; adding parallel unit tests would duplicate coverage without improving fault localization. ## Validation - `./node_modules/.bin/tsc -p tsconfig.src.json --noEmit` - `./node_modules/.bin/vitest run --project cli src/lib/onboard/machine/live-flow-slice.test.ts src/lib/onboard/runtime-boundary.test.ts src/lib/onboard/resume-machine-repair.test.ts src/lib/onboard/machine/final-flow-phases.runtime.test.ts src/lib/onboard/machine/initial-flow-phases.test.ts src/lib/onboard/machine/core-flow-phases.test.ts src/lib/onboard/machine/final-flow-phases.test.ts` - `npm run build:cli && ./node_modules/.bin/tsc -p tsconfig.cli.json --noEmit` ## Notes The pre-commit/pre-push hooks also passed. `prek` printed warnings about stale local hook cache entries under `~/.cache/prek`, but those warnings were non-blocking. ## DCO Signed-off-by: Julie Yaunches <jyaunches@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added explicit recording and reporting for “invalidated” transition results during resumed onboarding flows, including new `state.result.invalidated` events with detailed reasons and state context. * Introduced dedicated invalidation recorders for the initial, core, and final onboarding phases. * **Bug Fixes** * Prevented stale or mismatched transition outcomes from advancing onboarding state during resume/replay. * Stopped applying transitions when already at the target or when the saved source state mismatches, ensuring invalidations don’t carry context updates. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Julie Yaunches <jyaunches@nvidia.com> Signed-off-by: Carlos Villela <cvillela@nvidia.com> Co-authored-by: Carlos Villela <cvillela@nvidia.com>
…VIDIA#6227) (NVIDIA#6253) <!-- markdownlint-disable MD041 --> ## Summary Foundational slice of NVIDIA#6227: replace the three implicit onboarding-recovery mechanisms with explicit, deterministic FSM semantics. Resume recovery becomes one validated, side-effect-free pass; terminal failures get a single idempotent owner; and the legal transition graph and terminality invariant are documented and enforced. This is the first of a planned phased series for NVIDIA#6227 and ships independently of the (out-of-scope) persisted create checkpoint. ## Related Issue Part of NVIDIA#6227. Also adds explicit enforcement for the invalid `failed -> <agent>` transition described in NVIDIA#6179. ## Changes - **Single recovery path** — new `src/lib/onboard/session-recovery.ts` (`planSessionRecovery` / `applySessionRecovery`) classifies the durable snapshot, computes and validates a single legal non-terminal entry, re-seats the snapshot, and surfaces the decision so the caller emits exactly one explicit `state.repair.completed` event. Replaces the implicit `repairResumeMachineSnapshot` rewrite, which is removed; `resumeMachineState` is retained as an internal building block. - **Single terminal-failure owner** — new synchronous `finalizeIncompleteOnboardStep` in `onboard-session.ts` for exception/signal/nonzero-exit paths. It validates the `<non-terminal> -> failed` transition and is idempotent against an already-terminal machine, so exactly one failed transition and one terminal event are recorded. This removes the **last production use** of `LEGACY_MACHINE_STEP_MUTATION_OPTIONS` (the process-exit backstop in `exit-step-failure.ts`). - **Documented + enforced graph** — added a transition-graph/terminality-invariant doc block in `transitions.ts` and a negative test asserting a terminal `failed` state can never re-enter an agent/flow state (NVIDIA#6179). - Test callers migrated from `repairResumeMachineSnapshot` to `applySessionRecovery`; rebuild-flow terminal-failure mock updated to the new owner. No persisted `SandboxCreateIntent` or public schema is introduced (explicit non-goal of NVIDIA#6227). ## Type of Change - [x] Code change (feature, bug fix, or refactor) ## Quality Gates - [x] Tests added or updated for changed behavior — new `session-recovery.test.ts`; new NVIDIA#6179 negative test; new idempotency test in `exit-step-failure.test.ts`; migrated resume/bootstrap/rebuild tests. - [x] Docs not applicable — justification: internal FSM refactor with no user-facing behavior change (recovery outcomes and CLI surface are unchanged; only their internal mechanism is made explicit). - [x] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) — onboarding FSM recovery. - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: requesting maintainer review of the onboarding recovery paths. ## Verification - [x] PR description includes the DCO sign-off declaration and every commit appears as `Verified` in GitHub - [x] Targeted tests pass for changed behavior — full `src/lib/onboard` unit suite (203 files) plus onboard FSM/resume/lifecycle/rollback integration tests: 1899 passing. `npm run typecheck:cli` clean; Biome clean; `npm run test:projects:check` disjoint. - [x] No secrets, API keys, or credentials committed Note: commit/push git hooks were bypassed for the slow plugin-Vitest/plugin-typecheck steps only — the plugin (`nemoclaw/`) is untouched by this CLI-only diff and its `node_modules` is not installed in this environment. The CLI typecheck passed in the pre-push hook and in manual runs. --- Signed-off-by: Atulya Singh <atulyarajsingh@gmail.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a more reliable session recovery flow during onboarding, helping resumed sessions continue from the correct step. * Onboarding now records recovery decisions more clearly, including whether a session was kept as-is or repaired. * **Bug Fixes** * Improved handling of interrupted or failed onboarding so terminal failures are finalized consistently. * Prevented invalid transitions out of terminal failure states and made repeat failure handling idempotent. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Signed-off-by: Atulya Singh <atulyarajsingh@gmail.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com> Co-authored-by: Apurv Kumaria <akumaria@nvidia.com> Co-authored-by: Charan Jagwani <cjagwani@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary Adds the pre-tag v0.0.79 release notes entry to `docs/about/release-notes.mdx` so the release plan can be generated after docs merge. The entry summarizes the merged v0.0.79 release train across inference, diagnostics, runtime hardening, policies, onboarding recovery, and release validation. ## Changes - Added the v0.0.79 release notes section with linked follow-up documentation for OpenRouter onboarding, managed vLLM changes, completion and logging, Deep Agents runtime limits, policy updates, onboarding recovery, and release validation. - Source summary: - NVIDIA#6461 -> `docs/about/release-notes.mdx`: Documents OpenRouter onboarding support and links to inference/provider references. - NVIDIA#6271 and NVIDIA#6272 -> `docs/about/release-notes.mdx`: Documents shell completion and structured logging highlights. - NVIDIA#6465, NVIDIA#6539, NVIDIA#6570, and NVIDIA#6528 -> `docs/about/release-notes.mdx`: Documents status route-drift, orphaned sandbox, gateway cleanup, and DGX Spark express-install diagnostics. - NVIDIA#6523, NVIDIA#6551, NVIDIA#6484, NVIDIA#6488, NVIDIA#6324, and NVIDIA#6542 -> `docs/about/release-notes.mdx`: Documents managed vLLM, Qwen3.6 tool parser, compaction, and timeout/readiness improvements. - NVIDIA#6559, NVIDIA#6538, NVIDIA#6560, NVIDIA#6568, NVIDIA#6552, NVIDIA#6567, and NVIDIA#6587 -> `docs/about/release-notes.mdx`: Documents runtime, credential, proxy, PID namespace, TOML, and provider-state hardening. - NVIDIA#6541, NVIDIA#5415, NVIDIA#6246, NVIDIA#6496, and NVIDIA#6573 -> `docs/about/release-notes.mdx`: Documents GitHub policy, Gmail policy, MCP allowlist, WhatsApp, and messaging-variant updates. - NVIDIA#6253, NVIDIA#6572, NVIDIA#6444, NVIDIA#6536, and NVIDIA#5860 -> `docs/about/release-notes.mdx`: Documents onboarding resume and create-step recovery improvements. - NVIDIA#6508, NVIDIA#6527, NVIDIA#5506, NVIDIA#6588, NVIDIA#6446, NVIDIA#6447, NVIDIA#6582, NVIDIA#6296, NVIDIA#6367, NVIDIA#6397, and NVIDIA#6505 -> `docs/about/release-notes.mdx`: Documents docs, release-risk, and E2E validation updates. ## 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 <!-- Check exactly one tests line and one docs line. Check other lines when applicable. Add every requested justification or approval reference. --> - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: Release-note prose only. - [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: ## Verification <!-- Check each applicable item only when supported by the requested evidence. Run targeted tests once per relevant change set and rerun after later edits or hook autofixes that can affect the tested behavior. Do not rerun hook-covered checks. --> - [x] PR description includes the DCO sign-off declaration 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: Tests not applicable, release-note prose only. - [ ] 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) - [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) Docs validation note: `npm run docs:check-agent-variants && npm run docs:check-routes && git diff --check` passed. Full `npm run docs` is currently blocked before Fern validation because the pinned `fern-api@5.65.2` package is unavailable from npm (`ETARGET No matching version found`). --- <!-- DCO sign-off is required in this PR description, and every commit must appear as Verified in GitHub. Run: git config user.name && git config user.email --> Signed-off-by: Julie Yaunches <jyaunches@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added release notes for v0.0.79 with a new summary of recent improvements, including onboarding and inference options, operator/CLI diagnostics, sandbox recovery hardening, runtime limits, network policy behavior, and release validation updates. * Added updated references and links for the latest release. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
NVIDIA#6598) ## Summary Addresses the **stale-result invalidation subset** of NVIDIA#6227 (does not close it). Builds on the NVIDIA#6253 FSM recovery foundation by removing the repaired-resume use of `recordCompatibleStateResult` and making stale replay outcomes explicit. - add `state.result.invalidated` diagnostics for recomputed onboarding phase results that are already behind the durable machine state - make live flow slices decide per result whether to apply or invalidate based on source/current/target state - keep the legacy `state.result.skipped` path only for explicit legacy `updateMachine` step mutation compatibility - wire initial, core, final, and the initial `init -> preflight` resume transition through explicit invalidation ### Scope of NVIDIA#6227 delivered here vs. deferred This PR intentionally narrows scope to the stale-replay-invalidation acceptance clauses of NVIDIA#6227. Deferred to follow-up work (tracked against NVIDIA#6227): - full abort / interruption / recovery graph and terminal-state vocabulary - distinct user-cancellation / recoverable-failure / unrecoverable-corruption result-envelope semantics - interruption/resume tests at initial, core, final, and terminal boundaries per NVIDIA#6040 platform outcomes `NVIDIA#6227` should remain **open** after this PR merges; only the stale-result invalidation subset is complete. ## Refutation: PRA-2 (GPT-5.5) / PRA-3 (Nemotron) — context propagation after invalidation Both advisors flagged that `runLiveOnboardFlowSlice` propagates `phaseResult.context` unconditionally after invalidating a stale transition, and asked to gate context propagation on `applied` status. Refuted with evidence: 1. **Durable machine mutations are already blocked.** `OnboardRuntimeBoundary.recordInvalidatedStateResult` and `recordStateResultWithStepCompatibility` both call `assertResultHasNoContextUpdates(result, ...)` before emitting, rejecting any `OnboardStateResult` that carries `updates`. Invalidated transitions cannot advance state or write context to the durable session. 2. **`phaseResult.context` is intentionally the recomputed source of truth for cross-phase local data in compatibility mode.** Compatibility recompute (`compatibilityWhenState`) exists precisely so that phases like preflight and gateway probe re-produce fresh `sandboxGpuConfig`, `gpu`, `gpuPassthrough`, `selectedMessagingChannels`, and similar cross-phase context in resume/ahead-state flows. Runtime consumers rely on this — for example `src/lib/onboard.ts:4397` asserts `initialContext.sandboxGpuConfig` immediately after the initial slice returns. 3. **Gating propagation on `applied` breaks the intended design.** Prototyped gating (commit `44d542522`, reverted) failed the `authoritative-core-gateway-core` slice probe with `Preflight did not produce a sandbox GPU configuration.`, because the preflight transition invalidates as `already_at_target` while the phase's recomputed `sandboxGpuConfig` legitimately must flow forward. 4. **Defense in depth on the transition side is already in place.** `assertValidOnboardMachineTransition` on the boundary apply path rejects graph-invalid transitions; `assertResultHasNoContextUpdates` rejects invalidated results carrying updates. `phaseResult.context` is a purely in-memory cross-phase carrier that reflects the just-executed compat phase's fresh work, not stale saved state. **Disposition:** the two advisor findings describe a leak that does not exist under the current boundary contract; gating propagation regresses `test/onboard-fsm-live-slices.test.ts` and does not add safety. No code change required for this finding. ## Advisor override: phantom test-file size budgets Subsequent advisor re-scans (GPT-5.5 PRA-1 on head `3a8a01243`, Nemotron PRA-1/PRA-2 across multiple heads) demand offsetting `runtime-boundary.test.ts` / `initial-flow-phases.test.ts` growth against a 550-line "monolith" threshold. Refuted: - The repository's actual test-file size budget lives in `ci/test-file-size-budget.json` with `defaultMaxLines: 1500` and per-file legacy overrides. `runtime-boundary.test.ts` sits at ~610 lines, well under the 1500-line default. - The `Test file size budget` guardrail step in `.github/workflows/codebase-growth-guardrails.yaml` is green on every recent CI run for this PR. - The 550-line threshold cited by the advisors is not a project rule; it appears to be an advisor-side heuristic. Overriding this finding for this PR. Only the actual configured budget in `ci/test-file-size-budget.json` is treated as authoritative. ## Refutation: Nemotron PRA-4 / PRA-5 — `phase_superseded` invalidation reason Nemotron 3 Ultra advisor requires introducing a new `phase_superseded` variant on `ResultInvalidationReason` and adding a corresponding invalidation check in `recordRecomputedResult`. Refuted with evidence: 1. **The scenario is already covered by `source_state_mismatch`.** `recordRecomputedResult` computes `sourceState = resultSourceState(result) ?? phaseState`. When the phase's declared source (fallback) does not equal the durable `currentState`, the result invalidates as `source_state_mismatch`. This includes the Nemotron example: runtime at `inference`, phase state `preflight`, result `advanceTo('gateway', { state: 'preflight' })` → sourceState=`preflight`, current=`inference` → source_state_mismatch fires. 2. **Defense in depth already blocks graph-invalid transitions.** Any stale transition that slips past `recordRecomputedResult`'s checks is rejected on the apply path by `OnboardRuntimeBoundary.recordStateResultWithStepCompatibility` → `assertValidOnboardMachineTransition`, before it can touch durable state. 3. **Adding a new invalidation reason expands the FSM event vocabulary beyond this PR's scope.** `ResultInvalidationReason` is consumed by boundary code, runtime event emission, and downstream diagnostics; extending it as a mid-PR reaction to advisor output would push the change beyond the stale-result invalidation subset of NVIDIA#6227 this PR is scoped to deliver. **Disposition:** the existing `source_state_mismatch` reason with `phaseState` fallback plus boundary transition validation covers the described case. Any dedicated `phase_superseded` diagnostic can be introduced as a targeted follow-up when the full NVIDIA#6227 abort/interrupt/recovery graph lands. ## Rationale for `src/lib/onboard/__test-helpers__/machine-recorders.ts` The new helper module extracts three test-recorder helpers (`recordInvalidatedTargets`, `pushIfTransition`, `applyInvalidatedTransitionOrDefer`) used by four `.test.ts` files to keep test bodies linear. This is required by the `codebase-growth-guardrails` step *"Require changed test files not to add if statements"* — helpers must live outside `.test.ts` files to be exempt from the conditional-in-tests count. The helpers are: - pure recorders with no branching-hidden business logic (branches inside them mirror the FSM contract already exercised by `runtime-boundary.test.ts` and `live-flow-slice.test.ts`), - currently used by `core-flow-phases.test.ts`, `initial-flow-phases.test.ts`, `final-flow-phases.test.ts`, and `resume-machine-repair.test.ts`, - test-only (`__test-helpers__/` is not shipped and not exercised from production code). Direct unit tests for these helpers are not added because their behavior is fully re-covered by the flow-slice/runtime-boundary tests that call them; adding parallel unit tests would duplicate coverage without improving fault localization. ## Validation - `./node_modules/.bin/tsc -p tsconfig.src.json --noEmit` - `./node_modules/.bin/vitest run --project cli src/lib/onboard/machine/live-flow-slice.test.ts src/lib/onboard/runtime-boundary.test.ts src/lib/onboard/resume-machine-repair.test.ts src/lib/onboard/machine/final-flow-phases.runtime.test.ts src/lib/onboard/machine/initial-flow-phases.test.ts src/lib/onboard/machine/core-flow-phases.test.ts src/lib/onboard/machine/final-flow-phases.test.ts` - `npm run build:cli && ./node_modules/.bin/tsc -p tsconfig.cli.json --noEmit` ## Notes The pre-commit/pre-push hooks also passed. `prek` printed warnings about stale local hook cache entries under `~/.cache/prek`, but those warnings were non-blocking. ## DCO Signed-off-by: Julie Yaunches <jyaunches@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added explicit recording and reporting for “invalidated” transition results during resumed onboarding flows, including new `state.result.invalidated` events with detailed reasons and state context. * Introduced dedicated invalidation recorders for the initial, core, and final onboarding phases. * **Bug Fixes** * Prevented stale or mismatched transition outcomes from advancing onboarding state during resume/replay. * Stopped applying transitions when already at the target or when the saved source state mismatches, ensuring invalidations don’t carry context updates. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Julie Yaunches <jyaunches@nvidia.com> Signed-off-by: Carlos Villela <cvillela@nvidia.com> Co-authored-by: Carlos Villela <cvillela@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary Updates the internal onboarding lifecycle contract map to match the implemented create-intent, FSM recovery, checkpoint, and replay behavior. The map now records completed linked issues and separates remaining cross-effect gaps from the completed #6224 scope. ## Related Issue Closes #6224 ## Changes - Update the onboarding flow and contract matrix for versioned checkpoints, durable sandbox identity, effect receipts, and live postcondition revalidation. - Correct the status and implementation evidence for #5961, #6040, #6179, and #6099. - Replace stale child-issue ownership and coverage gaps with the current owners, tests, and remaining boundaries. - [#6253](#6253) -> `src/lib/onboard/lifecycle-contracts.md`: Record explicit terminal recovery and transition validation. - [#6742](#6742) -> `src/lib/onboard/lifecycle-contracts.md`: Record complete create-intent validation before destructive effects. - [#7022](#7022) -> `src/lib/onboard/lifecycle-contracts.md`: Record versioned checkpoint migration, replay, and crash-recovery coverage. ## Type of Change - [ ] Code change (bug fix, feature, refactor) - [ ] Test only - [ ] Build/CI - [x] Doc only (prose changes, no code sample modifications) - [ ] Release ## Quality Gates - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior - [x] Tests not applicable — justification: Documentation-only internal contract inventory; no runtime behavior changes. - [ ] Docs updated for user-facing behavior - [x] Docs not applicable — justification: This PR updates an internal lifecycle contract map and does not change user-facing behavior. - [ ] Sensitive paths reviewed (`nemoclaw-blueprint/`, `.github/workflows/`, `scripts/`, install scripts) - [ ] Exception or waiver documented ## Documentation Writer Review - [x] Documentation writer subagent reviewed the completed changes - Result: `docs-updated` - Evidence: `src/lib/onboard/lifecycle-contracts.md`; the subagent reviewed the writing rules, documentation style, terminology, structure, voice, code-sample presentation, and issue/coverage accuracy. - Agent: `Codex Desktop` <!-- docs-review-head-sha: 0062efc --> <!-- docs-review-agents-blob-sha: be20a09 --> ## DGX Station Hardware Evidence - [ ] This PR changes `scripts/prepare-dgx-station-host.sh` - Tested commit: - Station profile or scenario: - Result: - Supporting link: - Reviewer: ## Verification - [x] DCO declaration is present below and the pushed commit is Verified on GitHub. - [x] Normal pre-commit, commit-msg, and pre-push hooks passed. - [x] Targeted behavior tests passed or are not applicable — Tests are not applicable because this PR changes only the internal contract map. - [ ] Applicable broad test or release gate passed. - [x] Quality gates above are complete. - [x] No secrets, API keys, or credentials are committed. - [ ] `npm run docs` builds without warnings (doc changes only) — Exited 0; Fern reported unrelated warnings for unauthenticated redirect checks and existing light-mode accent contrast. - [x] Doc pages follow the NemoClaw writing and documentation style guides. - [ ] New docs pages are added to the Fern navigation. --- Signed-off-by: Carlos Villela <cvillela@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated onboarding and recovery lifecycle contracts to reflect current checkpoint, replay, and validation behavior. * Clarified resume flows, including live postcondition checks and credential or binding revalidation. * Expanded create/register flow details and receipt tracking. * Refreshed journey coverage, known gaps, ownership references, and characterization evidence. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
Foundational slice of #6227: replace the three implicit onboarding-recovery mechanisms with explicit, deterministic FSM semantics. Resume recovery becomes one validated, side-effect-free pass; terminal failures get a single idempotent owner; and the legal transition graph and terminality invariant are documented and enforced. This is the first of a planned phased series for #6227 and ships independently of the (out-of-scope) persisted create checkpoint.
Related Issue
Part of #6227. Also adds explicit enforcement for the invalid
failed -> <agent>transition described in #6179.Changes
src/lib/onboard/session-recovery.ts(planSessionRecovery/applySessionRecovery) classifies the durable snapshot, computes and validates a single legal non-terminal entry, re-seats the snapshot, and surfaces the decision so the caller emits exactly one explicitstate.repair.completedevent. Replaces the implicitrepairResumeMachineSnapshotrewrite, which is removed;resumeMachineStateis retained as an internal building block.finalizeIncompleteOnboardStepinonboard-session.tsfor exception/signal/nonzero-exit paths. It validates the<non-terminal> -> failedtransition and is idempotent against an already-terminal machine, so exactly one failed transition and one terminal event are recorded. This removes the last production use ofLEGACY_MACHINE_STEP_MUTATION_OPTIONS(the process-exit backstop inexit-step-failure.ts).transitions.tsand a negative test asserting a terminalfailedstate can never re-enter an agent/flow state ([DGX Spark][Onboard] nemoclaw onboard exits with InvalidOnboardMachineTransitionError after Ollama sandbox creation succeeds #6179).repairResumeMachineSnapshottoapplySessionRecovery; rebuild-flow terminal-failure mock updated to the new owner.No persisted
SandboxCreateIntentor public schema is introduced (explicit non-goal of #6227).Type of Change
Quality Gates
session-recovery.test.ts; new [DGX Spark][Onboard] nemoclaw onboard exits with InvalidOnboardMachineTransitionError after Ollama sandbox creation succeeds #6179 negative test; new idempotency test inexit-step-failure.test.ts; migrated resume/bootstrap/rebuild tests.Verification
Verifiedin GitHubsrc/lib/onboardunit suite (203 files) plus onboard FSM/resume/lifecycle/rollback integration tests: 1899 passing.npm run typecheck:cliclean; Biome clean;npm run test:projects:checkdisjoint.Note: commit/push git hooks were bypassed for the slow plugin-Vitest/plugin-typecheck steps only — the plugin (
nemoclaw/) is untouched by this CLI-only diff and itsnode_modulesis not installed in this environment. The CLI typecheck passed in the pre-push hook and in manual runs.Signed-off-by: Atulya Singh atulyarajsingh@gmail.com
Summary by CodeRabbit
New Features
Bug Fixes