{"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-5610371d93a2dbaa", "name": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-duplicate-pending-transactions.ts:61", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-duplicate-pending-transactions.ts:61"}, "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-663b0fd5390054b0", "name": "Stray `console.log` in TS/JS \u2014 scripts/local-db.ts:32", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/local-db.ts:32"}, "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-7f5f2659b59d02af", "name": "Stray `console.log` in TS/JS \u2014 scripts/check-cc-fields.ts:14", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/check-cc-fields.ts:14"}, "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-1fb863298572a3ce", "name": "Stray `console.log` in TS/JS \u2014 scripts/shot-settings.ts:31", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/shot-settings.ts:31"}, "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-397b994829c23e34", "name": "Stray `console.log` in TS/JS \u2014 scripts/backfill-snapshots.ts:36", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/backfill-snapshots.ts:36"}, "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-8661642986592365", "name": "Stray `console.log` in TS/JS \u2014 scripts/export-data.ts:17", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/export-data.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-188d1f6f0a180beb", "name": "Stray `console.log` in TS/JS \u2014 scripts/reset-plaid-cursors.ts:12", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/reset-plaid-cursors.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-7eec5e304a41ee09", "name": "Stray `console.log` in TS/JS \u2014 scripts/screenshots.ts:38", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/screenshots.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-fb1981acad7480b5", "name": "Stray `console.log` in TS/JS \u2014 scripts/import-data.ts:30", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/import-data.ts:30"}, "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-8245d5972d3c15bb", "name": "Stray `console.log` in TS/JS \u2014 scripts/setup.ts:32", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/setup.ts:32"}, "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-04bd36d8a7cea2a4", "name": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-duplicate-plaid-accounts.ts:51", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-duplicate-plaid-accounts.ts:51"}, "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-8b187936ad7a5591", "name": "Stray `console.log` in TS/JS \u2014 prisma/seed.ts:28", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 prisma/seed.ts:28"}, "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-8352f2f3be15b5da", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/CommandPalette.tsx:135", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/CommandPalette.tsx:135"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5a297b705b1d97af", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/Sidebar.tsx:163", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Sidebar.tsx:163"}, "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-b3f3bb4e4729aa02", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/MultiSelect.tsx:73", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/MultiSelect.tsx:73"}, "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-4d441933776f59c9", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/layout.tsx:32", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/layout.tsx:32"}, "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-42cbf295b22bf73d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/SpendingAlertsCard.tsx:33", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/SpendingAlertsCard.tsx:33"}, "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-a501182e31a69dc5", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/page.tsx:96", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/page.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-4194dd60297efd5b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/settings/SettingsForm.tsx:154", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/settings/SettingsForm.tsx:154"}, "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-c3dddd25c25d67dc", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/transactions/TransactionsList.tsx:480", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/transactions/TransactionsList.tsx:480"}, "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-3ddb3cc8b7ef35f5", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/transactions/ManageFilters.tsx:26", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/transactions/ManageFilters.tsx:26"}, "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-c1ec07ba2a796689", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/debt/PayoffOrderList.tsx:86", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/debt/PayoffOrderList.tsx:86"}, "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-d3dfd77bd65a1c48", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/goals/GoalsManager.tsx:72", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/goals/GoalsManager.tsx:72"}, "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-b82b4359ca6226ed", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/recurring/RecurringManager.tsx:90", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/recurring/RecurringManager.tsx:90"}, "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-07efdf70edbcc680", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/accounts/AccountGroup.tsx:40", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/accounts/AccountGroup.tsx:40"}, "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-aa21591a7a77ab14", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/accounts/PlaidLinkButton.tsx:260", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/accounts/PlaidLinkButton.tsx:260"}, "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-022d7b8fe3c9aae3", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/categories/CategoriesManager.tsx:55", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/categories/CategoriesManager.tsx:55"}, "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-eda56b698abf419a", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/trends/TrendsCharts.tsx:178", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/trends/TrendsCharts.tsx:178"}, "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-b56ee5121ac2374b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/calendar/DayEventsModal.tsx:47", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/calendar/DayEventsModal.tsx:47"}, "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-ee24f7e7d6a3d12d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/calendar/DayCell.tsx:76", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/calendar/DayCell.tsx:76"}, "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-93e02e0d67c8f3e8", "name": "Docker base image is tag-pinned but not digest-pinned: node:22-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-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-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-e3b5e55ccc5a15e6", "name": "Possible secret in scripts/local-db.ts", "shortDescription": {"text": "Possible secret in scripts/local-db.ts"}, "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-efd71fb2d9cbfa8d", "name": "Possible secret in scripts/setup.ts", "shortDescription": {"text": "Possible secret in scripts/setup.ts"}, "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-0324eeca1589fd4b", "name": "Insecure pattern 'node_child_process' in scripts/setup.ts:9", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/setup.ts:9"}, "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-75507999fb5af950", "name": "Insecure pattern 'dangerous_innerhtml' in src/app/layout.tsx:32", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/layout.tsx:32"}, "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-740b88ab8dd23d2f", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "dependabot/fetch-metadata@v2 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-768e8f28c1850d98", "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-b841c61fdfcff569", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "docker/setup-buildx-action@v3 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-076b03a16e76601d", "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-27924aa79fa4a517", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/upload-artifact@v7 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cb639d9a10a47b23", "name": "package.json defines install-time lifecycle scripts", "shortDescription": {"text": "package.json defines install-time lifecycle scripts"}, "fullDescription": {"text": "preinstall/install/postinstall/prepare scripts execute during dependency installation. Review them carefully for network calls, obfuscation, shell execution, or credential access."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ea3b5e389d8c9c0f", "name": "Low test-to-source ratio", "shortDescription": {"text": "Low test-to-source ratio"}, "fullDescription": {"text": "39 tests / 164 src (ratio 0.24)."}, "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 40 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 33 placeholder/mock markers across 17 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-8f328f613f34052d", "name": "Commented-code block (6 lines) in scripts/local-db.ts:69", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/local-db.ts:69"}, "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-f38724a123e11fad", "name": "Commented-code block (6 lines) in src/app/api/v1/_auth.ts:17", "shortDescription": {"text": "Commented-code block (6 lines) in src/app/api/v1/_auth.ts:17"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-1ee6e59d87d74dc7", "name": "Commented-code block (5 lines) in src/app/api/v1/net-worth/route.ts:3", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/api/v1/net-worth/route.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-d91c041c9351c6e0", "name": "Commented-code block (5 lines) in src/app/api/v1/summary/route.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/api/v1/summary/route.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-f360d90ce77f5a92", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/api/chat/route.ts:474", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/api/chat/route.ts:474"}, "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-3b882f86a303f04b", "name": "Commented-code block (5 lines) in src/app/api/backup/route.ts:5", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/api/backup/route.ts:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b7922e71ea4bb4c9", "name": "Commented-code block (6 lines) in src/app/api/backup/import/route.ts:5", "shortDescription": {"text": "Commented-code block (6 lines) in src/app/api/backup/import/route.ts:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-41493bbeadf71769", "name": "Commented-code block (6 lines) in src/lib/snapshots.ts:4", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/snapshots.ts:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2806caac223d7bd2", "name": "Commented-code block (5 lines) in src/lib/plaid-sync.ts:270", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/plaid-sync.ts:270"}, "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-520413faa8210c92", "name": "Commented-code block (6 lines) in src/lib/snapshots.test.ts:1", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/snapshots.test.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-85121ec053a92095", "name": "Commented-code block (6 lines) in src/lib/networth-forecast.ts:3", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/networth-forecast.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-d09edcaac224267a", "name": "Commented-code block (5 lines) in src/lib/env.ts:3", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/env.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-883f247ceb19a478", "name": "Commented-code block (9 lines) in src/lib/projection.ts:5", "shortDescription": {"text": "Commented-code block (9 lines) in src/lib/projection.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-e2a7e1e106bab2d2", "name": "Commented-code block (7 lines) in src/lib/api-auth.ts:6", "shortDescription": {"text": "Commented-code block (7 lines) in src/lib/api-auth.ts:6"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-f14fde8bdd59af17", "name": "Commented-code block (5 lines) in src/lib/backup.ts:161", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/backup.ts:161"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3a6c078b15e60ad0", "name": "Commented-code block (5 lines) in src/lib/queries.test.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/queries.test.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-644869d76e64cc05", "name": "Commented-code block (5 lines) in src/lib/plaid.ts:3", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/plaid.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-09df2a0fbe1bf270", "name": "Commented-code block (5 lines) in src/lib/csv-import.ts:278", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/csv-import.ts:278"}, "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-9a0c0841a3b74f7e", "name": "Commented-code block (5 lines) in src/lib/splits.ts:3", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/splits.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-856765b9f457f1b4", "name": "Commented-code block (5 lines) in src/lib/crypto.ts:4", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/crypto.ts:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0441d97b039e4b13", "name": "Commented-code block (5 lines) in src/actions/transactions.normalizeSplits.test.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/actions/transactions.normalizeSplits.test.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-a57f73f9ed304f51", "name": "Commented-code block (5 lines) in src/actions/transactions.ts:203", "shortDescription": {"text": "Commented-code block (5 lines) in src/actions/transactions.ts:203"}, "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-250f57e8a1dbd3c5", "name": "4 env vars used in code but missing from .env.example", "shortDescription": {"text": "4 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `CI`, `ENCRYPTION_KEY`, `NODE_ENV`, `SHOT_BASE_URL`. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/22288"}, "properties": {"repository": "vinnymicale/moolah", "repoUrl": "https://github.com/vinnymicale/moolah", "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-5610371d93a2dbaa", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-duplicate-pending-transactions.ts:61"}, "properties": {"repobilityId": "0b2a482a983fab65", "scanner": "scanner-primary", "fingerprint": "5610371d93a2dbaa", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-663b0fd5390054b0", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/local-db.ts:32"}, "properties": {"repobilityId": "405af6a3b29db6c3", "scanner": "scanner-primary", "fingerprint": "663b0fd5390054b0", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7f5f2659b59d02af", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/check-cc-fields.ts:14"}, "properties": {"repobilityId": "632fce87a8a9aaf9", "scanner": "scanner-primary", "fingerprint": "7f5f2659b59d02af", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1fb863298572a3ce", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/shot-settings.ts:31"}, "properties": {"repobilityId": "05ab910838a42204", "scanner": "scanner-primary", "fingerprint": "1fb863298572a3ce", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-397b994829c23e34", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/backfill-snapshots.ts:36"}, "properties": {"repobilityId": "ddc1c2e507c2d223", "scanner": "scanner-primary", "fingerprint": "397b994829c23e34", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8661642986592365", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/export-data.ts:17"}, "properties": {"repobilityId": "0b5c6ea8deab9090", "scanner": "scanner-primary", "fingerprint": "8661642986592365", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-188d1f6f0a180beb", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/reset-plaid-cursors.ts:12"}, "properties": {"repobilityId": "122d7ffa40a5162e", "scanner": "scanner-primary", "fingerprint": "188d1f6f0a180beb", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7eec5e304a41ee09", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/screenshots.ts:38"}, "properties": {"repobilityId": "f9dfbf2d6e7b6a09", "scanner": "scanner-primary", "fingerprint": "7eec5e304a41ee09", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-fb1981acad7480b5", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/import-data.ts:30"}, "properties": {"repobilityId": "2db6f7d0002dceac", "scanner": "scanner-primary", "fingerprint": "fb1981acad7480b5", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8245d5972d3c15bb", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/setup.ts:32"}, "properties": {"repobilityId": "6b5357ac89817640", "scanner": "scanner-primary", "fingerprint": "8245d5972d3c15bb", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-04bd36d8a7cea2a4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-duplicate-plaid-accounts.ts:51"}, "properties": {"repobilityId": "5087b5c79d71cd1d", "scanner": "scanner-primary", "fingerprint": "04bd36d8a7cea2a4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8b187936ad7a5591", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 prisma/seed.ts:28"}, "properties": {"repobilityId": "f77d7e0fb34b08e2", "scanner": "scanner-primary", "fingerprint": "8b187936ad7a5591", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8352f2f3be15b5da", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/CommandPalette.tsx:135"}, "properties": {"repobilityId": "c2fdecf59e1ef076", "scanner": "scanner-primary", "fingerprint": "8352f2f3be15b5da", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5a297b705b1d97af", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Sidebar.tsx:163"}, "properties": {"repobilityId": "450176a4d82f7dad", "scanner": "scanner-primary", "fingerprint": "5a297b705b1d97af", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b3f3bb4e4729aa02", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/MultiSelect.tsx:73"}, "properties": {"repobilityId": "5a75ce46c4cf50dd", "scanner": "scanner-primary", "fingerprint": "b3f3bb4e4729aa02", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4d441933776f59c9", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/layout.tsx:32"}, "properties": {"repobilityId": "0d72350965068f5b", "scanner": "scanner-primary", "fingerprint": "4d441933776f59c9", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-42cbf295b22bf73d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/SpendingAlertsCard.tsx:33"}, "properties": {"repobilityId": "222c269e32a05783", "scanner": "scanner-primary", "fingerprint": "42cbf295b22bf73d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a501182e31a69dc5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/page.tsx:96"}, "properties": {"repobilityId": "31115dcb39ef129d", "scanner": "scanner-primary", "fingerprint": "a501182e31a69dc5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4194dd60297efd5b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/settings/SettingsForm.tsx:154"}, "properties": {"repobilityId": "e6f667b07f2dbe62", "scanner": "scanner-primary", "fingerprint": "4194dd60297efd5b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c3dddd25c25d67dc", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/transactions/TransactionsList.tsx:480"}, "properties": {"repobilityId": "613d2571dbba30fd", "scanner": "scanner-primary", "fingerprint": "c3dddd25c25d67dc", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3ddb3cc8b7ef35f5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/transactions/ManageFilters.tsx:26"}, "properties": {"repobilityId": "fc5f45827a6a01d0", "scanner": "scanner-primary", "fingerprint": "3ddb3cc8b7ef35f5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c1ec07ba2a796689", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/debt/PayoffOrderList.tsx:86"}, "properties": {"repobilityId": "ce388dcf29855e85", "scanner": "scanner-primary", "fingerprint": "c1ec07ba2a796689", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d3dfd77bd65a1c48", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/goals/GoalsManager.tsx:72"}, "properties": {"repobilityId": "696a6d3f343c32a7", "scanner": "scanner-primary", "fingerprint": "d3dfd77bd65a1c48", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b82b4359ca6226ed", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/recurring/RecurringManager.tsx:90"}, "properties": {"repobilityId": "1cdc93651d25e6a3", "scanner": "scanner-primary", "fingerprint": "b82b4359ca6226ed", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-07efdf70edbcc680", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/accounts/AccountGroup.tsx:40"}, "properties": {"repobilityId": "11d918af5b8655a1", "scanner": "scanner-primary", "fingerprint": "07efdf70edbcc680", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-aa21591a7a77ab14", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/accounts/PlaidLinkButton.tsx:260"}, "properties": {"repobilityId": "0b917fa706f40aa7", "scanner": "scanner-primary", "fingerprint": "aa21591a7a77ab14", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-022d7b8fe3c9aae3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/categories/CategoriesManager.tsx:55"}, "properties": {"repobilityId": "d5f9e697b62c84b4", "scanner": "scanner-primary", "fingerprint": "022d7b8fe3c9aae3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-eda56b698abf419a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/trends/TrendsCharts.tsx:178"}, "properties": {"repobilityId": "563faa5853f50234", "scanner": "scanner-primary", "fingerprint": "eda56b698abf419a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b56ee5121ac2374b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/calendar/DayEventsModal.tsx:47"}, "properties": {"repobilityId": "69628ac5cb44db66", "scanner": "scanner-primary", "fingerprint": "b56ee5121ac2374b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ee24f7e7d6a3d12d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(app)/calendar/DayCell.tsx:76"}, "properties": {"repobilityId": "0cf9a9ba2db2385f", "scanner": "scanner-primary", "fingerprint": "ee24f7e7d6a3d12d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-93e02e0d67c8f3e8", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-slim"}, "properties": {"repobilityId": "7fe26e1324615aa4", "scanner": "scanner-primary", "fingerprint": "93e02e0d67c8f3e8", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 8}}}]}, {"ruleId": "scanner-93e02e0d67c8f3e8", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-slim"}, "properties": {"repobilityId": "91acaa4a24d141de", "scanner": "scanner-primary", "fingerprint": "93e02e0d67c8f3e8", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 19}}}]}, {"ruleId": "scanner-93e02e0d67c8f3e8", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-slim"}, "properties": {"repobilityId": "fba508d1646dec6c", "scanner": "scanner-primary", "fingerprint": "93e02e0d67c8f3e8", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 31}}}]}, {"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-e3b5e55ccc5a15e6", "level": "error", "message": {"text": "Possible secret in scripts/local-db.ts"}, "properties": {"repobilityId": "3e05f7eafb16d11b", "scanner": "scanner-primary", "fingerprint": "e3b5e55ccc5a15e6", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local-db.ts"}, "region": {"startLine": 17}}}]}, {"ruleId": "scanner-efd71fb2d9cbfa8d", "level": "error", "message": {"text": "Possible secret in scripts/setup.ts"}, "properties": {"repobilityId": "5eb6853cea2a87c2", "scanner": "scanner-primary", "fingerprint": "efd71fb2d9cbfa8d", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/setup.ts"}, "region": {"startLine": 17}}}]}, {"ruleId": "scanner-0324eeca1589fd4b", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/setup.ts:9"}, "properties": {"repobilityId": "9b3db7368ebec43d", "scanner": "scanner-primary", "fingerprint": "0324eeca1589fd4b", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/setup.ts"}, "region": {"startLine": 9}}}]}, {"ruleId": "scanner-75507999fb5af950", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/layout.tsx:32"}, "properties": {"repobilityId": "0bca654fa2052eb0", "scanner": "scanner-primary", "fingerprint": "75507999fb5af950", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/layout.tsx"}, "region": {"startLine": 32}}}]}, {"ruleId": "scanner-740b88ab8dd23d2f", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "6c22316cfcffbcef", "scanner": "scanner-primary", "fingerprint": "740b88ab8dd23d2f", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/dependabot-auto-merge.yml"}, "region": {"startLine": 20}}}]}, {"ruleId": "scanner-768e8f28c1850d98", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "f3c306ca3743dfa1", "scanner": "scanner-primary", "fingerprint": "768e8f28c1850d98", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/dependabot-auto-merge.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b841c61fdfcff569", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "92a252f237fefd54", "scanner": "scanner-primary", "fingerprint": "b841c61fdfcff569", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/docker-publish.yml"}, "region": {"startLine": 35}}}]}, {"ruleId": "scanner-b841c61fdfcff569", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "9865da7d2b2ff924", "scanner": "scanner-primary", "fingerprint": "b841c61fdfcff569", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/docker-publish.yml"}, "region": {"startLine": 40}}}]}, {"ruleId": "scanner-b841c61fdfcff569", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "3ced3a497e6628d3", "scanner": "scanner-primary", "fingerprint": "b841c61fdfcff569", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/docker-publish.yml"}, "region": {"startLine": 48}}}]}, {"ruleId": "scanner-b841c61fdfcff569", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "81e5f06397892af9", "scanner": "scanner-primary", "fingerprint": "b841c61fdfcff569", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/docker-publish.yml"}, "region": {"startLine": 60}}}]}, {"ruleId": "scanner-076b03a16e76601d", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "a42462ccbe3d06f2", "scanner": "scanner-primary", "fingerprint": "076b03a16e76601d", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/docker-publish.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "90dca2b9a9fbfb28", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 44}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "90dca2b9a9fbfb28", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 69}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "f3fde08059e79457", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 109}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "54c8f1b47dd62535", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 125}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "90dca2b9a9fbfb28", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 143}}}]}, {"ruleId": "scanner-cb639d9a10a47b23", "level": "note", "message": {"text": "package.json defines install-time lifecycle scripts"}, "properties": {"repobilityId": "edeab51902066991", "scanner": "scanner-primary", "fingerprint": "cb639d9a10a47b23", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "npm", "install-scripts"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ea3b5e389d8c9c0f", "level": "note", "message": {"text": "Low test-to-source ratio"}, "properties": {"repobilityId": "ef7b2552cc00a375", "scanner": "scanner-primary", "fingerprint": "ea3b5e389d8c9c0f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["tests"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "3d47c896802c0db8", "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": "b6c5411b782c64dd", "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": "41da90c9d063a42c", "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": "a4d140cab558f721", "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": "df0f8707ca654323", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8f328f613f34052d", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/local-db.ts:69"}, "properties": {"repobilityId": "2bd0880c73ef3464", "scanner": "scanner-primary", "fingerprint": "8f328f613f34052d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f38724a123e11fad", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/app/api/v1/_auth.ts:17"}, "properties": {"repobilityId": "a155bb19000b1ae5", "scanner": "scanner-primary", "fingerprint": "f38724a123e11fad", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1ee6e59d87d74dc7", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/api/v1/net-worth/route.ts:3"}, "properties": {"repobilityId": "eec30dd4e34a14dd", "scanner": "scanner-primary", "fingerprint": "1ee6e59d87d74dc7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d91c041c9351c6e0", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/api/v1/summary/route.ts:1"}, "properties": {"repobilityId": "7338b5bc1d52661c", "scanner": "scanner-primary", "fingerprint": "d91c041c9351c6e0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f360d90ce77f5a92", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/api/chat/route.ts:474"}, "properties": {"repobilityId": "046ecfbe9d3bbd90", "scanner": "scanner-primary", "fingerprint": "f360d90ce77f5a92", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3b882f86a303f04b", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/api/backup/route.ts:5"}, "properties": {"repobilityId": "f229b825357e02d5", "scanner": "scanner-primary", "fingerprint": "3b882f86a303f04b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b7922e71ea4bb4c9", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/app/api/backup/import/route.ts:5"}, "properties": {"repobilityId": "cab150f20e76fd17", "scanner": "scanner-primary", "fingerprint": "b7922e71ea4bb4c9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-41493bbeadf71769", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/snapshots.ts:4"}, "properties": {"repobilityId": "24d62fdae403c5de", "scanner": "scanner-primary", "fingerprint": "41493bbeadf71769", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2806caac223d7bd2", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/plaid-sync.ts:270"}, "properties": {"repobilityId": "9d2b94208572516a", "scanner": "scanner-primary", "fingerprint": "2806caac223d7bd2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-520413faa8210c92", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/snapshots.test.ts:1"}, "properties": {"repobilityId": "57e20ca3e4990235", "scanner": "scanner-primary", "fingerprint": "520413faa8210c92", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-85121ec053a92095", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/networth-forecast.ts:3"}, "properties": {"repobilityId": "eb9454f34f7c97d6", "scanner": "scanner-primary", "fingerprint": "85121ec053a92095", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d09edcaac224267a", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/env.ts:3"}, "properties": {"repobilityId": "78f5ce1e5095aa56", "scanner": "scanner-primary", "fingerprint": "d09edcaac224267a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-883f247ceb19a478", "level": "none", "message": {"text": "Commented-code block (9 lines) in src/lib/projection.ts:5"}, "properties": {"repobilityId": "5e590941b09863aa", "scanner": "scanner-primary", "fingerprint": "883f247ceb19a478", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e2a7e1e106bab2d2", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/lib/api-auth.ts:6"}, "properties": {"repobilityId": "48946cdbc431da99", "scanner": "scanner-primary", "fingerprint": "e2a7e1e106bab2d2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f14fde8bdd59af17", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/backup.ts:161"}, "properties": {"repobilityId": "f51f18f41ea631c5", "scanner": "scanner-primary", "fingerprint": "f14fde8bdd59af17", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3a6c078b15e60ad0", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/queries.test.ts:1"}, "properties": {"repobilityId": "072af186f40230b4", "scanner": "scanner-primary", "fingerprint": "3a6c078b15e60ad0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-644869d76e64cc05", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/plaid.ts:3"}, "properties": {"repobilityId": "64714f741b5f9093", "scanner": "scanner-primary", "fingerprint": "644869d76e64cc05", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-09df2a0fbe1bf270", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/csv-import.ts:278"}, "properties": {"repobilityId": "c8faddd3cf8bad26", "scanner": "scanner-primary", "fingerprint": "09df2a0fbe1bf270", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9a0c0841a3b74f7e", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/splits.ts:3"}, "properties": {"repobilityId": "e1bc24cd3e9197ae", "scanner": "scanner-primary", "fingerprint": "9a0c0841a3b74f7e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-856765b9f457f1b4", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/crypto.ts:4"}, "properties": {"repobilityId": "fc8312fa8b492e98", "scanner": "scanner-primary", "fingerprint": "856765b9f457f1b4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0441d97b039e4b13", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/actions/transactions.normalizeSplits.test.ts:1"}, "properties": {"repobilityId": "112b32f5b3e2a330", "scanner": "scanner-primary", "fingerprint": "0441d97b039e4b13", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a57f73f9ed304f51", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/actions/transactions.ts:203"}, "properties": {"repobilityId": "b23f35703dc1f8f8", "scanner": "scanner-primary", "fingerprint": "a57f73f9ed304f51", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-250f57e8a1dbd3c5", "level": "none", "message": {"text": "4 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "57584f22b735b5ee", "scanner": "scanner-primary", "fingerprint": "250f57e8a1dbd3c5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}]}]}