fix: rank complete allocator inventory and resolve declared dependencies (Closes #758) #761
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#761
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.
Closes #758
Head SHA:
ad59053cd7a2e7ecec60901666160a73eaa36efaBase:
master@854818e65a2741ba0740773fd9593d5e1f3d5751What changed
Two independent allocator defects, fixed together because either one alone still lets the queue select an ineligible issue.
Defect 1 — candidate truncation before ranking (AC1, AC2, AC3)
_allocator_candidates_from_giteafetched the complete open inventory throughapi_get_all, then sliced it withissues[: max(1, int(limit))]before constructing anyWorkCandidate. Everystatus:readyissue scores priority 20, andsort_candidatesbreaks that tie on lowest number, so the slice — not the ranking — chose the winner. Two callers asking the same question at differentlimitvalues received different answers.Candidate construction now consumes the full listing.
limitbounds the reported skip list only; the result carrieslimit_applies_to,skipped_total, andskipped_report_truncatedso a shortened report is never read as full coverage.A failed listing sets
inventory_complete=Falseand the tool fails closed rather than ranking a partial set.Defect 2 — dependency state inferred from body substrings (AC4-AC7)
Only
blocked on #anddownstream of #were recognized. The canonicalDepends: #N, #Nfield matched neither, sodependency_unmetstayedFalseand dependency-blocked issues were emitted as assignable.New module
allocator_dependencies.py:parse_dependency_refsextracts the canonical declaration into structured references, stopping at the next separator or sibling field, so references belonging to other linkage fields are never captured. The legacyblocked on #marker still parses.resolve_dependency_stateresolves each reference against live issue state — open means unmet, closed means met, unavailable or raising means unmet (fail closed).The complete open listing already proves openness, so no extra call is made for open references; anything absent from it is confirmed by a cached targeted lookup instead of being assumed closed.
Fall-through and policy (AC8, AC10)
The selection loop already advanced past a skipped candidate; with dependency state now resolved correctly that fall-through actually engages, and is covered by a regression.
SELECTION_POLICYstates the ranking and tie-break explicitly and is reported in the result.Evidence
Verified against master
854818e65a2741ba0740773fd9593d5e1f3d5751.The defect reproduces live: a dry run of
gitea_allocate_next_work(role=author, apply=false)returnedcandidate_count: 50and selected issue #644, whose body declares three dependencies that are all still open. Under this branch that candidate is marked ineligible and allocation continues.Tests: 35 new cases.
tests/test_allocator_dependencies.py(23) — parser forms, malformed input, open/closed/mixed/unavailable resolution, >50-candidate limit-invariant selection, apply-vs-preview parity, and a guard proving a pre-ranking slice would change the winner.tests/test_allocator_inventory_mcp.py(12) — MCP-levelgitea_allocate_next_workend to end against a faked Gitea API: 73-candidate inventory, identical winner atlimit=1andlimit=300, lookup caching, and fail-closed incomplete inventory.Full suite: 3672 passed, 2 failed, 6 skipped, 431 subtests passed.
Both failures are pre-existing on master and untouched by this branch —
test_issue_702_review_findings_f1_f6.py::TestF1RecoveryBeforeTerminalProbe::test_removed_worktree_recovers_before_probeandtest_reconciler_supersession_close.py::TestReconcilerSupersessionMcpTool::test_tool_posts_comment_and_closes_superseded_pr_issue. Both were reproduced identically in a detached worktree at unmodified854818ebefore this work was committed; neither touches allocator code.Boundary
No issue number is special-cased (AC14). Issues #642, #633, #634, #605, and #644 were read as evidence only; their scope, labels, and review state are unchanged. #628 keeps ownership of the durable dependency table; this PR corrects the present-day loader and selection path only. Dry-run no-mutation behavior and the lock-before-edit safeguards are unchanged (AC13).
Canonical PR State
ad59053cd7against #758 AC1-AC14repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #761
issue: #758
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 57940-e22d2084639d
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-fix-issue-758-allocator-dependency-aware
phase: claimed
candidate_head:
ad59053cd7target_branch: master
target_branch_sha:
854818e65alast_activity: 2026-07-19T18:22:02Z
expires_at: 2026-07-19T18:32:02Z
blocker: none
Independent review — APPROVE
Pinned head reviewed:
ad59053cd7a2e7ecec60901666160a73eaa36efaBase:
master@854818e65a2741ba0740773fd9593d5e1f3d5751Issue: #758
Reviewer: sysadmin / prgs-reviewer (not author jcwalker3)
Lease: session
57940-e22d2084639d, comment12940Worktree:
branches/review-fix-issue-758-allocator-dependency-aware(detached, clean, HEAD==pin)Acceptance criteria (AC1–AC14)
Safety properties
Independent validation
Baseline failures disposition
Both claimed failures reproduce identically on PR head and detached base
854818e:PR does not touch those paths. Label: pre-merge baseline-proven failure (not attributed to #761).
Review Metadata
Verdict
APPROVE at head
ad59053cd7.Review and merge are separate roles. This approval is not merge authorization.
Canonical PR State
STATE: ready-to-merge
WHO_IS_NEXT: merger
NEXT_ACTION: Merger session adopts reviewer lease or acquires merger lease, re-validates pinned head
ad59053cd7, and merges only with explicit operator authorizationNEXT_PROMPT:
WHAT_HAPPENED: Independent reviewer sysadmin/prgs-reviewer approved PR #761 at pinned head after full AC1-AC14 review and independent tests.
WHY: All acceptance criteria and safety properties for complete inventory ranking and dependency-aware eligibility are satisfied; formal approval submitted via native MCP; merge is a separate role.
ISSUE: 758
HEAD_SHA:
ad59053cd7REVIEW_STATUS: approved / approval_at_current_head
MERGE_READY: true
BLOCKERS: none for review; merge requires separate merger profile and explicit authorization
VALIDATION: focused 35 passed; related 49 passed; broader related slice 186 passed; two full-suite failures baseline-proven at 854818e; git diff --check clean; py_compile clean
NATIVE_REVIEW_PROOF: transport=native_mcp; entrypoint=mcp_server; profile=prgs-reviewer; identity=sysadmin; session=57940-e22d2084639d; lease_comment=12940; tool=gitea_submit_pr_review
LAST_UPDATED_BY: sysadmin (prgs-reviewer)
adopted_at: 2026-07-19T18:31:22Z
adopted_by_identity: sysadmin
adopted_by_profile: prgs-merger
adopted_from_session_id: 57940-e22d2084639d
adopted_from_profile: prgs-reviewer
adopted_from_reviewer_identity: sysadmin
adopted_from_comment_id: 12940
adoption_reason: merger-handoff-approved-head
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #761
issue: #758
reviewer_identity: sysadmin
profile: prgs-merger
session_id: 61137-01d254cefc92
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/merge-issue-758-allocator-dependency-aware
phase: adopted
candidate_head:
ad59053cd7target_branch: master
target_branch_sha:
854818e65alast_activity: 2026-07-19T18:31:22Z
expires_at: 2026-07-19T18:41:22Z
blocker: none
Stale #332 review-decision lock cleanup (#594)
Status: APPLIED
sysadminprgs-merger2026-07-19T18:32:19.495732+00:00approveon PR fix: rank complete allocator inventory and resolve declared dependencies (Closes #758) (#761)closed(merged=True)8a851eb87e63fc236d8897ed67f67cbe295bc3ae1prgs-reviewerManual deletion of session-state files is not the workflow.
This path only clears a lock when the referenced PR is merged/closed.