{"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-f58c94ebfa3a91a8", "name": "Icon-only button without accessible name \u2014 js/settings.js:81", "shortDescription": {"text": "Icon-only button without accessible name \u2014 js/settings.js:81"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a97bc4078fa7e976", "name": "Insecure pattern 'direct_innerhtml_assignment' in index.html:1178", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in index.html:1178"}, "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-20b345f4aead0610", "name": "Insecure pattern 'local_storage_auth_token' in index.html:1039", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in index.html:1039"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6ecf769194f8729e", "name": "Insecure pattern 'direct_innerhtml_assignment' in js/stats.js:34", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/stats.js:34"}, "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-46dcc8a8dddd639a", "name": "Insecure pattern 'direct_innerhtml_assignment' in js/assets.js:14", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/assets.js:14"}, "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-3f190717133b54d6", "name": "Insecure pattern 'direct_innerhtml_assignment' in js/calc.js:170", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/calc.js:170"}, "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-524f4bf43702aaf2", "name": "Insecure pattern 'direct_innerhtml_assignment' in js/settings.js:45", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/settings.js:45"}, "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-86cabfc97634d89d", "name": "Insecure pattern 'direct_innerhtml_assignment' in js/budget.js:8", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/budget.js:8"}, "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-395de883c6ba6c6b", "name": "Insecure pattern 'direct_innerhtml_assignment' in js/income.js:15", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/income.js:15"}, "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-5d78b0e8f5844e6f", "name": "Insecure pattern 'direct_innerhtml_assignment' in js/day.js:19", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/day.js:19"}, "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-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "0 test file(s) for 12 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-01f96f71d9907a8c", "name": "README lacks setup or run instructions", "shortDescription": {"text": "README lacks setup or run instructions"}, "fullDescription": {"text": "A README exists, but it does not contain common install/setup/run markers. This matches a frequent generated-code pattern: UI is present, operational handoff is thin."}, "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-bea357a6497a2d5d", "name": "Agent authority lacks a verifier contract: CLAUDE.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: CLAUDE.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ecb0d2c55ed6875d", "name": "Agent authority lacks a verifier contract: .claude/settings.local.json", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/settings.local.json"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-991af96b5fb2111d", "name": "Legacy-named symbol `budgetDB_v2` in js/sync.js:106", "shortDescription": {"text": "Legacy-named symbol `budgetDB_v2` in js/sync.js:106"}, "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-153d81ce8957a97f", "name": "Legacy-named symbol `budgetDB_v2` in js/db.js:49", "shortDescription": {"text": "Legacy-named symbol `budgetDB_v2` in js/db.js:49"}, "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-db25fb88618de92a", "name": "Legacy-named symbol `budgetDB_v2` in js/init.js:49", "shortDescription": {"text": "Legacy-named symbol `budgetDB_v2` in js/init.js:49"}, "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-9d04a8d27f42ce66", "name": "Commented-code block (5 lines) in js/init.js:118", "shortDescription": {"text": "Commented-code block (5 lines) in js/init.js:118"}, "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}}]}}, "automationDetails": {"id": "repobility/24335"}, "properties": {"repository": "artwem/void", "repoUrl": "https://github.com/artwem/void", "branch": "main"}, "results": [{"ruleId": "scanner-f58c94ebfa3a91a8", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 js/settings.js:81"}, "properties": {"repobilityId": "1c6b2df0abec28bc", "scanner": "scanner-primary", "fingerprint": "f58c94ebfa3a91a8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-a97bc4078fa7e976", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in index.html:1178"}, "properties": {"repobilityId": "f91708437a3a5445", "scanner": "scanner-primary", "fingerprint": "a97bc4078fa7e976", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "index.html"}, "region": {"startLine": 1178}}}]}, {"ruleId": "scanner-20b345f4aead0610", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in index.html:1039"}, "properties": {"repobilityId": "8f2a167064b03ceb", "scanner": "scanner-primary", "fingerprint": "20b345f4aead0610", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "index.html"}, "region": {"startLine": 1039}}}]}, {"ruleId": "scanner-6ecf769194f8729e", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/stats.js:34"}, "properties": {"repobilityId": "1b81e6b020f53c44", "scanner": "scanner-primary", "fingerprint": "6ecf769194f8729e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "js/stats.js"}, "region": {"startLine": 34}}}]}, {"ruleId": "scanner-46dcc8a8dddd639a", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/assets.js:14"}, "properties": {"repobilityId": "e5cf2ba21d525ba3", "scanner": "scanner-primary", "fingerprint": "46dcc8a8dddd639a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "js/assets.js"}, "region": {"startLine": 14}}}]}, {"ruleId": "scanner-3f190717133b54d6", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/calc.js:170"}, "properties": {"repobilityId": "8b126c9d94bf94fd", "scanner": "scanner-primary", "fingerprint": "3f190717133b54d6", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "js/calc.js"}, "region": {"startLine": 170}}}]}, {"ruleId": "scanner-524f4bf43702aaf2", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/settings.js:45"}, "properties": {"repobilityId": "3b88ea2253bc45a5", "scanner": "scanner-primary", "fingerprint": "524f4bf43702aaf2", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "js/settings.js"}, "region": {"startLine": 45}}}]}, {"ruleId": "scanner-86cabfc97634d89d", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/budget.js:8"}, "properties": {"repobilityId": "5e3b1eec930418aa", "scanner": "scanner-primary", "fingerprint": "86cabfc97634d89d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "js/budget.js"}, "region": {"startLine": 8}}}]}, {"ruleId": "scanner-395de883c6ba6c6b", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/income.js:15"}, "properties": {"repobilityId": "b3e8e0f4b1ec817a", "scanner": "scanner-primary", "fingerprint": "395de883c6ba6c6b", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "js/income.js"}, "region": {"startLine": 15}}}]}, {"ruleId": "scanner-5d78b0e8f5844e6f", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in js/day.js:19"}, "properties": {"repobilityId": "4e0468a1fe912116", "scanner": "scanner-primary", "fingerprint": "5d78b0e8f5844e6f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "js/day.js"}, "region": {"startLine": 19}}}]}, {"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": "0ca6436725edf94a", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-01f96f71d9907a8c", "level": "note", "message": {"text": "README lacks setup or run instructions"}, "properties": {"repobilityId": "043f293a876a0db7", "scanner": "scanner-primary", "fingerprint": "01f96f71d9907a8c", "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": "2e50a7dade7fec3f", "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": "89e824a568b6df8a", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-bea357a6497a2d5d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: CLAUDE.md"}, "properties": {"repobilityId": "aae72df3934829ac", "scanner": "scanner-primary", "fingerprint": "bea357a6497a2d5d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "CLAUDE.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ecb0d2c55ed6875d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/settings.local.json"}, "properties": {"repobilityId": "d8bae33a6d517bf0", "scanner": "scanner-primary", "fingerprint": "ecb0d2c55ed6875d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/settings.local.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-991af96b5fb2111d", "level": "note", "message": {"text": "Legacy-named symbol `budgetDB_v2` in js/sync.js:106"}, "properties": {"repobilityId": "e38d0013e9d88638", "scanner": "scanner-primary", "fingerprint": "991af96b5fb2111d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-153d81ce8957a97f", "level": "note", "message": {"text": "Legacy-named symbol `budgetDB_v2` in js/db.js:49"}, "properties": {"repobilityId": "a397defee3580fc7", "scanner": "scanner-primary", "fingerprint": "153d81ce8957a97f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-db25fb88618de92a", "level": "note", "message": {"text": "Legacy-named symbol `budgetDB_v2` in js/init.js:49"}, "properties": {"repobilityId": "c54004b1f4e32d1f", "scanner": "scanner-primary", "fingerprint": "db25fb88618de92a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-9d04a8d27f42ce66", "level": "none", "message": {"text": "Commented-code block (5 lines) in js/init.js:118"}, "properties": {"repobilityId": "d024c3f5041d7ce3", "scanner": "scanner-primary", "fingerprint": "9d04a8d27f42ce66", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}]}]}