fix(cli): accept channels status without --wait - #8900
Conversation
Remove the parser default on the channels status --timeout flag. oclif validates dependsOn whenever the flag has a value, and the default always supplied one, so every invocation without --wait was rejected. showSandboxChannelStatus already applies the documented 180-second budget when --wait is set without --timeout, and an explicit --timeout still requires --wait. Add the no-defaulted-dependent-flags repository check so no oclif flag combines a parser default with dependsOn, with regression tests for the no-wait invocations, the forwarded readiness contract, and the default budget. Fixes NVIDIA#8883. Signed-off-by: Kushagar Garg <dreamstick909@gmail.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 (2)
📝 WalkthroughWalkthroughThe channel status command now applies its timeout default in the action layer. A repository check detects flag definitions that combine ChangesChannel status validation
Managed image source update
Estimated code review effort: 3 (Moderate) | ~20 minutes Mergeability Score: ⚪ Minimal · up to This change restores documented no-wait channel-status usage while preserving the 180-second wait budget and explicit --timeout contract. Targeted tests and repository checks pass, and no actionable merge-blocking risk remains beyond normal checks and review. Sequence Diagram(s)sequenceDiagram
participant CLI
participant showSandboxChannelStatus
participant GatewayPolicy
CLI->>showSandboxChannelStatus: invoke status with undefined timeout
showSandboxChannelStatus->>showSandboxChannelStatus: apply 180-second timeout budget
showSandboxChannelStatus->>GatewayPolicy: check readiness with propagated deadline
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
PR Review Advisor — InformationalAdvisor assessment: Informational / low confidence Model lanes
2 terminology differences from the second opinionAdvisory only. These are normalized differences from the primary terminology receipt.
4 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: None Manual-only E2E: This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge. |
Pin the CHECKS registration for no-defaulted-dependent-flags so a future deletion or script-path error fails the checks-runner test instead of silently disabling the guard (PR review advisor PRA-1). Signed-off-by: Kushagar Garg <dreamstick909@gmail.com>
|
✨ Thanks for the fix. This restores the documented no-wait behavior for Related open issues: |
Thanks for the review man, also I have that issue you mentioned linked in the pr description |
|
The current CI blocker is unrelated to this PR.
The PR requires CI or test-harness owner intervention before all repository gates can pass. No PR source change is indicated by this failure. |
The synchronous legacy short-token recovery case raced the real 1-second acquisition budget: options() sets timeoutMs to 1000 and the sync path defaults to performance.now(), so marker recovery on a loaded CI runner can exceed the deadline and fail with "Timed out waiting for sandbox mutation lock for 'alpha'" (PR NVIDIA#8900, CLI shard 11). The asynchronous sibling already pins monotonicNow to 0 and is immune. Pin the synchronous case the same way so the deadline cannot expire while recovery does real filesystem work. Signed-off-by: Kushagar Garg <dreamstick909@gmail.com>
The synchronous legacy short-token recovery case raced the real 1-second acquisition budget: options() sets timeoutMs to 1000 and the sync path defaults to performance.now(), so marker recovery on a loaded CI runner can exceed the deadline and fail with "Timed out waiting for sandbox mutation lock for 'alpha'" (PR NVIDIA#8900, CLI shard 11). Drive the deadline from a stepping clock instead. Recovery success no longer depends on wall-clock load, and a genuine strand regression still exhausts the budget after 1,000 clock reads, so it fails with the real timeout error instead of blocking the synchronous worker the way a fully pinned clock would. Signed-off-by: Kushagar Garg <dreamstick909@gmail.com>
prekshivyas
left a comment
There was a problem hiding this comment.
Approved based on code review. Required CI checks remain merge gates.
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
cv
left a comment
There was a problem hiding this comment.
The no-wait status path preserves the documented wait budget and explicit timeout contract. The repository guard covers parser defaults combined with dependent flags, the staging source matches the current libssh2 inventory, and required checks pass on 8c0ac2e. No security, correctness, documentation, or review finding remains.
…ery (#8948) <!-- markdownlint-disable MD041 --> ## Summary The CLI test `does not strand synchronous recovery behind an expired legacy short-token marker` races a real 1-second clock: `options()` sets `timeoutMs: 1000` and the synchronous acquisition path defaults `monotonicNow` to `performance.now()`, so legacy-marker recovery doing real filesystem work can exceed the budget on a loaded CI runner. That produced the shard-11 failure `Timed out waiting for sandbox mutation lock for 'alpha'` on #8900 after its transient-failure retry was exhausted. This change drives the deadline from a stepping clock, so recovery success no longer depends on wall-clock load while a genuine strand regression still exhausts the budget after 1,000 clock reads and fails with the real timeout error. ## Changes - `src/lib/state/mcp-lifecycle-lock-acquisition.test.ts`: inject a stepping `monotonicNow` into the synchronous legacy short-token recovery case, with a comment recording the CI evidence. The asynchronous sibling pins its clock to `0`; the synchronous case steps instead because its sleep is `Atomics.wait`, and a fully pinned clock would let a future strand regression block the vitest worker where a stepping clock keeps that failure bounded at 1,000 clock reads with the real timeout error. - `test/mcp-lifecycle-lock.test.ts`: apply the same stepping-clock idiom (already used elsewhere in this file) to `preserves a replacement main lock published during stale recovery`, which raced a real 50 ms budget the same way and failed on this PR's own CI shard 4 with `observed-stale-token` when the deadline expired before stale recovery reached its first rename. ## 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 - [ ] Tests added or updated for changed behavior - [x] Existing tests cover changed behavior — justification: this change edits the test itself to remove a load-dependent race; the case still asserts the same recovery behavior, now deterministically. - [ ] Tests not applicable — justification: - [ ] Docs updated for user-facing behavior changes - [x] Docs not applicable — justification: test-only change; no user-facing surface. - [ ] 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: `no-docs-needed` - Evidence: test-only change; no documentation page references this test or the acquisition timeout budget. - Agent: Claude Code <!-- docs-review-head-sha: 66b73df --> <!-- docs-review-agents-blob-sha: c4923a3 --> ## 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: `npx vitest run --project cli src/lib/state/mcp-lifecycle-lock-acquisition.test.ts` → 28 passed, three consecutive runs; `npx vitest run --project integration test/mcp-lifecycle-lock.test.ts` → 44 passed, five consecutive runs plus one run on the merged tree - [ ] 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; one-case test edit with no runtime or repo-wide validation change. - [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: Kushagar Garg <dreamstick909@gmail.com> --------- Signed-off-by: Kushagar Garg <dreamstick909@gmail.com> Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Summary
nemoclaw <sandbox> channels statusrejected every invocation without--wait, including the documented no-wait forms, withAll of the following must be provided when using --timeout: --wait. Thetimeoutflag combineddefault: 180withdependsOn: ["wait"], and oclif validatesdependsOnwhenever the flag has a value, so the parser default triggered the dependency check on every parse. This change removes the parser default;showSandboxChannelStatusalready applies the documented 180-second budget, so--waitbehavior is unchanged and an explicit--timeoutstill requires--wait.Related Issue
Fixes #8883.
Reproduction
Against unmodified
mainatac6adacd, the new regression cases fail with the reported rejection; with this change they pass:The new repository check also pinpoints the defect on unmodified
main(src/commands/sandbox/channels/status.ts:35 timeout, exit 1) and passes on this branch (exit 0).Changes
src/commands/sandbox/channels/status.ts: removedefault: 180from thetimeoutflag and state the 180-second default in the flag description. The readiness action keeps applying the default (DEFAULT_WAIT_TIMEOUT_SECONDSinsrc/lib/actions/sandbox/channel-status.ts).src/commands/sandbox/channels/status.test.ts: add no-wait regression cases that fail on unfixedmain, and pin the forwarded contract for--waitwithout--timeout(timeoutSeconds: undefined).src/lib/actions/sandbox/channel-status.test.ts: pin the 180-second budget when the caller omitstimeoutSeconds(readinesselapsedMs: 180000and the first policy-probe deadline).scripts/checks/no-defaulted-dependent-flags.mts+ registration inscripts/checks/run.mts: new repository check that rejects any oclif flag combining a parserdefaultwithdependsOn. Requirement and consumer: this defect class is a per-flag combination any command can silently reintroduce, invisible to type checks and per-command tests; the check runs innpm run checks:repositoryvia therepository-checkspre-commit hook and CI. A direct change alone cannot prevent recurrence. Protecting test:test/no-defaulted-dependent-flags.test.ts.Type of Change
Quality Gates
docs/reference/commands.mdxdescribes the no-wait forms and states "The default timeout is 180 seconds, and--timeout <seconds>requires--wait", which now matches the CLI for the first time. Confirmed by the documentation writer review below.Documentation Writer Review
no-docs-neededVerification
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/commands/sandbox/channels/status.test.ts src/lib/actions/sandbox/channel-status.test.ts→ 24 passed;npx vitest run --project integration test/no-defaulted-dependent-flags.test.ts→ 6 passed;npx vitest run --project integration test/checks-runner.test.ts→ passed with the PRA-1 registration assertion;npx tsx scripts/checks/no-defaulted-dependent-flags.mts→ exit 0 on this branch, exit 1 on unmodifiedmainnpm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — command/result:SKIP=hadolint npm run check(applies becausescripts/checks/run.mtsgains a check; hadolint binary unavailable on this host and the diff changes no Dockerfile): the--all-filespre-commit stage passes; the full-suite manual stage fails on this macOS host only in tests that also fail on unmodified upstreammainat the merge base164a7bee— rerunning the failing set there fails 8 tests vs 6 at the PR head, a strict subset that includes documented issue Ollama WSL probe-order test fails on macOS because isWsl short-circuits on platform #8868 — and none of those files import the changed files.npm run checks:repositorypasses end to end with the new check; the PR CI aggregate is the authoritative broad run.npm run docsbuilds without warnings (doc changes only)Signed-off-by: Kushagar Garg dreamstick909@gmail.com
Summary by CodeRabbit
New Features
Bug Fixes
Tests