Open
opened 2026-07-22 03:28:20 -05:00 by jcwalker3
·
0 comments
No Branch/Tag Specified
master
feat/issue-798-worker-registry-schema
feat/issue-610-live-remote-parity
docs/issue-632-web-console-architecture
feat/issue-628-autonomous-handoffs-orchestration
fix/issue-790-slice-a-heartbeat-policy
fix/issue-760-exact-owner-renewal
fix/issue-787-kill-segment-separators
chore/issue-681-preserve-review-session-wip
v1.1.0
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
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#793
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.
Scope transfer
Slice C of Issue #790, transferred to its own issue so that closing #790 through the Slice A pull request does not imply this work is done. Issue #790 tracks and is completed by Slice A only. The acceptance criteria below are carried verbatim from the controller reassessment recorded in Issue #790 comment 13958.
Problem
Three gaps remain after Slice A.
Fencing is write-side only.
issue_lock_store.bind_session_lockperforms alock_generationcompare-and-swap inside the per-issue flock, and Slice A added the same compare-and-swap to the heartbeat writer. Butissue_lock_store.verify_lock_for_mutation— the gate every author mutation passes through — checks freshness, issue number, branch, and worktree, and does not check the generation. A session holding a stale in-memory lock record therefore still passes the read side after another session has reclaimed or retired the work.The Issue #760 renewal path predates heartbeats. It grants renewal to the exact recorded owner of an expired lease with no heartbeat requirement at all, which was correct when it landed because heartbeats did not exist. Now that they do, historical ownership is not evidence of present activity, and the boundary has to move.
The shared lifecycle covers one task class. Slice A migrated
author_issue_workand deliberately declared but did not rewire reviewer, merger, conflict-fix, and control-plane leases. Their durations are recorded inlease_policywithheartbeat_lifecycle_activefalse, and a Slice A test asserts the declared values still match the constants those modules own, so the two cannot drift apart before this issue migrates the call sites.Acceptance criteria
AC-C1.
verify_lock_for_mutationverifieslock_generationin addition to its existing freshness, issue, branch, and worktree checks, so a session holding a stale in-memory lock record cannot pass the read-side gate after another session has reclaimed or retired the work. This is #790 AC-N4.AC-C2. The Issue #760 exact-owner renewal path is re-scoped to require a fresh heartbeat within the grace window. A lease past the missed-heartbeat reclaim threshold is not renewable on historical ownership evidence alone and must use the sanctioned reclaim or re-adoption path under generation fencing, which mints a new generation and a genuine heartbeat. This is #790 AC-N5.
AC-C3. The remediation delivered by PR #791 remains in force until this replacement is implemented and covered end to end. It is not removed, weakened, or short-circuited before its replacement is proven.
AC-C4. Reviewer, merger, and conflict-fix leases read their durations from
lease_policyrather than module-local constants, and adopt the shared acquire, renew, expire, reclaim, release, and audit semantics. Task classes may keep different values; they may not keep different lifecycles.AC-C5. The control-plane lease default in
control_plane_dbis aligned to the same policy source, with explicit compatibility behavior for lease rows written under the previous default.AC-C6. A late heartbeat from a superseded session cannot revive or overwrite ownership after another session has reclaimed the task, across every migrated task class. Heartbeat, adoption, release, and reclaim operations are atomic and idempotent.
AC-C7. Native MCP integration tests cover every downstream gate this work touches, driving the real tools against a real repository and real durable state. Assessor-only coverage is explicitly insufficient: it did not catch either of the two sanction discard points found in review #499 on PR #791. This is #790 AC-N6 applied to this slice.
AC-C8. Existing behavior is preserved: Issue #753 dead-session recovery, Issue #755 owning-pull-request evidence, Issue #772 generation compare-and-swap, Issue #747 reviewer sliding TTL semantics where values are unchanged, and the Slice A heartbeat lifecycle and legacy-lock protection.
Required tests
verify_lock_for_mutationafter another session advances the generation.Dependencies
Depends on Issue #790 Slice A landing first, for
lease_policyand the heartbeat lifecycle this extends. Independent of Slice B; the two may proceed in either order. Touchesissue_lock_storeexpiry and conflict assessment, so it must not be allocated concurrently with Slice B or with any other work on those surfaces.Non-goals
Do not implement Slice B. Do not weaken worktree cleanliness, ancestry, publication, or binding checks. Do not make pid liveness an ownership authority. Do not use one identical duration for every task class merely because the lifecycle is shared.
Canonical issue state