{"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-bead75b0f9233e05", "name": "No API endpoints detected", "shortDescription": {"text": "No API endpoints detected"}, "fullDescription": {"text": "The scanner did not find FastAPI/Flask/Express/NestJS/GraphQL/gRPC routes. If this repo exposes APIs, the framework may be unsupported."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "info", "confidence": 1.0}}, {"id": "scanner-75b48d5e6dc0c528", "name": "`truncate` class without `title=` for hover reveal \u2014 src/App.tsx:41", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/App.tsx:41"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-60a0a02717cb3f34", "name": "`truncate` class without `title=` for hover reveal \u2014 src/games/scrabble/index.tsx:651", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/games/scrabble/index.tsx:651"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5630340377c362f9", "name": "`truncate` class without `title=` for hover reveal \u2014 src/screens/admin.tsx:304", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/screens/admin.tsx:304"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d9e30509b0a7742f", "name": "`truncate` class without `title=` for hover reveal \u2014 src/screens/leaderboard.tsx:106", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/screens/leaderboard.tsx:106"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-97d9ebb8744a82c1", "name": "`truncate` class without `title=` for hover reveal \u2014 src/screens/profile.tsx:111", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/screens/profile.tsx:111"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-154e9c0790f2b11b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/screens/game-hub.tsx:249", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/screens/game-hub.tsx:249"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5c0530028113f2a7", "name": "`truncate` class without `title=` for hover reveal \u2014 src/screens/feed.tsx:553", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/screens/feed.tsx:553"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-9962d1f93ebb9517", "name": "`truncate` class without `title=` for hover reveal \u2014 src/screens/home.tsx:64", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/screens/home.tsx:64"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5cff8d64b78e8b9b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/GameErrorBoundary.tsx:46", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/GameErrorBoundary.tsx:46"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "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-ff1deda31b8bdf1e", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "google/osv-scanner-action/osv-scanner-action@v2.3.5 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-ea3b5e389d8c9c0f", "name": "Low test-to-source ratio", "shortDescription": {"text": "Low test-to-source ratio"}, "fullDescription": {"text": "13 tests / 118 src (ratio 0.11)."}, "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-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 33 placeholder/mock markers across 12 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-d9fa7815d5d826f9", "name": "Legacy-named symbol `nq_session_v2` in src/contexts/AuthContext.tsx:18", "shortDescription": {"text": "Legacy-named symbol `nq_session_v2` in src/contexts/AuthContext.tsx:18"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-427183c779c22519", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/contexts/AuthContext.tsx:22", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/contexts/AuthContext.tsx: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-86edc364f9ec3f70", "name": "Commented-code block (5 lines) in src/games/scrabble/words.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/games/scrabble/words.ts: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-8654e85653b73834", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/webhooks.ts:166", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/webhooks.ts:166"}, "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-cd0cf4e4bf0d8416", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/send-report-email.ts:38", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/send-report-email.ts:38"}, "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-59c8874f2ecb623a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 public/sw.js:55", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/sw.js:55"}, "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-12bfb4631d98c09e", "name": "Frontend route `/welcome` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/welcome` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3d47341344301241", "name": "Frontend route `/admin` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/admin` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7d854e5b74efa787", "name": "Frontend route `/invite/:gameSlug/:code` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/invite/:gameSlug/:code` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-16b246ee92e875dc", "name": "Frontend route `games` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `games` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-708a3a4005425ba9", "name": "Frontend route `leaderboard` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `leaderboard` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4b4cc0b0f8013db2", "name": "Frontend route `chat` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `chat` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-11feb210c2f50b50", "name": "Frontend route `profile` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `profile` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3c459dd0935422f7", "name": "Frontend route `play/:gameId` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `play/:gameId` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-30ccb24790f723cf", "name": "Frontend route `admin/reports` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `admin/reports` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/24241"}, "properties": {"repository": "antonio59/noodle-quest-v2", "repoUrl": "https://github.com/antonio59/noodle-quest-v2", "branch": "main"}, "results": [{"ruleId": "scanner-bead75b0f9233e05", "level": "none", "message": {"text": "No API endpoints detected"}, "properties": {"repobilityId": "0f8bb852027c38f8", "scanner": "scanner-primary", "fingerprint": "bead75b0f9233e05", "layer": "api", "severity": "info", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-75b48d5e6dc0c528", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/App.tsx:41"}, "properties": {"repobilityId": "903e15ea3fb71cd0", "scanner": "scanner-primary", "fingerprint": "75b48d5e6dc0c528", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-60a0a02717cb3f34", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/games/scrabble/index.tsx:651"}, "properties": {"repobilityId": "810a8228e9ffe751", "scanner": "scanner-primary", "fingerprint": "60a0a02717cb3f34", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5630340377c362f9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/screens/admin.tsx:304"}, "properties": {"repobilityId": "e8c47b7ed663bcbf", "scanner": "scanner-primary", "fingerprint": "5630340377c362f9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d9e30509b0a7742f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/screens/leaderboard.tsx:106"}, "properties": {"repobilityId": "980f3458a824ab8b", "scanner": "scanner-primary", "fingerprint": "d9e30509b0a7742f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-97d9ebb8744a82c1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/screens/profile.tsx:111"}, "properties": {"repobilityId": "c7c8ddd503b1e20c", "scanner": "scanner-primary", "fingerprint": "97d9ebb8744a82c1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-154e9c0790f2b11b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/screens/game-hub.tsx:249"}, "properties": {"repobilityId": "167e57e6bbd59cd1", "scanner": "scanner-primary", "fingerprint": "154e9c0790f2b11b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5c0530028113f2a7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/screens/feed.tsx:553"}, "properties": {"repobilityId": "2dea9bae8698552d", "scanner": "scanner-primary", "fingerprint": "5c0530028113f2a7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9962d1f93ebb9517", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/screens/home.tsx:64"}, "properties": {"repobilityId": "54a5b56d42871791", "scanner": "scanner-primary", "fingerprint": "9962d1f93ebb9517", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5cff8d64b78e8b9b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/GameErrorBoundary.tsx:46"}, "properties": {"repobilityId": "f27df107a04ed3be", "scanner": "scanner-primary", "fingerprint": "5cff8d64b78e8b9b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"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-ff1deda31b8bdf1e", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "99d74a3b42c64b63", "scanner": "scanner-primary", "fingerprint": "ff1deda31b8bdf1e", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/osv-scanner.yml"}, "region": {"startLine": 25}}}]}, {"ruleId": "scanner-ff1deda31b8bdf1e", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "924ad24d175de593", "scanner": "scanner-primary", "fingerprint": "ff1deda31b8bdf1e", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/osv-scanner.yml"}, "region": {"startLine": 35}}}]}, {"ruleId": "scanner-ff1deda31b8bdf1e", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "631589f51aaf9403", "scanner": "scanner-primary", "fingerprint": "ff1deda31b8bdf1e", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/osv-scanner.yml"}, "region": {"startLine": 45}}}]}, {"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-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "94d1b448af0d6aa7", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "5cf02be97b6107d5", "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": "66a6e5aea7c9875b", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-d9fa7815d5d826f9", "level": "note", "message": {"text": "Legacy-named symbol `nq_session_v2` in src/contexts/AuthContext.tsx:18"}, "properties": {"repobilityId": "846f9c3b3cc6bccb", "scanner": "scanner-primary", "fingerprint": "d9fa7815d5d826f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-427183c779c22519", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/contexts/AuthContext.tsx:22"}, "properties": {"repobilityId": "c18a13d53f8bcba1", "scanner": "scanner-primary", "fingerprint": "427183c779c22519", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-86edc364f9ec3f70", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/games/scrabble/words.ts:1"}, "properties": {"repobilityId": "aa8e1009413570e9", "scanner": "scanner-primary", "fingerprint": "86edc364f9ec3f70", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8654e85653b73834", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/webhooks.ts:166"}, "properties": {"repobilityId": "8bd116384fa9976e", "scanner": "scanner-primary", "fingerprint": "8654e85653b73834", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-cd0cf4e4bf0d8416", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/send-report-email.ts:38"}, "properties": {"repobilityId": "0ffab821f2bdea2c", "scanner": "scanner-primary", "fingerprint": "cd0cf4e4bf0d8416", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-59c8874f2ecb623a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/sw.js:55"}, "properties": {"repobilityId": "ad996616a1884f5d", "scanner": "scanner-primary", "fingerprint": "59c8874f2ecb623a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-12bfb4631d98c09e", "level": "warning", "message": {"text": "Frontend route `/welcome` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "a443ecf06ee5f3d3", "scanner": "scanner-primary", "fingerprint": "12bfb4631d98c09e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-3d47341344301241", "level": "warning", "message": {"text": "Frontend route `/admin` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "3060fc2a800f6a3c", "scanner": "scanner-primary", "fingerprint": "3d47341344301241", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-7d854e5b74efa787", "level": "warning", "message": {"text": "Frontend route `/invite/:gameSlug/:code` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "47f185775d464325", "scanner": "scanner-primary", "fingerprint": "7d854e5b74efa787", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-16b246ee92e875dc", "level": "warning", "message": {"text": "Frontend route `games` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "6f6ac60c232093f2", "scanner": "scanner-primary", "fingerprint": "16b246ee92e875dc", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-708a3a4005425ba9", "level": "warning", "message": {"text": "Frontend route `leaderboard` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "5be37ffc393f1c3c", "scanner": "scanner-primary", "fingerprint": "708a3a4005425ba9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-4b4cc0b0f8013db2", "level": "warning", "message": {"text": "Frontend route `chat` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "d0c7b307cc9c3e10", "scanner": "scanner-primary", "fingerprint": "4b4cc0b0f8013db2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-11feb210c2f50b50", "level": "warning", "message": {"text": "Frontend route `profile` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "96c44ef5fce161fb", "scanner": "scanner-primary", "fingerprint": "11feb210c2f50b50", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-3c459dd0935422f7", "level": "warning", "message": {"text": "Frontend route `play/:gameId` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "0037d9a9ba6e4d91", "scanner": "scanner-primary", "fingerprint": "3c459dd0935422f7", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-30ccb24790f723cf", "level": "warning", "message": {"text": "Frontend route `admin/reports` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "802fe53d933b671c", "scanner": "scanner-primary", "fingerprint": "30ccb24790f723cf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}]}]}