feat(plan): add detect-state verb (P7b-i-c) - #88
Merged
Conversation
Adds polyphony plan detect-state --root-id N --item-id N — the routing
primitive plan-level.yaml will call at workflow entry to discover where
the plan workflow left off.
State machine (precedence order):
- error — arg validation or git remote unavailable
- not_started — no plan PR exists for this branch
- awaiting_review — open plan PR with current ancestor snapshot
- stale_generation — open plan PR whose ancestor_plan_generations
lags the manifest's plan_generations ledger
- closed_unmerged — PR was closed without merging
- merged_unseeded — PR merged, but parent lacks polyphony:planned tag
- complete — PR merged AND parent carries the planned tag
Composes existing primitives: BranchNameBuilder for branch naming,
git ls-remote for branch existence, gh pr list (highest-numbered wins
for "latest"), gh pr view for full state, RunManifestStore.Parse +
PlanPrFrontMatter.Parse for stale-generation detection (manifest read
from origin/feature/{root} via git show — same idiom OpenPlanPr will
use after #85 merges), twig show for the planned-tag check.
Always exits 0 (routing-style verb); workflow branches on result.state.
plannedTag default is polyphony:planned; overridable for non-default
namespaces.
Adds IGhClient to PlanCommands primary constructor; updates the five
existing PlanCommands test sites accordingly. Stacks on top of the
sdlc/plan-commit-and-push branch (PR #86) which added IGitClient.
16 tests cover the full state machine, both branch naming variants,
the stale-snapshot/current-snapshot/manifest-missing trio, and the
custom planned-tag override. 1798 total tests in the suite (3 pre-
existing ProcessRunner environment flakes, unrelated).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PolyphonyRequiem
added a commit
that referenced
this pull request
May 6, 2026
…b-i-d) (#89) Phase 3 P7b-i-d. Replaces v1.0.1's in-workflow LLM-verdict planning loop (technical_reviewer / readability_reviewer / review_router / plan_approval) with the platform-native PR-review flow built on the substrate verbs shipped in P7b-i-a / P7b-i-b / P7b-i-c (and the four prior plan/branch/pr verbs). Lifecycle per invocation: 1. depth_guard -> guidance_loader -> root_resolver -> type_loader 2. ancestor_chain -> state_detector 3. State-driven routes: not_started -> architect -> write_plan -> ensure_plan_branch -> commit_and_push -> open_plan_pr -> plan_reviewer (advisory comment) -> poll_status (single-shot) awaiting_review -> poll_status stale_generation -> architect (re-author) merged_unseeded -> seeder -> child_router (recurse) complete -> child_router (recurse only) closed_unmerged -> blocked exit 4. poll_status routes by review state: approved (no parent change) -> merge_plan_pr -> seeder approved + parent change -> parent_change_blocked_exit (P8 stub) changes_requested -> revise_counter -> architect (cap 5) pending -> pending_review_gate merged -> seeder closed -> closed_unmerged_gate Key design decisions (per files/p7-design-doc.md): - Q1 plan path: plans/plan-{item_id}.md (handled by write-plan verb) - Q2 reviewer: single advisory plan_reviewer + human approval (option 2) - Q3 pending review: in-workflow human_gate (option a) -- DEVIATES from design default (option b exit-with-pending) because polyphony-full's state_detector still uses the OLD single-string phase model and would infinite-loop on awaiting_review. Switch to (b) lands with Phase 2c. - Q4 root_id thread: root_resolver derives once via 'root resolve'; all downstream verbs read root_resolver.output.resolved_root_id - Q5 review posting: plan_reviewer is a script agent calling 'gh pr review --comment' once and returning - Q6 revise loop: capped at 5 iterations with revise_cap_gate - Q7 output shape: blocked exits use human_gate; reviewer-driven outputs surface via gate Markdown - Q8 parent change: refused at this PR; honest 'P8 not implemented' gate Architect output schema unchanged ({plan, children, open_questions, summary}) so the existing architect-plan-level.md prompt continues to work. Open-questions policy (open_questions_policy / open_questions_counter / open_questions_answer_counter / open_questions_gate) preserved verbatim from v1. Recursion preserved: plan_children_group for_each invokes ./plan-level.yaml per plannable child with depth+1. All error sites have explicit human_gate fallbacks (root_resolver_error_gate, type_loader_error_gate, state_detector_error_gate, write_plan_error_gate, ensure_branch_error_gate, commit_error_gate, open_pr_error_gate, poll_error_gate, merge_error_gate, stale_generation_gate, parent_change_blocked_exit, closed_unmerged_gate). Drive-by: fix pre-existing build break in PlanCommandsWritePlanTests.CreateCommand() -- it was missing IGitClient and IGhClient args added to PlanCommands ctor in P7b-i-c (#88). Main has been red since that merge; this PR brings the C# suite back to 1809/1809 green. Validation: - dotnet test: 1809/1809 pass (was: build break on main) - lint-plan-level.ps1: 10/10 checks pass - lint-plan-level.Tests.ps1: 5/5 Pester tests pass - lint-strict-undefined.ps1: 10 workflows scanned clean - lint-type-agnostic.ps1 -Surface all: 42 files scanned clean - lint-root-routing.ps1: 7 phases / 3 sub-workflows validated Pre-existing failure NOT addressed by this PR: - lint-implement-pg.ps1 expects claude-opus-4.7-1m-internal but YAML has claude-opus-4.6 / claude-opus-4.7. Same failure on main. Tracked separately. Co-authored-by: Daniel Green <dangreen@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
P7b-i-c —
polyphony plan detect-stateverbRe-opened against
mainafter #85/#86 merged. Original PR #87 was auto-closed by GitHub when its base branch was deleted.What this adds
polyphony plan detect-state --root-id N --item-id N— the routing primitiveplan-level.yamlcalls at workflow entry to discover where the plan workflow left off.State machine
not_startedawaiting_reviewstale_generationclosed_unmergedmerged_unseededplan seed-childrencompleteerrorComposition
Pure composition — no new infrastructure:
BranchNameBuilder,git ls-remote,gh pr list/view,RunManifestStore.Parse+PlanPrFrontMatter.Parse,twig show.Tests
16 new tests cover full state machine, branch naming, stale-snapshot/current-snapshot/manifest-missing, custom planned-tag override.