Address force-clarification review findings
Commit

Three issues from review on top of the force-clarification branch:
-
BestEffort silently defeated --force-with-lease. The OnRejection callback installed under BestEffort stored every per-ref ng status for downgrade to a warning, including lease-mismatch statuses.
sync --all-refs --force-with-leasecould then exit successfully after a concurrent target update, contradicting the lease.Export gitproto.IsLeaseFailure and add a syncer.leaseFailureError pass after finalizeCounts. Lease-class rejections (stale info / fetch first / non-fast-forward / does not match) now escalate to a fatal error even with BestEffort on; non-lease rejections continue to downgrade to warnings.
-
Public and unstable APIs accepted invalid force combinations and only rejected them deep in newSession (after auth resolution). Add SyncPolicy.Validate, invoke it from gitsync.SyncRequest.Validate and gitsync.PlanRequest.Validate, and from unstable.Client.Sync, .Plan, .Replicate. The syncer.go check stays as defense-in-depth for callers reaching syncer.Config directly (tests).
-
docs/usage.md described replicate as "fast-forward-only by design"; in fact replicate's contract is source-authoritative overwrite — divergent branches and tags are retargeted unconditionally, which is why force flags are unnecessary rather than disallowed by a gate. Rewrite the sentence.
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com Entire-Checkpoint: eaa899c96ddf