Review: S1 — pal-e-services: add westside-streamlit to var.services
Verdict: NEEDS_REFINEMENT
Board item
#1069 · Forgejo issue forgejo_admin/pal-e-services#60 · Reviewer: Dottie · Date: 2026-04-22Template Completeness
- [x] Type — Feature
- [x] Lineage — explicit (audit-discovered, links siblings + supersession)
- [x] Repo —
forgejo_admin/pal-e-services - [x] User Story — well-formed As/I want/So that
- [x] Context — substrate audit summary, schema verified, hostname declared
- [x] File Targets — files to modify and NOT to touch both listed
- [x] Acceptance Criteria — 7 items
- [x] Test Expectations — fmt/validate/plan with explicit run commands
- [x] Constraints — present
- [x] Checklist — present
- [x] Related — present
Traceability
- [x]
story:reachablelabel — Dashboard Reachable from Phone - [x] story note verified —
story-westside-streamlit-reachableexists at id 1401 - [x]
arch:services-tflabel present - [ ] arch note MISSING — no
arch-services-tfnote in pal-e-docs (search returned no results). Theproject-westside-streamlitArchitecture section listsarch-domain-westside-streamlit,arch-dataflow-westside-streamlit,arch-deployment-westside-streamlit,arch-ci-pipeline— but nothing for theservices-tfcomponent. [SCOPE] Create architecture notearch-services-tfdocumenting thevar.servicesfan-out pattern (Harbor project + robot accounts + Harbor creds + namespace + ArgoCD app + optional funnel). This pattern serves the entire platform, not just westside-streamlit, so the note belongs at platform scope, not project scope. - [x] Forgejo issue — #60 open, body well-structured
File Targets
- [x]
~/pal-e-services/terraform/k3s.tfvars— verified, exists, contains theservicesmap block. Confirmedwestside-streamlitkey is NOT yet present (no false-positive), so the change is correctly scoped as additive. - [x]
~/pal-e-services/terraform/variables.tf— verified, schema (lines 165-177) supports optionalsource_repo+source_pathfor kustomize overlays. Required fields:forgejo_repo,image_repo,port,funnel. Optional:target_revision,source_repo,source_path. Issue's "no schema extension needed" claim is correct. - [x]
~/pal-e-services/terraform/services.tf— verified, fans out viafor_each = var.servicesacrossharbor_project.service,harbor_robot_account.service_ci,harbor_robot_account.service_pull,kubernetes_namespace_v1.service,kubernetes_secret_v1.harbor_creds,argocd_application.service. AC plan-output checks match the resource names exactly. - [x] Overlay path —
~/pal-e-deployments/overlays/westside-streamlit/prod/verified (6 files: namespace, kustomization, ingress, secret.enc, harbor-creds.enc, deployment-patch). Namespace name innamespace.yaml=westside-streamlit✓ matches AC. - [!] Issue body says: "Reference the shape used by an existing kustomize-overlay service (e.g.
westside-contracts,pal-e-dora-exporter)." — BOTH OF THESE REFERENCE SERVICES DO NOT EXIST in~/pal-e-services/terraform/k3s.tfvars.grep westside-contracts ~/pal-e-services/terraform/k3s.tfvarsreturns zero hits; same forpal-e-dora-exporter. A dev grepping for the suggested examples will waste time. Existing kustomize-overlay services in k3s.tfvars:platform-validation,basketball-api,pal-e-docs,westsidekingsandqueens,pal-e-app,gcal-scheduler,mcd-tracker,mcd-tracker-app,pal-e-mail,westside-ai-assistant,playme2k. [BODY] Replace the example list with services that actually exist — recommendbasketball-api(close shape: same file lives in pal-e-deployments overlay, image_repo prefix matches service key) ANDpal-e-mail(matches thefunnel = falsepattern this ticket needs, see next finding).
Repo Placement
OK. Issue is correctly filed on
forgejo_admin/pal-e-services. Single-repo change, no cross-repo concerns.Dependencies
Documented:
- Lineage block calls out sibling
pal-e-services#61(Keycloak client) and notes thatwestside-streamlit#3/#6 are blocked by this ticket. - Lineage notes that
westside-streamlit#10was closed-but-incomplete and is superseded by sibling #61. Verified by reading #61 body.
Board state cross-check (board-westside-streamlit):
- #1069 (this ticket, S1) and #1070 (S2/Keycloak) both in
backlog. - #1071 (C1 Monthly), #1073 (C3 Tournament, blocked by C2), #1074 (O1 Marcus onboarding), #1072 (C2 migration 048) all in
backlog. - QA column has #960 (Keycloak client #10), #961 (streamlit-keycloak in-app), #933 (CI pipeline #2), #936 (Postgres role #5), #935 (k8s deploy #4) — none of these are blocking this ticket.
- #938 (Tailscale funnel #7) and #962 (#12 secret/env) in
next_up— the ticket does not block on these.
Recommendation: dependencies are correctly mapped; no missing blockers.
Acceptance Criteria
7 criteria, all individually verifiable. Notes:
- AC1 (key =
westside-streamlit) — verifiable viagrep - AC2 (
image_repoprefix) — verifiable via diff and Harbor project name post-apply - AC3 (
source_path = "overlays/westside-streamlit/prod") — pre-verified, directory exists - AC4 (5 specific resource creates) — exact match to
services.tfresource names; agent can grep plan output - AC5 (ArgoCD targets namespace
westside-streamlit) — guaranteed bydestination.namespace = each.keyin services.tf line 155 - AC6 (namespace creates cleanly or no-ops) — handles the pre-existing-namespace edge case correctly
- AC7 (no
tofu apply) — explicit Lucas-applies-after-merge gate
Missing AC — see Blast Radius / Decomposition for required additions.
Blast Radius
Critical risk: funnel collision. The kustomize overlay at
~/pal-e-deployments/overlays/westside-streamlit/prod/ingress.yaml already declares its own Tailscale ingress:
If the new tfvars entry sets
funnel = true, kubernetes_ingress_v1.service_funnel["westside-streamlit"] in services.tf (line 177) will create a SECOND westside-streamlit-funnel ingress in the same namespace. Both will register with Tailscale; only one will win the funnel hostname; the loser becomes a dead address. The comment block right above kubernetes_ingress_v1.service_funnel (services.tf:171-175) explicitly warns about this pattern — it's the exact lesson learned from westside-landing-funnel.The issue's File Targets section says "Copy the shape from an existing kustomize-overlay service entry verbatim" — but most kustomize-overlay services in k3s.tfvars use
funnel = true (e.g. basketball-api, pal-e-docs, pal-e-app, gcal-scheduler, mcd-tracker, mcd-tracker-app, westside-ai-assistant, playme2k, platform-validation). Only westsidekingsandqueens and pal-e-mail use funnel = false. A literal "copy verbatim" instruction will likely select the wrong template. [BODY] Add an explicit AC: "funnel = false — the kustomize overlay at overlays/westside-streamlit/prod/ingress.yaml already manages the Tailscale ingress; a Terraform-managed funnel would create a duplicate ingress and cause the same dead-address class of bug warned about in services.tf:171-175."Secondary risk:
forgejo_repo field omission. The schema requires forgejo_repo (line 168 of variables.tf, no default). The issue's AC list does not name it. A dev who copies westsidekingsandqueens verbatim will end up with forgejo_repo = "forgejo_admin/westside-app" — wrong. The correct value is forgejo_admin/westside-streamlit. [BODY] Add to AC: "forgejo_repo = "forgejo_admin/westside-streamlit" (the source repo for ArgoCD Image Updater write-back; distinct from source_repo which points to pal-e-deployments)."Tertiary risk:
port field. The funnel block uses each.value.port as the upstream port. With funnel = false this is harmless (the funnel resource is gated if v.funnel), so any sane number works. Recommend documenting port = 80 to match the overlay's Service port (overlay maps port: 80 → targetPort: 8501 in kustomization.yaml lines 47-51). Not a hard blocker since funnel = false short-circuits the field, but it pre-empts a future toggle bug.Pattern-similar bugs to consider: Per
feedback_harbor_project_naming, the image_repo prefix and service key MUST match exactly to avoid the 36-hour-outage class of bug. AC2 enforces this. ✓Decomposition Assessment
5-minute rule: 1 file, 1 repo, ~10 lines added to k3s.tfvars, 7 ACs. Well within a single agent pass. No decomposition needed.
Recommendation
Three findings; two are body-fix, one is scope. None are
BLOCK-class.- [BODY] Replace the non-existent reference services in File Targets (
westside-contracts,pal-e-dora-exporter) with services that actually exist in k3s.tfvars. Suggested:basketball-apifor the kustomize-overlay shape andpal-e-mailfor thefunnel = falseprecedent. Without this, a dev grepping for the suggested examples wastes time and may copy a wrong-shape template. - [BODY] Add explicit AC:
funnel = falsewith a one-line reason citing the existing overlay-managed ingress and theservices.tf:171-175warning. This is the highest-impact fix — without it the dev is one mis-copy away from a dead-ingress incident. - [BODY] Add explicit AC:
forgejo_repo = "forgejo_admin/westside-streamlit"so a verbatim copy fromwestsidekingsandqueensdoesn't carry the wrong source repo through. - [SCOPE] Create architecture note
arch-services-tfat platform scope documenting thevar.servicesfan-out pattern (label-traceability requirement; the labelarch:services-tfcurrently points to nothing). Lower urgency than the body fixes — the ticket can advance once the body is fixed; the arch note can be filed as a sibling story-tracking ticket.
After the three [BODY] fixes land via
skill-refine-ticket, this ticket is APPROVED for advance to todo.