Skip to content

Phase 1 -- External Resources Provisioning -- Analysis

Current-state assessment of the external resources Phase 1 takes responsibility for, the gap to the Phase 1 target, and the prioritised recommendations for closing the gap.

The Phase 1 target is described in specification.md; the requirements that Phase 1 must satisfy are listed in requirements.md. The downstream contracts Phase 1 produces are catalogued in exports.md.

Phase 1 is the foundation of the email-integration project: it captures the external resources Arda consumes (Postmark accounts, 1Password vault items, GitHub Actions secrets) and the typed references that downstream phases use to address them. The current state is partially complete — some external resources exist, the platform/ reference files are stubs, and a transition tool for GitHub Actions secret provisioning has been authored — but the deliverables are not yet aligned with the Revision 1 architecture in ../goal.md, ../architecture-overview.md, and ../phases.md.

The gaps fall into four categories:

  1. External resource provisioning — some Postmark accounts and 1Password items exist; others are partial or missing.
  2. platform/ reference files — stubs are in place but lack the enriched metadata Phase 3 / Phase 4 will consume.
  3. CI surfaceOP_SERVICE_ACCOUNT_TOKEN exists, but no drift-detection workflow is live.
  4. Documentation — the Postmark service overview and API observations note do not yet exist under current-system/oam/postmark-service/.

The work is bounded, sequential, and operator-driven; Phase 1 is the prerequisite for every subsequent phase.

Specification vs. Implementation Comparison

Section titled “Specification vs. Implementation Comparison”

Category 1: Significant Gaps (Features Not Implemented)

Section titled “Category 1: Significant Gaps (Features Not Implemented)”

External resources or repository-side artifacts specified by Phase 1 that are not yet present in their target state.

GapCurrent statePhase 1 target
PostmarkNonProd accountExistence not yet confirmed; sign-off pending in the parser-gated operator runbook B.2.Account created on Platform plan, owner mailbox 2FA enabled, account-level API token generated and stored in 1Password (Postmark-NonProd item in Arda-SystemsOAM).
Postmark-NonProd 1Password itemStub in the parser-gated operator runbook pending sign-off.Populated with the account-level API token; readable via op://Arda-SystemsOAM/Postmark-NonProd/credential.
Drift-detection workflowNo workflow exists.A scheduled GitHub Actions workflow exercises every external reference declared in platform/, asserts each Postmark account responds to a benign Account API call, and opens an automated investigation issue on failure.
Postmark service overviewPage does not exist.Operator-facing overview at current-system/oam/postmark-service/index.md: account topology, credential storage, OAM model (Postmark Console as primary surface), drift cadence.
Postmark API observations notePage does not exist.Brief design-intent note at current-system/oam/postmark-service/postmark-api-observations.md: authentication models for API and Webhooks, error model, idempotency / retry policy, webhook payload shapes, version-pin assumptions.
Operator runbookHeld in the parser-gated HUMAN-STEPS.md under the prior Phase-0 implementation’s scripts/postmark-foundations/ directory — inappropriate location and shape for Revision 1.Canonical operator runbook in the documentation repo at current-system/oam/postmark-service/operator-runbook.md. No parser-enforced gate; operator follows the runbook and records sign-off in the runbook itself.

Resources that exist but whose behavior or content differs from Phase 1’s target.

ResourceCurrent behaviorPhase 1 target behavior
platform/postmark-service.ts16-line stub: PostmarkAccount interface plus the two account references (POSTMARK_PROD_ACCOUNT, POSTMARK_NONPROD_ACCOUNT) with name and credential reference only.Same accounts plus Postmark API base URL constant (https://api.postmarkapp.com), plan attribute (Platform), and a version-pin metadata block describing the API surface assumptions Arda is committing to. Consumed by Phase 3 thin-wrappers, Phase 4 partition-email stack, and the drift workflow.
platform/one-password.ts3-line stub: only OAM_VAULT = "Arda-SystemsOAM".Vault constant plus typed item references for every 1Password item the project will reference, declared up front so downstream phases import named constants rather than string literals. Items: Postmark-Prod, Postmark-NonProd, IAC-SCRIPTS Service Account Token, Free Kanban Generator Postmark.
Parser-gated operator runbook (HUMAN-STEPS.md)Parsed at orchestrator startup; refuses to run live calls if any item is unchecked.Retired. The orchestrator the gate protected is itself being restructured (becomes Phase 3’s Corporate CLI). Operator sign-off is human-recorded in the canonical runbook; no machine gate.

Internal functionality or values not exposed as intended for downstream consumers.

Missing exposureCurrent statePhase 1 target
Typed 1Password item referencesplatform/one-password.ts has only the vault name. Downstream code references items as string literals (e.g., "op://Arda-SystemsOAM/Postmark-Prod/credential").Each 1Password item exposed as a typed constant with its op:// reference and its purpose. Downstream callers import the constants.
Postmark API surface metadataNo exposed constants for the API base URL or plan. Each consumer would otherwise hardcode them.platform/postmark-service.ts exposes the constants once; thin-wrappers and drift workflow consume them.
Drift-workflow contractNo workflow file; the OP_SERVICE_ACCOUNT_TOKEN-resolves-1P-references contract is implicit.A scheduled workflow that codifies the contract: every op:// reference declared in platform/ resolves successfully via OP_SERVICE_ACCOUNT_TOKEN.

Naming, casing, or structural inconsistencies that have low immediate impact.

DiscrepancyNotes
platform/postmark-service.ts filenameThe other platform/ files use the *-configuration.ts suffix (aws-configuration.ts, web-configuration.ts, user-account-configuration.ts); this file uses *-service.ts. Decision: keep *-service.ts — “service” reflects “external service Arda consumes” better than “configuration”, and renaming would create a worktree-wide ripple. Documented here so future readers do not re-litigate.
tools/gha-secret.ts locationA working implementation exists at infrastructure/scripts/gha-secrets/. Phase 1’s target location is infrastructure/tools/gha-secret.ts. The migration is a path-only move (declaratively-driven re-implementation is out of scope for this project per specification.md § Open Questions).
Specification requirementStatusNotes
REQ-EXT-001: PostmarkProd account exists, Platform plan, 2FA, account token in 1PpartialAccount exists; sign-off pending on owner 2FA + token capture per the parser-gated runbook B.1.
REQ-EXT-002: PostmarkNonProd account exists, Platform plan, 2FA, account token in 1PgapSign-off pending in the parser-gated runbook B.2.
REQ-EXT-003: 1Password vault Arda-SystemsOAM accessibleokVault exists; service account read-only access provisioned.
REQ-EXT-004: 1P items Postmark-Prod, Postmark-NonProd populatedpartialPostmark-Prod populated; Postmark-NonProd pending.
REQ-EXT-005: 1P item IAC-SCRIPTS Service Account Token populatedokPopulated per the parser-gated runbook B.4.
REQ-PLAT-001: platform/postmark-service.ts declares accounts + API metadatapartialAccounts declared; API base URL / plan / version-pin metadata not yet present.
REQ-PLAT-002: platform/one-password.ts declares all 1P referencespartialOnly OAM_VAULT declared; item references missing.
REQ-CI-001: OP_SERVICE_ACCOUNT_TOKEN provisioned in Arda-cards/infrastructureokProvisioned.
REQ-CI-002: Drift-detection workflow livegapNo workflow exists.
REQ-OPS-001: Operator runbook canonical at current-system/oam/postmark-service/gapPage does not exist.
REQ-DOC-001: Postmark service overview pagegapPage does not exist.
REQ-DOC-002: Postmark API observations notegapPage does not exist.

(Requirement IDs are forward references to requirements.md, where they are defined and traced through verification.md.)

Without these, no later phase can run. Operator-driven work; no code dependencies.

  1. Complete PostmarkNonProd setup — create the account, enable 2FA on the owner mailbox, generate the account-level API token, capture it in 1Password (Postmark-NonProd item).
  2. Confirm Postmark-Prod token freshness — verify the token captured in 1Password authenticates against the Postmark Account API; rotate if uncertain.
  3. Verify IAC-SCRIPTS Service Account Token — confirm read-only scope to Arda-SystemsOAM and that the token resolves the items above.

Repository-side declarations consumed by every later phase.

  1. Enrich platform/postmark-service.ts — add API base URL, plan attribute, version-pin metadata. No breaking change to the existing two account constants.
  2. Enrich platform/one-password.ts — declare typed constants for every 1Password item the project will reference, including Free Kanban Generator Postmark (consumed by Phase 3) declared up front so Phase 3 imports a typed reference.

Operationally important but does not block the next phase from starting if temporarily delayed.

  1. Drift-detection workflow — new GitHub Actions workflow at .github/workflows/external-resources-drift.yml (name TBD): scheduled monthly, asserts every platform/-declared op:// reference resolves and each Postmark account responds to a benign Account API call. Auto-issue on failure.
  2. Postmark service overview at current-system/oam/postmark-service/index.md.
  3. Postmark API observations note at current-system/oam/postmark-service/postmark-api-observations.md.
  4. Operator runbook at current-system/oam/postmark-service/operator-runbook.md. Replaces the parser-gated HUMAN-STEPS.md machine-gated artefact (deleted in Phase 1).

The tools/gha-secret.ts transition utility is assumed already in place for the purposes of this project (an existing implementation lives at infrastructure/scripts/gha-secrets/). Phase 1 declaratively designs as if that utility is the operator’s mechanism for setting the GitHub Actions secret; no code change to the utility itself is in scope here.

  • Decisions about retiring tools/gha-secret.ts — a future project will decide when the declarative GHA-secret pattern (or a 1Password-native GitHub mechanism) supersedes the tool. Phase 1 designs the declarative side as if the tool does not exist.
  • Path migration of the existing gha-secrets implementation to tools/gha-secret.ts — if it happens during this project, it is a side concern; the spec describes the target location only.
  • Changes to other Arda repositories — Phase 1 touches infrastructure (configuration files, drift workflow) and documentation (operator-facing pages). No operations or common-module work.