Files
Gitea-Tools/skills/llm-project-workflow/workflows/reconcile-landed-pr.md
T
sysadmin ddaf380db2 feat: gate reconciliation audit mode from unauthorized cleanup (Closes #419)
Add audit vs cleanup phase tracking so reconciliation audits stay read-only
unless cleanup is explicitly authorized with delete capability proof, safety
proof, and before/after snapshots. Block gitea_delete_branch and merged-cleanup
execution during audit phase, validate final reports for false no-mutations
claims, and document the boundary in the reconcile-landed-pr workflow.
2026-07-07 17:20:36 -04:00

443 lines
14 KiB
Markdown

---
task_mode: reconcile-landed-pr
canonical: true
final_report_schema: ../schemas/reconcile-landed-final-report.md
---
# Reconcile already-landed open PR workflow (canonical)
**Task mode:** `reconcile-landed-pr`
This file is the canonical reconciliation workflow for open PRs whose head SHA
is already an ancestor of the target branch. Load it before any reconciliation
mutation. Final report schema:
[`schemas/reconcile-landed-final-report.md`](../schemas/reconcile-landed-final-report.md).
**Default task prompt:**
> Reconcile already-landed open PRs in this project. Do not review or merge
> normal PRs. Close or comment only when exact capability is proven.
Do not improvise around the gates. Follow project skills, MCP gates, and
workflow rules exactly.
This is a reconciliation workflow. It is not a normal PR review/merge workflow.
---
## 0. Load the canonical workflow first
Before starting reconciliation work, check whether the project provides a
canonical reconcile-landed-PR workflow through a project skill, runbook, or MCP
helper.
If available, load it first and report:
* workflow source
* workflow version, commit, or hash
* whether this prompt conflicts with the loaded workflow
If the canonical workflow cannot be loaded and the project requires it, stop and
produce a recovery handoff only.
## 1. Mode isolation
This run is `reconcile-landed-pr` mode only.
**Do not review or merge normal PRs.**
Do not:
* approve PRs
* request changes on PRs
* merge PRs
* implement code
* edit repo files
* create branches
* create commits
* push branches
* create PRs
* run normal PR validation as review approval input
* perform author/coder implementation work
* perform raw MCP repair
If the task requires review, merge, issue implementation, or MCP repair mode,
stop and produce a handoff for the correct workflow.
Do not mix modes in one run.
## 2. Start with live identity, profile, runtime, and capability checks
Prove:
* authenticated identity
* active profile (reconciler or author with close capabilities, as required)
* repo/project
* runtime context
* exact capability for reading/listing PRs and issues
* exact capability for PR inspect (`gitea.read` / view PR)
* exact capability for issue inspect
* exact capability for PR comment, if commenting
* exact capability for issue comment, if commenting
* exact capability for PR close, if closing PRs
* exact capability for issue close, if closing issues
A nearby capability does not count.
Examples:
* `review_pr` does not authorize PR close
* `merge_pr` does not authorize PR close or issue close
* `create_issue` does not authorize `issue_comment`
* `issue_comment` does not authorize PR close
* `gitea.read` does not authorize close or comment mutations
If exact capability cannot be proven, stop and produce a recovery handoff only.
## 3. Stop immediately on blocked infrastructure
If any of the following appears, stop immediately:
* `infra_stop`
* MCP reconnect failure
* stale capability state
* missing capability
* workspace mismatch
* broken canonical workflow loading
* failed required preflight
* capability resolver warning that says the current state may be unsafe
* stale or inconsistent runtime context
Do not continue inventory, ancestry proof, commenting, closing, or cleanup.
Produce an executable recovery handoff only.
Blocked recovery handoffs must not include direct close or comment replay
commands.
Blocked handoffs must say to rerun the full workflow after the blocker clears.
## 4. Main checkout rule
This workflow should not mutate repo files.
Do not edit files in the main checkout.
Do not create branches, commits, or pushes.
Do not run implementation or reviewer validation worktrees for code edits.
Reading repository files is allowed only when needed to understand
reconciliation scope and only if this workflow permits it.
## 5. No raw MCP repair during reconciliation
Do not run `pkill`, kill MCP processes, edit MCP config, restart servers, or
perform control-checkout repair during reconciliation.
If MCP repair is required, stop and produce a separate `CONTROL-CHECKOUT REPAIR
MODE` handoff.
After repair, rerun the full workflow from the beginning.
## 6. No background task tools
Do not use `schedule`, `manage_task`, background jobs, async waits, delayed task
tools, or monitoring tasks during reconciliation.
Use direct commands and MCP tools only.
If a required action cannot complete synchronously, stop and produce a recovery
handoff.
## 7. No local Gitea fallback during normal reconciliation
During normal reconciliation workflows, do not read Gitea profile secret files.
Do not inspect `profiles.json`, local token stores, credential files, `.env`
Gitea credentials, keychain dumps, or token helper outputs.
Do not run local Gitea helper scripts when MCP tools are available.
Use MCP tools for Gitea operations.
Local fallback is allowed only in explicit recovery mode when MCP is unavailable
and identity/profile/capability can be independently proven.
## 8. Build a complete live open PR inventory
List open PRs for the target repo according to project policy.
Follow pagination until the tool proves there are no more pages.
Do not assume inventory is complete.
Pagination proof must not rely on assumed default API page size.
Inventory is complete only if one of the following is proven:
* the MCP response explicitly says there is no next page / `has_more=false` /
final page
* the workflow traversed pages until an empty page or explicit final page was
returned
* the tool response includes total-count or pagination metadata proving all
relevant PRs were returned
* the request explicitly set `page` / `limit` / `per_page`, and the response
explicitly proves the server honored that page size and did not truncate results
If pagination cannot be proven, report `INVENTORY_PAGINATION_UNPROVEN` and stop
unless project policy allows best-effort reconciliation with that limitation
disclosed.
## 9. Already-landed proof
For each candidate PR, prove whether the PR head SHA is already landed on the
target branch.
**Already-landed proof** must include:
* PR number and title
* candidate head SHA (full 40-hex)
* target branch name
* target branch SHA (full 40-hex) after fetch
* ancestor proof method (`git merge-base --is-ancestor`, equivalent forge API, or
documented project helper)
* ancestor proof result (true/false)
* live PR state (open/closed, merged flag)
Do not classify a PR as already-landed without live ancestor proof.
If ancestry cannot be proven, classify as `ANCESTRY_UNPROVEN` and skip close
mutations.
## 10. Linked issue live verification
If the PR claims to close or link an issue, fetch the linked issue live before
reporting its status.
If the linked issue was not fetched live in the current session, report:
`Linked issue status: not verified in this session`
Do not claim `issue open`, `issue closed`, or `issue resolved` without live
proof.
## 11. Reconciliation selection rules
Select PRs eligible for reconciliation:
* open PR state
* `merged=false` unless project policy says otherwise
* head SHA is ancestor of target branch (already-landed proof passed)
* not selected for normal review/merge in this run
Eligibility class for selected PRs: `ALREADY_LANDED_RECONCILE_REQUIRED`
Do not select PRs that fail already-landed proof for normal review/merge
treatment in this mode.
## 12. Reconciliation comment policy
Post a reconciliation comment only if:
* exact PR-comment or issue-comment capability is proven
* the comment adds durable evidence (ancestor proof summary, recommended close
action, linked issue status)
* the comment will not duplicate an equivalent recent reconciliation comment
If comment capability is missing, record the intended comment in the final
handoff only.
## 12A. Partial reconciliation policy (#302)
The durable policy when `close_pr` capability is missing is
**comment-then-stop** (`resolve_partial_reconciliation_plan` in
`review_proofs.py` enforces it):
* `close_pr` proven → full reconciliation: close the PR and report the
close result (`FULL_RECONCILE_CLOSE_ALLOWED`).
* `close_pr` missing, `comment_pr` proven → post exactly one
reconciliation comment carrying PR head SHA, target branch SHA,
ancestor proof, linked issue status, and the required missing
capability, then stop for a human or authorized close
(`PARTIAL_RECONCILE_COMMENT_THEN_STOP`).
* `comment_pr` also missing → no Gitea mutation; produce a recovery
handoff recording the intended comment and required capabilities
(`RECOVERY_HANDOFF_ONLY`).
* Ancestry not proven → no mutation regardless of capability
(`GATE_NOT_PROVEN`).
Final reports must explain why the comment was or was not posted and
name the missing capability (`assess_partial_reconciliation_report`).
## 13. PR close rules
Close a PR only if:
* already-landed proof passed in this session
* exact PR-close capability is proven
* PR is still open at mutation time (live re-fetch)
* head SHA still matches the proved candidate head SHA
If PR-close capability is missing, produce a recovery handoff with exact PR,
proof, and required capability. Do not loop forever re-blocking the reviewer
queue.
## 14. Issue close rules
Close a linked issue only if:
* exact issue-close capability is proven
* linked issue was fetched live
* issue resolution is justified by landed content and project policy
* issue is still open at mutation time
If issue-close capability is missing, report the gap in the handoff.
## 15. Missing capability behavior
If any required mutation capability is missing:
* do not improvise with review/merge tools
* do not ask the operator to bypass capability gates
* produce a recovery handoff listing exact missing capabilities
* include safe next action (profile switch, human close, or dedicated reconciler
profile)
## 15A. Audit vs cleanup phase (#419)
Reconciliation audits are **read-only** unless a separate cleanup phase is
explicitly authorized.
**Audit phase forbids** (``audit_reconciliation_mode.check_audit_mutation_allowed``
fails closed):
* ``gitea_delete_branch``
* ``git branch -D``
* ``git worktree remove``
* pushes
* issue/PR mutations
* file edits
Dry-run merged-cleanup reconciliation (``gitea_reconcile_merged_cleanups`` with
``dry_run=True``) stays in audit phase. Execution requires:
1. Operator approval or workflow authorization
2. Exact ``delete_branch`` capability proof (``gitea.branch.delete``)
3. Proof branch/worktree is safe to remove
4. Before/after state snapshot
Call ``gitea_authorize_reconciliation_cleanup_phase`` before any cleanup
mutation. Final reports must not claim ``no mutations`` if cleanup occurred.
Classify cleanup mutations as:
* remote branch deletion → **External-state mutations**
* local branch deletion → **Git ref mutations**
* worktree removal → **Cleanup mutations**
``audit_reconciliation_mode.assess_audit_reconciliation_report`` validates
these boundaries in final reports.
## 16. Mutation classification
Use precise mutation categories in the final report:
* File edits by reconciler: (expect `none`)
* Worktree/index mutations:
* Git ref mutations: (`git fetch` belongs here, not read-only diagnostics)
* MCP/Gitea mutations:
* Reconciliation mutations: (PR comment, issue comment, PR close, issue close)
* External-state mutations:
* Read-only diagnostics:
Do not use legacy `Workspace mutations`.
## 17. Identity privacy rule
Report identity as `username / profile` (#305).
Do not disclose personal email in final reports unless explicitly required.
## 18. Precise final report
Include:
* canonical workflow source/version/hash
* authenticated identity/profile
* repo/project
* capability proof summary (separate lines for inspect, comment, PR close,
issue close)
* inventory pagination proof
* selected PR(s) with already-landed proof
* linked issue live status
* mutations performed or blocked
* missing capabilities
* confirmation that no normal review, approval, request-changes, or merge was
performed
## 19. Local artifact and report consistency rule
Do not create local walkthrough, notes, markdown, JSON, or report artifacts
during reconciliation unless explicitly required.
If any file is edited, report under `File edits by reconciler`.
Default: no repo file edits.
## 20. Forbidden unsupported claims unless proven
Do not claim:
* `already-landed`
* `PR closed`
* `issue closed`
* `pagination complete`
* `inventory complete`
* `all gates passed`
* `no unsafe mutation`
unless the corresponding proof is included.
## 21. Proof wording enforcement
Forbidden unless supported by current-session evidence:
* pagination complete
* final page
* no next page
* PR closed
* issue closed
* all gates passed
If proof comes from prior state, label as prior proof, not live proof.
## 22. Final self-check before output
Verify:
* no normal review/merge mutations occurred
* `git fetch` is under Git ref mutations if it occurred
* already-landed proof is present for each selected PR
* handoff uses reconciliation schema, not author/reviewer merge schema
* no contradiction between narrative report and controller handoff
## 23. Controller handoff schema
End every run with `Controller Handoff` per
[`schemas/reconcile-landed-final-report.md`](../schemas/reconcile-landed-final-report.md).
## 24. Stop conditions summary
Stop immediately and produce a recovery handoff if:
* canonical workflow cannot be loaded
* identity/profile/capability cannot be proven
* runtime context is blocked
* `infra_stop` appears
* inventory pagination cannot be proven and best-effort is not allowed
* already-landed proof cannot be completed
* required close capability is missing and mutation was attempted
* live PR/issue state contradicts proof
* any report contradiction cannot be resolved
Do not improvise around the gates.