Address review: the target's emptiness needs asserting too
Commit

The previous commit fixed this asymmetry on the source leg and left it standing on the target: len(target.refMap) == 0 was still read as proof that the target holds no refs. It is the same mistake. receive.hideRefs omits matching refs from receive-pack's advertisement, so a populated target advertises nothing but the bare capabilities^{} sentinel — verified against git 2.53, where a repo holding refs/heads/other with receive.hideRefs=refs/heads/other advertises exactly that.
The target case is the sharper of the two, because receive.hideRefs and uploadpack.hideRefs are separate settings: the same probe confirms upload-pack still serves refs/heads/other to fetchers while receive-pack conceals it. A target wrongly judged empty is therefore one whose READERS see refs the source does not have — live divergence, reported as convergence, which is the one direction a watermark claim must never fail in.
So TargetAssertedEmpty joins SourceAssertedEmpty, corroborated the same way and failing closed to a distinct ErrTargetEmptyUnverified. A VISIBLE target ref still reports ErrSourceEmptyTargetPopulated rather than an unknown: hiding can conceal refs but never invent them, so anything advertised is real and that is divergence, not uncertainty.
Target ref names dropped by validation are now retained rather than only warned about, closing the same secondary hole the source side already covers: they leave refMap empty while the target plainly holds refs.
Exported documentation is corrected where it still described the superseded contract. SyncPolicy said AllowEmptySource relied on the source confirming emptiness through ls-refs=unborn, which stopped being true when the assertion became an input; ErrSourceEmptyUnverified said it meant a missing unborn assertion, when it covers a missing caller assertion and dropped ref names as well. Both now describe what the implementation actually requires, so an embedder cannot omit an assertion or misread the error.
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com Claude-Session: https://claude.ai/code/session_01714HJZAqpgwuwp6fcMWEhG Entire-Checkpoint: 01M0JE3619BM1KPE2YXS7Y5XVP