Skip to content

Add profiles, progress, friends, discovery, creator hub, leagues, kit, wardrobe and email - #18

Merged
dav3exe merged 170 commits into
startnextgen:mainfrom
Cybertron-HNG:main
Oct 22, 2026
Merged

dav3exe merged 170 commits into
startnextgen:mainfrom
Cybertron-HNG:main

Conversation

@dav3exe

@dav3exe dav3exe commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

What this adds

Brings startng-be up to date with the Cybertron-HNG fork's main (169 commits). New since the last upstream sync:

Players and progress

  • Player profiles and badges (S1): a public page for every player
  • Progress engine: run log, daily activity, streaks, streak freezes, XP and awards
  • Friends and follows: follow players, friends when it's mutual, invite links
  • Private tournaments: friends pick games and a time, share a link, follow their standings
  • Wardrobe: coins, rarity items, the daily shop, and game goals priced by difficulty

Games and discovery

  • Discovery (A1): game ranking, homepage shelves, featuring, play next
  • Spotlight (A2): Game of the Week and the daily challenge
  • Categories and 1-5 star ratings (T1)
  • Creator hub (T2): creator pages, top creators, dashboard and nightly rollup
  • Leagues (M2): Sprint, Daily and Weekly tracks
  • Challenge links (B1) and share cards (B2)
  • Kit (M1): play-session tracking, and the game standards now count the Kit (games.uses_kit)

Quality, safety and email

  • Score integrity: stat limits, rate limit, outlier flags, a review queue; fix for a lower score overwriting a best
  • Game health (live games that stop loading), duplicate finder, needs-fixing list, offensive-name filter
  • Email: opt-in topics, double opt-in, unsubscribe, tournament emails, newsletter, Brevo or SMTP sending
  • Phase 0 scaffolding: feature folders, flags, events

CI and security

  • CodeQL, pip-audit, dependency review, CodeRabbit; CI runs on stacked PRs
  • Upgraded fastapi, starlette, pillow, PyJWT and requests for known vulnerabilities
  • Fixed the CodeQL alerts: backtracking regex in the duplicate finder, game file paths kept inside the game's folder, game name sanitised in logs, health-check URL built only from a valid game name

Deploy notes

  • New alembic migrations up to 0040 (a single head): run alembic upgrade head.
  • New settings are listed in .env.example.

Checks

pytest (658 passed), malware-scan, Dependency audit and Analyze (python) pass. Dependency review fails only because the dependency graph isn't enabled on this repo; a maintainer has been asked to turn it on.

Blackburn0 and others added 30 commits October 20, 2026 22:54
…tions

Groundwork from the PRD so each owner builds in their own folder without editing the same files.

- app/features/: one folder per feature (copy _template), listed with one line in FEATURES. Each feature's
  tables, routes and admin permissions are loaded from there.
- Feature flags: FEATURES env (comma separated, "*" for all locally). A feature's routes answer 404 until its
  flag is on. GET /features lists what's on.
- app/events.py: publish/subscribe in process. Every event and its payload is listed in EVENTS; a failing
  handler is logged, never raised. game_published, game_updated and tournament_finished are now published.
- app/manifest.py: startng.json as registered sections, each parsed (and optionally saved on publish) by its
  owner. leaderboard and description work as before.
- admin.register_permissions: features add their own admin permissions.
Phase 0 scaffolding: feature folders, flags, events, startng.json sections
…s are upgraded and dependency graph is enabled
ci: pip-audit, dependency review, CodeQL, Dependabot, CodeRabbit
deps: upgrade vulnerable packages flagged by pip-audit
Private tournaments: friends pick games and a time, share a link, follow their own standings
…ards and the rules registry

PRD D1. Ships dark behind the progress flag. Every score submission is logged, the
player's day (Nigeria time) is updated, and registered award rules are evaluated; the
score response gains an optional unlocked list. Adds GET /me/progress and /me/awards,
migration 0020, and publishes run_recorded and award_unlocked.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…st leaderboard layer

PRD D2. Ships dark behind the integrity flag. startng.json stats can set a max
(score_out_of_range), scores are rate limited per player per game, and the
leaderboard is sorted in the database with a 30 second cache, with the same output as
before. Adds integrity.ranked and integrity.rank_of (contract C5, with only_users).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ublic progress and run retention

PRD D1-b. Streaks earn a freeze every 7 days (max 2) that a missed day spends
automatically. Signed-in plays record game_opens (C4); runs remember the tournament
they counted for. Adds GET /players/{id}/progress with a visibility hook for the profile
feature, a backfill command that makes runs from existing scores, and 180-day run
retention. Migration 0021.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…for D2-b

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…h their own reasons

The hiding the admin page does (off lists and pages, offline at its own address, out of tournaments) moves into
app/admin.py as hide_game and show_game, so features hide games the same way. register_hide_reason adds a
feature's own reason, ranked among reported, flagged and blocked.
app/features/moderation (flag "moderation"):
- check_text(text) returns the blocked word or None; require_clean raises a 422 (text_not_allowed) naming the
  field, not the word. Other features (crews, wardrobe) call these.
- Default lists in words.py: "strong" words caught even inside other words, the rest as whole words with
  simple endings (-s, -es, -ed, -ing), and an allow list for innocent names (Scunthorpe). Look-alikes, accents,
  spaced-out and stretched spellings (sh1t, $hit, s.h.i.t, shiiit) are undone first.
- Admins add blocked or allowed words (moderation_words, migration 0022), try a name, and see names already on
  start.ng that fail. Permission moderation.words.

While the flag is on, start.ng checks new game names, the description in startng.json (a description it found
in the page or README is just left out), character names and Creators listings. Live game names are left
alone and listed for admins instead.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nk-held rule and record_beaten

PRD D2-b. A run far beyond the player's previous best or the game's 99th percentile is
held for review: logged as flagged, kept off the board, out of tournaments, XP, awards and
events, and answered like any other run. Owners see their game's flags; admins with
scores.review clear or confirm them. Runs record the place reached so a rank counts only
once held across two runs, and record_beaten fires when the top spot changes hands.
Migration 0022.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found by running the engine on Postgres: 8 runs sent at once by a new player were all
logged, but the day's activity row said 2 runs, because each request read the row, added
to it and wrote it back. The day's row is now read with FOR UPDATE, so runs queue up.
Adds a Postgres-only regression test (skipped unless TEST_DATABASE_URL is set).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ore rows correctly

Running the leaderboard on Postgres with 50,000 scores showed the top 10 at p95 63 ms
(over the 50 ms goal) because the tied rows were fetched and sorted in Python. The whole
ordering is now done by the database in one query that follows the (game, best) index:
p95 16 ms. Also fixes a plain-score row stored as the JSON value null being ranked last.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Measured on Postgres, logging a run was adding about 53 ms at p95 per score, mostly the
six queries that build the snapshot after every run. They are only needed to evaluate
award rules, so with none registered (today) they are not run.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
dav3exe and others added 21 commits October 22, 2026 08:56
A2 spotlight: Game of the Week and the daily challenge
Merge dev into feat/m1-kit-sessions (for #69), migration -> 0038
M1 Kit: game_sessions (how long people play Kit games), behind the kit flag
Merge dev into feat/m2-leagues (for #71), migration -> 0039
M1 Kit: the publish check counts the Kit for the game standards, and publish sets games.uses_kit
feat: M2 Leagues backend (Sprint, Daily and Weekly tracks)
Fix: two alembic heads (games.uses_kit migration 0031 -> 0040)
…y difficulty

Players earn coins and items by playing any start.ng game (event handlers on runs, tournaments, challenges and
league promotions; no game changes). Coins are earn-only, kept in a ledger with a guarded balance and a daily cap
on coins from playing. Games can list goals in a startng.json `rewards` section; start.ng sets what each pays from
the share of players who reach it. 21 items in six rarities; epic, legendary and limited can't be bought. The
Hangout's live room sends what each player wears. Flag `wardrobe`, off by default.

Migration 0040 follows dev's 0039; renumber to 0041 if fix/uses-kit-migration-0040 merges first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dev now has 0040_games_uses_kit (#93), so the wardrobe migration follows it (one alembic head).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cache started as (0.0, {}) and counted as fresh while time.monotonic() was under SHARE_TTL, so on a machine
up for less than 10 minutes (a new CI runner) every item read 0%. It now starts empty (None).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Wardrobe: coins, rarity items, the daily shop and game goals priced by difficulty
Support authenticated SMTP with STARTTLS or implicit SSL alongside the existing log and Brevo providers. Document the required environment variables for deployment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
H1 email: send through SMTP (EMAIL_PROVIDER=smtp)
Polish from the end-to-end test: league names, plurals, faster ranking refresh, daily challenger badge
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Comment thread app/features/duplicates/service.py Fixed
Comment thread app/features/duplicates/service.py Fixed
Comment thread app/features/game_health/service.py Fixed
Comment thread app/game_store.py Fixed
Comment thread app/game_store.py Fixed
Comment thread app/game_store.py Fixed
Comment thread app/game_store.py Fixed
Comment thread app/admin.py Fixed
@dav3exe dav3exe changed the title Promote Cybertron-HNG main: discovery, creator hub, profiles, kit, leagues, wardrobe and more Add profiles, progress, friends, discovery, creator hub, leagues, kit, wardrobe and email Oct 22, 2026
@dav3exe
dav3exe merged commit 3db9bf1 into startnextgen:main Oct 22, 2026
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants