Repository navigation
fix(kanban): prevent reuse of unfinished worktree checkouts - #126018
Wenfengcheng wants to merge 1 commit into
Conversation
The fence design is sound — exclusive 1. A dead creator's fence permanently bricks a complete, correct workspace. 2. Pre-existing #126004 damage is still handed out as a workspace. The fence only exists for checkouts this code created, so a partial checkout left by the pre-merge version — or by a hand-run
|
|
@Enough1122 Thanks for the concrete failure cases. I checked the exact PR head ( The interrupted-publication case is reproducible: a creator subprocess exiting immediately after successful I also reproduced the unmarked Validation: 15 passed, 0 failed (five temporary feedback probes plus the existing ten creation-failure tests), isolated HOME/USERPROFILE/HERMES_HOME/APPDATA/LOCALAPPDATA. No product code change and no full-issue-resolution claim. Continuation decision: retain this independently useful partial fix; legacy unmarked recovery needs a safe ownership/publication contract, while timeout policy and stderr retention have existing owners as documented above. |
|
Correction accepted — the unfinished-fence error raised at |
Problem
Part of #126004. A failed/timed-out Kanban
git worktree addcan leave valid Git metadata before tracked files have been checked out. A retry then returns that partial directory as a usable worker workspace.Root cause
_ensure_git_worktreeaccepts a matching common directory as success;_resolve_worktree_workspaceindependently accepts an explicit linked checkout. Neither records whether the creator completed.Change
Verification
Frozen main base:
83597d9b712741bf427b01c26e1b02b4a1435a94.Native Windows, isolated HOME/USERPROFILE/HERMES_HOME/APPDATA/LOCALAPPDATA before imports, official
scripts/run_tests.shwith the existing test interpreter:resolve_workspace, timeout/nonzero × repo-anchor/explicit-target. Git--no-checkoutprovides deterministic early metadata; only the interrupted command outcome is injected.scratch.rmdir()on Windows (in-use cwd); the same failure was reproduced on the frozen base. Not claiming a full-suite PASS.git diff --check: clean.Broader DB/board/isolation run: 58 passed, 3 failed. All three failures reproduce on the frozen base in the same full DB file (51 passed, 3 failed on each head). Official Claude Code 2.1.280 / Opus 5.5 review is blocked by upstream HTTP 503
auth_unavailable; not PASS. Codex 0.153.4 / gpt-5.6-sol independent exact-head static review: STATIC PASS, no introduced blocker found (a bounded retry completed after the first attempt timed out). This does not replace the blocked Claude review. No real 41k-file/Defender benchmark is claimed.Scope / remaining acceptance
Delivered here: failed new checkout cleanup + rejection of unfinished marked checkouts through both reuse paths.
Remaining: timeout policy (pre-existing #98754 owns that contract), DB stderr retention, and recovery of legacy unmarked partial trees. Existing empty directories may still be used, but are never deleted on failure. An unresolved marker requires stopping the creator and verifying/repairing/removing the target before deleting the marker; no automatic stale-marker reclamation.
Overlap checked against actual diffs: #98754 changes only checkout budgets; #104226 covers hooks after a successful checkout; #80046 was closed unmerged at its author's request and its registry/lifecycle design is not resurrected here. No new tool/config/dependency, lifecycle registry, branch realignment, remote-tip policy or post-success hook changes.
Continuation decision
Continue safety/verification follow-through on this PR; do not claim full issue resolution. After this PR was published, #126020 appeared with overlapping cleanup and the remaining stderr-budget change. Its actual diff has been inspected. Keep this earlier independently verified contribution open; do not duplicate the newly owned stderr change. Timeout policy already overlaps #98754. Legacy unmarked partial recovery needs a separate proof that legitimate dirty user worktrees cannot be mistaken for incomplete checkouts.