{"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-8fac432efc7be45b", "name": "Stray `console.log` in TS/JS \u2014 server.js:29", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server.js:29"}, "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-a4b3bfcfba39440b", "name": "Stray `console.log` in TS/JS \u2014 server/routes/media.js:53", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/routes/media.js:53"}, "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-91ac31ef9794838f", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/js/input.js:114", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/js/input.js:114"}, "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-6372cebde0220094", "name": "No auth library detected", "shortDescription": {"text": "No auth library detected"}, "fullDescription": {"text": "The scanner did not find any standard auth library (JWT, OAuth, NextAuth, Auth0, etc.). The repo has auth/admin/session surface indicators, so auth may live in custom code, in a separate service, or be missing."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d2a2f42530bc24cd", "name": "Very large file: server/routes/game.js (2354 lines)", "shortDescription": {"text": "Very large file: server/routes/game.js (2354 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0b2dceefbd09595d", "name": "Very large file: test/routes/game.test.js (1532 lines)", "shortDescription": {"text": "Very large file: test/routes/game.test.js (1532 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "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-faccb9061e9b52a0", "name": "No README detected", "shortDescription": {"text": "No README detected"}, "fullDescription": {"text": "No README file was found. Generated repos without README context are hard to operate, validate, or safely hand off."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 22 console/debugger/print-style debug statements in non-test source. This is a common fast-generation residue before production cleanup."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 15 placeholder/mock markers across 7 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "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, operator-readme. 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-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license, ci, operator-readme. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-13b7ea18e75496d1", "name": "Agent instruction/config may expose a secret: .claude/launch.json", "shortDescription": {"text": "Agent instruction/config may expose a secret: .claude/launch.json"}, "fullDescription": {"text": "Agent-facing files are routinely pasted into LLM/tool contexts. Move literal tokens, keys, and passwords into a secret manager or document them as placeholders only."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-2c5f98b152cddb6d", "name": "Agent authority lacks a verifier contract: .claude/launch.json", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/launch.json"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-04605e1e3e720913", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/media/generate.js:17", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/media/generate.js:17"}, "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-ee6d7c25b43b79e6", "name": "Commented-code block (5 lines) in server/engine/acts.js:5", "shortDescription": {"text": "Commented-code block (5 lines) in server/engine/acts.js:5"}, "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-479fe26ff07f3567", "name": "Commented-code block (8 lines) in server/engine/combat.js:170", "shortDescription": {"text": "Commented-code block (8 lines) in server/engine/combat.js:170"}, "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-783d559de0ad1721", "name": "Commented-code block (5 lines) in server/ai/chronicle.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in server/ai/chronicle.js:1"}, "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-07d48c6eaa5ac955", "name": "Commented-code block (5 lines) in server/ai/hints.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in server/ai/hints.js:1"}, "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-0858a0d9d99ab475", "name": "Commented-code block (5 lines) in server/ai/parley.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in server/ai/parley.js:1"}, "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-67f7d626c61733eb", "name": "Commented-code block (6 lines) in server/ai/llm.js:1", "shortDescription": {"text": "Commented-code block (6 lines) in server/ai/llm.js:1"}, "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-cfee1a2237ac9006", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/routes/media.js:42", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/routes/media.js:42"}, "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-3b87f6a7d17b3ae0", "name": "Commented-code block (5 lines) in server/routes/game.js:2319", "shortDescription": {"text": "Commented-code block (5 lines) in server/routes/game.js:2319"}, "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-8f4bb758e4a792ad", "name": "Commented-code block (5 lines) in public/js/creation-card.js:3", "shortDescription": {"text": "Commented-code block (5 lines) in public/js/creation-card.js:3"}, "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-a5785b45aafd0aaa", "name": "`fetch()` without try/.catch or AbortSignal \u2014 public/js/auth-api.js:9", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/js/auth-api.js:9"}, "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-0f7d6dbf6835db82", "name": "`fetch()` without try/.catch or AbortSignal \u2014 public/js/api.js:9", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/js/api.js:9"}, "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-1ec327799707da50", "name": "Commented-code block (5 lines) in public/js/narrative.js:3", "shortDescription": {"text": "Commented-code block (5 lines) in public/js/narrative.js:3"}, "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-0c885e6b8d98eae1", "name": "JS POST `/api/admin/seed` admin endpoint without auth \u2014 seed-endpoint.js:2", "shortDescription": {"text": "JS POST `/api/admin/seed` admin endpoint without auth \u2014 seed-endpoint.js:2"}, "fullDescription": {"text": "Admin-scoped JS route with no recognizable auth: no middleware-position guard, no router-level guard above it in this file, and no inline permission call within the first 15 lines of the handler. If auth is applied where this router is mounted, dismiss with reason `by_design` or tag the route `// public-by-design`."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c45b692b40cde0f4", "name": "Dangling fetch: POST https://fal.run/fal-ai/flux/dev (server/media/generate.js:8)", "shortDescription": {"text": "Dangling fetch: POST https://fal.run/fal-ai/flux/dev (server/media/generate.js:8)"}, "fullDescription": {"text": "`server/media/generate.js:8` calls `POST https://fal.run/fal-ai/flux/dev` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/fal.run/fal-ai/flux/dev`\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-ad693a0016428226", "name": "Dangling fetch: GET https://queue.fal.run/fal-ai/flux/dev/requests/${requestId}/status (server/routes/media.js:42)", "shortDescription": {"text": "Dangling fetch: GET https://queue.fal.run/fal-ai/flux/dev/requests/${requestId}/status (server/routes/media.js:42)"}, "fullDescription": {"text": "`server/routes/media.js:42` calls `GET https://queue.fal.run/fal-ai/flux/dev/requests/${requestId}/status` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/queue.fal.run/fal-ai/flux/dev/requests/<p>/status`\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-e213119caa9f0e0c", "name": "Dangling fetch: GET https://queue.fal.run/fal-ai/flux/dev/requests/${requestId} (server/routes/media.js:56)", "shortDescription": {"text": "Dangling fetch: GET https://queue.fal.run/fal-ai/flux/dev/requests/${requestId} (server/routes/media.js:56)"}, "fullDescription": {"text": "`server/routes/media.js:56` calls `GET https://queue.fal.run/fal-ai/flux/dev/requests/${requestId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/queue.fal.run/fal-ai/flux/dev/requests/<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-fd9808226f05d9a7", "name": "Dangling fetch: POST https://queue.fal.run/fal-ai/flux/dev (server/routes/media.js:91)", "shortDescription": {"text": "Dangling fetch: POST https://queue.fal.run/fal-ai/flux/dev (server/routes/media.js:91)"}, "fullDescription": {"text": "`server/routes/media.js:91` calls `POST https://queue.fal.run/fal-ai/flux/dev` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/queue.fal.run/fal-ai/flux/dev`\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-38db75d33c02f12e", "name": "Dangling fetch: POST https://api.elevenlabs.io/v1/text-to-speech/${voiceId || VOICES.narrator}/stream (server/routes/med", "shortDescription": {"text": "Dangling fetch: POST https://api.elevenlabs.io/v1/text-to-speech/${voiceId || VOICES.narrator}/stream (server/routes/media.js:152)"}, "fullDescription": {"text": "`server/routes/media.js:152` calls `POST https://api.elevenlabs.io/v1/text-to-speech/${voiceId || VOICES.narrator}/stream` 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.elevenlabs.io/v1/text-to-speech/<p>/stream`\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-fb71a3f27fd61400", "name": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/auth.test.js:11)", "shortDescription": {"text": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/auth.test.js:11)"}, "fullDescription": {"text": "`test/routes/auth.test.js:11` calls `GET http://127.0.0.1:${port}${path}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/127.0.0.1:/<p>/<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-350332bff1b59e3f", "name": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/profiles.test.js:11)", "shortDescription": {"text": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/profiles.test.js:11)"}, "fullDescription": {"text": "`test/routes/profiles.test.js:11` calls `GET http://127.0.0.1:${port}${path}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/127.0.0.1:/<p>/<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-0ae4f16cb1dbbdfa", "name": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/game.test.js:263)", "shortDescription": {"text": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/game.test.js:263)"}, "fullDescription": {"text": "`test/routes/game.test.js:263` calls `GET http://127.0.0.1:${port}${path}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/127.0.0.1:/<p>/<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-26e6a609663416a3", "name": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/game.test.js:281)", "shortDescription": {"text": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/game.test.js:281)"}, "fullDescription": {"text": "`test/routes/game.test.js:281` calls `GET http://127.0.0.1:${port}${path}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/127.0.0.1:/<p>/<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-ea7e8c77184a204b", "name": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/game-mercy.test.js:191)", "shortDescription": {"text": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/game-mercy.test.js:191)"}, "fullDescription": {"text": "`test/routes/game-mercy.test.js:191` calls `GET http://127.0.0.1:${port}${path}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/127.0.0.1:/<p>/<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-0bc1465829874222", "name": "Dangling fetch: GET /api/auth${path} (public/js/auth-api.js:9)", "shortDescription": {"text": "Dangling fetch: GET /api/auth${path} (public/js/auth-api.js:9)"}, "fullDescription": {"text": "`public/js/auth-api.js:9` calls `GET /api/auth${path}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/auth/<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-74d0a1ee9bd23637", "name": "Dangling fetch: GET /api/game${path} (public/js/api.js:9)", "shortDescription": {"text": "Dangling fetch: GET /api/game${path} (public/js/api.js:9)"}, "fullDescription": {"text": "`public/js/api.js:9` calls `GET /api/game${path}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/game/<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-b2b125c445c84aea", "name": "Unused endpoint: POST /api/admin/seed", "shortDescription": {"text": "Unused endpoint: POST /api/admin/seed"}, "fullDescription": {"text": "`seed-endpoint.js` declares `POST /api/admin/seed` 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-6eb452fbfb454d20", "name": "Unused endpoint: USE /api/auth", "shortDescription": {"text": "Unused endpoint: USE /api/auth"}, "fullDescription": {"text": "`server.js` declares `USE /api/auth` 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-a3ee268a6e5c7990", "name": "Unused endpoint: USE /api/profiles", "shortDescription": {"text": "Unused endpoint: USE /api/profiles"}, "fullDescription": {"text": "`server.js` declares `USE /api/profiles` 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-7c9dfd15daa8fddb", "name": "Unused endpoint: USE /api/game", "shortDescription": {"text": "Unused endpoint: USE /api/game"}, "fullDescription": {"text": "`server.js` declares `USE /api/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-dde3adb27bf7eebe", "name": "Unused endpoint: USE /api", "shortDescription": {"text": "Unused endpoint: USE /api"}, "fullDescription": {"text": "`server.js` declares `USE /api` 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-afc2f8c3d0490b93", "name": "Unused endpoint: GET /api/adventures", "shortDescription": {"text": "Unused endpoint: GET /api/adventures"}, "fullDescription": {"text": "`server.js` declares `GET /api/adventures` 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-718c1513a4dff45c", "name": "Unused endpoint: GET /api/adventures/:slug/locations", "shortDescription": {"text": "Unused endpoint: GET /api/adventures/:slug/locations"}, "fullDescription": {"text": "`server.js` declares `GET /api/adventures/:slug/locations` 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-4756b4c4da7d2088", "name": "Unused endpoint: GET /api/health", "shortDescription": {"text": "Unused endpoint: GET /api/health"}, "fullDescription": {"text": "`server.js` declares `GET /api/health` 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-304b6f2b403d93f7", "name": "Unused endpoint: POST /register", "shortDescription": {"text": "Unused endpoint: POST /register"}, "fullDescription": {"text": "`server/routes/auth.js` declares `POST /register` 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-618721b912bad1c2", "name": "Unused endpoint: POST /login", "shortDescription": {"text": "Unused endpoint: POST /login"}, "fullDescription": {"text": "`server/routes/auth.js` declares `POST /login` 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/routes/auth.js` 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-99fc36db98c134ce", "name": "Unused endpoint: POST /logout", "shortDescription": {"text": "Unused endpoint: POST /logout"}, "fullDescription": {"text": "`server/routes/auth.js` 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-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`server/routes/profiles.js` 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-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`server/routes/profiles.js` 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-ca8faac7450cd79a", "name": "Unused endpoint: POST /:profileId/select-character", "shortDescription": {"text": "Unused endpoint: POST /:profileId/select-character"}, "fullDescription": {"text": "`server/routes/profiles.js` declares `POST /:profileId/select-character` 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-1e8f6c0da51e432b", "name": "Unused endpoint: POST /:profileId/claim-guest-character", "shortDescription": {"text": "Unused endpoint: POST /:profileId/claim-guest-character"}, "fullDescription": {"text": "`server/routes/profiles.js` declares `POST /:profileId/claim-guest-character` 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-76a94a45533de416", "name": "Unused endpoint: POST /bootstrap", "shortDescription": {"text": "Unused endpoint: POST /bootstrap"}, "fullDescription": {"text": "`server/routes/game.js` declares `POST /bootstrap` 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-d388b5b75933d1a8", "name": "Unused endpoint: GET /characters", "shortDescription": {"text": "Unused endpoint: GET /characters"}, "fullDescription": {"text": "`server/routes/game.js` declares `GET /characters` 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-3a4009fb98746e0c", "name": "Unused endpoint: POST /characters", "shortDescription": {"text": "Unused endpoint: POST /characters"}, "fullDescription": {"text": "`server/routes/game.js` declares `POST /characters` 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-c60f1dc17088cdb6", "name": "Unused endpoint: POST /hall", "shortDescription": {"text": "Unused endpoint: POST /hall"}, "fullDescription": {"text": "`server/routes/game.js` declares `POST /hall` 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-446b07ce7788494d", "name": "Unused endpoint: GET /portrait-options", "shortDescription": {"text": "Unused endpoint: GET /portrait-options"}, "fullDescription": {"text": "`server/routes/game.js` declares `GET /portrait-options` 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-35052699c2bd0ca2", "name": "Unused endpoint: GET /portrait/:characterId/render.png", "shortDescription": {"text": "Unused endpoint: GET /portrait/:characterId/render.png"}, "fullDescription": {"text": "`server/routes/game.js` declares `GET /portrait/:characterId/render.png` 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-79d2139368e0d8aa", "name": "Unused endpoint: POST /start-adventure", "shortDescription": {"text": "Unused endpoint: POST /start-adventure"}, "fullDescription": {"text": "`server/routes/game.js` declares `POST /start-adventure` 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-993f2adb65ea4abe", "name": "Unused endpoint: POST /command", "shortDescription": {"text": "Unused endpoint: POST /command"}, "fullDescription": {"text": "`server/routes/game.js` declares `POST /command` 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/24676"}, "properties": {"repository": "boparker/eamon-main-hall", "repoUrl": "https://github.com/boparker/eamon-main-hall", "branch": "main"}, "results": [{"ruleId": "scanner-8fac432efc7be45b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server.js:29"}, "properties": {"repobilityId": "a9deebb5fdc93edc", "scanner": "scanner-primary", "fingerprint": "8fac432efc7be45b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a4b3bfcfba39440b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/routes/media.js:53"}, "properties": {"repobilityId": "ba2f2baae93387e3", "scanner": "scanner-primary", "fingerprint": "a4b3bfcfba39440b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-91ac31ef9794838f", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/js/input.js:114"}, "properties": {"repobilityId": "0925c3fae2211ef4", "scanner": "scanner-primary", "fingerprint": "91ac31ef9794838f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/js/input.js"}, "region": {"startLine": 114}}}]}, {"ruleId": "scanner-6372cebde0220094", "level": "warning", "message": {"text": "No auth library detected"}, "properties": {"repobilityId": "a5b6035a5bbf8054", "scanner": "scanner-primary", "fingerprint": "6372cebde0220094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["coverage", "auth"]}}, {"ruleId": "scanner-d2a2f42530bc24cd", "level": "note", "message": {"text": "Very large file: server/routes/game.js (2354 lines)"}, "properties": {"repobilityId": "5b2f2e5f09d72a52", "scanner": "scanner-primary", "fingerprint": "d2a2f42530bc24cd", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-0b2dceefbd09595d", "level": "note", "message": {"text": "Very large file: test/routes/game.test.js (1532 lines)"}, "properties": {"repobilityId": "3ee91f32f943453b", "scanner": "scanner-primary", "fingerprint": "0b2dceefbd09595d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "8d5da14836dfdde0", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-faccb9061e9b52a0", "level": "note", "message": {"text": "No README detected"}, "properties": {"repobilityId": "0ee05dccb3309585", "scanner": "scanner-primary", "fingerprint": "faccb9061e9b52a0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["docs", "readme", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "ef1c454d1a83ff36", "scanner": "scanner-primary", "fingerprint": "3ab5d313dda8e5f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["debug", "cleanup", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "11b98b0be22e7b71", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "63b739729ac499e9", "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": "b31a9c3a1b383098", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "6034e8c8ead45a70", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-13b7ea18e75496d1", "level": "error", "message": {"text": "Agent instruction/config may expose a secret: .claude/launch.json"}, "properties": {"repobilityId": "b4f6a7f5fd987efa", "scanner": "scanner-primary", "fingerprint": "13b7ea18e75496d1", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["agent-instructions", "secrets", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/launch.json"}, "region": {"startLine": 9}}}]}, {"ruleId": "scanner-2c5f98b152cddb6d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/launch.json"}, "properties": {"repobilityId": "0de48c0f4ab303d8", "scanner": "scanner-primary", "fingerprint": "2c5f98b152cddb6d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/launch.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-04605e1e3e720913", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/media/generate.js:17"}, "properties": {"repobilityId": "f78cd6cd6f59e156", "scanner": "scanner-primary", "fingerprint": "04605e1e3e720913", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ee6d7c25b43b79e6", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/engine/acts.js:5"}, "properties": {"repobilityId": "d9ee9bf9979823bc", "scanner": "scanner-primary", "fingerprint": "ee6d7c25b43b79e6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-479fe26ff07f3567", "level": "none", "message": {"text": "Commented-code block (8 lines) in server/engine/combat.js:170"}, "properties": {"repobilityId": "4607c02ec7833c98", "scanner": "scanner-primary", "fingerprint": "479fe26ff07f3567", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-783d559de0ad1721", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/ai/chronicle.js:1"}, "properties": {"repobilityId": "0746e6b6172d6930", "scanner": "scanner-primary", "fingerprint": "783d559de0ad1721", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-07d48c6eaa5ac955", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/ai/hints.js:1"}, "properties": {"repobilityId": "aac5e78f9b72e135", "scanner": "scanner-primary", "fingerprint": "07d48c6eaa5ac955", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0858a0d9d99ab475", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/ai/parley.js:1"}, "properties": {"repobilityId": "98aeae4a0f55ca5a", "scanner": "scanner-primary", "fingerprint": "0858a0d9d99ab475", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-67f7d626c61733eb", "level": "none", "message": {"text": "Commented-code block (6 lines) in server/ai/llm.js:1"}, "properties": {"repobilityId": "b51dd65c22ceb281", "scanner": "scanner-primary", "fingerprint": "67f7d626c61733eb", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cfee1a2237ac9006", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/routes/media.js:42"}, "properties": {"repobilityId": "e3a9289f2b60f4cb", "scanner": "scanner-primary", "fingerprint": "cfee1a2237ac9006", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3b87f6a7d17b3ae0", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/routes/game.js:2319"}, "properties": {"repobilityId": "f70580940e82421e", "scanner": "scanner-primary", "fingerprint": "3b87f6a7d17b3ae0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8f4bb758e4a792ad", "level": "none", "message": {"text": "Commented-code block (5 lines) in public/js/creation-card.js:3"}, "properties": {"repobilityId": "1234a5cdfeb29476", "scanner": "scanner-primary", "fingerprint": "8f4bb758e4a792ad", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a5785b45aafd0aaa", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/js/auth-api.js:9"}, "properties": {"repobilityId": "ef221ec89de2addd", "scanner": "scanner-primary", "fingerprint": "a5785b45aafd0aaa", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0f7d6dbf6835db82", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/js/api.js:9"}, "properties": {"repobilityId": "a67fc4bbddf22ad7", "scanner": "scanner-primary", "fingerprint": "0f7d6dbf6835db82", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1ec327799707da50", "level": "none", "message": {"text": "Commented-code block (5 lines) in public/js/narrative.js:3"}, "properties": {"repobilityId": "c8c88e1374136eaa", "scanner": "scanner-primary", "fingerprint": "1ec327799707da50", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0c885e6b8d98eae1", "level": "error", "message": {"text": "JS POST `/api/admin/seed` admin endpoint without auth \u2014 seed-endpoint.js:2"}, "properties": {"repobilityId": "82659a67011cdd06", "scanner": "scanner-primary", "fingerprint": "0c885e6b8d98eae1", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.js.admin_unauth"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "seed-endpoint.js"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-c45b692b40cde0f4", "level": "error", "message": {"text": "Dangling fetch: POST https://fal.run/fal-ai/flux/dev (server/media/generate.js:8)"}, "properties": {"repobilityId": "9ebfee103ab85819", "scanner": "scanner-primary", "fingerprint": "c45b692b40cde0f4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ad693a0016428226", "level": "error", "message": {"text": "Dangling fetch: GET https://queue.fal.run/fal-ai/flux/dev/requests/${requestId}/status (server/routes/media.js:42)"}, "properties": {"repobilityId": "365d2b06cddf2bfc", "scanner": "scanner-primary", "fingerprint": "ad693a0016428226", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e213119caa9f0e0c", "level": "error", "message": {"text": "Dangling fetch: GET https://queue.fal.run/fal-ai/flux/dev/requests/${requestId} (server/routes/media.js:56)"}, "properties": {"repobilityId": "924788bb1ed84f7d", "scanner": "scanner-primary", "fingerprint": "e213119caa9f0e0c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-fd9808226f05d9a7", "level": "error", "message": {"text": "Dangling fetch: POST https://queue.fal.run/fal-ai/flux/dev (server/routes/media.js:91)"}, "properties": {"repobilityId": "62899b09e911db04", "scanner": "scanner-primary", "fingerprint": "fd9808226f05d9a7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-38db75d33c02f12e", "level": "error", "message": {"text": "Dangling fetch: POST https://api.elevenlabs.io/v1/text-to-speech/${voiceId || VOICES.narrator}/stream (server/routes/media.js:152)"}, "properties": {"repobilityId": "4054aea42a9478ba", "scanner": "scanner-primary", "fingerprint": "38db75d33c02f12e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-fb71a3f27fd61400", "level": "error", "message": {"text": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/auth.test.js:11)"}, "properties": {"repobilityId": "a2dfd75d023fe40a", "scanner": "scanner-primary", "fingerprint": "fb71a3f27fd61400", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-350332bff1b59e3f", "level": "error", "message": {"text": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/profiles.test.js:11)"}, "properties": {"repobilityId": "58b5217f126382f8", "scanner": "scanner-primary", "fingerprint": "350332bff1b59e3f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-0ae4f16cb1dbbdfa", "level": "error", "message": {"text": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/game.test.js:263)"}, "properties": {"repobilityId": "f0645fe423637119", "scanner": "scanner-primary", "fingerprint": "0ae4f16cb1dbbdfa", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-26e6a609663416a3", "level": "error", "message": {"text": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/game.test.js:281)"}, "properties": {"repobilityId": "6ffaaebc184760c3", "scanner": "scanner-primary", "fingerprint": "26e6a609663416a3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ea7e8c77184a204b", "level": "error", "message": {"text": "Dangling fetch: GET http://127.0.0.1:${port}${path} (test/routes/game-mercy.test.js:191)"}, "properties": {"repobilityId": "01e9152535cb6633", "scanner": "scanner-primary", "fingerprint": "ea7e8c77184a204b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-0bc1465829874222", "level": "error", "message": {"text": "Dangling fetch: GET /api/auth${path} (public/js/auth-api.js:9)"}, "properties": {"repobilityId": "3055e214ba1bbb1f", "scanner": "scanner-primary", "fingerprint": "0bc1465829874222", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-74d0a1ee9bd23637", "level": "error", "message": {"text": "Dangling fetch: GET /api/game${path} (public/js/api.js:9)"}, "properties": {"repobilityId": "eafc2237dfb4be66", "scanner": "scanner-primary", "fingerprint": "74d0a1ee9bd23637", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b2b125c445c84aea", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/seed"}, "properties": {"repobilityId": "406cf037be0c8390", "scanner": "scanner-primary", "fingerprint": "b2b125c445c84aea", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6eb452fbfb454d20", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth"}, "properties": {"repobilityId": "166e9dd94854ec87", "scanner": "scanner-primary", "fingerprint": "6eb452fbfb454d20", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a3ee268a6e5c7990", "level": "note", "message": {"text": "Unused endpoint: USE /api/profiles"}, "properties": {"repobilityId": "1c7b3ea116f5170b", "scanner": "scanner-primary", "fingerprint": "a3ee268a6e5c7990", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7c9dfd15daa8fddb", "level": "note", "message": {"text": "Unused endpoint: USE /api/game"}, "properties": {"repobilityId": "2b3ceacb5624ae7f", "scanner": "scanner-primary", "fingerprint": "7c9dfd15daa8fddb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dde3adb27bf7eebe", "level": "note", "message": {"text": "Unused endpoint: USE /api"}, "properties": {"repobilityId": "a3eddf5065ffbf6c", "scanner": "scanner-primary", "fingerprint": "dde3adb27bf7eebe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-afc2f8c3d0490b93", "level": "note", "message": {"text": "Unused endpoint: GET /api/adventures"}, "properties": {"repobilityId": "18c2ebb855a7058b", "scanner": "scanner-primary", "fingerprint": "afc2f8c3d0490b93", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-718c1513a4dff45c", "level": "note", "message": {"text": "Unused endpoint: GET /api/adventures/:slug/locations"}, "properties": {"repobilityId": "52365b137c30f313", "scanner": "scanner-primary", "fingerprint": "718c1513a4dff45c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4756b4c4da7d2088", "level": "note", "message": {"text": "Unused endpoint: GET /api/health"}, "properties": {"repobilityId": "98e09bb8fcd7909b", "scanner": "scanner-primary", "fingerprint": "4756b4c4da7d2088", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-304b6f2b403d93f7", "level": "note", "message": {"text": "Unused endpoint: POST /register"}, "properties": {"repobilityId": "99d0a92f288848c3", "scanner": "scanner-primary", "fingerprint": "304b6f2b403d93f7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-618721b912bad1c2", "level": "note", "message": {"text": "Unused endpoint: POST /login"}, "properties": {"repobilityId": "2689f0f5e061c9d0", "scanner": "scanner-primary", "fingerprint": "618721b912bad1c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fd1dc91abf32142d", "level": "note", "message": {"text": "Unused endpoint: GET /me"}, "properties": {"repobilityId": "f2f4c5a268ac22c6", "scanner": "scanner-primary", "fingerprint": "fd1dc91abf32142d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-99fc36db98c134ce", "level": "note", "message": {"text": "Unused endpoint: POST /logout"}, "properties": {"repobilityId": "146fdbc715b6210a", "scanner": "scanner-primary", "fingerprint": "99fc36db98c134ce", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "a95e04ce00a56884", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "78f2f4fa75323563", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ca8faac7450cd79a", "level": "note", "message": {"text": "Unused endpoint: POST /:profileId/select-character"}, "properties": {"repobilityId": "1198ba7f19998987", "scanner": "scanner-primary", "fingerprint": "ca8faac7450cd79a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1e8f6c0da51e432b", "level": "note", "message": {"text": "Unused endpoint: POST /:profileId/claim-guest-character"}, "properties": {"repobilityId": "3fd693a9dd822a3f", "scanner": "scanner-primary", "fingerprint": "1e8f6c0da51e432b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-76a94a45533de416", "level": "note", "message": {"text": "Unused endpoint: POST /bootstrap"}, "properties": {"repobilityId": "f4f1d697e1b32153", "scanner": "scanner-primary", "fingerprint": "76a94a45533de416", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d388b5b75933d1a8", "level": "note", "message": {"text": "Unused endpoint: GET /characters"}, "properties": {"repobilityId": "b87155537d6305e4", "scanner": "scanner-primary", "fingerprint": "d388b5b75933d1a8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3a4009fb98746e0c", "level": "note", "message": {"text": "Unused endpoint: POST /characters"}, "properties": {"repobilityId": "26bf0a5398de80f9", "scanner": "scanner-primary", "fingerprint": "3a4009fb98746e0c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c60f1dc17088cdb6", "level": "note", "message": {"text": "Unused endpoint: POST /hall"}, "properties": {"repobilityId": "d3cdfac3e7dc6d0f", "scanner": "scanner-primary", "fingerprint": "c60f1dc17088cdb6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-446b07ce7788494d", "level": "note", "message": {"text": "Unused endpoint: GET /portrait-options"}, "properties": {"repobilityId": "9baabca727603de7", "scanner": "scanner-primary", "fingerprint": "446b07ce7788494d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-35052699c2bd0ca2", "level": "note", "message": {"text": "Unused endpoint: GET /portrait/:characterId/render.png"}, "properties": {"repobilityId": "ccf90e1458f4836e", "scanner": "scanner-primary", "fingerprint": "35052699c2bd0ca2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-79d2139368e0d8aa", "level": "note", "message": {"text": "Unused endpoint: POST /start-adventure"}, "properties": {"repobilityId": "2f4e2434f4fcdc33", "scanner": "scanner-primary", "fingerprint": "79d2139368e0d8aa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-993f2adb65ea4abe", "level": "note", "message": {"text": "Unused endpoint: POST /command"}, "properties": {"repobilityId": "e2dba09a5c6d3e6a", "scanner": "scanner-primary", "fingerprint": "993f2adb65ea4abe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}