/**
* Ordered deploy-topic candidates for fetching a release's trees + content.
*
* serverKey (the publisher's identity topic) goes FIRST. It's a DEDICATED topic
* where the publisher's `DeployServer._onConnection` always attaches the tree
* channel, so a freshly-published release resolves instantly.
*
* The shared/registry topic is a FALLBACK, not the preferred first try. It is
* promiscuous — the same discovery key carries autobase registry replication,
* every fleet sidecar, and stale DHT advertisements. A dead / half-open peer
* there burns the full per-peer tree timeout (~5s each) because hyper-overlay's
* `_onTreeRequest` only fast-negatives (empty entries) for LIVE peers that
* actually answer; a peer whose overlay channel never opened just never
* responds. That's the ~12s stall observed on fresh releases (stortron,
* 2026-07-02). It remains in the list for publisher-offline / no-serverKey and
* as the genuine multi-source path once content is widely mirrored on LIVE
* seeders. The deeper multi-source fix — fast-skip peers whose overlay channel
* never opened, à la hypercore/BitTorrent advertise-then-request — is tracked
* in hyper-fleeky-dev #105.
*
* @param {object} topics
* @param {string|Buffer|null} [topics.serverKeyTopic] publisher identity topic (hex string or buffer)
* @param {Buffer|null} [topics.registryTopic] shared registry discovery key (buffer)
* @returns {Array<{label: string, topic: (string|Buffer), short: string}>}
*/
export function orderedTopicCandidates ({ serverKeyTopic = null, registryTopic = null } = {}) {
const short = (t) => (typeof t === 'string' ? t : t.toString('hex')).slice(0, 12)
const cands = []
if (serverKeyTopic) {
cands.push({ label: 'serverKey (publisher)', topic: serverKeyTopic, short: short(serverKeyTopic) })
}
if (registryTopic) {
cands.push({ label: 'registry (shared/multi-source)', topic: registryTopic, short: short(registryTopic) })
}
return cands
}