Phase 1 -- External Resources Provisioning -- Requirements
Functional requirements for Phase 1 of the email-integration project. Each requirement carries a unique identifier traceable through verification.md. Cross-phase contracts produced by Phase 1 are in exports.md.
Requirement identifier prefixes:
REQ-EXT-NNN— external resource provisioning (Postmark accounts, 1Password items).REQ-PLAT-NNN—platform/reference declarations ininfrastructure.REQ-CI-NNN— CI surface (GitHub Actions secret, drift-detection workflow).REQ-OPS-NNN— operator runbook and sign-off.REQ-DOC-NNN— documentation deliverables in thedocumentationrepo.
REQ-EXT: External resources
Section titled “REQ-EXT: External resources”REQ-EXT-001: PostmarkProd account exists and is accessible
Section titled “REQ-EXT-001: PostmarkProd account exists and is accessible”A Postmark account named PostmarkProd exists, on the Platform plan, with 2FA enabled on the owner mailbox. An account-level API token has been generated and stored in 1Password under Arda-SystemsOAM/Postmark-Prod (field: credential). The token authenticates successfully against the Postmark Account API.
REQ-EXT-002: PostmarkNonProd account exists and is accessible
Section titled “REQ-EXT-002: PostmarkNonProd account exists and is accessible”A Postmark account named PostmarkNonProd exists, on the Platform plan, with 2FA enabled on the owner mailbox. An account-level API token has been generated and stored in 1Password under Arda-SystemsOAM/Postmark-NonProd (field: credential). The token authenticates successfully against the Postmark Account API.
REQ-EXT-003: 1Password vault Arda-SystemsOAM accessible to operators and CI
Section titled “REQ-EXT-003: 1Password vault Arda-SystemsOAM accessible to operators and CI”The Arda-SystemsOAM 1Password vault exists and is accessible:
- To human operators via the 1Password desktop application (DesktopAuth biometric unlock).
- To CI workflows via the
IAC-SCRIPTS Service Account Token1Password service account, scoped read-only to this vault.
REQ-EXT-004: 1Password items populated
Section titled “REQ-EXT-004: 1Password items populated”All 1Password items the project will reference are present in Arda-SystemsOAM:
Postmark-Prod— fieldcredentialholds the PostmarkProd account-level API token.Postmark-NonProd— fieldcredentialholds the PostmarkNonProd account-level API token.IAC-SCRIPTS Service Account Token— fieldcredentialholds the 1Password service-account token.Free Kanban Generator Postmark— placeholder item created (populated by Phase 3 with the Free Kanban Tool’s Postmark server token; Phase 1 only declares its existence).
REQ-EXT-005: Account-token authentication contract
Section titled “REQ-EXT-005: Account-token authentication contract”Each Postmark account-level API token authenticates Postmark Account API calls via the X-Postmark-Account-Token HTTP header per Postmark’s published authentication model. Phase 1 does not introduce any wrapping or transformation of the token between 1Password and the Postmark API.
REQ-PLAT: platform/ reference declarations
Section titled “REQ-PLAT: platform/ reference declarations”REQ-PLAT-001: platform/postmark-service.ts declares Postmark accounts and API surface
Section titled “REQ-PLAT-001: platform/postmark-service.ts declares Postmark accounts and API surface”The TypeScript file infrastructure/src/main/cdk/platform/postmark-service.ts exports:
- A
PostmarkAccounttype with at leastname: stringandcredentialReference: stringfields. - Constants
POSTMARK_PROD_ACCOUNTandPOSTMARK_NONPROD_ACCOUNTof typePostmarkAccountpopulated with the liveop://references. - A constant for the Postmark Account API base URL (e.g.,
POSTMARK_ACCOUNT_API_BASE_URL = "https://api.postmarkapp.com"). - A constant identifying the Postmark plan Arda commits to (e.g.,
POSTMARK_PLAN = "Platform"). - A version-pin metadata block: a structured constant naming the Postmark API surface assumptions captured in the API observations note (see
REQ-DOC-002). Form: a typed object with at least the observation-note URL and the API surface’s freshness date. The exact shape is open during specification.
REQ-PLAT-002: platform/one-password.ts declares all 1Password references
Section titled “REQ-PLAT-002: platform/one-password.ts declares all 1Password references”The TypeScript file infrastructure/src/main/cdk/platform/one-password.ts exports:
- A constant
OAM_VAULT = "Arda-SystemsOAM". - Typed constants for each 1Password item referenced anywhere by the project:
POSTMARK_PROD_ITEM— thePostmark-Proditem, including itsop://reference and the field name (credential).POSTMARK_NONPROD_ITEM— analogous forPostmark-NonProd.IAC_SCRIPTS_SERVICE_ACCOUNT_ITEM— analogous forIAC-SCRIPTS Service Account Token.FREE_KANBAN_POSTMARK_ITEM— analogous forFree Kanban Generator Postmark(consumed by Phase 3; Phase 1 declares the typed reference up front).
The constants are immutable string-bearing objects; no functions, no side effects.
REQ-PLAT-003: No string-literal references to 1Password items elsewhere in the repository
Section titled “REQ-PLAT-003: No string-literal references to 1Password items elsewhere in the repository”After Phase 1, no other file in infrastructure/src/main/cdk/ constructs op://Arda-SystemsOAM/... strings inline; consumers import the typed constants from platform/one-password.ts and platform/postmark-service.ts.
(Note: this is a forward-looking requirement enforced by review; Phase 1 itself only ships the constants. Subsequent phases that introduce consumers must satisfy this requirement.)
REQ-CI: CI surface
Section titled “REQ-CI: CI surface”REQ-CI-001: OP_SERVICE_ACCOUNT_TOKEN provisioned
Section titled “REQ-CI-001: OP_SERVICE_ACCOUNT_TOKEN provisioned”The GitHub Actions repository secret OP_SERVICE_ACCOUNT_TOKEN is provisioned in Arda-cards/infrastructure. Its value matches the credential field of the IAC-SCRIPTS Service Account Token 1Password item (or is bound to it by rotation procedure).
REQ-CI-002: Drift-detection workflow exists and runs
Section titled “REQ-CI-002: Drift-detection workflow exists and runs”A GitHub Actions workflow exists at .github/workflows/external-resources-drift.yml (filename indicative; final name in specification.md). The workflow:
- Runs on a monthly schedule (
cron). - Authenticates to 1Password using
OP_SERVICE_ACCOUNT_TOKEN. - Resolves every
op://reference declared inplatform/one-password.tsandplatform/postmark-service.ts, asserting each returns a non-empty value. - For each Postmark account whose credential resolves, issues a benign Postmark Account API call (e.g.,
GET /servers?count=1&offset=0) and asserts a 2xx response. Bothcountandoffsetare required parameters of the Account API; omitting either returns HTTP 422. - On any failure, opens a GitHub issue with a fixed label set (
drift,phase-1,external-resources) containing the run URL and a brief observed-vs-declared diff.
REQ-CI-003: Drift-detection workflow uses no Postmark token as a GitHub Actions secret
Section titled “REQ-CI-003: Drift-detection workflow uses no Postmark token as a GitHub Actions secret”The workflow does not read any Postmark account-level token from a GitHub Actions secret. Postmark account tokens are resolved at workflow runtime via the 1Password SDK using OP_SERVICE_ACCOUNT_TOKEN.
REQ-OPS: Operator runbook and sign-off
Section titled “REQ-OPS: Operator runbook and sign-off”REQ-OPS-001: Canonical operator runbook lives in the documentation repo
Section titled “REQ-OPS-001: Canonical operator runbook lives in the documentation repo”An operator runbook page exists at current-system/oam/postmark-service/operator-runbook.md. It describes the manual steps required to provision the external resources covered by REQ-EXT-001 — REQ-EXT-005, in the order an operator should perform them.
REQ-OPS-002: Runbook includes troubleshooting
Section titled “REQ-OPS-002: Runbook includes troubleshooting”The runbook includes a per-step troubleshooting table (symptoms / causes / fixes) covering the most likely failure modes of each manual step (Postmark account creation, 2FA enablement, token generation, 1Password item creation).
REQ-OPS-003: Sign-off captured in the runbook itself
Section titled “REQ-OPS-003: Sign-off captured in the runbook itself”The runbook records operator sign-off (operator name, date, deviations) in a designated section. There is no machine-readable parsing of the sign-off; the runbook is a human document.
REQ-OPS-004: No infrastructure-side parser-enforced gate
Section titled “REQ-OPS-004: No infrastructure-side parser-enforced gate”Code in the infrastructure repository does not parse any operator-runbook file as a runtime gate (in contrast to the prior Phase-0 parser-gated HUMAN-STEPS.md pattern). Confidence that the manual steps were performed is established by:
- The operator’s sign-off in the runbook (audited at PR review time).
- The drift-detection workflow asserting that the resulting external state is reachable.
REQ-DOC: Documentation deliverables
Section titled “REQ-DOC: Documentation deliverables”REQ-DOC-001: Postmark service overview
Section titled “REQ-DOC-001: Postmark service overview”A page exists at current-system/oam/postmark-service/index.md describing:
- Postmark account topology:
PostmarkProd(production-bound) andPostmarkNonProd(development / sandbox) and the partitions each serves. - Credential storage: 1Password as the system of record; per-partition Secrets Manager copy at runtime (forward-references Phase 4 work); ESO projection to pods.
- OAM model: the Postmark Console as the primary operator surface for delivery diagnostics; Arda-side telemetry as a supplement.
- Drift-detection cadence and failure-handling.
REQ-DOC-002: Postmark API observations note
Section titled “REQ-DOC-002: Postmark API observations note”A page exists at current-system/oam/postmark-service/postmark-api-observations.md capturing Arda’s design intent against the Postmark API surface. Required content:
- Authentication models for both API and Webhooks. Specifically: the Account Token vs Server Token distinction and where each is used; the Bearer-token convention for webhooks; how Arda’s in-component validation conforms.
- Error model: how Postmark expresses errors (HTTP status +
ErrorCode+Message); which codes Arda treats as transient (retryable) vs permanent. - Idempotency conventions Arda relies on (e.g., create-or-skip on server / domain CRUD).
- Retry policy contract: Arda’s bounded retry with exponential backoff on 5xx / network failures.
- Webhook payload shapes: structural assumptions Arda’s webhook handler depends on.
- Version-pin assumptions: which Postmark API surface revision Arda is committing to; the
freshness dateafter which a re-validation is recommended.
REQ-DOC-003: Note depth bounded
Section titled “REQ-DOC-003: Note depth bounded”REQ-DOC-002 is a brief design-intent note (target ~3 pages). It cross-links to Postmark’s official documentation for the surface itself; it does not duplicate Postmark’s reference material.
REQ-DOC-004: Cross-link from Phase 1 to documentation pages
Section titled “REQ-DOC-004: Cross-link from Phase 1 to documentation pages”The Phase 1 deliverables index references current-system/oam/postmark-service/index.md as the operator entry point. The page is discoverable from current-system/oam/index.md (whichever index page exists or is added in this phase).
Out of scope of Phase 1
Section titled “Out of scope of Phase 1”Captured for clarity; not requirements.
- Postmark server creation (handled by Phase 3 for Free Kanban Tool, Phase 4 for partition tenants).
- Per-partition Secrets Manager entries (Phase 4).
- Per-tenant encryption keys (Phase 4).
- Decisions about retirement or replacement of the
tools/gha-secret.tstransition utility (out of scope of this project). - Helm chart additions (operations component, Phase 5b).
Copyright: © Arda Systems 2025-2026, All rights reserved