| … | … | @@ -475,7 +475,13 @@ export class DidPeerRouter { |
| 475 | 475 | // Learn a (did, firehoseKey) co-owner from a PUSHED announce; open its front (best-effort). A DIFFERENT |
| 476 | 476 | // firehoseKey under the same DID is a DISTINCT co-owner (tracked, never evicting the other). |
| 477 | 477 | async _onAnnounce (a, rpc, conn) { |
| 478 | | if (!a || !a.did || !a.repoKey || !a.firehoseKey) return |
| 478 | // repoKey is OPTIONAL — same contract as DidPeer.onAnnounce. A peer running the stateless virtual |
| 479 | // device (serve-membrane projectRepoCore:false) publishes no membrane-repo core and announces |
| 480 | // { firehoseKey, repoKey: null }; its repo is DERIVED over the get-repo-car RPC. Requiring repoKey |
| 481 | // HERE silently dropped that announce before it ever reached the DidPeer, so the peer went live:false |
| 482 | // and was never fronted — the fix in DidPeer.onAnnounce alone was not enough, because the router |
| 483 | // gates first. The firehose key is the only thing genuinely required: it is the trust anchor. |
| 484 | if (!a || !a.did || !a.firehoseKey) return |
| 479 | 485 | const did = a.did |
| 480 | 486 | const fhKeyHex = a.firehoseKey |
| 481 | 487 | if (a.handle) this._setHandle(a.handle, did) |
| … | … | @@ -486,6 +492,16 @@ export class DidPeerRouter { |
| 486 | 492 | if (existing) { // refresh write rpc + handle; nudge fetch (cores re-replicate via corestore regardless) |
| 487 | 493 | if (this._useRpc && rpc) existing.rpc = rpc |
| 488 | 494 | if (a.handle) existing.handle = a.handle |
| 495 | // The peer went STATELESS while we still hold a repo-core replica (it used to project, now it |
| 496 | // announces repoKey:null). That replica is frozen at whatever it last replicated, so once the head |
| 497 | // advances getRepoFromCommit's data-root assertion fails — safe, but permanently broken. Drop it so |
| 498 | // getRepo takes the derive-over-RPC path instead. The firehose (the trust anchor) is untouched. |
| 499 | if (!a.repoKey && existing.repo) { |
| 500 | const stale = existing.repo |
| 501 | existing.repo = null |
| 502 | existing._repoKey = null |
| 503 | try { await stale.close() } catch {} |
| 504 | } |
| 489 | 505 | if (existing.seq) existing.seq.core.update().catch(() => {}) |
| 490 | 506 | this._wake(did) |
| 491 | 507 | return |