Skip to content

Feat/social layer orchestration#9

Merged
JamesKane merged 8 commits into
mainfrom
feat/social-layer-orchestration
Jun 20, 2026
Merged

Feat/social layer orchestration#9
JamesKane merged 8 commits into
mainfrom
feat/social-layer-orchestration

Conversation

@JamesKane

Copy link
Copy Markdown
Owner

No description provided.

JamesKane and others added 8 commits June 19, 2026 15:35
Bring the dormant mig-0009 social.* schema live as a focused team↔tester
communication layer (support threads + announcements + community feed),
not a standalone social-media silo.

- mig 0041: ALTER conversation (kind/status/per-side read marks), message
  (from_team), feed_post (kind/topic/parent/pinned) — reuse, no recreate
- du_db::social: thread lifecycle, feed, blocks, reputation, unread counts,
  + canonical signed Edge messages
- Team web: /curator/inbox triage (HTMX two-panel) + /curator/announcements
- Member web: /messages + /feed (auth::User extractor; reputation/block gates)
- Edge API: signed /api/v1/social/* for the Navigator (verify_signed + DID
  bridge into ident.users; ownership-isolated reads)
- Navbar lazy unread badges (member + curator)

Identity DID-bridged into ident.users; central plaintext is justified as
operator (not citizen↔citizen P2P) communication. Tests run on ephemeral
DBs so mig 0041 is validated in-sequence with all 41 migrations.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Scope the rest of the social plans now that the team↔tester core is live:
- planning/social-layer-roadmap.md — Tier 1 (reputation engine, feed
  voting/moderation, block UX), Tier 2 (notifications + SYSTEM rail,
  group-project social surface on the D5 ACL), Tier 3 (peer DMs over D1,
  federated feed, recruitment — all kept). Records the locked scoping
  decisions (DID bridge, central-plaintext-for-operator-comms, team=role).
- Update the forward headers on Messaging/Reputation/group-project proposals
  to point at the roadmap and note what's now built.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make the social core self-standing and quality-gated (roadmap Tier 1).

- Reputation engine (mig 0042 + du_db::reputation): record_event (ledger +
  atomic score, points override for vote deltas), record_once (idempotent
  one-time bonus), score_of/at_least/can_post_to_feed guard. Award hooks:
  NEW_USER_BONUS at login/OAuth/Edge, ACCOUNT_VERIFIED at OAuth. Replaces the
  MIN_FEED_REPUTATION stub.
- Feed voting + moderation (mig 0043 feed_vote/feed_report): up/downvote with
  toggle drives author reputation; report -> /curator/moderation queue; spam
  verdict docks the author (SPAM_REPORT_VALIDATED) and soft-deletes.
- Block UX: /feed block button (community only) + /blocks manage page; team
  announcements are never block-filtered.

Tests: du-db tests/reputation.rs + voting/moderation in tests/social.rs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Generalize the unread infrastructure into a notification model and provide the
rail the collaboration flows write into (roadmap Tier 2a).

- mig 0044 social.notification + du_db::notification: notify/notify_system
  (self-notify skipped), list/unread_count/mark_read (recipient-scoped)/
  mark_all_read.
- Producers folded into du_db::social: team reply -> THREAD_REPLY to the
  requester; feed reply -> FEED_REPLY to the parent author.
- Web: navbar bell (lazy badge) + /notifications (open marks read + deep-links;
  read-all).
- Signed Edge: GET /api/v1/social/notifications + POST .../notifications/read.
- notify_system (actor=NULL) is the entry point IBD/match-consent + D4 will call.

Tier 2b (group-project social surface) assessed BLOCKED — no project-create path
(projects come from unbuilt Navigator groupProject ingest) + DID/UUID impedance;
documented in the roadmap, deferred pending a decision.

Tests: du-db tests/notification.rs + edge notification round-trip.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ate)

Unblock the group-project surface with a web project-create flow (the prior
blocker was that projects only existed in tests).

- du_db::research: create_project/get_project/projects_for_member + ProjectRow;
  du_db::auth: did_of / display_name_by_did (bridge the session UUID into the
  DID-keyed D5 ACL).
- routes/projects.rs (session-authed): /projects list, /projects/new + create
  (owner becomes founding ADMIN), /projects/:id detail with a members-only feed
  + roster + admin member management on the built D5 ACL. Accounts without a DID
  get a "needs AT-Proto account" notice.
- Project feed = feed_post kind=PROJECT, topic=project:<id> — isolated from the
  global community feed; membership-gated (not reputation-gated).

Projects will also arrive via Navigator groupProject ingest later; this is the
bridge until then.

Tests: du-db tests/projects.rs (create/membership/feed isolation) + du-web gating.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Close the orchestration loop: the D1 encrypted-exchange broker (mig 0032
exchange.*) already relays ciphertext (request -> dual consent -> session ->
blind relay_envelope); wire it into the 2a notification rail so the partner is
actually alerted.

- routes/exchange.rs: a fresh exchange request -> notify_system(partner) with a
  purpose-aware title (IBD match / genealogy-PII DM / generic); dual consent ->
  notify the other party. Partner DID bridged into ident.users for the
  (UUID-keyed) notification.
- du_db::exchange::create_request returns inserted-bool so re-sends don't
  re-notify.

This is the real D1 producer for the SYSTEM rail and serves both peer DMs and
IBD-match consent. The AppView stays a blind ciphertext relay; the crypto + DM
UI remain Navigator-side (it can't render ciphertext, by design). No central
plaintext — invariant held.

Tier 3b (federated feed) + 3c (recruitment) remain gated on cross-repo/Edge work.

Tests: extended the exchange route test (partner receives a SYSTEM notification).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ingest member-published com.decodingus.atmosphere.feed.post records and merge
them into the community feed (read-only), following the fed.* Jetstream pattern.

- mig 0045 fed.feed_post mirror + du_db::fed::feed (upsert time_us-guarded /
  recent).
- NS_FEED_POST added to INGEST_COLLECTIONS + table_for; du-jobs build_feed_post
  reads the top-level createdAt + reply.{root,parent}.uri.
- Web /feed interleaves federated + central community posts by recency; federated
  posts are read-only with a "via Atmosphere" badge. Edge feed returns a
  `federated` array.
- Lexicon documented in documents/atmosphere/10-Feed-Records.md.

AppView-side only: Navigator must publish feed.post records (the mirror is empty
until it does). Read-path follow-ups: cross-author reply threading +
federated-author block-filtering. Tier 3c (recruitment) remains.

Tests: du-db tests/fed_feed.rs + jetstream build_feed_post unit test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ker)

The last roadmap piece: a project researcher recruits a genetic cohort without
ever receiving it — the AppView brokers invitations and only opt-ins become
visible.

- mig 0046 research.recruitment_campaign + recruitment_target; du_db::recruitment
  (create_campaign, compute_cohort from fed.biosample by haplogroup/lineage with
  self-exclusion, deliver, respond, campaigns_for_project, accepted_dids,
  target_status, invitations_for).
- routes/recruitment.rs (session+DID): /projects/:id/recruit (admin + RECRUIT_MIN
  reputation gated) computes the cohort and delivers invitations via the
  notification rail; /recruitment/:id invitation accept/decline; accept notifies
  the researcher.
- INVARIANT: the researcher sees aggregate counts + opt-ins only — invited/declined
  DIDs are never surfaced (same "never materialize everyone" stance as IBD).

All three Tier-3 pieces are now built on the AppView side; remaining work is
Edge/cross-repo (Navigator crypto + feed.post publishing).

Tests: du-db tests/recruitment.rs (cohort/exclusion/opt-in privacy) + du-web gating.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JamesKane JamesKane merged commit 1ccd3cd into main Jun 20, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant