Skip to content

fix(rig-cli): a Ctrl-C'd trial build is not rejected, and running the previous build instead of a rejected one is said - #3139

Merged
gold-silver-copper merged 3 commits into
mainfrom
fix/trial-build-ctrl-c
Nov 8, 2026
Merged

gold-silver-copper merged 3 commits into
mainfrom
fix/trial-build-ctrl-c

Conversation

@gold-silver-copper

@gold-silver-copper gold-silver-copper commented Nov 8, 2026 •

Copy link
Copy Markdown
Collaborator

fix(rig-cli): a Ctrl-C'd trial build is not rejected, and running the previous build instead of a rejected one is said

Description

Two launcher fixes from the 2026-11-07 architecture audit (K3-A, d-2).

  1. A trial build stopped by the user's Ctrl-C before its first frame is no longer rejected. The reject check in crates/rig-cli/src/run.rs ignored stop::heard(), but the reload check just above it uses it. A user who pressed Ctrl-C during a new build's startup got that build recorded in bin/rejected. From then on every start silently ran the previous build, which no longer matches settings.toml. The check now leaves out a trial the launcher heard a signal for. The unclaimed trial file is removed by the next start's sweep, and the next start stages the build again.
  2. When a start runs the previous build because the configured one was rejected, the user is told. This happens in rebuild, where the launcher decides the previous build runs. That is also where it already says so for a failed build. The new build::passed_over returns true when the build cargo just made is the one in bin/rejected, is not the good build (a rejected build that later started is not passed over), and nothing staged replaces it. The launcher then prints one line on stderr:
    The new build stopped during startup before, so the previous build is running; rig build tries it again.

What users see change

  • Pressing Ctrl-C while a freshly built rig agent starts up (before its first screen) no longer marks that build as broken. The next rig tries the new build again instead of quietly running the old one.
  • When rig starts the previous build because the new build crashed during startup on an earlier run, it prints on stderr: "The new build stopped during startup before, so the previous build is running; rig build tries it again."
Bug Test Fails on base
Ctrl-C'd trial recorded as rejected rig-cli run::tests::a_trial_stopped_by_a_heard_ctrl_c_is_not_rejected yes: the interrupted trial is recorded in bin/rejected
Running the previous build instead of a rejected one is silent rig-cli build::tests::a_rebuilt_rejected_build_is_passed_over_out_loud added with the fix (it calls the new passed_over, so it does not compile on base)

The first test's fake trial build sends SIGINT to the test process by its pid (std::process::id()), not $PPID, so it cannot reach any other process. Nextest runs each test in its own process, which the existing run::stop::tests signal tests already rely on.

Changelog

  • (rig-cli) A trial build interrupted by Ctrl-C before it started is no longer rejected, and a start that runs the previous build because the new one was rejected says so on stderr.

Migration

None.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Testing

  • cargo nextest run --locked --profile local -p rig-cli on box2: 56 of 56 passed
  • cargo clippy --locked -p rig-cli --all-targets -- -D warnings on box2: clean
  • cargo xtask verify --affected --base origin/main on box2: "All 7 checks passed"
  • The first test fails on the test-only commit with the text above and passes at the head (box2)

Checklist:

  • I have updated READMEs and Rust docs affected by this change
  • I have added tests that prove my fix is effective or that my feature works
  • I did not edit CHANGELOG.md or MIGRATING.md (they are generated at release)

Notes

  • Production lines: +24 / -3 (run.rs, build.rs). Test lines: +50.
  • Review round 1: passed_over also requires the good build to differ from the one just built. Without that, a rejected build retried with rig build that then started (so became bin/good) was still said to be passed over. The second test now covers that step; it failed on the previous head with (false, Ok(()), true, true, false).
  • Differs from the audit's prior art (d-2.diff): the fake trial signals the test process by its explicit pid instead of $PPID.
  • Not verified: I did not drive a real rig start with a real agent build and Ctrl-C at a terminal. The stderr line itself is not asserted by a test (it is a plain eprintln! on the predicate the second test covers).

Follow-ups

  • The stderr line goes to the terminal before a full-screen front takes it, so an interactive user may only see it briefly. Passing it to the agent as a notice too, as a failed build already does, would be a separate change.

@gold-silver-copper
gold-silver-copper added this pull request to the merge queue Nov 8, 2026
Merged via the queue into main with commit e7710f1 Nov 8, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant