fix(author-lock): dead-session recovery cross-session PR base-sync (Closes #872) #880
Labels
Clear labels
allocator
anti-stomp
architecture
bug
chore
codex
concurrency
contamination
control-plane
dashboard
database
design
documentation
enhancement
gitea
glitchtip
important
incident
incident-bridge
integration
jenkins
labels
leases
mcp
mcp-health
mcp-menu
multi-project
mutating
nice-to-have
observability
portability
preflight
protected-branch
queue
read-only
reconnect
recovery
refactor
release
reliability
resumable-review
reviewer
roadmap
safety
security
self-hosted
sentry
stale-runtime
status:blocked
status:in-progress
status:pr-open
status:ready
terminal-lock
testing
tracker
type:bug
type:feature
type:feature
type:guardrail
visibility
workflow
workflow-hardening
workflow-hardening
Controller-owned work allocator
Prevent concurrent LLM session stomping
Architecture / structural design
OpenAI Codex client / workflow session surface
Concurrent session safety
Workflow or session contamination incident
MCP control-plane coordination and allocation authority
MCP operational dashboard/queue view
Internal coordination storage (SQLite/Postgres)
Design / investigation, no implementation
Docs / runbooks
New feature or improvement
Gitea MCP workflow
GlitchTip integration
Operational or process incident requiring durable audit trail
Sentry-to-Gitea incident bridging
Integration testing
Jenkins integration
Label taxonomy management
Lease adopt/release/expire lifecycle
MCP server / tooling
MCP namespace and runtime health
MCP menu surface
Work spanning multiple monitoring projects or Gitea repos
Mutating action; requires gating
Observability, metrics, traces, error reporting
Cross-platform / portability
Shared preflight gates before mutation
Protected branch / stable-branch policy concern
Work queue visibility and allocation
Read-only, no mutation
MCP client reconnect/reload recovery path
Recovery paths for stale/foreign leases
Code refactor / restructure
Release / versioning
Reliability / failure handling
Persist and resume prepared review verdicts across sessions
Reviewer workflow tooling
Roadmap / umbrella issue
Safety rails and fail-closed mutation guards
Security / trust boundary
Self-hosted infrastructure integration
Sentry error monitoring integration
Stale backend daemon / runtime-vs-master parity failures
Issue is blocked
Issue is being worked on
Issue has an open pull request
Issue is ready for work
Terminal review lock (#332) path
Tests / test coverage
Issue tracker hygiene / meta
Bug or defect
Feature or enhancement
Feature or enhancement
Safety gate or guardrail
Workflow state visibility for LLMs/operators
Cross-tool workflow
LLM workflow coordination hardening
LLM workflow coordination hardening
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Scaled-Tech-Consulting/Gitea-Tools#880
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary of Changes
Fixes Issue #872 by updating
read_merge_sync_provenanceinissue_lock_worktree.pyand_evaluate_issue_lock_recoveryingitea_mcp_server.pyto accept theremoteparameter and fetch missing remote commit SHAs inworktree_pathwhen assessing dead-session recovery.HEAD_RELATION_REMOTE_MERGE_SYNCEDafter a prior server-sidegitea_update_pr_branch_by_mergeadvanced the remote PR head.RuntimeError, or history rewriting.tests/test_issue_872_dead_session_two_base_syncs.py).Closes #872.
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #880
issue: none
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 18798-f94661c47008
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr880-202607240951
phase: claimed
candidate_head:
e42756b27ftarget_branch: master
target_branch_sha:
2976c21ee6last_activity: 2026-07-24T13:52:29Z
expires_at: 2026-07-24T14:02:29Z
blocker: none
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #880
issue: none
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 49636-f4b4854633a4
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/fix-issue-872-dead-session-two-base-syncs
phase: claimed
candidate_head:
e42756b27ftarget_branch: master
target_branch_sha:
2976c21ee6last_activity: 2026-07-24T14:03:17Z
expires_at: 2026-07-24T14:13:17Z
blocker: none
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #880
issue: #872
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: prgs-reviewer-97460-b5db4219
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr880-20260724144358
phase: claimed
candidate_head:
e42756b27ftarget_branch: master
target_branch_sha:
36fe4785eclast_activity: 2026-07-24T14:44:17Z
expires_at: 2026-07-24T14:54:17Z
blocker: none
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #880
issue: #872
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: prgs-reviewer-97460-b5db4219
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr880-20260724144358
phase: validated
candidate_head:
e42756b27ftarget_branch: master
target_branch_sha:
36fe4785eclast_activity: 2026-07-24T14:44:55Z
expires_at: 2026-07-24T14:54:55Z
blocker: none
Review: PR #880 — dead-session recovery cross-session PR base-sync (#872)
Verdict: APPROVE
Reviewer
sysadmin/prgs-reviewer(not authorjcwalker3). Heade42756b27f2b958b87b2f893a37daffb41e3a7b1not already on master. Scope is three files: remote-aware merge-sync provenance fetch, recovery path wiring, and focused tests. Focused suite: 5 passed. Secret sweep clean. No reviewer file edits.Review Metadata:
Canonical PR State
STATE: approved
WHO_IS_NEXT: merger
NEXT_ACTION: Merger assess sync status then merge only if merge_now at this head
NEXT_PROMPT:
WHAT_HAPPENED: Reviewer validated PR #880 against #872 and submitted APPROVE via native MCP gitea_submit_pr_review
WHY: Provenance fetch for cross-session merge-sync SHAs is correctly wired; focused tests pass; scope limited to issue #872; no secrets; author safety clean
ISSUE: #872
HEAD_SHA:
e42756b27fREVIEW_STATUS: approved
MERGE_READY: pending merger preflight
BLOCKERS: none
VALIDATION: focused tests/test_issue_872_dead_session_two_base_syncs.py — 5 passed; worktree clean; secret sweep clean; not already-landed
NATIVE_REVIEW_PROOF: transport=native_mcp; entrypoint=mcp_server; token_fingerprint=11d0a28f8701a278
LAST_UPDATED_BY: prgs-reviewer (sysadmin)
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #880
issue: #872
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 73614-610a005605f3
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr880-20260724144358
phase: claimed
candidate_head:
64e6d7b7dftarget_branch: master
target_branch_sha:
35714258f0last_activity: 2026-07-24T20:09:44Z
expires_at: 2026-07-24T20:19:44Z
blocker: none
APPROVE — issue #872 verified at head
64e6d7b7df(post base-sync onto master35714258f0). No blockers. Two non-blocking LOW observations are recorded below for a follow-up issue.NATIVE_REVIEW_PROOF: reviewed in native worktree /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr880-20260724144358 pinned at 64e6d7b7dfe0e5a74526e37f5e53bb88522401dd; diff, source reads, caller tracing, and test execution performed against that checkout.
Scope
git diff 35714258 64e6d7b7is 3 files, +358/-16:issue_lock_worktree.py(+41/-16),gitea_mcp_server.py(+1),tests/test_issue_872_dead_session_two_base_syncs.py(new, 332). One non-merge commit,e42756b. Nothing outside #872.Behavior verified
read_merge_sync_provenancegains an optionalremoteparameter. When the synced head is not present in the local object store, it fetches the named remote, re-probes presence, and falls back to a baregit fetchbefore re-probing again._evaluate_issue_lock_recoverypassesremote=remote.gitea_update_pr_branch_by_mergeadvanced the remote PR head, a dead-session worktree still sitting at the prior head could not observe the merge commit, so provenance came back unproven and recovery deadlocked.issue_lock_recovery. The new code only makes an already-required object locally readable; it never asserts a relation it has not observed.check=Falseand the result is decided solely by re-probing object presence, so a failed fetch leavessynced_presentfalse and provenance unproven.subprocess.run(no shell). Theremotevalue cannot be an arbitrary URL:gitea_lock_issueruns_resolve(remote, ...)before recovery evaluation, and_resolveraisesValueError: Unknown remotefor anything outside theREMOTESallowlist, so only a configured instance name can reachgit fetch.Test evidence (this session, at
64e6d7b7)venv/bin/python -m pytest tests/test_issue_872_dead_session_two_base_syncs.py tests/test_issue_lock_worktree.py -q— 20 passed.Coverage includes both the first and second base-sync recovery, plus three refusal paths that matter most here: dirty worktree blocks recovery, a foreign reclaimer blocks recovery, and a non-merge rebased remote head blocks recovery.
Non-blocking observations (LOW — follow-up issue, not merge blockers)
subprocess.runcalls inissue_lock_worktree.py; the other thirteen are local git plumbing that cannot stall. An unreachable or slow remote can block lock recovery for as long as git waits. Suggesttimeout=on both fetches with the timeout treated as "not present", which preserves the fail-closed result.remoteis a caller parameter and selects the fetch target. The allowlist makes it safe, but the sentence should say so rather than deny the parameter exists.Canonical PR State
STATE: approved
WHO_IS_NEXT: merger
NEXT_ACTION: Merge pull request 880 at head
64e6d7b7dfusing the merger role, then close issue 872 and clean up the merged branchNEXT_PROMPT:
WHAT_HAPPENED: Reviewed pull request 880 at head
64e6d7b7dfin a pinned reviewer worktree after the author base-synced the branch onto master35714258, traced the caller chain for the new remote parameter, confirmed the provenance proof conditions and their fail-closed behavior are unchanged, ran the focused and lock-worktree test scopes, and approved at that exact head with two non-blocking LOW observations.WHY: The change is required to break the #872 deadlock in which a dead author session could not complete a second cross-session base-sync recovery, because the merge commit produced server-side by gitea_update_pr_branch_by_merge was absent from the local object store and provenance therefore could not be proven; the fix supplies the missing object without relaxing any proof condition.
ISSUE: 872
HEAD_SHA:
64e6d7b7dfREVIEW_STATUS: approved
MERGE_READY: yes
BLOCKERS: none
VALIDATION: venv/bin/python -m pytest tests/test_issue_872_dead_session_two_base_syncs.py tests/test_issue_lock_worktree.py -q — 20 passed, run at
64e6d7b7dfin the reviewer worktree. Scope confirmed as 3 files, +358/-16, all within #872.LAST_UPDATED_BY: prgs-reviewer (sysadmin), session 73614-610a005605f3
adopted_at: 2026-07-24T20:13:28Z
adopted_by_identity: sysadmin
adopted_by_profile: prgs-merger
adopted_from_session_id: 73614-610a005605f3
adopted_from_profile: prgs-reviewer
adopted_from_reviewer_identity: sysadmin
adopted_from_comment_id: 16065
adoption_reason: merger-handoff-approved-head
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #880
issue: #872
reviewer_identity: sysadmin
profile: prgs-merger
session_id: 73614-610a005605f3
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr880-20260724144358
phase: adopted
candidate_head:
64e6d7b7dftarget_branch: master
target_branch_sha:
35714258f0last_activity: 2026-07-24T20:13:28Z
expires_at: 2026-07-24T20:23:28Z
blocker: none
Stale #332 review-decision lock cleanup (#594)
Status: APPLIED
sysadminprgs-merger2026-07-24T20:13:58.492902+00:00approveon PR fix(author-lock): dead-session recovery cross-session PR base-sync (Closes #872) (#880)closed(merged=True)9b5289940c898d75e90b8d05612d942f36008fb81prgs-reviewerManual deletion of session-state files is not the workflow.
This path only clears a lock when the referenced PR is merged/closed.