feat(labctl): land a PR/CR from the agent surface (pr merge) #48
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab!48
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/37"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Adds
labctl pr merge <n>so an AFK agent can land a mergeable PR/CR — the routine end-of-task step that until now always needed a human. TheTrackerseam growsMergePull(number) (PullRef, error), reachable over the run-token agent surface (repo-scoped by the run row), on both bindings.Closes #37
How
Tracker.MergePull+tracker.ErrMergeRejected(carries the backend's own words verbatim).internal/crmerge.Service, which both the operator route (POST /crs/{n}/merge) and the built-in tracker'sMergePullcall. The per-CR mutex (merge and close serialize), the cancellation-immune git window, author identity (repo's real identity else settings, never a bot), the per-op credential,Closes #Nclosure, and thecr.changed/issue.changedevents are preserved byte-for-byte — the operator route keeps its exact M6 status codes.ErrMergeRejected→ 409; an already-merged PR is a convergent no-op success; a 404 and a throttle stay their own typed conditions (404 / retryable), not a permanent "merge refused".POST /agent/v1/prs/{n}/merge+ the labctl client/CLI; a refusal is exit 1 with the message on stderr.Acceptance criteria
Closes #Nand emitting the same events as the operator merge —TestAgentBuiltinPRMergeFullLoop.MergePulltests + agent handler test.Testing
go build ./...,go vet ./...,gofmtclean, and the full suite green (the only failures are the pre-existing environmentalinternal/tmuxxtests — tmux can't start sessions in this sandbox; that package doesn't touch this change). New tests cover each binding'sMergePull, the agent handler, the labctl CLI, and the end-to-end builtin agent merge loop. A multi-agent adversarial review ran over the diff; its three confirmed findings (rate-limit/internal-error classification, forge head-survival coverage) are fixed in this branch.Add `labctl pr merge <n>` and grow the Tracker seam with MergePull, so an AFK agent can land a mergeable PR/CR entirely over the run-token surface — no forge token ever reaches the session. - Tracker seam: MergePull(number) (PullRef, error) + ErrMergeRejected sentinel. - Lift the ADR-0011 CR-merge/close orchestration out of the httpapi handler into a shared internal/crmerge.Service that BOTH the operator route and the built-in tracker's MergePull call — preserving the per-CR mutex, the cancellation-immune git window, author identity, per-op credential, Closes #N closure, and cr.changed/issue.changed events byte-for-byte. - Forgejo/GitHub bindings gain a real merge action performed under the server's forge token; fixed merge method (the forge enforces its own strategy and protection); a refusal surfaces verbatim as ErrMergeRejected (a throttle and a 404 stay their own typed conditions); an already-merged PR is a convergent no-op success. - Agent route POST /agent/v1/prs/{n}/merge (repo-scoped by the run row) plus the labctl client method and CLI command; a refusal is a 409 / exit 1 verbatim. - ADR-0024 records the decision; ADR-0011 gains a pointer. Closes #37 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011z1HjhQYV5i7PRbyNYofi6