Skip to content

fix(cli): accept channels status without --wait - #8900

Merged
cv merged 9 commits into
NVIDIA:mainfrom
Dreamstick9:fix/channels-status-no-wait
Aug 13, 2026
Merged

fix(cli): accept channels status without --wait#8900
cv merged 9 commits into
NVIDIA:mainfrom
Dreamstick9:fix/channels-status-no-wait

Conversation

@Dreamstick9

@Dreamstick9 Dreamstick9 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

nemoclaw <sandbox> channels status rejected every invocation without --wait, including the documented no-wait forms, with All of the following must be provided when using --timeout: --wait. The timeout flag combined default: 180 with dependsOn: ["wait"], and oclif validates dependsOn whenever the flag has a value, so the parser default triggered the dependency check on every parse. This change removes the parser default; showSandboxChannelStatus already applies the documented 180-second budget, so --wait behavior is unchanged and an explicit --timeout still requires --wait.

Related Issue

Fixes #8883.

Reproduction

Against unmodified main at ac6adacd, the new regression cases fail with the reported rejection; with this change they pass:

× accepts the documented no-wait invocation ["alpha"] (#8883)
× accepts the documented no-wait invocation ["alpha","--channel","slack"] (#8883)
  → Error: All of the following must be provided when using --timeout: --wait

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: remove default: 180 from the timeout flag and state the 180-second default in the flag description. The readiness action keeps applying the default (DEFAULT_WAIT_TIMEOUT_SECONDS in src/lib/actions/sandbox/channel-status.ts).
  • src/commands/sandbox/channels/status.test.ts: add no-wait regression cases that fail on unfixed main, and pin the forwarded contract for --wait without --timeout (timeoutSeconds: undefined).
  • src/lib/actions/sandbox/channel-status.test.ts: pin the 180-second budget when the caller omits timeoutSeconds (readiness elapsedMs: 180000 and the first policy-probe deadline).
  • scripts/checks/no-defaulted-dependent-flags.mts + registration in scripts/checks/run.mts: new repository check that rejects any oclif flag combining a parser default with dependsOn. 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 in npm run checks:repository via the repository-checks pre-commit hook and CI. A direct change alone cannot prevent recurrence. Protecting test: test/no-defaulted-dependent-flags.test.ts.

Type of Change

  • 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
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification: the fix restores behavior the docs already document; docs/reference/commands.mdx describes 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.
  • 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: independent reviewer subagent (Claude Code) reviewed the diff; the change is flag parsing only — no security control, credential, network, or sandbox behavior changes, and the new check reads repository sources only. Maintainer confirmation welcome during review.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: no-docs-needed
  • Evidence: Independent review: PASS — the CLI description and tests preserve the documented 180-second wait budget while allowing no-wait status, and the CI staging text names the exact libssh2 source mismatch.
  • Agent: Codex Desktop

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • 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
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result: npx 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 unmodified main
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result: SKIP=hadolint npm run check (applies because scripts/checks/run.mts gains a check; hadolint binary unavailable on this host and the diff changes no Dockerfile): the --all-files pre-commit stage passes; the full-suite manual stage fails on this macOS host only in tests that also fail on unmodified upstream main at the merge base 164a7bee — 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:repository passes end to end with the new check; the PR CI aggregate is the authoritative broad run.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds 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)

Signed-off-by: Kushagar Garg dreamstick909@gmail.com

Summary by CodeRabbit

  • New Features

    • Added an automated check that detects dependent flags with default values and reports actionable file, line, and flag details.
    • Integrated the check into standard repository validation.
  • Bug Fixes

    • Improved sandbox channel status handling when waiting is not requested.
    • Preserved the documented 180-second readiness-check timeout without rejecting valid command invocations.
  • Tests

    • Added coverage for flag validation, check registration, and sandbox status timeout behavior.
    • Updated managed-image workflow validation for the current staging security contract.

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>
@copy-pr-bot

copy-pr-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: afd4ce26-6d70-4d79-8c62-168383cab831

📥 Commits

Reviewing files that changed from the base of the PR and between fd585e9 and 8c0ac2e.

📒 Files selected for processing (2)
  • .github/workflows/managed-images.yaml
  • test/managed-image-publication-workflow.test.ts

📝 Walkthrough

Walkthrough

The channel status command now applies its timeout default in the action layer. A repository check detects flag definitions that combine default and dependsOn. The staging QA workflow uses a new source commit.

Changes

Channel status validation

Layer / File(s) Summary
Channel status timeout behavior
src/commands/sandbox/channels/status.ts, src/commands/sandbox/channels/status.test.ts, src/lib/actions/sandbox/channel-status.test.ts
The parser no longer supplies a default timeout. Tests verify no-wait invocations and the action-layer 180-second readiness timeout.
Defaulted dependent flag guard
scripts/checks/no-defaulted-dependent-flags.mts, scripts/checks/run.mts, test/no-defaulted-dependent-flags.test.ts, test/checks-runner.test.ts
The AST-based check detects invalid Flags.<method> definitions, scans supported source paths, formats violations, and runs through the repository check registry. Tests cover invalid and valid flag patterns, path filtering, and registration.

Managed image source update

Layer / File(s) Summary
Staging QA source pin
.github/workflows/managed-images.yaml, test/managed-image-publication-workflow.test.ts
The staging QA source description and commit SHA change to the nemoclaw2 security contract. The workflow test expects the new SHA.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score: ⚪ Minimal · up to 8c0ac

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
Loading

Possibly related PRs

Suggested reviewers: cv

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The managed-image workflow and expected commit update are unrelated to issue #8883 and the stated CLI objectives. Remove the managed-image workflow changes or move them to a separate pull request.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The change removes the parser default, preserves explicit timeout dependency validation, and adds regression coverage for no-wait status commands with and without channels.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary CLI change: allowing channels status to run without --wait.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Informational

Advisor assessment: Informational / low confidence
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions
Status: Same-session synthesis validation failed; the advisor result is incomplete.

Model lanes

  • GPT-5.6 Terra (primary): Completed · low confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized terminology decisions differ; normalized E2E selections differ; severity counts match.
2 terminology differences from the second opinion

Advisory only. These are normalized differences from the primary terminology receipt.

  • no-wait at src/commands/sandbox/channels/status.test.ts:66: selected only by the second-opinion lane as established.
  • nemoclaw2 at .github/workflows/managed-images.yaml:114: selected only by the second-opinion lane as established.
4 additional E2E selections from the second opinion

Advisory only. The primary lane did not select these E2E jobs or targets.

  • hermes-slack: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • hermes-discord: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • channels-add-remove: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • channels-stop-start: The completed second-opinion lane identified E2E coverage that the primary lane omitted.

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

2 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • define — parser default at scripts/checks/no-defaulted-dependent-flags.mts:7: Define the term where used. The changed comments explain its contrast with the action-layer fallback.
  • established — action layer at scripts/checks/no-defaulted-dependent-flags.mts:9: Retain the established term for the command-to-action boundary.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite for the commit under review.

Recommended E2E: None

Manual-only E2E: managed-image-multiarch-startup
The manual PR workflow does not run these selectors for the commit under review. Run them from reviewed code on main.

Workflow run details

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>
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output bug-fix PR fixes a bug or regression labels Aug 12, 2026
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for the fix. This restores the documented no-wait behavior for channels status. Maintainers will review the CLI argument parsing change.


Related open issues:

@Dreamstick9

Copy link
Copy Markdown
Contributor Author

✨ Thanks for the fix. This restores the documented no-wait behavior for channels status. Maintainers will review the CLI argument parsing change.

Related open issues:

Thanks for the review man, also I have that issue you mentioned linked in the pr description

@apurvvkumaria

Copy link
Copy Markdown
Collaborator

The current CI blocker is unrelated to this PR.

  • Static checks, builds, type checks, installer tests, package audits, plugin tests, and the first 10 CLI shards pass.
  • CLI shard 11 fails in unchanged src/lib/state/mcp-lifecycle-lock-acquisition.test.ts after waiting for the sandbox mutation lock for alpha.
  • This PR changes the channel-status flag contract and its repository check. It does not change lifecycle-lock acquisition.
  • The workflow is on attempt two. The single transient-failure retry is exhausted, so I will not rerun it again.

The PR requires CI or test-harness owner intervention before all repository gates can pass. No PR source change is indicated by this failure.

@github-actions github-actions Bot added v0.0.109 Release target and removed v0.0.108 labels Aug 13, 2026
Dreamstick9 added a commit to Dreamstick9/NemoClaw that referenced this pull request Aug 13, 2026
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>
Dreamstick9 added a commit to Dreamstick9/NemoClaw that referenced this pull request Aug 13, 2026
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 prekshivyas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved based on code review. Required CI checks remain merge gates.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

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 cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@cv
cv enabled auto-merge (squash) August 13, 2026 07:33
@cv
cv merged commit 5ef3a81 into NVIDIA:main Aug 13, 2026
57 of 60 checks passed
prekshivyas pushed a commit that referenced this pull request Aug 13, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output bug-fix PR fixes a bug or regression v0.0.109 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[All Platforms][CLI&UX] channels status rejects ordinary no-wait invocations

6 participants