Conversation
Governing rule: what would VMS do? SYSBOOT loads the executive before any
process exists, so VMS is NEVER in the state where a running system has no
executive. The deliverable is therefore a GUARANTEE, not an error path -- a
handled-but-impossible-on-VMS state is itself an authenticity defect.
Before this change, ovmx_init printed severity W ("%STARTUP-W-MODFAIL") when
vms.ko would not load and booted on to a full DCL session with no executive
at all, while the system services each returned SS$_NOSUCHDEV per call. That
status encoded "OVMX runs, minus the executive" -- a system that does not
exist. It failed politely rather than honestly.
Guarantees established:
BOOT IS FATAL. PID 1 loads vms.ko and opens /dev/vms before anything runs
(executive_attach); if either fails it reports %STARTUP-F-NOEXEC /
%STARTUP-F-NOBOOT and powers the machine off. No image can run without the
executive, which is what makes the per-call paths unreachable.
THE EXECUTIVE IS PINNED. PID 1 holds the descriptor for the life of the
system. vms_fops already carries .owner = THIS_MODULE, so that descriptor
holds a module reference and rmmod is refused while OVMX runs. Mid-life
loss is prevented, not responded to.
Consequently the fallbacks are DELETED, not corrected: sys_lock.c's
ensure_kif_open() (both return sites, plus its "Docker mode" framing, a Rule
9 violation) and vms_kif.c's absent-fd guard. SS$_NOSUCHDEV keeps its real
meaning elsewhere -- a caller named a VMS device that does not exist.
Docs and gate corrected, since both taught the superseded rule to every cold
agent: docs/design-executive-retrofit.md section 3 constraint 2, and
test_runtime_target.sh, whose check-3 exemption waved through any file merely
CONTAINING the string "SS$_NOSUCHDEV". Two positive checks replace it.
Tests (all run against the real kernel/QEMU runtime, per Rule 9):
tests/qemu/test_executive_integral.sh -- boots the real runtime with the
executive, then again with vms.ko removed from the initramfs; the second
boot must produce no banner, no login prompt, no completed startup. That
negative control is what proves the check can go red.
tests/qemu/test_kmod_pin.c -- an open descriptor pins vms.ko and rmmod is
refused for being in use.
The dead-legacy container's boot smoke test now asserts the refusal instead
of asserting a successful executive-less boot; install-skip is covered on the
real runtime by persistent-boot Boot 2, so no coverage is lost.
OVMX DESIGN CHOICE (Rule 8): %STARTUP-F-NOEXEC and %STARTUP-F-NOBOOT are
OVMX's own mnemonics, labelled as such in the source. VMS has no message for
"the executive vanished" because it is never in that state. An earlier wave
invented %SYSBOOT-F-LDFAIL and the oracle disproved it; nothing here is
presented as VMS-authentic.
Verified with podman: persistent-boot 12/12; executive-integral 9/9; kernel
executive 11 suites passed / 0 failed; negative control exactly 3 passed /
8 failed; ctest 40/40; Rule 9 gate PASS.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… (vms-0ff) The UAT SSHed into the dead-legacy Docker container on port 2222. That container has no /dev/vms, so the session it certified was a full interactive VMS login running with NO EXECUTIVE -- the exact state epic vms-6b8 exists to make unreachable. Once PID 1 began refusing to boot without an executive, the job could not pass, and it should not have: it was user-acceptance-testing a system OVMX no longer claims to be. The tempting fix -- exempt the container so the existing harness keeps working -- is the architecture drifting to fit the test harness, which is precisely what Rule 9 was written against. So the UAT moves to the runtime OVMX actually has: boot the real kernel under QEMU, log in over the console, drive DCL there. tests/uat/vms_session_qemu.sh runs the SAME command list and the SAME 13 assertions as the SSH script. Nothing was relaxed to make the new substrate pass; verified 13 passed / 0 failed with podman against the real runtime. Sequencing waits on the actual console prompts rather than sleeping a guessed number of seconds, and fails fast with the console dump if the guest dies or a prompt never arrives. A UAT paced by fixed sleeps is a flaky test waiting to happen, and a flaky test is a broken test (Rule 11). KNOWN COVERAGE GAP, recorded rather than hidden: driving DCL over the console does not exercise vmssshd, so SSH login is no longer covered end-to-end. The old job was its only live coverage (ctest's vmsssh_integration is skipped). tests/uat/vms_session_test.sh is retained unchanged for when the SSH path is brought up on QEMU with hostfwd; a follow-up item tracks that. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… all (vms-0ff)
The residual research question -- what VMS actually prints when a required
executive image will not load at bootstrap -- is ANSWERED, and the answer
changes this code rather than merely confirming it.
Observed on the reference lab's OpenVMS VAX V7.3 (~/vax/cluster, node VAX2,
2026-07-29) by renaming SYS$COMMON:[SYS$LDR]EXCEPTION.EXE aside and cold
booting `B/R5:10000000 DUA0`:
%EXECINIT, error loading system file - EXCEPTION.EXE R0 = 00000910
?06 HLT INST
PC = 871306A6
>>>
The machine HALTS -- no degraded boot, no bugcheck, no crash dump. Capture
archived at captures/vax2-execinit-missing-exception-2026-07-29.log; the
rename was verified reversible before the experiment and the system booted
cleanly afterwards.
So OVMX's fail-stop boot is not an OVMX invention. It is what VMS does, and
the message is now modelled on the observed one instead of on the invented
%STARTUP-F-NOEXEC / %STARTUP-F-NOBOOT pair. Four properties are reproduced
deliberately because they are the authenticity tells: the facility is
EXECINIT, not SYSBOOT; there is NO severity letter and NO mnemonic; the image
is a BARE FILENAME; the status is printed raw as "R0 = " + 8 hex digits.
This also independently re-disproves the earlier wave's %SYSBOOT-F-LDFAIL:
the complete VAX 7.3 SYSBOOT message set (HELP/MESSAGE/FACILITY=SYSBOOT, ~48
entries) has no such mnemonic. Useful corroboration from vendor-shipped docs:
SYSBOOT-E-I/O error reading file states that if the error occurred reading a
system loadable image, "SYSBOOT terminates the bootstrap operation".
STILL LABELLED OVMX DESIGN CHOICES (Rule 8), because VMS has no analogue: the
%OVMX-I-EXECINIT line carrying the underlying Linux error (VMS prints nothing
more -- "?06 HLT INST" is VAX console firmware, which OVMX has no equivalent
of), and reporting /dev/vms failing to OPEN in the same shape with no R0,
since a VMS executive has no device node.
NOT SILENTLY FIXED: R0 = 00000910 decodes via F$MESSAGE to
%SYSTEM-W-NOSUCHFILE, while in-tree ssdef.h defines SS$_NOSUCHFILE as 2696
(0xA88). That drift is real, is tracked (vms-556 / vms-c90, alongside
SS$_NOSUCHDEV 2680 vs the oracle's 2312), and needs OPERATOR SIGN-OFF -- a VMS
constant is never self-certified. The observed value is used here only to
reproduce an observed console line, and says so at its definition.
Re-verified after the change: executive-integral 8/8 (now asserting the
EXECINIT facility AND the R0 status, so a lookalike message cannot pass);
UAT on the real runtime 13/13; the dead-legacy container refuses with the
authentic shape and exits 1; Rule 9 gate PASS.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Update: the boot-failure message is now oracle-pinned — and the design turned out to be VMS-authenticThe residual research question this PR left open ("what does VMS actually print when a required executive image will not load?") is answered, and it changed the code ( Observed on The machine halts. No degraded boot, no bugcheck, no crash dump. Capture archived at So OVMX's fail-stop boot is not an OVMX invention — it is what VMS does. The message is now modelled on the observed one instead of the invented This also re-disproves the earlier Still labelled OVMX design choices (Rule 8)The Deliberately not fixed here
Three follow-ons remain open and are recorded in vms-c88 — most importantly whether VMS has a degraded-boot class for non-required images, which would mean OVMX's all-or-nothing gate is too coarse. It was not attempted because a second session was driving the same lab concurrently and the risk was leaving the oracle unbootable. Re-verified after the changeCI green by SHA |
⛔ HOLD — do not merge until SSH-on-QEMU landsOperator ruling, 2026-07-30. This PR is correct but it regresses a capability people actually use, and it must not merge until the replacement exists. What merging this would break today:
Net effect: the only interactive OVMX left would be a QEMU serial console. That is a real loss, and filing it as a follow-up (vms-2449) while merging was the wrong call. Condition for lifting the hold: SSH works against the QEMU runtime (guest networking + Rule 9 stays intact — the fix is SSH on the real runtime, not exempting the container from the executive gate. |
…AT actually works (vms-71a) (#10) * ci vms-71a: migrate Docker-based CI jobs off the dead root Dockerfile, delete it CLAUDE.md Rule 9 retired the Docker RUNTIME layer (operator ruling 2026-07-28). This finishes the migration blocking that ruling: - Delete the docker-build job outright. It built the retired glibc product container and ran a SHOW TIME smoke test + install-skip smoke test. SHOW TIME is already covered natively by tests/dcl/test_show_time.sh via the dcl-integration ctest target (build-and-test job); install-skip is covered on the real runtime by the persistent-boot job's Boot 2. No coverage lost. - conformance / corpus-conformance: these never ran the product image, only the root Dockerfile's disposable "builder" stage (cmake+gcc). Reproduced with a plain ubuntu:24.04 tooling container (repo bind-mounted at /src) instead -- Rule 9 permits Docker as build/test tooling, just not as a runtime. Verified locally with podman: conformance's 9/9 VMS programs compile and pass under the new job exactly as before. - uat-session: migrated from Docker+SSH (port 2222, the dead container) to distro/Dockerfile.bootable + QEMU console, using tests/uat/vms_session_qemu.sh (same 13 assertions, same command list as the SSH script -- adapted here to wait on the login prompt that already exists on this branch, since the boot-time executive marker vms-0ff added is not yet merged). Known, tracked coverage gap: SSH login itself has no CI coverage now that its only runtime is gone; tests/uat/vms_session_test.sh is retained for when SSH-on-QEMU exists (currently not planned -- vms-02d was cancelled). - Delete Dockerfile and docker-compose.yml. tests/integration/ test_runtime_target.sh (the Rule 9 gate) needed no edit -- it was written so file-absence is the pass state; confirmed via ctest (40/40 pass, 1 skip, runtime_target_gate passes). Coordinates with vms-a35 (PR #6 rebase): PR #6's docker-build smoke test was rewritten there into a boot-refusal witness for the (unmerged) executive-integral work. That step is deleted here along with the whole job, per operator ruling 2026-07-30 ("docker was cooked... pretty shit that you still have it around") -- it is not ported anywhere; the same property is proven on the real runtime by tests/qemu/test_executive_integral.sh. vms-71a * vms-71a: prove tests/uat/vms_session_qemu.sh actually works, fix its rigor Re-dispatch findings addressed (veracity adversary confirmed all four): 1. Actually ran the script (podman build -f distro/Dockerfile.bootable + podman run --entrypoint bash .../test.sh) on this host, repeatedly. 13/13 assertions pass, ~11-14s end to end. It had never been executed before -- bash -n is not coverage. 2. Disclosed provenance: this script is derived from origin/vms-0ff-executive-fatal:tests/uat/vms_session_qemu.sh, with the `wait_for '%STARTUP-I-EXEC'` wait deliberately dropped and the drop explained in a comment at that exact spot (that marker only exists on vms-0ff-executive-fatal's ovmx_init.c, not on main). 3. Fixed the three echo-satisfiable assertions (SYS$MANAGER, session_test_ passed, SYSTEM) plus a fourth found during rework (HELP SHOW): each command's own response is now captured into CMD_OUTPUT[cmd] by tracking byte offsets and stripping the guest tty's echo of the input line, and check_response() asserts against that captured response instead of grepping the whole console log (which also contains every command's own echo). Proven to actually distinguish real failure from vacuous pass: with the fix in place, the run genuinely caught a pre-existing DCL bug (SET DEFAULT SYS$MANAGER, no colon, fails -- see vms-dd9) that the old whole-log check could never have caught. Fixed by using the syntax proven to work (SYS$MANAGER:) rather than papering over an unrelated, out-of-scope defect. 4. Replaced the 16 fixed `sleep 0.4` calls with synchronisation on the actual DCL prompt ('$ ') reappearing in the bytes appended since each command was sent. Split BOOT_TIMEOUT/STEP_TIMEOUT/COMMAND_TIMEOUT/ SESSION_TIMEOUT so a slow boot can no longer silently consume the command-loop budget (previously BOOT_TIMEOUT double-duty'd as both the QEMU wall-clock kill switch and the login-wait budget). Negative checks now scan a strictly wider surface (whole console log, including boot log) which can only catch more real Unix leaks, never manufacture false ones (none of the leak strings are ones this script sends). Positive checks now scan post-login-only session output where still using a broad grep, narrowing the surface relative to before. * vms-71a: stop documenting the deleted Docker runtime as a way to run OVMX Rule 9 says do not document Docker as an OVMX runtime; these files still told readers to run the container this branch deletes: - README.md:54-63 documented `docker compose up --build` + SSH on 2222 as a way to run OVMX, naming a compose file that no longer exists. - docs/building.md:19 installed docker-compose-v2 for it; :63-73 gave full "Docker Container ... Full runtime" instructions. - docs/architecture.md:19-20 listed [Dockerfile, docker-compose.yml] as the System Integration layer; the Boot Sequence had a full "Docker Mode" section walking through `docker compose up --build`. - .claude/profiles/implementer.md:32-38 told every future implementer their build+test and compile-only-check commands were `docker compose --profile dev run` and `docker build -t ovmx-test:latest .` -- both now impossible since there is no root Dockerfile. - CLAUDE.md:178-179 listed the two files as present-and-pending-removal in the repo tree (they're gone); :236-239 described them as "retained because CI still depends on them" (it no longer does). Left untouched (out of scope): the pre-existing `docker build -f Dockerfile.bootable -o dist .` path in README.md/CLAUDE.md, which should read `distro/Dockerfile.bootable` -- a pre-existing typo unrelated to this migration, flagged in findings. * vms-71a: close the vacuous-assertion gap the round-2 fix missed Round-2 fixed the two assertions the round-1 adversary named, but left two vacuous check_regex whole-log scans in place with inline comments falsely certifying them as "not echo-satisfiable". Applying the binding mutation method (prefix each driven command with a bogus verb so DCL returns %DCL-E-IVVERB and no real output can appear; confirm the assertion then fails; restore and confirm it passes) to every positive assertion, not just the two named: - SHOW PROCESS /PRIVILEGES: check_regex('...|PRIV') was satisfied by the echo of the command itself (PRIV is a substring of "PRIVILEGES"). Replaced with check_response anchored to the command's own captured response, dropping the PRIV alternative. - SHOW TERMINAL: check_regex('...|_[A-Z]') was doubly satisfied by the echo alone -- case-insensitive grep matched 'Terminal' in the echoed command text, and '_[A-Z]' matched UAT_TEST/_OPA0: echoes elsewhere in the log. Replaced with an anchored check_response, dropping _[A-Z]. - SHOW TIME (found by re-deriving the property, not named in either challenge round): the whole-log date-format regex was satisfied by LOGOUT's own "logged out at 1-JAN-1970 ..." message even when SHOW TIME was rejected outright. Replaced with an anchored check_response. Removed check_contains()/check_regex(), the two whole-log positive- assertion helpers now with zero call sites -- they were the mechanism behind every vacuous check found this round, and leaving them in place is a footgun for the next edit. check_not_contains() (negative/leak checks) is untouched: those patterns are never typed by this script, so a whole-log scan cannot manufacture a false pass. All 7 positive assertions were mutation-tested individually against the real QEMU runtime (podman + qemu-system-aarch64, TCG, no /dev/kvm) and each was confirmed to flip PASS->FAIL when its driving command is broken by DCL, then confirmed to pass again unmutated. Unmutated run: 13/13, stable across 4 repeated runs. Also fixes the residual doc straggler from the round-3 ruling: .claude/agents/implementer.md:16 told every future implementer to run `docker-compose up`, a file this branch deletes.
Third rebase of PR #6. main advanced to 00f426c (vms-8019, "Executive-resident process table", PR #12). src/libvmssys/vms_kif.c auto-merged clean: vms-8019's new SETPRN/GETJPI/PROCSCAN wrappers carry no vms_dev_fd absence guard, so nothing this branch deletes came back. The one conflict is the kernel-executive negative-control literal in ci.yml, and the textual merge of it was WRONG in a way that would have silently weakened the control. Both branches independently moved the executive-absent split from "3 passed, 7 failed" to "3 passed, 8 failed" -- main by adding test_kmod_procnam, this branch by adding test_kmod_pin, both executive- dependent. Merged, BOTH suites exist, so the real split is 3 passed / 9 failed. Taking either side verbatim would have left a stale 8 that no longer describes reality; a stale count here is exactly the silent weakening the control exists to prevent. Resolved to 9, and the comment now records the arithmetic and the per-item history so the next merge sees the trap coming.
…persedes PR #6) (#14) * The executive is integral: OVMX must not boot without it (vms-0ff) Governing rule: what would VMS do? SYSBOOT loads the executive before any process exists, so VMS is NEVER in the state where a running system has no executive. The deliverable is therefore a GUARANTEE, not an error path -- a handled-but-impossible-on-VMS state is itself an authenticity defect. Before this change, ovmx_init printed severity W ("%STARTUP-W-MODFAIL") when vms.ko would not load and booted on to a full DCL session with no executive at all, while the system services each returned SS$_NOSUCHDEV per call. That status encoded "OVMX runs, minus the executive" -- a system that does not exist. It failed politely rather than honestly. Guarantees established: BOOT IS FATAL. PID 1 loads vms.ko and opens /dev/vms before anything runs (executive_attach); if either fails it reports %STARTUP-F-NOEXEC / %STARTUP-F-NOBOOT and powers the machine off. No image can run without the executive, which is what makes the per-call paths unreachable. THE EXECUTIVE IS PINNED. PID 1 holds the descriptor for the life of the system. vms_fops already carries .owner = THIS_MODULE, so that descriptor holds a module reference and rmmod is refused while OVMX runs. Mid-life loss is prevented, not responded to. Consequently the fallbacks are DELETED, not corrected: sys_lock.c's ensure_kif_open() (both return sites, plus its "Docker mode" framing, a Rule 9 violation) and vms_kif.c's absent-fd guard. SS$_NOSUCHDEV keeps its real meaning elsewhere -- a caller named a VMS device that does not exist. Docs and gate corrected, since both taught the superseded rule to every cold agent: docs/design-executive-retrofit.md section 3 constraint 2, and test_runtime_target.sh, whose check-3 exemption waved through any file merely CONTAINING the string "SS$_NOSUCHDEV". Two positive checks replace it. Tests (all run against the real kernel/QEMU runtime, per Rule 9): tests/qemu/test_executive_integral.sh -- boots the real runtime with the executive, then again with vms.ko removed from the initramfs; the second boot must produce no banner, no login prompt, no completed startup. That negative control is what proves the check can go red. tests/qemu/test_kmod_pin.c -- an open descriptor pins vms.ko and rmmod is refused for being in use. The dead-legacy container's boot smoke test now asserts the refusal instead of asserting a successful executive-less boot; install-skip is covered on the real runtime by persistent-boot Boot 2, so no coverage is lost. OVMX DESIGN CHOICE (Rule 8): %STARTUP-F-NOEXEC and %STARTUP-F-NOBOOT are OVMX's own mnemonics, labelled as such in the source. VMS has no message for "the executive vanished" because it is never in that state. An earlier wave invented %SYSBOOT-F-LDFAIL and the oracle disproved it; nothing here is presented as VMS-authentic. Verified with podman: persistent-boot 12/12; executive-integral 9/9; kernel executive 11 suites passed / 0 failed; negative control exactly 3 passed / 8 failed; ctest 40/40; Rule 9 gate PASS. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Move the UAT onto the real runtime instead of weakening the boot gate (vms-0ff) The UAT SSHed into the dead-legacy Docker container on port 2222. That container has no /dev/vms, so the session it certified was a full interactive VMS login running with NO EXECUTIVE -- the exact state epic vms-6b8 exists to make unreachable. Once PID 1 began refusing to boot without an executive, the job could not pass, and it should not have: it was user-acceptance-testing a system OVMX no longer claims to be. The tempting fix -- exempt the container so the existing harness keeps working -- is the architecture drifting to fit the test harness, which is precisely what Rule 9 was written against. So the UAT moves to the runtime OVMX actually has: boot the real kernel under QEMU, log in over the console, drive DCL there. tests/uat/vms_session_qemu.sh runs the SAME command list and the SAME 13 assertions as the SSH script. Nothing was relaxed to make the new substrate pass; verified 13 passed / 0 failed with podman against the real runtime. Sequencing waits on the actual console prompts rather than sleeping a guessed number of seconds, and fails fast with the console dump if the guest dies or a prompt never arrives. A UAT paced by fixed sleeps is a flaky test waiting to happen, and a flaky test is a broken test (Rule 11). KNOWN COVERAGE GAP, recorded rather than hidden: driving DCL over the console does not exercise vmssshd, so SSH login is no longer covered end-to-end. The old job was its only live coverage (ctest's vmsssh_integration is skipped). tests/uat/vms_session_test.sh is retained unchanged for when the SSH path is brought up on QEMU with hostfwd; a follow-up item tracks that. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Pin the boot-failure message to the oracle: it is VMS-authentic after all (vms-0ff) The residual research question -- what VMS actually prints when a required executive image will not load at bootstrap -- is ANSWERED, and the answer changes this code rather than merely confirming it. Observed on the reference lab's OpenVMS VAX V7.3 (~/vax/cluster, node VAX2, 2026-07-29) by renaming SYS$COMMON:[SYS$LDR]EXCEPTION.EXE aside and cold booting `B/R5:10000000 DUA0`: %EXECINIT, error loading system file - EXCEPTION.EXE R0 = 00000910 ?06 HLT INST PC = 871306A6 >>> The machine HALTS -- no degraded boot, no bugcheck, no crash dump. Capture archived at captures/vax2-execinit-missing-exception-2026-07-29.log; the rename was verified reversible before the experiment and the system booted cleanly afterwards. So OVMX's fail-stop boot is not an OVMX invention. It is what VMS does, and the message is now modelled on the observed one instead of on the invented %STARTUP-F-NOEXEC / %STARTUP-F-NOBOOT pair. Four properties are reproduced deliberately because they are the authenticity tells: the facility is EXECINIT, not SYSBOOT; there is NO severity letter and NO mnemonic; the image is a BARE FILENAME; the status is printed raw as "R0 = " + 8 hex digits. This also independently re-disproves the earlier wave's %SYSBOOT-F-LDFAIL: the complete VAX 7.3 SYSBOOT message set (HELP/MESSAGE/FACILITY=SYSBOOT, ~48 entries) has no such mnemonic. Useful corroboration from vendor-shipped docs: SYSBOOT-E-I/O error reading file states that if the error occurred reading a system loadable image, "SYSBOOT terminates the bootstrap operation". STILL LABELLED OVMX DESIGN CHOICES (Rule 8), because VMS has no analogue: the %OVMX-I-EXECINIT line carrying the underlying Linux error (VMS prints nothing more -- "?06 HLT INST" is VAX console firmware, which OVMX has no equivalent of), and reporting /dev/vms failing to OPEN in the same shape with no R0, since a VMS executive has no device node. NOT SILENTLY FIXED: R0 = 00000910 decodes via F$MESSAGE to %SYSTEM-W-NOSUCHFILE, while in-tree ssdef.h defines SS$_NOSUCHFILE as 2696 (0xA88). That drift is real, is tracked (vms-556 / vms-c90, alongside SS$_NOSUCHDEV 2680 vs the oracle's 2312), and needs OPERATOR SIGN-OFF -- a VMS constant is never self-certified. The observed value is used here only to reproduce an observed console line, and says so at its definition. Re-verified after the change: executive-integral 8/8 (now asserting the EXECINIT facility AND the R0 status, so a lookalike message cannot pass); UAT on the real runtime 13/13; the dead-legacy container refuses with the authentic shape and exits 1; Rule 9 gate PASS. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Stop wearing the EXECINIT facility for conditions VMS never faces (vms-a35) Round-2 adversary finding: execinit_halt()'s no-R0 branch printed a bare "%EXECINIT, error loading system file - VMS.KO" for two conditions the oracle capture never produces one for -- a module-load errno other than the pinned ENOENT, and /dev/vms (a Linux device node; VMS has no such thing) refusing to open. The oracle's %EXECINIT line always carries "R0 = "; a bare one is an invented VMS message wearing a VMS facility name for a condition VMS is never in (Rule 10's illegal third answer), and the function's own detail line already knew this (%OVMX-I-EXECINIT). Split execinit_halt() into two functions along that line: - execinit_halt(): the oracle-pinned path only, byte-exact, unchanged. - ovmx_exec_halt(): the not-oracle-pinned path, reporting through %OVMX-F-EXECINIT instead -- an OVMX event, not a VMS one. Both call sites in executive_attach() route through the correct one now. The success line moved for the same reason: "%STARTUP-I-EXEC, VMS executive attached on /dev/vms" named a Linux device node under a VMS facility. It is now "%OVMX-I-EXEC, ...". Updated both consumers (tests/uat/vms_session_qemu.sh's wait_for, test_executive_integral.sh's Boot A check) and the design doc. Added Boot C to test_executive_integral.sh: vms.ko loads successfully (a substitute module -- vmsfs.ko's own binary, built by the same Dockerfile stage -- that registers no /dev/vms) but /dev/vms never appears, proving the second reachable half of executive_attach()'s fatal path. Previously only Boot B (module missing entirely) was covered; the /dev/vms-absent path was reachable and had zero coverage. distro/Dockerfile.bootable now builds the NODEV initramfs alongside NOEXEC. Verified on real aarch64 QEMU under TCG (podman build RC=0): test_executive_integral.sh 14/14 (Boot A 4, Boot B 5, Boot C 5), and tests/uat/vms_session_qemu.sh 13/13 against the renamed %OVMX-I-EXEC wait. * Make the Rule 9 gate's checks 3b/3c behavioural, not token-presence (vms-a35) Round-2 adversary finding: both checks could be walked through without touching the guarantee they claim to enforce. Check 3b grepped ovmx_init.c for the literal strings "executive_attach", "execinit_halt" and "/dev/vms" appearing ANYWHERE in the file -- so executive_attach() could be reduced to a no-op (open /dev/vms and close it right back, drop the halt-on-failure branch) and still pass, because the tokens survive elsewhere in the file (e.g. execinit_halt's own definition). Replaced with a structural check against the extracted body of executive_attach() itself: it must open "/dev/vms" into a variable, check that variable for failure, reach a halt/exit/reboot call, and never close the descriptor again in the function. Check 3c only matched vms_kif_open() when an operator sat directly after the call, or the call appeared inside if/while parens -- so int rc = vms_kif_open(); if (rc < 0) return SS$_NOSUCHDEV; evaded it entirely (the call is assigned to a variable first; no operator follows it, and it isn't inside the if's parens). Added a second pass that, for every "var = vms_kif_open()" capture in a file, searches the rest of that file for the variable being branched on or compared. Both strengthened checks were proven by writing the exact evading refactor, confirming the gate went RED, then reverting and confirming PASS again: - sys_lock.c: (void)vms_kif_open(); -> int rc = vms_kif_open(); if (rc < 0) return; => gate FAILED on "variable 'rc' captures vms_kif_open() and is branched on later"; reverted => PASS. - ovmx_init.c: executive_attach() reduced to open-probe-fd/close/ printf, no halt call => gate FAILED on all three missing properties (no failure check, no halt/exit/reboot, fd closed); reverted => PASS. * Rule 9 gate: assert the halt is IN the failure branch, and check in the evasions (vms-a35) The gate twice certified the exact regression it exists to prevent, because each assertion was satisfiable by something other than the behaviour under test. check 3b. Property (c) grepped the WHOLE extracted body of executive_attach() for any halt/exit/reboot token, so it was satisfied by the unrelated execinit_halt() in the module-load-ENOENT branch. Replacing the /dev/vms halt with `fprintf("%OVMX-W-EXEC, continuing without executive"); return;` -- verbatim the silent fallback Rule 9 forbids -- left the gate printing "OK: executive_attach() opens /dev/vms, halts on failure, holds it open" over code that boots straight past a missing executive to a login prompt. Now the failure branch for the open descriptor is EXTRACTED (character-level brace/semicolon tracking, comments stripped) and the halt must be inside it, with nothing that returns to the caller ahead of it. Split into five named properties: capture, failure branch, halt-in-branch, no-escape-before-halt, never-closed. check 3c. The indirect pass recognised only if/while as branch contexts, and its comparison alternative could not match >= or <= AT ALL: the `>` matched, the whitespace class matched empty, then the digit class was asked to match the `=`. So `int rc = vms_kif_open(); return rc >= 0 ? 0 : -1;` -- the ensure_kif_open() body Rule 9 deleted, merely hoisted into a variable -- and `switch (rc)` both sailed through. Operator set is now < > <= >= == !=, and the branch contexts are if/while/switch, ternary, &&, ||, ! and return. tests/integration/test_runtime_target_negctl.sh is new and registered in ctest. It applies each recorded evasion to a sandbox copy and requires the gate to go RED for that evasion's own specific reason. It enforces on itself the rule that made the round-2 hole invisible: EVERY property gets a MINIMAL mutation that trips THAT property AND NO OTHER. Round 2's "proof" deleted the whole function body, tripping all properties at once, which proves nothing about any one of them -- so each case here also asserts the other properties' reasons do NOT appear. A positive control runs first, so a RED can be attributed to the mutation rather than to a broken sandbox. No test deleted, skipped or weakened; this is additive. * Kernel-executive harness: a 10-suite failure was reported as ALL TESTS PASSED (vms-a35) tests/qemu/run_tests.sh decided pass/fail with grep -q "FINAL RESULTS:.*0 suites failed" which is satisfied by the trailing zero of ANY count ending in zero. Latent since the harness was written; the vms-a35 merge product is the first tree that fires it, because vms-8019's test_kmod_procnam, vms-0ff's test_kmod_pin and vms-d0b's test_kmod_devtab together push the executive-absent failure count to 10. Observed, not reasoned about: the negative-control image printed "=== FINAL RESULTS: 3 suites passed, 10 suites failed ===" and then "ALL KERNEL MODULE TESTS PASSED", exiting 0. Both directions of the Phase-0 barrier were broken by it: - the positive kernel-executive job would have gone GREEN with 10 real executive failures -- the entire facility silently untested, which is precisely the drift the job exists to detect; - the negative-control job asserts a NONZERO exit, so it would have gone RED with "expected the harness to fail, but it exited 0" -- a red for the wrong reason, which trains people to re-run rather than read. Requiring the zero to stand alone ([^0-9]0) fixes both. Verified across 0/1/9/10/20/100: only 0 is green, and the old pattern was green for 0, 10, 20 and 100. Re-ran the real harness afterwards: negative control now exits 1 with "KERNEL MODULE TESTS FAILED" at 3 passed / 10 failed, and the positive suite still exits 0 at 13 passed / 0 failed. No test deleted, skipped or weakened -- this restores failure detection the harness had lost. * Rule 9 gate 3b: assert the failure branch is TERMINAL, not that a halt token precedes a return (vms-a35) Round 3 implemented only half of the settling condition. Check 3b(c)/(d) was a TOKEN-ORDER check: (d) compared the byte offset of the first return/goto against the first halt token, and never asserted the branch could not return to the caller. Five one-hunk mutations of executive_attach() were all CERTIFIED with "OK: executive_attach() ... halts inside the open-failure branch" / EXIT=0, and each boots PID 1 to a login prompt with no executive: 1. if (getenv("OVMX_ALLOW_NO_EXEC") == NULL) ovmx_exec_halt(...); fprintf("%OVMX-W-EXEC, continuing without executive"); -- Rule 9's warn-and-continue and Rule 10's env-var bridge in one hunk 2. if (errno != ENODEV) ovmx_exec_halt(...); -- survives one errno 3. ovmx_exec_halt_reason(...); -- (c)'s regex matched any identifier containing "halt"; nothing checked the callee 4. ovmx_exec_halt(...); fprintf("carrying on"); -- halt is not last 5. ovmx_exec_halt() itself gutted to an fprintf -- a halt that returns 3b now reads control flow structurally instead of searching for tokens. New helpers: strip_comments, func_body, last_top_stmt (brace/paren-depth statement splitter) and bare_call_name. Two new properties: (f) TERMINALITY -- the failure branch's LAST TOP-LEVEL statement must be a bare, unconditional call to a recognised halt entry point. A halt nested in a condition, or followed by any statement, leaves a path out. (g) the entry point must really end the system, re-derived from the source: the call chain must bottom out in _exit/exit/abort/reboot AND contain no `return` at any level, so the escape hatch cannot just move one frame down into halt_now(). (h) the pinned names are reserved -- a `#define ovmx_exec_halt(w, d) fprintf(...)` would otherwise reduce (f)/(g) to a spelling test. Check 3c: the indirect pass ended with `grep -vE '=[[:space:]]*vms_kif_open'`, meant to skip the assignment but discarding the whole LINE, so any line carrying both the capture and the use was invisible. Round 3 fixed the multi-line FORMATTING of the class, not the class -- all three shapes walked through when written on one line: int rc = vms_kif_open(); if (rc < 0) { } int rc = vms_kif_open(); (void)(rc >= 0 ? 0 : -1); int rc = vms_kif_open(); switch (rc) { case -1: break; default: break; } The exclusion is now textual: only the `<x> = vms_kif_open()` fragment is blanked, and the rest of the line is still scanned. test_runtime_target_negctl.sh gains 7 recorded controls (10 -> 20 cases, all passing): 3b(f-i..iv), 3b(g-ii), 3b(h), and 3c(v..vii). Each trips its own property and asserts every other property's reason is ABSENT, so a mutation that goes red for the wrong reason fails the suite. Product code is unchanged; this commit is gate-only. No test deleted, skipped or weakened. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Superseded by #14, which is merged to main as c710eb5. Closing — no work and no review history is lost. Why this was closed rather than un-held and merged in place: main advanced four times while this branch was being brought current (#9 The hold on this PR was VOID, not satisfied. It named exactly one lifting condition — "SSH works against the QEMU runtime … and the UAT drives a VMS session over it." SSH-on-QEMU was cancelled as a show horse ( What review added on top of what was here:
Known residuals are filed, not hidden: |
…t; toolchain builds it byte-identical twice (#470) MMK.EXE now drives the PLAN for a real multi-translation-unit OVMX component — the freestanding runtime (src/libvmssys vms_string/vms_snprintf/vms_math + a driver), described by the committed MMS descrip.mms tests/toolchain/component/ OVMXRT.MMS: four TCC compiles, a LIBRARIAN archive, a LINK, in dependency order, byte-identical across two runs. Zero bash in the plan — MMK drives it. This is spine #4's single-TU parse proof scaled to a real multi-TU + library component. The OVMX-native LIBRARIAN.EXE + LINK.EXE build that component's .OLB and image BYTE-IDENTICALLY across two independent builds (cmp clean) on the real component objects, with selective member pull (2 of 3 members). LIBRARIAN zeroes the ar mtime/uid/gid fields; with TCC.EXE's proven compile determinism (run_tcc_selfhost gen2==gen3), the whole TCC->LIBRARIAN->LINK chain is reproducible — the byte-identical-twice bar for the build OUTPUT. New host ctests (both green): toolchain-mmk-component-plan (MMK_EXE) and toolchain-mmk-component-build (LIBRARIAN/LINK/OVMXDUMP on the real objects). Residual gap (spine #6, vms-d1b, the CI gate): MMK's mailbox-driven DCL EXECUTION of the plan requires a real /dev/vms (QEMU); that + first-ever TCC-in-QEMU, toolchain staging into the initramfs, spawned-DCL foreign-command setup, and the byte-identical-in-QEMU assertion are specified precisely in docs/design-self-host-spine5-mmk-component.md. No unproven/red QEMU suite is shipped (Rule 6/7). Co-authored-by: alice <alice@workspace.local> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ve (#472) Bump OVMX_PRODUCT_VERSION V0.4-2 → V0.4-3. 15 PRs since V0.4-2. Headline: the self-host toolchain now BUILDS — MMK.EXE drives real compile+link inside OVMX against a live executive. SELF-HOST #4 COMPLETE MMK.EXE genuinely drives compile+link builds vs real /dev/vms (#464 capstone). Full exec-drive substrate: async AST delivery + interruptible $HIBER (#457), IO$M_NOW (#458), DCL-over-mailbox (#460), + crash fixes #463 (32→64 ptr-width) / #464 (IO$M_NOW func-code mask). Freeze-join fix (#459). Component build host-proven (#470). UX FIDELITY SHOW CPU (#465), file protection SET/display (#467), RECALL readline-independent (#468), DCL scripting $STATUS/%X + CALL/SUBROUTINE + DECK/EOD (#469), DIRECTORY wildcards/ellipsis (#461). + swept other threads' merged work Self-host spine #5/#6 (MMK-drives-a-real-component IN QEMU) in flight. Co-authored-by: alice <alice@workspace.local> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…byte-identical, zero-bash (CI gate) (#476) * vms-d1b: self-host spine #6 — MMK drives a real TCC compile in QEMU, byte-identical, zero-bash (CI gate) The shipped MMK.EXE now drives a REAL toolchain step inside OVMX in QEMU, against a real /dev/vms: it spawns a persistent DCL over VMS mailboxes and streams a descrip.mms whose action defines a foreign command TCC :== "$..." and invokes it to compile the REAL src/libvmssys freestanding runtime TU vms_string.c to an object. DCL activates the foreign command by fork()+execve() of the staged static TCC.EXE (a plain static image is not in-process-eligible, so imgact_activate returns SS$_UNSUPPORTED and DCL forks it) — the FIRST-EVER TCC.EXE run inside QEMU and the first time MMK drives a real compiler (not a DCL builtin) end to end. The parent (which never runs a compiler) asserts the driven object is a valid ELF relocatable carrying vms_strlen and is BYTE-IDENTICAL across two independent in-guest MMK-driven builds. Zero bash in the build path. This closes spine #6 (vms-d1b, the CI gate) and the MMK-driven-EXECUTION residual of spine #5 (vms-fe4) for the COMPILE stage. - tests/toolchain/mk_tcc_static.sh: builds tinycc as a PLAIN STATIC (musl) foreign-command image (distinct from mk_tcc.sh's IMGACT-packaged self-host image) — the binary DCL fork+execve activates, no IMGACT/shareable staging. - tests/toolchain/run_tcc_static_component.sh + CMake test toolchain-tcc-static-component: host proof the static TCC.EXE compiles the real runtime TUs (vms_string/vms_snprintf/driver) to valid, byte-identical objects; asserts vms_math.c is the documented x86 tcc-blocked TU (SSE "x" inline asm). - tests/qemu/test_syssvc_mmk_build.c: the QEMU suite (extends spine #4's test_syssvc_mmk_drive.c); honest-skips 77 with no /dev/vms. - tests/qemu/Dockerfile: stages static TCC.EXE at SYS$SYSTEM, tinycc's headers + musl's stdint.h closure beside it, and the real component source. The suite plugs into the STANDING kernel-executive CI barrier (builds the image from the checked-out tree, a clean context), so the MMK-driven native build is gated on every run — no new job. - facility_defects.sh: new per-facility control mmk-build-image-not-activated — dcl_exec_foreign_command reports success WITHOUT activating the image, so the driven TCC command completes but runs no compiler; reddens exactly the suite's five object/byte-identity assertions FAST (no $HIBER wedge), attributable to the build drive alone. A DEDICATED control, not a second suite on the sp_send=0 drive control: two ~50s $HIBER wedges do not fit run_tests.sh's 120s QEMU budget in one boot. Floor 96 -> 97. Verified in QEMU on this host: kernel-executive 76/76 (mmk_build 7/7); mmk-build-image-not-activated reddens exactly the 5 object assertions with no strays and the harness completes (no timeout); executive-absent mmk_build rc=77. BUILD.COM retirement is NOT done: the full compile->archive->LINK-to-image chain in-guest remains (vms_math not tcc-compilable on x86_64; LINK needs the SYS$LIBRARY shareables staged + logical-name resolution in LINK.EXE + IMGACT activation) — the precise residual for spine #7, documented in docs/design-self-host-spine5-mmk-component.md. No red gate shipped (Rule 6/7). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * vms-d1b: fix mmk_build CI timing — wait for MMK to EXIT (single generous bound), not a 2s reap grace CI's Kernel Executive job went red from a clean build: mmk_build produced the object and echoed the marker (build-#1 assertions GREEN) but MMK had not yet finished tearing down its spawned DCL within the tight 2s REAP_GRACE, so reap1 stayed 0, the reap1 short-circuit skipped drive #2, and the completion + byte-identity assertions reddened. CI's TCG is much slower than the dev host, where reap1 was always 1. Restructure drive_build to a SINGLE generous bounded wait (40s) that drains output (detecting the marker) AND polls for MMK to exit, returning the instant MMK exits -- so a green drive costs only its real runtime and the bound is only ever hit by a genuine hang. Removes the split 10s-marker / 2s-reap phases that were sized for a fast dev host. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * vms-d1b: make mmk_build load-robust — capture proof (marker+object) instead of waiting on MMK's exit The clean-build repro showed mmk_build's remaining flake was MMK's slow self-exit under contended TCG: the compile finished, the marker was echoed and the byte-identical object was on disk, but MMK had not yet torn down its spawned DCL and exited within the bound, so the reap-based assertion reddened. MMK's exit timing is not a property this suite tests. drive_build now stops the instant the PROOF is captured -- the DCL echoed OVMXD1B:COMPILED AND the object exists on disk -- and kills MMK as cleanup rather than gating on its self-exit. A genuine mid-drive $HIBER deadlock still fails hard (no marker is ever echoed). The completion assertion is now the marker (reliable), the reap-exit assertion is dropped, and the drive-#2 short-circuit is keyed on the object (robust under load), not on MMK's exit. The negctl declared set is unchanged (the 5 object/byte-identity assertions; the marker stays green). Verified: two consecutive clean green runs (mmk_build 6/6), and mmk-build-image-not-activated reddens exactly the 5 object assertions with the marker green. (A QEMU timeout / mmk_drive reap-flake seen intermittently here is this 10-container dev host's load, not the code: on CI the harness completed and mmk_drive passed.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: alice <alice@workspace.local> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e-identical, zero-bash (CI gate) (#488) Extends spine #6 (vms-d1b, MMK drives a real TCC COMPILE in QEMU) with the ARCHIVE stage. The shipped MMK.EXE now drives a real TWO-TU build over its persistent mailbox-driven DCL against a real /dev/vms: TCC.EXE compiles VMS_STRING.C + VMS_SNPRINTF.C (the two real src/libvmssys runtime TUs that ARE fully tcc-compilable on x86_64 -- vms_math.c's SSE "x"-constraint inline asm is not, so it is excluded) to objects LIBRARIAN.EXE /CREATEs OVMXRT.OLB from the two objects both driven as forked foreign-command IMAGES (fork+execve, like TCC.EXE), and the produced .OLB (a valid !<arch> object library carrying both members + vms_strlen/vms_snprintf) is asserted BYTE-IDENTICAL across two independent in-guest MMK-driven builds. Zero bash in the build path. Green in QEMU from a clean tests/qemu/Dockerfile build (12/0), wired into the standing kernel-executive CI barrier -- no new job. Finding: OVMXRT.MMS names the librarian foreign command `LIBR`, but `LIBR` abbreviates the built-in DCL LIBRARY verb (dcl_builtin.c min_abbrev=3), so DCL would run the in-process cmd_library() -- which resolves object names against the VMS default directory, not the fork's Linux cwd where TCC wrote them, and fails %LIBRARIAN-E-OPENIN. The in-guest MMS names it `LIBRARIAN` (9 chars, not a prefix of any built-in -> falls through to the foreign-command symbol and forks the staged LIBRARIAN.EXE), the exact trap OVMXRT.MMS already documents for `LNK` vs the built-in LINK, here for LIBRARY. Staging (tests/qemu/Dockerfile): build the vmslibrarian target static-musl and stage LIBRARIAN.EXE at SYS$SYSTEM beside TCC.EXE; stage VMS_SNPRINTF.C + its header in the component dir. Negctl: the existing mmk-build-image-not-activated control (dcl_activate_image -> SS$_NORMAL, foreign command reports success without running) now also reddens the six archive assertions (no driven TCC -> no objects -> LIBRARIAN has nothing to archive -> no .OLB); all six are declared in its knock_on_fail with an extended knock_on_why. Defect count unchanged (floor 97). HONEST SCOPE (Rule 6/7 -- no red gate, no premature retirement): this closes the COMPILE + ARCHIVE stages in-guest. The final LINK-to-runnable-image rung (LNK --executable --use the six OVMX shareables -> IMGACT activate -> image RUNS) is NOT driven here -- it needs the producer graph + IMGACT.EXE staged in the QEMU harness and the native-link+activate stack (host-proven by run_dcl_native.sh) reproduced under QEMU busybox. Tracked as vms-725. BUILD.COM therefore STAYS. Co-authored-by: alice <alice@workspace.local> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…for MMK's clean rundown (no leaked executive resources)
test_syssvc_mmk_drive gated on MMK.EXE reaping within a tight grace
("MMK.EXE completed ... rather than deadlocking in $HIBER"). Under
contended TCG (the Kernel Executive job runs ~76 suites in one QEMU VM
near a 120s wall) MMK echoes the DCL-computed marker OVMXB23:42 and drives
the build correctly, but its teardown-and-exit lags the marker → the reap
assertion reddens → the whole Kernel Executive gate goes red on unrelated
PRs (#499, #492).
Fix, keying on the PROOF like spine #6 (test_syssvc_mmk_build, vms-d1b):
success is the marker echoed back over the mailbox drive (the DCL-computed
independent oracle), NOT MMK's self-exit timing. A genuine mid-drive
$HIBER deadlock echoes no marker → got_marker stays 0 → the bound elapses
→ fails HARD. The negctl (facility_defects.sh mmk-drive-command-not-sent,
zero command bytes → wedged DCL → no marker) still reddens via the
require_fail assertion; its knock_on_fail (the removed reap assertion) is
cleared so the observed red set still equals require_fail + knock_on_fail
exactly.
Round 2 (teardown hygiene against the REAL shared executive, Rule 9):
success is keyed on the marker, but the parent STILL WAITS (bounded,
unasserted) for MMK to exit on its OWN. MMK $CREMBXed its command + result
mailboxes, armed a write-attention AST, and lib$spawned a persistent DCL
subprocess, and it tears all of that down in close_subprocess()/sp_close()
($FORCEX + $DELPRC the DCL, $DASSGN both mailboxes) as its last act before
exiting. SIGKILLing MMK the instant the marker appears skipped that
teardown, orphaning the DCL grandchild (which held this suite's stdout
FIFO open and sat blocked on the leaked mailbox) and leaking the
mailboxes/AST into the executive the next suite shares — deterministically
wedging the suite AFTER this one (test_syssvc_procnam), stalling the whole
run at ~60/76 at any wall. Now the parent polls for the marker while
draining MMK's output until MMK exits on its own, letting sp_close()
reclaim everything; SIGKILL is a last resort reached only by a genuine
wedge, which occurs only under the isolated one-defect-per-boot negctl.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…for MMK's clean rundown (no leaked executive resources) (#502) test_syssvc_mmk_drive gated on MMK.EXE reaping within a tight grace ("MMK.EXE completed ... rather than deadlocking in $HIBER"). Under contended TCG (the Kernel Executive job runs ~76 suites in one QEMU VM near a 120s wall) MMK echoes the DCL-computed marker OVMXB23:42 and drives the build correctly, but its teardown-and-exit lags the marker → the reap assertion reddens → the whole Kernel Executive gate goes red on unrelated PRs (#499, #492). Fix, keying on the PROOF like spine #6 (test_syssvc_mmk_build, vms-d1b): success is the marker echoed back over the mailbox drive (the DCL-computed independent oracle), NOT MMK's self-exit timing. A genuine mid-drive $HIBER deadlock echoes no marker → got_marker stays 0 → the bound elapses → fails HARD. The negctl (facility_defects.sh mmk-drive-command-not-sent, zero command bytes → wedged DCL → no marker) still reddens via the require_fail assertion; its knock_on_fail (the removed reap assertion) is cleared so the observed red set still equals require_fail + knock_on_fail exactly. Round 2 (teardown hygiene against the REAL shared executive, Rule 9): success is keyed on the marker, but the parent STILL WAITS (bounded, unasserted) for MMK to exit on its OWN. MMK $CREMBXed its command + result mailboxes, armed a write-attention AST, and lib$spawned a persistent DCL subprocess, and it tears all of that down in close_subprocess()/sp_close() ($FORCEX + $DELPRC the DCL, $DASSGN both mailboxes) as its last act before exiting. SIGKILLing MMK the instant the marker appears skipped that teardown, orphaning the DCL grandchild (which held this suite's stdout FIFO open and sat blocked on the leaked mailbox) and leaking the mailboxes/AST into the executive the next suite shares — deterministically wedging the suite AFTER this one (test_syssvc_procnam), stalling the whole run at ~60/76 at any wall. Now the parent polls for the marker while draining MMK's output until MMK exits on its own, letting sp_close() reclaim everything; SIGKILL is a last resort reached only by a genuine wedge, which occurs only under the isolated one-defect-per-boot negctl. Co-authored-by: alice <alice@workspace.local> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…unted (34→33) kernel-core/vms_cluster_fork.c gets a real injected negative control (§1 34->33). Defect fork-work-dispatch-uncounted: cf_deliver_work() drops the unique `f->st.work_dispatched++`, so the executive's own drain-convergence rule (work_dispatched >= work_posted) never converges — WORK_DISPATCHED stays 0 while WORK_POSTED climbs. A value-not-decision mutation. Frames are still delivered (RX_DISPATCHED is a different counter, stays correct), so only the work-accounting assertions redden, not the rx-frame one (minimality). suites_red: test_kmod_cluster_fork_hammer; require_fail "every posted work item was dispatched exactly once (no lost wakeup, no stuck poster)" + knock_on "cf_stats converged (dispatched >= enqueued/posted) within the 2s bound -- no lost wakeup" (both anchored). Static-proven (host): selftest injects + idempotent-teeth; §1 drops vms_cluster_fork.c (34->33); dash -n clean. Per-defect QEMU falsification: batched local rail run + CI negctl shard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HMDFjHCqxDuXgbyxNU572h
…ts-success-unstarted (33→32)
kernel-core/vms_cluster_fork_bind.c gets a real injected negative control (§1 33->32).
Defect fork-worker-start-reports-success-unstarted: vms_cluster_fork_worker_start()
short-circuits its (unique) exec_kthread_create with `0 &&`, so status stays 0
(success), ioworker_started is set and it returns SS__NORMAL — but the FC-P6.6 I/O
worker kthread is NEVER spawned ("reports success while doing nothing":
WORKER_START=1, IO_HANDLER_CALLS=0). Submissions still queue (io_sub stays green),
but no worker runs the blocking callback. suites_red: test_kmod_cluster_fork_hammer;
require_fail "the WORKER kthread really ran the blocking I/O callback ..." +
knock_on "THE FIX, MEASURED: the fork thread kept dispatching WHILE a served I/O
was blocking ..." (both anchored). Shares the suite with #6 (fork) but injected
separately, reddening a disjoint assertion pair.
Static-proven (host): selftest injects + idempotent-teeth; §1 drops
vms_cluster_fork_bind.c (33->32); dash -n clean; the escaped `0 && ` sed verified
to mutate exactly the create line. Per-defect QEMU falsification: batched local
rail run + CI negctl shard.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HMDFjHCqxDuXgbyxNU572h
…unted (34→33) kernel-core/vms_cluster_fork.c gets a real injected negative control (§1 34->33). Defect fork-work-dispatch-uncounted: cf_deliver_work() drops the unique `f->st.work_dispatched++`, so the executive's own drain-convergence rule (work_dispatched >= work_posted) never converges — WORK_DISPATCHED stays 0 while WORK_POSTED climbs. A value-not-decision mutation. Frames are still delivered (RX_DISPATCHED is a different counter, stays correct), so only the work-accounting assertions redden, not the rx-frame one (minimality). suites_red: test_kmod_cluster_fork_hammer; require_fail "every posted work item was dispatched exactly once (no lost wakeup, no stuck poster)" + knock_on "cf_stats converged (dispatched >= enqueued/posted) within the 2s bound -- no lost wakeup" (both anchored). Static-proven (host): selftest injects + idempotent-teeth; §1 drops vms_cluster_fork.c (34->33); dash -n clean. Per-defect QEMU falsification: batched local rail run + CI negctl shard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HMDFjHCqxDuXgbyxNU572h
…ts-success-unstarted (33→32)
kernel-core/vms_cluster_fork_bind.c gets a real injected negative control (§1 33->32).
Defect fork-worker-start-reports-success-unstarted: vms_cluster_fork_worker_start()
short-circuits its (unique) exec_kthread_create with `0 &&`, so status stays 0
(success), ioworker_started is set and it returns SS__NORMAL — but the FC-P6.6 I/O
worker kthread is NEVER spawned ("reports success while doing nothing":
WORKER_START=1, IO_HANDLER_CALLS=0). Submissions still queue (io_sub stays green),
but no worker runs the blocking callback. suites_red: test_kmod_cluster_fork_hammer;
require_fail "the WORKER kthread really ran the blocking I/O callback ..." +
knock_on "THE FIX, MEASURED: the fork thread kept dispatching WHILE a served I/O
was blocking ..." (both anchored). Shares the suite with #6 (fork) but injected
separately, reddening a disjoint assertion pair.
Static-proven (host): selftest injects + idempotent-teeth; §1 drops
vms_cluster_fork_bind.c (33->32); dash -n clean; the escaped `0 && ` sed verified
to mutate exactly the create line. Per-defect QEMU falsification: batched local
rail run + CI negctl shard.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HMDFjHCqxDuXgbyxNU572h
…unted (34→33) kernel-core/vms_cluster_fork.c gets a real injected negative control (§1 34->33). Defect fork-work-dispatch-uncounted: cf_deliver_work() drops the unique `f->st.work_dispatched++`, so the executive's own drain-convergence rule (work_dispatched >= work_posted) never converges — WORK_DISPATCHED stays 0 while WORK_POSTED climbs. A value-not-decision mutation. Frames are still delivered (RX_DISPATCHED is a different counter, stays correct), so only the work-accounting assertions redden, not the rx-frame one (minimality). suites_red: test_kmod_cluster_fork_hammer; require_fail "every posted work item was dispatched exactly once (no lost wakeup, no stuck poster)" + knock_on "cf_stats converged (dispatched >= enqueued/posted) within the 2s bound -- no lost wakeup" (both anchored). Static-proven (host): selftest injects + idempotent-teeth; §1 drops vms_cluster_fork.c (34->33); dash -n clean. Per-defect QEMU falsification: batched local rail run + CI negctl shard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HMDFjHCqxDuXgbyxNU572h
…ts-success-unstarted (33→32)
kernel-core/vms_cluster_fork_bind.c gets a real injected negative control (§1 33->32).
Defect fork-worker-start-reports-success-unstarted: vms_cluster_fork_worker_start()
short-circuits its (unique) exec_kthread_create with `0 &&`, so status stays 0
(success), ioworker_started is set and it returns SS__NORMAL — but the FC-P6.6 I/O
worker kthread is NEVER spawned ("reports success while doing nothing":
WORKER_START=1, IO_HANDLER_CALLS=0). Submissions still queue (io_sub stays green),
but no worker runs the blocking callback. suites_red: test_kmod_cluster_fork_hammer;
require_fail "the WORKER kthread really ran the blocking I/O callback ..." +
knock_on "THE FIX, MEASURED: the fork thread kept dispatching WHILE a served I/O
was blocking ..." (both anchored). Shares the suite with #6 (fork) but injected
separately, reddening a disjoint assertion pair.
Static-proven (host): selftest injects + idempotent-teeth; §1 drops
vms_cluster_fork_bind.c (33->32); dash -n clean; the escaped `0 && ` sed verified
to mutate exactly the create line. Per-defect QEMU falsification: batched local
rail run + CI negctl shard.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HMDFjHCqxDuXgbyxNU572h
…1244) Ground-verified against origin/main + the compat register; local checkout was stale. Wave C — status-line drift (body/register already showed the feature landed; header was stale): - design-authenticity-roadmap.md: "PROPOSED / no rd items exist" -> APPROVED/ACTIVE (vms-898/vms-6b8 funded, cited in the register). - design-files11-acp-executive.md: "design only, not yet built" -> LANDED (ACP model built; ods2.yaml vmsfs$runtime_fs implemented/real, ods2$reader verified/real; /vms passthrough retired vms-165). - design-libspawn-ovmx.md: "design only, no implementation" -> LANDED (async-AST/mbx prereqs + ovmx_spawn_pipeline.c/.h on main). - design-dcl-pipes.md: PIPE is real in dcl_cmd_process.c (pipe_split_segments), no longer a system() stub. - design-image-activation.md: correct §12 "symbol vectors not implemented" -> .vms$sv landed (vms-c65); delete the dead "Docker Mode" non-goal (Rule 9, one runtime = vms.ko/QEMU); retire the /vms/SYS0 passthrough install diagram (vms-165). - design-gcc-port-surface-gaps-register.md: banner the 2026-08-31 snapshot stale (predates the landed F2a host-surface trio); re-derive from the register. - design-alpha-crtl-archive.md: Option A landed (musl arch/alpha-dec-vms layer + mk_alpha_shr.sh on main), not "routing in progress". - design-mmk-exec-drive-ovmx.md: "BLOCKED as scoped" -> UNBLOCKED; design A prereqs landed, MMK drives compile->archive->LINK->activate in-guest (spine #6/#7). Wave D — internal pointer files + single-ledger + the draper security register: - internal/conductor-state.md + internal/lane-ownership.md: stale-snapshot banners (frozen at V0.5-5; latest is V0.6-16; lane-ownership still owns the deleted src/vmsscs/). Not refreshed to a fabricated "current" state, per the continuation-identity rule; corrected the dead vmsscs fact + noted the DECnet/self-hosting lanes. - qualifier-audit.md: hand table retired -> pointer to dcl-qualifiers.yaml (SSOT). - design-vms-parity-map.md: status/count tables retired -> compat register; narrative gap-analysis kept. - dcl-verb-fidelity-scoreboard.md: SNAPSHOT/should-be-generated banner -> the register owns verb/qualifier status. - draper-faithfulness-register.md (SECURITY): corrected the status column against origin/main code. RESOLVED (verified on main): SSH root-session cred drop (vms-49e, cred_drop.c), privilege-aware file access on the ACP path (vms-165 + acp_check_access), F$GETJPI lexical pid (vms_kif_getjpi_pid), process-control-by-PID (vms-904/dff7, resolve_control_target), sys$close indexed-file record loss (vms-5c6d, rms_idx_cleanup), XAB epoch (vms-3dd, unix_time_to_vms), invented STDRV line (vms-1fb), SHOW PROCESS LEF (vms-70eb/2b8), $HIBER/$SETPRI, and the re-armed DCL meta-facade tests (test_no_unix_leaks vms-fe21, test_mount, tautology family). Still live: logical-name split-brain for LNM$GROUP/JOB; residual uname()-sourced $GETSYI params. Left "status unverified -- re-check": SET UIC executive-visibility, on-disk Prolog-3/ISAM completeness (vms-890), STDRV phase-driver, and three remaining tautology tests. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Closes the execution pointer for epic vms-6b8. Cut fresh from current
main(no rework of PR #4 / #5, both of which stay held).The rule this applies
What would VMS do? SYSBOOT loads the executive before any process exists — VMS is never in the state where a running system has no executive. So the deliverable is a guarantee, not an error path. A handled-but-impossible-on-VMS state is itself an authenticity defect: it encodes "OVMX can be in a state VMS cannot", the same class of lie as a per-process fake that reports success.
This inverts the epic's previous standing constraint. The old rule — "if
/dev/vmsis absent, fail honestly withSS$_NOSUCHDEV" — was itself the defect being polished.What changed
Boot is fatal. PID 1 (
executive_attach) loadsvms.koand opens/dev/vmsbefore anything runs. Either failure →%STARTUP-F-NOEXEC/%STARTUP-F-NOBOOT, machine powers off. Previously: severity W, then boot on to a full DCL session with no executive.The executive is pinned. PID 1 holds the descriptor for the life of the system.
vms_fopsalready carries.owner = THIS_MODULE, sormmod vmsis refused while OVMX runs. Mid-life loss is prevented, not responded to.Fallbacks deleted, not corrected.
sys_lock.c'sensure_kif_open()(both return sites + its "Docker mode" framing, a Rule 9 violation) andvms_kif.c's absent-fd guard.SS$_NOSUCHDEVkeeps its real meaning elsewhere — a caller named a VMS device that does not exist.sys_event.chad no such path onmain; that was branch-only.Cold-start docs corrected, since both taught the superseded rule:
docs/design-executive-retrofit.md§3 constraint 2, andtest_runtime_target.sh— whose check-3 exemption waved through any file merely containing the stringSS$_NOSUCHDEV. Two positive checks replace it.Proof, on the real runtime
test_executive_integral.sh(new)test_kmod_pin.c(new)/dev/vms)ctest%STARTUP-I-EXEC, VMS executive attached on /dev/vms— the executive really does load in the QEMU runtime, so the fatal gate does not break the real boot.The new
test_executive_integral.shboots the real runtime twice: once normally, once withvms.koremoved from the initramfs. The second boot must yield no banner, no login prompt, no completed startup. That negative control is what makes this a gate rather than decoration.Notes for review
/dev/vmsnode. That neither unloads nor disturbs the running executive, but would stop new processes opening it by path. OVMX does not defend against a privileged actor sabotaging a running system, as VMS does not defend against one corrupting a resident executive image. Recorded in the design doc.%STARTUP-F-NOEXEC/%STARTUP-F-NOBOOTare OVMX design choices, labelled as such in-source. An earlier wave invented%SYSBOOT-F-LDFAILand the oracle disproved it; nothing here is presented as VMS-authentic. Oracle research on whether VAX 7.3 can demonstrate the condition at all is still running and is non-blocking.test_kmod_pinis executive-dependent. Adding such a suite must move that number; a comment now says so.🤖 Generated with Claude Code