All posts

21 August 2026/12 min read

The momentum score that never grew a second signal

Hecate's growth windows filled right on schedule a week after launch. The raw momentum score built on top of them still ties five unrelated repositories at a cap, and the fix for that lives in a dashboard query, not in the underlying data.

On 2026-08-07, Hecate had exactly one day of snapshot history for every repository it tracks, so every 7- and 30-day growth window was correctly NULL, and the momentum ranking meant to blend growth, usage and attention into one score had nothing to blend. It scored on attention alone, growth_component was NULL across all 2,011 rows, and signals_measured was 1 everywhere. The plan was to check again once a week of real history existed and see whether that resolved on its own.

A week later, the data problem is genuinely fixed, though not without a gap. Snapshots landed on thirteen of the fourteen days between 2026-08-07 and 2026-08-20; 2026-08-18 has no snapshot at all, because Docker Desktop failed to start that morning and the day's collection never ran. A missed day like that can't be backfilled after the fact, it describes a moment that's already passed. It didn't corrupt anything downstream, though: every 7-day comparison here lands on an exact snapshot match seven days out, so a repository's growth figure either exists from a real pair of snapshots or doesn't exist at all, it never quietly falls back to a stale day.

18 Aug — missing 2,010 2,068 2,075 2,079 7 Aug 20 Aug
Repositories tracked per daily snapshot. The count climbs from 2,010 to 2,079 as discovery adds new repos, with one real break: no snapshot exists for 18 August.

2,010 of the roughly 2,079 tracked repositories now have thirteen days of observed history and a populated stars_gained_7d. Net star growth across the whole catalog for the week was +611,090 (46,590,814 → 47,201,904), and the absolute leaders look exactly like leaders should: public-apis up 11,138 stars, skills up 9,794, MoneyPrinterTurbo up 9,733.

public-apis skills MoneyPrinterTurbo pi ponytail strix open-design hermes-agent spec-kit superpowers +11,138 +9,794 +9,733 +4,841 +4,532 +4,303 +4,153 +3,450 +3,243 +3,183
Top 10 repositories by absolute stars gained in 7 days. These figures are genuinely differentiated, not tied at a cap.

Not every one of those 2,010 rows is a meaningful comparison, though. Only 1,026 repositories have a real star-based growth figure at all: GitHub and GitLab are the only sources that report stars, so npm and PyPI repositories carry a structural zero, not a measured one. Filtered down to the sources where growth can actually mean something, the shape is unremarkable, most of the catalog barely moved.

63 447 365 88 40 20 3 Declined No change 0–0.5% 0.5–1% 1–2% 2–5% 5%+
7-day growth across the 1,026 repositories where a star-based figure is actually measurable. Most of the catalog didn't move.

The raw momentum table didn't get the same care. Query fct_momentum directly, ORDER BY momentum DESC, and the top of the ranking is a tie: systemd, h3.c, a scanned repo named skitter-creek-bath-salts, cua, and the npm package skills all sit at exactly 100.00, each pegged there by a single signal hitting the score's normalisation cap, not by three signals agreeing a repository is interesting. Across the whole table, only 32 rows out of roughly 2,068 have signals_measured = 2. Not one has all three.

23 2,013 32 0 0 signals 1 signal 2 signals 3 signals
2,013 of 2,068 momentum rows measure exactly one signal. A week after the milestone meant to fix that, almost nothing has moved past it.

This dashboard already knows that, and works around it: repositories are ranked by how many signals corroborate the score first, raw score second, and anything resting on a single signal gets demoted into its own section below a divider rather than competing with real multi-signal movement. pi leads at 54.7 on two signals, growth and attention. The next five, rosenbridge, asm-hall-of-shame, msword, wyzer, linkedin-feed-blocker, are single-signal attention movers, real Hacker News and Lobsters posts, ranked below pi even though their raw scores sit close to it. skills and standardwebhooks score higher than all of them in isolation, 100.0 and 82.3, and rank last anyway: single-signal usage numbers that would otherwise have swamped the top of the list exactly the way systemd and cua swamp it in the raw table.

2 signals corroborate 1 signal only SINGLE SIGNAL — RANKED SEPARATELY pi growth + attention rosenbridge attention asm-hall-of-shame attention msword attention wyzer attention linkedin-feed-blocker attention skills (npm) usage standardwebhooks usage 54.7 50.0 50.0 46.5 44.9 39.9 100.0 82.3
This dashboard's momentum leaders, ranked by signal count first. Full accent marks pi's two corroborating signals; every single-signal row, including the two usage-only repositories that score higher in isolation, gets the lighter shade and ranks below it.

That's a real fix, but it lives in this dashboard's own query, not in fct_momentum itself. Anything else that reads that table directly, an API response, a different report, this same panel rebuilt from scratch next month, inherits the tie all over again. The underlying score still caps at 100 and still can't tell a real three-signal mover from a repo that happens to have one metric pegged at its ceiling.

A routine sanity check catches a version of the same problem from another angle. Sorting fct_repository_growth by stars_growth_pct_7d instead of absolute growth is supposed to surface small repos accelerating fast. It doesn't: the top ten by percentage were ten packages with zero stars, click, PyYAML, numpy, eslint, rimraf among them, all showing 0 / 0 growth with nothing to divide by. It's the same root cause the 1,026-repository filter above already worked around for the distribution chart, just unfixed in this particular column.

Discovery is still doing its job: 49 of the 2,079 tracked repositories arrived because Hecate found them itself. And the forecast job, which couldn't even create its CronJob as of this morning's run, cronjobs.batch "hecate-forecast" not found, got redeployed later today and produced its first usable predictions; every batch before this one came back 100% insufficient_history. There's nothing to compare against yet, the target date is 2026-08-28, but it's running.

One honest caveat on all of this: today's dbt job didn't complete, 0 of 1, so the marts I queried directly reflect the last successful build, not necessarily this morning's fresh snapshot.

The lesson isn't really about Hecate specifically. A fix that lives in a dashboard's query is a real fix for anyone looking at that dashboard, and it is not a fix for the data underneath it. Both were true here at once: the growth window filled right on schedule, a smarter ranking already exists and already gets it right for this one view, and the raw table one layer down still ties five unrelated repositories at a normalisation cap, waiting for the next thing that queries it directly to rediscover the same problem from scratch.

  • hecate
  • data-engineering
  • sql