Review: Add permanent Postmark inbound webhook endpoint via Tailscale funnel
Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] Type -- Feature
- [x] Lineage -- Standalone, follows PR #582
- [x] Repo -- ldraney/pal-e-platform
- [x] User Story -- As a platform operator / I want a permanent webhook endpoint / So that inbound emails are reliably processed
- [x] Context -- Detailed background on Postmark inbound config, webhook.site expiry, security considerations
- [x] File Targets -- 2 modify targets, 2 don't-touch targets
- [x] Feature Flag -- none
- [x] Acceptance Criteria -- 4 criteria
- [x] Test Expectations -- 3 tests (manual + tofu plan)
- [x] Constraints -- 5 constraints listed
- [x] Checklist -- Standard PR/tests/no-unrelated
- [x] Related -- References project page, arch note, PR #582
Traceability
- [x] arch:deployment-postmark label -- arch-deployment-postmark note exists in pal-e-docs (architecture note covering SDK/MCP deployment pattern)
- [x] arch note verified -- arch-deployment-postmark exists and is active
- [x] story:postmark-email label -- label present on board item
- [ ] story note MISSING -- [SCOPE] postmark-project-page user-stories section has keys: sdk, mcp, ci. No "email" story entry exists. Create user story entry on postmark-project-page user-stories section for story key "email" linking to a story-postmark-email note.
- [x] Forgejo issue -- https://forgejo.tail5b443a.ts.net/ldraney/pal-e-platform/issues/583, open
File Targets
- [x] terraform/modules/postmark/main.tf -- verified: file exists, currently contains only postmark_server and postmark_domain resources. Adding k8s resources here is consistent with the stated design decision.
- [x] terraform/modules/postmark/variables.tf -- verified: file exists, currently has server_name, domain, return_path_subdomain variables.
- [x] terraform/modules/networking/main.tf -- correctly listed as don't-touch. Funnel ingress pattern confirmed there (9 instances of tailscale.com/funnel annotation).
- [x] terraform/dns.tf -- correctly listed as don't-touch.
Repo Placement
OK -- issue filed on ldraney/pal-e-platform, all file targets are in that repo. Single-repo change.
Dependencies
- PR #582 (MX record + pillar secrets) -- stated as already merged. No blocker.
- No other board items on board-platform-playbook appear related to this work.
- Tailscale operator must be deployed (it is -- networking module manages it).
Acceptance Criteria
- AC1: tofu plan shows resources -- agent-verifiable
- AC2: webhook endpoint reachable at funnel URL -- requires deployed infrastructure (post-deployment validation)
- AC3: InboundHookUrl points to funnel URL -- verifiable via tofu plan output
- AC4: inbound emails queryable via search_inbound_messages -- requires real email flow (post-deployment validation)
AC2 and AC4 are post-deployment validation criteria, not agent-verifiable. This is appropriate for infrastructure work.
Blast Radius
CRITICAL: The postmark module is instantiated TWICE in terraform/main.tf:
module.postmark_iss(intelligentstaffingsystems.ai)module.postmark_landscaping(landscaping-assistant.app)
Adding kubernetes_deployment_v1, kubernetes_service_v1, kubernetes_ingress_v1, and kubernetes_config_map_v1 directly to the module will create these resources for BOTH instances. The ticket only discusses the ISS domain inbound webhook. The agent needs clear guidance: either (a) add a boolean variable like
enable_inbound_webhook to make the k8s resources conditional, or (b) confirm that both Postmark servers need inbound webhook endpoints.Additionally, the module's versions.tf only declares the
postmark provider (marcus-carey/postmark ~> 1.0). Adding Kubernetes resources requires the hashicorp/kubernetes provider. Terraform inherits it from the root module, but the module should declare it in its own required_providers for explicitness.Decomposition Assessment
- 2 file targets in 1 repo -- under threshold
- 4 acceptance criteria -- under threshold
- All changes in one module -- fits single agent pass
- No decomposition needed.
Recommendation
- [SCOPE] Create user story entry "email" on postmark-project-page user-stories section, and create backing note story-postmark-email.
- [BODY] Address shared module blast radius: the postmark module is instantiated twice (postmark_iss, postmark_landscaping). Add guidance for the agent -- either add an
enable_inbound_webhookboolean variable to conditionally create k8s resources, or state that both instances need the webhook. Without this, the agent will create duplicate deployments/ingresses for both domains. - [BODY] Add constraint: module versions.tf needs kubernetes provider added to required_providers since the module will now manage Kubernetes resources alongside Postmark API resources.