Repository navigation
Description
Problem
squash-message.sh (278 lines) writes the SQUASH_AGENTMSG skeleton the agent completes. It builds the subject from the title and number, collects the trailers across every collapsed commit with awk, drops sign-offs the identity policy rejects, adds the machine sign-off, orders Assisted-by first and Signed-off-by last, reads the Related section of the description for issue references and decides which become Closes #N, then prints the briefing: description, commits in full, diffstat, trailers and what is missing. It is under the shell freeze in #588, and its trailer logic decides which attribution survives a squash.
Part of #324, within #588. Child 08 in #324's Children list. Replaces packages/agents/source/skills/merge-pr/shared/scripts/squash-message.sh.
Acceptance criteria
- AC1: Given a pull request number, or the open pull request for the current branch, when
agentrepo merge messageruns, thenSQUASH_AGENTMSGholds the subject<title> (#<number>), aCloses #Nline for each referenced open issue, and the ordered trailers, and the briefing prints the same sections as the shell script. - AC2: Given commits whose trailing trailer blocks overlap without being identical, when trailers are collected, then each distinct trailer line is kept once in first-seen order, a commit with no body contributes none from its subject, and
Assisted-bylines come first andSigned-off-bylines last with other trailers between. - AC3: Given a
Signed-off-bytrailer the identity policy rejects, when trailers are collected, then it is dropped withDropped sign-off: <trailer>on stderr, and an exit status other than 0 or 1 from the check stops the command with that status. - AC4: Given the machine sign-off identity is not already present, when the message is built, then it is appended once.
- AC5: Given references in the description's Related section to an open issue, a closed issue, a pull request, or an object GitHub answers for but does not describe as either, when the footer is built, then only an open issue becomes
Closes #N, the others become# Not closed: #N ...comment lines in the briefing and never in the draft, and the pull request's own number is skipped. - AC6: Given a GitHub request for a reference fails, when the command runs, then it exits with that request's status before writing, and an existing
SQUASH_AGENTMSGkeeps its previous content. - AC7: Given a qualified cross-repository reference such as
owner/repo#99in the Related section, when the footer is built, then it never becomes aClosesline for a local issue of the same number. - AC8: Given more files than GitHub listed, when the diffstat prints, then the "N of M files listed" note appears.
- AC9: Given
commit-lintis absent, when the command runs, then it exits 1 with a message naming the mise pin to add; givenghis absent, then it exits 1 with the shell script's separate message; given a pull request with no title, then it exits 1 with the shell script's separate message. - AC10: Given an existing
SQUASH_AGENTMSGfrom another pull request, when the command runs and succeeds, then it replaces it. - AC11: Non-functional: the only file written is
SQUASH_AGENTMSG, and the command runs on macOS, Linux and Windows in CI.
Scope and non-goals
Scope: agentrepo merge message, trailer collection and ordering, Related-section parsing, tests ported from the squash-message cases in merge-workflow.bats and lifecycle.bats.
Non-goal: writing the message body, which remains the agent's step. Non-goal: the sign-off identity policy itself, which commit-lint keeps. Non-goal: editing the shell script before child 14.
Approach
Meet AC1 to AC11 with failing cases first: golden skeleton and briefing output from the shell script on fixed fake-gh fixtures, then Go compared byte for byte. Mechanism is the implementer's choice.
Dependencies
Prerequisites: #321 (sign-off identity resolver, GraphQL reader) and #333.
Size
M. One pull request.
Verify plan
- AC1, AC2, AC4, AC8, AC10: golden comparison against the shell script on commit and trailer fixtures, including overlapping non-identical trailer blocks.
- AC3: a fake
commit-lintthat exits 0, 1 and 2. - AC5, AC6, AC7: fake GraphQL answers for each reference kind, one failing request with a pre-existing draft whose bytes are compared afterwards, and a qualified cross-repository reference.
- AC9: missing-
commit-lint, missing-ghand empty-title cases, each asserting its own message. - AC11: a worktree snapshot test; the CI matrix run.
- 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-bytrailer and the pull request has theprovenance:agent-assistedlabel. 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 finalStatus:comment names the merge commit.
Risks
Dropping a legitimate attribution trailer, keeping a rejected sign-off, or turning a foreign reference into a local closing keyword would change what lands on the default branch. The golden trailer fixtures and AC7 are the controls. Undo: revert; the shell script is untouched.
Operator authority
None.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Work type
Projects
- StatusShow more project fieldsBacklog
Activity
tbhb-agent commentedon Oct 27, 2026
Refinement: READY — The squash message skeleton and briefing are written by agentrepo merge
Model: gpt-6-astra
Child 08 The squash message skeleton and briefing are written by agentrepo merge
Verdict: READY
Checked: Trailer-line deduplication, failed-reference preservation, qualified-reference handling and distinct prerequisite diagnostics retain the round 2 corrections. They match
packages/agents/source/skills/merge-pr/shared/scripts/squash-message.sh:114,packages/agents/source/skills/merge-pr/shared/scripts/squash-message.sh:186andpackages/agents/source/skills/merge-pr/shared/scripts/squash-message.sh:200. Verification covers the stated outcomes.Gaps: None.
Split: None needed.
Definition of done
The definition of done for this issue (Feature). Tick each item and give its evidence.
check-leaks.shwith the repository's private-strings list, and the leak review of each post.docs/, CHANGELOG or help text), or the Verification section says "No doc impact" and why.provenance:agent-assistedlabel.Status:comment names the merge commit.mise run checkis green, and so are the coverage floorsmise run cover-go-checkandmise run cover-py-check, whichcheckdoesn't run.packages/agents/source/commits whatmise run generate-skills, thenmise run skill-tokens, thenapm installrewrite, in that order, andcheck-generated-skills(part oflint) passes.docs/agent-skills-migration.mdor the adoption docs, or the PR's Verification says "No consumer impact" and why.Round: 3 of 3