Skip to content

chore: merge dev to main - #302

Merged
jlian merged 81 commits into
mainfrom
dev
Aug 10, 2026
Merged

chore: merge dev to main#302
jlian merged 81 commits into
mainfrom
dev

Conversation

@jlian

@jlian jlian commented Aug 9, 2026

Copy link
Copy Markdown
Owner

No description provided.

jlian added 30 commits August 9, 2026 11:24
jlian added 2 commits August 10, 2026 00:20
Apple sign-in stored the live session, then tried to capture Apple's
revocation token. On capture failure the catch called signOut() and
rethrew, so the user saw "sign-in failed". signOut() is purely local
(clears signInMessage and the session); it makes no server call. The
server account and Apple grant stayed live, leaving an account the user
believes was never created. The Apple authorization code is single-use
and already consumed, so a retry cannot re-capture it, and the account
could not later be fully deleted because deletion needs that token to
revoke Apple's grant.

The account and session are genuinely usable, and the server deletion
flow already falls back to manual Apple revocation when the token is
absent. Treat capture as best-effort: log a warning and keep the
successful sign-in instead of tearing it down.

Also fix ci(ios-release): the preflight "Run iOS tests" step
unconditionally built -scheme Localhost. Rebuilding an accepted release
checks out that tag, and tags ios-v0.1.0 through ios-v0.3.0 define no
schemes block, so xcodegen generates no Localhost scheme and xcodebuild
fails before archive/upload. Following the existing tag-compatibility
pattern, derive behaviour from the checked-out sources and skip the
preflight tests when the tag has no Localhost scheme; the Archive step
still validates the rebuild.
Healthy health responses suppress completion logging, which previously bypassed outcome metadata extraction. Strip the metadata before deciding whether to log so routine health checks cannot expose internal observability details to clients.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 117 out of 118 changed files in this pull request and generated no new comments.

Suppressed comments (1)

ios/WingDex/Services/AuthenticatedRequest.swift:38

  • This accepts the all-zero trace ID even though that value is invalid under W3C Trace Context and the web validator already rejects it in src/lib/api-error.ts:1. A malformed X-Trace-Id can therefore be logged and shown as a native correlation reference that cannot identify a real trace. Reject the all-zero value here as well.

Copilot AI review requested due to automatic review settings August 10, 2026 07:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 117 out of 118 changed files in this pull request and generated no new comments.

Suppressed comments (6)

functions/lib/log.ts:240

  • failWithHeaders also silently discards its properties argument, so callers cannot attach diagnostic metadata to the terminal request event despite the public responder contract accepting it. Preserve approved properties through middleware, or remove the parameter and update callers to emit an explicit safe event.
    ios/WingDex/Views/HomeView.swift:34
  • AvatarView is hidden from the accessibility tree, so the label attached to that child is ignored and this settings button has no VoiceOver name. Put accessibilityLabel("Settings") on the Button itself.
    ios/WingDex/Views/WingDexView.swift:144
  • AvatarView is hidden from the accessibility tree, so the label attached to that child is ignored and this settings button has no VoiceOver name. Put accessibilityLabel("Settings") on the Button itself.
    ios/WingDex/Views/OutingsView.swift:105
  • AvatarView is hidden from the accessibility tree, so the label attached to that child is ignored and this settings button has no VoiceOver name. Put accessibilityLabel("Settings") on the Button itself.
    src/lib/model-cache.ts:50
  • Capping a server-provided Retry-After at five seconds retries before the server's requested time. A 429 with Retry-After: 60, for example, is retried twice while still throttled, wasting bandwidth and making the model download fail instead of recovering. Honor valid header values; keep the cap only for locally generated exponential backoff.
    functions/lib/log.ts:236
  • The responder still accepts failure properties, but now discards them unconditionally. Existing callers such as data/observations.ts pass safe counts and IDs for diagnosing validation failures, so those fields silently disappear from the only terminal request event. Either transport approved properties to middleware or remove this parameter and migrate callers to an explicit safe event so the API cannot imply metadata was recorded.

This issue also appears on line 239 of the same file.

jlian added 5 commits August 10, 2026 02:09
… photos

Wikimedia's User-Agent policy asks for a client name and a contact route and
blocks non-descriptive agents. SpeciesDetailView sent no agent at all, and the
other callers each invented their own string. A website satisfies the contact
requirement, so no address is exposed and no secret is needed.

Reference photos now name their creator and license. A sample of 144 Commons
bird photos found 139 requiring attribution, across eight different licenses,
so the blanket CC BY-SA 4.0 notice was wrong for most of them and filtering to
attribution-free images would have emptied half the galleries. Artist and
LicenseShortName already arrived in the extmetadata both clients request and
were being dropped at parse time. The caption links to the file page, which
carries the full notice.
The species view claimed every image was CC BY-SA 4.0. A sample of 144 Commons
bird photos found eight different licenses, so the notice was wrong for most of
them, and it named no creator even though 139 of the 144 require one.

The file page URL is derivable from the image URL, since the file name is the
path segment before the rendered width, so the credit needs one request per
species and nothing new in taxonomy.json. That matters because the occurrence
prior is keyed by sha256(taxonomy.json) and any new field there would invalidate
the shipped blob.

The reference caption keeps its plumage label and carries the credit on its own
line, so neither has to be truncated to fit.
The plumage label and the photo credit were still sharing one line here, so the
caption wrapped and neither read cleanly. Split them the same way the web does.
The HStack centred its columns, so the taller caption lifted the reference photo
out of line with the user's. Align to the top instead, which holds regardless of
how many lines the credit takes.
The model download failed on localhost but worked on Cloudflare. Hosts disagree
about what a .gz asset means: Cloudflare serves it as an opaque body, so the raw
gzip arrives and the loader decodes it, while wrangler dev labels it
Content-Encoding: gzip off the extension, so the browser decodes it in transit
and the loader was handed 24 MiB of already-decoded data to gunzip.

Measured against the shipped meta.json: the same request returns gzip_bytes
16478112 from Cloudflare and raw_bytes 24123497 from wrangler dev.

The gzip magic distinguishes the two and cannot collide, since a decoded blob
starts with WDOP. Dropping the Blob round trip also avoids copying 16 MiB and
lets the decode be tested at all: jsdom's Blob has no stream().

Every existing model-cache test stubs global fetch, so none of them could see a
transport difference. The download failure was also swallowed into component
state without a log, which is why this surfaced only by being noticed.
Copilot AI review requested due to automatic review settings August 10, 2026 09:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 126 out of 127 changed files in this pull request and generated no new comments.

Suppressed comments (7)

ios/WingDex/Views/SpeciesDetailView.swift:267

  • The credit tuple is assigned even when Commons returns neither Artist nor LicenseShortName, which leaves an effectively empty Photo link. Keep the file-page attribution visible with a fallback label, as the web species detail does.
    ios/WingDex/Views/SpeciesDetailView.swift:172
  • Species without a dex thumbnail use the asynchronously fetched Wikipedia image (displayedFullImageUrl falls back to fullImageUrl), but this task runs only once and fetchImageCredit reads only entry?.thumbnailUrl. Those displayed hero images therefore never receive a photo credit. Key the task to the displayed image URL and derive the file page from that URL.

This issue also appears on line 267 of the same file.
functions/lib/geocoding.ts:104

  • The substring check drops legitimate region context when a place name merely contains the state or country name. For example, California City in California is treated as already containing the state, so same-named results lose the context this function is meant to provide. Compare complete comma-separated label parts instead.
    src/components/flows/AddPhotosFlow.tsx:1041
  • artist is optional in GalleryImage, so using it as the render guard hides the file-page source and any available license whenever Commons omits that field. Guard on descriptionUrl and use a source fallback so every displayed gallery image remains attributable.
    src/lib/bird-id-local.ts:244
  • Discarding both writer promises creates unhandled promise rejections when a gzip stream is corrupt or truncated, in addition to the error returned by reading ds.readable. Await the producer and consumer together so decompression failures stay within the caller's normal error path.
    ios/WingDex/Services/AuthenticatedRequest.swift:37
  • This accepts the all-zero trace ID, although W3C reserves it as invalid and the web validator rejects it. A malformed header can therefore produce a bogus [ref: 00000000] in native logs. Reject the zero value before normalizing it.
    src/tests/add-photos-flow.test.ts:65
  • This decorative separator uses non-ASCII box-drawing characters in a code comment. Keep code comments to ASCII punctuation.

@jlian
jlian merged commit fae9515 into main Aug 10, 2026
5 checks passed
@jlian
jlian deleted the dev branch August 10, 2026 09:38
jlian added a commit that referenced this pull request Aug 10, 2026
… stale

The iOS release failed on 2026-08-10 with "Could not determine the next iOS
release version", because semantic-release reported "The local branch main is
behind the remote one".

Mechanism: iOS Release and Release share the release-<ref> concurrency group, so
they serialize. On the merge of #302 both triggered on fae9515 one second apart.
Release ran first, published 1.24.0, and pushed the version-bump commit 44a508c
to main. iOS Release then started 21 seconds later with a checkout pinned to
fae9515, which by then was one commit behind the remote, and semantic-release
refuses to release from a stale branch.

The concurrency group is doing its job; the checkout was not. Resolving the ref
at execution time picks up the bump the previous workflow just pushed.

This was fixed once in 8a72195, then reverted in two steps: 60189c3 replaced the
preflight ref with a resolver whose fallback was GITHUB_SHA, and b8f9dd9 pinned
the publish job to github.sha to avoid archiving code other than the triggering
commit. That concern does not apply under the shared concurrency group, where the
commit landing mid-run is the version bump this release requires.

Both jobs now select the ref inline, so the two modes are visible at the call
site rather than hidden in a resolver step: a dispatch with release_version still
checks out that tag to rebuild a shipped release, and everything else takes the
branch tip.
github-actions Bot pushed a commit that referenced this pull request Aug 10, 2026
## [1.24.1](v1.24.0...v1.24.1) (2026-08-10)

### Bug Fixes

* **ios-release:** check out the branch tip so queued releases are not stale ([5187948](5187948)), closes [#302](#302)
* **ios-release:** publish the exact commit preflight archived ([d007518](d007518))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(geocoding): proxy and rate-limit geocoding on web and iOS chore(iOS): prepare App Store submission

2 participants