Review: Add kustomize overlay in pal-e-deployments (westside-streamlit #4)

review-935-2026-04-11 Review

review needs-refinement

Verdict: NEEDS_REFINEMENT

Post-incident revision is thorough on intent (migration sequencing, Keycloak separation, no funnel annotation) but introduces several file-path and convention mismatches against the existing pal-e-deployments layout that would force the dev agent to guess. Fix these in the body and this ticket is ready.

Template Completeness

  • [x] Type — Feature
  • [x] Lineage — story:reachable | arch:k8s-deploy | type:infra
  • [x] Repo — forgejo_admin/pal-e-deployments
  • [x] User Story — platform operator + migration retirement
  • [x] Context — current cluster state, relationship to Keycloak children
  • [x] File Targets — create + delete lists
  • [x] Acceptance Criteria — 12, all testable
  • [x] Test Expectations — kustomize build / dry-run / SOPS / reachability
  • [x] Constraints — funnel prohibition, migration coupling, no Lucas-bypass
  • [x] Checklist — present
  • [x] Related — #2, #5, #3, #7 children, incident note

Traceability

  • [x] story:reachable — present on board item
  • [x] story note verified — story-westside-streamlit-reachable exists, explicitly lists "Add kustomize overlay in pal-e-deployments" as supporting ticket #3
  • [x] arch:k8s-deploy — present on board item
  • [ ] arch note MISSING — no arch-k8s-deploy note in pal-e-docs. Platform-wide gap (same as #933 arch:ci-pipeline). Treat as waiver per review-933-2026-04-10 precedent — not a blocker unique to this ticket.
  • [x] Bonus — arch-deployment-westside-streamlit explicitly enumerates "Kustomize overlay in pal-e-deployments" as gap item #4
  • [x] Forgejo issue — https://forgejo.tail5b443a.ts.net/forgejo_admin/westside-streamlit/issues/4 (open)
  • [x] Incident linkage — incident-2026-04-10-pal-e-streamlit-public-funnel cross-referenced

File Targets

  • [ ] bases/westside-streamlit/kustomization.yaml — CONVENTION MISMATCH. Every existing service (basketball-api, pal-e-docs, mcd-tracker, twitch-2k-wager, westside-ai-assistant, westsidekingsandqueens, gcal-scheduler, pal-e-production, platform-validation, pal-e-mail) uses the shared bases/standard base with per-overlay kustomize patches that rename the generic app Deployment/Service. Only bases/standard and bases/servicemonitor exist today. Inventing a per-service base for westside-streamlit is a new pattern.
  • [ ] bases/westside-streamlit/deployment.yaml — same convention mismatch. See overlays/basketball-api/prod/kustomization.yaml for the patch-the-shared-base pattern.
  • [ ] bases/westside-streamlit/service.yaml — same.
  • [ ] overlays/westside-streamlit/kustomization.yaml — DIRECTORY STRUCTURE MISMATCH. All existing overlays use overlays/{service}/prod/ (or dev/) subdirectory. Ticket specifies a flat overlays/westside-streamlit/. ArgoCD Application paths will break if this convention is broken.
  • [ ] overlays/westside-streamlit/namespace.yaml — same structure mismatch. Also, base Deployment in bases/standard/deployment.yaml already handles namespace via overlay kustomization; confirm namespace.yaml is needed at all.
  • [x] overlays/westside-streamlit/secret.enc.yaml — SOPS encrypted Secret is a valid pattern (used by all services; typically named harbor-creds.enc.yaml for Harbor creds — this one is app secret, name is fine).
  • [ ] overlays/westside-streamlit/networkpolicy.yaml — PATH AMBIGUITY. bases/standard/networkpolicy.yaml already exists with default ingress rules (from tailscale + monitoring namespaces). A per-overlay networkpolicy.yaml would add a second NetworkPolicy in parallel, not patch the base. If the intent is egress to postgres + kube-dns, that's a new policy (valid) — ticket should clarify it's additive to the base, not a replacement.
  • [x] overlays/westside-streamlit/ingress.yaml — no funnel annotation, tailnet-private. Correct. Supersedes orphan at overlays/pal-e-streamlit/dev/ingress.yaml.
  • [x] overlays/pal-e-streamlit/ DELETE — verified: this directory contains 5 files, only dev/ingress.yaml is tracked in git (committed via PR #109 at commit 693721c). The other 4 files are untracked locally. Deletion in the same PR is clean.
  • [ ] ArgoCD Application file — UNKNOWN LOCATION. Ticket says "check existing services — likely argocd-apps/ or per-service application.yaml." Verified: neither exists in pal-e-deployments. No argocd-apps/ directory, no application.yaml files anywhere. ArgoCD Applications are declared externally (likely pal-e-platform tofu or managed via ArgoCD UI). Dev agent will get stuck here without clarification.

Repo Placement

OK. All changes live in forgejo_admin/pal-e-deployments. Cluster-side cleanup is documented in PR body, not a repo change.

Dependencies

  • Upstream satisfied: #2 Dockerfile merged (image exists), #5 Postgres role merged (credentials exist).
  • Downstream blocked by this ticket: #3 Woodpecker CI (needs overlay kustomization.yaml to image-update), #10/#11/#12 Keycloak children (additive to this Deployment), #6 Tailscale funnel (uses this hostname once Keycloak lands).
  • Not blocked by anything in progress.
  • Keycloak child sequencing is explicitly enumerated in ticket body — good.

Acceptance Criteria

Strong. All 12 AC are programmatically verifiable: kustomize build exit 0, ArgoCD namespace creation, probe rollout, in-cluster postgres reachability + default-deny test, _stcore/health 200, SOPS decrypt, tailnet-private resolvability, public blocked at edge, orphan directory deleted, ArgoCD app Synced+Healthy, PR body documents manual cleanup, no funnel annotation. The only soft criterion is the ArgoCD Application check — hard to verify when the file location is undefined.

Blast Radius

  • Migration risk: medium. Deleting the orphan in the same PR is safe — no ArgoCD app currently watches overlays/pal-e-streamlit/, so the delete is a pure file-tree cleanup. Live cluster is untouched until Lucas runs kubectl delete namespace pal-e-streamlit manually post-merge.
  • Hostname conflict: flag — ticket uses westside-streamlit.tail5b443a.ts.net but story-westside-streamlit-reachable AC and arch-deployment-westside-streamlit target diagram both say westside-ops.tail5b443a.ts.net. The incident postmortem action items list "Rename pal-e-streamlit → westside-streamlit (namespace + hostname + local dir + overlay path)" supporting westside-streamlit — but story/arch say westside-ops. Reconcile before #6 funnel ticket lands.
  • Harbor project naming: per feedback_harbor_project_naming, Harbor projects derive from image_repo prefix. Ticket specifies harbor.tail5b443a.ts.net/westside/westside-streamlit:latest. Agent should verify the westside Harbor project exists before the kustomize build is valid at runtime.
  • Similar-pattern check: no other service has the per-service-base structure this ticket proposes, so convention drift is localized.

Decomposition Assessment

  • Discrete file changes: 8 creates + 1 directory delete + 1 ArgoCD Application = ~10 discrete changes.
  • File count: ~10 files, 1 repo — above 3-file threshold but all in one directory tree.
  • Acceptance criteria: 12 — above 5-AC threshold.
  • Estimated agent time: 10–15 minutes if conventions are clarified, longer if not.
  • Parallelizable subtasks: no — all manifests are tightly coupled for one service landing.
Borderline — at the upper edge of the five-minute rule. No decomposition recommended if the convention ambiguities are resolved in the body; if the agent has to guess at base vs patch pattern or ArgoCD Application location, it will stall. Keep as a single ticket but refine body.

Recommendation

  • [BODY] Clarify base pattern — either (a) change file targets to use bases/standard with per-overlay rename patches (matching every other service), OR (b) justify in the ticket body why westside-streamlit needs its own base. Current body is ambiguous and would force the agent to invent a new convention.
  • [BODY] Fix overlay directory structure — change overlays/westside-streamlit/ to overlays/westside-streamlit/prod/ (or /dev/) to match the existing convention across all 11 services.
  • [BODY] Resolve hostname discrepancy — ticket says westside-streamlit.tail5b443a.ts.net, story + arch note say westside-ops.tail5b443a.ts.net. Pick one and update the losing document.
  • [BODY] Clarify ArgoCD Application location — no argocd-apps/ directory and no application.yaml files exist in pal-e-deployments. Either (a) confirm Applications are managed elsewhere (pal-e-platform tofu or UI) and remove the file-target from this ticket (track as follow-up in that other repo), OR (b) specify the new path here and accept that this ticket is the first to establish the convention.
  • [BODY] Clarify networkpolicy intent — specify whether the per-overlay policy is additive (egress rules) on top of the base ingress policy, or a replacement. Recommend additive.
  • [SCOPE] Create architecture note arch-k8s-deploy — platform-wide gap, same as arch-ci-pipeline in #933. Waived for this ticket per #933 precedent.
  • Migration sequencing, Keycloak separation, and funnel prohibition are all handled correctly in the current body — no action on those.