| … | … | @@ -47,6 +47,33 @@ atproto-base's firehose/repo, and repoint favela's `atproto-did-peer` at it. Ret |
| 47 | 47 | Fold in the bridge front-liveness fix from this session's audit (staleStrikes on `rpcConnected:false`, |
| 48 | 48 | never relay from a dead front) — that was a separate open bug (hyper-social #10/#11). |
| 49 | 49 | |
| 50 | CANONICAL HOME = `atproto-did-peer` (chosen 2026-07-23, diverges from "extend PeerRouter"): it was |
| 51 | already the extracted shared package, leak-free (fixed the `on('append',pull)` range leak PeerFront |
| 52 | still carries), and already had the appview `commitOps`. Findings that settled the design: |
| 53 | - The "3×" is really 2× + a dead ancestor — the dormant bridge `did-peer.js` is a stale, buggy |
| 54 | ancestor of favela's module (still has the range-leak); retire outright. |
| 55 | - Decision "firehose vs repo projection" = NO fork: the consumer replicates BOTH cores (firehose→sig, |
| 56 | repo→records, `getRepoFromCommit` stitches). atproto-base is already a drop-in producer |
| 57 | (`firehoseKey`/`repoKey`/`subscribeRepos`/`getRepo` = "exactly PeerFront.getRepo's contract", |
| 58 | base.js:470). Only producer gap: atproto-base has no swarm/announce wrapper yet (join |
| 59 | `discoveryTopic(did)` + push `atproto/did-announce/v1`) — a small producer task, not consumer. |
| 60 | - Discovery already converged: both primitives use `atproto/did-announce/v1` PUSH (PeerRouter's |
| 61 | `_identify.learn` is announce-fed, NOT get-coords-pull — the skill's text is stale at 0.9.27). |
| 62 | PeerRouter's extra protomux-rpc is ONLY the write path → the write-relay is an optional layer. |
| 63 | |
| 64 | ### Phase 1 sub-steps |
| 65 | - ✅ 1a (2026-07-23, atproto-did-peer 0.2.0, commit 772e17a): `DidPeerRouter` absorbed PeerRouter's |
| 66 | co-owned multi-front (`did→Map<fhKey,DidPeer>`) + freshest-by-REV + optional swarm/relay/rpc/handles |
| 67 | layers; `DidPeer` gained the optional write/session/blob relay + getRepoStatus/describeRepo/handle. |
| 68 | ALL existing contracts preserved (add/onconnection/get/ready — router+commitops green; favela loads |
| 69 | clean + appview-ingest green under bare). Ported co-owned-front-thrash → test/co-owned.test.mjs. |
| 70 | - ▢ 1b — repoint the bridge: `server-bare.js`/`server.js`/`pds-serve.js` import the shared |
| 71 | `DidPeerRouter` (owns-swarm + join + relay + rpc). Bridge suite + `npm run smoke` green, THEN delete |
| 72 | `pds/lib/peer-front.js`, `peer-router.js`, `did-peer.js` (+ their tests). ⚠ verify the front's write |
| 73 | RPC + FleetRelay wiring end-to-end here (1a added them but only the read/freshest path is unit-tested). |
| 74 | - ▢ 1c — repoint favela: mostly free; migrate co-owned reads to `front()` freshest-selection. |
| 75 | - ▢ 1d — fold in hyper-social #10/#11 (never fold the relay from a front with `rpcConnected:false`). |
| 76 | |
| 50 | 77 | ## PHASE 2 — migration, rehearsed on a SNAPSHOT (never hot) |
| 51 | 78 | Per the wj62 discipline (`reconcileFromCar` on FRESH storage; rocksdb hot-copy is inconsistent): |
| 52 | 79 | stop a daemon, snapshot its storage, run the Phase-0 migration reader → atproto-base on a THROWAWAY |