forgepulse: an award badge for repositories in the top 10 of both rankings
forgepulse publishes two rankings of the
same fleet — human attention, built from unique views, external referrers and
new stars and forks, and raw clone volume — and they rarely agree, so a
repository that reaches the top ten of both now carries an award badge beside
its rank, in either view
(55028f2). The condition
lives in web/src/lib/rank.ts as inBothTopN, which is true only when the
attention rank exists and both ranks are 10 or better; the badge is styled in
styles.css and the rule is covered by rank.test.ts.
forgepulse: a fleet-wide feed of every star, newest first
forgepulse can now answer “who starred
what, and when” across the whole fleet: a new /stars page lists every star
across every tracked repository in one chronological feed — avatar, who, which
repository, when — which GitHub only offers per repository and never across an
account (af4a8ea). The
backend adds a star_events table populated from each repository’s
/stargazers endpoint requested with the star+json media type, which carries
the true starred_at per user and so needs no backfill wait, unlike the
human-attention baselines; it syncs alongside the existing star count.
forgepulse: the 1d/7d/30d windows now count back from the newest day GitHub reported
The window columns in forgepulse were
mostly empty at their recent end: GitHub’s traffic API lags a day or more, so
counting back from the wall clock left the newest days without rows and the 1d
column read zero for nearly every repository
(7f5acb4). The windows now
count back from the newest day that at least half of all repositories have a row
for, and each window is capped at that day, so a stray early same-day row cannot
leak in as a partial day or move the anchor — a plain MAX(day) would let one
early reporter blank out everyone else. It also makes 1d genuinely one day: the
old >= now − 1 day spanned up to two. It is the same lag the per-repository
clone baselines were added for, now
fixed at the window itself rather than at the comparison.
forgepulse: the echarts 6 bump moved the legend onto the axis labels
The echarts 5 → 6 bump in forgepulse
changed the default legend position from top to bottom, so on both charts the
legend collided with the x-axis date labels while the 48px the grid reserves at
the top sat empty — legend.top is now set explicitly, so the layout stops
depending on a library default
(94fb8c1). The same release
draws a filled marker on every data point, which on a hundred-day series is
clutter; the dots are hidden on all eight series through one shared base while the
axis tooltip still marks the hovered point
(1f70b65). Both rode in with
the vitest 4.1.11 / echarts 6.1.0 security bump.
forgepulse: the rank column stops stretching to the row height
The rank-trend arrows in
forgepulse’s Repository signal table
cost every row its bottom border alignment:
display: flex on .rank-share, added to stack the arrow, pulled that <td>
out of table layout, so it stopped growing to the row’s real height and stayed
clipped to its own content while the Name column stretched normally for longer
descriptions. Dropping the flex display and keeping the existing block-span
stacking restores the alignment — two lines of CSS, which is what a change made
to fit a two-character indicator should have cost in the first place.
forgepulse: per-repository clone baselines, and a sidebar that folds on a 14-inch screen
The clone-trend arrows added to forgepulse
two days ago were reading
“stable” almost everywhere, and the cause was GitHub’s traffic API rather than the
repositories: it reports a day’s row inconsistently per repository, so at any moment
only a handful have a same-day daily_traffic entry while most lag behind, and a single
fleet-wide “yesterday” cutoff therefore compares most repositories against data already
included in their current total
(762ea7b). The fix is to compare
each repository’s clone total against one day before that repository’s own most recent
row, computed in one query through a per-repository MAX(day), so the comparison never
depends on a shared calendar date — verified live, the trends now show real up and down
movement instead of universal stability.
forgepulse: rank-trend arrows in the repository signal table
forgepulse’s Repository signal table now
carries a Billboard-chart-style up / down / stable indicator on every row, in
both ranking modes, showing whether a repository moved since yesterday
(9306fec). It tracks
rank rather than the raw figure on purpose: clone volume ranks by
total_clones, a cumulative counter that only ever grows, so diffing the value
would read “up” almost every day regardless of real trend, while rank stays
relative and keeps meaning.
quadratula: how much of Schröder's 990 quasigroup laws small quasigroups already witness
quadratula is a new public repository that asks how much of the implication structure of Schröder’s 990 quasigroup equational laws is already visible in small quasigroups. It enumerates every quasigroup of order 1 to 6 up to isomorphism — 1,131,984 classes, in Rust on a pinned toolchain — computes which laws each one satisfies, and measures that exhaustive floor against Bruno Le Floch’s arXiv:2603.29909: quasigroups of order at most 4 already witness 95.34% of the 726,207 law-level non-implications (91.68% of the 1,958 between the 47 classes), and going to order 6 reaches 96.70%, realising 94 of the 114 varieties and separating 42 of the 47 classes.
forgepulse: manual refresh and an on-demand sync, behind a single-flight guard
forgepulse grew the two controls its
dashboard was missing: Refresh re-fetches the stored dashboard and detail
data without touching GitHub at all, while Sync now performs a real pull
through the existing POST /api/v1/sync endpoint outside the hourly schedule
and now surfaces the server’s error inline — an expired token says so
immediately instead of failing silently until the next scheduled attempt
(87cfe54). On-demand
sync then exposed a contention bug worth fixing properly: the scheduled tick and
the new endpoint shared one GitHub collector with no coordination, so a click
landing during the hourly run let multiple full 84-repo syncs proceed at once,
each with its own bounded per-repo fetch — enough load to trip secondary rate
limiting and queue on SQLite’s single writer, turning overlap into a crawl
rather than an error. A single-flight guard now rejects the second sync instead
of letting the two contend
(47b2e73).
forgepulse: the dashboard now shows when its numbers were last refreshed
forgepulse shows the age of its own data:
the homepage now reads the most recent successful sync run — already recorded in
the sync_runs table but never surfaced — and renders it next to the git-ref
pill as Updated <UTC> · <local> (Xh Ym ago), ticking every minute
(d4c5e85). Traffic
history is only as useful as the moment it was collected, and until now the
dashboard gave no way to tell a stale snapshot from a fresh one. The change
touches two new frontend modules plus tests for the relative-time formatter and
the API field behind it.
dratify v0.1.4/v0.1.5: published speed figures replaced with numbers anyone can reproduce
dratify tagged v0.1.4 and v0.1.5 after an audit of its published numbers: the README’s speed table came from CNF files that are not in the repository, and its “~18x” was the top of a range quoted as the typical value. A committed benchmark script (bench/repro.py) now produces figures anyone can reproduce — a second run held the geometric mean at ~15x while individual ratios moved between 11x and 22x, so the release quotes the mean and states the spread as a spread. The same pass (c34c31b) added a fuzz workflow and stopped error messages from reporting version skew in the vocabulary of an unrelated project’s module.
cdclkit v0.1.3: a self-check that verified nothing, honest benchmark notes, and docs that describe the program
cdclkit tagged
v0.1.3: the release leads
with the bug that mattered — --adaptive --self-check printed
s UNSATISFIABLE while verifying nothing. Both engines now require
dratify 0.1.4, with a test that fails if
they ever ask for different versions again. The same pass rewrote the docs to
describe the program (a fresh make test failed with 24 import errors while
the Makefile still claimed no dependencies), and
BENCHMARKS.md now
says what the published 20.1x figure is a sample of: one run per instance,
with individual ratios seen moving by a third between runs while the geometric
mean held.
dratify v0.1.3: tests behind the differential claim, and untrusted input that can no longer ask for gigabytes
dratify is tagged
v0.1.3: the docs said the
Python checker and the Rust checker were compared against DRATChecker on
acceptances and rejections, but the only two tests that did so had silently
skipped on every run — an import-time guard — so that claim had never once been
exercised. The new differential suite
(2889df3) sweeps 150 random
instances plus hand-written accept/reject cases, and CI installs the native
checker and fails if the tests skip. The same release hardens the
untrusted-input paths: header counts like p cnf 99999999999 0 that would have
asked for hundreds of gigabytes are rejected outright, register_native
validates the checker it is handed instead of unpacking a fixed tuple, and
proof parsing reports the offending line and token. Tests go from 87 to 96 and
coverage 84% to 87%, with each new guard confirmed to fail when its fix is
reverted.
forgepulse: human attention ranking lands on main
forgepulse merged its first pull request, PR #1: human attention is now the default explainable ranking alongside clone volume. The dashboard persists fork history, collects release/tag and Actions-checkout signals, and shows each traffic diagnosis with its evidence inline. Clone-volume mode also gained sortable Stars/Views/Clones column headers (c69739b).
dratify: the release workflow now tests the tag it publishes
dratify’s release pipeline could report a
successful release that published nothing: ci.yml triggers on branches and
pull requests and never on tags, so no test ever ran against the ref being
published, and combined with skip-existing a tag that forgot to bump the
version built the old one, had PyPI skip it as already present, and exited
green. The suite now
runs on the tag, and the build fails when the tag does not name the version it
produced — skip-existing
should absorb a re-run of the same release, not disguise a forgotten bump.
forgepulse v0.1.0: the baseline release
forgepulse hit its first tagged
release, v0.1.0:
the self-hosted GitHub traffic dashboard with retained clone and view history,
repository analytics, charts, referrer and path snapshots, and JSONL export.
The release note frames it explicitly as the baseline before the next feature
— human attention ranking, which is already landing on the develop branch.
forgepulse: repos above the fleet's median clone count
forgepulse now highlights repositories whose clone counts sit above the fleet’s median, and the comparison was fixed to use each repo’s own daily median against the fleet’s rather than its raw total, so a busy repo can no longer skew its own marker.
dratify: check DRAT/DRUP proofs of unsatisfiability in-process
dratify is a new public DRAT/DRUP proof
checker that runs inside your Python process: zero dependencies, no subprocess,
no compiler. It replays a solver’s derived-clause log to confirm the empty
clause really follows, sharing no code with the solver that wrote the proof,
and the same checker is published as a Rust crate. A register_native() seam
lets the Rust engine (~18x faster) be supplied without shipping a toolchain,
publishing is tokenless via Trusted Publishing, and the checker’s own tests
went from 12 to 71 with a coverage gate.
cdclkit: a readable CDCL SAT solver where every answer comes with a certificate
cdclkit is a new public CDCL SAT solver, preprocessor and encoding library, written from scratch in readable Python with an optional Rust engine (roughly 18x faster) shipped as cdclkit-native. Every answer comes with a certificate: a satisfying model is re-evaluated clause by clause, and an UNSAT answer emits a DRAT proof that an independent checker replays. It publishes on PyPI with no third-party code, and the tutorial walks one problem end to end, from DIMACS through the files between stages.
forgepulse: routing and link-click fixes
forgepulse fixed two web-UI bugs: opening a repository detail page directly, or in a new tab, no longer 404s, and modifier-clicking a link now opens it in a new tab instead of swallowing the click. CI was retriggered after a GitHub Actions outage stalled the pipeline.
forgepulse: GitHub links on detail pages, gghstats issues checked
forgepulse’s repository detail page now links its title, top referrers, and popular paths straight to GitHub (paths always, referrers only when they look like real hostnames), and the JSONL export filename embeds a UTC timestamp so re-downloads stop silently overwriting the previous file. A cross-check against the issues opened on hrodrig/gghstats found that three of them applied to forgepulse too — the export filename, the stats-panel jargon, and the rank column header — and were fixed here; the locale-formatting issue does not apply in the same shape yet.
forgepulse: launch-week fixes and features
forgepulse got its launch-week pass: the repository table is paginated, a favicon landed, and the static “LOCAL” badge now shows the running git ref. On the ops side, a scheduled sync that was silently failing (the /data volume was never chowned to the app user) and a repository detail page that replayed every historical referrer day are fixed, and the production container now restarts itself after a crash or reboot.
forgepulse: self-hosted GitHub traffic-history analytics
forgepulse is now public: a self-hosted GitHub traffic-history analytics app built with Rust, a Svelte frontend, SQLite for storage, and Podman for deployment. It keeps a running history of GitHub traffic metrics so trends accumulate instead of vanishing after GitHub’s rolling window.
cross-tetris: a shared-queue four-well Tetris
cross-tetris is a new game: four standard Tetris wells arranged in a cross, sharing a single piece stream. You — or a greedy rule-based AI — pick which well each piece falls into, the wells play out as ordinary real-time Tetris, and the game ends when any well tops out. The engine is Rust compiled to WASM with a React UI, and it is playable live.