---
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

## 18A. Reconciler close proof is enforced (#306)

When a reconciler run closes a PR, the final-report validator
(`final_report_validator` rule `reconcile.close_proof_fields`) **blocks** the
handoff unless it carries all four close proofs. The prompt is guidance; the
MCP validator is the authority.

A close is detected from `PRs closed: #<n>` (or a session close lock). Once a
close is reported, the handoff must include:

* `Capabilities proven:` naming `gitea.pr.close` — the exact close capability
* `Ancestor proof:` — the landed/ancestor proof for the closed PR
* `PRs closed:` — the PR close result (the closed PR number)
* `Linked issue live status:` (or `Issues closed:`) — the linked-issue result

Comment-only and blocked reconciliations (no PR close) are unaffected: the rule
returns no finding when nothing was closed.

## 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.