Review: Service onboarding: playme2k funnel + kustomize

review-788-2026-04-03 Doc

review needs-refinement

Verdict: NEEDS_REFINEMENT

Template Completeness

  • [x] Type -- Feature
  • [x] Lineage -- Standalone
  • [x] Repo -- forgejo_admin/pal-e-deployments
  • [x] User Story -- clear "As a Twitch viewer I want the site publicly accessible"
  • [x] Context -- sufficient background on service onboarding pattern
  • [x] File Targets -- present but inaccurate (see below)
  • [x] Acceptance Criteria -- 5 testable criteria
  • [x] Test Expectations -- curl health check + Stripe webhook test
  • [x] Constraints -- references service-onboarding-sop, CNPG, Tailscale
  • [x] Checklist -- present
  • [x] Related -- references project page, arch note, SOP

Traceability

  • [x] story:challenger-auth label -- "Sign in with 1 click from stream link"
  • [x] story note verified -- challenger-auth listed in project-twitch-2k-wager user-stories table
  • [x] arch:tailscale-funnel label -- present on board item
  • [ ] arch note MISSING -- [SCOPE] No arch-tailscale-funnel note exists in pal-e-docs. The issue's Related section references arch-deployment-twitch-2k-wager which also does not exist. The arch label and the referenced note name are mismatched. Recommend creating arch-deployment-twitch-2k-wager and updating board item label to arch:deployment-twitch-2k-wager.
  • [x] Forgejo issue -- forgejo_admin/twitch-2k-wager#3, open

File Targets

  • [ ] twitch-2k-wager/kustomization.yaml -- ISSUE: Wrong path. Established pattern is overlays/twitch-2k-wager/prod/kustomization.yaml. All 10+ existing services use overlays/{service}/prod/ with a base reference to ../../../bases/standard.
  • [ ] twitch-2k-wager/deployment.yaml -- ISSUE: Standard pattern does NOT use standalone deployment.yaml. Base template (bases/standard/deployment.yaml) is inherited via kustomize. Overlays use deployment-patch.yaml for container name, port, and env overrides.
  • [ ] twitch-2k-wager/service.yaml -- ISSUE: Same as above. Base service is inherited. Overlay patches rename and set port via JSON patches in kustomization.yaml.
  • [ ] twitch-2k-wager/namespace.yaml -- ISSUE: Namespaces are created by pal-e-services terraform (kubernetes_namespace_v1.service), not by kustomize overlays. No existing overlay contains a namespace.yaml.
  • [ ] twitch-2k-wager/cnpg-cluster.yaml -- ISSUE: CNPG clusters are managed in pal-e-services terraform (cnpg.tf), not in pal-e-deployments overlays. No existing overlay contains a CNPG resource.
  • [ ] twitch-2k-wager/secrets.yaml -- ISSUE: Harbor image pull secrets are managed by pal-e-services terraform. Application secrets (Stripe/Twitch) need SOPS-encrypted yaml (like harbor-creds.enc.yaml in westside overlay), but the issue doesn't mention SOPS.
  • [ ] Tailscale funnel config -- ISSUE: Ambiguous. Funnels are either terraform-managed (funnel = true in pal-e-services) or overlay-managed via ingress.yaml (funnel = false). The desired hostname playme2k differs from the likely service key twitch-2k-wager. Needs explicit decision.
Assessed: file targets are NOT specific enough for an agent. Every listed path is wrong or belongs in a different repo.

Repo Placement

ISSUE: Ticket targets only forgejo_admin/pal-e-deployments, but the actual service onboarding pattern requires changes in TWO repos:
  • pal-e-services (terraform/k3s.tfvars) -- Add service entry to services map. This creates Harbor project, robot accounts, namespace, ArgoCD application, and optionally the Tailscale funnel. Potentially add CNPG cluster to cnpg.tf.
  • pal-e-deployments (overlays/twitch-2k-wager/prod/) -- Kustomize overlay: kustomization.yaml, deployment-patch.yaml, ingress.yaml (if funnel=false), harbor-creds.enc.yaml.
This is a multi-repo ticket. The pal-e-services changes must be applied (tofu apply) before ArgoCD can sync the pal-e-deployments overlay.

Dependencies

  • [x] CNPG operator -- satisfied (already deployed per Constraints section)
  • [ ] pal-e-services tofu apply -- PENDING: service entry must be created and applied before ArgoCD can sync. Not documented in the ticket.
  • [ ] Harbor project -- PENDING: created by pal-e-services tofu apply. Required before first image push.
  • [ ] App image -- PENDING: no app code exists yet (repo is empty). The overlay can be created but ArgoCD sync will fail until an image is pushed.
  • [ ] Stripe/Twitch credentials -- PENDING: no secrets exist yet. AC #4 ("secrets mounted") cannot pass until credentials are provisioned.
Multiple unresolved dependencies not documented in the issue scope.

Acceptance Criteria

  • "playme2k.tail5b443a.ts.net resolves and serves HTTPS" -- testable via curl, but depends on app image existing
  • "ArgoCD syncs the deployment" -- verifiable via argocd CLI, but sync will fail without an image
  • "CNPG Postgres cluster running" -- verifiable via kubectl, but unclear if CNPG is in this ticket's scope or separate
  • "Stripe and Twitch secrets mounted" -- UNCLEAR: does this ticket create the secrets or just the mount points?
  • "Webhook endpoint reachable" -- depends on app being deployed with working routes
Several AC depend on work outside this ticket's stated scope (app code, credentials). An agent cannot verify these criteria after implementation of just the infra.

Blast Radius

Low risk. New overlay and new service entry -- no changes to existing services. Standard pattern established across 10+ services. Only concern: hostname decision (playme2k vs twitch-2k-wager) affects DNS and TLS. Rollback is straightforward (remove service entry + overlay).

Decomposition Assessment

Apply three-thing limit and five-minute rule:
  • Touches 2 repos (pal-e-services + pal-e-deployments) with sequential dependency (tofu apply before ArgoCD sync)
  • 5 acceptance criteria, several untestable without app code
  • File targets span infrastructure (terraform) and deployment (kustomize) -- distinct concerns
  • Estimated agent work: borderline. The pal-e-services tfvars addition is ~10 lines and the overlay is a template copy. A single agent COULD do both sequentially in ~5 minutes IF the ticket is correctly scoped with accurate file targets.
Recommendation: Fix file targets and repo placement first. After refinement, reassess whether decomposition is needed. The sequential tofu-apply dependency suggests two tickets may be cleaner, but it's not strictly required.

Recommendation

  • [BODY] Fix all file paths from twitch-2k-wager/X to overlays/twitch-2k-wager/prod/X. Replace standalone deployment.yaml, service.yaml, namespace.yaml with the actual kustomize pattern: kustomization.yaml, deployment-patch.yaml, ingress.yaml, harbor-creds.enc.yaml.
  • [BODY] Remove namespace.yaml from file targets -- namespaces are created by pal-e-services terraform.
  • [BODY] Move CNPG scope to pal-e-services file targets (terraform/cnpg.tf) or split to a separate ticket.
  • [BODY] Add pal-e-services file targets: terraform/k3s.tfvars (service entry) and optionally terraform/cnpg.tf.
  • [BODY] Clarify funnel strategy: terraform-managed (funnel = true, service key = playme2k) vs overlay-managed (funnel = false, custom ingress.yaml with TLS host playme2k). Document the hostname decision.
  • [BODY] Clarify secrets strategy: SOPS-encrypted yaml or deferred to a separate ticket?
  • [BODY] Narrow AC to what this infra ticket can actually verify (overlay exists, ArgoCD app created, namespace exists) vs what requires app code.
  • [LABEL] Change arch:tailscale-funnel to arch:deployment-twitch-2k-wager to match the referenced architecture component.
  • [SCOPE] Create architecture note arch-deployment-twitch-2k-wager for the deployment component.
  • [SCOPE] Create service-onboarding-sop note in pal-e-docs (referenced in Constraints but does not exist).