{"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-a7fecfbd89000155", "name": "Stray `console.log` in TS/JS \u2014 scripts/auth.ts:79", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/auth.ts:79"}, "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-8bf60188a4730a6b", "name": "Stray `console.log` in TS/JS \u2014 scripts/getEnv.ts:91", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/getEnv.ts:91"}, "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-a49909bbc741e118", "name": "Stray `console.log` in TS/JS \u2014 scripts/test_former_manual_ai.ts:7", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test_former_manual_ai.ts:7"}, "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-caa9fefcd7bd4c89", "name": "Stray `console.log` in TS/JS \u2014 scripts/test.ts:38", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test.ts:38"}, "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-90824f4d18f9c992", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-users-page.ts:12", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-users-page.ts:12"}, "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-6907d316ca69d1e1", "name": "Stray `console.log` in TS/JS \u2014 scripts/screenshot.ts:48", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/screenshot.ts:48"}, "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-9ed813981ebf541b", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-lab.ts:17", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-lab.ts:17"}, "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-f559ea67625079a5", "name": "Stray `console.log` in TS/JS \u2014 scripts/build.ts:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/build.ts:22"}, "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-510225c619b7fd75", "name": "Stray `console.log` in TS/JS \u2014 scripts/demo-test.ts:6", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/demo-test.ts:6"}, "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-de50903f47844064", "name": "Stray `console.log` in TS/JS \u2014 scripts/logs.ts:23", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/logs.ts:23"}, "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-726224d50c7081bb", "name": "Stray `console.log` in TS/JS \u2014 scripts/golden/generate.ts:249", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/golden/generate.ts:249"}, "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-0c67d07328f922e9", "name": "Stray `console.log` in TS/JS \u2014 scripts/e2e/rails_e2e.ts:27", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/e2e/rails_e2e.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-db519518cdcff9e6", "name": "Stray `console.log` in TS/JS \u2014 convex/imageRecognitionActions.ts:119", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 convex/imageRecognitionActions.ts:119"}, "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-efadb72d82ae0643", "name": "Stray `console.log` in TS/JS \u2014 convex/seed.ts:13", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 convex/seed.ts:13"}, "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-9a2c4e52327db7de", "name": "Stray `console.log` in TS/JS \u2014 convex/moderation.ts:1475", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 convex/moderation.ts:1475"}, "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-aa386ea026a5f395", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AppSidebar.tsx:188", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AppSidebar.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-a38effb70f4ea3d3", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/ops/index.tsx:134", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ops/index.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-78719a1215afd42a", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/ui/chart.tsx:81", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/ui/chart.tsx:81"}, "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-7d6b35ed77fc1805", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ImageRecognitionPage.tsx:251", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ImageRecognitionPage.tsx:251"}, "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-0efbc42d60644d72", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ModerationLogPage.tsx:142", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ModerationLogPage.tsx:142"}, "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-c95cdbdec61e8e37", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/QueuePage.tsx:1088", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/QueuePage.tsx:1088"}, "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-1b1bb4021fcddbda", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ModerateByIdPage.tsx:316", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ModerateByIdPage.tsx:316"}, "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-96b1392c9330f27b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ListsPage.tsx:412", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ListsPage.tsx:412"}, "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-3a9e939f7209ce45", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/MessagesPage.tsx:324", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/MessagesPage.tsx:324"}, "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-ef6a3a28ac995450", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/DashboardPage.tsx:266", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/DashboardPage.tsx:266"}, "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-a846e41b94e934d5", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/LabPage.tsx:174", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/LabPage.tsx:174"}, "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-016c476bfbb2f7e8", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/RulesPage.tsx:177", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/RulesPage.tsx:177"}, "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-c280fa1b57d5fac2", "name": "Privileged port 1001 in use", "shortDescription": {"text": "Privileged port 1001 in use"}, "fullDescription": {"text": "Port 1001 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1cb1b506e5a0716a", "name": "Privileged port 35 in use", "shortDescription": {"text": "Privileged port 35 in use"}, "fullDescription": {"text": "Port 35 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-aa5acaa49eb8315b", "name": "Containers defined but no K8s/orchestration manifest found", "shortDescription": {"text": "Containers defined but no K8s/orchestration manifest found"}, "fullDescription": {"text": "Repo has Dockerfiles/compose but no Kubernetes/Nomad manifests. If the target deployment is K8s, the manifests may live in a separate ops repo."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b58288e41547abf4", "name": "Possible secret in rails/spec/models/moderator_spec.rb", "shortDescription": {"text": "Possible secret in rails/spec/models/moderator_spec.rb"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-a047dc802a8c5032", "name": "Possible secret in rails/spec/requests/api/users_spec.rb", "shortDescription": {"text": "Possible secret in rails/spec/requests/api/users_spec.rb"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-5bf42bfaebbde9ed", "name": "Possible secret in rails/spec/requests/api/sessions_spec.rb", "shortDescription": {"text": "Possible secret in rails/spec/requests/api/sessions_spec.rb"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-1e27f215fe507e8e", "name": "Possible secret in rails/spec/requests/api/passwords_spec.rb", "shortDescription": {"text": "Possible secret in rails/spec/requests/api/passwords_spec.rb"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-549b893c78487825", "name": "Possible secret in rails/spec/support/api_helpers.rb", "shortDescription": {"text": "Possible secret in rails/spec/support/api_helpers.rb"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-080e1e443328ea67", "name": "Insecure pattern 'cors_wildcard' in rails/app/controllers/image_proxy_controller.rb:27", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in rails/app/controllers/image_proxy_controller.rb:27"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a8b7ac54e4944d86", "name": "Insecure pattern 'cors_wildcard' in rails/app/controllers/api/push_flagged_controller.rb:47", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in rails/app/controllers/api/push_flagged_controller.rb:47"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a0177386d6727424", "name": "Insecure pattern 'node_child_process' in scripts/redesign-screens.mjs:2", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/redesign-screens.mjs:2"}, "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-82662b9b45131802", "name": "Insecure pattern 'node_child_process' in scripts/auth.ts:1", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/auth.ts: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-72476dd8ad2f582e", "name": "Insecure pattern 'node_child_process' in scripts/getEnv.ts:1", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/getEnv.ts: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-ebc660611e246aab", "name": "Insecure pattern 'node_child_process' in scripts/test.ts:1", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/test.ts: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-a345e8b9255de105", "name": "Insecure pattern 'node_child_process' in scripts/screenshot.ts:1", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/screenshot.ts: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-7a94f0a3654d6593", "name": "Insecure pattern 'node_child_process' in scripts/redesign-public.mjs:2", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/redesign-public.mjs:2"}, "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-180233a674be78c4", "name": "Insecure pattern 'node_child_process' in scripts/logs.ts:1", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/logs.ts: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-31e7cbc9d5398573", "name": "Insecure pattern 'node_child_process' in scripts/queue-20-test.mjs:10", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/queue-20-test.mjs:10"}, "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-a7cdddedd9b5d3d9", "name": "Insecure pattern 'node_child_process' in scripts/redesign-screens2.mjs:2", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/redesign-screens2.mjs:2"}, "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-57ee8a0d258b788c", "name": "Insecure pattern 'private_key_in_repo' in convex/auth.ts:17", "shortDescription": {"text": "Insecure pattern 'private_key_in_repo' in convex/auth.ts:17"}, "fullDescription": {"text": "Found a known-risky pattern (private_key_in_repo). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-3616264d72115320", "name": "Insecure pattern 'cors_wildcard' in convex/http.ts:58", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in convex/http.ts:58"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-f560abfb99771ddd", "name": "Insecure pattern 'dangerous_innerhtml' in src/components/ui/chart.tsx:81", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/components/ui/chart.tsx:81"}, "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": "ruby/setup-ruby@v1 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-df9e707ff7cda24d", "name": "Very large file: convex/seedLists.ts (2182 lines)", "shortDescription": {"text": "Very large file: convex/seedLists.ts (2182 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5d470e782c572601", "name": "Very large file: convex/moderation.ts (1966 lines)", "shortDescription": {"text": "Very large file: convex/moderation.ts (1966 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-33a6dc747ad50632", "name": "Very large file: convex/seedAllRules.ts (1468 lines)", "shortDescription": {"text": "Very large file: convex/seedAllRules.ts (1468 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "13 test file(s) for 147 source file(s) (ratio 0.09). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 147 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 90 placeholder/mock markers across 28 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-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-5daa9a9d3a74df92", "name": "Commented-code block (7 lines) in rails/app/views/pwa/service-worker.js:8", "shortDescription": {"text": "Commented-code block (7 lines) in rails/app/views/pwa/service-worker.js: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-c814c0ac1bb7963f", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/sync-las-from-bq.py:59", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/sync-las-from-bq.py:59"}, "fullDescription": {"text": "`urllib.request.urlopen(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-05774936e6b41cea", "name": "Commented-code block (5 lines) in scripts/queue-20-test.mjs:3", "shortDescription": {"text": "Commented-code block (5 lines) in scripts/queue-20-test.mjs: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-914c3fa73eb8de30", "name": "Commented-code block (5 lines) in scripts/golden/generate.ts:3", "shortDescription": {"text": "Commented-code block (5 lines) in scripts/golden/generate.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-f4aef03047ad8292", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/e2e/rails_e2e.ts:50", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/e2e/rails_e2e.ts: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-4c8a07af1a7ccc48", "name": "Commented-code block (5 lines) in convex/remediation.ts:369", "shortDescription": {"text": "Commented-code block (5 lines) in convex/remediation.ts:369"}, "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-4ccbe4cfeb3d7bd5", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/remediation.ts:134", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/remediation.ts:134"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1457f9406e055558", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/viktorTools.ts:22", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/viktorTools.ts:22"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-44facd9927d95801", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/imageRecognitionActions.ts:205", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/imageRecognitionActions.ts:205"}, "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-a108ec5b7f759511", "name": "Commented-code block (7 lines) in convex/authz.ts:87", "shortDescription": {"text": "Commented-code block (7 lines) in convex/authz.ts:87"}, "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-b54cc0ce32659698", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/rulesAi.ts:110", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/rulesAi.ts:110"}, "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-879a18a53b0bafc0", "name": "Commented-code block (6 lines) in convex/_revokeLegacyTestAuth.ts:3", "shortDescription": {"text": "Commented-code block (6 lines) in convex/_revokeLegacyTestAuth.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-8f629b688eb1795e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/ViktorSpacesEmail.ts:36", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/ViktorSpacesEmail.ts:36"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-df8fbbec1f8ec041", "name": "Commented-code block (6 lines) in convex/moderation.ts:752", "shortDescription": {"text": "Commented-code block (6 lines) in convex/moderation.ts:752"}, "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-81e7ef0d2adb4581", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/moderation.ts:1566", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/moderation.ts:1566"}, "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-bcb39a4f6baa6c6c", "name": "Commented-code block (5 lines) in convex/seedAllRules.ts:1229", "shortDescription": {"text": "Commented-code block (5 lines) in convex/seedAllRules.ts:1229"}, "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-7e0b8a07c88c6b36", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/listsAi.ts:62", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/listsAi.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-e4347413dc5e99fd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 convex/aiParamScan.ts:461", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/aiParamScan.ts:461"}, "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-e8f65c0d2e09ec68", "name": "Commented-code block (7 lines) in src/components/JeImage.tsx:8", "shortDescription": {"text": "Commented-code block (7 lines) in src/components/JeImage.tsx: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-f77efe301dfbe21a", "name": "Commented-code block (9 lines) in src/lib/apiClient.ts:3", "shortDescription": {"text": "Commented-code block (9 lines) in src/lib/apiClient.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-a7a5da126d5d6a8c", "name": "Commented-code block (6 lines) in src/hooks/useApiQuery.ts:5", "shortDescription": {"text": "Commented-code block (6 lines) in src/hooks/useApiQuery.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-9a82cf7d16234d20", "name": "21 env vars used in code but missing from .env.example", "shortDescription": {"text": "21 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ANTHROPIC_API_KEY`, `APP_URL`, `AUTH_PRIVATE_KEY`, `CONVEX_SITE_URL`, `E2E_BASE_URL`, `E2E_CHROMIUM_PATH`, `FEEDLENS_API_BASE`, `FEEDLENS_API_KEY` + 13 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8e9387fe910e65db", "name": "Frontend route `/signup` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/signup` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-808ceccdc21bbe48", "name": "Frontend route `/users` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/users` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-acde7ab1e893848f", "name": "Frontend route `/image-recognition` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/image-recognition` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-840974726562f204", "name": "Frontend route `/moderate-by-id` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/moderate-by-id` has no Link/navigate to it \u2014 src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/21311"}, "properties": {"repository": "timur-cell/feedlens_moderation", "repoUrl": "https://github.com/timur-cell/feedlens_moderation", "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-a7fecfbd89000155", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/auth.ts:79"}, "properties": {"repobilityId": "7f83994acc353d0d", "scanner": "scanner-primary", "fingerprint": "a7fecfbd89000155", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8bf60188a4730a6b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/getEnv.ts:91"}, "properties": {"repobilityId": "8e1beda02fc878f0", "scanner": "scanner-primary", "fingerprint": "8bf60188a4730a6b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a49909bbc741e118", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test_former_manual_ai.ts:7"}, "properties": {"repobilityId": "91cba722f905854e", "scanner": "scanner-primary", "fingerprint": "a49909bbc741e118", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-caa9fefcd7bd4c89", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test.ts:38"}, "properties": {"repobilityId": "366bd2f243af55e3", "scanner": "scanner-primary", "fingerprint": "caa9fefcd7bd4c89", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-90824f4d18f9c992", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-users-page.ts:12"}, "properties": {"repobilityId": "d48801f274645fcc", "scanner": "scanner-primary", "fingerprint": "90824f4d18f9c992", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6907d316ca69d1e1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/screenshot.ts:48"}, "properties": {"repobilityId": "81570a54e8f710be", "scanner": "scanner-primary", "fingerprint": "6907d316ca69d1e1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9ed813981ebf541b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-lab.ts:17"}, "properties": {"repobilityId": "33b06a6dd9a08c0a", "scanner": "scanner-primary", "fingerprint": "9ed813981ebf541b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f559ea67625079a5", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/build.ts:22"}, "properties": {"repobilityId": "60ccf58db35ef027", "scanner": "scanner-primary", "fingerprint": "f559ea67625079a5", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-510225c619b7fd75", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/demo-test.ts:6"}, "properties": {"repobilityId": "33d4e4e43b242452", "scanner": "scanner-primary", "fingerprint": "510225c619b7fd75", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-de50903f47844064", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/logs.ts:23"}, "properties": {"repobilityId": "a2538dda152704cb", "scanner": "scanner-primary", "fingerprint": "de50903f47844064", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-726224d50c7081bb", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/golden/generate.ts:249"}, "properties": {"repobilityId": "6dc6cef8236666f9", "scanner": "scanner-primary", "fingerprint": "726224d50c7081bb", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0c67d07328f922e9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/e2e/rails_e2e.ts:27"}, "properties": {"repobilityId": "cdca81db645ff5bd", "scanner": "scanner-primary", "fingerprint": "0c67d07328f922e9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-db519518cdcff9e6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 convex/imageRecognitionActions.ts:119"}, "properties": {"repobilityId": "2002ca0dcb5f312e", "scanner": "scanner-primary", "fingerprint": "db519518cdcff9e6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-efadb72d82ae0643", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 convex/seed.ts:13"}, "properties": {"repobilityId": "343547810dd5a64c", "scanner": "scanner-primary", "fingerprint": "efadb72d82ae0643", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9a2c4e52327db7de", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 convex/moderation.ts:1475"}, "properties": {"repobilityId": "f3bcdc6d89cf69cb", "scanner": "scanner-primary", "fingerprint": "9a2c4e52327db7de", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-aa386ea026a5f395", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AppSidebar.tsx:188"}, "properties": {"repobilityId": "be1e4cca3f3be8bc", "scanner": "scanner-primary", "fingerprint": "aa386ea026a5f395", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a38effb70f4ea3d3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ops/index.tsx:134"}, "properties": {"repobilityId": "229f4f4ee2227e09", "scanner": "scanner-primary", "fingerprint": "a38effb70f4ea3d3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-78719a1215afd42a", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/ui/chart.tsx:81"}, "properties": {"repobilityId": "b8c68f17a4018107", "scanner": "scanner-primary", "fingerprint": "78719a1215afd42a", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-7d6b35ed77fc1805", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ImageRecognitionPage.tsx:251"}, "properties": {"repobilityId": "81bed391ae8f5378", "scanner": "scanner-primary", "fingerprint": "7d6b35ed77fc1805", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0efbc42d60644d72", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ModerationLogPage.tsx:142"}, "properties": {"repobilityId": "af05174727f61e7a", "scanner": "scanner-primary", "fingerprint": "0efbc42d60644d72", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c95cdbdec61e8e37", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/QueuePage.tsx:1088"}, "properties": {"repobilityId": "987ff2f006b0eda4", "scanner": "scanner-primary", "fingerprint": "c95cdbdec61e8e37", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1b1bb4021fcddbda", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ModerateByIdPage.tsx:316"}, "properties": {"repobilityId": "95c7176eb629ec91", "scanner": "scanner-primary", "fingerprint": "1b1bb4021fcddbda", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-96b1392c9330f27b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ListsPage.tsx:412"}, "properties": {"repobilityId": "2ae747b221cbcd86", "scanner": "scanner-primary", "fingerprint": "96b1392c9330f27b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3a9e939f7209ce45", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/MessagesPage.tsx:324"}, "properties": {"repobilityId": "6132b323c1ba84fa", "scanner": "scanner-primary", "fingerprint": "3a9e939f7209ce45", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ef6a3a28ac995450", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/DashboardPage.tsx:266"}, "properties": {"repobilityId": "5248edf1e73ab3b6", "scanner": "scanner-primary", "fingerprint": "ef6a3a28ac995450", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a846e41b94e934d5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/LabPage.tsx:174"}, "properties": {"repobilityId": "3e9db04c321700c1", "scanner": "scanner-primary", "fingerprint": "a846e41b94e934d5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-016c476bfbb2f7e8", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/RulesPage.tsx:177"}, "properties": {"repobilityId": "7f29a820ac6d24d0", "scanner": "scanner-primary", "fingerprint": "016c476bfbb2f7e8", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c280fa1b57d5fac2", "level": "warning", "message": {"text": "Privileged port 1001 in use"}, "properties": {"repobilityId": "eb126d41479634e4", "scanner": "scanner-primary", "fingerprint": "c280fa1b57d5fac2", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-1cb1b506e5a0716a", "level": "warning", "message": {"text": "Privileged port 35 in use"}, "properties": {"repobilityId": "e997ec9811d79c6d", "scanner": "scanner-primary", "fingerprint": "1cb1b506e5a0716a", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/config/recurring.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-aa5acaa49eb8315b", "level": "note", "message": {"text": "Containers defined but no K8s/orchestration manifest found"}, "properties": {"repobilityId": "b230ea9b68736081", "scanner": "scanner-primary", "fingerprint": "aa5acaa49eb8315b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["coverage", "deployment"]}}, {"ruleId": "scanner-b58288e41547abf4", "level": "error", "message": {"text": "Possible secret in rails/spec/models/moderator_spec.rb"}, "properties": {"repobilityId": "172a1643dbea3776", "scanner": "scanner-primary", "fingerprint": "b58288e41547abf4", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/spec/models/moderator_spec.rb"}, "region": {"startLine": 58}}}]}, {"ruleId": "scanner-a047dc802a8c5032", "level": "error", "message": {"text": "Possible secret in rails/spec/requests/api/users_spec.rb"}, "properties": {"repobilityId": "dacb3c58c95c3f57", "scanner": "scanner-primary", "fingerprint": "a047dc802a8c5032", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/spec/requests/api/users_spec.rb"}, "region": {"startLine": 114}}}]}, {"ruleId": "scanner-a047dc802a8c5032", "level": "error", "message": {"text": "Possible secret in rails/spec/requests/api/users_spec.rb"}, "properties": {"repobilityId": "dacb3c58c95c3f57", "scanner": "scanner-primary", "fingerprint": "a047dc802a8c5032", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/spec/requests/api/users_spec.rb"}, "region": {"startLine": 120}}}]}, {"ruleId": "scanner-a047dc802a8c5032", "level": "error", "message": {"text": "Possible secret in rails/spec/requests/api/users_spec.rb"}, "properties": {"repobilityId": "dacb3c58c95c3f57", "scanner": "scanner-primary", "fingerprint": "a047dc802a8c5032", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/spec/requests/api/users_spec.rb"}, "region": {"startLine": 198}}}]}, {"ruleId": "scanner-a047dc802a8c5032", "level": "error", "message": {"text": "Possible secret in rails/spec/requests/api/users_spec.rb"}, "properties": {"repobilityId": "dacb3c58c95c3f57", "scanner": "scanner-primary", "fingerprint": "a047dc802a8c5032", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/spec/requests/api/users_spec.rb"}, "region": {"startLine": 206}}}]}, {"ruleId": "scanner-5bf42bfaebbde9ed", "level": "error", "message": {"text": "Possible secret in rails/spec/requests/api/sessions_spec.rb"}, "properties": {"repobilityId": "ef847ca96592015d", "scanner": "scanner-primary", "fingerprint": "5bf42bfaebbde9ed", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/spec/requests/api/sessions_spec.rb"}, "region": {"startLine": 32}}}]}, {"ruleId": "scanner-5bf42bfaebbde9ed", "level": "error", "message": {"text": "Possible secret in rails/spec/requests/api/sessions_spec.rb"}, "properties": {"repobilityId": "ef847ca96592015d", "scanner": "scanner-primary", "fingerprint": "5bf42bfaebbde9ed", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/spec/requests/api/sessions_spec.rb"}, "region": {"startLine": 42}}}]}, {"ruleId": "scanner-5bf42bfaebbde9ed", "level": "error", "message": {"text": "Possible secret in rails/spec/requests/api/sessions_spec.rb"}, "properties": {"repobilityId": "ef847ca96592015d", "scanner": "scanner-primary", "fingerprint": "5bf42bfaebbde9ed", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/spec/requests/api/sessions_spec.rb"}, "region": {"startLine": 64}}}]}, {"ruleId": "scanner-1e27f215fe507e8e", "level": "error", "message": {"text": "Possible secret in rails/spec/requests/api/passwords_spec.rb"}, "properties": {"repobilityId": "f1e6570d260711fe", "scanner": "scanner-primary", "fingerprint": "1e27f215fe507e8e", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/spec/requests/api/passwords_spec.rb"}, "region": {"startLine": 25}}}]}, {"ruleId": "scanner-1e27f215fe507e8e", "level": "error", "message": {"text": "Possible secret in rails/spec/requests/api/passwords_spec.rb"}, "properties": {"repobilityId": "f1e6570d260711fe", "scanner": "scanner-primary", "fingerprint": "1e27f215fe507e8e", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/spec/requests/api/passwords_spec.rb"}, "region": {"startLine": 32}}}]}, {"ruleId": "scanner-549b893c78487825", "level": "error", "message": {"text": "Possible secret in rails/spec/support/api_helpers.rb"}, "properties": {"repobilityId": "295a9bc95117139a", "scanner": "scanner-primary", "fingerprint": "549b893c78487825", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/spec/support/api_helpers.rb"}, "region": {"startLine": 8}}}]}, {"ruleId": "scanner-080e1e443328ea67", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in rails/app/controllers/image_proxy_controller.rb:27"}, "properties": {"repobilityId": "9f65209c0dbb18da", "scanner": "scanner-primary", "fingerprint": "080e1e443328ea67", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/app/controllers/image_proxy_controller.rb"}, "region": {"startLine": 27}}}]}, {"ruleId": "scanner-a8b7ac54e4944d86", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in rails/app/controllers/api/push_flagged_controller.rb:47"}, "properties": {"repobilityId": "4cd2fe7c16ecf5b8", "scanner": "scanner-primary", "fingerprint": "a8b7ac54e4944d86", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rails/app/controllers/api/push_flagged_controller.rb"}, "region": {"startLine": 47}}}]}, {"ruleId": "scanner-a0177386d6727424", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/redesign-screens.mjs:2"}, "properties": {"repobilityId": "1b6b7b9536f14d1b", "scanner": "scanner-primary", "fingerprint": "a0177386d6727424", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/redesign-screens.mjs"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-82662b9b45131802", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/auth.ts:1"}, "properties": {"repobilityId": "9a9a5cd8256f7ed2", "scanner": "scanner-primary", "fingerprint": "82662b9b45131802", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/auth.ts"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-72476dd8ad2f582e", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/getEnv.ts:1"}, "properties": {"repobilityId": "f35c47556e4225f9", "scanner": "scanner-primary", "fingerprint": "72476dd8ad2f582e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/getEnv.ts"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ebc660611e246aab", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/test.ts:1"}, "properties": {"repobilityId": "3603e8a2cfc623ba", "scanner": "scanner-primary", "fingerprint": "ebc660611e246aab", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/test.ts"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-a345e8b9255de105", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/screenshot.ts:1"}, "properties": {"repobilityId": "94356314b09c3f25", "scanner": "scanner-primary", "fingerprint": "a345e8b9255de105", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/screenshot.ts"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-7a94f0a3654d6593", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/redesign-public.mjs:2"}, "properties": {"repobilityId": "4ce051bd07905470", "scanner": "scanner-primary", "fingerprint": "7a94f0a3654d6593", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/redesign-public.mjs"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-180233a674be78c4", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/logs.ts:1"}, "properties": {"repobilityId": "86281daafff61557", "scanner": "scanner-primary", "fingerprint": "180233a674be78c4", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/logs.ts"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-31e7cbc9d5398573", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/queue-20-test.mjs:10"}, "properties": {"repobilityId": "e720dd57de4e0ae6", "scanner": "scanner-primary", "fingerprint": "31e7cbc9d5398573", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/queue-20-test.mjs"}, "region": {"startLine": 10}}}]}, {"ruleId": "scanner-a7cdddedd9b5d3d9", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/redesign-screens2.mjs:2"}, "properties": {"repobilityId": "abf2e1d12754c793", "scanner": "scanner-primary", "fingerprint": "a7cdddedd9b5d3d9", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/redesign-screens2.mjs"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-57ee8a0d258b788c", "level": "error", "message": {"text": "Insecure pattern 'private_key_in_repo' in convex/auth.ts:17"}, "properties": {"repobilityId": "0e98a9826913a0dc", "scanner": "scanner-primary", "fingerprint": "57ee8a0d258b788c", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["owasp", "private_key_in_repo"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "convex/auth.ts"}, "region": {"startLine": 17}}}]}, {"ruleId": "scanner-3616264d72115320", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in convex/http.ts:58"}, "properties": {"repobilityId": "275ed841cb34dafb", "scanner": "scanner-primary", "fingerprint": "3616264d72115320", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "convex/http.ts"}, "region": {"startLine": 58}}}]}, {"ruleId": "scanner-f560abfb99771ddd", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/components/ui/chart.tsx:81"}, "properties": {"repobilityId": "33f10636e53b4298", "scanner": "scanner-primary", "fingerprint": "f560abfb99771ddd", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/ui/chart.tsx"}, "region": {"startLine": 81}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "64978d6af70613bb", "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": 42}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "dcb6504096fc20e7", "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": 69}}}]}, {"ruleId": "scanner-df9e707ff7cda24d", "level": "note", "message": {"text": "Very large file: convex/seedLists.ts (2182 lines)"}, "properties": {"repobilityId": "33e8bd4457f61109", "scanner": "scanner-primary", "fingerprint": "df9e707ff7cda24d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-5d470e782c572601", "level": "note", "message": {"text": "Very large file: convex/moderation.ts (1966 lines)"}, "properties": {"repobilityId": "cafcb9259e843410", "scanner": "scanner-primary", "fingerprint": "5d470e782c572601", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-33a6dc747ad50632", "level": "note", "message": {"text": "Very large file: convex/seedAllRules.ts (1468 lines)"}, "properties": {"repobilityId": "7e3ae328fe4d8017", "scanner": "scanner-primary", "fingerprint": "33a6dc747ad50632", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "19eb3dcb26b736b0", "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": "b5f9e6e49bc55e64", "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": "ce6385cf51f90098", "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": "84db583cd26b605c", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "f2e7ca8b0f35279f", "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": "9b5fd227d5421d24", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-5daa9a9d3a74df92", "level": "none", "message": {"text": "Commented-code block (7 lines) in rails/app/views/pwa/service-worker.js:8"}, "properties": {"repobilityId": "fe31de9bda4d8375", "scanner": "scanner-primary", "fingerprint": "5daa9a9d3a74df92", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c814c0ac1bb7963f", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/sync-las-from-bq.py:59"}, "properties": {"repobilityId": "5baf920fe463786a", "scanner": "scanner-primary", "fingerprint": "c814c0ac1bb7963f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-05774936e6b41cea", "level": "none", "message": {"text": "Commented-code block (5 lines) in scripts/queue-20-test.mjs:3"}, "properties": {"repobilityId": "3105cbcdb6ed3ded", "scanner": "scanner-primary", "fingerprint": "05774936e6b41cea", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-914c3fa73eb8de30", "level": "none", "message": {"text": "Commented-code block (5 lines) in scripts/golden/generate.ts:3"}, "properties": {"repobilityId": "e8b7d4a68e4ec0a1", "scanner": "scanner-primary", "fingerprint": "914c3fa73eb8de30", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f4aef03047ad8292", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/e2e/rails_e2e.ts:50"}, "properties": {"repobilityId": "81f83da7ac85debb", "scanner": "scanner-primary", "fingerprint": "f4aef03047ad8292", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4c8a07af1a7ccc48", "level": "none", "message": {"text": "Commented-code block (5 lines) in convex/remediation.ts:369"}, "properties": {"repobilityId": "a52fa5f509130e43", "scanner": "scanner-primary", "fingerprint": "4c8a07af1a7ccc48", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4ccbe4cfeb3d7bd5", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/remediation.ts:134"}, "properties": {"repobilityId": "3b20ecf34b772416", "scanner": "scanner-primary", "fingerprint": "4ccbe4cfeb3d7bd5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1457f9406e055558", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/viktorTools.ts:22"}, "properties": {"repobilityId": "072bd430ae27a8be", "scanner": "scanner-primary", "fingerprint": "1457f9406e055558", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-44facd9927d95801", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/imageRecognitionActions.ts:205"}, "properties": {"repobilityId": "1b67ef9e723c0909", "scanner": "scanner-primary", "fingerprint": "44facd9927d95801", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a108ec5b7f759511", "level": "none", "message": {"text": "Commented-code block (7 lines) in convex/authz.ts:87"}, "properties": {"repobilityId": "abf36c81fe46c097", "scanner": "scanner-primary", "fingerprint": "a108ec5b7f759511", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b54cc0ce32659698", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/rulesAi.ts:110"}, "properties": {"repobilityId": "47ce071e6a13c474", "scanner": "scanner-primary", "fingerprint": "b54cc0ce32659698", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-879a18a53b0bafc0", "level": "none", "message": {"text": "Commented-code block (6 lines) in convex/_revokeLegacyTestAuth.ts:3"}, "properties": {"repobilityId": "a26b43bc4c4d0a82", "scanner": "scanner-primary", "fingerprint": "879a18a53b0bafc0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8f629b688eb1795e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/ViktorSpacesEmail.ts:36"}, "properties": {"repobilityId": "885a63093212caad", "scanner": "scanner-primary", "fingerprint": "8f629b688eb1795e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-df8fbbec1f8ec041", "level": "none", "message": {"text": "Commented-code block (6 lines) in convex/moderation.ts:752"}, "properties": {"repobilityId": "435f3ede91ee70a2", "scanner": "scanner-primary", "fingerprint": "df8fbbec1f8ec041", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-81e7ef0d2adb4581", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/moderation.ts:1566"}, "properties": {"repobilityId": "fe83c1496c93bf6a", "scanner": "scanner-primary", "fingerprint": "81e7ef0d2adb4581", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bcb39a4f6baa6c6c", "level": "none", "message": {"text": "Commented-code block (5 lines) in convex/seedAllRules.ts:1229"}, "properties": {"repobilityId": "1787144b32a6140b", "scanner": "scanner-primary", "fingerprint": "bcb39a4f6baa6c6c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7e0b8a07c88c6b36", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/listsAi.ts:62"}, "properties": {"repobilityId": "976a36c55862260f", "scanner": "scanner-primary", "fingerprint": "7e0b8a07c88c6b36", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e4347413dc5e99fd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 convex/aiParamScan.ts:461"}, "properties": {"repobilityId": "0219dde8a663c5d4", "scanner": "scanner-primary", "fingerprint": "e4347413dc5e99fd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e8f65c0d2e09ec68", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/components/JeImage.tsx:8"}, "properties": {"repobilityId": "01c091c10620b6e7", "scanner": "scanner-primary", "fingerprint": "e8f65c0d2e09ec68", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f77efe301dfbe21a", "level": "none", "message": {"text": "Commented-code block (9 lines) in src/lib/apiClient.ts:3"}, "properties": {"repobilityId": "e789a5ba3deb04b2", "scanner": "scanner-primary", "fingerprint": "f77efe301dfbe21a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a7a5da126d5d6a8c", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/hooks/useApiQuery.ts:5"}, "properties": {"repobilityId": "64ff7b0d47caa084", "scanner": "scanner-primary", "fingerprint": "a7a5da126d5d6a8c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9a82cf7d16234d20", "level": "note", "message": {"text": "21 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "2fad2cbef136ee78", "scanner": "scanner-primary", "fingerprint": "9a82cf7d16234d20", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-8e9387fe910e65db", "level": "warning", "message": {"text": "Frontend route `/signup` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "9a43492bdaf235d5", "scanner": "scanner-primary", "fingerprint": "8e9387fe910e65db", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-808ceccdc21bbe48", "level": "warning", "message": {"text": "Frontend route `/users` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "3a0db38f03a26310", "scanner": "scanner-primary", "fingerprint": "808ceccdc21bbe48", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-acde7ab1e893848f", "level": "warning", "message": {"text": "Frontend route `/image-recognition` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "24b71975ed632e0a", "scanner": "scanner-primary", "fingerprint": "acde7ab1e893848f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-840974726562f204", "level": "warning", "message": {"text": "Frontend route `/moderate-by-id` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "0a7e676219dad4ce", "scanner": "scanner-primary", "fingerprint": "840974726562f204", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}]}]}