{"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-0fd6e8b34d41612f", "name": "Stray `console.log` in TS/JS \u2014 apps/api/prisma/seed/demo.ts:349", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/prisma/seed/demo.ts:349"}, "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-3c46d41d0f560791", "name": "Stray `console.log` in TS/JS \u2014 apps/api/prisma/seed/admin.ts:90", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/prisma/seed/admin.ts:90"}, "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-4fece72147c9a44d", "name": "Stray `console.log` in TS/JS \u2014 apps/api/prisma/seed/tours.ts:127", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/prisma/seed/tours.ts:127"}, "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-b78dc634d2fb3704", "name": "TODO/FIXME marker in shipping code \u2014 apps/api/src/common/outbox/outbox-relay.worker.ts:119", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 apps/api/src/common/outbox/outbox-relay.worker.ts:119"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-968d2cabeccda919", "name": "Stray `console.log` in TS/JS \u2014 apps/api/src/common/tracing/init.ts:64", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/common/tracing/init.ts:64"}, "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-d20765dee6b67038", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/app/tours/[slug]/page.tsx:131", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/app/tours/[slug]/page.tsx:131"}, "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-0811521e7825eaec", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/app/admin/page.tsx:130", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/app/admin/page.tsx:130"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-98ef3c10f881fa00", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/app/profile/trips/[id]/page.tsx:296", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/app/profile/trips/[id]/page.tsx:296"}, "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-c4c962937969d2fc", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/app/profile/chat/page.tsx:153", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/app/profile/chat/page.tsx:153"}, "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-2aefc745eb2396ba", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/app/profile/documents/page.tsx:167", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/app/profile/documents/page.tsx:167"}, "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-740febf3a0bd7d25", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/lib/seo/tour-jsonld.ts:11", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/lib/seo/tour-jsonld.ts:11"}, "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-5fc5b279baad2776", "name": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/_archive/trip-dashboard-future/ProfileS", "shortDescription": {"text": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/_archive/trip-dashboard-future/ProfileScreen.jsx:56"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-23588bc8f6ef72cf", "name": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/_archive/trip-dashboard-future/ChatScre", "shortDescription": {"text": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/_archive/trip-dashboard-future/ChatScreen.jsx:69"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-349509cc010bcad3", "name": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/_archive/trip-dashboard-future/Recorder", "shortDescription": {"text": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/_archive/trip-dashboard-future/RecorderScreen.jsx:73"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7326bc4fc5b045d2", "name": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/project/ui_kits/trip_dashboard/ProfileS", "shortDescription": {"text": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/project/ui_kits/trip_dashboard/ProfileScreen.jsx:56"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5add7b7732915a32", "name": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/project/ui_kits/trip_dashboard/ChatScre", "shortDescription": {"text": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/project/ui_kits/trip_dashboard/ChatScreen.jsx:69"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f648c508436ca78e", "name": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/project/ui_kits/trip_dashboard/Recorder", "shortDescription": {"text": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/project/ui_kits/trip_dashboard/RecorderScreen.jsx:73"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c6900b28ebfda6ad", "name": "Privileged port 126 in use", "shortDescription": {"text": "Privileged port 126 in use"}, "fullDescription": {"text": "Port 126 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-71a6414cd9ea7868", "name": "Privileged port 6 in use", "shortDescription": {"text": "Privileged port 6 in use"}, "fullDescription": {"text": "Port 6 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-41226660b9aa0907", "name": "Privileged port 9 in use", "shortDescription": {"text": "Privileged port 9 in use"}, "fullDescription": {"text": "Port 9 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3d70dcd36b57a39a", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-74e2e2316f173b7a", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-aa5acaa49eb8315b", "name": "Containers defined but no K8s/orchestration manifest found", "shortDescription": {"text": "Containers defined but no K8s/orchestration manifest found"}, "fullDescription": {"text": "Repo has Dockerfiles/compose but no Kubernetes/Nomad manifests. If the target deployment is K8s, the manifests may live in a separate ops repo."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ed02ca791b0bbf02", "name": "Possible secret in apps/api/prisma/seed/demo.ts", "shortDescription": {"text": "Possible secret in apps/api/prisma/seed/demo.ts"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-df21426f48d98ae5", "name": "Insecure pattern 'dangerous_innerhtml' in apps/web/app/tours/[slug]/page.tsx:131", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in apps/web/app/tours/[slug]/page.tsx:131"}, "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-645e19ad7523a311", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c0d7e7ed5be2029c", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-cbe310f193a6df9f", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-36fd3c86ff87e5ff", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "docker/metadata-action@v5 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a629b120390fd551", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b22b2b4586713b97", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/github-script@v7 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-27924aa79fa4a517", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c0840d07864313e3", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f0ca91c4494b8601", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "titoportas/update-project-fields@v0.1.0 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-552c05d86184721e", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ca9c9ae125359f8f", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-84012fa5b95d5abb", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-380bea2a77a8aa99", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/configure-pages@v5 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4c704fba7b23e966", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1cec8cbeb9dadf63", "name": "package.json defines install-time lifecycle scripts", "shortDescription": {"text": "package.json defines install-time lifecycle scripts"}, "fullDescription": {"text": "preinstall/install/postinstall/prepare scripts execute during dependency installation. Review them carefully for network calls, obfuscation, shell execution, or credential access."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "2 test file(s) for 411 source file(s) (ratio 0.00). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b06b8d86f24c77f9", "name": "Node manifest has dependencies but no lockfile: apps/api/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/api/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4a9eb7dc7c6e3880", "name": "Node manifest has dependencies but no lockfile: apps/web/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2699d5f16ae11282", "name": "Node manifest has dependencies but no lockfile: packages/shared/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/shared/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "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 34 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 112 placeholder/mock markers across 52 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing lockfile. 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-17d866d91a7c451e", "name": "Agent instruction/config may expose a secret: CLAUDE.md", "shortDescription": {"text": "Agent instruction/config may expose a secret: CLAUDE.md"}, "fullDescription": {"text": "Agent-facing files are routinely pasted into LLM/tool contexts. Move literal tokens, keys, and passwords into a secret manager or document them as placeholders only."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-f5ce3b8a6f641cfe", "name": "Commented-code block (6 lines) in apps/api/src/main.ts:37", "shortDescription": {"text": "Commented-code block (6 lines) in apps/api/src/main.ts:37"}, "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-d7f91aa4afba9036", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/modules/ai/openai.client.ts:87", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/modules/ai/openai.client.ts:87"}, "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-0d0ee849b63b3fb0", "name": "Commented-code block (5 lines) in apps/api/src/modules/audit/audit.service.ts:61", "shortDescription": {"text": "Commented-code block (5 lines) in apps/api/src/modules/audit/audit.service.ts:61"}, "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-b8385598a35d4779", "name": "Commented-code block (7 lines) in apps/api/src/modules/audit/audit.listener.ts:40", "shortDescription": {"text": "Commented-code block (7 lines) in apps/api/src/modules/audit/audit.listener.ts:40"}, "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-4390f27ed95f1e54", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/modules/payments/providers/yookassa-payment.provider.ts:119", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/modules/payments/providers/yookassa-payment.provider.ts:119"}, "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-1a26601c65f600ef", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/lib/api/ai.ts:48", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/lib/api/ai.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-8bc088097d4a6472", "name": "Commented-code block (6 lines) in apps/web/public/prototypes/tour-landing/hero/design-canvas.jsx:2", "shortDescription": {"text": "Commented-code block (6 lines) in apps/web/public/prototypes/tour-landing/hero/design-canvas.jsx:2"}, "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-bd4ce7701cb7b79b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/public/prototypes/tour-landing/hero/design-canvas.jsx:63", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/public/prototypes/tour-landing/hero/design-canvas.jsx:63"}, "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-96ad87491dec16a3", "name": "Commented-code block (6 lines) in docs/UX/prototypes/from-claude-design/tour-landing/hero/design-canvas.jsx:2", "shortDescription": {"text": "Commented-code block (6 lines) in docs/UX/prototypes/from-claude-design/tour-landing/hero/design-canvas.jsx:2"}, "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-b5b2f6215b64f3d8", "name": "`fetch()` without try/.catch or AbortSignal \u2014 docs/UX/prototypes/from-claude-design/tour-landing/hero/design-canvas.jsx:", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/UX/prototypes/from-claude-design/tour-landing/hero/design-canvas.jsx:63"}, "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-49b116b8cac4ea5c", "name": "Legacy-named symbol `priceOld` in docs/UX/prototypes/from-claude-design/homepage/src/sections1.jsx:147", "shortDescription": {"text": "Legacy-named symbol `priceOld` in docs/UX/prototypes/from-claude-design/homepage/src/sections1.jsx:147"}, "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-eac305b4373956aa", "name": "Legacy-named symbol `priceOld` in docs/UX/prototypes/from-claude-design/homepage/src/data-standalone.js:19", "shortDescription": {"text": "Legacy-named symbol `priceOld` in docs/UX/prototypes/from-claude-design/homepage/src/data-standalone.js:19"}, "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-f70953cf0e9891a4", "name": "Legacy-named symbol `priceOld` in docs/UX/prototypes/from-claude-design/homepage/src/data.js:43", "shortDescription": {"text": "Legacy-named symbol `priceOld` in docs/UX/prototypes/from-claude-design/homepage/src/data.js:43"}, "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-232eb06d42826e63", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/dashboard-fetch.mjs:31", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/dashboard-fetch.mjs:31"}, "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-23e78250af8ab053", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/automation/notify.mjs:101", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/automation/notify.mjs:101"}, "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-c429e457ee26fc5b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/automation/digest.mjs:142", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/automation/digest.mjs:142"}, "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-d0b17c8c07a7421d", "name": "8 env vars used in code but missing from .env.example", "shortDescription": {"text": "8 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ADMIN_BOOTSTRAP_EMAIL`, `ADMIN_BOOTSTRAP_PASSWORD`, `GITHUB_REPO`, `GITHUB_REPOSITORY`, `GITHUB_TOKEN`, `PROJECT_NUMBER`, `PROJECT_OWNER`, `TELEGRAM_CHAT_ID`. 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}}, {"id": "scanner-599d48c9e082bb82", "name": "Dangling fetch: POST https://api.github.com/graphql (scripts/dashboard-fetch.mjs:31)", "shortDescription": {"text": "Dangling fetch: POST https://api.github.com/graphql (scripts/dashboard-fetch.mjs:31)"}, "fullDescription": {"text": "`scripts/dashboard-fetch.mjs:31` calls `POST https://api.github.com/graphql` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.github.com/graphql`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-2d8155d9c9c96b2f", "name": "Dangling fetch: GET https://api.github.com/repos/${OWNER}/${REPO}/issues/${issueNumber}/sub_issues (scripts/dashboard-fe", "shortDescription": {"text": "Dangling fetch: GET https://api.github.com/repos/${OWNER}/${REPO}/issues/${issueNumber}/sub_issues (scripts/dashboard-fetch.mjs:128)"}, "fullDescription": {"text": "`scripts/dashboard-fetch.mjs:128` calls `GET https://api.github.com/repos/${OWNER}/${REPO}/issues/${issueNumber}/sub_issues` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.github.com/repos/<p>/<p>/issues/<p>/sub_issues`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-fd1dc91abf32142d", "name": "Unused endpoint: GET /me", "shortDescription": {"text": "Unused endpoint: GET /me"}, "fullDescription": {"text": "`apps/api/src/common/auth/decorators.ts` declares `GET /me` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-840af6ac8597d833", "name": "Unused endpoint: POST /comm/push/subscribe", "shortDescription": {"text": "Unused endpoint: POST /comm/push/subscribe"}, "fullDescription": {"text": "`apps/api/src/modules/comm/push/push.controller.ts` declares `POST /comm/push/subscribe` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2e6f81b56acb0997", "name": "Unused endpoint: DELETE /comm/push/subscribe", "shortDescription": {"text": "Unused endpoint: DELETE /comm/push/subscribe"}, "fullDescription": {"text": "`apps/api/src/modules/comm/push/push.controller.ts` declares `DELETE /comm/push/subscribe` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1b2550718c01f9ec", "name": "Unused endpoint: GET /comm/push/subscriptions", "shortDescription": {"text": "Unused endpoint: GET /comm/push/subscriptions"}, "fullDescription": {"text": "`apps/api/src/modules/comm/push/push.controller.ts` declares `GET /comm/push/subscriptions` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0e6bcbb8d994cb8f", "name": "Unused endpoint: GET /chat/threads", "shortDescription": {"text": "Unused endpoint: GET /chat/threads"}, "fullDescription": {"text": "`apps/api/src/modules/comm/chat/chat.controller.ts` declares `GET /chat/threads` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1965f215e37f3b17", "name": "Unused endpoint: GET /chat/threads/:id/messages", "shortDescription": {"text": "Unused endpoint: GET /chat/threads/:id/messages"}, "fullDescription": {"text": "`apps/api/src/modules/comm/chat/chat.controller.ts` declares `GET /chat/threads/:id/messages` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4df43fa2eb1c2266", "name": "Unused endpoint: POST /chat/threads/:id/messages", "shortDescription": {"text": "Unused endpoint: POST /chat/threads/:id/messages"}, "fullDescription": {"text": "`apps/api/src/modules/comm/chat/chat.controller.ts` declares `POST /chat/threads/:id/messages` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-593aa0a6ddf8635f", "name": "Unused endpoint: POST /chat/threads/:id/read", "shortDescription": {"text": "Unused endpoint: POST /chat/threads/:id/read"}, "fullDescription": {"text": "`apps/api/src/modules/comm/chat/chat.controller.ts` declares `POST /chat/threads/:id/read` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-98911d4dc53eb335", "name": "Unused endpoint: PATCH /comm/preferences/:category", "shortDescription": {"text": "Unused endpoint: PATCH /comm/preferences/:category"}, "fullDescription": {"text": "`apps/api/src/modules/comm/preferences/preferences.controller.ts` declares `PATCH /comm/preferences/:category` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2a845c7c973a8934", "name": "Unused endpoint: POST /ai/manager-chat", "shortDescription": {"text": "Unused endpoint: POST /ai/manager-chat"}, "fullDescription": {"text": "`apps/api/src/modules/ai/ai-manager.controller.ts` declares `POST /ai/manager-chat` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-aefe5887aeb720dd", "name": "Unused endpoint: GET /ai/manager-threads", "shortDescription": {"text": "Unused endpoint: GET /ai/manager-threads"}, "fullDescription": {"text": "`apps/api/src/modules/ai/ai-manager.controller.ts` declares `GET /ai/manager-threads` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-29dc0b4a530b3737", "name": "Unused endpoint: GET /ai/manager-threads/:id", "shortDescription": {"text": "Unused endpoint: GET /ai/manager-threads/:id"}, "fullDescription": {"text": "`apps/api/src/modules/ai/ai-manager.controller.ts` declares `GET /ai/manager-threads/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f85a32feeafd78c9", "name": "Unused endpoint: POST /ai/chat", "shortDescription": {"text": "Unused endpoint: POST /ai/chat"}, "fullDescription": {"text": "`apps/api/src/modules/ai/ai.controller.ts` declares `POST /ai/chat` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f154df0dd163f151", "name": "Unused endpoint: GET /ai/threads", "shortDescription": {"text": "Unused endpoint: GET /ai/threads"}, "fullDescription": {"text": "`apps/api/src/modules/ai/ai.controller.ts` declares `GET /ai/threads` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b0015c8319aec1b9", "name": "Unused endpoint: GET /ai/threads/:id", "shortDescription": {"text": "Unused endpoint: GET /ai/threads/:id"}, "fullDescription": {"text": "`apps/api/src/modules/ai/ai.controller.ts` declares `GET /ai/threads/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8292c0931391749a", "name": "Unused endpoint: POST /auth/register", "shortDescription": {"text": "Unused endpoint: POST /auth/register"}, "fullDescription": {"text": "`apps/api/src/modules/auth/auth.controller.ts` declares `POST /auth/register` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8fdbacfe9430a6ed", "name": "Unused endpoint: POST /auth/login", "shortDescription": {"text": "Unused endpoint: POST /auth/login"}, "fullDescription": {"text": "`apps/api/src/modules/auth/auth.controller.ts` declares `POST /auth/login` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b36892106ecdc9aa", "name": "Unused endpoint: POST /auth/refresh", "shortDescription": {"text": "Unused endpoint: POST /auth/refresh"}, "fullDescription": {"text": "`apps/api/src/modules/auth/auth.controller.ts` declares `POST /auth/refresh` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c059f57186114027", "name": "Unused endpoint: POST /auth/logout", "shortDescription": {"text": "Unused endpoint: POST /auth/logout"}, "fullDescription": {"text": "`apps/api/src/modules/auth/auth.controller.ts` declares `POST /auth/logout` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7472fafa02ed7ad5", "name": "Unused endpoint: POST /auth/logout-all", "shortDescription": {"text": "Unused endpoint: POST /auth/logout-all"}, "fullDescription": {"text": "`apps/api/src/modules/auth/auth.controller.ts` declares `POST /auth/logout-all` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-75d13cb23eb6e2e2", "name": "Unused endpoint: DELETE /auth/sessions/:id", "shortDescription": {"text": "Unused endpoint: DELETE /auth/sessions/:id"}, "fullDescription": {"text": "`apps/api/src/modules/auth/sessions/sessions.controller.ts` declares `DELETE /auth/sessions/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9de905d9461e015b", "name": "Unused endpoint: POST /auth/2fa/enroll", "shortDescription": {"text": "Unused endpoint: POST /auth/2fa/enroll"}, "fullDescription": {"text": "`apps/api/src/modules/auth/two-fa/two-fa.controller.ts` declares `POST /auth/2fa/enroll` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8e0c36741dcc96b8", "name": "Unused endpoint: POST /auth/2fa/verify-enroll", "shortDescription": {"text": "Unused endpoint: POST /auth/2fa/verify-enroll"}, "fullDescription": {"text": "`apps/api/src/modules/auth/two-fa/two-fa.controller.ts` declares `POST /auth/2fa/verify-enroll` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c1623a898f6e649f", "name": "Unused endpoint: POST /auth/2fa/verify", "shortDescription": {"text": "Unused endpoint: POST /auth/2fa/verify"}, "fullDescription": {"text": "`apps/api/src/modules/auth/two-fa/two-fa.controller.ts` declares `POST /auth/2fa/verify` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-210bb87d83d8938e", "name": "Unused endpoint: POST /auth/2fa/disable", "shortDescription": {"text": "Unused endpoint: POST /auth/2fa/disable"}, "fullDescription": {"text": "`apps/api/src/modules/auth/two-fa/two-fa.controller.ts` declares `POST /auth/2fa/disable` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fccda4834b4d97bb", "name": "Unused endpoint: POST /auth/password/reset-request", "shortDescription": {"text": "Unused endpoint: POST /auth/password/reset-request"}, "fullDescription": {"text": "`apps/api/src/modules/auth/password-reset/password-reset.controller.ts` declares `POST /auth/password/reset-request` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bcb608ab7f8c1fa9", "name": "Unused endpoint: POST /auth/password/reset", "shortDescription": {"text": "Unused endpoint: POST /auth/password/reset"}, "fullDescription": {"text": "`apps/api/src/modules/auth/password-reset/password-reset.controller.ts` declares `POST /auth/password/reset` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-15f44387c444f882", "name": "Unused endpoint: POST /leads/messenger-click", "shortDescription": {"text": "Unused endpoint: POST /leads/messenger-click"}, "fullDescription": {"text": "`apps/api/src/modules/leads/leads.controller.ts` declares `POST /leads/messenger-click` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-663b2aef3444dad1", "name": "Unused endpoint: GET /admin/leads/:id", "shortDescription": {"text": "Unused endpoint: GET /admin/leads/:id"}, "fullDescription": {"text": "`apps/api/src/modules/leads/admin-leads.controller.ts` declares `GET /admin/leads/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-925a7ed31635b4c2", "name": "Unused endpoint: PATCH /admin/leads/:id/status", "shortDescription": {"text": "Unused endpoint: PATCH /admin/leads/:id/status"}, "fullDescription": {"text": "`apps/api/src/modules/leads/admin-leads.controller.ts` declares `PATCH /admin/leads/:id/status` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6eca015e2643a3cc", "name": "Unused endpoint: GET /trips/me", "shortDescription": {"text": "Unused endpoint: GET /trips/me"}, "fullDescription": {"text": "`apps/api/src/modules/trips/trips.controller.ts` declares `GET /trips/me` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-be2504ba8bd8b337", "name": "Unused endpoint: GET /trips/:id", "shortDescription": {"text": "Unused endpoint: GET /trips/:id"}, "fullDescription": {"text": "`apps/api/src/modules/trips/trips.controller.ts` declares `GET /trips/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c4d0b8abb1f2ec8c", "name": "Unused endpoint: PATCH /trips/:id/status", "shortDescription": {"text": "Unused endpoint: PATCH /trips/:id/status"}, "fullDescription": {"text": "`apps/api/src/modules/trips/trips.controller.ts` declares `PATCH /trips/:id/status` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-be5fb36a72f0421e", "name": "Unused endpoint: PATCH /trips/:tripId/bookings/:id", "shortDescription": {"text": "Unused endpoint: PATCH /trips/:tripId/bookings/:id"}, "fullDescription": {"text": "`apps/api/src/modules/trips/bookings/bookings.controller.ts` declares `PATCH /trips/:tripId/bookings/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-dc66cd358f939834", "name": "Unused endpoint: DELETE /trips/:tripId/bookings/:id", "shortDescription": {"text": "Unused endpoint: DELETE /trips/:tripId/bookings/:id"}, "fullDescription": {"text": "`apps/api/src/modules/trips/bookings/bookings.controller.ts` declares `DELETE /trips/:tripId/bookings/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9b5c5b9835299140", "name": "Unused endpoint: PATCH /trips/:id/itinerary", "shortDescription": {"text": "Unused endpoint: PATCH /trips/:id/itinerary"}, "fullDescription": {"text": "`apps/api/src/modules/trips/itinerary/itinerary.controller.ts` declares `PATCH /trips/:id/itinerary` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d1657217ba0e147f", "name": "Unused endpoint: POST /trips/:id/itinerary/publish", "shortDescription": {"text": "Unused endpoint: POST /trips/:id/itinerary/publish"}, "fullDescription": {"text": "`apps/api/src/modules/trips/itinerary/itinerary.controller.ts` declares `POST /trips/:id/itinerary/publish` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-88030549cf03f70a", "name": "Unused endpoint: GET /trips/:id/itinerary", "shortDescription": {"text": "Unused endpoint: GET /trips/:id/itinerary"}, "fullDescription": {"text": "`apps/api/src/modules/trips/itinerary/itinerary.controller.ts` declares `GET /trips/:id/itinerary` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9a08554db01b581f", "name": "Unused endpoint: GET /trips/:id/itinerary/draft", "shortDescription": {"text": "Unused endpoint: GET /trips/:id/itinerary/draft"}, "fullDescription": {"text": "`apps/api/src/modules/trips/itinerary/itinerary.controller.ts` declares `GET /trips/:id/itinerary/draft` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b2fb03327ec7e635", "name": "Unused endpoint: GET /readiness", "shortDescription": {"text": "Unused endpoint: GET /readiness"}, "fullDescription": {"text": "`apps/api/src/modules/health/health.controller.ts` declares `GET /readiness` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ec71b190031541aa", "name": "Unused endpoint: POST /media/upload", "shortDescription": {"text": "Unused endpoint: POST /media/upload"}, "fullDescription": {"text": "`apps/api/src/modules/media/media.controller.ts` declares `POST /media/upload` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d799d831cf1bc643", "name": "Unused endpoint: POST /media/:id/finalize", "shortDescription": {"text": "Unused endpoint: POST /media/:id/finalize"}, "fullDescription": {"text": "`apps/api/src/modules/media/media.controller.ts` declares `POST /media/:id/finalize` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-faeec9069aebb500", "name": "Unused endpoint: GET /media/:id/url", "shortDescription": {"text": "Unused endpoint: GET /media/:id/url"}, "fullDescription": {"text": "`apps/api/src/modules/media/media.controller.ts` declares `GET /media/:id/url` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3db32ec32e0b7ad4", "name": "Unused endpoint: GET /media/me/documents", "shortDescription": {"text": "Unused endpoint: GET /media/me/documents"}, "fullDescription": {"text": "`apps/api/src/modules/media/media.controller.ts` declares `GET /media/me/documents` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0fddb95595304584", "name": "Unused endpoint: DELETE /media/:id", "shortDescription": {"text": "Unused endpoint: DELETE /media/:id"}, "fullDescription": {"text": "`apps/api/src/modules/media/media.controller.ts` declares `DELETE /media/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-281ba3b5898e57ef", "name": "Unused endpoint: GET /admin/tours/:id", "shortDescription": {"text": "Unused endpoint: GET /admin/tours/:id"}, "fullDescription": {"text": "`apps/api/src/modules/catalog/admin-catalog.controller.ts` declares `GET /admin/tours/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-83e9d6484fd52b95", "name": "Unused endpoint: PATCH /admin/tours/:id", "shortDescription": {"text": "Unused endpoint: PATCH /admin/tours/:id"}, "fullDescription": {"text": "`apps/api/src/modules/catalog/admin-catalog.controller.ts` declares `PATCH /admin/tours/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f2f4f33eab1f2a13", "name": "Unused endpoint: POST /admin/tours/:id/publish", "shortDescription": {"text": "Unused endpoint: POST /admin/tours/:id/publish"}, "fullDescription": {"text": "`apps/api/src/modules/catalog/admin-catalog.controller.ts` declares `POST /admin/tours/:id/publish` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-766a074251c3ddc4", "name": "Unused endpoint: POST /admin/tours/:id/archive", "shortDescription": {"text": "Unused endpoint: POST /admin/tours/:id/archive"}, "fullDescription": {"text": "`apps/api/src/modules/catalog/admin-catalog.controller.ts` declares `POST /admin/tours/:id/archive` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cc4a075cb62f6c4a", "name": "Unused endpoint: POST /admin/tours/:id/draft", "shortDescription": {"text": "Unused endpoint: POST /admin/tours/:id/draft"}, "fullDescription": {"text": "`apps/api/src/modules/catalog/admin-catalog.controller.ts` declares `POST /admin/tours/:id/draft` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/18210"}, "properties": {"repository": "Rivega42/indiahorizone", "repoUrl": "https://github.com/Rivega42/indiahorizone", "branch": "main"}, "results": [{"ruleId": "scanner-0fd6e8b34d41612f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/prisma/seed/demo.ts:349"}, "properties": {"repobilityId": "c6a7bbe1601bface", "scanner": "scanner-primary", "fingerprint": "0fd6e8b34d41612f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3c46d41d0f560791", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/prisma/seed/admin.ts:90"}, "properties": {"repobilityId": "f730fec376901679", "scanner": "scanner-primary", "fingerprint": "3c46d41d0f560791", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4fece72147c9a44d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/prisma/seed/tours.ts:127"}, "properties": {"repobilityId": "14b9027cbb7f7719", "scanner": "scanner-primary", "fingerprint": "4fece72147c9a44d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b78dc634d2fb3704", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 apps/api/src/common/outbox/outbox-relay.worker.ts:119"}, "properties": {"repobilityId": "7e650d2a7312ecb1", "scanner": "scanner-primary", "fingerprint": "b78dc634d2fb3704", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-968d2cabeccda919", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/common/tracing/init.ts:64"}, "properties": {"repobilityId": "1cab2e28497c037b", "scanner": "scanner-primary", "fingerprint": "968d2cabeccda919", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d20765dee6b67038", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/app/tours/[slug]/page.tsx:131"}, "properties": {"repobilityId": "d3de84c1057640a5", "scanner": "scanner-primary", "fingerprint": "d20765dee6b67038", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-0811521e7825eaec", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/app/admin/page.tsx:130"}, "properties": {"repobilityId": "aecdc7acd7aef397", "scanner": "scanner-primary", "fingerprint": "0811521e7825eaec", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-98ef3c10f881fa00", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/app/profile/trips/[id]/page.tsx:296"}, "properties": {"repobilityId": "44e615c9b6551792", "scanner": "scanner-primary", "fingerprint": "98ef3c10f881fa00", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c4c962937969d2fc", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/app/profile/chat/page.tsx:153"}, "properties": {"repobilityId": "5a9ffc6d40e5b3b2", "scanner": "scanner-primary", "fingerprint": "c4c962937969d2fc", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2aefc745eb2396ba", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/app/profile/documents/page.tsx:167"}, "properties": {"repobilityId": "65bebce81db7f5df", "scanner": "scanner-primary", "fingerprint": "2aefc745eb2396ba", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-740febf3a0bd7d25", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/lib/seo/tour-jsonld.ts:11"}, "properties": {"repobilityId": "4f099445a3683a01", "scanner": "scanner-primary", "fingerprint": "740febf3a0bd7d25", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-5fc5b279baad2776", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/_archive/trip-dashboard-future/ProfileScreen.jsx:56"}, "properties": {"repobilityId": "6624a55746255ec7", "scanner": "scanner-primary", "fingerprint": "5fc5b279baad2776", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-23588bc8f6ef72cf", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/_archive/trip-dashboard-future/ChatScreen.jsx:69"}, "properties": {"repobilityId": "d035384321cf3ec0", "scanner": "scanner-primary", "fingerprint": "23588bc8f6ef72cf", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-349509cc010bcad3", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/_archive/trip-dashboard-future/RecorderScreen.jsx:73"}, "properties": {"repobilityId": "fee8338b3a46a200", "scanner": "scanner-primary", "fingerprint": "349509cc010bcad3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-7326bc4fc5b045d2", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/project/ui_kits/trip_dashboard/ProfileScreen.jsx:56"}, "properties": {"repobilityId": "4b4bc00d152be09c", "scanner": "scanner-primary", "fingerprint": "7326bc4fc5b045d2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-5add7b7732915a32", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/project/ui_kits/trip_dashboard/ChatScreen.jsx:69"}, "properties": {"repobilityId": "1852337121d9f897", "scanner": "scanner-primary", "fingerprint": "5add7b7732915a32", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-f648c508436ca78e", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 docs/UX/prototypes/from-claude-design/project/ui_kits/trip_dashboard/RecorderScreen.jsx:73"}, "properties": {"repobilityId": "a49c375d475ff57f", "scanner": "scanner-primary", "fingerprint": "f648c508436ca78e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-c6900b28ebfda6ad", "level": "warning", "message": {"text": "Privileged port 126 in use"}, "properties": {"repobilityId": "1ca3d1213ae5f334", "scanner": "scanner-primary", "fingerprint": "c6900b28ebfda6ad", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "deploy/docker-compose.dev.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-71a6414cd9ea7868", "level": "warning", "message": {"text": "Privileged port 6 in use"}, "properties": {"repobilityId": "888a3c205ea7334c", "scanner": "scanner-primary", "fingerprint": "71a6414cd9ea7868", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/lighthouse.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-41226660b9aa0907", "level": "warning", "message": {"text": "Privileged port 9 in use"}, "properties": {"repobilityId": "31590a6ba3409390", "scanner": "scanner-primary", "fingerprint": "41226660b9aa0907", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/lighthouse.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3d70dcd36b57a39a", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "cef74e4e4869cb49", "scanner": "scanner-primary", "fingerprint": "3d70dcd36b57a39a", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/Dockerfile"}, "region": {"startLine": 14}}}]}, {"ruleId": "scanner-3d70dcd36b57a39a", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "bea6c317fed49a56", "scanner": "scanner-primary", "fingerprint": "3d70dcd36b57a39a", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/Dockerfile"}, "region": {"startLine": 45}}}]}, {"ruleId": "scanner-74e2e2316f173b7a", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "12b0c80eac650c97", "scanner": "scanner-primary", "fingerprint": "74e2e2316f173b7a", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/Dockerfile"}, "region": {"startLine": 16}}}]}, {"ruleId": "scanner-74e2e2316f173b7a", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "98c808f80fca42bb", "scanner": "scanner-primary", "fingerprint": "74e2e2316f173b7a", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/Dockerfile"}, "region": {"startLine": 73}}}]}, {"ruleId": "scanner-aa5acaa49eb8315b", "level": "note", "message": {"text": "Containers defined but no K8s/orchestration manifest found"}, "properties": {"repobilityId": "b230ea9b68736081", "scanner": "scanner-primary", "fingerprint": "aa5acaa49eb8315b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["coverage", "deployment"]}}, {"ruleId": "scanner-ed02ca791b0bbf02", "level": "error", "message": {"text": "Possible secret in apps/api/prisma/seed/demo.ts"}, "properties": {"repobilityId": "43ce8eda185865e5", "scanner": "scanner-primary", "fingerprint": "ed02ca791b0bbf02", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/prisma/seed/demo.ts"}, "region": {"startLine": 44}}}]}, {"ruleId": "scanner-ed02ca791b0bbf02", "level": "error", "message": {"text": "Possible secret in apps/api/prisma/seed/demo.ts"}, "properties": {"repobilityId": "43ce8eda185865e5", "scanner": "scanner-primary", "fingerprint": "ed02ca791b0bbf02", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/prisma/seed/demo.ts"}, "region": {"startLine": 45}}}]}, {"ruleId": "scanner-ed02ca791b0bbf02", "level": "error", "message": {"text": "Possible secret in apps/api/prisma/seed/demo.ts"}, "properties": {"repobilityId": "43ce8eda185865e5", "scanner": "scanner-primary", "fingerprint": "ed02ca791b0bbf02", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/prisma/seed/demo.ts"}, "region": {"startLine": 48}}}]}, {"ruleId": "scanner-df21426f48d98ae5", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in apps/web/app/tours/[slug]/page.tsx:131"}, "properties": {"repobilityId": "2469ff8a9bb0948b", "scanner": "scanner-primary", "fingerprint": "df21426f48d98ae5", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/app/tours/[slug]/page.tsx"}, "region": {"startLine": 131}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "208f477049539ea8", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 64}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "2099df36e09158fc", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 69}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "b1cebeda8a5a6f8e", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 76}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "464bed554b59e36f", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 80}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "a8be33f931aa9b69", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 89}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "208f477049539ea8", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 107}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "2099df36e09158fc", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 112}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "b1cebeda8a5a6f8e", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 119}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "464bed554b59e36f", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 123}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "a8be33f931aa9b69", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 133}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "199fd9d41ae3de06", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 166}}}]}, {"ruleId": "scanner-c0d7e7ed5be2029c", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "587d0ab25bd2e3fd", "scanner": "scanner-primary", "fingerprint": "c0d7e7ed5be2029c", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-cbe310f193a6df9f", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "573212e145c44806", "scanner": "scanner-primary", "fingerprint": "cbe310f193a6df9f", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/release-please.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-36fd3c86ff87e5ff", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "5d3f59703b2cb28a", "scanner": "scanner-primary", "fingerprint": "36fd3c86ff87e5ff", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-staging.yml"}, "region": {"startLine": 55}}}]}, {"ruleId": "scanner-36fd3c86ff87e5ff", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "5d3f59703b2cb28a", "scanner": "scanner-primary", "fingerprint": "36fd3c86ff87e5ff", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-staging.yml"}, "region": {"startLine": 90}}}]}, {"ruleId": "scanner-36fd3c86ff87e5ff", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "d77e98a2d265e475", "scanner": "scanner-primary", "fingerprint": "36fd3c86ff87e5ff", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-staging.yml"}, "region": {"startLine": 135}}}]}, {"ruleId": "scanner-a629b120390fd551", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "ed62bce030a81a93", "scanner": "scanner-primary", "fingerprint": "a629b120390fd551", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-staging.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b22b2b4586713b97", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "a140de1f44513897", "scanner": "scanner-primary", "fingerprint": "b22b2b4586713b97", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/auto-label-pr.yml"}, "region": {"startLine": 17}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "ae16880318b99912", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "54597edb7f5bad38", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 27}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 33}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "ae16880318b99912", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 62}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "54597edb7f5bad38", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 65}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 71}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "ae16880318b99912", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 102}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "54597edb7f5bad38", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 107}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 113}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "d8772e445ad1bf7d", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 128}}}]}, {"ruleId": "scanner-c0840d07864313e3", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "f93a04cefe667c37", "scanner": "scanner-primary", "fingerprint": "c0840d07864313e3", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/lighthouse.yml"}, "region": {"startLine": 40}}}]}, {"ruleId": "scanner-c0840d07864313e3", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "ac9e72355c471996", "scanner": "scanner-primary", "fingerprint": "c0840d07864313e3", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/lighthouse.yml"}, "region": {"startLine": 45}}}]}, {"ruleId": "scanner-c0840d07864313e3", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "40147a52cdfcf13f", "scanner": "scanner-primary", "fingerprint": "c0840d07864313e3", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/lighthouse.yml"}, "region": {"startLine": 51}}}]}, {"ruleId": "scanner-c0840d07864313e3", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "70ebbd96cb94cd0f", "scanner": "scanner-primary", "fingerprint": "c0840d07864313e3", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/lighthouse.yml"}, "region": {"startLine": 102}}}]}, {"ruleId": "scanner-f0ca91c4494b8601", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "027971ec22ecef81", "scanner": "scanner-primary", "fingerprint": "f0ca91c4494b8601", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/project-automation.yml"}, "region": {"startLine": 113}}}]}, {"ruleId": "scanner-f0ca91c4494b8601", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "027971ec22ecef81", "scanner": "scanner-primary", "fingerprint": "f0ca91c4494b8601", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/project-automation.yml"}, "region": {"startLine": 123}}}]}, {"ruleId": "scanner-552c05d86184721e", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "104aaeec4f48a122", "scanner": "scanner-primary", "fingerprint": "552c05d86184721e", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/prisma-check.yml"}, "region": {"startLine": 46}}}]}, {"ruleId": "scanner-552c05d86184721e", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "94d19739625dd401", "scanner": "scanner-primary", "fingerprint": "552c05d86184721e", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/prisma-check.yml"}, "region": {"startLine": 49}}}]}, {"ruleId": "scanner-552c05d86184721e", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "6e6f87520c936f58", "scanner": "scanner-primary", "fingerprint": "552c05d86184721e", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/prisma-check.yml"}, "region": {"startLine": 55}}}]}, {"ruleId": "scanner-ca9c9ae125359f8f", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "71bb4bd84c43c996", "scanner": "scanner-primary", "fingerprint": "ca9c9ae125359f8f", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-dev.yml"}, "region": {"startLine": 56}}}]}, {"ruleId": "scanner-ca9c9ae125359f8f", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "a959c42dd74bc249", "scanner": "scanner-primary", "fingerprint": "ca9c9ae125359f8f", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-dev.yml"}, "region": {"startLine": 61}}}]}, {"ruleId": "scanner-ca9c9ae125359f8f", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "2d5800b49394c9ba", "scanner": "scanner-primary", "fingerprint": "ca9c9ae125359f8f", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-dev.yml"}, "region": {"startLine": 68}}}]}, {"ruleId": "scanner-ca9c9ae125359f8f", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "e30c1122c565897e", "scanner": "scanner-primary", "fingerprint": "ca9c9ae125359f8f", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-dev.yml"}, "region": {"startLine": 72}}}]}, {"ruleId": "scanner-ca9c9ae125359f8f", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "ea6cd8e594e44cdc", "scanner": "scanner-primary", "fingerprint": "ca9c9ae125359f8f", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-dev.yml"}, "region": {"startLine": 79}}}]}, {"ruleId": "scanner-ca9c9ae125359f8f", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "8b4d55acb4d23f48", "scanner": "scanner-primary", "fingerprint": "ca9c9ae125359f8f", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-dev.yml"}, "region": {"startLine": 103}}}]}, {"ruleId": "scanner-84012fa5b95d5abb", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "dd2bee753ea8fb9c", "scanner": "scanner-primary", "fingerprint": "84012fa5b95d5abb", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-dev.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-380bea2a77a8aa99", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "8efd503d25f727e7", "scanner": "scanner-primary", "fingerprint": "380bea2a77a8aa99", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/dashboard-sync.yml"}, "region": {"startLine": 58}}}]}, {"ruleId": "scanner-380bea2a77a8aa99", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "b0bd2946cdac07bf", "scanner": "scanner-primary", "fingerprint": "380bea2a77a8aa99", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/dashboard-sync.yml"}, "region": {"startLine": 62}}}]}, {"ruleId": "scanner-380bea2a77a8aa99", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "36f57a42eabec1a8", "scanner": "scanner-primary", "fingerprint": "380bea2a77a8aa99", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/dashboard-sync.yml"}, "region": {"startLine": 68}}}]}, {"ruleId": "scanner-4c704fba7b23e966", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "d837b55e48c78a6b", "scanner": "scanner-primary", "fingerprint": "4c704fba7b23e966", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/dashboard-sync.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-1cec8cbeb9dadf63", "level": "note", "message": {"text": "package.json defines install-time lifecycle scripts"}, "properties": {"repobilityId": "c7ee797477e0b0b9", "scanner": "scanner-primary", "fingerprint": "1cec8cbeb9dadf63", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "npm", "install-scripts"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/package.json"}, "region": {"startLine": 1}}}]}, {"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-b06b8d86f24c77f9", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/api/package.json"}, "properties": {"repobilityId": "ce77cd34ed0306d4", "scanner": "scanner-primary", "fingerprint": "b06b8d86f24c77f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4a9eb7dc7c6e3880", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "properties": {"repobilityId": "6c1704bf24cf19ac", "scanner": "scanner-primary", "fingerprint": "4a9eb7dc7c6e3880", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-2699d5f16ae11282", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/shared/package.json"}, "properties": {"repobilityId": "37ac218a4ef9b430", "scanner": "scanner-primary", "fingerprint": "2699d5f16ae11282", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/shared/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "e1263c8a115b6541", "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": "017c1b3a4e14a086", "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": "7bda5a190ffd5c19", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "f36e9268c37c9258", "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": "0ea1a1ad6e63d05c", "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": "dc411599908cfb71", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-17d866d91a7c451e", "level": "error", "message": {"text": "Agent instruction/config may expose a secret: CLAUDE.md"}, "properties": {"repobilityId": "ccce5984e58a48f0", "scanner": "scanner-primary", "fingerprint": "17d866d91a7c451e", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["agent-instructions", "secrets", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "CLAUDE.md"}, "region": {"startLine": 388}}}]}, {"ruleId": "scanner-f5ce3b8a6f641cfe", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/api/src/main.ts:37"}, "properties": {"repobilityId": "902b7bf471f83916", "scanner": "scanner-primary", "fingerprint": "f5ce3b8a6f641cfe", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d7f91aa4afba9036", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/modules/ai/openai.client.ts:87"}, "properties": {"repobilityId": "9c7c9b7f05f36936", "scanner": "scanner-primary", "fingerprint": "d7f91aa4afba9036", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0d0ee849b63b3fb0", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/api/src/modules/audit/audit.service.ts:61"}, "properties": {"repobilityId": "4d3de95ef066a8b3", "scanner": "scanner-primary", "fingerprint": "0d0ee849b63b3fb0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b8385598a35d4779", "level": "none", "message": {"text": "Commented-code block (7 lines) in apps/api/src/modules/audit/audit.listener.ts:40"}, "properties": {"repobilityId": "2673d80c5d611e12", "scanner": "scanner-primary", "fingerprint": "b8385598a35d4779", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4390f27ed95f1e54", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/modules/payments/providers/yookassa-payment.provider.ts:119"}, "properties": {"repobilityId": "42e3779c2d4104cb", "scanner": "scanner-primary", "fingerprint": "4390f27ed95f1e54", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1a26601c65f600ef", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/lib/api/ai.ts:48"}, "properties": {"repobilityId": "43be0e59a06af6c1", "scanner": "scanner-primary", "fingerprint": "1a26601c65f600ef", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8bc088097d4a6472", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/web/public/prototypes/tour-landing/hero/design-canvas.jsx:2"}, "properties": {"repobilityId": "b762f0b8a6a5a644", "scanner": "scanner-primary", "fingerprint": "8bc088097d4a6472", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bd4ce7701cb7b79b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/public/prototypes/tour-landing/hero/design-canvas.jsx:63"}, "properties": {"repobilityId": "c420fe7157a93e42", "scanner": "scanner-primary", "fingerprint": "bd4ce7701cb7b79b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-96ad87491dec16a3", "level": "none", "message": {"text": "Commented-code block (6 lines) in docs/UX/prototypes/from-claude-design/tour-landing/hero/design-canvas.jsx:2"}, "properties": {"repobilityId": "4e84805fbc156884", "scanner": "scanner-primary", "fingerprint": "96ad87491dec16a3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b5b2f6215b64f3d8", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 docs/UX/prototypes/from-claude-design/tour-landing/hero/design-canvas.jsx:63"}, "properties": {"repobilityId": "ca00fcc072254405", "scanner": "scanner-primary", "fingerprint": "b5b2f6215b64f3d8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-49b116b8cac4ea5c", "level": "note", "message": {"text": "Legacy-named symbol `priceOld` in docs/UX/prototypes/from-claude-design/homepage/src/sections1.jsx:147"}, "properties": {"repobilityId": "2ec8ed016568451c", "scanner": "scanner-primary", "fingerprint": "49b116b8cac4ea5c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-eac305b4373956aa", "level": "note", "message": {"text": "Legacy-named symbol `priceOld` in docs/UX/prototypes/from-claude-design/homepage/src/data-standalone.js:19"}, "properties": {"repobilityId": "b2a1afef3560a336", "scanner": "scanner-primary", "fingerprint": "eac305b4373956aa", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-f70953cf0e9891a4", "level": "note", "message": {"text": "Legacy-named symbol `priceOld` in docs/UX/prototypes/from-claude-design/homepage/src/data.js:43"}, "properties": {"repobilityId": "c979b34802e2bf44", "scanner": "scanner-primary", "fingerprint": "f70953cf0e9891a4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-232eb06d42826e63", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/dashboard-fetch.mjs:31"}, "properties": {"repobilityId": "2d19bbb0e2c7bc30", "scanner": "scanner-primary", "fingerprint": "232eb06d42826e63", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-23e78250af8ab053", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/automation/notify.mjs:101"}, "properties": {"repobilityId": "c4ac32e50b75739d", "scanner": "scanner-primary", "fingerprint": "23e78250af8ab053", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c429e457ee26fc5b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/automation/digest.mjs:142"}, "properties": {"repobilityId": "66c106d30a6aeb0a", "scanner": "scanner-primary", "fingerprint": "c429e457ee26fc5b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d0b17c8c07a7421d", "level": "note", "message": {"text": "8 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "17fe720e8247f9df", "scanner": "scanner-primary", "fingerprint": "d0b17c8c07a7421d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-599d48c9e082bb82", "level": "error", "message": {"text": "Dangling fetch: POST https://api.github.com/graphql (scripts/dashboard-fetch.mjs:31)"}, "properties": {"repobilityId": "7118c533a5b8aa7f", "scanner": "scanner-primary", "fingerprint": "599d48c9e082bb82", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2d8155d9c9c96b2f", "level": "error", "message": {"text": "Dangling fetch: GET https://api.github.com/repos/${OWNER}/${REPO}/issues/${issueNumber}/sub_issues (scripts/dashboard-fetch.mjs:128)"}, "properties": {"repobilityId": "81da93d2583d318b", "scanner": "scanner-primary", "fingerprint": "2d8155d9c9c96b2f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-fd1dc91abf32142d", "level": "note", "message": {"text": "Unused endpoint: GET /me"}, "properties": {"repobilityId": "c417af7def1b635b", "scanner": "scanner-primary", "fingerprint": "fd1dc91abf32142d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-840af6ac8597d833", "level": "note", "message": {"text": "Unused endpoint: POST /comm/push/subscribe"}, "properties": {"repobilityId": "c82c5ebe15cc8d37", "scanner": "scanner-primary", "fingerprint": "840af6ac8597d833", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2e6f81b56acb0997", "level": "note", "message": {"text": "Unused endpoint: DELETE /comm/push/subscribe"}, "properties": {"repobilityId": "9a960ee95a180cef", "scanner": "scanner-primary", "fingerprint": "2e6f81b56acb0997", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1b2550718c01f9ec", "level": "note", "message": {"text": "Unused endpoint: GET /comm/push/subscriptions"}, "properties": {"repobilityId": "6ba8b288604cae89", "scanner": "scanner-primary", "fingerprint": "1b2550718c01f9ec", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0e6bcbb8d994cb8f", "level": "note", "message": {"text": "Unused endpoint: GET /chat/threads"}, "properties": {"repobilityId": "f102f1e1d4b2faf8", "scanner": "scanner-primary", "fingerprint": "0e6bcbb8d994cb8f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1965f215e37f3b17", "level": "note", "message": {"text": "Unused endpoint: GET /chat/threads/:id/messages"}, "properties": {"repobilityId": "b98b6adc5d6875f7", "scanner": "scanner-primary", "fingerprint": "1965f215e37f3b17", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4df43fa2eb1c2266", "level": "note", "message": {"text": "Unused endpoint: POST /chat/threads/:id/messages"}, "properties": {"repobilityId": "5342fa86ad147761", "scanner": "scanner-primary", "fingerprint": "4df43fa2eb1c2266", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-593aa0a6ddf8635f", "level": "note", "message": {"text": "Unused endpoint: POST /chat/threads/:id/read"}, "properties": {"repobilityId": "d0424a0d5377bfa0", "scanner": "scanner-primary", "fingerprint": "593aa0a6ddf8635f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-98911d4dc53eb335", "level": "note", "message": {"text": "Unused endpoint: PATCH /comm/preferences/:category"}, "properties": {"repobilityId": "2db4afcb48458a01", "scanner": "scanner-primary", "fingerprint": "98911d4dc53eb335", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2a845c7c973a8934", "level": "note", "message": {"text": "Unused endpoint: POST /ai/manager-chat"}, "properties": {"repobilityId": "d00972dab2f20b77", "scanner": "scanner-primary", "fingerprint": "2a845c7c973a8934", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-aefe5887aeb720dd", "level": "note", "message": {"text": "Unused endpoint: GET /ai/manager-threads"}, "properties": {"repobilityId": "8b849f941b8a6d6f", "scanner": "scanner-primary", "fingerprint": "aefe5887aeb720dd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-29dc0b4a530b3737", "level": "note", "message": {"text": "Unused endpoint: GET /ai/manager-threads/:id"}, "properties": {"repobilityId": "d63cb10af155d2e4", "scanner": "scanner-primary", "fingerprint": "29dc0b4a530b3737", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f85a32feeafd78c9", "level": "note", "message": {"text": "Unused endpoint: POST /ai/chat"}, "properties": {"repobilityId": "f8887ef1c3a7b4bd", "scanner": "scanner-primary", "fingerprint": "f85a32feeafd78c9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f154df0dd163f151", "level": "note", "message": {"text": "Unused endpoint: GET /ai/threads"}, "properties": {"repobilityId": "331f31df29b6c657", "scanner": "scanner-primary", "fingerprint": "f154df0dd163f151", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b0015c8319aec1b9", "level": "note", "message": {"text": "Unused endpoint: GET /ai/threads/:id"}, "properties": {"repobilityId": "76a1fa944afdf568", "scanner": "scanner-primary", "fingerprint": "b0015c8319aec1b9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8292c0931391749a", "level": "note", "message": {"text": "Unused endpoint: POST /auth/register"}, "properties": {"repobilityId": "ec68020e17376fbe", "scanner": "scanner-primary", "fingerprint": "8292c0931391749a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8fdbacfe9430a6ed", "level": "note", "message": {"text": "Unused endpoint: POST /auth/login"}, "properties": {"repobilityId": "4047eb078b786f80", "scanner": "scanner-primary", "fingerprint": "8fdbacfe9430a6ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b36892106ecdc9aa", "level": "note", "message": {"text": "Unused endpoint: POST /auth/refresh"}, "properties": {"repobilityId": "7497ad9ac944daf2", "scanner": "scanner-primary", "fingerprint": "b36892106ecdc9aa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c059f57186114027", "level": "note", "message": {"text": "Unused endpoint: POST /auth/logout"}, "properties": {"repobilityId": "4c897948336561a8", "scanner": "scanner-primary", "fingerprint": "c059f57186114027", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7472fafa02ed7ad5", "level": "note", "message": {"text": "Unused endpoint: POST /auth/logout-all"}, "properties": {"repobilityId": "2be848c580c44332", "scanner": "scanner-primary", "fingerprint": "7472fafa02ed7ad5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-75d13cb23eb6e2e2", "level": "note", "message": {"text": "Unused endpoint: DELETE /auth/sessions/:id"}, "properties": {"repobilityId": "050823c24d30ecb8", "scanner": "scanner-primary", "fingerprint": "75d13cb23eb6e2e2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9de905d9461e015b", "level": "note", "message": {"text": "Unused endpoint: POST /auth/2fa/enroll"}, "properties": {"repobilityId": "f0f16cf32d8a4ed5", "scanner": "scanner-primary", "fingerprint": "9de905d9461e015b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8e0c36741dcc96b8", "level": "note", "message": {"text": "Unused endpoint: POST /auth/2fa/verify-enroll"}, "properties": {"repobilityId": "c9a6c0306ce0799f", "scanner": "scanner-primary", "fingerprint": "8e0c36741dcc96b8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c1623a898f6e649f", "level": "note", "message": {"text": "Unused endpoint: POST /auth/2fa/verify"}, "properties": {"repobilityId": "2f81b4c877f7f4b0", "scanner": "scanner-primary", "fingerprint": "c1623a898f6e649f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-210bb87d83d8938e", "level": "note", "message": {"text": "Unused endpoint: POST /auth/2fa/disable"}, "properties": {"repobilityId": "849268b2f0b886e6", "scanner": "scanner-primary", "fingerprint": "210bb87d83d8938e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fccda4834b4d97bb", "level": "note", "message": {"text": "Unused endpoint: POST /auth/password/reset-request"}, "properties": {"repobilityId": "cd0b797fbf4480ee", "scanner": "scanner-primary", "fingerprint": "fccda4834b4d97bb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bcb608ab7f8c1fa9", "level": "note", "message": {"text": "Unused endpoint: POST /auth/password/reset"}, "properties": {"repobilityId": "c7becfa0939acffa", "scanner": "scanner-primary", "fingerprint": "bcb608ab7f8c1fa9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-15f44387c444f882", "level": "note", "message": {"text": "Unused endpoint: POST /leads/messenger-click"}, "properties": {"repobilityId": "fc2caceef8e4f9fb", "scanner": "scanner-primary", "fingerprint": "15f44387c444f882", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-663b2aef3444dad1", "level": "note", "message": {"text": "Unused endpoint: GET /admin/leads/:id"}, "properties": {"repobilityId": "1c6cbede299c5c7a", "scanner": "scanner-primary", "fingerprint": "663b2aef3444dad1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-925a7ed31635b4c2", "level": "note", "message": {"text": "Unused endpoint: PATCH /admin/leads/:id/status"}, "properties": {"repobilityId": "421d96a4f3955468", "scanner": "scanner-primary", "fingerprint": "925a7ed31635b4c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6eca015e2643a3cc", "level": "note", "message": {"text": "Unused endpoint: GET /trips/me"}, "properties": {"repobilityId": "0c6864ac47edecdd", "scanner": "scanner-primary", "fingerprint": "6eca015e2643a3cc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-be2504ba8bd8b337", "level": "note", "message": {"text": "Unused endpoint: GET /trips/:id"}, "properties": {"repobilityId": "e524981b6e6f6e58", "scanner": "scanner-primary", "fingerprint": "be2504ba8bd8b337", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c4d0b8abb1f2ec8c", "level": "note", "message": {"text": "Unused endpoint: PATCH /trips/:id/status"}, "properties": {"repobilityId": "5a49353da1f9d466", "scanner": "scanner-primary", "fingerprint": "c4d0b8abb1f2ec8c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-be5fb36a72f0421e", "level": "note", "message": {"text": "Unused endpoint: PATCH /trips/:tripId/bookings/:id"}, "properties": {"repobilityId": "72bb7640bccd116e", "scanner": "scanner-primary", "fingerprint": "be5fb36a72f0421e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dc66cd358f939834", "level": "note", "message": {"text": "Unused endpoint: DELETE /trips/:tripId/bookings/:id"}, "properties": {"repobilityId": "0d03dbf588fb4c3d", "scanner": "scanner-primary", "fingerprint": "dc66cd358f939834", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9b5c5b9835299140", "level": "note", "message": {"text": "Unused endpoint: PATCH /trips/:id/itinerary"}, "properties": {"repobilityId": "a27a5a76f59600ed", "scanner": "scanner-primary", "fingerprint": "9b5c5b9835299140", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d1657217ba0e147f", "level": "note", "message": {"text": "Unused endpoint: POST /trips/:id/itinerary/publish"}, "properties": {"repobilityId": "399c5b82ebf2e3ec", "scanner": "scanner-primary", "fingerprint": "d1657217ba0e147f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-88030549cf03f70a", "level": "note", "message": {"text": "Unused endpoint: GET /trips/:id/itinerary"}, "properties": {"repobilityId": "6bf44faf014c1d9f", "scanner": "scanner-primary", "fingerprint": "88030549cf03f70a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9a08554db01b581f", "level": "note", "message": {"text": "Unused endpoint: GET /trips/:id/itinerary/draft"}, "properties": {"repobilityId": "123fddbf63ab52e2", "scanner": "scanner-primary", "fingerprint": "9a08554db01b581f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b2fb03327ec7e635", "level": "note", "message": {"text": "Unused endpoint: GET /readiness"}, "properties": {"repobilityId": "1fa015bb3be1983d", "scanner": "scanner-primary", "fingerprint": "b2fb03327ec7e635", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ec71b190031541aa", "level": "note", "message": {"text": "Unused endpoint: POST /media/upload"}, "properties": {"repobilityId": "315b9258145f3357", "scanner": "scanner-primary", "fingerprint": "ec71b190031541aa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d799d831cf1bc643", "level": "note", "message": {"text": "Unused endpoint: POST /media/:id/finalize"}, "properties": {"repobilityId": "805fafdd066a3d14", "scanner": "scanner-primary", "fingerprint": "d799d831cf1bc643", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-faeec9069aebb500", "level": "note", "message": {"text": "Unused endpoint: GET /media/:id/url"}, "properties": {"repobilityId": "65abd651f0f4e7a2", "scanner": "scanner-primary", "fingerprint": "faeec9069aebb500", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3db32ec32e0b7ad4", "level": "note", "message": {"text": "Unused endpoint: GET /media/me/documents"}, "properties": {"repobilityId": "7a4513a700e4342e", "scanner": "scanner-primary", "fingerprint": "3db32ec32e0b7ad4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0fddb95595304584", "level": "note", "message": {"text": "Unused endpoint: DELETE /media/:id"}, "properties": {"repobilityId": "f84ecb2b307cbd74", "scanner": "scanner-primary", "fingerprint": "0fddb95595304584", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-281ba3b5898e57ef", "level": "note", "message": {"text": "Unused endpoint: GET /admin/tours/:id"}, "properties": {"repobilityId": "3be2cbb90c1bf802", "scanner": "scanner-primary", "fingerprint": "281ba3b5898e57ef", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-83e9d6484fd52b95", "level": "note", "message": {"text": "Unused endpoint: PATCH /admin/tours/:id"}, "properties": {"repobilityId": "77328a0221f50f65", "scanner": "scanner-primary", "fingerprint": "83e9d6484fd52b95", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f2f4f33eab1f2a13", "level": "note", "message": {"text": "Unused endpoint: POST /admin/tours/:id/publish"}, "properties": {"repobilityId": "fb47ce84bb41b89a", "scanner": "scanner-primary", "fingerprint": "f2f4f33eab1f2a13", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-766a074251c3ddc4", "level": "note", "message": {"text": "Unused endpoint: POST /admin/tours/:id/archive"}, "properties": {"repobilityId": "e46c62a2d29452a0", "scanner": "scanner-primary", "fingerprint": "766a074251c3ddc4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cc4a075cb62f6c4a", "level": "note", "message": {"text": "Unused endpoint: POST /admin/tours/:id/draft"}, "properties": {"repobilityId": "91f2ca59ac4c5476", "scanner": "scanner-primary", "fingerprint": "cc4a075cb62f6c4a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}