Skip to content

v0.30.0 — the review budget is measured, and a correct aux var stops failing the bump

Choose a tag to compare

@lucascouts lucascouts released this 07 Sep 16:14
· 581 commits to main since this release
2d0d014

Highlights

A number that had never been measured, and a bump that failed for being right.

The review budget was 120 seconds because a different story picked that value for a tool-free extraction path, and nobody checked it against the agentic round trip it ended up bounding. Measured over the maintainer's own overlay — 268 packages, 126 invocations, the ceiling lifted to 1800s so nothing was cut short — 122 reviews succeeded, spread from 7.4s to 124.6s, median 14.3s, p99 112.0s.

So 120s was wrong by 4.6 seconds, on one review out of 122. That is the worst place a ceiling can sit: just inside its own distribution, where it looks adequate and still takes the tail off. It is 300s now, 2.4x the largest measured success, and it stays finite on purpose — a review that genuinely hangs must still end. The constant's documentation carries the readings, the date and the machine, because nothing re-derives them automatically.

It is also configurable for the first time, and — more to the point — connected. WithClaudeCodeTimeout and the client's timeout field both already existed; what was missing is that newClaudeAsker never passed the option. Every review this tool has ever run used the package default, and no configuration could have changed it.

Separately, the autoupdate applier stopped failing bumps that had nothing wrong with them. substituteAuxVar decided on difference: if the rewritten ebuild came out equal to the original, it reported the variable as absent. But "nothing changed" has two causes and only one of them is a fault. net-misc/nxplayer shipped 10.0.59 and 10.0.60 both as build _1, so there was nothing to substitute — and the apply aborted naming a variable that was sitting right there in the file, leaving the staged tree behind. All six packages declaring aux_var were exposed to the same stall.

Changed

  • The review budget is a measured number now, not an inherited one. DefaultReviewTimeout moves from 120 to 300 seconds, on the readings above. The documentation also records what the measurement does NOT establish: the original five-of-five failure that opened the story is not reproduced by it.
  • Comments no longer state a budget the configuration can change. Four in-tree comments restated 120s away from the constant that defines it, and one had already become false. Each now names where the budget comes from instead of what it is.

Added

  • autoupdate.review.timeout (integer seconds, default 300) sets the deadline one overlay compare divergence review runs under, documented in config.example.yaml. Nested under autoupdate deliberately: the strict config probe mirrors top-level keys by hand, so a new top-level key would print field <key> not found in type config.probeConfig to stderr on every command.
  • Every claude invocation records what it cost — one line per invocation with the outcome and wall-clock time, for every outcome including success. A budget cannot be set from failures alone; those are precisely the runs that hit the ceiling.

Fixed

  • An auxiliary variable that already holds the right value no longer fails the bump. Presence decides now, which is what the sibling substituteCommitHash has done since it met the same conflation on a pure base correction: absence is the error, a no-op is a successful nothing.
  • The auxiliary variable substitution can no longer bleed past the assignment it means. regexp.QuoteMeta pins the variable's name but not its position, and ReplaceAllString rewrote every match — so a longer name merely ending in the target one, and a commented-out assignment, were rewritten too. A single bump could corrupt three lines it had no business touching. Latent rather than live: all six ebuilds put the assignment at column zero, so this is a guard against the next one.
  • Neither review wrapper blames the ebuilds any more. Both wrapped every failure as the claude CLI could not read the two ebuilds. Neither seam opens a file — the ebuilds arrive as bytes and go onto the CLI's stdin — so the sentence was false for every failure it could ever report.
  • A claude invocation killed by its own deadline now says so. run never read its own context, so a SIGKILL from this program's budget was indistinguishable from any other spawn failure, and the message sent whoever debugged it to the filesystem. Three outcomes now get three sentences; a run ended by a parent claims no number.
  • One precedence, consulted once, instead of two that could drift. The ordering that decides which of the three failures happened is now a classifier both the fixers and the review path consume. The four existing fixer messages are byte for byte what they were.

Full changelog: v0.29.1...v0.30.0