From ece94b7bb9d318ea8629195cc5626328c2acfa58 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 20 Sep 2026 04:22:46 +0000 Subject: [PATCH 1/4] Chore(deps): Bump rustix from 1.1.4 to 1.1.5 Bumps [rustix](https://github.com/bytecodealliance/rustix) from 1.1.4 to 1.1.5. - [Release notes](https://github.com/bytecodealliance/rustix/releases) - [Changelog](https://github.com/bytecodealliance/rustix/blob/main/CHANGES.md) - [Commits](https://github.com/bytecodealliance/rustix/compare/v1.1.4...v1.1.5) --- updated-dependencies: - dependency-name: rustix dependency-version: 1.1.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- repository-process-spawn/Cargo.toml | 2 +- xtask/Cargo.toml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5b15c6b..2ca1d806 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -413,9 +413,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" dependencies = [ "bitflags", "errno", diff --git a/Cargo.toml b/Cargo.toml index 230d7cf9..436cc956 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ repository-tasks = [] blake3 = { version = "=1.8.5", default-features = false, features = ["pure", "std"] } cap-fs-ext = { version = "=4.0.2", default-features = false, features = ["std"] } cap-std = { version = "=4.0.2", default-features = false } -rustix = { version = "=1.1.4", default-features = false, features = ["fs", "std"] } +rustix = { version = "=1.1.5", default-features = false, features = ["fs", "std"] } [dev-dependencies] allocation-counter = { version = "=0.8.1", default-features = false } diff --git a/repository-process-spawn/Cargo.toml b/repository-process-spawn/Cargo.toml index 1e6a5e4a..42d334a9 100644 --- a/repository-process-spawn/Cargo.toml +++ b/repository-process-spawn/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" publish = false [dependencies] -rustix = { version = "=1.1.4", default-features = false, features = ["process", "std"] } +rustix = { version = "=1.1.5", default-features = false, features = ["process", "std"] } [lints] workspace = true diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index a1089678..0d8b7932 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -36,7 +36,7 @@ md-5 = { version = "=0.11.0", default-features = false, optional = true } # Dedicated unsafe boundary sets exact child working directories by descriptor. repository-process-spawn = { path = "../repository-process-spawn", optional = true } # Safe POSIX descriptor flags and process-group signaling bound repository tools. -rustix = { version = "=1.1.4", default-features = false, features = ["fs", "process", "std"], optional = true } +rustix = { version = "=1.1.5", default-features = false, features = ["fs", "process", "std"], optional = true } # Serde drives duplicate-refusing repository JSON admission; no types escape xtask. serde = { version = "=1.0.229", default-features = false, features = ["std"], optional = true } # Typed JSON admission checks the committed documentation-tool lock graph. From afb5f000c2803c9226d7678ce0905d676723e474 Mon Sep 17 00:00:00 2001 From: James Ross Date: Sat, 3 Oct 2026 17:22:19 -0700 Subject: [PATCH 2/4] Build: reconcile rustix admission and fuzz graph (#102) --- CHANGELOG.md | 2 ++ .../cap-std-and-cap-fs-ext-4.0.2.md | 17 +++++++++++------ fuzz/Cargo.lock | 4 ++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d51e0c06..65ada11b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ after its public API and format compatibility policies are established. ## [Unreleased] +- Update rustix to 1.1.5 across the library, repository tools, process-spawn boundary and fuzz lockfile, retaining the existing filesystem and process contracts (#102). + - Update the repository-only YAML parser to yaml-rust2 0.13.0 and refresh its dependency admission, retaining existing workflow and Dependabot refusal expectations (#103). - Update the development-only Markdown validation graph and exact admission policy to markdownlint-cli2 0.23.3, addressing the js-yaml, smol-toml and markdown-it advisories while documenting the separate remaining braces advisory (#106). diff --git a/docs/dependencies/cap-std-and-cap-fs-ext-4.0.2.md b/docs/dependencies/cap-std-and-cap-fs-ext-4.0.2.md index f86da985..215bbf6e 100644 --- a/docs/dependencies/cap-std-and-cap-fs-ext-4.0.2.md +++ b/docs/dependencies/cap-std-and-cap-fs-ext-4.0.2.md @@ -1,7 +1,8 @@ -# Dependency Admission: cap-std, cap-fs-ext 4.0.2, and rustix 1.1.4 +# Dependency Admission: cap-std, cap-fs-ext 4.0.2, and rustix 1.1.5 - Status: Accepted for repository-task and segment-store filesystem boundaries - Date: 2026-07-26 +- Rustix admission updated: 2026-10-03 (#102) - Owner: Keep repository verification - Upstream: [bytecodealliance/cap-std](https://github.com/bytecodealliance/cap-std) @@ -10,7 +11,7 @@ Keep admits the exactly pinned `cap-std` 4.0.2 and `cap-fs-ext` 4.0.2 packages for the library's segment-store filesystem adapter and behind the `xtask` -crate's `repository-tasks` feature. The library also admits Rustix 1.1.4 for +crate's `repository-tasks` feature. The library also admits Rustix 1.1.5 for safe Linux filesystem-profile inspection and no-symlink root opening; `xtask` uses the same exact version behind `repository-tasks`. @@ -91,7 +92,7 @@ The locked non-Windows graph introduced for this boundary is: - `linux-raw-sys` 0.12.1; - `maybe-owned` 0.3.4; - `once_cell` 1.21.4; -- `rustix` 1.1.4; and +- `rustix` 1.1.5; and - `rustix-linux-procfs` 0.1.1. Windows resolution additionally retains the locked `windows-sys`, @@ -108,9 +109,7 @@ license through repository policy. Rustix declares `Apache-2.0 OR MIT`. The locked `winx` 0.36.4 transitive package declares only `Apache-2.0 WITH LLVM-exception`, so `deny.toml` admits that exact package and license combination rather than broadening the global license allowlist. -Their manifests declare no Rust-version floor. Compatibility is therefore -established only by Keep's pinned stable, MSRV, debug, release, Clippy, -dependency-policy, and advisory lanes. +The cap-std and cap-fs-ext manifests declare no Rust-version floor. Rustix 1.1.5 declares Rust 1.65, below Keep's pinned Rust 1.96.0; its previous 1.1.4 release declared 1.63. The version floor is compatibility metadata, not execution evidence. Keep's debug, release, Clippy, dependency-policy and advisory lanes remain required for the updated graph. The admitted packages and their platform dependencies may contain unsafe code around operating-system calls and handles. Keep-owned code invokes only their @@ -140,3 +139,9 @@ whole-process-group cleanup tests on every supported platform. Reopen this admission if either direct version, selected feature, resolved graph, license, supported platform, handle-retention invariant, or repository-task-only boundary changes. + +## Rustix 1.1.5 update + +The root, repository-task and isolated process-spawn manifests select the same exact Rustix version. The independently locked fuzz workspace also selects 1.1.5. The upgrade does not change selected features, Keep source or existing test expectations; filesystem admission, writer/reader locks, typed failures and bounded subprocess cleanup retain their existing contracts. + +Current validation must exercise the admitted Linux filesystem and process boundaries with the new graph. Historical recovery, crash and benchmark receipts remain evidence for their recorded builds, not new measurements of this dependency release. Finite conformance and regression runs do not establish universal equivalence or validation of every upstream platform. diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 7d421ee9..c7c687fe 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -288,9 +288,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rustix" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" dependencies = [ "bitflags", "errno", From 01988bc4f07257dd8fdf1fb19675257cc5e9ad56 Mon Sep 17 00:00:00 2001 From: James Ross Date: Sat, 3 Oct 2026 17:38:00 -0700 Subject: [PATCH 3/4] Fix: isolate locator children from golden writer handoffs (#178) --- CHANGELOG.md | 2 + .../durable-locator-isolation.md | 29 ++++++++++ .../controlled-inheritance.txt | 29 ++++++++++ .../durable-locator-isolation/hosted-red.txt | 8 +++ .../probe-source.txt | 57 +++++++++++++++++++ tests/durable_locator.rs | 19 +++++++ .../durable_locator_laws.rs | 4 +- tests/golden_file_worldline/suite.rs | 3 - 8 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 docs/testing-evidence/durable-locator-isolation.md create mode 100644 docs/testing-evidence/durable-locator-isolation/controlled-inheritance.txt create mode 100644 docs/testing-evidence/durable-locator-isolation/hosted-red.txt create mode 100644 docs/testing-evidence/durable-locator-isolation/probe-source.txt create mode 100644 tests/durable_locator.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index d51e0c06..a0f94409 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ after its public API and format compatibility policies are established. ## [Unreleased] +- Isolate durable locator subprocess laws from golden-store writer handoffs so their child launches cannot inherit another law's live lock descriptions (#178). + - Update the repository-only YAML parser to yaml-rust2 0.13.0 and refresh its dependency admission, retaining existing workflow and Dependabot refusal expectations (#103). - Update the development-only Markdown validation graph and exact admission policy to markdownlint-cli2 0.23.3, addressing the js-yaml, smol-toml and markdown-it advisories while documenting the separate remaining braces advisory (#106). diff --git a/docs/testing-evidence/durable-locator-isolation.md b/docs/testing-evidence/durable-locator-isolation.md new file mode 100644 index 00000000..9333bd6b --- /dev/null +++ b/docs/testing-evidence/durable-locator-isolation.md @@ -0,0 +1,29 @@ +# Durable locator process isolation + +Change kind: test-isolation bug fix for #178. Owner: `@flyingrobots`. The product oracles remain exact durable bytes, catalogued layout identity, typed refusal and original I/O sources; no expected product outcome changes. This record distinguishes observed runtime failure, a controlled kernel experiment, and the scheduling boundary introduced by the correction. + +## Observed RED + +Main `7a21faebdbed38c386db14873966d433754c6eb4` failed the release golden worldline law `suite::durable_layout_laws::supplied_range_layouts_cannot_replace_the_catalogued_target_binding` with `WriterLock { source: Busy }` in [run 37164344603](https://github.com/flyingrobots/keep/actions/runs/37164344603). The [failure excerpt](durable-locator-isolation/hosted-red.txt) retains the original diagnostics and timestamps with line-end whitespace normalized. Earlier green runs are not substituted for this observed RED. + +The failed law calls the real store fixture before asserting layout refusal. That fixture relinquishes and reacquires writer authority between catalog publication, migration and retention publication. Two sibling locator laws launched child processes from the same test executable. A child can inherit another thread's open flock descriptions until exec, extending their lifetime past the parent guard's drop. The log does not identify which handoff refused or prove that this schedule caused the hosted failure. + +## Controlled mechanism and limits + +On parent `3165890e9291cfb5fe10e81a9d7cd151f3e59464`, a separate diagnostic crate opened production Keep authority, held a child before exec with pipe handshakes, dropped the parent authority and observed exact public `WriterLockAcquireError::Busy`. After releasing and reaping the child, public acquisition succeeded. The [receipt](durable-locator-isolation/controlled-inheritance.txt) and [diagnostic source](durable-locator-isolation/probe-source.txt) preserve the experiment. No sleep or probabilistic workload determines that schedule. + +The diagnostic's isolated unsafe pre-exec hook performs only raw pipe reads and writes; it is not linked into Keep, added to the test suite, or used as a merge gate. It demonstrates an actual inherited-descriptor lifetime, not the exact unobserved CI trace. A separate strace run delaying syscall completion passed the original suite; it found no failing schedule and supplies no proof of absence. Keep production source and the failing test's assertions are identical between the observed RED revision and this parent. + +## Correction and retained contracts + +The two existing locator laws now run in `tests/durable_locator.rs`, a separate integration-test executable. Its parent creates no store or writer authority; each admitted child runs exactly one locator law serially and creates its own stores. The golden worldline executable no longer launches those children. Parallel execution of the two executables does not share their descriptor tables, so a locator child cannot inherit the golden executable's store locks. + +The locator laws still check that a relative handle keeps its original store after a working-directory change and that a deleted working directory preserves its exact NotFound cause. The golden layout-binding law retains its exact LayoutMissing checks and unchanged output sentinel. No law is deleted, ignored, retried or globally serialized. Only the locator child selectors change with their test-module coordinates. Shared fixture imports allow unused partial-record constructors only in the new locator executable; those constructors remain exercised by the golden suite. + +Keep's authority handoffs, flock semantics, public errors, APIs, formats and recovery protocols do not change. This correction removes the demonstrated interference mechanism from this suite without asserting that every possible cause of Busy has been eliminated. Any new failure remains a defect to diagnose, not a retry instruction. + +## Validation profile + +These unchanged laws remain medium tests using owned Linux ext4 scratch and real filesystem/process operations. The locator child retains its existing 20-second watchdog; that is an execution ceiling, not a latency promise. Focused validation runs both executables in debug and release inside copied Docker source, followed by the required stable-candidate chain and independent exact-head review. Commands and terminal results are recorded on the corrective PR; no pending execution is described as passing here. + +The original ordinary-Cargo resource enforcement gaps remain disclosed in the [enforcement profile](../testing/enforcement.md). Moving existing assertions does not establish new per-test memory limits, egress isolation, suite latency measurements or exhaustive scheduler exploration. #106's unrelated version-update waiver does not cover this change. No new assertion calibration or artificial fixture-count test is substituted for the existing runtime failure and retained product laws. Retire the separation if subprocess creation is removed or another verified process-isolation boundary makes inherited lock interference impossible. diff --git a/docs/testing-evidence/durable-locator-isolation/controlled-inheritance.txt b/docs/testing-evidence/durable-locator-isolation/controlled-inheritance.txt new file mode 100644 index 00000000..e50ed7c4 --- /dev/null +++ b/docs/testing-evidence/durable-locator-isolation/controlled-inheritance.txt @@ -0,0 +1,29 @@ + Locking 50 packages to latest Rust 1.96.0 compatible versions + Adding rustix v1.1.4 (available: v1.1.5) + Compiling rustix v1.1.4 + Compiling linux-raw-sys v0.12.1 + Compiling io-lifetimes v2.0.4 + Compiling io-lifetimes v3.0.1 + Compiling bitflags v2.13.1 + Compiling io-extras v0.19.0 + Compiling once_cell v1.21.4 + Compiling find-msvc-tools v0.1.9 + Compiling cap-primitives v4.0.2 + Compiling shlex v2.0.1 + Compiling ipnet v2.12.0 + Compiling maybe-owned v0.3.4 + Compiling cap-std v4.0.2 + Compiling ambient-authority v0.0.2 + Compiling cap-fs-ext v4.0.2 + Compiling constant_time_eq v0.4.2 + Compiling cfg-if v1.0.4 + Compiling arrayvec v0.7.8 + Compiling arrayref v0.3.9 + Compiling cc v1.3.0 + Compiling blake3 v1.8.5 + Compiling rustix-linux-procfs v0.1.1 + Compiling fs-set-times v0.20.3 + Compiling keep v0.0.0 (/build/keep178-parent-source) + Compiling keep-inherited-lock-probe v0.0.0 (/build/keep178-inheritance-probe) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.14s +controlled pre-exec child: parent drop => Busy; child exec/reap => acquired diff --git a/docs/testing-evidence/durable-locator-isolation/hosted-red.txt b/docs/testing-evidence/durable-locator-isolation/hosted-red.txt new file mode 100644 index 00000000..97700108 --- /dev/null +++ b/docs/testing-evidence/durable-locator-isolation/hosted-red.txt @@ -0,0 +1,8 @@ +Rust quality gates Test release profile 2026-10-04T00:24:47.3413241Z ---- suite::durable_layout_laws::supplied_range_layouts_cannot_replace_the_catalogued_target_binding stdout ---- +Rust quality gates Test release profile 2026-10-04T00:24:47.3414320Z Error: WriterLock { source: Busy } +Rust quality gates Test release profile 2026-10-04T00:24:47.3414537Z +Rust quality gates Test release profile 2026-10-04T00:24:47.3414541Z +Rust quality gates Test release profile 2026-10-04T00:24:47.3414631Z failures: +Rust quality gates Test release profile 2026-10-04T00:24:47.3415069Z suite::durable_layout_laws::supplied_range_layouts_cannot_replace_the_catalogued_target_binding +Rust quality gates Test release profile 2026-10-04T00:24:47.3415356Z +Rust quality gates Test release profile 2026-10-04T00:24:47.3415561Z test result: FAILED. 51 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.67s diff --git a/docs/testing-evidence/durable-locator-isolation/probe-source.txt b/docs/testing-evidence/durable-locator-isolation/probe-source.txt new file mode 100644 index 00000000..d8231c6e --- /dev/null +++ b/docs/testing-evidence/durable-locator-isolation/probe-source.txt @@ -0,0 +1,57 @@ +Diagnostic Cargo.toml (replace the Keep path with an isolated parent checkout): + +[package] +name = "keep-inherited-lock-probe" +version = "0.0.0" +edition = "2024" +[dependencies] +keep = { path = "/build/keep178-parent-source" } +rustix = { version = "=1.1.4", default-features = false, features = ["pipe", "std"] } + +Diagnostic src/main.rs: + +//! Isolated diagnostic crate; never linked into Keep or used as a CI gate. +//! A pipe handshake controls the inherited-descriptor lifetime across pre-exec. +//! The hook performs only async-signal-safe read/write syscalls, without allocation. +use std::{error::Error, io, os::unix::process::CommandExt, path::Path, process::Command}; +use keep::{FilesystemPlatformAdmission, FilesystemWriterLock, WriterLockAcquireError}; +use rustix::pipe::{PipeFlags, pipe_with}; + +fn main() -> Result<(), Box> { + let root_arg = std::env::args().nth(1).ok_or("scratch root argument missing")?; + let root = Path::new(&root_arg); + std::fs::create_dir(root)?; + let authority = FilesystemPlatformAdmission::initialize(root)?; + let (ready_read, ready_write) = pipe_with(PipeFlags::CLOEXEC)?; + let (release_read, release_write) = pipe_with(PipeFlags::CLOEXEC)?; + let mut command = Command::new("/bin/true"); + // SAFETY: the child hook touches only its captured owned descriptors, uses + // async-signal-safe raw read/write, and does not allocate, lock or unwind. + unsafe { + command.pre_exec(move || { + if rustix::io::write(&ready_write, &[1])? != 1 { + return Err(io::Error::from(io::ErrorKind::WriteZero)); + } + let mut byte = [0]; + if rustix::io::read(&release_read, &mut byte)? != 1 { + return Err(io::Error::from(io::ErrorKind::UnexpectedEof)); + } + Ok(()) + }); + } + let child = std::thread::spawn(move || command.status()); + let mut ready = [0]; + assert_eq!(rustix::io::read(&ready_read, &mut ready)?, 1); + drop(authority); + let during = FilesystemWriterLock::try_acquire(root); + // Release before asserting so even a failed diagnostic reaps its child. + assert_eq!(rustix::io::write(&release_write, &[1])?, 1); + let status = child.join().map_err(|_| "spawn thread panicked")??; + assert!(status.success()); + assert!(matches!(during, Err(WriterLockAcquireError::Busy)), + "a child before exec must retain inherited writer authority"); + let after = FilesystemWriterLock::try_acquire(root)?; + drop(after); + println!("controlled pre-exec child: parent drop => Busy; child exec/reap => acquired"); + Ok(()) +} diff --git a/tests/durable_locator.rs b/tests/durable_locator.rs new file mode 100644 index 00000000..83259ae9 --- /dev/null +++ b/tests/durable_locator.rs @@ -0,0 +1,19 @@ +//! This executable owns the process-isolated durable locator laws. +//! +//! Child creation must not share a process with golden-store writer handoffs: +//! a child can inherit a live flock description until exec. Separate test +//! executables have separate descriptor tables even when Cargo runs in parallel. +//! The locator parent owns no store; each admitted child runs one law serially. + +#![cfg(target_os = "linux")] + +#[path = "golden_file_worldline/durable_fixture.rs"] +#[allow( + dead_code, + reason = "locator laws share complete-store setup; other golden laws own partial-record cases" +)] +mod durable_fixture; +#[path = "golden_file_worldline/durable_locator_laws.rs"] +mod durable_locator_laws; +#[path = "segment_filesystem_stage/sandbox.rs"] +mod durable_sandbox; diff --git a/tests/golden_file_worldline/durable_locator_laws.rs b/tests/golden_file_worldline/durable_locator_laws.rs index f435f326..0a954568 100644 --- a/tests/golden_file_worldline/durable_locator_laws.rs +++ b/tests/golden_file_worldline/durable_locator_laws.rs @@ -18,7 +18,7 @@ use super::durable_sandbox::TestDirectory; type TestResult = Result<(), Box>; const CHILD: &str = "KEEP_DURABLE_LOCATOR_CHILD"; -const LAW: &str = "suite::durable_locator_laws::relative_store_handles_keep_their_initial_store_after_a_directory_change"; +const LAW: &str = "durable_locator_laws::relative_store_handles_keep_their_initial_store_after_a_directory_change"; #[test] fn relative_store_handles_keep_their_initial_store_after_a_directory_change() @@ -29,7 +29,7 @@ fn relative_store_handles_keep_their_initial_store_after_a_directory_change() #[test] fn an_unresolvable_relative_locator_preserves_its_io_cause() -> Result<(), Box> { run_isolated( - "suite::durable_locator_laws::an_unresolvable_relative_locator_preserves_its_io_cause", + "durable_locator_laws::an_unresolvable_relative_locator_preserves_its_io_cause", deleted_current_directory, ) } diff --git a/tests/golden_file_worldline/suite.rs b/tests/golden_file_worldline/suite.rs index 7fffef31..7519b499 100644 --- a/tests/golden_file_worldline/suite.rs +++ b/tests/golden_file_worldline/suite.rs @@ -31,9 +31,6 @@ mod durable_fixture; #[path = "durable_layout_laws.rs"] mod durable_layout_laws; #[cfg(target_os = "linux")] -#[path = "durable_locator_laws.rs"] -mod durable_locator_laws; -#[cfg(target_os = "linux")] #[path = "durable_namespace_laws.rs"] mod durable_namespace_laws; #[cfg(target_os = "linux")] From f9a9c2ec8614ce9f905ef97aeb2163b5acc5982a Mon Sep 17 00:00:00 2001 From: James Ross Date: Sat, 3 Oct 2026 17:40:33 -0700 Subject: [PATCH 4/4] Fix: retain locator module scope in isolated test executable (#178) --- .../durable-locator-isolation.md | 2 +- tests/durable_locator.rs | 12 ++---------- tests/durable_locator/suite.rs | 16 ++++++++++++++++ .../durable_locator_laws.rs | 4 ++-- 4 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 tests/durable_locator/suite.rs diff --git a/docs/testing-evidence/durable-locator-isolation.md b/docs/testing-evidence/durable-locator-isolation.md index 9333bd6b..f6d90268 100644 --- a/docs/testing-evidence/durable-locator-isolation.md +++ b/docs/testing-evidence/durable-locator-isolation.md @@ -18,7 +18,7 @@ The diagnostic's isolated unsafe pre-exec hook performs only raw pipe reads and The two existing locator laws now run in `tests/durable_locator.rs`, a separate integration-test executable. Its parent creates no store or writer authority; each admitted child runs exactly one locator law serially and creates its own stores. The golden worldline executable no longer launches those children. Parallel execution of the two executables does not share their descriptor tables, so a locator child cannot inherit the golden executable's store locks. -The locator laws still check that a relative handle keeps its original store after a working-directory change and that a deleted working directory preserves its exact NotFound cause. The golden layout-binding law retains its exact LayoutMissing checks and unchanged output sentinel. No law is deleted, ignored, retried or globally serialized. Only the locator child selectors change with their test-module coordinates. Shared fixture imports allow unused partial-record constructors only in the new locator executable; those constructors remain exercised by the golden suite. +The locator laws still check that a relative handle keeps its original store after a working-directory change and that a deleted working directory preserves its exact NotFound cause. The golden layout-binding law retains its exact LayoutMissing checks and unchanged output sentinel. No law is deleted, ignored, retried or globally serialized. The locator module and its exact child selectors remain byte-identical to the original. Shared fixture imports allow unused partial-record constructors and explicit sandbox removal only in the new locator executable; other filesystem laws still exercise those operations. Keep's authority handoffs, flock semantics, public errors, APIs, formats and recovery protocols do not change. This correction removes the demonstrated interference mechanism from this suite without asserting that every possible cause of Busy has been eliminated. Any new failure remains a defect to diagnose, not a retry instruction. diff --git a/tests/durable_locator.rs b/tests/durable_locator.rs index 83259ae9..cadff7c3 100644 --- a/tests/durable_locator.rs +++ b/tests/durable_locator.rs @@ -7,13 +7,5 @@ #![cfg(target_os = "linux")] -#[path = "golden_file_worldline/durable_fixture.rs"] -#[allow( - dead_code, - reason = "locator laws share complete-store setup; other golden laws own partial-record cases" -)] -mod durable_fixture; -#[path = "golden_file_worldline/durable_locator_laws.rs"] -mod durable_locator_laws; -#[path = "segment_filesystem_stage/sandbox.rs"] -mod durable_sandbox; +#[path = "durable_locator/suite.rs"] +mod suite; diff --git a/tests/durable_locator/suite.rs b/tests/durable_locator/suite.rs new file mode 100644 index 00000000..e1a1ac2d --- /dev/null +++ b/tests/durable_locator/suite.rs @@ -0,0 +1,16 @@ +//! This module owns the isolated locator suite's fixture imports. + +#[path = "../golden_file_worldline/durable_fixture.rs"] +#[allow( + dead_code, + reason = "locator laws use complete stores; golden laws cover partial-record construction" +)] +mod durable_fixture; +#[path = "../golden_file_worldline/durable_locator_laws.rs"] +mod durable_locator_laws; +#[path = "../segment_filesystem_stage/sandbox.rs"] +#[allow( + dead_code, + reason = "locator laws use Drop cleanup; other filesystem laws check explicit removal" +)] +mod durable_sandbox; diff --git a/tests/golden_file_worldline/durable_locator_laws.rs b/tests/golden_file_worldline/durable_locator_laws.rs index 0a954568..f435f326 100644 --- a/tests/golden_file_worldline/durable_locator_laws.rs +++ b/tests/golden_file_worldline/durable_locator_laws.rs @@ -18,7 +18,7 @@ use super::durable_sandbox::TestDirectory; type TestResult = Result<(), Box>; const CHILD: &str = "KEEP_DURABLE_LOCATOR_CHILD"; -const LAW: &str = "durable_locator_laws::relative_store_handles_keep_their_initial_store_after_a_directory_change"; +const LAW: &str = "suite::durable_locator_laws::relative_store_handles_keep_their_initial_store_after_a_directory_change"; #[test] fn relative_store_handles_keep_their_initial_store_after_a_directory_change() @@ -29,7 +29,7 @@ fn relative_store_handles_keep_their_initial_store_after_a_directory_change() #[test] fn an_unresolvable_relative_locator_preserves_its_io_cause() -> Result<(), Box> { run_isolated( - "durable_locator_laws::an_unresolvable_relative_locator_preserves_its_io_cause", + "suite::durable_locator_laws::an_unresolvable_relative_locator_preserves_its_io_cause", deleted_current_directory, ) }