# ADR-2026-08-10-plugin-change-request-mutations: Route Native Change-Request Mutations Through Providers **Status:** accepted **Date:** 2026-08-10 **Area:** frontend, protocol ## Context Repository-provider plugins can list repositories and expose review data, but Kandev's native **Create PR** workflow still delegates the complete operation to `agentctl`, whose provider-specific creation code supports only built-in hosts. Registered review providers likewise have no native unlink mutation or workspace association source, so plugin links cannot drive the same task-row indicators and unlink controls as built-in change requests. ## Decision `RepositoryProviderRegistration` gains an optional provider-neutral change-request creation callback. Kandev keeps the native create dialog and performs the ordinary Git push first through the existing executor path. Only after that push succeeds does the host call the active repository provider with the current workspace, task, session, persisted repository, title, description, destination branch, and supported options. Plugin callbacks must cross the authenticated action boundary. The callback forwards the session only as a selector: Kandev verifies that it belongs to the task, resolves the selected repository's exact worktree branch server-side, and adds that branch to `VerifiedActionContext`. Plugin servers use this verified head branch and repository; browser body fields never select the source branch. Normalized open reviews from registered providers also participate in the native VCS action state, so an already-linked plugin change request suppresses the primary **Create PR** action exactly like a built-in pull request. For a task-scoped action, the browser may include optional `repositoryId` and `sessionId` selectors. Kandev accepts the repository only when it is attached to the verified task and accepts the session only when it belongs to that task. When both selectors are present, the repository must have a worktree in that session and Kandev supplies its non-empty branch as `headBranch`; omitting selectors preserves existing task-only action behavior. `ReviewProviderRegistration` gains optional unlink and workspace-association external- store methods. Kandev renders unlink controls and task-row/card change-request glyphs from those normalized callbacks and snapshots. Providers own association queries and mutations; the host owns placement, accessibility, responsive behavior, pending/error feedback, lifecycle cancellation, and semantic icons. An explicit unlink must remain detached: provider implementations suppress automatic source-branch relinking for that task/review pair until the user explicitly links it again, and watch-owned associations relinquish ownership without deleting the task. Built-in providers retain their current adapters. `agentctl` receives no Bitbucket or plugin dispatch branch. Callback work and association subscriptions are revoked with their owning plugin, matching the existing repository/review provider lifecycle. ## Consequences Future code-host plugins can participate in native create, unlink, and task-indicator workflows without provider-specific host branches. Creation now has a deliberate two-stage failure model: a successful push followed by a failed remote create reopens the native dialog in retry state and does not push again unnecessarily. Provider implementations must truthfully declare option support and make create retries safe. Normal Kandev tasks need not copy session worktree branches into task-repository metadata merely to authorize a plugin create operation. ## Alternatives Considered - Add Bitbucket creation to `agentctl`: rejected because it moves plugin API/auth logic into the host and repeats for every future provider. - Register a plugin-owned **Create PR** button or modal: rejected because it duplicates Kandev's native Git eligibility, dialog, feedback, and mobile behavior. - Infer plugin links by refreshing every task's full review detail: rejected because a task list would create an unbounded provider-request fan-out; one workspace association snapshot is the reusable bounded contract.