M1-04: Code signing and on-device install #4
Labels
No labels
area/agent
area/capture
area/editor
area/geo
area/security
area/sync
area/transcription
area/ui
area/vault
area/voice-memos
blocked
milestone/M1
milestone/M2
milestone/M3
milestone/M4
needs-decision
needs-hardware
p0
p1
p2
type/bug
type/enhancement
type/feature
type/idea
type/infrastructure
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Stash/stash-ios#4
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Get a signed build onto Wes's iPhone.
Why it blocks everything after it
Issues 05 through 12 cannot be validated in the simulator. Background audio with the screen
locked, microphone route changes, phone-call interruptions, Live Activities and on-device
speech all behave differently or not at all on a simulator. Until this lands, nothing
downstream can be honestly marked done.
This is the schedule risk in M1. If provisioning fights us, that is the thing that costs the
day — not any of the audio work.
Scope
project.yml.README.md.⚠️ Public repo
No certificates, no provisioning profiles, no team identifiers committed. Signing config
reads from the local environment; document what has to be set, never the values.
Done when
make install(or equivalent, documented) puts the current build on the phone.Milestone 1 of the Stash v3 rebuild, scoped 2026-08-06. M1 is a functioning iOS app on Wes's
phone with no sync at all — the entire goal is recording voice memos reliably and getting
them off the device by hand. Sync arrives in M3.
Working agreement for every issue in this repo: feature branch, tested before the PR opens
(on-device where the label says so), then Wes reviews the PR and we walk the code together.
Docs update in the same commit. A PR that takes more than 20 minutes to review is too big —
say so and split it.
Branch
m1-04-code-signing, one commit.make installputs the current build on the phone.What's there
A
Makefile.make installregenerates the project, builds signed, installs and launches on a connected iPhone.make rundoes the same for the simulator,make buildis the unsigned simulator build CI runs,make lintis the same rules,make helplists them.Every target regenerates the
.xcodeprojfirst. Making that conditional would buy nothing and would let a stale project survive an edit toproject.yml.project.ymlgainsCODE_SIGN_STYLE: AutomaticandDEVELOPMENT_TEAM: ${STASH_DEV_TEAM}, which XcodeGen expands from the environment at generate time.Nothing about signing is committed
No certificate, no provisioning profile, no team identifier, no device UDID. Both values a device build needs are discovered from the machine:
STASH_DEV_TEAMSTASH_DEVICEThe team is the OU of the certificate subject, not the parenthesised identifier on the
security find-identityline — those are different values and the visible one is the wrong one. Worth naming because it fails in a confusing way.README.mddocuments what can be set and never a value. I also genericised the device name in the examples tomy-iphone, so even your phone's name isn't in the repo.What I validated
From a
make cleanstate, which is what a new machine actually starts in:make lint— exit 0, 0 violations, 7 files.make build— exit 0. Also regenerated withSTASH_DEV_TEAMunset and rebuilt for the simulator, since that is exactly the CI case; the unexpanded${STASH_DEV_TEAM}resolves to empty at build time and the build succeeds. CI is unaffected by this change.make install— exit 0, onwes-iphone(iPhone 17 Pro), afterdevicectl device uninstallso it was a genuine first install rather than an upgrade over the copy from issue #3. App confirmed present in the device process list afterwards, so it launched rather than launch-and-crash.make run— exit 0, app confirmed running in the simulator.Both error paths, deliberately triggered:
Confirmed the guard actually stops the chain —
xcodebuildnever ran.One bug found by testing rather than by reading. The first device detection matched the
Statecolumn on/available/. That worked, then stopped working ten minutes later:devicectlreportsavailable (paired)orconnecteddepending on what it last did, so detection silently returned nothing andmake installclaimed no phone was attached while the phone was attached. It now matches the hostname column, which does not move.What I did not validate
check-teamfailure text describes a recovery path I have not walked. The message is a guess at the right instructions, informed but unverified.README.mdis from how development profiles work, not from having watched this one expire..woodpecker/lint.ymlcould; the simulator build still has no macOS agent.Opening a PR. Leaving this issue open for you.