Files
amethyst/commons
Vitor PamplonaandClaude Opus 4.8 4ec44ad241 feat(concord): harvest full member roster from bounded channel history
The members roster was a fraction of the real membership (e.g. ~13 vs ~44 on
Armada). Concord membership includes every "observed author" (CORD-02 §5 — anyone
seen publishing), but the live channel subs only carry the recent tail the relay
serves, so most members — who posted outside that tail and never sent a Guestbook
Join — never appeared.

Add ConcordMemberHarvest: a headless, run-once background sweep mounted by the
members screen that pages every folded channel's history back to a bounded window
(90 days — tunable; bounds the data pulled onto the device, per the "how far back"
limit) in one pooled `fetchAllPagesFromPool`. The wraps ride the app's normal ingest
(global CacheClientConnector → concordSessions.ingest), which folds each author into
`observedAuthors`, so the roster fills in with no extra plumbing. AUTH is free — the
channel stream keys are already registered for these relays. `beginMemberHarvest()`
gates it to once per community.

Prerequisite fix: `ConcordCommunitySession.ingest` re-decrypted a channel's WHOLE
wrap buffer on every incoming message (reprojectChannel), which is O(n²) in the
message count — fine for a ~50-wrap live tail but fatal for a history sweep. Split
it: a message now projects only its own wrap (O(1)); the re-decrypt-all path stays
for a re-fold (where channel keys can change). This also speeds the live path.
`ConcordCommunitySessionTest` now asserts the one-wrap-per-message projection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 21:58:48 -04:00
..