{"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-0ee26cbaf27dd9c9", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 packages/ui/src/chart.jsx:61", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 packages/ui/src/chart.jsx:61"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-41be34dc99166a64", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/circles/MemberList.jsx:71", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/circles/MemberList.jsx:71"}, "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-9062a864909f4aee", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dashboard/RecentVideos.jsx:43", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dashboard/RecentVideos.jsx:43"}, "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-a5561c4e66a5e9cf", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dashboard/UpcomingPosts.jsx:52", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dashboard/UpcomingPosts.jsx:52"}, "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-99a000d437e02ba9", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dashboard/DraftPosts.jsx:50", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dashboard/DraftPosts.jsx:50"}, "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-5a9cb821ec8362da", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/billing/ReferralCard.jsx:59", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/billing/ReferralCard.jsx:59"}, "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-4332acf4ab95f7fa", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/media/StockVideoPanel.jsx:98", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/media/StockVideoPanel.jsx:98"}, "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-e3754be8c179f5ac", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/media/StockImagePanel.jsx:141", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/media/StockImagePanel.jsx:141"}, "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-5a37b55c15400af1", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/editor/MediaAttach.jsx:82", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/editor/MediaAttach.jsx:82"}, "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-01c621a5ec1e4b5a", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/src/components/platforms/PlatformCard.jsx:43", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/src/components/platforms/PlatformCard.jsx:43"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a37758b71554dac4", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/calendar/ContentIdeasPanel.jsx:59", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/calendar/ContentIdeasPanel.jsx:59"}, "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-13853d3327339bfe", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/trending/HashtagCard.jsx:36", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/trending/HashtagCard.jsx:36"}, "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-e6825d9e5b056893", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/shared/VideoThumbnailMock.jsx:42", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/shared/VideoThumbnailMock.jsx:42"}, "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-3e4f390edf567622", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/shared/SocialPostMock.jsx:45", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/shared/SocialPostMock.jsx:45"}, "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-d4678a590a552a4f", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Referrals.jsx:103", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Referrals.jsx:103"}, "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-882fe7e88ce42724", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/ContentSources.jsx:92", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/ContentSources.jsx:92"}, "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-cb17841267613b26", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/src/pages/BlogPost.jsx:121", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/src/pages/BlogPost.jsx:121"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-eefe91e881b6c854", "name": "TODO/FIXME marker in shipping code \u2014 apps/web/src/pages/Mission.jsx:8", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 apps/web/src/pages/Mission.jsx:8"}, "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-c3de2f78fcfaaeeb", "name": "Stray `console.log` in TS/JS \u2014 convex/admin.ts:33", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 convex/admin.ts:33"}, "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-42491110cc76e617", "name": "Stray `console.log` in TS/JS \u2014 convex/payments/stripeWebhook.ts:53", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 convex/payments/stripeWebhook.ts: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-ba03b66d41649146", "name": "Stray `console.log` in TS/JS \u2014 convex/payments/packs.ts:89", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 convex/payments/packs.ts:89"}, "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-5bfd40f9c2fda3ba", "name": "Insecure pattern 'dangerous_innerhtml' in packages/ui/src/chart.jsx:61", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in packages/ui/src/chart.jsx:61"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a3ee16423cf1df37", "name": "Insecure pattern 'dangerous_innerhtml' in apps/web/src/components/platforms/PlatformCard.jsx:43", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in apps/web/src/components/platforms/PlatformCard.jsx:43"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ce1ae03fd34e7cda", "name": "Insecure pattern 'dangerous_innerhtml' in apps/web/src/pages/BlogPost.jsx:121", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in apps/web/src/pages/BlogPost.jsx:121"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6b38de71321b766c", "name": "Insecure pattern 'local_storage_auth_token' in apps/web/src/pages/Connections.jsx:146", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in apps/web/src/pages/Connections.jsx:146"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-27924aa79fa4a517", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 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": "low", "confidence": 1.0}}, {"id": "scanner-cb639d9a10a47b23", "name": "package.json defines install-time lifecycle scripts", "shortDescription": {"text": "package.json defines install-time lifecycle scripts"}, "fullDescription": {"text": "preinstall/install/postinstall/prepare scripts execute during dependency installation. Review them carefully for network calls, obfuscation, shell execution, or credential access."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "8 test file(s) for 302 source file(s) (ratio 0.03). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-01f96f71d9907a8c", "name": "README lacks setup or run instructions", "shortDescription": {"text": "README lacks setup or run instructions"}, "fullDescription": {"text": "A README exists, but it does not contain common install/setup/run markers. This matches a frequent generated-code pattern: UI is present, operational handoff is thin."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-664e52d25af00096", "name": "Node manifest has dependencies but no lockfile: packages/lib/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/lib/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-eddecaa766cadff2", "name": "Node manifest has dependencies but no lockfile: packages/config/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/config/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-50218c90b43393bb", "name": "Node manifest has dependencies but no lockfile: packages/ui/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/ui/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4a9eb7dc7c6e3880", "name": "Node manifest has dependencies but no lockfile: apps/web/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 52 placeholder/mock markers across 30 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, operator-readme, lockfile. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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, operator-readme, lockfile. 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-bea357a6497a2d5d", "name": "Agent authority lacks a verifier contract: CLAUDE.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: CLAUDE.md"}, "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-fe44fa5ec9511b8a", "name": "Commented-code block (5 lines) in apps/web/src/main.jsx:14", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/src/main.jsx:14"}, "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-b4abebae245ceb05", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/components/media/ResizeModal.jsx:26", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/components/media/ResizeModal.jsx:26"}, "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-e535520af902485c", "name": "Commented-code block (5 lines) in convex/schema.ts:503", "shortDescription": {"text": "Commented-code block (5 lines) in convex/schema.ts:503"}, "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-a83f3e996b18e971", "name": "Commented-code block (7 lines) in convex/auth.config.ts:1", "shortDescription": {"text": "Commented-code block (7 lines) in convex/auth.config.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-fad354ef86393979", "name": "Commented-code block (5 lines) in convex/http.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in convex/http.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-f0d70fab9ea247bc", "name": "Commented-code block (5 lines) in convex/workspaces.ts:36", "shortDescription": {"text": "Commented-code block (5 lines) in convex/workspaces.ts:36"}, "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-ba83c8261a02682b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/media/aiImages.ts:36", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/media/aiImages.ts:36"}, "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-d038e9b935f5513e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/media/stockVideos.ts:49", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/media/stockVideos.ts:49"}, "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-f92a6c39f263b075", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/media/stockImages.ts:34", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/media/stockImages.ts:34"}, "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-9e4ea979a67dda94", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/media/gifs.ts:30", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/media/gifs.ts:30"}, "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-443d05e8a7ca26a5", "name": "Commented-code block (5 lines) in convex/publishing/oauthHelpers.ts:81", "shortDescription": {"text": "Commented-code block (5 lines) in convex/publishing/oauthHelpers.ts:81"}, "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-d20a269964bc4e4b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/publishing/metaHelpers.ts:41", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/publishing/metaHelpers.ts:41"}, "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-91429ff1625b8d1d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/publishing/youtubePublish.ts:64", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/publishing/youtubePublish.ts:64"}, "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-be57e641b6b8d01c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/publishing/oauth.ts:134", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/publishing/oauth.ts:134"}, "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-fac2eca1c57503a0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/publishing/directPublish.ts:63", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/publishing/directPublish.ts:63"}, "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-65df07ab4020db79", "name": "18 env vars used in code but missing from .env.example", "shortDescription": {"text": "18 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ADMIN_EMAILS`, `ANTHROPIC_API_KEY`, `CI`, `CLERK_JWT_ISSUER_DOMAIN`, `CLERK_JWT_ISSUER_DOMAIN_2`, `CLERK_SECRET_KEY`, `FROM_EMAIL`, `GIPHY_API_KEY` + 10 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2858ae7e1dc16ab1", "name": "Frontend route `/blog/:id` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `/blog/:id` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-2b17c57fd1116ab5", "name": "Frontend route `videos` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `videos` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-6cb76f1257d0471d", "name": "Frontend route `videos/:id` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `videos/:id` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-ed247604d799e069", "name": "Frontend route `posts` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `posts` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-e5e27ad662018936", "name": "Frontend route `posts/new` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `posts/new` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-5aac2bae60ad5d8d", "name": "Frontend route `posts/:id` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `posts/:id` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-77f7e8d61dc54135", "name": "Frontend route `calendar` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `calendar` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-b2e98a61144ddd6b", "name": "Frontend route `media` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `media` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-42c58cfe03a2adf2", "name": "Frontend route `sources` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `sources` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-3e53afc71e80ba2e", "name": "Frontend route `templates` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `templates` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-357d90d0b91f3033", "name": "Frontend route `campaigns` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `campaigns` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-9c0b29830e6c0af3", "name": "Frontend route `analytics` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `analytics` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-a5c30478895e7591", "name": "Frontend route `analytics/:id` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `analytics/:id` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-a11689357ee17f05", "name": "Frontend route `comments` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `comments` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-9d4332ac479ece66", "name": "Frontend route `trending` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `trending` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-e1ec013f4085e20c", "name": "Frontend route `connections` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `connections` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-b4fcaa983882e7f0", "name": "Frontend route `circles` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `circles` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-0f11d1b9326ed825", "name": "Frontend route `referrals` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `referrals` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-5a023b0cf59c4b54", "name": "Frontend route `billing` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `billing` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-e58cc33ab177360d", "name": "Frontend route `settings` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `settings` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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-74857791a7b4490c", "name": "Frontend route `pricing` has no Link/navigate to it \u2014 apps/web/src/App.jsx", "shortDescription": {"text": "Frontend route `pricing` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "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/25467"}, "properties": {"repository": "docmaasi/postpilot-help", "repoUrl": "https://github.com/docmaasi/postpilot-help", "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-0ee26cbaf27dd9c9", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 packages/ui/src/chart.jsx:61"}, "properties": {"repobilityId": "6cd7e5d432fd4ec1", "scanner": "scanner-primary", "fingerprint": "0ee26cbaf27dd9c9", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-41be34dc99166a64", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/circles/MemberList.jsx:71"}, "properties": {"repobilityId": "c9c2d392f995dda9", "scanner": "scanner-primary", "fingerprint": "41be34dc99166a64", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9062a864909f4aee", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dashboard/RecentVideos.jsx:43"}, "properties": {"repobilityId": "02a2906e47d6cd02", "scanner": "scanner-primary", "fingerprint": "9062a864909f4aee", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a5561c4e66a5e9cf", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dashboard/UpcomingPosts.jsx:52"}, "properties": {"repobilityId": "3c456a339c5eb509", "scanner": "scanner-primary", "fingerprint": "a5561c4e66a5e9cf", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-99a000d437e02ba9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dashboard/DraftPosts.jsx:50"}, "properties": {"repobilityId": "2a6f62fa6bf7560d", "scanner": "scanner-primary", "fingerprint": "99a000d437e02ba9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5a9cb821ec8362da", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/billing/ReferralCard.jsx:59"}, "properties": {"repobilityId": "5985a4a4ec71115d", "scanner": "scanner-primary", "fingerprint": "5a9cb821ec8362da", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4332acf4ab95f7fa", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/media/StockVideoPanel.jsx:98"}, "properties": {"repobilityId": "6e5d62ef01bcbfb8", "scanner": "scanner-primary", "fingerprint": "4332acf4ab95f7fa", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e3754be8c179f5ac", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/media/StockImagePanel.jsx:141"}, "properties": {"repobilityId": "8800ffa8533a6670", "scanner": "scanner-primary", "fingerprint": "e3754be8c179f5ac", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5a37b55c15400af1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/editor/MediaAttach.jsx:82"}, "properties": {"repobilityId": "0b56c8ea26a4737d", "scanner": "scanner-primary", "fingerprint": "5a37b55c15400af1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-01c621a5ec1e4b5a", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/src/components/platforms/PlatformCard.jsx:43"}, "properties": {"repobilityId": "bcac75efeb678435", "scanner": "scanner-primary", "fingerprint": "01c621a5ec1e4b5a", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-a37758b71554dac4", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/calendar/ContentIdeasPanel.jsx:59"}, "properties": {"repobilityId": "d835ffb0a9f8d127", "scanner": "scanner-primary", "fingerprint": "a37758b71554dac4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-13853d3327339bfe", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/trending/HashtagCard.jsx:36"}, "properties": {"repobilityId": "76ad684251843bfd", "scanner": "scanner-primary", "fingerprint": "13853d3327339bfe", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e6825d9e5b056893", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/shared/VideoThumbnailMock.jsx:42"}, "properties": {"repobilityId": "dc31d30a6716eb79", "scanner": "scanner-primary", "fingerprint": "e6825d9e5b056893", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3e4f390edf567622", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/shared/SocialPostMock.jsx:45"}, "properties": {"repobilityId": "eae3cff9330a4515", "scanner": "scanner-primary", "fingerprint": "3e4f390edf567622", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d4678a590a552a4f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Referrals.jsx:103"}, "properties": {"repobilityId": "7789b8e67ce307ce", "scanner": "scanner-primary", "fingerprint": "d4678a590a552a4f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-882fe7e88ce42724", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/ContentSources.jsx:92"}, "properties": {"repobilityId": "09984a5eb682358b", "scanner": "scanner-primary", "fingerprint": "882fe7e88ce42724", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-cb17841267613b26", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/src/pages/BlogPost.jsx:121"}, "properties": {"repobilityId": "6af9ef19f430ac12", "scanner": "scanner-primary", "fingerprint": "cb17841267613b26", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-eefe91e881b6c854", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 apps/web/src/pages/Mission.jsx:8"}, "properties": {"repobilityId": "ae59fba6a38d4f80", "scanner": "scanner-primary", "fingerprint": "eefe91e881b6c854", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-c3de2f78fcfaaeeb", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 convex/admin.ts:33"}, "properties": {"repobilityId": "edf65678c9554f71", "scanner": "scanner-primary", "fingerprint": "c3de2f78fcfaaeeb", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-42491110cc76e617", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 convex/payments/stripeWebhook.ts:53"}, "properties": {"repobilityId": "2bd4cb5ac02900b2", "scanner": "scanner-primary", "fingerprint": "42491110cc76e617", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ba03b66d41649146", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 convex/payments/packs.ts:89"}, "properties": {"repobilityId": "78019143f4f5d79a", "scanner": "scanner-primary", "fingerprint": "ba03b66d41649146", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5bfd40f9c2fda3ba", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in packages/ui/src/chart.jsx:61"}, "properties": {"repobilityId": "cc014cc78a3cfba3", "scanner": "scanner-primary", "fingerprint": "5bfd40f9c2fda3ba", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/ui/src/chart.jsx"}, "region": {"startLine": 61}}}]}, {"ruleId": "scanner-a3ee16423cf1df37", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in apps/web/src/components/platforms/PlatformCard.jsx:43"}, "properties": {"repobilityId": "3b20587a2e9ad7f9", "scanner": "scanner-primary", "fingerprint": "a3ee16423cf1df37", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/src/components/platforms/PlatformCard.jsx"}, "region": {"startLine": 43}}}]}, {"ruleId": "scanner-ce1ae03fd34e7cda", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in apps/web/src/pages/BlogPost.jsx:121"}, "properties": {"repobilityId": "153a12f6019db14e", "scanner": "scanner-primary", "fingerprint": "ce1ae03fd34e7cda", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/src/pages/BlogPost.jsx"}, "region": {"startLine": 121}}}]}, {"ruleId": "scanner-6b38de71321b766c", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in apps/web/src/pages/Connections.jsx:146"}, "properties": {"repobilityId": "dd9873bd8963077e", "scanner": "scanner-primary", "fingerprint": "6b38de71321b766c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/src/pages/Connections.jsx"}, "region": {"startLine": 146}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "ae16880318b99912", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 16}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "54597edb7f5bad38", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 19}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 22}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "bd7f3c1c34d83159", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 46}}}]}, {"ruleId": "scanner-cb639d9a10a47b23", "level": "note", "message": {"text": "package.json defines install-time lifecycle scripts"}, "properties": {"repobilityId": "b86179956da3a4a8", "scanner": "scanner-primary", "fingerprint": "cb639d9a10a47b23", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "npm", "install-scripts"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "484266dba64d564f", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-01f96f71d9907a8c", "level": "note", "message": {"text": "README lacks setup or run instructions"}, "properties": {"repobilityId": "5ce50aa0d1024c79", "scanner": "scanner-primary", "fingerprint": "01f96f71d9907a8c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["docs", "readme", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-664e52d25af00096", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/lib/package.json"}, "properties": {"repobilityId": "174354ac67c3b362", "scanner": "scanner-primary", "fingerprint": "664e52d25af00096", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/lib/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-eddecaa766cadff2", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/config/package.json"}, "properties": {"repobilityId": "03931bf3537e3eaf", "scanner": "scanner-primary", "fingerprint": "eddecaa766cadff2", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/config/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-50218c90b43393bb", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/ui/package.json"}, "properties": {"repobilityId": "637e26a8c754e81d", "scanner": "scanner-primary", "fingerprint": "50218c90b43393bb", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/ui/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4a9eb7dc7c6e3880", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "properties": {"repobilityId": "6c1704bf24cf19ac", "scanner": "scanner-primary", "fingerprint": "4a9eb7dc7c6e3880", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "11cfedd619c58373", "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": "1acc0e2c4e977e38", "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": "8d0cf684582db15f", "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": "e4a0e0e8ec36c75d", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-bea357a6497a2d5d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: CLAUDE.md"}, "properties": {"repobilityId": "aae72df3934829ac", "scanner": "scanner-primary", "fingerprint": "bea357a6497a2d5d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "CLAUDE.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-fe44fa5ec9511b8a", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/src/main.jsx:14"}, "properties": {"repobilityId": "c82cacc012e50035", "scanner": "scanner-primary", "fingerprint": "fe44fa5ec9511b8a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b4abebae245ceb05", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/components/media/ResizeModal.jsx:26"}, "properties": {"repobilityId": "83ec6f0c87d1584c", "scanner": "scanner-primary", "fingerprint": "b4abebae245ceb05", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e535520af902485c", "level": "none", "message": {"text": "Commented-code block (5 lines) in convex/schema.ts:503"}, "properties": {"repobilityId": "4865d28e40a58711", "scanner": "scanner-primary", "fingerprint": "e535520af902485c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a83f3e996b18e971", "level": "none", "message": {"text": "Commented-code block (7 lines) in convex/auth.config.ts:1"}, "properties": {"repobilityId": "f90768c4e814539f", "scanner": "scanner-primary", "fingerprint": "a83f3e996b18e971", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-fad354ef86393979", "level": "none", "message": {"text": "Commented-code block (5 lines) in convex/http.ts:1"}, "properties": {"repobilityId": "147ca9de310c707a", "scanner": "scanner-primary", "fingerprint": "fad354ef86393979", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f0d70fab9ea247bc", "level": "none", "message": {"text": "Commented-code block (5 lines) in convex/workspaces.ts:36"}, "properties": {"repobilityId": "106c332e12959017", "scanner": "scanner-primary", "fingerprint": "f0d70fab9ea247bc", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ba83c8261a02682b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/media/aiImages.ts:36"}, "properties": {"repobilityId": "e5e09d6946dd41e9", "scanner": "scanner-primary", "fingerprint": "ba83c8261a02682b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d038e9b935f5513e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/media/stockVideos.ts:49"}, "properties": {"repobilityId": "308ce1a0879b467c", "scanner": "scanner-primary", "fingerprint": "d038e9b935f5513e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f92a6c39f263b075", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/media/stockImages.ts:34"}, "properties": {"repobilityId": "e5b2d8c5413bc768", "scanner": "scanner-primary", "fingerprint": "f92a6c39f263b075", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9e4ea979a67dda94", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/media/gifs.ts:30"}, "properties": {"repobilityId": "a3235d99f715ef1a", "scanner": "scanner-primary", "fingerprint": "9e4ea979a67dda94", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-443d05e8a7ca26a5", "level": "none", "message": {"text": "Commented-code block (5 lines) in convex/publishing/oauthHelpers.ts:81"}, "properties": {"repobilityId": "dec1c3760c2d7822", "scanner": "scanner-primary", "fingerprint": "443d05e8a7ca26a5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d20a269964bc4e4b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/publishing/metaHelpers.ts:41"}, "properties": {"repobilityId": "660f8d1a981c34a2", "scanner": "scanner-primary", "fingerprint": "d20a269964bc4e4b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-91429ff1625b8d1d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/publishing/youtubePublish.ts:64"}, "properties": {"repobilityId": "71711da770253271", "scanner": "scanner-primary", "fingerprint": "91429ff1625b8d1d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-be57e641b6b8d01c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/publishing/oauth.ts:134"}, "properties": {"repobilityId": "69a69e5a7fb22b9b", "scanner": "scanner-primary", "fingerprint": "be57e641b6b8d01c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-fac2eca1c57503a0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/publishing/directPublish.ts:63"}, "properties": {"repobilityId": "5d2f43b33335c141", "scanner": "scanner-primary", "fingerprint": "fac2eca1c57503a0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-65df07ab4020db79", "level": "note", "message": {"text": "18 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "5e334d56f52c02e1", "scanner": "scanner-primary", "fingerprint": "65df07ab4020db79", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-2858ae7e1dc16ab1", "level": "warning", "message": {"text": "Frontend route `/blog/:id` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "31b81c156f1a0caa", "scanner": "scanner-primary", "fingerprint": "2858ae7e1dc16ab1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-2b17c57fd1116ab5", "level": "warning", "message": {"text": "Frontend route `videos` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "cc5c76cb450a9b79", "scanner": "scanner-primary", "fingerprint": "2b17c57fd1116ab5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-6cb76f1257d0471d", "level": "warning", "message": {"text": "Frontend route `videos/:id` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "61376fbdcd5e4566", "scanner": "scanner-primary", "fingerprint": "6cb76f1257d0471d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-ed247604d799e069", "level": "warning", "message": {"text": "Frontend route `posts` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "afb3023ae93fc36f", "scanner": "scanner-primary", "fingerprint": "ed247604d799e069", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-e5e27ad662018936", "level": "warning", "message": {"text": "Frontend route `posts/new` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "f5b6f7041b3adff3", "scanner": "scanner-primary", "fingerprint": "e5e27ad662018936", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-5aac2bae60ad5d8d", "level": "warning", "message": {"text": "Frontend route `posts/:id` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "e92de20f9e4160b3", "scanner": "scanner-primary", "fingerprint": "5aac2bae60ad5d8d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-77f7e8d61dc54135", "level": "warning", "message": {"text": "Frontend route `calendar` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "ab8a26186afde3a0", "scanner": "scanner-primary", "fingerprint": "77f7e8d61dc54135", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-b2e98a61144ddd6b", "level": "warning", "message": {"text": "Frontend route `media` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "ceadaedbade13923", "scanner": "scanner-primary", "fingerprint": "b2e98a61144ddd6b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-42c58cfe03a2adf2", "level": "warning", "message": {"text": "Frontend route `sources` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "13cb8bdff2290d9c", "scanner": "scanner-primary", "fingerprint": "42c58cfe03a2adf2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-3e53afc71e80ba2e", "level": "warning", "message": {"text": "Frontend route `templates` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "bacb601145be8655", "scanner": "scanner-primary", "fingerprint": "3e53afc71e80ba2e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-357d90d0b91f3033", "level": "warning", "message": {"text": "Frontend route `campaigns` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "9e71527f4a249579", "scanner": "scanner-primary", "fingerprint": "357d90d0b91f3033", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-9c0b29830e6c0af3", "level": "warning", "message": {"text": "Frontend route `analytics` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "a06405d8bf225c8a", "scanner": "scanner-primary", "fingerprint": "9c0b29830e6c0af3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-a5c30478895e7591", "level": "warning", "message": {"text": "Frontend route `analytics/:id` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "34bdc6900815b0f8", "scanner": "scanner-primary", "fingerprint": "a5c30478895e7591", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-a11689357ee17f05", "level": "warning", "message": {"text": "Frontend route `comments` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "f35cc30b464ec747", "scanner": "scanner-primary", "fingerprint": "a11689357ee17f05", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-9d4332ac479ece66", "level": "warning", "message": {"text": "Frontend route `trending` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "d8c42d5b61422068", "scanner": "scanner-primary", "fingerprint": "9d4332ac479ece66", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-e1ec013f4085e20c", "level": "warning", "message": {"text": "Frontend route `connections` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "98b249f2192721f5", "scanner": "scanner-primary", "fingerprint": "e1ec013f4085e20c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-b4fcaa983882e7f0", "level": "warning", "message": {"text": "Frontend route `circles` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "ff5bbb647bb4f128", "scanner": "scanner-primary", "fingerprint": "b4fcaa983882e7f0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-0f11d1b9326ed825", "level": "warning", "message": {"text": "Frontend route `referrals` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "0441308ef4e38d31", "scanner": "scanner-primary", "fingerprint": "0f11d1b9326ed825", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-5a023b0cf59c4b54", "level": "warning", "message": {"text": "Frontend route `billing` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "1322ef1d449ae527", "scanner": "scanner-primary", "fingerprint": "5a023b0cf59c4b54", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-e58cc33ab177360d", "level": "warning", "message": {"text": "Frontend route `settings` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "b4c76a4bb2fbce31", "scanner": "scanner-primary", "fingerprint": "e58cc33ab177360d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-74857791a7b4490c", "level": "warning", "message": {"text": "Frontend route `pricing` has no Link/navigate to it \u2014 apps/web/src/App.jsx"}, "properties": {"repobilityId": "2ffa8d8038543d54", "scanner": "scanner-primary", "fingerprint": "74857791a7b4490c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}]}]}