Skip to content

fix(chain): name EXECUTE->PLAN re-entry on reshaping discovery + prd-add upsert#6

Merged
lanmower merged 1 commit into
mainfrom
fix/planning-event-reentry-and-prd-upsert
Jun 8, 2026
Merged

fix(chain): name EXECUTE->PLAN re-entry on reshaping discovery + prd-add upsert#6
lanmower merged 1 commit into
mainfrom
fix/planning-event-reentry-and-prd-upsert

Conversation

@lanmower

@lanmower lanmower commented Jun 5, 2026

Copy link
Copy Markdown
Member

@

Problem

A mid-EXECUTE planning event -- a decision/directive that reshapes an existing PRD row (e.g. "this CPU mirror should be a real-GL renderer") -- had no clean routed move back to PLAN, so the agent narrated "I need to re-scope" and stranded in EXECUTE pointed at a plan that no longer matched the work.

Two coupled gaps:

  1. Prose, not legality. transitions.rs::handle() already permits transition to=PLAN from any phase (only to=COMPLETE is gated by the four-observation check). But EXECUTE instruction prose only named the back-edge for a "new unknown" as a terse trailing clause, while the Re-expand on discovery section pushed every discovery toward prd-add-and-stay. When a discovery reshaped a row rather than adding a sibling, the two conflicted and the agent had no named move -- the strand-in-prose failure.

  2. No re-scope path. prd::handle_add always seq.pushed, so re-adding an existing id produced a duplicate row (two pending rows sharing one id, one unresolvable by intent). Reshaping a row was impossible without orphaning its handle.

Fix

  • execute.rs: new "Planning-event re-entry" section distinguishing additive discovery (prd-add, stay in EXECUTE) from reshaping discovery (transition to=PLAN, re-cut the cover). Names the "I need to re-scope" narration urge as the tell that you are mid-reshape and must dispatch the transition instead. Updates the Dispatch trailing clause to match.
  • prd.rs: handle_add now upserts by id -- an existing id rewrites that row in place ({"rescoped": id}) preserving position and dependents; a fresh id appends ({"added": id}). This is the re-scope mechanism the prose points at, and it also fixes the pre-existing duplicate-row defect.
  • plan.rs: documents the upsert/re-scope contract and that PLAN re-entry is first-class, not a failure.

Transition-matrix validation

Audited transitions.rs against the paper model. All forward edges (PLAN->EXECUTE->EMIT->VERIFY->COMPLETE) and all back-edges (any->PLAN) are legal; to=COMPLETE is the only gated edge (worktree-clean AND remote-pushed AND prd-empty AND mutables-witnessed, each refusal naming the unmet condition). The defect was never legality -- it was that the legal back-edge was unnamed in prose and re-scope duplicated rows. Both now resolved.
@

@
fix(chain): name EXECUTE->PLAN re-entry on reshaping discovery + prd-add upsert

Two coupled gaps let a mid-EXECUTE planning event strand the chain:

1. transitions.rs already allows transition to=PLAN from any phase (only
   to=COMPLETE is gated), but EXECUTE instruction prose only named the back-edge
   for a "new unknown" as a terse trailing clause, while the Re-expand-on-discovery
   section pushed every discovery toward prd-add-and-stay. So when a decision
   *reshaped* an existing row (not added a sibling), the prose conflicted and the
   agent narrated "I need to re-scope" without a routed move -- stranding in EXECUTE
   pointed at a plan that no longer matched the work. Add an explicit
   Planning-event re-entry section distinguishing additive discovery (prd-add, stay)
   from reshaping discovery (transition to=PLAN, re-cut the cover), and name the
   narration urge as the tell.

2. prd::handle_add always pushed, so re-adding an existing id created a duplicate
   row (two pending rows, one unresolvable by intent) -- there was no re-scope path.
   Make handle_add upsert by id: an existing id rewrites that row in place
   (response {"rescoped": id}), preserving position and the dependents that name it.
   This is the re-scope mechanism the re-entry prose now points at.

plan.rs documents the upsert/re-scope contract and that PLAN re-entry is first-class.
@
@lanmower lanmower merged commit 121a976 into main Jun 8, 2026
1 of 2 checks passed
@lanmower lanmower deleted the fix/planning-event-reentry-and-prd-upsert branch June 8, 2026 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant