fed-sx-m2: Step 11b — Announce + Endorse projection folds + 19 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 20s

Two new projection modules for the rich verbs landed in Step 11a:

  next/kernel/announce_state.erl
    Per-target-Cid announcer set.
    State: [{TargetCid, [AnnouncerActorId, ...]}, ...]
    Set semantics — duplicate Announce by the same actor on the
    same target is a no-op.

    Public API:
      new/0, fold/2, fold_fn/0
      announcers_for/2, announce_count/2, announced_cids/1
      has_announced/3

  next/kernel/endorsement_state.erl
    Per-target-Cid + per-kind + per-actor endorsement counter.
    State: [{TargetCid, [{Kind, [{ActorId, Count}, ...]}, ...]}, ...]
    Additive semantics — re-endorse by the same actor under the
    same kind bumps the counter. Undo{Endorse} retraction defers
    to a follow-up.

    Public API:
      new/0, fold/2, fold_fn/0
      counters_for/2, total_for/2, kinds_for/2
      endorsers_for/3, has_endorsed/4

Both fold_fn/0 returns a 2-arity Erlang fun for
projection:start_link/3 (same plug shape as actor_state /
follower_graph / delivery_state). Non-matching activity types
pass through unchanged.

Read-side accessors cover both enumeration (announcers_for,
endorsers_for) and predicates (has_announced, has_endorsed) so
the feed/timeline projection layer doesn't have to re-implement
that logic on every consumer.

19/19 in next/tests/rich_verbs.sh:

  announce_state:
    - new/0 -> []
    - Announce -> announcer added
    - Two announces same target -> both in set
    - Duplicate announce by same actor -> no-op
    - announce_count + announced_cids
    - has_announced predicate
    - fold_fn/0 is fun/2
    - Non-Announce activity passes through

  endorsement_state:
    - new/0 -> []
    - Endorse -> counter 1
    - Two likes by different actors -> total 2
    - like + share -> two kinds tracked
    - endorsers_for(Cid, Kind)
    - has_endorsed predicate
    - fold_fn/0 is fun/2
    - Non-Endorse activity passes through
    - Same actor endorsing twice -> total = 2 (additive)

Conformance preserved at 761/761.
This commit is contained in:
2026-06-07 05:06:27 +00:00
parent 80f6fc9279
commit b2b61a0112
4 changed files with 390 additions and 0 deletions

View File

@@ -726,6 +726,22 @@ re-broadcast another actor's content to their own followers.
**Deliverables:**
- [x] **11b** — Projection folds for the new verbs.
- `next/kernel/announce_state.erl`: tracks per-Cid announcer
set. Public API `new/0`, `fold/2`, `fold_fn/0`,
`announcers_for/2`, `announce_count/2`,
`announced_cids/1`, `has_announced/3`. Set semantics
(duplicate Announce by same actor is a no-op).
- `next/kernel/endorsement_state.erl`: tracks per-Cid +
per-kind + per-actor endorsement counters. Public API
`new/0`, `fold/2`, `fold_fn/0`, `counters_for/2`,
`total_for/2`, `kinds_for/2`, `endorsers_for/3`,
`has_endorsed/4`. Additive semantics (re-endorse by same
actor under same kind bumps the counter; Undo{Endorse}
semantics defer to a follow-up).
Both `fold_fn/0`s plug into `projection:start_link/3`. 19/19
in `rich_verbs.sh` covering happy paths + predicates + non-
matching-activity pass-through.
- [x] **11a** — Announce + Endorse genesis activity-types
(Note already exists as an object-type from M1 — Create{Note}
is the publish path). Two new `DefineActivity` SX files in
@@ -994,6 +1010,20 @@ proceed.
Newest first.
- **2026-06-07** — Step 11b: projection folds for the new verbs.
Two new modules in `next/kernel/`:
`announce_state.erl` (per-Cid announcer-set fold, set
semantics) and `endorsement_state.erl` (per-Cid + per-kind
+ per-actor counter, additive semantics). Both follow the
same plug shape as `actor_state` / `follower_graph` /
`delivery_state`: `fold_fn/0` returns a 2-arity Erlang fun
for `projection:start_link/3`. Non-matching activities pass
through unchanged. Read-side accessors cover both
enumeration (announcers_for / endorsers_for) and predicates
(has_announced / has_endorsed) so the feed/timeline layer
doesn't have to re-implement that logic. 19/19 in
`rich_verbs.sh`. Conformance preserved at 761/761.
- **2026-06-07** — Step 11a: Announce + Endorse genesis
activity-types. Two new DefineActivity SX files in
`next/genesis/activity-types/`: announce.sx (`:object` is a