Allocator ignores active foreign leases and lets one claimed issue blockade the whole author queue #765
Closed
opened 2026-07-19 22:05:36 -05:00 by jcwalker3
·
2 comments
No Branch/Tag Specified
master
feat/issue-626-self-propagating-handoffs
fix/issue-772-unpublished-claim-recovery
archive/role-poisoning-dfb5ebd
archive/capability-role-invariants-bc9366c
docs/mcp-stable-control-runtime-policy
fix/issue-695-native-quarantine-v2
chore/issue-681-preserve-review-session-wip
fix/issue-673-remediate-regressions-part2
feat/issue-610-live-remote-parity
feat/issue-503-reviewer-active-worktree
feat/issue-470-preflight-contract
feat/issue-440-lock-recovery
feat/issue-440-branch-recovery
feat/issue-458-queue-fail-closed-copy
feat/issue-400-early-duplicate-work-gate
feat/issue-308-reconcile-inventory-pagination
feat/issue-308-reconcile-pagination-proof
docs/issue-261-agent-temp-artifact-cleanup
feat/issue-262-map-commit-files
fix/infra-stop-conflict-marker-false-positive
feat/issue-139-role-aware-task-routing
feat/issue-188-continuation-selection-wall
feat/issue-189-continuation-mode-proofs
feat/issue-232-refresh-wiki-proof-heads
feat/issue-210-block-workspace-edits
feat/issue-204-exact-issue-lock
docs/issue-80-label-taxonomy
docs/issue-79-safety-boundary-updates
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#765
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.
Problem
allocator_service.allocate_next_worknever consults active leases while selecting work. It expires stale leases and checks the terminal-review lock, but it never asks whether a candidate is already claimed by a live lease belonging to a different session.WorkCandidate.already_claimed_elsewhereexists andclassify_skiphonours it, but nothing ever populates it from live control-plane state. The MCP candidate loader does not set it.Consequence: the allocator returns the highest-ranked issue even when another concurrent session holds an active, unexpired lease on it.
assign_and_leasethen correctly returnswait, but only after that issue was already chosen. Because the allocator does not fall through to the next unclaimed candidate, a single claimed issue becomes a global blockade for every other author session, and the reported inventory is misleading (inventory_complete=truewithskipped_total=0while a leased issue is the selection).Observed
Live control-plane state carried an active author lease on one issue (
status=active,expired_by_time=false, owned by a different session id). A dry-run allocator preview for roleauthorstill selected that same issue, reportedskipped_total=0, and offered it asprimary_next_safe_action. Independent author sessions therefore had no eligible work even though many unclaimedstatus:readyissues existed.Ownership cannot be expressed today
Each allocator invocation registers a new
session_id(the same process produced...-68c3c00aand later...-40b391ef). Session id alone therefore cannot distinguish "my own in-progress task" from "another controller's task", and profile name cannot either, because every author session sharesprgs-author. A stable controller identity is required before ownership comparisons are meaningful.Required behaviour
claimed_by_other_session.primary_next_safe_actionfor a different controller.controller_instance_idto ownership comparisons.Acceptance criteria
skippedwith reasonclaimed_by_other_session.controller_instance_idvalues are treated as different owners.skippedsoskipped_totalreflects reality.controller_instance_idis persisted on sessions and surfaced on lease rows; legacy leases without it are treated as foreign, never silently adopted.primary_next_safe_actioncannot advertise a claimed issue.Non-goals
Canonical Issue State
STATE:
correction implemented and verified on a local branch; publication to Gitea was not performed because the author workspace-binding gate refused the commit
WHO_IS_NEXT:
user
NEXT_ACTION:
Operator must bind the gitea-tools author namespace to a branches/ worktree (or land a fix for the binding gap) so gitea_commit_files can publish branch fix/issue-765-allocator-foreign-lease; then a fresh author cycle publishes and opens the PR.
NEXT_PROMPT:
WHAT_HAPPENED:
Issue #765 was filed for the allocator ownership defect, locked to branch fix/issue-765-allocator-foreign-lease in worktree branches/issue-765-allocator-ownership, and implemented. Live claims are now loaded before ranking; candidates claimed by a different controller are excluded and reported in skipped with reason_code claimed_by_other_session, and ranking continues to the next unclaimed candidate. A stable controller_instance_id is persisted on sessions and surfaced on lease rows, so a controller can resume its own task while never adopting another controller's. The workflow dashboard applies the same exclusion. Work is preserved as local commit d06198b. gitea_commit_files was attempted exactly once and refused pre-API; a read-back of the branch returns 404, proving no branch, commit, or PR was created on Gitea.
WHY:
Session ids are regenerated per allocator invocation and every author session shares the prgs-author profile, so neither can express controller ownership. Without a durable identity the allocator either blockades the queue on someone else's lease or risks adopting it. A stable controller_instance_id makes the comparison decidable, and unidentifiable claims are excluded rather than adopted so the failure mode stays safe.
RELATED_PRS:
none - no PR was opened
BLOCKERS:
Blocker classification: environment/tooling blocker
gitea_commit_files exposes no worktree_path parameter, and neither GITEA_ACTIVE_WORKTREE nor GITEA_AUTHOR_WORKTREE is set on the running gitea-tools process, so the author workspace resolves to the stable control checkout and the #274 guard fails closed. This gap blocks all author publication, not one task. Direct git push, editing server env, writing a repo-root .env, and restarting MCP are outside sanctioned author authority, so no fallback was attempted.
VALIDATION:
New tests: tests/test_allocator_foreign_lease_exclusion.py, 23 cases covering ownership classification, foreign-lease exclusion, next-unclaimed selection, own-task resume across a new session id, task-local blocker isolation, concurrent controllers on different issues, all-claimed wait with owner_session_id preserved, ownership-defect reporting, skipped inventory accounting, and end-to-end exclusion against a real ControlPlaneDB. Full suite: 3717 passed, 6 skipped. Two failures (test_issue_702_review_findings_f1_f6, test_reconciler_supersession_close) were re-run against unmodified master at
fcf6981and fail identically there, so they are pre-existing and unrelated. One pre-existing contract test caught an over-broad first draft of the ownership classifier and the classifier was narrowed so that a claim with no identity on either side is foreign rather than unidentifiable, preserving the earlier wait contract. Read-only check against the live control-plane DB: the sole active claim is classified foreign, and with the live author-safe queue in dashboard order the corrected allocator skips that issue with reason_code claimed_by_other_session and selects the next unclaimed one, where the shipped allocator selected the claimed issue and reported zero skips.LAST_UPDATED_BY:
jcwalker3 / prgs-author / scheduled controller author cycle / 2026-07-20
[THREAD STATE LEDGER]
What is true now:
What changed:
issue #765 created; this canonical comment posted. No branch, commit, PR, review, or merge. The single gitea_commit_files attempt was refused before any API call and read-back confirmed absence.
What is blocked:
Who/what acts next:
Do not do:
Canonical Issue State
STATE:
AUTHOR_RECOVERY_REQUIRED — coherent #765 implementation exists only as local commit d06198b97d583f0b960adcb435931effbf305516 on branch fix/issue-765-allocator-foreign-lease; behavior is absent from master edaeede250f46f361784061f025ab0e867172d2c; no PR opened; remote branch unpublished
WHO_IS_NEXT:
author
NEXT_ACTION:
When the author WIP slot is free: bind the author MCP namespace to worktree branches/issue-765-allocator-ownership, re-lock/adopt #765 onto fix/issue-765-allocator-foreign-lease, rebase or re-apply d06198b onto current master if needed, publish only via gitea_commit_files, then open one PR closing #765 for independent review. Do not re-implement. Do not open a reconciler PR.
NEXT_PROMPT:
WHAT_HAPPENED:
Supervised reconciler branch-disposition for Issue #765 only (profile prgs-reconciler, identity sysadmin). Preflight: jasonwalker/UID 502; clean control checkout on master@edaeede matching prgs/master. Candidate worktree clean at d06198b. Issue #765 open with labels anti-stomp, mcp-health, status:ready, type:bug, workflow-hardening. Durable author handoff comment 13053 already recorded local completion + publication failure (workspace binding / #274). Comparison: d06198b not ancestor of master; stable patch-id bacafc5f… unmatched on master file history; all five changed blobs differ; master only has inert already_claimed_elsewhere. Worktree path alias issue-765-allocator-ownership is the lock-recorded semantic path (not branch-slug path). Issue lock exists for jcwalker3/prgs-author pid 86632, expires_at 2026-07-20T07:06:09Z (TTL elapsed; audit has_active_issue_lock=false). No active control-plane lease on #765. Worktree audit: active_issue_work, clean, no open PR, not removable. No mutations other than this disposition comment; artifacts preserved.
WHY:
The #765 defect (allocator ignores active foreign leases and blockades the author queue) is still present on shipped master. The candidate fully implements the required ownership model and tests. Without publishing this commit, concurrent author sessions remain at risk of selecting foreign-claimed work. Disposition is recovery of existing work, not new allocation or supersession cleanup.
RELATED_PRS:
none for #765. Open PR inventory complete (1 open: #767 Closes #607 only). Closed inventory scanned (349 total, inventory_complete=true): no PR title/body/head implements, supersedes, or closes #765.
BLOCKERS:
Blocker classification: environment/tooling + author-slot sequencing
fcf6981— author must rebase/re-apply before PR if merge would conflict, without discarding d06198b semantics.VALIDATION:
LAST_UPDATED_BY:
sysadmin / prgs-reconciler / supervised branch-disposition / 2026-07-20
[DISPOSITION PROOF]
Disposition class: AUTHOR_RECOVERY_REQUIRED
Preservation: keep branch + worktree until author publishes. No reconciler PR. No orphan cleanup yet.