Your GitHub profile as a 3D pixel art building in an interactive city
This report summarizes scanner evidence for srizzon/git-city, a TypeScript project with 5,802 GitHub stars. SynthScan examined 237,836 lines of code across 994 source files, recording 823 pattern matches distributed across 6 syntactic categories. The legacy adjusted pattern signal is 9.8 (Moderate pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 83 finding(s).
Are imports declared and package/API names verified? 2 finding(s).
Are wrappers, guards, and repeated structures necessary? 773 finding(s).
Which changes need focused human review? 823 finding(s).
Run additional scans to build a history of the legacy pattern signal. Score changes are not a measure of AI adoption or code quality.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 823 distinct pattern matches across 6 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | party/drive.ts | 44 | // ─── League city driving ──────────────────────────────────── | COMMENT |
| MEDIUM | party/townlive.ts | 4 | // ─── Town live tally ──────────────────────────────────────── | COMMENT |
| MEDIUM | party/fly.ts | 5 | // ─── Tunables ─────────────────────────────────────────────── | COMMENT |
| MEDIUM | party/fly.ts | 21 | // ─── Bug Invasion boss (live event) ───────────────────────── | COMMENT |
| MEDIUM | party/fly.ts | 57 | // ─── Validators ───────────────────────────────────────────── | COMMENT |
| MEDIUM | party/fly.ts | 77 | // ─── Types ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | party/fly.ts | 193 | // ─── Server ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | party/fly.ts | 200 | // ─── Boss state (live event) ────────────────────────────── | COMMENT |
| MEDIUM | party/smash.ts | 22 | // ─── Smash (drive room side) ──────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 5 | // ─── Types (inline — party/ can't use @/ alias) ───────────── | COMMENT |
| MEDIUM | party/arcade.ts | 126 | // ─── Map config (loaded dynamically from Supabase) ─────────── | COMMENT |
| MEDIUM | party/arcade.ts | 276 | // ─── Rate limiting ─────────────────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 298 | // ─── Game constants ───────────────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 304 | // ─── PX Milestones ────────────────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 320 | // ─── Chat filter ───────────────────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 365 | // ─── Mute tracking ────────────────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 372 | // ─── Server ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 390 | // ── Game state (10s challenge) ────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 396 | // ── Load config + restore state ──────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 542 | // ── Auth ─────────────────────────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 592 | // ── Connection ───────────────────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 680 | // ── Messages ─────────────────────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 858 | // ── Game: Start ─────────────────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 873 | // ── Game: Stop ──────────────────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 894 | // ── Score submission (async, always sends result) ───────── | COMMENT |
| MEDIUM | party/arcade.ts | 1111 | // ── Disconnect ───────────────────────────────────────────── | COMMENT |
| MEDIUM | party/arcade.ts | 1146 | // ── HTTP: player count + hot-reload ──────────────────────── | COMMENT |
| MEDIUM | party/race.ts | 31 | // ─── Town race track ──────────────────────────────────────── | COMMENT |
| MEDIUM | .claude/skills/gg/kit/src/clock.ts | 1 | // ─── Film clock ───────────────────────────────────────────── | COMMENT |
| MEDIUM | .claude/skills/gg/kit/src/film.ts | 1 | // ─── Film ─────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/vscode-extension/src/activity/tracker.ts | 35 | // ─── State ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/vscode-extension/src/activity/tracker.ts | 58 | // ─── Public API ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/vscode-extension/src/activity/tracker.ts | 161 | // ─── State Transitions ───────────────────────────────────────── | COMMENT |
| MEDIUM | packages/vscode-extension/src/activity/tracker.ts | 182 | // ─── Event Handling ───────────────────────────────────────────── | COMMENT |
| MEDIUM | packages/vscode-extension/src/activity/tracker.ts | 272 | // ─── Idle Timer ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/proxy.ts | 116 | // ── 0. Block bots from API routes ───────────────────────────────── | COMMENT |
| MEDIUM | src/proxy.ts | 126 | // ── 1. Rate Limit ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/proxy.ts | 148 | // ── 2. Supabase Session Refresh ────────────────────────────────────── | COMMENT |
| MEDIUM | src/proxy.ts | 185 | // ── 3. Security headers ───────────────────────────────────────────── | COMMENT |
| MEDIUM | src/proxy.ts | 191 | // ── 3b. Referral capture ──────────────────────────────────────────── | COMMENT |
| MEDIUM | src/proxy.ts | 205 | // ── 4. Attach rate-limit headers so clients can self-throttle ──────── | COMMENT |
| MEDIUM | src/app/arcade/page.tsx | 336 | // ─── Room Section ─────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/arcade/page.tsx | 371 | // ─── Room Card ────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/arcade/[slug]/page.tsx | 247 | // ── Client-side prediction ────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/league-client.tsx | 197 | // ─── Race track ──────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/league-client.tsx | 207 | // ─── Editor ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/league-client.tsx | 388 | // ─── Drive ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/league-client.tsx | 657 | // ─── Intro ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/league-client.tsx | 664 | // ─── Cover ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/league-client.tsx | 791 | // ─── First steps ─────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/league-client.tsx | 858 | // ─── Identity panels (editor) ────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/settings/settings-client.tsx | 97 | // ─── Name ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/settings/settings-client.tsx | 145 | // ─── Identity ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/settings/settings-client.tsx | 276 | // ─── Invite link ───────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/settings/settings-client.tsx | 349 | // ─── Who can join ──────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/settings/settings-client.tsx | 394 | // ─── Join requests ─────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/settings/settings-client.tsx | 494 | // ─── Members ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/settings/settings-client.tsx | 659 | // ─── Transfer admin ────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/town/[slug]/settings/settings-client.tsx | 721 | // ─── Delete ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/app/admin/ads/_components/ad-form-fields.tsx | 112 | // ─── Landmark-specific fields ─────────────────────────── | COMMENT |
| 678 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | party/drive.ts | 41 | import { SmashRoom } from "./smash"; | COMMENT |
| LOW | party/smash.ts | 21 | COMMENT | |
| LOW | .claude/skills/gg/kit/src/Studio.tsx | 1 | "use client"; | COMMENT |
| LOW | .claude/skills/gg/kit/src/examples/gitcity/EndCard.tsx | 1 | "use client"; | COMMENT |
| LOW | supabase/config.toml | 61 | # If enabled, seeds the database after migrations during a db reset. | COMMENT |
| LOW | supabase/config.toml | 101 | # Port to use for the email testing server web interface. | COMMENT |
| LOW | supabase/config.toml | 161 | # JWT issuer URL. If not set, defaults to auth.external_url. | COMMENT |
| LOW | supabase/config.toml | 181 | COMMENT | |
| LOW | supabase/config.toml | 201 | # Number of sign up and sign-in requests that can be made in a 5 minute interval per IP address (excludes anonymous user | COMMENT |
| LOW | supabase/config.toml | 221 | enable_confirmations = false | COMMENT |
| LOW | supabase/config.toml | 241 | # Uncomment to customize email template | COMMENT |
| LOW | supabase/config.toml | 261 | COMMENT | |
| LOW | supabase/config.toml | 401 | s3_access_key = "env(S3_ACCESS_KEY)" | COMMENT |
| LOW | .github/workflows/deploy-staging-migrations.yml | 1 | name: Deploy migrations to staging | COMMENT |
| LOW | .github/workflows/deploy-migrations.yml | 1 | name: Deploy migrations to production | COMMENT |
| LOW | .conductor/settings.toml | 1 | #:schema https://conductor.build/schemas/settings.repo.schema.json | COMMENT |
| LOW | src/app/api/dev/login/route.ts | 1 | import { NextResponse } from "next/server"; | COMMENT |
| LOW | src/app/api/cron/refresh-buildings/route.ts | 21 | gifts_sent: 0, | COMMENT |
| LOW | src/app/api/cron/refresh-buildings/route.ts | 41 | // Legacy rows (and year rollovers) have no valid split yet → they take ONE full | COMMENT |
| LOW | src/components/IntroColdOpen.tsx | 1 | "use client"; | COMMENT |
| LOW | src/components/BossShareCard.tsx | 1 | "use client"; | COMMENT |
| LOW | src/components/BossVictoryScreen.tsx | 1 | "use client"; | COMMENT |
| LOW | src/components/EffectsLayer.tsx | 121 | // Cosmetics show based on what the camera is LOOKING AT (view frustum + gather | COMMENT |
| LOW | src/components/league/hud/drive/DrivePrompt.tsx | 1 | "use client"; | COMMENT |
| LOW | src/components/league/hud/drive/TouchControls.tsx | 1 | "use client"; | COMMENT |
| LOW | src/lib/perfMode.ts | 81 | downgradeAutoTier: () => void; | COMMENT |
| LOW | src/lib/silenceThreeClockWarning.ts | 1 | // ─── Silence the THREE.Clock deprecation spam ────────────────────────────── | COMMENT |
| LOW | src/lib/arcade/engine/sprites.ts | 1 | // ─── Cozy People spritesheet format (greyscale + tinting) ─── | COMMENT |
| LOW | src/lib/cosmetics/modelBase.ts | 1 | // Single source of truth for where cosmetic GLB models are served from. | COMMENT |
| LOW | src/lib/trailer/demo/film.ts | 1 | // ─── Demo film ────────────────────────────────────────────── | COMMENT |
| LOW | src/lib/drift/score.ts | 1 | // ─── Drift score ──────────────────────────────────────────── | COMMENT |
| LOW | src/lib/drift/scenery.ts | 1 | // ─── Drift spot scenery ───────────────────────────────────── | COMMENT |
| LOW | src/lib/events/schema.ts | 1 | // ─── Event config schema + validators ────────────────────────── | COMMENT |
| LOW | src/lib/league-city/starter.ts | 1 | // ─── Starter city ─────────────────────────────────────────── | COMMENT |
| LOW | src/lib/league-city/rivalry-maps.ts | 1 | // ─── Claude Code vs Codex maps ────────────────────────────── | COMMENT |
| LOW | src/lib/league-city/smash.ts | 1 | // ─── Smash ────────────────────────────────────────────────── | COMMENT |
| LOW | src/lib/league-city/race/race.ts | 1 | // ─── Races ────────────────────────────────────────────────── | COMMENT |
| LOW | src/lib/league-city/race/laps.ts | 1 | // ─── Lap timing ───────────────────────────────────────────── | COMMENT |
| LOW | src/lib/league-city/drive/battle.ts | 1 | // ─── Drive battle ─────────────────────────────────────────── | COMMENT |
| LOW | src/lib/league-city/drive/bots.ts | 1 | // ─── Town bots ────────────────────────────────────────────── | COMMENT |
| LOW | src/lib/league-city/drive/crown.ts | 1 | // ─── Crown Rush ───────────────────────────────────────────── | COMMENT |
| LOW | src/lib/league-city/editor/state.ts | 1 | // ─── League city editor state ─────────────────────────────── | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/app/admin/email-monitoring/layout.tsx | 5 | export default async function AdminEmailMonitoringLayout({ children }: { children: React.ReactNode }) { | CODE |
| LOW | src/components/EffectsPOC.tsx | 911 | function createPreviewWindowTexture( | CODE |
| LOW | src/components/ThemeSkyFX.tsx | 338 | function makeSunsetCirrusDomeTexture(seed = 1, w = 1024, h = 512): THREE.CanvasTexture { | CODE |
| LOW | src/components/ShopPreview.tsx | 38 | function createPreviewWindowTexture( | CODE |
| LOW | src/lib/items.ts | 161 | export async function getOwnedItemsForDevelopers( | CODE |
| LOW | src/lib/github-api.ts | 334 | export async function fetchWeekContributionDays( | CODE |
| LOW | src/lib/achievements.ts | 194 | export async function getAchievementsForDevelopers( | CODE |
| LOW⚡ | src/lib/himetrica.ts | 119 | export function trackDisabledButtonClicked(button_name: string) { | CODE |
| LOW⚡ | src/lib/himetrica.ts | 129 | export function trackEArcadeSurveyStarted() { | CODE |
| LOW⚡ | src/lib/himetrica.ts | 133 | export function trackEArcadeSurveyCompleted() { | CODE |
| LOW | src/lib/social-links-server.ts | 11 | export async function fetchGithubSocialSuggestions(login: string): Promise<SocialLinks> { | CODE |
| LOW | src/lib/social-links-server.ts | 46 | export async function seedSocialLinksFromGithub(developerId: number, login: string): Promise<void> { | CODE |
| LOW | src/lib/auth-provision.ts | 42 | export async function provisionDeveloperOnLogin( | CODE |
| LOW | src/lib/create-developer.ts | 14 | export async function createDeveloperFromGitHub(login: string): Promise<{ id: number; github_login: string }> { | CODE |
| LOW | src/lib/auth-identity.ts | 24 | export function githubLoginsFromIdentities(user: User | null | undefined): string[] { | CODE |
| LOW | src/lib/leagues/service.ts | 472 | export async function getOrCreateInviteToken(viewer: Viewer, league: League): Promise<string> { | CODE |
| LOW | src/lib/landmarks/welcome-email.ts | 15 | export function renderLandmarkWelcomeEmail(landmark: Landmark) { | CODE |
| LOW | src/lib/notification-senders/league-overtaken.ts | 33 | export function renderLeagueOvertakenEmail(d: LeagueOvertakenEmailData, links: EmailLinks) { | CODE |
| LOW | src/lib/notification-senders/league-overtaken.ts | 79 | export async function sendLeagueOvertakenNotification(opts: { | CODE |
| LOW | src/lib/notification-senders/referral.ts | 20 | export function renderReferralJoinedEmail(d: ReferralJoinedData, links: EmailLinks) { | CODE |
| LOW | src/lib/notification-senders/referral.ts | 49 | export function sendReferralJoinedNotification( | CODE |
| LOW | src/lib/notification-senders/league-joined.ts | 53 | export function sendLeagueJoinedNotification(opts: { | CODE |
| LOW | src/lib/notification-senders/gift.ts | 63 | export function sendGiftReceivedNotification( | CODE |
| LOW | src/lib/notification-senders/streak.ts | 31 | export function renderStreakMilestoneEmail(d: StreakMilestoneData, links: EmailLinks) { | CODE |
| LOW | src/lib/notification-senders/streak.ts | 69 | export function sendStreakMilestoneNotification( | CODE |
| LOW | src/lib/notification-senders/raid.ts | 69 | export function sendRaidAlertNotification( | CODE |
| LOW | src/lib/notification-senders/town-demolished.ts | 46 | export function renderTownDemolishedEmail(d: TownDemolishedEmailData, links: EmailLinks) { | CODE |
| LOW | src/lib/notification-senders/league-invited.ts | 59 | export function sendLeagueInvitedNotification(opts: { | CODE |
| LOW | src/lib/notification-senders/race.ts | 116 | export async function sendRacePassedNotification(opts: RacePassedEmailData & { developerId: number }) { | CODE |
| LOW | src/lib/notification-senders/race.ts | 135 | export async function sendRaceChallengeNotification(opts: RaceChallengeEmailData & { developerId: number; fromId: number | CODE |
| LOW | src/lib/notification-senders/streak-broken.ts | 47 | export function sendStreakBrokenNotification( | CODE |
| LOW | src/lib/notification-senders/daily-reminder.ts | 121 | export async function sendDailyReminderNotification(devId: number, data: DailyReminderData, date: string) { | CODE |
| LOW | src/lib/notification-senders/league-requests.ts | 58 | export function sendJoinRequestNotification(opts: { | CODE |
| LOW | src/lib/notification-senders/league-requests.ts | 97 | export function renderRequestApprovedEmail(d: RequestApprovedEmailData, links: EmailLinks) { | CODE |
| LOW | src/lib/notification-senders/league-requests.ts | 122 | export function sendRequestApprovedNotification(opts: { | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | src/components/ThemeSkyFX.tsx | 774 | // • 1 sphere draw call = seamless warm horizon glow | COMMENT |
| MEDIUM | src/components/ThemeSkyFX.tsx | 370 | draw(0); draw(-w); draw(+w); // seamless wrap | CODE |
| MEDIUM | src/components/CityCanvas.tsx | 178 | new THREE.Vector3(800, 700, 1000), // WP0: Orbital start (seamless) | CODE |
| MEDIUM | src/components/CityCanvas.tsx | 185 | new THREE.Vector3(800, 700, 1000), // WP7: Orbital end (seamless) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | package-lock.json | 3349 | "resolved": "https://registry.npmjs.org/@reown/appkit-scaffold-ui/-/appkit-scaffold-ui-1.8.19.tgz", | CODE |
| MEDIUM | package-lock.json | 6604 | "resolved": "https://registry.npmjs.org/@reown/appkit-scaffold-ui/-/appkit-scaffold-ui-1.7.8.tgz", | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/app/admin/ads/_components/ad-form-fields.tsx | 162 | <input required placeholder="Acme Inc" value={form.brand} onChange={(e) => set("brand", e.target.value)} classNa | CODE |
| LOW | src/lib/leagues/names.test.ts | 27 | expect(companyLeagueName(" Acme Corp ", "acme")).toBe("Acme Corp"); | CODE |