Skip to content

fix(automations): keep background scan runs single-provider#740

Merged
daniel-lxs merged 1 commit into
developfrom
claude/hungry-keller-1ac3be
Jul 23, 2026
Merged

fix(automations): keep background scan runs single-provider#740
daniel-lxs merged 1 commit into
developfrom
claude/hungry-keller-1ac3be

Conversation

@daniel-lxs

@daniel-lxs daniel-lxs commented Jul 23, 2026

Copy link
Copy Markdown
Member

Problem

Background-automation scan runs whose repository scope spans multiple source-control providers fail at bootstrap with "Failed to create source control token."

A scan payload over a mixed-provider repository set gets no sourceControlProvider stamp (resolveWorkspaceSourceControlProvider deliberately returns undefined for ambiguous sets), so dequeue falls back to the GitHub default and GitHub token minting fails with Selected repositories not found — the non-GitHub repository names don't exist in the GitHub installation. This breaks even on deployments with a working GitHub app.

Reproduced locally: a scheduled dependabot_triage scan over a Bitbucket + Azure DevOps repository set was canceled at the createSourceControlToken phase, and a fresh manual trigger reproduced the identical failure.

Fix

A run's source-control token is minted for exactly one provider, so every launched scan run must be single-provider:

  • dependabot-triage: scope to GitHub repositories only (Dependabot alerts are GitHub-only), stamp sourceControlProvider: 'github', and skip when no active GitHub repository is environment-backed — matching codeql-triage's existing behavior.
  • codeql-triage: stamp the provider explicitly instead of relying on the homogeneous-workspace fallback.
  • sentry-triage + suggester routes: partition the environment-backed scope into one scan run per (provider, host) with explicit sourceControlProvider/sourceControlHost stamps and per-partition prompts — mirroring the merged-pr-audit runner's partition pattern.
  • scheduled-triage-runner: buildScanTask now returns payloads: [...]; one task run launches per payload.
  • github-deployment-scope: new shared partitionActiveRepositoriesByProvider helper (deterministic provider-enum + host ordering, same identity rules as the audit runner).
  • dequeue-helpers: warn loudly when the ambiguous GitHub fallback engages so any future launch surface that forgets to stamp is diagnosable from the run's cancellation.

Snapshot-resume provider inheritance was fixed separately (#732/#734); this PR only covers fresh scan/automation launches.

Validation

  • 16 new unit tests across the partition helper, dependabot/sentry scan builders, the multi-payload runner loop, and the suggester dispatch fan-out; 416 tests pass in the changed areas.
  • Live-stack E2E on a mixed Bitbucket + ADO deployment: pre-fix triggers reproduced the token failure; post-fix, dependabot skips cleanly and a multi-provider triage scan launched two runs — one stamped ado, one stamped bitbucket — both passing createSourceControlToken with tokens minted for their own providers.
  • pnpm lint and pnpm check-types clean. pnpm knip passes on this branch (CI Knip job is green, and verified locally from a clean checkout of the branch). The local pre-push knip failure turned out to be environmental, not code: knip walks ancestor .gitignore files past the git-worktree boundary, and a worktree nested under a checkout's .agents/worktrees/ (which the parent's .gitignore ignores) poisons its analysis with phantom unused-file/export findings. The same commit passes knip from a non-nested directory.

🤖 Generated with Claude Code

Multi-provider repository scopes left scan payloads unstamped, so dequeue
fell back to the GitHub default and token minting failed on the non-GitHub
repository names ("Failed to create source control token.").

- dependabot-triage: scope to GitHub repositories only (Dependabot alerts
  are GitHub-only), stamp sourceControlProvider, and skip when no active
  GitHub repository is environment-backed (matching codeql-triage)
- codeql-triage: stamp the provider explicitly
- sentry-triage + suggester routes: partition environment-backed scopes
  into per-(provider, host) scan runs with explicit stamps, mirroring the
  merged-pr-audit runner
- scheduled-triage-runner: buildScanTask now returns one payload per run
- github-deployment-scope: shared partitionActiveRepositoriesByProvider
- dequeue-helpers: warn when the ambiguous GitHub fallback engages

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@roomote-roomote

roomote-roomote Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

2 issues outstanding. See task

  • packages/sdk/src/server/automations/scheduled-triage-runner.ts:213 A failure after one partition has been queued records the whole pass as failed, but recordAutomationRunOutcome still advances lastRunAt. The scheduler will therefore skip the remaining partitions until the next daily/weekly window, even though the run is reported as failed. Preserve/retry the unqueued partitions or avoid advancing the schedule after a partial launch failure.
  • packages/sdk/src/server/automations/github-deployment-scope.ts:120 A legacy active row with host = NULL is still emitted when the same (provider, fullName) is active on another host. Its payload has no sourceControlHost, and downstream repository resolution rejects that ambiguous identity. Match the merged-PR audit's guard by excluding ambiguous hostless rows (and add coverage for this collision).

Reviewed 49f8910

@daniel-lxs
daniel-lxs merged commit 2287a9a into develop Jul 23, 2026
17 checks passed
@daniel-lxs
daniel-lxs deleted the claude/hungry-keller-1ac3be branch July 23, 2026 23:00
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