Skip to content

Email Integration -- Current-System Documentation Retrofit (Revision 1)

A project-completion deliverable. After the email integration’s implementation lands across all repositories, the current-system/ documentation tree (and the related domain/information-model/ tree) must be updated to reflect the deployed state. Aligned with the Revision 1 goal.md acceptance criterion #10 (Documentation is current) and the related runtime-design-review.md proposal under reviews/R1/.

Revision 1 note. Supersedes the prior current-system retrofit (now superseded by this document). Substantive changes:

  • Inventory expanded to cover the Corporate Resource Group as a runtime instance group, the arda.ardamails.com zone, the Postmark service overview and API observations note, the Postmark thin-wrapper constructs, the tools/gha-secret.ts transition utility, and drift-detection conventions.
  • Authentication retrofit: existing pages that reference API-gateway-level authorisers must be reconciled with the in-component (Ktor) authentication scheme adopted by the email service.
  • Phase numbering removed. Retrofit happens once at project completion (no “after Phase 6” — the project’s final phase is 5b, but the retrofit trigger is project-completion, not a specific phase).
  • Architecture reconciliation: the existing current-system/architecture/ tree is enumerated as a touchpoint; pattern descriptions for instance groups, declarative-by-default operator scripts, third-party-API thin-wrappers, and AWS-account-vs-instance-group decoupling are aligned with the practices adopted in this project.
  • Per-decision references updated: DQ-R1-NNN series joins the existing DQ-001..013 and DQ-201..208 series.

current-system/ describes what is, not what was designed. Retrofit is a snapshot of the deployed system. Any divergence between the design documents (under roadmap/in-progress/email-integration/revision-1/) and the implementation is resolved in favour of the implementation when retrofitting; significant divergences are recorded in the project’s decision log first.

Retrofit happens once at project completion as part of the standard Arda lifecycle (per CLAUDE.md Project Workflow § Project Lifecycle, step 4). No incremental updates during implementation phases.

The shop-access functional domain sits at the bottom of the dependency hierarchy (see functional/index.md; the functional-tld.drawio.svg diagram in public/assets/diagrams/ is rendered there). The retrofit reaffirms this — the email module must not introduce upward dependencies into procurement, resources, or reference-data domains.

The Corporate Resource Group is a new instance group introduced by this project (founding member: Free Kanban Tool). It does not sit in the current-system/functional/ tree alongside Application Runtime modules; it is documented under current-system/oam/corporate/ (and as part of the runtime instance-group taxonomy under current-system/runtime/). The functional domain hierarchy is unaffected by Corporate.

The pages below are identified by:

  • Grepping the current-system/ tree for shop-access references and for two reference modules: the existing pdfRender module (similar location, different shape) and persistence-bearing modules Item (functional/reference-data/item/index.md) and Orders (functional/procurement/, with order-lifecycle.md, order-line-management.md, order-implementation-notes.md, etc.).
  • Surveying the new touchpoints introduced by Revision 1: instance groups, Corporate Resource Group, Postmark service, Postmark thin-wrappers, drift detection, and the tools/ operator-utility convention.

The pdfRender module has no persistence, no information model, and no lifecycle workflows, so it does not surface most of the touchpoints a stateful module needs. The Item and Orders precedents are a closer fit for the email module’s documentation footprint.

Each row will be revisited at retrofit time; some may be no-ops if the design intent already matches the implementation.

PathPurposeModel after
email-module.mdModule reference page: purpose, integrations, block diagram, public interface (EmailConfigurationService, EmailJobService), key types, HOCON configuration, ESO secret bindings, Helm contributions. Note: in-component authentication for email-service routes (no API-gateway authoriser).shop-access/pdf-render-module.md (structure) and reference-data/item/index.md (persistence-bearing additions: bitemporal mention, DataAuthority pattern reference, persistence block diagram nodes)
email-configuration-lifecycle.mdProvision flow (Scenario 1), bounded DNS verification (Scenarios 1b.1/.2/.3), lock/unlock (Scenario 6), decommission (Scenario 4). Sequence diagrams + UC referencesprocurement/order-lifecycle.md
email-job-lifecycle.mdSend flow (Scenario 2), webhook event handling (Scenario 3), cancel (Scenario 5.a), resend (Scenario 5.b). Sequence diagrams + UC referencesprocurement/order-lifecycle.md
email-implementation-notes.mdData-model summary (entity fields, status enums); persistence schema (DDL highlights for email_configuration and email_job); bitemporal application policy (per DQ-240.a / DQ-250.c resolution); cross-Universe rule application; encryption envelope handling; cross-cutting links (cross-cutting-design.md OAM, audit). Implementation-internal notes that don’t belong in the public module pageprocurement/order-implementation-notes.md
index.md (optional)Domain index for shop-access modules. Currently absent; consider creating to introduce both pdf-render and email togetherNone (new)
PathPurposeModel after
index.mdPostmark service overview: account topology (PostmarkProd / PostmarkNonProd), credential storage (1Password as system of record; per-partition Secrets Manager; ESO-projected at runtime), the Postmark Console as the primary OAM surface, drift-detection cadence and findings.New page; sibling-of-similar-shape under current-system/oam/
postmark-api-observations.mdPostmark API surface design intent, captured during Revision-1 implementation: authentication models for both API and Webhooks, error model, idempotency conventions, retry policy, webhook payload shapes, version-pin assumptions. Written so future implementors do not re-derive these from third-party documentation.New page; goal.md acceptance criterion #9
free-platform-server.mdOperational reference for the Free Kanban Tool’s Postmark server (the Corporate Resource Group’s founding consumer): server identity, sending domain (freekanban.arda.ardamails.com), token storage location (Free Kanban Generator Postmark 1Password item), drift assertions specific to this server.None (new); cross-references current-system/oam/corporate/ for the Corporate-instance view
PathPurposeModel after
index.mdCorporate Resource Group overview: purpose, instance-group placement (peer to Application Runtimes), founding member (Free Kanban Tool), AWS-account placement note (Root account for now), reserved-name discipline.New page
free-kanban-tool.mdFree Kanban Tool operational reference: sending domain, Postmark server identity, DNS records (DKIM TXT + Return-Path CNAME), CDK construct identity, Corporate CLI invocation, drift-detection workflow link.New page
PathPurposeModel after
drift-detection.mdConvention for periodic drift / integration tests. What “drift” means in each resource category; where the tests live (per-script CI workflow, scheduled trigger); how failures are surfaced (auto-opened GitHub issue with a fixed label set). Catalogue of current drift checks: Corporate Postmark, future Application Runtime Postmark, future 1Password vault assertion.New page; informed by runtime-design-review.md § 5.5
operator-scripts.mdGeneralised contract for operator-facing scripts (robust, self-defined, self-documenting). Catalogue of principal operator scripts: amm.sh (existing), deploy-root.sh (existing), tools/corporate-cli.ts (new). Distinction between principal scripts and tools/ ad-hoc utilities (e.g., tools/gha-secret.ts).New page; informed by runtime-design-review.md § 5.3 / § 5.4
PathPurposeModel after
instance-groups.mdTop-level taxonomy of instance groups: Application Runtimes (with pointer to platform-structure.md), Platform-level (Root, OAM), Corporate (with pointer to current-system/oam/corporate/). Naming and lifecycle conventions per group. AWS-account-vs-instance-group decoupling note.New page; informed by runtime-design-review.md § 5.6
PathPurposeModel after
external-resources.mdHow external resources (Postmark accounts, 1Password vaults, GitHub organisation, etc.) are represented in the infrastructure repository. Distinction between referenced (Arda does not create) and API-managed (Arda creates / reconciles via API). Worked examples: Postmark accounts, 1Password vaults.New page; informed by runtime-design-review.md § 5.1
instance-modeling.mdHow the instances/ directory is structured. Cross-instance reference convention: direct TS import for compile-time constants; importValues(forElement) pattern for runtime-resolved values. platform/ vs instances/ distinction.New page; informed by runtime-design-review.md § 5.2
tools.mdConvention for the tools/ directory: ad-hoc operator utilities (e.g., tools/gha-secret.ts). Inclusion criteria; relationship to instance-driven CLIs.New page; informed by runtime-design-review.md § 5.4
root.mdRoot-instance reference: ardamails.com zone, NS-delegation table to other instance groups, the existing root DNS structure. Sister-page to current-system/oam/corporate/index.md.New page; informed by runtime-design-review.md § 5.7
failure-mode-analyses/Folder split from the existing iac/failure-mode-analysis.md (one file per analysed script: amm.md, plus corporate-cli.md and postmark-foundations.md as their analyses are produced). New index.md for the folder.The existing single-file analysis becomes amm.md inside the folder
PathPurposeModel after
domain/information-model/<category>/email-configuration.mdDomain-level entity definition: class diagram, lifecycle, reference relationships, bitemporal classification. Category TBD at retrofit time — candidates: operations/ (configured tenant capability), assets/ (durable per-tenant resource), or a new shop-access subsection. EmailConfiguration is not transactional; it’s a tenant-scoped resource whose lifecycle is provisioning + verification + decommission.transactions/purchase-orders.md (class diagram + relationships pattern); category-level index.md files for the chosen home
domain/information-model/transactions/email-job.mdDomain-level entity definition: EmailJob is a transactional record (submit → status progression → terminal).transactions/purchase-orders.md
PathUpdate
current-system/functional/index.mdConfirm the shop-access section’s “Email” bullet matches the delivered module’s purpose; add a link to shop-access/email-module.md (and to the lifecycle / implementation-notes pages) next to the existing shop-access/pdf-render-module.md link.
current-system/functional/api-endpoint-catalog.mdAdd the three email module endpoints under a new sub-section: /v1/shop-access/email/email-configuration/*, /v1/shop-access/email/email-job/*, /v1/shop-access/email/postmark-events. Verify against the deployed OpenAPI. Note that authentication is in-component (Ktor) for each route — no API-gateway authoriser dependency.
current-system/architecture/patterns/general/naming-conventions.mdConfirm any module-naming examples that include shopAccess — add shopAccess.email if the file enumerates modules. Reconcile with the reserved-name discipline (arda and partition names reserved at the ardamails.com level).
current-system/architecture/structure/viewpoint-mapping.mdIf shop-access is enumerated, add the email module entry. If instance-group taxonomy is part of the viewpoint mapping, reflect Application Runtime, Platform-level, and Corporate as peer instance groups.
current-system/architecture/structure/design-framework.mdVerify any module-tier examples accommodate the email module’s L1/L2/L3/L4 layering. Add (or reconcile) a section on third-party-API thin-wrappers as a construct shape distinct from L2 / L3 CDK Constructs.
current-system/architecture/structure/module-concept.mdVerify the documented module-concept handles the email module’s two-service shape (EmailConfigurationService + EmailJobService in one module).
current-system/architecture/patterns/Reconcile pattern descriptions with the practices adopted in this project. At minimum: declarative-by-default operator scripts, cross-instance reference convention (TS import for constants; importValues for runtime-resolved values), thin-wrapper construct shape (platform/constructs/<provider>/), AWS-account-vs-instance-group decoupling. New worked examples may be drawn from this project.
current-system/oam/service-monitoring.mdDocument the email-module metrics (email_send_total{tenant, status}, email_provisioning_duration_seconds, etc.) and operator alerts (email_configuration_pending_stale, email_configuration_provisioning_stuck, drift-detection auto-issue) per the cross-cutting design. Cross-link the Postmark Console as the primary OAM surface for delivery diagnostics.
current-system/oam/security/secrets-vault.mdIf existing entries enumerate ESO-managed secrets, add {fqn}-I-EmailPostmarkAccountToken and {fqn}-I-EmailEncryptionKey. Add the OP_SERVICE_ACCOUNT_TOKEN GitHub Actions secret as a related-but-separate credential surface.
current-system/oam/security/Reconcile any pages on credential management with the 1Password-as-system-of-record pattern. The Free Kanban Generator Postmark 1Password item is a worked example of a credential never persisted to AWS Secrets Manager.
current-system/runtime/dns-structure.mdAdd the ardamails.com mail root, the arda.ardamails.com Corporate sending zone, and per-partition mail sub-zones; confirm the diagram matches the deployed Route53 hierarchy. Capture the NS-delegation pattern from Root to each peer zone.
current-system/runtime/index.mdIf the runtime principles page authored in this project’s planning has not yet landed under current-system/, the retrofit incorporates it (or merges its content). The principle list (1: repo as platform reference; 2: IaC unit-tested; 3: operator-driven scripts; 4: drift detection; 5: instance groups; 6: code follows the CDK hierarchy) is the canonical version.
current-system/runtime/iac/index.mdUpdate the IaC tools listing to include the third-party-API SDKs in use (Postmark client, GitHub Octokit, 1Password SDK). Update the directory map to reflect tools/ and the new instances/Corporate/, instances/Root/ directories. Reflect the platform/constructs/<provider>/ thin-wrappers as a construct category sibling to xgress/, compute/, etc.
current-system/runtime/iac/apps.mdGeneralise from “Infrastructure + Partition” Apps to “one or more top-level resources for a specific instance.” Note that some instances (Corporate, Root) deploy zero AWS-CDK stacks but still have an App-equivalent.
current-system/runtime/iac/constructs.mdReconcile with the third-party-API thin-wrapper convention at platform/constructs/<provider>/. The thin-wrappers follow a leaner shape than full CDK L2 constructs.
current-system/runtime/iac/stacks.mdAdd a section on Stacks for third-party services (where the exportDefinition / exportValues machinery is replaced by a typed result object written to 1Password or a context file).
current-system/runtime/iac/orchestration.mdRename to scope explicitly to amm.sh. Move the operator-script principles (operator-driven, robust, self-defined, self-documenting) into the new current-system/oam/operator-scripts.md page.
current-system/runtime/platform-structure.mdRe-frame the document title and opening to “Application Runtime Platform Structure”; add a final section pointing to current-system/runtime/instance-groups.md for the broader instance-group taxonomy (Root, OAM, Corporate as peers).
current-system/runtime/environments.mdSame re-framing — this page covers Application Runtime environments only. Add a leading note that Corporate-instance “environments” exist (e.g., the production Free Kanban Tool) but follow a different shape.
current-system/data-model/index.mdCurrently a stub. If the page is fleshed out before retrofit, ensure email entities are enumerated; otherwise no action.
domain/information-model/<chosen-category>/index.mdWhen email-configuration.md and email-job.md are added (above), update the category index page to list them in the entity table.
domain/information-model/index.mdVerify the top-level information-model TOC reflects the new entities; usually no-op if categories are auto-indexed by Starlight.
PathReason to check
current-system/architecture/patterns/persistence/data-authority-pattern.mdVerify the cross-Universe rule documented during this project (no FK across services; per-service inTransaction) is still accurate after the email module’s EmailConfigurationUniverse and EmailJobUniverse are deployed.
current-system/architecture/patterns/persistence/bitemporal-persistence.mdVerify the bitemporal pattern application documented for the email module (per DQ-240.a / DQ-250.c) is consistent with the canonical pattern. Special case: the EmailJob webhook events use Postmark wire timestamp as effective_as_of while recorded_as_of = now() — if novel for Arda, consider a short note.
current-system/architecture/patterns/persistence/universe-design.mdVerify the cross-Universe rule + per-service Universe ownership rule documented during this project is accurately reflected.
current-system/architecture/patterns/persistence/parent-child-persistence.mdNo-op expected; email module has no parent-child entity relationship.
current-system/architecture/patterns/persistence/table-mappings.mdVerify if the page enumerates table-to-entity mappings; if so, add email_configuration and email_job.
current-system/architecture/patterns/persistence/exposed-patterns.mdVerify if any patterns documented here changed during the email module implementation.
current-system/context/system-context.mdVerify Postmark is now listed as an integrated external system; add 1Password as an integrated external system if it is not already enumerated (the email integration introduces 1Password as a first-class external resource consumed by the IaC pipeline).
current-system/context/cloud-providers.mdVerify Postmark is listed alongside other cloud / SaaS providers.
current-system/runtime/url-naming.mdVerify the /v1/shop-access/email/* path scheme is consistent with the documented URL convention. Confirm the arda.ardamails.com and freekanban.arda.ardamails.com naming is consistent with the DNS-naming convention.
current-system/runtime/network-routing.mdVerify the inbound auth narrative is consistent with the in-component (Ktor) authentication adopted by the email service; if the page asserts API-gateway-level authorisers as universal, reconcile.
current-system/runtime/mtls.mdNo-op expected; the email service uses HTTPS over the existing routing path. Verify nothing in this page implies the email module requires mTLS.
domain/information-model/meta/entity-references.mdVerify the cross-Universe reference shape used by EmailJob.EMAIL_CONFIG_REFERENCE_* (eId + rId + cached display fields, no FK) is accurately reflected as a worked example.
domain/information-model/common/identity.mdNo-op expected; email entities use the standard EntityId / Binding model.
PathUpdate
public/assets/diagrams/functional-tld.drawio.svgAlready mentions “Email” as a Shop Access module (verified). No update expected unless module subdivision changes during implementation.
public/assets/diagrams/mail-dns-structure.drawio.svgVerify it matches the deployed Route53 hierarchy. The Revision-1 hierarchy has ardamails.com (Root), arda.ardamails.com (Corporate), and per-partition mail sub-zones ({partition}.ardamails.com). Update the diagram if it predates the Corporate split.
public/assets/diagrams/instance-groups.drawio.svg (new)New diagram showing Application Runtimes, Platform-level (Root, OAM), and Corporate as peer instance groups; the AWS-account placement note inside the Corporate box.
Class diagram(s) inside domain/information-model/<category>/email-configuration.md and transactions/email-job.mdNew PlantUML class diagrams modeled after transactions/purchase-orders.md. Validate via the plantuml-diagrams skill at retrofit time.

The original inventory (R1) was anchored on the pdfRender module, which has no persistence and no internal information model. R2 expanded the inventory after observing how persistence-bearing modules (Item, Orders) are documented:

  • Per-behavior pages. Major workflows (provisioning lifecycle, send lifecycle) get their own pages alongside the module-level page, mirroring procurement/order-lifecycle.md, order-creation.md, order-line-management.md.
  • Implementation-notes page. Captures schema-level + bitemporal-application choices that don’t belong in the public module page, mirroring procurement/order-implementation-notes.md.
  • Domain information-model entries. Persisted entities get domain-level entity definitions under domain/information-model/<category>/. Currently transactions/purchase-orders.md is the worked example; email-job.md follows the same pattern.

EmailConfiguration’s classification (operations/ vs assets/ vs new) is left for retrofit-time decision because the canonical placement of “configured tenant capability” entities is not yet established in the domain model.

Revision 1 adds three additional precedent shifts:

  • Instance-group documentation. The Corporate Resource Group is documented under current-system/oam/corporate/ (operational view) and under current-system/runtime/instance-groups.md (taxonomy view). The pattern can be reused for future instance groups (OAM when defined; future Corporate sub-groups).
  • Third-party-API documentation. Postmark is the first third-party API for which Arda creates resources via IaC; current-system/oam/postmark-service/ (operational view) and current-system/runtime/iac/external-resources.md (pattern view) are the worked examples.
  • Drift-detection documentation. A new page current-system/oam/drift-detection.md captures the convention; the Corporate Postmark drift workflow is the founding instance.
  1. Walk the inventory above. For each row, decide create / update / no-op based on the deployed implementation.
  2. For each create / update: produce a draft, then run make pr-checks in the documentation worktree.
  3. Move project documents from roadmap/in-progress/email-integration/ to roadmap/completed/email-integration/ per CLAUDE.md Project Lifecycle step 4. Note that the original (pre-revision) and revision-1 sub-tree both move; the relationship between them is preserved.
  4. Update internal links in moved documents (e.g., scenario references) if the move changes relative paths.
  5. Open a single PR (or one per repo if more than one repository is touched) with the standard CHANGELOG entries.
  • Re-litigating design decisions. The decision log is frozen at project completion; new questions surfaced during retrofit are recorded as follow-ups.
  • Refactoring the current-system/ structure beyond the touchpoints inventoried above. Larger restructuring is a separate effort.
  • Cross-domain documentation (e.g., procurement consumers of the email module). Procurement’s adoption is a downstream project that owns its own documentation updates.
  • Documentation for OAM capabilities outside the email integration (the wider OAM tooling roadmap is separate).