vms-6be: self-host spine #7 — MMK drives compile→ARCHIVE in QEMU (byte-identical, zero-bash CI gate) - #488
Merged
Conversation
…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
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.EXEnow drives a real two-TU build over its persistent mailbox-driven DCL against a real/dev/vms, zero bash:TCC.EXEVMS_STRING.CandVMS_SNPRINTF.Cto objectsLIBRARIAN.EXE/CREATEsOVMXRT.OLBfrom the two objectsBoth run as forked foreign-command images (
fork+execve, likeTCC.EXE). The produced.OLB— a valid!<arch>object library carrying both members plusvms_strlen/vms_snprintf— is asserted byte-identical across two independent in-guest MMK-driven builds.Green in QEMU:
test_syssvc_mmk_build12 passed / 0 failed, from a cleantests/qemu/Dockerfilebuild and again from a cleangit archive HEAD. Wired into the standingkernel-executiveCI barrier — no new job.Component choice
vms_math.cis excluded: its SSE"x"-constraint inline asm +__builtin_fabsare not tinycc-compilable on x86_64 (asserted byrun_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:
LIBRcollides with the built-inLIBRARYverbOVMXRT.MMSnames the librarian foreign commandLIBR, butLIBRis a valid abbreviation of the built-in DCLLIBRARYverb (dcl_builtin.cmin_abbrev=3), so DCL runs the in-processcmd_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 itLIBRARIAN(9 chars, not a prefix of any built-in → falls through to the foreign-command symbol and forks the stagedLIBRARIAN.EXE), the exact trapOVMXRT.MMSalready documents forLNKvs the built-inLINK, here forLIBRARY.Negative control
The existing
mmk-build-image-not-activatedper-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 itsknock_on_failwith an extendedknock_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 --usethe six OVMX shareables → IMGACT activate → image RUNS to its oracle exit) is NOT driven here — it needs the producer graph +IMGACT.EXEstaged in the QEMU harness and the native-link+activate stack (host-proven bysrc/imgact/test/run_dcl_native.sh) reproduced under QEMU busybox. Tracked as vms-725.BUILD.COMtherefore 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