feat: harden issue lock store against concurrent session clobbering (Closes #438)

Replace read-modify-write on the global /tmp/gitea_issue_lock.json pointer with
atomic per-issue locks under GITEA_ISSUE_LOCK_DIR using flock serialization,
PID/session metadata, fail-closed stale recovery, and pre-mutation freshness
re-checks in gitea_create_pr. Queue inventory now surfaces live_issue_locks.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
2026-07-07 16:25:30 -04:00
co-authored by Claude Opus 4.8
parent 89a7d4dbfc
commit 992d055998
7 changed files with 829 additions and 50 deletions
+13 -5
View File
@@ -274,12 +274,20 @@ is proven abandoned and the takeover is recorded.
Gitea-Tools lease gates: `gitea_lock_issue` (fail-closed before author
mutations), `status:in-progress`, and claim comments. `gitea_lock_issue`
records an `author_issue_work` lease in the issue-lock payload with issue
number, optional PR number, branch, worktree path, claimant identity/profile,
acquires an atomic per-issue lock under `GITEA_ISSUE_LOCK_DIR` (default
`/tmp/gitea_issue_locks/`) and updates the legacy session pointer at
`GITEA_ISSUE_LOCK_FILE` only when safe. The payload records issue number,
branch, repo scope, worktree path, claimant identity/profile, PID, session id,
created timestamp, expiry timestamp, and last heartbeat timestamp. An active
same-issue/same-operation lease blocks duplicate work. An expired lease still
blocks takeover until a recovery review records why the prior work is abandoned,
completed, or unsafe to continue.
same-issue/same-operation lease blocks duplicate work. An expired or dead-PID
lease still blocks takeover until a recovery review records why the prior work
is abandoned, completed, or unsafe to continue.
Author/reviewer/reconciler final reports must include **Issue lock proof** with:
lock acquired, lock owner, lock freshness, no competing live lock (when
applicable), and whether the lock was released or intentionally retained.
`gitea_lock_issue` returns a canonical `lock_proof` string for handoffs.
`gitea_list_claim_inventory` exposes `live_issue_locks` for queue visibility.
Remote branches matching the issue number are also treated as active work unless
the recovery review proves the branch is abandoned or superseded. Never delete