declare maxConcurrentJobs in the CRD schema the executor installs - #17
Conversation
There was a problem hiding this comment.
{
"verdict": "request-changes",
"summary": "The maxConcurrentJobs CRD schema fix is correct and well-guarded by a new test, but two critical issues block merge: the test file has no Ginkgo suite entry-point so all specs silently pass zero tests, and CRDClientBuilder violates the XxxFunc naming convention for function-type adapters.",
"comments": [
{
"file": "pkg/k8s_connector_test.go",
"line": 41,
"severity": "critical",
"message": "Missing Ginkgo suite file. This test file (and the one at line 117) contains Describe/It specs but no pkg/k8s_connector_suite_test.go with TestSuite + RunSpecs. make test exits 0 while discovering 0 specs — silent coverage loss. Create pkg/k8s_connector_suite_test.go with the standard Ginkgo TestSuite entry-point. (rule: go-testing/suite-test-file-required)"
},
{
"file": "pkg/k8s_connector.go",
"line": 42,
"severity": "critical",
"message": "Function-type adapter must be named CRDClientBuilderFunc (XxxFunc convention). Renaming is required so consumers can find the adapter by grepping for the interface name + 'Func'. (rule: go-functional-composition/func-type-name)"
}
],
"concerns_addressed": [
"correctness: maxConcurrentJobs added to configSpecSchema() — the field is now declared in the CRD schema, preventing silent pruning on executor restart",
"correctness: configSpecSchema() doc comment thoroughly explains the failure mode and sync requirement with AgentConfiguration",
"tests: new test 'declares every field AgentConfiguration reads from spec' guards against future schema drift for maxConcurrentJobs",
"correctness: close(stopCh) in Listen() — verified as producer-owned channel (created inside Listen, closed by receiver), not a concurrency bug",
"correctness: cs.PrependReactor() — verified as void-return method, not a bare error call",
"correctness: //counterfeiter:generate directive IS present at line 28 above K8sConnector interface — false positive from funnel"
]
}bborbe
commented
Aug 15, 2026
Both CRITICAL findings are refuted with evidence. 1. "Missing Ginkgo suite file … The suite entry-point exists at funcTestPkg(t*testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Pkg Suite")
}Ginkgo requires exactly one Independently disproved before this review: removing A spec that fails on demand is a spec that runs. 2. The |
Problem
maxConcurrentJobshas never durably applied in any cluster.v0.5.0 added the field to
AgentConfigurationand to the Helm chart'scrds/config-crd.yaml,but not to
configSpecSchema()inpkg/k8s_connector.go— the schema this service installsitself.
main.go:82callsSetupCustomResourceDefinition(ctx)on every executor start,which overwrites the cluster CRD from the compiled-in schema.
So on every pod start:
maxConcurrentJobs.Config.config.MaxConcurrentJobsreads0.deferIfAtConcurrencyCaptreats0as unlimited and returns immediately — cap disabled.Verified live: the cluster CRD declared 13 spec properties and none was
maxConcurrentJobs;kubectl get config agent-github-update-go -o jsonpath='{.spec.maxConcurrentJobs}'returnedempty on both dev and prod. The CRD showed
generation: 246— that is this overwrite loop.This also explains the "reverting" CRD. Hand-applying the fixed CRD appeared to work and
then silently revert three separate times today. Each revert was simply the next pod start.
Helm was never the culprit (it genuinely does not upgrade
crds/), and neither was aconcurrent operator — the binary reclaims the CRD by design.
Consequence for prior measurements: prod bursts recorded as evidence of the concurrency
race (15 released → 15 admitted) were mostly the cap being switched off, not the race. The
race is real and separately fixed in #16, proven by a unit test that does not depend on cluster
state — but it was not the whole story.
Fix
Declare the field in
configSpecSchema(), matchinghelm/crds/config-crd.yaml:Plus a doc comment on
configSpecSchemastating the invariant that was violated: any fieldadded to
AgentConfigurationmust be added here too, or it is pruned everywhere withinseconds of the next restart.
Test
New spec asserting the installed schema declares
maxConcurrentJobsas an integer. Verified inboth directions — removing the field from the schema fails the test, restoring it passes.
This is the guard that would have caught the v0.5.0 omission: the field existed in the Go
struct, in the values files, and in the Helm chart, and every one of those looked correct.
Note on
funlenconfigSpecSchemalanded at 82 lines against an 80 limit. I did not extract a helper tosatisfy the counter — a function that exists only to shorten another one is worse than the
lint. Instead the rationale moved to the function's doc comment (where it belongs, since the
invariant covers the whole function) and the field is declared on one line, matching the
existing style of its neighbours.