🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

feat: add Helm chart for standalone AI Gateway - #27256

Merged
pawbana merged 10 commits into
mainfrom
pawel/aigov-318-create-helm-chart-for-standalone-ai-gateway
Jul 22, 2026
Merged

feat: add Helm chart for standalone AI Gateway#27256
pawbana merged 10 commits into
mainfrom
pawel/aigov-318-create-helm-chart-for-standalone-ai-gateway

Conversation

@pawbana

@pawbana pawbana commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Adds the coder-ai-gateway Helm chart for deploying the Coder AI Gateway as a standalone Kubernetes workload.

The chart requires an existing key Secret and either an explicit Coder URL or Coder Service configuration. It supports listener and Coder-facing TLS, configurable probes and workload settings, and optional Service, Ingress, and Gateway API HTTPRoute resources.

Integrates the chart with existing Helm build, lint, golden generation, release artifact, Helm repository, and OCI publishing workflows.

@linear-code

linear-code Bot commented Jul 15, 2026

Copy link
Copy Markdown

AIGOV-318

pawbana commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

@pawbana
pawbana force-pushed the pawel/aigov-318-create-helm-chart-for-standalone-ai-gateway branch 4 times, most recently from 4e23a5a to d65696c Compare July 15, 2026 10:09
@pawbana pawbana changed the title tmp-commit feat: add heml chart for standalone AI Gateway Jul 15, 2026
@pawbana
pawbana force-pushed the pawel/aigov-318-create-helm-chart-for-standalone-ai-gateway branch from d65696c to 531f6b8 Compare July 15, 2026 10:40
@pawbana

pawbana commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

@coder-agents-review

coder-agents-review Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Chat: Review posted | View chat
Requested: 2026-07-16 17:02 UTC by @pawbana
Spend: $78.20 / $100.00

Review history
  • R1 (2026-07-15): 16 reviewers, 4 Nit, 6 Note, 1 P2, 10 P3, COMMENT. Review
  • R2 (2026-07-15): 13 reviewers, 8 Nit, 6 Note, 1 P2, 12 P3, 1 P4, COMMENT. Review
  • R3 (2026-07-16), 8 Nit, 6 Note, 1 P2, 12 P3, 1 P4, COMMENT. Review
  • R4 (2026-07-16): 10 reviewers, 10 Nit, 7 Note, 1 P2, 13 P3, 1 P4, COMMENT. Review

deep-review v0.9.0 | Round 4 | f997afa..41c0f78

Last posted: Round 4, 32 findings (1 P2, 13 P3, 1 P4, 10 Nit, 7 Note), COMMENT. Review

Finding inventory

Finding inventory - PR #27256

Law analysis

R1: Effective +2469 -7 (40 files), head 531f6b8. R2: Effective +3054 -7 (51 files, 1001 production / 2053 test), head 2f1347a. Verdict: Don't split (advisory), unchanged both rounds. Growth is schema + docs + golden fixtures within the single concern.

Findings

# Sev Status Location Summary Round Reviewer Posted
CRF-1 Nit Dropped by orchestrator (empirically disproven; copy is load-bearing) tests/chart_test.go:75 Redundant tc := tc loop-variable copy R1 Netero No
CRF-2 P3 Author fixed (2f1347a) tests/chart_test.go:23 Six of 13 fail validation branches have no test case R1 Netero, Mafu-san Yes
CRF-3 P3 Author fixed (2f1347a) tests/chart_test.go:123 HTTPRoute CRD-missing guard structurally untestable (harness hardcodes --api-versions) R1 Netero Yes
CRF-4 P2 Author fixed (2f1347a) templates/_aigateway.tpl:125 Liveness probe with no startupProbe crashloops pod while coderd unreachable at startup R1 Mafuuu P2, Pariston P2, Kite P2 Yes
CRF-5 P3 Author fixed (2f1347a) templates/_helpers.tpl:19 renderTemplate narrows extraTemplates to strings only; diverges from libcoder + sibling charts R1 Robin P3, Zoro P3 Yes
CRF-6 P3 Author fixed (2f1347a) templates/_helpers.tpl:71 Chart-owned env $owned list is hand-maintained duplicate of containerspec; fails open on drift R1 Meruem P3, Hisoka Note, Chopper Note Yes
CRF-7 P3 Author fixed (2f1347a) templates/_aigateway.tpl:87 CODER_AI_GATEWAY_KEY unguarded; user coder.env value crashes container ("mutually exclusive") R1 Mafuuu P3 Yes
CRF-8 P3 Author fixed (2f1347a) templates/NOTES.txt:5 NOTES/README print in-cluster Service URL unconditionally even when service.enabled=false R1 Mafuuu P3, Chopper P3, Hisoka Note, Bisky Note Yes
CRF-9 P3 Author fixed, panel-verified R4 templates/ingress.yaml:32 listenerTLS + ingress/httproute renders plaintext-to-TLS backend; no validation/warning R1 Hisoka P3, Mafuuu Note, Meruem Note Yes
CRF-10 P3 Author fixed (2f1347a) templates/_aigateway.tpl:30 automountServiceAccountToken suppression only on created SA; disableCreate path mounts unused token R1 Kurapika P3 Yes
CRF-11 P3 Author fixed (2f1347a) templates/_helpers.tpl:10 coderURL namespace substitution untested under non-default release namespace R1 Bisky P3 Yes
CRF-12 P3 Author fixed (2f1347a) values.yaml:188 service.enabled diverges from chart's own enable convention and sibling coder.service.enable R1 Gon P2, Zoro Nit, Luffy Nit Yes
CRF-13 Nit Author fixed (2f1347a) templates/_aigateway.tpl:27 Inline pod-template component annotation duplicates coder.componentAnnotation override R1 Gon P3, Zoro Nit Yes
CRF-14 Nit Author fixed (2f1347a) templates/_aigateway.tpl:125 Probes hardcoded, no values surface; coder chart exposes probe knobs R1 Pariston Nit Yes
CRF-15 Nit Author fixed (2f1347a) templates/_helpers.tpl:29 0.1.0 install-from-Git sentinel duplicates libcoder's coder.image tag check R1 Meruem Nit Yes
CRF-16 Nit Author fixed (2f1347a) commit/PR title Title misspells "helm" as "heml"; lands in main on squash R1 Leorio Nit, Mafu-san Nit Body
CRF-17 Nit Author fixed (2f1347a) values.yaml:186 Comment "for port 4001" contradicts default service.port 80 R1 Gon Nit Yes
CRF-18 Note Author accepted R2 (conscious choice, matches sibling charts) templates/_aigateway.tpl:91 Metrics listener always-on, unauthenticated on 0.0.0.0:2112, no toggle, no NetworkPolicy R1 Kurapika Note, Luffy Note Yes
CRF-19 Note Author fixed (2f1347a) templates/_aigateway.tpl:31 terminationGracePeriodSeconds (300) equals binary shutdown timeout; SIGKILL cuts in-flight streams R1 Mafuuu Note Yes
CRF-20 Note Author fixed (2f1347a) templates/service.yaml:32 nodePort rendered regardless of service.type; conflict only caught at apply, not render R1 Kite Note Yes
CRF-21 Note Author fixed (2f1347a) values.yaml:113 Default resources inherited from libcoder (2000m/4096Mi) heavy for a forwarding gateway R1 Kite Note Yes
CRF-22 Note Author accepted R2 (conscious choice) templates/_aigateway.tpl:130 Readiness probe ties Service membership to coderd DRPC; coderd blip drops all replicas at once R1 Pariston Note Yes
CRF-23 Note Author fixed (2f1347a) README.md:75 README hardcodes http:// proxy target; scheme is https when listenerTLS set R1 Leorio Note Yes
CRF-24 Note Open (informational, not posted) tests/chart_test.go:121 Test harness is a third near-identical copy of coder/provisioner harnesses R1 Robin Note, Zoro Note No
CRF-25 Note Open (informational, not posted) tests/testdata/owned_env.yaml:1 Chart-owned env guard tested for only 1 of 10 protected variables R1 Bisky Note No
CRF-26 Note Open (informational, not posted) templates/_aigateway.tpl:82 Ports 4001/2112 hardcoded and repeated across templates/NOTES/README R1 Gon Note No
CRF-27 P3 Author fixed, panel-verified R4 templates/_helpers.tpl:101 Env override guard scans only coder.env, not coder.envFrom; CRF-7 class left open, "cannot be overridden" promise false for envFrom R2 Hisoka P3 Yes
CRF-28 P3 Author fixed, panel-verified R4 values.yaml:119 startupProbe/livenessProbe comment misdirects: following it while enabling liveness reintroduces CRF-4 crashloop; liveness-off also removes restart-on-hang R2 Mafuuu P3, Pariston Note, Meruem Note Yes
CRF-29 P4 Author fixed, panel-verified R4 templates/_aigateway.tpl:112 livenessProbe render branch has zero golden coverage (only case sets enabled:false) R2 Bisky P4 Yes
CRF-30 Nit Author fixed, panel-verified R4 values.yaml:194 Secret refs inconsistent: keySecret/caSecret/clientSecret use .name, listenerTLS uses .secretName R2 Gon Nit Yes
CRF-31 Nit Author fixed, panel-verified R4 values.yaml:197 terminationGracePeriodSeconds 330 coupled to binary shutdown timeout with no comment (CRF-19 fix undocumented) R2 Gon P3 (downgraded) Yes
CRF-32 Nit Author fixed, panel-verified R4 README.md:14 README kubectl create secret lacks -n; verbatim use into non-default namespace misplaces the Secret R2 Leorio Nit Yes
CRF-33 Note Open (informational, not posted) templates/service.yaml:28 Service port named http carries HTTPS when listenerTLS set R2 Gon Note No
CRF-34 Nit Author fixed, panel-verified R4 templates/_aigateway.tpl:106 Probe field-projection block triplicated verbatim across startup/liveness/readiness R2 Meruem Nit, Robin Note Yes
CRF-35 Note Dropped R4 (Komugi withdrew: goldens match Chart.yaml 0.1.0, not a defect) tests/testdata/custom.golden:52 Goldens hardcode 0.1.0 version R2 Komugi Note No
CRF-36 Nit Open README.md:82,158 Namespace-flag class incomplete: helm get notes (:82) and kubectl rollout restart (:158) still lack --namespace R4 Netero, Mafu-san, Leorio Yes
CRF-37 Nit Open enterprise/cli/aigatewaystart.go:38 "Keep shutdownTimeout in sync with terminationGracePeriodSeconds" comment can be read as "make equal," reintroducing CRF-19 R4 Mafu-san Yes
CRF-38 Note Open templates/NOTES.txt:6 Direct proxy path (coderd -> Service with listenerTLS) does not warn coderd must trust the listener cert; CRF-9 docs cover only the ingress path R4 Mafuuu Yes
CRF-39 P3 Open templates/httproute.yaml:14 httproute.enable with default empty parentRefs renders an inert HTTPRoute attached to no Gateway; no validation, asymmetric with ingress.host guard R4 Meruem P3 Yes

Contested and acknowledged

CRF-9 (P3, templates/ingress.yaml:32) - listenerTLS + ingress plaintext-to-TLS backend

  • Finding (R1): Enabling listenerTLS together with ingress/httproute renders a backend that speaks plaintext HTTP to the HTTPS listener on 4001, with no backend-protocol hint. Hisoka rendered the combination and got TLS-handshake 502s at request time. Proposed a validate rejection or documented backend-protocol requirement.
  • Author defense (R2): "Ingress or HTTPRoute + HTTPS on backend is possible configuration. Check was not added. Extended documentation." Author rejects a hard validation failure (the combination is legitimate for controllers that support backend TLS) and instead added a README section on controller-specific backend TLS annotations.
  • Status: contested; not yet evaluated by the panel. Reviewers judge whether documentation is a sufficient response or a validation/warning is still warranted.

CRF-9 (P3, templates/ingress.yaml:32) - listenerTLS + ingress plaintext-to-TLS backend

  • Finding (R1): Enabling listenerTLS together with ingress/httproute renders a backend that targets the Service port with no backend-protocol hint, so a controller such as ingress-nginx speaks plaintext HTTP to the HTTPS listener on 4001 and requests fail at runtime (TLS-handshake 502s). The chart validates several other cross-field combinations but not this one. Proposed a validate rejection or documented backend-protocol requirement.
  • Author defense (R2): "Ingress or HTTPRoute + HTTPS on backend is possible configuration. Check was not added. Extended documentation." Declined a hard validate reject (the combination is legitimate for controllers that re-originate TLS at the backend) and added a README section on controller-specific backend TLS.
  • Panel disposition (R2, 7 reviewers): Unanimous that a hard validate fail is wrong (Hisoka, Mafuuu, Kurapika, Meruem, Knov, Pariston, Leorio all agree the combination is legitimate and controller-specific backend TLS cannot be validated generically). Kurapika confirmed it fails closed (no security exposure). 5 reviewers (Hisoka, Mafuuu, Kurapika, Meruem, Knov) judged the README documentation a sufficient ceiling and voted close. 2 reviewers (Pariston P3, Leorio P3) re-raised on doc/UX completeness: the README teaches the fix but never names the failure symptom (502/handshake) so an operator has nothing to grep for (Leorio), and there is no install-time signal though NOTES.txt already computes the exact condition (Pariston). Disposition: hard-validation question closed (author correct); residual kept open at P3 for the two cheap, non-blocking doc/UX additions. Re-raised as a reply on the existing thread.

CRF-18 (Note, templates/_aigateway.tpl:91) - metrics listener always-on

  • Finding (R1): Metrics listener is hardcoded on, unauthenticated on 0.0.0.0:2112, with no disable toggle. The note asked whether the absent toggle was a conscious decision worth stating.
  • Author accepted (R2): "Yes, it is conscious choice." Matches sibling coder/provisioner charts. Note answered as intended.

CRF-22 (Note, templates/_aigateway.tpl:130) - readiness probe coupled to coderd DRPC

  • Finding (R1): Readiness probe ties data-plane Service membership to the coderd DRPC connection, so a coderd blip drops all replicas from endpoints at once. Flagged to confirm intent.
  • Author accepted (R2): "Yes, it is conscious choice." Readiness is now gated behind readinessProbe.enabled (default true). Intentional coupling confirmed.

CRF-1 (Nit, tests/chart_test.go:75) - tc := tc copy

  • Finding: Netero recommended deleting the tc := tc copy as redundant under Go 1.22+ per-iteration semantics, matching sibling helm tests.
  • Empirical disproof (Komugi): The outer tc is shared across the inner for _, namespace := range testNamespaces loop, which mutates tc.namespace and launches t.Parallel() subtests closing over it. Only default_values has two namespaces. Deleting line 75 and running GOMAXPROCS=2 go test -race -run TestRenderChart -count=8 fails deterministically (default/default_values reads the coder golden while templating namespace default). The copy is load-bearing. Empirical result wins; finding dropped, not posted.

Round log

Round 4 update

Churn guard: PROCEED. Head 022bf63 -> 41c0f78, one commit touching only README.md (+3 -1) that adds the CRF-9 symptom sentence ("TLS handshake error reported as HTTP 502"), the non-optional half of the R2 residual. All 8 posted findings now addressed. Because R3's panel was blocked, the 7 R3 fixes (CRF-27, CRF-28, CRF-29, CRF-30, CRF-31, CRF-32, CRF-34) plus the CRF-9 R4 doc fix are all present but never panel-verified; the R4 panel verifies them against the current code.

Round 4 panel

10-reviewer panel (bisky, hisoka, mafu-san, mafuuu, pariston, gon, leorio, meruem, komugi + wildcard kite) plus Netero. All 8 prior fixes independently verified against head 41c0f78 and confirmed real (structural, not symptom patches); no regressions. New: 1 P3 (CRF-39 inert HTTPRoute), 2 Nit (CRF-36 namespace class, CRF-37 in-sync comment), 1 Note (CRF-38 direct-proxy TLS trust). CRF-35 withdrawn by Komugi. Highest new severity P3, so COMMENT. Reviewed against f997afa..41c0f78.

Round 3 update

Churn guard: BLOCKED. Branch rebased (new base f997afa), head 2f1347a -> 022bf63. 7 of 8 posted findings addressed with fixes + author replies (CRF-27, CRF-28, CRF-29, CRF-30, CRF-31, CRF-32, CRF-34; correctness unverified, panel deferred). CRF-9's R2 doc/symptom residual is silent: no code change (README/NOTES still lack "502"/"handshake"), no author reply after the R2 panel re-raise, thread resolved in the UI. One silent posted finding blocks the panel per the deep-review BLOCKED rule. Posted a COMMENT naming the silent item and the response needed; no inline comments, no panel, no Netero. Note: the R2 re-raise reply's thread-unresolve failed (bot token lacks unresolveReviewThread), so the thread appeared resolved to the author.

Round 2 update

Churn guard: PROCEED. 19 addressed (CRF-2 through CRF-8, CRF-10 through CRF-17, CRF-19, CRF-20, CRF-21, CRF-23), 2 acknowledged (CRF-18, CRF-22), 1 contested (CRF-9). "Author fixed" = author claims fixed; panel verifies on encounter. New commit 531f6b8 -> 2f1347a, +585 lines. CRF-24/25/26 remain informational (never posted).

Round 2 panel

13-reviewer panel (bisky, hisoka, mafu-san, mafuuu, pariston, gon, leorio, kurapika, komugi, meruem, robin, ging-go + wildcard knov) plus Netero (no findings) and Law (Don't split). All 19 author-claimed fixes independently verified against the tree; CRF-2/3/5/6/10/11/15 confirmed structural, not symptom patches. CRF-9 disposed (hard validation rejected by consensus; residual doc gap re-raised P3). New: 2 P3 (CRF-27 envFrom guard gap, CRF-28 misleading probe comment), 1 P4, 4 Nit, informational notes. Highest new severity P3, so COMMENT. Reviewed against cc11c8a..2f1347a.

Round 1

Netero + Law (infrastructure), then 16-reviewer panel (bisky, hisoka, mafu-san, mafuuu, pariston, gon, leorio, kurapika, chopper, ging-go, komugi, luffy, robin, zoro + wildcards meruem, kite). Law: Don't split (advisory). Highest severity P2 (liveness/startup crashloop, 3-reviewer convergence). No P0/P1, so COMMENT event. CRF-1 dropped (Komugi empirical disproof). Reviewed against cc11c8a..531f6b8.

About deep-review

CRF = Coder Review Finding (P0-P4, Nit, Note)

Reviewer Focus
Bisky tests
Chopper ops/errors
Churn-guard change verification
Ging language modernization
Gon naming
Hisoka edge cases
Killua perf
Kite change integrity
Knov contracts
Knuckle SQL
Komugi flake/determinism
Kurapika security
Law decomposition
Leorio docs
Luffy product
Mafu-san process
Mafuuu contracts
Melody dispatch/pairing
Meruem structural
Nami frontend
Netero mechanical checks
Pariston premise testing
Pen-botter product gaps
Razor verification
Robin duplication
Ryosuke Go arch
Takumi concurrency
Zoro shape

🤖 Managed by Coder Agents.

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is a well-built chart. It reuses the libcoder library the way the coder and provisioner charts do, keeps the imperative surface to a few template helpers, ships render-time validation with precise field-level error messages, and backs it with a deterministic golden-file suite (63% test density) that the panel ran green under -race and a GOMAXPROCS sweep. Bisky's take: "this test suite is lovely... These are real gems." No scope drift: every one of the 40 files belongs to the chart or its mechanical build/release wiring, which mirrors the existing chart entries line-for-line.

Severity count: 1 P2, 10 P3, 4 Nit, 6 Note. No P0/P1, so this is a COMMENT, not a block. The one finding to fix before shipping is the liveness/startup race (CRF-4): three reviewers independently traced that the process does not open its /healthz listener until it has connected to coderd and loaded providers, so on a fresh co-install or during a coderd outage the gateway crashloops. The rest cluster into contract-narrowing (CRF-5, CRF-6, CRF-7), operator-signal correctness (CRF-8, CRF-9, CRF-23), and convention drift (CRF-12, CRF-13).

Process notes, not inline findings:

  • The commit subject / PR title misspells "helm" as "heml" (CRF-16). It squash-merges into main permanently. Suggest feat(helm/ai-gateway): add Helm chart for standalone AI Gateway.
  • The PR description claims the suite covers "all validation error cases," but 6 of the 13 fail branches have no test (this is CRF-2). Mafu-san flagged this as fake completeness: a reviewer trusting the description approves ~46% of the validation logic as tested when it is not. Either add the cases or scope the wording.
  • Netero's round-1 tc := tc nit was dropped: Komugi empirically proved the copy is load-bearing for the parallel multi-namespace subtests (deleting it fails default_values deterministically). Do not remove it.

No findings against the build/release plumbing: the charts list drives the build/ai-gateway_helm_$(VERSION).tgz target before signing, and the attestation ./build/*_helm_*.tgz glob already covers the artifact.

🤖 This review was automatically generated with Coder Agents.

Comment thread helm/ai-gateway/templates/_aigateway.tpl
Comment thread helm/ai-gateway/templates/_aigateway.tpl
Comment thread helm/ai-gateway/templates/_helpers.tpl Outdated
Comment thread helm/ai-gateway/templates/_helpers.tpl Outdated
Comment thread helm/ai-gateway/templates/_aigateway.tpl Outdated
Comment thread helm/ai-gateway/values.yaml
Comment thread helm/ai-gateway/templates/_aigateway.tpl
Comment thread helm/ai-gateway/README.md Outdated
Comment thread helm/ai-gateway/tests/chart_test.go
Comment thread helm/ai-gateway/tests/chart_test.go Outdated
@pawbana pawbana changed the title feat: add heml chart for standalone AI Gateway feat(helm/ai-gateway): add Helm chart for standalone AI Gateway Jul 15, 2026
@pawbana pawbana changed the title feat(helm/ai-gateway): add Helm chart for standalone AI Gateway feat: add Helm chart for standalone AI Gateway Jul 15, 2026
@pawbana

pawbana commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Strong round-2 turnaround. Every one of the 19 round-1 findings the author marked fixed was independently verified against the tree, and the important ones were fixed at the root rather than patched at the symptom: the chart-owned env guard now derives its protected list from the rendered ownedEnv (no more hand-maintained duplicate), automountServiceAccountToken: false moved to the pod spec so it holds on the disableCreate path, extraTemplates delegates to libcoder's coder.renderTemplate again, and the HTTPRoute CRD guard is now actually testable via per-case apiVersions. Bisky: "this test suite is a genuine gem, and I do not say that often" - all 13 validation branches now have a verbatim-message test. TestRenderChart passes.

Contested CRF-9 (listenerTLS behind ingress/httproute): the panel agrees unanimously with the author that a hard validate reject would be wrong, because backend-TLS to the HTTPS listener is legitimate for controllers that re-originate TLS and the chart cannot know the controller's annotation dialect. Kurapika confirmed it fails closed, so there is no security exposure. Five reviewers accept the new README section as a sufficient ceiling. Two (Pariston, Leorio) re-raised a cheap residual: the docs teach the fix but never name the symptom (a 502 / TLS handshake error), and there is no install-time signal even though NOTES.txt already computes the exact condition. Kept open at P3 as a non-blocking doc/UX ask, not a request for validation. See the reply on that thread.

Severity count this round: 2 P3, 1 P4, 4 Nit (all new; no regressions of prior fixes). Two are follow-on consequences of round-1 fixes rather than the original issues re-opening (CRF-27 is the sibling of CRF-7; CRF-28 is guidance that can undo CRF-4).

Acknowledged as intentional by the author and accepted: CRF-18 (metrics listener always-on, matches sibling charts) and CRF-22 (readiness coupled to the coderd DRPC connection).

Process notes:

  • The CI title check is red (✗ title). The current PR title parses clean against the conventional-commit validator, so this may be a stale run after the "heml" -> "Helm" rename, but reviewers could not read the failing run (no GitHub credentials in the worktree). Please confirm it is green before merge rather than assume the rename cleared it; a failing check is a bug until proven stale.
  • The branch commits still read feat: add heml chart for standalone AI Gateway and agentic review 1. The PR title is corrected, so a squash merge lands a clean subject and this is cosmetic, but if the branch is rebase- or merge-committed the "heml" typo reaches main history. Squash, or reword both subjects.

🤖 This review was automatically generated with Coder Agents.

Comment thread helm/ai-gateway/templates/_helpers.tpl Outdated
Comment thread helm/ai-gateway/values.yaml Outdated
Comment thread helm/ai-gateway/templates/_aigateway.tpl
Comment thread helm/ai-gateway/values.yaml Outdated
Comment thread helm/ai-gateway/values.yaml
Comment thread helm/ai-gateway/README.md Outdated
Comment thread helm/ai-gateway/templates/_aigateway.tpl Outdated
@pawbana
pawbana force-pushed the pawel/aigov-318-create-helm-chart-for-standalone-ai-gateway branch from 2f1347a to 022bf63 Compare July 16, 2026 09:41
@pawbana

pawbana commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Round 3 review is blocked on one unaddressed finding, so the panel did not run this round.

The rest of the round looks good: seven findings from round 2 received targeted fixes and per-thread replies (CRF-27 env/envFrom guard wording, CRF-28 probe-comment rewrite, CRF-29 livenessProbe golden coverage, CRF-30 secret-ref naming, CRF-31 grace-period comment, CRF-32 README --namespace, CRF-34 probe-template dedup). Those are queued for panel verification and will be checked on the next round.

Blocking item, needs a response before the panel re-engages:

CRF-9 (P3, listenerTLS behind ingress/httproute). In round 2 the panel agreed with you that a hard validate reject is wrong and accepted the README section as the right layer. Two reviewers left a small, concrete residual open: the README teaches the correct backend-TLS config but never names the failure symptom, so an operator debugging a 502 has nothing to search for. The ask was one sentence, for example: "If the entry point is not configured for backend TLS, it speaks plaintext HTTP to the HTTPS listener and every request fails with a TLS handshake error, typically surfaced as an HTTP 502." An install-time NOTES.txt hint was suggested as optional. This round's commit touches README.md but neither README.md nor NOTES.txt contains "502" or "handshake," and there is no reply on the thread; it was resolved without a code change or response. A resolved thread with no fix and no explanation is not a resolution.

To unblock, do one of: add the symptom sentence to the README TLS section; file a tracking issue and link it here; or reply explaining why it should not be done. Any of the three clears the block.

Transparency on our side: the round-2 re-raise was posted as a reply that tried to reopen the thread, but our bot token lacks the permission to unresolve threads (the API rejected it), so the thread stayed marked resolved and the residual was easy to miss. That is on us. The finding itself still stands.

🤖 This review was automatically generated with Coder Agents.

@pawbana

pawbana commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

@pawbana
pawbana force-pushed the pawel/aigov-318-create-helm-chart-for-standalone-ai-gateway branch from 41c0f78 to e3686d1 Compare July 16, 2026 17:02

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Round 4 is in good shape. All eight fixes from rounds 2-3 (the seven that round 3's blocked panel never got to verify, plus the round-4 CRF-9 doc sentence) were independently checked against the current tree and confirmed real, structural fixes rather than symptom patches: the env guard now derives its owned-set from the rendered ownedEnv and documents the envFrom gap honestly, the probe comments no longer misdirect, the three probe blocks are collapsed into one coder-ai-gateway.probe template with golden coverage, the secret-ref naming is uniform, and the grace-period coupling is documented on both sides. TestRenderChart passes and Komugi re-forced the parallel-namespace schedule with no flake. Hisoka: "The seams I expected to split held under load. A worthy opponent."

Four new findings this round, severity count 1 P3, 2 Nit, 1 Note. The P3 is a pre-existing correctness gap the panel reached this round, not a regression. The two Nits are the tail of the round-2 namespace-flag fix (the sweep fixed two commands and missed two) and a comment-wording risk. None are blocking; this stays a COMMENT.

Komugi withdrew the round-2 CRF-35 note (goldens hardcoding 0.1.0 matches Chart.yaml and the sibling charts; not a defect). CRF-18 and CRF-22 remain accepted as intentional by the author.

🤖 This review was automatically generated with Coder Agents.

Comment thread helm/ai-gateway/templates/httproute.yaml
Comment thread helm/ai-gateway/README.md Outdated
Comment thread enterprise/cli/aigatewaystart.go Outdated
Comment thread helm/ai-gateway/templates/NOTES.txt
@pawbana
pawbana force-pushed the pawel/aigov-318-create-helm-chart-for-standalone-ai-gateway branch 4 times, most recently from 8249272 to 27e7f4c Compare July 20, 2026 12:54
@pawbana
pawbana marked this pull request as ready for review July 20, 2026 13:03
@pawbana
pawbana requested a review from johnstcn July 20, 2026 13:03
@coder-tasks

coder-tasks Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Documentation Check

This PR adds a new helm/ai-gateway chart that deploys the Coder AI Gateway as a standalone Kubernetes workload. This is a new, user-facing deployment method for a Premium (AI Governance) feature, and it isn't covered anywhere under docs/. Coder documents comparable Helm deployments (see the external provisioner chart in docs/admin/provisioners/index.md), so this warrants customer-facing docs.

The release/build wiring (release.yaml, tag-and-release.yaml, Makefile, helm/Makefile, scripts/helm.sh), golden-file tests, and the aigatewaystart.go comment are intentionally excluded (tooling/CI/test-only, no user-visible surface).

New Documentation Needed

  • docs/ai-coder/ai-gateway/ (new page, e.g. standalone-deployment.md) - Document deploying a standalone AI Gateway on Kubernetes via the helm/ai-gateway chart: prerequisites (AI Gateway key Secret), Coder connection via the in-cluster aigateway.coderService, listener/Coder TLS, networking (Service/Ingress/HTTPRoute), scaling (coder.replicaCount, resources, CODER_AI_GATEWAY_MAX_CONCURRENCY), and metrics (port 2112). Add the page to docs/manifest.json. Since AI Gateway is Premium, give the H1 a (Premium) suffix and set "state": ["premium"] on the manifest entry.

    ⚠️ Still no corresponding documentation found in this PR. Note: the aigateway.coderURL value option was removed in the latest commit; the Coder connection is now configured solely through the in-cluster aigateway.coderService.

Updates Needed

  • docs/ai-coder/ai-gateway/setup.md and docs/ai-coder/ai-gateway/index.md - Both state the Gateway "runs inside the Coder control plane (coderd), requiring no separate compute to deploy or scale." With the new standalone Helm mode this is no longer the only option; note and link the standalone deployment path.
  • docs/ai-coder/ai-gateway/ai-gateway-proxy/setup.md - The CODER_AI_GATEWAY_PROXY_TARGET section already describes forwarding to a non-embedded AI Gateway; link it to the new standalone deployment doc, and mention the private-CA trust requirement when the standalone listener uses TLS.

Automated review via Coder Agents

Comment thread helm/ai-gateway/tests/chart_test.go Outdated
Comment thread Makefile Outdated
Comment thread helm/ai-gateway/templates/_helpers.tpl Outdated
Comment on lines +19 to +46
{{- define "coder-ai-gateway.ownedEnv" -}}
- name: CODER_AI_GATEWAY_HTTP_ADDRESS
value: 0.0.0.0:4001
- name: CODER_AI_GATEWAY_KEY_FILE
value: /etc/coder/ai-gateway-auth/key
- name: CODER_URL
value: {{ include "coder-ai-gateway.coderURL" . | quote }}
- name: CODER_PROMETHEUS_ENABLE
value: "true"
- name: CODER_PROMETHEUS_ADDRESS
value: 0.0.0.0:2112
{{- if .Values.aigateway.listenerTLS.name }}
- name: CODER_AI_GATEWAY_TLS_CERT_FILE
value: /etc/coder/ai-gateway-listener/tls.crt
- name: CODER_AI_GATEWAY_TLS_KEY_FILE
value: /etc/coder/ai-gateway-listener/tls.key
{{- end }}
{{- if .Values.aigateway.coderTLS.caSecret.name }}
- name: CODER_CLIENT_TLS_CA_FILE
value: /etc/coder/coder-client-ca/ca.crt
{{- end }}
{{- if .Values.aigateway.coderTLS.clientSecret.name }}
- name: CODER_CLIENT_TLS_CERT_FILE
value: /etc/coder/coder-client-tls/tls.crt
- name: CODER_CLIENT_TLS_KEY_FILE
value: /etc/coder/coder-client-tls/tls.key
{{- end }}
{{- end -}}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why do we need to protect these environment variables like this? Is there absolutely no situation where a deployment administrator might want to override them in some way?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Maybe my assumption is wrong but I though knobs provided by chart would be more convenient to use. Having 2nd source of truth I think would be worse so either knobs are removed or env vars need to be set.
Most of the knobs are boilerplate around K8s secrets or address / port synchronization between pod / service.

CODER_AI_GATEWAY_TLS_CERT_FILE, CODER_AI_GATEWAY_TLS_KEY_FILE, CODER_CLIENT_TLS_CA_FILE, CODER_CLIENT_TLS_CERT_FILE, CODER_CLIENT_TLS_KEY_FILE -> configurable though aigateway.{listenerTLS, caSecret, clientSecret} options.
It helps by keeping mounting paths of secrets + flag / env var values in sync.

Similar CODER_AI_GATEWAY_KEY_FILE is managed by aigateway.keySecret although maybe there could be a use for setting CODER_AI_GATEWAY_KEY directly as env var instead of mounting a secret. I think mounting a secret is better / good practice so I though it would be ok to force it this way?

CODER_AI_GATEWAY_HTTP_ADDRESS and CODER_PROMETHEUS_ADDRESS are blocked so ports between binary / pod / services are in sync. Those are not configurable.

CODER_PROMETHEUS_ENABLE -> always enabled, not configurable maybe should be?

CODER_URL -> configurable by aigateway.coderURL or aigateway.coderService, maybe overengineered a bit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think mounting a secret is better / good practice so I though it would be ok to force it this way?

You're not wrong, but some orgs have different 'best practices'. A deployment admin might want to:

  • Change the interface or port
  • Change the paths of the various _FILEs
  • Disable prometheus entirely

My recommendation would be to just stick to ensuring that either _KEY xor _KEY_FILE are set (not both), but allow the user to override the others. CODER_URL is also probably fine to manage directly.

Comment thread helm/ai-gateway/tests/chart_test.go
@pawbana pawbana added experimental Changes that might not necessarily be merged, until its approved to proceed with. and removed experimental Changes that might not necessarily be merged, until its approved to proceed with. labels Jul 21, 2026
@pawbana
pawbana force-pushed the pawel/aigov-318-create-helm-chart-for-standalone-ai-gateway branch from 27e7f4c to 9f4f825 Compare July 21, 2026 17:12
@pawbana
pawbana force-pushed the pawel/aigov-318-create-helm-chart-for-standalone-ai-gateway branch from 9f4f825 to fe8af0a Compare July 22, 2026 11:11
@pawbana
pawbana force-pushed the pawel/aigov-318-create-helm-chart-for-standalone-ai-gateway branch from fe8af0a to 12ca765 Compare July 22, 2026 14:06
@pawbana
pawbana merged commit 8a3fb04 into main Jul 22, 2026
45 of 48 checks passed
@pawbana
pawbana deleted the pawel/aigov-318-create-helm-chart-for-standalone-ai-gateway branch July 22, 2026 15:42
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 22, 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.

2 participants