Skip to content

vms-6be: self-host spine #7 — MMK drives compile→ARCHIVE in QEMU (byte-identical, zero-bash CI gate) - #488

Merged
baron-3dl merged 1 commit into
mainfrom
vms-6be-link-image-in-guest
Aug 13, 2026
Merged

baron-3dl merged 1 commit into
mainfrom
vms-6be-link-image-in-guest

Conversation

@baron-3dl

Copy link
Copy Markdown
Contributor

Self-host spine #7 (vms-6be): MMK drives compile→ARCHIVE in-guest

Extends spine #6 (#476, 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, zero bash:

stage image driven what it does
compile TCC.EXE compiles VMS_STRING.C and VMS_SNPRINTF.C to objects
archive LIBRARIAN.EXE /CREATEs OVMXRT.OLB from the two objects

Both run as forked foreign-command images (fork+execve, like TCC.EXE). The produced .OLB — a valid !<arch> object library carrying both members plus vms_strlen/vms_snprintf — is asserted byte-identical across two independent in-guest MMK-driven builds.

Green in QEMU: test_syssvc_mmk_build 12 passed / 0 failed, from a clean tests/qemu/Dockerfile build and again from a clean git archive HEAD. Wired into the standing kernel-executive CI barrier — no new job.

Component choice

vms_math.c is excluded: its SSE "x"-constraint inline asm + __builtin_fabs are not tinycc-compilable on x86_64 (asserted by run_tcc_static_component.sh). The in-guest library is the two string/format TUs that DO compile; OVMXRT.MMS's full 3-TU form stays the host-side plan/determinism proof.

Finding: LIBR collides with the built-in LIBRARY verb

OVMXRT.MMS names the librarian foreign command LIBR, but LIBR is a valid abbreviation of the built-in DCL LIBRARY verb (dcl_builtin.c min_abbrev=3), so DCL runs 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.

Negative control

The existing mmk-build-image-not-activated per-facility control (dcl_activate_image → SS$_NORMAL) 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 to its oracle exit) 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 src/imgact/test/run_dcl_native.sh) reproduced under QEMU busybox. Tracked as vms-725. BUILD.COM therefore STAYS — spine #5/#6/#7 are not yet fully complete; self-hosting's final rung remains.

Item: vms-6be. Design record: docs/design-self-host-spine5-mmk-component.md.

🤖 Generated with Claude Code

…e-identical, zero-bash (CI gate)

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: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@baron-3dl
baron-3dl merged commit db05ce0 into main Aug 13, 2026
70 checks passed
baron-3dl added a commit that referenced this pull request Aug 13, 2026
…INK→ACTIVATE in QEMU (zero-bash CI gate) (#493)

* vms-725: self-host spine #7 FINAL rung — MMK drives compile→archive→LINK→ACTIVATE in QEMU, byte-identical, zero-bash (CI gate)

Extends spine #7 archive (vms-6be, #488) with the LINK-to-runnable-image rung.
The shipped MMK.EXE now drives the WHOLE OVMX-native build chain over its
persistent mailbox-driven DCL against a real /dev/vms, and the harness activates
the produced image through IMGACT to its oracle exit:

  TCC.EXE       compiles VMS_STRING.C + VMS_SNPRINTF.C + the driver OVMXRTRUN.C
  LIBRARIAN.EXE /CREATEs OVMXRT.OLB from the two runtime objects
  LINK.EXE      --executable --use DECC$SHR.EXE links OVMXRTRUN.OBJ + OVMXRT.OLB
                into OVMXRT.EXE (selectively pulling VMS_STRING from the library)
  [activate]    the harness fork+execs OVMXRT.EXE -> the kernel loads its
                PT_INTERP=/vms/.../IMGACT.EXE, which maps DECC$SHR from SYS$LIBRARY
                and binds the one cross-image import -> it RUNS to exit 216
                (vms_strlen("OVMXRT")*36 -- nowhere else for 216 to come from)

Every stage byte-identical across two in-guest MMK-driven builds. Green in QEMU:
test_syssvc_mmk_build 18/0, from a clean tests/qemu/Dockerfile build. Self-host's
final MMK-driven rung: MMK builds a real OVMX component to a running image
entirely inside OVMX.

Key findings / choices:
- Only DECC$SHR is --use'd, NOT the "six shareables" the residual anticipated:
  the component is freestanding (its sole external symbol is vms_strlen, in the
  .OLB), so the executable's only cross-image import is crt0/exit from DECC$SHR.
- The producer graph (IMGACT.EXE via src/imgact/Makefile; DECC$SHR.EXE via
  mk_decc_shr.sh whole-archiving musl libc.a + libgcc.a through the static
  LINK.EXE) BUILDS CLEAN in the ubuntu+musl-gcc Dockerfile -- the alpine-only
  assumption was unfounded.
- `LNK`, not `LINK`: LINK IS the built-in DCL verb; LNK (not a prefix of it)
  falls through to the foreign-command symbol and forks the staged LINK.EXE --
  the same trap as LIBRARIAN vs LIBRARY (vms-6be). The `$` in the absolute
  DECC$SHR.EXE --use path is an ordinary VMS filename char in the raw DCL tail.
- vms_snprintf stays archive-only: TCC compiles its varargs to tinycc's __va_arg
  helper, which DECC$SHR does not export, so the runnable image pulls VMS_STRING
  only. The .OLB still carries both members (proven).

Staging (tests/qemu/Dockerfile): build the static vmslink LINK.EXE + IMGACT.EXE
(make ARCH=x86_64) + DECC$SHR.EXE (mk_decc_shr.sh); stage LINK.EXE/IMGACT.EXE at
SYS$SYSTEM, DECC$SHR.EXE at SYS$LIBRARY, OVMXRTRUN.C in the component dir.

Negctl: the existing mmk-build-image-not-activated control now also reddens the
six LINK+activate assertions (no driven toolchain -> no image -> no exit 216);
all declared in its knock_on_fail with extended knock_on_why. Floor unchanged.

BUILD.COM STAYS (Rule 6/7). It is NOT cleared by this proof: it is still
load-bearing for the S4 self-host FIXPOINT (run_link_selfhost_native.sh:136 copies
+ drives it multi-TU to build LINK.EXE gen2==gen3, a 1.0 gate) AND
run_build_com_native.sh (S3.2). The vms-725 MMK chain builds a small 2-TU
component, not the multi-TU LINK.EXE self-host fixpoint. Retirement waits on
porting that fixpoint from BUILD.COM to an MMK descrip.mms -- tracked as vms-89d.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* vms-725: fix flaky mmk_build gate — run LINK+activate on one drive, raise per-drive bound

The first cut wired the LINK+activate onto BOTH in-guest MMK drives. Under slow/
contended TCG that reddened intermittently: the 40s per-drive bound elapsed AFTER
the archive but BEFORE the LINK (the drive was progressing, not wedged), killing
MMK mid-drive; and two heavy full-chain drives pushed the whole suite toward
run_tests.sh's 120s whole-VM budget. mmk_build passed 3x then failed once (7/11)
— a Rule 8 flake, not shippable.

Fix (mmk_build now 16/0 across repeated runs, whole VM 76/76 + green when the host
has capacity):
- Drive #1 is the lighter compile+archive drive (vms-6be); drive #2 runs the full
  compile→archive→LINK chain + activation. The compile+archive OUTPUTS are still
  asserted byte-identical across the two drives; the LINK runs once.
- The LINK OUTPUT's byte-identity is proven byte-identical on the host
  (run_mmk_component_build.sh links the image twice, cmp-clean); in-guest the rung
  proves the driven LINK yields a real image that ACTIVATES and RUNS (exit 216) —
  the property that could not be shown before. This keeps the suite close to the
  vms-6be weight the kernel-executive barrier already carries reliably.
- Per-drive bound raised 40s→60s so a slow-but-progressing full drive completes
  the LINK before cleanup.

Negctl mmk-build-image-not-activated: the two dropped image assertions
(build #2 / image byte-identity) removed from knock_on_fail; the four LINK+
activate assertions kept (produced / valid ET_DYN / PT_INTERP / activated 216),
knock_on_why updated. Assertion set: 1 require + 14 knock = the 15 non-completion
assertions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* vms-725: shrink mmk_build to one runtime TU per drive — fit the 120s whole-VM CI budget

CI revealed the real budget: the kernel-executive gate runs ~76 suites in ONE
QEMU VM under run_tests.sh's fixed `timeout 120`, already near the edge on CI's
slower runner. The prior cut's mmk_build PASSED on CI (16/0), but the VM then hit
120s during the very NEXT suite (test_syssvc_mmk_drive), and the qemu timeout
(SIGTERM) reddened the whole run. My two-runtime-TU + LINK+activate suite was the
tipping weight.

Fix: each drive now compiles ONE runtime TU (vms_string), not two, making the
suite LIGHTER than the vms-6be compile+archive suite (−2 heavy TCC compiles,
+ a cheap driver compile + fast LINK + instant activation). Kept: two-drive
compile+archive byte-identity, the LINK+activate proof (drive #2), exit-216
activation. The archive is now single-member; LIBRARIAN archiving MULTIPLE members
and the LINK output's byte-identity remain host-proven
(run_mmk_component_build.sh). Assertion set: 1 require + 14 knock still equals the
15 non-completion assertions; negctl + docs updated to match.

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
…tes real OVMX code) (#500)

Bump OVMX_PRODUCT_VERSION V0.4-3 → V0.4-4. ~12 PRs since V0.4-3. Headline:
OVMX's own toolchain now builds real OVMX code to a running image INSIDE OVMX.

  SELF-HOST IN-GUEST   MMK.EXE drives TCC→LIBRARIAN→LINK over its mailbox DCL vs
                       real /dev/vms: #476 compile-in-QEMU (first-ever TCC-in-guest),
                       #488 archive, #493 full compile→archive→LINK→ACTIVATE (linked
                       OVMXRT.EXE IMGACT-activates + runs, exit 216), byte-identical,
                       CI-gated from clean archive. (BUILD.COM retirement → vms-89d.)
  UX FIDELITY          #461 DIRECTORY wildcards/ellipsis · #478 COPY/DELETE/RENAME
                       (explicit-version DELETE) · #481 HELP .HLB library · #487 SET
                       SYMBOL scope · #491 DCL ON/SET NOON error control
  BOOT INTEGRITY       #499 boot-smoke green (aligned 3 e2e tests to authentic
                       DELETE/DIRECTORY output; strengthened the fail-stop guard)
  + swept other threads' merged work

Co-authored-by: alice <alice@workspace.local>
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