Choose a Metric the Number Can Support

Retro Visits is an aggregate page-view counter for the workshop homepage. An accepted homepage load adds one view. It does not identify unique people, devices or verified human visitors. Opening another tab or returning later may count again; unknown bots may count too.

A static GitHub Pages document cannot persist a shared count on its own. The site therefore reads a small Python/SQLite backend. The frontend stays on GitHub Pages. The backend keeps the aggregate across process restarts and serializes concurrent increments; it does not seed the ticker with a decorative popularity number.

Make Reloads and Retries Behave

The browser first makes a GET request, which reads the total without incrementing it. An allowed origin also receives a short-lived signed challenge. A POST then supplies that challenge, an allowed homepage path and a random event value. The backend can reject invalid requests and return the current total for duplicate retries without adding another view.

The tab stores its random event for 30 seconds. A rapid reload normally reuses it; a later load replaces it. This is short-lived retry suppression, not a stable visitor identifier. If session storage is unavailable, the request can still work but rapid reload suppression becomes less effective. Offline loads are not queued for later counting.

The backend currently accepts only the homepage paths. Blog pages do not load the incrementing counter script. That preserves what the existing total means instead of quietly broadening it to every new article.

Be Precise About Privacy

The aggregate is durable. SQLite also temporarily holds digests of events and consumed challenges for duplicate/replay suppression, with active expiration and cleanup. Expiration is not a guarantee that old bytes have been forensically erased from the database file.

The application does not persist raw IPs, user agents, referrers, cookies or browser fingerprints. Its rate limiter derives short-lived in-memory buckets from network addresses and rotates their key. Those buckets do not go to disk. The dedicated connector and edge provider still process requests; the application cannot make promises about separately enabled provider logs.

CORS and signed challenges are useful controls, not proof of a human visitor. A custom client can spoof an Origin header and request a challenge. Host/path allowlists, body limits, deadlines, replay checks and rate limits reduce accidental misuse and cheap bursts. They do not turn this approximate counter into a billing or security metric.

Keep a Small Feature From Blocking the Site

The client sends no credentials and has a five-second deadline. If the endpoint fails, returns malformed data or times out, the digits stay as dashes with an accessible unavailable message. Navigation and articles keep working. It never substitutes a locally cached count to make the site appear busier.

The database is kept outside the public website and is not replaced by source deployment. Test databases remain separate. Backend and connector boot services were verified at activation; the website's later blog publication does not reconfigure that infrastructure.

Exercise the Edge Cases With Fixture Data

The public backend tests cover persistence across a real process restart, concurrent unique events, concurrent duplicate retries, request/CORS behavior, malformed inputs, test/bot skipping, rate limits and expiration. Ten browser fixture states exercise desktop/tablet/phone rendering, reload suppression, large totals, offline behavior, disabled configuration and timeouts.

These tests use intercepted requests and disposable data, rather than a series of production increments. The counter's public documentation, backend source and tests let readers inspect the mechanism. The honest result is modest: a shared count of accepted homepage loads, with stated limits.

THE PAPER TRAIL

Evidence & Sources

The implementation and tests for this workshop tool are public. The sources below describe its actual counting and storage rules.

  1. Counter documentation
  2. Backend source
  3. Browser client
  4. Backend test cases
  5. Rendered fixture tests
  6. Counter activation commit