Skip to content

porch declares PROTOCOL COMPLETE while the builder branch is still ahead of main #57

Description

@pseudoseed

What happens

porch done emits its own state commits after the PR it was tracking has already merged, so those commits can never be in that PR. The builder branch is then ahead of origin/main at the exact moment porch prints:

🎉 PROTOCOL COMPLETE

  Project <id> has completed the <protocol> protocol.

Observed on a BUGFIX run (dvarr issue cluesmith#109, PR cluesmith#116). After the PR merged:

$ git log --oneline origin/main..HEAD
68e9e2d [Issue 109] docs: landing record for the seam fix
9bef385 chore(porch): bugfix-109 protocol complete
d93585d chore(porch): bugfix-109 PR #116 merged

Two of those three are porch's own, from packages/codev/src/commands/porch/index.ts:

  • L487 — chore(porch): ${state.id} PR #${options.merged} merged, written by done --merged N, which by definition runs after the merge.
  • L656 — chore(porch): ${state.id} protocol complete, written by advanceProtocolPhase on the terminal transition, immediately before the completion banner.

Why it matters

The completion banner is the builder's done signal, and it is wrong at the moment it prints. A builder that trusts it stops. A builder that doesn't trust it improvises a second, unmodelled "docs" PR to land the leftovers — which is what happened here (PR cluesmith#118).

That improvised PR is the real damage, because it exists outside the protocol:

  • No phase owns it, so porch status shows verified with nothing outstanding.
  • No gate covers it.
  • No notification step is attached to it, so the architect is never told the builder is waiting on a decision. The builder sits idle and the worktree is never cleaned up, with nothing anywhere reporting a problem.

The last point is the one that cost real time. Every other hand-off in the protocol has an afx send architect attached; this one has none, because the protocol does not know the PR exists.

Related

approve() already carries a note acknowledging half of this (L897-L900):

// NOTE: The 'verified' state is committed to the builder branch, which may not
// be merged back to main. The closed GitHub Issue serves as the canonical "done"
// signal on main. State alignment (making status.yaml on main authoritative) is
// tracked as future work per spec 653.

Spec 653 covers making status.yaml on main authoritative. This issue is the adjacent problem: not where state lives, but that porch reports success while work is still unlanded, and provides no path or notification for landing it. Fixing 653 might dissolve it; fixing it alone would not fix 653.

Suggested fixes

Roughly in order of cost.

1. Don't lie in the banner. Before printing PROTOCOL COMPLETE, check whether the branch is ahead of its base:

git rev-list --count origin/<base>..HEAD

If non-zero, print what is unlanded and the next action instead of a clean completion. Cheap, and it converts a silent wrong signal into an explicit one.

2. Model the landing step. Give protocols that produce post-merge state commits a terminal land step with its own phase prompt and its own afx send architect notification, so the follow-up PR is a first-class thing rather than something each builder improvises differently.

3. Remove the orphan commits. Have done --merged N and the terminal transition write state without committing to the builder branch — amend into the PR before it merges, or write where main already owns it. Nothing is left behind and neither of the above is needed. Largest change, and probably wants to be designed together with spec 653.

Reproduction

Any protocol run to completion. BUGFIX is the shortest:

  1. Run a BUGFIX project through to porch done <id> --pr N --branch <branch>.
  2. Merge the PR.
  3. porch done <id> --merged N
  4. porch done <id> → prints PROTOCOL COMPLETE.
  5. git log --oneline origin/main..HEAD → two commits, unlanded.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/porchProtocol orchestratorbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions