fed-sx-m2: Step 7a — delivery:delivery_set/2,3 + 17 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 44s

New next/kernel/delivery.erl computes the audience-resolved
deduplicated recipient list for an outbound activity.

delivery_set/2(Activity, KernelState)
delivery_set/3(Activity, KernelState, FollowerGraph)
  Returns a deduplicated list of ActorId atoms. Step 8 will
  resolve each entry to {PeerInstanceUrl, ActorId} via the
  peer-actors cache.

Sources unioned then deduped:
  - :to field   (single ActorId or list, atoms or audience symbols)
  - :cc field   (same shape)
  - audience-symbol expansion:
      followers -> sender's followers from follower_graph
      public    -> [] for v2 (Step 7b layers known-peer-instance set)

Self-delivery suppressed every time the sender's ActorId appears
in the set.

Module lives in its own file (not inside outbox.erl) so Step 8's
delivery-queue gen_server has a clean home alongside it.

17/17 in next/tests/delivery_set.sh covering:
  - empty activity -> []
  - single :to atom + list :to recipients
  - :to + :cc unioned
  - self-suppression
  - duplicate / cross-field dedup
  - followers symbol expands via follower_graph state
  - empty follower-graph -> []
  - public v2 placeholder -> []
  - mixed explicit + followers
  - collect_recipients raw flat
  - suppress_self drops every match
  - dedup preserves first-occurrence order
  - expand_audience pass-through for plain ActorId

Conformance 761/761. 86/86 across 6 Step-7-adjacent suites
(follower_graph, follow_lifecycle, auto_accept, inbox,
nx_kernel_multi, outbox_publish).
This commit is contained in:
2026-06-06 23:34:18 +00:00
parent ee8a396ccd
commit 086c576d48
3 changed files with 276 additions and 16 deletions

View File

@@ -478,22 +478,30 @@ expansion via the audience predicates from M1's genesis bundle.
**Deliverables:**
- `outbox:delivery_set/2(Activity, KernelState) -> [InboxUrl]`.
- Public expansion: every known peer instance's shared inbox (or every
follower of the publishing actor — both modes supported).
- Followers expansion: follower-graph lookup.
- Self-delivery suppression (don't POST to your own inbox).
- Returns a list of `{PeerInstanceUrl, ActorId}` tuples.
**Tests:**
- Activity with `:to: [bob]` → delivery set is bob's inbox.
- Activity with `:to: [Followers]` → set is current followers' inboxes.
- Activity with `:to: [Public]` → set is public reach.
- Self-deliveries excluded.
- Empty audience → empty set.
**Acceptance:** `bash next/tests/delivery_set.sh` passes 12+ cases.
- [x] **7a** — `delivery:delivery_set/2,3` returns the
audience-resolved deduplicated list of ActorId atoms for an
outbound activity. Sources: explicit `:to` and `:cc` fields
(atom or list of atoms / audience symbols), plus expansion of
`followers` (via follower_graph) and `public` (v2 placeholder
— Step 7c). Self-delivery is suppressed every time the
sender's ActorId appears in the set. Returns are ActorId
atoms for now; Step 8 will resolve each entry to
`{PeerInstanceUrl, ActorId}` via the peer-actors cache. 17
cases in `delivery_set.sh` covering empty / single / list /
cc-union / self-suppress / dedup / followers-expand /
public-empty / mixed audience / collect_recipients +
suppress_self + dedup helpers + expand_audience pass-through.
Module lives in `next/kernel/delivery.erl` (separate from
outbox so Step 8's delivery-queue gen_server has a clean home).
- [ ] **7b** — Public expansion: when Cfg or KernelState carries
a known-peer-instance set, `public` expands to one entry per
peer instance for the public-reach broadcast (Mastodon's
shared inbox per-instance pattern). v2 ships the empty case
via 7a so callers don't have to special-case the symbol.
- [ ] **7c** — Outbox-side integration: `outbox:publish/2`
computes the delivery set after sign + log and stashes it in
the Result proplist as `{delivery_set, [ActorId, ...]}`. Step
8's delivery-queue worker reads it off the publish result.
---
@@ -837,6 +845,20 @@ proceed.
Newest first.
- **2026-06-06** — Step 7a: audience-resolving delivery set.
New `next/kernel/delivery.erl`: `delivery_set/2,3(Activity,
KernelState[, FollowerGraph])` returns a deduplicated list of
ActorId atoms — the targets an outbound activity needs to be
POSTed to. Sources: `:to` and `:cc` fields (single atom or
list, atoms or audience symbols), plus expansion of `followers`
via the supplied follower_graph state. `public` placeholder
returns `[]` for v2; Step 7b will populate via a known-
peer-instance set. Self-delivery suppressed. ActorIds for now —
Step 8 resolves each entry to `{PeerInstanceUrl, ActorId}` via
peer-actors cache. 17/17 in `delivery_set.sh`. Conformance
761/761. Lives in its own module (not inside `outbox`) so the
Step 8 delivery-queue gen_server has a clean home.
- **2026-06-06** — Step 6c (closes Step 6): auto-Accept publish on
Follow ingestion. New `maybe_auto_accept/3` in `http_server.erl`
fires after successful inbox append + projection broadcast: