Skip to content
This repository was archived by the owner on Sep 20, 2026. It is now read-only.

fix(bridge): count pipeline-shaped coders toward CODER_AGENT_SLOTS - #338

Merged
joryirving merged 1 commit into
mainfrom
koji/coder-slot-pipeline-count
Sep 16, 2026
Merged

joryirving merged 1 commit into
mainfrom
koji/coder-slot-pipeline-count

Conversation

@joryirving

Copy link
Copy Markdown
Contributor

What

_coder_agent_name only read spec.coderAgentRef, so pipeline-shaped Workloadsspec.pipeline, the shape a retry re-dispatched with an explicit pipeline produces — resolved to None. Those Workloads name the coder on the issue-fix step's agentRef, not at the top level, so they contributed nothing to _load_by_coder_agent. Their coder never consumed a CODER_AGENT_SLOTS slot, and a second coder could be dispatched alongside them.

Fall back to the pipeline's issue-fix step agentRef when there's no top-level coderAgentRef, so these Workloads count toward coder load.

Evidence

Observed on the cluster: two coder Jobs running concurrently under CODER_AGENT_SLOTS={"coder":1}.

  • wl-…-587: standard shape, spec.coderAgentRef.name = coder → counted.
  • wl-…-578: pipeline shape (spec.pipeline[], coder on the issue-fix step), no spec.coderAgentRef → invisible to the load counter.

When 587's tick ran, 578 was active but uncounted, so load[coder]=0 and the slot cap admitted a second coder.

Test

Added test_counts_pipeline_shaped_coder. Verified load-bearing: it fails without the fix ({} instead of {"coder-py": 1}) and passes with it. Full suite: 636 passed.

Scope

Counting only. Does not change how pipeline Workloads are created or which agent they use — it makes an existing coder visible to the slot accounting it was already meant to be subject to.

_coder_agent_name only read spec.coderAgentRef, so pipeline-shaped Workloads
(spec.pipeline, e.g. a retry re-dispatched with an explicit pipeline) named
their coder on the issue-fix step's agentRef and resolved to None. Such
Workloads contributed nothing to _load_by_coder_agent, so their coder never
consumed a slot and a second coder could be dispatched alongside them --
observed as two 'coder' Jobs running at once under a coder:1 cap. Fall back to
the pipeline issue-fix step's agentRef so these Workloads count.

@its-saffron its-saffron Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Automated Review

Full PR review.

Analysis engine: MiniMax-M3@https://litellm.jory.dev/v1 (anthropic) — escalated (fast_low_confidence)

Recommendation

Approve. This is a narrowly scoped, well-explained fix to the coder-load accounting in _coder_agent_name. It restores correctness for pipeline-shaped Workloads without expanding scope or touching unrelated logic, and it ships with a load-bearing unit test that the author confirms fails on the unfixed code path. CI is green (docker and test both succeeded on the head commit).

Change-by-change findings

bridge/main.py_coder_agent_name

  • The previous implementation read spec.coderAgentRef unconditionally and returned None if it was missing or empty (ref.get("name") on an empty dict). The new implementation preserves the top-level path and adds a fallback that walks spec.pipeline for the first step with kind == "issue-fix" and reads agentRef.name from there. That matches the documented pipeline shape and the observed workload (wl-…-578) on the cluster.
  • Defensive handling is appropriate and matches the surrounding codebase style: isinstance(..., dict), ref.get("name") truthiness check, list iteration with continue on malformed entries. The loop returns the first matching issue-fix step's agent, which is consistent with how a pipeline-shaped Workload would be produced by retry re-dispatch.
  • The docstring now describes both shapes and the failure mode this fixes, including the concrete coder:1 cap observation. Helpful for future readers.
  • Scope is contained: counting only, as the PR body states. coderAgentRef continues to take precedence, so any Workload that already had a top-level ref still resolves identically. No behavioral change for existing workloads.

tests/test_bridge_runtime.py_pipeline_workload fixture + test_counts_pipeline_shaped_coder

  • The fixture builds a minimal but representative pipeline-shaped Workload (spec.pipeline with an issue-fix step and a review step, no coderAgentRef, with the created-by: dispatch-bridge label needed by _list_bridge_workloads to filter in). This matches the shape described in the docstring and the test catches the exact bug class (returning {} before, {"coder-py": 1} after).
  • The test wires the fixture through the same FakeAPI + _load_by_coder_agent plumbing as test_counts_running_issue_fix, so it exercises the real code path end-to-end rather than calling _coder_agent_name directly. Good.
  • The author confirmed load-bearing behavior (fails without the fix) and the full suite passes (636 tests), which is consistent with the CI test check being green.

Risk flags

The classifier returned no risk flags. The change touches the coder-load accounting path that gates the CODER_AGENT_SLOTS cap, but it strictly extends visibility (additional workloads now count) without altering which workloads count when both shapes are present. The wildcard / default branches in _load_by_coder_agent are unaffected. No auth, public-routes, file-serving, path, secret, or migration surfaces in this diff.

Standards Compliance

  • AGENTS.md sets expectations about issue authoring (imperative ask + named file paths) for the autonomous loop. That governs how issues are filed, not PR review. The PR body is descriptive and identifies the bug, the shape, the observed evidence, and the verification (failing-without-fix, passing-with-fix, full-suite green), which aligns with the repo's commit-message style seen in history (fix(bridge): …).
  • No repository convention appears violated by the diff (no new modules, no API surface change, no manifest change). The change is consistent with prior bridge-runtime fixes in style and scope.

Tool Harness Findings

The tool harness issued no tool calls and the reviewer relied on the corpus directly. The diff is small and self-contained, and the impacted function _coder_agent_name plus its sole caller in _load_by_coder_agent are visible in the impact scan, so the absence of native tool reads does not materially weaken this review.

CI

docker and test checks both succeeded on the head commit a3e61e6. Authoritative.

Unknowns or Needs Verification

  • The exact pipeline step ordering and kind value used by Foreman's retry re-dispatch when this PR was filed is not externally documented in the corpus; the code's reliance on kind == "issue-fix" is consistent with the codebase's task model (_task fixtures use kind="issue-fix") and with the pipeline shape shown in the test fixture, but I have not verified the Foreman CRD schema itself. This is a minor unverifiable point, not a blocker, since the test mirrors the real shape closely and the docstring documents the assumption.
  • Whether other pipeline shapes (e.g. pipelines without an issue-fix step at all) are ever produced by retry re-dispatch could not be confirmed from the corpus. The current fallback handles the absence of issue-fix cleanly by returning None, matching pre-fix behavior for that case, so no regression is implied.

@joryirving
joryirving merged commit eacce68 into main Sep 16, 2026
3 checks passed
@joryirving
joryirving deleted the koji/coder-slot-pipeline-count branch September 16, 2026 23:37
@its-miso its-miso Bot mentioned this pull request Sep 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant