Split publish/cleanup gates so allowlist changes don't orphan remote records#38
Split publish/cleanup gates so allowlist changes don't orphan remote records#38
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes a rollback hazard in Atmosphere’s post lifecycle hooks where narrowing the syncable post-type allowlist could prevent cleanup of already-synced remote AT Protocol records, leaving orphaned records behind.
Changes:
- Split
on_status_change()gating so the allowlist applies only to publish/update scheduling, while unpublish cleanup schedules deletion based on existing stored TIDs (regardless of current allowlist). - Remove the allowlist check from
on_before_delete()so permanent deletes always capture TIDs and schedule remote record cleanup when publication metadata exists. - Add PHPUnit coverage for the new cleanup behavior and for the regression that new publishes still respect the allowlist.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
includes/class-atmosphere.php |
Separates publish/update allowlist gating from cleanup paths; ensures unpublish + permanent delete still clean up remote records based on stored TIDs. |
tests/phpunit/tests/class-test-status-change.php |
Adds regression tests verifying cleanup bypasses allowlist for previously-synced posts, while new publish remains allowlist-gated. |
.github/changelog/fix-cleanup-gate-split |
Adds changelog entry documenting the fix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if ( ! \in_array( $post->post_type, Backfill::syncable_post_types(), true ) ) { | ||
| $is_new_publish = 'publish' === $new_status && 'publish' !== $old_status; | ||
| $is_update = 'publish' === $new_status && 'publish' === $old_status; | ||
| $is_unpublish = 'publish' === $old_status && 'publish' !== $new_status; |
There was a problem hiding this comment.
Do we want to delete posts that were put into draft mode!? Is it possible to re-publish posts in Bluesky? Mastodon is very picky with that... once deleted, it can't be published (with the same ID) again.
There was a problem hiding this comment.
Those are good questions. I would think that if someone made a post a draft, it should be deleted. But, the how should we act on re-publish is fair. Let me think about it a bit and checkout the AT docs a bit.
Fixes the rollback hazard where narrowing `atmosphere_syncable_post_types` (directly or via the `activitypub_support_post_types` option projected into that filter, as FOSSE's `Post_Types` projector does) orphans the remote AT Protocol records of posts that were already synced under the wider configuration.
Proposed changes:
Rationale
The bug is a gate-conflation issue. `Backfill::syncable_post_types()` answers "what post types is this site willing to publish to Bluesky?" — a publish-time eligibility question. Both cleanup paths were reusing it as a proxy for "was this post ever synced?", which only coincides when the allowlist never narrows. A site owner unchecking a post type on the AP side (where FOSSE's new projector surfaces that control in a way most sites already used) becomes a normal operation, not an edge case — at which point the conflation silently leaks orphaned records.
FOSSE PR Automattic/fosse#31 surfaces this path by making the allowlist editable via AP's existing checkbox UI, but the bug pre-exists in every standalone Atmosphere site that filters `atmosphere_syncable_post_types` in PHP. Fixing it here — not in a FOSSE-side workaround — is correct per Atmosphere's existing upstream-first positioning: post-type-agnostic correctness lives here.
Other information:
Three new PHPUnit cases in `tests/phpunit/tests/class-test-status-change.php`:
Full suite runs clean (97/97).
Testing instructions:
Changelog entry
Changelog Entry Details
Significance
Type
Message
Preserve remote cleanup of already-synced posts when their post type is removed from the syncable allowlist.
Companion references: