Review: Create ISS staging environment with auto-deploy on merge to main
Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] Type -- Feature
- [x] Lineage -- references #192 and #194
- [x] Repo -- ldraney/pal-e-services
- [x] User Story -- As a developer / staging auto-deploy / verify before prod
- [x] Context -- explains current risk (auto-deploy to prod), staging rationale
- [x] File Targets -- 4 targets across 2 repos + DNS
- [x] Feature Flag -- none (appropriate for infra work)
- [x] Acceptance Criteria -- 7 items
- [x] Test Expectations -- 4 items with run command
- [x] Constraints -- 4 constraints
- [x] Checklist -- standard PR gates
- [x] Related -- project-iss, #192, #194
- [x] Dependency Chain -- bonus section, well-documented
- [x] Keycloak -- bonus section, clear instructions
Traceability
- [x] story:dev-environment label -- verified in project-iss user-stories section (row: "dev-environment", backing "#192 / #193 / #194 + docs/pipeline.md")
- [x] story note verified -- found in project-iss user-stories table
- [x] arch:argocd label -- references ArgoCD deployment pattern
- [x] arch note verified -- arch-argocd note exists in pal-e-docs (slug: arch-argocd, "ArgoCD + Image Updater Deployment Pattern")
- [x] Forgejo issue -- ldraney/pal-e-services#193, open
File Targets
- [x]
terraform/k3s.tfvars.example(pal-e-services) -- verified: containsservicesmap (line 517, existing ISS entry) andservice_databasesmap (line 551, existingissentry). Agent needs to add staging service entry and staging database entry. - [x]
terraform/keycloak.tf(pal-e-services) -- verified: usesfor_each = var.keycloak_clients. Issue correctly says "no structural changes needed" -- Keycloak client URIs are managed in k3s.tfvars, not keycloak.tf. - [x]
terraform/databases.tf(pal-e-services) -- verified: usesfor_each = var.service_databases. Issue correctly says "no structural changes needed". - [x]
overlays/intelligentstaffingsystems/staging/(pal-e-deployments) -- verified: does not exist yet (expected, to be created). Prod overlay exists atoverlays/intelligentstaffingsystems/prod/with kustomization.yaml, deployment-patch.yaml, secrets.enc.yaml, README.md -- staging should mirror this structure. - [ ] DNS -- ISSUE: Issue says "add A record via DNS provider (GoDaddy)" but DNS records are terraform-managed in
pal-e-platform/terraform/dns.tf. Existing pattern:godaddy_dns_record.iss_dev(line 64) uses a CNAME pointing tointelligentstaffingsystems.ai, not an A record. Staging should follow the same CNAME pattern. This is a 3rd repo not listed in File Targets. - [ ] Caddy reverse proxy -- MISSING: The custom domain routing path (per arch-argocd) requires Caddy on the Hetzner edge VPS to proxy
staging.intelligentstaffingsystems.aitointelligentstaffingsystems-staging.tail5b443a.ts.net. Caddy is managed by SaltStack (hetzner-edge module usessalt_master_ip). The issue does not mention Caddy/Salt configuration. Without this, DNS alone will not route traffic to staging.
Repo Placement
Issue is filed on
pal-e-services. Work actually spans 3 repos:pal-e-services-- terraform k3s.tfvars (service entry, database entry, Keycloak client URIs)pal-e-deployments-- staging overlay (acknowledged in issue)pal-e-platform-- DNS record in dns.tf + Caddy/Salt config (NOT acknowledged in issue)
The issue does not clarify whether the agent should create PRs in all 3 repos or how cross-repo coordination works.
Dependencies
- #192 (dev environment, board item 1892) -- backlog, independent. Confirmed parallel.
- #194 (prod manual promotion, board item 1894) -- backlog, blocked by this ticket. Confirmed: both open.
- No in-progress blockers found on board-iss.
- Dependency chain is well-documented in the issue body.
Acceptance Criteria
7 ACs, all verifiable by an agent:
- AC1 (namespace) --
kubectl get ns intelligentstaffingsystems-staging - AC2 (ArgoCD synced) --
argocd app get intelligentstaffingsystems-staging - AC3 (image updater) -- check annotations on ArgoCD application CR
- AC4 (staging URL) --
curl -sI https://staging.intelligentstaffingsystems.ai - AC5 (databases) -- kubectl or psql verification
- AC6 (Keycloak) -- verify redirect URIs via Keycloak admin API
- AC7 (DNS) --
dig staging.intelligentstaffingsystems.ai
All criteria are testable. AC4 depends on Caddy/Salt configuration which is not scoped in the issue (see File Targets issues).
Blast Radius
- var.services addition: Low risk. New entry follows arch-argocd's var.services pattern (7 resources via for_each). Does not modify existing services.
- Keycloak client URIs: Medium risk. Adding staging redirect URIs to the shared
intelligentstaffingsystemsclient. Misconfiguration could affect prod/dev auth flows. However, the pattern matches the existing dev URIs already added. - Image updater overlap: During the gap between #193 (this) and #194 (prod manual promotion), BOTH staging and prod will auto-deploy on new images. This is documented and expected but worth noting -- any broken merge to main hits prod immediately during this period.
- Network policies: pal-e-platform's
network-policies.tfhas explicit entries for theintelligentstaffingsystemsnamespace. The newintelligentstaffingsystems-stagingnamespace may need its own network policy entries. Not mentioned in the issue. - Stale image_repo in k3s.tfvars.example: The example file says
image_repo = "intelligentstaffingsystems/intelligentstaffingsystems"(line 519), but the production overlay referencesharbor.tail5b443a.ts.net/intelligentstaffingsystems/app. Per the "Image Repo Mismatch Fix" memory note, the actual k3s.tfvars was fixed tointelligentstaffingsystems/app. The issue's constraint perpetuates the stale value. The agent must use the correct value (intelligentstaffingsystems/app) for staging.
Decomposition Assessment
File targets: 4+ files across 3 repos (pal-e-services + pal-e-deployments + pal-e-platform). ACs: 7 (exceeds threshold of 5). Estimated time: 5-10 minutes for an experienced agent. Per user preference (memory: "No Decomposition"), no decomposition recommended. The work is cohesive -- it follows the arch-argocd "Onboarding a New Service" pattern, and splitting it would create coordination overhead. A single agent with platform knowledge can execute this as one unit.
Recommendations
[BODY]Fix image_repo reference in Constraints section:intelligentstaffingsystems/intelligentstaffingsystemsshould beintelligentstaffingsystems/app(matches prod overlay and image repo mismatch fix). Also update k3s.tfvars.example line 519 to reflect the actual value.[BODY]Fix DNS file target: DNS is terraform-managed inpal-e-platform/terraform/dns.tf, not added manually via GoDaddy. Addpal-e-platform/terraform/dns.tfto File Targets. Follow the existing CNAME pattern (cf.godaddy_dns_record.iss_devat line 64) rather than an A record.[BODY]Add Caddy/Salt configuration to scope:staging.intelligentstaffingsystems.aineeds a Caddy reverse proxy entry on the Hetzner edge VPS to route tointelligentstaffingsystems-staging.tail5b443a.ts.net. This is managed by SaltStack. Without it, AC4 (staging URL serves app) will fail. Document whether this is handled in this ticket or a separate one.[BODY]Clarify cross-repo PR strategy: Work spans pal-e-services, pal-e-deployments, and pal-e-platform. State whether the agent should create PRs in all repos, and specify the order of operations (e.g., pal-e-services terraform first, then pal-e-deployments overlay, then pal-e-platform DNS).