Skip to content

CRITICAL: plan detect-state (and 5 sibling sites) hard-code github.com slug regex; blocks all ADO dispatches #415

Description

@PolyphonyRequiem

Parent: #414
Severity: CRITICAL — blocks every ADO dispatch at plan-level.yaml state_detector step

Symptom

First-run dispatch against an ADO-hosted repo (e.g. cloudvault-service-api at https://microsoft@dev.azure.com/microsoft/CloudVault/_git/cloudvault-service-api) trips state_detector_error_gate immediately:

🚦 GATE · state_detector_error_gate
Scope: wave_dispatch_loop[0] / dispatch_items[0] / plan_level_dispatch
State: error
Error: Could not resolve repo slug from origin remote

Root cause

Polyphony has a duplicated GitHub-only slug regex at 6 sites:

Site Line
Sdlc/Observers/PlanObserver.cs 41
Commands/PlanCommands.DetectState.cs 31
Commands/BranchCommands.LoadTree.cs 20
Commands/BranchCommands.Route.cs 361
Commands/PrCommands.cs 43
Commands/StatusCommand.cs 51

All use a variant of:

new(@"github\.com[:/]([^/]+/[^/.]+?)(?:\.git)?/?$", RegexOptions.Compiled);

ADO origin URLs (dev.azure.com/{org}/{project}/_git/{repo}) never match → empty slug → plan detect-state returns state: error.

The launcher already has the right values (the apex-driver invocation passes --input platform=ado --input organization=microsoft --input project=OS --input repository=cloudvault-service-api), but plan detect-state ignores workflow inputs and derives the slug itself from origin.

Why this wasn't caught earlier

Polyphony self-hosts on GitHub, so the dogfood path never exercises state_detector against an ADO origin. Every CI scenario that goes through plan-level.yaml is implicitly GitHub.

The platform abstraction exists in the executor layer — there are dedicated PrCommands.*Ado verbs (OpenPlanAdo, MergePlanAdo, CreateFeatureAdo, …) that take org/project/repo as explicit inputs. The observer layer has no equivalent — it tries to derive a GitHub-shaped slug and silently degrades on ADO.

Fix shape

Two layers, both required:

1. Make slug resolution platform-aware (C#)

Either:
(a) Promote the slug abstraction from owner/repo to a discriminated RepoIdentity (GitHubRepo(owner, repo) | AdoRepo(org, project, repo)) and update all 6 regex sites + every consumer.
(b) Extend TryResolveSlugAsync to recognize ADO URLs and return a stringly-typed slug like dev.azure.com/{org}/{project}/_git/{repo}, with each consumer doing its own platform branch.

(a) is the right shape long-term but bigger; (b) is a faster patch with worse hygiene. Recommend (a) given the existing *Ado vs no-suffix split makes the discriminator natural.

2. Add explicit override flags to plan detect-state (and matching verbs)

Even with (a), detect-state should accept explicit --platform, --organization, --project, --repository (or --repo owner/repo) as overrides — workflow YAML can pass them from workflow.input so the verb doesn't have to derive from origin.

Update plan-level.yaml state_detector step to pass the inputs through.

3. Test coverage

Add a CI scenario in tests/harness/scenarios/ exercising plan-level.yaml against a synthetic ADO origin URL. The existing "GitHub-only fallthrough" gap means we need an ADO-shaped fixture before this kind of regression is catchable.

Workaround for the operator (none satisfactory)

There is no --repo override on plan detect-state. Operators on ADO currently cannot proceed past state_detector without a polyphony patch.

Cross-refs

  • Friction report (cloudvault dogfood, May 2026)
  • Sibling: child issue for state next-ready defense-in-depth (different verb, similar shape — both verbs derive slug from origin and silently degrade)
  • The architectural through-line in Epic: First-run friction for newly-onboarded repos (May 2026 dogfood) #414 ("either own the assumption or verify it explicitly") points at this exact gap: the observer layer trusts that origin URL is GitHub-shaped, with no override and no defense.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpolyphony-followupFollow-up from a shipped PR

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions