Skip to content

vms-6a1: SHOW USERS fails honestly with no executive (INV-6 fabrication fix) - #839

Merged
baron-3dl merged 2 commits into
mainfrom
work/vms-6a1
Aug 28, 2026
Merged

baron-3dl merged 2 commits into
mainfrom
work/vms-6a1

Conversation

@baron-3dl

@baron-3dl baron-3dl commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Defect (vms-6a1, INV-6 / Rule 9)

cmd_show_users() in src/vmsdcl/dcl_cmd_show.c printed its banner and the
Total number of users = N, number of processes = M summary
unconditionally, then returned SS$_NORMAL, without ever checking whether
the process-table scan reached the executive. With /dev/vms absent the first
vms_kif_procscan() cannot be delivered, process_count stays 0, and the code
still printed ...number of processes = 0 and reported success -- a fabricated
system display with no executive behind it.

The status contract (task premise corrected)

The task assumed vms_kif_procscan() returns SS$_NOSUCHDEV when absent. It
does not: the bare KIF_CALL path maps a bad-fd ioctl through
vms_kif_kerr_to_ss() -> default -> SS$_BUGCHECK (676). The real
distinguisher is that the executive answers with SS$_NORMAL (a row) or
SS$_NONEXPR (2280, table exhausted); anything else means the transport
never reached the executive. Gate: readable = (scan_st & 1) || scan_st == SS$_NONEXPR.

Adjudication — no-executive frame matches SHOW SYSTEM (a made-call)

My first fix emitted %SYSTEM-W-NOSUCHDEV and returned, dropping the
banner+headings. That satisfied the QEMU negctl but broke two host tests
(test_show_users_full, test_show_users_terminal) which require the frame --
and those host tests had always contradicted the negctl on one line: the
negctl forbids number of processes with no executive, the host test EXPECTed
Total number of users on the same line (main: host-green, negctl-red).

Controlling precedent = SHOW SYSTEM. cmd_show_system /
test_show_system_no_fabrication.sh: with no executive it prints banner +
column headings + NO rows and no computed count line. SHOW USERS is the only
SHOW command that prints a walked count; a count from a scan that hard-failed
is a mild fabrication (claims "I enumerated 0" when the truth is "I could not
enumerate"). So the faithful behavior, matching SHOW SYSTEM:

  1. cmd_show_users: keep the first-scan readable gate. Executive-unreadable
    branch prints the same frame SHOW SYSTEM does -- banner + column headings
    (honouring the bare-vs-/FULL split) + NO rows + NO count line -- and
    returns SS$_NORMAL. The count line prints only when the table was readable,
    including readable-but-empty (SS$_NONEXPR -> honest = 0).
  2. test_show_users_terminal.sh (a strengthening): removed
    EXPECT: contains:Total number of users, added
    EXPECT_NOT: contains:number of processes; every other assertion
    (Username/Node/Interactive headings; no PID/terminal/_FTA rows) unchanged;
    header comment records why. This overrides a documented test-author
    choice
    and reconciles the host contract to SHOW SYSTEM + the negctl.
  3. test_show_users_full.sh: unchanged; passes (checks /FULL headings + no
    rows; the frame still prints).
  4. test_syssvc_spawn_users.c (QEMU negctl): unchanged; its
    !has_substr(out,"number of processes") now matches the code.

Verification

Device-absent SHOW USERS (real DCL.EXE, no /dev/vms):

      OpenVMX User Processes at 28-AUG-2026 13:55:38.59
      Username     Node       Interactive  Subprocess     Batch

SHOW USERS/FULL:

      OpenVMX User Processes at 28-AUG-2026 13:55:38.59
      Username     Node       Process Name      PID        Terminal
  • No number of processes substring; banner + headings present; no rows.
  • ctest -R dcl-integration -> PASS (was test docs vms-b33: Phase 2 verdict, tenth run -- GO #124, the failing one);
    harness runs both show_users scripts -> both PASS.
  • ctest -R show -> 5/5 pass. QEMU negctl binary exits 77.

🤖 Generated with Claude Code

baron-3dl and others added 2 commits August 28, 2026 13:39
cmd_show_users() printed its banner and the "Total number of users = N,
number of processes = M" summary UNCONDITIONALLY, then returned
SS$_NORMAL, without ever checking whether the process-table scan reached
the executive. With /dev/vms absent the first vms_kif_procscan() cannot
be delivered, process_count stays 0, and the code still printed
"...number of processes = 0" and reported success -- a fabricated
system display with no executive behind it (INV-6 / Rule 9).

Gate all output on the first vms_kif_procscan() status. The executive
answers with SS$_NORMAL (a row) or SS$_NONEXPR (table exhausted); the
bare KIF_CALL transport path returns a kerr_to_ss() code (SS$_BUGCHECK
for a bad-fd ioctl -- NOT SS$_NOSUCHDEV, NOT SS$_NONEXPR) when /dev/vms
is absent. So admit precisely the executive-answered statuses and treat
everything else as "no executive": emit %SYSTEM-W-NOSUCHDEV and return
SS$_NOSUCHDEV before the banner/summary can print. A present-but-empty
table (SS$_NONEXPR) still falls through and prints the honest
0-users/0-processes summary, so the fix does not suppress a legitimate
empty display.

The banner/node/timestamp moved below the guard; the pass-1 loop reuses
the guard's fetched row and re-fetches at the tail (no discarded probe).
No test changes: tests/qemu/test_syssvc_spawn_users.c device_absent
negative control is correct as-is.

Verified: piping "SHOW USERS" into the real DCL.EXE with no /dev/vms now
emits "%SYSTEM-W-NOSUCHDEV, no such device available" and contains no
"number of processes" substring; ctest -R show all pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The first-scan status guard was right to suppress the fabricated count,
but returning SS$_NOSUCHDEV and dropping the banner+headings broke two
host tests (test_show_users_full, test_show_users_terminal) that require
the frame -- and those tests and the QEMU negctl had always contradicted
on one line: the negctl forbids "number of processes" with no executive,
the host test EXPECTed "Total number of users" on the same line.

Adjudication (controlling precedent = SHOW SYSTEM): with no executive,
cmd_show_system prints banner + column headings + NO rows and NO computed
count line. SHOW USERS is the only SHOW command that prints a WALKED
count; a count from a scan that hard-failed is a mild fabrication ("I
enumerated 0" vs "I couldn't enumerate"). So the executive-unreadable
branch now prints the SAME frame SHOW SYSTEM does -- banner + headings
(honouring the bare-vs-/FULL column split), no rows, NO count line -- and
returns SS$_NORMAL. The count line prints only when the table was
readable, INCLUDING readable-but-empty (SS$_NONEXPR -> honest "= 0").

Replaces the NOSUCHDEV-and-return with a `readable` flag gating only the
walk + count line; banner and headings print in both paths; row loops
naturally emit nothing when unreadable.

test_show_users_terminal.sh reconciled to SHOW SYSTEM + the negctl
(a strengthening): drop EXPECT contains:Total number of users, add
EXPECT_NOT contains:number of processes; all other assertions unchanged;
header comment records why. test_show_users_full.sh unchanged (passes).
QEMU negctl unchanged.

Verified: ctest -R dcl-integration GREEN (was test #124, failing);
ctest -R show 5/5; device-absent SHOW USERS prints banner + Username/Node/
Interactive headings, no "number of processes", no rows; SHOW USERS/FULL
prints Process Name/Terminal headings, no Interactive, no rows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@baron-3dl
baron-3dl merged commit d08a8d7 into main Aug 28, 2026
96 checks passed
baron-3dl added a commit that referenced this pull request Aug 28, 2026
…ce parity, SHOW USERS de-fab (#858)

Bumps OVMX_PRODUCT_VERSION and os-release V0.5-7 -> V0.5-8. 14 commits since V0.5-7.

Distributed Lock Manager — the cross-node ladder tops out at a real GRANT:
  - #849 vms-e8f1/vms-17c  DLM rung-2 (H4): the first REAL cross-node $ENQ GRANT
                           — node B holds a lock on A's behalf for A's CSID,
                           $ENQ returns SS$_NORMAL over live SCS (no longer
                           INV-6 "grants nothing"). The distributed lock
                           manager now actually locks across nodes.
  - #845 vms-209          DLM harness H3 — a cross-node $ENQ reaches node B's
                           real executive
  - #843 vms-4bd0         DLM harness H2 — two real-executive QEMU nodes
                           complete the full VMS$VAXcluster join
  - #842 vms-534          DLM harness H1 — two real-executive nodes exchange
                           the 0x6007 HELLO over a socket netdev
  - #840 vms-4b6          DLM harness rung H0 — SCSD.EXE composes with a real
                           executive
  - #841 docs             Alpha cross-node DLM wire oracle — observed SCS
                           transport + documented GRANT semantics (Rule 8)

Alpha co-release parity — authenticated login + the shared SHOW battery:
  - #852 vms-f2c          Alpha DCL/SHOW acceptance parity — the same shared
                           11-command battery x86_64 runs, now on
                           qemu-system-alpha
  - #847                  vms.ko guards BG fork-inherit tracepoints behind
                           CONFIG_TRACEPOINTS (Alpha P0 modpost fix)

Authenticity (INV-6 de-fabrication):
  - #839 vms-6a1          SHOW USERS fails honestly when the executive is
                           absent — no more per-process fabricated user list

Boot console fidelity:
  - #850 vms-dec          kill boot-console newline spam (the operator's echoed
                           RETURNs) + a type-during-boot regression gate

Networking (layered-product promotion):
  - #851 vms-67f          TCP/IP Services promoted to a first-class layered
                           product — build plan + roadmap (1.0 blocker)

Docs / ledger:
  - #745                  Alpha C-RTL archive DECIDED — Option A (operator
                           ruling 2026-08-23)
  - #709 vms-da0          OpenVMS GCC port × OVMX faithful-surface gap analysis
  - #838                  reconcile the release block for the V0.5-7 tag
                           (INV-LEDGER)

QA'd under KVM boot-to-login on the workshop host with the full SHOW
acceptance battery VMS-faithful; boot console clean (no newline flood) and
SHOW USERS honest. Release notes are generated at tag time by
tools/gen_release_notes.py (INV-LEDGER single-ledger); the roadmap narrative
block + public site are the conductor's reconcile (INV-0/INV-LEDGER).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant