worktree finish --keep exits 1 silently when the worktree fast-forward fails; route it through Checkout #849
Labels
No labels
P0
P1
P2
P3
bug
category/code-change
category/cross-repo
category/eval-run
category/investigation
category/no-test-target
category/owner-ruling
category/prose-artifact
category/recurring-chore
category/structure
category/umbrella
crc-refactor
create
delete
enhancement
filed-by/agent
filed-by/user
frozen
lint-rule
needs-info
needs-triage
next
plugin/cc-architect
plugin/os
plugin/os-adr
plugin/os-aidd-lint
plugin/os-backlog
plugin/os-context
plugin/os-doc-hygiene
plugin/os-sdlc
plugin/os-vault
project/cc-os
ready-for-agent
ready-for-human
recurring
review
rule-proposal
update
waiting
wayfinder:grilling
wayfinder:map
wayfinder:map
wayfinder:research
wayfinder:task
wayfinder:task
wontfix
worklist/deviations
worklist/lint-rule
worklist/new-implement-build
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jared/cc-os#849
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Problem
FinishCommand#keep_aligned(plugins/os/lib/worktree/finish_command.rb:59) runsgit merge --ff-only <base>in the kept worktree through an inlineGit.new(worktree_path). When the fast-forward fails, for example because the worktree has uncommitted changes that it would overwrite, finish returns exit 1 and prints nothing. By then the branch is already merged into base.The
os:worktreeskill maps exit 1 to "Merge conflicts. The CLI prints the files. Resolve them, then run step 3 again." An agent would run finish again against a branch that is already merged.plugins/os/invariants.mditem 20 says every non-zero exit prints its reason.The inline
Git.newalso bypassesCheckout, which #844 made the owner of worktree-side git actions (checkout.rb:7,bring_up_toatcheckout.rb:29-35).RemovalandConflictScanreceive their git through a keyword with a default;keep_alignedhas no seam.Observed
Contract-auditor GAP line, #844 implementation 9, dispatch 75: "FinishCommand#keep_aligned returns EXIT_CONFLICTS when the worktree ff-only fails and prints no message (finish_command.rb:59). The ticket does not specify this case."
Lens challenge of the same dispatch's P2 line (2026-09-30), verdict "code defect found": "An object that obeys P2 already exists. Checkout ... FinishCommand#keep_aligned is the one worktree-side action that stayed behind."
Reproduce
pwith a commit not on base, and leave an uncommitted change inpto a file that base also changes.worktree finish p --keepfrom the main checkout.p.Origin
/os-sdlc:implement 844contract audit and lens challengekeep_alignedbuilds its own git and has no failure message ← #844 did not specify the casekeep_aligned); plugins/os/lib/worktree/checkout.rbVERDICT: CREATE — defect shipped in #844; breaks invariants.md item 20 (ticket-skeptic, 2026-09-30).
From #1589 port check: FIXED. Keep path now goes through Integration#align (plugins/os-git/lib/os_git/integration.rb:268-271), which raises MergeConflict on a failed ff-only. Finish#keep_aligned rescues it (plugins/os-git/lib/os_git/worktree/finish.rb:45-50) and Outcome.keep_failed prints the message (plugins/os-git/lib/os_git/worktree/finish/outcome.rb:39). Exit is 1 with a printed reason. No inline Git.new remains. Not closed.