feat(xpkg): subos.env declarations, and one source for the Lua stdlib — 0.0.48 - #32
Merged
Conversation
… — 0.0.48
PATH and RPATH cover linking, not discovery. A GL driver is found through
LIBGL_DRIVERS_PATH, an EGL vendor through __EGL_VENDOR_LIBRARY_DIRS, a font
config through XDG_DATA_DIRS — no amount of linking supplies those, and the
process that has to see them is the user's own binary, which xlings never
wraps. `xvm.add`'s `envs` is per-shim and cannot reach it.
`subos.env{var, op, value, binding}` lets a package declare one, carried to
the consumer as a `subos_env` op with its own var/value/mode fields. The
recipe's set/prepend choice travels as `mode` because `op` is already the
category the consumer dispatches on. Slice 1 implements set and prepend;
`append` is refused rather than quietly treated as `set`.
The capability probe has to be `type(subos.env) == "function"`, not
`if subos.env then`. import() answers an unknown module with a permissive
proxy whose every key is a truthy callable table, so the truthiness test is
true on clients that will accept the call and discard it — install succeeds,
nothing is configured, nothing complains. `if xvm.files then` in the V2 spec
is safe only because `xvm` is a module those clients already ship. A test
pins both halves so the rule cannot be relaxed by accident.
Build: xmake and CMake entry points are gone, mcpp is the only one. The Lua
stdlib now has a single copy under version control — build.mcpp generates the
embedded .cppm into MCPP_OUT_DIR instead of it being committed alongside its
own source. Those two had already drifted: xvm.files shipped in 0.0.47 as an
edit to the generated file alone, and the .lua that is nominally its source
never had it, so an xmake build would have silently deleted the feature. That
content is restored to the .lua, and the shape that allowed it is gone.
Also refreshes the CI pins (xlings 0.4.69 → 2026.8.4.2, mcpp 0.0.109 →
2026.8.4.1), which rot silently and fail looking like network errors.
This was referenced Aug 4, 2026
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.
What
subos.env{var, op, value, binding}— a package declares an environment variable its subos must export to every process entering it.PATH and RPATH cover linking, not discovery. A GL driver is found through
LIBGL_DRIVERS_PATH, an EGL vendor through__EGL_VENDOR_LIBRARY_DIRS, a font config throughXDG_DATA_DIRS. None of those can be linked in, and the process that has to see them is the user's own binary — which xlings never wraps, soxvm.add's per-shimenvscannot reach it.Carried to the consumer as an
op = "subos_env"entry with its ownvar/value/modefields. The recipe'sset/prependchoice travels asmodebecauseopis already the category the consumer dispatches on. Slice 1 implementssetandprepend;appendis refused and returnsfalserather than quietly behaving likeset.The probe rule this establishes
Recipes must write:
not
if subos.env then.import()answers an unknown module with a permissive proxy whose every key is a truthy callable table — so the truthiness test is true on clients that predate this module, the recipe takes the new branch, and the call evaporates. Install succeeds, nothing is configured, nothing complains.if xvm.files thenin the V2 spec is safe only becausexvmis a module those clients already ship, so the missing field really is nil. A missing module never is.SubosEnv_ProbeMustTestTypeBecauseUnknownModulesAreTruthypins both halves.Build: mcpp only
xmake and CMake entry points are gone (the CMake one still declared
project(mcpplibs-templates)and atemplates_testtarget — it never built this library).mcpp build/mcpp testis the only path, which CI already used.The Lua stdlib now has one copy under version control.
build.mcppgenerates the embedded.cppmintoMCPP_OUT_DIRinstead of it being committed next to its own source.Those two had already drifted:
xvm.filesshipped in 0.0.47 as an edit to the generated file alone, andsrc/lua-stdlib/xim/libxpkg/xvm.luanever had it. An xmake build would have regenerated from that stale source and silently deleted the feature — nothing reads both copies, so nothing could notice. This restores the content to the.luaand removes the shape that allowed it.Also refreshes the CI pins (xlings 0.4.69 → 2026.8.4.2, mcpp 0.0.109 → 2026.8.4.1). Those rot silently and fail looking like network errors.
Verified
mcpp test— 100 tests pass (the 4 macOS-only elfpatch cases stay filtered on a Linux runner, as before).Consumed by openxlings/xlings subos slice 1:
.agents/docs/2026-08-05-subos-minimum-design.md.