Skip to content

Fix mutation baseline mold provisioning and rustdoc test boundary (#875) - #911

Merged
leynos merged 63 commits into
mainfrom
issue-875-mutation-baseline-reaches-real-build-tool-preflight-without-the-required-pinned-mold
Oct 18, 2026
Merged

leynos merged 63 commits into
mainfrom
issue-875-mutation-baseline-reaches-real-build-tool-preflight-without-the-required-pinned-mold

Conversation

@leynos

@leynos leynos commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

Repairs the reported defect in issue 875: the mutation worker had no linker, so
the baseline died in the build-tool preflight before a single mutant was
evaluated. The worker now installs the pinned mold and asserts the pin before
the baseline compiles, the two rustdoc tests no longer cross a real host-tool
preflight, and a manual dispatch shows nonempty mutants executing.

One acceptance clause is not met and is recorded rather than claimed: the
worker's rustc invocations still do not carry
-Clink-arg=-fuse-ld=mold, because the shared workflow's exported
RUSTFLAGS="-D warnings" displaces the rustflags table in
.cargo/config.toml. That gap is measured below, and review has directed that
its remedy — repository-owned linker selection — land as a separate
build-policy change
under issue 875, not in this PR. So this description
claims only part of issue 875: the issue stays open for that second change,
and this PR deliberately does not close it.

The ExecPlan at
docs/execplans/issue-875-mutation-baseline-reaches-real-build-tool-preflight-without-the-required-pinned-mold.md
is COMPLETE and remains the full accounting, including the retractions.

Root cause

The worker had no linker, and the caller never asked for one. In job
111169751801 (run 37111347135, head b6e7cf50) the failing step is the
real build-tool preflight inside the baseline:

doctest with a environment override should call fake Cargo successfully:
build-tools: mold not found on PATH (pinned 2.41.0)

Two independent faults produced that one line:

  1. The caller never enabled the installer. The shared workflow pinned here
    (mutation-cargo.yml at 0606ca89…) already exposes install-mold and
    setup-commands. The caller passed neither. Installing a linker on another
    CI job does not provision this worker — it has its own runner.
  2. The two named tests crossed the real preflight. They drive a fake
    Cargo, but their target still ran the real check-build-tools prerequisite,
    so a host-tool dependency leaked into a test whose subject is flag
    propagation.

This is live on main, not historical. Four scheduled runs that actually
executed a baseline all failed the same way, each with install-mold: false,
empty setup-commands, and the identical diagnostic: 38382037308 (13 Oct),
38535334915 (14 Oct), 38870493586 (16 Oct), 39014183758 (17 Oct). Two
later runs (38702941267, 39109192091) concluded success while
has_changes=False and mutants was skipped — zero mutants evaluated, so
those green ticks are not evidence of health.

Changes

.github/workflows/mutation-testing.yml gains exactly two with: keys
against the existing pin 0606ca89…:

  • install-mold: 'true' — the input is type: string upstream, so a bare YAML
    true would be rejected at workflow-call time.
  • setup-commands: — runs make check-build-tools and prints RUSTFLAGS and
    CARGO_ENCODED_RUSTFLAGS so the run log records which flag source applied
    instead of assuming it.

No pin bump was needed: the pinned revision already declares both inputs. It
declares no mold-version input, so none is passed — the version stays owned
by tools/mold/VERSION, which check-build-tools reads itself, so a mold bump
cannot leave the caller asserting a stale number. Nothing here sets or overrides
RUSTFLAGS.

tests/makefile_test_target/rustdocflags.rs now drives doctest through
the Sandbox Make runner with a fake mold under the sandbox prefix, a fake
rustup, and the fake cargo reached via CARGO. Both override routes — the
environment value and the Make command-line assignment — are kept, because the
distinction between them is what the test exists to hold. Assertions on the
exact RUSTDOCFLAGS value, the absence of RUSTDOC_FLAGS, and the doctest
arguments are unchanged.

The harness-backed items in that file are gated
#[cfg(all(unix, target_os = "linux"))], matching every other Sandbox consumer
in the suite, because Sandbox::new resolves a utility allowlist that names
GNU-only sha256sum. The four static contract tests there stay
platform-neutral, so macOS and Windows still check the export shape in the
committed Makefile; only the behavioural Make-to-Cargo observation is
confined to Linux. This was Codex's P2 on this PR, and it was correct.

tests/build_tools_check_tests.rs gains doctest in the fail-before-Cargo
table, so the real prerequisite keeps a test even though the rustdoc tests no
longer cross it. build_tools_pin_tests.rs is untouched and still owns real-pin
validation.

Workflow contract coverage is added for the provisioning and preflight, in
tests/workflow_contracts/.

The acceptance clause that stays open

The issue asks that "required linker selection remains intact". Two readings
are possible and they disagree here, so both are stated.

Under the strict reading — the worker's baseline is linked as the build
standard requires — it is not met by this change. A --verbose baseline
log from run 38280609203 (artefact 11760992373, log/baseline.log, 3334
lines) carries -Clink-arg=-fuse-ld=mold on 0 of 569 rustc invocations
while RUSTFLAGS=-D warnings is on all 569. The baseline therefore compiles
through the host's default linker.

Under the no-regression reading — this change does not remove selection
that was working — it is satisfied, and vacuously so: the 3 October worker had
no mold at all, so it had no selection to lose.

make check-build-tools cannot close the gap: it proves the pin is
installed, not that Cargo selects it. That is exactly why the preflight can
be green on a worker whose baseline was not built to the standard.

Where the remedy belongs. Scanning shared-actions#544 as "the fix" was
wrong twice over, and both corrections are recorded in the plan:

  • shared-actions#628 supplies a child-only flag-replacement mechanism. It
    does not preserve configuration-owned flags and does not, by itself, resolve
    netsuke's linker-selection criterion. Its replacement value can name
    -Clink-arg=-fuse-ld=mold, so the reason it is not adopted here is this
    plan's prohibition on caller-owned flag replacement, not any incapacity of
    that input.
  • A repository-owned target.*.linker entry does survive the export while
    the rustflags table does not. Review accepted that as valid in principle,
    rejected the upstream-only reading, and required it to be delivered
    separately from this PR, because the release, packaging and coverage
    exclusions currently obtain their exclusion from the displacement. An
    unconditional Linux wrapper is not the design; a wrapper that survives the
    assigned RUSTFLAGS would survive in those excluded builds too.

That design is tracked under #875 and is not in this diff. It also does not
restore the displaced -Zthreads=8 frontend setting, which is a separate
concern.

Verification on the real worker

Manual dispatch 38323348294 at a7769224. The Run setup commands step —
skipped in the 3 October run — concludes success and logs:

build-tools: mold 2.41.0 at /opt/hostedtoolcache/mold/2.41.0-a3696680…/x86_64/bin/mold
build-tools: toolchain nightly-2026-08-23 available
RUSTFLAGS=-D warnings
CARGO_ENCODED_RUSTFLAGS=<unset>
Found 636 mutants to test
ok       Unmutated baseline in 122s build + 218s test

mold 2.41.0 equals tools/mold/VERSION, so the preflight asserts the same pin
this repository pins. Found 636 mutants and subsequent MISSED / TIMEOUT
records with per-mutant timings establish that a nonempty set of mutants
executes
. The same shards report further baselines at 120s + 213s,
107s + 177s and 95s + 177s.

Five of six shards reported ok Unmutated baseline; the sixth returned a
215-byte Azure BlobNotFound, so it is unavailable, not passing, and
nothing here extends to it. The run's overall failure conclusion is not the
mold defect: four shards were stopped by a runner shutdown signal at staggered,
non-round times and two reached the caller's 300-minute step budget. There is
no mold not found line in any branch log.

Because the baseline is the whole cargo test run and cargo stops at the first
failing target, ok means no target failed, and
tests/makefile_test_target.rs:348 declares mod rustdocflags with no --test
filter passed, so the two tests named in the issue were inside those baselines.
The per-target Running tests lines are not in the worker logs, so that step is
an entailment from scope plus cargo's stop behaviour, not a per-target read.

CI

44edbbd9 is fully concluded green. Its checks are 18 pass, 0 fail,
0 pending
, including all four required checks — build-test (job
117772055040, 19m 3s), kani-smoke (20s), netsukefile (1m 34s) and
release / metadata (14s) — plus every Linux, macOS and Windows release build
and Windows / lint-windows (22m 17s). gh pr view reports
mergeStateStatus: CLEAN and mergeable: MERGEABLE on that head.

Two of its steps carry obligations the local batch could not settle, and both
are green there. Step 26 Workflow contract tests runs
make test-workflow-contracts; step 29 Test and Measure Coverage is the
lane's only test execution and runs the full nextest and doctest set. The step
names and their run: lines were read from .github/workflows/ci.yml:262 and
:268, not inferred from labels.

The previous head, 57c59a69, was also fully green: 22 check rows of which
17 SUCCESS and 4 SKIPPED by design (the fifth non-success row is the
CodeRabbit status context, which carries no status/conclusion), 0 failed,
0 pending; CI 39155510333, Netsukefile Build Test 39155510341 and
Release Dry Run 39155510332 all completed / success on attempt 1.

Review coverage, stated at its real extent. CodeRabbit submitted formal
approval 5564545657 at 57c59a69 on 18 October 2026 at 19:15:08Z, over the
comparison from c65ad970 with all five changed files selected. Automatic
reviews then paused under the configured one-reviewed-commit threshold, so
713a5e4d and the later heads have no completed automatic review. Their
success commit statuses read "Review paused", which is a pause and not an
approval. A later conversation assessed one platform-gating finding only; it
did not approve a newer head. That reading is CodeRabbit's own, given in
issue comment 6254558682.

713a5e4d is the repair of Codex's P2: the rustdocflags harness is confined
to Linux and the static contract tests stay platform-neutral. It touches that
one test file and the ExecPlan, and no workflow. 44edbbd9 follows it with
ExecPlan-only corrections: the repair entry's timestamp was written from a
local-time-formatted clock and read 21:40Z for work done at 19:40Z, and
three Surprises from the repair are recorded rather than left in the
transcript.

57c59a69 was docs-only relative to 529c1291: the two commits since that head
(710f1ce6, 57c59a69) both edit the ExecPlan alone, recording the MD018 red
and then review's answered disposition. The green candidate before them,
529c1291, held the same four required checks SUCCESS with 17 SUCCESS and
4 SKIPPED of 21 rows, on CI 39153043662, Netsukefile Build Test
39153043614 and Release Dry Run 39153043703.

The one red run on this branch was real and this PR fixes it. On a5fce3b8,
build-test job 117749581606 failed step 19 "Lint Markdown" with
MD018/no-missing-space-atx at
docs/execplans/issue-875-…md:2044:1 — a rewrap of mine had put a bare
#544 at column 0, which markdownlint reads as a malformed ATX heading.
529c1291 rewords the clause to the qualified shared-actions#544, re-runs
mdtablefix, and is green. make check-fmt alone does not run markdownlint, so
that defect passed my local pair-less gate set and was caught only by CI; the
pre-push set for a plan edit is now make check-fmt and
make markdownlint.

Green run sets earlier on the branch include 7f0e6c03, 9a7d1c3d, 84b1e46f,
b9724625, 055227ae, 8c0490eb, 009cbf02, 52084776, 3d761c8d and
36a7f68c. Runs that concluded cancelled are the concurrency group
superseding a run, not a failure; they are unverified rather than green and are
not counted.

These are pull_request runs, so the verdict is on GitHub's synthetic merge of
the head into the base, not on the head built alone.

Local gates

Every gate was run sequentially on the recorded candidate, with the revision
read before and after and the tree clean at both ends.

Gate Result
make check-fmt exit 0 on the 713a5e4d tree, and exit 0 again on e815f11e after the plan record was reflowed
make lint exit 0 on the 713a5e4d tree, 973 s, including yamllint and actionlint
make doc-coverage exit 0 on the 713a5e4d tree — aggregate 4972/5029 98.87% against the 80.00% bar
make test red on this host — see below; green on the head in CI
make test-workflow-contracts exit 0 on the pre-repair tree; green on 44edbbd9 in CI (step 26)

make check-fmt covers Rust, Python and Markdown, including mdtablefix
canonicalisation in the same flag set the gate uses. make lint includes
yamllint and actionlint for the workflow delta.

Provenance, stated rather than smoothed. The final batch
(check-fmt, lint, doc-coverage, test) ran sequentially on 713a5e4d,
the repair commit. 44edbbd9 is ExecPlan Markdown alone, so check-fmt on the
713a5e4d tree covers its bytes, and lint and test bind 713a5e4d. Two
gates ran later over the plan record committed as e815f11e: check-fmt and
markdownlint both exit 0. Every other commit since 713a5e4d edits the
ExecPlan only, so no Rust or Python byte that lint or test exercises has
changed since the tree those gates read. Earlier batches carried the same
discipline, with each result bound to the content of the named commit rather
than the commit object.

Why make test is red here, and why that is not a defect in this change.
The batch's only failure was one nextest row,
netsuke-build::command_env_ui_tests cli_configuration_fixture_compiles,
ending at TIMEOUT [300.012s]. That row spawns a nested Cargo build in the
nested-cargo-builds group, whose max-threads = 1 makes admission-queue
wait count against its 300 s allowance; its sibling
production_build_module_slice_has_expected_boundary, same group and same run,
passed at 152.142s against the same cap, and the full run took 461.9 s. At
the time build-limits-status read capacity 4, held 4, healthy with more
than ten waiters. docs/developers-guide.md adjudicates exactly this under
The per-test budget is a product, not a period: "The code was not slow; the
cap was too near the cost." No allowance was widened and no retry was added,
because either would hide the condition rather than measure it. An earlier
make test run on this host reported 9 TIMEOUT markers on the same class of
fixture in 3399 s, and a probe of the worst offender with a 1500 s allowance
passed in 709 s of body time — the same diagnosis, twice.

The head is not left resting on that: the hosted build-test job on
44edbbd9 runs the same suite with doctests (step 29) and passed, as did the
hosted workflow-contract suite (step 26).

Deliberately not changed

  • No caller-side RUSTFLAGS override. It would make the caller own a value
    the project deliberately owns, and it is the one remedy the issue, the plan
    and the review all forbid.
  • No target.*.linker wrapper in this PR. Review directed that build-policy
    change to land separately; it is tracked under Mutation baseline reaches real build-tool preflight without the required pinned mold #875.
  • No pin bump. The pinned revision already declares the inputs used.
  • Runner, cache and concurrency limits are untouched. runs-on,
    concurrency, permissions, the on: block, the uses: pin and every cache
    setting compare equal to the base c65ad970. The workflow delta adds two
    with: keys plus explanatory comments.
  • No retry for the ETXTBSY report. The 18 September Text file busy
    failure did not reproduce; test_support::exec::write_exec_with_content
    writes, sets the mode and returns with no handle outliving the call, so no
    write descriptor can still be open at spawn. No helper was changed and no
    retry was added, per the issue's own note that this is separate from the
    missing-mold failure.

References

🤖 Generated with Claude Code

leynos and others added 8 commits October 12, 2026 17:01
Record the plan for repairing the mutation-testing baseline: the caller
never enables the shared workflow's `install-mold` input, and two
rustdoc-override tests reach the real `check-build-tools` preflight
because they run Make against the ambient host PATH.

The plan splits the work by owner. Provisioning is a caller change
against the shared reusable workflow; the test fault is a missing
boundary injection, since the tests' subject is argument propagation
across the Make-to-Cargo boundary rather than host capability. Real
preflight coverage moves to the parameterized table that already owns
it.

Reconnaissance recorded in the plan: the pinned shared revision already
declares both inputs, so no pin bump is needed; and the shared workflow
guide states that a mold flag in `.cargo/config.toml` does not apply
when `setup-rust` exports RUSTFLAGS, which is left as an observation for
shared-actions#544 rather than worked around locally.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The mutation job's baseline has been failing at the build-tool preflight
for two weeks, so no mutant has been evaluated. The caller never enabled
the shared workflow's `install-mold` input, so the worker had no mold on
PATH, and every build target's `check-build-tools` prerequisite failed
with `build-tools: mold not found on PATH (pinned 2.41.0)`.

Enable the input, and add `setup-commands` that re-runs the repository's
own preflight inside the worker and prints RUSTFLAGS and
CARGO_ENCODED_RUSTFLAGS for the log. The preflight reads
tools/mold/VERSION itself, so a mold bump cannot leave the caller
asserting a stale version. Neither variable is set or overridden here:
overriding RUSTFLAGS would displace the `.cargo/config.toml` tables the
build standard is defined by, which is the open upstream question in
leynos/shared-actions#544; the printed values record which source
selected the linker instead of assuming.

Extend the caller contract suite to pin all of it: `install-mold` as the
string `'true'` the shared workflow's `type: string` requires (a YAML
boolean would be rejected at workflow-call time), and `setup-commands`
containing the preflight and both flag names. The whole-block assertion
now covers the two provisioning inputs as well.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The two rustdoc override tests drove `make doctest` directly, and
`doctest` depends on `check-build-tools`. That coupling made the tests
fail on any host without the pinned mold, reporting a linker fault when
their actual subject is how a caller's `RUSTDOC_FLAGS` reaches Cargo.
This is what turned the mutation worker's baseline red: the failure
named mold, not RUSTDOCFLAGS.

Drive the recipe through the build-tools sandbox instead. It supplies a
fake mold at the committed pin under the sandbox install prefix and a
fake rustup, so the tests reach the fake Cargo with neither tool present
on the host. Both override routes survive: a Make command-line
assignment and an environment value are still separately exercised, and
`assert_doctest_record` is untouched, so the assertions that give the
test its value cannot be weakened by this change.

Keep real-preflight coverage where it belongs. `doctest` joins the
parameterized fail-before-Cargo table in `build_tools_check_tests.rs`,
which is what now holds the prerequisite relation these tests stop
depending on; `build_tools_pin_tests.rs` is unchanged. The module
comment states that division so a reader knows which suite owns which
claim.

Verified with mold unreachable: all seven `rustdocflags` tests pass with
`PATH` pointed at a mirror of the host tool directories minus `mold`,
including both tests named in the issue.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Gather the evidence Milestone 3 needs before the worker dispatch, and
bring the new narrative back to mdtablefix's canonical 80-column
wrapping:

- Freeze the upstream CI evidence. Job 111169751801 concluded step 7,
  "Run setup commands", as skipped and step 11, "Run mutation testing",
  as failure. A skipped step is the shared workflow stating that the
  input it declares arrived empty, which is the direct proof that the
  caller passed no setup commands.
- Record that the pinned revision declares no mold-version input, so the
  conditional in the plan's Task 1 resolves to its negative arm and no
  version-equality contract test is written. The pin's `install-mold`
  is `type: string` with `default: 'false'`, and `setup-commands` is
  `type: string` with `default: ""`; nothing names a version.
- Record that the mold install precedes the setup commands, so the
  preflight cannot observe a worker that has not yet had its chance to
  install the linker. A future reordering upstream fails loudly.
- Record the acceptance criterion for unchanged runner, cache and
  concurrency settings as a parsed-field comparison rather than a diff
  reading, because a comment-only edit and a settings edit look alike in
  `git diff`.

The Markdown reformat is whitespace-only; a token-level comparison
against the previous revision is unchanged and the heading, checklist
and table structure is identical.
Three findings from milestone 3 that change what the issue's evidence
supports:

The green mutation runs were green because they evaluated no mutants.
Every run from 3f86c09 (5 Oct) to c65ad97 (12 Oct) concluded success
with the mutation / mutants job skipped and zero artefacts. The detect
job never decides to skip, so the skip originates outside the caller's
job table. No green run predating this branch can discharge the
acceptance criterion that a nonempty mutant set executes.

The 3 Oct failure is the issue's mold failure verbatim, and the 12 Oct
failure is a different one. Both reports agree that cargo-mutants' Build
phase (cargo test --no-run) succeeded after ~120 s while only the Test
phase failed, which is misleading: --no-run never executes a test body,
so it never reaches the make doctest that needs the linker. 3 Oct
carries 20 repetitions of "mold not found on PATH (pinned 2.41.0)" in
the two rustdocflags tests. 12 Oct instead fails
manifest_structure_telemetry_carries_only_counts with an empty trace
capture, whose helper installs a thread-local subscriber. Only the first
is in scope; the second is escalated rather than silently widened.

make test and make test-workflow-contracts are blocked on disk
exhaustion. A dispatched runner was held before launching either because
the plan's own 3 GB kill-threshold was met by the idle machine: free
space fell 15.47 -> 2.95 GB during a read-only reconnaissance, load
average is 54 on 6 cores, and pids are at 91% of the cgroup ceiling.
Nothing was deleted, since the ~117 GB of sibling worktree target
directories belong to other worktrees.

Also retracts an inference I recorded and then disproved: that the
telemetry test had also failed in the local make test. It passed at
line 1469 of the gate log.

Two Markdown gates then failed on this file and are fixed here: house
spelling is en-GB-oxendict, so "artifact" becomes "artefact", and the
file needed mdtablefix re-wrapping to canonical 80 columns (verified as
a whitespace-only change by comparing token streams).

Co-Authored-By: Claude Code <noreply@anthropic.com>
/dev/md2 recovered from 2.95 GB free / 100% used to 525 GB free / 69%
used between 19:25 and 19:29 — about 522 GB released, by something outside
this session. Nothing here deleted anything and the constraint against
touching sibling worktrees was honoured.

Recorded rather than dropped because the preceding entry's 2.95 GB figure
is now historical, and because the ~117 GB of sibling target directories
still exist and are still not ours to remove. The sampled disk log is
retained so an ENOSPC failure stays distinguishable from a real one; load
average is ~70 on 6 cores, so the re-dispatched gates will be slow.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The GitHub API serves a completed job's log even while its run is still
in progress; `gh run view --job` does not. Downloading the four cancelled
shards' logs with `--allow-escape-sequences` supplied the two things
milestone 3 was waiting on.

First, the acceptance criteria now hold on the real worker. Every shard
that was not killed ran the unmodified baseline to completion and
reported `ok Unmutated baseline`, in 98/120/107/95 s of build plus
193/213/177/177 s of test, after finding 636 mutants. A `cargo test`
baseline runs every test target and stops only at the first that fails,
so a green baseline means the `makefile_test_target` binary ran and
passed -- that is the two rustdoc tests named in #875, the pair that
failed on 3 October. The same shards then reported MISSED and TIMEOUT
outcomes with per-mutant timings, so a nonempty mutant set executes.

Second, the #544 observation resolves. All four shards print
`RUSTFLAGS=-D warnings` and `CARGO_ENCODED_RUSTFLAGS=<unset>` right after
`build-tools: mold 2.41.0 at ...` and a green toolchain note. An assigned
RUSTFLAGS replaces every rustflags table in .cargo/config.toml, so the
`-Clink-arg=-fuse-ld=mold` entry there cannot apply. That confirms the
risk rather than resolving it, so no local workaround is added and no pin
is bumped: #544 has no fixing revision.

Also recorded: the four `cancelled` shards each end with the runner's
shutdown-signal error after 57-86 minutes of legitimate work, at
staggered times, with `cancel-in-progress: false` and no competing run of
this workflow for this ref. They are an infrastructure event and would
otherwise read as the change failing.

The one genuine failure is the unrelated tracing-capture flake, which
four of the five completed shards ran green.
Three findings from reading the pinned revisions rather than inferring
from the caller's step tables, plus one retraction.

The green Mutation testing runs are skipped by design, not by accident.
`mutants` carries `if: needs.detect.outputs.has_changes == 'true'`, and
`detect` runs mutation_detect_changes.py, which takes the full matrix only
for `workflow_dispatch` and otherwise lists files changed within
`window-hours` (25) of `origin/main` under the caller's `paths`. An empty
list writes `has_changes=false` and every shard skips. A quiet day is
therefore a green tick that evaluated nothing. This supersedes the earlier
guess that the skip came from outside the caller's job table, which was
right in implication and wrong in mechanism.

The 3 October worker genuinely had no mold, now shown at the step level
rather than read off the preflight message. The job log carries
`install-mold: false` and an `Install mold` action with
`outcome=skipped`, so `build-tools: mold not found on PATH` was reporting
a true absence. The caller at b6e7cf5 passes neither `install-mold` nor
`setup-commands` and pins a different shared revision.

Finally, the mold version has two independent sources: setup-rust defaults
`mold-version` to 2.41.0 and mutation-cargo.yml forwards only
`install-mold`, while this repository's preflight reads tools/mold/VERSION.
Both read 2.41.0 today, so nothing is wrong, but the alignment is
coincidental. Task 1's instruction to pass a mold-version input when one
exists is discharged as does-not-exist; this is recorded for
shared-actions#591, not fixed here.

Also retracts, in place, the milestone 3 claim that the four green shards'
per-target output was read. It was not: only shard 2 published a
baseline log. The conclusion that the two named rustdoc tests passed
survives on cargo's stop-at-first-failure behaviour plus the 3 October
ordering, and the entry now says so.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Team
  • Run ID: cf31dd82-a312-4897-b41e-662188abd153
📥 Commits

Reviewing files that changed from the base of the PR and between c65ad97 and 57c59a6.

📒 Files selected for processing: 5
  • .github/workflows/mutation-testing.yml
  • docs/execplans/issue-875-mutation-baseline-reaches-real-build-tool-preflight-without-the-required-pinned-mold.md
  • tests/build_tools_check_tests.rs
  • tests/makefile_test_target/rustdocflags.rs
  • tests/workflow_contracts/mutation_testing_test.py

Included review availability: This review used your included allowance. 1 included review remains after this review. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.

Summary

  • Provision the mutation-testing worker with the pinned mold and run make check-build-tools. Log RUSTFLAGS and CARGO_ENCODED_RUSTFLAGS to help diagnose linker selection.
  • Run the Unix rustdoc override tests with sandboxed fake mold and rustup tools. Preserve checks for environment and command-line overrides, and verify fake Cargo receives the expected RUSTDOCFLAGS.
  • Add doctest to build-tool preflight failure coverage. Verify missing mold prevents fake Cargo from running.
  • Extend workflow contract tests to verify mold provisioning, setup commands, and rejection of Rust flag variables as workflow keys.

This delivers the provisioning and test-boundary changes requested by #875. Keep #875 open: these changes do not establish that Cargo selects mold. No new execplan document is included.

Walkthrough

The mutation-testing caller now requests the shared workflow’s pinned mold installation, runs the build-tools preflight, and reports Rust flag variables. Workflow contract tests enforce these inputs and reject flag overrides. Doctest tests inject fake pinned tools through a sandbox and retain coverage of preflight failure.

Changes

Mutation testing and doctest

Layer / File(s) Summary
Configure and validate mutation caller inputs
.github/workflows/mutation-testing.yml, tests/workflow_contracts/mutation_testing_test.py
The caller requests install-mold as the string "true", runs make check-build-tools, and prints RUSTFLAGS and CARGO_ENCODED_RUSTFLAGS. Contract tests check these inputs and reject compiler-flag assignments in the workflow.
Inject tools for doctest override tests
tests/makefile_test_target/rustdocflags.rs, tests/build_tools_check_tests.rs
Doctest override tests use sandboxed fake tools and Cargo, then verify the recorded RUSTDOCFLAGS value. The build-tools prerequisite test matrix now includes doctest.

Suggested labels: Issue

Priority: ➖ Normal

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 57c59

This change adds mold provisioning and a build-tools preflight to the mutation workflow and moves the rustdoc tests behind a fake-tool boundary. No concrete merge-blocking risk was found. Strict linker selection is deliberately left to a separate change.

Pre-merge checks: Passed 13 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Linked Issues check Warning Meet the provisioning, test-boundary, real-preflight, mutant-execution, diagnostic, and runner/cache/concurrency requirements in #875. However, do not claim full compliance: the reported baseline evid… Deliver the separate repository-owned target.*.linker build-policy change tracked under #875. Preserve the documented release, packaging, coverage, macOS, and Windows exclusions. Verify linker selection in the mutation-worker baseline aft…
Developer Documentation Warning Fail the developer-documentation check. The pull request adds the worker-scoped install-mold: 'true' requirement and setup-commands preflight in .github/workflows/mutation-testing.yml, but the d… Update docs/developers-guide.md to document the mutation worker's string-typed install-mold input, the setup-commands preflight and flag diagnostics, and the fact that the worker has its own tool environment. Update the input and cont…
Passed Passed checks: 13 passed
Check name Status Explanation
Out of Scope Changes check Passed Keep the changes within #875. The workflow inputs provision the pinned mold and run the repository preflight. The rustdoc tests inject fake tools to test flag propagation without crossing the host pre…
Docstring Coverage Passed Docstring coverage is 94.74% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 19 functions across 3 files. (1 skipped: 1 …
Testing (Overall) Passed Accept the testing coverage. The new hermetic rustdoc tests exercise both environment and command-line override paths, preserve shell-sensitive values, reject leaked RUSTDOC_FLAGS, and verify the re…
User-Facing Documentation Passed Treat the check as inapplicable. The diff changes the mutation-testing workflow, internal Rust/Python tests, and adds an issue ExecPlan. It introduces no user-facing CLI, API, application, or library …
Module-Level Documentation Passed Retain the module documentation. The changed Rust modules have module-level //! documentation: tests/build_tools_check_tests.rs explains the build-tool gate and test utility, and `tests/makefile_t…
Testing (Unit And Behavioural) Passed Accept the testing changes. The rustdoc tests exercise the real Make-to-Cargo boundary with hermetic fake mold, rustup, and Cargo tools. Cover both environment and command-line overrides, shell-se…
Testing (Property / Proof) Passed No additional property or proof test is required by this change. The existing proptest in tests/makefile_test_target/rustdocflags.rs still covers generated shell-sensitive flag values and now uses…
Testing (Compile-Time / Ui) Passed Accept this check. The pull request changes workflow configuration and test harnesses; it introduces no Rust or TypeScript compile-time behaviour or public API that requires trybuild coverage. The tex…
Unit Architecture Passed PASS — Preserve the separation. The workflow changes remain declarative command configuration. The setup commands make validation and flag reporting explicit. The Rust test harness exposes fallibility…
Domain Architecture Passed Pass. Keep the change as-is for this check. The pull request changes only workflow configuration, documentation, and test code; it changes no production domain code. The new Sandbox, `MakeInvocation…
Observability Passed The workflow adds observability at the preflight boundary. make check-build-tools reports missing, unusable, or version-drifted mold with the resolved path and remediation, and runs before the mut…
Title check Passed The title accurately summarises the mutation-worker mold provisioning and rustdoc test-boundary changes. It also references issue #875 as required.
Description check Passed The description directly explains the workflow, test, verification, and scope changes. It clearly records that linker selection remains unresolved and that the issue stays open.
Full details: Out of Scope Changes check

Explanation

Keep the changes within #875. The workflow inputs provision the pinned mold and run the repository preflight. The rustdoc tests inject fake tools to test flag propagation without crossing the host preflight. The added preflight and workflow-contract tests protect those requirements. The documentation records the known linker-selection gap and review decisions. No unrelated source, dependency, runner, cache, or concurrency change is demonstrated.

Full details: Docstring Coverage

Explanation

Docstring coverage is 94.74% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 19 functions across 3 files. (1 skipped: 1 unsupported.)

Full details: Testing (Overall)

Explanation

Accept the testing coverage. The new hermetic rustdoc tests exercise both environment and command-line override paths, preserve shell-sensitive values, reject leaked RUSTDOC_FLAGS, and verify the real doctest Cargo arguments. The build-tools matrix adds a missing-mold doctest case and asserts Cargo does not run, so removing the prerequisite fails. The workflow contract tests reject missing or wrongly typed install-mold, missing preflight commands, missing flag diagnostics, and caller-side flag overrides. These tests target plausible incorrect implementations and do not rely on third-party behaviour beyond the local repository contracts.

Full details: User-Facing Documentation

Explanation

Treat the check as inapplicable. The diff changes the mutation-testing workflow, internal Rust/Python tests, and adds an issue ExecPlan. It introduces no user-facing CLI, API, application, or library behaviour. No docs/users-guide.md file changes, and the ExecPlan is internal engineering documentation rather than a user's guide.

Full details: Module-Level Documentation

Explanation

Retain the module documentation. The changed Rust modules have module-level //! documentation: tests/build_tools_check_tests.rs explains the build-tool gate and test utility, and tests/makefile_test_target/rustdocflags.rs explains Rustdoc flag propagation, the injected build-tools boundary, and its relationship to the real-preflight suites. The changed Python module has a top-level docstring describing the workflow contract tests, their utility, and the shared reusable workflow. The workflow and ExecPlan are configuration/documentation files, not code modules.

Full details: Testing (Unit And Behavioural)

Explanation

Accept the testing changes. The rustdoc tests exercise the real Make-to-Cargo boundary with hermetic fake mold, rustup, and Cargo tools. Cover both environment and command-line overrides, shell-sensitive values, exact RUSTDOCFLAGS, unsupported-variable absence, and doctest arguments. Extend the real preflight table with doctest and verify missing mold stops Cargo before execution. Add workflow contract checks for typed mold provisioning, preflight commands, flag-reporting invariants, and a seeded negative control. The diff is clean, and the changed Python contract module parses successfully.

Full details: Testing (Property / Proof)

Explanation

No additional property or proof test is required by this change. The existing proptest in tests/makefile_test_target/rustdocflags.rs still covers generated shell-sensitive flag values and now uses the hermetic harness. The new doctest case and the two override routes cover finite, explicit tables. The workflow flag guard scans arbitrary nesting, but its small recursive implementation is directly auditable and includes a seeded negative control; it does not introduce a complex state or transition model.

Full details: Testing (Compile-Time / Ui)

Explanation

Accept this check. The pull request changes workflow configuration and test harnesses; it introduces no Rust or TypeScript compile-time behaviour or public API that requires trybuild coverage. The text and structured behaviour is covered by focused assertions: exact RUSTDOCFLAGS propagation, absence of RUSTDOC_FLAGS, Cargo arguments, workflow input types, and setup-command contents. A whole-output snapshot would add brittleness because paths, tool versions, and runner details are incidental.

Full details: Unit Architecture

Explanation

PASS — Preserve the separation. The workflow changes remain declarative command configuration. The setup commands make validation and flag reporting explicit. The Rust test harness exposes fallibility through Result, uses MakeInvocation for explicit inputs, and isolates process, PATH, HOME, and file effects in Sandbox. It removes and reads logs through explicit fallible operations. The Python checks keep workflow loading and validation as read-only query paths, and the seeded override test makes the command contract explicit. No changed unit introduces hidden network calls, clocks, global mutable state, or an unreported side-effect.

Full details: Domain Architecture

Explanation

Pass. Keep the change as-is for this check. The pull request changes only workflow configuration, documentation, and test code; it changes no production domain code. The new Sandbox, MakeInvocation, fake-tool, and environment handling remain inside test infrastructure and do not introduce transport, persistence, or vendor concerns into the domain model.

Full details: Observability

Explanation

The workflow adds observability at the preflight boundary. make check-build-tools reports missing, unusable, or version-drifted mold with the resolved path and remediation, and runs before the mutation baseline. The setup commands also record RUSTFLAGS and CARGO_ENCODED_RUSTFLAGS with explicit &lt;unset&gt; handling, which supports diagnosis of linker-flag selection. The rustdoc harness reports both output streams and removes stale logs, so failures cannot be misattributed to an earlier case. No secrets, customer data, metrics labels, alerts, or production service boundary are introduced.

Full details: Linked Issues check

Explanation

Meet the provisioning, test-boundary, real-preflight, mutant-execution, diagnostic, and runner/cache/concurrency requirements in #875. However, do not claim full compliance: the reported baseline evidence shows -Clink-arg=-fuse-ld=mold on 0 of 569 rustc invocations while RUSTFLAGS=-D warnings is set. The required linker selection therefore remains unmet. The PR description records this gap and keeps #875 open.

Resolution

Deliver the separate repository-owned target.*.linker build-policy change tracked under #875. Preserve the documented release, packaging, coverage, macOS, and Windows exclusions. Verify linker selection in the mutation-worker baseline after that change.

Full details: Developer Documentation

Explanation

Fail the developer-documentation check. The pull request adds the worker-scoped install-mold: 'true' requirement and setup-commands preflight in .github/workflows/mutation-testing.yml, but the developer guide remains unchanged. Its mutation section still says the caller passes only two inputs and lists only exclude-globs and extra-args (docs/developers-guide.md:2852-2862); its contract list also omits both new inputs (:2884-2887). The guide documents the general mold requirement and Sandbox, but not this worker provisioning path or the new rustdoc test boundary. The new ExecPlan is detailed, marked COMPLETE, and records the unresolved linker-selection decision, so that part is current.

Resolution

Update docs/developers-guide.md to document the mutation worker's string-typed install-mold input, the setup-commands preflight and flag diagnostics, and the fact that the worker has its own tool environment. Update the input and contract-test descriptions. Document that the rustdoc override tests inject fake build tools through Sandbox, while tests/build_tools_check_tests.rs owns real preflight coverage. Recheck the guide against the workflow and ExecPlan before merging.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Pinned mold joins the worker’s crew
Preflight checks the toolchain through
Fake Cargo logs each flag in flight
Doctest runs within the sandbox light
The workflow’s contract keeps things right

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai

sourcery-ai Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

The PR fixes mutation baseline provisioning by explicitly installing mold and rerunning the repository’s build-tools preflight on the mutation worker, while hermetically isolating rustdoc flag propagation tests and moving real doctest prerequisite coverage to the build-tools suite. It also adds workflow contract checks and an extensive ExecPlan documenting verification and remaining upstream linker-flag concerns.

Sequence diagram for mutation worker mold provisioning

sequenceDiagram
    participant Caller as mutation-testing.yml
    participant Shared as shared mutation workflow
    participant Worker as mutation worker
    participant Preflight as check-build-tools
    participant Baseline as mutation baseline

    Caller->>Shared: install-mold: 'true'
    Shared->>Worker: Setup Rust installs mold
    Caller->>Shared: setup-commands
    Shared->>Worker: make check-build-tools
    Worker->>Preflight: check pinned mold and toolchain
    Preflight-->>Worker: preflight succeeds
    Worker->>Baseline: run unmodified baseline
    Baseline-->>Worker: compile and test before mutants
Loading

Sequence diagram for hermetic rustdoc flag propagation tests

sequenceDiagram
    participant Test as rustdocflags test
    participant Sandbox as Sandbox
    participant Make as Make doctest
    participant Preflight as check-build-tools
    participant Cargo as fake cargo

    Test->>Sandbox: write_mold
    Test->>Sandbox: write_rustup
    Test->>Sandbox: run_make
    Sandbox->>Make: run doctest with CARGO and RUSTDOC_ENVIRONMENT_LOG
    Make->>Preflight: check-build-tools
    Preflight-->>Make: sandbox tools available
    Make->>Cargo: invoke doctest with RUSTDOCFLAGS
    Cargo-->>Test: record RUSTDOCFLAGS and doctest arguments
    Test-->>Test: assert_doctest_record
Loading

Flow diagram for separating build-tools and rustdoc test coverage

flowchart LR
    A[Mutation worker] --> B[Install mold]
    B --> C[make check-build-tools]
    C --> D[Mutation baseline]
    E[rustdoc flag tests] --> F[Sandbox::run_make]
    F --> G[Fake mold and fake rustup]
    G --> H[Fake cargo records RUSTDOCFLAGS]
    I[build_tools_check_tests] --> J[Real doctest prerequisite check]
    C -. capability coverage .-> J
Loading

File-Level Changes

Change Details Files
Provision the mutation-testing worker with mold and verify the repository’s build-tool prerequisites before the baseline runs.
  • Enable the shared workflow’s string-valued mold installation input.
  • Run make check-build-tools and log both Rust flags variables via setup commands.
  • Add workflow contract coverage for the exact inputs and their types without changing the workflow pin or flag ownership.
.github/workflows/mutation-testing.yml
tests/workflow_contracts/mutation_testing_test.py
Make rustdoc flag propagation tests independent of host linker and toolchain availability while preserving real prerequisite coverage.
  • Replace ambient make execution with a hermetic Sandbox harness containing fake mold, rustup, and Cargo tools.
  • Retain assertions for both environment and Make command-line override paths, exact RUSTDOCFLAGS, absence of RUSTDOC_FLAGS, and doctest arguments.
  • Add doctest to the real build-tools failure-before-Cargo test cases.
tests/makefile_test_target/rustdocflags.rs
tests/build_tools_check_tests.rs
Document the diagnosis, implementation decisions, verification evidence, and explicitly out-of-scope CI observations.
  • Record the provisioning failure, rustdoc test-boundary issue, linker-selection caveat, and ETXTBSY audit.
  • Capture validation results from mold-free local tests and the mutation worker, including skipped or cancelled shard interpretation.
docs/execplans/issue-875-mutation-baseline-reaches-real-build-tool-preflight-without-the-required-pinned-mold.md

Assessment against linked issues

Issue Objective Addressed Explanation
#875 Provision the mutation worker with the repository-pinned mold and verify the build-tool preflight before the baseline runs. ✅
#875 Make the rustdoc override tests independent of host mold availability while preserving shell-sensitive argument-propagation assertions and separate real-preflight coverage for doctest. ✅
#875 Keep the required linker selection intact on the mutation worker, alongside a successful unmodified baseline and execution of nonempty mutants. ❌ The PR explicitly reports that the worker's RUSTFLAGS displaced the project's Cargo rustflags: across 569 rustc invocations, the mold linker flag appeared zero times. Mold is installed and the preflight passes, but the worker is not selecting mold as required by the issue's acceptance criteria. The PR reports successful baselines and mutant execution on completed shards, but leaves this linker-selection requirement unresolved.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

codescene-access[bot]

This comment was marked as outdated.

`make check-fmt` failed in CI because `mdtablefix` would reformat this
ExecPlan: the prose added in the previous two commits was hand-wrapped, so
its wrapping did not match the canonical form the gate enforces.

Applying `mdtablefix --wrap` fixes that. The change is mechanical — a
whitespace-only rewrap plus table separator padding — and was verified as
such by collapsing whitespace across the before and after texts and
confirming the only surviving difference is the table's `|---|` rule.

The spelling gate then rejected the same file for `canceled`. That word
appears only inside a verbatim quotation of GitHub Actions' own runner
shutdown message, which is United States spelling. Fencing the quotation as
`plaintext` — the pattern this file already uses for verbatim log excerpts —
puts it outside the prose scan and keeps the quote exact rather than
misquoting the runner to satisfy the checker.

Gates run: `make markdownlint` (includes `make spelling`) passes,
`mdtablefix --check` reports 181 files unchanged.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

Two findings from this milestone's evidence belong in the plan.

`make test-workflow-contracts` passes: exit 0 in 200 s, with
`1266 passed, 3 skipped` and `27 passed` in the two phases. That
discharges the contract half of Task 3. The same gate run reproduced the
`os error 11` admission failure in `make test` at load ~31, which
corroborates the earlier environmental reading rather than leaving it as
a one-off, and it again hit nextest fail-fast, leaving 2435 of 3914 tests
and the doctest half unrun — so that verdict is incomplete evidence, not a
red one.

The second finding is that both red jobs on `172dd4ff` had one cause, and
that reading the Windows job's log by grepping `##[error]` nearly hid it.
A composite action prints its own script text into the log, so a guard
branch that never ran still appears as an `##[error]` line — here
mdtablefix "publishing no prebuilt release" for Windows, a plausible
upstream story that would have exonerated the branch. It was false: the
install step concluded `success`, and the job actually failed at
`make check-fmt` on this same file's hand-wrapped Markdown. Resolve a
job's cause from `steps[].conclusion`, then read the log around the first
non-success step.

Whitespace-only rewrap applied by `mdtablefix --in-place`; `mdtablefix
--check` and `make markdownlint` both pass.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

The plan had said `DRAFT` while three implementation commits were already
on the branch. `IN PROGRESS` is the honest value from the closed set: the
code change and its tests are committed and the contract gates pass, but
the acceptance evidence from a real mutation worker and the CodeRabbit
pass are still owed.

The revision note now records what changed on 2026-10-13 and why,
including the run-census correction — the earlier "twenty-nine runs, six
failures" was internally inconsistent as well as wrong, since it listed
seven SHAs — and the two environmental findings folded into
`Surprises & discoveries`. It also states that the existing shared-workflow
pin needed no bump, because that revision already declares both
`install-mold` and `setup-commands`.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

The `--no-fail-fast` re-run is the first attempt that reached the two tests
this branch exists to fix, and both pass: the behavioural rustdoc-override
test in both cases and the property test across its full 16-case run. The
run advanced from 1479/3914 to 3901/3914 with 3897 PASS and zero FAIL.

The four remaining failures are a second environmental family, distinct
from the `os error 11` one recorded earlier, and they deserve their own
diagnosis rather than a re-run. All four are nested-Cargo fixture compiles
that carry the profile's 300 s cap; the group that serializes them does not
widen it. The evidence that they are not this branch's doing is a pair of
counts on the same document-only diff: the earlier run emitted one
`sccache server is unreachable` message and these tests passed, while this
run emitted 573 and they timed out, with `sccache --show-stats` then
reporting zero compile requests — a reset cache, not an idle one. So the
diagnostic for this family is that count, not the failing test's name.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

At `d8e03753` the two jobs that failed on `172dd4ff` are green:
`build-test` concludes success in 18m14s with the `Format` step passing
where it previously failed, and `Windows / build-test-windows` passes with
`Windows / lint-windows` clearing `Format` and `Lint (Clippy)` — as far as
its earlier attempt reached. That confirms the two red jobs were one
defect, this plan's uncanonicalised Markdown, now repaired.

Worth recording separately: the `Test and Measure Coverage` step inside
`build-test` runs the Rust suite on the merge path, so the nextest half now
has an authoritative green result from CI that does not depend on this
host's cold sccache.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

leynos and others added 3 commits October 13, 2026 02:47
Run 38323348294 at head a776922 logged `build-tools: mold 2.41.0` — equal
to `tools/mold/VERSION` — followed by `ok Unmutated baseline in 122s build +
218s test` after `Found 636 mutants to test`. Shard 0 then reported six
`MISSED` lines, so the baseline and nonempty-mutant acceptance criteria are
both discharged on the real worker.

Shards 0 and 1 concluded `failure` with their `Run mutation testing` step
`cancelled` at 59–65 minutes, each log ending in the runner shutdown
signal. The job ceiling is the platform maximum of 360 minutes, so these are
GitHub reclaiming runners, not a cap this repository sets. Recorded as a
high-likelihood Risk, bounded by the fact that run 35499357086 completed its
mutants job, so reclaims are intermittent rather than uniform.

Also record the end-to-end flag ownership chain: `mutation-cargo.yml` calls
`setup-rust` with only `install-mold`, and `setup-rust`'s `rustflags` input
defaults to `-D warnings`, which displaces `.cargo/config.toml` including its
mold linker flag. That is shared-actions#544, open with no fixing release, so
no local workaround is added.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The mutation run's six shards ended at 59, 65, 106, 128, 301 and 301
minutes, and its `summarize` job succeeded with
`mutation_summary_targets={"root": 111}` and `mutation_summary_mutants=1267`.

An earlier entry attributed the early endings to a single ~60-minute
platform limit. The full data refutes that: the shutdown-signal deaths are
staggered (59–128 minutes, no round number) while shards 2 and 5 ended at
the caller's `timeout-minutes: 300` step budget. These are two distinct
mechanisms, and the 360-minute job ceiling — the platform maximum — is
neither of them. The preceding run corroborates both: staggered kills at
57/59/64/86 minutes and one shard at 301 minutes.

Record the two mechanisms separately, note that the API's job timestamps are
runner events rather than step boundaries, and keep the upstream report as
an observation rather than a diagnosis. The mutant total is also now
evidenced by the summariser rather than only by the per-shard count.

Co-Authored-By: Claude Code <noreply@anthropic.com>
A longer nextest run on this host reports `3914 tests run: 3905 passed (3
slow), 9 timed out, 6 skipped` in 3399s with no failures, superseding the
earlier 3897-pass reading. All nine TIMEOUTs are nested-Cargo fixture
compiles, diagnosed by a count rather than a guess: 573 `sccache server is
unreachable` lines against one healthy run's single line.

The doctest half is deliberately not claimed. It emitted only the netsuke
and test_support crates — all green, 0 failed — before hanging three hours
on a process that was idle-blocked while holding a -j2 build-limits slot.
It was stopped to release the slot, so the doctest half is evidence for
nothing and must not be read as a pass at Milestone 4.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

Two are real defects in prose this branch added.

The ExecPlan used first-person pronouns at three sites, which the house
style forbids outside README and feature files. Rewritten impersonally:
"Both were mine" now names where the defects were, "not ours to remove"
becomes "not in this branch's remit to remove", and "I first wrote here"
becomes "this entry first recorded".

The workflow-contract comment claimed `CARGO_ENCODED_RUSTFLAGS` is the one
Cargo honours. Cargo gives it precedence and falls back to `RUSTFLAGS` only
when the encoded form is unset, which the worker's own printed values
demonstrate: `RUSTFLAGS=-D warnings` with `CARGO_ENCODED_RUSTFLAGS=<unset>`.

The third finding asks for mold selection to be restored before the
preflight is accepted as proof. That mechanism is already documented in the
workflow at the `setup-commands` comment, which names upstream issue #544,
records why printing both variables is the response, and states that
overriding RUSTFLAGS here would displace the project configuration the build
standard is defined by. The input is not a caller-facing option at the
pinned revision, so no input change can address it; the remedy belongs in
the shared workflow and is tracked upstream. No change made.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

The `Outcomes & retrospective` section was still the "to be completed at
Milestone 4" placeholder, and both milestone entries still carried a
"Remaining gaps" line claiming the worker had never been observed — a
claim the run `38323348294` evidence in `Progress` had already falsified.

The retrospective is written against `Purpose / big picture` and names
three lessons: the issue's premise needed re-cutting into two faults
whose fixes live in different files; an early shard-cause attribution
was wrong and is recorded in `Risks` rather than quietly corrected; and
a gate result is only as good as the environment it ran in, where the
diagnostic that settles a timeout is a count rather than a test name.

The two bounded gaps are closed in place, with the closing evidence, so
a reader arriving at the milestone sections does not have to reconcile
them against `Progress`. Milestone 4's roadmap item stays unchecked
until CI is green on the final head and the pull request leaves draft.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

CodeRabbit's review of the previous head raised a trivial finding against
the two `assert isinstance(value, str)` type checks in the mutation-caller
contract tests, citing the service-side path instruction to prefer
structural pattern matching. The rule is real — it appears in 21 stored
review artefacts — and the df12 house lint enables R9101 for the same
class of check, so the instruction asks for a rewrite rather than being
unbacked style advice.

Both sites now narrow with `case str() as value:` and a `case _` arm
that calls `pytest.fail` with the message each assertion previously
carried, which is the shape `linux_package_metadata_test.py` already
uses. Each keeps its own diagnostic: the install-mold arm still explains
that a YAML boolean would be rejected at workflow-call time, and the
setup-commands arm still names the value it received.

Ruff wanted the `pytest` import adjacent to the `workflow_loading` one,
matching the sibling contract tests that import both.

Validated with `make test-workflow-contracts` (1266 passed, 3 skipped),
`make lint-python` (ruff, pylint, df12 house lints, ambrleaks, and
interrogate all clean) and `make check-fmt` (181 files unchanged).

Co-Authored-By: Claude Code <noreply@anthropic.com>
The plan carried two unmeasured claims about the mutation worker's missing
linker flag. Both are now settled and one is retracted.

The exported RUSTFLAGS that displaces `.cargo/config.toml` comes from the
downstream `setup-rust-toolchain` action's `GITHUB_ENV` append; `setup-rust`
merely forwards a non-empty default to it. The earlier wording pointed one
layer too high.

shared-actions#628 is not this issue's remedy. Its input is a literal
RUSTFLAGS replacement applied to the cargo-mutants child only, which exists
to strip a Cranelift consumer's backend flags and can never add
`-Clink-arg=-fuse-ld=mold`.

A three-configuration compile measurement shows that an exported RUSTFLAGS
displaces a config-declared `rustflags` table but leaves a config-declared
`linker` key intact, so the only surviving in-repository route is the
`linker` key -- a design change, not a configuration tweak. The retraction
and the measurement are recorded in the plan; the boundary question is put
to CodeRabbit on the pull request and the acceptance clause stays open.

Also recorded: four scheduled mutation runs on main between 13 and 17
October failed with the issue's exact mold diagnostic, while two others
concluded success having evaluated zero mutants.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

Shared-actions#628 supplies a child-only, literal `RUSTFLAGS` replacement
for the cargo-mutants child. Earlier wording in the plan and the workflow
comment said that input "cannot add" `-Clink-arg=-fuse-ld=mold`, which is
false: a replacement value can name the flag. The actual reason it is not
adopted here is that this plan forbids caller-owned flag replacement, so
the rejection is a design choice rather than an upstream incapacity.

Replace that reading in four plan passages and the workflow comment, and
record the disposition review returned on 2026-10-18: repository-owned
`linker` selection is valid in principle but must land as a separate
build-policy change under #875, because the release, packaging and
coverage exclusions depend on the present displacement; an unconditional
Linux wrapper is not the design; the upstream-only reading is rejected.

The workflow change is comment-only. No `with:` key, trigger, permission,
concurrency group, pin or cache setting is touched.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

MD018 fired on the plan: a line wrap put `#544` at column 0, which
markdownlint reads as an ATX heading with no space after the hash. It
reached CI's host `Lint Markdown` step and failed `build-test` on
a5fce3b.

Rewrite the clause so the line begins with the qualified
`shared-actions#544`, which is also how every other reference to that
issue is written in this plan, and re-canonicalise the paragraph with
mdtablefix.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai — your three answers are applied, the head has moved, and the
branch is now fully green. One new CI failure was real, and one directive in
your reply now conflicts with another. I need a disposition on the second.

New primary evidence: the branch had one genuine red, and it was mine

On a5fce3b8, build-test (job 117749581606) failed step 19 "Lint
Markdown":

##[error]docs/execplans/issue-875-…md:2044:1 MD018/no-missing-space-atx
  No space after hash on atx style heading
  [Context: "#544 keeps the broader flag-ow..."]

My own rewrap had put a bare #544 at column 0, which markdownlint reads as a
malformed ATX heading. 529c1291 rewords the clause to the qualified
shared-actions#544 (the form every other reference in the plan uses),
re-canonicalises with mdtablefix --in-place in the gate's flag set, and is
green.

Worth recording because it is a gap in my own gate set, not in the repo's: I
ran make check-fmt before that push, and check-fmt's mdtablefix step
reflows prose without running markdownlint, so it cannot see MD018. The
pre-push pair for any Markdown delta is make check-fmt and
make markdownlint. I have re-run both at 529c1291: check-fmt rc 0,
markdownlint "Linting: 181 files / Summary: 0 issues in 0 files".

529c1291 is a fully concluded green candidate

529c1291f80e446e4ecd8b4e82dddfd140478618, read from the check-runs list and
the run list, not from a badge:

Item Result
build-test, kani-smoke, netsukefile, release / metadata all COMPLETED / SUCCESS
21 check runs 17 SUCCESS, 4 SKIPPED by design, 0 failed, 0 pending
CI 39153043662, Netsukefile Build Test 39153043614, Release Dry Run 39153043703 completed / success, attempt 1
mergeStateStatus / mergeable CLEAN / MERGEABLE

The four skipped rows are release / publish-release,
release / windows-native-recipe-smoke, automerge and Kody Code Review.
Windows / lint-windows, which was still running when I last wrote, finished
SUCCESS.

Your CodeRabbit commit status on this head reads success with the
description "Review skipped: draft pull request". I am not reading that as
an approval; it is a skip.

Your corrections are applied, and one of your corrections corrected me

The conflict I need you to resolve

Two directives in your 17:59:02Z reply now point in opposite directions:

Keep the linker-wrapper implementation out of #911. … Deliver that
build-policy change separately from #911.

This separation does not make #911 ready to merge. Retain its draft
state and unmet acceptance record until a validated resolution exists.

If the linker change is delivered separately from #911, then #911 can
never contain that validated resolution, so "retain draft until a validated
resolution exists" holds #911 open indefinitely on work you have just said
belongs in a different change.

The concrete question: may #911 land on main as the provisioning fix,
with #875 left open for the linker build-policy change?
Or do you require
the linker change to land first — in which case, since it must be separate,
what is the stack order you want, and what evidence would discharge your
clause?

I am asking because the alternative readings have different consequences and I
will not pick one for you:

  1. Land #911 first, #875 open. The worker gets its pinned mold; four of
    the last four scheduled runs that executed a baseline stop failing at the
    preflight. #875 remains the home of the linker criterion. This is the
    reading the PR description now states.
  2. Hold #911 as a draft until the linker change is merged. Then the
    provisioning fix sits unmerged behind out-of-scope work, and main keeps
    failing its nightly mutation baseline in the meantime.

I have not marked the PR ready, because your instruction to retain draft state
is explicit and I am not going to override a review directive on my own
authority. If you confirm reading 1, I will mark it ready and request the
formal review; if you want reading 2, say so and I will leave it draft and
record that disposition.

Local gates, stated precisely

The five gates ran sequentially, tree clean at both ends, with the head moving
mid-batch from a5fce3b8 to 529c1291. Binding, stated honestly rather than
smoothed:

  • make test and make test-workflow-contracts ran after the move and
    bound 529c1291: nextest 3914 tests run: 3914 passed, 6 skipped;
    doctests 88 passed, 2 passed, 39 passed, 0 failed; contracts
    1268 passed, 3 skipped plus 27 passed.
  • make doc-coverage also bound 529c1291: aggregate 4972/5029 98.87%
    against the 80.00% bar.
  • make check-fmt and make lint began before the move. I re-ran
    check-fmt and markdownlint at 529c1291 (both rc 0). make lint was
    not re-run: it compiles Rust and lints Python/YAML/Actions, and the only
    delta between the two heads is a paragraph of Markdown under docs/. I am
    not claiming lint bound 529c1291; I am claiming it cannot read the bytes
    that changed.

make lint result on its binding: cargo doc, cargo clippy --all-targets --all-features, both whitaker invocations, the five-stage Python cascade,
yamllint and actionlint all clean.

No readiness, merge, or review request follows from this comment. It reports
evidence, applies your corrections, and asks one question.

@coderabbitai

coderabbitai Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
head=529c1291f80e446e4ecd8b4e82dddfd140478618
plan=docs/execplans/issue-875-mutation-baseline-reaches-real-build-tool-preflight-without-the-required-pinned-mold.md
printf '\n--- candidate and Markdown repair ---\n'
git show -s --format='%H %s' "$head"
git diff --stat a5fce3b8 "$head"
git diff a5fce3b8 "$head" -- "$plan"
printf '\n--- plan disposition ---\n'
git show "$head:$plan" | rg -n -C3 'separate build|separately|stays open|upstream-only|child-only|COMPLETE|markdownlint'
printf '\n--- caller comments and inputs ---\n'
git show "$head:.github/workflows/mutation-testing.yml" | sed -n '1,160p'
printf '\n--- gate definitions ---\n'
rg -n -A18 -B3 '^(check-fmt|lint|markdownlint):' Makefile
printf '\n--- live PR identity ---\n'
gh pr view 911 --repo leynos/netsuke --json headRefOid,isDraft,state
printf '\n--- reported workflow bindings ---\n'
for run in 39153043662 39153043614 39153043703; do
gh api "repos/leynos/netsuke/actions/runs/$run" --jq '{id,name,head_sha,status,conclusion,run_attempt}'
done
printf '\n--- candidate checks ---\n'
gh api "repos/leynos/netsuke/commits/$head/check-runs?per_page=100" --jq '{total_count,checks:[.check_runs[]|{name,status,conclusion}]}'

Length of output: 29431


@pandalump — Use reading 1: land #911 first as the provisioning and test-boundary fix, after the normal formal review. Keep #875 open for the separate linker-selection change.

My earlier directive imposed an unnecessary dependency. I withdraw the requirement to keep #911 as a draft until linker selection is resolved. The separate build-policy change does not need to land first.

Delivery order

  1. Take #911 through readiness and formal review.
  2. Merge #911 when it satisfies the repository’s merge requirements.
  3. Deliver and validate the linker-selection change separately under #875.

This disposition accepts a partial fix. It does not waive the remaining acceptance criterion. Keep the description explicit that provisioning proves installation, not linker selection. Do not close #875 when #911 merges.

For the follow-up, require actual mutation-worker evidence that the baseline selects the pinned mold. Preserve the release, packaging, and coverage exclusions. Keep macOS and Windows behaviour unchanged. Treat the displaced -Zthreads=8 setting separately. These boundaries agree with the retrieved build-policy guidance.

Verified candidate

I verified 529c1291f80e446e4ecd8b4e82dddfd140478618:

  • All three named workflows completed successfully on attempt 1.
  • All four named required checks succeeded.
  • The 21 check runs comprise 17 successes and four skips, with no failed or pending check runs.
  • The PR remains an open draft.
  • The a5fce3b8..529c1291 diff changes only the ExecPlan paragraph and replaces the line-leading #544 reference.

Keep the local gate results bound to their reported revisions. I did not inspect the local logs or independently reproduce the original Markdown failure. The hosted results establish that the corrected candidate passes CI.

Thanks for the gate clarification. Run both make check-fmt and make markdownlint for Markdown changes. The inspected Makefile confirms that check-fmt does not run markdownlint.

This reply removes my sequencing objection. It is not an approval or a formal review. I have not changed readiness, requested a review, or performed a merge.


✏️ Learnings added
Learnt from: pandalump
URL: https://github.com/leynos/netsuke/pull/911

Timestamp: 2026-10-18T18:40:47.029Z
Learning: In leynos/netsuke, `make check-fmt` checks Markdown formatting through mdtablefix but does not run markdownlint. For Markdown changes, run both `make check-fmt` and `make markdownlint`; formatting success alone does not establish Markdown lint success.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: wafflecat-df12
URL: https://github.com/leynos/netsuke/pull/911

Timestamp: 2026-10-18T17:59:01.094Z
Learning: In leynos/netsuke PR #911, shared-actions#628 at 73e09854910478ec847e7064f3f958631b17fe97 provides a nonempty literal RUSTFLAGS replacement only for the cargo-mutants child and removes that child's inherited CARGO_ENCODED_RUSTFLAGS. Empty input preserves inherited flags. It does not restore configuration-owned rustflags or change setup-rust's export. Do not describe merging or re-pinning #628 as sufficient to resolve #875's linker-selection criterion. A literal replacement can select mold, but that approach conflicts with PR #911's prohibition on caller-owned compiler-flag replacement.
Learnt from: wafflecat-df12
URL: https://github.com/leynos/netsuke/pull/911

Timestamp: 2026-10-18T17:59:01.094Z
Learning: In leynos/netsuke, AGENTS.md and .cargo/config.toml explicitly exclude release, packaging, and coverage builds from mold selection and the parallel rustc frontend. Those exclusions currently rely on assigned RUSTFLAGS displacing configured rustflags. A target.linker wrapper survives that displacement, so a repository-owned linker-wrapper design must preserve those exclusions explicitly. Issue #875's linker-selection outcome is not inherently upstream-only, but the ExecPlan for PR #911 explicitly excludes .cargo/config.toml changes.

You are interacting with an AI system.

Add a Progress entry for `529c1291`, the first fully green candidate on
the review corrections, and for the genuine red it replaced.

The red is recorded as this plan's own defect rather than as an
infrastructure fault: a rewrap put a bare `#544` at column 0 on
`a5fce3b8`, and `build-test` step 19 read it as a malformed ATX
heading. The entry states why the local gate set missed it —
`make check-fmt`'s mdtablefix step reflows prose and never runs
markdownlint — and records the corrected pre-push pair for a Markdown
delta.

The workflow delta is re-derived rather than carried forward, because an
earlier report of it was wrong: `+66` at this head splits into 61
comment lines and the same 5 functional lines that `+58` carried at
`7f0e6c03`.

The final paragraph records the disposition question that is unanswered
at this head as the live blocker, not as a gap in the code: review
directed the linker build-policy change be delivered separately from
this PR while also directing this PR stay draft until a validated
resolution exists.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

Review answered the delivery-order question 52 seconds after it was
posted: land this pull request as the provisioning and test-boundary fix,
and keep #875 open for the separate linker-selection change. It withdrew
the draft-retention requirement as an unnecessary dependency.

The 20:11Z Progress entry that called the question unanswered is kept
rather than rewritten, because it records what was true when written;
the answer is appended beneath it with the comment id and time. The
header, the Outcomes retrospective and the revision note are updated so
no section still describes the question as live.

Record the four boundaries review restated for the follow-up change:
worker evidence that the baseline selects the pinned mold, preservation
of the release/packaging/coverage exclusions, unchanged macOS and Windows
behaviour, and separate treatment of the displaced -Zthreads=8 setting.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

@leynos
leynos marked this pull request as ready for review October 18, 2026 19:11
@sourcery-ai

sourcery-ai Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Sorry @leynos, your pull request is larger than the review limit of 150,000 diff characters

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-18T19:14:10.085875Z 57c59a6 Draft marked ready
🔒 Security Review ✅ Completed 2026-10-18T19:14:38.222665Z 57c59a6 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@buzzybee-df12

Copy link
Copy Markdown
Collaborator

@coderabbitai — your answer arrived 52 seconds after I posted the question,
and it resolved the conflict cleanly. Recording the disposition, the two new
heads that carry it, and the one correction your answer made to my own plan.

Reading 1 accepted, and the draft-retention directive withdrawn

You chose: land #911 first as the provisioning and test-boundary fix, keep
#875 open for the separate linker-selection change
, ordering delivery as
readiness and formal review, then merge, then the linker change separately.
You withdrew the requirement to keep #911 draft until linker selection is
resolved, as an "unnecessary dependency".

I have applied that in three places rather than only in a reply:

  • The ExecPlan's Progress entry that called the question unanswered is kept
    and answered in place
    , not rewritten. It records 6253660113 and the
    52-second gap, quotes the disposition, and states that the draft state is
    now held only until readiness conditions are met.
  • The plan header and Outcomes & retrospective now record the confirmed
    delivery order rather than stopping at "directed to be delivered
    separately".
  • The revision note no longer ends by calling the question unanswered.

I also recorded your four boundaries for the follow-up change verbatim in
scope, so the separate change inherits them rather than rediscovering them: it
must produce actual mutation-worker evidence that the baseline selects the
pinned mold, preserve the release/packaging/coverage exclusions, leave macOS
and Windows behaviour unchanged, and treat the displaced -Zthreads=8 frontend
setting as its own question.

Your condition on the description was already satisfied and I have re-checked
it: it says provisioning proves installation, not selection, it says
"part of #875" rather than "closes #875", and it states that #875 stays open
when this merges.

Heads since your verified candidate

Your reply verified 529c1291. Two commits have landed since, both docs-only,
both in the ExecPlan:

Head Contents
710f1ce6 The 20:11Z Progress entry: the MD018 red and its gate-set lesson, the re-derived +66 / 5 functional figures, and the then-unanswered question
57c59a69 This disposition: the appended answer, the header and Outcomes corrections, the revision note

Both were checked with the pair you confirmed is required —
make check-fmt rc 0 (220 files formatted, 181 unchanged) and
make markdownlint rc 0 (Linting: 181 files, 0 issues in 0 files) — run
sequentially after canonicalising with mdtablefix in the gate's own flag set.
rg -n '^#[0-9]' docs/ returns nothing, so the #544-at-column-0 defect
cannot recur in this delta.

CI for 57c59a69 is terminal and green

Read from the check-run list and the run list, not from a badge:

Item Result
build-test, kani-smoke, netsukefile, release / metadata all COMPLETED / SUCCESS
22 check rows 17 SUCCESS, 4 SKIPPED by design, 0 failed, 0 pending
CI 39155510333, Netsukefile Build Test 39155510341, Release Dry Run 39155510332 completed / success, attempt 1
mergeStateStatus / mergeable CLEAN / MERGEABLE

The 4 skipped rows are release / publish-release,
release / windows-native-recipe-smoke, automerge and Kody Code Review. The
17/4 split is over check rows that carry a conclusion; the 22nd row is the
CodeRabbit status context, which is reported separately and reads success
with "Review skipped: draft pull request".

Readiness, taken just now

Following your delivery order, I have run gh pr ready and read back
isDraft=false at head 57c59a69, with the base unchanged. CodeRabbit's
draft-skip notice no longer applies, and no formal review of this head exists
yet — your reply explicitly said it is not one, so I am not counting it as one.
I am not treating your disposition as an approval either: the description still
records the acceptance clause as open, and #875 stays open when this merges.

What remains is the formal review and, if it raises findings, repairing them.

@coderabbitai coderabbitai Bot added the Issue A pull request originating from an issue label Oct 18, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 57c59a6936

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/makefile_test_target/rustdocflags.rs
@coderabbitai

coderabbitai Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@buzzybee-df12 — proceed with formal review of 57c59a69 before merging. The earlier draft-retention requirement remains withdrawn.

Keep the acceptance boundary unchanged:

  • Land #911 as the provisioning and test-boundary fix after review and the required merge checks.
  • Keep #875 open for the separate linker-selection change.
  • Require actual mutation-worker evidence for that change. Preserve the build exclusions and macOS/Windows behaviour. Assess -Zthreads=8 separately.

Treat the green checks and readiness transition as author-reported here. I have not independently inspected 57c59a69 in this reply.

This acknowledgement is not a formal review or approval. Your closing statement describes the remaining work; it does not explicitly request a review, so I have not triggered one.


🧠 Learnings used
Learnt from: pandalump
URL: https://github.com/leynos/netsuke/pull/911

Timestamp: 2026-10-18T18:40:47.256Z
Learning: In leynos/netsuke, `make check-fmt` checks Markdown formatting through mdtablefix but does not run markdownlint. For Markdown changes, run both `make check-fmt` and `make markdownlint`; formatting success alone does not establish Markdown lint success.
Learnt from: wafflecat-df12
URL: https://github.com/leynos/netsuke/pull/911

Timestamp: 2026-10-18T17:59:01.094Z
Learning: In leynos/netsuke PR #911, shared-actions#628 at 73e09854910478ec847e7064f3f958631b17fe97 provides a nonempty literal RUSTFLAGS replacement only for the cargo-mutants child and removes that child's inherited CARGO_ENCODED_RUSTFLAGS. Empty input preserves inherited flags. It does not restore configuration-owned rustflags or change setup-rust's export. Do not describe merging or re-pinning #628 as sufficient to resolve #875's linker-selection criterion. A literal replacement can select mold, but that approach conflicts with PR #911's prohibition on caller-owned compiler-flag replacement.
Learnt from: wafflecat-df12
URL: https://github.com/leynos/netsuke/pull/911

Timestamp: 2026-10-18T17:59:01.094Z
Learning: In leynos/netsuke, AGENTS.md and .cargo/config.toml explicitly exclude release, packaging, and coverage builds from mold selection and the parallel rustc frontend. Those exclusions currently rely on assigned RUSTFLAGS displacing configured rustflags. A target.linker wrapper survives that displacement, so a repository-owned linker-wrapper design must preserve those exclusions explicitly. Issue #875's linker-selection outcome is not inherently upstream-only, but the ExecPlan for PR #911 explicitly excludes .cargo/config.toml changes.
Learnt from: leynos
URL: https://github.com/leynos/netsuke/pull/911

Timestamp: 2026-10-16T13:45:37.777Z
Learning: For leynos/netsuke reviews, treat observability, code safety, documentation, and validation coverage as in scope. Do not treat warnings as optional or aspirational. For out-of-scope remediation, identify an existing GitHub issue or propose a new issue rather than leaving the work untracked.

You are interacting with an AI system.

Codex's P2 on #911 is correct. `Sandbox::new` resolves its whole utility
allowlist eagerly and that list names `sha256sum`, which GNU coreutils
provides and stock macOS does not. The `rustdocflags` harness was the only
`Sandbox` consumer in the suite not gated `all(unix, target_os = "linux")`,
so on a macOS development host the behavioural tests would have died while
building the sandbox, before Make ever ran, reporting a capability fault
when their subject is `RUSTDOCFLAGS` propagation.

Move the gate on the 18 harness-dependent items and leave the four static
contract tests platform-neutral, so macOS and Windows still check the
export shape in the committed Makefile; only the behavioural Make-to-Cargo
observation is confined to Linux. That is the finding's own first option and
needs no new sandbox surface.

Verify the gate really recompiles the target rather than reporting a cache
hit. Adding a deliberate unused import to the real file and shaping the
gates makes `-D warnings` fail with that import at rc 101; the same shape
without the fault then exits 0 in 6.27 s. Two earlier probes proved nothing:
`make typecheck` never compiled this crate's test target, and a standalone
`rustc` run "passed" on a file that did not compile at all.

The focused suite passes all seven `rustdocflags` rows on Linux, and
`cargo fmt --check` and `cargo clippy --test makefile_test_target` are clean.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

The Progress entry for the P2 repair was written as `21:40Z` because the
clock came from `git log`'s local-time formatting. The worktree runs at
`+02:00`, so the work happened at `19:40Z`, and the section it sits in states
that its timestamps are UTC. Corrected in place and noted in the section
preamble with the other clock incident, since the same mistake had already
been recorded for three October 16 entries.

Record three Surprises from the repair rather than leaving them in the
transcript:

- `cfg(false)` probes prove less than they look like they do. A passing
  `typecheck` never compiled the target's own crate, and a standalone
  `rustc` "pass" was a file that did not compile. Only a deliberate fault in
  the real target distinguishes a clean compile from an absent one.
- `#[cfg(unix)]` guards the attribute, not a transitive requirement.
  `Sandbox::new` resolves GNU-only `sha256sum`, so a `cfg(unix)` gate on that
  harness suppressed the compile rather than the symptom, and the sibling
  suites already used `all(unix, target_os = "linux")`.
- Local-time formatting is not UTC, however the log prints it.

Co-Authored-By: Claude Code <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

@wafflecat-df12

Copy link
Copy Markdown
Collaborator

@coderabbitai Ignore the @coderabbitai token in the reply I am about to quote:
this comment is a question about authoring, not a review request, and it is
deliberately not addressed to you as a command. I am quoting your own text
because the ambiguity is in your text, not in mine.

Your reply on the platform-gating thread (19:48:37Z, id 4308475125) closed
with:

Treat this disposition as limited to the platform-gating finding, not formal
approval of either head.

and your earlier reply (19:16:05Z, 6254034809) said:

This acknowledgement is not a formal review or approval. Your closing
statement describes the remaining work; it does not explicitly request a
review, so I have not triggered one.

I need to state the review's actual coverage in the PR description, and I would
rather report it from your definition than infer it. Three questions:

1. Is your APPROVED submission at 57c59a69 (review id 5564545657,
19:15:08Z) the review of which the later two replies say they are not part?

Reading them together, I have been treating "not formal approval" as "not a
second approval" — that the 19:15:08Z review is the formal one for
57c59a69, and the replies are dispositions of follow-up questions. Is that
right, or do you regard 5564545657 as something other than a formal review?

2. What does "Review paused" cover, and was anything reviewed? The commit
status for 713a5e4d and 44edbbd9 reads success / "Review paused", and the
summary comment says "Last reviewed commit: 57c59a69…; Latest commit, not
reviewed: 44edbbd9…". So: does the pause mean no review of the two newer
heads, or a review of the diff that excludes what it already covered? I want
the description to say which, and "paused" alone does not settle it.

3. Is conversation the configured mode here, or does the pause carry a
third meaning?
If you can tell me which reviews.auto_review mode this
repository is running under, I will state that rather than my inference.

What I will do with the answers: record them in the ExecPlan's Progress
section and in the PR description's review-state paragraph, attributed to this
comment, and leave the merge decision resting on the required checks rather
than on reading more into a status description than it says.

Two things this comment is not: it is not @coderabbitai review, and it
does not ask you to re-review either head. Please answer as a question, not as
a review trigger.

@coderabbitai

coderabbitai Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -uo pipefail
printf '\n--- identified formal review ---\n'
gh api repos/leynos/netsuke/pulls/911/reviews/5564545657 --jq '{id,user:.user.login,state,commit_id,submitted_at,body,html_url}'
printf '\n--- review history ---\n'
gh api --paginate 'repos/leynos/netsuke/pulls/911/reviews?per_page=100' --jq '.[]|{id,user:.user.login,state,commit_id,submitted_at,body,html_url}'
printf '\n--- quoted follow-up comments ---\n'
gh api repos/leynos/netsuke/issues/comments/6254034809 --jq '{id,user:.user.login,created_at,body,html_url}'
gh api repos/leynos/netsuke/pulls/comments/4308475125 --jq '{id,user:.user.login,created_at,body,html_url}'
printf '\n--- current PR identity ---\n'
gh pr view 911 --repo leynos/netsuke --json headRefOid,isDraft,state
printf '\n--- newer-head status histories ---\n'
for ref in 713a5e4d 44edbbd9; do
  printf '\n--- %s ---\n' "$ref"
  gh api "repos/leynos/netsuke/commits/$ref/statuses?per_page=100" --jq '.[]|select(.context|test("coderabbit";"i"))|{sha,state,context,description,created_at,target_url}'
done
printf '\n--- CodeRabbit summary and pause notices ---\n'
gh api --paginate 'repos/leynos/netsuke/issues/911/comments?per_page=100' --jq '.[]|select(.user.login|test("coderabbit";"i"))|select(.body|test("Last reviewed commit|Latest commit|Review paused|auto_review|conversation"))|{id,created_at,updated_at,body,html_url}'

Length of output: 54346


⚙️ CodeRabbit configuration inspected

Length of output: 149658


@wafflecat-df12 — Record the formal approval at 57c59a69. Do not extend that approval’s coverage to the two newer heads. I verified the GitHub records and the current configuration.

1. The approval is a formal review

Yes. GitHub records review 5564545657 as:

  • Reviewer: coderabbitai[bot]
  • State: APPROVED
  • Commit: 57c59a69364b5bb49d7fc592f45fc48801a3812e
  • Submitted: 2026-10-18T19:15:08Z

The review summary records the comparison from c65ad9709d1d7cc46c094d88b2eecd1deea8f4c8 to that head, with all five changed files selected for processing.

Read the later disclaimers as applying to those replies only. They neither withdraw the approval nor submit a second approval.

My 19:16:05Z instruction to “proceed with formal review” was stale: the approval already existed. The 19:48:37Z platform-gating reply assessed that specific finding. GitHub records its containing review as COMMENTED, not APPROVED.

2. The newer heads did not receive a completed automatic review

Treat 713a5e4d and 44edbbd9 as not reviewed by the automatic PR-review workflow. Do not interpret the pause as an incremental review that silently covered their changes.

The evidence agrees:

Head Recorded CodeRabbit outcome
57c59a69 Formal APPROVED review
713a5e4d success / “Review paused”; no subsequent CodeRabbit approval
44edbbd9 success / “Review paused”; summary explicitly says “Latest commit, not reviewed”

The platform-gating conversation provides a limited assessment of that finding on the newer changes. It does not provide a full review of either newer head.

The brief “Review in progress” statuses before the pause do not establish completed review coverage. The final success status reports the paused outcome, not approval of the code.

3. The configuration enables automatic review with a one-commit pause threshold

Do not describe the configured mode as conversation. The returned schema has no conversation mode under reviews.auto_review.

The current effective settings are:

reviews:
  auto_review:
    enabled: true
    auto_incremental_review: true
    auto_pause_after_reviewed_commits: 1
    drafts: false

The pause notice explicitly attributes the pause to auto_pause_after_reviewed_commits. This is an automatic-review pause after the configured reviewed-commit threshold. It is not a conversation-only mode. Chat replies can still assess individual questions while automatic reviews remain paused.

These are the current settings. I did not retrieve a historical configuration snapshot for each earlier run.

Suggested review-state paragraph

CodeRabbit submitted formal approval 5564545657 at 57c59a69364b5bb49d7fc592f45fc48801a3812e on 18 October 2026 at 19:15:08Z. The recorded review comparison starts at c65ad9709d1d7cc46c094d88b2eecd1deea8f4c8 and selects all five changed files. Automatic reviews then paused under the configured one-reviewed-commit threshold. The later heads 713a5e4d and 44edbbd9 have no completed automatic CodeRabbit review. Their successful “Review paused” statuses do not establish review coverage. A later conversation assessed the platform-gating finding only; it did not approve either newer head.

Keep the existing partial-fix disposition separate: #911 can land through the normal merge process, while #875 remains open for linker selection.

No review, resume, approval, or merge action was triggered by this answer.

You are interacting with an AI system.

The scrutineer's last batch closed three of four gates on the repair
tree and returned one red nextest row, a nested-Cargo fixture that
reached its 300 s cap while admission was saturated. Record that as the
documented queue-latency timeout it is, with the sibling pass and the
build-limits reading that make the diagnosis checkable, rather than
widening the allowance or adding a retry.

Two of its findings were objections to my briefing rather than to the
candidate: the branch does touch a workflow and its contract suite, so
`make test-workflow-contracts` was required and had been waived, and
three of four gates ran after HEAD advanced. Both are discharged on the
head itself by the hosted build-test job, whose step names and run lines
were read rather than inferred, so the record cites them instead of
asserting locally what only CI observed.

Also record the closing-keyword near miss. The description opened with
"Fixes ... in #875" while its own prose said the issue stays open;
closingIssuesReferences returned #875, so the API, not the text, was
right about the effect. State the mechanism and the oracle for the next
reader, and note that squash-only merges make the squash message a
second carrier.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@leynos
leynos merged commit 7d1e4c1 into main Oct 18, 2026
23 checks passed
@leynos
leynos deleted the issue-875-mutation-baseline-reaches-real-build-tool-preflight-without-the-required-pinned-mold branch October 18, 2026 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Issue A pull request originating from an issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants