Repository navigation
fix(vibe): Stop blocking handoff on checks already red on main - #303
Merged
Merged
Conversation
Operator ruling, 2026-10-16: a handoff check that also fails on the main the session captured is not the session's failure. Three handoffs in two days stopped on such checks (the API path filter, the e2e volume guard, a capability-parity fixture). - main-sync-validate reruns each failing handoff check on the captured mainSha in one disposable checkout bootstrapped with loops-setup.sh, pinning diff-relative selectors to the session's selected packages. - Fails there too: main-preexisting, publication proceeds and the result lists it. Passes there: one session rerun, session-caused if it fails again, flaky if it passes. Cannot run on main: session-caused. - Runs are bounded by run-bounded.mjs; passing checks are never rerun; the recipe binds a comparison reserve for the Claude envelope. The receipt keeps every run's log and digest. Build checks are unchanged. - Handoff, quality-loop, guardrails, the ticket template and the change, environment and ticket workers record each main-preexisting failure once on the Engineering checklist as a Known main failure. - Release vibe 1.0.51 with rebuilt bundles and both manifests. Testing: vitest main-sync-main-comparison (7), contract test (6), vibe pytest, node:test suites, two main-failures evals on Claude and Codex Risks: A handoff now spends one bootstrap of the captured main when a check fails; a check main cannot run still blocks
…ilures # Conflicts: # CHANGELOG.md
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.
Purpose
Operator ruling, 2026-10-16. When a handoff validation check fails, handoff runs the same check on the main the session captured (
mainSha). If it fails there too, the session didn't cause it. It is recorded on the live ticket's Engineering checklist as a known main failure and doesn't block publishing or assignment. Only a failure that passes on the captured main and fails on the session's commit blocks. This applies in both harnesses.In two days, three handoffs stopped on checks that were already red on main: the API path filter, the e2e volume guard and a capability-parity fixture. Each session ended with "a needed fix stops the handoff".
What changed
tools/vibe-workers/src/main-sync-main-comparison.ts, used byexecuteChecksinmain-sync-checks.ts). Only at handoff, and only for a check that failed: the executor makes one disposable detached checkout of the capturedmainShaand bootstraps it once with the repo's own.closedloop-ai/loops-setup.sh(the same pristine bootstrap input readiness uses). The checkout is shared by every failing check and removed in afinally(git worktree remove --force). If the cleanup can't be proven, the run refuses. Diff-relative selectors (typecheck:affected,test:affected, the pinnedturbo --filter=...[sha]) run the same task over the packages the session selected, so main gets the same question. A Biome check over a file that main doesn't have can't run on main.main-preexisting. Publication proceeds and the result lists it undermainPreexistingFailures.session-causedand blocks. If it passes it isflaky, counted as passed and listed underflakyChecks.session-caused. That's the conservative choice, and it blocks.scripts/run-bounded.mjs, with that check's own time limit (15 minutes for the bootstrap). Checks that passed are never rerun. There is at most one main run and one session rerun per failing check. The handoff recipe binds acomparisonreserve (one bootstrap plus 2x each command budget) into its identity, so the Claude validation envelope covers it.validationEnvelopeMsrefuses a reserve that wasn't derived from the commands. Build-loop deploys are unchanged: a failing quick check still blocks.comparison: the classification,mainSha, the session run or runs and the main run, each with its log and sha256. The command receipt now admits a non-zero exit only withmain-preexistingevidence. A blocked validation recordsfailedChecks, and the next success clears it.validationMatchesre-verifies every evidence log digest at push and request time.quality-loop.mdgains "Failures already on main", the one statement of the rule.guardrails.md("Plugins and tooling") and the handoff skill now say a main-only failure is not a needed fix. Handoff step 7 continues onmainPreexistingFailuresand passes them to step 8. The change worker returns them unchanged. The environment worker pushes as usual. The ticket template and ticket worker place each one once at the end of the Engineering checklist as- [ ] Known main failure: <check>; fails on captured main <sha>; evidence: .... It never also goes on the Pre-existing failures line and is never routed to the person.environment.mdand the README describe the comparison.Commands run
main-sync-main-comparison.test.tsdrives the real CLI bundle through the fixture. It covers:typecheck:affectedpinned on main toturbo typecheck --filter=app, followed by a successful push;Every case asserts that the main checkout is gone. On the 1.0.50 bundle the four classification cases fail.
test_vibe_main_only_failures_contract.py: 6 of 6 fail on 1.0.50.The full vitest suite ran on this laptop at a load average of 20 to 70 from other sessions. Some long fixture cases in
main-sync.test.ts,main-sync-input-boundary.test.ts,main-sync-ci.test.tsandmain-sync-input-references.test.tshit their 20s and 30s timeouts. Three of them were rerun at the same load on an unchanged 1.0.50 checkout and timed out the same way there.main-sync-ci,main-sync-budgetandmain-sync-budget-ref-readpass when run alone. CI'sTypeScript (vibe-workers)job is the authority for the full suite.Evals, one run each, tag
main-failures:claude plugin eval, Sonnet): 2 of 2 here. On 1.0.50 the main-only case scored 0.67: it continued but wrote a generic "pre-existing failure" line, not a Known main failure.evals/codex/run.py): 2 of 2 here. On 1.0.50 the main-only case fails on the same grader.