{"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-df82e6e434fe0c65", "name": "TODO/FIXME marker in shipping code \u2014 src/games/plugins/match-event-listener.ts:28", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/games/plugins/match-event-listener.ts:28"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6e0aa178ef33c87c", "name": "Stray `console.log` in TS/JS \u2014 src/html/@client/htmx.ts:7", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/html/@client/htmx.ts:7"}, "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-6e4768e3402cb5b6", "name": "Docker base image is tag-pinned but not digest-pinned: node:24.16.0-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:24.16.0-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-aa5acaa49eb8315b", "name": "Containers defined but no K8s/orchestration manifest found", "shortDescription": {"text": "Containers defined but no K8s/orchestration manifest found"}, "fullDescription": {"text": "Repo has Dockerfiles/compose but no Kubernetes/Nomad manifests. If the target deployment is K8s, the manifests may live in a separate ops repo."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-48b41b8d85174b86", "name": "Insecure pattern 'cors_wildcard' in docs/api/README.md:13", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in docs/api/README.md:13"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-030f2c020a762168", "name": "Insecure pattern 'cors_wildcard' in src/main.ts:87", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in src/main.ts:87"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b3b56af4be3f2925", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/html/@client/mention-completion.ts:17", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/html/@client/mention-completion.ts:17"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7efbda965f283c17", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "docker/metadata-action@v6 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1838a141491ce38c", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6ba9bfab5f283202", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "docker/metadata-action@v6 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b769174c9fcf8ea8", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea3b5e389d8c9c0f", "name": "Low test-to-source ratio", "shortDescription": {"text": "Low test-to-source ratio"}, "fullDescription": {"text": "97 tests / 656 src (ratio 0.15)."}, "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-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-4cd2157a5b83f835", "name": "Commented-code block (7 lines) in playwright.config.ts:40", "shortDescription": {"text": "Commented-code block (7 lines) in playwright.config.ts:40"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-1946ec471474784b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/logs-tf/fetch-log.ts:7", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/logs-tf/fetch-log.ts:7"}, "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-6e6e3dde0a917dc0", "name": "Commented-code block (5 lines) in src/games/pick-teams.ts:40", "shortDescription": {"text": "Commented-code block (5 lines) in src/games/pick-teams.ts:40"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ce80b5a6986882b1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/tf2-quick-server/client.ts:80", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/tf2-quick-server/client.ts:80"}, "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-367ebd28edaa2fe1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/atlas/send-heartbeat.ts:24", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/atlas/send-heartbeat.ts:24"}, "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-7f0875735140a68a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/discord/plugins/notify-substitute-request.ts:114", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/discord/plugins/notify-substitute-request.ts:114"}, "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-5e39f681f64050ac", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/discord/plugins/bump-join-prompt.ts:32", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/discord/plugins/bump-join-prompt.ts:32"}, "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-2abc615193a928d4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/steam/get-tf2-in-game-hours.ts:32", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/steam/get-tf2-in-game-hours.ts:32"}, "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-9d3f0374ab894a05", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/serveme-tf/cache.ts:16", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/serveme-tf/cache.ts:16"}, "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-3d122add75b65ecd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/serveme-tf/plugins/end-reservation.ts:19", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/serveme-tf/plugins/end-reservation.ts:19"}, "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-1f3c793126e910ed", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/twitch-tv/get-app-access-token.ts:22", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/twitch-tv/get-app-access-token.ts:22"}, "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-de52d289aeb6e9c5", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/twitch-tv/fetch-user-access-token.ts:24", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/twitch-tv/fetch-user-access-token.ts:24"}, "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-6d1494350d1bdb9d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/twitch-tv/get-streams.ts:10", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/twitch-tv/get-streams.ts:10"}, "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-f1af32e344143064", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/twitch-tv/fetch-user.ts:31", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/twitch-tv/fetch-user.ts:31"}, "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-c588bf36dd2f7fb0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/etf2l/get-player-profile.ts:19", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/etf2l/get-player-profile.ts:19"}, "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-4360165cb0d4eac3", "name": "Dangling fetch: GET https://logs.tf/api/v1/log/${logId} (src/logs-tf/fetch-log.ts:7)", "shortDescription": {"text": "Dangling fetch: GET https://logs.tf/api/v1/log/${logId} (src/logs-tf/fetch-log.ts:7)"}, "fullDescription": {"text": "`src/logs-tf/fetch-log.ts:7` calls `GET https://logs.tf/api/v1/log/${logId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/logs.tf/api/v1/log/<p>`\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-615e68322bd39963", "name": "Dangling fetch: GET /chat/mentions?q=${encodeURIComponent(query)} (src/html/@client/mention-completion.ts:70)", "shortDescription": {"text": "Dangling fetch: GET /chat/mentions?q=${encodeURIComponent(query)} (src/html/@client/mention-completion.ts:70)"}, "fullDescription": {"text": "`src/html/@client/mention-completion.ts:70` calls `GET /chat/mentions?q=${encodeURIComponent(query)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/chat/mentions`\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-7cf6d582b167e582", "name": "Dangling fetch: POST https://id.twitch.tv/oauth2/token?${params} (src/twitch-tv/fetch-user-access-token.ts:24)", "shortDescription": {"text": "Dangling fetch: POST https://id.twitch.tv/oauth2/token?${params} (src/twitch-tv/fetch-user-access-token.ts:24)"}, "fullDescription": {"text": "`src/twitch-tv/fetch-user-access-token.ts:24` calls `POST https://id.twitch.tv/oauth2/token?${params}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/id.twitch.tv/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-aa83a064978e9410", "name": "Dangling fetch: GET https://api.twitch.tv/helix/users (src/twitch-tv/fetch-user.ts:31)", "shortDescription": {"text": "Dangling fetch: GET https://api.twitch.tv/helix/users (src/twitch-tv/fetch-user.ts:31)"}, "fullDescription": {"text": "`src/twitch-tv/fetch-user.ts:31` calls `GET https://api.twitch.tv/helix/users` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.twitch.tv/helix/users`\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-4913e48f35530424", "name": "Unused endpoint: GET /auth/sign-out", "shortDescription": {"text": "Unused endpoint: GET /auth/sign-out"}, "fullDescription": {"text": "`src/auth/plugins/sign-out.ts` declares `GET /auth/sign-out` 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-8a90a086e5d71142", "name": "Unused endpoint: GET /auth/steam", "shortDescription": {"text": "Unused endpoint: GET /auth/steam"}, "fullDescription": {"text": "`src/auth/plugins/steam.ts` declares `GET /auth/steam` 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-ce8ab53cd219932a", "name": "Unused endpoint: GET /auth/steam/return", "shortDescription": {"text": "Unused endpoint: GET /auth/steam/return"}, "fullDescription": {"text": "`src/auth/plugins/steam.ts` declares `GET /auth/steam/return` 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-60839e9ab2180c19", "name": "Unused endpoint: GET /:filename.js", "shortDescription": {"text": "Unused endpoint: GET /:filename.js"}, "fullDescription": {"text": "`src/html/plugins/serve-bundles.ts` declares `GET /:filename.js` 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-9156ccb8e7763b54", "name": "Unused endpoint: GET /ws", "shortDescription": {"text": "Unused endpoint: GET /ws"}, "fullDescription": {"text": "`src/websocket/index.ts` declares `GET /ws` 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-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`src/routes/index.ts` declares `GET /` 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-fc2d8ae9e42191e3", "name": "Unused endpoint: GET /:selection?", "shortDescription": {"text": "Unused endpoint: GET /:selection?"}, "fullDescription": {"text": "`src/routes/players/:steamId/win-loss-chart/index.ts` declares `GET /:selection?` 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-67d28fa8cd6bb12f", "name": "Unused endpoint: PUT /", "shortDescription": {"text": "Unused endpoint: PUT /"}, "fullDescription": {"text": "`src/routes/players/:steamId/verify/index.ts` declares `PUT /` 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-3b30f4c0994a30b4", "name": "Unused endpoint: DELETE /", "shortDescription": {"text": "Unused endpoint: DELETE /"}, "fullDescription": {"text": "`src/routes/players/:steamId/edit/skill/index.ts` declares `DELETE /` 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-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`src/routes/players/:steamId/edit/skill/index.ts` declares `POST /` 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-97eb385961c3ba73", "name": "Unused endpoint: DELETE /game", "shortDescription": {"text": "Unused endpoint: DELETE /game"}, "fullDescription": {"text": "`src/routes/static-game-servers/:id/index.ts` declares `DELETE /game` 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-b6cd387852111bb6", "name": "Unused endpoint: PUT /disconnect", "shortDescription": {"text": "Unused endpoint: PUT /disconnect"}, "fullDescription": {"text": "`src/routes/twitch/index.ts` declares `PUT /disconnect` 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/21027"}, "properties": {"repository": "tf2pickup-org/tf2pickup", "repoUrl": "https://github.com/tf2pickup-org/tf2pickup", "branch": "main"}, "results": [{"ruleId": "scanner-df82e6e434fe0c65", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/games/plugins/match-event-listener.ts:28"}, "properties": {"repobilityId": "126941420277eebc", "scanner": "scanner-primary", "fingerprint": "df82e6e434fe0c65", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-6e0aa178ef33c87c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/html/@client/htmx.ts:7"}, "properties": {"repobilityId": "0651d81d6eddec4a", "scanner": "scanner-primary", "fingerprint": "6e0aa178ef33c87c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6e4768e3402cb5b6", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:24.16.0-slim"}, "properties": {"repobilityId": "8974413fd2e5e962", "scanner": "scanner-primary", "fingerprint": "6e4768e3402cb5b6", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-aa5acaa49eb8315b", "level": "note", "message": {"text": "Containers defined but no K8s/orchestration manifest found"}, "properties": {"repobilityId": "b230ea9b68736081", "scanner": "scanner-primary", "fingerprint": "aa5acaa49eb8315b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["coverage", "deployment"]}}, {"ruleId": "scanner-48b41b8d85174b86", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in docs/api/README.md:13"}, "properties": {"repobilityId": "61602fda5ff4c59c", "scanner": "scanner-primary", "fingerprint": "48b41b8d85174b86", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docs/api/README.md"}, "region": {"startLine": 13}}}]}, {"ruleId": "scanner-030f2c020a762168", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in src/main.ts:87"}, "properties": {"repobilityId": "f9df8c75aebf37b2", "scanner": "scanner-primary", "fingerprint": "030f2c020a762168", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/main.ts"}, "region": {"startLine": 87}}}]}, {"ruleId": "scanner-b3b56af4be3f2925", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/html/@client/mention-completion.ts:17"}, "properties": {"repobilityId": "104ddc1c99038b6e", "scanner": "scanner-primary", "fingerprint": "b3b56af4be3f2925", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/html/@client/mention-completion.ts"}, "region": {"startLine": 17}}}]}, {"ruleId": "scanner-7efbda965f283c17", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "5532ab43c439ba65", "scanner": "scanner-primary", "fingerprint": "7efbda965f283c17", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/test.yml"}, "region": {"startLine": 49}}}]}, {"ruleId": "scanner-7efbda965f283c17", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "62ad0442a529d2b4", "scanner": "scanner-primary", "fingerprint": "7efbda965f283c17", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/test.yml"}, "region": {"startLine": 61}}}]}, {"ruleId": "scanner-7efbda965f283c17", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "bafbf8df17e8e512", "scanner": "scanner-primary", "fingerprint": "7efbda965f283c17", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/test.yml"}, "region": {"startLine": 65}}}]}, {"ruleId": "scanner-7efbda965f283c17", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "936d59e0fe228df4", "scanner": "scanner-primary", "fingerprint": "7efbda965f283c17", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/test.yml"}, "region": {"startLine": 76}}}]}, {"ruleId": "scanner-7efbda965f283c17", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "14a46638d9083271", "scanner": "scanner-primary", "fingerprint": "7efbda965f283c17", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/test.yml"}, "region": {"startLine": 140}}}]}, {"ruleId": "scanner-7efbda965f283c17", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "936d59e0fe228df4", "scanner": "scanner-primary", "fingerprint": "7efbda965f283c17", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/test.yml"}, "region": {"startLine": 223}}}]}, {"ruleId": "scanner-7efbda965f283c17", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "14a46638d9083271", "scanner": "scanner-primary", "fingerprint": "7efbda965f283c17", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/test.yml"}, "region": {"startLine": 247}}}]}, {"ruleId": "scanner-7efbda965f283c17", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "936d59e0fe228df4", "scanner": "scanner-primary", "fingerprint": "7efbda965f283c17", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/test.yml"}, "region": {"startLine": 260}}}]}, {"ruleId": "scanner-1838a141491ce38c", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "b8fd4f5048f96576", "scanner": "scanner-primary", "fingerprint": "1838a141491ce38c", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/release.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-6ba9bfab5f283202", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "243948e99b4a5ffe", "scanner": "scanner-primary", "fingerprint": "6ba9bfab5f283202", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 29}}}]}, {"ruleId": "scanner-6ba9bfab5f283202", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "1505f291f72cd1c7", "scanner": "scanner-primary", "fingerprint": "6ba9bfab5f283202", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 41}}}]}, {"ruleId": "scanner-6ba9bfab5f283202", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "5b6bee9c4eeb9848", "scanner": "scanner-primary", "fingerprint": "6ba9bfab5f283202", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 48}}}]}, {"ruleId": "scanner-6ba9bfab5f283202", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "e1b2342bc0401269", "scanner": "scanner-primary", "fingerprint": "6ba9bfab5f283202", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 52}}}]}, {"ruleId": "scanner-b769174c9fcf8ea8", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "e34b6cb9b56931d2", "scanner": "scanner-primary", "fingerprint": "b769174c9fcf8ea8", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ea3b5e389d8c9c0f", "level": "note", "message": {"text": "Low test-to-source ratio"}, "properties": {"repobilityId": "ef7b2552cc00a375", "scanner": "scanner-primary", "fingerprint": "ea3b5e389d8c9c0f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["tests"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "4aa6284845070ecb", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "e52442294f22adb4", "scanner": "scanner-primary", "fingerprint": "ea8f3013f588db25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8424db9c75e04ba4", "level": "none", "message": {"text": "Very short observed git history"}, "properties": {"repobilityId": "01b06f65ac217228", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-4cd2157a5b83f835", "level": "none", "message": {"text": "Commented-code block (7 lines) in playwright.config.ts:40"}, "properties": {"repobilityId": "6c36f370531ec825", "scanner": "scanner-primary", "fingerprint": "4cd2157a5b83f835", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1946ec471474784b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/logs-tf/fetch-log.ts:7"}, "properties": {"repobilityId": "d56e0948932eabd7", "scanner": "scanner-primary", "fingerprint": "1946ec471474784b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6e6e3dde0a917dc0", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/games/pick-teams.ts:40"}, "properties": {"repobilityId": "92b2c12f9ac81114", "scanner": "scanner-primary", "fingerprint": "6e6e3dde0a917dc0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ce80b5a6986882b1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/tf2-quick-server/client.ts:80"}, "properties": {"repobilityId": "bf5c43ba39b3ec59", "scanner": "scanner-primary", "fingerprint": "ce80b5a6986882b1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-367ebd28edaa2fe1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/atlas/send-heartbeat.ts:24"}, "properties": {"repobilityId": "e6d9d2adbd0ac9ca", "scanner": "scanner-primary", "fingerprint": "367ebd28edaa2fe1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7f0875735140a68a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/discord/plugins/notify-substitute-request.ts:114"}, "properties": {"repobilityId": "27f0a4e94b1745b3", "scanner": "scanner-primary", "fingerprint": "7f0875735140a68a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5e39f681f64050ac", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/discord/plugins/bump-join-prompt.ts:32"}, "properties": {"repobilityId": "7dd2a95a2864afea", "scanner": "scanner-primary", "fingerprint": "5e39f681f64050ac", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2abc615193a928d4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/steam/get-tf2-in-game-hours.ts:32"}, "properties": {"repobilityId": "e9bd527612637a0e", "scanner": "scanner-primary", "fingerprint": "2abc615193a928d4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9d3f0374ab894a05", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/serveme-tf/cache.ts:16"}, "properties": {"repobilityId": "e32cb14779180a3c", "scanner": "scanner-primary", "fingerprint": "9d3f0374ab894a05", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3d122add75b65ecd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/serveme-tf/plugins/end-reservation.ts:19"}, "properties": {"repobilityId": "2e91f87aa917307e", "scanner": "scanner-primary", "fingerprint": "3d122add75b65ecd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1f3c793126e910ed", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/twitch-tv/get-app-access-token.ts:22"}, "properties": {"repobilityId": "12da2ab1b204e382", "scanner": "scanner-primary", "fingerprint": "1f3c793126e910ed", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-de52d289aeb6e9c5", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/twitch-tv/fetch-user-access-token.ts:24"}, "properties": {"repobilityId": "7ce136446929aaf9", "scanner": "scanner-primary", "fingerprint": "de52d289aeb6e9c5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6d1494350d1bdb9d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/twitch-tv/get-streams.ts:10"}, "properties": {"repobilityId": "51c3795bf26746a7", "scanner": "scanner-primary", "fingerprint": "6d1494350d1bdb9d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f1af32e344143064", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/twitch-tv/fetch-user.ts:31"}, "properties": {"repobilityId": "cf67ac63ae23edf1", "scanner": "scanner-primary", "fingerprint": "f1af32e344143064", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c588bf36dd2f7fb0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/etf2l/get-player-profile.ts:19"}, "properties": {"repobilityId": "f294ba0baa6f958c", "scanner": "scanner-primary", "fingerprint": "c588bf36dd2f7fb0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4360165cb0d4eac3", "level": "error", "message": {"text": "Dangling fetch: GET https://logs.tf/api/v1/log/${logId} (src/logs-tf/fetch-log.ts:7)"}, "properties": {"repobilityId": "af1cdc000bcf11b4", "scanner": "scanner-primary", "fingerprint": "4360165cb0d4eac3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-615e68322bd39963", "level": "error", "message": {"text": "Dangling fetch: GET /chat/mentions?q=${encodeURIComponent(query)} (src/html/@client/mention-completion.ts:70)"}, "properties": {"repobilityId": "2a3776f88804bf75", "scanner": "scanner-primary", "fingerprint": "615e68322bd39963", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-7cf6d582b167e582", "level": "error", "message": {"text": "Dangling fetch: POST https://id.twitch.tv/oauth2/token?${params} (src/twitch-tv/fetch-user-access-token.ts:24)"}, "properties": {"repobilityId": "9991dab367f400b5", "scanner": "scanner-primary", "fingerprint": "7cf6d582b167e582", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-aa83a064978e9410", "level": "error", "message": {"text": "Dangling fetch: GET https://api.twitch.tv/helix/users (src/twitch-tv/fetch-user.ts:31)"}, "properties": {"repobilityId": "50cfb8d95a2512cf", "scanner": "scanner-primary", "fingerprint": "aa83a064978e9410", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4913e48f35530424", "level": "note", "message": {"text": "Unused endpoint: GET /auth/sign-out"}, "properties": {"repobilityId": "30b4d98b4e44b802", "scanner": "scanner-primary", "fingerprint": "4913e48f35530424", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8a90a086e5d71142", "level": "note", "message": {"text": "Unused endpoint: GET /auth/steam"}, "properties": {"repobilityId": "4edb44dfc1c992f8", "scanner": "scanner-primary", "fingerprint": "8a90a086e5d71142", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ce8ab53cd219932a", "level": "note", "message": {"text": "Unused endpoint: GET /auth/steam/return"}, "properties": {"repobilityId": "29cfeaa4ddd249b3", "scanner": "scanner-primary", "fingerprint": "ce8ab53cd219932a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-60839e9ab2180c19", "level": "note", "message": {"text": "Unused endpoint: GET /:filename.js"}, "properties": {"repobilityId": "7bcd4f6b9c0cc01a", "scanner": "scanner-primary", "fingerprint": "60839e9ab2180c19", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9156ccb8e7763b54", "level": "note", "message": {"text": "Unused endpoint: GET /ws"}, "properties": {"repobilityId": "ce0b9071ccb0b42a", "scanner": "scanner-primary", "fingerprint": "9156ccb8e7763b54", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "bdd10f33d4d2bad6", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fc2d8ae9e42191e3", "level": "note", "message": {"text": "Unused endpoint: GET /:selection?"}, "properties": {"repobilityId": "04ca0ceb5603a9d9", "scanner": "scanner-primary", "fingerprint": "fc2d8ae9e42191e3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-67d28fa8cd6bb12f", "level": "note", "message": {"text": "Unused endpoint: PUT /"}, "properties": {"repobilityId": "6249442dc43dda0f", "scanner": "scanner-primary", "fingerprint": "67d28fa8cd6bb12f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3b30f4c0994a30b4", "level": "note", "message": {"text": "Unused endpoint: DELETE /"}, "properties": {"repobilityId": "1f74e18657df377b", "scanner": "scanner-primary", "fingerprint": "3b30f4c0994a30b4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "19ee870f9bd12e1c", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-97eb385961c3ba73", "level": "note", "message": {"text": "Unused endpoint: DELETE /game"}, "properties": {"repobilityId": "e8d30362b665fbcf", "scanner": "scanner-primary", "fingerprint": "97eb385961c3ba73", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b6cd387852111bb6", "level": "note", "message": {"text": "Unused endpoint: PUT /disconnect"}, "properties": {"repobilityId": "9579c9e5c767e20b", "scanner": "scanner-primary", "fingerprint": "b6cd387852111bb6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}