fix(workflow): remove status:pr-open when the associated PR reaches a terminal state #780

Closed
opened 2026-07-21 14:04:34 -05:00 by jcwalker3 · 3 comments
Owner

Problem

The workflow applies status:pr-open while an issue has an active pull request, but the label is not reliably removed when that PR is merged or otherwise reaches a terminal state.

A repository-wide audit found 40 closed issues carrying the stale label:

  • Issue #626, cleaned separately after its controller closure.
  • An additional 39 closed issues subsequently cleaned in one authorized batch.
  • After cleanup, a complete paginated enumeration confirmed zero closed issues carrying status:pr-open.
  • The repository had zero open pull requests during the audit, so none of those labels represented a legitimate active PR.

This required manual label repair and shows that the normal merge/controller closure path does not enforce terminal label cleanup.

Expected behavior

When the PR associated with an issue is merged, closed, superseded, or otherwise made terminal:

  1. Remove status:pr-open from the associated issue.
  2. Preserve every other issue label exactly.
  3. Preserve the issue’s correct open or closed state.
  4. Support an empty resulting label set when status:pr-open was the only label.
  5. Make the operation idempotent so retries are safe.
  6. Verify the resulting state through read-after-write checks.
  7. Fail closed and report actionable diagnostics if label cleanup cannot be completed.

Scope

Review every sanctioned terminal path that can leave an issue associated with a non-open PR, including:

  • successful merge;
  • controller post-merge closure;
  • PR closed without merge;
  • superseded or abandoned PR handling;
  • reconciliation of an already-landed change;
  • recovery or retry after a partial workflow failure.

There should be one authoritative cleanup rule or shared helper rather than independent behavior that can drift between paths.

Acceptance criteria

  • status:pr-open is automatically absent after every applicable terminal transition.
  • All unrelated labels remain unchanged.
  • Empty replacement-label sets work correctly.
  • Repeated cleanup calls are harmless.
  • Tests cover merge, close-without-merge, supersession, already-landed reconciliation, retry/idempotency, unrelated-label preservation, and the only-label case.
  • Controller/terminal validation detects and reports any residual status:pr-open.
  • Existing canonical workflow documentation and final-report requirements are updated where necessary.
  • A regression test demonstrates the previously observed leak and passes with the fix.

Evidence

The cleanup audit examined all 356 closed issues through complete pagination. Forty stale instances were repaired in total, including #626. Final read-back returned zero closed issues labeled status:pr-open, with no issue-state or unrelated-label drift.

## Problem The workflow applies `status:pr-open` while an issue has an active pull request, but the label is not reliably removed when that PR is merged or otherwise reaches a terminal state. A repository-wide audit found 40 closed issues carrying the stale label: - Issue #626, cleaned separately after its controller closure. - An additional 39 closed issues subsequently cleaned in one authorized batch. - After cleanup, a complete paginated enumeration confirmed zero closed issues carrying `status:pr-open`. - The repository had zero open pull requests during the audit, so none of those labels represented a legitimate active PR. This required manual label repair and shows that the normal merge/controller closure path does not enforce terminal label cleanup. ## Expected behavior When the PR associated with an issue is merged, closed, superseded, or otherwise made terminal: 1. Remove `status:pr-open` from the associated issue. 2. Preserve every other issue label exactly. 3. Preserve the issue’s correct open or closed state. 4. Support an empty resulting label set when `status:pr-open` was the only label. 5. Make the operation idempotent so retries are safe. 6. Verify the resulting state through read-after-write checks. 7. Fail closed and report actionable diagnostics if label cleanup cannot be completed. ## Scope Review every sanctioned terminal path that can leave an issue associated with a non-open PR, including: - successful merge; - controller post-merge closure; - PR closed without merge; - superseded or abandoned PR handling; - reconciliation of an already-landed change; - recovery or retry after a partial workflow failure. There should be one authoritative cleanup rule or shared helper rather than independent behavior that can drift between paths. ## Acceptance criteria - `status:pr-open` is automatically absent after every applicable terminal transition. - All unrelated labels remain unchanged. - Empty replacement-label sets work correctly. - Repeated cleanup calls are harmless. - Tests cover merge, close-without-merge, supersession, already-landed reconciliation, retry/idempotency, unrelated-label preservation, and the only-label case. - Controller/terminal validation detects and reports any residual `status:pr-open`. - Existing canonical workflow documentation and final-report requirements are updated where necessary. - A regression test demonstrates the previously observed leak and passes with the fix. ## Evidence The cleanup audit examined all 356 closed issues through complete pagination. Forty stale instances were repaired in total, including #626. Final read-back returned zero closed issues labeled `status:pr-open`, with no issue-state or unrelated-label drift.
jcwalker3 added the status:readyworkflow-hardeningtype:bug labels 2026-07-21 14:04:34 -05:00
Author
Owner

RELATED ISSUE

Related: #513 — defines the issue-label taxonomy and generic workflow transitions. Issue #780 addresses enforcement of status:pr-open cleanup when a PR becomes terminal.

This comment records the relationship because the documented gitea_edit_issue tool is not implemented on the current server.

RELATED ISSUE Related: #513 — defines the issue-label taxonomy and generic workflow transitions. Issue #780 addresses enforcement of `status:pr-open` cleanup when a PR becomes terminal. This comment records the relationship because the documented gitea_edit_issue tool is not implemented on the current server.
jcwalker3 added status:in-progress and removed status:ready labels 2026-07-21 14:21:53 -05:00
Author
Owner

Issue claim heartbeat

<!-- gitea-issue-claim-heartbeat:v1 --> **Issue claim heartbeat** - kind: claim - issue: #780 - branch: fix/issue-780-terminal-pr-open-label-cleanup - phase: claimed - profile: prgs-author - pr: none - blocker: none - next_action: create worktree and begin implementation
jcwalker3 added status:pr-open and removed status:in-progress labels 2026-07-21 14:43:00 -05:00
Owner

[THREAD STATE LEDGER]

what is true now

  • Server-side decision state: PR #782 reached its terminal transition at head ed0e8c82de. Merge result: merge commit 8e149e6cfa landed on master.
  • Local verdict/state: Issue #780 is in closed state and still carries status:pr-open. Its live label set is status:pr-open, type:bug, workflow-hardening.

what changed

  • Merge performed by sysadmin / prgs-merger under merger lease session 48296-08f4a3cd6b63 (lease marker comment 13658), with review 492 recorded as an APPROVE verdict and approval_at_current_head true at the exact pinned head.
  • The prgs-reviewer review decision lock was cleared after the merge; audit comment 13662.

what is blocked

  • Blocker classification: environment/tooling blocker
  • The merge result carried no pr_open_label_cleanup field and the terminal label cleanup did not execute. The MCP process that performed this merge was loaded from master df3167488c, which predates this change. pr_open_label_cleanup and gitea_assess_terminal_label_hygiene exist only in the code this merge has just landed, so the merge path emitted the legacy cleanup_status field instead. That legacy field tracks status:in-progress, not status:pr-open, and its "not present" value for #780 says nothing about the label under audit here.
  • Terminal-label hygiene cannot be assessed from the running process: gitea_assess_terminal_label_hygiene is not registered in it.

who/what acts next

  • Next actor: user (operator) for the restart, then reconciler (prgs-reconciler) for the cleanup
  • Required action:
    1. Operator advances the canonical checkout to 8e149e6cfa and restarts every gitea MCP namespace so the landed code is the code in memory.
    2. Reconciler retires status:pr-open from issue #780 through gitea_cleanup_terminal_pr_labels (reason retry_recovery), preserving type:bug and workflow-hardening verbatim.
    3. Reconciler runs gitea_assess_terminal_label_hygiene and confirms zero residual violation for #780.
    4. Reconciler runs gitea_cleanup_post_merge_moot_lease for PR #782 with apply true. Dry-run evidence was recorded this session: session 48296-08f4a3cd6b63, candidate head ed0e8c82de, lease marker 13658, lease_moot true, cleanup_allowed true.
  • Do not do: do not hand-edit the label set outside terminal_pr_label_cleanup.py; do not reopen PR #782; do not touch issue #781.

Canonical Issue State

STATE: PR #782 landed on master at the pinned head; terminal status:pr-open cleanup outstanding
WHO_IS_NEXT: user
NEXT_ACTION: Advance the canonical checkout to 8e149e6cfa, restart the gitea MCP namespaces, then hand off to prgs-reconciler to retire status:pr-open from issue #780 via gitea_cleanup_terminal_pr_labels and confirm with gitea_assess_terminal_label_hygiene.
NEXT_PROMPT:

Task: complete terminal label cleanup for issue #780 in Scaled-Tech-Consulting/Gitea-Tools.
Precondition: canonical checkout advanced to 8e149e6cfa3557e4642a3ac72c971460adbc3037 and all gitea MCP namespaces restarted.
Required profile: prgs-reconciler. Native MCP tools only.
1. Verify master parity reports the running process at 8e149e6cfa3557e4642a3ac72c971460adbc3037.
2. Run gitea_cleanup_terminal_pr_labels for issue #780 with reason retry_recovery.
3. Confirm issue #780 retains exactly type:bug and workflow-hardening and no longer carries status:pr-open.
4. Run gitea_assess_terminal_label_hygiene and confirm zero residual violation.
5. Run gitea_cleanup_post_merge_moot_lease for PR #782 with apply true, expected_session_id 48296-08f4a3cd6b63, expected_candidate_head ed0e8c82deafa44079a23b5ddd73092b4d554ddf, expected_lease_comment_id 13658.
Do not modify issue #781. Do not hand-edit labels outside the sanctioned cleanup rule.

WHAT_HAPPENED: The merger role verified OS identity, repository binding, namespace health, runtime/master parity, and mutation eligibility, acquired a native merger lease after finding no active reviewer lease to adopt, rechecked the live head and review state immediately before mutation, and merged PR #782 at exactly ed0e8c82de. Read-after-write confirms PR #782 in closed state with merge commit 8e149e6cfa. Read-after-write on issue #780 shows status:pr-open still attached, because the self-applying cleanup this PR introduces was not present in the process that ran the merge.
WHY: An MCP process loads its code at startup. This change landed remotely during this session, so the running process continues to execute the pre-change merge path until the canonical checkout advances and the namespaces restart. The residual label is a deployment-ordering artifact, not a defect in the landed rule.
RELATED_PRS: #782
BLOCKERS: environment/tooling blocker — the process that performed the merge predates the cleanup code this merge landed; a namespace restart is required before the cleanup and its hygiene assessor can run.
VALIDATION: merge gates all passed (identity sysadmin/prgs-merger, author jcwalker3, no self-merge, PR mergeable, review 492 undismissed and not stale with approval_at_current_head true, namespace health client-namespace proven, master parity in parity at df3167488c, lease provenance sanctioned_acquire_merger comment 13658); read-after-write on PR #782 and issue #780 completed; source inspection confirms pr_open_label_cleanup occurs 11 times and assess_terminal_label_hygiene twice at ed0e8c8 and zero times at df31674.
LAST_UPDATED_BY: sysadmin / prgs-merger

[THREAD STATE LEDGER] **what is true now** - Server-side decision state: PR #782 reached its terminal transition at head ed0e8c82deafa44079a23b5ddd73092b4d554ddf. Merge result: merge commit 8e149e6cfa3557e4642a3ac72c971460adbc3037 landed on master. - Local verdict/state: Issue #780 is in closed state and still carries `status:pr-open`. Its live label set is `status:pr-open`, `type:bug`, `workflow-hardening`. **what changed** - Merge performed by sysadmin / prgs-merger under merger lease session 48296-08f4a3cd6b63 (lease marker comment 13658), with review 492 recorded as an APPROVE verdict and `approval_at_current_head` true at the exact pinned head. - The prgs-reviewer review decision lock was cleared after the merge; audit comment 13662. **what is blocked** - Blocker classification: environment/tooling blocker - The merge result carried no `pr_open_label_cleanup` field and the terminal label cleanup did not execute. The MCP process that performed this merge was loaded from master df3167488c5451f802549b40463ad59cbaad6109, which predates this change. `pr_open_label_cleanup` and `gitea_assess_terminal_label_hygiene` exist only in the code this merge has just landed, so the merge path emitted the legacy `cleanup_status` field instead. That legacy field tracks `status:in-progress`, not `status:pr-open`, and its "not present" value for #780 says nothing about the label under audit here. - Terminal-label hygiene cannot be assessed from the running process: `gitea_assess_terminal_label_hygiene` is not registered in it. **who/what acts next** - Next actor: user (operator) for the restart, then reconciler (prgs-reconciler) for the cleanup - Required action: 1. Operator advances the canonical checkout to 8e149e6cfa3557e4642a3ac72c971460adbc3037 and restarts every gitea MCP namespace so the landed code is the code in memory. 2. Reconciler retires `status:pr-open` from issue #780 through `gitea_cleanup_terminal_pr_labels` (reason `retry_recovery`), preserving `type:bug` and `workflow-hardening` verbatim. 3. Reconciler runs `gitea_assess_terminal_label_hygiene` and confirms zero residual violation for #780. 4. Reconciler runs `gitea_cleanup_post_merge_moot_lease` for PR #782 with `apply` true. Dry-run evidence was recorded this session: session 48296-08f4a3cd6b63, candidate head ed0e8c82deafa44079a23b5ddd73092b4d554ddf, lease marker 13658, `lease_moot` true, `cleanup_allowed` true. - Do not do: do not hand-edit the label set outside `terminal_pr_label_cleanup.py`; do not reopen PR #782; do not touch issue #781. ## Canonical Issue State STATE: PR #782 landed on master at the pinned head; terminal `status:pr-open` cleanup outstanding WHO_IS_NEXT: user NEXT_ACTION: Advance the canonical checkout to 8e149e6cfa3557e4642a3ac72c971460adbc3037, restart the gitea MCP namespaces, then hand off to prgs-reconciler to retire `status:pr-open` from issue #780 via `gitea_cleanup_terminal_pr_labels` and confirm with `gitea_assess_terminal_label_hygiene`. NEXT_PROMPT: ```text Task: complete terminal label cleanup for issue #780 in Scaled-Tech-Consulting/Gitea-Tools. Precondition: canonical checkout advanced to 8e149e6cfa3557e4642a3ac72c971460adbc3037 and all gitea MCP namespaces restarted. Required profile: prgs-reconciler. Native MCP tools only. 1. Verify master parity reports the running process at 8e149e6cfa3557e4642a3ac72c971460adbc3037. 2. Run gitea_cleanup_terminal_pr_labels for issue #780 with reason retry_recovery. 3. Confirm issue #780 retains exactly type:bug and workflow-hardening and no longer carries status:pr-open. 4. Run gitea_assess_terminal_label_hygiene and confirm zero residual violation. 5. Run gitea_cleanup_post_merge_moot_lease for PR #782 with apply true, expected_session_id 48296-08f4a3cd6b63, expected_candidate_head ed0e8c82deafa44079a23b5ddd73092b4d554ddf, expected_lease_comment_id 13658. Do not modify issue #781. Do not hand-edit labels outside the sanctioned cleanup rule. ``` WHAT_HAPPENED: The merger role verified OS identity, repository binding, namespace health, runtime/master parity, and mutation eligibility, acquired a native merger lease after finding no active reviewer lease to adopt, rechecked the live head and review state immediately before mutation, and merged PR #782 at exactly ed0e8c82deafa44079a23b5ddd73092b4d554ddf. Read-after-write confirms PR #782 in closed state with merge commit 8e149e6cfa3557e4642a3ac72c971460adbc3037. Read-after-write on issue #780 shows `status:pr-open` still attached, because the self-applying cleanup this PR introduces was not present in the process that ran the merge. WHY: An MCP process loads its code at startup. This change landed remotely during this session, so the running process continues to execute the pre-change merge path until the canonical checkout advances and the namespaces restart. The residual label is a deployment-ordering artifact, not a defect in the landed rule. RELATED_PRS: #782 BLOCKERS: environment/tooling blocker — the process that performed the merge predates the cleanup code this merge landed; a namespace restart is required before the cleanup and its hygiene assessor can run. VALIDATION: merge gates all passed (identity sysadmin/prgs-merger, author jcwalker3, no self-merge, PR mergeable, review 492 undismissed and not stale with approval_at_current_head true, namespace health client-namespace proven, master parity in parity at df3167488c54, lease provenance sanctioned_acquire_merger comment 13658); read-after-write on PR #782 and issue #780 completed; source inspection confirms `pr_open_label_cleanup` occurs 11 times and `assess_terminal_label_hygiene` twice at ed0e8c8 and zero times at df31674. LAST_UPDATED_BY: sysadmin / prgs-merger
sysadmin removed the status:pr-open label 2026-07-21 15:25:24 -05:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#780