fix(delivery): the on_green_tests gate ran the suite in the live checkout
Fourth instance of the same defect, and the last of the three commands that run as root against a mission tree. `verify_tests` execs the project's test command with `workdir = repo` — the live checkout — inside a container running as ROOT. `cargo test` writes `target/`, so the checkout ends up owned by two uids and the next phase's cargo hits permission-denied. The harness reported `uids=0,65532` the first time this gate ever ran end to end. It survived because it had never run. Every one of the ten harness fixtures used `commit_policy: "always"`; `on_green_tests` and `on_reviewer_approval` were parsed, implemented, and never exercised — and `Gate`'s own doc already records that three recipes carried this policy while it "did precisely nothing" for want of a reader. A policy that is never exercised is indistinguishable from one that is ignored. Consolidated rather than fixed a third time. `root_copy` now owns the pattern — copy through `mission_fs::pack_dir` into a SIBLING of the mission dir, run there, and purge FROM INSIDE THE CONTAINER, because the copy's `target/` is root-owned and the server (uid 65532) cannot delete it. `benchmark_runner` moved onto it; `evaluator_tools::Sandbox` keeps its own copy logic for now (it carries an allow-list and a judge-facing API, so folding it in is a larger change than this moment warrants — noted, not done). The gate fails CLOSED if the copy cannot be made: an unverifiable suite must not license a push. Also adds the `refactor` scenario, which is what found this. I had written it off as "structurally identical to four existing scenarios" — wrong: it is the only recipe carrying `on_green_tests`, and that made it the only one testing this code path at all. 245 lib tests, 20 test binaries.
This commit is contained in:
@@ -345,7 +345,29 @@ pub async fn capture_phase_diff_at(
|
||||
if gate == Gate::OnGreenTests {
|
||||
let container = std::env::var("CLAWMATES_RUNTIME_CONTAINER")
|
||||
.unwrap_or_else(|_| "clawmates-runtime".to_string());
|
||||
let o = verify_tests(&repo, &container).await;
|
||||
// Against a COPY, never the checkout. `verify_tests` execs
|
||||
// `cargo test` in a container running as ROOT, which writes
|
||||
// `target/` — in the live tree that leaves root-owned build
|
||||
// output in a checkout owned by uid 65532 and breaks the
|
||||
// single-writer invariant. Measured the first time this gate
|
||||
// ever ran end to end: `uids=0,65532`.
|
||||
//
|
||||
// The gate had been implemented but never exercised (every
|
||||
// harness fixture used `commit_policy: "always"`), which is why
|
||||
// a bug this mechanical survived in it.
|
||||
let gate_root = crate::root_copy::copy_root("_gate", mission_id);
|
||||
crate::root_copy::purge(&container, &gate_root).await;
|
||||
let o = match crate::root_copy::RootCopy::of(&repo, &gate_root) {
|
||||
Ok(copy) => {
|
||||
let r = verify_tests(copy.workdir(), &container).await;
|
||||
crate::root_copy::purge(&container, &gate_root).await;
|
||||
r
|
||||
}
|
||||
// Fail-closed: an unverifiable suite must not license a push.
|
||||
Err(e) => TestOutcome::CouldNotRun(format!(
|
||||
"could not copy the checkout to test it: {e}"
|
||||
)),
|
||||
};
|
||||
// An infrastructure fault must be loud. The gate degrades
|
||||
// safely either way, but "we could not run the suite" is a
|
||||
// problem with the platform and needs to look like one.
|
||||
|
||||
Reference in New Issue
Block a user