status:pr-open was applied by gitea_create_pr and never removed again. Every
terminal path finished without touching it, so a repository audit found 40
closed issues still advertising an open PR.
Add terminal_pr_label_cleanup.py as the single authoritative rule and route
every sanctioned terminal path through it, so the paths cannot drift:
- merge (gitea_merge_pr)
- close without merge (gitea_edit_pr)
- supersession/abandonment (gitea_reconcile_superseded_by_merged_pr)
- already-landed reconciliation (gitea_reconcile_already_landed_pr)
- controller closure (gitea_close_issue)
- retry/recovery (new gitea_cleanup_terminal_pr_labels)
The rule removes only status:pr-open, preserves every other label, allows an
empty resulting set, is a no-op when the label is absent (so retries are
safe), and confirms the outcome by read-after-write rather than assumption.
Controller closure runs the cleanup before the state change and fails closed
if it cannot be completed and verified; closing first would bake in the stale
label with no later step to catch it. Post-merge cleanup never blocks the
merge, which already happened, and reports failures with a safe next action.
Also:
- gitea_assess_terminal_label_hygiene: read-only terminal validation that
reports residual status:pr-open, exempting issues with a genuinely open PR.
- _put_issue_label_names now accepts Gitea's empty response body when the
requested set is empty, so clearing the last label works.
- test_audit's close_issue fixture keys on the request instead of call order,
since closing now also reads labels for the cleanup and its read-back.
Docs: label-taxonomy terminal-transition section, runbook pointer, and the
review-merge / reconcile-landed final-report terminal-label requirements.
Suite: 4045 passed, 11 failed, 6 skipped. The same 11 failures reproduce on
clean master df31674 (4010 passed, 11 failed) and are pre-existing.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
65 lines
1.9 KiB
Markdown
65 lines
1.9 KiB
Markdown
# Reconcile-landed controller handoff schema
|
|
|
|
**Task mode:** `reconcile-landed-pr`
|
|
|
|
End every reconciliation run with a section titled exactly `Controller Handoff`.
|
|
Use this canonical field set. Do not omit fields — use `none` or
|
|
`not verified in this session` where appropriate.
|
|
|
|
Reject stale author/reviewer fields: `PR number opened`, `Pinned reviewed head`,
|
|
`Scratch worktree used`, `Workspace mutations`, `Mutations: None` (when mutations
|
|
occurred).
|
|
|
|
```md
|
|
## Controller Handoff
|
|
|
|
- Task:
|
|
- Repo:
|
|
- Role:
|
|
- Identity:
|
|
- Active profile:
|
|
- Runtime context:
|
|
- Selected PR:
|
|
- PR live state:
|
|
- Candidate head SHA:
|
|
- Target branch:
|
|
- Target branch SHA:
|
|
- Ancestor proof:
|
|
- Linked issue:
|
|
- Linked issue live status:
|
|
- Eligibility class:
|
|
- Capabilities proven:
|
|
- Missing capabilities:
|
|
- PR comments posted:
|
|
- Issue comments posted:
|
|
- PRs closed:
|
|
- Issues closed:
|
|
- File edits by reconciler:
|
|
- Worktree/index mutations:
|
|
- Git ref mutations:
|
|
- MCP/Gitea mutations:
|
|
- Reconciliation mutations:
|
|
- Terminal label cleanup:
|
|
- External-state mutations:
|
|
- Read-only diagnostics:
|
|
- Blockers:
|
|
- Current status:
|
|
- Safe next action:
|
|
- Safety statement:
|
|
- No review/merge confirmation:
|
|
```
|
|
|
|
Identity format: `username / profile` (not personal email unless required — #305).
|
|
|
|
`git fetch` belongs under `Git ref mutations`, not read-only diagnostics (#297).
|
|
|
|
`Terminal label cleanup` (#780) reports the `pr_open_label_cleanup` record the
|
|
reconciliation tool returned — `clean` / `failed` / `not applicable (no linked
|
|
issue)`, with the labels removed and preserved. Reconciliation is a terminal
|
|
transition, so a non-`clean` record blocks any "reconciled" claim; recover with
|
|
`gitea_cleanup_terminal_pr_labels` (`terminal_reason='retry_recovery'`) and
|
|
confirm with `gitea_assess_terminal_label_hygiene`.
|
|
|
|
The report must also carry the canonical self-propagating handoff block
|
|
(`schemas/self-propagating-handoff.md`, #626) and that block must be posted to
|
|
the Gitea issue or PR thread. |