{"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-506be2b95088f5d3", "name": "git log failed \u2014 history analysis incomplete", "shortDescription": {"text": "git log failed \u2014 history analysis incomplete"}, "fullDescription": {"text": "fatal: not a git repository (or any parent up to mount point /data)\nStopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-9710c8d059e53154", "name": "No frontend routes/components detected", "shortDescription": {"text": "No frontend routes/components detected"}, "fullDescription": {"text": "No React/Vue/Next routes were found. This is fine for backend-only repos."}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "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-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "0 test file(s) for 1 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-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-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-67b2b937becfc1c9", "name": "FastAPI POST `add_holding` without auth dependency \u2014 server.py:140", "shortDescription": {"text": "FastAPI POST `add_holding` without auth dependency \u2014 server.py:140"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-8ad5ab6efdee30ff", "name": "FastAPI DELETE `remove_holding` without auth dependency \u2014 server.py:162", "shortDescription": {"text": "FastAPI DELETE `remove_holding` without auth dependency \u2014 server.py:162"}, "fullDescription": {"text": "`@router.delete` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-64e13c1c9db0e996", "name": "Unused endpoint: GET /api/market", "shortDescription": {"text": "Unused endpoint: GET /api/market"}, "fullDescription": {"text": "`server.py` declares `GET /api/market` 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-778f45a124dbd2e7", "name": "Unused endpoint: GET /api/news", "shortDescription": {"text": "Unused endpoint: GET /api/news"}, "fullDescription": {"text": "`server.py` declares `GET /api/news` 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-d018b74536d52921", "name": "Unused endpoint: GET /api/quotes", "shortDescription": {"text": "Unused endpoint: GET /api/quotes"}, "fullDescription": {"text": "`server.py` declares `GET /api/quotes` 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-c018e66cb359d5a7", "name": "Unused endpoint: GET /api/intraday/{ticker}", "shortDescription": {"text": "Unused endpoint: GET /api/intraday/{ticker}"}, "fullDescription": {"text": "`server.py` declares `GET /api/intraday/{ticker}` 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-9e1face0a0dde5e7", "name": "Unused endpoint: GET /api/stocks", "shortDescription": {"text": "Unused endpoint: GET /api/stocks"}, "fullDescription": {"text": "`server.py` declares `GET /api/stocks` 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-3ab0bcb48a865a5f", "name": "Unused endpoint: GET /api/stocks/{ticker}", "shortDescription": {"text": "Unused endpoint: GET /api/stocks/{ticker}"}, "fullDescription": {"text": "`server.py` declares `GET /api/stocks/{ticker}` 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-be7805c54200a988", "name": "Unused endpoint: GET /api/portfolio", "shortDescription": {"text": "Unused endpoint: GET /api/portfolio"}, "fullDescription": {"text": "`server.py` declares `GET /api/portfolio` 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-11bf6cc9fa04f524", "name": "Unused endpoint: POST /api/portfolio", "shortDescription": {"text": "Unused endpoint: POST /api/portfolio"}, "fullDescription": {"text": "`server.py` declares `POST /api/portfolio` 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-0a41123d73d73266", "name": "Unused endpoint: DELETE /api/portfolio/{holding_id}", "shortDescription": {"text": "Unused endpoint: DELETE /api/portfolio/{holding_id}"}, "fullDescription": {"text": "`server.py` declares `DELETE /api/portfolio/{holding_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-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`server.py` declares `GET /` 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/22079"}, "properties": {"repository": "VarunSridhar64/stocksage", "repoUrl": "https://github.com/VarunSridhar64/stocksage", "branch": "main"}, "results": [{"ruleId": "scanner-506be2b95088f5d3", "level": "none", "message": {"text": "git log failed \u2014 history analysis incomplete"}, "properties": {"repobilityId": "b424308a11bb9b22", "scanner": "scanner-primary", "fingerprint": "506be2b95088f5d3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["git", "tooling"]}}, {"ruleId": "scanner-9710c8d059e53154", "level": "none", "message": {"text": "No frontend routes/components detected"}, "properties": {"repobilityId": "44ca61485762e494", "scanner": "scanner-primary", "fingerprint": "9710c8d059e53154", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["coverage"]}}, {"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-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "4ba91113d8f090ec", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "7c57b6b366a8aca9", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-67b2b937becfc1c9", "level": "error", "message": {"text": "FastAPI POST `add_holding` without auth dependency \u2014 server.py:140"}, "properties": {"repobilityId": "022aadc247eb7387", "scanner": "scanner-primary", "fingerprint": "67b2b937becfc1c9", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server.py"}, "region": {"startLine": 140}}}]}, {"ruleId": "scanner-8ad5ab6efdee30ff", "level": "error", "message": {"text": "FastAPI DELETE `remove_holding` without auth dependency \u2014 server.py:162"}, "properties": {"repobilityId": "ffa5979d13d2e5cd", "scanner": "scanner-primary", "fingerprint": "8ad5ab6efdee30ff", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server.py"}, "region": {"startLine": 162}}}]}, {"ruleId": "scanner-64e13c1c9db0e996", "level": "note", "message": {"text": "Unused endpoint: GET /api/market"}, "properties": {"repobilityId": "4ed5d165dc79b05d", "scanner": "scanner-primary", "fingerprint": "64e13c1c9db0e996", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-778f45a124dbd2e7", "level": "note", "message": {"text": "Unused endpoint: GET /api/news"}, "properties": {"repobilityId": "e8b2b9c79acee4fa", "scanner": "scanner-primary", "fingerprint": "778f45a124dbd2e7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d018b74536d52921", "level": "note", "message": {"text": "Unused endpoint: GET /api/quotes"}, "properties": {"repobilityId": "72db33d0d8dbcda4", "scanner": "scanner-primary", "fingerprint": "d018b74536d52921", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c018e66cb359d5a7", "level": "note", "message": {"text": "Unused endpoint: GET /api/intraday/{ticker}"}, "properties": {"repobilityId": "13f6f92a9091071e", "scanner": "scanner-primary", "fingerprint": "c018e66cb359d5a7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9e1face0a0dde5e7", "level": "note", "message": {"text": "Unused endpoint: GET /api/stocks"}, "properties": {"repobilityId": "85dfbc91a23f4ba3", "scanner": "scanner-primary", "fingerprint": "9e1face0a0dde5e7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3ab0bcb48a865a5f", "level": "note", "message": {"text": "Unused endpoint: GET /api/stocks/{ticker}"}, "properties": {"repobilityId": "0e87d146523e82dc", "scanner": "scanner-primary", "fingerprint": "3ab0bcb48a865a5f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-be7805c54200a988", "level": "note", "message": {"text": "Unused endpoint: GET /api/portfolio"}, "properties": {"repobilityId": "0dd4ec6837cb24c1", "scanner": "scanner-primary", "fingerprint": "be7805c54200a988", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-11bf6cc9fa04f524", "level": "note", "message": {"text": "Unused endpoint: POST /api/portfolio"}, "properties": {"repobilityId": "53f70aa9781c2f64", "scanner": "scanner-primary", "fingerprint": "11bf6cc9fa04f524", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0a41123d73d73266", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/portfolio/{holding_id}"}, "properties": {"repobilityId": "8427c144ef5ad63d", "scanner": "scanner-primary", "fingerprint": "0a41123d73d73266", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "9e89b3880b9621fb", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}