{"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-89380598fefe7418", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AssignTeacherDialog.tsx:155", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AssignTeacherDialog.tsx:155"}, "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-440dcde0c522b1bd", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/MediaPreview.tsx:123", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/MediaPreview.tsx:123"}, "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-f83bea6ca90be1d7", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminAdminsPanel.tsx:107", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminAdminsPanel.tsx:107"}, "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-0b16003f44f10445", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/StudentPicker.tsx:135", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/StudentPicker.tsx:135"}, "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-724079d203a75ce3", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/FeedbackThread.tsx:188", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/FeedbackThread.tsx:188"}, "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-c83dfa64e5a077ef", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminOnboardingVideos.tsx:564", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminOnboardingVideos.tsx:564"}, "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-daf6762d3f2cc03a", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/TeacherInvites.tsx:172", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/TeacherInvites.tsx:172"}, "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-3df30f822b3b8d68", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/InboxList.tsx:259", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/InboxList.tsx:259"}, "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-2d18e973f50e0cb6", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminTagsManager.tsx:134", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminTagsManager.tsx:134"}, "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-a15bc83df760078b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminUsersTable.tsx:264", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminUsersTable.tsx:264"}, "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-8716e82bc34cae96", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminEngagementPanel.tsx:112", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminEngagementPanel.tsx:112"}, "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-075c8271bb023064", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/MediaPicker.tsx:830", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/MediaPicker.tsx:830"}, "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-ca2e6e017432eb1d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AppShell.tsx:34", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AppShell.tsx:34"}, "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-7457fc544660ccab", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/ThreadView.tsx:368", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ThreadView.tsx:368"}, "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-f84f6bbc985c65f5", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/SearchableUserChecklist.tsx:123", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/SearchableUserChecklist.tsx:123"}, "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-76ae0f5bc145bd89", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/StudentCardDialog.tsx:129", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/StudentCardDialog.tsx:129"}, "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-5b80d6b8a6165dd6", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminTutorWorkPanel.tsx:201", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminTutorWorkPanel.tsx:201"}, "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-918651a4c6b5eab5", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/FeedbackList.tsx:98", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/FeedbackList.tsx: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-53369f298f765f6e", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AcquisitionSources.tsx:216", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AcquisitionSources.tsx:216"}, "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-7eeca5682bcd5b36", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminConnectionsPanel.tsx:362", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminConnectionsPanel.tsx:362"}, "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-f980392d4c52822a", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/SubscriptionDialog.tsx:95", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/SubscriptionDialog.tsx:95"}, "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-5d7c8936279e82fb", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/BannedUsersPanel.tsx:53", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/BannedUsersPanel.tsx:53"}, "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-59ba4741e3e86649", "name": "TODO/FIXME marker in shipping code \u2014 src/app/api/student/summary/route.ts:118", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/app/api/student/summary/route.ts:118"}, "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-a13bdaa3637c6624", "name": "Insecure pattern 'node_child_process' in next.config.mjs:1", "shortDescription": {"text": "Insecure pattern 'node_child_process' in next.config.mjs:1"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-799f345ec1261ab6", "name": "Insecure pattern 'exec_used' in src/lib/video-compress.ts:49", "shortDescription": {"text": "Insecure pattern 'exec_used' in src/lib/video-compress.ts:49"}, "fullDescription": {"text": "Found a known-risky pattern (exec_used). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-4601e3ad3bb28677", "name": "No CI/CD pipelines detected", "shortDescription": {"text": "No CI/CD pipelines detected"}, "fullDescription": {"text": "No GitHub Actions, GitLab CI, or CircleCI configs found. Without CI you can't gate deploys on tests/lints."}, "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": "33 tests / 225 src (ratio 0.15)."}, "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-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 28 console/debugger/print-style debug statements in non-test source. This is a common fast-generation residue before production cleanup."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 35 placeholder/mock markers across 21 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci. 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": "low", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license, ci. 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-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6006152df11cf55a", "name": "Commented-code block (5 lines) in scripts/db-push.mjs:2", "shortDescription": {"text": "Commented-code block (5 lines) in scripts/db-push.mjs:2"}, "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-87d2db001632f8ac", "name": "Commented-code block (6 lines) in scripts/sync-qstash.mjs:2", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/sync-qstash.mjs:2"}, "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-a3c6bfb6f39a2e23", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/sync-qstash.mjs:75", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/sync-qstash.mjs:75"}, "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-90d19ede2fbcbd0d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/list-qstash.mjs:21", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/list-qstash.mjs:21"}, "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-02a20f0abf5ab780", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AssignTeacherDialog.tsx:55", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AssignTeacherDialog.tsx: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-f4d1e59694d547c4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminAdminsPanel.tsx:65", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminAdminsPanel.tsx:65"}, "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-d8c22a46e0b8b4d8", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/MiniAppMenu.tsx:93", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/MiniAppMenu.tsx:93"}, "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-c1523192ea76cb5d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/StudentPicker.tsx:34", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/StudentPicker.tsx: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-e28685542bc55c2a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/FeedbackThread.tsx:75", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/FeedbackThread.tsx:75"}, "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-efe0e8230517c1bb", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminOnboardingVideos.tsx:71", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminOnboardingVideos.tsx:71"}, "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-9b4b96810adfb801", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/TagPicker.tsx:28", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/TagPicker.tsx:28"}, "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-66c7fc8ff6d6b657", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/TeacherInvites.tsx:34", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/TeacherInvites.tsx: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-71a6fc5a0e414d5f", "name": "Commented-code block (5 lines) in src/components/InboxList.tsx:90", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/InboxList.tsx:90"}, "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-086e0cb025727b25", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/InboxList.tsx:73", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/InboxList.tsx:73"}, "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-408e9a5ec6a9b795", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AuditLog.tsx:183", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AuditLog.tsx:183"}, "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-364e0fbce6641e4f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminTagsManager.tsx:32", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminTagsManager.tsx:32"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-423633974a2974a7", "name": "Commented-code block (7 lines) in src/components/AdminUsersTable.tsx:63", "shortDescription": {"text": "Commented-code block (7 lines) in src/components/AdminUsersTable.tsx:63"}, "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-422c7617c41db622", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminUsersTable.tsx:93", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminUsersTable.tsx:93"}, "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-063e0f8bea6a512d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminEngagementPanel.tsx:48", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminEngagementPanel.tsx:48"}, "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-cf32c82fa917adec", "name": "Commented-code block (6 lines) in src/components/MediaPicker.tsx:184", "shortDescription": {"text": "Commented-code block (6 lines) in src/components/MediaPicker.tsx:184"}, "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-b97230beddc62dd2", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/MediaPicker.tsx:82", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/MediaPicker.tsx:82"}, "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-a31009a1d43ae096", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/FeedbackChat.tsx:56", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/FeedbackChat.tsx:56"}, "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-24cc34d89c8f886f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditTranscriptDialog.tsx:47", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditTranscriptDialog.tsx:47"}, "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-f68293108bfd1896", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/ThreadView.tsx:76", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/ThreadView.tsx:76"}, "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-b007e37307361e6b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditPreferredNameDialog.tsx:59", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditPreferredNameDialog.tsx:59"}, "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-e53e6d0599029ba9", "name": "Commented-code block (6 lines) in src/components/MessageBubble.tsx:763", "shortDescription": {"text": "Commented-code block (6 lines) in src/components/MessageBubble.tsx:763"}, "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-5188d8dcdc27c268", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditMediaItemDialog.tsx:46", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditMediaItemDialog.tsx:46"}, "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-9aa2143e874121b0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/SubscriberSummary.tsx:35", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/SubscriberSummary.tsx:35"}, "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-5e2436989420d7a0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminSettingsPanel.tsx:40", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminSettingsPanel.tsx:40"}, "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-4fb452584520cf7f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/PlaybackProvider.tsx:65", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/PlaybackProvider.tsx:65"}, "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-7651866cbc325d0c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/FeedbackList.tsx:43", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/FeedbackList.tsx:43"}, "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-7c94139a6db6d2ee", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AcquisitionSources.tsx:35", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AcquisitionSources.tsx:35"}, "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-6c07c87793937813", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/SubscriptionDialog.tsx:58", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/SubscriptionDialog.tsx:58"}, "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-108a2b7f74ac46a4", "name": "Commented-code block (5 lines) in src/components/EditUserTranscriptsDialog.tsx:34", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/EditUserTranscriptsDialog.tsx:34"}, "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-f7d7485ff0ea018c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditUserTranscriptsDialog.tsx:50", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditUserTranscriptsDialog.tsx:50"}, "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-67860f56fe99bd67", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditTranslationDialog.tsx:47", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditTranslationDialog.tsx:47"}, "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-82c627e6d74a3c76", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/BannedUsersPanel.tsx:17", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/BannedUsersPanel.tsx:17"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-559327f9afe16858", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/student/referrals/page.tsx:50", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/student/referrals/page.tsx:50"}, "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-39dcb5e3409da25e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/student/freeze/page.tsx:38", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/student/freeze/page.tsx: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-cc797b3f10328ed9", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/student/response-window/page.tsx:37", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/student/response-window/page.tsx:37"}, "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-51657a0468bbe258", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/student/transcripts/page.tsx:38", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/student/transcripts/page.tsx: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-54c6035fd2205d5b", "name": "Commented-code block (5 lines) in src/app/api/student/response-window/route.ts:125", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/api/student/response-window/route.ts:125"}, "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-f3e10458c6264aba", "name": "Commented-code block (5 lines) in src/app/api/webhook/route.ts:17", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/api/webhook/route.ts:17"}, "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-1f4f890d20ae4b7f", "name": "Commented-code block (14 lines) in src/app/api/media/[messageId]/route.ts:51", "shortDescription": {"text": "Commented-code block (14 lines) in src/app/api/media/[messageId]/route.ts:51"}, "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-d691c350d9775b1a", "name": "Commented-code block (6 lines) in src/app/api/admin/users/route.ts:38", "shortDescription": {"text": "Commented-code block (6 lines) in src/app/api/admin/users/route.ts:38"}, "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-c02d6ad8e4e5105e", "name": "Commented-code block (6 lines) in src/app/api/admin/users/[id]/profile-link/route.ts:78", "shortDescription": {"text": "Commented-code block (6 lines) in src/app/api/admin/users/[id]/profile-link/route.ts:78"}, "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-b16b6229fe6d734a", "name": "Commented-code block (5 lines) in src/app/api/admin/acquisition-sources/route.ts:28", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/api/admin/acquisition-sources/route.ts:28"}, "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-6d2c7712cb074c4b", "name": "Commented-code block (6 lines) in src/app/api/admin/onboarding-videos/route.ts:52", "shortDescription": {"text": "Commented-code block (6 lines) in src/app/api/admin/onboarding-videos/route.ts:52"}, "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-cd4fbb335c51c0f7", "name": "Commented-code block (5 lines) in src/app/api/admin/onboarding-videos/[step]/route.ts:90", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/api/admin/onboarding-videos/[step]/route.ts:90"}, "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-2543c63524139c24", "name": "Commented-code block (14 lines) in src/app/api/admin/upload-proxy/[...path]/route.ts:5", "shortDescription": {"text": "Commented-code block (14 lines) in src/app/api/admin/upload-proxy/[...path]/route.ts:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-fd6e7933634d5eaa", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/api/admin/upload-proxy/[...path]/route.ts:85", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/api/admin/upload-proxy/[...path]/route.ts:85"}, "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-f775e6dde4341ad8", "name": "Commented-code block (6 lines) in src/app/api/cron/store-media/route.ts:26", "shortDescription": {"text": "Commented-code block (6 lines) in src/app/api/cron/store-media/route.ts:26"}, "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-9cf07fb6c5468aca", "name": "Commented-code block (6 lines) in src/app/api/cron/engagement/route.ts:55", "shortDescription": {"text": "Commented-code block (6 lines) in src/app/api/cron/engagement/route.ts:55"}, "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-263798dfce1b2f88", "name": "Commented-code block (11 lines) in src/app/api/cron/deliver-scheduled/route.ts:21", "shortDescription": {"text": "Commented-code block (11 lines) in src/app/api/cron/deliver-scheduled/route.ts:21"}, "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-0ed0e565606a4a40", "name": "Commented-code block (5 lines) in src/app/api/cron/subscriptions/route.ts:135", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/api/cron/subscriptions/route.ts:135"}, "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-fcd3410ef87c5a65", "name": "Commented-code block (8 lines) in src/app/api/inbox/route.ts:89", "shortDescription": {"text": "Commented-code block (8 lines) in src/app/api/inbox/route.ts:89"}, "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-e7997a84bcefe1d2", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/page.tsx:54", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/page.tsx:54"}, "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-59c75af4ae7c4734", "name": "Commented-code block (5 lines) in src/lib/storage-object-check.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/storage-object-check.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-597ec3440b00984f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/storage-object-check.ts:28", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/storage-object-check.ts:28"}, "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-a6b309c75a1eabf8", "name": "Commented-code block (5 lines) in src/lib/env.ts:76", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/env.ts:76"}, "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-99c03b982714bda3", "name": "Commented-code block (5 lines) in src/lib/storage-sign.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/storage-sign.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-21b453c0cbd32592", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/storage-sign.ts:33", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/storage-sign.ts:33"}, "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-89ed4b5b669995dc", "name": "Commented-code block (6 lines) in src/lib/video-compress.ts:5", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/video-compress.ts:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-4b78b3cf7755213e", "name": "Commented-code block (5 lines) in src/lib/direct-upload.ts:10", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/direct-upload.ts:10"}, "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-45e9a021e43401d0", "name": "Commented-code block (5 lines) in src/lib/i18n/bot.ts:49", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/i18n/bot.ts:49"}, "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-d58bd7889b794209", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/hooks/useInitDataAuth.ts:33", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/hooks/useInitDataAuth.ts:33"}, "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-b38605edf54abdd9", "name": "Commented-code block (5 lines) in src/server/onboarding.ts:77", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/onboarding.ts:77"}, "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-be84dfab3bb8eb1f", "name": "Commented-code block (5 lines) in src/server/response-window.ts:94", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/response-window.ts:94"}, "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-b51ba4967b7f242b", "name": "Commented-code block (5 lines) in src/server/notifications.ts:55", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/notifications.ts:55"}, "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-5aa0d8549dc218a4", "name": "Commented-code block (7 lines) in src/server/invites.ts:169", "shortDescription": {"text": "Commented-code block (7 lines) in src/server/invites.ts:169"}, "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-9da46628126d103a", "name": "Commented-code block (5 lines) in src/server/transcribe.ts:144", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/transcribe.ts:144"}, "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-72ef78748a0da7f5", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/transcribe.ts:47", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/transcribe.ts:47"}, "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-4bc495f3fd2b2f9c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/store-media.ts:54", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/store-media.ts:54"}, "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-9dabaf9da6fae7c9", "name": "Commented-code block (5 lines) in src/server/media-storage.ts:51", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/media-storage.ts:51"}, "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-59cf5c38223a45ed", "name": "Commented-code block (5 lines) in src/server/settings.ts:5", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/settings.ts:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6510d31a791d187f", "name": "Commented-code block (5 lines) in src/server/transcript-delivery.ts:98", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/transcript-delivery.ts:98"}, "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-e867f8a74ad6279c", "name": "Commented-code block (5 lines) in src/server/handlers/onboarding-callbacks.ts:109", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/handlers/onboarding-callbacks.ts:109"}, "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-73d25d7053ee67dc", "name": "Commented-code block (5 lines) in src/server/handlers/start.ts:146", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/handlers/start.ts:146"}, "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-cea30154b264d8ba", "name": "Commented-code block (5 lines) in src/server/handlers/teacher-reply.ts:154", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/handlers/teacher-reply.ts:154"}, "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-2d98d402500a3939", "name": "Commented-code block (5 lines) in src/server/handlers/student-message.ts:113", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/handlers/student-message.ts:113"}, "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-cc0f9d8e41b33b0e", "name": "11 env vars used in code but missing from .env.example", "shortDescription": {"text": "11 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `BUILD_MESSAGE`, `BUILD_REF`, `BUILD_REPO`, `BUILD_REPO_OWNER`, `BUILD_SHA`, `BUILD_TIME`, `VERCEL_GIT_COMMIT_MESSAGE`, `VERCEL_GIT_COMMIT_REF` + 3 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}}]}}, "automationDetails": {"id": "repobility/17884"}, "properties": {"repository": "raziel-gershoni/hebtut", "repoUrl": "https://github.com/raziel-gershoni/hebtut", "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-89380598fefe7418", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AssignTeacherDialog.tsx:155"}, "properties": {"repobilityId": "bd024dd1e3b353e1", "scanner": "scanner-primary", "fingerprint": "89380598fefe7418", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-440dcde0c522b1bd", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/MediaPreview.tsx:123"}, "properties": {"repobilityId": "6eb5da26ef9127c4", "scanner": "scanner-primary", "fingerprint": "440dcde0c522b1bd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f83bea6ca90be1d7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminAdminsPanel.tsx:107"}, "properties": {"repobilityId": "c9a946874ca06ece", "scanner": "scanner-primary", "fingerprint": "f83bea6ca90be1d7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0b16003f44f10445", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/StudentPicker.tsx:135"}, "properties": {"repobilityId": "28f6ee51853f72ea", "scanner": "scanner-primary", "fingerprint": "0b16003f44f10445", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-724079d203a75ce3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/FeedbackThread.tsx:188"}, "properties": {"repobilityId": "8b34a65b6202daaf", "scanner": "scanner-primary", "fingerprint": "724079d203a75ce3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c83dfa64e5a077ef", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminOnboardingVideos.tsx:564"}, "properties": {"repobilityId": "ba73cc43da0e07ac", "scanner": "scanner-primary", "fingerprint": "c83dfa64e5a077ef", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-daf6762d3f2cc03a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/TeacherInvites.tsx:172"}, "properties": {"repobilityId": "bad37ce2fedd55f1", "scanner": "scanner-primary", "fingerprint": "daf6762d3f2cc03a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3df30f822b3b8d68", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/InboxList.tsx:259"}, "properties": {"repobilityId": "7431cb1ec8be8b92", "scanner": "scanner-primary", "fingerprint": "3df30f822b3b8d68", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2d18e973f50e0cb6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminTagsManager.tsx:134"}, "properties": {"repobilityId": "6c115a6f5141b6a4", "scanner": "scanner-primary", "fingerprint": "2d18e973f50e0cb6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a15bc83df760078b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminUsersTable.tsx:264"}, "properties": {"repobilityId": "71e5281c426ab01e", "scanner": "scanner-primary", "fingerprint": "a15bc83df760078b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8716e82bc34cae96", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminEngagementPanel.tsx:112"}, "properties": {"repobilityId": "e4b2f9e2c4b1d64b", "scanner": "scanner-primary", "fingerprint": "8716e82bc34cae96", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-075c8271bb023064", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/MediaPicker.tsx:830"}, "properties": {"repobilityId": "7262c64b2926b257", "scanner": "scanner-primary", "fingerprint": "075c8271bb023064", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ca2e6e017432eb1d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AppShell.tsx:34"}, "properties": {"repobilityId": "e43655288de2f4b3", "scanner": "scanner-primary", "fingerprint": "ca2e6e017432eb1d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7457fc544660ccab", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ThreadView.tsx:368"}, "properties": {"repobilityId": "c98ddf66d848aa9d", "scanner": "scanner-primary", "fingerprint": "7457fc544660ccab", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f84f6bbc985c65f5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/SearchableUserChecklist.tsx:123"}, "properties": {"repobilityId": "fd110a0a65512088", "scanner": "scanner-primary", "fingerprint": "f84f6bbc985c65f5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-76ae0f5bc145bd89", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/StudentCardDialog.tsx:129"}, "properties": {"repobilityId": "7142f18545c48242", "scanner": "scanner-primary", "fingerprint": "76ae0f5bc145bd89", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5b80d6b8a6165dd6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminTutorWorkPanel.tsx:201"}, "properties": {"repobilityId": "78945b8d5b6ee6f3", "scanner": "scanner-primary", "fingerprint": "5b80d6b8a6165dd6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-918651a4c6b5eab5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/FeedbackList.tsx:98"}, "properties": {"repobilityId": "dfed8a9442b03d06", "scanner": "scanner-primary", "fingerprint": "918651a4c6b5eab5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-53369f298f765f6e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AcquisitionSources.tsx:216"}, "properties": {"repobilityId": "0de33ff0d6479e7e", "scanner": "scanner-primary", "fingerprint": "53369f298f765f6e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7eeca5682bcd5b36", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AdminConnectionsPanel.tsx:362"}, "properties": {"repobilityId": "79384fc91c57a693", "scanner": "scanner-primary", "fingerprint": "7eeca5682bcd5b36", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f980392d4c52822a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/SubscriptionDialog.tsx:95"}, "properties": {"repobilityId": "7a8726a31ce8ff25", "scanner": "scanner-primary", "fingerprint": "f980392d4c52822a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5d7c8936279e82fb", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/BannedUsersPanel.tsx:53"}, "properties": {"repobilityId": "509f72d192be0d52", "scanner": "scanner-primary", "fingerprint": "5d7c8936279e82fb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-59ba4741e3e86649", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/app/api/student/summary/route.ts:118"}, "properties": {"repobilityId": "ecf03748950608ed", "scanner": "scanner-primary", "fingerprint": "59ba4741e3e86649", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-a13bdaa3637c6624", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in next.config.mjs:1"}, "properties": {"repobilityId": "aaae2e64114a611e", "scanner": "scanner-primary", "fingerprint": "a13bdaa3637c6624", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "next.config.mjs"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-799f345ec1261ab6", "level": "error", "message": {"text": "Insecure pattern 'exec_used' in src/lib/video-compress.ts:49"}, "properties": {"repobilityId": "3a7044940bbec2db", "scanner": "scanner-primary", "fingerprint": "799f345ec1261ab6", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "exec_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/lib/video-compress.ts"}, "region": {"startLine": 49}}}]}, {"ruleId": "scanner-4601e3ad3bb28677", "level": "warning", "message": {"text": "No CI/CD pipelines detected"}, "properties": {"repobilityId": "c3ee439bce2bc51e", "scanner": "scanner-primary", "fingerprint": "4601e3ad3bb28677", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["coverage"]}}, {"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": "41658e0fc03a283d", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "2ffa52fd1d84d10b", "scanner": "scanner-primary", "fingerprint": "3ab5d313dda8e5f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["debug", "cleanup", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "677d19c2637106a8", "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": "e5dcb6b938d1da8d", "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": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "4be921c479de5213", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "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": "801839e1a3dd059a", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "d19ec40833e65334", "scanner": "scanner-primary", "fingerprint": "ea8f3013f588db25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8424db9c75e04ba4", "level": "none", "message": {"text": "Very short observed git history"}, "properties": {"repobilityId": "0a9a2a31b3afba5b", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-6006152df11cf55a", "level": "none", "message": {"text": "Commented-code block (5 lines) in scripts/db-push.mjs:2"}, "properties": {"repobilityId": "a87d5952c1910afc", "scanner": "scanner-primary", "fingerprint": "6006152df11cf55a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-87d2db001632f8ac", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/sync-qstash.mjs:2"}, "properties": {"repobilityId": "225506055a4e1af2", "scanner": "scanner-primary", "fingerprint": "87d2db001632f8ac", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a3c6bfb6f39a2e23", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/sync-qstash.mjs:75"}, "properties": {"repobilityId": "094020fd6e85545f", "scanner": "scanner-primary", "fingerprint": "a3c6bfb6f39a2e23", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-90d19ede2fbcbd0d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/list-qstash.mjs:21"}, "properties": {"repobilityId": "46ea30f5384af0e1", "scanner": "scanner-primary", "fingerprint": "90d19ede2fbcbd0d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-02a20f0abf5ab780", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AssignTeacherDialog.tsx:55"}, "properties": {"repobilityId": "edbe191f701aaa27", "scanner": "scanner-primary", "fingerprint": "02a20f0abf5ab780", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f4d1e59694d547c4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminAdminsPanel.tsx:65"}, "properties": {"repobilityId": "371829cc25fd5d53", "scanner": "scanner-primary", "fingerprint": "f4d1e59694d547c4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d8c22a46e0b8b4d8", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/MiniAppMenu.tsx:93"}, "properties": {"repobilityId": "0fa116de5852f28b", "scanner": "scanner-primary", "fingerprint": "d8c22a46e0b8b4d8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c1523192ea76cb5d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/StudentPicker.tsx:34"}, "properties": {"repobilityId": "986000af3a0bc11d", "scanner": "scanner-primary", "fingerprint": "c1523192ea76cb5d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e28685542bc55c2a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/FeedbackThread.tsx:75"}, "properties": {"repobilityId": "c921a7c54cb3a12a", "scanner": "scanner-primary", "fingerprint": "e28685542bc55c2a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-efe0e8230517c1bb", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminOnboardingVideos.tsx:71"}, "properties": {"repobilityId": "7bf39650b97cd68e", "scanner": "scanner-primary", "fingerprint": "efe0e8230517c1bb", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9b4b96810adfb801", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/TagPicker.tsx:28"}, "properties": {"repobilityId": "cb59484b1fe24ddb", "scanner": "scanner-primary", "fingerprint": "9b4b96810adfb801", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-66c7fc8ff6d6b657", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/TeacherInvites.tsx:34"}, "properties": {"repobilityId": "3116b767220aa62f", "scanner": "scanner-primary", "fingerprint": "66c7fc8ff6d6b657", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-71a6fc5a0e414d5f", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/InboxList.tsx:90"}, "properties": {"repobilityId": "1b4414a4a7eb84a3", "scanner": "scanner-primary", "fingerprint": "71a6fc5a0e414d5f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-086e0cb025727b25", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/InboxList.tsx:73"}, "properties": {"repobilityId": "8112a98b328e1cd8", "scanner": "scanner-primary", "fingerprint": "086e0cb025727b25", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-408e9a5ec6a9b795", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AuditLog.tsx:183"}, "properties": {"repobilityId": "4682bf64e59a974a", "scanner": "scanner-primary", "fingerprint": "408e9a5ec6a9b795", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-364e0fbce6641e4f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminTagsManager.tsx:32"}, "properties": {"repobilityId": "556dbc3c5ced8cd1", "scanner": "scanner-primary", "fingerprint": "364e0fbce6641e4f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-423633974a2974a7", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/components/AdminUsersTable.tsx:63"}, "properties": {"repobilityId": "368a286f2bdf7897", "scanner": "scanner-primary", "fingerprint": "423633974a2974a7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-422c7617c41db622", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminUsersTable.tsx:93"}, "properties": {"repobilityId": "ac44190d9b797ff9", "scanner": "scanner-primary", "fingerprint": "422c7617c41db622", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-063e0f8bea6a512d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminEngagementPanel.tsx:48"}, "properties": {"repobilityId": "a783f57d6add986c", "scanner": "scanner-primary", "fingerprint": "063e0f8bea6a512d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-cf32c82fa917adec", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/components/MediaPicker.tsx:184"}, "properties": {"repobilityId": "dcb1928f202a078b", "scanner": "scanner-primary", "fingerprint": "cf32c82fa917adec", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b97230beddc62dd2", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/MediaPicker.tsx:82"}, "properties": {"repobilityId": "8f8bb15cad9fccdd", "scanner": "scanner-primary", "fingerprint": "b97230beddc62dd2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a31009a1d43ae096", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/FeedbackChat.tsx:56"}, "properties": {"repobilityId": "61e123399caa1076", "scanner": "scanner-primary", "fingerprint": "a31009a1d43ae096", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-24cc34d89c8f886f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditTranscriptDialog.tsx:47"}, "properties": {"repobilityId": "e748d1212f19fde0", "scanner": "scanner-primary", "fingerprint": "24cc34d89c8f886f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f68293108bfd1896", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/ThreadView.tsx:76"}, "properties": {"repobilityId": "64c0e949e11368a6", "scanner": "scanner-primary", "fingerprint": "f68293108bfd1896", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b007e37307361e6b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditPreferredNameDialog.tsx:59"}, "properties": {"repobilityId": "53e60d2519cbb455", "scanner": "scanner-primary", "fingerprint": "b007e37307361e6b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e53e6d0599029ba9", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/components/MessageBubble.tsx:763"}, "properties": {"repobilityId": "57111eb3941e37bd", "scanner": "scanner-primary", "fingerprint": "e53e6d0599029ba9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5188d8dcdc27c268", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditMediaItemDialog.tsx:46"}, "properties": {"repobilityId": "e94284f1a7c7e501", "scanner": "scanner-primary", "fingerprint": "5188d8dcdc27c268", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9aa2143e874121b0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/SubscriberSummary.tsx:35"}, "properties": {"repobilityId": "0af7b6cb5d92997e", "scanner": "scanner-primary", "fingerprint": "9aa2143e874121b0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5e2436989420d7a0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AdminSettingsPanel.tsx:40"}, "properties": {"repobilityId": "31fb604e73a98721", "scanner": "scanner-primary", "fingerprint": "5e2436989420d7a0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4fb452584520cf7f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/PlaybackProvider.tsx:65"}, "properties": {"repobilityId": "a2d52abd7f017cce", "scanner": "scanner-primary", "fingerprint": "4fb452584520cf7f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7651866cbc325d0c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/FeedbackList.tsx:43"}, "properties": {"repobilityId": "a2f85f739529ac7f", "scanner": "scanner-primary", "fingerprint": "7651866cbc325d0c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7c94139a6db6d2ee", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/AcquisitionSources.tsx:35"}, "properties": {"repobilityId": "e370ef362155cf2d", "scanner": "scanner-primary", "fingerprint": "7c94139a6db6d2ee", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6c07c87793937813", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/SubscriptionDialog.tsx:58"}, "properties": {"repobilityId": "92dc9e211c66b818", "scanner": "scanner-primary", "fingerprint": "6c07c87793937813", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-108a2b7f74ac46a4", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/EditUserTranscriptsDialog.tsx:34"}, "properties": {"repobilityId": "e61dd583808c4802", "scanner": "scanner-primary", "fingerprint": "108a2b7f74ac46a4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f7d7485ff0ea018c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditUserTranscriptsDialog.tsx:50"}, "properties": {"repobilityId": "31e574586413c67c", "scanner": "scanner-primary", "fingerprint": "f7d7485ff0ea018c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-67860f56fe99bd67", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/EditTranslationDialog.tsx:47"}, "properties": {"repobilityId": "0989655c88a03ab3", "scanner": "scanner-primary", "fingerprint": "67860f56fe99bd67", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-82c627e6d74a3c76", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/BannedUsersPanel.tsx:17"}, "properties": {"repobilityId": "d8cb7a2918588f0f", "scanner": "scanner-primary", "fingerprint": "82c627e6d74a3c76", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-559327f9afe16858", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/student/referrals/page.tsx:50"}, "properties": {"repobilityId": "5652fb05760aa727", "scanner": "scanner-primary", "fingerprint": "559327f9afe16858", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-39dcb5e3409da25e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/student/freeze/page.tsx:38"}, "properties": {"repobilityId": "563c11612620faeb", "scanner": "scanner-primary", "fingerprint": "39dcb5e3409da25e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-cc797b3f10328ed9", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/student/response-window/page.tsx:37"}, "properties": {"repobilityId": "07e10e0e16cf8d91", "scanner": "scanner-primary", "fingerprint": "cc797b3f10328ed9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-51657a0468bbe258", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/student/transcripts/page.tsx:38"}, "properties": {"repobilityId": "572da4a0358569f8", "scanner": "scanner-primary", "fingerprint": "51657a0468bbe258", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-54c6035fd2205d5b", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/api/student/response-window/route.ts:125"}, "properties": {"repobilityId": "f9099ee4c726ee3c", "scanner": "scanner-primary", "fingerprint": "54c6035fd2205d5b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f3e10458c6264aba", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/api/webhook/route.ts:17"}, "properties": {"repobilityId": "e7382d25f28539c3", "scanner": "scanner-primary", "fingerprint": "f3e10458c6264aba", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1f4f890d20ae4b7f", "level": "none", "message": {"text": "Commented-code block (14 lines) in src/app/api/media/[messageId]/route.ts:51"}, "properties": {"repobilityId": "56aadf3a3ea884bb", "scanner": "scanner-primary", "fingerprint": "1f4f890d20ae4b7f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d691c350d9775b1a", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/app/api/admin/users/route.ts:38"}, "properties": {"repobilityId": "eb57d3f90d40156e", "scanner": "scanner-primary", "fingerprint": "d691c350d9775b1a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c02d6ad8e4e5105e", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/app/api/admin/users/[id]/profile-link/route.ts:78"}, "properties": {"repobilityId": "1830bc974f055c8a", "scanner": "scanner-primary", "fingerprint": "c02d6ad8e4e5105e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b16b6229fe6d734a", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/api/admin/acquisition-sources/route.ts:28"}, "properties": {"repobilityId": "d76ab261d6f9b216", "scanner": "scanner-primary", "fingerprint": "b16b6229fe6d734a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6d2c7712cb074c4b", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/app/api/admin/onboarding-videos/route.ts:52"}, "properties": {"repobilityId": "9f3e561b154b1457", "scanner": "scanner-primary", "fingerprint": "6d2c7712cb074c4b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cd4fbb335c51c0f7", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/api/admin/onboarding-videos/[step]/route.ts:90"}, "properties": {"repobilityId": "d8e1fccbdea3a580", "scanner": "scanner-primary", "fingerprint": "cd4fbb335c51c0f7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2543c63524139c24", "level": "none", "message": {"text": "Commented-code block (14 lines) in src/app/api/admin/upload-proxy/[...path]/route.ts:5"}, "properties": {"repobilityId": "2f7d7e3c8139b51d", "scanner": "scanner-primary", "fingerprint": "2543c63524139c24", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-fd6e7933634d5eaa", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/api/admin/upload-proxy/[...path]/route.ts:85"}, "properties": {"repobilityId": "2e363a529bddb391", "scanner": "scanner-primary", "fingerprint": "fd6e7933634d5eaa", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f775e6dde4341ad8", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/app/api/cron/store-media/route.ts:26"}, "properties": {"repobilityId": "930e022914ad0a25", "scanner": "scanner-primary", "fingerprint": "f775e6dde4341ad8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9cf07fb6c5468aca", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/app/api/cron/engagement/route.ts:55"}, "properties": {"repobilityId": "f6399cb23ac7702d", "scanner": "scanner-primary", "fingerprint": "9cf07fb6c5468aca", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-263798dfce1b2f88", "level": "none", "message": {"text": "Commented-code block (11 lines) in src/app/api/cron/deliver-scheduled/route.ts:21"}, "properties": {"repobilityId": "e2eebf97b1061c9f", "scanner": "scanner-primary", "fingerprint": "263798dfce1b2f88", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0ed0e565606a4a40", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/api/cron/subscriptions/route.ts:135"}, "properties": {"repobilityId": "39904aacab63e360", "scanner": "scanner-primary", "fingerprint": "0ed0e565606a4a40", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-fcd3410ef87c5a65", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/app/api/inbox/route.ts:89"}, "properties": {"repobilityId": "a74833321db21ad8", "scanner": "scanner-primary", "fingerprint": "fcd3410ef87c5a65", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e7997a84bcefe1d2", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/page.tsx:54"}, "properties": {"repobilityId": "5126b77c70bea970", "scanner": "scanner-primary", "fingerprint": "e7997a84bcefe1d2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-59c75af4ae7c4734", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/storage-object-check.ts:1"}, "properties": {"repobilityId": "82a4a099db490f24", "scanner": "scanner-primary", "fingerprint": "59c75af4ae7c4734", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-597ec3440b00984f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/storage-object-check.ts:28"}, "properties": {"repobilityId": "844c9379b11fb5a4", "scanner": "scanner-primary", "fingerprint": "597ec3440b00984f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a6b309c75a1eabf8", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/env.ts:76"}, "properties": {"repobilityId": "f0dc03b2c0d08447", "scanner": "scanner-primary", "fingerprint": "a6b309c75a1eabf8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-99c03b982714bda3", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/storage-sign.ts:1"}, "properties": {"repobilityId": "3fe11f0226ca0387", "scanner": "scanner-primary", "fingerprint": "99c03b982714bda3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-21b453c0cbd32592", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/storage-sign.ts:33"}, "properties": {"repobilityId": "7db4fc783c77f0d3", "scanner": "scanner-primary", "fingerprint": "21b453c0cbd32592", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-89ed4b5b669995dc", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/video-compress.ts:5"}, "properties": {"repobilityId": "1c01c5f62a89c436", "scanner": "scanner-primary", "fingerprint": "89ed4b5b669995dc", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4b78b3cf7755213e", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/direct-upload.ts:10"}, "properties": {"repobilityId": "e5a0663ff6c4034e", "scanner": "scanner-primary", "fingerprint": "4b78b3cf7755213e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-45e9a021e43401d0", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/i18n/bot.ts:49"}, "properties": {"repobilityId": "2e26ff5a83ad3d9d", "scanner": "scanner-primary", "fingerprint": "45e9a021e43401d0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d58bd7889b794209", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/hooks/useInitDataAuth.ts:33"}, "properties": {"repobilityId": "d7deb250ff6820d7", "scanner": "scanner-primary", "fingerprint": "d58bd7889b794209", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b38605edf54abdd9", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/onboarding.ts:77"}, "properties": {"repobilityId": "888124139bf5da65", "scanner": "scanner-primary", "fingerprint": "b38605edf54abdd9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-be84dfab3bb8eb1f", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/response-window.ts:94"}, "properties": {"repobilityId": "00dc1c78b70dacb9", "scanner": "scanner-primary", "fingerprint": "be84dfab3bb8eb1f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b51ba4967b7f242b", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/notifications.ts:55"}, "properties": {"repobilityId": "aa663a4114b567e8", "scanner": "scanner-primary", "fingerprint": "b51ba4967b7f242b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5aa0d8549dc218a4", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/server/invites.ts:169"}, "properties": {"repobilityId": "5cf4b36b30e6d1c8", "scanner": "scanner-primary", "fingerprint": "5aa0d8549dc218a4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9da46628126d103a", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/transcribe.ts:144"}, "properties": {"repobilityId": "e278d01731955391", "scanner": "scanner-primary", "fingerprint": "9da46628126d103a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-72ef78748a0da7f5", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/transcribe.ts:47"}, "properties": {"repobilityId": "51775a862f47c952", "scanner": "scanner-primary", "fingerprint": "72ef78748a0da7f5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4bc495f3fd2b2f9c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/store-media.ts:54"}, "properties": {"repobilityId": "0167803267c03d41", "scanner": "scanner-primary", "fingerprint": "4bc495f3fd2b2f9c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9dabaf9da6fae7c9", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/media-storage.ts:51"}, "properties": {"repobilityId": "a58d1cce47401897", "scanner": "scanner-primary", "fingerprint": "9dabaf9da6fae7c9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-59cf5c38223a45ed", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/settings.ts:5"}, "properties": {"repobilityId": "c5fff08e7a8a25aa", "scanner": "scanner-primary", "fingerprint": "59cf5c38223a45ed", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6510d31a791d187f", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/transcript-delivery.ts:98"}, "properties": {"repobilityId": "3f2fc6e6107b31cf", "scanner": "scanner-primary", "fingerprint": "6510d31a791d187f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e867f8a74ad6279c", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/handlers/onboarding-callbacks.ts:109"}, "properties": {"repobilityId": "1af1452553bfdbca", "scanner": "scanner-primary", "fingerprint": "e867f8a74ad6279c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-73d25d7053ee67dc", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/handlers/start.ts:146"}, "properties": {"repobilityId": "6504882712baa448", "scanner": "scanner-primary", "fingerprint": "73d25d7053ee67dc", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cea30154b264d8ba", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/handlers/teacher-reply.ts:154"}, "properties": {"repobilityId": "505d33dedc06eb69", "scanner": "scanner-primary", "fingerprint": "cea30154b264d8ba", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2d98d402500a3939", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/handlers/student-message.ts:113"}, "properties": {"repobilityId": "b4c6aee36d697874", "scanner": "scanner-primary", "fingerprint": "2d98d402500a3939", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cc0f9d8e41b33b0e", "level": "note", "message": {"text": "11 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "c82cd8cd626c3599", "scanner": "scanner-primary", "fingerprint": "cc0f9d8e41b33b0e", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}]}]}