Postmark
Notes
Review 8
-
Review: Add shared Postmark inbound webhook endpoint via Tailscale funnel (r2)
review-2001-2026-08-04-r2Verdict: APPROVED
Re-review of board item #2001 after refinement. All three issues from
review-2001-2026-08-04have been resolved.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 shared webhook endpoint / So that inbound emails are reliably processed and queryable
- [x] Context -- Detailed background on Postmark inbound config, webhook.site expiry, security (no HMAC, Basic Auth recommended), architecture decision (shared platform service, not per-app)
- [x] File Targets -- 4 create/modify targets, 3 don't-touch targets with reasons
- [x] Feature Flag -- none
- [x] Acceptance Criteria -- 5 criteria
- [x] Test Expectations -- 3 tests (manual curl, manual email, tofu plan)
- [x] Constraints -- 6 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 (active architecture note)
- [x] arch note verified -- arch-deployment-postmark covers SDK/MCP deployment pattern with diagram
- [x] story:postmark-email label -- label present on board item
- [x] story note verified -- story-postmark-email-inbound exists (user-story note, active), linked from project-postmark-email user-stories section with key "inbound"
- [x] Forgejo issue -- https://forgejo.tail5b443a.ts.net/ldraney/pal-e-platform/issues/583, open
File Targets
- [x]
terraform/postmark-inbound.tf(new) -- verified: file does not exist yet. Will contain k8s deployment, configmap, service, secret, and ingress as top-level resources. Correct placement outside the per-app module. - [x]
terraform/modules/postmark/main.tf-- verified: contains postmark_server and postmark_domain resources only. Adding inbound_hook_url to postmark_server.this is a minimal change. - [x]
terraform/modules/postmark/variables.tf-- verified: currently has server_name, domain, return_path_subdomain. Adding inbound_hook_url (string, default "") is consistent. - [x]
terraform/main.tf-- verified: postmark_iss at line 168, postmark_landscaping at line 177. Issue correctly says to pass URL to ISS instance only; landscaping wired later. - [x]
terraform/modules/networking/main.tf-- correctly listed as don't-touch. Funnel pattern confirmed (9 tailscale.com/funnel annotations, ingress_class_name "tailscale"). - [x]
terraform/dns.tf-- correctly listed as don't-touch. - [x]
terraform/modules/postmark/versions.tf-- correctly listed as don't-touch. Only declares postmark provider. Kubernetes provider is at top level (versions.tf line 11-12, providers.tf line 1).
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 are related to this work or block it.
- Tailscale operator is deployed (networking module manages it). Not a blocker.
- Kubernetes provider is declared at root level -- no additional provider config needed.
Acceptance Criteria
- AC1: tofu plan shows new resources as top-level + updated InboundHookUrl on ISS server -- agent-verifiable
- AC2: webhook endpoint reachable at funnel URL, returns 200 on POST -- post-deployment validation
- AC3: InboundHookUrl on ISS Postmark server points to funnel URL with Basic Auth -- verifiable via tofu plan output
- AC4: inbound emails queryable via search_inbound_messages -- post-deployment validation
- AC5: postmark module remains clean, no kubernetes provider dependency -- agent-verifiable (check versions.tf unchanged)
AC2 and AC4 are post-deployment validation criteria. Appropriate for infrastructure work.
Blast Radius
Previous issue resolved: Webhook k8s resources now live at top level in
postmark-inbound.tf, not inside the per-app module. The module is instantiated twice (postmark_iss, postmark_landscaping), but only receives a new variable -- no k8s resources duplicated. Only the ISS instance gets the URL initially.No other services reference inbound webhook patterns. No existing
inbound_hook_urlorpostmark-inboundreferences found in the terraform directory.Decomposition Assessment
- 4 file targets (1 new, 3 modify) in 1 repo -- under threshold
- 5 acceptance criteria -- at threshold, not over
- Estimated agent work under 5 minutes -- straightforward k8s resource creation + variable wiring
- No decomposition needed.
Previous Review Issues -- Resolution Status
- Shared module blast radius -- RESOLVED: Webhook resources now live at top level in
postmark-inbound.tf, not inside the per-app module. Issue body clearly states the architecture decision and the agent's don't-touch boundaries. - Missing kubernetes provider -- RESOLVED: Top-level resources use the already-declared kubernetes provider (versions.tf line 11-12, providers.tf line 1). Module's versions.tf is explicitly listed as don't-touch.
- Missing story note -- RESOLVED:
story-postmark-email-inboundcreated as user-story note in project postmark-email. Linked from project-postmark-email user-stories section with key "inbound".
Recommendation
No action needed. All previous issues resolved. Scope is solid, file targets verified, traceability complete.
-
Review: Add permanent Postmark inbound webhook endpoint via Tailscale funnel
review-2001-2026-08-04Verdict: 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_webhookto 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
postmarkprovider (marcus-carey/postmark ~> 1.0). Adding Kubernetes resources requires thehashicorp/kubernetesprovider. 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.
-
Review: Sprint 3: Woodpecker pipeline -- postmark-account-sdk
review-1917-2026-07-26Verdict: READY
Override: Original NEEDS_REFINEMENT was a false positive — the review agent searched for
project-postmarkbut the project page exists atpostmark-project-page. Other review agents (1916, 1919) found it correctly. Story traceability is intact:story:cimaps tostory-postmark-ciwhich is listed onpostmark-project-page.Template Completeness
- [x] All 12 template sections present and well-formed
Traceability
- [x] story:ci label — maps to story-postmark-ci on postmark-project-page
- [x] arch:ci-pipeline label — arch-ci-pipeline note verified
- [x] Forgejo issue — ldraney/postmark-account-sdk#3, open
File Targets
- [x] .woodpecker.yml — does not exist yet (create). Reference implementations confirmed.
Dependencies
- [x] Blocker #2 (SDK implementation) resolved — board item #1915 in done
Acceptance Criteria
4 criteria, all agent-verifiable, under 5-limit threshold.
Decomposition
Not needed — 1 file, 1 repo, well under 5-minute threshold.
-
Review: Sprint 2: SDK implementation -- postmark-account-sdk (re-review)
review-1915-2026-07-25-r2Verdict: APPROVED
Re-review of board item #1915 after refinement. Prior review
review-1915-2026-07-25returned NEEDS_REFINEMENT with three issues. All three are now resolved.Prior Issues -- Resolution
- [x] [LABEL] arch:api changed to arch:domain-postmark --
arch-domain-postmarknote verified, belongs to postmark project - [x] [BODY]
tests/test_templates.pyadded to File Targets -- Templates API group now covered - [x] [SCOPE] Project page exists at
postmark-project-page-- user-stories section confirmed with story key "sdk" linking tostory-postmark-sdk
Template Completeness
- [x] Type -- Feature
- [x] Lineage
- [x] Repo
- [x] User Story
- [x] Context
- [x] File Targets -- 7 items (pyproject.toml, src package, conftest, 4 test files)
- [x] Feature Flag -- none (appropriate for SDK/infra work)
- [x] Acceptance Criteria -- 6 items
- [x] Test Expectations -- 2 items
- [x] Constraints -- 5 items
- [x] Checklist -- 3 items
- [x] Related
All 12 required sections present per
template-issue-feature.Traceability
- [x] story:sdk label -- Postmark SDK Foundation
- [x] story note verified --
story-postmark-sdkexists in pal-e-docs - [x] story note on project page -- found in
postmark-project-pageuser-stories section, key "sdk" links tostory-postmark-sdk - [x] arch:domain-postmark label -- Postmark Domain Model
- [x] arch note verified --
arch-domain-postmarknote exists in pal-e-docs, documents PostmarkAccountSDK entity model - [x] Forgejo issue -- ldraney/postmark-account-sdk#2, open
Full traceability triangle verified. All backing notes exist.
File Targets
- [x]
pyproject.toml-- new file, project config with pytest/httpx dependencies - [x]
src/postmark_account_sdk/-- new SDK package (detailed structure in docs/acceptance-criteria.md: __init__.py, client.py, servers.py, domains.py, senders.py, templates.py) - [x]
tests/conftest.py-- shared fixtures, token loading - [x]
tests/test_servers.py-- Server Management API (5 endpoints) - [x]
tests/test_domains.py-- Domains API (9 endpoints) - [x]
tests/test_sender_signatures.py-- Sender Signatures API (8 endpoints). Note: acceptance-criteria.md calls thistest_senders.py; cosmetic naming difference, not blocking since the doc is the detailed guide per Constraints section. - [x]
tests/test_templates.py-- Templates API (1 endpoint: PUT /templates/push)
All file targets are new files. Repo currently contains only Sprint 1 docs: CLAUDE.md, README.md, docs/, postmark-account-api.yaml. Verified via Forgejo API tree listing.
Repo Placement
OK -- Issue filed on
ldraney/postmark-account-sdk, work targets same repo. Single-repo scope.Dependencies
- Blocked by #1 (docs PR) -- RESOLVED. Board item #1911 in done column, PR #4 merged.
- Sibling:
ldraney/postmark-server-sdk#2(board item #1914, 8 points) -- parallel server SDK issue, same sprint 2, same pattern. No ordering dependency. - Downstream: Sprint 3 items depend on SDKs:
- #1917 -- Sprint 3: Woodpecker pipeline (postmark-account-sdk)
- #1919 -- Sprint 3: MCP implementation (postmark-account-mcp)
- Dependencies documented in Lineage and Related sections.
Acceptance Criteria
6 criteria, all verifiable by an agent:
- AC1: "Every endpoint in postmark-account-api.yaml has at least one test" -- verifiable by cross-referencing swagger (23 endpoints across 4 groups per docs/acceptance-criteria.md)
- AC2: "All tests pass against the real Postmark API" -- verifiable via
pytest tests/ -v - AC3: "SDK client handles auth via POSTMARK_ACCOUNT_TOKEN env var" -- verifiable
- AC4: "Error responses are handled gracefully" -- verifiable (agent interprets as proper exception handling)
- AC5: "Tests are organized by API group matching the swagger spec sections" -- verifiable by file structure, 4 groups confirmed in swagger
- AC6: "Destructive tests are safe" -- verifiable (create/cleanup pattern)
The docs/acceptance-criteria.md provides detailed endpoint-to-test mapping (23 endpoints, 23 tests). Test Expectations are clear: full pytest suite, real API, no mocks.
Blast Radius
Clean. Greenfield SDK repo with no existing consumers. Sibling
postmark-server-sdk#2follows identical pattern (same template structure, same forgejo-sdk reference). No cross-repo impact. MCP repos (sprint 3) will consume the SDK but are not yet implemented.Decomposition Assessment
- File targets: 7 files in 1 repo -- single-repo, under the >3 files across >2 repos threshold
- Acceptance criteria: 6 items -- at the >5 threshold boundary, but tightly coupled (single SDK implementation with cross-cutting quality constraints)
- Clear source of truth: swagger spec (23 endpoints) + docs/acceptance-criteria.md (complete endpoint-to-test mapping)
- Clear pattern reference: ~/forgejo-sdk
- Estimated agent work: 5-point story with established scaffolding. Manageable in a single agent pass.
No decomposition needed. Work is coherent and single-repo with comprehensive documentation.
Observations (non-blocking)
- Issue File Targets say
tests/test_sender_signatures.pybut docs/acceptance-criteria.md saystests/test_senders.py. The Constraints section directs the agent to "Read docs/acceptance-criteria.md for the detailed endpoint-to-test mapping," so the doc naming will prevail. Cosmetic only.
Recommendation
No action needed. Scope is solid, all prior issues resolved, traceability complete.
- [x] [LABEL] arch:api changed to arch:domain-postmark --
-
Review: Sprint 2: SDK implementation -- postmark-server-sdk (r2)
review-1914-2026-07-25-r2Verdict: APPROVED
Re-review of board item #1914 after refinement. Prior review
review-1914-2026-07-25returned NEEDS_REFINEMENT with two findings. Both addressed.Refinement Resolution
- [LABEL]
arch:apitoarch:domain-postmark-- FIXED. Board item #1914 now carriesarch:domain-postmark. Verified via fresh board pull. - [DECOMPOSE] Decomposition waived -- ACCEPTED. This is intentionally an 8-point ticket for agent-driven implementation where a dev agent implements the full SDK in one pass. The repo's
docs/acceptance-criteria.mdprovides a detailed endpoint-to-test mapping (43 endpoints across 7 groups) that serves as the agent's implementation guide. Decomposition would add overhead without benefit for single-agent execution.
Template Completeness
- [x] Type -- Feature
- [x] Lineage -- Blocked by #1 (docs PR), Sprint 2
- [x] Repo -- ldraney/postmark-server-sdk
- [x] User Story -- well-formed (developer wants pytest coverage of every endpoint)
- [x] Context -- references swagger spec, forgejo-sdk pattern, token source
- [x] File Targets -- 10 files/directories listed
- [x] Feature Flag -- none (appropriate for SDK infrastructure)
- [x] Acceptance Criteria -- 5 criteria, supplemented by docs/acceptance-criteria.md
- [x] Test Expectations -- pytest command specified, real API (no mocks)
- [x] Constraints -- forgejo-sdk patterns, uv/pyproject.toml
- [x] Checklist -- present
- [x] Related -- present
Traceability
- [x] story:sdk label -- Postmark SDK Foundation
- [x] story note verified --
story-postmark-sdkexists inpostmark-project-pageuser-stories section (key: sdk, metric: 100% endpoint coverage in pytest) - [x] arch:domain-postmark label -- corrected from prior review
- [x] arch note verified --
arch-domain-postmarknote exists in pal-e-docs (architecture type, active tag, ER diagram covering PostmarkServerSDK entities) - [x] Forgejo issue -- ldraney/postmark-server-sdk#2, state: open
File Targets
- [x]
pyproject.toml-- to create. No conflict with existing repo contents (CLAUDE.md, README.md, docs/, swagger spec). - [x]
src/postmark_server_sdk/-- to create. Note: issue body usespostmark_server_sdkbutdocs/acceptance-criteria.mdusespostmark_sdk. See recommendation. - [x]
tests/conftest.py-- to create. Token loading from POSTMARK_SERVER_TOKEN env var. - [x]
tests/test_sending.py-- to create. 4 endpoints (send, batch, template, batch-template). - [x]
tests/test_bounces.py-- to create. 5 endpoints. - [x]
tests/test_messages.py-- to create. 11 endpoints (7 outbound + 4 inbound). - [x]
tests/test_templates.py-- to create. 6 endpoints (CRUD + validate). - [x]
tests/test_stats.py-- to create. 12 endpoints across outbound stats. - [x]
tests/test_server.py-- to create. 2 endpoints (get/edit config). - [x]
tests/test_inbound.py-- to create. Note: issue saystest_inbound.pybut acceptance-criteria.md saystest_inbound_rules.py. See recommendation.
All targets are new files -- Sprint 1 (docs PR, #1910) is in done. No existing files to verify against.
Repo Placement
OK. Issue filed on ldraney/postmark-server-sdk, all work targets the same repo. No cross-repo concerns.
Dependencies
- Blocked by: ldraney/postmark-server-sdk#1 (docs PR) -- RESOLVED. Board item #1910 is in done column.
- Sibling: Board item #1915 "Sprint 2: SDK implementation -- postmark-account-sdk" is in backlog with same labels. Independent -- can run in parallel.
- Downstream: Sprint 3 MCP items (#1918 postmark-server-mcp, #1919 postmark-account-mcp) depend on SDK packages being installable. No blocking concern for this sprint.
Acceptance Criteria
5 criteria in the issue body, all agent-verifiable:
- "Every endpoint in postmark-server-api.yaml has at least one test" -- verifiable by counting endpoints (43 per acceptance-criteria.md, 41 operationIds in swagger -- close enough, likely minor counting difference)
- "All tests pass against the real Postmark API" -- verifiable via
pytest tests/ -v - "SDK client handles auth via POSTMARK_SERVER_TOKEN env var" -- verifiable by code inspection
- "Error responses are handled gracefully" -- verifiable but slightly vague (minor concern, carried from prior review)
- "Tests are organized by API group matching the swagger spec sections" -- verifiable by file structure
The
docs/acceptance-criteria.mdprovides a detailed 7-section completion checklist plus per-endpoint test expectations for each group. This compensates for the issue body's higher-level AC.Blast Radius
Sibling repo postmark-account-sdk (#1915) follows the identical pattern. Both SDKs will be pip-installed by MCP repos in Sprint 3. No downstream consumers exist yet. The arch:domain-postmark label fix applied to #1914 was also applied to #1915.
Decomposition Assessment
- File targets: 10+ files in 1 repo (single-repo, no multi-repo trigger)
- Acceptance criteria: 5 in issue body (under threshold)
- Estimated agent work: 43 endpoints, ~45 minutes. Exceeds 5-minute rule.
- Waived. Caller explicitly states this is intentionally a large ticket (8 points) designed for agent-driven implementation in one pass. The
docs/acceptance-criteria.mdin the repo provides the detailed endpoint-to-test mapping that guides the dev agent. Decomposition would fragment the work without benefit.
Recommendation
Minor [BODY] items -- non-blocking, can be fixed during implementation or before:
- [BODY] Align package directory name: issue body says
src/postmark_server_sdk/,docs/acceptance-criteria.mdsayssrc/postmark_sdk/. Pick one and update the other. Recommendpostmark_server_sdkto match repo name and distinguish from account SDK. - [BODY] Align test file name: issue body says
tests/test_inbound.py, acceptance-criteria.md saystests/test_inbound_rules.py. Recommendtest_inbound_rules.pyto match the source module nameinbound_rules.py. - [BODY] Acceptance-criteria.md completion checklist item 7 references Woodpecker CI (issue #3), which is Sprint 3 scope. Consider removing or marking as out-of-scope for this ticket.
None of these block implementation. The dev agent should follow
docs/acceptance-criteria.mdas the authoritative source for file names and endpoint mappings. - [LABEL]
-
Review: Sprint 2: SDK implementation -- postmark-account-sdk
review-1915-2026-07-25Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] Type -- Feature
- [x] Lineage
- [x] Repo
- [x] User Story
- [x] Context
- [x] File Targets
- [x] Feature Flag -- none (appropriate for SDK/infra work)
- [x] Acceptance Criteria -- 6 items
- [x] Test Expectations
- [x] Constraints
- [x] Checklist
- [x] Related
All 12 required sections present per
template-issue-feature.Traceability
- [x] story:sdk label -- Postmark SDK Foundation
- [x] story note verified --
story-postmark-sdkexists in pal-e-docs - [ ] story note on project page MISSING -- [SCOPE] No
project-postmarkproject page exists. The story notestory-postmark-sdkreferencespostmark-project-pagein its Related section, suggesting this page should be created. - [x] arch:api label present
- [ ] arch note WRONG PROJECT -- [LABEL]
arch-apinote exists but belongs toprediction-assistant(Kalshi), not postmark. The postmark project usesarch-domain-postmark,arch-dataflow-postmark,arch-deployment-postmark. Label should bearch:domain-postmarkto reference the correct architecture note. - [x] Forgejo issue -- ldraney/postmark-account-sdk#2, open
File Targets
- [x]
pyproject.toml-- new file, project config - [x]
src/postmark_account_sdk/-- new package directory - [x]
tests/conftest.py-- new file, shared fixtures - [x]
tests/test_servers.py-- covers Server Management API (5 endpoints) - [x]
tests/test_domains.py-- covers Domains API (9 endpoints) - [x]
tests/test_sender_signatures.py-- covers Sender Signatures API (8 endpoints) - [ ]
tests/test_templates.py-- MISSING: [BODY] Templates API group (PUT /templates/push) has no test file listed. The swagger spec defines 4 API tag groups but only 3 test files are listed. AC #5 requires "Tests are organized by API group matching the swagger spec sections."
Repo currently contains only docs from Sprint 1:
CLAUDE.md,README.md,docs/,postmark-account-api.yaml. All file targets are new files, which is correct.Repo Placement
OK -- Issue filed on
ldraney/postmark-account-sdk, work targets same repo. Single-repo scope.Dependencies
- Blocked by #1 (docs PR) -- RESOLVED (issue #1 closed, PR #4 merged). Blocker cleared.
- Sibling:
ldraney/postmark-server-sdk#2(board item #1914, 8 points) -- parallel server SDK issue, same sprint 2, same pattern. No ordering dependency between the two SDKs. - Downstream: Sprint 3 items depend on SDKs being complete:
- #1917 -- Sprint 3: Woodpecker pipeline (postmark-account-sdk)
- #1919 -- Sprint 3: MCP implementation (postmark-account-mcp)
- Dependencies are documented in the Lineage and Related sections.
Acceptance Criteria
6 criteria, all verifiable:
- AC1: "Every endpoint in postmark-account-api.yaml has at least one test" -- verifiable by cross-referencing swagger paths vs test coverage. Swagger has 22 endpoints across 4 groups.
- AC2: "All tests pass against the real Postmark API" -- verifiable via
pytest tests/ -v - AC3: "SDK client handles auth via POSTMARK_ACCOUNT_TOKEN env var" -- verifiable
- AC4: "Error responses are handled gracefully" -- slightly vague but acceptable (agent can interpret as proper exception handling)
- AC5: "Tests are organized by API group matching the swagger spec sections" -- verifiable, but contradicted by missing templates test file in File Targets
- AC6: "Destructive tests are safe" -- verifiable and important for account-level operations. Good addition vs the sibling server-sdk issue.
Blast Radius
Clean. Greenfield SDK repo with no existing consumers. Sibling
postmark-server-sdk#2follows identical pattern (same template structure, same forgejo-sdk reference). No cross-repo impact. MCP repos (sprint 3) will consume the SDK but are not yet implemented.The
~/forgejo-sdkpattern reference should provide a clear implementation model for the agent.Decomposition Assessment
- File targets: 6 files (should be 7 with templates) in 1 repo -- under the >3 files across >2 repos threshold
- Acceptance criteria: 6 items -- at the >5 threshold boundary
- Estimated agent work: Single repo, clear swagger spec as source of truth, clear pattern to follow (forgejo-sdk). 4 API groups, 22 total endpoints. Manageable in a single agent pass despite being a 5-point story.
No decomposition needed. The work is coherent and single-repo.
Recommendations
- [BODY] Add
tests/test_templates.pyto File Targets -- Templates API (PUT /templates/push) is the 4th API group in the swagger spec. AC #5 requires tests organized by API group. - [LABEL] Change
arch:apilabel toarch:domain-postmark-- thearch-apinote belongs to prediction-assistant, not postmark. The correct postmark arch note isarch-domain-postmarkwhich documents the PostmarkAccountSDK entity model. - [SCOPE] Create
project-postmarkproject page with user-stories section -- the story notestory-postmark-sdkexists but no project page hosts it. The story note itself referencespostmark-project-pageas a parent.
-
Review: Sprint 2: SDK implementation -- postmark-server-sdk
review-1914-2026-07-25Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] Type -- Feature
- [x] Lineage -- Blocked by #1 (docs PR), Sprint 2
- [x] Repo -- ldraney/postmark-server-sdk
- [x] User Story -- present, well-formed
- [x] Context -- present, references swagger spec and forgejo-sdk pattern
- [x] File Targets -- 10 files/directories listed
- [x] Feature Flag -- none (appropriate for SDK infra)
- [x] Acceptance Criteria -- 5 criteria
- [x] Test Expectations -- present, pytest command specified
- [x] Constraints -- present, references forgejo-sdk patterns
- [x] Checklist -- present
- [x] Related -- present
Traceability
- [x] story:sdk label -- Postmark SDK Foundation
- [x] story note verified -- story-postmark-sdk exists and is listed in postmark-project-page user-stories section (key: sdk, metric: 100% endpoint coverage in pytest)
- [ ] arch:api label -- WRONG NOTE.
arch-apibelongs to prediction-assistant (Kalshi API integration), not postmark. The postmark project usesarch-domain-postmark(SDK client entities) andarch-dataflow-postmark(SDK-to-Postmark API call flow). [LABEL] Changearch:apitoarch:domain-postmarkorarch:dataflow-postmark. - [x] Forgejo issue -- ldraney/postmark-server-sdk#2, state: open
File Targets
- [x]
pyproject.toml-- to create. Repo currently has only docs from Sprint 1 (CLAUDE.md, README.md, docs/, postmark-server-api.yaml). Verified no conflict. - [x]
src/postmark_server_sdk/-- to create. Package directory. Follows forgejo-sdk pattern (src/forgejo_sdk/ has client.py, __init__.py, and per-group modules). - [x]
tests/conftest.py-- to create. Shared fixtures, token loading. Matches forgejo-sdk/tests/conftest.py pattern. - [x]
tests/test_sending.py-- to create. Covers /email, /email/batch, /email/batchWithTemplates, /email/withTemplate endpoints. - [x]
tests/test_bounces.py-- to create. Covers /bounces endpoints. - [x]
tests/test_messages.py-- to create. Covers /messages/inbound, /messages/outbound, /messages/outbound/clicks, /messages/outbound/opens. - [x]
tests/test_templates.py-- to create. Covers /templates, /templates/validate. - [x]
tests/test_stats.py-- to create. Covers 9 /stats/outbound/* endpoints. - [x]
tests/test_server.py-- to create. Covers /server endpoint. - [x]
tests/test_inbound.py-- to create. Covers /triggers/inboundrules.
Note: File targets list test files but do not explicitly list SDK source modules (e.g.,
src/postmark_server_sdk/client.py,__init__.py, per-group modules). The forgejo-sdk pattern includes per-group modules insrc/. These implied files add to the true scope.Repo Placement
OK. Issue filed on ldraney/postmark-server-sdk, all work targets the same repo. No cross-repo concerns for this sprint.
Dependencies
- Blocked by: ldraney/postmark-server-sdk#1 (docs PR) -- RESOLVED. Issue #1 is closed, board item #1910 is in done column.
- Sibling: board item #1915 "Sprint 2: SDK implementation -- postmark-account-sdk" is in backlog with same labels (type:feature, arch:api, story:sdk). Independent -- can run in parallel.
- Downstream: Sprint 3 MCP items (#1918, #1919) depend on SDK packages being installable. No blocking concern for this sprint.
Acceptance Criteria
5 criteria, all testable by an agent:
- "Every endpoint in postmark-server-api.yaml has at least one test" -- verifiable by counting endpoints vs test functions
- "All tests pass against the real Postmark API" -- verifiable via
pytest tests/ -v - "SDK client handles auth via POSTMARK_SERVER_TOKEN env var" -- verifiable by code inspection
- "Error responses are handled gracefully" -- verifiable but vague. What constitutes "graceful"? (minor concern)
- "Tests are organized by API group matching the swagger spec sections" -- verifiable by file structure
Test command is real:
pytest tests/ -v. Token source documented:~/secrets/postmark/intelligentstaffingsystems/.env.Blast Radius
Sibling repo postmark-account-sdk (#1915) has an identical pattern. Both SDKs will be pip-installed by MCP repos in Sprint 3. No downstream consumers exist yet. The arch:api label mismatch affects #1915 too (same label, same wrong arch note).
Decomposition Assessment
- File targets: 10+ files in 1 repo (does not trigger ">3 files across >2 repos")
- Acceptance criteria: 5 (does not trigger ">5 acceptance criteria")
- Estimated agent work: 43 endpoints to implement in SDK + 43 tests across 7 test files + package setup + conftest. At ~1 min per endpoint (SDK method + test), estimated 45+ minutes. EXCEEDS 5-minute threshold.
- 8 story points confirms large scope.
NEEDS DECOMPOSITION -- route to skill-decompose-ticket. Recommended split: one sub-ticket per API group (sending, bounces, messages, templates, stats, server, inbound) plus one for package scaffolding (pyproject.toml, client.py, conftest.py).
Recommendation
- [LABEL] Change
arch:apitoarch:domain-postmarkon board item #1914. The currentarch-apinote belongs to prediction-assistant, not postmark. Also affects sibling #1915. - [DECOMPOSE] 43 endpoints across 8 API groups, estimated 45+ minutes of agent work. Route to skill-decompose-ticket. Suggested sub-tickets: (1) package scaffolding, (2) sending endpoints, (3) bounces, (4) messages, (5) templates, (6) stats, (7) server config, (8) inbound rules.
-
Review: Sprint 1: Docs PR -- postmark-account-sdk (v2)
review-1911-2026-07-25-v2Verdict: APPROVED
Re-review of board item #1911 after refinement. All four issues from
review-1911-2026-07-25(NEEDS_REFINEMENT) have been resolved.Template Completeness
- [x] Type -- Feature
- [x] Lineage -- Standalone, Sprint 1
- [x] Repo -- ldraney/postmark-account-sdk
- [x] User Story -- complete As a/I want/So that
- [x] Context -- detailed motivation and pattern references
- [x] File Targets -- 6 files to create + 3 reference repos
- [x] Feature Flag -- "none" (appropriate for docs-only PR)
- [x] Acceptance Criteria -- 7 items
- [x] Test Expectations -- "No tests -- docs only PR"
- [x] Constraints -- 4 constraints with correct repo references
- [x] Checklist -- 2 items (missing "Tests pass" but justified for docs-only)
- [x] Related -- "postmark -- parent project"
Traceability
- [x] story:sdk label -- Postmark SDK Foundation
- [x] story note verified --
story-postmark-sdkexists in pal-e-docs and listed inpostmark-project-pageuser-stories section with key "sdk" - [x] arch:domain-postmark label -- Postmark Domain Model
- [x] arch note verified --
arch-domain-postmarkexists in pal-e-docs with mermaid ER diagram - [x] Forgejo issue -- ldraney/postmark-account-sdk#1, state: open
File Targets
- [x]
~/forgejo-mcp/-- verified: CLAUDE.md symlink, README.md, docs/ directory with architecture.md (docs structure reference) - [x]
~/forgejo-sdk/-- verified: pyproject.toml, src/, tests/ (SDK code structure reference) - [x]
~/postmark-email/postmark-account-api.yaml-- verified: 29k, Postmark Account-level API v0.9.0, 23 operations across 4 path groups - [x]
ldraney/postmark-account-sdk-- verified on Forgejo (created 2026-07-25, not empty, main branch). Not cloned locally; implementing agent will clone. - [x] All 6 target files are "to be created" -- no pre-existing file verification needed beyond sources
Repo Placement
OK. Issue filed on
ldraney/postmark-account-sdk,### Reposection matches. Single-repo scope.Dependencies
- Sprint 2: SDK implementation (#1915, 5pt) depends on this docs PR completing first -- documented by sprint numbering
- Sprint 3: Woodpecker pipeline (#1917, 2pt) depends on Sprint 2
- No items in in_progress blocking this ticket
- Sibling Sprint 1 docs PRs (#1910 postmark-server-sdk, #1912 postmark-server-mcp, #1913 postmark-account-mcp) are independent -- can run in parallel
Acceptance Criteria
- [x] 7 AC items, all agent-verifiable (file existence, symlink check, content grep, mermaid presence)
- [x] AC 7 now specifically enumerates endpoint groups: servers, domains, sender signatures
- Minor note: swagger spec has a 4th path group
/templates/push(1 utility PUT operation) not listed in the parenthetical. This is a cross-cutting operation, not an entity group -- the domain model inarch-domain-postmarkalso omits it. Implementing agent should include it if discovered during spec reading. Not a blocker.
Blast Radius
Minimal. Docs-only PR in a new repo. Swagger spec is copied, not modified at source. No downstream consumers affected.
Decomposition Assessment
6 file targets in 1 repo, 7 AC items. AC count is 7 (above >5 threshold) but all work is documentation generation from a swagger spec following a known pattern. Estimated agent time: under 5 minutes. No decomposition needed.
Previous Review Issues -- Resolution
# Original Issue Resolution 1 [BODY] Constraints referenced ~/forgejo-sdk for docs pattern, but forgejo-sdk has no docs/ directory FIXED. Now cites ~/forgejo-mcp for docs structure, ~/forgejo-sdk for SDK code structure only 2 [BODY] AC 7 was vague ("All docs reference the Postmark Account API endpoints") FIXED. Now enumerates specific endpoint groups: servers, domains, sender signatures 3 [LABEL] arch:api label pointed to prediction-assistant arch note FIXED. Changed to arch:domain-postmark; arch-domain-postmark note exists 4 [SCOPE] story note missing from project page FIXED. story-postmark-sdk exists and is listed on postmark-project-page user-stories section Recommendation
No action needed. All previous NEEDS_REFINEMENT issues resolved. Ticket is ready for implementation.
Board 1
-
Postmark SDK + MCP
board-postmarkNo content