fix(gate): preserve exact-owner renewal evidence across duplicate rechecks (Closes #945) #946
Open
jcwalker3
wants to merge 1 commits from
fix/issue-945-owning-pr-renewal-evidence into master
pull from: fix/issue-945-owning-pr-renewal-evidence
merge into: :master
:master
:fix/issue-945-owning-pr-renewal-evidence
:fix/issue-943-runtime-context-helpers
:fix/issue-941-scope-guard-bootstrap-wiring
:docs/issue-930-remote-mcp-coupling-inventory
:fix/issue-927-pytest-config
:feat/issue-708-mcp-namespace-attachment
:fix/issue-892-author-bootstrap-deadlock
:fix/issue-686-detect-reject-manual-mcp
:feat/issue-707-cross-project-boundaries
:fix/issue-690-review-profile-switch-guard
:fix/issue-704-prevent-env-workspace-bindings
:fix/issue-700-durable-walls
:fix/issue-672-mcp-config-drift
:fix/issue-689-deterministic-mcp-namespace
:fix/issue-678-codex-mcp-reconnect
:feat/issue-649-sentry-console-correlation
:feat/issue-666-concurrent-mcp-restart-tests
:feat/issue-659-maintenance-drain-mode
:feat/issue-648-notifications-console
:fix/issue-670-direct-master-incident
:feat/issue-644-console-recovery
:feat/issue-650-providers-insights
:feat/issue-669-scoped-component-recovery
:docs/issue-668-mcp-ha-rolling-restart
:feat/issue-667-console-restart-controls
:feat/issue-665-restart-audit
:feat/issue-664-break-glass-restart
:feat/issue-645-linkage-console
:feat/issue-643-request-preview-initiate
:fix/issue-897-permission-stale-runtime-classification
:feat/issue-641-runtime-session-view
:feat/issue-663-restart-classes
:feat/issue-661-drain-proof-hard-gate
:fix/issue-854-semantic-container-exclusion
:issue-640
:fix/issue-682-starlette-httpx2
1
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
79334d4840 |
fix(gate): preserve exact-owner renewal evidence across duplicate rechecks (Closes #945)
An exact-owner lease renewal (#760) is granted the owning-PR duplicate-work
waiver inside gitea_lock_issue, but every later enforcement path rebuilt that
proof from the durable lock through
issue_lock_recovery.recovered_owning_pr_from_lock, which reads only the
dead_session_recovery block. A plain renewal persists its proof under
lease_renewal instead, so the waiver expired with the lock call and the next
author mutation was refused duplicate_commit_prevented with
owning_pr_recovery_exempted: false on the very PR the renewal had just proved.
Add issue_lock_renewal.owning_pr_renewal_from_lock as the renewal mirror of the
recovery rebuild, and resolve both halves through one helper,
_owning_pr_continuation_from_lock, in the same precedence gitea_lock_issue
applies. The three enforcement paths that previously saw only recovery evidence
now share that resolver: the commit/create-PR duplicate recheck, the read-only
duplicate assessor, and the push-ownership prover.
The rebuild re-applies the equality the renewal assessor required (PR head ==
local head == remote head) and additionally binds the record to the claimant the
lock names, so a renewal block cannot be reused under another identity, profile,
or workflow session. Validation of the resulting token against live PR state is
unchanged and still owned solely by
issue_work_duplicate_gate._assess_owning_pr_exemption, so repository, issue, PR,
branch and head binding continue to be enforced in exactly one place.
No public signature, MCP tool schema, refusal shape, or reason code changes.
Dead-session recovery behaviour is untouched.
Tests: tests/test_issue_945_owning_pr_renewal_continuation.py - 49 tests,
8 subtests, all in-memory (no durable branch, worktree, lock, lease or PR).
Against unmodified
|