{"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-599c3ec1ecdef87a", "name": "Possibly dead Python function: boost_health", "shortDescription": {"text": "Possibly dead Python function: boost_health"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d8190ab083f5147d", "name": "Possibly dead Python function: set_anthropic_client", "shortDescription": {"text": "Possibly dead Python function: set_anthropic_client"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c9d6b09f98b22e0d", "name": "Possibly dead Python function: set_anthropic_client", "shortDescription": {"text": "Possibly dead Python function: set_anthropic_client"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4f3736cf9c9465e0", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/SearchableSelect.tsx:115", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/SearchableSelect.tsx:115"}, "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-e79f1cf62ca1b367", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/InviteBotsModal.tsx:104", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/InviteBotsModal.tsx:104"}, "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-5dbc1327bd3ef055", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/BotMessenger.tsx:384", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/BotMessenger.tsx:384"}, "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-1d4090b255b98bc2", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/AddGroupsWizard.tsx:541", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/AddGroupsWizard.tsx:541"}, "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-8726377916944a0e", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/GroupDetailModal.tsx:177", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/GroupDetailModal.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-b3860c5a9997f1db", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/shell/AdminShell.tsx:96", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/shell/AdminShell.tsx:96"}, "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-667d0e2e174e569a", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/shell/AppShell.tsx:259", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/shell/AppShell.tsx:259"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-688e0ddaa4c9efcb", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Bots.tsx:245", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Bots.tsx:245"}, "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-c036a2caa05d5106", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Groups.tsx:413", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Groups.tsx:413"}, "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-1fefb12ab8b7de42", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Activity.tsx:753", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Activity.tsx:753"}, "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-edd89cafd0c3affb", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Leads.tsx:1106", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Leads.tsx:1106"}, "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-cb7f93a5c3466662", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Dashboard.tsx:121", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Dashboard.tsx:121"}, "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-c5cce64140a4f0d9", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/admin/Proxies.tsx:157", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/admin/Proxies.tsx:157"}, "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-a32c1965f022fde6", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/admin/TenantDetail.tsx:243", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/admin/TenantDetail.tsx:243"}, "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-32159a328ebbddad", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/admin/Appeals.tsx:268", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/admin/Appeals.tsx:268"}, "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-c4c11fa65406094e", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/admin/BotDetail.tsx:684", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/admin/BotDetail.tsx:684"}, "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-5711bc7a764ef3d1", "name": "Dockerfile runs as root: apps/worker/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: apps/worker/Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7d088219524090a5", "name": "Docker base image is tag-pinned but not digest-pinned: python:3.11-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.11-slim"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4944204233b58e2c", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/_shared/cors.ts:5", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/_shared/cors.ts:5"}, "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-e4f658c0c00de0d4", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/deploy-pages@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-448d8837178ae57a", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-bd4ed5c8d5d215cf", "name": "Very large file: apps/worker/parpost/adapters/telegram.py (1009 lines)", "shortDescription": {"text": "Very large file: apps/worker/parpost/adapters/telegram.py (1009 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-f717eadc659356db", "name": "Very large file: apps/web/src/routes/app/Audience.tsx (2439 lines)", "shortDescription": {"text": "Very large file: apps/web/src/routes/app/Audience.tsx (2439 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-8a68de0382e8bd4a", "name": "Very large file: apps/web/src/routes/app/Leads.tsx (1624 lines)", "shortDescription": {"text": "Very large file: apps/web/src/routes/app/Leads.tsx (1624 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-bccee20f577a1a21", "name": "Very large file: apps/web/src/routes/admin/BotDetail.tsx (1410 lines)", "shortDescription": {"text": "Very large file: apps/web/src/routes/admin/BotDetail.tsx (1410 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-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-cb3e52667c84fb86", "name": "Node manifest has dependencies but no lockfile: packages/types/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/types/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4a9eb7dc7c6e3880", "name": "Node manifest has dependencies but no lockfile: apps/web/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 109 placeholder/mock markers across 32 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-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license, lockfile. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c2afbd5c476621ec", "name": "Commented-code block (5 lines) in supabase/functions/impersonate/index.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in supabase/functions/impersonate/index.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-393369ba064612a9", "name": "Commented-code block (7 lines) in supabase/functions/admin-adjust-parsy/index.ts:1", "shortDescription": {"text": "Commented-code block (7 lines) in supabase/functions/admin-adjust-parsy/index.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-d3ea97bbb1a683df", "name": "Commented-code block (6 lines) in supabase/functions/learning-assist/index.ts:1", "shortDescription": {"text": "Commented-code block (6 lines) in supabase/functions/learning-assist/index.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-f876f6c8e607df29", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/learning-assist/index.ts:91", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/learning-assist/index.ts:91"}, "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-f6d4a67d13ce256f", "name": "Commented-code block (5 lines) in supabase/functions/admin-proxy-stats/index.ts:14", "shortDescription": {"text": "Commented-code block (5 lines) in supabase/functions/admin-proxy-stats/index.ts:14"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ac2446374357b1dd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/inbox-draft/index.ts:104", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/inbox-draft/index.ts:104"}, "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-37ed1c4e014ec8b2", "name": "Commented-code block (5 lines) in supabase/functions/_shared/supabase.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in supabase/functions/_shared/supabase.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-3037690801d2ea1e", "name": "Commented-code block (5 lines) in supabase/functions/stripe-webhook/index.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in supabase/functions/stripe-webhook/index.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-5c40eaa8c9a78b2b", "name": "Commented-code block (7 lines) in supabase/functions/lead-verdict/index.ts:1", "shortDescription": {"text": "Commented-code block (7 lines) in supabase/functions/lead-verdict/index.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-db7efd7306895d35", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/lead-verdict/index.ts:84", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/lead-verdict/index.ts:84"}, "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-919142950cd30113", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/ai-generate/index.ts:254", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/ai-generate/index.ts:254"}, "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-c2ab080d0263d74a", "name": "Commented-code block (8 lines) in supabase/functions/admin-proxy-create/index.ts:7", "shortDescription": {"text": "Commented-code block (8 lines) in supabase/functions/admin-proxy-create/index.ts:7"}, "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-0ce98a7b5bf27533", "name": "Stub function `self_avatar` (body is just `pass`/`return`) \u2014 apps/worker/parpost/adapters/facebook.py:81", "shortDescription": {"text": "Stub function `self_avatar` (body is just `pass`/`return`) \u2014 apps/worker/parpost/adapters/facebook.py:81"}, "fullDescription": {"text": "Likely an AI scaffold that was never filled in. Remove or implement."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ecf601a69bb60bde", "name": "Commented-code block (6 lines) in apps/web/src/main.tsx:17", "shortDescription": {"text": "Commented-code block (6 lines) in apps/web/src/main.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-14f926b154bf11a7", "name": "Commented-code block (6 lines) in apps/web/src/hooks/useTenantBalance.ts:7", "shortDescription": {"text": "Commented-code block (6 lines) in apps/web/src/hooks/useTenantBalance.ts:7"}, "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-6e2b4bffa6e72772", "name": "Commented-code block (5 lines) in apps/web/src/components/BotProfileEditModal.tsx:76", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/src/components/BotProfileEditModal.tsx:76"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0105c7344d7fa8d6", "name": "Commented-code block (7 lines) in apps/web/src/lib/supabase.ts:16", "shortDescription": {"text": "Commented-code block (7 lines) in apps/web/src/lib/supabase.ts:16"}, "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-b5eee375f0252d07", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/lib/supabase.ts:134", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/lib/supabase.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-530a937cbd16e669", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Audience.tsx:780", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Audience.tsx:780"}, "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-812c161b756155d2", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Posting.tsx:748", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Posting.tsx:748"}, "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-7115f40994b383a9", "name": "Commented-code block (5 lines) in apps/web/src/routes/app/Leads.tsx:151", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/src/routes/app/Leads.tsx:151"}, "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-eeb3636e9eea9e27", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Leads.tsx:234", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Leads.tsx:234"}, "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-6eef6e94ef0b1b48", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Settings.tsx:245", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Settings.tsx:245"}, "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-755e4b0b74c5878b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Billing.tsx:134", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Billing.tsx: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-7ea36975cf194416", "name": "Commented-code block (6 lines) in apps/web/src/routes/admin/Proxies.tsx:11", "shortDescription": {"text": "Commented-code block (6 lines) in apps/web/src/routes/admin/Proxies.tsx:11"}, "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-fcb048350dcf5746", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/admin/TenantDetail.tsx:74", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/admin/TenantDetail.tsx:74"}, "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-3507d014555c6572", "name": "Commented-code block (5 lines) in apps/web/src/routes/admin/BotDetail.tsx:869", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/src/routes/admin/BotDetail.tsx:869"}, "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-b334d875f2339fa1", "name": "5 env vars used in code but missing from .env.example", "shortDescription": {"text": "5 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `BASE_URL`, `MODE`, `VITE_BASE_PATH`, `VITE_SUPABASE_ANON_KEY`, `VITE_SUPABASE_URL`. 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-2c04133e54348533", "name": "Near-duplicate function bodies in 2 places", "shortDescription": {"text": "Near-duplicate function bodies in 2 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\napps/worker/parpost/metering.py:debit, apps/worker/parpost/metering.py:credit\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-be46ea126aa5d8dc", "name": "Near-duplicate function bodies in 3 places", "shortDescription": {"text": "Near-duplicate function bodies in 3 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\napps/worker/parpost/adapters/telegram.py:post, apps/worker/parpost/adapters/facebook.py:post, apps/worker/parpost/adapters/base.py:post\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-600652c55e0e7210", "name": "Frontend route `/verify` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `/verify` has no Link/navigate to it \u2014 apps/web/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-48f0655fef3f1d83", "name": "Frontend route `bots` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `bots` has no Link/navigate to it \u2014 apps/web/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-10af3d1f2317df4f", "name": "Frontend route `audience` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `audience` has no Link/navigate to it \u2014 apps/web/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-4f846750ecdee04d", "name": "Frontend route `posting` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `posting` has no Link/navigate to it \u2014 apps/web/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-e6f084391512a9f1", "name": "Frontend route `groups` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `groups` has no Link/navigate to it \u2014 apps/web/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-f8f805ddd9556a47", "name": "Frontend route `leads` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `leads` has no Link/navigate to it \u2014 apps/web/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-697f7d6fc1b60192", "name": "Frontend route `inbox` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `inbox` has no Link/navigate to it \u2014 apps/web/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-9f20e1473acfd395", "name": "Frontend route `activity` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `activity` has no Link/navigate to it \u2014 apps/web/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-c440054c57b73ba8", "name": "Frontend route `billing` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `billing` has no Link/navigate to it \u2014 apps/web/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-42bfc76f6bb25e2f", "name": "Frontend route `settings` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `settings` has no Link/navigate to it \u2014 apps/web/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-23125f3709c9108e", "name": "Frontend route `tenants` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `tenants` has no Link/navigate to it \u2014 apps/web/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-27ec93b47564c74e", "name": "Frontend route `tenants/:id` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `tenants/:id` has no Link/navigate to it \u2014 apps/web/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-57b49450b9eff155", "name": "Frontend route `fleet` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `fleet` has no Link/navigate to it \u2014 apps/web/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-a40a3f5eb7c6075a", "name": "Frontend route `bots/:id` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `bots/:id` has no Link/navigate to it \u2014 apps/web/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-014ea487d8e0630d", "name": "Frontend route `proxies` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `proxies` has no Link/navigate to it \u2014 apps/web/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-c0066f0f8666bef6", "name": "Frontend route `config` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `config` has no Link/navigate to it \u2014 apps/web/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-a1be83e9afe57809", "name": "Frontend route `abuse` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `abuse` has no Link/navigate to it \u2014 apps/web/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-8d6f15305337e985", "name": "Frontend route `appeals` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `appeals` has no Link/navigate to it \u2014 apps/web/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-b21c6d063f82725b", "name": "Frontend route `audit` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `audit` has no Link/navigate to it \u2014 apps/web/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/25331"}, "properties": {"repository": "denkrupka/ParPost", "repoUrl": "https://github.com/denkrupka/ParPost", "branch": "main"}, "results": [{"ruleId": "scanner-599c3ec1ecdef87a", "level": "note", "message": {"text": "Possibly dead Python function: boost_health"}, "properties": {"repobilityId": "05374763112d9fc8", "scanner": "scanner-primary", "fingerprint": "599c3ec1ecdef87a", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/worker/parpost/pacing.py:170"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-d8190ab083f5147d", "level": "note", "message": {"text": "Possibly dead Python function: set_anthropic_client"}, "properties": {"repobilityId": "981ed3bb615549bf", "scanner": "scanner-primary", "fingerprint": "d8190ab083f5147d", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/worker/parpost/ai/inbox_draft.py:29"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-c9d6b09f98b22e0d", "level": "note", "message": {"text": "Possibly dead Python function: set_anthropic_client"}, "properties": {"repobilityId": "981ed3bb615549bf", "scanner": "scanner-primary", "fingerprint": "c9d6b09f98b22e0d", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/worker/parpost/ai/group_ai.py:27"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4f3736cf9c9465e0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/SearchableSelect.tsx:115"}, "properties": {"repobilityId": "f8f0c4026349cabc", "scanner": "scanner-primary", "fingerprint": "4f3736cf9c9465e0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e79f1cf62ca1b367", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/InviteBotsModal.tsx:104"}, "properties": {"repobilityId": "f157a1779f816f60", "scanner": "scanner-primary", "fingerprint": "e79f1cf62ca1b367", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5dbc1327bd3ef055", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/BotMessenger.tsx:384"}, "properties": {"repobilityId": "b21a5da5e24bbc40", "scanner": "scanner-primary", "fingerprint": "5dbc1327bd3ef055", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1d4090b255b98bc2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/AddGroupsWizard.tsx:541"}, "properties": {"repobilityId": "2587c905e0f7859d", "scanner": "scanner-primary", "fingerprint": "1d4090b255b98bc2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8726377916944a0e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/GroupDetailModal.tsx:177"}, "properties": {"repobilityId": "a90e855f5eb17a60", "scanner": "scanner-primary", "fingerprint": "8726377916944a0e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b3860c5a9997f1db", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/shell/AdminShell.tsx:96"}, "properties": {"repobilityId": "f3fedb6900d84eca", "scanner": "scanner-primary", "fingerprint": "b3860c5a9997f1db", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-667d0e2e174e569a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/shell/AppShell.tsx:259"}, "properties": {"repobilityId": "d30f6b54bfb1a249", "scanner": "scanner-primary", "fingerprint": "667d0e2e174e569a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-688e0ddaa4c9efcb", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Bots.tsx:245"}, "properties": {"repobilityId": "bfe6d1f2c34a83f2", "scanner": "scanner-primary", "fingerprint": "688e0ddaa4c9efcb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c036a2caa05d5106", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Groups.tsx:413"}, "properties": {"repobilityId": "d68fb5d35048df2e", "scanner": "scanner-primary", "fingerprint": "c036a2caa05d5106", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1fefb12ab8b7de42", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Activity.tsx:753"}, "properties": {"repobilityId": "55ea4406925746f3", "scanner": "scanner-primary", "fingerprint": "1fefb12ab8b7de42", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-edd89cafd0c3affb", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Leads.tsx:1106"}, "properties": {"repobilityId": "4e9f84474ca28d29", "scanner": "scanner-primary", "fingerprint": "edd89cafd0c3affb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-cb7f93a5c3466662", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/app/Dashboard.tsx:121"}, "properties": {"repobilityId": "20bfe02c28445f61", "scanner": "scanner-primary", "fingerprint": "cb7f93a5c3466662", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c5cce64140a4f0d9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/admin/Proxies.tsx:157"}, "properties": {"repobilityId": "11a4c3b632c4d51f", "scanner": "scanner-primary", "fingerprint": "c5cce64140a4f0d9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a32c1965f022fde6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/admin/TenantDetail.tsx:243"}, "properties": {"repobilityId": "d55e06493ca69a43", "scanner": "scanner-primary", "fingerprint": "a32c1965f022fde6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-32159a328ebbddad", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/admin/Appeals.tsx:268"}, "properties": {"repobilityId": "7eb39a73031de65c", "scanner": "scanner-primary", "fingerprint": "32159a328ebbddad", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c4c11fa65406094e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/routes/admin/BotDetail.tsx:684"}, "properties": {"repobilityId": "192d6673be75ab4e", "scanner": "scanner-primary", "fingerprint": "c4c11fa65406094e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5711bc7a764ef3d1", "level": "warning", "message": {"text": "Dockerfile runs as root: apps/worker/Dockerfile"}, "properties": {"repobilityId": "cf4cee7637fe488a", "scanner": "scanner-primary", "fingerprint": "5711bc7a764ef3d1", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-7d088219524090a5", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.11-slim"}, "properties": {"repobilityId": "44f6494a86865156", "scanner": "scanner-primary", "fingerprint": "7d088219524090a5", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/worker/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4944204233b58e2c", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/_shared/cors.ts:5"}, "properties": {"repobilityId": "7c8e268f4e944077", "scanner": "scanner-primary", "fingerprint": "4944204233b58e2c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/_shared/cors.ts"}, "region": {"startLine": 5}}}]}, {"ruleId": "scanner-e4f658c0c00de0d4", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "25e1fa3783e7cb32", "scanner": "scanner-primary", "fingerprint": "e4f658c0c00de0d4", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/pages.yml"}, "region": {"startLine": 49}}}]}, {"ruleId": "scanner-448d8837178ae57a", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "13af6451e15656fc", "scanner": "scanner-primary", "fingerprint": "448d8837178ae57a", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/pages.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-bd4ed5c8d5d215cf", "level": "note", "message": {"text": "Very large file: apps/worker/parpost/adapters/telegram.py (1009 lines)"}, "properties": {"repobilityId": "4df1b429d87778bd", "scanner": "scanner-primary", "fingerprint": "bd4ed5c8d5d215cf", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-f717eadc659356db", "level": "note", "message": {"text": "Very large file: apps/web/src/routes/app/Audience.tsx (2439 lines)"}, "properties": {"repobilityId": "b9e61f08274836a1", "scanner": "scanner-primary", "fingerprint": "f717eadc659356db", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-8a68de0382e8bd4a", "level": "note", "message": {"text": "Very large file: apps/web/src/routes/app/Leads.tsx (1624 lines)"}, "properties": {"repobilityId": "85c1bd784112a2bc", "scanner": "scanner-primary", "fingerprint": "8a68de0382e8bd4a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-bccee20f577a1a21", "level": "note", "message": {"text": "Very large file: apps/web/src/routes/admin/BotDetail.tsx (1410 lines)"}, "properties": {"repobilityId": "8dd023da652e4847", "scanner": "scanner-primary", "fingerprint": "bccee20f577a1a21", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "6ac6007be5ff78b5", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-cb3e52667c84fb86", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/types/package.json"}, "properties": {"repobilityId": "b5e2784f829944e6", "scanner": "scanner-primary", "fingerprint": "cb3e52667c84fb86", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/types/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4a9eb7dc7c6e3880", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "properties": {"repobilityId": "6c1704bf24cf19ac", "scanner": "scanner-primary", "fingerprint": "4a9eb7dc7c6e3880", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "8fbc2a6a4550fbb9", "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": "091b42b523a873ba", "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": "adf80d0c05bee0d4", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "2b268d9616628f97", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-c2afbd5c476621ec", "level": "none", "message": {"text": "Commented-code block (5 lines) in supabase/functions/impersonate/index.ts:1"}, "properties": {"repobilityId": "71cdd81664026914", "scanner": "scanner-primary", "fingerprint": "c2afbd5c476621ec", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-393369ba064612a9", "level": "none", "message": {"text": "Commented-code block (7 lines) in supabase/functions/admin-adjust-parsy/index.ts:1"}, "properties": {"repobilityId": "0818acd1c3884df1", "scanner": "scanner-primary", "fingerprint": "393369ba064612a9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d3ea97bbb1a683df", "level": "none", "message": {"text": "Commented-code block (6 lines) in supabase/functions/learning-assist/index.ts:1"}, "properties": {"repobilityId": "637c884aee65c040", "scanner": "scanner-primary", "fingerprint": "d3ea97bbb1a683df", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f876f6c8e607df29", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/learning-assist/index.ts:91"}, "properties": {"repobilityId": "4544a8174c52bc33", "scanner": "scanner-primary", "fingerprint": "f876f6c8e607df29", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f6d4a67d13ce256f", "level": "none", "message": {"text": "Commented-code block (5 lines) in supabase/functions/admin-proxy-stats/index.ts:14"}, "properties": {"repobilityId": "8229402b1c899df5", "scanner": "scanner-primary", "fingerprint": "f6d4a67d13ce256f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ac2446374357b1dd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/inbox-draft/index.ts:104"}, "properties": {"repobilityId": "72dfdf1daf35debc", "scanner": "scanner-primary", "fingerprint": "ac2446374357b1dd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-37ed1c4e014ec8b2", "level": "none", "message": {"text": "Commented-code block (5 lines) in supabase/functions/_shared/supabase.ts:1"}, "properties": {"repobilityId": "8bdc304e757df653", "scanner": "scanner-primary", "fingerprint": "37ed1c4e014ec8b2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3037690801d2ea1e", "level": "none", "message": {"text": "Commented-code block (5 lines) in supabase/functions/stripe-webhook/index.ts:1"}, "properties": {"repobilityId": "6208ac075b15d61d", "scanner": "scanner-primary", "fingerprint": "3037690801d2ea1e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5c40eaa8c9a78b2b", "level": "none", "message": {"text": "Commented-code block (7 lines) in supabase/functions/lead-verdict/index.ts:1"}, "properties": {"repobilityId": "364799eb7929050d", "scanner": "scanner-primary", "fingerprint": "5c40eaa8c9a78b2b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-db7efd7306895d35", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/lead-verdict/index.ts:84"}, "properties": {"repobilityId": "b8498cccbb05ee46", "scanner": "scanner-primary", "fingerprint": "db7efd7306895d35", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-919142950cd30113", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/ai-generate/index.ts:254"}, "properties": {"repobilityId": "0c3bdca2db8af585", "scanner": "scanner-primary", "fingerprint": "919142950cd30113", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c2ab080d0263d74a", "level": "none", "message": {"text": "Commented-code block (8 lines) in supabase/functions/admin-proxy-create/index.ts:7"}, "properties": {"repobilityId": "b967554adb32a052", "scanner": "scanner-primary", "fingerprint": "c2ab080d0263d74a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0ce98a7b5bf27533", "level": "note", "message": {"text": "Stub function `self_avatar` (body is just `pass`/`return`) \u2014 apps/worker/parpost/adapters/facebook.py:81"}, "properties": {"repobilityId": "47d789007cd2802f", "scanner": "scanner-primary", "fingerprint": "0ce98a7b5bf27533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "empty-handler", "dead-code"]}}, {"ruleId": "scanner-ecf601a69bb60bde", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/web/src/main.tsx:17"}, "properties": {"repobilityId": "458d1afb3a9b1157", "scanner": "scanner-primary", "fingerprint": "ecf601a69bb60bde", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-14f926b154bf11a7", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/web/src/hooks/useTenantBalance.ts:7"}, "properties": {"repobilityId": "61544972af233bbc", "scanner": "scanner-primary", "fingerprint": "14f926b154bf11a7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6e2b4bffa6e72772", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/src/components/BotProfileEditModal.tsx:76"}, "properties": {"repobilityId": "8fae64ce4a8c98c5", "scanner": "scanner-primary", "fingerprint": "6e2b4bffa6e72772", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0105c7344d7fa8d6", "level": "none", "message": {"text": "Commented-code block (7 lines) in apps/web/src/lib/supabase.ts:16"}, "properties": {"repobilityId": "6ca914b8a02a34c1", "scanner": "scanner-primary", "fingerprint": "0105c7344d7fa8d6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b5eee375f0252d07", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/lib/supabase.ts:134"}, "properties": {"repobilityId": "d1f0125821864d66", "scanner": "scanner-primary", "fingerprint": "b5eee375f0252d07", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-530a937cbd16e669", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Audience.tsx:780"}, "properties": {"repobilityId": "7d6c5adb65630c71", "scanner": "scanner-primary", "fingerprint": "530a937cbd16e669", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-812c161b756155d2", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Posting.tsx:748"}, "properties": {"repobilityId": "978be5aafdcd508f", "scanner": "scanner-primary", "fingerprint": "812c161b756155d2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7115f40994b383a9", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/src/routes/app/Leads.tsx:151"}, "properties": {"repobilityId": "cec7eb81c90c98ce", "scanner": "scanner-primary", "fingerprint": "7115f40994b383a9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-eeb3636e9eea9e27", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Leads.tsx:234"}, "properties": {"repobilityId": "25022823c38f82f8", "scanner": "scanner-primary", "fingerprint": "eeb3636e9eea9e27", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6eef6e94ef0b1b48", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Settings.tsx:245"}, "properties": {"repobilityId": "28846f17c8551fc3", "scanner": "scanner-primary", "fingerprint": "6eef6e94ef0b1b48", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-755e4b0b74c5878b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/app/Billing.tsx:134"}, "properties": {"repobilityId": "8bec052f81f4eb7b", "scanner": "scanner-primary", "fingerprint": "755e4b0b74c5878b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7ea36975cf194416", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/web/src/routes/admin/Proxies.tsx:11"}, "properties": {"repobilityId": "f5cc2fdd26f2a7da", "scanner": "scanner-primary", "fingerprint": "7ea36975cf194416", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-fcb048350dcf5746", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/routes/admin/TenantDetail.tsx:74"}, "properties": {"repobilityId": "0c40653a5abfc48c", "scanner": "scanner-primary", "fingerprint": "fcb048350dcf5746", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3507d014555c6572", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/src/routes/admin/BotDetail.tsx:869"}, "properties": {"repobilityId": "85532b3b13eebe1b", "scanner": "scanner-primary", "fingerprint": "3507d014555c6572", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b334d875f2339fa1", "level": "note", "message": {"text": "5 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "faa38682016f5d53", "scanner": "scanner-primary", "fingerprint": "b334d875f2339fa1", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "501f93edbe7d6bcb", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "e332c87a47d913d0", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "674a7e0b62afd122", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-600652c55e0e7210", "level": "warning", "message": {"text": "Frontend route `/verify` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "60d62933d87ddf1f", "scanner": "scanner-primary", "fingerprint": "600652c55e0e7210", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-48f0655fef3f1d83", "level": "warning", "message": {"text": "Frontend route `bots` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "6dabfc84c4b99b8e", "scanner": "scanner-primary", "fingerprint": "48f0655fef3f1d83", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-10af3d1f2317df4f", "level": "warning", "message": {"text": "Frontend route `audience` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "0ee9f349ea878fb6", "scanner": "scanner-primary", "fingerprint": "10af3d1f2317df4f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-4f846750ecdee04d", "level": "warning", "message": {"text": "Frontend route `posting` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "836d4b67b43f640d", "scanner": "scanner-primary", "fingerprint": "4f846750ecdee04d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-e6f084391512a9f1", "level": "warning", "message": {"text": "Frontend route `groups` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "77742a4b121c4816", "scanner": "scanner-primary", "fingerprint": "e6f084391512a9f1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-f8f805ddd9556a47", "level": "warning", "message": {"text": "Frontend route `leads` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "2a3ad7cb6ec334f4", "scanner": "scanner-primary", "fingerprint": "f8f805ddd9556a47", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-697f7d6fc1b60192", "level": "warning", "message": {"text": "Frontend route `inbox` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "5abb6cb7bf6c3e44", "scanner": "scanner-primary", "fingerprint": "697f7d6fc1b60192", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-9f20e1473acfd395", "level": "warning", "message": {"text": "Frontend route `activity` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "0dd69c562a632bbe", "scanner": "scanner-primary", "fingerprint": "9f20e1473acfd395", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-c440054c57b73ba8", "level": "warning", "message": {"text": "Frontend route `billing` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "15689d988966f20e", "scanner": "scanner-primary", "fingerprint": "c440054c57b73ba8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-42bfc76f6bb25e2f", "level": "warning", "message": {"text": "Frontend route `settings` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "e19804a54328eecf", "scanner": "scanner-primary", "fingerprint": "42bfc76f6bb25e2f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-23125f3709c9108e", "level": "warning", "message": {"text": "Frontend route `tenants` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "6c29443b53289711", "scanner": "scanner-primary", "fingerprint": "23125f3709c9108e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-27ec93b47564c74e", "level": "warning", "message": {"text": "Frontend route `tenants/:id` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "acd6858910b358c8", "scanner": "scanner-primary", "fingerprint": "27ec93b47564c74e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-57b49450b9eff155", "level": "warning", "message": {"text": "Frontend route `fleet` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "560fd756e15ccba9", "scanner": "scanner-primary", "fingerprint": "57b49450b9eff155", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-a40a3f5eb7c6075a", "level": "warning", "message": {"text": "Frontend route `bots/:id` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "3dbe745cd32bad91", "scanner": "scanner-primary", "fingerprint": "a40a3f5eb7c6075a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-014ea487d8e0630d", "level": "warning", "message": {"text": "Frontend route `proxies` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "775186349973845b", "scanner": "scanner-primary", "fingerprint": "014ea487d8e0630d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-c0066f0f8666bef6", "level": "warning", "message": {"text": "Frontend route `config` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "cfcad205c391d86d", "scanner": "scanner-primary", "fingerprint": "c0066f0f8666bef6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-a1be83e9afe57809", "level": "warning", "message": {"text": "Frontend route `abuse` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "d941bfacb0fbb719", "scanner": "scanner-primary", "fingerprint": "a1be83e9afe57809", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-8d6f15305337e985", "level": "warning", "message": {"text": "Frontend route `appeals` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "33d18c8f06c80939", "scanner": "scanner-primary", "fingerprint": "8d6f15305337e985", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-b21c6d063f82725b", "level": "warning", "message": {"text": "Frontend route `audit` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "0f0ab11441b2ad53", "scanner": "scanner-primary", "fingerprint": "b21c6d063f82725b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}]}]}