iOS Infrastructure

project-ios-infrastructure forgejo

Notes

Review 10
  • Verdict: APPROVED

    Re-review after refinement. Both issues from review-1542-2026-06-21 resolved.

    Previous Review Issues

    • [x] arch-tofu-consumers note missing — FALSE POSITIVE (confirmed). Note exists at slug arch-tofu-consumers (id 2067), created 2026-06-20. Full-text search fails to find it (indexing gap), but direct slug fetch succeeds. Project page project-page-ios-infrastructure also references it in the Architecture section.
    • [x] Makefile target naming — FIXED. Issue body updated: AC, test expectations, and file targets all use tofu-plan/tofu-apply/tofu-import/tofu-validate, matching pal-e-platform Makefile convention.

    Template Completeness

    • [x] Type — Feature
    • [x] Lineage — Standalone, discovered during PR #138
    • [x] Repo — ldraney/pal-e-services
    • [x] User Story — well-formed (platform engineer, worktree guardrails, no flag memorization)
    • [x] Context — thorough explanation of gap (plan vs apply locking, flag incantations, Kubernetes backend)
    • [x] File Targets — 2 targets (Makefile new, sop-platform-tf-changes update)
    • [x] Feature Flag — none (appropriate for DX tooling)
    • [x] Acceptance Criteria — 5 items
    • [x] Test Expectations — manual verification steps + make tofu-validate
    • [x] Constraints — 5 constraints listed
    • [x] Checklist — standard 3-item
    • [x] Related — 6 references

    Traceability

    • [x] story:provision label — present on board item
    • [x] story note verified — found in project-page-ios-infrastructure user-stories section (key: "provision", role: Platform engineer, metric: "tofu apply provisions bundle IDs, profiles, devices, DNS")
    • [x] arch:tofu-consumers label — present on board item
    • [x] arch note verified — arch-tofu-consumers (id 2067) exists in pal-e-docs. Covers consumer split between pal-e-platform and pal-e-services, data flow, Keycloak split, and docs pattern.
    • [x] Forgejo issue — https://forgejo.tail5b443a.ts.net/ldraney/pal-e-services/issues/140, state: open

    File Targets

    • [x] Makefile — verified: no Makefile currently exists in pal-e-services repo (confirmed via Forgejo API tree listing). New file creation is correct.
    • [x] sop-platform-tf-changes (pal-e-docs) — verified: note exists (slug: sop-platform-tf-changes, id 426), status: active. The pal-e-services section currently says -lock=false for both plan AND apply, confirming the issue's claim that locking is applied too broadly.
    • [x] Constraint reference: ~/secrets/pal-e-services/k3s.tfvars — verified: file exists at /home/ldraney/secrets/pal-e-services/k3s.tfvars (9.5k).
    • [x] Convention reference: pal-e-platform Makefile — verified: exists with tofu-plan, tofu-apply, tofu-fmt, tofu-init, tofu-secrets, tofu-validate-secrets targets. Issue naming convention matches.

    Repo Placement

    OK — Makefile goes in pal-e-services repo (where the issue is filed). SOP update is in pal-e-docs (separate system, updated via MCP tool). Both are correctly identified. No multi-repo PR needed.

    Dependencies

    • No blocking dependencies on the board. Item #1534 (pal-e-services: CLAUDE.md symlink + docs upgrade) is in todo on the same repo but is independent work.
    • The worktree-workflow SOP is referenced but does NOT need modification — only sop-platform-tf-changes needs the locking clarification.

    Acceptance Criteria

    5 AC items, all manually verifiable. Assessment:

    • AC 1-4: Makefile targets — agent can verify by reading generated Makefile and confirming flag usage (-lock=false on plan, default locking on apply/import). Manual testing from /tmp/ clone is appropriate.
    • AC 5: SOP update — agent can verify by reading the updated pal-e-docs note content.
    • No missing criteria detected. The scope is well-bounded.

    Blast Radius

    • CI pipeline note: The SOP's pal-e-services section currently uses -lock=false on apply. The ticket explicitly excludes .woodpecker.yaml changes. Acceptable — CI locking semantics differ (in-cluster context). The SOP update should note this distinction.
    • pal-e-platform already has a Makefile: Confirmed. New Makefile follows same tofu- prefix convention. No naming conflict.
    • No other repos with similar Terraform consumer patterns lack Makefiles (pal-e-platform has one, appstoreconnect-tofu is a provider not a consumer).

    Decomposition Assessment

    2 file targets across 1 repo + 1 pal-e-docs note update. 5 acceptance criteria. Estimated agent work well under 5 minutes. No decomposition needed.

    Recommendation

    No action needed. Both previous review issues resolved. Scope is solid, all file targets verified, traceability complete, fits in a single agent pass.

  • Verdict: NEEDS_REFINEMENT

    Template Completeness

    • [x] Type -- Feature
    • [x] Lineage -- Standalone, discovered during PR #138
    • [x] Repo -- ldraney/pal-e-services
    • [x] User Story -- present, well-formed
    • [x] Context -- thorough explanation of the gap (plan vs apply locking, flag incantations)
    • [x] File Targets -- 2 targets (Makefile new, sop-platform-tf-changes update)
    • [x] Feature Flag -- none (appropriate for DX tooling)
    • [x] Acceptance Criteria -- 5 items
    • [x] Test Expectations -- manual verification steps + make validate
    • [x] Constraints -- 4 constraints listed
    • [x] Checklist -- standard 3-item
    • [x] Related -- 5 references

    Traceability

    • [x] story:provision label -- present on board item
    • [x] story note verified -- found in project-page-ios-infrastructure user-stories section (key: "provision", role: Platform engineer)
    • [x] arch:tofu-consumers label -- present on board item
    • [ ] arch note MISSING -- [SCOPE] Create architecture note arch-tofu-consumers. Search returned zero results. This label is also used by board items #1533 and #1534 on the same board.
    • [x] Forgejo issue -- https://forgejo.tail5b443a.ts.net/ldraney/pal-e-services/issues/140, state: open

    File Targets

    • [x] Makefile -- verified: no Makefile currently exists in pal-e-services (confirmed via Forgejo API tree listing). New file creation is correct.
    • [x] sop-platform-tf-changes (pal-e-docs) -- verified: note exists (slug: sop-platform-tf-changes), status: active, project: pal-e-platform. The pal-e-services section currently says -lock=false for both plan AND apply, confirming the issue's claim that locking is applied too broadly.
    • [x] Constraint reference: ~/secrets/pal-e-services/k3s.tfvars -- verified: file exists at /home/ldraney/secrets/pal-e-services/k3s.tfvars.
    • [x] Convention reference: pal-e-platform Makefile -- verified: exists and contains tofu-plan, tofu-apply, tofu-fmt targets. Good convention to follow. Note: pal-e-platform uses tofu- prefix; issue should follow the same naming.

    Repo Placement

    OK -- Makefile goes in pal-e-services repo (where the issue is filed). SOP update is in pal-e-docs (separate system, updated via MCP tool). Both are correctly identified.

    Dependencies

    • No blocking dependencies on the board. Item #1534 (pal-e-services: CLAUDE.md symlink + docs upgrade) is in todo on the same repo but is independent work.
    • The worktree-workflow SOP (slug: worktree-workflow) is referenced but does NOT need modification -- only sop-platform-tf-changes needs the locking clarification.

    Acceptance Criteria

    5 AC items, all manually verifiable. Assessment:

    • AC 1-4: Makefile targets -- agent can verify by reading generated Makefile and confirming flag usage. Manual testing from /tmp/ clone is appropriate.
    • AC 5: SOP update -- agent can verify by reading the updated pal-e-docs note content.
    • No missing criteria detected. The scope is well-bounded.

    Blast Radius

    • CI pipeline inconsistency: The pal-e-services Woodpecker CI apply step (.woodpecker/terraform.yaml) currently uses -lock=false on apply. The ticket explicitly says "CI pipeline unchanged" and excludes .woodpecker.yaml. This is acceptable -- the CI locking fix should be a separate issue since CI runs in-cluster with different locking semantics. However, the SOP update should note this distinction.
    • pal-e-platform already has a Makefile: Confirmed. pal-e-platform uses tofu-plan, tofu-apply, tofu-fmt naming. The new Makefile should follow this convention (not make plan / make apply as the AC currently suggests).
    • No other repos with similar Terraform patterns lack Makefiles (pal-e-platform already has one, appstoreconnect-tofu is a provider not a consumer).

    Decomposition Assessment

    2 file targets across 1 repo + 1 pal-e-docs note. 5 acceptance criteria. Estimated agent work well under 5 minutes. No decomposition needed.

    Recommendation

    • [SCOPE] Create architecture note arch-tofu-consumers for the tofu-consumers component. This label is shared by 3 board items (#1533, #1534, #1542) and has no backing architecture note.
    • [BODY] Clarify Makefile target naming convention: AC says "make plan" / "make apply" but pal-e-platform convention uses tofu-plan / tofu-apply prefix. Update AC to use make tofu-plan / make tofu-apply for cross-repo consistency, or explicitly document why a different naming is chosen.
  • Verdict: APPROVED

    v3 re-review after file target fix. Previous reviews: review-1534-2026-06-20 (NEEDS_REFINEMENT), review-1534-2026-06-20-v2 (NEEDS_REFINEMENT). The sole remaining v2 issue (wrong filename docs/service-registration.md) has been corrected to docs/service-onboarding.md. All checks pass.

    Template Completeness

    • [x] Type -- Feature
    • [x] Lineage -- Standalone, repo standardization wave
    • [x] Repo -- ldraney/pal-e-services
    • [x] User Story -- present and well-formed
    • [x] Context -- adequate, explains scope limitation on mermaid
    • [x] File Targets -- 4 specific files listed with clear descriptions
    • [x] Feature Flag -- none (correct)
    • [x] Acceptance Criteria -- 4 specific, verifiable items
    • [x] Test Expectations -- present (2 items)
    • [x] Constraints -- present
    • [x] Checklist -- present
    • [x] Related -- present, references arch-tofu-consumers and project-page-ios-infrastructure

    Traceability

    • [x] story:provision label -- "Platform engineer provisions infrastructure via tofu apply"
    • [x] story entry exists -- found in project-page-ios-infrastructure user-stories table (key: provision, role: Platform engineer)
    • [ ] story note still TBD -- Story Note column says "TBD" (no backing story note created). Cross-cutting concern shared by all story:provision tickets (#1533, #1534, #1535). Not a blocker for this ticket's scope clarity, but the note should be created before any story:provision ticket reaches done.
    • [x] arch:tofu-consumers label -- tofu-consumers architecture component
    • [x] arch note verified -- arch-tofu-consumers note exists in pal-e-docs (confirmed via direct get_note). Documents consumer split between pal-e-platform and pal-e-services, data flow, docs pattern.
    • [x] Forgejo issue -- ldraney/pal-e-services#131, open

    File Targets

    • [x] README.md -- verified: exists in repo as regular file (3235 bytes). Will be rewritten as TOC.
    • [x] CLAUDE.md -- verified: exists as standalone file (2239 bytes). Will become symlink to README.md.
    • [x] docs/image-updater-sops.md -- verified: exists (4492 bytes), has 5 mermaid blocks. Issue correctly says "no changes needed."
    • [x] docs/service-onboarding.md -- verified: exists (7129 bytes, 266 lines, no mermaid currently). Correct target for adding service onboarding flowchart. FIXED from v2: filename corrected from docs/service-registration.md.

    Repo Placement

    OK -- issue filed on pal-e-services, all work scoped to pal-e-services. Single-repo change.

    Dependencies

    • Sibling ticket #1533 (pal-e-platform: CLAUDE.md symlink + docs upgrade) follows the same pattern. No blocking dependency. Both share arch:tofu-consumers.
    • No items currently in in_progress on board-project-ios-infrastructure. All 6 items are in backlog.
    • Pattern reference (godaddy-tofu / appstoreconnect-tofu) is stable -- those repos already standardized.

    Acceptance Criteria

    • [x] "readlink CLAUDE.md -> README.md" -- verifiable by agent
    • [x] "README.md has documentation table linking to all docs/ files" -- verifiable by agent
    • [x] "docs/image-updater-sops.md mermaid retained" -- verifiable by checking mermaid block presence
    • [x] "No content lost from current CLAUDE.md" -- verifiable by diff

    All 4 ACs are specific and agent-verifiable.

    Blast Radius

    Low. Documentation-only change. No code, no CI pipeline, no downstream consumers affected. The same pattern is being applied across sibling tickets (#1532, #1533) independently.

    Decomposition Assessment

    3 file modifications in 1 repo, 4 ACs. Well within the 5-minute rule. No decomposition needed. 2-point estimate is appropriate.

    Recommendations

    No action needed.

    Previous Review Disposition

    v2 Recommendation Status
    [BODY] Fix file target: docs/service-registration.md does not exist, correct filename is docs/service-onboarding.md RESOLVED -- issue body now references docs/service-onboarding.md

    Full Review History

    Version Verdict Issues Found Resolved By
    v1 (review-1534-2026-06-20) NEEDS_REFINEMENT 4 issues: glob file targets, unclear AC, missing arch note, missing story note v2
    v2 (review-1534-2026-06-20-v2) NEEDS_REFINEMENT 1 issue: wrong filename (service-registration.md vs service-onboarding.md) v3
    v3 (review-1534-2026-06-20-v3) APPROVED None --
  • Verdict: NEEDS_REFINEMENT

    Re-review after scope refinement. Previous review: review-1534-2026-06-20 (NEEDS_REFINEMENT). Three of four previous recommendations resolved. One remaining file target issue.

    Template Completeness

    • [x] Type -- Feature
    • [x] Lineage -- Standalone, repo standardization wave
    • [x] Repo -- ldraney/pal-e-services
    • [x] User Story -- present and well-formed
    • [x] Context -- adequate, explains scope limitation on mermaid
    • [x] File Targets -- FIXED from v1: now lists specific files instead of glob. Four files listed with clear descriptions.
    • [x] Feature Flag -- none (correct)
    • [x] Acceptance Criteria -- 4 specific, verifiable items (fixed from v1)
    • [x] Test Expectations -- present (2 items)
    • [x] Constraints -- present
    • [x] Checklist -- present
    • [x] Related -- present, now references arch-tofu-consumers

    Traceability

    • [x] story:provision label -- "Platform engineer provisions infrastructure via tofu apply"
    • [x] story entry exists -- found in project-page-ios-infrastructure user-stories table (key: provision, role: Platform engineer)
    • [ ] story note still TBD -- Story Note column says "TBD" (no backing story note created). This is a cross-cutting concern shared by all story:provision tickets (#1533, #1534, #1535). Not a blocker for this ticket's scope clarity, but the note should be created before any story:provision ticket reaches done.
    • [x] arch:tofu-consumers label -- tofu-consumers architecture component
    • [x] arch note verified -- arch-tofu-consumers note exists in pal-e-docs (created since v1 review). Documents consumer split between pal-e-platform and pal-e-services, data flow, docs pattern.
    • [x] Forgejo issue -- ldraney/pal-e-services#131, open

    File Targets

    • [x] README.md -- verified: exists in repo as a regular file (not symlink). Currently 3235 bytes. Will be rewritten as TOC.
    • [x] CLAUDE.md -- verified: exists as standalone file. Will become symlink to README.md.
    • [x] docs/image-updater-sops.md -- verified: exists, already has mermaid diagram (graph TB showing CI pipeline through Image Updater). Issue correctly says "no changes needed."
    • [ ] docs/service-registration.md -- WRONG FILENAME: this file does not exist in the repo. The actual file is docs/service-onboarding.md (265 lines, no mermaid, covers the GitOps service onboarding flow). The issue says "add service onboarding flowchart (mermaid) if this file exists, otherwise create it" -- the intent is correct but the filename is wrong. Note: there is also a root-level SERVICE_ONBOARDING.md (618 lines) that covers the same topic in more detail.

    Repo Placement

    OK -- issue filed on pal-e-services, all work scoped to pal-e-services. Single-repo change.

    Dependencies

    • Sibling ticket #1533 (pal-e-platform: CLAUDE.md symlink + docs upgrade) follows the same pattern. No blocking dependency. Both share arch:tofu-consumers.
    • No items currently in in_progress on board-project-ios-infrastructure. All 6 items are in backlog.
    • Pattern reference (godaddy-tofu / appstoreconnect-tofu) is stable -- those repos already standardized.

    Acceptance Criteria

    • [x] "readlink CLAUDE.md -> README.md" -- verifiable by agent
    • [x] "README.md has documentation table linking to all docs/ files" -- verifiable by agent
    • [x] "docs/image-updater-sops.md mermaid retained" -- verifiable by checking mermaid block presence
    • [x] "No content lost from current CLAUDE.md" -- verifiable by diff

    All 4 ACs are specific and agent-verifiable. Significant improvement from v1.

    Blast Radius

    Low. Documentation-only change. No code, no CI pipeline, no downstream consumers affected. The same pattern is being applied across sibling tickets (#1532, #1533) independently.

    Decomposition Assessment

    3 file modifications in 1 repo, 4 ACs. Well within the 5-minute rule. No decomposition needed. 2-point estimate is appropriate.

    Recommendations

    • [BODY] Fix file target: docs/service-registration.md does not exist. The correct filename is docs/service-onboarding.md. Update the File Targets section to reference the correct file.

    Previous Review Disposition

    v1 Recommendation Status
    [BODY] Replace glob with specific file list RESOLVED -- issue now lists 4 specific files
    [BODY] Clarify AC #3 mermaid scope RESOLVED -- AC now says "docs/image-updater-sops.md mermaid retained" and mermaid addition scoped to one file
    [SCOPE] Create arch-tofu-consumers note RESOLVED -- note exists in pal-e-docs
    [SCOPE] Create story note for story:provision OPEN -- still TBD, but cross-cutting (not a blocker for this ticket's scope)
  • Verdict: APPROVED

    Re-review after scope refinement. All four issues from review-1536-2026-06-20 have been resolved.

    Template Completeness

    • [x] Type -- Spike
    • [x] Lineage -- Standalone, part of iOS Infrastructure wave 1
    • [x] Repo -- ldraney/claude-custom
    • [x] Question -- Clear yes/no framing: "Is the MacStadium Orka API sufficient for a Terraform provider?" with comparison sub-questions (AWS EC2 Mac, Xcode Cloud)
    • [x] Deliverables -- 6 items listed, including template-mandated docs/macstadium-orka-research.md and follow-up tickets
    • [x] Time-box -- 1 session (2-3 hours research)
    • [x] Constraints -- "Document findings in docs/macstadium-orka-research.md" (corrected from "issue comments" in v1)
    • [x] Checklist -- 4 items covering research, recommendation, docs file, and follow-up tickets
    • [x] Related -- References project-page-ios-infrastructure and arch-mac-bootstrap

    Traceability

    • [x] story:mac-fleet label -- present on board item
    • [x] story note verified -- mac-fleet entry found in project-page-ios-infrastructure user-stories table (Role: Platform engineer, Success Metric: "Any Mac bootstrapped from Salt and connected to Woodpecker within 30 minutes")
    • [x] arch:mac-bootstrap label -- present on board item
    • [x] arch note verified -- arch-mac-bootstrap note exists in pal-e-docs (doc type, project: project-ios-infrastructure). Covers Salt bootstrap sequence, Orka provider, Woodpecker agent, keychain constraints.
    • [x] Forgejo issue -- ldraney/claude-custom#273, open

    File Targets

    N/A -- Spikes have no pre-existing file targets per template convention. The spike output will be docs/macstadium-orka-research.md, which does not yet exist (confirmed). This is correct -- the file is a deliverable, not a target to verify.

    Repo Placement

    OK. Issue filed on ldraney/claude-custom, Repo field says ldraney/claude-custom. Research spike producing a docs/ file -- claude-custom is the correct home for cross-cutting infrastructure research docs.

    Dependencies

    No blocking dependencies. Board item #1532 (macbook-ssh CLAUDE.md) shares the arch:mac-bootstrap label but is independent work. No items in in_progress column. The spike itself informs future orka-tofu provider work but that dependency flows forward (spike outputs inform new tickets), not backward.

    Acceptance Criteria

    All 6 deliverables are concrete and agent-verifiable:

    • Orka API capability matrix -- checkable (table in docs file)
    • Pricing comparison table -- checkable (table in docs file)
    • Go/no-go recommendation -- checkable (explicit section)
    • If go: initial resource list -- conditional, checkable
    • docs/macstadium-orka-research.md -- checkable (file exists)
    • Follow-up tickets filed if go -- checkable (Forgejo issues exist or rationale documented)

    The 4-item Checklist section mirrors the deliverables and provides a completion tracker. All criteria are verifiable by an agent after implementation.

    Blast Radius

    Low. Research spike with no code changes. Findings inform future decisions about orka-tofu provider creation. No downstream consumers affected during the spike itself.

    Decomposition Assessment

    No decomposition needed. Single research spike, 6 deliverables all within a single session, single repo (claude-custom), output is one docs file plus potential follow-up issues. Well within the 5-minute rule for agent work (the 2-3 hour time-box is for research depth, not implementation complexity).

    v1 Issues Resolution

    v1 Issue Status
    [BODY] Add docs/macstadium-orka-research.md deliverable RESOLVED -- now listed as deliverable #5
    [BODY] Add follow-up tickets deliverable RESOLVED -- now listed as deliverable #6 and checklist item #4
    [SCOPE] Create project page project-ios-infrastructure RESOLVED -- project-page-ios-infrastructure exists with user-stories section
    [SCOPE] Create arch note arch-mac-bootstrap RESOLVED -- arch-mac-bootstrap note exists in pal-e-docs

    Recommendation

    No action needed. All v1 issues resolved. Ticket is ready for todo.

  • Verdict: READY

    Board item #1535 on board-project-ios-infrastructure. Forgejo issue: ldraney/appstoreconnect-tofu#3. Reviewed 2026-06-20 (re-review v2).

    Re-review context: Previous review (review-1535-2026-06-20) returned NEEDS_REFINEMENT due to missing arch-asc-provider note and missing project-page-ios-infrastructure. Both have since been created. Issue body was unchanged -- it was already clean.

    Template Completeness

    • [x] Type -- Feature
    • [x] Lineage -- Standalone, first code implementation
    • [x] Repo -- ldraney/appstoreconnect-tofu
    • [x] User Story -- platform engineer wants declarative bundle ID management
    • [x] Context -- adequate background, references architecture.md and godaddy-tofu patterns
    • [x] File Targets -- 7 files to create, clearly specified with purpose
    • [x] Feature Flag -- "none" (appropriate for provider infrastructure)
    • [x] Acceptance Criteria -- 5 items covering build, plan, apply, destroy, data source
    • [x] Test Expectations -- unit (JWT, JSON:API) and integration (TF_ACC=1)
    • [x] Constraints -- godaddy-tofu patterns, JSON:API in pkg/, env vars only
    • [x] Checklist -- PR opened, tests pass, no unrelated changes
    • [x] Related -- project-ios-infrastructure

    All required sections present. Template is fully complete.

    Traceability

    • [x] story:provision label -- present on board item
    • [x] story note verified -- "provision" entry found in project-page-ios-infrastructure user-stories section (Role: Platform engineer, Success: "tofu apply provisions bundle IDs, profiles, devices, DNS for a new iOS app")
    • [x] arch:asc-provider label -- present on board item
    • [x] arch note verified -- arch-asc-provider note exists in pal-e-docs (project: project-ios-infrastructure, covers API capabilities, auth, app creation constraint, consumer info)
    • [x] Forgejo issue -- https://forgejo.tail5b443a.ts.net/ldraney/appstoreconnect-tofu/issues/3, state: open

    All three traceability legs verified. Previous blockers resolved.

    File Targets

    • [x] main.go -- to create, consistent with docs/conventions.md debug flag pattern
    • [x] provider.go -- to create, consistent with docs/architecture.md diagram
    • [x] go.mod / go.sum -- to create, standard Go module init
    • [x] pkg/appstoreconnect/client.go -- to create, consistent with architecture.md Client class diagram
    • [x] pkg/appstoreconnect/bundle_ids.go -- to create, consistent with architecture.md BundleID struct
    • [x] resource_bundle_id.go -- to create, consistent with architecture.md resource diagram
    • [x] data_source_bundle_ids.go -- to create, consistent with architecture.md data source diagram

    All files are new (repo currently contains only CLAUDE.md, README.md, and docs/). File paths are consistent with the documented architecture and conventions. The repo's docs/conventions.md provides detailed Go patterns (factory pattern, debug flag, ImportState, JSON:API handling, error mapping) that give the implementing agent strong guardrails.

    Repo Placement

    OK. Issue filed on ldraney/appstoreconnect-tofu, all work targets that repo. Single-repo scope.

    Dependencies

    • No upstream blockers on the board -- this is the first implementation ticket.
    • Board item #1537 (Manual: Create Palinks app in ASC) logically depends on bundle_id existing first (per architecture diagram: BID -> APP). Correctly sequenced.
    • godaddy-tofu repo exists and is the pattern reference. Not a code dependency, but a convention dependency -- agent needs read access to study patterns.
    • No cross-repo code dependencies.

    Acceptance Criteria

    5 ACs, all agent-verifiable:

    • go build -- verifiable via CLI
    • tofu plan -- verifiable via CLI (requires provider config)
    • tofu apply creates bundle ID -- verifiable against live API (requires API credentials)
    • tofu destroy removes bundle ID -- verifiable against live API
    • Data source lists bundle IDs -- verifiable via tofu plan output

    ACs are well-scoped and testable. The tofu apply/destroy ACs require live API credentials which the agent would need access to (env vars per Constraints section).

    Blast Radius

    Minimal. This is a greenfield provider in its own repo. No existing consumers. The only downstream integration point is pal-e-platform/terraform/ios.tf (shown in architecture.md), which would consume this provider after it's published. No blast radius concerns for this ticket.

    Decomposition Assessment

    7 files to create across 1 repo. 5 acceptance criteria. 2 test categories. All files follow well-documented patterns from godaddy-tofu and the repo's own docs/conventions.md. The strong convention docs (factory pattern, CRUD mapping, JSON:API handling, error table, naming conventions) significantly reduce implementation ambiguity. Estimated agent work: ~5 minutes, borderline but feasible as a single pass given the pattern-following nature. No decomposition needed.

    Recommendation

    No action needed. Ticket is ready to move from backlog to todo.

  • Verdict: APPROVED

    Re-review of board item #1532 after scope refinement. All three findings from review-1532-2026-06-20 (NEEDS_REFINEMENT) have been resolved.

    Previous Findings — Resolution

    • [x] [SCOPE] Project page project-page-ios-infrastructure — NOW EXISTS with user-stories section. Story build is listed (role: Platform engineer, metric: Woodpecker builds, signs, uploads to TestFlight with zero manual steps).
    • [x] [SCOPE] Architecture note arch-mac-bootstrap — NOW EXISTS in pal-e-docs (note type: doc, project: project-ios-infrastructure). Covers Salt states, Orka provider, Woodpecker agent, keychain/certs components.
    • [x] [BODY] File target descriptions — FIXED. Issue body now says "no changes needed unless TOC references need updating" for docs/ios-pipeline.md and docs/dev-build-guide.md. ACs updated to say "Existing mermaid diagrams ... are retained".

    Template Completeness

    • [x] Type — Feature
    • [x] Lineage
    • [x] Repo
    • [x] User Story
    • [x] Context
    • [x] File Targets
    • [x] Feature Flag — "none"
    • [x] Acceptance Criteria
    • [x] Test Expectations
    • [x] Constraints
    • [x] Checklist
    • [x] Related

    Traceability

    • [x] story:build label — present on board item
    • [x] story note verified — found in project-page-ios-infrastructure user-stories section (key: build)
    • [x] arch:mac-bootstrap label — present on board item
    • [x] arch note verified — arch-mac-bootstrap note exists in pal-e-docs (slug: arch-mac-bootstrap)
    • [x] Forgejo issue — https://forgejo.tail5b443a.ts.net/ldraney/macbook-ssh/issues/4, open

    File Targets

    • [x] README.md — verified: exists in repo, currently a project overview with docs table. Will be rewritten as TOC following godaddy-tofu/appstoreconnect-tofu pattern.
    • [x] CLAUDE.md — verified: does NOT exist (correct — will be created as symlink to README.md).
    • [x] docs/ios-pipeline.md — verified: exists, contains 4 mermaid blocks. Issue correctly states "no changes needed unless TOC references need updating".
    • [x] docs/dev-build-guide.md — verified: exists, contains 2 mermaid blocks. Issue correctly states "no changes needed unless TOC references need updating".

    Repo Placement

    OK. Issue filed on ldraney/macbook-ssh, all file targets are in macbook-ssh. Single repo, no cross-repo concerns.

    Dependencies

    No blocking dependencies. Sibling tickets #1533 (pal-e-platform) and #1534 (pal-e-services) are the same pattern for other repos but are independent — no ordering requirement. All board items are in backlog.

    Acceptance Criteria

    3 ACs, all agent-verifiable:

    • readlink CLAUDE.md returns README.md — verifiable via shell command
    • README.md has documentation table linking to all docs/ files — verifiable by reading file
    • Existing mermaid diagrams in docs/ios-pipeline.md and docs/dev-build-guide.md are retained — verifiable by confirming mermaid blocks still present after changes

    Test expectations are reasonable: symlink resolves, mermaid renders in Forgejo.

    Blast Radius

    Low. Documentation-only change (symlink + README rewrite). No code, no config, no CI changes. The repo has a .claude-no-enforce file, so no hook enforcement concerns. Sibling repos have their own independent tickets.

    Decomposition Assessment

    2 files modified (README.md rewrite, CLAUDE.md symlink creation), 2 files verified unchanged. 3 ACs. 1 repo. Well under the 5-minute rule. No decomposition needed.

    Recommendation

    No action needed. All previous findings resolved. Ticket is ready to move to todo.

  • Verdict: APPROVED

    Re-review after scope refinement. All three [BODY] issues from review-1533-2026-06-20 have been resolved. The remaining [SCOPE] item (missing arch note) is non-blocking for implementation -- the work itself does not depend on it.

    Template Completeness

    • [x] Type -- Feature
    • [x] Lineage -- Standalone, repo standardization wave 1
    • [x] Repo -- ldraney/pal-e-platform
    • [x] User Story
    • [x] Context
    • [x] File Targets
    • [x] Feature Flag -- none (correct, infra/docs change)
    • [x] Acceptance Criteria
    • [x] Test Expectations
    • [x] Constraints
    • [x] Checklist
    • [x] Related

    Traceability

    • [x] story:provision label -- "Platform engineer provisions iOS infra via tofu apply"
    • [x] story note verified -- found in project-page-ios-infrastructure user-stories section (key: provision)
    • [x] arch:tofu-consumers label
    • [ ] arch note MISSING -- arch-tofu-consumers note does not exist in pal-e-docs. [SCOPE] Create architecture note arch-tofu-consumers. Non-blocking: the implementation agent does not need this note to complete the work.
    • [x] Forgejo issue -- ldraney/pal-e-platform#459, open

    File Targets

    • [x] README.md -- verified: exists (3825 bytes), regular file. Richer than CLAUDE.md. Will be rewritten as project TOC with docs table.
    • [x] CLAUDE.md -- verified: exists as regular file (1597 bytes, NOT a symlink). Will be replaced with symlink to README.md.
    • [x] docs/architecture.md -- verified: exists, 0 mermaid occurrences. Issue specifies: add system component flowchart.
    • [x] docs/networking.md -- verified: exists, 0 mermaid occurrences. Issue specifies: add network topology diagram.
    • [x] docs/database.md -- verified: exists, 0 mermaid occurrences. Issue specifies: add CNPG cluster diagram.
    • [x] docs/hetzner-edge.md -- verified: exists, already has mermaid. Issue correctly says "no changes needed."
    • [x] docs/keycloak-smtp.md -- verified: exists. Issue correctly says "no mermaid needed."
    • [x] docs/monitoring.md -- verified: exists. Issue correctly says "no mermaid needed."
    • [x] docs/secrets.md -- verified: exists. Issue correctly says "no mermaid needed."

    All 9 file target claims verified against the repo tree. The v1 ambiguity about docs/*.md glob is fully resolved -- each file is listed explicitly with its action.

    Repo Placement

    OK. Issue filed on ldraney/pal-e-platform, all file targets in that repo. Single-repo change.

    Dependencies

    No blocking dependencies. Board siblings #1532 (macbook-ssh) and #1534 (pal-e-services) are identical symlink+docs tasks for other repos -- independent, no ordering constraint. All board items are in backlog; nothing in in_progress or next_up.

    Acceptance Criteria

    • [x] readlink CLAUDE.md returns README.md -- verifiable, clear pass/fail
    • [x] README.md has documentation table linking to all 7 docs/ files -- verifiable by grep
    • [x] docs/architecture.md has a system component flowchart (mermaid) -- verifiable by grep for mermaid block + flowchart keyword
    • [x] docs/networking.md has a network topology diagram (mermaid) -- verifiable by grep for mermaid block
    • [x] docs/database.md has a CNPG cluster diagram (mermaid) -- verifiable by grep for mermaid block
    • [x] No content lost from current CLAUDE.md -- verifiable by diff

    All 6 ACs are specific, testable, and automatable. The v1 ambiguity ("Existing docs have mermaid diagrams") has been replaced with 3 named-file ACs.

    Blast Radius

    Low. Documentation/metadata change only. No code changes, no CI impact. The README.md is the richer file (3825 bytes vs 1597 for CLAUDE.md) so merge direction is clear: CLAUDE.md content folds into README.md.

    Decomposition Assessment

    5 files modified (README.md, CLAUDE.md symlink, 3 docs with mermaid), 6 AC. On the boundary but feasible for a single agent pass: the mermaid additions are one diagram each, and the symlink+TOC pattern is well-established from godaddy-tofu. Estimated agent time: ~4 minutes. No decomposition needed.

    Recommendation

    • [SCOPE] Create architecture note arch-tofu-consumers in pal-e-docs documenting which repos consume the pal-e-platform base (pal-e-services, godaddy-tofu, appstoreconnect-tofu, etc.). Non-blocking for this ticket -- can be done in parallel or after.

    All [BODY] issues from v1 review are resolved. Ticket is ready for implementation.

  • Verdict: NEEDS_REFINEMENT

    Template Completeness

    • [x] Type -- Feature
    • [x] Lineage -- Standalone, repo standardization wave 1
    • [x] Repo -- ldraney/pal-e-platform
    • [x] User Story
    • [x] Context
    • [x] File Targets
    • [x] Feature Flag -- none (correct, infra/docs change)
    • [x] Acceptance Criteria
    • [x] Test Expectations
    • [x] Constraints
    • [x] Checklist
    • [x] Related

    Traceability

    • [x] story:provision label -- "Platform engineer provisions iOS infra via tofu apply"
    • [x] story note verified -- found in project-page-ios-infrastructure user-stories section (key: provision)
    • [x] arch:tofu-consumers label
    • [ ] arch note MISSING -- [SCOPE] No note found for arch-tofu-consumers in pal-e-docs. Create architecture note arch-tofu-consumers documenting the repos that consume the pal-e-platform base.
    • [x] Forgejo issue -- ldraney/pal-e-platform#459, open

    File Targets

    • [x] README.md -- verified: exists (78 lines), already has a documentation table and architecture section. Content is richer than CLAUDE.md. The task is to merge CLAUDE.md content into this file and ensure TOC pattern matches godaddy-tofu.
    • [x] CLAUDE.md -- verified: exists as a regular file (45 lines, ASCII text, NOT a symlink). Must be replaced with a symlink to README.md.
    • [ ] docs/*.md -- ISSUE: The issue Context section says "Existing docs (hetzner-edge.md, keycloak-smtp.md) need mermaid diagrams added" but the repo has 7 doc files (architecture.md, database.md, hetzner-edge.md, keycloak-smtp.md, monitoring.md, networking.md, secrets.md) plus 1 spike. Only hetzner-edge.md already has mermaid. The issue body mentions only 2 docs but AC says "Existing docs have mermaid diagrams" (all of them). The scope is ambiguous: does the agent add mermaid to all 6 remaining docs, or just keycloak-smtp.md? This needs clarification.

    Repo Placement

    OK. Issue is filed on ldraney/pal-e-platform, and all file targets are in that repo. Single-repo change.

    Dependencies

    No blocking dependencies. Board sibling items #1532 (macbook-ssh) and #1534 (pal-e-services) are identical symlink+docs tasks for other repos -- independent, no ordering constraint. No items in in_progress or next_up columns.

    Acceptance Criteria

    • [x] readlink CLAUDE.md -- verifiable, clear pass/fail
    • [x] README.md has documentation table -- verifiable by grep
    • [ ] "Existing docs have mermaid diagrams" -- ambiguous scope. Does this mean ALL 7 docs, or just the 2 mentioned in Context? If all 7, the scope is larger than a 3-point ticket. hetzner-edge.md already has mermaid, so only 6 (or 1) need work.
    • [x] No content lost from CLAUDE.md -- verifiable by diff

    Blast Radius

    Low. This is a documentation/metadata change only. No code changes, no CI impact. The README.md already has a complete documentation table, so the merge direction matters: CLAUDE.md content should be folded into README.md (not the reverse). The existing README.md is the richer file (78 lines vs 45 lines for CLAUDE.md).

    Decomposition Assessment

    If scope is "all 7 docs get mermaid": 8+ file targets in 1 repo, potentially >5 minutes of agent work crafting meaningful mermaid diagrams for architecture.md, database.md, monitoring.md, networking.md, secrets.md, and keycloak-smtp.md. This would warrant decomposition or a scope reduction.

    If scope is "just keycloak-smtp.md + symlink swap": 3 file targets, 4 AC -- fits a single agent pass. No decomposition needed.

    Current ambiguity makes this assessment indeterminate.

    Recommendation

    • [BODY] Clarify the docs/*.md file target: list each specific doc file that needs mermaid added. The Context section names only hetzner-edge.md and keycloak-smtp.md, but hetzner-edge.md already has mermaid. If the intent is all docs, list them explicitly and consider raising points from 3 to 5. If only keycloak-smtp.md, change the wildcard to the specific file.
    • [BODY] Update AC #3 from "Existing docs have mermaid diagrams" to name specific files (e.g., "keycloak-smtp.md has a mermaid diagram" or list all 6 files).
    • [SCOPE] Create architecture note arch-tofu-consumers in pal-e-docs documenting which repos consume the pal-e-platform base (pal-e-services, godaddy-tofu, appstoreconnect-tofu, etc.).
  • Verdict: NEEDS_REFINEMENT

    Template Completeness

    • [x] Type -- Feature
    • [x] Lineage -- Standalone, repo standardization
    • [x] Repo -- ldraney/pal-e-services
    • [x] User Story -- present and well-formed
    • [x] Context -- adequate
    • [ ] File Targets -- PARTIAL: uses glob pattern docs/*.md instead of listing specific files. Repo has 7 docs; only image-updater-sops.md already has mermaid. Issue does not specify which docs get diagrams or what kind of diagrams.
    • [x] Feature Flag -- none (correct for this work)
    • [x] Acceptance Criteria -- present (4 items)
    • [x] Test Expectations -- present (2 items)
    • [x] Constraints -- present
    • [x] Checklist -- present
    • [x] Related -- present

    Traceability

    • [x] story:provision label -- "Platform engineer provisions infrastructure via tofu apply"
    • [ ] story note MISSING -- story:provision entry exists in project-page-ios-infrastructure user-stories table, but Story Note column is "TBD" (no backing story note created yet). [SCOPE] Create story note for story:provision and update the user-stories table.
    • [x] arch:tofu-consumers label -- tofu-consumers architecture component
    • [ ] arch note MISSING -- no note matching "arch-tofu-consumers" found in pal-e-docs. [SCOPE] Create architecture note arch-tofu-consumers for component tofu-consumers.
    • [x] Forgejo issue -- ldraney/pal-e-services#131, open

    File Targets

    • [x] CLAUDE.md -- verified: exists in repo, currently a standalone file (not a symlink). Contains tech stack, key paths, common operations.
    • [x] README.md -- verified: exists in repo, currently a separate file. Has three-repo paradigm docs, documentation table, what-this-repo-deploys, quick start.
    • [ ] docs/*.md -- ISSUE: glob pattern instead of specific targets. The repo has 7 docs: dev-prod-environments.md, image-updater-sops.md, keycloak.md, secrets-management.md, service-onboarding.md, terraform-layout.md, troubleshooting.md. Only image-updater-sops.md already has a mermaid diagram. The issue says "add mermaid diagrams to existing docs" without specifying which ones get diagrams or what kind. An agent needs specific file-by-file guidance.

    Repo Placement

    OK -- issue filed on pal-e-services, work scoped to pal-e-services. Single-repo change.

    Dependencies

    • Sibling ticket #1533 (pal-e-platform: CLAUDE.md symlink + docs upgrade) is the same pattern applied to a different repo. No blocking dependency, but the two should follow the same approach.
    • Sibling ticket #1532 (macbook-ssh) is the same pattern for a different repo.
    • The issue references "Follow godaddy-tofu / appstoreconnect-tofu pattern exactly" -- those repos have already been standardized. This is a dependency on their pattern being the template.
    • No blocking items in in_progress.

    Acceptance Criteria

    • [x] "readlink CLAUDE.md -> README.md" -- verifiable by agent
    • [x] "README.md has documentation table linking to docs/" -- verifiable by agent
    • [ ] "Existing docs have mermaid diagrams" -- VAGUE: which docs? All 7? Just the ones where diagrams add value? What kind of diagrams (flowcharts, sequence, ER)? An agent cannot determine this without more guidance.
    • [x] "No content lost from current CLAUDE.md" -- verifiable by diff

    Blast Radius

    Low blast radius. CLAUDE.md symlink is a repo-local convention change. README.md rewrite affects only repo documentation. No code changes, no CI pipeline changes, no downstream consumers affected. The same pattern exists in sibling tickets (#1532, #1533) -- consistency matters but each is independent.

    Decomposition Assessment

    If the scope is clarified to specific docs, this is a 2-point ticket (CLAUDE.md symlink + README.md rewrite + targeted mermaid additions). If "all 7 docs" is the intent, that is 9 files across 1 repo with potentially substantial mermaid diagram creation for each -- borderline on the 5-minute rule. Recommend clarifying scope to keep it at 2 points. No decomposition needed if scope is narrowed.

    Recommendations

    • [BODY] Replace glob docs/*.md with specific file list. At minimum list which docs get mermaid diagrams and describe each diagram type (e.g., "docs/terraform-layout.md -- add flowchart showing file dependency order", "docs/service-onboarding.md -- add sequence diagram for onboarding flow").
    • [BODY] Clarify AC #3: "Existing docs have mermaid diagrams" -- specify which docs and what diagram types. Note that image-updater-sops.md already has a mermaid diagram.
    • [SCOPE] Create architecture note arch-tofu-consumers for the tofu-consumers component.
    • [SCOPE] Create story note for story:provision and update the user-stories table on project-page-ios-infrastructure.
Project Page 1
  • iOS Infrastructure project-page-ios-infrastructure

    iOS Infrastructure

    Vision

    Full IaC pipeline for iOS app lifecycle: from DNS registration to App Store distribution. Three custom OpenTofu providers (godaddy, appstoreconnect, orka) consumed by pal-e-platform, with Woodpecker CI driving builds on API-managed Mac infrastructure. Any Mac — personal, cloud, or owned mini — is bootstrapped from Salt states and joins the build fleet.

    User Stories

    Key Story Note Role Success Metric
    provision TBD Platform engineer tofu apply provisions bundle IDs, profiles, devices, DNS for a new iOS app
    build TBD Platform engineer Woodpecker builds, signs, and uploads to TestFlight with zero manual steps (after one-time app creation)
    mac-fleet TBD Platform engineer Any Mac bootstrapped from Salt and connected to Woodpecker within 30 minutes
    no-fastlane TBD Platform engineer Dev build on iPhone using only ASC API + xcodebuild — zero Fastlane dependency

    Architecture

    Three-provider ecosystem consumed by pal-e-platform/terraform/:

    • godaddy-tofu — DNS (done)
    • appstoreconnect-tofu — Apple infrastructure (in progress)
    • orka-tofu — Mac cloud VMs (not started, pending API research)

    Build pipeline: Woodpecker CI → Mac agent (self-hosted) → xcodebuild + xcrun altool

    Mac bootstrap: Salt states (Xcode CLI tools, certs, keychain, Woodpecker agent)

    Architecture notes:

    Note Scope
    arch-mac-bootstrap Salt bootstrap sequence, keychain constraints, Mac-as-cattle pattern
    arch-asc-provider ASC API capabilities, auth, app creation constraint
    arch-tofu-consumers How pal-e-platform and pal-e-services consume providers, Keycloak split

    Keycloak split: Platform creates realms (infrastructure primitive). Services manages users, clients, roles, group mappings inside realms (application-scoped).

    Board

    Board: board-project-ios-infrastructure

    Status

    Component Status
    godaddy-tofu Done — in production
    appstoreconnect-tofu Repo + docs (PR #2 approved). API verified live.
    orka-tofu Not started — needs API research spike
    Mac Salt bootstrap Not started — macbook-ssh has docs, needs Salt states
    Woodpecker Mac agent Not started — depends on Salt bootstrap
    Palinks TestFlight (no Fastlane) Blocked — app not created in ASC web UI yet
    fastlane-tofu Archived — redundant (Fastlane just wraps ASC API + xcodebuild)

    Milestones

    None yet.

    Repos

    Repo Platform Role Status
    ldraney/godaddy-tofu Forgejo DNS provider Production
    ldraney/appstoreconnect-tofu Forgejo Apple infra provider PR #2 (docs)
    ldraney/orka-tofu Forgejo Mac cloud provider Not created yet
    ldraney/pal-e-platform Forgejo Consumer (terraform/) Active
    ldraney/pal-e-services Forgejo Service registration + Keycloak users Active
    ldraney/macbook-ssh Forgejo Mac bootstrap (→ Salt) Docs only
    ldraney/palinks-ios Forgejo iOS app Archive builds
    ldraney/landscaping-assistant-ios Forgejo iOS app (template) TestFlight
    ldraney/fastlane-tofu Forgejo Archived — redundant Archived
Doc 4
  • Architecture: Tofu Provider Consumers

    Purpose

    How pal-e-platform and pal-e-services consume the three custom OpenTofu providers (godaddy, appstoreconnect, orka) to provision infrastructure for iOS apps.

    Consumer Split

    Repo Scope Providers Used
    pal-e-platform Infrastructure primitives: DNS records, bundle IDs, profiles, Mac VMs, Keycloak realms godaddy, appstoreconnect, orka
    pal-e-services Application-level config: service registration, Keycloak users/clients/roles, app deployments (none directly — consumes platform outputs)

    Data Flow

    For a new iOS app:

    1. pal-e-platform: tofu apply creates DNS record (godaddy), bundle ID + profile (appstoreconnect), Mac VM (orka)
    2. Manual step: operator creates app in App Store Connect web UI (API restriction)
    3. pal-e-platform: tofu import imports the app resource
    4. pal-e-services: registers the service, configures Keycloak realm users/clients, sets up Woodpecker pipeline
    5. Woodpecker: Mac agent runs xcodebuild + xcrun altool to build, sign, upload

    Docs Pattern

    Both repos follow the CLAUDE.md → README.md symlink + docs/ pattern. README.md is a TOC linking into docs/ which contain mermaid diagrams. Tickets #1533 and #1534 bring these repos into compliance.

    Keycloak Split

    Platform creates realms (infrastructure primitive). Services manages what lives inside realms — users, clients, roles, group mappings — because these are application-scoped.

    • Repos: pal-e-platform, pal-e-services
    • Tickets: #1533 (pal-e-platform docs), #1534 (pal-e-services docs)
    • Board: board-project-ios-infrastructure
  • Architecture: App Store Connect Provider

    Purpose

    Custom OpenTofu provider for the App Store Connect REST API. Manages iOS app lifecycle (bundle IDs, profiles, devices, apps) as infrastructure-as-code. Built in Go with the Terraform Plugin Framework.

    API Capabilities

    Resource Create Read Update Delete Priority
    Apps NO (Apple blocks) Yes Yes NO P0
    Bundle IDs Yes Yes Yes P0
    Profiles Yes Yes Yes P1
    Certificates Yes P1
    Devices Yes Yes Yes P2
    Beta Groups Yes Yes Yes Yes P2

    Key Constraint

    POST /v1/apps returns 403 regardless of API key role — Apple restricts app creation to the web UI. The pipeline must detect new apps and prompt the operator to create them manually at appstoreconnect.apple.com, then import via tofu import.

    Auth

    JWT (ES256) bearer tokens generated from an API key (.p8 file). Tokens expire after 20 minutes; the client auto-regenerates. Key has Admin role.

    Consumer

    pal-e-platform/terraform/ declares appstoreconnect provider resources alongside godaddy and orka providers. A single tofu apply provisions DNS + Apple infra + Mac VMs.

    • Repo: appstoreconnect-tofu
    • Ticket: #1535 (P0 bundle_id resource)
    • Board: board-project-ios-infrastructure
  • Architecture: Mac Bootstrap arch-mac-bootstrap

    Architecture: Mac Bootstrap

    Purpose

    Define how any Mac (personal MacBook, cloud VM, owned Mac mini) is bootstrapped from bare metal to a functioning iOS build agent. Salt states provide the IaC layer — the same states work regardless of where the Mac lives.

    Components

    Component Repo Role
    Salt states macbook-ssh (future) Xcode CLI tools, certs, keychain, Woodpecker agent install
    Orka provider orka-tofu Provision Mac VMs via MacStadium API
    Woodpecker agent pal-e-platform Self-hosted CI agent on Mac, connects to Woodpecker server
    Keychain + certs macbook-ssh Import signing certs, create ci-build keychain

    Bootstrap Sequence

    1. tofu apply in orka-tofu provisions a Mac VM (or skip for physical Mac)
    2. Salt highstate installs Xcode CLI tools, Homebrew, git
    3. Salt imports Apple Developer signing certs into ci-build keychain
    4. Salt installs and configures Woodpecker agent (connects to Woodpecker server on pal-e cluster)
    5. Mac registers as build agent — Woodpecker pipelines can now target it

    Key Constraint

    macOS restricts keychain access in non-GUI SSH sessions. Build commands must run through tmux (started from a GUI terminal) or the Woodpecker agent process (which runs as a LaunchAgent). Direct ssh mac "xcodebuild" fails with 0 valid signing identities.

    • Tickets: #1532 (macbook-ssh docs), #1536 (Orka spike)
    • Repos: macbook-ssh, orka-tofu
    • Board: board-project-ios-infrastructure
  • One-time manual step: create the Palinks app entity in App Store Connect.

    1. Go to appstoreconnect.apple.com → Apps → + → New App
    2. Platform: iOS
    3. Name: Palinks
    4. Primary Language: English (U.S.)
    5. Bundle ID: select com.palinks.app
    6. SKU: com.palinks.app
    7. Click Create

    This unblocks xcrun altool --upload-app for TestFlight uploads. Apple does not allow app creation via API (POST /v1/apps returns 403 regardless of key role).

Board 1