linkedin-studio/references/trend-scoring-modes.md
Kjell Tore Guttormsen 2a8459c674 feat(linkedin-studio): RE-R3d — temporal overlay (first-mover + saturation) [skip-docs]
R3 slice (b): the rest of hull #3. The morning brief now reads the temporal axis
the R3b seen-log records but the ranking ignored. Two DERIVED signals, computed at
brief time from already-persisted fields (publishedAt/capturedAt -> ageDays,
surfacedCount), never stored:

- first-mover: recent (ageDays <= --first-mover-days, default 2) AND never surfaced
  on a prior day -> ranked up, badge "first ute". Future-dated (ageDays<0) excluded.
- saturation: surfaced on >= --saturation-at (default 3) prior days -> ranked down,
  badge "mettet (Nx)". Self-surfacing (our seen-log), not market coverage.
- warming (1..at-1) keeps the R3b "sett Nx" badge but only at >=2 (contract intact);
  neutral carries no badge.

SB1 derived (no schema bump: SCHEMA_VERSION 4 / BRIEF_SCHEMA_VERSION 1 untouched).
SB2 the R3a relevance composite stays the PRIMARY sort key; the temporal rank is a
new cmp key after pillar-overlap, before effectiveDate -> re-orders only WITHIN a
(composite, overlap) tier. temporalSignal is pure (saturationAt clamped >=1).

Prior-day surfacings exclude today (via lastSurfacedAt), so a same-day re-render is
byte-identical (caught by the R3c run-daily SC7 regression; fixes a latent R3b
prior-day imprecision too). brief CLI gains --first-mover-days / --saturation-at;
schedule untouched (nightly uses defaults).

Wiring: trend-spotter.md (prose), trend-scoring-modes.md (one-line consumer note),
README (## Temporal overlay), gate Section 16m (+6 unconditional -> ASSERT floor
111->117), TRENDS_TESTS_FLOOR 192->216. Counts 29/19/27 unchanged. Zero new files.

Gate: Passed 132 / Failed 0; trends 216/216; hook suite 139/139 untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011vmzxpsFpc8q19LaogAWLD
2026-06-26 12:10:42 +02:00

105 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Trend Scoring Modes Reference
**Single source of truth** for how a discovered trend/topic candidate is scored.
There are **two modes** — they share the same 110 per-dimension scale and the same
composite formula, but they weight the dimensions differently because a feed post and
a long-form chronicle reward different things. Surfaces (the `trend-spotter` agent, any
research-engine pass) **select a mode and apply the matching rubric** — they do not
restate the weights inline. Cite this file; do not duplicate it.
This file defines **methodology** (the weights), not user preference. The *source list*
a pass polls is separate and user-overridable — see
`config/trends-sources.template.md``${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/trends/sources.md`.
## How to read this file
- Score each dimension **110** (see the bands in the per-mode tables).
- Composite = the weighted sum of the five dimension scores. Each mode's weights sum to
**100 %**, so the composite stays on the same 010 scale across modes.
- The **ordering** of the weights is the signal; the exact percentages are a deliberate,
documented choice, not a measured coefficient. (Timing grounding — why a feed post
weights recency and a chronicle does not — traces to
`references/algorithm-signals-reference.md`; this file does not restate algorithm
magnitudes.)
## Mode selection
| Mode | Use for | Driver |
|------|---------|--------|
| **kortform** | feed posts (`/linkedin:post`, `:quick`, `:react`, `:carousel`, `:video`) | timing + audience pull — a good post published early beats a perfect post published late |
| **long-form** | chronicles / newsletters / series editions (`/linkedin:newsletter`) | depth + angle — a chronicle has a longer shelf life; whether there is *enough material for a full piece* matters more than a 24-hour window |
If no mode is declared, default to **kortform** (the feed is the higher-cadence surface).
A caller may pass the mode explicitly (e.g. the long-form orchestrator requesting
`long-form`); a future slice may read a per-user default from the profile.
## Mode: kortform (LinkedIn feed post)
Tuned for the feed: timing and audience pull carry real weight because the first-mover
window is short.
| Dimension | Weight | 12 (Low) | 35 (Medium) | 68 (High) | 910 (Exceptional) |
|-----------|--------|-----------|---------------|-------------|---------------------|
| **Pillar Fit** | 30 % | Outside all 5 pillars | Tangential to one pillar | Direct hit on one pillar | Intersects 2+ pillars |
| **Audience Relevance** | 25 % | Wrong audience entirely | Some audience overlap | Core audience cares | Audience actively asking about this |
| **Timing** | 20 % | >7 days old, saturated | 37 days, moderate coverage | 2472h, early coverage | <24h, you would be among first |
| **Angle Potential** | 15 % | Only obvious take available | One good angle possible | 23 strong angles | Contrarian or unique angle clear |
| **Authority Match** | 10 % | No credibility on topic | Some related experience | Direct experience | Published authority on this |
```
Composite = (Pillar × 0.30) + (Audience × 0.25) + (Timing × 0.20) + (Angle × 0.15) + (Authority × 0.10)
```
## Mode: long-form (chronicle / newsletter / series)
Reweighted for a longer piece: **depth potential** enters at 25 %, and **timing drops to
10 %** — a chronicle is not a 24-hour reaction, so recency matters less than whether the
topic has enough substance and a differentiated angle to carry a full edition.
| Dimension | Weight | 12 (Low) | 35 (Medium) | 68 (High) | 910 (Exceptional) |
|-----------|--------|-----------|---------------|-------------|---------------------|
| **Pillar / thesis fit** | 30 % | Outside the active theses | Tangential to one thesis | Fits one thesis / series arc | Advances 2+ theses or a live series arc |
| **Depth potential** | 25 % | A single post at most | Enough for one solid post | Enough for a full chronicle | Enough for a multi-part series |
| **Angle / differentiation** | 20 % | Commodity take only | One non-obvious angle | 23 differentiated angles | Original thesis the field lacks |
| **Authority / experience** | 15 % | No credibility on topic | Some related experience | Direct lived experience | Published authority on this |
| **Currency** | 10 % | Stale / already resolved | Relevant this quarter | Relevant now, durable | Relevant now AND will compound |
```
Composite = (Pillar × 0.30) + (Depth × 0.25) + (Angle × 0.20) + (Authority × 0.15) + (Currency × 0.10)
```
## Why the two modes differ (the one delta)
The two rubrics are the same five-dimension instrument with one deliberate swap:
- **kortform:** Timing **20 %**, no depth dimension — the feed rewards being early.
- **long-form:** Timing → Currency at **10 %**, Depth potential added at **25 %** — a
chronicle rewards substance and a durable angle over speed.
Pillar fit (30 %) and authority (kortform 10 % / long-form 15 %) anchor both: an off-pillar
or low-credibility topic scores low in either mode, because topic relevance and credibility
are non-negotiable regardless of format.
## Composite → action
The same priority bands apply to both modes (the composite is on the same 010 scale):
| Composite | Priority | kortform action | long-form action |
|-----------|----------|-----------------|------------------|
| 8.010 | **Immediate** | Draft within 24h | Promote to the edition backlog now |
| 6.07.9 | **High** | Publish within 4872h | Strong edition candidate — schedule it |
| 4.05.9 | **Medium** | Add to this week's calendar | Hold as a backlog candidate, revisit |
| 2.03.9 | **Low** | Note, skip for now | Park unless the angle sharpens |
| 01.9 | **Skip** | Off positioning | Off positioning |
## Consumers
- `agents/trend-spotter.md` — reads the requested mode and applies the matching rubric
instead of inlining a matrix (wired in research-engine slice 2b).
- Any future research-engine pass that scores candidates before writing them to the trend
store (`scripts/trends/`).
**Note (RE-R3d):** the morning brief applies a *brief-time* **temporal overlay** (first-mover /
saturation, derived from the publish/capture dates + the seen-log) as a **within-composite-tier**
ranking refinement. It is a separate layer from this file — it does **not** change the capture-time
dimension weights, bands, or composite formula above.