fix(validation): allowlist http/https with a required host for link URIs master
NormalizeURI guarded embed.external.uri, embed.external.sources[].uri and richtext #link.uri with a blocklist (javascript, data, vbscript, file, mailto). Every one of those fields is rendered as an href, and the blocklist still signed ftp:, blob:, intent:, gopher:, ws: and any custom app scheme into federated records. Changes: - Allowlist {http, https}; anything else -> ErrURISchemeNotAllowed. - Require an authority ("//host") for http(s): "https:foo", "https://", "https:///path" satisfy the atproto format but the WHATWG parser clients render through rejects them, so the link silently vanished in the UI while the API returned 200. New ErrURINoAuthority / corpus "no_authority". - Python bridges (kagi-news, reddit-highlights) mirror both rules; shared corpus uri_vectors.json gains ftp/blob/intent/gopher/ws/FTP, at://, empty-host, userinfo-only and IPv6-literal vectors; the unreachable opaque-URI branch and its urn:/magnet:/at:// rationale are removed. - sources[] guard test now includes ftp: so it proves the allowlist. Companion frontend change: coves-frontend fix/url-scheme-policy. Closes #1 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>