bug(run): text appended after the automated PR-body trailer is wiped by the next QA pass — isAutomatedPRBody treats "contains the trailer" as "wholly automated"

Open
#1,594 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
54/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
github, typescript
Domain
backend, testing

Research direction

Start in src/lib/workflow/worktree-manager.ts at isAutomatedPRBody and the update branch around line 2827, then read buildAutomatedPRBody and the existing body tests. Run the named Vitest cases for “after the trailer” and “tail keeps” to see the current behavior. Done means regenerated bodies preserve the text after the trailer verbatim while hand-edited generated content still triggers the existing warning.

Written by the indexing model from the issue text.

Description

bug

Found while closing #1520 (PR #1587); filed with the owner's word 2026-10-26.

Problem

sequant run regenerates the PR body after every QA pass. #1247 AC-2 added the guard isAutomatedPRBody (src/lib/workflow/worktree-manager.ts:2612): a body is overwritten only when it is empty or contains the trailer 🤖 Generated by sequant run`` (AUTOMATED_PR_TRAILER, :2601); otherwise the run prints `PR #N body was edited by hand; not overwritten` (:2827–2835) and leaves it. The guard answers "did sequant write this body" with "does the trailer appear anywhere", so a body that a human (or the runner) appended to still counts as wholly automated and is replaced in full on the next QA pass. Nothing warns, and the PR's own history is the only record that the text existed.

Measured on PR #1587: the runner appended a verification section after the trailer (body 9,184 characters); the next qa-only pass rewrote the body from the exec summary, the verdict and the Follow-ups list (4,369 characters). The section had to be re-appended by hand after the last QA pass. A reviewer who adds notes to a generated body between QA passes loses them the same way.

This matters for the surface #1520 chose: R-1 puts the computed Read-first partition on the PR because the PR is where the merge decision is made; a body that silently resets undermines that.

Decision

ID Decision Rejected alternative
D-1 Everything after the trailer survives a regeneration: the run rebuilds the automated part and re-attaches the preserved tail verbatim Posting additions as PR comments instead (works for the runner, does nothing for a human who edits the body, and moves the evidence off the surface R-1 chose)
D-2 The hand-edit guard keeps its current meaning for text above or inside the generated part: a body whose generated part was edited is still left alone with the existing warning Diffing the generated part against a stored copy (state has no copy of the body; capImportedText already makes the text non-reproducible)

Acceptance Criteria

  • AC-1: Text after the trailer in an existing automated body is present, verbatim, at the end of the regenerated body. Evidence: npx vitest run src/lib/workflow/worktree-manager.build-pr-body.test.ts -t "after the trailer" → ≥ 1 passed, 0 failed (new case; today the filter matches 0 of 59 tests)
  • AC-1 is classified as a gate test by isGateTestEvidence; the PR body carries its SEQUANT_MUTATION record (drop the preserved tail from the rebuilt body → the new case fails; restore).
  • AC-2: A body with the trailer and nothing after it regenerates exactly as today, and a body without the trailer is still not overwritten and still prints the hand-edit warning. Evidence: npx vitest run src/lib/workflow/worktree-manager.build-pr-body.test.ts src/lib/workflow/worktree-manager.test.ts → 0 failed (59 and the existing #1247 cases pass today)
  • AC-3: The preserved tail is not re-capped or sanitized as exec text: capImportedText (#1582's file) does not run on it, and a SEQUANT_MUTATION marker inside the tail survives. Evidence: npx vitest run src/lib/workflow/worktree-manager.build-pr-body.test.ts -t "tail keeps" → ≥ 1 passed, 0 failed (new case)
  • AC-4: On a real run the appended text survives: append one line after the trailer on a testbed PR (ad-motion #285, next run number), run sequant run <N> --phases qa --force, and read the body. Evidence: gh pr view "$PR" --json body --jq .body | grep -c '<the appended line>' → 1 (runner, testbed)

May touch

src/lib/workflow/worktree-manager.ts (isAutomatedPRBody, the update branch at :2827, buildAutomatedPRBody's caller), worktree-manager.build-pr-body.test.ts, worktree-manager.test.ts, docs/ page that describes the PR body, CHANGELOG. Independent hunks from #1582 (capImportedText); either may land first.

Non-Goals

  • Preserving edits made inside the generated part (D-2).
  • Changing what the generated part contains (the exec summary cut is #1582; the Read-first comment is a PR comment, #1520).
  • No edits under plugin/, .claude/skills/, templates/skills/ (plugin freeze).
Dominant language
TypeScript
Stars
1
Forks
1
Avg merge
11h 3m
Merged PRs (30d)
84

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from sequant-io/sequant

All issues in sequant-io/sequant

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.