{"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": "WEB003", "name": "Public web service has no security.txt", "shortDescription": {"text": "Public web service has no security.txt"}, "fullDescription": {"text": "security.txt gives researchers and customers a safe disclosure channel. Public web apps and APIs should publish it under /.well-known/security.txt."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "medium", "confidence": 0.78, "cwe": "", "owasp": ""}}, {"id": "WEB015", "name": "Public web app has no Content Security Policy", "shortDescription": {"text": "Public web app has no Content Security Policy"}, "fullDescription": {"text": "A Content Security Policy reduces the blast radius of injected scripts if the app is ever served through preview, static hosting, or a web container outside its normal sandbox."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "medium", "confidence": 0.7, "cwe": "", "owasp": ""}}, {"id": "DKR001", "name": "Docker final stage has no non-root USER", "shortDescription": {"text": "Docker final stage has no non-root USER"}, "fullDescription": {"text": "Docker images run as root unless the image or Dockerfile switches to a non-root user."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.82, "cwe": "", "owasp": ""}}, {"id": "DKR014", "name": "Dockerfile copies broad context with incomplete .dockerignore", "shortDescription": {"text": "Dockerfile copies broad context with incomplete .dockerignore"}, "fullDescription": {"text": "COPY . or ADD . is safer when .dockerignore excludes secrets, git history, keys, and generated artifacts."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.76, "cwe": "", "owasp": ""}}, {"id": "DEPCUR-NPM", "name": "npm package `dotenv` is 1 major version(s) behind (16.6.1 -> 17.4.2)", "shortDescription": {"text": "npm package `dotenv` is 1 major version(s) behind (16.6.1 -> 17.4.2)"}, "fullDescription": {"text": "`dotenv` is pinned/resolved at 16.6.1 but the latest stable release on the npm registry is 17.4.2 (1 major version(s) behind). Outdated dependencies accumulate unpatched bugs and make future security upgrades harder. This is the version-currency signal Dependabot version-update PRs raise."}, "properties": {"scanner": "repobility-dependency-currency", "category": "dependency", "severity": "medium", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "CORE_NO_CI", "name": "No CI/CD configuration found", "shortDescription": {"text": "No CI/CD configuration found"}, "fullDescription": {"text": "Add a CI/CD pipeline: create .github/workflows/ci.yml for GitHub Actions with steps to lint, test, and build on every push and pull request."}, "properties": {"scanner": "repobility-core", "category": "practices", "severity": "medium", "confidence": null, "cwe": "", "owasp": ""}}, {"id": "WEB011", "name": "Public web app has no humans.txt", "shortDescription": {"text": "Public web app has no humans.txt"}, "fullDescription": {"text": "humans.txt is optional, but it gives operators and reviewers a simple place to find ownership, contact, and important public documentation links."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "low", "confidence": 0.5, "cwe": "", "owasp": ""}}, {"id": "WEB008", "name": "Public docs site has no llms.txt", "shortDescription": {"text": "Public docs site has no llms.txt"}, "fullDescription": {"text": "AI coding agents increasingly read llms.txt to find canonical docs and API workflows. Without it, agents are more likely to browse pages repeatedly or use stale instructions."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "low", "confidence": 0.64, "cwe": "", "owasp": ""}}, {"id": "WEB002", "name": "Public web app has no sitemap", "shortDescription": {"text": "Public web app has no sitemap"}, "fullDescription": {"text": "A sitemap gives search engines, docs crawlers, and AI agents a structured list of public pages. Without one, important docs and product pages are easy to miss."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "low", "confidence": 0.72, "cwe": "", "owasp": ""}}, {"id": "WEB001", "name": "Public web app has no robots.txt", "shortDescription": {"text": "Public web app has no robots.txt"}, "fullDescription": {"text": "Public websites should publish a robots.txt file so crawlers and AI agents can discover crawl rules and sitemap locations without guessing."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "low", "confidence": 0.74, "cwe": "", "owasp": ""}}, {"id": "DKR008", "name": ".dockerignore misses sensitive defaults", "shortDescription": {"text": ".dockerignore misses sensitive defaults"}, "fullDescription": {"text": ".dockerignore exists but does not cover common secret or VCS patterns."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.72, "cwe": "", "owasp": ""}}, {"id": "CORE_NO_LICENSE", "name": "No LICENSE file", "shortDescription": {"text": "No LICENSE file"}, "fullDescription": {"text": "Add a LICENSE file to your repository. Use choosealicense.com to pick the right license (MIT for permissive, Apache 2.0 for patent protection, GPL for copyleft)."}, "properties": {"scanner": "repobility-core", "category": "documentation", "severity": "low", "confidence": null, "cwe": "", "owasp": ""}}, {"id": "MINED045", "name": "[MINED045] Ts Non Null Assertion: x! asserts not null - bypasses null checks - TypeError if wrong.", "shortDescription": {"text": "[MINED045] Ts Non Null Assertion: x! asserts not null - bypasses null checks - TypeError if wrong."}, "fullDescription": {"text": "Review and fix per the pattern semantics. See CWE-476 /  for context."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "info", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "MINED044", "name": "[MINED044] Js Console Log Prod: console.log left in code. Should be replaced with logger or removed.", "shortDescription": {"text": "[MINED044] Js Console Log Prod: console.log left in code. Should be replaced with logger or removed."}, "fullDescription": {"text": "Review and fix per the pattern semantics. See CWE-532 /  for context."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "info", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC118", "name": "[SEC118] UUIDv1 / UUIDv3 used for security-sensitive identifier: UUIDv1 encodes the MAC address and timestamp, making it", "shortDescription": {"text": "[SEC118] UUIDv1 / UUIDv3 used for security-sensitive identifier: UUIDv1 encodes the MAC address and timestamp, making it predictable. Used as a session token or password-reset key, it's enumerable."}, "fullDescription": {"text": "Use `uuid.uuid4()` (random) or `secrets.token_urlsafe()` for tokens. In Go, use `uuid.NewRandom()` (google/uuid)."}, "properties": {"scanner": "repobility-threat-engine", "category": "crypto", "severity": "info", "confidence": 0.1, "cwe": "", "owasp": ""}}, {"id": "SEC020", "name": "[SEC020] Secret Printed to Logs: Debug or diagnostic code appears to print a credential-bearing value. This is a frequen", "shortDescription": {"text": "[SEC020] Secret Printed to Logs: Debug or diagnostic code appears to print a credential-bearing value. This is a frequent AI-assisted coding failure: the helper exposes the exact value needed for troubleshooting."}, "fullDescription": {"text": "Log only redacted, hashed, or last-four-style metadata. Rotate any secret that may have reached logs."}, "properties": {"scanner": "repobility-threat-engine", "category": "credential_exposure", "severity": "info", "confidence": 0.1, "cwe": "", "owasp": ""}}, {"id": "SEC040", "name": "[SEC040] innerHTML XSS \u2014 template literal with server-supplied data: Setting .innerHTML with a template literal that int", "shortDescription": {"text": "[SEC040] innerHTML XSS \u2014 template literal with server-supplied data: Setting .innerHTML with a template literal that interpolates server-supplied or user-supplied data is the canonical stored/reflected XSS vector. The browser parses the HTM"}, "fullDescription": {"text": "For plain text: use el.textContent = data.value (auto-escapes).\nFor HTML you need to render: el.innerHTML = DOMPurify.sanitize(html).\nFor React/Vue/Svelte: stop using innerHTML; use the framework's binding.\nWhen data comes from CV/PDF parsers, sanitize at the parser boundary too."}, "properties": {"scanner": "repobility-threat-engine", "category": "xss", "severity": "high", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC135", "name": "[SEC135] Auth/permission check missing on AI-generated endpoint: Mutating HTTP endpoint generated by an AI agent without", "shortDescription": {"text": "[SEC135] Auth/permission check missing on AI-generated endpoint: Mutating HTTP endpoint generated by an AI agent without an auth decorator or middleware. The number-one production-incident pattern we see in AI-generated SaaS code: the AI bu"}, "fullDescription": {"text": "Add the project's auth decorator/middleware: `@login_required` (Django/Flask), `@permission_classes([IsAuthenticated])` (DRF), `Depends(get_current_user)` (FastAPI), `requireAuth` middleware (Express). For genuinely public endpoints, add a `# public-endpoint` marker comment so future scans skip them."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "high", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "MINED118", "name": "Dockerfile FROM `node:24-alpine` not pinned by digest", "shortDescription": {"text": "Dockerfile FROM `node:24-alpine` not pinned by digest"}, "fullDescription": {"text": "`FROM node:24-alpine` resolves the tag at build time. The registry CAN re-push a different image for the same tag, so every build is potentially different. Production images should pin to `image@sha256:...` for reproducibility + supply-chain integrity."}, "properties": {"scanner": "repobility-supply-chain", "category": "dependency", "severity": "high", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "MINED113", "name": "Express POST /api/v1/events/update has no auth", "shortDescription": {"text": "Express POST /api/v1/events/update has no auth"}, "fullDescription": {"text": "Express route POST /api/v1/events/update declared without an auth middleware in its handler chain. Destructive methods (POST/PUT/DELETE/PATCH) on unauthenticated routes are OWASP A01:2021 broken access control."}, "properties": {"scanner": "repobility-route-auth", "category": "quality", "severity": "high", "confidence": 0.8, "cwe": "", "owasp": ""}}, {"id": "scanner-b2311a4f38df2c50", "name": "Stray `console.log` in TS/JS \u2014 server/index.ts:320", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/index.ts:320"}, "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-d63da3583b14afc0", "name": "Dockerfile runs as root: Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3fad4f283eec7d6b", "name": "Docker base image is tag-pinned but not digest-pinned: node:24-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:24-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-c211d967b7cc0885", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/ui/dayView.ts:652", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/ui/dayView.ts:652"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6372cebde0220094", "name": "No auth library detected", "shortDescription": {"text": "No auth library detected"}, "fullDescription": {"text": "The scanner did not find any standard auth library (JWT, OAuth, NextAuth, Auth0, etc.). The repo has auth/admin/session surface indicators, so auth may live in custom code, in a separate service, or be missing."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4601e3ad3bb28677", "name": "No CI/CD pipelines detected", "shortDescription": {"text": "No CI/CD pipelines detected"}, "fullDescription": {"text": "No GitHub Actions, GitLab CI, or CircleCI configs found. Without CI you can't gate deploys on tests/lints."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-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-32273e4ef633bd65", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/caldav.ts:53", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/caldav.ts:53"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-296c7d37719a72e6", "name": "Commented-code block (5 lines) in server/webdav.ts:5", "shortDescription": {"text": "Commented-code block (5 lines) in server/webdav.ts:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8f3b7f399d2f3c79", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/webdav.ts:2", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/webdav.ts:2"}, "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-0bf4e38ce03e2b62", "name": "Commented-code block (5 lines) in src/main.ts:3", "shortDescription": {"text": "Commented-code block (5 lines) in src/main.ts:3"}, "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-bebd325ab433bcd0", "name": "Commented-code block (5 lines) in src/ui/dayView.ts:7", "shortDescription": {"text": "Commented-code block (5 lines) in src/ui/dayView.ts:7"}, "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-be8cfb40371cba05", "name": "Commented-code block (5 lines) in src/ui/dragDrop.ts:6", "shortDescription": {"text": "Commented-code block (5 lines) in src/ui/dragDrop.ts:6"}, "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-3012accbe92c641b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/api.ts:20", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/api.ts:20"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-225f40fe3354ced0", "name": "Commented-code block (5 lines) in src/services/tagSuggest.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/services/tagSuggest.ts:1"}, "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-bffe5cae8fd94163", "name": "Commented-code block (5 lines) in src/services/ics.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/services/ics.ts:1"}, "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-fc72006d13a8be20", "name": "Legacy-named symbol `doneOld` in src/services/selectors.test.ts:197", "shortDescription": {"text": "Legacy-named symbol `doneOld` in src/services/selectors.test.ts:197"}, "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-319e66a630e14977", "name": "2 env vars used in code but missing from .env.example", "shortDescription": {"text": "2 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `DODAY_EVENTS_CALENDAR`, `DODAY_TASKS_CALENDAR`. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8751c5f1cbfaf0c3", "name": "Dangling fetch: GET /api/v1/ping (server/auth.test.ts:51)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/ping (server/auth.test.ts:51)"}, "fullDescription": {"text": "`server/auth.test.ts:51` calls `GET /api/v1/ping` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/v1/ping`\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-bb1424b3c1ece8ba", "name": "Dangling fetch: GET / (server/auth.test.ts:56)", "shortDescription": {"text": "Dangling fetch: GET / (server/auth.test.ts:56)"}, "fullDescription": {"text": "`server/auth.test.ts:56` calls `GET /` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/`\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-ed02074754ca2950", "name": "Dangling fetch: GET /api/v1/ping (server/auth.test.ts:85)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/ping (server/auth.test.ts:85)"}, "fullDescription": {"text": "`server/auth.test.ts:85` calls `GET /api/v1/ping` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/v1/ping`\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-febdbe99505abeb2", "name": "Dangling fetch: GET /api/v1/${route} (src/services/api.ts:20)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/${route} (src/services/api.ts:20)"}, "fullDescription": {"text": "`src/services/api.ts:20` calls `GET /api/v1/${route}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/<p>`\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-cdf4a061ea3b16cd", "name": "Dangling fetch: PUT /api/v1/${route} (src/services/api.ts:32)", "shortDescription": {"text": "Dangling fetch: PUT /api/v1/${route} (src/services/api.ts:32)"}, "fullDescription": {"text": "`src/services/api.ts:32` calls `PUT /api/v1/${route}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/<p>`\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-e5bfb0d10c35048e", "name": "Dangling fetch: POST /api/v1/${route} (src/services/api.ts:66)", "shortDescription": {"text": "Dangling fetch: POST /api/v1/${route} (src/services/api.ts:66)"}, "fullDescription": {"text": "`src/services/api.ts:66` calls `POST /api/v1/${route}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/<p>`\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-5ca735a2e6e3646c", "name": "Unused endpoint: GET /logout", "shortDescription": {"text": "Unused endpoint: GET /logout"}, "fullDescription": {"text": "`server/auth.ts` declares `GET /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-a436691337284d03", "name": "Unused endpoint: GET /api/v1/health", "shortDescription": {"text": "Unused endpoint: GET /api/v1/health"}, "fullDescription": {"text": "`server/index.ts` declares `GET /api/v1/health` 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-70e492b047131cf3", "name": "Unused endpoint: POST /api/v1/tasks", "shortDescription": {"text": "Unused endpoint: POST /api/v1/tasks"}, "fullDescription": {"text": "`server/index.ts` declares `POST /api/v1/tasks` 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-2c3db5c8b0a13cfb", "name": "Unused endpoint: POST /api/v1/tasks/toggle", "shortDescription": {"text": "Unused endpoint: POST /api/v1/tasks/toggle"}, "fullDescription": {"text": "`server/index.ts` declares `POST /api/v1/tasks/toggle` 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-a7034a84827384d3", "name": "Unused endpoint: POST /api/v1/tasks/update", "shortDescription": {"text": "Unused endpoint: POST /api/v1/tasks/update"}, "fullDescription": {"text": "`server/index.ts` declares `POST /api/v1/tasks/update` 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-46c9e64fd4c96770", "name": "Unused endpoint: POST /api/v1/events", "shortDescription": {"text": "Unused endpoint: POST /api/v1/events"}, "fullDescription": {"text": "`server/index.ts` declares `POST /api/v1/events` 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-51f6a941fe9a09c9", "name": "Unused endpoint: POST /api/v1/events/update", "shortDescription": {"text": "Unused endpoint: POST /api/v1/events/update"}, "fullDescription": {"text": "`server/index.ts` declares `POST /api/v1/events/update` 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-3abf952b8d28d710", "name": "Unused endpoint: USE /*", "shortDescription": {"text": "Unused endpoint: USE /*"}, "fullDescription": {"text": "`server/index.ts` declares `USE /*` 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/23759"}, "properties": {"repository": "01msmr/doday", "repoUrl": "https://github.com/01msmr/doday", "branch": "main"}, "results": [{"ruleId": "WEB003", "level": "warning", "message": {"text": "Public web service has no security.txt"}, "properties": {"repobilityId": 223365, "scanner": "repobility-web-presence", "fingerprint": "5cd26606c5a53c9f403ff7a92a6917c19cf440a23ce03e2b90e8c493312ef8cd", "category": "quality", "severity": "medium", "confidence": 0.78, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Repository looks like a public web app/API but no security.txt file or route was discovered.", "evidence": {"rule_id": "WEB003", "scanner": "repobility-web-presence", "references": ["https://www.rfc-editor.org/rfc/rfc9116", "https://github.com/Lissy93/web-check"], "correlation_key": "fp|5cd26606c5a53c9f403ff7a92a6917c19cf440a23ce03e2b90e8c493312ef8cd"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".well-known/security.txt"}, "region": {"startLine": 1}}}]}, {"ruleId": "WEB015", "level": "warning", "message": {"text": "Public web app has no Content Security Policy"}, "properties": {"repobilityId": 223349, "scanner": "repobility-web-presence", "fingerprint": "7eb70cae3ff63d8ed7c31706185d32b37655333b40b58ca826d740b08fb1ad63", "category": "quality", "severity": "medium", "confidence": 0.7, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Repository looks like a public web app but no CSP header, framework header config, Helmet policy, or CSP meta tag was discovered.", "evidence": {"rule_id": "WEB015", "scanner": "repobility-web-presence", "references": ["https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP", "https://github.com/Lissy93/web-check"], "correlation_key": "fp|7eb70cae3ff63d8ed7c31706185d32b37655333b40b58ca826d740b08fb1ad63"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "index.html"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR001", "level": "warning", "message": {"text": "Docker final stage has no non-root USER"}, "properties": {"repobilityId": 223294, "scanner": "repobility-docker", "fingerprint": "b228f79b4485823052d80f718266efce3dac1331c8dd87bedbbb561ba08b541d", "category": "docker", "severity": "medium", "confidence": 0.82, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "No USER directive was found in the final runtime stage.", "evidence": {"rule_id": "DKR001", "scanner": "repobility-docker", "final_base": "node:24-alpine", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|b228f79b4485823052d80f718266efce3dac1331c8dd87bedbbb561ba08b541d"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 12}}}]}, {"ruleId": "DKR014", "level": "warning", "message": {"text": "Dockerfile copies broad context with incomplete .dockerignore"}, "properties": {"repobilityId": 223290, "scanner": "repobility-docker", "fingerprint": "a71ad409976d35dc3985ba1837a9ad2c58be63c9e794998f30d1085a648008f8", "category": "docker", "severity": "medium", "confidence": 0.76, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Broad context copy found and .dockerignore misses sensitive defaults.", "evidence": {"rule_id": "DKR014", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|a71ad409976d35dc3985ba1837a9ad2c58be63c9e794998f30d1085a648008f8", "missing_patterns": [".git", "id_rsa", "*.pem", "*.key"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 8}}}]}, {"ruleId": "DEPCUR-NPM", "level": "warning", "message": {"text": "npm package `dotenv` is 1 major version(s) behind (16.6.1 -> 17.4.2)"}, "properties": {"repobilityId": 223241, "scanner": "repobility-dependency-currency", "fingerprint": "ed32d98d590c66d304d1b3e95e2f20326dbd6cb582d6bd82fcf862bd26917cb6", "category": "dependency", "severity": "medium", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"gap": "1 major version(s) behind", "signal": "currency", "cwe_ids": [], "package": "dotenv", "scanner": "repobility-dependency-currency", "ecosystem": "npm", "languages": ["javascript"], "latest_version": "17.4.2", "correlation_key": "fp|ed32d98d590c66d304d1b3e95e2f20326dbd6cb582d6bd82fcf862bd26917cb6", "current_version": "16.6.1"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "DEPCUR-NPM", "level": "warning", "message": {"text": "npm package `@hono/node-server` is 1 major version(s) behind (1.19.14 -> 2.0.5)"}, "properties": {"repobilityId": 223239, "scanner": "repobility-dependency-currency", "fingerprint": "e91791edcac47026e46a4a1d9393580f892c2ba602070cc11410ff60ddd980bd", "category": "dependency", "severity": "medium", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"gap": "1 major version(s) behind", "signal": "currency", "cwe_ids": [], "package": "@hono/node-server", "scanner": "repobility-dependency-currency", "ecosystem": "npm", "languages": ["javascript"], "latest_version": "2.0.5", "correlation_key": "fp|e91791edcac47026e46a4a1d9393580f892c2ba602070cc11410ff60ddd980bd", "current_version": "1.19.14"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "DEPCUR-NPM", "level": "warning", "message": {"text": "npm package `@fortawesome/fontawesome-free` is 1 major version(s) behind (6.7.2 -> 7.2.0)"}, "properties": {"repobilityId": 223238, "scanner": "repobility-dependency-currency", "fingerprint": "a8c77387c4657ef557295fe4a604980dd38dc0e59acb23e473a4664b16c2a058", "category": "dependency", "severity": "medium", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"gap": "1 major version(s) behind", "signal": "currency", "cwe_ids": [], "package": "@fortawesome/fontawesome-free", "scanner": "repobility-dependency-currency", "ecosystem": "npm", "languages": ["javascript"], "latest_version": "7.2.0", "correlation_key": "fp|a8c77387c4657ef557295fe4a604980dd38dc0e59acb23e473a4664b16c2a058", "current_version": "6.7.2"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "CORE_NO_CI", "level": "warning", "message": {"text": "No CI/CD configuration found"}, "properties": {"repobilityId": 223202, "scanner": "repobility-core", "fingerprint": "ca5da3551af97272c4f099fc472740148135a15816b81b90bd862e8f91ec66ce", "category": "practices", "severity": "medium", "confidence": null, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"rule_id": "CORE_NO_CI", "scanner": "repobility-core", "correlation_key": "repo|practices|core_no_ci"}}}, {"ruleId": "WEB011", "level": "note", "message": {"text": "Public web app has no humans.txt"}, "properties": {"repobilityId": 223346, "scanner": "repobility-web-presence", "fingerprint": "bdd551fbe1ab6405480e0d5755632562c2096cb9e9a6a071ef60e4c27a6873f1", "category": "quality", "severity": "low", "confidence": 0.5, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Repository looks like a public web app but no humans.txt file or route was discovered.", "evidence": {"rule_id": "WEB011", "scanner": "repobility-web-presence", "references": ["https://github.com/Lissy93/web-check"], "correlation_key": "fp|bdd551fbe1ab6405480e0d5755632562c2096cb9e9a6a071ef60e4c27a6873f1"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "humans.txt"}, "region": {"startLine": 1}}}]}, {"ruleId": "WEB008", "level": "note", "message": {"text": "Public docs site has no llms.txt"}, "properties": {"repobilityId": 223338, "scanner": "repobility-web-presence", "fingerprint": "cdce8ed8706710d39c3e7272dad572dd639cff74fd3d2ac62d8f6f522b891d76", "category": "quality", "severity": "low", "confidence": 0.64, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Repository looks public and documentation-heavy but no llms.txt file or route was discovered.", "evidence": {"rule_id": "WEB008", "scanner": "repobility-web-presence", "references": ["https://llmstxt.org/"], "correlation_key": "fp|cdce8ed8706710d39c3e7272dad572dd639cff74fd3d2ac62d8f6f522b891d76"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "llms.txt"}, "region": {"startLine": 1}}}]}, {"ruleId": "WEB002", "level": "note", "message": {"text": "Public web app has no sitemap"}, "properties": {"repobilityId": 223335, "scanner": "repobility-web-presence", "fingerprint": "fccbe72d13ca3ba9197ec37b0daa0802fb6d5ebff54b3eb9f09b59b0f8d0acdf", "category": "quality", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Repository looks like a public web app but no sitemap file or route was discovered.", "evidence": {"rule_id": "WEB002", "scanner": "repobility-web-presence", "references": ["https://www.sitemaps.org/protocol.html", "https://github.com/Lissy93/web-check"], "correlation_key": "fp|fccbe72d13ca3ba9197ec37b0daa0802fb6d5ebff54b3eb9f09b59b0f8d0acdf"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "sitemap.xml"}, "region": {"startLine": 1}}}]}, {"ruleId": "WEB001", "level": "note", "message": {"text": "Public web app has no robots.txt"}, "properties": {"repobilityId": 223302, "scanner": "repobility-web-presence", "fingerprint": "cae3f2223945958e14d8eb90f7965fa26b47011cc5be29c2855a4054937e29c4", "category": "quality", "severity": "low", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Repository looks like a public web app but no robots.txt file or route was discovered.", "evidence": {"rule_id": "WEB001", "scanner": "repobility-web-presence", "references": ["https://www.rfc-editor.org/rfc/rfc9309", "https://github.com/Lissy93/web-check"], "correlation_key": "fp|cae3f2223945958e14d8eb90f7965fa26b47011cc5be29c2855a4054937e29c4"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "robots.txt"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR008", "level": "note", "message": {"text": ".dockerignore misses sensitive defaults"}, "properties": {"repobilityId": 223301, "scanner": "repobility-docker", "fingerprint": "aea2ad92c68c4ee1f8432bb1ec25e7d45ac12c9e1790ac2d3fffe638b1acce12", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "A Docker build context should exclude secrets and repository metadata.", "evidence": {"rule_id": "DKR008", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|aea2ad92c68c4ee1f8432bb1ec25e7d45ac12c9e1790ac2d3fffe638b1acce12", "missing_patterns": [".git", "id_rsa", "*.pem", "*.key"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".dockerignore"}, "region": {"startLine": 1}}}]}, {"ruleId": "CORE_NO_LICENSE", "level": "note", "message": {"text": "No LICENSE file"}, "properties": {"repobilityId": 223198, "scanner": "repobility-core", "fingerprint": "9314e9238cd99885865b92490d1aaa96ca62b1390c9377878d5f3d99227e1c3c", "category": "documentation", "severity": "low", "confidence": null, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"rule_id": "CORE_NO_LICENSE", "scanner": "repobility-core", "correlation_key": "repo|documentation|core_no_license"}}}, {"ruleId": "MINED045", "level": "none", "message": {"text": "[MINED045] Ts Non Null Assertion: x! asserts not null - bypasses null checks - TypeError if wrong."}, "properties": {"repobilityId": 223286, "scanner": "repobility-threat-engine", "fingerprint": "262c02d2f6a5f5d2ded9b43d2135960da906915aa226058076b6ef261f695392", "category": "quality", "severity": "info", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"mined": true, "mining": {"slug": "ts-non-null-assertion", "owasp": null, "cwe_ids": ["CWE-476"], "languages": ["typescript", "tsx"], "precision": 1.0, "promoted_at": "2026-05-18T14:01:32.348005+00:00", "triaged_in_corpus": 12, "observations_count": 1810954, "ai_coder_pattern_id": 105}, "scanner": "repobility-threat-engine", "correlation_key": "fp|262c02d2f6a5f5d2ded9b43d2135960da906915aa226058076b6ef261f695392"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ui/dragDrop.ts"}, "region": {"startLine": 57}}}]}, {"ruleId": "MINED044", "level": "none", "message": {"text": "[MINED044] Js Console Log Prod: console.log left in code. Should be replaced with logger or removed."}, "properties": {"repobilityId": 223264, "scanner": "repobility-threat-engine", "fingerprint": "2733dc57ce29fd31f7f33aea3b04262a23d2b32d37d986ccb5371bd023eaad98", "category": "quality", "severity": "info", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"mined": true, "mining": {"slug": "js-console-log-prod", "owasp": null, "cwe_ids": ["CWE-532"], "languages": ["javascript", "typescript", "tsx", "jsx"], "precision": 1.0, "promoted_at": "2026-05-18T14:01:32.348003+00:00", "triaged_in_corpus": 10, "observations_count": 1940833, "ai_coder_pattern_id": 102}, "scanner": "repobility-threat-engine", "correlation_key": "fp|2733dc57ce29fd31f7f33aea3b04262a23d2b32d37d986ccb5371bd023eaad98"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/index.ts"}, "region": {"startLine": 309}}}]}, {"ruleId": "SEC118", "level": "none", "message": {"text": "[SEC118] UUIDv1 / UUIDv3 used for security-sensitive identifier: UUIDv1 encodes the MAC address and timestamp, making it predictable. Used as a session token or password-reset key, it's enumerable."}, "properties": {"repobilityId": 223263, "scanner": "repobility-threat-engine", "fingerprint": "af4b3d09d85ab9d5e8ac5ae51fa0ac456112aef5673558534e0458a7f25707ba", "category": "crypto", "severity": "info", "confidence": 0.1, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Safe pattern 'randomUUID' detected on same line", "evidence": {"match": "crypto.randomUUID", "reason": "Safe pattern 'randomUUID' detected on same line", "rule_id": "SEC118", "scanner": "repobility-threat-engine", "confidence": 0.1, "correlation_key": "code|crypto|src/services/tagregistry.ts|60|sec118"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/services/tagRegistry.ts"}, "region": {"startLine": 60}}}]}, {"ruleId": "SEC118", "level": "none", "message": {"text": "[SEC118] UUIDv1 / UUIDv3 used for security-sensitive identifier: UUIDv1 encodes the MAC address and timestamp, making it predictable. Used as a session token or password-reset key, it's enumerable."}, "properties": {"repobilityId": 223259, "scanner": "repobility-threat-engine", "fingerprint": "11b7aa11297ce8fd9115b71430e5d24836e3f7392c1447f85f3370c0b9e647b7", "category": "crypto", "severity": "info", "confidence": 0.1, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Safe pattern 'randomUUID' detected on same line", "evidence": {"match": "crypto.randomUUID", "reason": "Safe pattern 'randomUUID' detected on same line", "rule_id": "SEC118", "scanner": "repobility-threat-engine", "confidence": 0.1, "correlation_key": "code|crypto|src/services/ics.ts|40|sec118"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/services/ics.ts"}, "region": {"startLine": 40}}}]}, {"ruleId": "SEC118", "level": "none", "message": {"text": "[SEC118] UUIDv1 / UUIDv3 used for security-sensitive identifier: UUIDv1 encodes the MAC address and timestamp, making it predictable. Used as a session token or password-reset key, it's enumerable."}, "properties": {"repobilityId": 223258, "scanner": "repobility-threat-engine", "fingerprint": "641c3853b979c3e4d6173982d298cc24f3a86b3022d47dccd0e070be92d87fbd", "category": "crypto", "severity": "info", "confidence": 0.1, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Safe pattern 'randomUUID' detected on same line", "evidence": {"match": "crypto.randomUUID", "reason": "Safe pattern 'randomUUID' detected on same line", "rule_id": "SEC118", "scanner": "repobility-threat-engine", "confidence": 0.1, "correlation_key": "code|crypto|server/index.ts|164|sec118"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/index.ts"}, "region": {"startLine": 164}}}]}, {"ruleId": "SEC020", "level": "none", "message": {"text": "[SEC020] Secret Printed to Logs: Debug or diagnostic code appears to print a credential-bearing value. This is a frequent AI-assisted coding failure: the helper exposes the exact value needed for troubleshooting."}, "properties": {"repobilityId": 223251, "scanner": "repobility-threat-engine", "fingerprint": "51224287d7131e5c0d1f6b4a017e2275582a04c2905d4f14d1f9ef47361514c8", "category": "credential_exposure", "severity": "info", "confidence": 0.1, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Safe context pattern detected", "evidence": {"match": "console.log(`Nextcloud: ${config.nextcloudUrl} (Daten in ${config.dataDir})", "reason": "Safe context pattern detected", "rule_id": "SEC020", "scanner": "repobility-threat-engine", "confidence": 0.1, "correlation_key": "secret|server/index.ts|32|console.log nextcloud: config.nextcloudurl daten in config.datadir"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/index.ts"}, "region": {"startLine": 321}}}]}, {"ruleId": "SEC040", "level": "error", "message": {"text": "[SEC040] innerHTML XSS \u2014 template literal with server-supplied data: Setting .innerHTML with a template literal that interpolates server-supplied or user-supplied data is the canonical stored/reflected XSS vector. The browser parses the HTML and executes any <script> or event-handler attributes in the data. CWE-79. Especially dangerous when the data comes from a CV parser, profile field, or any user-input pipeline."}, "properties": {"repobilityId": 223278, "scanner": "repobility-threat-engine", "fingerprint": "d9c623642e68e7fcacc521b8a628da9102cf2353cb50e15061791db64ac75d16", "category": "xss", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "map(\n      (day) =>\n        `<span class=\"week-dot${done.has(day) ? ' filled' : ''}${day === today ?", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC040", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|d9c623642e68e7fcacc521b8a628da9102cf2353cb50e15061791db64ac75d16"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ui/cockpitView.ts"}, "region": {"startLine": 131}}}]}, {"ruleId": "SEC040", "level": "error", "message": {"text": "[SEC040] innerHTML XSS \u2014 template literal with server-supplied data: Setting .innerHTML with a template literal that interpolates server-supplied or user-supplied data is the canonical stored/reflected XSS vector. The browser parses the HTML and executes any <script> or event-handler attributes in the data. CWE-79. Especially dangerous when the data comes from a CV parser, profile field, or any user-input pipeline."}, "properties": {"repobilityId": 223270, "scanner": "repobility-threat-engine", "fingerprint": "114d576dc66c7f662ec90e975e12f7c43228e44ce9d10636c87c2a2abb34ef6e", "category": "xss", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "map((tag) => `#${tag}", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC040", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|114d576dc66c7f662ec90e975e12f7c43228e44ce9d10636c87c2a2abb34ef6e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/services/tagService.ts"}, "region": {"startLine": 58}}}]}, {"ruleId": "SEC040", "level": "error", "message": {"text": "[SEC040] innerHTML XSS \u2014 template literal with server-supplied data: Setting .innerHTML with a template literal that interpolates server-supplied or user-supplied data is the canonical stored/reflected XSS vector. The browser parses the HTML and executes any <script> or event-handler attributes in the data. CWE-79. Especially dangerous when the data comes from a CV parser, profile field, or any user-input pipeline."}, "properties": {"repobilityId": 223265, "scanner": "repobility-threat-engine", "fingerprint": "e497b62a3f2164c4cec63f0f86c4245442d6d2a4771df266338b45293e52e342", "category": "xss", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "map((tag) => `#${tag}", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC040", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|e497b62a3f2164c4cec63f0f86c4245442d6d2a4771df266338b45293e52e342"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/services/dragMove.ts"}, "region": {"startLine": 39}}}]}, {"ruleId": "SEC135", "level": "error", "message": {"text": "[SEC135] Auth/permission check missing on AI-generated endpoint: Mutating HTTP endpoint generated by an AI agent without an auth decorator or middleware. The number-one production-incident pattern we see in AI-generated SaaS code: the AI builds the route, builds the handler, and forgets to wire the auth check that the rest of the codebase uses. CWE-862 (missing authorization). High-severity because the route is fully functional, just unprotected \u2014 attackers can call it directly."}, "properties": {"repobilityId": 223250, "scanner": "repobility-threat-engine", "fingerprint": "b0629d795d03385177c94e0108933f290b7848d34f4870e5500a39e8c887ea27", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "app.post('/api/v1/tasks', async (c) => {", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC135", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|b0629d795d03385177c94e0108933f290b7848d34f4870e5500a39e8c887ea27"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/index.ts"}, "region": {"startLine": 158}}}]}, {"ruleId": "SEC135", "level": "error", "message": {"text": "[SEC135] Auth/permission check missing on AI-generated endpoint: Mutating HTTP endpoint generated by an AI agent without an auth decorator or middleware. The number-one production-incident pattern we see in AI-generated SaaS code: the AI builds the route, builds the handler, and forgets to wire the auth check that the rest of the codebase uses. CWE-862 (missing authorization). High-severity because the route is fully functional, just unprotected \u2014 attackers can call it directly."}, "properties": {"repobilityId": 223243, "scanner": "repobility-threat-engine", "fingerprint": "0f9191cbec1ce812ea0f88f2d96cf1325c9dda5ff62c882b328db4f28163d6a7", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "app.post('/login', async (c) => {", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC135", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|0f9191cbec1ce812ea0f88f2d96cf1325c9dda5ff62c882b328db4f28163d6a7"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/auth.ts"}, "region": {"startLine": 105}}}]}, {"ruleId": "MINED118", "level": "error", "message": {"text": "Dockerfile FROM `node:24-alpine` not pinned by digest"}, "properties": {"repobilityId": 223235, "scanner": "repobility-supply-chain", "fingerprint": "41002ede0aa9747fd62ea176cb3c87fd1923d8135e5f67e377928fa6c3204efb", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "docker-from-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["dockerfile"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|41002ede0aa9747fd62ea176cb3c87fd1923d8135e5f67e377928fa6c3204efb"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 12}}}]}, {"ruleId": "MINED118", "level": "error", "message": {"text": "Dockerfile FROM `node:24-alpine` not pinned by digest"}, "properties": {"repobilityId": 223232, "scanner": "repobility-supply-chain", "fingerprint": "588703560a423f38f9a2e2b77e0272965373f33e61cd0ec4e221d963bd95626a", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "docker-from-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["dockerfile"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|588703560a423f38f9a2e2b77e0272965373f33e61cd0ec4e221d963bd95626a"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 4}}}]}, {"ruleId": "MINED113", "level": "error", "message": {"text": "Express POST /api/v1/events/update has no auth"}, "properties": {"repobilityId": 223227, "scanner": "repobility-route-auth", "fingerprint": "63d9cfe425d1a8973c4ef80616a5989c72abe69bcf9cb8d1c6c38bbadb457cee", "category": "quality", "severity": "high", "confidence": 0.8, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "express-destructive-unauth", "owasp": "A01:2021", "cwe_ids": ["CWE-306", "CWE-862"], "languages": ["python", "javascript"], "observations_count": 7836}, "scanner": "repobility-route-auth", "correlation_key": "fp|63d9cfe425d1a8973c4ef80616a5989c72abe69bcf9cb8d1c6c38bbadb457cee"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/index.ts"}, "region": {"startLine": 263}}}]}, {"ruleId": "MINED113", "level": "error", "message": {"text": "Express POST /api/v1/events has no auth"}, "properties": {"repobilityId": 223226, "scanner": "repobility-route-auth", "fingerprint": "d3404e3ccb0d6de733f704008021745b21a344272d5b0de0539f93187a917e48", "category": "quality", "severity": "high", "confidence": 0.8, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "express-destructive-unauth", "owasp": "A01:2021", "cwe_ids": ["CWE-306", "CWE-862"], "languages": ["python", "javascript"], "observations_count": 7836}, "scanner": "repobility-route-auth", "correlation_key": "fp|d3404e3ccb0d6de733f704008021745b21a344272d5b0de0539f93187a917e48"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/index.ts"}, "region": {"startLine": 229}}}]}, {"ruleId": "MINED113", "level": "error", "message": {"text": "Express POST /api/v1/tasks/update has no auth"}, "properties": {"repobilityId": 223223, "scanner": "repobility-route-auth", "fingerprint": "9ac31fb333cbf81ecdb26ee4a51bc8545f95495433ed0a24642e9d2c3aee3cf1", "category": "quality", "severity": "high", "confidence": 0.8, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "express-destructive-unauth", "owasp": "A01:2021", "cwe_ids": ["CWE-306", "CWE-862"], "languages": ["python", "javascript"], "observations_count": 7836}, "scanner": "repobility-route-auth", "correlation_key": "fp|9ac31fb333cbf81ecdb26ee4a51bc8545f95495433ed0a24642e9d2c3aee3cf1"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/index.ts"}, "region": {"startLine": 194}}}]}, {"ruleId": "MINED113", "level": "error", "message": {"text": "Express POST /api/v1/tasks/toggle has no auth"}, "properties": {"repobilityId": 223220, "scanner": "repobility-route-auth", "fingerprint": "1573e08cc7f5707962aa7e9f74ff7dd520f27195341845e6d9974a94acc039e9", "category": "quality", "severity": "high", "confidence": 0.8, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "express-destructive-unauth", "owasp": "A01:2021", "cwe_ids": ["CWE-306", "CWE-862"], "languages": ["python", "javascript"], "observations_count": 7836}, "scanner": "repobility-route-auth", "correlation_key": "fp|1573e08cc7f5707962aa7e9f74ff7dd520f27195341845e6d9974a94acc039e9"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/index.ts"}, "region": {"startLine": 175}}}]}, {"ruleId": "MINED113", "level": "error", "message": {"text": "Express POST /api/v1/tasks has no auth"}, "properties": {"repobilityId": 223219, "scanner": "repobility-route-auth", "fingerprint": "0a247a0c94b9f4f51f88c4f16d7872c480c0d35ab326e9ba229cc36b64994c44", "category": "quality", "severity": "high", "confidence": 0.8, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "express-destructive-unauth", "owasp": "A01:2021", "cwe_ids": ["CWE-306", "CWE-862"], "languages": ["python", "javascript"], "observations_count": 7836}, "scanner": "repobility-route-auth", "correlation_key": "fp|0a247a0c94b9f4f51f88c4f16d7872c480c0d35ab326e9ba229cc36b64994c44"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/index.ts"}, "region": {"startLine": 158}}}]}, {"ruleId": "MINED113", "level": "error", "message": {"text": "Express POST /login has no auth"}, "properties": {"repobilityId": 223208, "scanner": "repobility-route-auth", "fingerprint": "f5f905b4a2da3aad3723eeca596ad71d7f5e1b1415d68f3a10feec481de926ca", "category": "quality", "severity": "high", "confidence": 0.8, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "express-destructive-unauth", "owasp": "A01:2021", "cwe_ids": ["CWE-306", "CWE-862"], "languages": ["python", "javascript"], "observations_count": 7836}, "scanner": "repobility-route-auth", "correlation_key": "fp|f5f905b4a2da3aad3723eeca596ad71d7f5e1b1415d68f3a10feec481de926ca"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/auth.ts"}, "region": {"startLine": 105}}}]}, {"ruleId": "scanner-b2311a4f38df2c50", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/index.ts:320"}, "properties": {"repobilityId": "b4961a877930fd2f", "scanner": "scanner-primary", "fingerprint": "b2311a4f38df2c50", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d63da3583b14afc0", "level": "warning", "message": {"text": "Dockerfile runs as root: Dockerfile"}, "properties": {"repobilityId": "a2ed1bd120e507db", "scanner": "scanner-primary", "fingerprint": "d63da3583b14afc0", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-3fad4f283eec7d6b", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:24-alpine"}, "properties": {"repobilityId": "9d1578a3f263acb0", "scanner": "scanner-primary", "fingerprint": "3fad4f283eec7d6b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 4}}}]}, {"ruleId": "scanner-3fad4f283eec7d6b", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:24-alpine"}, "properties": {"repobilityId": "a90928d8b5c90714", "scanner": "scanner-primary", "fingerprint": "3fad4f283eec7d6b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 12}}}]}, {"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-c211d967b7cc0885", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/ui/dayView.ts:652"}, "properties": {"repobilityId": "81ffecbb9d5fd947", "scanner": "scanner-primary", "fingerprint": "c211d967b7cc0885", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ui/dayView.ts"}, "region": {"startLine": 652}}}]}, {"ruleId": "scanner-6372cebde0220094", "level": "warning", "message": {"text": "No auth library detected"}, "properties": {"repobilityId": "a5b6035a5bbf8054", "scanner": "scanner-primary", "fingerprint": "6372cebde0220094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["coverage", "auth"]}}, {"ruleId": "scanner-4601e3ad3bb28677", "level": "warning", "message": {"text": "No CI/CD pipelines detected"}, "properties": {"repobilityId": "c3ee439bce2bc51e", "scanner": "scanner-primary", "fingerprint": "4601e3ad3bb28677", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "bb1543309de49e6f", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "a17c3a7b974e283f", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "29a36dced5a8ec48", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "b676082db066ca09", "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": "1082ee46dc7aba6c", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-32273e4ef633bd65", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/caldav.ts:53"}, "properties": {"repobilityId": "848007f9bab5b6a0", "scanner": "scanner-primary", "fingerprint": "32273e4ef633bd65", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-296c7d37719a72e6", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/webdav.ts:5"}, "properties": {"repobilityId": "338ead083735f176", "scanner": "scanner-primary", "fingerprint": "296c7d37719a72e6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8f3b7f399d2f3c79", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/webdav.ts:2"}, "properties": {"repobilityId": "b4c08adaae0b5ea2", "scanner": "scanner-primary", "fingerprint": "8f3b7f399d2f3c79", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0bf4e38ce03e2b62", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/main.ts:3"}, "properties": {"repobilityId": "dfecc74a4fd05178", "scanner": "scanner-primary", "fingerprint": "0bf4e38ce03e2b62", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bebd325ab433bcd0", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/ui/dayView.ts:7"}, "properties": {"repobilityId": "d777fd2817002cda", "scanner": "scanner-primary", "fingerprint": "bebd325ab433bcd0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-be8cfb40371cba05", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/ui/dragDrop.ts:6"}, "properties": {"repobilityId": "34f3366ae3461a69", "scanner": "scanner-primary", "fingerprint": "be8cfb40371cba05", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3012accbe92c641b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/api.ts:20"}, "properties": {"repobilityId": "a52ff4d4550cf93e", "scanner": "scanner-primary", "fingerprint": "3012accbe92c641b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-225f40fe3354ced0", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/services/tagSuggest.ts:1"}, "properties": {"repobilityId": "cad25fa77f1caab0", "scanner": "scanner-primary", "fingerprint": "225f40fe3354ced0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bffe5cae8fd94163", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/services/ics.ts:1"}, "properties": {"repobilityId": "fcc958fd7a943b77", "scanner": "scanner-primary", "fingerprint": "bffe5cae8fd94163", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-fc72006d13a8be20", "level": "note", "message": {"text": "Legacy-named symbol `doneOld` in src/services/selectors.test.ts:197"}, "properties": {"repobilityId": "753e2007839c2216", "scanner": "scanner-primary", "fingerprint": "fc72006d13a8be20", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-319e66a630e14977", "level": "none", "message": {"text": "2 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "d838d1fc5d8231c9", "scanner": "scanner-primary", "fingerprint": "319e66a630e14977", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-8751c5f1cbfaf0c3", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/ping (server/auth.test.ts:51)"}, "properties": {"repobilityId": "a8169a028eb7020f", "scanner": "scanner-primary", "fingerprint": "8751c5f1cbfaf0c3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-bb1424b3c1ece8ba", "level": "error", "message": {"text": "Dangling fetch: GET / (server/auth.test.ts:56)"}, "properties": {"repobilityId": "e849520a7211f97c", "scanner": "scanner-primary", "fingerprint": "bb1424b3c1ece8ba", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-ed02074754ca2950", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/ping (server/auth.test.ts:85)"}, "properties": {"repobilityId": "7223c46686632b1b", "scanner": "scanner-primary", "fingerprint": "ed02074754ca2950", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-febdbe99505abeb2", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/${route} (src/services/api.ts:20)"}, "properties": {"repobilityId": "80277188a65c8a42", "scanner": "scanner-primary", "fingerprint": "febdbe99505abeb2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-cdf4a061ea3b16cd", "level": "error", "message": {"text": "Dangling fetch: PUT /api/v1/${route} (src/services/api.ts:32)"}, "properties": {"repobilityId": "98df140ee02b5da3", "scanner": "scanner-primary", "fingerprint": "cdf4a061ea3b16cd", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e5bfb0d10c35048e", "level": "error", "message": {"text": "Dangling fetch: POST /api/v1/${route} (src/services/api.ts:66)"}, "properties": {"repobilityId": "12e592ab4e2197c7", "scanner": "scanner-primary", "fingerprint": "e5bfb0d10c35048e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5ca735a2e6e3646c", "level": "note", "message": {"text": "Unused endpoint: GET /logout"}, "properties": {"repobilityId": "56402de38093cd4b", "scanner": "scanner-primary", "fingerprint": "5ca735a2e6e3646c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a436691337284d03", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/health"}, "properties": {"repobilityId": "69fcc8c90dbd25b4", "scanner": "scanner-primary", "fingerprint": "a436691337284d03", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-70e492b047131cf3", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/tasks"}, "properties": {"repobilityId": "3a199492b4672942", "scanner": "scanner-primary", "fingerprint": "70e492b047131cf3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2c3db5c8b0a13cfb", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/tasks/toggle"}, "properties": {"repobilityId": "23ad4626d97e3f26", "scanner": "scanner-primary", "fingerprint": "2c3db5c8b0a13cfb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a7034a84827384d3", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/tasks/update"}, "properties": {"repobilityId": "41b5837d906e0e60", "scanner": "scanner-primary", "fingerprint": "a7034a84827384d3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-46c9e64fd4c96770", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/events"}, "properties": {"repobilityId": "943141bf15bb0af4", "scanner": "scanner-primary", "fingerprint": "46c9e64fd4c96770", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-51f6a941fe9a09c9", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/events/update"}, "properties": {"repobilityId": "7aaf92273e168954", "scanner": "scanner-primary", "fingerprint": "51f6a941fe9a09c9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3abf952b8d28d710", "level": "note", "message": {"text": "Unused endpoint: USE /*"}, "properties": {"repobilityId": "0f369f6b8a80d0a2", "scanner": "scanner-primary", "fingerprint": "3abf952b8d28d710", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}