fix(communities): resolve prefix-free community handles on every path master
Community actors are provisioned with a "c-" prefixed handle (c-science.coves.social) that namespaces them apart from user actors on the PDS. Clients display and link to the prefix-free form, so the AppView has to accept both. It did so in ResolveCommunityIdentifier but not in GetCommunity — the lookup backing social.coves.community.get, which is what /c/{handle} actually hits. The result was a community page whose feed loaded (200) while its metadata 404'd. The two paths had drifted because each hand-rolled its own handle lookup. Both now share LookupByHandle, along with the comment service's community filter, which had the same gap and degraded to empty results rather than an error. Also reserves the "c-" namespace at creation. Stripping exactly one leading "c-" is only unambiguous while no name starts with "c-" itself: "c-sharp" would provision c-c-sharp.coves.social, which strips back to c-sharp.coves.social — the stored handle of the *different* community named "sharp", so its own link would resolve to the wrong place. The prefixed retry is skipped for identifiers already starting with "c-", so resolution cannot break the tie either. The same namespace is held back from local user registration, where squatting c-science.coves.social would otherwise block provisioning of the "science" community. Changes: - Add LookupByHandle: exact match, then a "c-" prefixed retry on a genuine miss. Bridged communities are stored unprefixed and resolve on the first lookup, never reaching the retry. - Route GetCommunity, ResolveCommunityIdentifier, and the comment service's community filter through it. - Propagate non-NotFound repository errors instead of reporting them as "community not found", so a database outage no longer looks like a missing community or triggers a second query. - Reject community names starting with "c-" (reserved prefix). - Reject local user handles whose first label starts with "c-", scoped to this instance's domain via the new WithInstanceDomain option. External user indexing is deliberately untouched: a remote c-foo.example.com is in someone else's namespace. - Tests for GetCommunity's handle forms, both reservations, and the over-rejection boundaries (c, csharp, cats, self-host, c2-fast). Deploy note: this must ship before the frontend change that links to prefix-free handles, since older backends reject that form. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>