A community based topic aggregation platform built on atproto

fix(posts): re-review round on Opus 5 — postv2 aggregation + edit-path validation parity master

The task 6-8 reviews were re-run on a stronger model after discovering the original panel had fallen back to Opus 4.8 mid-loop. Task 6's re-review found two classes of defect the earlier pass missed. AGGREGATION (product-breaking): vote and comment counting still switched on the legacy "social.coves.community.post" literal with no postv2 arm, so every author-owned post silently never accumulated votes or comments — the row was indexed, the count was never touched, and the failure logged as an "unsupported collection" line nobody read. The reindex-votes repair tool had the same gap, so it could not even fix the drift. Routes both collections through one shared posts.IsPostCollection predicate. Also fixes comment hydration stamping the deprecated $type (and a fabricated author field) on author-owned posts served through getComments. EDIT-PATH VALIDATION: UpdatePost never ran normalizeEmbedURIs or NormalizeLinkURIs, so an author could create a clean post and edit it into a signed record create would have refused — javascript:/data: embed and facet link URIs, unencoded URIs, and an uncapped external.sources array. Normalization now lives inside the shared gate (validatePostContent -> normalizeAndValidatePostContent) so both paths get it once. tags/langs were also written with zero validation against a lexicon that caps them, and were silently discarded on create while honored on update; both now carry through create and are validated in the shared gate. Plus: dead error return on enhanceExternalEmbed, a stale STUB header on postv2.go, and the update lexicon's error vocabulary reconciled additively. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QDvRJ45k6E5KrBARDHUtiM