From cd28c0336ce214d00e399a133396d8faf21e7fa8 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Thu, 2 Jul 2026 13:07:35 +0200 Subject: [PATCH] refactor(federation): store verified epoch as peer baseline; drop redundant assertion --- .../src/routes/federation.peerInitiateOutbound.test.ts | 1 - packages/server/src/routes/federation.ts | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/server/src/routes/federation.peerInitiateOutbound.test.ts b/packages/server/src/routes/federation.peerInitiateOutbound.test.ts index 74925525..ac518682 100644 --- a/packages/server/src/routes/federation.peerInitiateOutbound.test.ts +++ b/packages/server/src/routes/federation.peerInitiateOutbound.test.ts @@ -271,7 +271,6 @@ describe('POST /api/federation/peer/initiate — 202 token capture & 200 clear', .where(eq(schema.federationPeers.origin, 'https://remote.example')).get(); expect(peer?.status).toBe('needs_attention'); expect(peer?.needsAttentionReason).toBe('repeer_incomplete'); - expect(peer?.status).not.toBe('active'); }); it('(c) on 200 with a valid signed epoch, activates (verified:true) and clears needsAttentionReason', async () => { diff --git a/packages/server/src/routes/federation.ts b/packages/server/src/routes/federation.ts index cb10f66d..37e42553 100644 --- a/packages/server/src/routes/federation.ts +++ b/packages/server/src/routes/federation.ts @@ -1001,7 +1001,11 @@ export async function federationRoutes(app: FastifyInstance): Promise { } db.update(schema.federationPeers) - .set({ status: 'active', lastSeenAt: Date.now(), instanceName: remoteInstanceName, peerInstanceId: remoteInstanceId, needsAttentionReason: null, approvalToken: null }) + // The baseline is trust-consequential (design §9 — a poisoned baseline can drive + // a spurious heal), so store the epoch we cryptographically verified via the signed + // /epoch round-trip, not the unverified handshake-response body. They are normally + // identical; the verified one is authoritative if they ever differ. + .set({ status: 'active', lastSeenAt: Date.now(), instanceName: remoteInstanceName, peerInstanceId: verifiedEpoch, needsAttentionReason: null, approvalToken: null }) .where(eq(schema.federationPeers.id, peerId)) .run(); connectionManager.sendToAdmins({ type: 'federation_peers_changed' as const });