Review: Stalwart: domain + account setup for landscaping-assistant.app

review-1736-2026-07-04-v2 Review

review ready

Verdict: READY

Re-review of board item #1736. Previous review (review-1736-2026-07-04) returned NEEDS_REFINEMENT. All three issues have been addressed.

Template Completeness

  • [x] Type -- Feature
  • [x] Lineage -- "Depends on: pal-e-platform#498 (Stalwart install)"
  • [x] Repo -- ldraney/pal-e-services (with cross-repo note explaining pillar lives in pal-e-platform)
  • [x] User Story -- "As a platform admin I want SMTP sending accounts configured..."
  • [x] Context -- good detail on both domains and SMTP-only accounts
  • [x] File Targets -- salt/pillar/stalwart.sls (correct, matches arch note)
  • [x] Feature Flag -- "none"
  • [x] Acceptance Criteria -- 6 criteria (verifiable)
  • [x] Test Expectations -- swaks command with proper flags
  • [x] Constraints -- present (strong passwords, send-only, RSA 2048-bit)
  • [x] Checklist -- present
  • [x] Related -- present

Traceability

  • [x] story:self-hosted label -- "As platform admin, I want zero third-party email dependencies so I control deliverability"
  • [x] story note verified -- found in project-stalwart-email user-stories section
  • [x] arch:stalwart label -- references Stalwart Mail Server component
  • [x] arch note verified -- arch-stalwart note exists with full architecture diagram and key files listing
  • [x] Forgejo issue -- https://forgejo.tail5b443a.ts.net/ldraney/pal-e-services/issues/164, open

File Targets

  • [x] salt/pillar/stalwart.sls -- verified: directory salt/pillar/ exists in pal-e-platform with existing .sls files (caddy.sls, k3s.sls, firewall.sls, etc.). File does not exist yet (to be created). Path matches arch-stalwart note's Key Files section. Cross-repo note explicitly documents that this file lives in pal-e-platform.
  • [x] Credentials storage -- "Document SMTP account credentials in Salt GPG pillar or secrets pipeline" -- salt/pillar/secrets/ directory exists with existing encrypted pillar files (services.sls, platform.sls, forgejo.sls).

Repo Placement

Acceptable. Issue filed on ldraney/pal-e-services for project tracking. Explicit cross-repo note added: "Issue filed on pal-e-services for project tracking; Salt pillar configuration is in pal-e-platform (salt/pillar/stalwart.sls)." Board is project-level (board-stalwart-email), not repo-level, so the organizational choice is reasonable.

Dependencies

  • Blocked by #1733 (pal-e-platform#498): "Salt: Stalwart install + systemd service state" -- currently in next_up column. Must complete before domains can be created. Documented in Lineage section.
  • Blocks #1737 (pal-e-services#165): DNS SPF/DKIM/DMARC for landscaping-assistant.app -- in todo. Needs DKIM public key output from this ticket.
  • Blocks #1738 (pal-e-services#166): DNS SPF/DKIM/DMARC for westsidekingsandqueens.com -- in todo. Needs DKIM public key output from this ticket.
  • Downstream dependency documented in AC: "DKIM public keys extracted and documented in a note or pillar output (downstream DNS tickets #165/#166 depend on this)"

Acceptance Criteria

6 criteria, all verifiable:
  • Domain existence (x2): verifiable via Stalwart admin API GET /api/domain/{name}
  • SMTP AUTH (x2): verifiable via swaks command (test command provided in Test Expectations)
  • DKIM key generation (x1): verifiable by checking keys exist after domain creation
  • DKIM export (x1): verifiable by checking output artifact exists for downstream consumers
Test command is specific and real: swaks --to test@gmail.com --from noreply@landscaping-assistant.app --server 127.0.0.1:587 --auth --auth-user noreply@landscaping-assistant.app

Blast Radius

Low. Configuring a new service (Stalwart) with no modifications to existing services. Downstream consumers (DNS tickets, future Keycloak config) are separate tickets. No sibling services share this pattern since Stalwart is the only mail server in the platform.

Decomposition Assessment

1 file target in 1 repo. 6 acceptance criteria (slightly over 5 threshold), but criteria are repetitive -- same 3 operations (create domain, create account, export DKIM) applied to 2 domains. Actual complexity is low. Estimated agent time less than 5 minutes once Stalwart is running. No decomposition needed.

Previous Review Issues -- Resolution

  • [x] File targets corrected: removed incorrect terraform/keycloak.tf reference, replaced with salt/pillar/stalwart.sls
  • [x] Cross-repo note added: explicit documentation that issue is filed on pal-e-services but file changes target pal-e-platform
  • [x] DKIM output artifact AC added: "DKIM public keys extracted and documented in a note or pillar output (downstream DNS tickets #165/#166 depend on this)"

Recommendation

No action needed. Ticket is ready for implementation once blocker #1733 (Stalwart install) completes.