{"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-cc3107c62ea7e6a1", "name": "Stray `console.log` in TS/JS \u2014 scripts/reset-password.ts:57", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/reset-password.ts:57"}, "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-175333a56e85b234", "name": "Stray `console.log` in TS/JS \u2014 scripts/seed.ts:30", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed.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-b7cd1f1f68f088c7", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(authenticated)/page.tsx:321", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(authenticated)/page.tsx:321"}, "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-b9f49dbeab444a1a", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(authenticated)/leads/page.tsx:87", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(authenticated)/leads/page.tsx:87"}, "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-9e202fee5a90e431", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/(authenticated)/leads/[id]/page.tsx:48", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(authenticated)/leads/[id]/page.tsx:48"}, "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-e4e9f62e23bae822", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/dashboard/attention-widget.tsx:48", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/dashboard/attention-widget.tsx:48"}, "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-3e6ff6af789d6083", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/comps/market-comp-list.tsx:84", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/comps/market-comp-list.tsx:84"}, "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-9be93795fd487dab", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/comps/rent-comp-list.tsx:67", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/comps/rent-comp-list.tsx:67"}, "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-71c91417482a16c1", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/global-search.tsx:147", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/global-search.tsx:147"}, "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-0594be8bf55ad540", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/contacts/contact-list.tsx:158", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/contacts/contact-list.tsx:158"}, "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-eb8b83dd60efade2", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/underwriting/assumptions-form.tsx:864", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/underwriting/assumptions-form.tsx:864"}, "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-40170e9461415389", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/pipeline/deal-card.tsx:65", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/pipeline/deal-card.tsx:65"}, "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-c3a1989a108be152", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/pipeline/pipeline-table.tsx:149", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/pipeline/pipeline-table.tsx:149"}, "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-b60dead8d8dabbbb", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/pipeline/import-deals-dialog.tsx:229", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/pipeline/import-deals-dialog.tsx:229"}, "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-4f85e3e6fbba1993", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/deals/import-om-dialog.tsx:409", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/deals/import-om-dialog.tsx:409"}, "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-bb208d8f150f1879", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/deals/compare-deals.tsx:218", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/deals/compare-deals.tsx:218"}, "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-c4d80a106aba0b94", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/deals/deal-comps-card.tsx:158", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/deals/deal-comps-card.tsx:158"}, "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-7723f2af489e21f4", "name": "Very large file: src/components/underwriting/assumptions-form.tsx (2701 lines)", "shortDescription": {"text": "Very large file: src/components/underwriting/assumptions-form.tsx (2701 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-3b4f66d07c93aa1a", "name": "Very large file: src/lib/excel-export.ts (1481 lines)", "shortDescription": {"text": "Very large file: src/lib/excel-export.ts (1481 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-5dc244a071f0022c", "name": "Very large file: src/lib/underwriting.ts (2488 lines)", "shortDescription": {"text": "Very large file: src/lib/underwriting.ts (2488 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "7 test file(s) for 173 source file(s) (ratio 0.04). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 12 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 160 placeholder/mock markers across 31 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-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. 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-bea357a6497a2d5d", "name": "Agent authority lacks a verifier contract: CLAUDE.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: CLAUDE.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-f8df32132a622f33", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/capture-fixtures.mjs:29", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/capture-fixtures.mjs:29"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1b009a0e508e0467", "name": "Legacy-named symbol `property_tax_v2` in src/components/underwriting/assumptions-form.tsx:2207", "shortDescription": {"text": "Legacy-named symbol `property_tax_v2` in src/components/underwriting/assumptions-form.tsx:2207"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b5408acec2c242ab", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/underwriting/underwriting-client.tsx:102", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/underwriting/underwriting-client.tsx:102"}, "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-0c216ca7b4978036", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/editable-metrics.tsx:21", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/editable-metrics.tsx:21"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3e9658090d84bea6", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/due-diligence-closing.tsx:18", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/due-diligence-closing.tsx:18"}, "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-f35a5b648acab0c8", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/financing-calculator.tsx:199", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/financing-calculator.tsx:199"}, "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-2880922e1f51fff0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/editable-property-details.tsx:38", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/editable-property-details.tsx:38"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-24e5d37675674f6a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/seller-broker-financials.tsx:19", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/seller-broker-financials.tsx:19"}, "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-268d2f5bab067701", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/deal-contacts.tsx:70", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/deal-contacts.tsx:70"}, "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-de34e996540ed6e4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/t12-statement.tsx:310", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/t12-statement.tsx:310"}, "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-a851ddb6875d886e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/buy-box-scorecard.tsx:187", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/buy-box-scorecard.tsx:187"}, "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-e094b6a5d250425a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/deal-photo.tsx:51", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/deal-photo.tsx:51"}, "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-437d6c5736d5ce3a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/upload-client.ts:18", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/upload-client.ts:18"}, "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-20faffaedb2af0bc", "name": "Legacy-named symbol `property_tax_v2` in src/lib/excel-export.ts:111", "shortDescription": {"text": "Legacy-named symbol `property_tax_v2` in src/lib/excel-export.ts:111"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7fb8bc9c2cc4f203", "name": "Commented-code block (5 lines) in src/lib/excel-export.ts:1344", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/excel-export.ts:1344"}, "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-02a59f7a441e1ca3", "name": "Legacy-named symbol `property_tax_v2` in src/lib/checks.ts:21", "shortDescription": {"text": "Legacy-named symbol `property_tax_v2` in src/lib/checks.ts:21"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-12939aa7888764ac", "name": "Legacy-named symbol `property_tax_v2` in src/lib/underwriting.ts:479", "shortDescription": {"text": "Legacy-named symbol `property_tax_v2` in src/lib/underwriting.ts:479"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-90e6d7d0bc8c9534", "name": "Commented-code block (5 lines) in src/lib/underwriting.ts:81", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/underwriting.ts:81"}, "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-8e047ab7af03962f", "name": "7 env vars used in code but missing from .env.example", "shortDescription": {"text": "7 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `BASE_URL`, `COOKIE`, `CRON_SECRET`, `NODE_ENV`, `RESEND_API_KEY`, `UPDATE_GOLDEN`, `VERCEL_GIT_COMMIT_SHA`. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/24109"}, "properties": {"repository": "almasy77/MonumentEquity", "repoUrl": "https://github.com/almasy77/MonumentEquity", "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-cc3107c62ea7e6a1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/reset-password.ts:57"}, "properties": {"repobilityId": "cff7b49d20a9d0b4", "scanner": "scanner-primary", "fingerprint": "cc3107c62ea7e6a1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-175333a56e85b234", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed.ts:30"}, "properties": {"repobilityId": "6b45b8d4fff61a2c", "scanner": "scanner-primary", "fingerprint": "175333a56e85b234", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b7cd1f1f68f088c7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(authenticated)/page.tsx:321"}, "properties": {"repobilityId": "c345e87e174beb60", "scanner": "scanner-primary", "fingerprint": "b7cd1f1f68f088c7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b9f49dbeab444a1a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(authenticated)/leads/page.tsx:87"}, "properties": {"repobilityId": "96d5948dfefb1f69", "scanner": "scanner-primary", "fingerprint": "b9f49dbeab444a1a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9e202fee5a90e431", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/(authenticated)/leads/[id]/page.tsx:48"}, "properties": {"repobilityId": "8b54099fdda136fd", "scanner": "scanner-primary", "fingerprint": "9e202fee5a90e431", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e4e9f62e23bae822", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/dashboard/attention-widget.tsx:48"}, "properties": {"repobilityId": "059d9576728ffe72", "scanner": "scanner-primary", "fingerprint": "e4e9f62e23bae822", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3e6ff6af789d6083", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/comps/market-comp-list.tsx:84"}, "properties": {"repobilityId": "e46dc10f5cd58ee3", "scanner": "scanner-primary", "fingerprint": "3e6ff6af789d6083", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9be93795fd487dab", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/comps/rent-comp-list.tsx:67"}, "properties": {"repobilityId": "60205f38c9ab9650", "scanner": "scanner-primary", "fingerprint": "9be93795fd487dab", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-71c91417482a16c1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/global-search.tsx:147"}, "properties": {"repobilityId": "14221f523f27b2f6", "scanner": "scanner-primary", "fingerprint": "71c91417482a16c1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0594be8bf55ad540", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/contacts/contact-list.tsx:158"}, "properties": {"repobilityId": "29c21abd2fde4d68", "scanner": "scanner-primary", "fingerprint": "0594be8bf55ad540", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-eb8b83dd60efade2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/underwriting/assumptions-form.tsx:864"}, "properties": {"repobilityId": "a34a9a25ad70032c", "scanner": "scanner-primary", "fingerprint": "eb8b83dd60efade2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-40170e9461415389", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/pipeline/deal-card.tsx:65"}, "properties": {"repobilityId": "c5e64aa147f583b3", "scanner": "scanner-primary", "fingerprint": "40170e9461415389", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c3a1989a108be152", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/pipeline/pipeline-table.tsx:149"}, "properties": {"repobilityId": "eee009f6a7a454ed", "scanner": "scanner-primary", "fingerprint": "c3a1989a108be152", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b60dead8d8dabbbb", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/pipeline/import-deals-dialog.tsx:229"}, "properties": {"repobilityId": "495288c8b88779ae", "scanner": "scanner-primary", "fingerprint": "b60dead8d8dabbbb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4f85e3e6fbba1993", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/deals/import-om-dialog.tsx:409"}, "properties": {"repobilityId": "b8b68fabc302cf09", "scanner": "scanner-primary", "fingerprint": "4f85e3e6fbba1993", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-bb208d8f150f1879", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/deals/compare-deals.tsx:218"}, "properties": {"repobilityId": "e8f32ca39b4fe01d", "scanner": "scanner-primary", "fingerprint": "bb208d8f150f1879", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c4d80a106aba0b94", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/deals/deal-comps-card.tsx:158"}, "properties": {"repobilityId": "33cc975a87fbe7dd", "scanner": "scanner-primary", "fingerprint": "c4d80a106aba0b94", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7723f2af489e21f4", "level": "note", "message": {"text": "Very large file: src/components/underwriting/assumptions-form.tsx (2701 lines)"}, "properties": {"repobilityId": "572d5e7c4159e44d", "scanner": "scanner-primary", "fingerprint": "7723f2af489e21f4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-3b4f66d07c93aa1a", "level": "note", "message": {"text": "Very large file: src/lib/excel-export.ts (1481 lines)"}, "properties": {"repobilityId": "3aaa2be5ada14254", "scanner": "scanner-primary", "fingerprint": "3b4f66d07c93aa1a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-5dc244a071f0022c", "level": "note", "message": {"text": "Very large file: src/lib/underwriting.ts (2488 lines)"}, "properties": {"repobilityId": "f8dadb5c82f7a23c", "scanner": "scanner-primary", "fingerprint": "5dc244a071f0022c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "c38f23b9672f2051", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "48b3458fefc788d5", "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": "510adce7cee0a4df", "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": "004578bb62dfd566", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "dd24c5fe01359d75", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-bea357a6497a2d5d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: CLAUDE.md"}, "properties": {"repobilityId": "aae72df3934829ac", "scanner": "scanner-primary", "fingerprint": "bea357a6497a2d5d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "CLAUDE.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f8df32132a622f33", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/capture-fixtures.mjs:29"}, "properties": {"repobilityId": "fd99e4339f02171a", "scanner": "scanner-primary", "fingerprint": "f8df32132a622f33", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1b009a0e508e0467", "level": "note", "message": {"text": "Legacy-named symbol `property_tax_v2` in src/components/underwriting/assumptions-form.tsx:2207"}, "properties": {"repobilityId": "6cc77e47db7d0634", "scanner": "scanner-primary", "fingerprint": "1b009a0e508e0467", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-b5408acec2c242ab", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/underwriting/underwriting-client.tsx:102"}, "properties": {"repobilityId": "430face95669adf0", "scanner": "scanner-primary", "fingerprint": "b5408acec2c242ab", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0c216ca7b4978036", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/editable-metrics.tsx:21"}, "properties": {"repobilityId": "fb10b595d6a44d9d", "scanner": "scanner-primary", "fingerprint": "0c216ca7b4978036", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3e9658090d84bea6", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/due-diligence-closing.tsx:18"}, "properties": {"repobilityId": "cbb107800ff3ec3d", "scanner": "scanner-primary", "fingerprint": "3e9658090d84bea6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f35a5b648acab0c8", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/financing-calculator.tsx:199"}, "properties": {"repobilityId": "bbe7df83f8fd8c75", "scanner": "scanner-primary", "fingerprint": "f35a5b648acab0c8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2880922e1f51fff0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/editable-property-details.tsx:38"}, "properties": {"repobilityId": "d719f6569df73779", "scanner": "scanner-primary", "fingerprint": "2880922e1f51fff0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-24e5d37675674f6a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/seller-broker-financials.tsx:19"}, "properties": {"repobilityId": "1efa9e44b9a01902", "scanner": "scanner-primary", "fingerprint": "24e5d37675674f6a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-268d2f5bab067701", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/deal-contacts.tsx:70"}, "properties": {"repobilityId": "eb6db094dcb04fc7", "scanner": "scanner-primary", "fingerprint": "268d2f5bab067701", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-de34e996540ed6e4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/t12-statement.tsx:310"}, "properties": {"repobilityId": "c33a7f410978d02c", "scanner": "scanner-primary", "fingerprint": "de34e996540ed6e4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a851ddb6875d886e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/buy-box-scorecard.tsx:187"}, "properties": {"repobilityId": "bc0b5eb6f762020c", "scanner": "scanner-primary", "fingerprint": "a851ddb6875d886e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e094b6a5d250425a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/deals/deal-photo.tsx:51"}, "properties": {"repobilityId": "33b0cc5523ce9a19", "scanner": "scanner-primary", "fingerprint": "e094b6a5d250425a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-437d6c5736d5ce3a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/upload-client.ts:18"}, "properties": {"repobilityId": "1b3662c0e1771cd0", "scanner": "scanner-primary", "fingerprint": "437d6c5736d5ce3a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-20faffaedb2af0bc", "level": "note", "message": {"text": "Legacy-named symbol `property_tax_v2` in src/lib/excel-export.ts:111"}, "properties": {"repobilityId": "7c4d26f6d7891356", "scanner": "scanner-primary", "fingerprint": "20faffaedb2af0bc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-7fb8bc9c2cc4f203", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/excel-export.ts:1344"}, "properties": {"repobilityId": "98493e4c8ce07571", "scanner": "scanner-primary", "fingerprint": "7fb8bc9c2cc4f203", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-02a59f7a441e1ca3", "level": "note", "message": {"text": "Legacy-named symbol `property_tax_v2` in src/lib/checks.ts:21"}, "properties": {"repobilityId": "fcc8627a02924039", "scanner": "scanner-primary", "fingerprint": "02a59f7a441e1ca3", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-12939aa7888764ac", "level": "note", "message": {"text": "Legacy-named symbol `property_tax_v2` in src/lib/underwriting.ts:479"}, "properties": {"repobilityId": "d0d71a6797d23e18", "scanner": "scanner-primary", "fingerprint": "12939aa7888764ac", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-90e6d7d0bc8c9534", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/underwriting.ts:81"}, "properties": {"repobilityId": "ccb4b642a1e9ef93", "scanner": "scanner-primary", "fingerprint": "90e6d7d0bc8c9534", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8e047ab7af03962f", "level": "note", "message": {"text": "7 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "5a0455f6498c27ad", "scanner": "scanner-primary", "fingerprint": "8e047ab7af03962f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}]}]}