Add iOS pipeline and custom domain docs #250

Merged
ldraney merged 4 commits from docs/ios-pipeline-and-dns into main 2026-06-18 22:19:54 +00:00
Owner

Summary

  • New docs/ios-pipeline.md — iOS build pipeline for the Turbo Native shell
  • Updated docs/networking.md — custom domain routing chain and config locations
  • Updated docs/pipeline.md — reconciled Fastlane references with actual xcodebuild workflow

Changes

  • New docs/ios-pipeline.md — Turbo Native architecture, build steps (SSH + tmux keychain workaround), App Store Connect, TestFlight setup, when-to-rebuild matrix, Why Not Fastlane section, future CI notes
  • Updated docs/networking.md — three-hop routing chain (GoDaddy DNS → Caddy on Hetzner → Tailscale Funnel → k3s), URL matrix, config locations across pal-e-platform/services/deployments, Keycloak client config, troubleshooting
  • Updated docs/pipeline.md — replaced stale Fastlane references with actual xcodebuild workflow
  • API identifiers replaced with env var placeholders throughout

Test Plan

  • Docs-only PR, no code changes to verify
  • iOS pipeline steps match actual App Store submission session
  • Networking routing chain matches actual DNS/Caddy/Funnel config

Review Checklist

  • No secrets or passwords in docs (identifiers replaced with placeholders)
  • Cross-references to existing docs (pipeline.md, ios-dev-builds.md, app-architecture.md)
  • Known issue #249 documented in troubleshooting section
  • Fastlane vs xcodebuild discrepancy explained
  • References #249 (documents the Keycloak root_url issue; does not fix it)
  • project-landscaping-assistant
## Summary - New `docs/ios-pipeline.md` — iOS build pipeline for the Turbo Native shell - Updated `docs/networking.md` — custom domain routing chain and config locations - Updated `docs/pipeline.md` — reconciled Fastlane references with actual xcodebuild workflow ## Changes - New `docs/ios-pipeline.md` — Turbo Native architecture, build steps (SSH + tmux keychain workaround), App Store Connect, TestFlight setup, when-to-rebuild matrix, Why Not Fastlane section, future CI notes - Updated `docs/networking.md` — three-hop routing chain (GoDaddy DNS → Caddy on Hetzner → Tailscale Funnel → k3s), URL matrix, config locations across pal-e-platform/services/deployments, Keycloak client config, troubleshooting - Updated `docs/pipeline.md` — replaced stale Fastlane references with actual xcodebuild workflow - API identifiers replaced with env var placeholders throughout ## Test Plan - [ ] Docs-only PR, no code changes to verify - [ ] iOS pipeline steps match actual App Store submission session - [ ] Networking routing chain matches actual DNS/Caddy/Funnel config ## Review Checklist - [x] No secrets or passwords in docs (identifiers replaced with placeholders) - [x] Cross-references to existing docs (pipeline.md, ios-dev-builds.md, app-architecture.md) - [x] Known issue #249 documented in troubleshooting section - [x] Fastlane vs xcodebuild discrepancy explained ## Related Notes - References #249 (documents the Keycloak root_url issue; does not fix it) - `project-landscaping-assistant`
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add custom domain and DNS routing docs to networking.md
Some checks are pending
CI / scan_ruby (pull_request) Waiting to run
CI / scan_js (pull_request) Waiting to run
CI / lint (pull_request) Waiting to run
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
11e6b9574c
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

PR #250 Review

DOMAIN REVIEW

Tech stack: Markdown documentation only (no code changes). Review focuses on documentation accuracy, internal consistency, cross-reference correctness, and secrets exposure.

Two files changed:

  • docs/ios-pipeline.md (new, 153 lines) -- iOS build pipeline documentation
  • docs/networking.md (appended, 57 lines) -- Custom domain routing chain

BLOCKERS

1. Incorrect issue cross-reference -- #249 mismatch

The PR body states "Closes #249" and the Review Checklist says "Known issue #249 documented in troubleshooting section." However, issue #249 is titled "Test user login fails: keycloak-test-users.env has wrong usernames" -- a test-user login bug. The troubleshooting section in networking.md references #249 in the context of a Keycloak root_url misconfiguration ("Back to Application" link pointing to the wrong URL). These are completely different issues.

Additionally, a docs-only PR cannot close a bug about wrong usernames in an env file. Either the "Closes #249" is wrong and should reference a different issue, or issue #249 was repurposed/mislabeled. This must be corrected before merge -- an incorrect Closes directive will auto-close the wrong issue.

2. Contradictory build tooling across docs

The new ios-pipeline.md documents raw xcodebuild commands with XcodeGen and manual tmux send-keys for archive/export/upload. Meanwhile, the existing docs describe a different workflow:

  • pipeline.md (lines 115-117): ssh macbook "cd ~/landscaping-assistant-ios && fastlane beta" / fastlane release
  • ios-dev-builds.md (lines 97-145): Full Fastlane Fastfile with beta and release lanes, build_app, upload_to_testflight, upload_to_app_store

These are mutually exclusive approaches. If the project migrated from Fastlane to raw xcodebuild+XcodeGen, the existing docs need updating. If both approaches are valid, the new doc should explain when to use which. As-is, a reader following pipeline.md will run fastlane beta while a reader following ios-pipeline.md will run raw xcodebuild -- contradictory instructions for the same operation.

3. Apple API credentials exposed in documentation

ios-pipeline.md includes specific Apple API credential identifiers in the build commands:

  • authenticationKeyID 2A6BSP3H76
  • authenticationKeyIssuerID e5ecbb14-2397-43f2-83fa-915967608055

While the private key file itself (.p8) is not included, the Key ID and Issuer ID are sensitive identifiers that should not be in a public-facing or version-controlled document. These should be replaced with placeholder values (e.g., YOUR_KEY_ID, YOUR_ISSUER_ID) or referenced via environment variables, with actual values stored in the secrets path only.


NITS

4. CLAUDE.md docs table not updated

The Documentation table in CLAUDE.md does not include an entry for the new docs/ios-pipeline.md. All other docs are listed there. Add a row like:

| [iOS Pipeline](docs/ios-pipeline.md) | Turbo Native build pipeline, App Store Connect, when to rebuild |

5. Production URL not reflected in CLAUDE.md URLs table

The networking doc now documents https://landscaping-assistant.app as the primary public URL. The CLAUDE.md URLs table still shows only the Tailscale hostname for Production. Consider adding the public URL:

| Production (public) | https://landscaping-assistant.app |

6. Hetzner VPS IP address in docs

networking.md includes the literal IP 178.156.129.142 for the Hetzner edge VPS. This is a minor operational exposure concern. It is less sensitive than API keys but does provide targeting information. Consider whether this level of detail is needed in application docs vs. infrastructure docs.

7. Mermaid diagram in ios-pipeline.md

The Mermaid graph LR diagram uses escaped quotes in node labels (\"). This renders correctly in most Mermaid renderers but may break in some. Verify it renders properly in Forgejo's markdown preview.

8. "Related" section link format

In ios-pipeline.md, the "Source" line at the bottom reads forgejo/ldraney/landscaping-assistant-ios as plain text rather than a clickable link. Consider making it a proper link:

- Source: [landscaping-assistant-ios](https://forgejo.tail5b443a.ts.net/ldraney/landscaping-assistant-ios)

SOP COMPLIANCE

  • PR body has: ## Summary, ## Changes, ## Test Plan, ## Related -- all present
  • No .env files or credential files committed
  • No secrets in committed content -- Apple API Key ID and Issuer ID are in ios-pipeline.md (Blocker #3)
  • No unnecessary file changes (scope is tight: 2 doc files)
  • Commit messages are descriptive (single commit, clear title)

PROCESS OBSERVATIONS

  • Documentation debt risk: The Fastlane vs xcodebuild contradiction (Blocker #2) suggests the iOS build process evolved but earlier docs were not updated. This PR should either update the older docs or explicitly explain the relationship. Leaving contradictory instructions across three docs creates operational confusion.
  • Cross-reference integrity: The #249 mismatch (Blocker #1) suggests the issue was either repurposed or the wrong number was cited. Docs that reference issue numbers must be verified against the actual issue content.
  • Good practice: The "When to Rebuild iOS" matrix and the routing chain diagram are both high-value additions that will reduce operational questions.

VERDICT: NOT APPROVED

Three blockers must be resolved:

  1. Fix the #249 cross-reference (either correct the issue number or remove the "Closes" directive)
  2. Reconcile the Fastlane vs xcodebuild contradiction across docs
  3. Remove or redact Apple API credential identifiers from ios-pipeline.md
## PR #250 Review ### DOMAIN REVIEW **Tech stack:** Markdown documentation only (no code changes). Review focuses on documentation accuracy, internal consistency, cross-reference correctness, and secrets exposure. **Two files changed:** - `docs/ios-pipeline.md` (new, 153 lines) -- iOS build pipeline documentation - `docs/networking.md` (appended, 57 lines) -- Custom domain routing chain --- ### BLOCKERS **1. Incorrect issue cross-reference -- #249 mismatch** The PR body states "Closes #249" and the Review Checklist says "Known issue #249 documented in troubleshooting section." However, issue #249 is titled **"Test user login fails: keycloak-test-users.env has wrong usernames"** -- a test-user login bug. The troubleshooting section in `networking.md` references #249 in the context of a Keycloak `root_url` misconfiguration ("Back to Application" link pointing to the wrong URL). These are completely different issues. Additionally, a docs-only PR cannot close a bug about wrong usernames in an env file. Either the "Closes #249" is wrong and should reference a different issue, or issue #249 was repurposed/mislabeled. This must be corrected before merge -- an incorrect `Closes` directive will auto-close the wrong issue. **2. Contradictory build tooling across docs** The new `ios-pipeline.md` documents raw `xcodebuild` commands with XcodeGen and manual `tmux send-keys` for archive/export/upload. Meanwhile, the existing docs describe a different workflow: - `pipeline.md` (lines 115-117): `ssh macbook "cd ~/landscaping-assistant-ios && fastlane beta"` / `fastlane release` - `ios-dev-builds.md` (lines 97-145): Full Fastlane `Fastfile` with `beta` and `release` lanes, `build_app`, `upload_to_testflight`, `upload_to_app_store` These are mutually exclusive approaches. If the project migrated from Fastlane to raw xcodebuild+XcodeGen, the existing docs need updating. If both approaches are valid, the new doc should explain when to use which. As-is, a reader following `pipeline.md` will run `fastlane beta` while a reader following `ios-pipeline.md` will run raw `xcodebuild` -- contradictory instructions for the same operation. **3. Apple API credentials exposed in documentation** `ios-pipeline.md` includes specific Apple API credential identifiers in the build commands: - `authenticationKeyID 2A6BSP3H76` - `authenticationKeyIssuerID e5ecbb14-2397-43f2-83fa-915967608055` While the private key file itself (`.p8`) is not included, the Key ID and Issuer ID are sensitive identifiers that should not be in a public-facing or version-controlled document. These should be replaced with placeholder values (e.g., `YOUR_KEY_ID`, `YOUR_ISSUER_ID`) or referenced via environment variables, with actual values stored in the secrets path only. --- ### NITS **4. CLAUDE.md docs table not updated** The Documentation table in `CLAUDE.md` does not include an entry for the new `docs/ios-pipeline.md`. All other docs are listed there. Add a row like: ``` | [iOS Pipeline](docs/ios-pipeline.md) | Turbo Native build pipeline, App Store Connect, when to rebuild | ``` **5. Production URL not reflected in CLAUDE.md URLs table** The networking doc now documents `https://landscaping-assistant.app` as the primary public URL. The CLAUDE.md URLs table still shows only the Tailscale hostname for Production. Consider adding the public URL: ``` | Production (public) | https://landscaping-assistant.app | ``` **6. Hetzner VPS IP address in docs** `networking.md` includes the literal IP `178.156.129.142` for the Hetzner edge VPS. This is a minor operational exposure concern. It is less sensitive than API keys but does provide targeting information. Consider whether this level of detail is needed in application docs vs. infrastructure docs. **7. Mermaid diagram in ios-pipeline.md** The Mermaid `graph LR` diagram uses escaped quotes in node labels (`\"`). This renders correctly in most Mermaid renderers but may break in some. Verify it renders properly in Forgejo's markdown preview. **8. "Related" section link format** In `ios-pipeline.md`, the "Source" line at the bottom reads `forgejo/ldraney/landscaping-assistant-ios` as plain text rather than a clickable link. Consider making it a proper link: ``` - Source: [landscaping-assistant-ios](https://forgejo.tail5b443a.ts.net/ldraney/landscaping-assistant-ios) ``` --- ### SOP COMPLIANCE - [x] PR body has: ## Summary, ## Changes, ## Test Plan, ## Related -- all present - [x] No `.env` files or credential files committed - [ ] No secrets in committed content -- **Apple API Key ID and Issuer ID are in ios-pipeline.md** (Blocker #3) - [x] No unnecessary file changes (scope is tight: 2 doc files) - [x] Commit messages are descriptive (single commit, clear title) --- ### PROCESS OBSERVATIONS - **Documentation debt risk:** The Fastlane vs xcodebuild contradiction (Blocker #2) suggests the iOS build process evolved but earlier docs were not updated. This PR should either update the older docs or explicitly explain the relationship. Leaving contradictory instructions across three docs creates operational confusion. - **Cross-reference integrity:** The #249 mismatch (Blocker #1) suggests the issue was either repurposed or the wrong number was cited. Docs that reference issue numbers must be verified against the actual issue content. - **Good practice:** The "When to Rebuild iOS" matrix and the routing chain diagram are both high-value additions that will reduce operational questions. --- ### VERDICT: NOT APPROVED Three blockers must be resolved: 1. Fix the #249 cross-reference (either correct the issue number or remove the "Closes" directive) 2. Reconcile the Fastlane vs xcodebuild contradiction across docs 3. Remove or redact Apple API credential identifiers from ios-pipeline.md
Address QA review: reconcile Fastlane docs, redact API identifiers
Some checks are pending
CI / scan_ruby (pull_request) Waiting to run
CI / scan_js (pull_request) Waiting to run
CI / lint (pull_request) Waiting to run
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
c435c74f73
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

PR #250 Review (Re-review)

PREVIOUS BLOCKERS -- STATUS

Three blockers were identified in the initial review. Verifying each:

  1. Wrong Closes #249 reference -- FIXED. PR body now reads "References #249 (documents the Keycloak root_url issue; does not fix it)". Issue #249 remains open, which is correct since this PR only documents the known issue.

  2. Contradictory Fastlane vs xcodebuild docs -- FIXED. docs/pipeline.md diff replaces Fastlane with xcodebuild in the Mermaid diagram (node renamed from FL to XCB), updates the TestFlight section to reference xcodebuild directly, and links to the new docs/ios-pipeline.md for full build commands. The new ios-pipeline.md includes a "Why Not Fastlane?" section that cleanly explains the boundary: Fastlane for local dev tasks, xcodebuild for production archive/export/upload due to API key auth limitations over SSH. Note: docs/ios-dev-builds.md still documents Fastlane lanes -- this is correct and consistent with the stated division of responsibility.

  3. API credentials in docs -- FIXED. Apple API Key ID and Issuer ID are replaced with $APPLE_KEY_ID and $APPLE_ISSUER_ID environment variable placeholders throughout docs/ios-pipeline.md. The doc explicitly directs readers to ~/secrets/apple-developer/.env on the MacBook for actual values. Remaining identifiers (Team ID HAY64YD5PX, App ID 6780226794, Bundle ID com.palenterprises.landscaping) are public Apple identifiers discoverable from any signed binary or App Store listing -- not credentials.

DOMAIN REVIEW

Docs-only PR (Markdown). No code changes. Domain checks applied: documentation accuracy, cross-reference integrity, information architecture.

Cross-references verified:

  • docs/ios-pipeline.md links to pipeline.md, ios-dev-builds.md, app-architecture.md -- all exist
  • docs/pipeline.md updated link: [iOS Pipeline](ios-pipeline.md) -- target exists in this PR
  • docs/networking.md references issue #249 -- confirmed open
  • docs/networking.md references PR #230 incident -- confirmed exists (closed)
  • Config locations table references pal-e-platform, pal-e-services, pal-e-deployments repos -- consistent with existing pipeline.md documentation of the three-repo model

Factual consistency:

  • Routing chain (GoDaddy DNS -> Caddy on Hetzner -> Tailscale Funnel -> k3s) matches the config locations table and is consistent with the existing config/environments/production.rb which lists both landscaping-assistant.app and landscaping-assistant.tail5b443a.ts.net in config.hosts
  • The 178.156.129.142 IP is a public-facing VPS IP, discoverable via DNS -- not a secret
  • Keycloak auth URL auth.palinks.app and realm landscaping are consistent with existing docs

Information architecture:

  • Clear separation: ios-pipeline.md (production builds), ios-dev-builds.md (dev/testing), pipeline.md (overview of all flows). Each doc links to the others. No orphaned docs.
  • The "When to Rebuild iOS" matrix is a good addition -- makes it immediately clear that most changes are server-side only

BLOCKERS

None. All three previous blockers are resolved.

NITS

  1. CLAUDE.md docs table not updated. The docs table in CLAUDE.md (line ~33) lists [iOS Dev Builds](docs/ios-dev-builds.md) but does not include the new docs/ios-pipeline.md. Consider adding a row: | [iOS Pipeline](docs/ios-pipeline.md) | Turbo Native build process, App Store Connect, xcodebuild workflow |. This is non-blocking since CLAUDE.md is a convenience index, not a functional dependency.

  2. CLAUDE.md URL table omits public domain. The URLs table in CLAUDE.md lists only the Tailscale production URL. The networking doc now documents https://landscaping-assistant.app as the primary public URL. Consider adding it to the CLAUDE.md URL table for discoverability. Non-blocking.

  3. docs/ios-dev-builds.md still says "See also Pipeline for the full build-to-deploy lifecycle" on line 3. Now that ios-pipeline.md exists, this could also link to it since the pipeline doc itself now defers iOS production details to ios-pipeline.md. Minor cross-reference gap, non-blocking.

SOP COMPLIANCE

  • PR body has Summary, Changes, Test Plan, Related sections
  • No secrets or credentials committed (API identifiers use env var placeholders)
  • No unnecessary file changes (three docs files, all related to the stated scope)
  • Commit messages are descriptive (scope matches PR title)
  • Issue reference is correct ("References #249", not "Closes #249")
  • No .env files or credential files in the diff

PROCESS OBSERVATIONS

  • Docs-only PR with zero deployment risk. No code paths affected.
  • Captures operational knowledge (the tmux keychain workaround, the Fastlane limitation) that would otherwise be tribal knowledge. Good documentation hygiene.
  • The three-nit pattern (CLAUDE.md index, CLAUDE.md URLs, ios-dev-builds.md cross-ref) suggests a follow-up housekeeping PR to update all doc indexes after merge. Low priority.

VERDICT: APPROVED

## PR #250 Review (Re-review) ### PREVIOUS BLOCKERS -- STATUS Three blockers were identified in the initial review. Verifying each: 1. **Wrong `Closes #249` reference** -- FIXED. PR body now reads "References #249 (documents the Keycloak root_url issue; does not fix it)". Issue #249 remains open, which is correct since this PR only documents the known issue. 2. **Contradictory Fastlane vs xcodebuild docs** -- FIXED. `docs/pipeline.md` diff replaces `Fastlane` with `xcodebuild` in the Mermaid diagram (node renamed from `FL` to `XCB`), updates the TestFlight section to reference `xcodebuild` directly, and links to the new `docs/ios-pipeline.md` for full build commands. The new `ios-pipeline.md` includes a "Why Not Fastlane?" section that cleanly explains the boundary: Fastlane for local dev tasks, `xcodebuild` for production archive/export/upload due to API key auth limitations over SSH. Note: `docs/ios-dev-builds.md` still documents Fastlane lanes -- this is correct and consistent with the stated division of responsibility. 3. **API credentials in docs** -- FIXED. Apple API Key ID and Issuer ID are replaced with `$APPLE_KEY_ID` and `$APPLE_ISSUER_ID` environment variable placeholders throughout `docs/ios-pipeline.md`. The doc explicitly directs readers to `~/secrets/apple-developer/.env` on the MacBook for actual values. Remaining identifiers (Team ID `HAY64YD5PX`, App ID `6780226794`, Bundle ID `com.palenterprises.landscaping`) are public Apple identifiers discoverable from any signed binary or App Store listing -- not credentials. ### DOMAIN REVIEW Docs-only PR (Markdown). No code changes. Domain checks applied: documentation accuracy, cross-reference integrity, information architecture. **Cross-references verified:** - `docs/ios-pipeline.md` links to `pipeline.md`, `ios-dev-builds.md`, `app-architecture.md` -- all exist - `docs/pipeline.md` updated link: `[iOS Pipeline](ios-pipeline.md)` -- target exists in this PR - `docs/networking.md` references issue #249 -- confirmed open - `docs/networking.md` references PR #230 incident -- confirmed exists (closed) - Config locations table references `pal-e-platform`, `pal-e-services`, `pal-e-deployments` repos -- consistent with existing pipeline.md documentation of the three-repo model **Factual consistency:** - Routing chain (GoDaddy DNS -> Caddy on Hetzner -> Tailscale Funnel -> k3s) matches the config locations table and is consistent with the existing `config/environments/production.rb` which lists both `landscaping-assistant.app` and `landscaping-assistant.tail5b443a.ts.net` in `config.hosts` - The `178.156.129.142` IP is a public-facing VPS IP, discoverable via DNS -- not a secret - Keycloak auth URL `auth.palinks.app` and realm `landscaping` are consistent with existing docs **Information architecture:** - Clear separation: `ios-pipeline.md` (production builds), `ios-dev-builds.md` (dev/testing), `pipeline.md` (overview of all flows). Each doc links to the others. No orphaned docs. - The "When to Rebuild iOS" matrix is a good addition -- makes it immediately clear that most changes are server-side only ### BLOCKERS None. All three previous blockers are resolved. ### NITS 1. **CLAUDE.md docs table not updated.** The docs table in `CLAUDE.md` (line ~33) lists `[iOS Dev Builds](docs/ios-dev-builds.md)` but does not include the new `docs/ios-pipeline.md`. Consider adding a row: `| [iOS Pipeline](docs/ios-pipeline.md) | Turbo Native build process, App Store Connect, xcodebuild workflow |`. This is non-blocking since CLAUDE.md is a convenience index, not a functional dependency. 2. **CLAUDE.md URL table omits public domain.** The URLs table in `CLAUDE.md` lists only the Tailscale production URL. The networking doc now documents `https://landscaping-assistant.app` as the primary public URL. Consider adding it to the CLAUDE.md URL table for discoverability. Non-blocking. 3. **`docs/ios-dev-builds.md` still says "See also [Pipeline](pipeline.md) for the full build-to-deploy lifecycle" on line 3.** Now that `ios-pipeline.md` exists, this could also link to it since the pipeline doc itself now defers iOS production details to `ios-pipeline.md`. Minor cross-reference gap, non-blocking. ### SOP COMPLIANCE - [x] PR body has Summary, Changes, Test Plan, Related sections - [x] No secrets or credentials committed (API identifiers use env var placeholders) - [x] No unnecessary file changes (three docs files, all related to the stated scope) - [x] Commit messages are descriptive (scope matches PR title) - [x] Issue reference is correct ("References #249", not "Closes #249") - [x] No .env files or credential files in the diff ### PROCESS OBSERVATIONS - Docs-only PR with zero deployment risk. No code paths affected. - Captures operational knowledge (the tmux keychain workaround, the Fastlane limitation) that would otherwise be tribal knowledge. Good documentation hygiene. - The three-nit pattern (CLAUDE.md index, CLAUDE.md URLs, ios-dev-builds.md cross-ref) suggests a follow-up housekeeping PR to update all doc indexes after merge. Low priority. ### VERDICT: APPROVED
README as single source of truth, CLAUDE.md symlinks to it
Some checks are pending
CI / scan_ruby (pull_request) Waiting to run
CI / scan_js (pull_request) Waiting to run
CI / lint (pull_request) Waiting to run
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
cab1d0a2fc
- Rewrote README.md as organized table of contents to docs/
- Added missing docs: ios-pipeline.md, security.md
- Categorized docs into App, Infrastructure, Development, User Stories
- Updated production URL to landscaping-assistant.app
- CLAUDE.md is now a symlink to README.md (single source of truth)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

PR #250 Review

DOMAIN REVIEW

Tech stack: Documentation (Markdown, Mermaid diagrams). No application code changes.

Files reviewed (4 changed, +268/-42):

  • README.md -- rewritten as categorized table of contents with subsections (App, Infrastructure & Deploy, Development, User Stories)
  • docs/ios-pipeline.md -- new, 161 lines documenting Turbo Native build pipeline
  • docs/networking.md -- 54 lines added for custom domain routing chain
  • docs/pipeline.md -- Fastlane references replaced with xcodebuild workflow

CLAUDE.md symlink: PR #221 (already merged) established CLAUDE.md as a symlink to README.md. The README.md changes in this PR propagate through the symlink automatically, so no separate CLAUDE.md diff entry is needed. Correct behavior.

Content quality observations:

  1. docs/ios-pipeline.md is thorough and well-structured. The keychain constraint workaround (tmux send-keys) is documented with both the failing pattern and the working pattern -- good operational documentation. The "When to Rebuild iOS" matrix is a useful quick-reference. The "Why Not Fastlane?" section explains the decision clearly.

  2. docs/networking.md custom domain section correctly documents the three-hop routing chain (GoDaddy DNS -> Caddy on Hetzner -> Tailscale Funnel -> k3s). The Config Locations table maps each layer to its source-of-truth file across three repos -- high-value for cross-repo orientation. Known issue #249 is properly called out with a concrete fix action.

  3. docs/pipeline.md changes are consistent: every Fastlane reference is replaced with the xcodebuild equivalent, Mermaid diagram node labels updated, cross-reference to the new ios-pipeline.md added. The sequence diagram at the bottom also updated.

  4. README.md reorganization: all 19 previously-listed docs are preserved. Two new entries added: iOS Pipeline (new in this PR) and Security (existing doc, previously unlisted in README). Categorization into App / Infrastructure & Deploy / Development / User Stories subsections is logical. Production URL updated from Tailscale hostname to landscaping-assistant.app. Quick Start section promoted above Documentation for better onboarding.

Cross-reference validation: All 21 doc links in the new README resolve to existing files on disk. Internal cross-references within the new/changed docs (pipeline.md -> ios-pipeline.md, ios-pipeline.md -> pipeline.md, ios-pipeline.md -> ios-dev-builds.md, ios-pipeline.md -> app-architecture.md) are all valid.

Secrets check: Actual API key values use $APPLE_KEY_ID and $APPLE_ISSUER_ID placeholders throughout. The key file path references ~/secrets/apple-developer/ (documenting where secrets live, not exposing them). Apple Team ID (HAY64YD5PX) and App ID (6780226794) are public identifiers from App Store Connect, not secrets. Hetzner VPS IP (178.156.129.142) is a public-facing infrastructure address, appropriately documented.

BLOCKERS

None.

NITS

  1. Networking description mismatch in README vs old CLAUDE.md context: The in-repo CLAUDE.md (symlink to README) will get the updated Networking description ("Custom domain routing, Tailscale Funnel, DNS, Keycloak URLs"), but the embedded copy in the user's global ~/.claude/CLAUDE.md still says "Tailscale Funnel ingress, cluster routing, URL setup". Not a PR issue -- just a note that the external copy will drift.

  2. iOS Dev Builds description still says "Fastlane setup": The README entry for iOS Dev Builds reads "TestFlight, wireless install, Fastlane setup" -- but docs/pipeline.md now says Fastlane is not used for the production pipeline. The ios-dev-builds.md doc does still cover Fastlane for local dev tasks, so the description is technically accurate, but it could confuse someone who just read the "Why Not Fastlane?" section. Consider updating to "TestFlight, wireless install, local dev tools" or similar. Non-blocking.

  3. Pipeline description shortened: The README changes Pipeline's description from "Full lifecycle: local dev, prod deploy, iOS dev builds, App Store" to "Full lifecycle: local dev, prod deploy, iOS builds, App Store". Dropping "dev" from "iOS dev builds" is appropriate since the new iOS Pipeline doc covers production builds. No action needed, just noting it was intentional.

SOP COMPLIANCE

  • PR body has ## Summary, ## Changes, ## Test Plan, ## Related
  • No secrets committed (placeholders used correctly)
  • No unnecessary file changes (all 4 files are docs, scoped to the PR description)
  • Commit messages are descriptive (per PR title and 4-commit structure)
  • Parent issue #249 referenced (not closed -- correct, this PR documents the issue rather than fixing it)

PROCESS OBSERVATIONS

Clean docs-only PR. The README reorganization into categorized subsections improves discoverability as the doc count grows (now 21 entries). The iOS pipeline documentation captures operational knowledge (keychain constraint, tmux workaround) that would otherwise be tribal knowledge. The networking custom domain section correctly cross-references configs across three repos (pal-e-platform, pal-e-services, pal-e-deployments), which is high-value for incident response.

VERDICT: APPROVED

## PR #250 Review ### DOMAIN REVIEW **Tech stack:** Documentation (Markdown, Mermaid diagrams). No application code changes. **Files reviewed (4 changed, +268/-42):** - `README.md` -- rewritten as categorized table of contents with subsections (App, Infrastructure & Deploy, Development, User Stories) - `docs/ios-pipeline.md` -- new, 161 lines documenting Turbo Native build pipeline - `docs/networking.md` -- 54 lines added for custom domain routing chain - `docs/pipeline.md` -- Fastlane references replaced with xcodebuild workflow **CLAUDE.md symlink:** PR #221 (already merged) established CLAUDE.md as a symlink to README.md. The README.md changes in this PR propagate through the symlink automatically, so no separate CLAUDE.md diff entry is needed. Correct behavior. **Content quality observations:** 1. `docs/ios-pipeline.md` is thorough and well-structured. The keychain constraint workaround (`tmux send-keys`) is documented with both the failing pattern and the working pattern -- good operational documentation. The "When to Rebuild iOS" matrix is a useful quick-reference. The "Why Not Fastlane?" section explains the decision clearly. 2. `docs/networking.md` custom domain section correctly documents the three-hop routing chain (GoDaddy DNS -> Caddy on Hetzner -> Tailscale Funnel -> k3s). The Config Locations table maps each layer to its source-of-truth file across three repos -- high-value for cross-repo orientation. Known issue #249 is properly called out with a concrete fix action. 3. `docs/pipeline.md` changes are consistent: every Fastlane reference is replaced with the xcodebuild equivalent, Mermaid diagram node labels updated, cross-reference to the new `ios-pipeline.md` added. The sequence diagram at the bottom also updated. 4. `README.md` reorganization: all 19 previously-listed docs are preserved. Two new entries added: `iOS Pipeline` (new in this PR) and `Security` (existing doc, previously unlisted in README). Categorization into App / Infrastructure & Deploy / Development / User Stories subsections is logical. Production URL updated from Tailscale hostname to `landscaping-assistant.app`. Quick Start section promoted above Documentation for better onboarding. **Cross-reference validation:** All 21 doc links in the new README resolve to existing files on disk. Internal cross-references within the new/changed docs (`pipeline.md` -> `ios-pipeline.md`, `ios-pipeline.md` -> `pipeline.md`, `ios-pipeline.md` -> `ios-dev-builds.md`, `ios-pipeline.md` -> `app-architecture.md`) are all valid. **Secrets check:** Actual API key values use `$APPLE_KEY_ID` and `$APPLE_ISSUER_ID` placeholders throughout. The key file path references `~/secrets/apple-developer/` (documenting where secrets live, not exposing them). Apple Team ID (`HAY64YD5PX`) and App ID (`6780226794`) are public identifiers from App Store Connect, not secrets. Hetzner VPS IP (`178.156.129.142`) is a public-facing infrastructure address, appropriately documented. ### BLOCKERS None. ### NITS 1. **Networking description mismatch in README vs old CLAUDE.md context:** The in-repo CLAUDE.md (symlink to README) will get the updated Networking description ("Custom domain routing, Tailscale Funnel, DNS, Keycloak URLs"), but the embedded copy in the user's global `~/.claude/CLAUDE.md` still says "Tailscale Funnel ingress, cluster routing, URL setup". Not a PR issue -- just a note that the external copy will drift. 2. **iOS Dev Builds description still says "Fastlane setup":** The README entry for iOS Dev Builds reads "TestFlight, wireless install, Fastlane setup" -- but `docs/pipeline.md` now says Fastlane is not used for the production pipeline. The ios-dev-builds.md doc does still cover Fastlane for local dev tasks, so the description is technically accurate, but it could confuse someone who just read the "Why Not Fastlane?" section. Consider updating to "TestFlight, wireless install, local dev tools" or similar. Non-blocking. 3. **Pipeline description shortened:** The README changes Pipeline's description from "Full lifecycle: local dev, prod deploy, iOS dev builds, App Store" to "Full lifecycle: local dev, prod deploy, iOS builds, App Store". Dropping "dev" from "iOS dev builds" is appropriate since the new iOS Pipeline doc covers production builds. No action needed, just noting it was intentional. ### SOP COMPLIANCE - [x] PR body has ## Summary, ## Changes, ## Test Plan, ## Related - [x] No secrets committed (placeholders used correctly) - [x] No unnecessary file changes (all 4 files are docs, scoped to the PR description) - [x] Commit messages are descriptive (per PR title and 4-commit structure) - [x] Parent issue #249 referenced (not closed -- correct, this PR documents the issue rather than fixing it) ### PROCESS OBSERVATIONS Clean docs-only PR. The README reorganization into categorized subsections improves discoverability as the doc count grows (now 21 entries). The iOS pipeline documentation captures operational knowledge (keychain constraint, tmux workaround) that would otherwise be tribal knowledge. The networking custom domain section correctly cross-references configs across three repos (pal-e-platform, pal-e-services, pal-e-deployments), which is high-value for incident response. ### VERDICT: APPROVED
ldraney deleted branch docs/ios-pipeline-and-dns 2026-06-18 22:19:54 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/landscaping-assistant!250
No description provided.