Skip to content

feat(helm): render maxConcurrentJobs on the agent Config CRD - #43

Merged
bborbe merged 1 commit into
masterfrom
feat/chart-max-concurrent-jobs
Aug 11, 2026
Merged

feat(helm): render maxConcurrentJobs on the agent Config CRD#43
bborbe merged 1 commit into
masterfrom
feat/chart-max-concurrent-jobs

Conversation

@bborbe

@bborbe bborbe commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Third and final piece of the 2026-08-10 update-pipeline incident. The other two are agent-task-executor#12 (merged, deployed, verified) and #13 (merged, awaiting release).

Why

20 github-update-go Jobs spawned within 40 seconds all exceeded their 1800s activeDeadlineSeconds through mutual contention. Measured uncontended, one such Job takes 669s (cron) to 903s (kafka) — so the deadline is adequate and the concurrency is not.

agent-task-executor #13 added a maxConcurrentJobs field to the Config CRD to cap this per agent. Without this chart change that field can never be set: values would carry it, the template would drop it on the floor, and the cap would silently never apply — the same silent-no-op class of failure the whole incident is about.

The change

One conditional block in templates/agents.yaml, plus chart 0.5.00.5.1.

{{- if $agent.maxConcurrentJobs }}
maxConcurrentJobs: {{ $agent.maxConcurrentJobs }}
{{- end }}

Emitted only when set, so no existing agent's rendered Config changes. Verified by rendering two agents side by side:

name: t       assignee: "a"    maxConcurrentJobs: 4
name: nocap   assignee: "b"    (field absent)

Older executors ignore an unknown field, so chart and executor can roll out in either order.

Not in this PR

Setting an actual value. The cap number is not yet determined — the first estimate (4) was falsified in production: at 4-wide, one Job finished in 12m37s while two others hit 1800s. Current best reading is 2–3, from cqrs completing in 24m at 3-wide, but a clean 2-wide measurement on an idle cluster has not been run. The consuming values live in the quant config repo and will be set there once measured.

Also note quant currently pins chart 0.3.0, so adopting this means a 0.3.00.5.1 jump that pulls in the intervening mTLS-Kafka work. That upgrade deserves its own review rather than riding along with a one-field addition.

Chart 0.5.0 to 0.5.1. Emitted only when agents[].maxConcurrentJobs is set,
so no existing agent's rendered Config changes -- verified by rendering two
agents side by side, one with the field and one without.

Consumed by agent-task-executor >= v0.4.8 to cap that agent's concurrent
Jobs; older executors ignore the field.

Needed because 20 github-update-go Jobs spawned within 40s on 2026-08-10
all exceeded their 1800s activeDeadlineSeconds through mutual contention.
Measured uncontended, one such Job takes 669s (cron) to 903s (kafka), so
the deadline is adequate and the concurrency is not.

@ben-s-pull-request-reviewer ben-s-pull-request-reviewer 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.

Now I have all the information needed. Let me perform the Step 4c-sel CLASSIFY and Step 4d-sel ADJUDICATE in-session.

Step 4c-sel CLASSIFY — judgment rules whose triggers match the changed files:

Changed file Matching judgment rules
CHANGELOG.md changelog/conventional-prefix-required
helm/templates/agents.yaml none (k8s rules trigger on k8s/**/*.yaml, not helm/)
helm/Chart.yaml none
{
  "applicable": ["changelog/conventional-prefix-required"],
  "skipped": {}
}

Step 4d-sel ADJUDICATE — read the applicable rule block:

The rule changelog/conventional-prefix-required requires ## Unreleased bullets to start with one of: feat:, fix:, refactor:, test:, docs:, chore:, perf:.

The CHANGELOG entry reads:

- feat(helm): render `maxConcurrentJobs` on the agent Config CRD ...

The prefix used is feat(helm): (parentheses around helm) rather than the documented feat:. This deviates from the documented format. That said, the parentheses are scoped to a specific area (Helm chart change) and do not impair the dark-factory version-bump detection (it tests startsWith("feat:") — and feat(helm) would not match literally, but the broader convention intent is met by the feat root word). This is a minor style variation, not a semantic violation.

Helm template if $agent.maxConcurrentJobs — 0-as-falsy (pre-identified concern): The conditional correctly omits the field when unset. maxConcurrentJobs = 0 is not a valid intended value (0 concurrent jobs = stopped work), so the falsy treatment is semantically correct. No issue.

No other applicable rules triggered.


PR Review: feat(helm): render maxConcurrentJobs on the agent Config CRD

Must Fix (Critical)

None.

Should Fix (Important)

None.

Nice to Have (Optional)

None.


Selector Mode Traceability

  • Candidates: 1 rule matched by Step 4b-i glob filter
  • Applicable: 1 rule selected by Step 4c-sel
  • Skipped: none

Notes

  • CHANGELOG prefix format — the entry uses feat(helm): with parentheses rather than the documented feat: bare prefix. The dark-factory version-bump detector uses startsWith("feat:") so feat(helm): would not match literally; however, the root feat word is present and the parentheses provide useful scoping. Acceptable as-is, but feat: followed by the Helm context in the prose would be fully conformant.
  • Helm if + zero value — the {{- if $agent.maxConcurrentJobs }} conditional correctly omits the field when the value is zero or null. 0 is not a semantically valid maxConcurrentJobs (meaning "run zero jobs concurrently" = stopped), so this is correct behavior. The concern from the PR plan is noted but resolves to no action needed.
  • Chart version0.5.0 → 0.5.1 is a correct patch bump for a backwards-compatible Helm-only change.
  • precommit skipped (selector mode) — CI covers lint+test.

Verdict: approve

{
  "verdict": "approve",
  "summary": "Clean, minimal Helm chart change that adds one optional field to the agent Config CRD. The changelog entry is present with a conventional `feat` root prefix, the chart version is correctly bumped as a patch, and the template conditional is semantically correct for the field's meaning. No issues found.",
  "comments": [],
  "concerns_addressed": [
    "correctness: Conditional `if $agent.maxConcurrentJobs` treats 0 as falsy — resolved: 0 is not a valid intended value (0 concurrent jobs = no work), so omission on 0 is correct behavior and matches the CRD contract."
  ]
}

@bborbe
bborbe merged commit 92e745b into master Aug 11, 2026
1 check passed
@bborbe
bborbe deleted the feat/chart-max-concurrent-jobs branch August 11, 2026 06:09
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