feed: verb-aware smart dedupe — reactions collapse cross-actor, posts stay per-actor + 9 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 54s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 54s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,7 @@ if [ ! -x "$SX_SERVER" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
SUITES=(basic fanout rank integration content notify home)
|
SUITES=(basic fanout rank integration content notify home dedupe)
|
||||||
|
|
||||||
OUT_JSON="lib/feed/scoreboard.json"
|
OUT_JSON="lib/feed/scoreboard.json"
|
||||||
OUT_MD="lib/feed/scoreboard.md"
|
OUT_MD="lib/feed/scoreboard.md"
|
||||||
|
|||||||
@@ -46,11 +46,31 @@
|
|||||||
((a (get ev :activity)))
|
((a (get ev :activity)))
|
||||||
(list (get ev :to) (get a :actor) (get a :verb) (get a :object)))))
|
(list (get ev :to) (get a :actor) (get a :verb) (get a :object)))))
|
||||||
|
|
||||||
|
; verbs whose duplicates collapse across actors (reactions, not authorship).
|
||||||
|
; rebindable: callers can (set! feed/collapse-verbs ...) to tune the policy.
|
||||||
|
(define
|
||||||
|
feed/collapse-verbs
|
||||||
|
(list "like" "favourite" "follow" "boost" "repost"))
|
||||||
|
|
||||||
|
; per-verb key: collapse-verbs fold on (verb object); the rest key on
|
||||||
|
; (actor verb object).
|
||||||
|
(define
|
||||||
|
feed/smart-key
|
||||||
|
(fn
|
||||||
|
(a)
|
||||||
|
(if
|
||||||
|
(feed/-elem? (get a :verb) feed/collapse-verbs)
|
||||||
|
(feed/collapse-key a)
|
||||||
|
(feed/activity-key a))))
|
||||||
|
|
||||||
; --- ready-made dedupers ----------------------------------------------------
|
; --- ready-made dedupers ----------------------------------------------------
|
||||||
|
|
||||||
(define feed/dedupe-activities (fn (s) (feed/dedupe s feed/activity-key)))
|
(define feed/dedupe-activities (fn (s) (feed/dedupe s feed/activity-key)))
|
||||||
|
|
||||||
(define feed/dedupe-collapse (fn (s) (feed/dedupe s feed/collapse-key)))
|
(define feed/dedupe-collapse (fn (s) (feed/dedupe s feed/collapse-key)))
|
||||||
|
|
||||||
|
; verb-aware: reactions collapse cross-actor, posts stay distinct per actor
|
||||||
|
(define feed/dedupe-smart (fn (s) (feed/dedupe s feed/smart-key)))
|
||||||
|
|
||||||
; dedupe an inbox: at most one event per receiver per (actor verb object)
|
; dedupe an inbox: at most one event per receiver per (actor verb object)
|
||||||
(define feed/dedupe-inbox (fn (inbox) (feed/dedupe inbox feed/event-key)))
|
(define feed/dedupe-inbox (fn (inbox) (feed/dedupe inbox feed/event-key)))
|
||||||
|
|||||||
@@ -6,9 +6,10 @@
|
|||||||
"integration": {"pass": 22, "fail": 0},
|
"integration": {"pass": 22, "fail": 0},
|
||||||
"content": {"pass": 15, "fail": 0},
|
"content": {"pass": 15, "fail": 0},
|
||||||
"notify": {"pass": 8, "fail": 0},
|
"notify": {"pass": 8, "fail": 0},
|
||||||
"home": {"pass": 6, "fail": 0}
|
"home": {"pass": 6, "fail": 0},
|
||||||
|
"dedupe": {"pass": 9, "fail": 0}
|
||||||
},
|
},
|
||||||
"total_pass": 134,
|
"total_pass": 143,
|
||||||
"total_fail": 0,
|
"total_fail": 0,
|
||||||
"total": 134
|
"total": 143
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,4 +11,5 @@ _Generated by `lib/feed/conformance.sh`_
|
|||||||
| content | 15 | 0 | 15 |
|
| content | 15 | 0 | 15 |
|
||||||
| notify | 8 | 0 | 8 |
|
| notify | 8 | 0 | 8 |
|
||||||
| home | 6 | 0 | 6 |
|
| home | 6 | 0 | 6 |
|
||||||
| **Total** | **134** | **0** | **134** |
|
| dedupe | 9 | 0 | 9 |
|
||||||
|
| **Total** | **143** | **0** | **143** |
|
||||||
|
|||||||
56
lib/feed/tests/dedupe.sx
Normal file
56
lib/feed/tests/dedupe.sx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
; Follow-up — verb-aware (smart) dedupe. (feed-test name got expected)
|
||||||
|
|
||||||
|
; reactions (like/follow) collapse cross-actor; posts stay distinct per actor
|
||||||
|
(define
|
||||||
|
M
|
||||||
|
(feed/stream
|
||||||
|
(list
|
||||||
|
(feed/activity "alice" "like" "X" 1 (list))
|
||||||
|
(feed/activity "bob" "like" "X" 2 (list))
|
||||||
|
(feed/activity "alice" "post" "P" 3 (list))
|
||||||
|
(feed/activity "bob" "post" "P" 4 (list))
|
||||||
|
(feed/activity "alice" "follow" "C" 5 (list))
|
||||||
|
(feed/activity "bob" "follow" "C" 6 (list))))) ; collapses
|
||||||
|
|
||||||
|
(feed-test
|
||||||
|
"smart dedupe total"
|
||||||
|
(feed/count (feed/dedupe-smart M))
|
||||||
|
4)
|
||||||
|
(feed-test
|
||||||
|
"smart keeps both posts"
|
||||||
|
(feed/count (feed/by-verb (feed/dedupe-smart M) "post"))
|
||||||
|
2)
|
||||||
|
(feed-test
|
||||||
|
"smart collapses likes to one"
|
||||||
|
(feed/count (feed/by-verb (feed/dedupe-smart M) "like"))
|
||||||
|
1)
|
||||||
|
(feed-test
|
||||||
|
"smart collapses follows to one"
|
||||||
|
(feed/count (feed/by-verb (feed/dedupe-smart M) "follow"))
|
||||||
|
1)
|
||||||
|
(feed-test
|
||||||
|
"collapsed like keeps first actor"
|
||||||
|
(map feed/actor (feed/items (feed/by-verb (feed/dedupe-smart M) "like")))
|
||||||
|
(list "alice"))
|
||||||
|
|
||||||
|
; contrast: plain activity dedupe keeps cross-actor likes distinct
|
||||||
|
(feed-test
|
||||||
|
"activity dedupe keeps both likes"
|
||||||
|
(feed/count (feed/by-verb (feed/dedupe-activities M) "like"))
|
||||||
|
2)
|
||||||
|
|
||||||
|
; contrast: blanket collapse folds the two posts (same verb+object) too
|
||||||
|
(feed-test
|
||||||
|
"collapse dedupe folds posts"
|
||||||
|
(feed/count (feed/by-verb (feed/dedupe-collapse M) "post"))
|
||||||
|
1)
|
||||||
|
|
||||||
|
; smart-key dispatch
|
||||||
|
(feed-test
|
||||||
|
"smart-key reaction -> (verb object)"
|
||||||
|
(feed/smart-key (feed/activity "alice" "like" "X" 0 (list)))
|
||||||
|
(list "like" "X"))
|
||||||
|
(feed-test
|
||||||
|
"smart-key post -> (actor verb object)"
|
||||||
|
(feed/smart-key (feed/activity "alice" "post" "P" 0 (list)))
|
||||||
|
(list "alice" "post" "P"))
|
||||||
@@ -14,7 +14,7 @@ APL, ACL visibility filtering via `lib/acl/`, federation via fed-sx.
|
|||||||
|
|
||||||
## Status (rolling)
|
## Status (rolling)
|
||||||
|
|
||||||
`bash lib/feed/conformance.sh` → **134/134** (Phases 1–4 + TF-IDF + notifications + home)
|
`bash lib/feed/conformance.sh` → **143/143** (Phases 1–4 + TF-IDF + notifications + home + smart-dedupe)
|
||||||
|
|
||||||
## Ground rules
|
## Ground rules
|
||||||
|
|
||||||
@@ -147,6 +147,10 @@ are function parameters. Real acl-sx / fed-sx wire in at the call site unchanged
|
|||||||
- [x] **Capstone** `feed/home` — the whole pipeline as one line: fanout ∘ inbox ∘
|
- [x] **Capstone** `feed/home` — the whole pipeline as one line: fanout ∘ inbox ∘
|
||||||
dedupe ∘ ACL ∘ rank ∘ take (`home.sx`); 6 tests incl. per-viewer ACL + cross-post
|
dedupe ∘ ACL ∘ rank ∘ take (`home.sx`); 6 tests incl. per-viewer ACL + cross-post
|
||||||
dedupe. (134/134 total.)
|
dedupe. (134/134 total.)
|
||||||
|
- [x] Per-verb dedupe rules (briefing gotcha #3) — `feed/dedupe-smart` /
|
||||||
|
`feed/smart-key`: reactions (like/follow/boost/...) collapse cross-actor on
|
||||||
|
(verb,object); posts stay distinct per actor. `feed/collapse-verbs` is
|
||||||
|
rebindable policy; 9 tests. (143/143 total.)
|
||||||
|
|
||||||
(none)
|
(none)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user