|
| 1 | +# mcpp-index: Capability & Runtime Metadata (Long-term Design) |
| 2 | + |
| 3 | +> Created: 2026-06-03 · Owner: sunrisepeak · Status: design (industrial / long-term) |
| 4 | +> Repo: `mcpp-community/mcpp-index` (redirects to `mcpplibs/mcpp-index`) |
| 5 | +> Master plan: `/home/speak/workspace/github/agentdocs/2026-06-03-mcpp-ecosystem-architecture-plan.md` |
| 6 | +> Sibling sub-doc: `.agents/docs/2026-06-03-gl-runtime-packages-plan.md` (the GL runtime package |
| 7 | +> boundary this design generalizes from). |
| 8 | +
|
| 9 | +This document specifies how the mcpp package registry models **dependency capabilities and runtime |
| 10 | +requirements** as long-term, industrial metadata — not as one-off scripts or per-consumer pins. It |
| 11 | +is written to outlive any single package (imgui, glfw) and to guide every native package that touches |
| 12 | +a non-vendorable host resource (GPU driver, GLVND, display server). |
| 13 | + |
| 14 | +--- |
| 15 | + |
| 16 | +## 1. The two-plane dependency model |
| 17 | + |
| 18 | +mcpp dependencies split into two planes. The split is a hard rule, not a convenience. |
| 19 | + |
| 20 | +### 1.1 Hermetic plane (vendored, reproducible) |
| 21 | + |
| 22 | +- **Content:** source packages + toolchains. |
| 23 | +- **Properties:** content-addressed, pinned by `sha256`, byte-reproducible via lockfile + index checksums. |
| 24 | +- **Examples today:** |
| 25 | + - `compat.opengl` — Khronos OpenGL **headers** only (registry tarball, sha256-pinned). It is a |
| 26 | + header provider and must **not** become a host driver wrapper. |
| 27 | + - `compat.glfw` — GLFW built from upstream source (tag `3.4`, sha256-pinned), per-platform sources. |
| 28 | + - `imgui` — the module package, source tarball sha256-pinned. |
| 29 | + |
| 30 | +The hermetic plane is where Cargo-style guarantees apply directly: SemVer resolution, lockfile, |
| 31 | +index checksum verification. Anything here can and must be vendored and hashed. |
| 32 | + |
| 33 | +### 1.2 Host plane (discovered, passed through, never vendored) |
| 34 | + |
| 35 | +- **Content:** GPU drivers, GLVND/GLX dispatch, display server (X11/Wayland) — host singletons that |
| 36 | + are machine-specific and licensed/installed outside the package world. |
| 37 | +- **Properties:** **discovered at install time** on the host and **passed through** via binding |
| 38 | + (symlink farm + RUNPATH), never copied into the registry, never sha256-pinned as redistributable. |
| 39 | +- **Reproducibility model:** **intent-level**, not byte-level. The manifest declares *what capability |
| 40 | + is needed* (e.g. `opengl.glx.driver`); `mcpp doctor`/`why` records *what host actually satisfied it*. |
| 41 | + Two machines with different NVIDIA driver builds are both "reproducible" w.r.t. the declared intent. |
| 42 | + |
| 43 | +**Iron rule:** GPU drivers and host singletons live in the host plane forever. Vendoring a vendor |
| 44 | +driver tarball as if it were a normal redistributable package is prohibited. |
| 45 | + |
| 46 | +The worked example of the host plane is `compat.glx-runtime` (next section). |
| 47 | + |
| 48 | +--- |
| 49 | + |
| 50 | +## 2. Capability / runtime metadata schema (as it exists today) |
| 51 | + |
| 52 | +Native packages declare runtime needs under `mcpp.runtime` (and, on Linux, under |
| 53 | +`mcpp.linux.runtime`). The schema in production today is: |
| 54 | + |
| 55 | +```lua |
| 56 | +runtime = { |
| 57 | + library_dirs = { ... }, -- dirs to add to the consumer's RUNPATH/link runtime dirs |
| 58 | + dlopen_libs = { ... }, -- soname strings the package will dlopen at runtime |
| 59 | + capabilities = { ... }, -- abstract host capabilities required (provider-resolved) |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +These propagate along the dependency graph: a consumer of a package inherits that package's |
| 64 | +`runtime` requirements (and so does a consumer of a consumer). imgui declares **none** of this — it |
| 65 | +inherits everything transitively through `compat.glfw` / `compat.opengl`. |
| 66 | + |
| 67 | +### 2.1 Worked example: `compat.glx-runtime` (the host-plane adapter) |
| 68 | + |
| 69 | +File: `pkgs/c/compat.glx-runtime.lua`. Verified contents: |
| 70 | + |
| 71 | +- It is a real package (`type = "package"`, version `"2026.06.03"`) but its tarball is just a Khronos |
| 72 | + README pinned for provenance; the substance is its `install()` script. |
| 73 | +- `install()` calls `link_runtime_libs()`, which **symlinks the HOST's GLVND/GL/GLX libraries** out of |
| 74 | + host library dirs into its install dir `mcpp_generated/glx_runtime/lib`. The discovered patterns are: |
| 75 | + `libGL.so*`, `libGLX.so*`, `libGLX_*.so*` (covers `libGLX_nvidia*`), `libGLdispatch.so*`, |
| 76 | + `libOpenGL.so*`, `libEGL.so*`, `libEGL_*.so*`, `libGLES*.so*`, `libnvidia*.so*`, `libglapi.so*`, |
| 77 | + `libdrm*.so*`, `libexpat.so*`, `libxshmfence.so*`, `libbsd.so*`, `libmd.so*`. |
| 78 | +- Host search dirs: `$MCPP_HOST_GL_LIBRARY_PATH` (override) then `/lib/x86_64-linux-gnu`, |
| 79 | + `/usr/lib/x86_64-linux-gnu`, `/lib64`, `/usr/lib64`, `/usr/lib`. |
| 80 | +- It **fails the install** if `libGLX.so.0` or `libGL.so.1` are not found on the host — i.e. the host |
| 81 | + plane is validated, not silently skipped. |
| 82 | +- It declares: |
| 83 | + ```lua |
| 84 | + runtime = { |
| 85 | + library_dirs = { "mcpp_generated/glx_runtime/lib" }, |
| 86 | + dlopen_libs = { "libGLX.so.0", "libGL.so.1", "libGL.so" }, |
| 87 | + capabilities = { "x11.display", "opengl.glx.driver" }, |
| 88 | + } |
| 89 | + ``` |
| 90 | +- It depends on `compat.xext = "1.3.7"`. |
| 91 | + |
| 92 | +This is exactly the "host plane" passthrough: drivers are host-specific, discovered, symlinked, and |
| 93 | +exposed via `library_dirs` so the consumer's RUNPATH can find them — never vendored. |
| 94 | + |
| 95 | +### 2.2 Dependency wiring: glfw -> glx-runtime (Linux) |
| 96 | + |
| 97 | +File: `pkgs/c/compat.glfw.lua`. Verified: the Linux block declares BOTH the runtime capabilities AND |
| 98 | +the dep on the host-plane package, so any consumer of glfw transitively pulls glx-runtime: |
| 99 | + |
| 100 | +```lua |
| 101 | +linux = { |
| 102 | + cflags = { "-D_DEFAULT_SOURCE", "-D_GLFW_X11" }, |
| 103 | + runtime = { |
| 104 | + dlopen_libs = { "libGLX.so.0", "libGL.so.1", "libGL.so" }, |
| 105 | + capabilities = { "x11.display", "opengl.glx.driver" }, |
| 106 | + }, |
| 107 | + deps = { |
| 108 | + ["compat.glx-runtime"] = "2026.06.03", |
| 109 | + ["compat.x11"] = "1.8.13", |
| 110 | + ["compat.xcursor"] = "1.2.3", |
| 111 | + ["compat.xext"] = "1.3.7", |
| 112 | + ["compat.xfixes"] = "6.0.2", |
| 113 | + ["compat.xi"] = "1.8.3", |
| 114 | + ["compat.xinerama"] = "1.1.6", |
| 115 | + ["compat.xorgproto"] = "2025.1", |
| 116 | + ["compat.xrandr"] = "1.5.5", |
| 117 | + ["compat.xrender"] = "0.9.12", |
| 118 | + }, |
| 119 | +} |
| 120 | +``` |
| 121 | + |
| 122 | +`compat.glfw` also has a top-level `deps = { ["compat.opengl"] = "2026.05.31" }` (headers, hermetic |
| 123 | +plane). `compat.opengl` is header-only and depends only on `compat.khrplatform` — it does **not** |
| 124 | +declare any `runtime` block, which is correct (headers carry no runtime host requirement). |
| 125 | + |
| 126 | +**Conclusion (verified):** the wiring `glfw -> glx-runtime` is present and correct on Linux. The |
| 127 | +capability set and dep version (`2026.06.03`) match the glx-runtime package's own version. The |
| 128 | +remaining gaps to a no-shim window run live in the **mcpp core** (RUNPATH must include the dependency |
| 129 | +`runtime.library_dirs`) and in stale consumer lockfiles — not in this metadata. See master plan R2/R3. |
| 130 | + |
| 131 | +--- |
| 132 | + |
| 133 | +## 3. Proposed additions (long-term) |
| 134 | + |
| 135 | +These are not yet in the schema. They are the declarative spine that lets mcpp stay zero-config while |
| 136 | +remaining correct across ABIs and platforms. |
| 137 | + |
| 138 | +### 3.1 `abi` capability declared by native packages |
| 139 | + |
| 140 | +**Gap (verified today):** there is **no `abi` field** on `compat.glfw`, `compat.opengl`, or |
| 141 | +`compat.glx-runtime`. A grep for `abi` matches only the `capabilities` lines — confirming the field is |
| 142 | +absent. Nothing in the index tells the resolver that these packages link against glibc. |
| 143 | + |
| 144 | +**Why it matters:** mcpp's bootstrap default toolchain on a fresh host is `gcc-musl-static`. musl |
| 145 | +cannot link the glibc world (X11/GL), which is the master-plan **R1** failure (`arc4random_buf` |
| 146 | +implicit decl while linking `libXdmcp`). Today the only workarounds are pinning a toolchain (which we |
| 147 | +explicitly want to avoid) or setting an env-level default. |
| 148 | + |
| 149 | +**Proposal:** native packages declare an ABI capability, e.g. |
| 150 | + |
| 151 | +```lua |
| 152 | +mcpp = { |
| 153 | + abi = "glibc", -- one of: "glibc" | "musl" | "msvc" |
| 154 | + -- ... |
| 155 | +} |
| 156 | +``` |
| 157 | + |
| 158 | +The resolver unions ABI requirements across the dependency graph and **auto-selects an |
| 159 | +ABI-compatible toolchain** (here: a glibc gcc). This removes the musl-static default trap **without |
| 160 | +any consumer pinning** — the package states its truth (glibc) and the resolver does the rest. The |
| 161 | +master plan calls this "abi drives toolchain selection." |
| 162 | + |
| 163 | +### 3.2 Capability -> provider resolution |
| 164 | + |
| 165 | +Capabilities like `opengl.glx.driver` and `x11.display` are abstract today; `compat.glx-runtime` |
| 166 | +happens to be the thing that satisfies them on Linux, wired by hand via `deps`. Long term, make this a |
| 167 | +**registry-level capability -> provider map per platform**, e.g.: |
| 168 | + |
| 169 | +| capability | linux provider | macosx provider | windows provider | |
| 170 | +|---------------------|-----------------------|------------------|------------------| |
| 171 | +| `opengl.glx.driver` | `glvnd-linux` (≈ glx-runtime) | `opengl-macos` | `opengl-win` | |
| 172 | +| `x11.display` | `x11-runtime` | (n/a) | (n/a) | |
| 173 | + |
| 174 | +A package that declares `capabilities = { "opengl.glx.driver" }` would then have the correct provider |
| 175 | +package injected automatically for the active platform, instead of every windowing package |
| 176 | +hand-listing `compat.glx-runtime` in its Linux `deps`. This keeps consumers and even mid-tier packages |
| 177 | +free of platform-specific provider wiring. |
| 178 | + |
| 179 | +### 3.3 Declarative-first, with an imperative escape hatch |
| 180 | + |
| 181 | +Both additions are **declarative-first**: packages state intent (`abi`, `capabilities`), the resolver |
| 182 | +computes the plan. But we deliberately keep the **imperative escape hatch** — the `install()` Lua |
| 183 | +scripts (as `compat.glx-runtime` already uses) remain available for the long tail (host discovery, |
| 184 | +symlink farms, anything not expressible declaratively). This mirrors Cargo's `build.rs` lesson: a pure |
| 185 | +declarative model eventually hits a case it can't express, so an escape hatch must always exist. |
| 186 | + |
| 187 | +--- |
| 188 | + |
| 189 | +## 4. Immutable-version policy |
| 190 | + |
| 191 | +**Policy:** a published version is immutable. Once `name@version` is in the index with a `sha256`, that |
| 192 | +pairing never changes. Fixes and content changes ship as a **new version**, never as an in-place |
| 193 | +overwrite. This is the crates.io lesson — overwriting a published version silently breaks every |
| 194 | +lockfile that already trusts the old checksum. |
| 195 | + |
| 196 | +**The imgui 0.0.1 sha bump (PR #30) is a one-time exception.** The `imgui-m` 0.0.1 git tag was *moved* |
| 197 | +onto the merged backend-abstraction + cross-platform commit, so the GitHub source tarball checksum |
| 198 | +changed: |
| 199 | + |
| 200 | +- old: `b87188bd2ca7d8010a695d5ebfccd76eb3e28b3e002885207493225057f5e190` |
| 201 | +- new: `168d1f9a2dfc3823d671385654823f7eba25f146d029ceeacfb19a84617af4a0` |
| 202 | + |
| 203 | +PR #30 updates `pkgs/i/imgui.lua` (linux/macosx/windows) so `imgui = "0.0.1"` resolves against the |
| 204 | +re-released tarball. This is acceptable **only** as a transitional fix while 0.0.1 is the first/early |
| 205 | +release. **Future releases must bump the version** (0.0.2, …) rather than re-tagging and overwriting a |
| 206 | +published sha. The master plan records the same caveat (§2.4 / §4.3 / §8). |
| 207 | + |
| 208 | +--- |
| 209 | + |
| 210 | +## 5. Status / cross-references |
| 211 | + |
| 212 | +- **PR #30** (`imgui: update 0.0.1 sha256 for re-released tarball`): OPEN, mergeable, base `main`, |
| 213 | + head `imgui-0.0.1-rerelease`, author Sunrisepeak — https://github.com/mcpplibs/mcpp-index/pull/30 |
| 214 | +- Verified metadata files: |
| 215 | + - `pkgs/c/compat.glx-runtime.lua` — host-plane GL passthrough (symlink farm + runtime block). |
| 216 | + - `pkgs/c/compat.glfw.lua` — Linux `deps` on `compat.glx-runtime` + matching `runtime` capabilities. |
| 217 | + - `pkgs/c/compat.opengl.lua` — header-only, no runtime block (correct). |
| 218 | + - `pkgs/i/imgui.lua` — Form A descriptor, sha being updated by PR #30. |
| 219 | +- **abi gap:** no `abi` field on any compat package today (verified). Section 3.1 is the proposed fix. |
| 220 | +- Sibling: `.agents/docs/2026-06-03-gl-runtime-packages-plan.md` (package boundary checkpoint, PR #27). |
| 221 | +- Master plan: `/home/speak/workspace/github/agentdocs/2026-06-03-mcpp-ecosystem-architecture-plan.md`. |
0 commit comments