Phase 4 -- Runtime Platform Updates -- Analysis
A capability-oriented bridge between ../goal.md (project intent) and the downstream requirements.md / specification.md / verification.md / exports.md (the contract) and the ../plan/ tree (the run-level execution machinery — evaluation.md, choreography.md, per-run plans).
1. Executive Summary
Section titled “1. Executive Summary”Phase 4 enables four Application Runtime partitions (prod, demo, dev, stage; kyle excluded per DQ-R1-021) to authoritatively send email on a per-partition mail sub-zone of ardamails.com, with the per-partition AWS infrastructure that Phase 5b’s Email module will consume at runtime.
- Fan-out scope: 4 partition-email stacks across 2 AWS accounts. Alpha001 carries
prod+demo; Alpha002 carriesdev+stage. Each account hosts one Infrastructure and two Partitions percurrent-system/runtime/platform-structure.md. - Upstream dependencies: Phase 2 (
ardamails.comzone +AllowCreatingNSRecordsRole) and Phase 3 (PostmarkSendingDomainthin-wrapper,DnsEmailRecordsxgress construct,corporate-clireusable utilities). - Downstream consumers: Phases 5a (consumes nothing from Phase 4) and 5b (consumes SM secret ARNs and IAM role ARNs via the STS chain).
- Rollout order:
dev→stage→demo→prod, operator-enforced viaamm.sh(DQ-R1-021).
2. Dispatch — how to read this document
Section titled “2. Dispatch — how to read this document”Each Capability section (§4–§11) is self-contained: read one without paging through the others. Implementation Groups (§12) and the DAG (§13) are the execution view: read them when planning PR sequencing.
| Looking for… | Read |
|---|---|
| Goal-to-Capability traceability (which goal item is covered where) | §3 |
| What Phase 4 changes for DNS sub-zones / records | §4 (C-DNS-Authority) |
| Postmark Sender Signature mechanics + token delivery (δ.1) | §5 (C-Postmark-Sending) |
Encryption-key SM secret (envelope design lives in email-server-key-encryption.md) | §6 (C-EmailKey-At-Rest) |
| IAM role construct reuse + Root no-drift guard | §7 (C-Runtime-DNS-Writes) |
| Fallback role for SM versions older than AWSPREVIOUS | §8 (C-Fallback-Decryption) |
| Drift workflow shape and probe logic | §9 (C-Drift-Detection) |
amm.sh partition-mail steps + minimal corporate-cli extraction | §10 (C-Operator-Surface) |
| Per-partition mail documentation pages | §11 (C-Documentation) |
| Execution order, PR sequencing, DAG | §12 + §13.1–§13.2 |
When amm.sh is ready and which invocations create which resources | §13.3 |
| Capability readiness criteria | §13.4 |
| Out-of-scope concerns | §14 |
| Decisions made and rationale | §15 + ../../decision-log.md |
| Spec / verification carry-forwards | §16 |
3. Goal-to-Capability map
Section titled “3. Goal-to-Capability map”Each goal-item is owned by exactly one Capability. No goal-item is unowned.
Goal item (../goal.md) | Capability |
|---|---|
| Success criterion #1 (sub-zones live and delegated) | C-DNS-Authority |
| Success criterion #2 (deploy-time Postmark credential resolution) | C-Postmark-Sending |
| Success criterion #3 (encryption-key secret + ESO) | C-EmailKey-At-Rest |
| Success criterion #4, role (a) DNS-provisioning | C-Runtime-DNS-Writes |
| Success criterion #4, role (b) SM-fallback | C-Fallback-Decryption |
Success criterion #5 (arda-nonprod first Signature verified) | C-Postmark-Sending (specifically G-POSTMARK-5) |
Success criterion #6 (runtime-platform-drift covers partition surfaces) | C-Drift-Detection |
Scope bullet “Operator surfaces integrated into amm.sh” (DQ-R1-022) | C-Operator-Surface |
| Deliverable rows 11 + 11b (documentation) | C-Documentation |
Success criteria #7 + #8 (decision-log + phases.md patches) | Meta — this analysis + ../../decision-log.md |
PART A — Capabilities
Section titled “PART A — Capabilities”Each Capability section follows the same five-subsection structure: Purpose & linkage, Already in place, What Phase 4 adds (gap rows tagged → Group), What’s reused, Out-of-scope edges.
4. C-DNS-Authority
Section titled “4. C-DNS-Authority”4.1 Purpose & linkage
Section titled “4.1 Purpose & linkage”Each partition becomes a DNS authority for {partition}.ardamails.com — owning SPF and DMARC policy and the namespace under which Postmark will publish DKIM records. Supports goal success criterion #1.
4.2 Already in place
Section titled “4.2 Already in place”| Foundation | Source |
|---|---|
ardamails.com root zone | Phase 2; exported arda-ardamails-zone |
AllowCreatingNSRecordsRole (Root account) | Phase 2; reused by Phase 4 for NS-delegation only (distinct from the per-partition DNS-records role in §7) |
WriteNSRecordsToUpstreamDns construct | Phase 2; constructs/xgress/write-ns-records-to-upstream-dns.ts |
DnsZone xgress construct | Phase 3 (renamed from Route53HostedZone); constructs/xgress/dns-zone.ts |
4.3 What Phase 4 adds
Section titled “4.3 What Phase 4 adds”| Gap | Description | → Group |
|---|---|---|
| G-DNS-1 | r53.PublicHostedZone per partition (prod.ardamails.com, demo.ardamails.com in Alpha001; dev.ardamails.com, stage.ardamails.com in Alpha002). RemovalPolicy.RETAIN. Exported as ${publishingPrefix}-API-PartitionMailZoneId and ${publishingPrefix}-API-PartitionMailZoneName (zone-name needed for SDK ListHostedZonesByName-style lookups and for record-set FQDN composition). The -API- marker is correct because the consumer is the operations Helm chart (non-CDK), per the convention in cdk-infrastructure.md § Export naming. Phase 3’s Corporate-I-MailZoneId used -I- because its consumer was a sibling CDK stack (FreeKanbanToolMailDns); Phase 4 has no such CDK consumer (operations is not CDK-deployed). Models image-storage.ts, where every export uses -API- for the same reason. | G-B |
| G-DNS-2 | NS-delegation record per partition in ardamails.com via WriteNSRecordsToUpstreamDns. CR Lambda assumes AllowCreatingNSRecordsRole (Phase 2). | G-B |
| G-DNS-3 | SPF v=spf1 include:spf.mtasv.net ~all TXT record at each partition apex. | G-B |
| G-DNS-4 | DMARC p=quarantine; sp=quarantine; rua=mailto:dmarc-reports@arda.cards at _dmarc.{partition}.ardamails.com (per pre-design follow-up C2: reuse Corporate mailbox; no per-partition mailboxes). | G-B |
| G-DNS-5 | Reserved-name list extension: prod, demo, dev, stage, kyle reserved at the ardamails.com level so future tenants cannot appropriate partition names as slugs (per pre-design follow-up B4: extend the Phase 3 mechanism used to reserve arda). Workspace-scoped (no per-partition fan-out) — landed in PR #1 (G-A) alongside the other workspace refactors. | G-A |
4.4 What’s reused
Section titled “4.4 What’s reused”DnsZone, WriteNSRecordsToUpstreamDns, AllowCreatingNSRecordsRole (Root account, NS-delegation path only). Reserved-name mechanism from Phase 3.
4.5 Out-of-scope edges
Section titled “4.5 Out-of-scope edges”- DKIM TXT and Return-Path CNAME records under partition sub-zones → C-Postmark-Sending (their values are produced by the Postmark API at deploy time).
- Per-tenant DNS records → Phase 5b.
- Apex SPF/DMARC on the root
ardamails.comzone → out of project. kyle.ardamails.comsub-zone → deferred (DQ-R1-021).
5. C-Postmark-Sending
Section titled “5. C-Postmark-Sending”5.1 Purpose & linkage
Section titled “5.1 Purpose & linkage”Each partition can authoritatively send email from its own Postmark Sender Signature with a distinct DKIM signing key. Supports goal success criteria #2 (deploy-time credential resolution) and #5 (arda-nonprod unlock).
5.2 Already in place
Section titled “5.2 Already in place”| Foundation | Source |
|---|---|
PostmarkSendingDomain thin-wrapper | Phase 3; platform/constructs/postmark/sending-domain.ts |
sendingDomainPlacement() typed FQDN composer | Phase 3 |
DnsEmailRecords xgress construct (DKIM TXT + Return-Path CNAME emitter) | Phase 3 |
POSTMARK_PROD_ACCOUNT + POSTMARK_NONPROD_ACCOUNT typed references | Phase 1; platform/postmark-service.ts |
arda-prod Postmark account approval | External (Postmark Support ticket #11236087, approved 2026-05-11). prod + demo rollouts have no external prerequisite. |
arda-nonprod Postmark account approval | Pending (ticket #11236089). Unlocked by G-POSTMARK-5 (dev partition’s first non-prod Sender Signature). |
5.3 What Phase 4 adds
Section titled “5.3 What Phase 4 adds”| Gap | Description | → Group |
|---|---|---|
| G-POSTMARK-1 | postmarkCredentialOpReference(partition: PartitionId): string in platform/postmark-service.ts returning the op://Arda-{Env}OAM/Postmark/credential reference. Consumed by amm.sh (via op read); CDK has no 1Password dependency. | G-A |
| G-POSTMARK-2 | Partition Postmark Sender Signature per partition (PostmarkSendingDomain instantiated per partition; one Signature per partition sub-zone — DQ-R1-017). Created via Postmark Account API in amm.sh’s Phase A step (before cdk deploy) — the API call returns the DKIM selector / Return-Path target which tools/register-partition-mail-signature.ts writes into cdk.context.json, and cdk deploy (Phase B) reads that context at synth time. See § 10.3 G-OP-2 and § 13.3 for the operator-level sequencing. | G-C |
| G-POSTMARK-3 | DKIM TXT + Return-Path CNAME records per partition (via DnsEmailRecords). Values come from Postmark API at deploy time, written to cdk.context.json (Phase 3 pattern). | G-C |
| G-POSTMARK-4 | Per-partition Postmark account-token SM secret {fqn}-I-EmailPostmarkAccountToken declared in partition-email stack via SecretValue.cfnParameter() (δ.1 pattern; amm.sh reads from 1Password and passes as NoEcho parameter). RemovalPolicy.RETAIN. Exported as ${publishingPrefix}-API-EmailPostmarkAccountTokenArn for the operations Helm chart’s ESO ExternalSecret. The {fqn}-I-… in the SM resource name is a separate concern from the CFN export name: the resource name’s -I- marker indicates intra-partition AWS scope (per the existing partitionSecrets.cfn.yaml convention); the CFN export’s -API- marker indicates non-CDK consumption. | G-C |
| G-POSTMARK-5 | arda-nonprod unlock: the dev partition’s Sender Signature registration (a special case of G-POSTMARK-2 applied to PostmarkNonProd). Operator replies to Postmark Compliance (#11236089) with verified-domain evidence. | G-C-for-dev |
5.4 What’s reused
Section titled “5.4 What’s reused”PostmarkSendingDomain, DnsEmailRecords, sendingDomainPlacement(), partitionSecrets.cfn.yaml NoEcho-parameter pattern (5 secrets already use it — ArdaApiKey, HubspotPAT, AmazonCreatorsApi, etc.), amm.sh GHA ::add-mask:: hygiene.
5.5 Out-of-scope edges
Section titled “5.5 Out-of-scope edges”- Per-tenant Sender Signatures and per-tenant DNS records → deferred to Phase 5b (DQ-R1-017). The current Phase 4 design (one Signature per partition + DMARC relaxed alignment) lets all tenants in a partition send from
{config}.{tenant}.{partition}.ardamails.comwhile DKIM-signed by the partition’s key. This works because receivers accept relaxed-aligned DKIM, but the trade-off is that all tenants share the partition’s DKIM-domain reputation. If Phase 5b decides per-tenant reputation isolation is required (whole-population from v1, opt-in for sensitive tenants, or as a remediation path for tenants generating bounce/spam issues), each affected tenant will need (a) its own Sender Signature registered via the Postmark Account API and (b) per-tenant DKIM TXT + Return-Path CNAME records written into the partition mail sub-zone. Phase 4’sEmailDnsProvisioningRole(G-IAM-3) is provisioned specifically to enable (b) — it is the explicit Phase-4 deliverable that unlocks per-tenant Signatures whenever Phase 5b chooses to introduce them. Phase 5b’s decision does not require any Phase 4 re-work. Tracked in DQ-R1-023 as a Phase 5b open question. PostmarkServerresources (per-tenant servers; independent of the Signature decision) → Phase 5b.- Inbound webhook handling → Phase 5b.
- Bulk / broadcast Message Stream → out of project (transactional-only per
cross-cutting-design.md§ 7a).
6. C-EmailKey-At-Rest
Section titled “6. C-EmailKey-At-Rest”6.1 Purpose & linkage
Section titled “6.1 Purpose & linkage”The encryption material that Phase 5b’s TokenCipher will use to encrypt per-tenant Postmark server tokens before persistence exists in AWS Secrets Manager, ready for ESO projection. Supports goal success criterion #3.
6.2 Already in place
Section titled “6.2 Already in place”| Foundation | Source |
|---|---|
| AWS Secrets Manager per-account | Standing infrastructure |
ESO ClusterSecretStore per partition cluster | Pre-Phase-4 entry criterion |
| Two-axis envelope and dispatch design (DQ-R1-019) | email-server-key-encryption.md |
6.3 What Phase 4 adds
Section titled “6.3 What Phase 4 adds”| Gap | Description | → Group |
|---|---|---|
| G-KEY-1 | Per-partition encryption-key SM secret {fqn}-I-EmailEncryptionKey (passwordLength: 64, RemovalPolicy.RETAIN). Versioning delegated to AWS SM native (AWSCURRENT / AWSPREVIOUS). Exported as ${publishingPrefix}-API-EmailEncryptionKeyArn for the operations Helm chart’s two ESO ExternalSecret mounts (AWSCURRENT + AWSPREVIOUS — both reference the same secret ARN with different versionStage selectors). CDK generateSecretString is “generate-if-missing” semantics: subsequent cdk deploy runs (and amm.sh re-runs that drive them) are no-ops on this secret. Rotation is exclusively operator-driven via aws secretsmanager update-secret (runbook in G-OP-5). The generateSecretString configuration must be treated as immutable post-launch — changing fields like passwordLength could trigger silent regeneration. Full lifecycle invariants in email-server-key-encryption.md § CDK lifecycle invariants. | G-C |
6.4 What’s reused
Section titled “6.4 What’s reused”AWS SM native versioning (no Phase 4 code for envelope dispatch — that machinery is Phase 5b consuming this Phase 4 secret).
6.5 Out-of-scope edges
Section titled “6.5 Out-of-scope edges”TokenCipherclass (HKDF + AES-256-GCM + envelope codec) → Phase 5a (common-module, general-purpose per B1).- ESO
ExternalSecretHelm definitions (AWSCURRENT + AWSPREVIOUS mounts) → Phase 5b. - Lazy + coroutine migration → Phase 5b.
- SDK-fallback consumer wiring → Phase 5b (uses C-Fallback-Decryption).
- Rotation procedure (operator-driven via
aws secretsmanager update-secret) → documented inemail-server-key-encryption.md§ Sub-decision 3; runbook deliverable in G-OP-5. - CDK lifecycle invariants (
generateSecretStringis “generate-if-missing”;amm.shre-runs are no-ops; config must be treated as immutable post-launch) →email-server-key-encryption.md§ CDK lifecycle invariants.
7. C-Runtime-DNS-Writes
Section titled “7. C-Runtime-DNS-Writes”7.1 Purpose & linkage
Section titled “7.1 Purpose & linkage”The operations component running in a partition can write DKIM/Return-Path DNS records into the partition’s mail sub-zone at runtime. Supports goal success criterion #4 (DNS-provisioning role). Whether Phase 5b actually exercises this role — and on what frequency — depends on the per-tenant Sender Signature decision tracked as DQ-R1-023. If Phase 5b adopts per-tenant Sender Signatures (options β / γ / δ in DQ-R1-023), the role is exercised at tenant onboarding (and at remediation events for option δ) to register the per-tenant DKIM TXT + Return-Path CNAME records into the partition mail sub-zone. If Phase 5b stays with the partition Signature (option α), the role is provisioned but not exercised in v1 — it remains available for future per-tenant Signature introduction without re-doing Phase 4 IAM work.
7.2 Already in place
Section titled “7.2 Already in place”| Foundation | Source |
|---|---|
AllowCreatingNSRecordsRole construct | Phase 2; constructs/oam/allow-creating-ns-records-role.ts. Permissions are already generic Route53 record-set CRUD (ChangeResourceRecordSets, ListResourceRecordSets, ListHostedZonesByName) with allowedParentHostedZoneIds scope-tightening — the “NSRecords” name is misleading. |
| Per-partition pod IRSA role | eks-stack.ts:250, exported as ${publishingPrefix}-EksPodRoleArn |
| STS-chain precedent | infrastructure/src/main/cdk/constructs/storage/image-asset-bucket.ts ImageUploadPreSigningRole pattern |
7.3 What Phase 4 adds
Section titled “7.3 What Phase 4 adds”| Gap | Description | → Group |
|---|---|---|
| G-IAM-1 | Generalize AllowCreatingNSRecordsRole construct + rename to AllowCreatingDnsRecordsRole (mechanical). Parameterize the trust principal so callers can choose between (a) Lambda + OrgID (Root use case, default for backwards compatibility) and (b) iam.AccountPrincipal(account).withConditions({ ArnLike: ... }) (Phase 4 STS-chain use case). The class rename lands in the same PR — the CDK construct ID at the Root call site is preserved (new AllowCreatingDnsRecordsRole(this, "AllowCreatingNSRecordsRole", …)), so the synthesized CloudFormation logical IDs are unchanged. T-I2’s byte-equality test catches any regression regardless. (See DQ-R1-020 update for the override of the original “defer the rename” guidance.) | G-A |
| G-IAM-2 | CDK Template.fromStack() snapshot-equality unit test in root-dns-stack.test.ts (or in the construct’s own test) asserting the Root-account synthesis output is byte-identical before and after G-IAM-1. Fails closed on any Root regression. | G-A |
| G-IAM-3 | Per-partition DNS-records role instantiation in partition-email stack: one role per partition’s stack, trust principal = iam.AccountPrincipal(account).withConditions({ ArnLike: { "aws:PrincipalArn": ${fqn}-* } }); resource scoping via allowedParentHostedZoneIds: [zone.hostedZoneId] to just that partition’s mail sub-zone (single-zone scope; per-partition least-privilege isolation — a dev pod cannot assume into the stage partition’s role, and the dev role cannot write to stage.ardamails.com). Permissions inherited from the construct: route53:ChangeResourceRecordSets, route53:ListResourceRecordSets, route53:ListHostedZonesByName. route53:GetChange intentionally omitted (requires arn:aws:route53:::change/* resource scope; Postmark verification is API-driven, no Route53 propagation wait needed). Exported as ${publishingPrefix}-API-EmailDnsProvisioningRoleArn for the operations Helm chart (-API- because the consumer is non-CDK; matches the image-storage.ts precedent where imagePresignRoleArnAPI is exported the same way). | G-D |
7.4 What’s reused
Section titled “7.4 What’s reused”AllowCreatingNSRecordsRole construct (generalized — same construct serves Root and Phase 4 use cases). STS-chain pattern from image-asset-bucket.ts.
7.5 Out-of-scope edges
Section titled “7.5 Out-of-scope edges”- Runtime DNS-write code in the Email module → Phase 5b. The shape and frequency of these writes depend on DQ-R1-023 (per-tenant Sender Signature decision; pending Phase 5b planning).
route53:GetChangepermission → omitted by design (see G-IAM-3 note).- Tightening
allowedParentHostedZoneIdson the existing Root-account instantiation → future security-hardening project (out of project pergoal.md).
8. C-Fallback-Decryption
Section titled “8. C-Fallback-Decryption”8.1 Purpose & linkage
Section titled “8.1 Purpose & linkage”The operations pod can decrypt rare ciphertexts whose k{versionId} predates AWSPREVIOUS (SDK cache-miss path per DQ-R1-019). Supports goal success criterion #4 (SM-fallback role).
8.2 Already in place
Section titled “8.2 Already in place”| Foundation | Source |
|---|---|
| Per-partition pod IRSA role | ${publishingPrefix}-EksPodRoleArn |
| STS-chain trust-policy shape | Same as C-Runtime-DNS-Writes; mirrors image-asset-bucket.ts |
8.3 What Phase 4 adds
Section titled “8.3 What Phase 4 adds”| Gap | Description | → Group |
|---|---|---|
| G-IAM-4 | Per-partition EmailEncryptionKeyFallbackRole declared fresh in partition-email stack. Trust principal = account principal + ArnLike on {fqn}-*. Permission: secretsmanager:GetSecretValue on ${encryptionKeySecret.secretArn}* (full SM-secret ARN; the trailing wildcard tolerates the SM-appended random 6-character suffix — SM versions are selected at API call time via VersionId/VersionStage, not encoded in the resource ARN). Exported as ${publishingPrefix}-API-EmailEncryptionKeyFallbackRoleArn for the operations Helm chart. | G-D |
8.4 What’s reused
Section titled “8.4 What’s reused”Trust-policy shape from C-Runtime-DNS-Writes; STS-chain pattern.
8.5 Out-of-scope edges
Section titled “8.5 Out-of-scope edges”- SDK-fallback consumer code in
TokenCipher→ Phase 5b. - Custom-stage SM version mounting (preemptive AWSPREVIOUS-1 retention) → out-of-project hardening.
9. C-Drift-Detection
Section titled “9. C-Drift-Detection”9.1 Purpose & linkage
Section titled “9.1 Purpose & linkage”Partition-mail state divergence between declared and observed (Postmark, DNS, AWS SM) is detected automatically and surfaced as a labelled GitHub issue. Supports goal success criterion #6.
9.2 Already in place
Section titled “9.2 Already in place”| Foundation | Source |
|---|---|
corporate-drift.yml workflow | Phase 3; .github/workflows/corporate-drift.yml |
tools/corporate-drift.ts driver | Phase 3 |
| Issue-on-failure pattern with labels | Phase 1 / Phase 3 conventions |
| Postmark + DNS probe helpers | Phase 3’s corporate-drift driver |
9.3 What Phase 4 adds
Section titled “9.3 What Phase 4 adds”| Gap | Description | → Group |
|---|---|---|
| G-DRIFT-1 | New .github/workflows/runtime-platform-drift.yml. Daily cron. Failure-issue labels: drift + runtime-platform (per pre-design follow-up C3). | G-E |
| G-DRIFT-2 | Driver script enumerating instances/Alpha001/{prod,demo}.ts + instances/Alpha002/{dev,stage}.ts. Asserts Postmark + DNS + cross-seam state for every partition Signature. | G-E |
| G-DRIFT-3 | Minimal shared utility extraction from corporate-drift (per DQ-R1-018 — corporate-drift is not renamed). Both workflows source the extracted helpers. | G-E |
9.4 What’s reused
Section titled “9.4 What’s reused”corporate-drift workflow shape; issue-creation pattern; Postmark + DNS probe logic (extracted to shared utilities).
9.5 Out-of-scope edges
Section titled “9.5 Out-of-scope edges”- 1Password vault-scope expansion → unnecessary (drift uses Postmark API + AWS SDK probes per pre-design follow-up B5 resolution; no per-partition 1P read needed).
- Per-tenant drift → Phase 5b (extends
runtime-platform-driftlater). corporate-driftrename → rejected (DQ-R1-018 keeps it; future runtime-platform drift unrelated to email plugs intoruntime-platform-drift).
10. C-Operator-Surface
Section titled “10. C-Operator-Surface”10.1 Purpose & linkage
Section titled “10.1 Purpose & linkage”Operators provision and rotate partition mail through the existing amm.sh entry point, following its idempotency / security / pre-flight rules. Supports DQ-R1-022 and the scope bullet “Operator surfaces integrated into amm.sh.”
10.2 Already in place
Section titled “10.2 Already in place”| Foundation | Source |
|---|---|
amm.sh partition deploy script | Pre-Phase-4; already does op read + GHA ::add-mask:: + CFN NoEcho-parameter for 5 partition-scoped secrets |
partitionSecrets.cfn.yaml deploy step | Pre-Phase-4 canonical δ pattern |
corporate-cli.ts | Phase 3; includes idempotency, retry, redaction, conflict-check utilities |
10.3 What Phase 4 adds
Section titled “10.3 What Phase 4 adds”| Gap | Description | → Group |
|---|---|---|
| G-OP-1 | amm.sh partition-mail step (bash side, three direct calls in order): (i) op read 'op://Arda-{Env}OAM/Postmark/credential' to obtain the Postmark account-level token; (ii) npx ts-node tools/register-partition-mail-signature.ts <infrastructure> <partition> (Phase A; see G-OP-2); (iii) cdk deploy ${infrastructure}-${partition}-Email --parameters PostmarkAccountToken=... (Phase B). SecretValue.cfnParameter() lifecycle: amm.sh re-runs with an unchanged 1Password value are no-ops on the Postmark SM secret (CFN sees the parameter resolves to the same value). Rotation happens only when the 1Password item is updated first — never via out-of-band aws secretsmanager put-secret-value, which CDK would revert on the next deploy (intentional, per B2 — 1Password is the source of truth). | G-C |
| G-OP-2 | tools/register-partition-mail-signature.ts — new TypeScript entry script (the Phase A imperative step, mirroring Phase 3’s corporate-cli Phase A pattern). Composes the extracted helpers from G-OP-4 to: register the {partition}.ardamails.com Postmark Sender Signature via the Account API (idempotent: list-then-create); capture the Postmark-issued DKIM selector / public key / Return-Path target; write them into cdk.context.json (committed). Runs before the cdk deploy of step G-OP-1.iii, not after — CDK reads context at synth time, so the Postmark API call must precede deploy. The script is invoked only by amm.sh; it is not a standalone operator-facing CLI (per DQ-R1-022’s “no partition-mail-cli” framing). | G-C |
| G-OP-3 | GHA ::add-mask:: hygiene for the Postmark token (token from op read is not auto-masked; explicit mask required). Applied in amm.sh immediately after step G-OP-1.i, before either G-OP-1.ii or G-OP-1.iii. | G-C |
| G-OP-4 | TypeScript helpers under tools/lib/ (or equivalent shared location) — extracted from corporate-cli per pre-design follow-up B3 (minimal cut: only what register-partition-mail-signature.ts actually needs). Candidates: 1Password SDK resolution wrapper, Postmark Account API client with retry / backoff, idempotent list-then-create helpers, output redaction, conflict-check. Consumed by both corporate-cli and register-partition-mail-signature.ts; not invoked directly from bash. amm.sh stays a thin orchestrator — there is no bash reimplementation of Postmark or 1P logic. Workspace-scoped — landed in PR #1 (G-A) so the helpers are available when G-OP-2’s register-partition-mail-signature.ts lands in PR #2. (DQ-R1-022 implementation route.) | G-A |
| G-OP-5 | Encryption-key rotation operator runbook: aws secretsmanager update-secret against {fqn}-I-EmailEncryptionKey → ESO refreshes → operations pod’s TokenCipher reloads → lazy + coroutine migration mops up. Forward-pointer to email-server-key-encryption.md for the full mechanism. | G-F |
10.4 What’s reused
Section titled “10.4 What’s reused”amm.sh’s op-read + GHA-masking pattern (existing for 5 secrets); corporate-cli’s idempotency / retry / redaction / conflict-check helpers (extracted, not reimplemented).
10.5 Out-of-scope edges
Section titled “10.5 Out-of-scope edges”- Standalone
partition-mail-cli→ rejected (DQ-R1-022). - Full
corporate-clirefactor → rejected (B3 minimal cut). - Operator UI / dashboard → out of project (Postmark Console is the OAM surface).
11. C-Documentation
Section titled “11. C-Documentation”11.1 Purpose & linkage
Section titled “11.1 Purpose & linkage”Operators, Phase 5b authors, and future maintainers can understand the partition mail capability without re-deriving it from code or DQ-R1-NNN entries. Supports goal deliverable rows 11 + 11b.
11.2 Already in place
Section titled “11.2 Already in place”| Foundation | Source |
|---|---|
secret-delivery-pattern.md stub | Committed 2026-05-11 in this branch (current-system/oam/security/secret-delivery-pattern.md) |
secrets-vault.md cross-link | Wired to secret-delivery-pattern.md |
operator-runbook.md (Phase 1) | Updated 2026-05-11 with the Message Stream Discipline section |
sending-email-via-free-kanban-tool.md (Phase 3) | Updated 2026-05-11 (arda-prod approval status; maturity: review) |
11.3 What Phase 4 adds
Section titled “11.3 What Phase 4 adds”| Gap | Description | → Group |
|---|---|---|
| G-DOC-1 | Fill secret-delivery-pattern.md content with two worked examples: partitionSecrets.cfn.yaml (existing) and the Phase 4 Postmark token (δ.1). Upgrade frontmatter maturity: draft → review. | G-F |
| G-DOC-2 | Per-partition mail pages in current-system/runtime/ (topology, partition zone structure, NS-delegation chain). | G-F |
| G-DOC-3 | Multi-partition / multi-Signature updates in current-system/oam/postmark-service/ (account-to-partition mapping; the post-Phase-4 Sender Signature inventory). | G-F |
| G-DOC-4 | V-PART-NNN verification entry in verification.md for the Root no-drift check (see §16). | G-A (entry authored alongside the unit test) |
| G-DOC-5 | Current-system retrofit at project completion: reconcile new Phase-4 pages with the broader current-system/ trees once Phase 5b lands. | Post-Phase-4 (project closeout) |
11.4 What’s reused
Section titled “11.4 What’s reused”Phase 3 OAM page conventions; Phase 3 operator-runbook structure.
11.5 Out-of-scope edges
Section titled “11.5 Out-of-scope edges”- Phase 5b docs (Email module,
TokenCipherimplementation pages) → Phase 5b. - Documentation site infrastructure changes → out of project.
PART B — Implementation
Section titled “PART B — Implementation”12. Implementation Groups
Section titled “12. Implementation Groups”Six Groups. Each Group has a self-contained test surface for isolated verification; the DAG (§13) is the only inter-Group sequencing constraint.
12.1 G-A — Workspace refactors + accessor
Section titled “12.1 G-A — Workspace refactors + accessor”| Field | Value |
|---|---|
| Scope | Workspace-only (no per-partition fan-out) |
| Contains | G-IAM-1 (construct generalization + rename), G-IAM-2 (byte-equality unit test), G-POSTMARK-1 (accessor), G-DNS-5 (reserved-words list extension — workspace-scoped), G-OP-4 (TypeScript helpers under tools/lib/ — workspace-scoped, prerequisite for PR #2’s register-partition-mail-signature.ts), G-DOC-4 (verification entry) |
| Completes Capability | None directly. Unblocks G-D (construct generalized; Root no-drift gated) and G-C-for-dev (helpers + accessor in place so PR #2’s register-partition-mail-signature.ts can compile against them). |
| Test surface (isolated) | (a) CDK Template.fromStack() snapshot-equality unit test for RootDnsStack synthesis output — fails closed on any Root regression. (b) Unit test for postmarkCredentialOpReference(partition) returning the four expected op://Arda-{Env}OAM/Postmark/credential references. (c) Reserved-words list test asserts prod, demo, dev, stage, kyle are reserved (plus arda baseline from Phase 3). (d) tools/lib/*.test.ts covers each extracted helper (Postmark client retry/backoff, op-resolver, redaction). |
| Acceptance criteria | • Construct generalized with backwards-compatible default principal shape. • Class renamed; file moved; import sites updated (compilation gate). • Byte-equality unit test green. • Accessor function shipped with unit test. • Reserved-words list extended; tenant-slug validator rejects partition names. • tools/lib/ helpers extracted from corporate-cli (minimal cut per B3); both corporate-cli and the future register-partition-mail-signature.ts import from there; corporate-drift continues to function unchanged.• make pr-checks passes.• Zero AWS changes (Synth-only PR). |
| AWS impact | Synth-only |
| Deploy unit | Single PR; merge to main. No cdk deploy. |
12.2 G-B — Per-partition DNS authority
Section titled “12.2 G-B — Per-partition DNS authority”| Field | Value |
|---|---|
| Scope | Per-partition (fan-out begins) |
| Contains | G-DNS-1 through G-DNS-4 (per-partition resources). G-DNS-5 (reserved-words list extension) is workspace-scoped and lands in G-A — see § 12.1. |
| Completes Capability | C-DNS-Authority (per partition; together with G-DNS-5 in G-A which provides the registry extension) |
| Test surface (isolated) | Stack-level CDK Template assertions: zone declared with correct name; NS-write CR present; SPF + DMARC TXT contents match agreed strings. (The reserved-words assertion is in G-A’s test surface, not here.) |
| Acceptance criteria | • dig NS {partition}.ardamails.com @8.8.8.8 returns the partition zone’s nameservers via root delegation.• dig TXT {partition}.ardamails.com returns the SPF record.• dig TXT _dmarc.{partition}.ardamails.com returns the DMARC record. |
| AWS impact | Resource-touching (per partition) |
| Deploy unit | Bundled into the per-partition PR (see §13.2). |
12.3 G-C — Per-partition Postmark + secrets + operator step
Section titled “12.3 G-C — Per-partition Postmark + secrets + operator step”| Field | Value |
|---|---|
| Scope | Per-partition |
| Contains | G-POSTMARK-2, 3, 4 (and G-POSTMARK-5 for dev); G-KEY-1; G-OP-1, 2, 3 (G-OP-4 — TypeScript helper extraction — is workspace-scoped and lands in G-A) |
| Completes Capability | C-Postmark-Sending (per partition; fully completed at dev rollout via G-POSTMARK-5 unlocking arda-nonprod). C-EmailKey-At-Rest (per partition). C-Operator-Surface deploy-time path. |
| Test surface (isolated) | • Postmark Account API client mocks for Sender Signature idempotency (list-then-create). • CDK Template assertions for both SM secrets (resource shape, names, RemovalPolicy.RETAIN).• DKIM TXT + Return-Path CNAME shape assertions. • amm.sh dependency-injectable tests for op read + cdk deploy --parameters, with mocks for op CLI, Postmark client, AWS SDK. |
| Acceptance criteria | • Sender Signature verified in Postmark Console (DKIM, Return-Path) for the partition. • aws secretsmanager describe-secret --secret-id {fqn}-I-EmailPostmarkAccountToken returns secret with DeletionPolicy: Retain.• aws secretsmanager describe-secret --secret-id {fqn}-I-EmailEncryptionKey returns secret with DeletionPolicy: Retain.• amm.sh partition-mail step re-runs idempotently (second run is a no-op).• ( dev partition only) Reply sent to Postmark Compliance #11236089 with verified-domain evidence. |
| AWS impact | Resource-touching (per partition; Postmark side also creates non-AWS state) |
| Deploy unit | Bundled into the per-partition PR (see §13.2). |
12.4 G-D — Per-partition IAM roles
Section titled “12.4 G-D — Per-partition IAM roles”| Field | Value |
|---|---|
| Scope | Per-partition |
| Contains | G-IAM-3, G-IAM-4 |
| Completes Capability | C-Runtime-DNS-Writes (per partition — four partitions = four completions). C-Fallback-Decryption (per partition). |
| Test surface (isolated) | CDK Template assertions: each role’s trust-policy condition (ArnLike on {fqn}-*); each role’s Action + Resource statements. DNS-records role uses the generalized construct from G-A with partition-scoped allowedParentHostedZoneIds. |
| Acceptance criteria | • Both roles exist in each partition’s Infrastructure account (aws iam get-role).• Trust-policy condition matches the partition pod-role name prefix. • Resource scoping verified: DNS-records role’s ChangeResourceRecordSets resources are limited to the partition’s mail hosted zone ARN; fallback role’s GetSecretValue resource is limited to {fqn}-I-EmailEncryptionKey*.• Root no-drift verification (V-PART-NNN) passes — re-run after G-A merges, before any G-D deploy. |
| AWS impact | Resource-touching (per partition for both roles — each partition-email stack declares its own DNS-records role + fallback role) |
| Deploy unit | Bundled into the per-partition PR (see §13.2). |
12.5 G-E — Drift workflow
Section titled “12.5 G-E — Drift workflow”| Field | Value |
|---|---|
| Scope | Workspace-only |
| Contains | G-DRIFT-1, 2, 3 |
| Completes Capability | C-Drift-Detection |
| Test surface (isolated) | Workflow YAML lints; driver script exercises a fixture asset list and produces the expected report shape; shared-utility unit tests (extracted helpers work for both workflows). |
| Acceptance criteria | • Workflow runs on a scheduled cron tick (manual workflow_dispatch for the first verification).• Fails closed: creates GitHub issue with drift + runtime-platform labels on a synthetic drift fixture.• corporate-drift continues to work unchanged after shared-utility extraction (regression check). |
| AWS impact | None |
| Deploy unit | Single PR; merge to main. |
12.6 G-F — Documentation
Section titled “12.6 G-F — Documentation”| Field | Value |
|---|---|
| Scope | Workspace-only |
| Contains | G-DOC-1, 2, 3; G-OP-5 (rotation runbook) |
| Completes Capability | C-Documentation. C-Operator-Surface rotation path. |
| Test surface (isolated) | make pr-checks passes (link integrity, lint, smoke tests). All page slugs resolve. |
| Acceptance criteria | • secret-delivery-pattern.md upgraded from maturity: draft to maturity: review.• At least one new page in current-system/runtime/ describing partition mail topology.• current-system/oam/postmark-service/ reflects multi-partition Signature inventory.• Encryption-key rotation runbook exists and is linked from operator-runbook.md. |
| AWS impact | None |
| Deploy unit | Single PR; merge to main. |
13. DAG of Implementation Groups
Section titled “13. DAG of Implementation Groups”13.1 DAG
Section titled “13.1 DAG”The diagram below shows the Phase 4 Implementation Groups and the dependencies between them. G-A (workspace refactors) is a hard prerequisite for the per-partition Groups G-C and G-D — the generalized IAM construct, the partition-aware accessor, and the extracted tools/lib/ helpers all originate there. The per-partition Groups G-B, G-C, G-D are bundled per partition and land sequentially via PRs #2–#5 (dev → stage → demo → prod per DQ-R1-021). G-E (drift workflow) and G-F (documentation) are soft-dependent on the partition Groups and land last.
Edges:
| Edge | Type | Reason |
|---|---|---|
| G-A → G-B | Soft | amm.sh references the new accessor (G-POSTMARK-1), but amm.sh doesn’t run until G-C. G-A can land before or alongside G-B. |
| G-A → G-C | Hard | G-C’s register-partition-mail-signature.ts (G-OP-2) imports the tools/lib/* helpers extracted in G-A (G-OP-4); G-C also calls postmarkCredentialOpReference() (G-POSTMARK-1). G-A must merge before G-C can compile. |
| G-A → G-D | Hard | G-D’s DNS-records role instantiation uses the generalized construct from G-A. G-A must merge and Root no-drift must pass before any G-D deploy. |
| G-B → G-C | Hard | G-C composes additional resources onto the partition-email stack G-B authors. |
| G-B → G-D | Hard | G-D composes IAM resources onto G-B’s stack and references G-B’s hosted zone ARN for resource-scoping. |
| G-C ‖ G-D | Independent | Same stack, different resource families; can be PR’d together or separately. Per §13.2, they are bundled. |
| G-C → G-E | Soft | Drift workflow probes the SM secrets and Postmark state landed in G-C. G-E can be authored alongside G-C; verification happens once G-C is live for at least one partition. |
| all → G-F | Soft | Docs cite all the implementations. G-F lands last. |
13.2 Pinned PR / rollout sequence
Section titled “13.2 Pinned PR / rollout sequence”| # | PR | Group(s) | Scope | Sequencing |
|---|---|---|---|---|
| 1 | phase-4-G-A | G-A | Workspace | Lands first. Must merge before #3-#6. Root no-drift verification runs after merge, before #3 starts. |
| 2 | phase-4-G-B-C-D-dev | G-B + G-C + G-D | Partition: dev | Per DQ-R1-021, dev is first. Per-partition bundling: one PR carries DNS authority + Postmark/secrets + IAM for the partition. amm.sh rolls the partition forward post-merge. G-POSTMARK-5 (arda-nonprod unlock) lands here. |
| 3 | phase-4-G-B-C-D-stage | G-B + G-C + G-D | Partition: stage | After PR #2’s deploy is verified live. |
| 4 | phase-4-G-B-C-D-demo | G-B + G-C + G-D | Partition: demo | After PR #3. |
| 5 | phase-4-G-B-C-D-prod | G-B + G-C + G-D | Partition: prod | After PR #4. |
| 6 | phase-4-G-E | G-E | Workspace | Can land anywhere after PR #2 is live (dev provides enough state for drift to probe). Recommended after PR #2 to start exercising the workflow early. |
| 7 | phase-4-G-F | G-F | Workspace | Last. Documentation reflects what’s actually been built. |
Total: 7 PRs. Per-partition rollback semantics: PR #N’s failure is contained — partitions deployed under PR #M (M < N) remain operational; partitions later in the rollout simply haven’t started.
Per-partition cdk diff discipline: Each per-partition PR (#2–#5) carries the cdk diff summary for that partition only. The diff is refreshed before merge if upstream PRs land between authoring and merge.
13.3 amm.sh execution events
Section titled “13.3 amm.sh execution events”amm.sh is the only mechanism that creates Phase 4’s partition-mail resources end-to-end (CDK deploy + Postmark Account API calls + 1Password reads). The script gains its Phase 4 partition-mail step in G-C (G-OP-1..4); the code change lands as part of PR #2 alongside the dev deploy. Once PR #2 merges, amm.sh is ready to execute against any of the four active partitions; PRs #3–#5 do not modify the script — they only add the per-partition instance config and trigger another invocation.
| Event | Triggered by | Effect |
|---|---|---|
amm.sh partition-mail code lands on main | PR #2 merge (G-C-for-dev) | The script now contains the new partition-mail step, three bash calls in order: (i) op read the Postmark account-level token (+ GHA ::add-mask::); (ii) npx ts-node tools/register-partition-mail-signature.ts <infrastructure> <partition> — Phase A: calls Postmark Account API to register the Sender Signature, writes the returned DKIM selector / Return-Path target into cdk.context.json; (iii) cdk deploy ${infrastructure}-${partition}-Email --parameters PostmarkAccountToken=… — Phase B: declarative deploy that reads context and emits DNS records + SM secrets + IAM roles. The code is partition-agnostic; the partition is the operator’s invocation argument. (Phase A precedes Phase B because CDK synth reads cdk.context.json — the Postmark API call must complete before deploy.) |
First execution — amm.sh for dev | Operator-initiated after PR #2 merges (or run from the PR branch before merge as a pre-merge verification) | Creates dev.ardamails.com zone + NS-delegation + SPF/DMARC; populates both SM secrets; declares both IAM roles; registers the dev.ardamails.com Sender Signature on PostmarkNonProd. G-POSTMARK-5 fires here — the registration unlocks arda-nonprod account approval (Postmark ticket #11236089). |
Subsequent executions — amm.sh for stage, demo, prod | Operator-initiated after PRs #3, #4, #5 merge respectively | Each invocation creates the equivalent resources for its partition. The amm.sh code is unchanged from PR #2; only the partition argument and the per-partition instance config differ. prod and demo (on PostmarkProd) have no external-approval prerequisite (the account is already approved per K-10 / 2026-05-11). |
| Rotation invocations (post-Phase 4) | Operator-initiated whenever a 1Password Postmark-token value is updated or an encryption-key rotation runs | The same amm.sh step re-runs; the Postmark token’s SM secret is updated to match the new 1P value (CFN sees a different NoEcho parameter resolution); encryption-key rotation goes through the separate aws secretsmanager update-secret path documented in G-OP-5 (not amm.sh). |
Readiness preconditions — all must hold before any partition amm.sh invocation:
| Precondition | Verified by |
|---|---|
| PR #1 (G-A) merged | postmarkCredentialOpReference(partition) accessor unit test green; generalized AllowCreatingNSRecordsRole construct unit test green |
| Root no-drift verification passed | V-PART-NNN in verification.md (operator step; runs after PR #1 merge, before any partition deploy) |
| Per-partition PR (#2–#5) merged for the target partition | Stack code + instance config on main |
Partition’s Arda-{Env}OAM 1P vault contains Postmark/credential item with a valid account-level token | Operator pre-flight: op read "$(postmarkCredentialOpReference dev)" returns a non-empty value |
| Operator has AWS SSO credentials for the partition’s Infrastructure account | aws sts get-caller-identity --profile <profile> matches Alpha001 (for prod / demo) or Alpha002 (for dev / stage) |
amm.sh is not invoked during G-A (PR #1, code-only), G-E (PR #6, workflow YAML and driver scripts only), or G-F (PR #7, documentation only).
13.4 Capability readiness criteria
Section titled “13.4 Capability readiness criteria”Each row is an evaluable, observable condition. A Capability is “ready” only when the criterion holds.
| Capability | Readiness criterion (evaluable) | Met at end of |
|---|---|---|
| C-DNS-Authority | dig NS {partition}.ardamails.com @8.8.8.8 returns the partition zone’s nameservers via root delegation, for each of prod, demo, dev, stage. | G-B-for-each-partition (full readiness after PRs #2–#5 deployed) |
| C-Postmark-Sending | Postmark Console shows each {partition}.ardamails.com Sender Signature with DKIM verified and Return-Path verified, for both arda-prod and arda-nonprod. arda-nonprod account is approved by Postmark Support. | G-C-for-dev (arda-nonprod unlock) + G-C-for-each-partition (per-partition completion) |
| C-EmailKey-At-Rest | aws secretsmanager describe-secret --secret-id {fqn}-I-EmailEncryptionKey returns secret with AWSCURRENT versionId and DeletionPolicy: Retain, for each partition. ESO ClusterSecretStore resolves the secret on a probe pod (Phase 4 verifies projection works; Phase 5b consumes the projected secret). Re-running amm.sh for a deployed partition with no code or 1P changes does not create a new SM versionId on {fqn}-I-EmailEncryptionKey (verifiable via describe-secret versionId comparison before/after a no-op amm.sh run; catches accidental generateSecretString config drift in future PRs). | G-C-for-each-partition |
| C-Runtime-DNS-Writes | aws iam get-role --role-name <DnsRecordsRoleName> returns the role with the expected trust policy (account principal + ArnLike on {fqn}-*) and resource-scoped Route53 permissions (single zone — that partition’s mail sub-zone only), for each partition (dev, stage in Alpha002; demo, prod in Alpha001). | G-D for each partition (PRs #2–#5 — full readiness after PR #5) |
| C-Fallback-Decryption | aws iam get-role --role-name <EmailEncryptionKeyFallbackRoleName> returns the role with secretsmanager:GetSecretValue on {fqn}-I-EmailEncryptionKey*, for each partition. | G-D-for-each-partition |
| C-Drift-Detection | runtime-platform-drift workflow has completed a successful scheduled run; a synthetic drift fixture produces a labelled GitHub issue. | G-E (full readiness after at least one partition is live for the probes to find state) |
| C-Operator-Surface | amm.sh partition-mail step runs idempotently for at least one partition; encryption-key rotation runbook exists at the documented path and is linked from operator-runbook.md. | G-C-for-dev (deploy-time path) + G-F (rotation path) |
| C-Documentation | secret-delivery-pattern.md maturity: review; new pages in current-system/runtime/ describe partition mail topology; make pr-checks passes on the documentation repo. | G-F |
PART C — Cross-cutting
Section titled “PART C — Cross-cutting”14. Out of scope
Section titled “14. Out of scope”| ID | Concern | Where it belongs |
|---|---|---|
| O-1 | Per-tenant Postmark Sender Signatures | Phase 5b |
| O-2 | TokenCipher primitive (HKDF, AES-256-GCM, envelope codec) | Phase 5a (common-module, general-purpose per B1) |
| O-3 | Backend ShopAccess/Email module in operations | Phase 5b |
| O-4 | Tightening allowedParentHostedZoneIds on the Root-account instantiation | Future security-hardening project (out of project per goal.md) |
| O-5 | kyle partition mail capability | Deferred until partition resumes (DQ-R1-021) |
| O-6 | Apex SPF/DMARC on ardamails.com | Out of project |
| O-7 | Automated AWS SM rotation via Rotation Lambda | Future operator decision; design accommodates per DQ-R1-019 |
| O-8 | Standalone partition-mail-cli | Rejected (DQ-R1-022; amm.sh integration is the operator surface) |
15. Resolved design questions
Section titled “15. Resolved design questions”All design questions are resolved. Full text in ../../decision-log.md.
| ID | Topic | One-line resolution |
|---|---|---|
| DQ-R1-017 | Postmark Sender Signature granularity | One Signature per partition sub-zone; leaves inherit DKIM; per-tenant Signatures deferred to Phase 5b |
| DQ-R1-018 | corporate-drift rename and scope | Keep corporate-drift; add parallel runtime-platform-drift; share via reusable scripts / composite actions |
| DQ-R1-019 | Per-partition encryption-key derivation | Single SM secret per partition with native versioning; two-axis envelope a{N}.k{SM-VERSION-ID}; lazy + coroutine migration; SDK fallback (full design in email-server-key-encryption.md) |
| DQ-R1-020 | DNS-provisioning + SM-fallback IAM roles | Two per-purpose roles; DNS-records via reuse of the existing AllowCreatingNSRecordsRole construct (generalized) with Root no-drift guard; fallback role fresh; both STS-chained |
| DQ-R1-021 | Order of partition rollout | dev → stage → demo → prod; kyle excluded |
| DQ-R1-022 | Operator CLI shape | Integrate into amm.sh; share utilities with corporate-cli; no standalone partition-mail-cli |
| B1 | Phase 5a TokenCipher location | common-module, general-purpose encrypted-field utility (not email-specific) |
| B2 | Postmark account-token deploy-time delivery | δ.1 — NoEcho CFN parameter |
| B3 | amm.sh extraction scope from corporate-cli | Minimal cut: only what amm.sh’s partition-mail step needs |
| B4 | kyle reservation registry mechanism | Extend the Phase 3 mechanism used to reserve arda at the ardamails.com level |
| B5 | Cross-partition deploy gating in CI | Operator-enforced via amm.sh; no tools/cdk-runner.js matrix change |
| C1 | CDK stack name | ${infrastructure}-${partition}-Email; immutable, locked at first deploy |
| C2 | DMARC reporting mailbox | Reuse dmarc-reports@arda.cards for all partitions |
| C3 | runtime-platform-drift cron + labels | Daily; labels drift + runtime-platform |
16. Forward-references to specification.md and verification.md
Section titled “16. Forward-references to specification.md and verification.md”| Concern | Carries to | Notes |
|---|---|---|
| NS-delegation TTL during rollout | verification.md (V-PART-NNN) | Operator wait time between NS write and DKIM probe; depends on existing TTL settings in ardamails.com |
Wrong-token failure mode in amm.sh | specification.md + verification.md | Deploy-time serverinfo call to verify token authenticates against the right Postmark account before continuing |
| Cross-stack synthesis ordering (G-B → G-C/G-D wiring) | specification.md | Concrete CDK plumbing — Fn.importValue vs addDependency |
runtime-platform-drift scope pin (B5 / G-16 option a confirmed) | specification.md | Postmark API + AWS SDK probe path; no 1P vault-scope change |
| Root no-drift verification (V-PART-NNN) | verification.md | Operator-driven; runs after G-A merges, before any G-D deploy |
Per-partition cdk diff surfacing pattern | specification.md (operator workflow) | Per partition, refresh PR description |
Helm-values-injection path for -API- exports | specification.md | How the operations Helm chart (or amm.sh driving Helm) reads the six -API- exports per partition (PartitionMailZoneId, PartitionMailZoneName, EmailPostmarkAccountTokenArn, EmailEncryptionKeyArn, EmailDnsProvisioningRoleArn, EmailEncryptionKeyFallbackRoleArn) and threads them into chart values / ESO ExternalSecret definitions. Must be concrete: which script reads aws cloudformation list-exports, where the values land in values.yaml. |
17. References
Section titled “17. References”../goal.md— Phase 4 contract, success criteria, scope, deliverables.../../phases.md§ Phase 4 — phase plan, entry / exit criteria, dependencies.../../decision-log.md— Round R1-Phase4 decisions (DQ-R1-017..022) and pre-design follow-ups closed section.email-server-key-encryption.md— full design for the encryption-key envelope and rotation flow (DQ-R1-019).../../cross-cutting-design.md— auth, secrets, drift; § 7a Message stream discipline.../../architecture-overview.md— system structure; Application Runtime topology; mail topology.../../../../../current-system/runtime/environments.mdandplatform-structure.md— Infrastructure / Partition / Account model.../../../../../current-system/oam/security/secret-delivery-pattern.md— canonical δ secret-delivery path.../../../../../current-system/oam/postmark-service/operator-runbook.md— Phase 1 operator runbook (with the new Message Stream Discipline section).- Phase 3 analogues (de-facto templates for
requirements.md,specification.md,verification.md,exports.md):3-corporate-updates/analysis.mdand its sibling artifacts in that directory.
Copyright: (c) Arda Systems 2025-2026, All rights reserved
Copyright: © Arda Systems 2025-2026, All rights reserved