pilot worktree sync generates the squash subject instead of taking the branch HEAD's, whenever the lane branch has more than one commit
Version: Pilot Shell v10.2.4 (Solo tier), Linux, Python 3.12 build.
Summary
When pilot worktree sync squash-merges a lane branch, the resulting commit's subject depends on
how many commits the branch carries:
| Commits on the lane branch |
Resulting squash subject |
| exactly 1 |
the commit's own subject, preserved verbatim |
| 2 or more |
generated as <type>: implement <branch-name> |
In the multi-commit case every commit's full message is concatenated into the squash body, oldest
first, so no information is lost. The problem is confined to the subject line — and to the
conventional-commit <type> in it, which is derived from the branch name rather than from what the
change actually did.
Reproduction
Verified in both directions on one installation.
Single commit — subject and body preserved verbatim:
lane branch: 1 commit, subject "fix: <description of the change>"
squash on the base branch: subject "fix: <description of the change>"
Two or more commits — subject generated:
lane branch: 9 commits, HEAD's subject "test: <description of the change>"
squash on the base branch: subject "docs: implement <branch-name>"
In that second example the change was test-infrastructure work. It landed on the base branch typed
docs:, because the generated type came from the branch rather than from the diff or from HEAD's own
subject.
Why this hits the structured workflows specifically
A spec-style lane is always the multi-commit case by construction: it commits the plan document
first, then implements against it. So the generated subject is not an edge case for that workflow —
it is the normal outcome of every run.
A quick-fix-style lane that commits once keeps its subject, which is why the behaviour is easy to
miss: it looks like it works, right up until the workflow that always has two or more commits.
Impact
Low severity, but it is silent and it is in history permanently.
- An author writes a considered subject line expecting it to head the commit on the base branch, and
finds it demoted to a line in the body.
- The base branch's log acquires conventional-commit types that describe the branch rather than the
change, which degrades any tooling or review process that reads those types — docs: on a commit
that changed only test code, for example.
sync reports success, and nothing prompts anyone to read the log afterwards, so it is typically
discovered long after the fact. Rewriting an already-landed commit to correct it is not a
reasonable remedy, so the wrong subject simply stays.
Suggested fix
Take the branch HEAD's subject as the squash subject in the multi-commit case, exactly as the
single-commit case already does. The concatenated body already preserves every commit's message, so
nothing is lost by doing so, and the <type> then reflects the change rather than the branch name.
If the generated form is deliberate — to signal that a squash collapsed several commits — consider
keeping HEAD's subject and recording the collapse in the body instead, where it does not displace the
one line most tooling and most readers actually see.
Note on a related documentation claim
Local documentation carried the assertion that sync "preserves the lane's own commit message
through the squash, subject and body alike". That is true only for a single-commit branch. Worth
checking whether the same claim appears in the upstream docs.
pilot worktree syncgenerates the squash subject instead of taking the branch HEAD's, whenever the lane branch has more than one commitVersion: Pilot Shell v10.2.4 (Solo tier), Linux, Python 3.12 build.
Summary
When
pilot worktree syncsquash-merges a lane branch, the resulting commit's subject depends onhow many commits the branch carries:
<type>: implement <branch-name>In the multi-commit case every commit's full message is concatenated into the squash body, oldest
first, so no information is lost. The problem is confined to the subject line — and to the
conventional-commit
<type>in it, which is derived from the branch name rather than from what thechange actually did.
Reproduction
Verified in both directions on one installation.
Single commit — subject and body preserved verbatim:
Two or more commits — subject generated:
In that second example the change was test-infrastructure work. It landed on the base branch typed
docs:, because the generated type came from the branch rather than from the diff or from HEAD's ownsubject.
Why this hits the structured workflows specifically
A spec-style lane is always the multi-commit case by construction: it commits the plan document
first, then implements against it. So the generated subject is not an edge case for that workflow —
it is the normal outcome of every run.
A quick-fix-style lane that commits once keeps its subject, which is why the behaviour is easy to
miss: it looks like it works, right up until the workflow that always has two or more commits.
Impact
Low severity, but it is silent and it is in history permanently.
finds it demoted to a line in the body.
change, which degrades any tooling or review process that reads those types —
docs:on a committhat changed only test code, for example.
syncreports success, and nothing prompts anyone to read the log afterwards, so it is typicallydiscovered long after the fact. Rewriting an already-landed commit to correct it is not a
reasonable remedy, so the wrong subject simply stays.
Suggested fix
Take the branch HEAD's subject as the squash subject in the multi-commit case, exactly as the
single-commit case already does. The concatenated body already preserves every commit's message, so
nothing is lost by doing so, and the
<type>then reflects the change rather than the branch name.If the generated form is deliberate — to signal that a squash collapsed several commits — consider
keeping HEAD's subject and recording the collapse in the body instead, where it does not displace the
one line most tooling and most readers actually see.
Note on a related documentation claim
Local documentation carried the assertion that
sync"preserves the lane's own commit messagethrough the squash, subject and body alike". That is true only for a single-commit branch. Worth
checking whether the same claim appears in the upstream docs.