{"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-9fe211ea49d9b279", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/page.tsx:59", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/page.tsx:59"}, "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-10e50eae22542e2b", "name": "Stray `console.log` in TS/JS \u2014 src/app/api/cron/fetch-tenders/route.ts:227", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/app/api/cron/fetch-tenders/route.ts:227"}, "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-3ee5eae830a34579", "name": "Stray `console.log` in TS/JS \u2014 src/app/api/stripe/webhook/route.ts:93", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/app/api/stripe/webhook/route.ts:93"}, "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-3238805c13add903", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/page.tsx:679", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/page.tsx:679"}, "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-aea0c183a826ffb3", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/articles/[slug]/layout.tsx:88", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/articles/[slug]/layout.tsx:88"}, "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-57bb08e01b29002f", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/articles/[slug]/page.tsx:143", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/articles/[slug]/page.tsx:143"}, "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-0895913c3bfa5795", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/suppliers/page.tsx:409", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/suppliers/page.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-b1e5ac2a6216d8a8", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/suppliers/page.tsx:728", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/suppliers/page.tsx:728"}, "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-7694b8f5b429d513", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/directory/page.tsx:130", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/directory/page.tsx:130"}, "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-fa79f399bda8aac3", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/areas/[state]/[suburb]/page.tsx:103", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/areas/[state]/[suburb]/page.tsx:103"}, "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-91402a3c3d929374", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/feasibility/page.tsx:1158", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/feasibility/page.tsx:1158"}, "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-1bf6de2405b8cada", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/feasibility/page.tsx:1367", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/feasibility/page.tsx:1367"}, "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-19fa924bed5f9a96", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/professionals/page.tsx:129", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/professionals/page.tsx:129"}, "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-f5cf90b237be8dc6", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/professionals/page.tsx:698", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/professionals/page.tsx:698"}, "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-49972fcd2d51c5f8", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/guide/page.tsx:324", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/guide/page.tsx:324"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ca7c1b982e3f29eb", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/tenders/[id]/page.tsx:382", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/tenders/[id]/page.tsx:382"}, "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-a954671e7fce026f", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/SiteNav.tsx:108", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/SiteNav.tsx:108"}, "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-208e4138c6eaf496", "name": "TODO/FIXME marker in shipping code \u2014 src/lib/spatial-api.ts:400", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/lib/spatial-api.ts:400"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-baa13e58954a3605", "name": "Stray `console.log` in TS/JS \u2014 outreach/send-outreach.js:152", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 outreach/send-outreach.js:152"}, "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-17e017fb1c4ba236", "name": "Stray `console.log` in TS/JS \u2014 outreach/send-campaign.js:140", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 outreach/send-campaign.js:140"}, "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-b92d5d14fe1aa526", "name": "Insecure pattern 'dangerous_innerhtml' in src/app/page.tsx:59", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/page.tsx:59"}, "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-b39389a3e0f62dd1", "name": "Insecure pattern 'dangerous_innerhtml' in src/app/articles/[slug]/layout.tsx:88", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/articles/[slug]/layout.tsx:88"}, "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-cbf27404b0ec3298", "name": "Insecure pattern 'dangerous_innerhtml' in src/app/articles/[slug]/page.tsx:143", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/articles/[slug]/page.tsx:143"}, "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-1cf8f3b32f893f57", "name": "Insecure pattern 'dangerous_innerhtml' in src/app/suppliers/page.tsx:728", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/suppliers/page.tsx:728"}, "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-d1a9c81cb6e87903", "name": "Insecure pattern 'dangerous_innerhtml' in src/app/areas/[state]/[suburb]/page.tsx:103", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/areas/[state]/[suburb]/page.tsx:103"}, "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-9c8c56107059e332", "name": "Insecure pattern 'dangerous_innerhtml' in src/app/feasibility/page.tsx:1367", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/feasibility/page.tsx:1367"}, "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-c5da918577d7b1ad", "name": "Insecure pattern 'dangerous_innerhtml' in src/app/professionals/page.tsx:698", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/professionals/page.tsx:698"}, "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-5b6032c4cde4928d", "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@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e727f37b3ad5a0d3", "name": "Very large file: src/app/admin/page.tsx (1148 lines)", "shortDescription": {"text": "Very large file: src/app/admin/page.tsx (1148 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-3c5d1d5588afc60d", "name": "Very large file: src/app/directory/page.tsx (1428 lines)", "shortDescription": {"text": "Very large file: src/app/directory/page.tsx (1428 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-bb8268910b151fee", "name": "Very large file: src/app/feasibility/page.tsx (1377 lines)", "shortDescription": {"text": "Very large file: src/app/feasibility/page.tsx (1377 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-9ece9322efad2704", "name": "Very large file: src/lib/articles-batch2.ts (1640 lines)", "shortDescription": {"text": "Very large file: src/lib/articles-batch2.ts (1640 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-fdadbeccc0da6389", "name": "Very large file: src/lib/articles-data.ts (3697 lines)", "shortDescription": {"text": "Very large file: src/lib/articles-data.ts (3697 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": "6 test file(s) for 132 source file(s) (ratio 0.05). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-fe61efcee13c97ec", "name": "37 TODO/FIXME markers", "shortDescription": {"text": "37 TODO/FIXME markers"}, "fullDescription": {"text": "High count of TODO/FIXME/HACK markers \u2014 track them as issues so they're not forgotten."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-faccb9061e9b52a0", "name": "No README detected", "shortDescription": {"text": "No README detected"}, "fullDescription": {"text": "No README file was found. Generated repos without README context are hard to operate, validate, or safely hand off."}, "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 33 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 197 placeholder/mock markers across 22 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-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, operator-readme. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license, operator-readme. 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-17d866d91a7c451e", "name": "Agent instruction/config may expose a secret: CLAUDE.md", "shortDescription": {"text": "Agent instruction/config may expose a secret: CLAUDE.md"}, "fullDescription": {"text": "Agent-facing files are routinely pasted into LLM/tool contexts. Move literal tokens, keys, and passwords into a secret manager or document them as placeholders only."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-e93a0f2b3ce96492", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/dashboard/pro/page.tsx:395", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/dashboard/pro/page.tsx:395"}, "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-26453b8359ae59af", "name": "Commented-code block (5 lines) in src/app/api/feasibility/route.ts:58", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/api/feasibility/route.ts:58"}, "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-4926d06f0a7d43e0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/page.tsx:174", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/page.tsx:174"}, "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-21a656c7a19efc7e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/suppliers/page.tsx:57", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/suppliers/page.tsx:57"}, "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-9b379f7fd9764083", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/suppliers/register/page.tsx:64", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/suppliers/register/page.tsx:64"}, "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-23040ba14ab42963", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/forum/NewPostModal.tsx:58", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/forum/NewPostModal.tsx:58"}, "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-da44bb905c528803", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/forum/page.tsx:124", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/forum/page.tsx:124"}, "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-d46271b1adc421b9", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/forum/[id]/page.tsx:131", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/forum/[id]/page.tsx:131"}, "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-4f41c17d53c45133", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/directory/page.tsx:237", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/directory/page.tsx:237"}, "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-3c8eb86d00256abb", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/feasibility/page.tsx:327", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/feasibility/page.tsx:327"}, "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-35331dcd98ea708b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/join/page.tsx:321", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/join/page.tsx:321"}, "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-340a58a3002e7131", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/professionals/page.tsx:56", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/professionals/page.tsx:56"}, "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-c9b0acece8baf448", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/professionals/[state]/[slug]/page.tsx:59", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/professionals/[state]/[slug]/page.tsx:59"}, "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-f9e02babda418615", "name": "Commented-code block (5 lines) in src/components/SuburbAutocomplete.tsx:81", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/SuburbAutocomplete.tsx: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-dfaccb776dfac987", "name": "Commented-code block (5 lines) in src/lib/demand-signals.ts:5", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/demand-signals.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-7c47750d96318226", "name": "Commented-code block (5 lines) in src/lib/spatial-api.ts:30", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/spatial-api.ts:30"}, "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-6930cedac10aa0b4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 outreach/send-campaign.js:100", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 outreach/send-campaign.js:100"}, "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}}]}}, "automationDetails": {"id": "repobility/23977"}, "properties": {"repository": "AIandLife/kdr-guide", "repoUrl": "https://github.com/AIandLife/kdr-guide", "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-9fe211ea49d9b279", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/page.tsx:59"}, "properties": {"repobilityId": "4d4ab3e03315f684", "scanner": "scanner-primary", "fingerprint": "9fe211ea49d9b279", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-10e50eae22542e2b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/app/api/cron/fetch-tenders/route.ts:227"}, "properties": {"repobilityId": "8a783362cc8ab451", "scanner": "scanner-primary", "fingerprint": "10e50eae22542e2b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3ee5eae830a34579", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/app/api/stripe/webhook/route.ts:93"}, "properties": {"repobilityId": "e3501193b3efa3b7", "scanner": "scanner-primary", "fingerprint": "3ee5eae830a34579", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3238805c13add903", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/page.tsx:679"}, "properties": {"repobilityId": "8d313b2589100140", "scanner": "scanner-primary", "fingerprint": "3238805c13add903", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-aea0c183a826ffb3", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/articles/[slug]/layout.tsx:88"}, "properties": {"repobilityId": "fbb2933f447e1286", "scanner": "scanner-primary", "fingerprint": "aea0c183a826ffb3", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-57bb08e01b29002f", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/articles/[slug]/page.tsx:143"}, "properties": {"repobilityId": "c7fab6169c05b637", "scanner": "scanner-primary", "fingerprint": "57bb08e01b29002f", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-0895913c3bfa5795", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/suppliers/page.tsx:409"}, "properties": {"repobilityId": "793c0344daae4995", "scanner": "scanner-primary", "fingerprint": "0895913c3bfa5795", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b1e5ac2a6216d8a8", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/suppliers/page.tsx:728"}, "properties": {"repobilityId": "f7df993d390ba9a5", "scanner": "scanner-primary", "fingerprint": "b1e5ac2a6216d8a8", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-7694b8f5b429d513", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/directory/page.tsx:130"}, "properties": {"repobilityId": "84780c66a45ebdc0", "scanner": "scanner-primary", "fingerprint": "7694b8f5b429d513", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fa79f399bda8aac3", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/areas/[state]/[suburb]/page.tsx:103"}, "properties": {"repobilityId": "6d879025e959d31e", "scanner": "scanner-primary", "fingerprint": "fa79f399bda8aac3", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-91402a3c3d929374", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/feasibility/page.tsx:1158"}, "properties": {"repobilityId": "e090c04f53c8d715", "scanner": "scanner-primary", "fingerprint": "91402a3c3d929374", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1bf6de2405b8cada", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/feasibility/page.tsx:1367"}, "properties": {"repobilityId": "c20b86d42dae1c2f", "scanner": "scanner-primary", "fingerprint": "1bf6de2405b8cada", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-19fa924bed5f9a96", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/professionals/page.tsx:129"}, "properties": {"repobilityId": "1ad7a306368dadf0", "scanner": "scanner-primary", "fingerprint": "19fa924bed5f9a96", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f5cf90b237be8dc6", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/professionals/page.tsx:698"}, "properties": {"repobilityId": "fe8fdf5c3f0e2b14", "scanner": "scanner-primary", "fingerprint": "f5cf90b237be8dc6", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-49972fcd2d51c5f8", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/guide/page.tsx:324"}, "properties": {"repobilityId": "ac42e3fbe47b6002", "scanner": "scanner-primary", "fingerprint": "49972fcd2d51c5f8", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ca7c1b982e3f29eb", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/tenders/[id]/page.tsx:382"}, "properties": {"repobilityId": "92ad9cbdfe4ac678", "scanner": "scanner-primary", "fingerprint": "ca7c1b982e3f29eb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a954671e7fce026f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/SiteNav.tsx:108"}, "properties": {"repobilityId": "db3d52f185285296", "scanner": "scanner-primary", "fingerprint": "a954671e7fce026f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-208e4138c6eaf496", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/lib/spatial-api.ts:400"}, "properties": {"repobilityId": "baf786f3b67c75b1", "scanner": "scanner-primary", "fingerprint": "208e4138c6eaf496", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-baa13e58954a3605", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 outreach/send-outreach.js:152"}, "properties": {"repobilityId": "4e9e9057a0e8de71", "scanner": "scanner-primary", "fingerprint": "baa13e58954a3605", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-17e017fb1c4ba236", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 outreach/send-campaign.js:140"}, "properties": {"repobilityId": "00ba8c49e0925c18", "scanner": "scanner-primary", "fingerprint": "17e017fb1c4ba236", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b92d5d14fe1aa526", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/page.tsx:59"}, "properties": {"repobilityId": "88fd235b712bda65", "scanner": "scanner-primary", "fingerprint": "b92d5d14fe1aa526", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/page.tsx"}, "region": {"startLine": 59}}}]}, {"ruleId": "scanner-b39389a3e0f62dd1", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/articles/[slug]/layout.tsx:88"}, "properties": {"repobilityId": "a1b097dee6cb00f6", "scanner": "scanner-primary", "fingerprint": "b39389a3e0f62dd1", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/articles/[slug]/layout.tsx"}, "region": {"startLine": 88}}}]}, {"ruleId": "scanner-cbf27404b0ec3298", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/articles/[slug]/page.tsx:143"}, "properties": {"repobilityId": "c7fe5c63e87d54b7", "scanner": "scanner-primary", "fingerprint": "cbf27404b0ec3298", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/articles/[slug]/page.tsx"}, "region": {"startLine": 143}}}]}, {"ruleId": "scanner-1cf8f3b32f893f57", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/suppliers/page.tsx:728"}, "properties": {"repobilityId": "f11bf5d87f822d04", "scanner": "scanner-primary", "fingerprint": "1cf8f3b32f893f57", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/suppliers/page.tsx"}, "region": {"startLine": 728}}}]}, {"ruleId": "scanner-d1a9c81cb6e87903", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/areas/[state]/[suburb]/page.tsx:103"}, "properties": {"repobilityId": "731a3af5ca9ad0f7", "scanner": "scanner-primary", "fingerprint": "d1a9c81cb6e87903", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/areas/[state]/[suburb]/page.tsx"}, "region": {"startLine": 103}}}]}, {"ruleId": "scanner-9c8c56107059e332", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/feasibility/page.tsx:1367"}, "properties": {"repobilityId": "96a8f8c5c2531772", "scanner": "scanner-primary", "fingerprint": "9c8c56107059e332", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/feasibility/page.tsx"}, "region": {"startLine": 1367}}}]}, {"ruleId": "scanner-c5da918577d7b1ad", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/professionals/page.tsx:698"}, "properties": {"repobilityId": "a2a7a2f05eac4dbd", "scanner": "scanner-primary", "fingerprint": "c5da918577d7b1ad", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/professionals/page.tsx"}, "region": {"startLine": 698}}}]}, {"ruleId": "scanner-5b6032c4cde4928d", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "a283c30bd0d8e836", "scanner": "scanner-primary", "fingerprint": "5b6032c4cde4928d", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/nightly-smoke.yml"}, "region": {"startLine": 33}}}]}, {"ruleId": "scanner-e727f37b3ad5a0d3", "level": "note", "message": {"text": "Very large file: src/app/admin/page.tsx (1148 lines)"}, "properties": {"repobilityId": "af0b4e3680cbed6a", "scanner": "scanner-primary", "fingerprint": "e727f37b3ad5a0d3", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-3c5d1d5588afc60d", "level": "note", "message": {"text": "Very large file: src/app/directory/page.tsx (1428 lines)"}, "properties": {"repobilityId": "595e21d293fc6984", "scanner": "scanner-primary", "fingerprint": "3c5d1d5588afc60d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-bb8268910b151fee", "level": "note", "message": {"text": "Very large file: src/app/feasibility/page.tsx (1377 lines)"}, "properties": {"repobilityId": "f84bb486dba6492b", "scanner": "scanner-primary", "fingerprint": "bb8268910b151fee", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-9ece9322efad2704", "level": "note", "message": {"text": "Very large file: src/lib/articles-batch2.ts (1640 lines)"}, "properties": {"repobilityId": "ef8340905a0336f7", "scanner": "scanner-primary", "fingerprint": "9ece9322efad2704", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-fdadbeccc0da6389", "level": "note", "message": {"text": "Very large file: src/lib/articles-data.ts (3697 lines)"}, "properties": {"repobilityId": "71440a49d9cadfa3", "scanner": "scanner-primary", "fingerprint": "fdadbeccc0da6389", "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-fe61efcee13c97ec", "level": "note", "message": {"text": "37 TODO/FIXME markers"}, "properties": {"repobilityId": "4b38c118003e07d2", "scanner": "scanner-primary", "fingerprint": "fe61efcee13c97ec", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["maintenance"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "8724aaeafabc8eef", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-faccb9061e9b52a0", "level": "note", "message": {"text": "No README detected"}, "properties": {"repobilityId": "29bd30468ead474e", "scanner": "scanner-primary", "fingerprint": "faccb9061e9b52a0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["docs", "readme", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "c24d30f83ef06e42", "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": "bbff508ba8718360", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "b9b4fa6d23b9dac1", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "b27a4c26eabd777e", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "b83375ec5e6dcf94", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "562bc1af4d4326f5", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-17d866d91a7c451e", "level": "error", "message": {"text": "Agent instruction/config may expose a secret: CLAUDE.md"}, "properties": {"repobilityId": "ccce5984e58a48f0", "scanner": "scanner-primary", "fingerprint": "17d866d91a7c451e", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["agent-instructions", "secrets", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "CLAUDE.md"}, "region": {"startLine": 140}}}]}, {"ruleId": "scanner-e93a0f2b3ce96492", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/dashboard/pro/page.tsx:395"}, "properties": {"repobilityId": "e5516a770b6fa1f1", "scanner": "scanner-primary", "fingerprint": "e93a0f2b3ce96492", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-26453b8359ae59af", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/api/feasibility/route.ts:58"}, "properties": {"repobilityId": "24d18bf5fe184adf", "scanner": "scanner-primary", "fingerprint": "26453b8359ae59af", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4926d06f0a7d43e0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/page.tsx:174"}, "properties": {"repobilityId": "3b9e5d4a3f1d1846", "scanner": "scanner-primary", "fingerprint": "4926d06f0a7d43e0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-21a656c7a19efc7e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/suppliers/page.tsx:57"}, "properties": {"repobilityId": "bcd167e1f2f00876", "scanner": "scanner-primary", "fingerprint": "21a656c7a19efc7e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9b379f7fd9764083", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/suppliers/register/page.tsx:64"}, "properties": {"repobilityId": "2a17b6d80c36cd23", "scanner": "scanner-primary", "fingerprint": "9b379f7fd9764083", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-23040ba14ab42963", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/forum/NewPostModal.tsx:58"}, "properties": {"repobilityId": "54a28e667d588418", "scanner": "scanner-primary", "fingerprint": "23040ba14ab42963", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-da44bb905c528803", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/forum/page.tsx:124"}, "properties": {"repobilityId": "eb36a37a89d0c2cc", "scanner": "scanner-primary", "fingerprint": "da44bb905c528803", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d46271b1adc421b9", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/forum/[id]/page.tsx:131"}, "properties": {"repobilityId": "4218bce4476bbe69", "scanner": "scanner-primary", "fingerprint": "d46271b1adc421b9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4f41c17d53c45133", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/directory/page.tsx:237"}, "properties": {"repobilityId": "e9563f03f14c17fd", "scanner": "scanner-primary", "fingerprint": "4f41c17d53c45133", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3c8eb86d00256abb", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/feasibility/page.tsx:327"}, "properties": {"repobilityId": "6bb1a60a8db15bc2", "scanner": "scanner-primary", "fingerprint": "3c8eb86d00256abb", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-35331dcd98ea708b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/join/page.tsx:321"}, "properties": {"repobilityId": "911cdd263cca95f7", "scanner": "scanner-primary", "fingerprint": "35331dcd98ea708b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-340a58a3002e7131", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/professionals/page.tsx:56"}, "properties": {"repobilityId": "3fdd0b8445657b91", "scanner": "scanner-primary", "fingerprint": "340a58a3002e7131", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c9b0acece8baf448", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/professionals/[state]/[slug]/page.tsx:59"}, "properties": {"repobilityId": "897a4eb3eb6d26f8", "scanner": "scanner-primary", "fingerprint": "c9b0acece8baf448", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f9e02babda418615", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/SuburbAutocomplete.tsx:81"}, "properties": {"repobilityId": "4dafbe666067064a", "scanner": "scanner-primary", "fingerprint": "f9e02babda418615", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-dfaccb776dfac987", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/demand-signals.ts:5"}, "properties": {"repobilityId": "cac3241834dcf37f", "scanner": "scanner-primary", "fingerprint": "dfaccb776dfac987", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7c47750d96318226", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/spatial-api.ts:30"}, "properties": {"repobilityId": "d9ae7612d322cd84", "scanner": "scanner-primary", "fingerprint": "7c47750d96318226", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6930cedac10aa0b4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 outreach/send-campaign.js:100"}, "properties": {"repobilityId": "d673af1f1904635c", "scanner": "scanner-primary", "fingerprint": "6930cedac10aa0b4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}]}]}