Skip to content

Push the branch and write the pull request from agentrepo pr #918

Description

@tbhb-agent

Problem

publish.sh performs the writes after every gate passes. It plans the push (new branch, current, fast-forward, or a rewrite that leases on the exact remote commit), pushes with the repository's pre-push hook, checks through git ls-remote that origin holds the reviewed commit, and rechecks the branch, draft and identity before writing. It then creates the pull request through gh-post, or edits an open one (base, title, body, labels, reviewers, assignees, milestone, draft state) while preserving the owner-review label. A wrong lease or a retried uncertain write is the costly failure here.

Part of #588 and #323. Delivers in Go the behavior of packages/agents/source/skills/pr/shared/scripts/publish.sh. This change adds Go behavior only and switches no caller.

Acceptance criteria

  1. AC1: Given a new branch, a branch origin already holds at the reviewed commit, or a fast-forward, when publication runs, then it plans the push kind from what origin holds now (read from origin itself), pushes only when there is something to push, and checks through git ls-remote that origin holds the reviewed commit afterwards.
  2. AC2: Given a rebased branch and no --rewrite, when publication runs, then it refuses to push and says to use --rewrite only on the operator's word; given --rewrite, then it pushes with a lease on the exact commit origin holds.
  3. AC3: Given HEAD behind origin's branch, origin holding a commit never fetched here, or origin's branch unreadable, when publication runs with or without --rewrite, then it refuses before any push.
  4. AC4: Given --dry-run, when publication runs, then it prints the push plan, warns when the real push would not fast-forward, checks the identity, and pushes and writes nothing without consulting the confirmation.
  5. AC5: Given a repository pre-push hook, when publication pushes, then the hook runs before the push completes and its failure stops publication.
  6. AC6: Given HEAD moved during the push, or origin holds a commit other than the reviewed one afterwards, when publication continues, then it refuses before any pull request is touched; given unattended mode and a branch, draft or signed-in account that changed since the checks, then it refuses before the GitHub write, with the account change and the draft change as separate cases.
  7. AC7: Given no open pull request for the branch, when publication succeeds, then a pull request is created through gh-post with the draft's base, head branch, title, body, draft flag, labels, reviewers, assignees and milestone, and its URL is printed.
  8. AC8: Given an open pull request for the branch, when publication succeeds, then its base, title and body are edited, labels, reviewers and assignees are reconciled in both directions, an empty milestone value removes the milestone and a set one applies it, readiness is set or undone to match the draft's draft value, and the URL is printed.
  9. AC9: Given an open pull request that carries the owner-review label (matched in any letter case), when publication reconciles labels, then that label is preserved and never removed, and publication never adds it from the draft's properties.
  10. AC10: Given gh fails while reading the open pull request's current properties, when publication edits, then no edit has been made.
  11. AC11: Given a write's outcome is uncertain, when publication fails, then it is not retried and the output says to inspect GitHub.
  12. AC12: Non-functional: pull request creation and content edits (base, title, body) go through gh-post with the body from --body-file; property-only edits (labels, reviewers, assignees, milestone) also go through gh-post, with empty standard input as the shell does and no body file; readiness changes use gh pr ready; no other gh write is made.

Scope and non-goals

Scope: push planning, the push, the remote check, the post-push rechecks, creation and editing, and handing the publication outcome (number, URL, head, base, draft state, push kind) to the caller.

Non-goal: the gates and confirmation before this, and property resolution, which child 08 ports. Non-goal: recording the publication result and the unattended report, which child 10 owns (that recording happens only in unattended mode today). Non-goal: the gh-post implementation. Non-goal: switching the shell caller, which child 12 does.

Approach

Meet AC1 to AC12 with failing table-driven cases first, using bare scratch repositories as remotes and the fake gh and gh-post the Bats suite uses, and match the shell's lease and refusal output byte for byte. The unattended recheck cases follow tests/skills/agent-pr/publish.bats.

Dependencies

Blocked by: #917, #760 (identity and rate-limit reporting), #753 (protection of new Go enforcement paths).

Prerequisite: #321.

Size

M. One pull request. Estimated under 650 changed code lines with tests (about 190 shell lines of behavior).

Verify plan

  • AC1, AC2, AC3: Go tests over bare remotes with new, current, fast-forward, rebased, behind and unfetched-commit setups.
  • AC4: a test runs a dry run with a recording confirmation source and asserts no push or write.
  • AC5: a test with a hook that records and one that fails.
  • AC6: tests where a stub moves HEAD, rewrites the remote ref after the push, switches the signed-in account, and changes the draft; tests/skills/agent-pr/publish.bats cases are the oracle.
  • AC7, AC8, AC9, AC10: tests with a fake gh and a recording gh-post, including an owner-review label in mixed case and a failing read.
  • AC11: a test where the create call fails after sending asserts exactly one attempt and that the output carries the instruction to inspect GitHub.
  • AC12: a test asserts every gh write outside gh pr ready goes through gh-post; the creation and content-edit calls carry --body-file, and a property-only edit carries no body file and has empty standard input.
  • Go tests run in the existing Go CI on macOS, Linux and Windows.
  • Definition of done: D1 each AC is verified at the merged head, with the commands and results cited in the pull request's Verification. D2 an independent review approves the exact merged head, and every finding has a recorded disposition. D3 required checks pass with no gate loosened. D4 the leak scans the repository specifies are clean, and every post made for this work passes the per-post leak review before it is posted. D5 every commit is signed. D6 the documentation matches the change or the Verification says why there is no impact. D7 every commit has an Assisted-by trailer and the pull request has the provenance:agent-assisted label. D8 the pull request stays within the size limits. D9 follow-ups are filed as issues and listed under Related. D10 the merge closes the issue through a closing reference, the board shows Done, and the final Status: comment names the merge commit.

Risks

A force push with the wrong lease overwrites a collaborator's commits, and a retried create can open a duplicate. The AC2, AC3 and AC11 cases are the control. Undo: revert the change; nothing calls the Go publication yet and the shell publishes as before.

Operator authority

None. The pr scripts are not on the owner-path list in .agents/agent-skills.conf; if the port touches lib.sh, agent.sh or a guard*.sh file, the pull request says so and states the owner review.

Activity

  1. tbhb-agent commented on Oct 27, 2026

    @tbhb-agent
    ContributorAuthor

    Refinement: READY — Push the branch and write the pull request from agentrepo pr
    Model: gpt-6-astra

    Child 09 Push the branch and write the pull request from agentrepo pr

    Verdict: READY

    Checked: Verification now distinguishes body-file content writes from property-only edits with empty stdin, while retaining readiness changes. The uncertain-create check now asserts both no retry and the inspection diagnostic. Earlier creation, owner-label and post-push corrections remain covered. Evidence: packages/agents/source/skills/pr/shared/scripts/publish.sh:114, packages/agents/source/skills/pr/shared/scripts/publish.sh:138, packages/agents/source/skills/pr/shared/scripts/publish.sh:151, packages/agents/source/skills/pr/shared/scripts/publish.sh:179.

    Gaps: None.

    Split: M remains plausible; no further split justified.

    Definition of done

    The definition of done for this issue (Feature). Tick each item and give its evidence.

    • D1 The author verified each AC on the merged head, and the Verification section of the pull request cites each AC ID with its evidence: the command and its result, or a link.
    • D2 An independent reviewer approved the exact merged head, and the author resolved each finding or filed it as a follow-up.
    • D3 The required checks pass on that head, and any loosened gate has the owner's approval of that exact head.
    • D4 The leak scans come back clean: gitleaks, devtools' check-leaks.sh with the repository's private-strings list, and the leak review of each post.
    • D5 The author signed each commit, the squash included.
    • D6 The docs match the change (README, docs/, CHANGELOG or help text), or the Verification section says "No doc impact" and why.
    • D7 The commits and the squash have Assisted-by trailers, and the pull request has the provenance:agent-assisted label.
    • D8 The pull request stays within the size limits, or the owner approved its exact head over the hard limit.
    • D9 The author files follow-ups and deferred findings as issues with at least a Problem and numbered AC and lists them under the Related section of the pull request. Any work left in the code links its issue.
    • D10 The merge closes the issue through a closing reference and the board shows Done. The final Status: comment names the merge commit.
    • devtools-1 mise run check is green, and so are the coverage floors mise run cover-go-check and mise run cover-py-check, which check doesn't run.
    • devtools-2 A change to skill sources under packages/agents/source/ commits what mise run generate-skills, then mise run skill-tokens, then apm install rewrite, in that order, and check-generated-skills (part of lint) passes.
    • devtools-3 A consumer-visible change (the vendored payload, a skill, a reusable workflow, a task or a pin) has its consumer steps in docs/agent-skills-migration.md or the adoption docs, or the PR's Verification says "No consumer impact" and why.

    Round: 3 of 3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    refinement:readyPassed the Definition of Ready; may be picked up

    Fields

    Priority

    None yet

    Work type

    None yet

    Projects

    • Status
      Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions