Skip to content

[All Platforms][UX] --tail flag semantic mismatch + shields status terminology drift #3702

@coder-glenn

Description

@coder-glenn

Description

Description

Two small but real UX inconsistencies between commands that operators
will type back-to-back. Filing as one bug because they share a theme
("NemoClaw and OpenShell describe the same concept with slightly
different words") and the fix surface is similar.

(E1) The `--tail` flag has different semantics in the NemoClaw CLI vs
     OpenShell CLI:

       nemoclaw  logs --tail 20      # works: returns last 20 lines
                                           # `--tail` here means "N lines"
       openshell logs  --tail        # works: stream live logs
       openshell logs  --tail 20     # FAILS:
                                           # "error: unexpected argument '20' found"

     For the OpenShell CLI, `--tail` is a boolean meaning "stream live
     logs" and the line count is `-n ` instead. For the NemoClaw CLI,
     `--tail` accepts an integer.

     A user who runs `nemoclaw  logs --tail 20`, sees it work, and
     then runs `openshell logs  --tail 20` to look at the same
     logs from one level lower will see a confusing error. The
     cli-selection-guide.html doc shows `openshell logs
     --tail` with no value (which is technically correct) — but does not
     warn that the same flag means a different thing in NemoClaw.

(E2) The "shields" state has two different textual representations on
     the same v0.0.44 sandbox, at the same instant:

       $ nemoclaw  status
       ...
       Permissions: shields down (check `shields status` for details)
       ...

       $ nemoclaw  shields status
       Shields: NOT CONFIGURED (default mutable state)
       Config is mutable. Run `nemoclaw  shields up` to opt
       into lockdown.

     The status command calls the same state "shields down", and the
     shields-status command calls it "NOT CONFIGURED (default mutable
     state)". Both refer to the same internal state. A user who reads
     "shields down" in `status` will look for a "shields up" command
     to "raise the shields back" — but in reality nothing has been
     "lowered"; the sandbox was never configured for shields in the
     first place.

     This is also inconsistent with the doctor output, which uses yet
     another label: `[warn] Shields: down` (the same as `status`).

     One canonical vocabulary should win across all three commands.
Environment
Device:        ipp2-1558 (10.176.178.100), x86_64 server, 32 vCPU / 125 GB RAM, NVIDIA A100 80GB PCIe
OS:            Ubuntu 24.04.4 LTS (Linux 6.17.0-23-generic)
Architecture:  x86_64
Node.js:       v22.x
Docker:        29.5.0
OpenShell CLI: 0.0.39
NemoClaw:      v0.0.44
OpenClaw:      v2026.4.24
Steps to Reproduce
(E1)
1. nemoclaw test logs --tail 20            # exit 0, returns ~20 lines
2. openshell logs test --tail 20            # exit 2, "unexpected argument '20'"
3. openshell logs --help | grep -A2 -- '--tail'
   → confirms --tail is boolean ("Stream live logs"), with -n N for count.
4. nemoclaw test logs --help | grep -- '--tail'
   → confirms --tail takes an integer ([default: 200]).

(E2) On a sandbox that has never had `shields up` run:
1. nemoclaw  status
   →  "Permissions: shields down (check `shields status` for details)"
2. nemoclaw  shields status
   →  "Shields: NOT CONFIGURED (default mutable state)"
3. nemoclaw  doctor
   →  "[warn] Shields: down"
Expected Result
(E1) Either:
     - both CLIs use the same semantic for --tail (preferred:
       `--tail ` everywhere, with a separate `--follow` boolean for
       streaming), OR
     - the docs prominently flag the asymmetry next to the example.

(E2) `nemoclaw status`, `nemoclaw doctor`, and `nemoclaw shields status`
     use one canonical label for each shields state. Suggested
     vocabulary aligned with the operator action:
       mutable_default     (sandbox has never been shielded)
       locked              (shields up)
       temporarily_unlocked  (shields down --timeout ...)
     The `shields status` command already uses one of these
     (`NOT CONFIGURED`, but the underlying state in code is
     `mutable_default`); the other commands should follow.
Actual Result
(E1) Confirmed mismatch (see Steps).
(E2) Three commands, three labels:
       status   → "shields down"
       doctor   → "Shields: down"
       shields status → "NOT CONFIGURED (default mutable state)"
Logs
$ nemoclaw test logs --tail 20 2>&1 | tail -3
[1779099576.573] [gateway] [WARN] Container exited
    [exit 0]

$ openshell logs test --tail 20 2>&1
error: unexpected argument '20' found

Usage: openshell logs [OPTIONS] [NAME]

$ nemoclaw test status 2>&1 | grep -i shields
    Permissions: shields down (check `shields status` for details)

$ nemoclaw test shields status
  Shields: NOT CONFIGURED (default mutable state)
  Config is mutable. Run `nemoclaw  shields up` to opt into lockdown.

$ nemoclaw test doctor 2>&1 | grep -i shields
    [warn] Shields: down
Suggested Fix
(E1) Rename NemoClaw's `--tail ` to `-n ` (the openshell name) so
     the line-count flag is the same letter on both CLIs, and keep
     `--tail` as the boolean alias for "live stream" if any.
     Alternatively the cheaper fix is to teach openshell's `--tail` to
     accept an optional `` so both invocations work.

(E2) Use one canonical label across status, doctor, and shields-status.
     The `shields status` already prints both the machine label
     (`mutable_default`) and a human description; the other commands
     should converge on the same label set. The runtime-controls.md
     section in the docs uses `mutable_default / locked /
     temporarily_unlocked` as the documented vocabulary; the CLI should
     match.

Bug Details

Field Value
Priority Unprioritized
Action Dev - Open - To fix
Disposition Open issue
Module Machine Learning - NemoClaw
Engineer Aaron Erickson
Requester Glenn Zheng
Keyword NemoClaw
Days Open 0

[NVB#6186962]

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions