{"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-347732fa6958511a", "name": "Stray `console.log` in TS/JS \u2014 tests/funnel-1B.spec.ts:454", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 tests/funnel-1B.spec.ts:454"}, "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-f94caf9623a36198", "name": "Stray `console.log` in TS/JS \u2014 tests/a11y.spec.ts:31", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 tests/a11y.spec.ts:31"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8af1d5ac4b14b0fd", "name": "Stray `console.log` in TS/JS \u2014 tests/funnel-1A.spec.ts:340", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 tests/funnel-1A.spec.ts:340"}, "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-14487266784234ec", "name": "Stray `console.log` in TS/JS \u2014 scripts/setup-test-user.ts:36", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/setup-test-user.ts:36"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c4a55e95e8610946", "name": "Stray `console.log` in TS/JS \u2014 scripts/check-airport-metros.ts:8", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/check-airport-metros.ts:8"}, "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-7679459fa7f9667e", "name": "Stray `console.log` in TS/JS \u2014 scripts/debug-enrich.ts:15", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/debug-enrich.ts:15"}, "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-6606ca132ddc7b7e", "name": "Stray `console.log` in TS/JS \u2014 scripts/backfill-media.ts:215", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/backfill-media.ts:215"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-175333a56e85b234", "name": "Stray `console.log` in TS/JS \u2014 scripts/seed.ts:30", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed.ts:30"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-dc8fa9b0263f0c92", "name": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-test-trips.ts:63", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-test-trips.ts:63"}, "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-1c57ed5bff7db448", "name": "Stray `console.log` in TS/JS \u2014 scripts/backfill-referral-codes.ts:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/backfill-referral-codes.ts:22"}, "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-e4634ab2f01216d4", "name": "Stray `console.log` in TS/JS \u2014 scripts/fetch-chat-avatars.ts:145", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/fetch-chat-avatars.ts:145"}, "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-2610d26ac452e3e3", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/admin/CrewManagement.tsx:84", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/admin/CrewManagement.tsx:84"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ce03cadea8e447b0", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/bookings/BookingsList.tsx:188", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/bookings/BookingsList.tsx:188"}, "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-a3e36ed8ac528b8d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/TripSwitcher.tsx:89", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/TripSwitcher.tsx:89"}, "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-392e724df554950d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/AccountMenu.tsx:85", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/AccountMenu.tsx:85"}, "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-46c787103c1f8d16", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/destinations/DestinationSearch.tsx:325", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/destinations/DestinationSearch.tsx:325"}, "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-106a0c14e1082e20", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/destinations/Destinations.tsx:711", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/destinations/Destinations.tsx:711"}, "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-e4d57a2cde3160e5", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/feed/MessageComposer.tsx:123", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/feed/MessageComposer.tsx:123"}, "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-e0c3535ffcd7a4d0", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/feed/Gallery.tsx:248", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/feed/Gallery.tsx:248"}, "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-e1d26d03078fb39d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/feed/Lightbox.tsx:276", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/feed/Lightbox.tsx:276"}, "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-d807303d43d7539d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/feed/MessageBubble.tsx:106", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/feed/MessageBubble.tsx:106"}, "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-d87835bdc2cc7328", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/marketing/Hero.tsx:145", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/marketing/Hero.tsx:145"}, "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-02f440143bb7d498", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/marketing/curated/PersonalisedSpecGrid.tsx:50", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/marketing/curated/PersonalisedSpecGrid.tsx:50"}, "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-f96097ebd1c177b1", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/marketing/curated/TeaserForm.tsx:512", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/marketing/curated/TeaserForm.tsx:512"}, "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-2760ae798f405ee6", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/PolaroidSlotPicker.tsx:197", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/PolaroidSlotPicker.tsx:197"}, "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-ae1de0dbff8dcfea", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/AirportSearch.tsx:228", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/AirportSearch.tsx:228"}, "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-51884c565463a826", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/PlacePills.tsx:40", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/PlacePills.tsx:40"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ee226768d4262b2b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/PolaroidSwapDialog.tsx:109", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/PolaroidSwapDialog.tsx:109"}, "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-895ec08e80dd3240", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/StaySheet.tsx:141", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/StaySheet.tsx:141"}, "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-904567bd5db1a26a", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/Polaroid.tsx:61", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/Polaroid.tsx:61"}, "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-5b8923d8279c9a1c", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/FlightsSheet.tsx:118", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/FlightsSheet.tsx:118"}, "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-afe9a66e64ddcf75", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/ledger/ObligationRow.tsx:157", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ledger/ObligationRow.tsx:157"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-a6e2bdae407b2e40", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/invites/PriorCrewChips.tsx:77", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/invites/PriorCrewChips.tsx:77"}, "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-9cf564a99dc66ddd", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/invites/InvitePanel.tsx:183", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/invites/InvitePanel.tsx:183"}, "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-9ee3656f5f916786", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/trips/TripPreview.tsx:92", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/trips/TripPreview.tsx:92"}, "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-8142cb29f09b5754", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/DateRangePicker.tsx:88", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/DateRangePicker.tsx:88"}, "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-5802f2af907380f4", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/DatePicker.tsx:79", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/DatePicker.tsx:79"}, "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-045c8efd6072a293", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/Select.tsx:142", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/Select.tsx:142"}, "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-f7937b600a2c0ba7", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/MoneyInput.tsx:154", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/MoneyInput.tsx:154"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-7e3cc994640dbf41", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/DateTimePicker.tsx:105", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/DateTimePicker.tsx:105"}, "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-b5e80481efec9109", "name": "Stray `console.log` in TS/JS \u2014 src/lib/referrals/attribution.ts:26", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/lib/referrals/attribution.ts:26"}, "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-224ba5f7431ea461", "name": "Insecure pattern 'direct_innerhtml_assignment' in prototype/stockholm_trip.html:621", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in prototype/stockholm_trip.html:621"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea3b5e389d8c9c0f", "name": "Low test-to-source ratio", "shortDescription": {"text": "Low test-to-source ratio"}, "fullDescription": {"text": "62 tests / 371 src (ratio 0.17)."}, "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-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 68 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 94 placeholder/mock markers across 38 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, ci. 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, ci. 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-22bf5973103eb650", "name": "Commented-code block (9 lines) in tests/e2e/curated-teaser-phase2.spec.ts:104", "shortDescription": {"text": "Commented-code block (9 lines) in tests/e2e/curated-teaser-phase2.spec.ts:104"}, "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-a2698237955cc1ef", "name": "Commented-code block (10 lines) in tests/e2e/curated-teaser-phase1.spec.ts:193", "shortDescription": {"text": "Commented-code block (10 lines) in tests/e2e/curated-teaser-phase1.spec.ts:193"}, "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-af6b322f5f2db9e1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/backfill-media.ts:106", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/backfill-media.ts:106"}, "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-489708f912e832c9", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/fetch-chat-avatars.ts:91", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/fetch-chat-avatars.ts:91"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-f77ca5285b219fad", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/api/cron/teaser-cost-alert/route.ts:65", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/api/cron/teaser-cost-alert/route.ts: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-12c1b8421f6f7ac3", "name": "Commented-code block (5 lines) in src/app/(app)/trips/[slug]/destinations/page.tsx:55", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/(app)/trips/[slug]/destinations/page.tsx:55"}, "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-1b24695db9d3cd34", "name": "Commented-code block (6 lines) in src/hooks/useNotifications.ts:83", "shortDescription": {"text": "Commented-code block (6 lines) in src/hooks/useNotifications.ts:83"}, "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-a4b13ef28f52ecb5", "name": "Commented-code block (5 lines) in src/components/referrals/ReferralRewardsList.tsx:23", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/referrals/ReferralRewardsList.tsx:23"}, "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-6f886b82a74105ba", "name": "Commented-code block (7 lines) in src/components/layout/NotificationsBell.tsx:76", "shortDescription": {"text": "Commented-code block (7 lines) in src/components/layout/NotificationsBell.tsx:76"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-f2f5c89c993baf53", "name": "Commented-code block (6 lines) in src/components/destinations/DestinationSearch.tsx:76", "shortDescription": {"text": "Commented-code block (6 lines) in src/components/destinations/DestinationSearch.tsx:76"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-020dca570a2a7759", "name": "Commented-code block (5 lines) in src/components/destinations/Destinations.tsx:200", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/destinations/Destinations.tsx:200"}, "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-30c105132c4b5664", "name": "Commented-code block (5 lines) in src/components/marketing/curated/PersonalisedTeaserBlocks.tsx:172", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/marketing/curated/PersonalisedTeaserBlocks.tsx:172"}, "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-09abe8ab207a3acd", "name": "Commented-code block (6 lines) in src/components/overview/DraftingFlow.tsx:83", "shortDescription": {"text": "Commented-code block (6 lines) in src/components/overview/DraftingFlow.tsx:83"}, "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-a7dbd1c33c4a5eb5", "name": "Commented-code block (5 lines) in src/components/ledger/Ledger.tsx:365", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/ledger/Ledger.tsx:365"}, "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-450383aef555541d", "name": "Commented-code block (5 lines) in src/lib/places.ts:25", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/places.ts:25"}, "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-413d9a199f74f678", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/places.ts:193", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/places.ts:193"}, "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-8a76b8207240e820", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/mapbox.ts:68", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/mapbox.ts:68"}, "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-69af8998d5614216", "name": "Commented-code block (6 lines) in src/lib/plan.ts:94", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/plan.ts:94"}, "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-135020690e535613", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/photoStorage.ts:53", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/photoStorage.ts:53"}, "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-d279f21cd2daab3c", "name": "Commented-code block (5 lines) in src/lib/types.ts:105", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/types.ts:105"}, "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-a09bba05448330d8", "name": "Legacy-named symbol `rest_v1` in src/lib/wikimedia.ts:10", "shortDescription": {"text": "Legacy-named symbol `rest_v1` in src/lib/wikimedia.ts:10"}, "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-3552671747a32edb", "name": "Commented-code block (5 lines) in src/lib/stripe/webhookCheckout.ts:205", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/stripe/webhookCheckout.ts:205"}, "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-00a4824ba2a423d3", "name": "Legacy-named symbol `price_unknown_legacy` in src/lib/stripe/__tests__/billingInterval.test.ts:41", "shortDescription": {"text": "Legacy-named symbol `price_unknown_legacy` in src/lib/stripe/__tests__/billingInterval.test.ts:41"}, "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-ba49d1da61e829e2", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/places/client.ts:48", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/places/client.ts:48"}, "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-56b3e7bd825fc3ca", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/weather/client.ts:47", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/weather/client.ts:47"}, "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-bac23f85d2df4be3", "name": "Commented-code block (8 lines) in src/lib/applications/answerLabels.ts:8", "shortDescription": {"text": "Commented-code block (8 lines) in src/lib/applications/answerLabels.ts:8"}, "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-b9a6b3d11167e734", "name": "Commented-code block (6 lines) in src/lib/auth/checkoutProvisioning.ts:89", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/auth/checkoutProvisioning.ts:89"}, "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-f066eed98f7dc088", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/email/welcomeEmail.ts:64", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/email/welcomeEmail.ts: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-6c25697f05757233", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/email/teaserEmails.ts:175", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/email/teaserEmails.ts:175"}, "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-d0d7827a6fff3086", "name": "Commented-code block (6 lines) in src/lib/ledger/obligations.ts:58", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/ledger/obligations.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-8b773ef05ddc8691", "name": "Commented-code block (7 lines) in src/lib/ai/schema.ts:20", "shortDescription": {"text": "Commented-code block (7 lines) in src/lib/ai/schema.ts:20"}, "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-6c7a0b338c26e90c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/actions/priceRefresh.ts:187", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/actions/priceRefresh.ts:187"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-df25b330c57ab370", "name": "Commented-code block (5 lines) in src/lib/actions/draftCandidates.ts:202", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/actions/draftCandidates.ts:202"}, "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-f1565736abf86813", "name": "Commented-code block (5 lines) in src/lib/actions/ledger.ts:207", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/actions/ledger.ts:207"}, "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-517ebf83081ddbd0", "name": "Commented-code block (5 lines) in src/lib/actions/lockAndDraft.ts:333", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/actions/lockAndDraft.ts:333"}, "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-fcf1095231fb5908", "name": "Commented-code block (8 lines) in src/lib/actions/overviewInline.ts:226", "shortDescription": {"text": "Commented-code block (8 lines) in src/lib/actions/overviewInline.ts:226"}, "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-4829414a4d428e0b", "name": "Commented-code block (6 lines) in src/lib/actions/teaser.ts:99", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/actions/teaser.ts:99"}, "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-269849046d87d460", "name": "Commented-code block (6 lines) in src/lib/actions/__tests__/foundingReservation.test.ts:5", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/actions/__tests__/foundingReservation.test.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-83635f82cb2ee964", "name": "Commented-code block (5 lines) in src/lib/actions/__tests__/roadmap.test.ts:5", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/actions/__tests__/roadmap.test.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-5997863a7539a3eb", "name": "Commented-code block (9 lines) in src/lib/actions/__tests__/draftLeadResume.test.ts:5", "shortDescription": {"text": "Commented-code block (9 lines) in src/lib/actions/__tests__/draftLeadResume.test.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-8e047ab7af03962f", "name": "7 env vars used in code but missing from .env.example", "shortDescription": {"text": "7 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `CI`, `CODESPACE_NAME`, `GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN`, `NODE_ENV`, `NO_COLOR`, `PLAYWRIGHT_BASE_URL`, `PLAYWRIGHT_PORT`. 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/25264"}, "properties": {"repository": "datguynig/tripcrew", "repoUrl": "https://github.com/datguynig/tripcrew", "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-347732fa6958511a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 tests/funnel-1B.spec.ts:454"}, "properties": {"repobilityId": "d41bc128e878977b", "scanner": "scanner-primary", "fingerprint": "347732fa6958511a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f94caf9623a36198", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 tests/a11y.spec.ts:31"}, "properties": {"repobilityId": "f65c0bd4fcb053ac", "scanner": "scanner-primary", "fingerprint": "f94caf9623a36198", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8af1d5ac4b14b0fd", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 tests/funnel-1A.spec.ts:340"}, "properties": {"repobilityId": "11c15b59f79656ae", "scanner": "scanner-primary", "fingerprint": "8af1d5ac4b14b0fd", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-14487266784234ec", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/setup-test-user.ts:36"}, "properties": {"repobilityId": "a70cb29230b9c678", "scanner": "scanner-primary", "fingerprint": "14487266784234ec", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c4a55e95e8610946", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/check-airport-metros.ts:8"}, "properties": {"repobilityId": "46340f44a77c57e8", "scanner": "scanner-primary", "fingerprint": "c4a55e95e8610946", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7679459fa7f9667e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/debug-enrich.ts:15"}, "properties": {"repobilityId": "ac06013e4031594f", "scanner": "scanner-primary", "fingerprint": "7679459fa7f9667e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6606ca132ddc7b7e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/backfill-media.ts:215"}, "properties": {"repobilityId": "498b9e1ee0538998", "scanner": "scanner-primary", "fingerprint": "6606ca132ddc7b7e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-175333a56e85b234", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed.ts:30"}, "properties": {"repobilityId": "6b45b8d4fff61a2c", "scanner": "scanner-primary", "fingerprint": "175333a56e85b234", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-dc8fa9b0263f0c92", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-test-trips.ts:63"}, "properties": {"repobilityId": "fd9d6d40b5bb2e57", "scanner": "scanner-primary", "fingerprint": "dc8fa9b0263f0c92", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1c57ed5bff7db448", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/backfill-referral-codes.ts:22"}, "properties": {"repobilityId": "029b7accf4e4b8a3", "scanner": "scanner-primary", "fingerprint": "1c57ed5bff7db448", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e4634ab2f01216d4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/fetch-chat-avatars.ts:145"}, "properties": {"repobilityId": "bbd2a18d8216f8d5", "scanner": "scanner-primary", "fingerprint": "e4634ab2f01216d4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2610d26ac452e3e3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/admin/CrewManagement.tsx:84"}, "properties": {"repobilityId": "fc910c4db69e01df", "scanner": "scanner-primary", "fingerprint": "2610d26ac452e3e3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ce03cadea8e447b0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/bookings/BookingsList.tsx:188"}, "properties": {"repobilityId": "c3cf2f5b7db718f4", "scanner": "scanner-primary", "fingerprint": "ce03cadea8e447b0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a3e36ed8ac528b8d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/TripSwitcher.tsx:89"}, "properties": {"repobilityId": "b5d45cb162b02122", "scanner": "scanner-primary", "fingerprint": "a3e36ed8ac528b8d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-392e724df554950d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/AccountMenu.tsx:85"}, "properties": {"repobilityId": "8b4766ded0c7065e", "scanner": "scanner-primary", "fingerprint": "392e724df554950d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-46c787103c1f8d16", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/destinations/DestinationSearch.tsx:325"}, "properties": {"repobilityId": "f5ef2aebeda4d7b7", "scanner": "scanner-primary", "fingerprint": "46c787103c1f8d16", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-106a0c14e1082e20", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/destinations/Destinations.tsx:711"}, "properties": {"repobilityId": "fe32220f64f7c083", "scanner": "scanner-primary", "fingerprint": "106a0c14e1082e20", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e4d57a2cde3160e5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/feed/MessageComposer.tsx:123"}, "properties": {"repobilityId": "ecbc5ab7921a1b0e", "scanner": "scanner-primary", "fingerprint": "e4d57a2cde3160e5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e0c3535ffcd7a4d0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/feed/Gallery.tsx:248"}, "properties": {"repobilityId": "858ed9a17a5b45f9", "scanner": "scanner-primary", "fingerprint": "e0c3535ffcd7a4d0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e1d26d03078fb39d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/feed/Lightbox.tsx:276"}, "properties": {"repobilityId": "111b1428026cd663", "scanner": "scanner-primary", "fingerprint": "e1d26d03078fb39d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d807303d43d7539d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/feed/MessageBubble.tsx:106"}, "properties": {"repobilityId": "313c06e415d78c86", "scanner": "scanner-primary", "fingerprint": "d807303d43d7539d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d87835bdc2cc7328", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/marketing/Hero.tsx:145"}, "properties": {"repobilityId": "3a5af47729740094", "scanner": "scanner-primary", "fingerprint": "d87835bdc2cc7328", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-02f440143bb7d498", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/marketing/curated/PersonalisedSpecGrid.tsx:50"}, "properties": {"repobilityId": "9d0d2c8e96ce5ba2", "scanner": "scanner-primary", "fingerprint": "02f440143bb7d498", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f96097ebd1c177b1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/marketing/curated/TeaserForm.tsx:512"}, "properties": {"repobilityId": "bad45eba08cb281c", "scanner": "scanner-primary", "fingerprint": "f96097ebd1c177b1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2760ae798f405ee6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/PolaroidSlotPicker.tsx:197"}, "properties": {"repobilityId": "2ccafb4d5e16056d", "scanner": "scanner-primary", "fingerprint": "2760ae798f405ee6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ae1de0dbff8dcfea", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/AirportSearch.tsx:228"}, "properties": {"repobilityId": "80abce50920bd9c2", "scanner": "scanner-primary", "fingerprint": "ae1de0dbff8dcfea", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-51884c565463a826", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/PlacePills.tsx:40"}, "properties": {"repobilityId": "47ddc173e84fc059", "scanner": "scanner-primary", "fingerprint": "51884c565463a826", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ee226768d4262b2b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/PolaroidSwapDialog.tsx:109"}, "properties": {"repobilityId": "bd1e9c2ca1a5bf5b", "scanner": "scanner-primary", "fingerprint": "ee226768d4262b2b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-895ec08e80dd3240", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/StaySheet.tsx:141"}, "properties": {"repobilityId": "00c1cdad279a0d37", "scanner": "scanner-primary", "fingerprint": "895ec08e80dd3240", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-904567bd5db1a26a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/Polaroid.tsx:61"}, "properties": {"repobilityId": "4e39ee43d04e170b", "scanner": "scanner-primary", "fingerprint": "904567bd5db1a26a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5b8923d8279c9a1c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/overview/FlightsSheet.tsx:118"}, "properties": {"repobilityId": "42c43413233ea889", "scanner": "scanner-primary", "fingerprint": "5b8923d8279c9a1c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-afe9a66e64ddcf75", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ledger/ObligationRow.tsx:157"}, "properties": {"repobilityId": "a4c768b0394607d5", "scanner": "scanner-primary", "fingerprint": "afe9a66e64ddcf75", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a6e2bdae407b2e40", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/invites/PriorCrewChips.tsx:77"}, "properties": {"repobilityId": "bd3499bd584ed1ee", "scanner": "scanner-primary", "fingerprint": "a6e2bdae407b2e40", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9cf564a99dc66ddd", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/invites/InvitePanel.tsx:183"}, "properties": {"repobilityId": "722f1f960bbe92cb", "scanner": "scanner-primary", "fingerprint": "9cf564a99dc66ddd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9ee3656f5f916786", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/trips/TripPreview.tsx:92"}, "properties": {"repobilityId": "3d0f578fe62b2872", "scanner": "scanner-primary", "fingerprint": "9ee3656f5f916786", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8142cb29f09b5754", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/DateRangePicker.tsx:88"}, "properties": {"repobilityId": "f2e5165370cbcd85", "scanner": "scanner-primary", "fingerprint": "8142cb29f09b5754", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5802f2af907380f4", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/DatePicker.tsx:79"}, "properties": {"repobilityId": "3edff622b45b4408", "scanner": "scanner-primary", "fingerprint": "5802f2af907380f4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-045c8efd6072a293", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/Select.tsx:142"}, "properties": {"repobilityId": "96ab2a7ad9d0fa63", "scanner": "scanner-primary", "fingerprint": "045c8efd6072a293", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f7937b600a2c0ba7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/MoneyInput.tsx:154"}, "properties": {"repobilityId": "a7be5cacccccca65", "scanner": "scanner-primary", "fingerprint": "f7937b600a2c0ba7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7e3cc994640dbf41", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/ui/DateTimePicker.tsx:105"}, "properties": {"repobilityId": "69eed7ad19df54ba", "scanner": "scanner-primary", "fingerprint": "7e3cc994640dbf41", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b5e80481efec9109", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/lib/referrals/attribution.ts:26"}, "properties": {"repobilityId": "6b60f2b88ad42ca3", "scanner": "scanner-primary", "fingerprint": "b5e80481efec9109", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-224ba5f7431ea461", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in prototype/stockholm_trip.html:621"}, "properties": {"repobilityId": "664d65790fc5f66e", "scanner": "scanner-primary", "fingerprint": "224ba5f7431ea461", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "prototype/stockholm_trip.html"}, "region": {"startLine": 621}}}]}, {"ruleId": "scanner-ea3b5e389d8c9c0f", "level": "note", "message": {"text": "Low test-to-source ratio"}, "properties": {"repobilityId": "ef7b2552cc00a375", "scanner": "scanner-primary", "fingerprint": "ea3b5e389d8c9c0f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["tests"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "4aa28948e4f708e4", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "92eb7c2aeb9399d9", "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": "fa021c96030399dc", "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": "189f27abf3802b32", "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": "a899e2c12944b49c", "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": "b790a70af5b2c965", "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": "37b9c2b751c00842", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-22bf5973103eb650", "level": "none", "message": {"text": "Commented-code block (9 lines) in tests/e2e/curated-teaser-phase2.spec.ts:104"}, "properties": {"repobilityId": "3910207f1af046b8", "scanner": "scanner-primary", "fingerprint": "22bf5973103eb650", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a2698237955cc1ef", "level": "none", "message": {"text": "Commented-code block (10 lines) in tests/e2e/curated-teaser-phase1.spec.ts:193"}, "properties": {"repobilityId": "0b311e005ed6cbb8", "scanner": "scanner-primary", "fingerprint": "a2698237955cc1ef", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-af6b322f5f2db9e1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/backfill-media.ts:106"}, "properties": {"repobilityId": "e8ccf4b862383798", "scanner": "scanner-primary", "fingerprint": "af6b322f5f2db9e1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-489708f912e832c9", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/fetch-chat-avatars.ts:91"}, "properties": {"repobilityId": "f300897a8996bae4", "scanner": "scanner-primary", "fingerprint": "489708f912e832c9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f77ca5285b219fad", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/api/cron/teaser-cost-alert/route.ts:65"}, "properties": {"repobilityId": "e9978483cc14d0b2", "scanner": "scanner-primary", "fingerprint": "f77ca5285b219fad", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-12c1b8421f6f7ac3", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/(app)/trips/[slug]/destinations/page.tsx:55"}, "properties": {"repobilityId": "4da59c6fab2f5fd4", "scanner": "scanner-primary", "fingerprint": "12c1b8421f6f7ac3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1b24695db9d3cd34", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/hooks/useNotifications.ts:83"}, "properties": {"repobilityId": "e5608e9c43907b61", "scanner": "scanner-primary", "fingerprint": "1b24695db9d3cd34", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a4b13ef28f52ecb5", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/referrals/ReferralRewardsList.tsx:23"}, "properties": {"repobilityId": "c5f4dd4d822ab093", "scanner": "scanner-primary", "fingerprint": "a4b13ef28f52ecb5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6f886b82a74105ba", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/components/layout/NotificationsBell.tsx:76"}, "properties": {"repobilityId": "89186dfa20a0b132", "scanner": "scanner-primary", "fingerprint": "6f886b82a74105ba", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f2f5c89c993baf53", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/components/destinations/DestinationSearch.tsx:76"}, "properties": {"repobilityId": "559105636afe2502", "scanner": "scanner-primary", "fingerprint": "f2f5c89c993baf53", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-020dca570a2a7759", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/destinations/Destinations.tsx:200"}, "properties": {"repobilityId": "8909fa57b5daa502", "scanner": "scanner-primary", "fingerprint": "020dca570a2a7759", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-30c105132c4b5664", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/marketing/curated/PersonalisedTeaserBlocks.tsx:172"}, "properties": {"repobilityId": "df57c168cce35a5f", "scanner": "scanner-primary", "fingerprint": "30c105132c4b5664", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-09abe8ab207a3acd", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/components/overview/DraftingFlow.tsx:83"}, "properties": {"repobilityId": "9b2268fe5d4dd105", "scanner": "scanner-primary", "fingerprint": "09abe8ab207a3acd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a7dbd1c33c4a5eb5", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/ledger/Ledger.tsx:365"}, "properties": {"repobilityId": "30ee5c98cfc14e9b", "scanner": "scanner-primary", "fingerprint": "a7dbd1c33c4a5eb5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-450383aef555541d", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/places.ts:25"}, "properties": {"repobilityId": "a5eab400f7a138c2", "scanner": "scanner-primary", "fingerprint": "450383aef555541d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-413d9a199f74f678", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/places.ts:193"}, "properties": {"repobilityId": "8698f94eefbe3d84", "scanner": "scanner-primary", "fingerprint": "413d9a199f74f678", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8a76b8207240e820", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/mapbox.ts:68"}, "properties": {"repobilityId": "d1219a1ad499bd2c", "scanner": "scanner-primary", "fingerprint": "8a76b8207240e820", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-69af8998d5614216", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/plan.ts:94"}, "properties": {"repobilityId": "4c4f5b55993f6699", "scanner": "scanner-primary", "fingerprint": "69af8998d5614216", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-135020690e535613", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/photoStorage.ts:53"}, "properties": {"repobilityId": "82eab138ee0e6658", "scanner": "scanner-primary", "fingerprint": "135020690e535613", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d279f21cd2daab3c", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/types.ts:105"}, "properties": {"repobilityId": "599c3976401807f5", "scanner": "scanner-primary", "fingerprint": "d279f21cd2daab3c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a09bba05448330d8", "level": "note", "message": {"text": "Legacy-named symbol `rest_v1` in src/lib/wikimedia.ts:10"}, "properties": {"repobilityId": "b15e7b5539181d9b", "scanner": "scanner-primary", "fingerprint": "a09bba05448330d8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-3552671747a32edb", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/stripe/webhookCheckout.ts:205"}, "properties": {"repobilityId": "1c84787bf4e701d6", "scanner": "scanner-primary", "fingerprint": "3552671747a32edb", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-00a4824ba2a423d3", "level": "note", "message": {"text": "Legacy-named symbol `price_unknown_legacy` in src/lib/stripe/__tests__/billingInterval.test.ts:41"}, "properties": {"repobilityId": "ed90dcd353a6d609", "scanner": "scanner-primary", "fingerprint": "00a4824ba2a423d3", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-ba49d1da61e829e2", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/places/client.ts:48"}, "properties": {"repobilityId": "178ead7959a8bb75", "scanner": "scanner-primary", "fingerprint": "ba49d1da61e829e2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-56b3e7bd825fc3ca", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/weather/client.ts:47"}, "properties": {"repobilityId": "931ddc5bff089da4", "scanner": "scanner-primary", "fingerprint": "56b3e7bd825fc3ca", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bac23f85d2df4be3", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/lib/applications/answerLabels.ts:8"}, "properties": {"repobilityId": "7ed59f0f02cf319e", "scanner": "scanner-primary", "fingerprint": "bac23f85d2df4be3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b9a6b3d11167e734", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/auth/checkoutProvisioning.ts:89"}, "properties": {"repobilityId": "89b95330b1918c3c", "scanner": "scanner-primary", "fingerprint": "b9a6b3d11167e734", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f066eed98f7dc088", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/email/welcomeEmail.ts:64"}, "properties": {"repobilityId": "b667be5a2c926def", "scanner": "scanner-primary", "fingerprint": "f066eed98f7dc088", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6c25697f05757233", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/email/teaserEmails.ts:175"}, "properties": {"repobilityId": "43aaf20a005c4091", "scanner": "scanner-primary", "fingerprint": "6c25697f05757233", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d0d7827a6fff3086", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/ledger/obligations.ts:58"}, "properties": {"repobilityId": "408a6f76fb4c02c8", "scanner": "scanner-primary", "fingerprint": "d0d7827a6fff3086", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8b773ef05ddc8691", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/lib/ai/schema.ts:20"}, "properties": {"repobilityId": "106e0cb81f455e6d", "scanner": "scanner-primary", "fingerprint": "8b773ef05ddc8691", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6c7a0b338c26e90c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/actions/priceRefresh.ts:187"}, "properties": {"repobilityId": "17ab57f634e919a2", "scanner": "scanner-primary", "fingerprint": "6c7a0b338c26e90c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-df25b330c57ab370", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/actions/draftCandidates.ts:202"}, "properties": {"repobilityId": "6336e696ea6a89f4", "scanner": "scanner-primary", "fingerprint": "df25b330c57ab370", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f1565736abf86813", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/actions/ledger.ts:207"}, "properties": {"repobilityId": "d037c5e7ef650730", "scanner": "scanner-primary", "fingerprint": "f1565736abf86813", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-517ebf83081ddbd0", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/actions/lockAndDraft.ts:333"}, "properties": {"repobilityId": "353c09b76515b1d4", "scanner": "scanner-primary", "fingerprint": "517ebf83081ddbd0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-fcf1095231fb5908", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/lib/actions/overviewInline.ts:226"}, "properties": {"repobilityId": "185b709660f5b1fd", "scanner": "scanner-primary", "fingerprint": "fcf1095231fb5908", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4829414a4d428e0b", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/actions/teaser.ts:99"}, "properties": {"repobilityId": "b33a93f430a4a118", "scanner": "scanner-primary", "fingerprint": "4829414a4d428e0b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-269849046d87d460", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/actions/__tests__/foundingReservation.test.ts:5"}, "properties": {"repobilityId": "589644a167ceeeae", "scanner": "scanner-primary", "fingerprint": "269849046d87d460", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-83635f82cb2ee964", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/actions/__tests__/roadmap.test.ts:5"}, "properties": {"repobilityId": "0d0d3f793a6d0efb", "scanner": "scanner-primary", "fingerprint": "83635f82cb2ee964", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5997863a7539a3eb", "level": "none", "message": {"text": "Commented-code block (9 lines) in src/lib/actions/__tests__/draftLeadResume.test.ts:5"}, "properties": {"repobilityId": "19503715a4e603c9", "scanner": "scanner-primary", "fingerprint": "5997863a7539a3eb", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8e047ab7af03962f", "level": "note", "message": {"text": "7 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "5a0455f6498c27ad", "scanner": "scanner-primary", "fingerprint": "8e047ab7af03962f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}]}]}