Jannis Braun
344a429e98
feat(web): automatic re-attach on connect + AccountPanel fallback action (re-attach spec §3.4)
2026-07-03 02:19:51 +02:00
Jannis Braun
d45366c4ff
feat(federation): owner-initiated detached-account re-attach — proof-gated re-bind with stub merge (re-attach spec §3.2, §3.3)
2026-07-03 02:06:00 +02:00
Jannis Braun
7bff6c1a1b
feat(federation): outbound attach-proof verification + home-profile fetch helpers (re-attach spec §3.1)
2026-07-03 01:54:50 +02:00
Jannis Braun
af94f12389
feat(federation): S2S verify-attach-proof endpoint — single-use, peer-domain-bound, signed response (re-attach spec §3.1)
2026-07-03 01:49:20 +02:00
Jannis Braun
1c962ded12
feat(auth): attach-proof mint endpoint for detached-account re-attach (re-attach spec §3.1)
2026-07-03 01:41:08 +02:00
Jannis Braun
669d80d7c7
feat(federation): federation_attach_proofs table (re-attach spec §3.1)
2026-07-03 01:36:30 +02:00
Jannis Braun
a0238eabc2
feat(federation): startup sweep removes dead-incarnation channels and self-homed stubs (dead-incarnation spec §3.4)
2026-07-03 01:05:26 +02:00
Jannis Braun
3591773a4c
feat(federation): deleted flag on wire profile snapshots — tombstone markers never leave the instance (dead-incarnation spec §3.3)
2026-07-03 00:59:37 +02:00
Jannis Braun
5ffc7c565e
feat(federation): sync endpoint scopes friend events to the requesting peer, pagination-safe (dead-incarnation spec §3.2)
2026-07-03 00:50:31 +02:00
Jannis Braun
bd40058613
feat(federation): sync endpoint scopes DM channels to the requesting peer (dead-incarnation spec §3.2)
2026-07-03 00:42:02 +02:00
Jannis Braun
99c8361b75
feat(federation): receiver guard — never create replicated stubs homed at our own domain (dead-incarnation spec §3.1)
2026-07-03 00:37:27 +02:00
Jannis Braun
54ab660204
feat(federation): near-instant reset detection — probe epoch at the auth-failure transition + on worker startup
...
A reset peer reaches needs_attention via the auth-failure path (HMAC desynced by
the new incarnation) without passing through unreachable, so the 5s recovery
probe never saw it — detection waited up to a full 15-min health-check cycle
before 'Re-peer & heal' surfaced. Extract detectResetForPeer() and fire it
event-driven at the transition, plus a startup sweep for already-stuck peers.
15-min tick remains the backstop.
2026-07-02 20:10:35 +02:00
Jannis Braun
13d050c1bb
fix(federation): close detached-account gaps from final review — presence/hydrate guards, ack re-detect clear, self-delete password (detach spec §4.3/§4.4/§4.6)
2026-07-02 19:34:32 +02:00
Jannis Braun
172398171a
docs(systems): finish detach consolidation — federation.md §6.3b, database.md, stale comments (detach spec §8)
2026-07-02 19:15:24 +02:00
Jannis Braun
9e917d5117
feat(federation): account-settings notice for detached accounts (detach spec §4.7)
2026-07-02 19:10:35 +02:00
Jannis Braun
5ad8aefaff
feat(federation): reset-cleanup panel — informational detach copy, real server-side Dismiss, Keep removed (detach spec §4.6)
2026-07-02 19:06:21 +02:00
Jannis Braun
42ad5e141d
feat(federation): server-side acknowledge for reset events (acknowledged_at + admin endpoint) (detach spec §4.6)
2026-07-02 18:59:33 +02:00
Jannis Braun
7e1e32de69
feat(federation): detached accounts get local profile+password self-service; self-view flag (detach spec §4.4, §4.7)
2026-07-02 18:54:37 +02:00
Jannis Braun
ea66ec5dbd
test(federation): pin registration 409 + suffixed stub creation against detached accounts (detach spec §4.3.5)
...
Also add the positive companion assertion (folded in from a Task 3 review
Minor): findFederatedUser tier-2 STILL returns a NON-detached (orphaned=0)
same-name federated row, locking that the eq(federation_home_orphaned, 0)
clause discriminates on the flag alone and never over-filters legitimate
replicated identities.
All three behaviors pass against the shipped Task 1-3 code; no product-code
change was required.
2026-07-02 18:47:29 +02:00
Jannis Braun
68be2e26b1
feat(federation): S2S surfaces exclude detached accounts — tier-2, profile_update, identity delete (detach spec §4.3)
2026-07-02 18:39:54 +02:00
Jannis Braun
d37919b5a0
feat(federation): reset heal detaches real accounts instead of freeze+rename (detach spec §4.2)
2026-07-02 18:33:47 +02:00
Jannis Braun
79c1138813
feat(federation): detached accounts keep local-password login; self-heal permanently disabled (detach spec §4.1)
2026-07-02 18:28:55 +02:00
Jannis Braun
1629f8fbe1
fix(dm): enforce read-only guard on DM reactions (WS) + harden purge/ownership tests
...
Finding 1: handleReactionAdd/Remove now drop reactions on a dead 1-on-1
(isDeadOneOnOne) — previously a survivor could react on a Deleted-User
thread and the relay fanned out to all peers via undefined target-origins.
Client Message.tsx withdraws add/toggle reaction affordances for dead DMs
(existing reactions still display read-only).
Finding 2: dmMembership purge test now runs with foreign_keys=ON (matches
prod) and asserts dm_members/dm_messages cascade cleanup on channel purge.
Finding 3: tombstone group-DM ownership transfer filters isDeleted=0 so
ownership can never move to a tombstoned member; covered by a new test.
2026-07-02 16:45:44 +02:00
Jannis Braun
3da18bc87c
test(dm): cover zero-other and mixed-others branches of isDeletedPartnerDm
2026-07-02 16:22:44 +02:00
Jannis Braun
ae07ae66e4
feat(dm): read-only composer notice for Deleted-User 1-on-1 threads (C2)
2026-07-02 16:20:38 +02:00
Jannis Braun
2a0574ee6c
test(dm): lock Deleted-User name resolution + updateUserEverywhere DM patch (C1)
2026-07-02 16:02:44 +02:00
Jannis Braun
a380927e72
test(dm): assert JOIN users guard drops orphan author in DM membership backfill (S5 review)
2026-07-02 16:00:19 +02:00
Jannis Braun
3470bb1914
fix(dm): idempotent backfill restores pre-existing broken Deleted-User 1-on-1 threads (S5)
2026-07-02 15:54:46 +02:00
Jannis Braun
d03f8e4f77
fix(federation): heal path broadcasts user_updated so tombstoned-stub DMs update live (S4)
2026-07-02 15:50:08 +02:00
Jannis Braun
3ebdd048bd
feat(dm): read-only guard blocks message create/edit/delete in a Deleted-User 1-on-1 (S3)
2026-07-02 15:47:18 +02:00
Jannis Braun
12d8256f65
fix(dm): purge DMs with zero live members (exclude-uid, scoped) so dead-both threads clean up (S2)
2026-07-02 15:37:33 +02:00
Jannis Braun
e5a1cc9506
fix(dm): keep 1-on-1 dm_members on tombstone, drop only group membership (S1)
2026-07-02 15:32:04 +02:00
Jannis Braun
6926bdb8f8
fix(federation): /peer/initiate handles needs_attention/awaiting_approval/rejected rows instead of 500ing
2026-07-02 13:29:46 +02:00
Jannis Braun
cd28c0336c
refactor(federation): store verified epoch as peer baseline; drop redundant assertion
2026-07-02 13:07:35 +02:00
Jannis Braun
ad7c86e89e
fix(web): Re-peer surfaces incomplete outcome instead of false success (BUG-2)
2026-07-02 13:03:03 +02:00
Jannis Braun
c6f0e6f25d
fix(federation): initiator handles 409 + verifies handshake before activating (BUG-1b/BUG-2)
2026-07-02 12:56:26 +02:00
Jannis Braun
edcb4cb72a
fix(federation): /peer/accept returns honest 409 instead of false 200 for existing peer (BUG-1a)
2026-07-02 12:40:16 +02:00
Jannis Braun
442811e600
test(federation): reproduce handshake desync BUG-1/BUG-2 over real handshake (RED) (BUG-0)
...
#1 control passes (harness validated); #2 fails (200 vs expected 409 — false success);
#4 fails (s2sHealthy false — Re-peer reports success on dead peering). Turned green by the fixes.
2026-07-02 12:32:09 +02:00
Jannis Braun
085670cff3
fix(federation): handshake sourceOrigin honors PUBLIC_ORIGIN (align with S2S auth origin)
2026-07-02 12:31:02 +02:00
Jannis Braun
aa7bf5b532
test(federation): real-handshake two-instance harness helpers (BUG-0)
2026-07-02 11:51:54 +02:00
Jannis Braun
df1e457971
feat(federation): add needs_attention_reason 'repeer_incomplete' (BUG-2 prep)
2026-07-02 11:46:10 +02:00
Jannis Braun
fd0ff4d199
fix(federation): clear federation_home_orphaned on tombstone (BUG-5)
2026-07-02 11:42:48 +02:00
Jannis Braun
6de14b281b
fix(federation): friend-add returns graceful 503 instead of 500 on peer lookup failure (BUG-3)
...
lookupRemoteUser now maps peer HTTP failures (403/5xx, malformed body) to a
structured {ok:false,reason:'unreachable'} instead of throwing, and the
federated friend-add wraps the call in try/catch as defense-in-depth. A
desynced/unreachable peer no longer surfaces as a raw 500 on a user action.
README.md left unstaged.
2026-07-02 11:23:08 +02:00
Jannis Braun
43d1dad1d7
fix(federation): carry error body on HttpError so Reset-cleanup owns-spaces copy reaches the UI
...
Also narrow SanitizedPeer.needsAttentionReason to the shared union.
2026-07-02 02:19:13 +02:00
Jannis Braun
be7749b83f
fix(federation): scope Reset-cleanup Remove owns-spaces detection to ownedSpaces payload
2026-07-02 02:01:50 +02:00
Jannis Braun
946255c4a1
feat(federation): admin Reset cleanup UI (Re-peer + Keep/Remove)
2026-07-02 01:57:30 +02:00
Jannis Braun
9d00cf024a
feat(federation): client handler for federation_peer_reset_detected
2026-07-02 01:51:18 +02:00
Jannis Braun
290cd606c0
feat(federation): GET /reset-events admin endpoint + types
2026-07-02 01:47:58 +02:00
Jannis Braun
ee52ff0c7b
feat(federation): expose needsAttentionReason on peer API
2026-07-02 01:43:12 +02:00
Jannis Braun
732d146396
feat(federation): quarantine real accounts on reset heal (freeze + free-handle)
2026-07-02 01:39:26 +02:00