Repository navigation
feat(runners): a code repository picks its Runner; Runners lose Runs AI Code Fixes - #5086
Merged
Merged
Conversation
…tch on a Runner A repository's settings in Code now pick the Runner AI works in it on (CodeRepository.runnerId), and a repository that picks none runs on a global Runner - the one OneUptime runs for every project - while its project uses global Runners. A Runner no longer has a "Runs AI Code Fixes" switch: it takes code work exactly while a repository of its project picks it. - One pure rule (Types/Runner/CodeRepositoryRunner) decides who may work in a repository; the server reads it for the code-fix claim (CodeFixClaimQuery joins each run to its repository), the repository token (only the repository's Runner gets one), the Runner's heartbeat capability, Code's gate, the exception checklist and the queue sweeper. - Runs are queued on their repository where the server can decide it: exception fixes from their readiness resolution, subject, trace and service recipes from the same facts their details route reads (CodeFixRunRepository). - The migration carries today's choice over: a project's code-fix Runner becomes the Runner of every repository it has, then the old column goes. - The Runner dialog and page lose the switch; a Runner's page lists the repositories that pick it; Code's repository settings get a Runner step with the one Runner picker; Code's blockers say which Runner is missing and link the repository's settings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d text in 17 languages - The claim, queue, readiness, gate, token and Kubernetes AI access suites read the repository's Runner choice instead of a Runner's code-fix switch; the claim's tenancy suite pins the candidate SQL a project's Runner and a global Runner are given, and the re-read by id. - New suites: the pure rule (Types/Runner/CodeRepositoryRunner) and the claim's SQL condition (CodeFixClaimQuery). - The Dashboard's 27 new sentences are translated in all 16 languages; the 13 this change no longer shows are gone from every locale. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The migration reads agent Runners with the predicate an earlier migration holds to the server's rule (IS_KUBERNETES_AGENT_RUNNER_SQL), and a new opt-in Postgres suite runs it on seeded rows - wired into the schema drift workflow - besides a statement-level suite. - New suites for the server reader (CodeRepositoryRunnerChoice), the run's repository at enqueue (CodeFixRunRepository, SubjectCodeFixRun), the repository token refusal, the claim and queue count per worker, the global Runners for code route and AIAgentService readers, and the repository's Runner setting (project check, agent Runner refusal, ACL). - Dashboard suites for the picker for a repository, its loader, the Settings field and card, and a Runner's Code Repositories card; the one-rule guard covers repositories too. - App's ingress, heartbeat and registration suites read the repository pick instead of the dropped switch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e fix switch - Code: a repository's Settings say what it runs on (Global Runner and how it is doing, a Runner of the project's own linked to its page, or why there is none); Edit Settings' Runner step offers Global Runner first, then the project's own Runners but never the Kubernetes agent's, and saves the Runner picked or none; the Runner blockers link to those settings. The fixture serves the global Runners for code, the project's Runners and switch, and saves the form as the server is sent it. - Global Runners: Create Runner asks only what a Runner may run, the list shows no AI code fix capability, and a Runner's page lists the code repositories that pick it (or says none does), each linked to its settings in Code; the switch's words name code repositories too. - The exception page's fixture uses the server's current Runner check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uage - Code (ai/ai-agent): a new "Pick the repository's Runner" section - the Runner step of a repository's Edit Settings, Global Runner when it picks none, what each runs, Use global Runners - and the steps, prerequisites, verification and failure words follow the repository's Runner instead of the Runs AI Code Fixes switch. - GitHub App, Runbook Agents (no switch row; code fixes are not a capability; the override's words), and a 13 -> 14 upgrade note on what the migration carries over, with the switch named as it was in the older notes of every translation. - Runner README: the third kind of work follows the repositories that pick the Runner. - Docs suites hold it: the Code page facts, the switch kept in English as a removed setting, the new note's place and claims, and the Runner form's capabilities. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…bal jest - The two Dashboard suites (the picker for a repository and the Settings page's Runner field) take jest itself from the global, as the other Dashboard suites that name jest.SpiedFunction do: @jest/globals types jest.spyOn() as jest-mock's spy, which the global annotation does not accept, so npm run compile-tests failed on them. - The exception page's readiness suite reads the refusal's message with contains checks instead of a regular expression. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- installation/upgrading (17 languages): master's note that visitors keep their own address now follows the runbook variables note; the note that a code repository picks its Runner follows it, before the endpoint pointer, with its link's anchor localized again. - RunbookVariablesUpgradeDocs is master's (its next note is the visitors note); VisitorAddressesUpgradeDocs now expects this change's note after it, and CodeRepositoryRunnerUpgradeDocs the visitors note before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the Runner step plainly - Prettier over six files the change touched (Runner model, Runner and AI agent data APIs, RunnerService, CodeFixReadiness, the Dashboard's RunnerChoices) and one import instead of two in CodeRepositoryRunnerChoice (no-duplicate-imports). - The Runner README said "Settings → Edit Settings → Runner", which reads as the old Settings → Runners path RunnersLiveUnderRunbooks keeps out of the shipped source; it now says Edit Settings, then its Runner step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a migration of their own SchemaMigrationsOnlineDdl refuses a new migration that builds an index or adds a foreign key on a table that already exists inside its transaction: both block the table's writes while they scan it. CodeRepository holds every project's repositories, so: - AddCodeRepositoryRunner1804300000000 keeps the new nullable column (added without a rewrite), the backfill and dropping the switch. - AddCodeRepositoryRunnerIndexAndKey1804350000000, registered right after it with transaction = false, builds the index with OnlineDdl.createIndex and adds the key to Runner with OnlineDdl.addForeignKey (NOT VALID, then validated), with the generated names, so the drift check finds nothing. - The statement suite records both (the online ones through OnlineDdl), and the Postgres suite runs both on seeded rows - the second outside a transaction, then again as a stopped run would - and checks the key is validated and the index valid. Each way of breaking the second migration (no key, no index, a key that does not set the Runner to null) fails it. - OwnedScopeEveryKindWithOwners lists CodeRepository.runner with its reason: a repository picks the Runner its AI works on, and Runners are read in full, so they can be picked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Dashboard locales (17 languages): master's new keys (the finding strip and the improvement card) kept in master's order; this change's 27 keys appended and its 13 removed keys dropped, merged key by key from the common base - neither side changed a key the other removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
…Runbooks UI review of the repository Runner choice: - Edit Settings' Runner step is a field like the dialog's others: the form draws its title and the card's description above the menu (no "(Optional)": empty is Global Runner), the picker no small label of its own, and its lines are the form's size. The menu is named by the form's label. While the choices load it holds a menu's room, not the page loader. - The settings card draws the Runner's status as the Runners page does (a green, red or grey dot); on Global Runner a repository with setup, build or test commands is told they are skipped, right above them. - A pick the page cannot name is a Runner the reader does not have access to (a repository can only pick its project's Runners, and a deleted one leaves it on Global Runner): said so, not "Unknown Runner (<id>)" or "a Runner this project no longer has". A refused Runner read no longer wipes out the global Runners, so a Settings Member is not told the server runs none. - A repository that picked none on a server with no global Runner is told to pick one of its own, not what a picked Runner does. - RunnerNotOnline names the Runner (CodeTaskBlocker.runnerName): "The Runner this repository picks, prod-eu-west-1, is not online." - A Runner's page lists the repositories that pick it in Runner Details, where the Runs AI Code Fixes switch was, instead of a card that sat empty between Runner Status and the setup command; with none, one short line says where a repository picks its Runner. - Setup Instructions are the card's body: as a description they were hidden on phones and nested blocks in a paragraph. - The orphaned run message says what to do once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e-code-remediation-ui-review
This was referenced Oct 20, 2026
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.
What
From the maintainer's feedback doc: "Remove Runs AI Code Fixes from here, and in the Code Repo section, we should be able to select a runner to run from (if not selected, it will run on global runner)."
runnerservice), then the project's own Runners. Empty means Global Runner. The settings card says what the repository runs on, with how it is doing, or why there is nothing to run on.Common/Types/Runner/CodeRepositoryRunner) decides who may work in a repository; the server reads it for the code-fix claim and the queue count (CodeFixClaimQueryjoins each run to its repository), the repository token (only the repository's Runner, or a global Runner for a repository that picks none, is given one), the Runner's heartbeat capability, Code's gate and blockers, the exception page's checklist and the queue sweeper. A repository can only pick one of its own project's Runners (the project reference check), never the in-cluster Runner the Kubernetes agent chart installed.1804300000000-AddCodeRepositoryRunneradds the column and carries today's choice over: each project's repositories pick the Runner it had the switch on for (alive most recently, never an agent row, a deleted, a global or a never-connected one), then the switch's column goes;down()gives the switch back to every picked Runner.1804350000000-AddCodeRepositoryRunnerIndexAndKeybuilds the column's index and its key toRunneronline (OnlineDdl, outside a transaction), so repositories stay writable while it runs.Tests
/runner/global-code-runners,AIAgentServicereaders, the repository's Runner setting (project check, agent-row refusal, ACL), both migrations statement-by-statement, and an opt-in Postgres suite that runs both on seeded rows (agent predicate checked row by row againstRunnerService.isKubernetesAgentRunnerRow; the key validated and the index valid, also when run again; mutation-checked) - wired intopostgres-schema-drift.yaml. All migrations on a fresh database: no schema drift. Dashboard: the picker for a repository, its loader, the Settings field and card, the Runner page card; the one-rule guard now covers repositories.UI review
Looked at, in real Chromium through the offline Code and Global Runners fixtures (and the exception page's), at 1280px and 390px, light and dark, in English and German:
What changed, and why:
aria-labelledby). While its choices load it holds a menu-sized placeholder instead of the page loader, which pushed the step down 130px and then jumped. The runbook step editor keeps its compact picker (RunnerPicker isFormField).RunnerLiveStatusBubble, whichRunnerStatusElementnow draws through too) instead of grey "· Connected" text; one of the project's Runners links to its page.SET NULL), so in practice this means the reader may not read Runners (a Settings Member) - the pick itself is fine. For the same reader,RunnerChoicesLoader.loadForCodeRepositorynow reads the project's Runners on their own: one refused read failed the whole load, and the card said "None: this server runs no global Runner".CodeTaskBlocker.runnerName(its English message already named it); without one the unnamed sentence stays.validateDOMNestingwarnings). It is the card's body now.Tests added or changed in the review:
Common/Tests/App/Dashboard/CodeRepositoryRunnerPicker.test.tsx: the picker as a form field (no label of its own, named by the form's label, form-size lines; negative control for the step editor), a pick the reader cannot see (no id, no warning colour), no global Runner with nothing picked, a refused Runner read keeping the global Runners and the switch, the card's status dot (connected, disconnected; still), the skipped-commands line and its negative controls, line- and menu-sized loading placeholders.CodeRepositorySettingsRunner.test.tsx: the field is drawn by the form (description, no "(Optional)",aria-labelledbypassed through) and the card passeshasCommands; the Runner page's loader, list and empty line, the row's place in Runner Details (after the capabilities, before Labels, not for agent rows or unreadable repositories), Setup Instructions as the card's body.RunnerStatus.test.tsx:RunnerLiveStatusBubble- its three statuses, the same colours a Runner row draws, a still connected dot, a suffix.CodeConversationParts.test.tsx: RunnerNotOnline names the Runner in bold; a name on another blocker is never drawn.CodeTaskCopy.test.ts: the named sentence is the unnamed one with the name in it, translated in all 16 languages.CodeFixReadiness.test.ts(the blocker carriesrunnerName; an unknown name is left out),CodeTaskGate.test.ts,CodeFixRunQueue.test.ts(the reason said once).RunnerUi.test.ts: the Runner page's new strings in every locale.Left as they are (on master already, outside this change): the Runners list's Capabilities column runs under the sticky actions column at 1280px; the top pixel of a helper line shows between a select and its open menu (shared Dropdown); "Step 3 of 4" is not translated in a stepped dialog on a phone; Reset Runner Key nests a paragraph in a paragraph (Common
ResetObjectID).Run after the review, on the branch with the newest master merged (no rebase, no force-push):
npx jest Guard: 151 suites, 4,764 tests), the locale suites (31 suites, 1,173 tests).ee/moved aside (and put back; nothing committed meanwhile).tsc --noEmitfor Common, the Dashboard and E2E; Commonnpm run compile-tests(all three parts); Apptsc. E2E's--listFilesreaches only itself and Common.npm run i18n:check: every locale sound, no translation lost.i18n:extract --dry-runadds only 35 model titles that are missing on master already (SCIM, SSO, Vercel), none of this change's.--checkon every code, test and data file the branch changes: clean exceptpackages/Runner/README.md, which master's own copy fails too (its tables; CI lints.ts/.tsxonly). ESLint on every.ts/.tsx/spec file this review changed: clean (the offline fixtures'.jsare outside every tsconfig, as on master).🤖 Generated with Claude Code