{"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-9075cdfd6162bc63", "name": "Stray `console.log` in TS/JS \u2014 prisma/seed.ts:40", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 prisma/seed.ts:40"}, "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-e0ebe9512da92763", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/layout.tsx:33", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/layout.tsx:33"}, "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-99f30a107f167ded", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/kiosk/page.tsx:344", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/kiosk/page.tsx:344"}, "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-45d3a42cbcc727fa", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/AdminSidebar.tsx:73", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/AdminSidebar.tsx:73"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8f4688b5c4fec085", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/schedule/WeekCalendar.tsx:230", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/schedule/WeekCalendar.tsx:230"}, "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-39baf63326749ba1", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/notifications/page.tsx:136", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/notifications/page.tsx:136"}, "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-010c0a203512ce39", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/marketing/WorkflowManager.tsx:172", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/marketing/WorkflowManager.tsx:172"}, "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-8b04ad801025dd6b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/marketing/messages/page.tsx:68", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/marketing/messages/page.tsx:68"}, "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-7477f6204a88689d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/pos/POSTerminal.tsx:312", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/pos/POSTerminal.tsx:312"}, "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-f02e4ca09e30a31a", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/reports/page.tsx:330", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/reports/page.tsx:330"}, "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-dc4be5a153fbfe4c", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/setup/StepDone.tsx:44", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/setup/StepDone.tsx:44"}, "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-98712a35a5a9f147", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/curriculum/page.tsx:37", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/curriculum/page.tsx:37"}, "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-42d8585778ce3716", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/member/page.tsx:133", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/member/page.tsx:133"}, "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-63f0b06140818484", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/member/MemberNav.tsx:116", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/member/MemberNav.tsx:116"}, "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-d6d9b726a60d63ff", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/member/schedule/page.tsx:288", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/member/schedule/page.tsx:288"}, "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-b7fe14146bf3105b", "name": "Stray `console.log` in TS/JS \u2014 src/lib/email.ts:19", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/lib/email.ts:19"}, "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-865c9547c2216250", "name": "Insecure pattern 'dangerous_innerhtml' in src/app/layout.tsx:33", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/layout.tsx:33"}, "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-6968e867cdee1d8f", "name": "Possible secret in src/app/kiosk/new/KioskSignup.tsx", "shortDescription": {"text": "Possible secret in src/app/kiosk/new/KioskSignup.tsx"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-210e1654a5b0b3a1", "name": "Insecure pattern 'document_write' in src/app/admin/members/[id]/MemberQRCode.tsx:131", "shortDescription": {"text": "Insecure pattern 'document_write' in src/app/admin/members/[id]/MemberQRCode.tsx:131"}, "fullDescription": {"text": "Found a known-risky pattern (document_write). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "low", "confidence": 1.0}}, {"id": "scanner-749d7b593da9e001", "name": "Insecure pattern 'document_write' in src/app/member/profile/ProfileClient.tsx:524", "shortDescription": {"text": "Insecure pattern 'document_write' in src/app/member/profile/ProfileClient.tsx:524"}, "fullDescription": {"text": "Found a known-risky pattern (document_write). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "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": "16 test file(s) for 235 source file(s) (ratio 0.07). 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-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 16 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 137 placeholder/mock markers across 36 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, 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-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d6c80792a25931b8", "name": "`fetch()` without try/.catch or AbortSignal \u2014 public/sw.js:26", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/sw.js:26"}, "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-a1e1aa7f8442cd7e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/kiosk/WaiverScreen.tsx:37", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/kiosk/WaiverScreen.tsx:37"}, "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-1469af170ac1fa9f", "name": "Legacy-named symbol `cus_legacy` in src/app/api/admin/pos/sales/route.square.test.ts:81", "shortDescription": {"text": "Legacy-named symbol `cus_legacy` in src/app/api/admin/pos/sales/route.square.test.ts:81"}, "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-991509c0813cdfdc", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/settings/page.tsx:185", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/settings/page.tsx:185"}, "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-841dc49289f0a3b6", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/schedule/WeekCalendar.tsx:108", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/schedule/WeekCalendar.tsx:108"}, "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-e4a8b929cf4c36db", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/schedule/ClassForm.tsx:154", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/schedule/ClassForm.tsx:154"}, "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-5ea6730016eb6b44", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/schedule/[id]/roster/RosterClient.tsx:83", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/schedule/[id]/roster/RosterClient.tsx:83"}, "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-7105af2c8db08309", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/schedule/[id]/edit-series/EditSeriesForm.tsx:64", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/schedule/[id]/edit-series/EditSeriesForm.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-bcd96bc128bdce6b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/users/new/page.tsx:25", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/users/new/page.tsx:25"}, "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-9d6c06aeec2f12ac", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/users/[id]/page.tsx:27", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/users/[id]/page.tsx:27"}, "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-a07312cf717dc45d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/leads/LeadActions.tsx:12", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/leads/LeadActions.tsx:12"}, "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-7bf1e51e8ec90ab5", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/families/CreatePortalAccount.tsx:28", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/families/CreatePortalAccount.tsx:28"}, "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-c1baa5ea82e9712c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/marketing/WorkflowManager.tsx:97", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/marketing/WorkflowManager.tsx:97"}, "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-ccd65cd5b78cee7d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/marketing/messages/ComposeMessage.tsx:25", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/marketing/messages/ComposeMessage.tsx:25"}, "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-75cbd4ee61bdceb1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/pos/POSTerminal.tsx:126", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/pos/POSTerminal.tsx:126"}, "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-1a2105e09d7cd149", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/pos/items/ItemsManager.tsx:65", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/pos/items/ItemsManager.tsx:65"}, "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-25eaaef74fe0a83c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/belts/BeltRequirementsEditor.tsx:32", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/belts/BeltRequirementsEditor.tsx:32"}, "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-89fb8d958ffea326", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/new/page.tsx:28", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/new/page.tsx:28"}, "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-a11a89b3227e2429", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/AttendanceManager.tsx:45", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/AttendanceManager.tsx:45"}, "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-c12487f9192dff25", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/DeleteMemberButton.tsx:13", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/DeleteMemberButton.tsx:13"}, "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-372807c44e144730", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/WaiverToggle.tsx:13", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/WaiverToggle.tsx:13"}, "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-1d4fd3543a8b8658", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/FamilyManager.tsx:28", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/FamilyManager.tsx:28"}, "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-666827e139ebbd2f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/BeltStripesEditor.tsx:23", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/BeltStripesEditor.tsx:23"}, "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-6e8b397b1ef30204", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/CreateMemberAccount.tsx:35", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/CreateMemberAccount.tsx:35"}, "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-025999a5693021dd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/ProgressionSection.tsx:80", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/ProgressionSection.tsx:80"}, "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-42cc97d210e382fe", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/edit/EditMemberForm.tsx:36", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/edit/EditMemberForm.tsx:36"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b1290295e7119bee", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/WizardShell.tsx:40", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/WizardShell.tsx:40"}, "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-a5d85411885626a5", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/StepDone.tsx:15", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/StepDone.tsx:15"}, "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-ed70c1d12fa7156a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/schedule/ScheduleSetupClient.tsx:93", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/schedule/ScheduleSetupClient.tsx:93"}, "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-e28aeb4141cd4737", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/families/FamiliesSetupClient.tsx:21", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/families/FamiliesSetupClient.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-650b6f4be07bfd6d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/pos/PosSetupClient.tsx:80", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/pos/PosSetupClient.tsx:80"}, "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-73b5f1ff1de9223b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/belts/BeltSetupClient.tsx:24", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/belts/BeltSetupClient.tsx:24"}, "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-b8509f0f9fa90a06", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/plans/PlanSetupClient.tsx:37", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/plans/PlanSetupClient.tsx:37"}, "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-c2f37f9df718a089", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/features/FeatureVisibilityClient.tsx:34", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/features/FeatureVisibilityClient.tsx:34"}, "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-50c692367ceed912", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/curriculum/[id]/CurriculumBuilder.tsx:99", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/curriculum/[id]/CurriculumBuilder.tsx:99"}, "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-a72fb56576a6fa09", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/plans/new/page.tsx:26", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/plans/new/page.tsx:26"}, "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-6d52b83f5d602e0e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/plans/[id]/edit/page.tsx:34", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/plans/[id]/edit/page.tsx:34"}, "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-d40e041d353bdd5c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/enroll/PaymentStep.tsx:74", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/enroll/PaymentStep.tsx:74"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6040dd63b73fc408", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/enroll/page.tsx:474", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/enroll/page.tsx:474"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7503ef37dd4dc92e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/member/schedule/page.tsx:132", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/member/schedule/page.tsx:132"}, "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-4dc59b591bc51235", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/member/profile/ProfileClient.tsx:20", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/member/profile/ProfileClient.tsx:20"}, "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-c3f93551cfeb2911", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/widget/lead/page.tsx:35", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/widget/lead/page.tsx:35"}, "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-022e6399d1ef2beb", "name": "12 env vars used in code but missing from .env.example", "shortDescription": {"text": "12 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `AUTH_SECRET`, `BLOB_READ_WRITE_TOKEN`, `CRON_SECRET`, `NEXTAUTH_SECRET`, `NEXTAUTH_URL`, `NEXT_PUBLIC_APP_URL`, `NODE_ENV`, `SQUARE_ACCESS_TOKEN` + 4 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/18328"}, "properties": {"repository": "robreed64/bjj-checkin", "repoUrl": "https://github.com/robreed64/bjj-checkin", "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-9075cdfd6162bc63", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 prisma/seed.ts:40"}, "properties": {"repobilityId": "f77d7e0fb34b08e2", "scanner": "scanner-primary", "fingerprint": "9075cdfd6162bc63", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e0ebe9512da92763", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/layout.tsx:33"}, "properties": {"repobilityId": "0d72350965068f5b", "scanner": "scanner-primary", "fingerprint": "e0ebe9512da92763", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-99f30a107f167ded", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/kiosk/page.tsx:344"}, "properties": {"repobilityId": "fe3c9882865e8125", "scanner": "scanner-primary", "fingerprint": "99f30a107f167ded", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-45d3a42cbcc727fa", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/AdminSidebar.tsx:73"}, "properties": {"repobilityId": "5072b72547d09b82", "scanner": "scanner-primary", "fingerprint": "45d3a42cbcc727fa", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8f4688b5c4fec085", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/schedule/WeekCalendar.tsx:230"}, "properties": {"repobilityId": "926072c9697f2bf9", "scanner": "scanner-primary", "fingerprint": "8f4688b5c4fec085", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-39baf63326749ba1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/notifications/page.tsx:136"}, "properties": {"repobilityId": "1b5879d4263638af", "scanner": "scanner-primary", "fingerprint": "39baf63326749ba1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-010c0a203512ce39", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/marketing/WorkflowManager.tsx:172"}, "properties": {"repobilityId": "9283b2eb925591dd", "scanner": "scanner-primary", "fingerprint": "010c0a203512ce39", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8b04ad801025dd6b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/marketing/messages/page.tsx:68"}, "properties": {"repobilityId": "4e1d3592d6404ff6", "scanner": "scanner-primary", "fingerprint": "8b04ad801025dd6b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7477f6204a88689d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/pos/POSTerminal.tsx:312"}, "properties": {"repobilityId": "6930ec24f865891a", "scanner": "scanner-primary", "fingerprint": "7477f6204a88689d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f02e4ca09e30a31a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/reports/page.tsx:330"}, "properties": {"repobilityId": "b403cb8ac5852776", "scanner": "scanner-primary", "fingerprint": "f02e4ca09e30a31a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-dc4be5a153fbfe4c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/setup/StepDone.tsx:44"}, "properties": {"repobilityId": "ee216a3c7c4cdb6f", "scanner": "scanner-primary", "fingerprint": "dc4be5a153fbfe4c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-98712a35a5a9f147", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/admin/curriculum/page.tsx:37"}, "properties": {"repobilityId": "bd65e96122fff88d", "scanner": "scanner-primary", "fingerprint": "98712a35a5a9f147", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-42d8585778ce3716", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/member/page.tsx:133"}, "properties": {"repobilityId": "289e1186c62cfde4", "scanner": "scanner-primary", "fingerprint": "42d8585778ce3716", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-63f0b06140818484", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/member/MemberNav.tsx:116"}, "properties": {"repobilityId": "3499f1a8d002927d", "scanner": "scanner-primary", "fingerprint": "63f0b06140818484", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d6d9b726a60d63ff", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/member/schedule/page.tsx:288"}, "properties": {"repobilityId": "9968e7d091bfbc0a", "scanner": "scanner-primary", "fingerprint": "d6d9b726a60d63ff", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b7fe14146bf3105b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/lib/email.ts:19"}, "properties": {"repobilityId": "bdf73540c4990d36", "scanner": "scanner-primary", "fingerprint": "b7fe14146bf3105b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-865c9547c2216250", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/layout.tsx:33"}, "properties": {"repobilityId": "0bca654fa2052eb0", "scanner": "scanner-primary", "fingerprint": "865c9547c2216250", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/layout.tsx"}, "region": {"startLine": 33}}}]}, {"ruleId": "scanner-6968e867cdee1d8f", "level": "error", "message": {"text": "Possible secret in src/app/kiosk/new/KioskSignup.tsx"}, "properties": {"repobilityId": "959f3f9d332c20fb", "scanner": "scanner-primary", "fingerprint": "6968e867cdee1d8f", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/kiosk/new/KioskSignup.tsx"}, "region": {"startLine": 82}}}]}, {"ruleId": "scanner-6968e867cdee1d8f", "level": "error", "message": {"text": "Possible secret in src/app/kiosk/new/KioskSignup.tsx"}, "properties": {"repobilityId": "959f3f9d332c20fb", "scanner": "scanner-primary", "fingerprint": "6968e867cdee1d8f", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/kiosk/new/KioskSignup.tsx"}, "region": {"startLine": 84}}}]}, {"ruleId": "scanner-210e1654a5b0b3a1", "level": "note", "message": {"text": "Insecure pattern 'document_write' in src/app/admin/members/[id]/MemberQRCode.tsx:131"}, "properties": {"repobilityId": "75eed82cd206978c", "scanner": "scanner-primary", "fingerprint": "210e1654a5b0b3a1", "layer": "security", "severity": "low", "confidence": 1.0, "tags": ["owasp", "document_write"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/admin/members/[id]/MemberQRCode.tsx"}, "region": {"startLine": 131}}}]}, {"ruleId": "scanner-749d7b593da9e001", "level": "note", "message": {"text": "Insecure pattern 'document_write' in src/app/member/profile/ProfileClient.tsx:524"}, "properties": {"repobilityId": "903df23eb47ee2e1", "scanner": "scanner-primary", "fingerprint": "749d7b593da9e001", "layer": "security", "severity": "low", "confidence": 1.0, "tags": ["owasp", "document_write"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/member/profile/ProfileClient.tsx"}, "region": {"startLine": 524}}}]}, {"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": "8f5e4d9c4acb2644", "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": "19dd73d8cd876b6a", "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": "90ccaf25f46fa650", "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": "4223cb4c91bf2e5e", "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": "226c6bf4422f0cf9", "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": "eb881be68ecfa1e4", "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": "4d4c7b3aa44e686a", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "c5773e591f064d99", "scanner": "scanner-primary", "fingerprint": "ea8f3013f588db25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8424db9c75e04ba4", "level": "none", "message": {"text": "Very short observed git history"}, "properties": {"repobilityId": "198d3e60d2b587fb", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-d6c80792a25931b8", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/sw.js:26"}, "properties": {"repobilityId": "37c94a5adcd85631", "scanner": "scanner-primary", "fingerprint": "d6c80792a25931b8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a1e1aa7f8442cd7e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/kiosk/WaiverScreen.tsx:37"}, "properties": {"repobilityId": "20d654578add7247", "scanner": "scanner-primary", "fingerprint": "a1e1aa7f8442cd7e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1469af170ac1fa9f", "level": "note", "message": {"text": "Legacy-named symbol `cus_legacy` in src/app/api/admin/pos/sales/route.square.test.ts:81"}, "properties": {"repobilityId": "4ad002290ec9831a", "scanner": "scanner-primary", "fingerprint": "1469af170ac1fa9f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-991509c0813cdfdc", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/settings/page.tsx:185"}, "properties": {"repobilityId": "77d075f320ee5c40", "scanner": "scanner-primary", "fingerprint": "991509c0813cdfdc", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-841dc49289f0a3b6", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/schedule/WeekCalendar.tsx:108"}, "properties": {"repobilityId": "d8a968c8ce925819", "scanner": "scanner-primary", "fingerprint": "841dc49289f0a3b6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e4a8b929cf4c36db", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/schedule/ClassForm.tsx:154"}, "properties": {"repobilityId": "9e018ce77f30653d", "scanner": "scanner-primary", "fingerprint": "e4a8b929cf4c36db", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5ea6730016eb6b44", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/schedule/[id]/roster/RosterClient.tsx:83"}, "properties": {"repobilityId": "babbbc44cca9e688", "scanner": "scanner-primary", "fingerprint": "5ea6730016eb6b44", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7105af2c8db08309", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/schedule/[id]/edit-series/EditSeriesForm.tsx:64"}, "properties": {"repobilityId": "583b95ad1263ff59", "scanner": "scanner-primary", "fingerprint": "7105af2c8db08309", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bcd96bc128bdce6b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/users/new/page.tsx:25"}, "properties": {"repobilityId": "ba93e8ed4e103eed", "scanner": "scanner-primary", "fingerprint": "bcd96bc128bdce6b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9d6c06aeec2f12ac", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/users/[id]/page.tsx:27"}, "properties": {"repobilityId": "c0d9f44f4cf59a5a", "scanner": "scanner-primary", "fingerprint": "9d6c06aeec2f12ac", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a07312cf717dc45d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/leads/LeadActions.tsx:12"}, "properties": {"repobilityId": "c22e03cd0e1d0d70", "scanner": "scanner-primary", "fingerprint": "a07312cf717dc45d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7bf1e51e8ec90ab5", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/families/CreatePortalAccount.tsx:28"}, "properties": {"repobilityId": "e0cfeae66a14d9f7", "scanner": "scanner-primary", "fingerprint": "7bf1e51e8ec90ab5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c1baa5ea82e9712c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/marketing/WorkflowManager.tsx:97"}, "properties": {"repobilityId": "d651fff193eb81ef", "scanner": "scanner-primary", "fingerprint": "c1baa5ea82e9712c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ccd65cd5b78cee7d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/marketing/messages/ComposeMessage.tsx:25"}, "properties": {"repobilityId": "dc3853795aa00a54", "scanner": "scanner-primary", "fingerprint": "ccd65cd5b78cee7d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-75cbd4ee61bdceb1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/pos/POSTerminal.tsx:126"}, "properties": {"repobilityId": "6a3064cba1345a3a", "scanner": "scanner-primary", "fingerprint": "75cbd4ee61bdceb1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1a2105e09d7cd149", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/pos/items/ItemsManager.tsx:65"}, "properties": {"repobilityId": "f861d4b9286fb2c7", "scanner": "scanner-primary", "fingerprint": "1a2105e09d7cd149", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-25eaaef74fe0a83c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/belts/BeltRequirementsEditor.tsx:32"}, "properties": {"repobilityId": "25a4bbcd7cad7d19", "scanner": "scanner-primary", "fingerprint": "25eaaef74fe0a83c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-89fb8d958ffea326", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/new/page.tsx:28"}, "properties": {"repobilityId": "3da7be126176196b", "scanner": "scanner-primary", "fingerprint": "89fb8d958ffea326", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a11a89b3227e2429", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/AttendanceManager.tsx:45"}, "properties": {"repobilityId": "e55d31afbf5ae14d", "scanner": "scanner-primary", "fingerprint": "a11a89b3227e2429", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c12487f9192dff25", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/DeleteMemberButton.tsx:13"}, "properties": {"repobilityId": "8e0124e85ed975d9", "scanner": "scanner-primary", "fingerprint": "c12487f9192dff25", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-372807c44e144730", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/WaiverToggle.tsx:13"}, "properties": {"repobilityId": "fc4d052a3bd0b4d6", "scanner": "scanner-primary", "fingerprint": "372807c44e144730", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1d4fd3543a8b8658", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/FamilyManager.tsx:28"}, "properties": {"repobilityId": "07ebb08de2d14602", "scanner": "scanner-primary", "fingerprint": "1d4fd3543a8b8658", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-666827e139ebbd2f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/BeltStripesEditor.tsx:23"}, "properties": {"repobilityId": "55e0efa5fd95c9d3", "scanner": "scanner-primary", "fingerprint": "666827e139ebbd2f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6e8b397b1ef30204", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/CreateMemberAccount.tsx:35"}, "properties": {"repobilityId": "036b60f53b2317dc", "scanner": "scanner-primary", "fingerprint": "6e8b397b1ef30204", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-025999a5693021dd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/ProgressionSection.tsx:80"}, "properties": {"repobilityId": "9973c816760ae22d", "scanner": "scanner-primary", "fingerprint": "025999a5693021dd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-42cc97d210e382fe", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/members/[id]/edit/EditMemberForm.tsx:36"}, "properties": {"repobilityId": "860393ce8b65f64f", "scanner": "scanner-primary", "fingerprint": "42cc97d210e382fe", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b1290295e7119bee", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/WizardShell.tsx:40"}, "properties": {"repobilityId": "179067dbd1235373", "scanner": "scanner-primary", "fingerprint": "b1290295e7119bee", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a5d85411885626a5", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/StepDone.tsx:15"}, "properties": {"repobilityId": "e93f660c206bd494", "scanner": "scanner-primary", "fingerprint": "a5d85411885626a5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ed70c1d12fa7156a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/schedule/ScheduleSetupClient.tsx:93"}, "properties": {"repobilityId": "33e80ab16867e43e", "scanner": "scanner-primary", "fingerprint": "ed70c1d12fa7156a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e28aeb4141cd4737", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/families/FamiliesSetupClient.tsx:21"}, "properties": {"repobilityId": "0af49c7a92ce4d6e", "scanner": "scanner-primary", "fingerprint": "e28aeb4141cd4737", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-650b6f4be07bfd6d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/pos/PosSetupClient.tsx:80"}, "properties": {"repobilityId": "118dcb43164603bc", "scanner": "scanner-primary", "fingerprint": "650b6f4be07bfd6d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-73b5f1ff1de9223b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/belts/BeltSetupClient.tsx:24"}, "properties": {"repobilityId": "900ca060ae18682b", "scanner": "scanner-primary", "fingerprint": "73b5f1ff1de9223b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b8509f0f9fa90a06", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/plans/PlanSetupClient.tsx:37"}, "properties": {"repobilityId": "2f024fb0d3a876c1", "scanner": "scanner-primary", "fingerprint": "b8509f0f9fa90a06", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c2f37f9df718a089", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/setup/features/FeatureVisibilityClient.tsx:34"}, "properties": {"repobilityId": "cf33deb8a2397d62", "scanner": "scanner-primary", "fingerprint": "c2f37f9df718a089", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-50c692367ceed912", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/curriculum/[id]/CurriculumBuilder.tsx:99"}, "properties": {"repobilityId": "a1d947c707f951e0", "scanner": "scanner-primary", "fingerprint": "50c692367ceed912", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a72fb56576a6fa09", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/plans/new/page.tsx:26"}, "properties": {"repobilityId": "52184a746cad6fe9", "scanner": "scanner-primary", "fingerprint": "a72fb56576a6fa09", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6d52b83f5d602e0e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/admin/plans/[id]/edit/page.tsx:34"}, "properties": {"repobilityId": "0ed758b1868294aa", "scanner": "scanner-primary", "fingerprint": "6d52b83f5d602e0e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d40e041d353bdd5c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/enroll/PaymentStep.tsx:74"}, "properties": {"repobilityId": "6b2beba0af1e0bfe", "scanner": "scanner-primary", "fingerprint": "d40e041d353bdd5c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6040dd63b73fc408", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/enroll/page.tsx:474"}, "properties": {"repobilityId": "17d79718f7c65351", "scanner": "scanner-primary", "fingerprint": "6040dd63b73fc408", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7503ef37dd4dc92e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/member/schedule/page.tsx:132"}, "properties": {"repobilityId": "5be2bfa5c2edbab5", "scanner": "scanner-primary", "fingerprint": "7503ef37dd4dc92e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4dc59b591bc51235", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/member/profile/ProfileClient.tsx:20"}, "properties": {"repobilityId": "66f1be6079bc3a49", "scanner": "scanner-primary", "fingerprint": "4dc59b591bc51235", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c3f93551cfeb2911", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/widget/lead/page.tsx:35"}, "properties": {"repobilityId": "4f24c670a15c239c", "scanner": "scanner-primary", "fingerprint": "c3f93551cfeb2911", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-022e6399d1ef2beb", "level": "note", "message": {"text": "12 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "7bf4178327da75a2", "scanner": "scanner-primary", "fingerprint": "022e6399d1ef2beb", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}]}]}