Round out other-kind ref semantics and unit-test the rejection logic
Commit

Two real semantic gaps in the AllRefs flow that the second-pass review caught:
-
CanReplicateRelay rejected RefKindOther outright, so a user running replicate --all-refs periodically as a mirror would succeed on first run (Action=Create), succeed on no-op runs (Action=Skip), and fail the moment a notes/pull ref updated ("replicate-unsupported-ref- kind"). Replicate's overwrite semantics make the FF concern that keeps other-kind out of the sync incremental relay irrelevant here: add the kind to CanReplicateRelay with the same shape as branch and tag. The TestRun_IntegrationAllRefsReplicateRejects... test that pinned the old behavior is converted to a positive idempotent re-run test that exercises both create and update.
-
PlanRef treated RefKindOther like a branch and ran a fast-forward ancestry check on it. A typical refs/notes/* append produces a new commit that isn't an ancestor of the previous notes tip, so the check would always fail and the user would see the cryptic "is not an ancestor of" message. Group RefKindOther with RefKindTag in PlanRef so a non-trivial update blocks with "use --force to update <kind> ref <name>" — clear, kind-aware, and consistent with the tag-retarget pattern. Replicate is unaffected (it doesn't run the FF check).
Plus polish:
- fetch and probe --all-refs help text now lists branches and tags alongside notes/pulls/custom, matching the library contract.
- Unit tests for applyRejections and finalizeCounts pin the keying logic, the empty-map fast path, the warned-Reason format, and the Pushed/Deleted/Warned tallies independent of strategy execution.
- docs/usage.md notes the sync-vs-replicate force semantics for other-kind refs.
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com Entire-Checkpoint: fd6c72102033