Resync bundled backends + switch photo-post AT projector onto atmosphere_post_embed#164
Merged
kraftbj merged 5 commits intoMay 20, 2026
Conversation
Refreshes bundled/activitypub/ and bundled/atmosphere/ via tools/sync-bundled.sh. Upstream SHAs: - wordpress-activitypub trunk -> 31cdcd0a - wordpress-atmosphere trunk -> 2a0383a Notable Atmosphere changes brought in: - atmosphere_post_embed filter plus Post::upload_image_blob() / Post::get_attachment_aspect_ratio() helpers (PR 72). The next commit refactors Photo_Post_Atmosphere onto this surface. Post::upload_thumbnail() remains as a back-compat alias. - Re-sync publication on theme / site-URL changes (PR 76) and publication link tag for standard.site discovery (PR 75). - Publishing classifier, publication URI staleness, and handle button hang fixes after the 1.0.0 release cut (PR 74). - Atmosphere 1.0.0 release (PR 73). The bundled copy still reports ATMOSPHERE_VERSION = 'unreleased' because the vendored tree is trunk, not a tagged release. Notable ActivityPub changes brought in: - toot:blurhash declared in the JSON-LD context (PR 3327). Pairs with FOSSE's Blurhash injection so the field validates against Mastodon's schema. - SWICG basic-profile conformance improvements for C2S (PR 3328) and supporting OAuth scope / token refactors. - Tombstone migration and post-types helper changes. Known regressions from this resync (not introduced by FOSSE code): - 3 Admin\Bluesky_ProviderTest::test_handle_oauth_callback_* cases now fail. Atmosphere's OAuth client was substantially rewritten; the fosse-side stubs in fake_atmosphere_oauth_environment() need to be updated to match the new request flow. Tracking separately so this resync isn't held up.
wordpress-atmosphere PR 72 added a focused atmosphere_post_embed
filter for swapping the embed attached to a Bluesky post record,
plus a renamed Post::upload_image_blob() (with upload_thumbnail() as
a backward-compatible alias) and a public
Post::get_attachment_aspect_ratio() helper that centralizes
metadata-driven aspectRatio resolution. With the previous commit
resyncing the bundled copy, the projector can target that focused
seam instead of leaning on the wider atmosphere_transform_bsky_post
for embed work.
The refactor splits the projector across two filters:
- atmosphere_post_embed (new) - builds the
app.bsky.embed.images envelope. All upload / overflow /
featured-image-bail logic lives here. When uploads fail
(featured image, all attachments, or budget exhaustion) the
filter returns the input embed unchanged so Atmosphere
cleanly ships short-form text with no embed.
- atmosphere_transform_bsky_post (existing, slimmed) - rewrites
the record's text and re-extracts facets. Now gated on
record.embed.$type === 'app.bsky.embed.images' so a fully-
failed upload pass leaves Atmosphere's default short-form text
in place; rewriting to a caption-only string when no images
actually shipped would strip useful body content.
atmosphere_is_short_form_post stays put - still the right seam to
force the short-form path for photo posts.
Other changes:
- upload_blob() now calls Post::upload_image_blob() (the
documented successor name). Functional behavior unchanged.
- get_aspect_ratio() now delegates to
Post::get_attachment_aspect_ratio() so every downstream
image-embed consumer reads dimensions the same way (including
the unit-suffix sanitation that helper applies).
Tests:
- apply_transform_filter() helper now simulates Atmosphere's
full composition: run atmosphere_post_embed first, attach the
result onto the record, then run atmosphere_transform_bsky_post.
Mirrors the call order inside shipped Post::transform().
- 2 new tests cover the new embed-filter contract directly:
pass-through for non-short-form strategies and pass-through on
a non-WP_Post second arg.
- Existing 26 tests pass unchanged - the helper transparently
adds the new filter to the round-trip.
Refs DOTCOM-17143.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR resyncs the vendored ActivityPub and ATmosphere backends to newer upstream trunk SHAs, and updates FOSSE’s Photo_Post_Atmosphere projector to use ATmosphere’s newer atmosphere_post_embed seam for emitting app.bsky.embed.images on Bluesky.
Changes:
- Resync bundled
activitypubandatmosphereplugins to newer upstream revisions (includes substantial OAuth, publishing, and cleanup changes). - Refactor
Photo_Post_Atmosphereto build the image embed viaatmosphere_post_embed, and gate caption/facet rewriting on the images embed actually being attached. - Update/extend tests to simulate ATmosphere’s composition order and to accommodate upstream OAuth transient shape changes.
Reviewed changes
Copilot reviewed 35 out of 36 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/class-photo-post-atmosphere.php | Switches photo-post projection to build embeds via atmosphere_post_embed and rewrites text/facets only when an images embed is present. |
| tests/php/Photo_Post_AtmosphereTest.php | Updates helper pipeline to run atmosphere_post_embed before atmosphere_transform_bsky_post; adds defensive embed-filter tests. |
| tests/php/Admin/Onboarding_WizardTest.php | Seeds atmosphere_identity to avoid warnings when testing corrupted connection shapes after upstream identity split. |
| tests/php/Admin/Bluesky_ProviderTest.php | Updates OAuth test fixtures to match upstream’s encrypted DPoP JWK transient format. |
| bundled/atmosphere/vendor/composer/installed.php | Vendored upstream resync metadata (reference SHA update). |
| bundled/atmosphere/uninstall.php | Vendored upstream resync: expanded uninstall cleanup (options/meta/transients) and broader scheduled-hook clearing. |
| bundled/atmosphere/readme.txt | Vendored upstream resync: readme updates including 1.0.0 changelog content. |
| bundled/atmosphere/includes/wp-admin/class-admin.php | Vendored upstream resync: admin UX + OAuth redirect hardening + metadata filter validation. |
| bundled/atmosphere/includes/transformer/class-tid.php | Vendored upstream resync: persisted monotonic TID floor + safer clock id seeding. |
| bundled/atmosphere/includes/transformer/class-publication.php | Vendored upstream resync: validates transform filter return type before use. |
| bundled/atmosphere/includes/transformer/class-post.php | Vendored upstream resync: adds atmosphere_post_embed seam, redaction support, and stronger filter-return validation. |
| bundled/atmosphere/includes/transformer/class-facet.php | Vendored upstream resync: safer mention resolution and handle validation. |
| bundled/atmosphere/includes/transformer/class-document.php | Vendored upstream resync: redaction support, DID provenance meta, and safer filter handling. |
| bundled/atmosphere/includes/transformer/class-comment.php | Vendored upstream resync: redaction guard and safer filter handling. |
| bundled/atmosphere/includes/transformer/class-base.php | Vendored upstream resync: central redaction predicate for transformers. |
| bundled/atmosphere/includes/oauth/class-resolver.php | Vendored upstream resync: wp_safe_remote_* usage, SSRF/url validation, and DID-doc hardening. |
| bundled/atmosphere/includes/oauth/class-nonce-storage.php | Vendored upstream resync: nonce keying includes DID. |
| bundled/atmosphere/includes/oauth/class-dpop.php | Vendored upstream resync: adds exp to DPoP proof payload. |
| bundled/atmosphere/includes/oauth/class-client.php | Vendored upstream resync: encrypted transient storage, refresh locking, revocation worker, and rate limiting. |
| bundled/atmosphere/includes/functions.php | Vendored upstream resync: identity split helpers + publishability predicates + expanded cron hook management. |
| bundled/atmosphere/includes/class-reaction-sync.php | Vendored upstream resync: moderation pipeline for imported reactions and safer post lookup. |
| bundled/atmosphere/includes/class-publisher.php | Vendored upstream resync: publishability gating + reconcile cleanup paths + deterministic comment ordering. |
| bundled/atmosphere/includes/class-handle.php | Vendored upstream resync: handle update timeout and identity/connection sync behavior. |
| bundled/atmosphere/includes/class-backfill.php | Vendored upstream resync: uses publishability predicate and excludes password-protected posts. |
| bundled/atmosphere/includes/class-atmosphere.php | Vendored upstream resync: publication link tag, visibility cleanup migration, and broader lifecycle hardening. |
| bundled/atmosphere/includes/class-api.php | Vendored upstream resync: uses wp_safe_remote_request and hardens JSON decode. |
| bundled/atmosphere/atmosphere.php | Vendored upstream resync: version bump and deactivation hook cleanup semantics. |
| bundled/activitypub/includes/rest/oauth/class-token-controller.php | Vendored upstream resync: adds Retry-After header on 429 error responses. |
| bundled/activitypub/includes/rest/oauth/class-clients-controller.php | Vendored upstream resync: standardized 429 responses with Retry-After. |
| bundled/activitypub/includes/rest/oauth/class-authorization-controller.php | Vendored upstream resync: standardized 429 responses with Retry-After. |
| bundled/activitypub/includes/oauth/class-token.php | Vendored upstream resync: exposes activitypub_actor_id alongside IndieAuth me. |
| bundled/activitypub/includes/oauth/class-server.php | Vendored upstream resync: advertises supported scopes via Scope::supported(). |
| bundled/activitypub/includes/oauth/class-scope.php | Vendored upstream resync: normalizes/advertises Basic Profile canonical scope aliases. |
| bundled/activitypub/includes/activity/class-base-object.php | Vendored upstream resync: adds blurhash terms to JSON-LD context. |
| bundled/activitypub/includes/activity/class-activity.php | Vendored upstream resync: adds blurhash term mapping. |
| bundled/activitypub/composer.json | Vendored upstream resync: dev dependency bump. |
Comments suppressed due to low confidence (1)
src/class-photo-post-atmosphere.php:223
$attemptedis used to enforce the 4-image cap, but it’s incremented on failed uploads too. If a post has >4 candidate attachments and one of the early (non-featured) uploads fails, the loop will treat later attachments as overflow and stop trying to fill the remaining slots, potentially emitting fewer than MAX_IMAGES even though more successful uploads were available. Consider tracking the cap based on the number of successfully attached images (e.g., separate counters for scanned vs attached) so non-featured failures don’t reduce the final image count.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs DOTCOM-17143.
Resyncs both bundled backends to current upstream trunk and refactors
Photo_Post_Atmosphereonto the focused embed seam introduced upstream by wordpress-atmosphere PR 72.Upstream SHAs
31cdcd0a(Add blurhash term to JSON-LD context)2a0383a(Re-sync publication on theme and site-URL changes)Notable upstream changes brought in
Atmosphere:
atmosphere_post_embedfilter +Post::upload_image_blob()/Post::get_attachment_aspect_ratio()helpers (wordpress-atmosphere PR 72) — the surface the second commit targets.Post::upload_thumbnail()remains as a back-compat alias for Publication / Document callers.ATMOSPHERE_VERSION = 'unreleased'because we vendor trunk, not the release tag.ActivityPub:
toot:blurhashdeclared in the JSON-LD context (PR 3327). Pairs with FOSSE's own Blurhash injection so the field validates against Mastodon's schema without a FOSSE-side@contextshim.Photo-post projector refactor
The previous shape (PR 156) deliberately targeted the shipped Atmosphere surface —
atmosphere_transform_bsky_postplusPost::upload_thumbnail()— so the photo-post AT federation worked the moment that PR landed, with or without PR 72 upstream. The class docblock called out the cleaner two-line switchover for when PR 72 made it into the bundled copy. That's this commit.Three filter callbacks now do the work:
atmosphere_is_short_form_postatmosphere_post_embed(new)app.bsky.embed.imagesfrom up to 4 uploaded blob refs. All upload / overflow / featured-image-bail logic lives here.atmosphere_transform_bsky_post(slimmed)textand re-extract facets. Now gated onrecord.embed.$type === 'app.bsky.embed.images'so a fully-failed upload pass leaves Atmosphere's default short-form text in place.Other cleanups:
upload_blob()callsPost::upload_image_blob()(the documented successor). Functional behavior unchanged.get_aspect_ratio()delegates toPost::get_attachment_aspect_ratio()so every downstream image-embed consumer reads dimensions the same way (including theis_numeric()sanitation that helper applies — protects against a unit-suffixed string like"1600px"propagating as a misleading integer).Failure-mode posture (unchanged from PR 156)
fosse_photo_post_atmosphere_upload_budget_seconds(default 30s).Tests
WP_Postsecond-arg pass-through).apply_transform_filter()helper now simulates Atmosphere's full composition order — runatmosphere_post_embed, attach result, then runatmosphere_transform_bsky_post— so the embed-attached → text-rewritten chain is exercised end-to-end the way shipped Atmosphere does it insidePost::transform().Known regressions from the bundled resync
Three OAuth callback tests in
Admin\Bluesky_ProviderTeststarted failing with the Atmosphere resync (not introduced by the photo-post refactor):test_handle_oauth_callback_success_emits_success_noticetest_handle_oauth_callback_warns_when_connection_not_persistedtest_handle_oauth_callback_warns_when_sync_publication_failsAtmosphere's OAuth client was substantially rewritten upstream (~1000 lines changed in
includes/oauth/class-client.php). The FOSSE-side stubs infake_atmosphere_oauth_environment()/intercept_token_endpoint_success()need to be refreshed against the new request flow. Filing as a separate follow-up so this resync isn't held up — flagging here so it isn't a surprise on the next test run.The pre-existing BlurhashTest and Blurhash_CLITest failures on
trunkare unchanged by this PR.Testing instructions
composer test-php -- --filter Photo_Post_Atmosphere— 28/28 pass.composer lint-php -- src/class-photo-post-atmosphere.php tests/php/Photo_Post_AtmosphereTest.php— clean.embed.$type === "app.bsky.embed.images"(Flashes / Pinksky render it as a native image post; web bsky.app shows it inline). Toggle offPhoto_Post::is_photo_post()via thefosse_is_photo_postfilter and confirm the record reverts toembed.$type === "app.bsky.embed.external"(today's default link card).