Phase 1 -- External Resources Provisioning -- Specification
Implementation specification for the work that brings the external resources, repository declarations, CI surface, and operator-facing documentation into the state required by requirements.md. The cross-phase contracts produced are catalogued in exports.md; the verification strategy and tests are in verification.md. Current-state context is in analysis.md.
This specification is target-state only. Where the analysis identifies partial existing artifacts, the specification states the destination; the implementor may reuse, port, or rebuild as appropriate.
1. Project type and scope
Section titled “1. Project type and scope”- Project type: Modification (per
analysis.md). - Repositories touched:
/infrastructure(configuration files, drift workflow),/documentation(operator-facing pages). No work in/operationsor/common-module. - Worktree strategy: Single worktree per repository; no multi-agent parallelism for Phase 1. (The phase is operator-driven and the code surface is small.)
- Effort shape: ~5 tasks across two repositories, primarily declarative additions to existing files plus three new documentation pages and one new GitHub Actions workflow.
2. Quality and convention guidelines
Section titled “2. Quality and convention guidelines”The implementor follows the conventions established in:
- The
instructions/repositories.mdfile in the workspace repo (Arda-cards/workspace) — repo overview. - The
instructions/dev-workflows.mdfile in the workspace repo — build, test, deploy commands. typescript-codingskill — TypeScript style for theplatform/files.unit-tests-infraskill — conventions for unit tests added underinfrastructure.document-writing+path-conventionsskills — conventions for thedocumentationpages.
CHANGELOG entries are required in every repository whose code changes; see the per-task acceptance criteria.
3. Tasks
Section titled “3. Tasks”The tasks below are sequenced. Each lists scope, source references, acceptance criteria, and STOP points where the operator must explicitly confirm before the next task begins. Per-task verification appears in verification.md; the test identifiers (V-XXX-NNN) are forward references.
Task 1: Confirm and complete external-resource provisioning (operator)
Section titled “Task 1: Confirm and complete external-resource provisioning (operator)”Requirements covered: REQ-EXT-001 — REQ-EXT-005; REQ-CI-001.
Scope: the operator confirms or completes the manual external-resource provisioning, recorded in the canonical runbook at /documentation/src/content/docs/current-system/oam/postmark-service/operator-runbook.md (delivered by Task 5 below). For Phase 1’s first execution the runbook is followed in draft form during Task 5’s authoring.
- PostmarkProd: confirm the account exists, is on the Platform plan, has 2FA enabled on the owner mailbox, and that the account-level API token captured in 1Password (
Postmark-Proditem) authenticates against the Postmark Account API. - PostmarkNonProd: same as above for the NonProd account. Create the account if missing.
- 1Password items: confirm
Postmark-Prod,Postmark-NonProd,IAC-SCRIPTS Service Account Token, and theFree Kanban Generator Postmarkplaceholder item exist with the required field shapes. - Service-account access: confirm the 1Password service-account token has read-only access to the
Arda-SystemsOAMvault and resolves at least one item via the SDK. - GitHub Actions secret: confirm
OP_SERVICE_ACCOUNT_TOKENis provisioned in theArda-cards/infrastructurerepository and its value matches theIAC-SCRIPTS Service Account Token1Password item. If missing or stale, provision it using the existingtools/gha-secret.tsutility (the utility itself is assumed in place; its retirement and any path migration is out of scope of this project).
Acceptance criteria
Section titled “Acceptance criteria”- All
REQ-EXT-NNNitems reach the “ok” status inanalysis.md§ Summary Table. - The operator records sign-off in the canonical runbook (delivered by Task 5).
STOP — review and approval
Section titled “STOP — review and approval”After Task 1, the operator confirms with the rest of the team that the external resources are ready. No subsequent task should run before this confirmation.
Task 2: Enrich platform/postmark-service.ts
Section titled “Task 2: Enrich platform/postmark-service.ts”Requirements covered: REQ-PLAT-001.
Scope: extend the existing infrastructure/src/main/cdk/platform/postmark-service.ts file with the API surface metadata.
Changes
Section titled “Changes”The existing file declares PostmarkAccount plus the two account constants. Add:
POSTMARK_ACCOUNT_API_BASE_URL: string— value"https://api.postmarkapp.com".POSTMARK_PLAN: string— value"Platform".- A
POSTMARK_API_SURFACEconstant of a typed shape with at least:freshnessDate: string(ISO date) — the date as of which the API surface assumptions were last verified against Postmark’s published documentation.observationsNotePath: string— the path tocurrent-system/oam/postmark-service/postmark-api-observations.md(relative to the documentation root) so the constant points readers to the design-intent note.
The exact TypeScript shape (interface vs type vs as const literal) is left to the implementor’s judgement; the values must be exported for downstream consumption.
Source references
Section titled “Source references”- Existing file:
/infrastructure/src/main/cdk/platform/postmark-service.ts - Sibling pattern:
/infrastructure/src/main/cdk/platform/aws-configuration.ts,/infrastructure/src/main/cdk/platform/web-configuration.ts
Acceptance criteria
Section titled “Acceptance criteria”- All exports above present and typed.
tsc --noEmitpasses in/infrastructure.- A unit test (
V-PLAT-001, seeverification.md) verifies the shape and content of the new exports. - CHANGELOG entry in
/infrastructureunder “Added”.
Task 3: Enrich platform/one-password.ts
Section titled “Task 3: Enrich platform/one-password.ts”Requirements covered: REQ-PLAT-002, REQ-PLAT-003.
Scope: extend the existing infrastructure/src/main/cdk/platform/one-password.ts with typed constants for every 1Password item the project will reference.
Changes
Section titled “Changes”The existing file exports only OAM_VAULT. Add typed constants for the four items:
POSTMARK_PROD_ITEM— title"Postmark-Prod", vaultOAM_VAULT, primary field"credential", full reference"op://Arda-SystemsOAM/Postmark-Prod/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.
A typed shape (OnePasswordItem interface) is recommended:
export interface OnePasswordItem { readonly vault: string; readonly title: string; readonly primaryField: string; readonly reference: string; // op:// URI for the primary field}The reference field is a derived value; it must be consistent with vault, title, and primaryField.
Source references
Section titled “Source references”- Existing file:
/infrastructure/src/main/cdk/platform/one-password.ts
Acceptance criteria
Section titled “Acceptance criteria”- All four items declared as typed
OnePasswordItemconstants plus the existingOAM_VAULT. tsc --noEmitpasses.- A unit test (
V-PLAT-002) verifies the shape, vault, and reference consistency of each constant. - CHANGELOG entry in
/infrastructureunder “Added”.
Task 4: Drift-check module and drift-detection workflow (dual-purpose)
Section titled “Task 4: Drift-check module and drift-detection workflow (dual-purpose)”Requirements covered: REQ-CI-002, REQ-CI-003; also delivers the connectivity-test runner consumed by V-EXT-001 — V-EXT-005 and V-CI-101.
Scope: a single TypeScript module that (i) operators can run locally to verify external-resource state, and (ii) a GitHub Actions workflow invokes on a monthly schedule. The same code in two invocation contexts. Plus the workflow file itself.
Drift-check module (tools/drift-check.ts)
Section titled “Drift-check module (tools/drift-check.ts)”A single TS module with one public entry point. Its body:
- Imports the constants from
platform/postmark-service.tsandplatform/one-password.ts. - Resolves each declared
op://reference using the 1Password SDK. The SDK’s auth source is auto-detected:- Local-dev: DesktopAuth (biometric unlock against the operator’s 1Password app).
- CI:
OP_SERVICE_ACCOUNT_TOKENenv var (the established convention from the prior implementation’sinfrastructure/scripts/lib/one-password.ts).
- Asserts each reference returns a non-empty value.
- For each Postmark account whose credential resolves, issues a benign Postmark Account API call (
GET /servers?count=1) and asserts a 2xx response. - Exits zero on full success; exits non-zero with a structured error report (JSON to stdout) on any failure.
The module is testable with mocked 1Password SDK and mocked HTTP client (see V-CI-001 — V-CI-003). Operator invocation: npx ts-node tools/drift-check.ts. CI invocation: a single npx ts-node step in the workflow.
This is the dual-purpose point: V-EXT-001 — V-EXT-005 (operator-runnable connectivity tests) and the drift workflow’s body are the same code. Operators and CI read identical structured output.
Drift-detection workflow (.github/workflows/external-resources-drift.yml, filename per OQ-1)
Section titled “Drift-detection workflow (.github/workflows/external-resources-drift.yml, filename per OQ-1)”- Triggers:
schedule(cron: '0 9 1 * *'— 09:00 UTC on the 1st of each month, matching the Postmark-foundations integration cadence) andworkflow_dispatch(operator-triggered ad hoc). - Permissions:
contents: read,issues: write(for the failure-issue step). - Steps:
- Checkout the repository.
- Install
infrastructuredependencies (npm ci). - Invoke
npx ts-node tools/drift-check.tswithOP_SERVICE_ACCOUNT_TOKENin env. - On failure: a follow-up step opens a GitHub issue using
gh issue create, with titleDrift detected in external resources (run YYYY-MM-DD), body containing the run URL and the failure report, and labelsdrift,phase-1,external-resources.
Source references
Section titled “Source references”- Postmark-foundations workflow as a template:
/infrastructure/.github/workflows/postmark-foundations.yml(from the prior Phase-0 implementation; uses thegh issue createpattern on schedule failures). - 1Password SDK usage:
/infrastructure/scripts/lib/one-password.ts(from the prior Phase-0 implementation; reusable wrapper — the dual-auth discovery logic informs the new module).
Acceptance criteria
Section titled “Acceptance criteria”- The drift-check module exists at
tools/drift-check.ts(filename perOQ-2) with a documented public entry point. - The workflow file exists, validates against the GitHub Actions schema (no
actionlinterrors if available). - Unit tests against the drift-check module pass:
V-CI-001,V-CI-002,V-CI-003. - A first manual run (
workflow_dispatch) completes successfully against the live external resources after Task 1’s sign-off (V-CI-101,V-CI-102). - An operator can run
npx ts-node tools/drift-check.tslocally with DesktopAuth resolution and the script reports green against the live external resources (operator validation ofV-EXT-001—V-EXT-005). - CHANGELOG entry in
/infrastructureunder “Added”.
Task 5: Documentation deliverables
Section titled “Task 5: Documentation deliverables”Requirements covered: REQ-OPS-001 — REQ-OPS-004, REQ-DOC-001 — REQ-DOC-004.
Scope: three new documentation pages in /documentation/src/content/docs/current-system/oam/postmark-service/. Plus one update to current-system/oam/index.md to discover the new section.
index.md— Postmark service overview. Covers account topology, credential storage, OAM model (Postmark Console as primary surface), drift cadence. Sized ~2 pages.postmark-api-observations.md— Postmark API observations note. Covers authentication models for API and Webhooks, error model, idempotency / retry conventions, webhook payload shapes, version-pin assumptions. Cross-links to Postmark official docs for the surface itself. Sized ~3 pages (perREQ-DOC-003).operator-runbook.md— canonical operator runbook for the manual external-resource provisioning steps. Covers all manual steps required byREQ-EXT-001-REQ-EXT-005, in operator-execution order. Includes a per-step troubleshooting table and a sign-off section. Sized ~3-4 pages.
The runbook supersedes infrastructure/scripts/postmark-foundations/HUMAN-STEPS.md. The infrastructure-side file is deleted as part of this task (it was a parser-gated artefact whose gate is retired); a redirect from its former location is not required because no external link refers to it.
Update to current-system/oam/index.md
Section titled “Update to current-system/oam/index.md”If current-system/oam/index.md exists and indexes its sub-sections, add an entry for postmark-service/. If it does not exist or does not index sub-sections, no action; Starlight auto-discovers child pages.
Acceptance criteria
Section titled “Acceptance criteria”- All three pages exist, well-formed, with the required content per
requirements.md. make pr-checkspasses in/documentation(lint, link check, smoke tests).infrastructure/scripts/postmark-foundations/HUMAN-STEPS.mdis removed; no remaining code in/infrastructureparses a HUMAN-STEPS file as a runtime gate (verified by grep).- CHANGELOG entries: one in
/documentationunder “Added”; one in/infrastructureunder “Removed” (for the deleted HUMAN-STEPS file and any associated parser code).
STOP — documentation review
Section titled “STOP — documentation review”After Task 5 lands in /documentation, the operator runbook is reviewable as a coherent end-to-end document. Confirm with reviewers before declaring Phase 1 complete.
4. Out of scope of this specification
Section titled “4. Out of scope of this specification”Restated for clarity; identical to requirements.md § Out of scope of Phase 1.
- Postmark server creation (Phase 3 / Phase 4).
- Per-partition Secrets Manager / encryption keys (Phase 4).
- Decisions about retiring
tools/gha-secret.ts(a future project). - Helm chart additions (Phase 5b).
- Migration of any existing
infrastructure/scripts/gha-secrets/implementation toinfrastructure/tools/gha-secret.ts(a side concern; the spec does not depend on that migration happening during Phase 1).
5. Open Questions and Decisions
Section titled “5. Open Questions and Decisions”| # | Question | Options | Recommendation | Decision |
|---|---|---|---|---|
| OQ-1 | Final filename of the drift workflow | external-resources-drift.yml; phase-1-drift.yml; op-drift.yml | external-resources-drift.yml — describes the asserted invariant, not the phase | Decided — see DQ-R1-001 |
| OQ-2 | Final location of the drift-check TypeScript | infrastructure/scripts/drift-check.ts; infrastructure/tools/drift-check.ts | tools/drift-check.ts — it is operator-runnable in addition to CI-runnable; consistent with the tools/ convention | Decided — see DQ-R1-002 |
| OQ-3 | Where to surface the runbook’s sign-off mechanism | A code block; a YAML frontmatter field; a designated table | A designated Markdown section (“Operator Sign-off”) with a small table for name / date / deviations | Decided — see DQ-R1-003 |
| OQ-4 | Whether to delete the existing infrastructure/scripts/postmark-foundations/HUMAN-STEPS.md and its parser in this phase, or to defer the parser deletion | Delete in Task 5; defer parser deletion to a follow-up | Delete in Task 5 — per REQ-OPS-004, no parser gate remains | Decided — see DQ-R1-004 |
| OQ-5 | API-surface freshness cadence | Annually; at each Postmark major-update post; on first drift-test failure attributable to surface drift | At first drift-test failure attributable to surface drift, augmented by an annual review | Decided — see DQ-R1-005 |
The Open Questions table records decisions as they are resolved during implementation. Each decision is recorded in the project-level decision log using the DQ-R1-NNN numbering scheme (per ../architecture-overview.md § 10).
6. References
Section titled “6. References”analysis.md— current-state assessment and prioritised recommendations.requirements.md— requirement IDs traced through verification.verification.md— test catalogue and traceability table.exports.md— cross-phase contracts produced by Phase 1.../goal.md— project-level goal, constraints, and acceptance criteria.../architecture-overview.md— system architecture and instance-group taxonomy.../phases.md— the full phase plan.../cross-cutting-design.md— cross-cutting security and OAM concerns.../decision-log.md— project-wide decisions, including DQ-R1-NNN entries.
Copyright: © Arda Systems 2025-2026, All rights reserved