{"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-a6556ac91ea7684c", "name": "Possibly dead Python function: tunnel_loop", "shortDescription": {"text": "Possibly dead Python function: tunnel_loop"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3d94167d4fce30fa", "name": "Possibly dead Python function: read_output", "shortDescription": {"text": "Possibly dead Python function: read_output"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8e9b3673940c1ae4", "name": "Possibly dead Python function: watchdog", "shortDescription": {"text": "Possibly dead Python function: watchdog"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-166dff3c3df6a10e", "name": "ORM models found but no DB engine detected", "shortDescription": {"text": "ORM models found but no DB engine detected"}, "fullDescription": {"text": "The repo defines tables/models but no DB connection string was found. Likely lives in env vars or a config file the scanner didn't read."}, "properties": {"scanner": "scanner-primary", "layer": "data", "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-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "0 test file(s) for 5 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-faccb9061e9b52a0", "name": "No README detected", "shortDescription": {"text": "No README detected"}, "fullDescription": {"text": "No README file was found. Generated repos without README context are hard to operate, validate, or safely hand off."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci, tests, operator-readme. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "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 license, ci, tests, operator-readme. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2c04133e54348533", "name": "Near-duplicate function bodies in 2 places", "shortDescription": {"text": "Near-duplicate function bodies in 2 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\napp.py:kunden_detail, app.py:kunden_edit\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-46c56f3dd8a94494", "name": "Flask mutation route `login` without `@login_required` \u2014 app.py:143", "shortDescription": {"text": "Flask mutation route `login` without `@login_required` \u2014 app.py:143"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-e40d92d119feb422", "name": "Flask mutation route `logout` without `@login_required` \u2014 app.py:157", "shortDescription": {"text": "Flask mutation route `logout` without `@login_required` \u2014 app.py:157"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-015000a33c1b0702", "name": "Flask mutation route `kunden_neu` without `@login_required` \u2014 app.py:231", "shortDescription": {"text": "Flask mutation route `kunden_neu` without `@login_required` \u2014 app.py:231"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-1a9b153b5f162dd2", "name": "Flask mutation route `kunden_edit` without `@login_required` \u2014 app.py:260", "shortDescription": {"text": "Flask mutation route `kunden_edit` without `@login_required` \u2014 app.py:260"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-b3a04b99d7270976", "name": "Flask mutation route `kunden_delete` without `@login_required` \u2014 app.py:280", "shortDescription": {"text": "Flask mutation route `kunden_delete` without `@login_required` \u2014 app.py:280"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-ce5f54971a97d470", "name": "Flask mutation route `produkte_neu` without `@login_required` \u2014 app.py:299", "shortDescription": {"text": "Flask mutation route `produkte_neu` without `@login_required` \u2014 app.py:299"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-d330253bdec2e898", "name": "Flask mutation route `produkte_edit` without `@login_required` \u2014 app.py:315", "shortDescription": {"text": "Flask mutation route `produkte_edit` without `@login_required` \u2014 app.py:315"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-d1b926730aec3a8e", "name": "Flask mutation route `produkte_delete` without `@login_required` \u2014 app.py:337", "shortDescription": {"text": "Flask mutation route `produkte_delete` without `@login_required` \u2014 app.py:337"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-99674556f233d851", "name": "Flask mutation route `auftraege_neu` without `@login_required` \u2014 app.py:370", "shortDescription": {"text": "Flask mutation route `auftraege_neu` without `@login_required` \u2014 app.py:370"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-b1ae524aeb3196e9", "name": "Flask mutation route `auftraege_edit` without `@login_required` \u2014 app.py:416", "shortDescription": {"text": "Flask mutation route `auftraege_edit` without `@login_required` \u2014 app.py:416"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-5f89aec5bee46094", "name": "Flask mutation route `auftraege_status` without `@login_required` \u2014 app.py:451", "shortDescription": {"text": "Flask mutation route `auftraege_status` without `@login_required` \u2014 app.py:451"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-372e571637046bc0", "name": "Flask mutation route `auftraege_delete` without `@login_required` \u2014 app.py:462", "shortDescription": {"text": "Flask mutation route `auftraege_delete` without `@login_required` \u2014 app.py:462"}, "fullDescription": {"text": "Flask route declares POST/PUT/DELETE/PATCH methods without an auth decorator. Add `@login_required` (Flask-Login) or equivalent."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-4c7ad61ba1b23915", "name": "Unused endpoint: ANY /login", "shortDescription": {"text": "Unused endpoint: ANY /login"}, "fullDescription": {"text": "`app.py` declares `ANY /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-c9e449c3b9e73b73", "name": "Unused endpoint: ANY /logout", "shortDescription": {"text": "Unused endpoint: ANY /logout"}, "fullDescription": {"text": "`app.py` declares `ANY /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-1a6d91f2236825bf", "name": "Unused endpoint: ANY /", "shortDescription": {"text": "Unused endpoint: ANY /"}, "fullDescription": {"text": "`app.py` declares `ANY /` 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-7151a183712ea76b", "name": "Unused endpoint: ANY /kunden", "shortDescription": {"text": "Unused endpoint: ANY /kunden"}, "fullDescription": {"text": "`app.py` declares `ANY /kunden` 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-470b9d05249277b4", "name": "Unused endpoint: ANY /kunden/neu", "shortDescription": {"text": "Unused endpoint: ANY /kunden/neu"}, "fullDescription": {"text": "`app.py` declares `ANY /kunden/neu` 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-908c10ec344f9020", "name": "Unused endpoint: ANY /kunden/<int:id>", "shortDescription": {"text": "Unused endpoint: ANY /kunden/<int:id>"}, "fullDescription": {"text": "`app.py` declares `ANY /kunden/<int: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-4514b5a94ceb217d", "name": "Unused endpoint: ANY /kunden/<int:id>/bearbeiten", "shortDescription": {"text": "Unused endpoint: ANY /kunden/<int:id>/bearbeiten"}, "fullDescription": {"text": "`app.py` declares `ANY /kunden/<int:id>/bearbeiten` 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-7b996fd5213adc46", "name": "Unused endpoint: ANY /kunden/<int:id>/loeschen", "shortDescription": {"text": "Unused endpoint: ANY /kunden/<int:id>/loeschen"}, "fullDescription": {"text": "`app.py` declares `ANY /kunden/<int:id>/loeschen` 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-e1e430a039672c6b", "name": "Unused endpoint: ANY /produkte", "shortDescription": {"text": "Unused endpoint: ANY /produkte"}, "fullDescription": {"text": "`app.py` declares `ANY /produkte` 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-8f41e62e0c81a4d3", "name": "Unused endpoint: ANY /produkte/neu", "shortDescription": {"text": "Unused endpoint: ANY /produkte/neu"}, "fullDescription": {"text": "`app.py` declares `ANY /produkte/neu` 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-f38d762a8d6c300b", "name": "Unused endpoint: ANY /produkte/<int:id>/bearbeiten", "shortDescription": {"text": "Unused endpoint: ANY /produkte/<int:id>/bearbeiten"}, "fullDescription": {"text": "`app.py` declares `ANY /produkte/<int:id>/bearbeiten` 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-eec10dd684678608", "name": "Unused endpoint: ANY /produkte/<int:id>/loeschen", "shortDescription": {"text": "Unused endpoint: ANY /produkte/<int:id>/loeschen"}, "fullDescription": {"text": "`app.py` declares `ANY /produkte/<int:id>/loeschen` 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-b78089a668dcde44", "name": "Unused endpoint: ANY /auftraege", "shortDescription": {"text": "Unused endpoint: ANY /auftraege"}, "fullDescription": {"text": "`app.py` declares `ANY /auftraege` 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-6cf92aa7b148f981", "name": "Unused endpoint: ANY /auftraege/neu", "shortDescription": {"text": "Unused endpoint: ANY /auftraege/neu"}, "fullDescription": {"text": "`app.py` declares `ANY /auftraege/neu` 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-7a4d6d49aa0c9a3a", "name": "Unused endpoint: ANY /auftraege/<int:id>", "shortDescription": {"text": "Unused endpoint: ANY /auftraege/<int:id>"}, "fullDescription": {"text": "`app.py` declares `ANY /auftraege/<int: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-99f2fd00981e53db", "name": "Unused endpoint: ANY /auftraege/<int:id>/bearbeiten", "shortDescription": {"text": "Unused endpoint: ANY /auftraege/<int:id>/bearbeiten"}, "fullDescription": {"text": "`app.py` declares `ANY /auftraege/<int:id>/bearbeiten` 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-f2b3ce6e04199ccc", "name": "Unused endpoint: ANY /auftraege/<int:id>/status", "shortDescription": {"text": "Unused endpoint: ANY /auftraege/<int:id>/status"}, "fullDescription": {"text": "`app.py` declares `ANY /auftraege/<int: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-f8a3a36dbe144aaf", "name": "Unused endpoint: ANY /auftraege/<int:id>/loeschen", "shortDescription": {"text": "Unused endpoint: ANY /auftraege/<int:id>/loeschen"}, "fullDescription": {"text": "`app.py` declares `ANY /auftraege/<int:id>/loeschen` 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/24208"}, "properties": {"repository": "AngeloVRD/studforge-app", "repoUrl": "https://github.com/AngeloVRD/studforge-app", "branch": "main"}, "results": [{"ruleId": "scanner-a6556ac91ea7684c", "level": "note", "message": {"text": "Possibly dead Python function: tunnel_loop"}, "properties": {"repobilityId": "1a35e545fb800186", "scanner": "scanner-primary", "fingerprint": "a6556ac91ea7684c", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server.py:143"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3d94167d4fce30fa", "level": "note", "message": {"text": "Possibly dead Python function: read_output"}, "properties": {"repobilityId": "dc41f6ee67338b82", "scanner": "scanner-primary", "fingerprint": "3d94167d4fce30fa", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server.py:168"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-8e9b3673940c1ae4", "level": "note", "message": {"text": "Possibly dead Python function: watchdog"}, "properties": {"repobilityId": "9551af4d260536d8", "scanner": "scanner-primary", "fingerprint": "8e9b3673940c1ae4", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "main.py:184"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-166dff3c3df6a10e", "level": "warning", "message": {"text": "ORM models found but no DB engine detected"}, "properties": {"repobilityId": "cda36de65e114635", "scanner": "scanner-primary", "fingerprint": "166dff3c3df6a10e", "layer": "data", "severity": "medium", "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-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": "914a12bd1861072c", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-faccb9061e9b52a0", "level": "note", "message": {"text": "No README detected"}, "properties": {"repobilityId": "e2df0ec8252d609c", "scanner": "scanner-primary", "fingerprint": "faccb9061e9b52a0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["docs", "readme", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "d829d0036dc82ddb", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "20ddd0e7e0bb2e65", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "2c7b3599aa0ae5a7", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-46c56f3dd8a94494", "level": "error", "message": {"text": "Flask mutation route `login` without `@login_required` \u2014 app.py:143"}, "properties": {"repobilityId": "262d76b3ce891aff", "scanner": "scanner-primary", "fingerprint": "46c56f3dd8a94494", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app.py"}, "region": {"startLine": 143}}}]}, {"ruleId": "scanner-e40d92d119feb422", "level": "error", "message": {"text": "Flask mutation route `logout` without `@login_required` \u2014 app.py:157"}, "properties": {"repobilityId": "de5a46f682eb6bfc", "scanner": "scanner-primary", "fingerprint": "e40d92d119feb422", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app.py"}, "region": {"startLine": 157}}}]}, {"ruleId": "scanner-015000a33c1b0702", "level": "error", "message": {"text": "Flask mutation route `kunden_neu` without `@login_required` \u2014 app.py:231"}, "properties": {"repobilityId": "6799bca614f5cf89", "scanner": "scanner-primary", "fingerprint": "015000a33c1b0702", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app.py"}, "region": {"startLine": 231}}}]}, {"ruleId": "scanner-1a9b153b5f162dd2", "level": "error", "message": {"text": "Flask mutation route `kunden_edit` without `@login_required` \u2014 app.py:260"}, "properties": {"repobilityId": "837c4cbf1d6dbcdc", "scanner": "scanner-primary", "fingerprint": "1a9b153b5f162dd2", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app.py"}, "region": {"startLine": 260}}}]}, {"ruleId": "scanner-b3a04b99d7270976", "level": "error", "message": {"text": "Flask mutation route `kunden_delete` without `@login_required` \u2014 app.py:280"}, "properties": {"repobilityId": "4b068575f89da1e0", "scanner": "scanner-primary", "fingerprint": "b3a04b99d7270976", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app.py"}, "region": {"startLine": 280}}}]}, {"ruleId": "scanner-ce5f54971a97d470", "level": "error", "message": {"text": "Flask mutation route `produkte_neu` without `@login_required` \u2014 app.py:299"}, "properties": {"repobilityId": "0ce3f04954d89f53", "scanner": "scanner-primary", "fingerprint": "ce5f54971a97d470", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app.py"}, "region": {"startLine": 299}}}]}, {"ruleId": "scanner-d330253bdec2e898", "level": "error", "message": {"text": "Flask mutation route `produkte_edit` without `@login_required` \u2014 app.py:315"}, "properties": {"repobilityId": "244d16e1fb1a6052", "scanner": "scanner-primary", "fingerprint": "d330253bdec2e898", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app.py"}, "region": {"startLine": 315}}}]}, {"ruleId": "scanner-d1b926730aec3a8e", "level": "error", "message": {"text": "Flask mutation route `produkte_delete` without `@login_required` \u2014 app.py:337"}, "properties": {"repobilityId": "4645d9d6801ff16d", "scanner": "scanner-primary", "fingerprint": "d1b926730aec3a8e", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app.py"}, "region": {"startLine": 337}}}]}, {"ruleId": "scanner-99674556f233d851", "level": "error", "message": {"text": "Flask mutation route `auftraege_neu` without `@login_required` \u2014 app.py:370"}, "properties": {"repobilityId": "37fdd6da920f9998", "scanner": "scanner-primary", "fingerprint": "99674556f233d851", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app.py"}, "region": {"startLine": 370}}}]}, {"ruleId": "scanner-b1ae524aeb3196e9", "level": "error", "message": {"text": "Flask mutation route `auftraege_edit` without `@login_required` \u2014 app.py:416"}, "properties": {"repobilityId": "1096fbe5564aaffe", "scanner": "scanner-primary", "fingerprint": "b1ae524aeb3196e9", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app.py"}, "region": {"startLine": 416}}}]}, {"ruleId": "scanner-5f89aec5bee46094", "level": "error", "message": {"text": "Flask mutation route `auftraege_status` without `@login_required` \u2014 app.py:451"}, "properties": {"repobilityId": "ffa5c3eecbe5d186", "scanner": "scanner-primary", "fingerprint": "5f89aec5bee46094", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app.py"}, "region": {"startLine": 451}}}]}, {"ruleId": "scanner-372e571637046bc0", "level": "error", "message": {"text": "Flask mutation route `auftraege_delete` without `@login_required` \u2014 app.py:462"}, "properties": {"repobilityId": "a4934fb9c02609c7", "scanner": "scanner-primary", "fingerprint": "372e571637046bc0", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.flask.unauth_route"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app.py"}, "region": {"startLine": 462}}}]}, {"ruleId": "scanner-4c7ad61ba1b23915", "level": "note", "message": {"text": "Unused endpoint: ANY /login"}, "properties": {"repobilityId": "2d2d4aa670f43283", "scanner": "scanner-primary", "fingerprint": "4c7ad61ba1b23915", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c9e449c3b9e73b73", "level": "note", "message": {"text": "Unused endpoint: ANY /logout"}, "properties": {"repobilityId": "1d0f5ae7dd7dbf56", "scanner": "scanner-primary", "fingerprint": "c9e449c3b9e73b73", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1a6d91f2236825bf", "level": "note", "message": {"text": "Unused endpoint: ANY /"}, "properties": {"repobilityId": "302fe621a396c5fd", "scanner": "scanner-primary", "fingerprint": "1a6d91f2236825bf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7151a183712ea76b", "level": "note", "message": {"text": "Unused endpoint: ANY /kunden"}, "properties": {"repobilityId": "ab4ad38ed5e9c944", "scanner": "scanner-primary", "fingerprint": "7151a183712ea76b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-470b9d05249277b4", "level": "note", "message": {"text": "Unused endpoint: ANY /kunden/neu"}, "properties": {"repobilityId": "11cee5b613a607c9", "scanner": "scanner-primary", "fingerprint": "470b9d05249277b4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-908c10ec344f9020", "level": "note", "message": {"text": "Unused endpoint: ANY /kunden/<int:id>"}, "properties": {"repobilityId": "88080508c0de627c", "scanner": "scanner-primary", "fingerprint": "908c10ec344f9020", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4514b5a94ceb217d", "level": "note", "message": {"text": "Unused endpoint: ANY /kunden/<int:id>/bearbeiten"}, "properties": {"repobilityId": "540fbffa229b3356", "scanner": "scanner-primary", "fingerprint": "4514b5a94ceb217d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7b996fd5213adc46", "level": "note", "message": {"text": "Unused endpoint: ANY /kunden/<int:id>/loeschen"}, "properties": {"repobilityId": "282a0f9c1efc86e1", "scanner": "scanner-primary", "fingerprint": "7b996fd5213adc46", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e1e430a039672c6b", "level": "note", "message": {"text": "Unused endpoint: ANY /produkte"}, "properties": {"repobilityId": "0bb98b9e936aff1c", "scanner": "scanner-primary", "fingerprint": "e1e430a039672c6b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8f41e62e0c81a4d3", "level": "note", "message": {"text": "Unused endpoint: ANY /produkte/neu"}, "properties": {"repobilityId": "2508b284b8f41ee6", "scanner": "scanner-primary", "fingerprint": "8f41e62e0c81a4d3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f38d762a8d6c300b", "level": "note", "message": {"text": "Unused endpoint: ANY /produkte/<int:id>/bearbeiten"}, "properties": {"repobilityId": "f957af9ebd05ffc2", "scanner": "scanner-primary", "fingerprint": "f38d762a8d6c300b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-eec10dd684678608", "level": "note", "message": {"text": "Unused endpoint: ANY /produkte/<int:id>/loeschen"}, "properties": {"repobilityId": "87c16824707976d0", "scanner": "scanner-primary", "fingerprint": "eec10dd684678608", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b78089a668dcde44", "level": "note", "message": {"text": "Unused endpoint: ANY /auftraege"}, "properties": {"repobilityId": "5bad59e64826a04d", "scanner": "scanner-primary", "fingerprint": "b78089a668dcde44", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6cf92aa7b148f981", "level": "note", "message": {"text": "Unused endpoint: ANY /auftraege/neu"}, "properties": {"repobilityId": "35a7579870ae9d92", "scanner": "scanner-primary", "fingerprint": "6cf92aa7b148f981", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a4d6d49aa0c9a3a", "level": "note", "message": {"text": "Unused endpoint: ANY /auftraege/<int:id>"}, "properties": {"repobilityId": "da3c73c999a4b419", "scanner": "scanner-primary", "fingerprint": "7a4d6d49aa0c9a3a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-99f2fd00981e53db", "level": "note", "message": {"text": "Unused endpoint: ANY /auftraege/<int:id>/bearbeiten"}, "properties": {"repobilityId": "68abd31f1b7751a1", "scanner": "scanner-primary", "fingerprint": "99f2fd00981e53db", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f2b3ce6e04199ccc", "level": "note", "message": {"text": "Unused endpoint: ANY /auftraege/<int:id>/status"}, "properties": {"repobilityId": "4d779d5969ef609d", "scanner": "scanner-primary", "fingerprint": "f2b3ce6e04199ccc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f8a3a36dbe144aaf", "level": "note", "message": {"text": "Unused endpoint: ANY /auftraege/<int:id>/loeschen"}, "properties": {"repobilityId": "683abd1b822d87d6", "scanner": "scanner-primary", "fingerprint": "f8a3a36dbe144aaf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}