Repository navigation
Conversation
`/fix <issue#>` solves exactly one issue with one implementer, one `code-reviewer` over the whole diff, at most one fix round, and a PR this session pushes and parks. Two sequential agent rungs on the happy path, three when the review comes back red — against `/turbox`'s eight or more. A narrowing of standard mode rather than a new transport: `commands/fix.md` passes `--auto-mode=1 --turbo --standard --fix` to the same launcher, and `skills/fix-fleet/SKILL.md` reuses `lib/turbox-fleet.sh` for `worktree-add`, `stage-commit`, `round-permitted` and `audit` instead of forking them. What it drops is design — no security lens, no design-planner, no plan-reviewer, no wave decomposition, no per-task spec-compliance. What it keeps is diligence: the full launcher preflight and claim protocol, worktree isolation, the explicit-path staging refusal, an independent reviewer validated through the canonical `uberdev_child_validate_phase1_review_result` boundary, the project's full test suite, and the park-the-PR rule. The lane's own failure mode is answered structurally rather than hoped away: the implementer's return vocabulary carries `TOO_BIG`, meaning "this issue wants a decomposition — run /turbox". It ends the run with the worktree and the claim intact, and the controller is told never to argue an agent out of it. Without that escape, a lane with no design rungs would quietly produce a plausible PR nobody planned. Circuit breakers FX1-FX4. FX1 refuses a second issue number BEFORE gh runs and therefore before Step 4.5 can write a claim — a lane that discovered its second issue after claiming both would leave `uberdev:active` labels behind with nothing running. FX2 is the lane's own `fixRounds` (default 1), resolved beside FX1; it is deliberately not the turbox per-task ladder, whose value stays with its SSOT and is not copied here. A red suite, standing blockers or an UNREVIEWED run each open the PR as a draft. Also fixed, both pre-existing and both measured rather than inferred: - `/uberdev:uninstall-aliases` walked its alias list with `for SHORT in $SHORTS`. Under the Bash tool's /bin/zsh an unquoted scalar does not word-split, so the loop ran once over the whole string and the command removed nothing. Extracted the fence and ran it against a scratch HOME under both shells: the old form removed 0 of 16 under zsh and 16 of 16 under bash; the here-doc reader removes 16 of 16 under both. - `/turbox` was missing from the README alias table and the `UBERDEV_NO_AUTO_ALIAS` row while the prose claimed fifteen forwarders, and `/turbox` and `/premerge` were missing from `tests/aliases.test.sh`'s A1 and A6 loops — so neither command's forwarder nor its `allowed-tools` byte-equality was ever checked. Surfaces moved: all SIX alias surfaces (the five-surface recipe repeated across RFCs 0005/0007/0008/0009/0010 omits `references/configuration.md`, which docs-accuracy T6b enforces — the correction is recorded in `tests/aliases.test.sh`'s header); both chained vendor locks; the run-tree policy's `does_not_govern` declaration; the sdd-wave-contract §C5 cap-sweep ignore-list and its three tallies; CLAUDE.md's bump-lane table, which gains a fourth row so a reviewer does not read a `/fix` PR as an unbumped user-facing change; CI wiring; and the version bump to 0.57.0. `tests/fix-lane.test.sh` is 166 rows. The FX-E rows EXECUTE the launcher and the lib against a stubbed `gh` and `claude` — without the stub, the one row that deliberately passes the arity gate reaches the claim protocol and writes a live claim nothing releases. The refusal rows assert a gh call COUNT of zero rather than the absence of a string, so they cannot pass vacuously in CI, and the plan envelope is PARSED rather than grepped: prose in the RFC claimed 13 keys while the composer emitted 14, and no grep over either file could have seen the disagreement. Closes #797
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
added 4 commits
August 24, 2026 12:23
…mment Two findings from the review of #798, both real. `grep -c` exits 1 when it matches nothing, and matching nothing is the SUCCESS path for the Phase 3a blocker count: a clean review is zero blockers. Run as the last command of a fence it would report the good outcome as a failed probe. Switched to awk, which exits 0 either way, and added the regression row — the same hazard the test harness's own gh-call counter hit. The FX2 guard comment still described the pre-fix pattern. It claimed the glob rejects "the literal 0" and named `-ge`; the shipped pattern is `''|*[!0-9]*` and the test is `-lt`. Behaviour was always correct — the numeric gate catches 0 — but a comment that misattributes which gate does the work is exactly what gets the "redundant" one deleted later.
`printf | grep -q` is an early-exiting reader under pipefail: grep leaves on the first match and printf takes EPIPE, so the pipeline status is the writer's death rather than the match. tests/epipe-guard.test.sh forbids the shape corpus-wide and reds on the file that adds one. Caught by the full-suite re-run, not by the earlier targeted pass — epipe-guard was green when I ran it, and the FX-E4 envelope rows that introduced the pipes landed afterwards.
…le cap Global CLAUDE.md: "Comment the why, three lines max ... Rationale that needs more room goes in an RFC, an ADR or the issue, named here in one line." Measured over the added lines: five blocks in lib/solve-launcher.sh ran 6 to 11 lines (47 comment lines in over-cap blocks). Every one had RFC 0022 as its long form already, so the cut moves the reader one hop rather than losing the reasoning: section 2 for why --fix requires --standard, 3.1 for why FX1 sits ahead of gh, 3.6 for the lane's own cap, 4 for the third marker pair and the narrow envelope. Now 3 blocks at the cap (ruler plus three lines). Re-ran the fixtures that read this file's bytes rather than assuming a comment edit is inert: the sdd-wave-contract C5 cap sweep still totals 43 hit lines, and fix-lane, turbox-fleet and solve-claim are green.
…ound
Three lenses over the diff proposed 16 cuts. The ones applied here, plus one
that turned out to be a defect rather than a simplification.
THE DEFECT. `$(( X + 0 ))` was canonicalising the FX2 rounds knob, and bash
arithmetic reads a leading zero as base 8: `UBERDEV_FIX_FIX_ROUNDS=010`
silently resolved to a cap of 8, and `08`/`09` are fatal arithmetic errors
rather than the lane's own diagnostic. The suite could not see it because it
only exercised `007`, where octal and decimal agree.
Replaced with a parameter-expansion strip that runs BEFORE validation, which
also collapses three operations into one gate: stripping makes `0` and `00`
become the empty string, which the existing glob already refuses, so the
separate `-lt 1` test and the arithmetic both go away. Verified over the full
input set in bash AND zsh: '' 0 00 000 -1 abc 1.5 +2 1e3 refused; 007->7
010->10 08->8 09->9 0100->100. The new rows red on the old form.
FX-E3 was also asserting `fixRounds` equals 1 while passing 1 — the same value
`${UBERDEV_FIX_FIX_ROUNDS:-1}` produces on its own, so the row held even if the
launcher ignored the env var. Now a non-default value.
CUTS, each verified against the owner that keeps the coverage:
- FX-S9's eight greps of the composer SOURCE: FX-E4 parses the same facts out
of the JSON the launcher actually printed, which is strictly better evidence.
Mutation-checked — smuggling `riskIssueCount` into the envelope still reds.
- the alias-row byte-equality check: tests/aliases.test.sh A6 owns it, and this
PR added `fix` to its loop.
- the RFC-number uniqueness check: docs-accuracy already fails on `uniq -d`
over every docs/rfc/NNNN-*.md.
- the CHANGELOG's FX1-FX4 table: a third copy of one RFC 0022 and the skill
both own and test-lock. A user reading release notes does not operate
breakers.
- two more over-cap comment blocks, and a pure back-reference comment.
SKILL.md was 488 lines against a hard 500-line ceiling. Moved the orientation
section to references/rationale.md — the pattern the sibling lane already
uses — leaving a pointer: 468 lines, and the fixture now reads SKILL.md plus
its references/ so a rule the skill still states is still found.
DECLINED: moving FX1 below the ISSUE_NUMS parse to save one python3 spawn. The
placement ahead of the first gh call IS the guarantee, it is line-number
locked, and one subprocess is not worth loosening it.
The sdd-wave-contract C5 tallies move 43/21 -> 40/18: the trims removed three
cap-sweep hit lines. Re-ran every fixture that reads these files' bytes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
/fix <issue#>— a lean single-issue lane, the speedup version of/turbox./turbox/fixdesign-planner→plan-reviewerOwnssetsspec-compliance-reviewer+code-reviewer, per taskcode-reviewer, whole difffixRoundsfrom the plan (default 1)A narrowing of standard mode, not a new transport:
commands/fix.mdpasses--auto-mode=1 --turbo --standard --fixto the same launcher, andskills/fix-fleet/SKILL.mdreuseslib/turbox-fleet.shforworktree-add,stage-commit,round-permittedandauditrather than forking them.What it drops is design, not diligence. The change is still committed by
explicit path, still reviewed by an independent agent against the
phase1-reviewer-v1contract, still validated through the canonicaluberdev_child_validate_phase1_review_resultboundary, still run against thefull test suite, and still parked as a PR nobody merges.
The failure mode, answered structurally
An operator picks the lean lane because it is fast, the issue turns out to need
a decomposition, and a lane with no design rungs produces a plausible-looking
PR nobody planned.
The implementer's return vocabulary carries
TOO_BIG— a first-classanswer meaning this issue wants a decomposition, run
/turbox. It ends therun with the worktree and the claim intact, and the controller is told never to
argue an agent out of it.
Circuit breakers
ghruns, andtherefore before Step 4.5 can write a claim. A lane that discovered its
second issue after claiming both would leave
uberdev:activelabels behindwith nothing running.
fixRounds, the lane's own ceiling (default 1,UBERDEV_FIX_FIX_ROUNDS),resolved and validated beside FX1. Deliberately not the turbox per-task
cap, whose value stays with its SSOT and is not copied into this lane.
retest_rounds, shared, because it bounds the same thing on both lanes.rejects: one re-prompt, then stop or count the run
UNREVIEWED.A red suite, standing blockers, or an
UNREVIEWEDrun each open the PR as adraft, named in both the body and the report.
Pre-existing bugs fixed, both measured rather than inferred
/uberdev:uninstall-aliasesremoved nothing under Claude Code. It walkedits alias list with
for SHORT in $SHORTS; under the Bash tool's/bin/zshanunquoted scalar does not word-split, so the loop ran once over the whole
string and every
[ -e "$DEST_DIR/${SHORT}.md" ]missed. Extracted the fenceand ran it against a scratch
HOMEunder both shells:for SHORT in $SHORTS(before)Alias-table drift.
/turboxwas missing from the README alias table andthe
UBERDEV_NO_AUTO_ALIASrow while the prose claimed fifteen forwarders, and/turboxand/premergewere missing fromtests/aliases.test.sh's A1 and A6loops — so neither command's forwarder nor its
allowed-toolsbyte-equalitywas ever checked. Both loops now cover them.
Surfaces moved
All six alias surfaces. The five-surface recipe repeated across RFCs 0005,
0007, 0008, 0009 and 0010 omits
skills/using-uberdev/references/configuration.md,which
docs-accuracyT6b provably enforces — following the RFC recipe lands ared build. The correction is recorded in
tests/aliases.test.sh's header.Both chained vendor locks (
vendor.jsonC-COVER + the RFC 0019 componentcount), the run-tree policy's
does_not_governdeclaration, thesdd-wave-contract§C5 cap-sweep ignore-list and its three tallies, CI wiring,and the version bump to 0.57.0.
CLAUDE.md's bump-lane table gains a fourth row:/turboxand/fixopen onePR per issue rather than a stack, so there is no once-per-stack commit to carry
the bump — it rides whatever lands the PR. Without that row a reviewer reads a
/fixPR as an unbumped user-facing change.Tests
tests/fix-lane.test.sh, 166 rows, wired into the ubuntu job and declaredUnix-only.
The
FX-E*rows execute the launcher and the lib against a stubbedghand
claude. The stub is not a nicety: the one row that deliberately passesthe arity gate reaches Step 4.5 and would otherwise write a live claim on
whatever repo
gh repo viewresolved, which nothing in the run releases.Two deliberate choices about what those rows assert:
of an error string. That proves the guard rather than the message, and it
cannot pass vacuously in CI, where an unstubbed run would die at
gh repo viewfor want of auth and every negative would hold trivially.envelope had 13 keys while the composer emitted 14; no grep over either file
could have seen the disagreement.
Both the envelope key-count row and the audit-sink traversal guard were
mutation-checked — break the source, the row reds.
Verification
Green locally:
fix-lane(166),aliases,docs-accuracy(309),epipe-guard(93),turbox-fleet,turbox-fleet-runtime(146),sdd-wave-contract(77),solve-run-tree-scope,skill-renderer-awk-collision,skill-size,ci-wiring,vendor-provenance(63).A full re-run of the ubuntu list was still in flight when this PR was opened —
CI is the authority. The first full pass was green on all 134 fixtures except
the three reds now fixed here.
Not done
The post-merge release ritual: the
v0.57.0tag and the GitHub Release. Thosestay in the operator's foreground, after the landing commit is on
main.Closes #797