Skip to content

feature(sdk) + docs(kb): curateAds — the D51 ad-dissemination helper (3.26.0) - #704

Open
jacoby149 wants to merge 1 commit into
devfrom
jacoby149/ads-tracking-round-robin-greedy
Open

feature(sdk) + docs(kb): curateAds — the D51 ad-dissemination helper (3.26.0)#704
jacoby149 wants to merge 1 commit into
devfrom
jacoby149/ads-tracking-round-robin-greedy

Conversation

@jacoby149

Copy link
Copy Markdown
Owner

What

The ads lane's second foundation: the curateAds D51 helper — the per-creator choice of how their ads get mixed into a viewer's feed, as a shared, deterministic SDK helper (not SQL).

The stateful algorithms (round-robin needs "which ad showed last," greedy needs performance numbers) don't belong in a query, and being pure + shared means every app curates a given creator's ads identically from the same inputs.

The helper

curateAds(creatorAds, setting, state)  the ordered active subset to show

The caller takes the first entry for a single post (the composer's "Rotate my ads") or the whole list for a curated-subset surface. Four modes:

mode behavior needs metrics?
round_robin rotate past lastShownDocId, wrap-around no (app-local state)
pinned just the creator's pick no
frequency_capped drop ads already shown cap× this session no (app-local counts)
greedy order by performance, highest first yes

Filters on body.status (an ad is showable unless paused — status defaults to active). The active set is canonically ordered by doc_id first, so the output is independent of the order the ads arrive in (pinned by a determinism test).

The v0 greedy gap (operator-surfaced)

greedy weights by offer performance, but the v0 ad object carries no stats (D55 — a counter is a write on a read path; impression/revenue verification is the v4 layer). So with no performance supplied, greedy degrades to round_robin (equal exposure — no ad starved) and becomes true greedy the instant the v4 metrics layer feeds per-ad scores into state.performance. The other three modes need no metrics at all.

This is documented in the KB (ads.md Dissemination section) so it's not a silent lie.

Notes

  • New: sdk/src/curate.ts (+ curate.test.ts), exported from index.ts; dist/ rebuilt.
  • 110 SDK tests green (22 new), typecheck + build clean.
  • Gates the composer's rotation + any curated-subset surface.

KB: knowledge/knowledge-base/web10-v3/social/ads.md (Dissemination) + ads-catalog.md.

…(3.26.0)

The per-creator choice of how their ads get mixed into a viewer's feed is a
shared, deterministic SDK helper, not SQL. sdk/src/curate.ts exports
curateAds(creatorAds, setting, state) → the ordered active subset to show,
with four modes: round_robin (rotate past lastShown), pinned (the creator's
pick), frequency_capped (drop ads shown cap× this session), and greedy
(order by performance). Filters on body.status (showable unless paused).
Canonical doc_id ordering makes the output independent of input order
(pinned by a determinism test).

The v0 greedy gap (operator-surfaced): greedy weights by offer performance,
but the v0 ad object carries no stats (D55). So with no performance supplied,
greedy degrades to round_robin (equal exposure — no ad starved) and becomes
true greedy the instant the v4 metrics layer feeds performance in. KB
ads.md Dissemination section updated (signature + the degradation note).

110 SDK tests green (22 new), typecheck + build clean.
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