feat: non-destructive lock recovery for pushed branches (Closes #440) #467

Closed
jcwalker3 wants to merge 3 commits from feat/issue-440-lock-recovery into master
Owner

Summary

Closes #440. Delivers non-destructive recovery when an author pushes work but loses the MCP session lock (restart/crash): keyed durable locks, own-branch adoption, structured branch ownership, and gitea_create_pr resolution without remote branch deletion.

Changes

  • issue_lock_store.py — keyed per-issue lock files under GITEA_ISSUE_LOCK_DIR; session binding; find_lock_for_branch for post-restart create_pr
  • issue_lock_adoption.py — adopt exact own branch; block competing same-issue branches
  • issue_branch_ownership.py — canonical (fix|feat|docs|chore)/issue-<n>-<desc> parsing (#440 AC 6)
  • gitea_mcp_server.py — wire store + adoption into gitea_lock_issue / gitea_create_pr
  • Docs — non-destructive recovery runbook; prohibit manual global lock seeding
  • Tests — restart adoption, durable create_pr, competing actor block, open-PR block, substring false-positive guard

Verification

venv/bin/python -m unittest tests.test_issue_branch_ownership tests.test_issue_lock_adoption tests.test_issue_lock_recovery tests.test_issue_lock_store tests.test_mcp_server.TestIssueLocking tests.test_mcp_server.TestCreatePR -q
# 42 tests OK

Worktree

branches/issue-440-lock-recovery @ 43874bf

Closes #440

## Summary Closes #440. Delivers non-destructive recovery when an author pushes work but loses the MCP session lock (restart/crash): keyed durable locks, own-branch adoption, structured branch ownership, and `gitea_create_pr` resolution without remote branch deletion. ## Changes - **`issue_lock_store.py`** — keyed per-issue lock files under `GITEA_ISSUE_LOCK_DIR`; session binding; `find_lock_for_branch` for post-restart `create_pr` - **`issue_lock_adoption.py`** — adopt exact own branch; block competing same-issue branches - **`issue_branch_ownership.py`** — canonical `(fix|feat|docs|chore)/issue-<n>-<desc>` parsing (#440 AC 6) - **`gitea_mcp_server.py`** — wire store + adoption into `gitea_lock_issue` / `gitea_create_pr` - **Docs** — non-destructive recovery runbook; prohibit manual global lock seeding - **Tests** — restart adoption, durable `create_pr`, competing actor block, open-PR block, substring false-positive guard ## Verification ```bash venv/bin/python -m unittest tests.test_issue_branch_ownership tests.test_issue_lock_adoption tests.test_issue_lock_recovery tests.test_issue_lock_store tests.test_mcp_server.TestIssueLocking tests.test_mcp_server.TestCreatePR -q # 42 tests OK ``` ## Worktree `branches/issue-440-lock-recovery` @ `43874bf` Closes #440
jcwalker3 added 3 commits 2026-07-07 16:25:18 -05:00
Store per remote/org/repo/issue locks under GITEA_ISSUE_LOCK_DIR with
atomic writes and per-session binding. Integrate own-branch adoption for
lock recovery, update worktree-start and cleanup reconcile, and add tests
documenting the ban on manual global lock seeding.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adds structured issue-branch ownership parsing, wires it into lock adoption
and gitea_lock_issue validation, documents the restart recovery workflow, and
adds regression tests for adoption, durable create_pr resolution, and open-PR
blocking without remote branch deletion.

Built on keyed persistent lock store and own-branch adoption (#443 / #442).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
jcwalker3 force-pushed feat/issue-440-lock-recovery from 43874bf092 to d67b2f54eb 2026-07-07 16:25:18 -05:00 Compare
sysadmin closed this pull request 2026-07-07 16:33:01 -05:00
Author
Owner

Closing as an unsafe duplicate/stacked #440 umbrella PR. The canonical path is the child stack: #465/#443 for keyed persistent lock store, #461/#442 for own-branch adoption/create_pr recovery, and #464/#438 for related lock survival/store work. Revisit #440 only after the child stack lands or is closed/superseded.

Closing as an unsafe duplicate/stacked #440 umbrella PR. The canonical path is the child stack: #465/#443 for keyed persistent lock store, #461/#442 for own-branch adoption/create_pr recovery, and #464/#438 for related lock survival/store work. Revisit #440 only after the child stack lands or is closed/superseded.
Owner

Closing as an unsafe duplicate/stacked #440 umbrella PR. The canonical path is the child stack: #465/#443 for keyed persistent lock store, #461/#442 for own-branch adoption/create_pr recovery, and #464/#438 for related lock survival/store work. Revisit #440 only after the child stack lands or is closed/superseded.

Closing as an unsafe duplicate/stacked #440 umbrella PR. The canonical path is the child stack: #465/#443 for keyed persistent lock store, #461/#442 for own-branch adoption/create_pr recovery, and #464/#438 for related lock survival/store work. Revisit #440 only after the child stack lands or is closed/superseded.

Pull request closed

Please reopen this pull request to perform a merge.
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#467