* feat(ci): make post-repair revalidation opt-in A CI repair used to restart the whole pipeline at Review, so every repaired check cost another full Review, Test, Document, Lint, Push, and PR pass over the change. That is the most expensive single behavior the pipeline has, and it was unconditional. ci.revalidate_repairs selects between the two deliveries. It defaults to false: the repair is published immediately through publishRunHead - the same guarded path the Push step uses, so review-approved-head continuity, the force-with-lease anchor, remote verification, the push binding, and the gate-mirror update all still apply - and the CI monitor keeps watching the same run. Set true to keep the repair local, revoke the run's review approval, and restart validation at Review so no CI repair is published without having been reviewed. The key lives in the existing ci block, so it inherits that block's global config, trusted-default-branch-only sourcing, and repo-overrides-global precedence with no new mechanism. It is a *bool so an explicit project false overrides a global true rather than reading as unset. Both CI fix paths take the same decision: the automatic auto-fix round and the manual round a person authorizes at the CI gate. No-change retries, the durable fix-attempt budget, duplicate-check suppression, transient reruns, merge-conflict handling, force-push safety, custody, and cancellation are untouched. The CI step logs which policy is in force before its first poll. VISION.md gains the constraint this default follows from: cost is a user-visible property of the gate, so a design that clearly adds significant end-to-end latency or token consumption must be opt-in. * no-mistakes(review): Preserve CI repair continuity across rebases * no-mistakes(document): Correct stale CI repair documentation * no-mistakes(ci): Fixed late gate-mirror failures misreporting published CI repairs. Published repairs now continue CI monitoring with a warning after durable remote binding, while Push-step mirror failures still propagate. Added regression coverage. Verified targeted race tests, rebase tests, make lint, and git diff --check * no-mistakes(document): Document late gate-mirror failure handling * fix(ci): decide repair publication by provable continuity A CI repair was published whenever ci.revalidate_repairs was off, and a merge-conflict repair rebases, so its head is not a descendant of the reviewed head. The publication guard was relaxed for that case with a base-ancestry exception, and a repair that reset to the rebase base satisfied it: reproduced, the reviewed commits were force-pushed away while the pipeline reported success. The actor was the CI repair agent itself, so provenance cannot stand in for the proof either. One rule now decides delivery on every CI-fix path, automatic and manual, CI failure and merge conflict alike: a repair is published without revalidating only when its continuity with the reviewed, published head can be PROVEN; when it cannot, the repair revalidates from Review. Continuity is proven when the repaired head is the run's durable review-approved commit or a descendant of it, read through the same reviewApprovedHead accessor the publication guard enforces, so the decision to publish and the guard that permits the push cannot disagree. Every failure to establish it - unreadable run, missing or malformed approval, unverifiable ancestry - counts as unproven. ci.revalidate_repairs still sets the intent identically on every path: false publishes when it is provable, true revalidates outright. Merge-conflict repairs are not carved out; they simply always land in the cannot-be-proven half, because resolving a conflict changes the commit's patch-id and no content-based guard can separate a resolved rebase from a dropped one. They now revalidate rather than being refused, so conflict repair keeps working. The base-ancestry exception and its rewriteBase plumbing are deleted; assertReviewApprovedPushHead is descendant-only again with no exception. Regressions: a genuine conflict rebase revalidates and succeeds; a reset-to-base conflict repair revalidates, never reaches the remote, and the reviewed work survives; an ordinary provable repair still publishes with the flag off and still restarts with it on; a run with no review authority revalidates rather than publishing. * no-mistakes(review): Correct merge-conflict revalidation guidance across all surfaces * no-mistakes(document): Correct CI repair revalidation documentation * no-mistakes(lint): Regenerate no-mistakes skill documentation * fix(push): record a publication only once all of it has settled The gate-mirror update ran after the push binding and the recorded head, which forced a choice between two wrong answers on a mirror failure. Returning the error made the CI monitor call an already published repair failed, and its next attempt then saw a clean, already-advanced head as producing no changes. Swallowing the error left the gate behind the remote for good, and `no-mistakes rerun` resolves its starting head from the gate, so a later rerun silently omitted the published repair. Settle the gate mirror before recording anything durable. Publication is now all-or-nothing: remote push, gate mirror, push binding, and recorded head all land or none of them are recorded. A partial failure is simply retryable - the next attempt re-enters the same path, finds the remote already at this head via an up-to-date no-op push, and completes the publication once the mirror works. The CI-repair warning special case is gone with it. Also correct four surfaces that still said the default publishes every repair, when it publishes only a repair whose continuity is provable, and make the merge-conflict regression conflict for real: the base and the feature now edit the same line, so the resolved rebase genuinely changes the commit's patch-id rather than replaying cleanly. Regressions: an unsettled publication records nothing and the retry completes it; a real conflict rebase revalidates and succeeds; a reset-to-base conflict repair revalidates and the reviewed content survives on the remote. * no-mistakes(review): Make CI repair publication atomic and retryable * no-mistakes(document): Correct CI publication documentation * fix(ci): fire the unsettled-publication retry only on real evidence The retry added for a part-way publication triggered on any clean worktree whose HEAD differed from the run's recorded head. That is not evidence a publication was attempted: a fix agent that commits and then errors leaves exactly that state, and so does a fixture whose recorded head trails the branch. The retry then ran instead of the fix round and the repair agent was never called, which is what broke TestCIStep_BitbucketAutoFixUsesLivePRHeadSHAForLogs on CI. publishRepair now records the commit whose publication it began and could not finish, and clears it on success or when the repair revalidates instead. The retry fires only for that exact commit, so it still settles a stalled publication without spending another fix attempt, and never swallows a fix round. The marker is in memory only: after a daemon restart the next fix attempt settles it instead, at the cost of one attempt, which is the honest accounting rather than a durable claim the process cannot make. Regression: a differing head with no attempted publication still runs the fix agent and never logs the retry. * no-mistakes(review): Retry unsettled publications before evaluating CI checks * no-mistakes(document): Document CI publication retry evidence * fix(ci): bound the publication retry and order the revalidation write Two defects in the repair-publication path, both reported on the PR. The unsettled-publication retry costs no repair attempt by design, so a gate mirror that could never be settled retried on every poll until the CI idle timeout - seven days by default - while the repaired commit already sat on the remote. Bound it to three attempts, then park for a person with the published head named, because a rerun would resume from the stale gate head and omit the repair. CI is testing the published commit, so no fix agent can help; what a person needs is to know the local gate is behind. recordLocalRepair advanced the in-memory head before its durable write. A failed write left the monitor watching a head the run record did not know about, still carrying its old review approval, with the revalidation the call exists to trigger silently lost. Write durably first, then advance. Regressions: the retry stops at its bound and parks naming the published head while spending only one fix attempt; a failed revalidation write leaves both the live head and the review approval untouched. * no-mistakes(review): Persist and safely settle CI publication retries * no-mistakes(document): Clarify CI publication settlement documentation * no-mistakes(ci): Serialized the process-heavy CI repair fixture tests to prevent macOS subprocess exhaustion and indefinite fake-gh stalls. Verified with 3 repeated focused runs, 25 repetitions of the previously hanging case, and the full internal/pipeline/steps suite (passed in 113.6s) * test(ci): stop paying for a monitor loop to assert a delivery decision The macOS job timed out at the 600s package cap: the repair fixture tests each drove the full CI monitor loop, so every case spent provider polls and several subprocesses on a two-core runner to observe something commitRepair already reports. Serializing them made the wall clock worse, not better. Assert the delivery decision from commitRepair - Revalidate, the remote, the review approval, the push binding - and keep exactly one monitor-loop test for the wiring that is genuinely the monitor's: turning a held repair into a restart at Review and stating the policy in force. Four full monitor loops go away and the cases run in parallel again. Coverage is unchanged: every case still asserts the same observables, and the paths that are about the monitor - the fix round not being swallowed, the bounded publication retry - still drive Execute. * revert(ci): strip the unscoped publication-retry machinery Two things were added to this branch by auto-answered review findings that were never in its scope, and the captain has declined both. Removed, not repaired: - retryPendingRepair and its CI poll-loop call site, its bound, and its exhaustion gate. New runtime behaviour in the monitor. - The durable pending-publication state it needed: SetCIPendingPublication, the ci_pending_publish_head / ci_pending_publish_attempts columns and their migration, the StepResult fields, and the restore-on-CI-entry path. A persistence and schema addition. - publishRunHead's publicationProgress return, which existed only to tell that machinery whether the remote had been verified. Three reported defects went with the code that contained them rather than being fixed: a restored pending publication bypassed by a provider skip path, a marker write that could be lost, and a marker never consumed after a daemon restart. They are not reachable once the machinery is gone. Kept unchanged: the uniform provable-continuity rule, the corrected agent guidance and docs, the single-statement UpdateRunPublication, the reference docs that no longer describe the removed mirror warning, and the real merge-conflict regression. Tests that only exercised the removed machinery go with it. What survives still covers behaviour that survives, including that a partial publication records nothing and the next attempt completes it - which is the atomicity guarantee, not the retry. * no-mistakes(document): Deduplicate CI revalidation configuration guidance
8.0 KiB
git push no-mistakes
Kill all the slop. Raise clean PR.
English · 简体中文
no-mistakes puts a local git proxy in front of your real remote.
Push to no-mistakes instead of origin, and it spins up a disposable worktree, runs an AI-driven validation pipeline, forwards the branch to the configured push target only after every check passes, and opens a clean PR automatically.
- Non-blocking - the pipeline runs in an isolated worktree without disrupting your work.
- Agent-agnostic -
claude,codex,grok,rovodev,opencode,pi,copilot,antigravity, orcursor/acp:<target>viaacpx, with ordered fallbacks; every gate requires a runnable configured pipeline agent. - Agent-native -
/no-mistakeslets your coding agent do a task and gate it, or gate existing committed work: it runs the pipeline, has the pipeline apply safe fixes, and escalates the rest to you. - Human stays in charge - auto-fix or review findings, your call.
- Clean PRs by default - push, open PR, watch CI, and auto-fix failures in one shot.
Full documentation: https://kunchenguid.github.io/no-mistakes/
How it works
your branch
│ git push no-mistakes
▼
┌────────────────────────────────────────────────┐
│ disposable worktree — your work stays put │
│ review → test → docs → lint → push → PR → CI │
└────────────────────────────────────────────────┘
│ every check green
▼
clean PR, opened for you
Each step either passes on its own or stops with a finding for you to act on. Safe, mechanical fixes are applied automatically; anything that touches your intent is escalated for you to approve, fix, or skip. The initial change reaches the configured push target only after every local gate is green.
When CI itself fails, the pipeline repairs it and publishes that repair through the same guarded force-push path - but only when it can prove the repair builds on the head you already reviewed. When it cannot prove that, the repair goes back through Review before it is published, so unrelated history cannot replace the reviewed commit. Merge-conflict repairs rewrite history, so they always take that safer route.
Set ci.revalidate_repairs: true if every CI repair must itself be reviewed, at the cost of another full pass over your change each time CI is repaired.
Install
curl -fsSL https://raw.githubusercontent.com/kunchenguid/no-mistakes/main/docs/install.sh | sh
Windows, Go install, and build-from-source instructions are in the installation guide.
Quick Start
$ no-mistakes init
✓ Gate initialized
repo /Users/you/src/my-repo
gate no-mistakes → /Users/you/.no-mistakes/repos/abc123def456.git
remote git@github.com:you/my-repo.git
skill /no-mistakes installed for agents at user level
Push through the gate with:
git push no-mistakes <branch>
$ git checkout my-branch
# do some work in the branch...
$ git push no-mistakes
* Pipeline started
Run no-mistakes to review.
$ no-mistakes
# opens the TUI for the active run
For GitHub fork contributions, keep origin pointed at the parent repository and initialize with no-mistakes init --fork-url <your-fork-url>.
From the TUI you act on each finding: auto-fix ones are applied for you (or approve to let them), ask-user ones are a judgement call you approve, fix, or skip.
Once every check is green, the gate forwards your branch to the configured push target and opens the PR for you, so there is no manual git push origin and no hand-written PR body.
Prefer to let your coding agent drive the same flow headlessly?
Use /no-mistakes (see below).
Three ways to trigger the gate
Every change runs through the same pipeline. Pick the entry point that fits how you're working when the change is ready:
git push no-mistakes- the explicit Git path. Push a committed branch to the gate remote instead oforigin.no-mistakes- the TUI. Run it after making changes (no commit needed) and a wizard walks you through creating a branch, committing, and pushing through the gate, then attaches to the run.no-mistakes -ydoes all of that automatically./no-mistakes- the agent skill. Tell the coding agent to do a task and gate it with/no-mistakes <task>, or use bare/no-mistakesto gate existing committed work. It runs the pipeline, has the pipeline apply safe fixes, and stops to ask you about anything that needs a human call.
no-mistakes init installs the /no-mistakes skill for Claude Code and other agents. Under the hood the skill drives no-mistakes axi, a non-interactive TOON interface to the same approval flow.
See the quick start for the full first-run walkthrough.
Development
make build # Build bin/no-mistakes with version info
make test # Run go test -race ./... (excludes the e2e suite)
make e2e # Run the tagged end-to-end agent journey suite
make e2e-record # Re-record e2e fixtures when agent wire formats change
make lint # Check generated skill drift and run go vet ./...
make skill # Regenerate committed no-mistakes skill files
make fmt # Run gofmt -w .
make demo # Regenerate demo.gif and demo.mp4 (needs vhs and ffmpeg)
make docs # Build the Astro docs site in docs/dist
See Makefile for the full target list.
make e2e-record overwrites internal/e2e/fixtures/ from the real claude, codex, opencode, and antigravity CLIs, spends real API quota, and should be reviewed before committing.
