Workflow overhaul plan#

Written 2026-10-09. Owner: Sven. Executed mostly by Claude.

Why#

Wake v1 and the map phase shipped, but every feature took a lot of Sven’s time. Three things caused most of it:

  • GSD ran at full ceremony. Interactive mode, the long discuss round and every optional audit were switched on. Phase 4 delivered two requirements and produced 17 planning documents with about 4,300 lines. .planning holds roughly 36,000 lines of Markdown next to 9,300 lines of Swift.

  • Two sources of truth. ROADMAP.md and REQUIREMENTS.md copied the YouTrack tickets, and the two drifted apart (WAK-6 and WAK-7 are still open in YouTrack although the map shipped). The retrospective already named planning drift as the biggest non-coding cost.

  • Sven was the only test rig for device bugs. The first-tap bug went through three fixes that were green in the simulator and failed on the phone. Each round needed a TestFlight build and Sven’s time. The app has no logging at all, so nothing from the device ever reached Claude.

On top of that, every build and every TestFlight upload needs the MacBook, which is usually switched off or on the boat.

Goals#

  1. Sven can drop a bug or idea into the project by voice in a few seconds, from anywhere.

  2. Claude keeps working on queued tickets without the Mac and without Sven at a desk.

  3. Sven’s input happens at two points only: confirming what a ticket means before work starts, and testing the TestFlight build.

  4. Claude can see what happened in the app when Sven reports a problem.

  5. A human-readable product documentation exists: what is planned, what is built, how it works.

  6. Everything stays within free tiers, except the Claude Max 5x plan.

Target workflow#

 Sven (voice)        Claude (cloud)            Sven (phone)        Claude (cloud)          Xcode Cloud           Sven (boat)
 ────────────        ──────────────            ────────────        ──────────────          ───────────           ───────────
 "Hey Siri,     ──▶  triage routine:      ──▶  reads summary, ──▶  GitHub Action picks ──▶ builds + runs all ──▶ installs build,
  Wake note"         rewrites the note,        corrects or         up the ticket, builds    tests on the PR,     tests, moves card
  → issue `inbox`    adds acceptance           sets `ready`        it with GSD, opens PR    merge → TestFlight   to "Accepted" or
                     criteria + size                               fixes red checks                              dictates new note

Who does what#

Step

Who

Needs the Mac

Capture a note

Sven, via Siri or Back Tap

no

Turn the note into a proper ticket

Claude, scheduled routine

no

Confirm the ticket (ready)

Sven, GitHub app

no

Write code, run WakeCore tests, open PR

Claude, GitHub Action on Linux

no

Build the app, run unit and UI tests

Xcode Cloud

no

Fix failing checks

Claude, reads results via App Store Connect API

no

Review the PR against the ticket

Claude, a separate review run with fresh context

no

Merge

Claude only if the ticket has automerge, otherwise Sven

no

TestFlight upload

Xcode Cloud after merge to main

no

Test on the water, accept

Sven

no

Device-only debugging, XcodeBuildMCP sessions

Claude with Sven

yes

One-time setup (see Stage 0)

Sven with Claude

yes

Decisions#

Topic

Decision

Ticket system

GitHub Issues in svenfi/first_claude_app. YouTrack is retired after migration.

Roadmap view

One GitHub Projects board (free for private repos).

Product documentation

Markdown in docs/, built with Sphinx, MyST and the PyData theme. Published to Cloudflare Pages behind Cloudflare Access (free up to 50 users, login by email code). GitHub Pages is not an option: on a free personal account it only works for public repos.

CI and distribution

Xcode Cloud (25 compute hours per month included in the Developer Program).

Claude without the Mac

anthropics/claude-code-action on GitHub-hosted Linux runners, authenticated with the Max subscription (CLAUDE_CODE_OAUTH_TOKEN), plus scheduled Claude Code routines.

Framework

Keep GSD, upgrade to GSD Core (@opengsd/gsd-core), run it much leaner (see “GSD configuration”).

Analytics and diagnostics

PostHog, EU cloud, plus an on-device diagnostics log. Only Sven for now; privacy work comes when other testers join.

Merge policy

Claude merges only when the ticket carries the automerge label.

App Store Connect API key

A new key just for CI and cloud use, role “Developer”. The existing Mac key Sven-key-asc-dev stays for local work.

Voice capture

iOS Shortcut “Wake note”, triggered by Siri or Back Tap (iPhone 14, no Action button).

Repository

Stays private. Stays one repository, also when boat hardware or a server is added later.

Language

Everything in the project is written in English.

Board and labels#

Board columns

Column

Meaning

Inbox

Raw note, not yet triaged

Needs confirmation

Claude has rewritten it; waiting for Sven

Ready

Sven confirmed; Claude may start

In progress

Claude is working, PR may be open

To test

Merged and in a TestFlight build

Accepted

Sven has used it and it works; docs are final

Labels

  • Type: bug, feature, chore, docs

  • Flow: inbox, needs-confirmation, ready, needs-decision, needs-mac, automerge

  • Review: approved, rework, escalated

  • Size: size:fast, size:quick, size:phase (rules in Quick task or full phase?)

  • Component: app now; boat, server later

  • Priority: p1, p2, p3

Rules for Claude#

These go into CLAUDE.md so every session, local or cloud, follows them.

  1. Never start without ready. A ticket in inbox or needs-confirmation is only triaged, never built.

  2. Stop and label needs-decision instead of guessing when a change:

    • alters the CloudKit schema,

    • adds a permission or background mode,

    • adds a third-party dependency,

    • costs money or uses a new external service,

    • changes an architecture decision recorded in docs/architecture/ (the folder is created in Stage 1; until then the decisions recorded in .planning/ count).

  3. Ask in the ticket, not in the run. Questions go into an issue comment, and the run ends. Sven answers by voice or text, and the next run picks it up.

  4. Merge only with automerge, and only after the review run has set approved. Otherwise leave the PR open with a description written for a non-Swift reader: what changed, what to look at in the build, and screenshots from the UI tests.

  5. A feature is done only with docs. Every feature PR updates its page under docs/product/features/ and adds a line to docs/product/changelog.md.

  6. Red checks get three attempts. After the third failed fix, label needs-mac and summarise what was tried.

  7. Device-only bugs get instrumentation first. If a bug cannot be reproduced in tests, the first PR adds logging around it and asks Sven to reproduce on the phone.

  8. Three rejected reviews stop the loop. After the third rework verdict on the same ticket, label escalated and wait for Sven.

Rollout#

Each stage has a clear end. Tasks are marked [Sven], [Claude] or [Sven + Mac].

Stage 0: one evening at the Mac#

  • [Sven + Mac] Upgrade GSD to GSD Core: npx @opengsd/gsd-core@latest --claude --global, then the same with --local in the repo so cloud sessions get the commands too. Run /gsd-health afterwards. Done 2026-10-10: global and --local, both 1.16.0. Health is clean apart from the expected W006 for phases 5 to 7 and the W028 shadowing below.

  • [Sven + Mac] Resolve the W028 shadowing that /gsd-health reports: the global skills shadow all 72 repo-local commands on the Mac. Decided 2026-10-10: keep both installs. W028 is accepted as informational; run /gsd-update in both places when updating so the versions stay equal.

  • [Claude] Make the local install portable before committing it. The --local install wrote absolute /Users/svenfi/... paths into 244 files under .claude/ (the @ include at the top of every workflow and the shim fallback), and it put all hooks plus worktree.baseRef: "head" into settings.local.json, which is gitignored. Move the hooks and the worktree setting to .claude/settings.json, replace the absolute paths with $CLAUDE_PROJECT_DIR-relative ones (or report it upstream if the installer cannot), then commit .claude/ without settings.local.json so cloud sessions get the commands. Done 2026-10-10: reinstalled with --relative-includes --portable-hooks (0 absolute paths left), hooks and worktree.baseRef moved to .claude/settings.json, settings.local.json and .claude/worktrees/ ignored at repo level, .claude/ committed.

  • [Sven + Mac] Set up Xcode Cloud in Xcode (menu Integrate, not Product; product is Wake, not WakeCore) with two workflows:

    • PR: start on pull request changes under ios/, any source branch, target main, auto-cancel on. One action only, Test - iOS with scheme Wake, “Required To Pass”, a single iPhone simulator (not “Recommended iPhones”). No separate Build action, the test action builds anyway. Pin the Xcode version to the one used on the Mac. Created 2026-10-10; the “scheme may only exist locally” warning is a false positive while the checkout has unpushed commits. A manual start condition on main is needed for manual runs. First manual run 2026-10-10: green on Xcode 27 in 21 min, 130 tests passed, 1 known skip, 2 pre-existing compiler warnings in CloudKitSyncConfigTests.swift. Pinning the Xcode version was not needed.

    • Main: start on changes to main under ios/, archive, distribute to the internal TestFlight group “Meine Testgruppe Wake”.

    Set the next build number in App Store Connect (Apps, Wake, Xcode Cloud, Settings gear, Build Number). TestFlight was at build 9 on 2026-10-10, so the next build number was set to 10. Main workflow created and proven 2026-10-10: run 12 archived and distributed to “Meine Testgruppe Wake”.

  • [Sven] In GitHub branch protection for main, require a pull request before merging. Deferred 2026-10-10: a private repo needs GitHub Pro ($4/month) for branch protection or rulesets. Not required for the plan; the merge rules are enforced by the review run and the automerge rule. Revisit once the Action has run unattended for a few weeks. Open decision: with the ios/ files filter, a docs-only PR never gets an Xcode Cloud check, and a GitHub-required check that never reports blocks the merge forever. Proposed: do not make Xcode Cloud required at the GitHub level; make the Claude review run the required check and let it refuse approved for any PR touching ios/ without a green Xcode Cloud check.

  • [Sven] Create the new App Store Connect API key (role “Developer”). Store the .p8, the key ID and the issuer ID as GitHub secrets ASC_KEY_P8, ASC_KEY_ID, ASC_ISSUER_ID. Done 2026-10-10.

  • [Sven + Mac] Run claude setup-token and store the result as the GitHub secret CLAUDE_CODE_OAUTH_TOKEN. Done 2026-10-10.

  • [Sven] Install the Claude GitHub app on the repository. Done 2026-10-10 (verified by Sven at github.com/settings/installations; first proof in Stage 1).

  • [Claude] Remove the stale worktree under .claude/worktrees/. Delete merged remote branches. Done 2026-10-10: nothing left to remove.

  • [Sven + Mac] Confirm whether the Xcode Cloud PR workflow can distribute PR builds to TestFlight. Only needed for Plan B.

Done when: a manually opened test PR gets a green Xcode Cloud check, and merging it produces a TestFlight build without touching the Mac. 2026-10-10: PR #16 (WAK-35 speed/distance charts, built by GSD quick task 261010-u05) got a green “Wake | PR | Test - iOS” check as Xcode Cloud build 10. Note: every Xcode Cloud run, including PR test runs, consumes a build number. Merged the same evening: Main workflow run 12 archived and uploaded to the internal TestFlight group without the Mac. Stage 0 done 2026-10-10, except the deferred branch-protection item.

Stage 1: cloud setup, no Mac needed#

  • [Claude] Create labels, milestones and the Projects board as described above. 2026-10-10: 20 labels and the milestones “v2.0 Map & richer logging” (open) and “v1.0 MVP” (closed) exist. The board is pending: the gh token lacks the project scope (gh auth refresh -s project,read:project).

  • [Claude] Migrate all 39 YouTrack WAK tickets to GitHub Issues: done 2026-10-10 as #17–#55 (mapping in the migration script’s wak-to-gh.json). Priority map: Critical/Major → p1, Normal → p2, Minor → p3. Six imported closed: the three resolved tickets plus the Phase 4 epic, WAK-6 and WAK-7, which had shipped but were never closed.

    • keep the WAK number in the title,

    • map priority and type to labels,

    • turn the v2 epics into a milestone,

    • import resolved tickets as closed for history.

  • [Sven] Archive the YouTrack project afterwards. Remove the YouTrack MCP from the project setup.

  • [Claude] Rewrite CLAUDE.md: done 2026-10-10 (quick 261010-vd3). CLAUDE.md is generated by gsd-tools generate-claude-md --output CLAUDE.md from PROJECT.md and the codebase map; the hand-written “Working on Wake” section outside the markers carries the rules below.

    • drop the outdated Windows and MacInCloud research,

    • add the real architecture (via /gsd-map-codebase), conventions and test commands,

    • add the rules above.

  • [Claude] Set up docs/ as a Sphinx project: done 2026-10-10 (quick 261010-vpm); sphinx 7.4.7 / myst-parser 3.0.1 / pydata-sphinx-theme 0.15.4, pinned to work on Python 3.9 locally and 3.12 in CI; build with sphinx-build -W.

    • conf.py with myst-parser and pydata-sphinx-theme,

    • sections product/ (features, changelog, roadmap overview), process/, architecture/ (ADRs), plan/.

  • [Claude] Write a first feature page for each existing feature, from the code and the v1/v2 summaries: logging at the helm, voyage history, map, CloudKit sync. Done 2026-10-10 (quick 261010-w26).

  • [Claude] Add GitHub Action docs.yml: on changes under docs/, build with Sphinx and deploy to Cloudflare Pages. Done 2026-10-10 (quick 261010-whe); the deploy step skips with a notice until the two Cloudflare secrets exist. The Pages project must be a Direct Upload project named wake-docs with production branch main, and the production domain needs its own Access application (the Pages “access policy” toggle only covers previews).

  • [Sven] Create a free Cloudflare account and a Pages project. Add an Access policy that allows only Sven’s email. Store CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID as GitHub secrets.

  • [Claude] Add GitHub Action core-tests.yml: run swift test for ios/WakeCore on Ubuntu. This mirrors the pre-commit hook in CI. Done 2026-10-10 (quick 261010-whe), container swift:6.4. First Linux compile of WakeCore ever; a red first run means a WakeCore portability fix, not a weaker workflow.

  • [Claude] Add GitHub Action claude.yml with anthropics/claude-code-action:

    • triggers: issue labeled ready, @claude in comments, and failed checks on claude/* branches,

    • the prompt states the rules above and how to pick /gsd-fast, /gsd-quick or a phase from the size label.

    • Done 2026-10-11 (quick 261010-wte). Failed checks are handled by the bash router in claude-review.yml, which dispatches claude.yml in fix mode (the action has no check-event trigger of its own). size:phase tickets stop with needs-decision. Builder on Sonnet; see docs/process/github-actions.md.

  • [Claude] Add GitHub Action claude-review.yml, a second Claude run that reviews every PR from a claude/* branch: done 2026-10-11 (quick 261010-wte). Three jobs: bash router (waits for green checks including Wake | PR | Test - iOS when ios/ changed, counts fix attempts), Opus reviewer (read-only, PR head in pr-head/), bash verdict (comment, approved/rework, escalation after the third rework, automerge with the workflow token because the action revokes its app token). UI-test screenshots are not available to the reviewer yet. Open verifications are listed on the docs page.

    • When: only after all required checks, including Xcode Cloud, are green. Reviewing red PRs wastes usage.

    • Fresh context: it is a separate run that never sees the builder’s conversation. It gets the ticket, the diff, the test results and the UI-test screenshots, nothing else.

    • What it checks:

      • every acceptance criterion in the ticket is met and nothing outside the ticket was changed,

      • tests were not weakened or deleted to get green (it reads test changes first),

      • the rules above were followed: needs-decision cases, docs updated, changelog line present.

    • Verdict: a PR comment that ticks off the acceptance criteria, then the label approved or rework with concrete findings. rework triggers the builder again on the same branch.

    • Model: if usage allows, the reviewer runs on a stronger model than the builder.

  • [Claude] Write a cloud environment setup script that installs Swift on Linux. Add download.swift.org to the network allowlist of the cloud environment.

  • [Claude] Create two routines:

    • Triage, three times a day: rewrite inbox notes into tickets and comment “This is how I understood you”. Propose size and labels, then move the ticket to needs-confirmation.

    • Nightly feedback: read TestFlight screenshot feedback and crash reports via the App Store Connect API, and PostHog errors once Stage 2 is done. File or update tickets.

  • [Claude] Write docs/process/voice-capture.md: step-by-step instructions for the iOS Shortcut (below).

  • [Sven] Build the Shortcut on the iPhone (about two minutes), set up Back Tap, try it once.

Done when: a dictated note becomes a confirmed ticket, Claude builds it in the cloud, a separate review run approves it, and the result arrives in TestFlight while the Mac stays off.

The voice capture Shortcut#

  1. Dictate Text.

  2. Get Contents of URL, method POST, to https://api.github.com/repos/svenfi/first_claude_app/issues:

    • header Authorization: Bearer <token> (a fine-grained personal access token, this repository only, permission Issues read/write),

    • JSON body: title = first words of the note; body = full note, date and “captured via Siri”; label inbox.

  3. If the request fails (no signal at sea), append the note to an Apple Note called “Wake queue”. A second Shortcut “Flush Wake queue” sends the queued notes later.

Siri phrase: “Wake note”. Back Tap is under Settings → Accessibility → Touch → Back Tap, set to double tap.

Stage 2: first feature through the new pipeline, diagnostics and analytics#

This stage is built like any other feature, as tickets in the new flow. That tests the pipeline on something useful.

  • Diagnostics log (size:quick). Apple Logger with subsystem com.svenfi.wake and categories for UI taps, voyage state, GPS quality and sync. Plus a small on-device ring buffer of the last few hundred entries that the app can export.

  • Shake to report (size:quick --discuss). Shaking the phone opens a sheet: dictate or type a note, optional screenshot. The app files a GitHub issue with build number, iOS version, device, current voyage ID and the recent log lines. The GitHub token is entered once in a hidden settings screen and kept in the Keychain. It is never compiled into the app.

  • PostHog (size:phase, because it adds the first third-party dependency):

    • add the iOS SDK via Swift Package Manager, EU host, with all calls going through one Analytics wrapper,

    • define an event catalogue in docs/architecture/analytics-events.md,

    • send no coordinates for now; evaluate SwiftUI session replay,

    • give Claude access through the official PostHog MCP server in the cloud environment and locally.

Done when: Sven reports a problem from the boat, and Claude can reconstruct the steps before it from the attached log and PostHog without asking.

Stage 3: tidy up the planning files#

  • [Claude] Run /gsd-cleanup to move the finished v1 phases 00 to 03 into milestones/v1.0-phases/.

  • [Claude] Rewrite STATE.md as a digest under 100 lines (it is about 26 KB now).

  • [Claude] Turn REQUIREMENTS.md and ROADMAP.md into short indexes that link to GitHub issues instead of copying them.

  • [Claude] When v2 is done, /gsd-complete-milestone archives its phases the same way.

From then on, .planning is Claude’s working memory. Sven reads the board and docs/, not .planning.

GSD configuration#

Changes to .planning/config.json. The aim is fewer questions without more misunderstandings. Most misunderstandings come from missing context, so the rewritten CLAUDE.md and the product docs matter more than any of these switches.

Key

Now

New

Why

mode

interactive

yolo

no approval prompts during runs; approval happens on the ticket

workflow.discuss_mode

discuss

assumptions

Claude states its assumptions and Sven corrects a few, instead of a long interview

workflow.text_mode

false

true

plain-text output, needed for headless and remote runs

workflow.nyquist_validation

true

false

heavy audit with little value at this size

workflow.ui_review

true

false

Sven reviews visuals in the TestFlight build anyway

workflow.auto_prune_state

(unset)

true

keeps STATE.md short automatically

workflow.context_guard_mode

(unset)

auto

pauses cleanly instead of degrading when the context fills up

git.branching_strategy

none

phase

every phase gets its own branch and PR; quick tasks from the GitHub Action run on claude/* branches anyway

workflow.use_worktrees

true

true on the Mac, false in the GitHub Action

with commit_docs: true the quick workflow commits the plan before it dispatches the executor, which moves HEAD past origin/HEAD, and every quick task then falls back to sequential mode. The --local install fixes this on the Mac with worktree.baseRef: "head" in settings.local.json, but that file is gitignored. In the Action the claude/* branch is the isolation, so false is simpler there

text_mode: true also changes local Mac sessions: numbered lists instead of menus. Accepted, because one setting for both places is simpler than two.

These stay on, because they catch errors before Sven has to: research, plan_check, verifier, node_repair, code_review, ui_phase.

Plan B: gsd-loop#

Plan A is our own GitHub Action (claude.yml, Stage 1). If it turns out unreliable or too much work to maintain, the fallback is gsd-loop from the Open GSD project (open-gsd/gsd-spec-build-loop, npm @opengsd/gsd-loop, version 0.4.1 as of October 2026).

What it is. A set of Claude Code skills that turn labelled GitHub issues into reviewed pull requests. It has four playbooks:

Playbook

Runs

Does

Discover

interactive

maps a large, unclear effort into decisions and delivery slices

Spec

interactive

interviews you about an idea and files issues with numbered outcomes (O-N) and exclusions (X-N)

Build

unattended

fixes one PR labelled gsd:rework, or takes the oldest gsd:ready issue and opens a PR

Review

unattended

checks one PR against its issue and the required CI, then labels it gsd:approved or sends it back as gsd:rework. After three failed reviews it labels the issue gsd:escalated

State lives in labels: gsd:map, gsd:ready, gsd:blocked, gsd:rework, gsd:approved, gsd:escalated.

What it would give us over Plan A

  • A label model that already exists and is maintained by someone else.

  • (The independent review pass is no longer a difference: Plan A adopted it as claude-review.yml.)

  • A reviewer that refuses to treat missing CI as green, which fits Xcode Cloud as a required check.

How it differs from Plan A, and what would have to change

  • It never merges and never enables auto-merge. The automerge rule would go away. Instead, the Xcode Cloud PR workflow would distribute each PR build to TestFlight (to be checked in Stage 0), and Sven’s merge after testing becomes the acceptance.

  • It is not a GitHub Action. It runs as skills inside Claude Code and relies on Claude Code’s recurring tasks. In the cloud that means two routines, one for Build and one for Review, running hourly. Routines have a one-hour minimum; gsd-loop itself is designed for 15 to 60 minutes, so the loop would be somewhat slower.

  • Build does not use GSD Core. It has its own process and does not touch .planning. It would only handle size:fast and size:quick tickets. size:phase tickets stay with GSD phases.

  • Spec is an interview, so it cannot replace the triage routine. The triage routine would write issues in the O-N / X-N format and leave gsd:ready to Sven.

Switching to Plan B

  1. npx @opengsd/gsd-loop@latest install, then npx @opengsd/gsd-loop@latest init. This creates the labels and wires the Xcode Cloud check as required.

  2. Disable claude.yml and map the existing labels: ready becomes gsd:ready, needs-decision becomes gsd:blocked.

  3. Create the Build and Review routines.

  4. Adjust the triage routine to the O-N / X-N issue format.

  5. Run two or three quick tickets through it before relying on it.

Why it is not Plan A. The project is very young (single-digit GitHub stars, one open issue), it takes the merge decision away for good, and it makes the flow depend on routine scheduling instead of GitHub events.

Later: boat data and passage planning#

Two large features are coming: logging data from the boat’s NMEA 2000 network (engine running, anchor alarm, polar diagram) and passage planning with weather, tides and the polar diagram. They do not change the workflow above, but they get their own milestone that starts with research, not code.

Questions for that research milestone:

  1. Backend or not. An anchor alarm that reaches Sven ashore, and logging while the phone is not aboard, need a device on the boat that is always on and a way to reach the phone over LTE. That questions the “no backend” principle (WAK-24). This is an architecture decision and gets an ADR.

  2. Buy or build the boat gateway. First survey ready-made NMEA 2000 gateways (for example from Yacht Devices or Actisense) and Signal K running on a small computer aboard with CAN and LTE. Own embedded software only if nothing fits.

  3. Signal K as the data model. If the app talks Signal K instead of raw NMEA 2000, the hardware underneath can change without touching the app.

  4. Recorded boat data as test fixtures. Record real NMEA 2000 traffic once and keep the recordings in the repo. All interpretation logic (engine on, anchor drag, polar points) is written so that it runs on Linux against these recordings, the same way WakeCore works today. That lets Claude develop it in the cloud. Only flashing hardware and the final test on the bus need Sven aboard.

  5. Data sources for routing. Weather (GRIB), tides, possibly charts: licences and offline use matter more than technology. Where routing runs (phone or server) depends on question 1.

Repository layout when it comes: ios/ for the app, boat/ for gateway code or configuration, server/ if needed. One board, a component label per area. Xcode Cloud only starts on changes under ios/, which protects the 25 hours.

Risks and open points#

Risk

What we do

GSD has no documented recipe for running inside a GitHub Action

Try with one small ticket in Stage 1 before relying on it. First fallback: the Action runs Claude Code without GSD for size:quick tickets. If the Action as a whole does not work out, switch to Plan B: gsd-loop.

Max 5x usage runs out with autonomous runs and full phases

Watch usage for the first weeks. Routines stop when the limit is hit and resume after the reset.

25 Xcode Cloud hours are not enough

Path filters on ios/, [ci skip] for docs-only commits, simulator tests only on one device. Paid tiers start at 100 hours.

Claude in the cloud cannot see the UI

UI tests attach screenshots. Visual checks stay with Sven in the TestFlight build.

Device-only bugs still need the Mac

The diagnostics log moves most of them to the cloud. The rest get needs-mac and wait for an evening at the Mac.

Swift on Linux in the cloud environment

Only WakeCore runs there; SwiftUI, SwiftData and CloudKit compile only in Xcode Cloud. Keep pure logic in WakeCore.

PostHog is the first third-party runtime dependency

Wrapped behind one Analytics type so it can be removed or swapped.

Each PR now costs two Claude runs (build and review)

Review only starts on green checks. If usage gets tight, skip review for size:fast tickets.

GitHub token in the voice Shortcut and in the app

Fine-grained, this repo only, Issues only. Easy to revoke.

References#

  • GSD Core: https://github.com/open-gsd/gsd-core

  • gsd-loop (Plan B): https://github.com/open-gsd/gsd-spec-build-loop

  • Claude Code GitHub Actions: https://code.claude.com/docs/en/github-actions

  • Claude Code routines: https://code.claude.com/docs/en/routines

  • Claude Code cloud environments: https://code.claude.com/docs/en/cloud-environments

  • Xcode Cloud: https://developer.apple.com/xcode-cloud/

  • Xcode Cloud required PR checks: https://developer.apple.com/documentation/xcode/configuring-requirements-for-merging-a-pull-request

  • App Store Connect API, build actions: https://developer.apple.com/documentation/appstoreconnectapi/build-actions

  • TestFlight feedback via API: https://developer.apple.com/documentation/appstoreconnectapi/beta-feedback-screenshot-submissions

  • PostHog MCP: https://posthog.com/docs/model-context-protocol

  • GitHub plans (Pages availability): https://docs.github.com/en/get-started/learning-about-github/githubs-plans