{"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-fc610291627c4d22", "name": "`truncate` class without `title=` for hover reveal \u2014 packages/ui/src/blocks/audio-player/audio-player.tsx:215", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 packages/ui/src/blocks/audio-player/audio-player.tsx:215"}, "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-e5befbe2e8719e1d", "name": "Stray `console.log` in TS/JS \u2014 scripts/migrate.ts:84", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/migrate.ts:84"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-71aac3dcf34e5e25", "name": "Stray `console.log` in TS/JS \u2014 scripts/seed-admin.ts:33", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-admin.ts:33"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0347d29695339ebd", "name": "Stray `console.log` in TS/JS \u2014 scripts/seed-quran.ts:100", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-quran.ts:100"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9f3225a3cbecf9c7", "name": "Stray `console.log` in TS/JS \u2014 scripts/heal-embedded-slugs.ts:27", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/heal-embedded-slugs.ts:27"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6bf7befd51797e98", "name": "Stray `console.log` in TS/JS \u2014 scripts/seed-adhkar.ts:46", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-adhkar.ts:46"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-771caf75679e127b", "name": "Stray `console.log` in TS/JS \u2014 scripts/heal-malformed-slugs.ts:70", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/heal-malformed-slugs.ts:70"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1477c6fd6a7bdb4f", "name": "Stray `console.log` in TS/JS \u2014 scripts/reset-admin-password.ts:43", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/reset-admin-password.ts:43"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0213b1d0db424f09", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/admin/features/playlists/components/track-list.tsx:62", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/admin/features/playlists/components/track-list.tsx:62"}, "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-1d5855a0ba39a882", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/admin/features/playlists/components/track-uploader.tsx:102", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/admin/features/playlists/components/track-uploader.tsx:102"}, "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-e32c26d122bcc305", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/app/api/v1/quran/tafsir/route.ts:12", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/app/api/v1/quran/tafsir/route.ts:12"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-615198146f704a1b", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/app/api/quran/tafsir/route.ts:9", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/app/api/quran/tafsir/route.ts:9"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3fada4b90c15b9b0", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/features/player/components/continue-listening.tsx:122", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/features/player/components/continue-listening.tsx:122"}, "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-42d9ff757fe1a2e9", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/features/seo/components/json-ld.tsx:30", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/features/seo/components/json-ld.tsx:30"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-262744216c379c62", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/features/quran/components/tafsir-sheet.tsx:83", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/features/quran/components/tafsir-sheet.tsx:83"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-af6a18e8e53ff1b2", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/mobile/features/quran/components/tafsir-sheet.tsx:19", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/mobile/features/quran/components/tafsir-sheet.tsx:19"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6ff2db4d29bba0d7", "name": "Insecure pattern 'dangerous_innerhtml' in apps/web/features/seo/components/json-ld.tsx:30", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in apps/web/features/seo/components/json-ld.tsx:30"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-611a2cc107050204", "name": "Insecure pattern 'dangerous_innerhtml' in apps/web/features/quran/components/tafsir-sheet.tsx:83", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in apps/web/features/quran/components/tafsir-sheet.tsx:83"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-27924aa79fa4a517", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-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-0a0634ffe3eb1107", "name": "Node manifest has dependencies but no lockfile: packages/api/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/api/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3f65e1ca9b00183a", "name": "Node manifest has dependencies but no lockfile: packages/eslint-config/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/eslint-config/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-16c8b93ec958d12f", "name": "Node manifest has dependencies but no lockfile: packages/shared-core/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/shared-core/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-eddecaa766cadff2", "name": "Node manifest has dependencies but no lockfile: packages/config/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/config/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-50218c90b43393bb", "name": "Node manifest has dependencies but no lockfile: packages/ui/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/ui/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5c30f715681a4005", "name": "Node manifest has dependencies but no lockfile: apps/admin/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/admin/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4a9eb7dc7c6e3880", "name": "Node manifest has dependencies but no lockfile: apps/web/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d0c2205560692580", "name": "Node manifest has dependencies but no lockfile: apps/mobile/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/mobile/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 26 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 27 placeholder/mock markers across 11 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, lockfile. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2b2bd7498f274cb5", "name": "Commented-code block (5 lines) in packages/api/src/db/migrations/0004-i18n-indexes.ts:47", "shortDescription": {"text": "Commented-code block (5 lines) in packages/api/src/db/migrations/0004-i18n-indexes.ts:47"}, "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-d6bfecce692242cd", "name": "Commented-code block (8 lines) in packages/shared-core/src/prayer-times/compute.ts:161", "shortDescription": {"text": "Commented-code block (8 lines) in packages/shared-core/src/prayer-times/compute.ts:161"}, "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-07601dca2dcb56ff", "name": "Commented-code block (10 lines) in scripts/migrate.ts:39", "shortDescription": {"text": "Commented-code block (10 lines) in scripts/migrate.ts:39"}, "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-97b0650cc83d8983", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/seed-quran.ts:62", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/seed-quran.ts:62"}, "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-593437fa00efc533", "name": "Commented-code block (5 lines) in apps/admin/proxy.ts:29", "shortDescription": {"text": "Commented-code block (5 lines) in apps/admin/proxy.ts:29"}, "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-08b5a74a3c0de62b", "name": "Commented-code block (7 lines) in apps/admin/app/api/health/route.ts:5", "shortDescription": {"text": "Commented-code block (7 lines) in apps/admin/app/api/health/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-1129d70d1ca1f611", "name": "Commented-code block (5 lines) in apps/admin/features/adhkar/components/azkar-items-editor.tsx:13", "shortDescription": {"text": "Commented-code block (5 lines) in apps/admin/features/adhkar/components/azkar-items-editor.tsx:13"}, "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-0d29d79de8d3f333", "name": "Commented-code block (7 lines) in apps/web/app/api/health/route.ts:5", "shortDescription": {"text": "Commented-code block (7 lines) in apps/web/app/api/health/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-61b9d6b367fc7358", "name": "Commented-code block (6 lines) in apps/web/app/[locale]/adhkar/[slug]/page.tsx:13", "shortDescription": {"text": "Commented-code block (6 lines) in apps/web/app/[locale]/adhkar/[slug]/page.tsx:13"}, "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-99096d754ecab953", "name": "Commented-code block (6 lines) in apps/web/app/[locale]/playlists/[slug]/page.tsx:17", "shortDescription": {"text": "Commented-code block (6 lines) in apps/web/app/[locale]/playlists/[slug]/page.tsx: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-cf1f4fa50bb94cc8", "name": "Commented-code block (6 lines) in apps/web/features/prayer-times/hooks/use-adhan-scheduler.ts:60", "shortDescription": {"text": "Commented-code block (6 lines) in apps/web/features/prayer-times/hooks/use-adhan-scheduler.ts:60"}, "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-d73e1e1d93e685b4", "name": "Commented-code block (5 lines) in apps/web/features/prayer-times/components/sun-arc.tsx:23", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/features/prayer-times/components/sun-arc.tsx:23"}, "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-e38c1ac8a347ee82", "name": "Commented-code block (10 lines) in apps/web/features/prayer-times/lib/adhan-schedule.ts:37", "shortDescription": {"text": "Commented-code block (10 lines) in apps/web/features/prayer-times/lib/adhan-schedule.ts:37"}, "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-252e6071721759f6", "name": "Commented-code block (6 lines) in apps/web/features/prayer-times/lib/azkar-reminder-schedule.ts:36", "shortDescription": {"text": "Commented-code block (6 lines) in apps/web/features/prayer-times/lib/azkar-reminder-schedule.ts:36"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-bd036bfb9b908b09", "name": "Commented-code block (7 lines) in apps/web/features/prayer-times/lib/fired-event-store.ts:1", "shortDescription": {"text": "Commented-code block (7 lines) in apps/web/features/prayer-times/lib/fired-event-store.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-dd43efc75ea158e8", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/features/quran/hooks/use-ayah-audio.ts:29", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/features/quran/hooks/use-ayah-audio.ts:29"}, "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-f36a2c96a9f7e5bd", "name": "Commented-code block (6 lines) in apps/web/features/playlists/lib/soundcloud-oembed.ts:4", "shortDescription": {"text": "Commented-code block (6 lines) in apps/web/features/playlists/lib/soundcloud-oembed.ts:4"}, "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-6e406d0a9255e029", "name": "Commented-code block (9 lines) in apps/web/lib/csp.ts:22", "shortDescription": {"text": "Commented-code block (9 lines) in apps/web/lib/csp.ts:22"}, "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-ceb05fd10924f3ff", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/lib/csp.ts:38", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/lib/csp.ts:38"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5b9b1bde37dd62bd", "name": "Commented-code block (5 lines) in apps/web/lib/cors.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/lib/cors.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-e9d70b069d5b3dac", "name": "Commented-code block (8 lines) in apps/web/public/sw.js:20", "shortDescription": {"text": "Commented-code block (8 lines) in apps/web/public/sw.js:20"}, "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-afa71db46e224792", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/public/sw.js:140", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/public/sw.js:140"}, "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-7a320074b212dfd9", "name": "Commented-code block (6 lines) in apps/mobile/components/bottom-dock.tsx:1", "shortDescription": {"text": "Commented-code block (6 lines) in apps/mobile/components/bottom-dock.tsx: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-ec97cd1b7ecd61e8", "name": "Commented-code block (7 lines) in apps/mobile/components/bottom-tab-bar.tsx:1", "shortDescription": {"text": "Commented-code block (7 lines) in apps/mobile/components/bottom-tab-bar.tsx: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-2b47ed014757a02e", "name": "Commented-code block (6 lines) in apps/mobile/components/icons/tab-icons.tsx:1", "shortDescription": {"text": "Commented-code block (6 lines) in apps/mobile/components/icons/tab-icons.tsx: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-e79fa77cf05d5760", "name": "Commented-code block (5 lines) in apps/mobile/features/prayer-times/hooks/use-azkar-reminders.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in apps/mobile/features/prayer-times/hooks/use-azkar-reminders.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-0e4451d8d510d712", "name": "Commented-code block (6 lines) in apps/mobile/features/prayer-times/components/sun-arc.tsx:1", "shortDescription": {"text": "Commented-code block (6 lines) in apps/mobile/features/prayer-times/components/sun-arc.tsx: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-d64717d1cb566a09", "name": "Commented-code block (5 lines) in apps/mobile/features/quran/hooks/use-ayah-audio.ts:8", "shortDescription": {"text": "Commented-code block (5 lines) in apps/mobile/features/quran/hooks/use-ayah-audio.ts:8"}, "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-2ead3ae780a668e8", "name": "Commented-code block (6 lines) in apps/mobile/lib/api.ts:21", "shortDescription": {"text": "Commented-code block (6 lines) in apps/mobile/lib/api.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-f9e7f08b67db4c84", "name": "Commented-code block (5 lines) in apps/mobile/lib/player-context.tsx:1", "shortDescription": {"text": "Commented-code block (5 lines) in apps/mobile/lib/player-context.tsx: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-c3b1416a12444289", "name": "Commented-code block (6 lines) in apps/mobile/lib/theme-context.tsx:6", "shortDescription": {"text": "Commented-code block (6 lines) in apps/mobile/lib/theme-context.tsx:6"}, "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-e559a3aca3f95c72", "name": "Commented-code block (5 lines) in apps/mobile/lib/device-local.ts:3", "shortDescription": {"text": "Commented-code block (5 lines) in apps/mobile/lib/device-local.ts:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-319e66a630e14977", "name": "2 env vars used in code but missing from .env.example", "shortDescription": {"text": "2 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `CI`, `NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA`. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/23965"}, "properties": {"repository": "AhmedMuhammedElsaid/Nour-Platform", "repoUrl": "https://github.com/AhmedMuhammedElsaid/Nour-Platform", "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-fc610291627c4d22", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 packages/ui/src/blocks/audio-player/audio-player.tsx:215"}, "properties": {"repobilityId": "302b29aea79c4a2f", "scanner": "scanner-primary", "fingerprint": "fc610291627c4d22", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e5befbe2e8719e1d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/migrate.ts:84"}, "properties": {"repobilityId": "886ea65b2e117422", "scanner": "scanner-primary", "fingerprint": "e5befbe2e8719e1d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-71aac3dcf34e5e25", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-admin.ts:33"}, "properties": {"repobilityId": "442ee759a63ef5a7", "scanner": "scanner-primary", "fingerprint": "71aac3dcf34e5e25", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0347d29695339ebd", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-quran.ts:100"}, "properties": {"repobilityId": "5f90a62f3c588201", "scanner": "scanner-primary", "fingerprint": "0347d29695339ebd", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9f3225a3cbecf9c7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/heal-embedded-slugs.ts:27"}, "properties": {"repobilityId": "8d5e142d811f16b2", "scanner": "scanner-primary", "fingerprint": "9f3225a3cbecf9c7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6bf7befd51797e98", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-adhkar.ts:46"}, "properties": {"repobilityId": "5bf745a111da4843", "scanner": "scanner-primary", "fingerprint": "6bf7befd51797e98", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-771caf75679e127b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/heal-malformed-slugs.ts:70"}, "properties": {"repobilityId": "ae815db34d448f2b", "scanner": "scanner-primary", "fingerprint": "771caf75679e127b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1477c6fd6a7bdb4f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/reset-admin-password.ts:43"}, "properties": {"repobilityId": "6279f810d865c7f7", "scanner": "scanner-primary", "fingerprint": "1477c6fd6a7bdb4f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0213b1d0db424f09", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/admin/features/playlists/components/track-list.tsx:62"}, "properties": {"repobilityId": "7857c634982c8aa5", "scanner": "scanner-primary", "fingerprint": "0213b1d0db424f09", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1d5855a0ba39a882", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/admin/features/playlists/components/track-uploader.tsx:102"}, "properties": {"repobilityId": "0c0ace42d04ed876", "scanner": "scanner-primary", "fingerprint": "1d5855a0ba39a882", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e32c26d122bcc305", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/app/api/v1/quran/tafsir/route.ts:12"}, "properties": {"repobilityId": "b304d1799fa29930", "scanner": "scanner-primary", "fingerprint": "e32c26d122bcc305", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-615198146f704a1b", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/app/api/quran/tafsir/route.ts:9"}, "properties": {"repobilityId": "4a4292dd26787c42", "scanner": "scanner-primary", "fingerprint": "615198146f704a1b", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-3fada4b90c15b9b0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/features/player/components/continue-listening.tsx:122"}, "properties": {"repobilityId": "6168e6a7d0ecf1d2", "scanner": "scanner-primary", "fingerprint": "3fada4b90c15b9b0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-42d9ff757fe1a2e9", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/features/seo/components/json-ld.tsx:30"}, "properties": {"repobilityId": "6035735131cb8418", "scanner": "scanner-primary", "fingerprint": "42d9ff757fe1a2e9", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-262744216c379c62", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/features/quran/components/tafsir-sheet.tsx:83"}, "properties": {"repobilityId": "00785ef77f068ed0", "scanner": "scanner-primary", "fingerprint": "262744216c379c62", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-af6a18e8e53ff1b2", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/mobile/features/quran/components/tafsir-sheet.tsx:19"}, "properties": {"repobilityId": "49edb1b69a33805d", "scanner": "scanner-primary", "fingerprint": "af6a18e8e53ff1b2", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-6ff2db4d29bba0d7", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in apps/web/features/seo/components/json-ld.tsx:30"}, "properties": {"repobilityId": "1f0b543a8bfa9f77", "scanner": "scanner-primary", "fingerprint": "6ff2db4d29bba0d7", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/features/seo/components/json-ld.tsx"}, "region": {"startLine": 30}}}]}, {"ruleId": "scanner-611a2cc107050204", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in apps/web/features/quran/components/tafsir-sheet.tsx:83"}, "properties": {"repobilityId": "1f1dac8a5ddae972", "scanner": "scanner-primary", "fingerprint": "611a2cc107050204", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/features/quran/components/tafsir-sheet.tsx"}, "region": {"startLine": 83}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "ae16880318b99912", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "54597edb7f5bad38", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 31}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 37}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "54c8f1b47dd62535", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 46}}}]}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "7a9c96c6a4b6a8ad", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-0a0634ffe3eb1107", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/api/package.json"}, "properties": {"repobilityId": "61aa8b13d545e157", "scanner": "scanner-primary", "fingerprint": "0a0634ffe3eb1107", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/api/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3f65e1ca9b00183a", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/eslint-config/package.json"}, "properties": {"repobilityId": "7374bbf66cd702ed", "scanner": "scanner-primary", "fingerprint": "3f65e1ca9b00183a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/eslint-config/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-16c8b93ec958d12f", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/shared-core/package.json"}, "properties": {"repobilityId": "fd6737781d8408e6", "scanner": "scanner-primary", "fingerprint": "16c8b93ec958d12f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/shared-core/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-eddecaa766cadff2", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/config/package.json"}, "properties": {"repobilityId": "03931bf3537e3eaf", "scanner": "scanner-primary", "fingerprint": "eddecaa766cadff2", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/config/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-50218c90b43393bb", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/ui/package.json"}, "properties": {"repobilityId": "637e26a8c754e81d", "scanner": "scanner-primary", "fingerprint": "50218c90b43393bb", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/ui/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-5c30f715681a4005", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/admin/package.json"}, "properties": {"repobilityId": "17d56c8f05bdd359", "scanner": "scanner-primary", "fingerprint": "5c30f715681a4005", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/admin/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4a9eb7dc7c6e3880", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "properties": {"repobilityId": "6c1704bf24cf19ac", "scanner": "scanner-primary", "fingerprint": "4a9eb7dc7c6e3880", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-d0c2205560692580", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/mobile/package.json"}, "properties": {"repobilityId": "b3dfed7bb3d70ed3", "scanner": "scanner-primary", "fingerprint": "d0c2205560692580", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/mobile/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "1e8f309942abd14b", "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": "bdda21354c499413", "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": "537f34a6bec6fa1a", "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": "81dd32879e35148d", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-2b2bd7498f274cb5", "level": "none", "message": {"text": "Commented-code block (5 lines) in packages/api/src/db/migrations/0004-i18n-indexes.ts:47"}, "properties": {"repobilityId": "93ada6108a6c8afb", "scanner": "scanner-primary", "fingerprint": "2b2bd7498f274cb5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d6bfecce692242cd", "level": "none", "message": {"text": "Commented-code block (8 lines) in packages/shared-core/src/prayer-times/compute.ts:161"}, "properties": {"repobilityId": "926c2cd5fb0530ab", "scanner": "scanner-primary", "fingerprint": "d6bfecce692242cd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-07601dca2dcb56ff", "level": "none", "message": {"text": "Commented-code block (10 lines) in scripts/migrate.ts:39"}, "properties": {"repobilityId": "ebadb5b9f2658b10", "scanner": "scanner-primary", "fingerprint": "07601dca2dcb56ff", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-97b0650cc83d8983", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/seed-quran.ts:62"}, "properties": {"repobilityId": "9fb3a5ac556a3d57", "scanner": "scanner-primary", "fingerprint": "97b0650cc83d8983", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-593437fa00efc533", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/admin/proxy.ts:29"}, "properties": {"repobilityId": "eca19469a785bb5a", "scanner": "scanner-primary", "fingerprint": "593437fa00efc533", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-08b5a74a3c0de62b", "level": "none", "message": {"text": "Commented-code block (7 lines) in apps/admin/app/api/health/route.ts:5"}, "properties": {"repobilityId": "968a569147282273", "scanner": "scanner-primary", "fingerprint": "08b5a74a3c0de62b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1129d70d1ca1f611", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/admin/features/adhkar/components/azkar-items-editor.tsx:13"}, "properties": {"repobilityId": "99854ba9d0764f34", "scanner": "scanner-primary", "fingerprint": "1129d70d1ca1f611", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0d29d79de8d3f333", "level": "none", "message": {"text": "Commented-code block (7 lines) in apps/web/app/api/health/route.ts:5"}, "properties": {"repobilityId": "8211de6199e71291", "scanner": "scanner-primary", "fingerprint": "0d29d79de8d3f333", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-61b9d6b367fc7358", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/web/app/[locale]/adhkar/[slug]/page.tsx:13"}, "properties": {"repobilityId": "184d830795aaaa83", "scanner": "scanner-primary", "fingerprint": "61b9d6b367fc7358", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-99096d754ecab953", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/web/app/[locale]/playlists/[slug]/page.tsx:17"}, "properties": {"repobilityId": "d3604fdf80bb2a2d", "scanner": "scanner-primary", "fingerprint": "99096d754ecab953", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cf1f4fa50bb94cc8", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/web/features/prayer-times/hooks/use-adhan-scheduler.ts:60"}, "properties": {"repobilityId": "3dee096b01d8a557", "scanner": "scanner-primary", "fingerprint": "cf1f4fa50bb94cc8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d73e1e1d93e685b4", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/features/prayer-times/components/sun-arc.tsx:23"}, "properties": {"repobilityId": "8522fef9f4dbfe59", "scanner": "scanner-primary", "fingerprint": "d73e1e1d93e685b4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e38c1ac8a347ee82", "level": "none", "message": {"text": "Commented-code block (10 lines) in apps/web/features/prayer-times/lib/adhan-schedule.ts:37"}, "properties": {"repobilityId": "3b5c0a4148041375", "scanner": "scanner-primary", "fingerprint": "e38c1ac8a347ee82", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-252e6071721759f6", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/web/features/prayer-times/lib/azkar-reminder-schedule.ts:36"}, "properties": {"repobilityId": "22953e14d6c2f5ca", "scanner": "scanner-primary", "fingerprint": "252e6071721759f6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bd036bfb9b908b09", "level": "none", "message": {"text": "Commented-code block (7 lines) in apps/web/features/prayer-times/lib/fired-event-store.ts:1"}, "properties": {"repobilityId": "0ac786c14ad1c9e9", "scanner": "scanner-primary", "fingerprint": "bd036bfb9b908b09", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-dd43efc75ea158e8", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/features/quran/hooks/use-ayah-audio.ts:29"}, "properties": {"repobilityId": "00cb51e7c1fa47e1", "scanner": "scanner-primary", "fingerprint": "dd43efc75ea158e8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f36a2c96a9f7e5bd", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/web/features/playlists/lib/soundcloud-oembed.ts:4"}, "properties": {"repobilityId": "d2842d0e71e5d85c", "scanner": "scanner-primary", "fingerprint": "f36a2c96a9f7e5bd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6e406d0a9255e029", "level": "none", "message": {"text": "Commented-code block (9 lines) in apps/web/lib/csp.ts:22"}, "properties": {"repobilityId": "b7cfdd892e56d4c8", "scanner": "scanner-primary", "fingerprint": "6e406d0a9255e029", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ceb05fd10924f3ff", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/lib/csp.ts:38"}, "properties": {"repobilityId": "1a530c53b313ae05", "scanner": "scanner-primary", "fingerprint": "ceb05fd10924f3ff", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5b9b1bde37dd62bd", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/lib/cors.ts:1"}, "properties": {"repobilityId": "2c3fba6620719c52", "scanner": "scanner-primary", "fingerprint": "5b9b1bde37dd62bd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e9d70b069d5b3dac", "level": "none", "message": {"text": "Commented-code block (8 lines) in apps/web/public/sw.js:20"}, "properties": {"repobilityId": "12ca519a3735a984", "scanner": "scanner-primary", "fingerprint": "e9d70b069d5b3dac", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-afa71db46e224792", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/public/sw.js:140"}, "properties": {"repobilityId": "bb2396b2039e130e", "scanner": "scanner-primary", "fingerprint": "afa71db46e224792", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7a320074b212dfd9", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/mobile/components/bottom-dock.tsx:1"}, "properties": {"repobilityId": "a8bf802018d56e2a", "scanner": "scanner-primary", "fingerprint": "7a320074b212dfd9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ec97cd1b7ecd61e8", "level": "none", "message": {"text": "Commented-code block (7 lines) in apps/mobile/components/bottom-tab-bar.tsx:1"}, "properties": {"repobilityId": "9e579478edea0312", "scanner": "scanner-primary", "fingerprint": "ec97cd1b7ecd61e8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2b47ed014757a02e", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/mobile/components/icons/tab-icons.tsx:1"}, "properties": {"repobilityId": "a28d9a5f72e81462", "scanner": "scanner-primary", "fingerprint": "2b47ed014757a02e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e79fa77cf05d5760", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/mobile/features/prayer-times/hooks/use-azkar-reminders.ts:1"}, "properties": {"repobilityId": "5904b3cf10761182", "scanner": "scanner-primary", "fingerprint": "e79fa77cf05d5760", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0e4451d8d510d712", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/mobile/features/prayer-times/components/sun-arc.tsx:1"}, "properties": {"repobilityId": "280631ac10d53fbe", "scanner": "scanner-primary", "fingerprint": "0e4451d8d510d712", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d64717d1cb566a09", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/mobile/features/quran/hooks/use-ayah-audio.ts:8"}, "properties": {"repobilityId": "1199787becd47f19", "scanner": "scanner-primary", "fingerprint": "d64717d1cb566a09", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2ead3ae780a668e8", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/mobile/lib/api.ts:21"}, "properties": {"repobilityId": "e7f4b9897be3edb5", "scanner": "scanner-primary", "fingerprint": "2ead3ae780a668e8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f9e7f08b67db4c84", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/mobile/lib/player-context.tsx:1"}, "properties": {"repobilityId": "ae48368e686027df", "scanner": "scanner-primary", "fingerprint": "f9e7f08b67db4c84", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c3b1416a12444289", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/mobile/lib/theme-context.tsx:6"}, "properties": {"repobilityId": "96bb4e0afe6c3fd6", "scanner": "scanner-primary", "fingerprint": "c3b1416a12444289", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e559a3aca3f95c72", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/mobile/lib/device-local.ts:3"}, "properties": {"repobilityId": "66c2574c18179761", "scanner": "scanner-primary", "fingerprint": "e559a3aca3f95c72", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-319e66a630e14977", "level": "none", "message": {"text": "2 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "d838d1fc5d8231c9", "scanner": "scanner-primary", "fingerprint": "319e66a630e14977", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}]}]}