timescale.info
Sign inSign up

How OpenChronology was built

Every merged pull request of openchronology/timeline-app, its first week of commits and its releases; and before them the 2020 PureScript editor, from snapshots of its deleted repositories in the Wayback Machine. Written to this server through the HTTP API.

327 moments · 2020-03-09T00:15:08Z CE – 2026-11-02T20:11:21Z CE · by @athan · @athan

#168 · Rank browsing by account standing; weigh popularity by who starred

  • timeline-app
  • pull request

Closes #103, as designed in [the issue](https://github.com/openchronology/timeline-app/issues/103#issuecomment-6201093056), with the newcomer decision: public timelines of accounts that aren't yet established stay out of default browsing. ## The problem Popularity was stars plus public forks, every one counted the same. A handful of throwaway accounts could lift a spam timeline to the top of Popular. And every new account's public timelines went straight into the browse list. ## Account standing Each account has a standing from 0 to 1. It's used for ranking and shown only to administrators (`server/standing.mjs`, `docs/browsing.md`). An account is **established** when it is: - **in good standing:** not suspended, not untrusted, and with no moderation restriction in force (#115); - **confirmed:** a confirmed email, or a social sign-in; - **old enough:** 30 days, or 7 days and **endorsed**. **Endorsed** means starred or publicly forked by an endorsing account: a confirmed account at least 30 days old, an administrator, or a trusted account, never the account itself. Administrators and trusted accounts are always established, with standing 1. An established account's standing is 0.4, plus up to 0.4 for age (up to 30 days), 0.1 for two-factor authentication, and 0.02 per endorser (up to 0.2). It is capped at 1. ## What changes - **Browsing:** public timelines with no search text list only established owners' timelines, plus featured ones. - Others stay reachable by link, on their owner's profile and among a reader's favorites. - Text search still finds them, ranked after established accounts' matches. - Owners not yet established see a note under **Sharing & settings → Visibility** saying how to become established. - **Popularity:** the total standing of the accounts that starred or publicly forked a timeline. Each account counts once, and the owner's own stars and forks count for nothing, so new accounts add nothing. - **New sort:** **Trending this month**, on the platform and in the editor's dashboard. It counts stars and forks from the last 30 days. - **Not published:** standing and the established flag are left out of search results. - **Administration:** **Users** shows each account's standing and the reason, for example "Established · standing 86% · 2 endorsing accounts" or "Not established: newer than 7 days". A **Standing** setting offers From its activity / Trusted / Untrusted. - **Seeding:** marks the seed account trusted, so curated timelines stay listed. ## When it updates | Event | Updates | | --- | --- | | Star or unstar | The timeline's popularity and its owner's standing, at once | | Trust, suspension or admin-role change; moderation restrict or lift | That account, the accounts it endorses (one step), and the popularity of what they starred, at once | | Accounts ageing, email or 2FA confirmation, forks published, trending ageing out | A sweep every 15 minutes (`startStanding`), and once at migration | Scores live in their own tables, `oc_account_standing` and `oc_timeline_popularity`, plus `oc_users.trust` for the override. Recomputing never rewrites `oc_timelines` rows, so it sends no live-update notices to open timelines. ## Performance Measured on a synthetic dataset of 100k accounts, 220k public timelines, 199k stars and 20k forks: | Operation | Time | | --- | --- | | Sweep, no changes (standing / popularity) | 4.3 s (3.2 s / 1.1 s) | | Sweep, first run | 7.3 s | | One account's refresh (as after a star) | 4 ms | | One timeline's popularity | 11–23 ms | | Browse (featured / popularity / trending / newest) | 0.76–0.88 s, vs 2.3–2.5 s for the same query on `main` | | Text search | 28 ms | The full sweep runs as one set-based pass rather than a per-timeline lookup; that change took it from 10.5 s to 4.3 s. The old browse query counted public forks for every listed timeline on each request; it now reads the stored score. The remaining 0.8 s is the pre-existing sort over every match plus the total count, which thi…

Sources

Open #168 · Rank browsing by account standing; weigh popularity by who starred in the timeline