Editorial
The editorial module is where the platform’s thesis becomes code. Five editorial constraints — topical diversity, recency / freshness, sentiment balance, editorial promotion, and sensitive-topic guard — applied to a candidate set through the ranker.
The ranker is the platform’s headline deep module: a pure function from
(candidate_set, constraint_configuration) to a ranked list of articles.
That’s the entire interface. Everything else in the module is in service of
making that function trustworthy, testable, and editorially defensible.
What the code looks like
Section titled “What the code looks like”The ranker lives at
tutorial/serving/src/serving/ranker.py.
It is dependency-free — no database connection, no HTTP framework, no
filesystem. That isolation is deliberate (ADR-0010
explains why) and is what makes the test suite
fast and exhaustive: every config, every constraint, every edge case
covered with seeded inputs.
The sensitive-topic detector is its own deep module:
- Code:
tutorial/serving/src/serving/sensitivity.py - Tests:
tutorial/serving/tests/test_sensitivity.py - dbt-side enrichment:
article_sensitivity.py
The editorial configuration is a table, not code:
constraint_configurations.sql.
That table is what the editor interface reads and writes, and it is part of
the analytical contract analysts can query directly.
Hard rules vs soft weights
Section titled “Hard rules vs soft weights”The mixed-enforcement model (ADR-0010) refuses the temptation to make every editorial concern a numeric preference.
Soft constraints (weighted into a score):
- Topical diversity — anti-overlap with already-ranked articles in the list
- Recency / freshness — exponential decay against article age, half-life tunable
- Sentiment balance — Wasserstein-style penalty against a target sentiment distribution; degrades gracefully when sentiment scores are absent
Hard rules (applied after sorting):
- Editorial promotion — articles in the always-include list are inserted at their target positions, period
- Sensitive-topic guard — a hard cap on the share of sensitive articles per list, dropping from the bottom until the cap holds
A promoted investigation cannot vanish into a low weight. A sensitive-topic cap cannot be overridden by a high relevance score. That asymmetry is the editorial promise this module makes.
The full math is documented
Section titled “The full math is documented”ADR-0015 spells out the exact formulas: the score combination, each soft-term shape, the configuration schema, and the defaults. Anyone reading the ranker code can compare line-for-line against the ADR.
After this module
Section titled “After this module”The ranker is consumed by serving through /recommendations/
and /preview endpoints. The editor module gives editors
sliders + toggles + an always-include list management UI that all read and
write the constraint_configurations table the ranker references. The
evaluation module sweeps configurations and produces the
Pareto chart that makes the editorial-cost-of-clicks argument visible.