A community based topic aggregation platform built on atproto

fix(posts): author delete now compensates directly instead of waiting for the firehose master

Fixes a production data-erasure/staleness bug found live: when an author deleted their own postv2, deleteAuthorPost removed the record from the author's repo and returned, leaving the AppView-side cleanup (soft-delete the index row, withdraw the community's acceptance, stamp the admission row) entirely to the firehose consumer — which never runs for an author whose PDS is not on a configured jetstream feed. The post stayed served, the acceptance dangled in the community repo citing a record nobody could fetch, and getStatus kept answering "accepted". The delete path now runs the compensation directly, mirroring the create path's settleSubmission and the consumer's tombstoneAuthorPost/withdrawAcceptance, for every community THIS AppView hosts. A community hosted elsewhere is a graceful skip (ErrCommunityNotHosted) — its own AppView performs that cleanup over the firehose — so the local delete always completes and is locally consistent regardless of where the community lives. Changes: - compensateAuthorDelete / withdrawAcceptanceOf: soft-delete the index row, then for each community that admitted the post withdraw the acceptance and stamp the admission row back to pending at the withdrawal's committed rev - Failures SURFACE (the client is the retry loop; every step is idempotent), unlike the consumer which swallows; ErrCommunityNotHosted is the sole graceful skip; the ErrNotFound retry branch runs the full compensation so a crash mid-way converges on retry - Compensation is default-on: the withdrawer is derived from the mandatory community service, so no wiring omission can silently restore the bug - New one-method AcceptanceWithdrawer interface so the service can never write a verdict (accept/remove/repin) - Review hardening: the multi-community loop accumulates failures (errors.Join) instead of aborting on the first, so one sick community PDS can't starve the others; a community credential failure is severed from the author's session so it can't masquerade as a 401; a committed withdrawal reporting no rev surfaces instead of silently succeeding unstamped Tests: T1 outer acceptance contract + a T0 battery over every branch, each proven to bite by mutation. make ci green at 5456/0/0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QDvRJ45k6E5KrBARDHUtiM