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> reports status: complete | phase: verified — substantive approval recorded.
- Builder-side: the builder's separate worktree (
.builders/<protocol>-<id>/) polls its own status.yaml and 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 local gate_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
pr gate (gate_pending: pr).
- Human merges the PR via GitHub UI /
gh pr merge — GitHub's "auto-delete branch on merge" setting removes builder/pir-<id> from the remote.
- Architect runs
porch approve <id> pr --a-human-explicitly-approved-this.
- Porch updates
status.yaml locally, commits, attempts to push to builder/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-approval gate_pending: pr state. It cannot make the porch 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 push hint at the tail of the porch approve output, 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
Problem
When the architect runs
porch approve <id> <gate> --a-human-explicitly-approved-thisafter 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:porch next <id>reportsstatus: complete | phase: verified— substantive approval recorded..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
prgate (gate_pending: pr).gh pr merge— GitHub's "auto-delete branch on merge" setting removesbuilder/pir-<id>from the remote.porch approve <id> pr --a-human-explicitly-approved-this.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.status: complete | phase: verified— substantive approval landed locally.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
afx send architect "Project N complete. PR merged. Ready for cleanup.") never fires.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.Related
porch doneself-completion — same lifecycle / state-sync family).