{"version": "2.1.0", "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "runs": [{"tool": {"driver": {"name": "Repobility", "informationUri": "https://repobility.com", "rules": [{"id": "scanner-2ebf9fa384a5932a", "name": "Stray `console.log` in TS/JS \u2014 server/src/index.ts:20", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/src/index.ts:20"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d63da3583b14afc0", "name": "Dockerfile runs as root: Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-59cbf6e36a0e3777", "name": "Docker base image is tag-pinned but not digest-pinned: node:22-bookworm-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-bookworm-slim"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "2 test file(s) for 24 source file(s) (ratio 0.08). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d7101ca1926e3342", "name": "Node manifest has dependencies but no lockfile: server/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: server/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1a6aeb84f8544549", "name": "Node manifest has dependencies but no lockfile: client/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: client/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci, lockfile. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-56ea7cfd5339f8e0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/src/auth.ts:60", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/src/auth.ts:60"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2652369659902c66", "name": "Frontend route `/game/:id` has no Link/navigate to it \u2014 client/src/App.tsx", "shortDescription": {"text": "Frontend route `/game/:id` has no Link/navigate to it \u2014 client/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6bd2d93ae318634c", "name": "Frontend route `/g/:id` has no Link/navigate to it \u2014 client/src/App.tsx", "shortDescription": {"text": "Frontend route `/g/:id` has no Link/navigate to it \u2014 client/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-97bf77a80efd07d4", "name": "Frontend route `/join/:code` has no Link/navigate to it \u2014 client/src/App.tsx", "shortDescription": {"text": "Frontend route `/join/:code` has no Link/navigate to it \u2014 client/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-02a9c7393c2c916f", "name": "Frontend route `/watch/:token` has no Link/navigate to it \u2014 client/src/App.tsx", "shortDescription": {"text": "Frontend route `/watch/:token` has no Link/navigate to it \u2014 client/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-76506a89e19da0f9", "name": "Dangling fetch: POST https://discord.com/api/oauth2/token (server/src/auth.ts:60)", "shortDescription": {"text": "Dangling fetch: POST https://discord.com/api/oauth2/token (server/src/auth.ts:60)"}, "fullDescription": {"text": "`server/src/auth.ts:60` calls `POST https://discord.com/api/oauth2/token` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/discord.com/api/oauth2/token`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-f8ba728bf1410748", "name": "Dangling fetch: GET https://discord.com/api/users/@me (server/src/auth.ts:77)", "shortDescription": {"text": "Dangling fetch: GET https://discord.com/api/users/@me (server/src/auth.ts:77)"}, "fullDescription": {"text": "`server/src/auth.ts:77` calls `GET https://discord.com/api/users/@me` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/discord.com/api/users/@me`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-1f73639ffd7a9369", "name": "Unused endpoint: GET /discord", "shortDescription": {"text": "Unused endpoint: GET /discord"}, "fullDescription": {"text": "`server/src/auth.ts` declares `GET /discord` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-484486b417ea62ed", "name": "Unused endpoint: GET /discord/callback", "shortDescription": {"text": "Unused endpoint: GET /discord/callback"}, "fullDescription": {"text": "`server/src/auth.ts` declares `GET /discord/callback` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-99fc36db98c134ce", "name": "Unused endpoint: POST /logout", "shortDescription": {"text": "Unused endpoint: POST /logout"}, "fullDescription": {"text": "`server/src/auth.ts` declares `POST /logout` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fd1dc91abf32142d", "name": "Unused endpoint: GET /me", "shortDescription": {"text": "Unused endpoint: GET /me"}, "fullDescription": {"text": "`server/src/routes.ts` declares `GET /me` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-87ebb297212b5a95", "name": "Unused endpoint: POST /me/notify-turns", "shortDescription": {"text": "Unused endpoint: POST /me/notify-turns"}, "fullDescription": {"text": "`server/src/routes.ts` declares `POST /me/notify-turns` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ca785bf42d8b56d8", "name": "Unused endpoint: POST /games", "shortDescription": {"text": "Unused endpoint: POST /games"}, "fullDescription": {"text": "`server/src/routes.ts` declares `POST /games` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e4d97fab27109173", "name": "Unused endpoint: GET /games", "shortDescription": {"text": "Unused endpoint: GET /games"}, "fullDescription": {"text": "`server/src/routes.ts` declares `GET /games` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-32029cef8bc1e5e3", "name": "Unused endpoint: GET /games/:id", "shortDescription": {"text": "Unused endpoint: GET /games/:id"}, "fullDescription": {"text": "`server/src/routes.ts` declares `GET /games/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6983b4e906cb3c36", "name": "Unused endpoint: POST /games/:id/start", "shortDescription": {"text": "Unused endpoint: POST /games/:id/start"}, "fullDescription": {"text": "`server/src/routes.ts` declares `POST /games/:id/start` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c0ece0815bd36e83", "name": "Unused endpoint: POST /games/:id/turn", "shortDescription": {"text": "Unused endpoint: POST /games/:id/turn"}, "fullDescription": {"text": "`server/src/routes.ts` declares `POST /games/:id/turn` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e3d56e91020c8538", "name": "Unused endpoint: POST /games/:id/skip", "shortDescription": {"text": "Unused endpoint: POST /games/:id/skip"}, "fullDescription": {"text": "`server/src/routes.ts` declares `POST /games/:id/skip` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-140cc11f67ad2837", "name": "Unused endpoint: POST /games/:id/presence", "shortDescription": {"text": "Unused endpoint: POST /games/:id/presence"}, "fullDescription": {"text": "`server/src/routes.ts` declares `POST /games/:id/presence` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a735d93543b84f7d", "name": "Unused endpoint: POST /contributions/:id/react", "shortDescription": {"text": "Unused endpoint: POST /contributions/:id/react"}, "fullDescription": {"text": "`server/src/routes.ts` declares `POST /contributions/:id/react` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cb01b82a4d465625", "name": "Unused endpoint: GET /games/:id/events", "shortDescription": {"text": "Unused endpoint: GET /games/:id/events"}, "fullDescription": {"text": "`server/src/routes.ts` declares `GET /games/:id/events` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-115b93d94b7b116c", "name": "Unused endpoint: GET /games/:id/export.md", "shortDescription": {"text": "Unused endpoint: GET /games/:id/export.md"}, "fullDescription": {"text": "`server/src/routes.ts` declares `GET /games/:id/export.md` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8a9399f3b49acdda", "name": "Unused endpoint: GET /games/:id/stats", "shortDescription": {"text": "Unused endpoint: GET /games/:id/stats"}, "fullDescription": {"text": "`server/src/routes.ts` declares `GET /games/:id/stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5315de6c65debe60", "name": "Unused endpoint: GET /join-info/:code", "shortDescription": {"text": "Unused endpoint: GET /join-info/:code"}, "fullDescription": {"text": "`server/src/routes.ts` declares `GET /join-info/:code` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-54f9d73b31f351dd", "name": "Unused endpoint: POST /join/:code", "shortDescription": {"text": "Unused endpoint: POST /join/:code"}, "fullDescription": {"text": "`server/src/routes.ts` declares `POST /join/:code` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a460cef1f3efcd6e", "name": "Unused endpoint: GET /gallery", "shortDescription": {"text": "Unused endpoint: GET /gallery"}, "fullDescription": {"text": "`server/src/routes.ts` declares `GET /gallery` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ac7280181bec7648", "name": "Unused endpoint: GET /watch/:token", "shortDescription": {"text": "Unused endpoint: GET /watch/:token"}, "fullDescription": {"text": "`server/src/routes.ts` declares `GET /watch/:token` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/25267"}, "properties": {"repository": "davemo88/exquisite-prompt", "repoUrl": "https://github.com/davemo88/exquisite-prompt", "branch": "main"}, "results": [{"ruleId": "scanner-2ebf9fa384a5932a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/src/index.ts:20"}, "properties": {"repobilityId": "966123b8e19cb728", "scanner": "scanner-primary", "fingerprint": "2ebf9fa384a5932a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d63da3583b14afc0", "level": "warning", "message": {"text": "Dockerfile runs as root: Dockerfile"}, "properties": {"repobilityId": "a2ed1bd120e507db", "scanner": "scanner-primary", "fingerprint": "d63da3583b14afc0", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-59cbf6e36a0e3777", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-bookworm-slim"}, "properties": {"repobilityId": "aef587af3b117845", "scanner": "scanner-primary", "fingerprint": "59cbf6e36a0e3777", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "4938df9088c5aef1", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-d7101ca1926e3342", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: server/package.json"}, "properties": {"repobilityId": "bbcd0a89809ced91", "scanner": "scanner-primary", "fingerprint": "d7101ca1926e3342", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-1a6aeb84f8544549", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: client/package.json"}, "properties": {"repobilityId": "289cda4e29a77d84", "scanner": "scanner-primary", "fingerprint": "1a6aeb84f8544549", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "3c43939692de85ce", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "7d089908e3d96b1a", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-56ea7cfd5339f8e0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/src/auth.ts:60"}, "properties": {"repobilityId": "98f473eedda78925", "scanner": "scanner-primary", "fingerprint": "56ea7cfd5339f8e0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2652369659902c66", "level": "warning", "message": {"text": "Frontend route `/game/:id` has no Link/navigate to it \u2014 client/src/App.tsx"}, "properties": {"repobilityId": "a91cc5283f565ab8", "scanner": "scanner-primary", "fingerprint": "2652369659902c66", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-6bd2d93ae318634c", "level": "warning", "message": {"text": "Frontend route `/g/:id` has no Link/navigate to it \u2014 client/src/App.tsx"}, "properties": {"repobilityId": "7242a25a36078483", "scanner": "scanner-primary", "fingerprint": "6bd2d93ae318634c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-97bf77a80efd07d4", "level": "warning", "message": {"text": "Frontend route `/join/:code` has no Link/navigate to it \u2014 client/src/App.tsx"}, "properties": {"repobilityId": "621aec7efed85288", "scanner": "scanner-primary", "fingerprint": "97bf77a80efd07d4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-02a9c7393c2c916f", "level": "warning", "message": {"text": "Frontend route `/watch/:token` has no Link/navigate to it \u2014 client/src/App.tsx"}, "properties": {"repobilityId": "bc9493c1ee9f1631", "scanner": "scanner-primary", "fingerprint": "02a9c7393c2c916f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-76506a89e19da0f9", "level": "error", "message": {"text": "Dangling fetch: POST https://discord.com/api/oauth2/token (server/src/auth.ts:60)"}, "properties": {"repobilityId": "fb3c11affdf192f8", "scanner": "scanner-primary", "fingerprint": "76506a89e19da0f9", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-f8ba728bf1410748", "level": "error", "message": {"text": "Dangling fetch: GET https://discord.com/api/users/@me (server/src/auth.ts:77)"}, "properties": {"repobilityId": "8a77eb3e3e569c07", "scanner": "scanner-primary", "fingerprint": "f8ba728bf1410748", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1f73639ffd7a9369", "level": "note", "message": {"text": "Unused endpoint: GET /discord"}, "properties": {"repobilityId": "fc92aa152ddd0fbf", "scanner": "scanner-primary", "fingerprint": "1f73639ffd7a9369", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-484486b417ea62ed", "level": "note", "message": {"text": "Unused endpoint: GET /discord/callback"}, "properties": {"repobilityId": "faa6b52d751796a1", "scanner": "scanner-primary", "fingerprint": "484486b417ea62ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-99fc36db98c134ce", "level": "note", "message": {"text": "Unused endpoint: POST /logout"}, "properties": {"repobilityId": "334312fe6658bbd0", "scanner": "scanner-primary", "fingerprint": "99fc36db98c134ce", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fd1dc91abf32142d", "level": "note", "message": {"text": "Unused endpoint: GET /me"}, "properties": {"repobilityId": "fa9a1ab36afd9174", "scanner": "scanner-primary", "fingerprint": "fd1dc91abf32142d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-87ebb297212b5a95", "level": "note", "message": {"text": "Unused endpoint: POST /me/notify-turns"}, "properties": {"repobilityId": "638eaeee75bc4c63", "scanner": "scanner-primary", "fingerprint": "87ebb297212b5a95", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ca785bf42d8b56d8", "level": "note", "message": {"text": "Unused endpoint: POST /games"}, "properties": {"repobilityId": "b098a6e42ece9dee", "scanner": "scanner-primary", "fingerprint": "ca785bf42d8b56d8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e4d97fab27109173", "level": "note", "message": {"text": "Unused endpoint: GET /games"}, "properties": {"repobilityId": "947d45804dabdff3", "scanner": "scanner-primary", "fingerprint": "e4d97fab27109173", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-32029cef8bc1e5e3", "level": "note", "message": {"text": "Unused endpoint: GET /games/:id"}, "properties": {"repobilityId": "4a662d4566529336", "scanner": "scanner-primary", "fingerprint": "32029cef8bc1e5e3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6983b4e906cb3c36", "level": "note", "message": {"text": "Unused endpoint: POST /games/:id/start"}, "properties": {"repobilityId": "3fc9b12ae752ca74", "scanner": "scanner-primary", "fingerprint": "6983b4e906cb3c36", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c0ece0815bd36e83", "level": "note", "message": {"text": "Unused endpoint: POST /games/:id/turn"}, "properties": {"repobilityId": "589f7a496b6ff6b9", "scanner": "scanner-primary", "fingerprint": "c0ece0815bd36e83", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e3d56e91020c8538", "level": "note", "message": {"text": "Unused endpoint: POST /games/:id/skip"}, "properties": {"repobilityId": "a350095d6e5127da", "scanner": "scanner-primary", "fingerprint": "e3d56e91020c8538", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-140cc11f67ad2837", "level": "note", "message": {"text": "Unused endpoint: POST /games/:id/presence"}, "properties": {"repobilityId": "37a4c0b8ea81d993", "scanner": "scanner-primary", "fingerprint": "140cc11f67ad2837", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a735d93543b84f7d", "level": "note", "message": {"text": "Unused endpoint: POST /contributions/:id/react"}, "properties": {"repobilityId": "841396d4798d6fe2", "scanner": "scanner-primary", "fingerprint": "a735d93543b84f7d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cb01b82a4d465625", "level": "note", "message": {"text": "Unused endpoint: GET /games/:id/events"}, "properties": {"repobilityId": "d7d25f7c39ab0553", "scanner": "scanner-primary", "fingerprint": "cb01b82a4d465625", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-115b93d94b7b116c", "level": "note", "message": {"text": "Unused endpoint: GET /games/:id/export.md"}, "properties": {"repobilityId": "3a6a4752c09018b0", "scanner": "scanner-primary", "fingerprint": "115b93d94b7b116c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8a9399f3b49acdda", "level": "note", "message": {"text": "Unused endpoint: GET /games/:id/stats"}, "properties": {"repobilityId": "5eadcbfdd73503ff", "scanner": "scanner-primary", "fingerprint": "8a9399f3b49acdda", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5315de6c65debe60", "level": "note", "message": {"text": "Unused endpoint: GET /join-info/:code"}, "properties": {"repobilityId": "7b5d9384be99881d", "scanner": "scanner-primary", "fingerprint": "5315de6c65debe60", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-54f9d73b31f351dd", "level": "note", "message": {"text": "Unused endpoint: POST /join/:code"}, "properties": {"repobilityId": "4615521107faf9f8", "scanner": "scanner-primary", "fingerprint": "54f9d73b31f351dd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a460cef1f3efcd6e", "level": "note", "message": {"text": "Unused endpoint: GET /gallery"}, "properties": {"repobilityId": "670ced19ab9e8bb9", "scanner": "scanner-primary", "fingerprint": "a460cef1f3efcd6e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ac7280181bec7648", "level": "note", "message": {"text": "Unused endpoint: GET /watch/:token"}, "properties": {"repobilityId": "fd047c8b5cde9b10", "scanner": "scanner-primary", "fingerprint": "ac7280181bec7648", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}