Skip to content

DO NOT MERGE YET — The executive is integral: OVMX must not boot without it (vms-0ff) - #6

Closed
baron-3dl wants to merge 3 commits into
mainfrom
vms-0ff-executive-fatal
Closed

baron-3dl wants to merge 3 commits into
mainfrom
vms-0ff-executive-fatal

Conversation

@baron-3dl

Copy link
Copy Markdown
Contributor

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/vms is absent, fail honestly with SS$_NOSUCHDEV" — was itself the defect being polished.

What changed

Boot is fatal. PID 1 (executive_attach) loads vms.ko and opens /dev/vms before 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_fops already carries .owner = THIS_MODULE, so rmmod vms is refused while OVMX runs. Mid-life loss is prevented, not responded to.

Fallbacks deleted, not corrected. sys_lock.c's ensure_kif_open() (both return sites + 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. sys_event.c had no such path on main; that was branch-only.

Cold-start docs corrected, since both taught the superseded rule: docs/design-executive-retrofit.md §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.

Proof, on the real runtime

Check Result
test_executive_integral.sh (new) 9/9
test_kmod_pin.c (new) 5/5
Kernel executive (QEMU, /dev/vms) 11 suites passed, 0 failed
Negative control exactly 3 passed / 8 failed
Persistent boot 12/12 (unchanged)
ctest 40/40
Rule 9 gate PASS

%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.sh boots the real runtime twice: once normally, once with vms.ko removed 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

  • Boundary stated, not papered over: a privileged host actor can still unlink the /dev/vms node. 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.
  • Rule 8 labelling: %STARTUP-F-NOEXEC / %STARTUP-F-NOBOOT are OVMX design choices, labelled as such in-source. An earlier wave invented %SYSBOOT-F-LDFAIL and 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.
  • Dead-legacy container: its boot smoke test now asserts the refusal rather than a successful executive-less boot (which is the forbidden state). Install-skip is covered on the real runtime by persistent-boot Boot 2 — no coverage lost.
  • The negative control's pinned suite count moved 7 → 8 because test_kmod_pin is executive-dependent. Adding such a suite must move that number; a comment now says so.

🤖 Generated with Claude Code

baron-3dl and others added 3 commits July 29, 2026 22:08
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>
@baron-3dl

Copy link
Copy Markdown
Contributor Author

Update: the boot-failure message is now oracle-pinned — and the design turned out to be VMS-authentic

The 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 (549f8af).

Observed on ~/vax/cluster node VAX2, OpenVMS VAX V7.3, 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 ~/vax/cluster/captures/vax2-execinit-missing-exception-2026-07-29.log; I read it directly rather than trusting the agent's report. The rename was verified reversible beforehand and the node rebooted cleanly and rejoined the cluster after.

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 %STARTUP-F-NOEXEC / %STARTUP-F-NOBOOT pair. Four properties are reproduced deliberately because they are the authenticity tells: facility is EXECINIT, not SYSBOOT; there is no severity letter and no mnemonic; the image is a bare filename; the status prints raw as R0 = + 8 hex digits.

This also re-disproves the earlier %SYSBOOT-F-LDFAIL independently — the complete VAX 7.3 SYSBOOT set (HELP/MESSAGE/FACILITY=SYSBOOT, ~48 entries) has no such mnemonic. 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)

The %OVMX-I-EXECINIT detail line carrying the Linux error (VMS prints nothing more — ?06 HLT INST is VAX console firmware), and reporting /dev/vms failing to open in the same shape with no R0, since a VMS executive has no device node.

Deliberately not fixed here

R0 = 00000910 decodes to %SYSTEM-W-NOSUCHFILE, but in-tree ssdef.h has SS$_NOSUCHFILE = 2696 (0xA88). Another wrong constant — tracked in vms-556 / vms-c90 and needing operator sign-off. ovmx_init.c uses the observed value only to reproduce an observed console line and says so at its definition; it does not redefine the constant.

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 change

CI green by SHA 549f8af. Locally: executive-integral 8/8 (now asserts the EXECINIT facility and R0 = 00000910, 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.

@baron-3dl baron-3dl changed the title The executive is integral: OVMX must not boot without it (vms-0ff) DO NOT MERGE YET — The executive is integral: OVMX must not boot without it (vms-0ff) Jul 30, 2026
@baron-3dl

Copy link
Copy Markdown
Contributor Author

⛔ HOLD — do not merge until SSH-on-QEMU lands

Operator 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:

  • docker run ovmx-test / docker-compose up stop yielding a working OVMX — PID 1 reports the EXECINIT load failure and exits, by design.
  • SSH into OVMX disappears entirely. The QEMU runtime boots with -nic none — there is no networking in the real runtime at all — so the dead-legacy container was the only way to SSH in.
  • The --device /dev/vms route that would make a container honest is not available on this host (WSL2, no kernel headers, so vms.ko cannot be built or loaded on the host).

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 + hostfwd, vmssshd running under the real executive) and the UAT drives a VMS session over it. Then this PR merges with no window in which OVMX is unusable.

Rule 9 stays intact — the fix is SSH on the real runtime, not exempting the container from the executive gate.

baron-3dl added a commit that referenced this pull request Jul 30, 2026
…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.
baron-3dl added a commit that referenced this pull request Jul 30, 2026
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.
baron-3dl added a commit that referenced this pull request Jul 30, 2026
…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>
@baron-3dl

Copy link
Copy Markdown
Contributor Author

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 vms-97d, #10 vms-71a, #11 vms-a4b, #12 vms-8019, #13 vms-d0b), so the rebase would have required a force-push over the branch this PR points at. #14 carries every commit from this branch plus the rebase merges and five rounds of adversarial review.

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 (vms-02d), so that condition could never be met and this PR would have been held forever by construction. The capability it protected was SSH into the dead-legacy Docker container: a VMS login with no executive — precisely the facade this work exists to delete. That container no longer exists; #10 deleted it.

What review added on top of what was here:

  • tests/qemu/run_tests.sh reported ALL KERNEL MODULE TESTS PASSED while printing 10 suites failed — pass/fail was grep -q "FINAL RESULTS:.*0 suites failed", satisfied by the trailing zero of any count ending in zero. Latent since the harness was written; this is the first tree to reach double digits.
  • Boot C: Boots A and B both only exercised module-missing. The reachable path where vms.ko loads but /dev/vms never appears had zero coverage.
  • The Rule 9 gate itself certified the regression it exists to prevent — a one-line warn-and-continue passed with Rule 9 gate: PASS while the real QEMU boot went 10 passed / 4 failed. Now structural, with a 20-case negative-control suite in ctest.
  • %EXECINIT is now used only for the oracle-pinned condition; conditions VMS never faces report through %OVMX-F-EXECINIT rather than wearing a VMS facility name.

Known residuals are filed, not hidden: vms-2d3 (an env-gated bypass before the open evades both the lint and Boot B/C) and vms-fe5 (test_kmod_pin.c proves same-process pinning, not the cross-process rmmod refusal).

@baron-3dl baron-3dl closed this Jul 30, 2026
baron-3dl added a commit that referenced this pull request Aug 13, 2026
…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>
baron-3dl added a commit that referenced this pull request Aug 13, 2026
…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>
baron-3dl added a commit that referenced this pull request Aug 13, 2026
…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>
baron-3dl added a commit that referenced this pull request Aug 13, 2026
…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>
baron-3dl pushed a commit that referenced this pull request Aug 13, 2026
…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>
baron-3dl added a commit that referenced this pull request Aug 13, 2026
…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>
baron-3dl added a commit that referenced this pull request Sep 11, 2026
…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
baron-3dl added a commit that referenced this pull request Sep 11, 2026
…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
baron-3dl added a commit that referenced this pull request Sep 12, 2026
…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
baron-3dl added a commit that referenced this pull request Sep 12, 2026
…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
baron-3dl added a commit that referenced this pull request Sep 12, 2026
…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
baron-3dl added a commit that referenced this pull request Sep 12, 2026
…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
baron-3dl added a commit that referenced this pull request Sep 14, 2026
…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>
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