diff --git a/.add/state.json b/.add/state.json
index c2eb7488..c943c4be 100644
--- a/.add/state.json
+++ b/.add/state.json
@@ -1,7 +1,7 @@
{
"project": "moon",
"stage": "production",
- "active_task": "resp3-type-fidelity",
+ "active_task": "monoio-ci-coverage",
"active_milestone": "v0-9-client-compat",
"tasks": {
"hotpath-lock-quickwins": {
@@ -200,12 +200,12 @@
},
"monoio-ci-coverage": {
"title": "CI runs the test suite on a monoio build (and clippy --all-targets)",
- "phase": "ground",
- "gate": "none",
+ "phase": "done",
+ "gate": "PASS",
"milestone": "v0-9-client-compat",
"depends_on": [],
"created": "2026-08-09T07:32:03+00:00",
- "updated": "2026-08-09T07:32:03+00:00"
+ "updated": "2026-08-10T08:35:14+00:00"
},
"client-identity-introspection": {
"title": "HELLO/COMMAND/ROLE/RESET identity + registry-dispatch reconciliation",
@@ -410,7 +410,7 @@
}
},
"created": "2026-06-11T03:18:21+00:00",
- "updated": "2026-08-10T06:47:03+00:00",
+ "updated": "2026-08-10T08:35:14+00:00",
"setup": {
"locked": true,
"locked_at": "2026-06-11T03:28:00+00:00",
diff --git a/.add/tasks/monoio-ci-coverage/TASK.md b/.add/tasks/monoio-ci-coverage/TASK.md
index 65dd2583..c0e09b0c 100644
--- a/.add/tasks/monoio-ci-coverage/TASK.md
+++ b/.add/tasks/monoio-ci-coverage/TASK.md
@@ -2,7 +2,7 @@
slug: monoio-ci-coverage · created: 2026-08-09 · stage: production
autonomy: auto
-phase: ground
+phase: done
@@ -15,33 +15,144 @@ phase: ground
@@ -53,11 +164,52 @@ Assumptions — lowest-confidence first:
```gherkin
-Scenario:
- Given
- When
- Then
- And # required for every rejection
+Scenario: a monoio-only defect blocks the merge # the whole point of the task
+ Given a PR whose change is wrong ONLY on the monoio dispatch path
+ And the tokio `check` job passes, because it never executes that path
+ When CI runs on the PR
+ Then `check-monoio` fails and the PR is not mergeable
+ And this is exactly the v0.8.6 inline-GET ACL bypass (#457), which shipped green
+
+Scenario: the job tests the shipped runtime, not the fallback
+ Given the `check-monoio` job
+ When it builds and runs tests
+ Then it uses the DEFAULT feature set (runtime-monoio)
+ And its command contains no `--no-default-features --features runtime-tokio`
+ And `MOON_NO_URING` is unset, so the io_uring driver is the one exercised
+
+Scenario: monoio-gated code is reachable at all
+ Given 30 `src/` files behind `#[cfg(feature = "runtime-monoio")]`, 3 of them test-only modules
+ And 26 integration test files referencing runtime-monoio
+ When `check-monoio` runs
+ Then those tests execute and are counted in its summary
+ And the tokio `check` job's own test count is unchanged
+
+Scenario: a known load-sensitive flake does not redden the job
+ Given `dbsize_offload_logical` fails under full-suite parallel load roughly 1 run in 3 (#459)
+ When `check-monoio` runs it
+ Then `--profile ci` retries it (retries = 2) and the job exits 0
+ And the log still reports it as FLAKY, so the signal is not swallowed
+
+Scenario: a genuine failure is never masked by retries
+ Given a test that fails deterministically on monoio
+ When `check-monoio` retries it twice
+ Then all 3 attempts fail and the job FAILS
+ And the job is REQUIRED, so the PR cannot merge
+
+Scenario: the runner being offline does not fake a pass # rejection
+ Given the self-hosted `moon-dev` runner is offline or its service is flapping
+ When a PR opens
+ Then `check-monoio` QUEUES and the PR is not green
+ And it never reports success or skips — a silent skip would restore the exact blind
+ spot this task exists to remove (see gotcha_selfhosted_runner_offline_service_active)
+
+Scenario: artifacts never collide with the tokio job # rejection
+ Given `check` and `check-monoio` may run concurrently on the same self-hosted runner
+ And they build INCOMPATIBLE feature sets from one checkout
+ When both run
+ Then each uses its own CARGO_TARGET_DIR
+ And neither invalidates the other's cache, and neither can execute the other's binaries
```
@@ -68,14 +220,52 @@ Scenario:
## 3 · CONTRACT — freeze the shape ▸ docs/05-step-3-contract.md
-```
- body: { }
- 200 -> { }
- 4xx -> { error: "" | "" }
-Schema:
+```yaml
+# .github/workflows/ci.yml — NEW job, sibling of `check`
+check-monoio:
+ name: Check (monoio — the shipped runtime)
+ runs-on: [self-hosted, moon-dev] # only Linux runner => only io_uring
+ env:
+ CARGO_TARGET_DIR: /home/tindang/ci-target/check-monoio # isolated from `check`
+ MOON_DISK_FREE_MIN_PCT: "0"
+ CARGO_BUILD_JOBS: "6"
+ # MOON_NO_URING deliberately UNSET — the tokio jobs set it; this job must not.
+ steps:
+ - uses: actions/checkout@v7
+ - uses: dtolnay/rust-toolchain@1.94.1
+ - uses: taiki-e/install-action@nextest
+ - name: Test (default features = runtime-monoio)
+ run: cargo nextest run --profile ci # NOT `cargo test` — no retries there
+ timeout-minutes: 30
```
-Status: DRAFT
+Scope — in: `.github/workflows/ci.yml` (one new job) · `CLAUDE.md` CI section (document it)
+Scope — out: `.config/nextest.toml` (the `ci` profile already covers this flake class — proven,
+ 5145 pass / 1 flaky / exit 0) · fixing #459 or the `blocking_peer_eof` flake ·
+ any `src/` change · the `MOON_NO_URING` epoll leg (a later task if wanted)
+
+Target: a monoio-only defect fails a PR. Verified by the negative control in §4 — deliberately
+ break a monoio-only path, confirm `check-monoio` fails while `check` still passes.
+
+Invariants:
+ - the tokio `check` job is untouched: same features, same steps, same test count
+ - no `continue-on-error`, no `if: always()`, nothing that lets the job pass while not running
+ - the job is REQUIRED in branch protection (otherwise it is advisory and will be ignored)
+
+Status: **FROZEN @ v1** — approved by Tin Dang, 2026-08-10
+
+Lowest-confidence flags surfaced AT the freeze (both accepted by the approver):
+1. **[contract] "REQUIRED" is not something this task can deliver alone.** Adding the job to
+ `ci.yml` makes it RUN; only branch protection makes it BLOCK. That is a repo admin setting, not
+ a workflow field, so the Must "the job is REQUIRED" is half-satisfiable by code. If it is never
+ added to branch protection the job is advisory, and an advisory red job gets ignored — which
+ would leave the blind spot open while *looking* closed, the worst outcome. **Approver accepted
+ this and owns the branch-protection change.** Cost if forgotten: the task reports done while
+ delivering nothing that can stop a merge.
+2. **[contract] Cold-cache build time is unmeasured.** Test time is a measured 80.3s, but the
+ default (monoio) feature set has never been built in CI, so the first run pays a full cold build
+ with no data behind it. If it proves punitive the remedy is cache warming or a prebuilt target
+ dir — never dropping the job, since 80s of test time is not the cost driver.
+### Negative control — planned, runs at VERIFY
-
+The config guard proves the job is DECLARED correctly; it cannot prove the job CATCHES anything.
+So the gate also requires a one-time negative control: introduce a deliberate defect on a
+monoio-only path, then confirm
+ - the tokio suite still PASSES (demonstrating the blind spot is real, not theoretical), and
+ - the monoio suite FAILS (demonstrating the new job closes it),
+then revert. Evidence goes in §6. Without this, "CI now covers monoio" is an unverified claim about
+a YAML file.
---
@@ -124,33 +341,67 @@ Constraints: do NOT change any test or the contract; allow-list packages only; a
## 6 · VERIFY — evidence + non-functional review ▸ docs/08-step-6-verify.md
-- [ ] all tests pass
-- [ ] coverage did not decrease
-- [ ] no test or contract was altered during build
-- [ ] the green was EARNED, not gamed — no overfit to fixtures, vacuous asserts, or stubbed-away logic (score with an adversarial refute-read — a subagent recommended under `autonomy: auto`; a confirmed cheat is HARD-STOP)
-- [ ] concurrency / timing of the risky operation is safe
-- [ ] no exposed secrets, injection openings, or unexpected dependencies
-- [ ] layering & dependencies follow CONVENTIONS.md
+- [x] all tests pass — `ci_covers_monoio` 5/5 under BOTH feature sets (it is runtime-agnostic, so
+ it must hold in each); `multi_queues_inline_get` 6/6 after the negative control was reverted.
+- [x] coverage did not decrease — +5 tests, +1 CI job. Nothing removed, and
+ `the_tokio_job_is_still_covered` exists specifically to prove tokio coverage was not traded away.
+- [x] no test or contract was altered during build — the frozen §3 was implemented verbatim
+ (runner, target dir, `nextest --profile ci`, no `continue-on-error`, `MOON_NO_URING` unset).
+- [x] the green was EARNED — see the NEGATIVE CONTROL below. The config guard alone proves only that
+ a YAML file says the right words; the control proves the job CATCHES a real defect.
+- [x] concurrency / timing — the job takes its own `CARGO_TARGET_DIR`, so it cannot race `check`'s
+ artifacts on the shared self-hosted runner. `--profile ci` supplies the retries that keep a
+ known load-sensitive flake class from reddening a required job.
+- [x] no exposed secrets / unexpected dependencies — no new crate; the guard test reads a repo file
+ with `std::fs` and parses it with string ops (no YAML dependency added).
+- [x] layering — CI config lives in `.github/workflows/`; the guard is a normal integration test.
- [ ] a person reviewed and approved the change
-### Build expectations — what "correct" looks like (fill BEFORE build; confirm each at the gate)
-> Pre-declare the OBSERVABLE outcomes a correct build must produce — derived from §2 SCENARIOS
-> + §3 CONTRACT — so this gate checks the build is RIGHT, not merely that tests are green. Each
-> row is evidence you can SEE, not a restatement of a test name.
-- [ ] — confirmed by
-- [ ] — confirmed by
+### NEGATIVE CONTROL — the evidence that matters
-### Deep checks — do not skim (fill the path that applies; the resolver judges which)
-- [ ] WIRING (code) — every new symbol is referenced; record where / how confirmed
-- [ ] DEAD-CODE (code) — no new unused or orphaned symbol introduced
-- [ ] SEMANTIC (prose / non-code) — read in full, not skimmed:
+A CI-config change can be green and still be worthless. So the claim "CI now covers monoio" was
+tested directly: a deliberate defect was injected on `try_inline_dispatch` (which is
+`cfg(feature = "runtime-monoio")`, so a tokio build cannot reach it), making inline GET answer
+`$6\r\nBROKEN\r\n`, and both suites were run against it.
+
+| leg | `acl_inline_read_enforcement` | `multi_queues_inline_get` | meaning |
+|---|---|---|---|
+| **tokio** — what CI ran before this task | 4 passed | **6 passed** | the blind spot is REAL: this defect ships green today |
+| **monoio** — what `check-monoio` runs | 4 passed | 3 passed, **3 FAILED** | the new job CATCHES it |
+
+An incidental confirmation arrived first: the tokio leg *compiled* while monoio did not, because
+`try_inline_dispatch` is cfg'd out entirely under tokio — the isolation is structural, not incidental.
+
+Reverted immediately via `git checkout --`; verified `0` residual `NEGATIVE CONTROL` / `BROKEN`
+markers in `src/`, a clean `git status` for `src/`, and `multi_queues_inline_get` back to 6/6.
+
+### Gates
+
+| gate | result |
+| --- | --- |
+| `ci_covers_monoio` (default/monoio) | 5 / 5 |
+| `ci_covers_monoio` (tokio) | 5 / 5 |
+| RED run before build | 4 failed / 1 passed — all four "no `check-monoio` job" |
+| negative control | tokio PASSES the defect · monoio FAILS it |
+| YAML structural parse | 9 jobs, `check-monoio` well-formed |
+| `cargo clippy --all-targets -D warnings` (both feature sets) | exit 0 |
+| `cargo fmt --check` | exit 0 |
+| pre-landing suite measurement (`moon-dev`, kernel 6.17) | **5145 passed, 1 flaky, 244 skipped, exit 0, 80.3s** |
### GATE RECORD
-Outcome:
-If RISK-ACCEPTED -> owner: · ticket: · expires: (never for a security gap)
-Reviewed by: · date:
+Outcome: **PASS**
+Reviewed by: Tin Dang · date: 2026-08-10
+
+Approved on the negative control, not on the config guard: the same deliberate monoio-only defect
+PASSES the tokio suite (6/6) and FAILS the new job (3/6). That is the difference between "a YAML
+file says the right words" and "the job catches defects".
+
+OPEN, and owned by the approver: `check-monoio` must be added to branch protection. Until then it
+RUNS but does not BLOCK — flagged at the freeze (§3 flag 1) and accepted there.
-
+
---
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0ac6cd0b..4e03e76e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -31,9 +31,12 @@ concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
+# Workflow-level env merges into EVERY job and a job cannot unset an inherited
+# key (an empty value is still a set variable). MOON_NO_URING therefore lives
+# per-job, never here — see `check-monoio`, which exists to run io_uring and was
+# silently running the timer fallback for as long as this was a global.
env:
CARGO_TERM_COLOR: always
- MOON_NO_URING: "1"
# 2026-07-13 CI optimization: no debuginfo in CI builds/tests — halves
# artifact size (faster rust-cache save/restore) and speeds linking.
# Backtraces in CI keep function names via symbol table; local builds
@@ -95,6 +98,9 @@ jobs:
runs-on: [self-hosted, moon-dev]
env:
CARGO_TARGET_DIR: /home/tindang/ci-target/check
+ # tokio's io_uring bridge is off in CI (it floods errors under load).
+ # Per-job, never workflow-level: `check-monoio` must not inherit it.
+ MOON_NO_URING: "1"
# Spawned test servers must not trip the diskfull write-pause on the
# VM's shared-volume mounts.
MOON_DISK_FREE_MIN_PCT: "0"
@@ -136,6 +142,55 @@ jobs:
run: "cargo nextest run --profile ci --no-default-features --features runtime-tokio,jemalloc,graph --lib -E 'test(graph::)'"
timeout-minutes: 5
+ # ── monoio — the runtime Moon actually SHIPS ────────────────────────
+ # Until this job existed, every CI job that EXECUTED tests did so under
+ # `--no-default-features --features runtime-tokio`. Moon's default feature
+ # set is runtime-monoio, and that is what ships on Linux — so 26 monoio
+ # integration test files and 30 monoio-gated src/ files were unreachable by
+ # CI. That is how the v0.8.6 inline-GET ACL bypass (#457) shipped green: it
+ # was wrong only on the monoio dispatch path, which no CI job could see.
+ #
+ # Self-hosted is not a preference: it is the only Linux runner, and therefore
+ # the only place monoio's io_uring driver executes at all. MOON_NO_URING must
+ # reach this job from NOWHERE — the point is io_uring. Its first cut left the
+ # job block clean but inherited `MOON_NO_URING: "1"` from workflow-level env,
+ # which a job cannot unset; every cooperative_yield() fell back to the
+ # sleep(ZERO) timer park and `monoio_yield_overhead_is_microscopic` failed at
+ # 1.45ms/yield. That var is now per-job and `ci_covers_monoio.rs` asserts both
+ # scopes.
+ #
+ # Measured before landing (moon-dev, kernel 6.17, 2026-08-10):
+ # cargo nextest run --profile ci -> 5145 passed, 1 flaky, 244 skipped,
+ # exit 0, 80.3s of test time. The `ci` profile's retries=2 absorbs the
+ # known load-sensitive flake class (#459) while still reporting it FLAKY,
+ # so the job is green from day one without hiding the signal.
+ #
+ # Guarded by tests/ci_covers_monoio.rs — weakening this job (wrong features,
+ # continue-on-error, bare `cargo test`, shared target dir) fails that suite.
+ check-monoio:
+ name: Check (monoio — the shipped runtime)
+ runs-on: [self-hosted, moon-dev]
+ env:
+ # MUST differ from `check`'s dir: the two jobs build incompatible feature
+ # sets from one checkout and can run concurrently on this runner.
+ CARGO_TARGET_DIR: /home/tindang/ci-target/check-monoio
+ MOON_DISK_FREE_MIN_PCT: "0"
+ CARGO_BUILD_JOBS: "6"
+ steps:
+ - uses: actions/checkout@v7
+ - uses: dtolnay/rust-toolchain@1.94.1
+ - uses: taiki-e/install-action@nextest
+
+ # Default features == runtime-monoio. Never --no-default-features here.
+ # `--profile ci` is load-bearing: a bare `cargo test` has no retries, and
+ # an intermittently-red required job gets disabled — which is worse than
+ # no job, because it still looks like coverage.
+ - name: Test (default features — monoio + io_uring)
+ run: cargo nextest run --profile ci
+ # 30m mirrors `check`: the budget is dominated by compiling test
+ # binaries on a cold CARGO_TARGET_DIR, not by the 80s of test time.
+ timeout-minutes: 30
+
# ── macOS — clippy + test (tokio), clippy (monoio/kqueue) ───────────
# Main-push only (2026-07-13 queue-killer round): macOS runners are the
# scarcest hosted pool and were the long pole on every PR. Development
@@ -285,6 +340,9 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
env:
+ # Spawns a real (tokio-built) moon on a GitHub-hosted runner, where
+ # io_uring may be unavailable or restricted by seccomp.
+ MOON_NO_URING: "1"
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: sccache
steps:
@@ -322,6 +380,11 @@ jobs:
runs-on: [self-hosted, moon-dev]
env:
CARGO_TARGET_DIR: /home/tindang/ci-target/client-compat
+ # Kept from when this was a workflow-level global, so this job's recorded
+ # waiver baseline stays comparable: the differ probes RESP wire shapes,
+ # which the I/O driver does not change. Drop it if the driver ever
+ # becomes part of what this job is meant to prove.
+ MOON_NO_URING: "1"
MOON_DISK_FREE_MIN_PCT: "0"
CARGO_BUILD_JOBS: "6"
steps:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b51bbf4c..185e31fb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
+- **CI now tests the runtime Moon actually ships (`check-monoio`).** Every CI job that *executed*
+ tests did so under `--no-default-features --features runtime-tokio,…`, while Moon's default
+ feature set — and what ships on Linux — is `runtime-monoio`. 26 monoio integration test files and
+ 30 monoio-gated `src/` files were unreachable by CI. That is how the v0.8.6 inline-GET ACL bypass
+ shipped green: it was wrong only on the monoio dispatch path, which no CI job could see. The new
+ job runs on the self-hosted Linux runner (the only place monoio's io_uring driver executes at
+ all), uses the default feature set, and invokes `cargo nextest run --profile ci` so the repo's
+ existing flake policy applies — a bare `cargo test` has no retries, and an intermittently-red
+ required job gets disabled, which is worse than no job because it still looks like coverage.
+ Measured before landing: **5145 passed, 1 flaky, 244 skipped, exit 0, 80.3s**.
+
+ Proven by negative control rather than asserted: a deliberate defect on the monoio-only
+ `try_inline_dispatch` path **passes** the tokio suite 6/6 and **fails** the new job 3/6.
+ `tests/ci_covers_monoio.rs` guards the job against being silently weakened — wrong feature set,
+ `continue-on-error`, a bare `cargo test`, or a shared `CARGO_TARGET_DIR` all fail the suite.
+
+ The job's first cut proved the premise but not the driver: `MOON_NO_URING: "1"` lived in the
+ workflow-level `env:`, which merges into every job and cannot be unset by one, so the job whose
+ whole point is io_uring ran with io_uring force-disabled. `monoio_yield_overhead_is_microscopic`
+ caught it at 1.45ms/yield (the `sleep(ZERO)` timer-park signature). That variable is now per-job,
+ and `ci_covers_monoio.rs` asserts **both** scopes.
+
- **Client-compat harness: raw-RESP diff against a real `redis-server`
(`scripts/test-client-compat.sh`).** Moon's existing Redis comparison
(`scripts/test-commands.sh`) goes through `redis-cli`, which renders replies
diff --git a/tests/ci_covers_monoio.rs b/tests/ci_covers_monoio.rs
new file mode 100644
index 00000000..38427494
--- /dev/null
+++ b/tests/ci_covers_monoio.rs
@@ -0,0 +1,191 @@
+//! CI must execute the runtime Moon actually ships.
+//!
+//! Moon's default feature set is `runtime-monoio`, and that is what ships on
+//! Linux. Yet every CI job that EXECUTED tests did so under
+//! `--no-default-features --features runtime-tokio,…` — 26 monoio integration
+//! test files and 30 monoio-gated `src/` files were unreachable by CI. That is
+//! how the v0.8.6 inline-GET ACL bypass (#457) shipped green: it was wrong only
+//! on the monoio path, and no CI job could see it.
+//!
+//! These tests guard the FIX, not the bug. They read `.github/workflows/ci.yml`
+//! and assert the monoio job exists and has not been quietly weakened — because
+//! the failure mode of CI coverage is silent: a job that stops running, or is
+//! switched to the wrong feature set, looks identical to a green build.
+//!
+//! Deliberately a repo-config test, not a runtime test: nothing observable at
+//! runtime can tell you which runtime CI exercised.
+
+use std::path::PathBuf;
+
+fn workflow() -> String {
+ let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(".github/workflows/ci.yml");
+ std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("cannot read {}: {e}", path.display()))
+}
+
+/// Return the body of a top-level job block, from ` :` to the next
+/// top-level job key at the same two-space indent.
+fn job_block(yaml: &str, name: &str) -> Option {
+ let needle = format!("\n {name}:\n");
+ let start = yaml.find(&needle)? + 1;
+ let rest = &yaml[start + needle.len() - 1..];
+ // Next line that begins with exactly two spaces then a non-space: the next job.
+ let mut end = rest.len();
+ for (idx, _) in rest.match_indices('\n') {
+ let line = &rest[idx + 1..];
+ let after_indent = line.strip_prefix(" ");
+ if let Some(a) = after_indent
+ && !a.starts_with(' ')
+ && !a.starts_with('#')
+ && a.contains(':')
+ {
+ end = idx + 1;
+ break;
+ }
+ }
+ Some(rest[..end].to_string())
+}
+
+/// Body of the top-level `env:` mapping — the block every job inherits.
+/// Empty string when the workflow declares none.
+fn workflow_env_block(yaml: &str) -> String {
+ let Some(start) = yaml.find("\nenv:\n") else {
+ return String::new();
+ };
+ let rest = &yaml[start + "\nenv:\n".len()..];
+ // Ends at the first line that is not indented and not blank/comment.
+ let mut end = rest.len();
+ for (idx, _) in rest.match_indices('\n') {
+ let line = &rest[idx + 1..];
+ let head = line.split('\n').next().unwrap_or("");
+ if !head.is_empty() && !head.starts_with(' ') && !head.starts_with('#') {
+ end = idx + 1;
+ break;
+ }
+ }
+ rest[..end].to_string()
+}
+
+#[test]
+fn ci_has_a_job_that_tests_the_default_monoio_runtime() {
+ let yaml = workflow();
+ let job = job_block(&yaml, "check-monoio").expect(
+ "ci.yml has no `check-monoio` job. CI would then execute tests ONLY under \
+ runtime-tokio, leaving the shipped runtime untested — the gap that let the \
+ v0.8.6 inline-GET ACL bypass (#457) ship green.",
+ );
+
+ let tests = job
+ .lines()
+ .filter(|l| l.contains("cargo nextest run") || l.contains("cargo test"))
+ .collect::>();
+ assert!(
+ !tests.is_empty(),
+ "`check-monoio` runs no test command at all; it would be theatre.\n{job}"
+ );
+
+ for line in &tests {
+ assert!(
+ !line.contains("--no-default-features"),
+ "`check-monoio` must test the DEFAULT (monoio) feature set. This line opts out \
+ of it, which silently makes the job a duplicate of the tokio `check` job:\n {line}"
+ );
+ assert!(
+ !line.contains("runtime-tokio"),
+ "`check-monoio` must not select runtime-tokio:\n {line}"
+ );
+ }
+}
+
+#[test]
+fn the_monoio_job_uses_the_ci_profile_so_known_flakes_retry() {
+ // The suite has a load-sensitive flake class (fixed-port listeners, kill-9
+ // timing under full-suite parallel load). `.config/nextest.toml`'s `ci`
+ // profile carries `retries = 2` for exactly that. A bare `cargo test` has
+ // no retries, so it would redden the job intermittently — and an
+ // intermittently-red required job gets disabled, which is worse than no
+ // job because it still looks like coverage.
+ let yaml = workflow();
+ let job = job_block(&yaml, "check-monoio").expect("no `check-monoio` job");
+
+ assert!(
+ job.contains("cargo nextest run --profile ci"),
+ "`check-monoio` must run `cargo nextest run --profile ci`, never a bare \
+ `cargo test` — the profile is what supplies retries for the known flake class.\n{job}"
+ );
+}
+
+#[test]
+fn the_monoio_job_cannot_pass_without_running() {
+ // Three ways a job can look green while proving nothing.
+ let yaml = workflow();
+ let job = job_block(&yaml, "check-monoio").expect("no `check-monoio` job");
+
+ assert!(
+ !job.contains("continue-on-error"),
+ "`check-monoio` must not set continue-on-error — a monoio-only failure has to \
+ be able to block a merge, or the job is advisory and will be ignored.\n{job}"
+ );
+ assert!(
+ !job.contains("MOON_NO_URING"),
+ "`check-monoio` must NOT set MOON_NO_URING. The tokio jobs set it; this job exists \
+ to exercise the io_uring driver that actually ships on Linux.\n{job}"
+ );
+ // A clean job block is not enough: workflow-level `env:` merges into every
+ // job, and a job cannot unset an inherited key (an empty value is still a
+ // set variable to `env::var_os`). This assertion is the one the first cut of
+ // this job was missing — the job block was clean, the comment said io_uring
+ // was the point, and the workflow-level `MOON_NO_URING: "1"` silently forced
+ // every `cooperative_yield()` onto the `sleep(ZERO)` timer fallback.
+ // `monoio_yield_overhead_is_microscopic` caught it at 1.45ms/yield.
+ assert!(
+ !workflow_env_block(&yaml).contains("MOON_NO_URING"),
+ "workflow-level `env:` must NOT define MOON_NO_URING — it merges into `check-monoio`, \
+ which cannot unset it, and force-disables the io_uring driver that job exists to \
+ exercise. Set it per-job on the tokio jobs instead."
+ );
+ assert!(
+ job.contains("self-hosted"),
+ "`check-monoio` must run on the self-hosted Linux runner — it is the only runner \
+ where monoio's io_uring driver executes at all.\n{job}"
+ );
+}
+
+#[test]
+fn the_monoio_job_does_not_share_artifacts_with_the_tokio_job() {
+ // `check` and `check-monoio` build INCOMPATIBLE feature sets from one
+ // checkout and can run concurrently on the same self-hosted runner. Sharing
+ // a target dir would make them invalidate each other's cache continuously,
+ // and could let one job execute the other's binaries.
+ let yaml = workflow();
+ let mono = job_block(&yaml, "check-monoio").expect("no `check-monoio` job");
+ let tokio = job_block(&yaml, "check").expect("no `check` job");
+
+ let dir_of = |j: &str| -> Option {
+ j.lines()
+ .find(|l| l.trim_start().starts_with("CARGO_TARGET_DIR:"))
+ .map(|l| l.split(':').nth(1).unwrap_or("").trim().to_string())
+ };
+
+ let m = dir_of(&mono).expect("`check-monoio` must set its own CARGO_TARGET_DIR");
+ let t = dir_of(&tokio);
+ if let Some(t) = t {
+ assert_ne!(
+ m, t,
+ "`check-monoio` and `check` must not share CARGO_TARGET_DIR ({m}) — they build \
+ incompatible feature sets and may run concurrently on the same runner."
+ );
+ }
+}
+
+#[test]
+fn the_tokio_job_is_still_covered() {
+ // This task ADDS a runtime to CI; it must not trade one blind spot for
+ // another. tokio remains a supported runtime (portability, Windows).
+ let yaml = workflow();
+ let tokio = job_block(&yaml, "check").expect("no `check` job");
+ assert!(
+ tokio.contains("runtime-tokio"),
+ "the tokio `check` job must keep testing runtime-tokio — adding monoio coverage \
+ must not remove tokio coverage.\n{tokio}"
+ );
+}