From 53a2c6e7d442659a88f32dc8ee6e31b1f2824ab7 Mon Sep 17 00:00:00 2001 From: Derek Corniello Date: Tue, 28 Jul 2026 19:21:48 -0700 Subject: [PATCH 1/5] Document the crates.io freeze and the git-dependency relationship The README described a publish-first coupled-change flow and a semver range that no longer exist: mux-compiler consumes this repo as a git dependency on main, pinned by its Cargo.lock, so merging here is what makes a change available. Drop the crates.io version badge, which would otherwise advertise 0.5.0 as current indefinitely, and say plainly that published versions stay up but no new ones are coming. Also note that a sibling checkout and MUX_RUNTIME_SRC take precedence over the locked commit. That ordering is easy to forget and a stale sibling silently shadows the commit Cargo.lock names. --- README.md | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 373aa4c..5198ffc 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ **The runtime and standard library for [Mux](https://github.com/muxlang)** [![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat-square)](LICENSE) -[![crates.io](https://img.shields.io/crates/v/mux-runtime.svg?style=flat-square)](https://crates.io/crates/mux-runtime) [![Documentation](https://img.shields.io/badge/docs-online-blue.svg?style=flat-square)](https://mux-lang.dev) [![Sonar Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=muxlang_mux-runtime&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=muxlang_mux-runtime) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=muxlang_mux-runtime&metric=coverage)](https://sonarcloud.io/summary/new_code?id=muxlang_mux-runtime) @@ -16,8 +15,13 @@ Compiled Mux programs link against this library at compile time. It is plain, stable Rust with **no LLVM dependency** - so runtime and standard-library work -needs only a Rust toolchain, not the compiler's LLVM 22 + clang setup. Published -to crates.io as [`mux-runtime`](https://crates.io/crates/mux-runtime). +needs only a Rust toolchain, not the compiler's LLVM 22 + clang setup. + +> **crates.io is frozen.** Versions through 0.5.0 remain published and are not +> yanked, but no new ones will be. `mux-compiler` consumes this repo as a git +> dependency on `main`, pinned to an exact commit by its `Cargo.lock`, so +> merging here is what makes a change available. See +> [ADR 0004](https://github.com/muxlang/mux-context/blob/main/docs/decisions/0004-runtime-resolved-from-source.md). --- @@ -60,19 +64,27 @@ merge (shared CI runners are too noisy for a wall-clock threshold). ## Relationship to the compiler The compiler does not import this crate as Rust code - it links the built library -when producing executables and fetches the published crate from crates.io (pinning -a compatible semver range). For coupled local development, check this repo out as a -sibling of `mux-compiler` (the compiler resolves `../mux-runtime` automatically) or -set `MUX_RUNTIME_SRC` to a local checkout. +when producing executables. It resolves this repo as a git dependency on `main`, +pinned to an exact commit by its `Cargo.lock`, and builds the library from the +checkout cargo makes for that commit. + +For coupled local development, check this repo out as a sibling of +`mux-compiler` (the compiler resolves `../mux-runtime` automatically) or set +`MUX_RUNTIME_SRC` to a local checkout. Both take precedence over the locked +commit, so remember they are there - a stale sibling silently shadows the commit +`Cargo.lock` names. --- ## Versioning -Versioned independently of the compiler. The compiler pins a compatible semver -range and `mux --version` reports both, e.g. `mux 0.5.1 (runtime 0.5.0)`. A -coupled change ships as two steps: publish the runtime first, then bump the -compiler's `mux-runtime` pin. +The compiler identifies this repo by commit, not by version: `mux version` +reports the locked commit as semver build metadata, e.g. +`runtime v0.5.0+g4e2dc14`. A coupled change is one PR here and one in +`mux-compiler` - no publish step between them. + +The `version` field in `Cargo.toml` is inert while crates.io is frozen. Record +changes under an `## [Unreleased]` heading in the changelog instead. Full release steps: [muxlang/mux-context release process](https://github.com/muxlang/mux-context/blob/main/docs/release-process.md#mux-runtime). From 342a0af0ed3da424e56093f8cd3331990f9a5cb1 Mon Sep 17 00:00:00 2001 From: Derek Corniello Date: Tue, 28 Jul 2026 22:43:22 -0700 Subject: [PATCH 2/5] Describe prebuilt-only runtime resolution The compiler no longer builds this crate while compiling a Mux program, so a sibling checkout and MUX_RUNTIME_SRC no longer override anything. Coupled local development now means building here and pointing MUX_RUNTIME_LIB at the archive. Also note that the full feature set is always linked, and that this costs nothing: static linking discards archive members nothing references, so a program that never touches sql carries no SQLite. --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5198ffc..caf5453 100644 --- a/README.md +++ b/README.md @@ -68,11 +68,15 @@ when producing executables. It resolves this repo as a git dependency on `main`, pinned to an exact commit by its `Cargo.lock`, and builds the library from the checkout cargo makes for that commit. -For coupled local development, check this repo out as a sibling of -`mux-compiler` (the compiler resolves `../mux-runtime` automatically) or set -`MUX_RUNTIME_SRC` to a local checkout. Both take precedence over the locked -commit, so remember they are there - a stale sibling silently shadows the commit -`Cargo.lock` names. +For coupled local development, build this repo and point `MUX_RUNTIME_LIB` at the +resulting `target/debug/libmux_runtime.a`. That is the first thing the compiler +consults, so it overrides the library cargo built from the locked commit - +which also means a leftover `MUX_RUNTIME_LIB` will keep overriding it until you +unset it. + +The compiler never builds this crate while compiling a Mux program, and always +links the `full` feature set. Static linking discards archive members nothing +references, so a program that does not touch `sql` carries no SQLite. --- From fb8865faeab0da54e108f4b8129f2e1ab855b640 Mon Sep 17 00:00:00 2001 From: Derek Corniello Date: Tue, 28 Jul 2026 23:31:43 -0700 Subject: [PATCH 3/5] Correct how the compiler obtains the runtime archive The README described the compiler building the library from the git checkout cargo makes for the locked commit. That lookup was removed with the source-build path; the compiler links the archive from cargo's target/ directory, which takes an explicit `cargo build -p mux-runtime` because cargo emits a dependency's rlib and never its staticlib. --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index caf5453..2443b5c 100644 --- a/README.md +++ b/README.md @@ -65,8 +65,9 @@ merge (shared CI runners are too noisy for a wall-clock threshold). The compiler does not import this crate as Rust code - it links the built library when producing executables. It resolves this repo as a git dependency on `main`, -pinned to an exact commit by its `Cargo.lock`, and builds the library from the -checkout cargo makes for that commit. +pinned to an exact commit by its `Cargo.lock`, and links the archive cargo builds +into its `target/` directory. Producing that archive takes `cargo build -p +mux-runtime`: cargo emits a dependency's rlib and never its staticlib. For coupled local development, build this repo and point `MUX_RUNTIME_LIB` at the resulting `target/debug/libmux_runtime.a`. That is the first thing the compiler From b3c10f6834f4e385169838d1a9f10f25390cdd79 Mon Sep 17 00:00:00 2001 From: Derek Corniello Date: Tue, 28 Jul 2026 23:33:27 -0700 Subject: [PATCH 4/5] Update AGENTS for the git-dependency workflow The coupled-change steps still described publishing the runtime and bumping a semver pin, local coupled dev still described a sibling checkout and MUX_RUNTIME_SRC, and the release section still described publishing to crates.io. None of those mechanisms remain after ADR 0004. Also drop the note about keeping the full feature list in sync with full_runtime_features(): that parity test went with the feature-trimmed runtime builds. --- AGENTS.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e89d626..8eaa3ef 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -82,19 +82,24 @@ No LLVM/clang needed. CI runs fmt + clippy + tests + a SonarQube scan. - The compiler links the BUILT library; it does NOT import this crate's Rust code. - Changing exported FFI symbols/signatures is a coupled change with the compiler. - A coupled change (a new language feature needing a new runtime function) ships in - TWO steps: publish the runtime (new version) first, then bump the compiler's - `mux-runtime = "X.Y"` pin. -- Local coupled dev: check this out as a sibling of `mux-compiler` (resolved as - `../mux-runtime` automatically) or set `MUX_RUNTIME_SRC`. -- The compiler's `full_runtime_features()` parity test reads this `Cargo.toml`'s - `full` feature list - keep them in sync. + ONE step per repo and no publish: merge here, then move the compiler's pin with + `cargo update -p mux-runtime`. See + [ADR 0004](https://github.com/muxlang/mux-context/blob/main/docs/decisions/0004-runtime-resolved-from-source.md). +- Local coupled dev: build here and point `MUX_RUNTIME_LIB` at the resulting + `target/debug/libmux_runtime.a`. It is the first thing runtime resolution + consults, so it overrides the archive built from the locked commit - and a + leftover value keeps overriding it until unset. +- The compiler always links the `full` feature set; it no longer builds a + feature-trimmed runtime, so there is no feature-parity test to keep in sync. ## Release -Versioned independently of the compiler. Published manually from a local checkout -(MAINTAINER-ONLY, no token in CI). Full steps: +Not released on its own cadence. crates.io is frozen (versions through 0.5.0 stay +published, no new ones), and `mux-compiler` consumes this repo as a git dependency +pinned by its `Cargo.lock` - so merging to `main` is what makes a change +available. The `version` field is inert while the channel is frozen; record +changes under an `## [Unreleased]` changelog heading. Full steps: [muxlang/mux-context release process](https://github.com/muxlang/mux-context/blob/main/docs/release-process.md#mux-runtime). -Publish the runtime before bumping the compiler's `mux-runtime` pin. ## Related repos From 05a35fa8f10801b2f61f31f6d35d542147928a23 Mon Sep 17 00:00:00 2001 From: Derek Corniello Date: Wed, 29 Jul 2026 11:13:57 -0700 Subject: [PATCH 5/5] Address PR review: keep the downstream smoke test honest; add Unreleased Two findings from Greptile on #28, both valid. The Downstream Compiler Smoke Test passed this checkout to the compiler via MUX_RUNTIME_SRC. The compiler no longer reads that variable, so once the ADR 0004 change is on mux-compiler main this job would have linked the runtime its own Cargo.lock pins and silently stopped testing the runtime under review - while still reporting green. It now builds the archive from this checkout and forces it with MUX_RUNTIME_LIB, which is the resolution rule that survives. That matters beyond this job: this is the cross-repo check that catches FFI breaks at their origin, and the argument against automating the compiler's pin rests on it working. The README told contributors to record changes under an `Unreleased` heading that did not exist, while the changelog preamble still described crates.io publishing and semver pinning. Added the heading and replaced the preamble with the freeze and why there is no version to bump. --- .github/workflows/ci.yml | 23 ++++++++++++++++++----- CHANGELOG.md | 14 ++++++++++++-- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 71c9a97..b3b088a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -197,8 +197,12 @@ jobs: LLVM_SYS_221_STRICT_VERSIONING: "1" CC: clang-22 CXX: clang++-22 - # Build the runtime from THIS PR's checked-out source, not from crates.io. - MUX_RUNTIME_SRC: ${{ github.workspace }} + # Force the archive built from THIS PR's source below. The compiler no + # longer reads MUX_RUNTIME_SRC and never builds a runtime while compiling + # a program (muxlang/mux-context ADR 0004), so without this it would link + # the runtime its own Cargo.lock pins and this job would silently stop + # testing the runtime under review. + MUX_RUNTIME_LIB: ${{ github.workspace }}/target/debug/libmux_runtime.a steps: - name: Check out runtime (this PR) uses: actions/checkout@v4 @@ -223,9 +227,9 @@ jobs: - name: Cache Cargo registry and build uses: actions/cache@v4 with: - # Intentionally NOT caching ~/.cache/mux-lang: the compiler builds the - # runtime from source there, and this job exists to exercise THIS - # branch's runtime source, so it must rebuild it fresh every run. + # The runtime archive itself is rebuilt from this checkout every run + # (below) rather than restored, since exercising THIS branch's source + # is the whole point of the job. path: | ~/.cargo/registry ~/.cargo/git @@ -234,6 +238,15 @@ jobs: key: ${{ runner.os }}-downstream-cargo-${{ hashFiles('mux-compiler/Cargo.lock') }}-${{ hashFiles('Cargo.lock') }} restore-keys: | ${{ runner.os }}-downstream-cargo- + - name: Build this PR's runtime archive + # Compiled Mux programs link libmux_runtime.a, and cargo emits a + # dependency's rlib but never its staticlib - so the archive has to be + # built here explicitly, from this checkout. + run: | + set -euo pipefail + cargo build --locked + test -f "$MUX_RUNTIME_LIB" + - name: Compiler executable integration tests against runtime source # These tests compile and link .mux programs end to end, so an # undefined-symbol / FFI-signature break in the runtime fails here. diff --git a/CHANGELOG.md b/CHANGELOG.md index a3287fd..c41f874 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,18 @@ All notable changes to this project will be documented in this file. -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). + +Versions through 0.5.0 were published to crates.io. That channel is now frozen: +`mux-compiler` consumes this repo as a git dependency pinned to a commit by its +`Cargo.lock`, so merging to `main` is what makes a change available and there is +no version to bump. Record changes under `Unreleased` as part of the change +itself - see +[ADR 0004](https://github.com/muxlang/mux-context/blob/main/docs/decisions/0004-runtime-resolved-from-source.md). + +## [Unreleased] + +Nothing yet. ## [0.5.0] - 2026-07-13