ReviewOS

also looking at this

stacks/buddy

fix(ci): land the lock-file repair instead of describing it

#1408
Merged glennmichael123 wants to merge fix/persist-the-mechanical-lockfile-repair into main
6 files +193 -15
9 days ago

The mechanical repair reported:

Regenerated the lock file and pushed the result. No model was needed.

Nothing pushed anything. The callback rewrote the file in the workspace, the job ended, and the workspace went with it — so the one repair Buddy can make without a model, and the one it is most confident about, never reached a branch.

That is the worst shape a report can take: confident, specific and wrong.

Reporting what actually happened

Three outcomes, now distinct:

ResultReportfixed
Regenerated and pushed"…and pushed the result. No model was needed."true
Regenerated, push failed"…but could not push it to the branch. The change is in the workspace only, so the run will still be red."false
Install failed"Tried to regenerate the lock file, but the install did not succeed."false

fixed is true only for the first — a file rewritten in a discarded workspace has repaired nothing.

Landing it

commitAndPush in src/utils/git.ts. Deliberately not GitProvider.commitChanges, which does git reset --hard origin/<base> + git clean -fd: correct for a dependency update Buddy owns end to end, catastrophic on a branch carrying someone else's commits. The fix-ci job has already checked the branch out with credentials, so a local commit is sufficient and safe.

Staging nothing counts as success with nothing to record — an identical regenerated file is not a failure.

A tested policy I nearly broke

I first changed the checkout to secrets.BUDDY_TOKEN || secrets.GITHUB_TOKEN, so the push would re-trigger CI and actually turn the build green. The suite stopped me:

cli-setup-extended.test.ts: GITHUB_TOKEN is primary for bot attribution; BUDDY_TOKEN rides alongside it for elevated scopes. The || pattern breaks that.

Five tests, and they are right — a PAT push would attribute Buddy's commits to whoever owns the token. Reverted.

So the trade stands and is now documented rather than implied away: the fix lands, but the checks still need re-running, because GitHub does not start a workflow run for a GITHUB_TOKEN push. Making that automatic without breaking attribution wants its own change — re-running the failed run via the API, guarded by the attempt counter from #1407.

--dry-run was not dry

The callback was passed unconditionally and never consulted the flag, so buddy fix-ci --dry-run rewrote lock files on disk while reporting it had changed nothing. attemptFix now takes the flag and reports the repair it would make without calling the callback at all.

Still open

failsOnBase remains unwired — deciding it needs a way to find the base branch's run, and the provider exposes only getWorkflowRunLogs(runId).

Verification

  • 1909 pass / 0 fail (+4), lint clean, typecheck clean
  • check:docs green: 75 pages, 33 commands, 221 config keys
  • Docs site builds: 73 pages

🤖 Generated with Claude Code

https://claude.ai/code/session_01UWouahBJT3msK7V2VDYY6T

6 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.