Repository navigation
porch approve state-push silently fails when project tracking branch was auto-deleted on PR merge; breaks state-sync to builder worktree #801
Description
Problem
When the architect runs porch approve <id> <gate> --a-human-explicitly-approved-this after the PR for that project has been merged on GitHub, porch's state-update commit attempts to push to the project's tracking branch (e.g. builder/pir-<id>). If GitHub's "auto-delete branch on merge" repo setting is on, that branch was already deleted at merge time. The push fails with a non-fast-forward / remote-rejected error (visible only as a tail-of-output hint), but porch's local state update succeeds — leading to two desynced views:
- Architect-side:
porch next <id>reportsstatus: complete | phase: verified— substantive approval recorded. - Builder-side: the builder's separate worktree (
.builders/<protocol>-<id>/) polls its ownstatus.yamland never sees the approved-gate state, because the only sync channel (push/pull on the now-deleted tracking branch) is broken. The builder remains effectively stuck at its own localgate_pending: <gate>view forever.
Observed sequence
- Architect spawns a PIR builder; builder works through plan / implement / review phases.
- Builder writes review + opens PR; reaches the
prgate (gate_pending: pr). - Human merges the PR via GitHub UI /
gh pr merge— GitHub's "auto-delete branch on merge" setting removesbuilder/pir-<id>from the remote. - Architect runs
porch approve <id> pr --a-human-explicitly-approved-this. - Porch updates
status.yamllocally, commits, attempts to push tobuilder/pir-<id>→ push fails (the branch no longer exists on the remote). The push hint surfaces only at the tail of the command output, not as a distinct porch-side error or warning. - Architect-side state shows
status: complete | phase: verified— substantive approval landed locally. - Builder-side: never woken. The builder, if it polls
porch next <id>from its worktree, sees its own pre-approvalgate_pending: prstate. It cannot make theporch done --merged <PR>call its protocol's review prompt instructs it to, because its view of state is stale and there is no remote to pull the new state from.
The PR is merged, the work is genuinely done, but the builder is silently stranded — its only "wakeup" path (porch detecting the gate-approved state change via git pull on the tracking branch) is broken because there is no branch to pull from.
Impact
- Every PIR / SPIR builder whose project branch is auto-deleted on merge produces a silent state-sync failure between architect-side and builder-side porch views.
- The builder is stuck pending its own gate forever, until the architect/user manually cleans up the builder (worktree + Tower terminal). The builder's intended cleanup-notification (
afx send architect "Project N complete. PR merged. Ready for cleanup.") never fires. - The push-failure surfaces only as a
git pushhint at the tail of theporch approveoutput, not as a distinct error or warning from porch itself. Easy to miss — the substantive "Gate X approved" message comes first, and the hint blends into normal git noise. - Cleanup still works (cleanup is a separate code path that does not depend on builder-side porch state), so the user-visible outcome is a "silent dead pane" until cleanup runs.
Related
- Sibling: porch: verify-wedge — a reworked artifact can't re-enter verify after its approval gate has fired (rollback can't target current phase) #776 (porch verify-wedge — porch state-machine recovery gap).
- Sibling: afx cleanup can't reach orphaned Tower terminals after porch done self-completion (registry-keyed cleanup, no fallback) #783 (orphaned Tower terminals after
porch doneself-completion — same lifecycle / state-sync family). - All three are afx / porch-lifecycle gaps where a state transition leaves an unreachable artifact or an unsynced view.
Activity
amrmelsayed commentedon May 21, 2026
Siblings already filed in this defect family:\n- #776 — porch verify-wedge (cannot re-enter verify after gate fires on rework)\n- #783 — orphaned Tower terminals after
porch doneself-completion (cleanup can't reap registry-independent terminal)\n\nAll three are afx/porch-lifecycle gaps where a state transition leaves an unreachable artifact or unsynced view.amrmelsayed commentedon May 21, 2026
Flip-side sibling: #802 (state-bookkeeping commits accumulate as orphan artifacts when the branch is NOT auto-deleted). Both #801 and #802 are the same root design choice — porch using ephemeral PR source-branches as durable state storage — manifesting in opposite outcomes depending on whether the auto-delete-on-merge setting fires. Fixing one without the other leaves the other failure mode active.