Review: Wire up palinks.app custom domain via Hetzner edge proxy

review-1392-2026-06-13 Review

review needs-refinement

Verdict: NEEDS_REFINEMENT

Template Completeness

  • [x] Type
  • [x] Lineage
  • [x] Repo
  • [x] User Story
  • [x] Context
  • [x] File Targets
  • [x] Feature Flag
  • [x] Acceptance Criteria
  • [x] Test Expectations
  • [x] Constraints
  • [x] Checklist
  • [x] Related
All required sections for template-issue-feature are present. Template is complete.

Traceability

  • [x] story:custom-domain label -- "Route palinks.app to production"
  • [x] story note verified -- found in project-palinks user-stories section
  • [x] arch:palinks label -- palinks architecture component
  • [x] arch note verified -- arch-palinks note exists in pal-e-docs (doc type, active)
  • [x] Forgejo issue -- ldraney/palinks#28, state: open
All three traceability legs are satisfied.

File Targets

  • [x] GoDaddy DNS (A records) -- manual/API, correctly specified (palinks.app and www.palinks.app to 178.156.129.142)
  • [ ] pal-e-platform Caddy config -- ISSUE: no specific file path given, just "Add palinks.app site block to Caddy config on edge-proxy." The agent needs a concrete path (e.g., salt/edge-proxy/caddy/Caddyfile or equivalent) to know where to make changes.
  • [x] config/environments/production.rb -- verified: file exists, config.hosts is currently commented out (lines 63-66). The file also references palinks-dev host allowlisting in the recent commit history. Note: the issue says config.hosts but the current pattern in development.rb uses config.hosts << (append), not assignment. The agent should follow the existing pattern.
  • [x] docs/custom-domain.md -- verified: file exists with "Remaining Work" section (5 items). Marking complete is straightforward.
  • [ ] pal-e-services Keycloak -- ISSUE: no specific file path or Keycloak admin procedure specified. "Add https://palinks.app/* to Keycloak client redirect URIs" is an admin task, not a code change. How is this done -- Terraform, Keycloak admin UI, or a config file?

Repo Placement

Issue is filed on ldraney/palinks but correctly declares Multi-repo scope. Touches:
  • ldraney/palinks -- Rails host config + docs (code changes)
  • ldraney/pal-e-platform -- Caddy/Salt config (code changes)
  • pal-e-services -- Keycloak redirect URIs (admin/config)
  • GoDaddy DNS -- A records (manual)
This is 4 distinct systems. A single Forgejo issue across this many repos is problematic for agent execution -- an agent cloned into palinks cannot modify pal-e-platform files.

Dependencies

  • [x] pal-e-platform #419 (Hetzner edge provisioning) -- done, on board in done column (item #1417)
  • [x] Spike #15 (custom domain routing) -- done, on board in done column (item #1377)
  • No blocking items in in_progress or todo columns for this story
Dependencies are satisfied and correctly documented in Lineage.

Acceptance Criteria

5 acceptance criteria. All are verifiable with curl and browser testing:
  • curl -I https://palinks.app returns 200 -- testable after DNS propagation
  • curl -I https://www.palinks.app returns 301 -- testable
  • TLS via Let's Encrypt -- verifiable via curl certificate inspection
  • Rails accepts palinks.app host -- verifiable via curl
  • Keycloak login/logout works -- requires browser test
However, these criteria cannot be verified until all 4 systems are wired up. No individual sub-task can satisfy any criterion in isolation.

Blast Radius

  • The docs/custom-domain.md already lists landscaping-assistant.app and westsidekingsandqueens.com as future domains using the same edge proxy pattern. This ticket establishes the pattern for those future domains.
  • No downstream consumers affected beyond the app itself.
  • The Keycloak redirect URI change could affect existing auth flows if misconfigured (e.g., if the existing tailscale funnel URI is removed instead of added alongside).

Decomposition Assessment

NEEDS DECOMPOSITION.
  • File targets across repos: 4+ targets across 4 systems (palinks, pal-e-platform, pal-e-services, GoDaddy) -- exceeds the >3 targets across >2 repos threshold
  • Acceptance criteria: 5 -- at the threshold
  • Points mismatch: Scored at 1 point but the multi-repo, multi-system scope is at least 3-5 points of work
  • Agent executability: No single agent can execute this ticket. An agent cloned into palinks cannot modify pal-e-platform Salt configs, cannot access Keycloak admin, and cannot set GoDaddy DNS records.
Recommended decomposition:
  • GoDaddy DNS (manual/task) -- Set A records for palinks.app and www.palinks.app
  • pal-e-platform: Caddy config (issue) -- Add palinks.app site block to Caddy on edge-proxy, filed on pal-e-platform repo
  • palinks: Rails host + docs (issue) -- Add palinks.app to config.hosts, update docs/custom-domain.md, filed on palinks repo
  • pal-e-services: Keycloak redirect URIs (task) -- Add palinks.app to client redirect URIs
  • End-to-end verification (task) -- curl + browser verification after all sub-tasks complete

Recommendations

  • [DECOMPOSE] 4+ file targets across 4 systems, no single agent can execute. Route to skill-decompose-ticket for sub-ticket creation.
  • [BODY] Add specific file path for Caddy config in pal-e-platform (e.g., the Salt state or Caddyfile path on edge-proxy).
  • [BODY] Clarify Keycloak redirect URI update mechanism -- is it Terraform, admin UI, or a config file in pal-e-services?
  • [LABEL] Update points from 1 to at least 3 -- multi-repo multi-system work cannot be 1 point.