Skip to content

porch: plan_phases:[] populated empty on plan→implement transition (causes implement→implement loop) #697

@waleedkadous

Description

@waleedkadous

Problem

For ASPIR projects, status.yaml shows plan_phases: [] even when the plan file's machine-readable JSON block is well-formed, with multiple phases defined. This breaks the phase state machine: porch never transitions implement → review on completion because the "all phases complete" predicate cannot fire when the list is empty, and the default on_complete: "implement" action sends it back to itself. The builder observes an endless stream of alternating phase-transition and build-complete porch commits with no advancement.

Observed behavior

Seen on at least two ASPIR projects:

  • 694 (team-page-surface-review-block): plan's JSON block had 4 phases. After each porch done, porch re-entered implement phase, iteration 1, and returned the same initial implement tasks. Workaround: bypass porch and create the PR directly after the 3-way implementation consultation approved unanimously.
  • 494 (new-air-protocol-autonomous-im): stuck in specify with empty plan_phases.

Here's the relevant excerpt from 694's status.yaml after the plan phase supposedly completed:

id: '694'
title: team-page-surface-review-block
protocol: aspir
phase: implement
plan_phases: []             # <-- never populated
current_plan_phase: null

And the plan's JSON block (well-formed):

{
  \"phases\": [
    {\"id\": \"phase_1_wire_type\", \"title\": \"Extend wire type with reviewBlocking array\"},
    {\"id\": \"phase_2_query_and_parser\", \"title\": \"Extend GraphQL query and add two-pass relationship derivation\"},
    {\"id\": \"phase_3_dashboard_ui\", \"title\": \"Render review-blocking section in MemberCard\"},
    {\"id\": \"phase_4_e2e_and_docs\", \"title\": \"Add E2E coverage and update docs\"}
  ]
}

Expected behavior

After the plan phase completes (plan file written and committed), porch should parse the JSON block from the plan file and populate status.yaml.plan_phases with the list so that:

  • current_plan_phase can advance through each phase in order during implement
  • The on_all_phases_complete predicate fires and transitions to review

Reproduction steps

  1. afx spawn <id> --protocol aspir on a project with a multi-phase plan
  2. Let porch run through specify → plan
  3. After plan is approved, observe status.yaml shows plan_phases: []
  4. porch done <id> during implement never advances to review — loops back to implement iteration 1

Suspected root cause

The plan→implement transition handler is not extracting/populating plan_phases from the plan file. The JSON block parses cleanly with python3 -c \"import json; json.load(open(...))\", so the extractor either:

  • Is not being called at the expected time, OR
  • Is being called but its results are not being written to status.yaml, OR
  • Is looking at the wrong file path (ASPIR vs SPIR path resolution)

Impact

  • Breaks autonomous ASPIR workflow — builders must manually work around by creating PRs without porch's state machine
  • Creates noisy commit history with 15+ porch state commits that never advance state
  • Blocks the optional verify phase from being reached through porch

Follow-up

Identified during work on project 694 (review). See that file's Follow-up Items section for additional context.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions