{"schema_version":"2","scorer_version":"0.1.0","scoring_version":"prov-5+qual-2+sec-2","generated_at":"2026-11-14T14:52:08.447911Z","repo":{"ref":{"host":"github.com","owner":"whyhowie","name":"RokuPyRemote"},"default_branch":"main","clone_url":"https://github.com/whyhowie/RokuPyRemote.git","html_url":"https://github.com/whyhowie/RokuPyRemote","description":"A Python-based Roku remote controller on local network.","stars":0,"forks":0,"is_fork":false,"is_archived":false,"is_private":false,"size_kb":18451,"primary_language":"Python","license_spdx":"MIT","created_at":"2026-05-26T01:46:02Z","pushed_at":"2026-05-26T04:47:53Z","security_policy_url":null,"distribution":{"owner_created_at":"2020-10-14T20:54:14Z","owner_type":"User","release_assets":[{"name":"roku_remote.exe","size":17520536,"download_count":6,"release_tag":"v0.1.0","url":"https://github.com/whyhowie/RokuPyRemote/releases/download/v0.1.0/roku_remote.exe"}]}},"commit_sha":"30aab7ed75d7b7a477bdff7abb7401992f155e74","profile":{"lines_by_language":{"Python":987},"files_by_category":{"source":11,"docs":2,"binary":2,"config":1,"other":1,"oversized":1},"source_lines":987,"test_lines":0},"pillars":{"ai_provenance":{"score":0.0,"confidence":0.42,"coverage":1.0,"label":"possible","breakdown":{"attributed_share":0.0,"suspected_share":0.7792,"estimated_share":0.0,"ai_artifacts":0.0,"flagged_work_units":1.0,"flagged_releases":null,"style_index":0.5},"summary":"Weak signals consistent with AI-assisted development."},"quality":{"score":50.6,"confidence":0.9,"coverage":1.0,"label":"weak","breakdown":{"complexity":100.0,"duplication":91.1,"lint":22.3,"testing":0.0,"docs":65.0,"type_safety":40.0,"process":null},"summary":"Code quality is weak: test-to-source ratio 0.00, no CI test run detected; 0% of function code in complex or long functions; 2% duplicated lines. Weakest area: testing."},"security":{"score":63.5,"confidence":0.85,"coverage":1.0,"label":"weak","breakdown":{"secrets":100.0,"sast":49.7,"dependencies":null,"ci_actions":null,"posture":0.0,"scorecard":null},"summary":"Security posture is weak: 2 high-severity SAST findings. Weakest area: posture."}},"analyzer_results":[{"analyzer":"sec-scorecard","pillar":"security","status":"skipped","tool_version":null,"metrics":{},"findings":[],"evidence":[],"data":{},"error":"no published OpenSSF Scorecard result for this repo"},{"analyzer":"sec-registry","pillar":"security","status":"skipped","tool_version":null,"metrics":{},"findings":[],"evidence":[],"data":{},"error":"no registry dependencies declared"},{"analyzer":"ai-attribution","pillar":"ai_provenance","status":"ok","tool_version":"signatures-v1","metrics":{"commits":9.0,"attributed_commits":0.0,"attributed_commit_share":0.0,"effective_loc":1377.0,"attributed_loc":0.0,"attributed_loc_share":0.0,"tools_detected":0.0},"findings":[],"evidence":[],"data":{"attributed_loc_by_commit":{},"tools":{},"monthly":{"2026-05":{"loc":1377,"attributed_loc":0}}},"error":null},{"analyzer":"ai-artifacts","pillar":"ai_provenance","status":"ok","tool_version":"signatures-v1","metrics":{"artifacts":0.0,"workflow_agents":0.0,"tools_configured":0.0},"findings":[],"evidence":[],"data":{"artifacts":[],"workflows":[],"tools":[]},"error":null},{"analyzer":"ai-velocity","pillar":"ai_provenance","status":"ok","tool_version":"prov-4","metrics":{"work_units":2.0,"flagged_units":1.0,"pre_ai_era_bursts":0.0,"pre_ai_era_measured_loc":0.0,"pre_ai_era_burst_loc":0.0,"measured_loc":1377.0,"flagged_loc":1073.0,"flagged_loc_share":0.7792302106027597,"max_loc_per_hour":677.3277222514466,"median_loc_per_hour":376.6638611257233,"pr_timed_units":0.0,"excluded_import_loc":0.0},"findings":[],"evidence":[{"kind":"velocity-burst","description":"1,073 lines of first-party code in ~1.6h (677 lines/hour, 2 commit session)","ref":"b6be0788305e733855ddfe821b6298d957271358","url":"https://github.com/whyhowie/RokuPyRemote/commit/b6be0788305e733855ddfe821b6298d957271358","weight":0.203198316675434}],"data":{"flagged_loc_by_commit":{"f7797a5b27680422f755dffa1747709e2cbabe67":630,"b6be0788305e733855ddfe821b6298d957271358":443},"excluded_import_commits":[]},"error":null},{"analyzer":"ai-release-velocity","pillar":"ai_provenance","status":"skipped","tool_version":null,"metrics":{},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"ai-stylometry","pillar":"ai_provenance","status":"ok","tool_version":null,"metrics":{"lines_scanned":987.0,"index":0.5,"count:narrated_steps":0.0,"per_kloc:narrated_steps":0.0,"files:narrated_steps":0.0,"count:placeholder":0.0,"per_kloc:placeholder":0.0,"files:placeholder":0.0,"count:emoji_in_code":1.0,"per_kloc:emoji_in_code":1.0,"files:emoji_in_code":1.0,"count:assistant_voice":0.0,"per_kloc:assistant_voice":0.0,"files:assistant_voice":0.0},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-secrets","pillar":"security","status":"ok","tool_version":"gitleaks 8.30.1","metrics":{"secrets_current":0.0,"secrets_history":0.0,"secrets_nonprod":0.0,"secrets_low_confidence":0.0},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-sast","pillar":"security","status":"ok","tool_version":"opengrep 1.33.1; rules f1d2b562b414","metrics":{"findings":4.0,"findings_high":2.0,"findings_medium":2.0,"findings_low":0.0,"weighted_findings":2.0,"scanned_lines":987.0,"parse_errors":0.0},"findings":[{"rule_id":"opengrep/python.lang.security.audit.dangerous-subprocess-use-audit","severity":"high","message":"Detected subprocess function 'Popen' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. [confidence low]","path":"dev.py","line":30,"fingerprint":"python.lang.security.audit.dangerous-subprocess-use-audit:dev.py:30"},{"rule_id":"opengrep/python.lang.security.use-defused-xml","severity":"high","message":"The Python documentation recommends using `defusedxml` instead of `xml` because the native Python `xml` library is vulnerable to XML External Entity (XXE) attacks. These attacks can leak confidential data and \"XML bombs\" can cause denial of service. [confidence low]","path":"roku_remote/network.py","line":4,"fingerprint":"python.lang.security.use-defused-xml:roku_remote/network.py:4"},{"rule_id":"opengrep/python.lang.security.audit.dynamic-urllib-use-detected","severity":"medium","message":"Detected a dynamic value being used with urllib. urllib supports 'file://' schemes, so a dynamic value controlled by a malicious actor may allow them to read arbitrary files. Audit uses of urllib calls to ensure user data cannot control the URLs, or consider using the 'requests' library instead. [confidence low]","path":"roku_remote/network.py","line":22,"fingerprint":"python.lang.security.audit.dynamic-urllib-use-detected:roku_remote/network.py:22"},{"rule_id":"opengrep/python.lang.security.audit.dynamic-urllib-use-detected","severity":"medium","message":"Detected a dynamic value being used with urllib. urllib supports 'file://' schemes, so a dynamic value controlled by a malicious actor may allow them to read arbitrary files. Audit uses of urllib calls to ensure user data cannot control the URLs, or consider using the 'requests' library instead. [confidence low]","path":"roku_remote/network.py","line":45,"fingerprint":"python.lang.security.audit.dynamic-urllib-use-detected:roku_remote/network.py:45"}],"evidence":[],"data":{"rulesets":["python"]},"error":null},{"analyzer":"sec-deps","pillar":"security","status":"skipped","tool_version":null,"metrics":{},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-actions","pillar":"security","status":"skipped","tool_version":null,"metrics":{},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-posture","pillar":"security","status":"ok","tool_version":null,"metrics":{"check:security_policy":0.0,"check:dependency_updates":0.0,"check:signed_commits":0.0,"check:lockfiles":1.0,"signed_commit_share":0.0,"unpinned_manifests":0.0},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-distribution","pillar":"security","status":"ok","tool_version":null,"metrics":{"signals":1.0,"binary_assets":1.0,"suspicious":0.0},"findings":[],"evidence":[{"kind":"binary-release-asset","description":"release v0.1.0 ships roku_remote.exe (6 downloads)","ref":"roku_remote.exe","url":"https://github.com/whyhowie/RokuPyRemote/releases/download/v0.1.0/roku_remote.exe","weight":0.0}],"data":{"signals":["binary-release-assets"],"suspicious":false,"unusual_traction":false,"metadata":true},"error":null},{"analyzer":"qual-complexity","pillar":"quality","status":"ok","tool_version":"lizard 1.25.1","metrics":{"functions":82.0,"function_nloc":652.0,"mean_ccn":1.91,"p90_ccn":3.0,"complex_functions":0.0,"long_functions":0.0,"many_param_functions":1.0,"risky_nloc_share":0.0},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"qual-duplication","pillar":"quality","status":"ok","tool_version":"repotrust-dup-w6","metrics":{"compared_lines":770.0,"duplicated_lines":12.0,"duplicated_share":0.0156,"files":11.0},"findings":[],"evidence":[{"kind":"duplicate-code","description":"6+ duplicated lines: roku_remote.py:14 and roku_remote/__main__.py:5","ref":"roku_remote.py","url":"https://github.com/whyhowie/RokuPyRemote/blob/30aab7ed75d7b7a477bdff7abb7401992f155e74/roku_remote.py#L14","weight":0.3}],"data":{},"error":null},{"analyzer":"qual-lint","pillar":"quality","status":"ok","tool_version":"opengrep 1.33.1; rules f1d2b562b414","metrics":{"findings":4.0,"weighted_findings":6.0,"scanned_lines":987.0,"category:best-practice":3.0,"category:maintainability":1.0},"findings":[{"rule_id":"opengrep/python.lang.best-practice.arbitrary-sleep","severity":"high","message":"time.sleep() call; did you mean to leave this in?","path":"dev.py","line":49,"fingerprint":"python.lang.best-practice.arbitrary-sleep:dev.py:49"},{"rule_id":"opengrep/python.lang.maintainability.is-function-without-parentheses","severity":"medium","message":"Is \"is_directory\" a function or an attribute? If it is a function, you may have meant event.is_directory() because event.is_directory is always true.","path":"dev.py","line":33,"fingerprint":"python.lang.maintainability.is-function-without-parentheses:dev.py:33"},{"rule_id":"opengrep/python.lang.best-practice.unspecified-open-encoding","severity":"medium","message":"Missing 'encoding' parameter. 'open()' uses device locale encodings by default, corrupting files with special characters. Specify the encoding to ensure cross-platform support when opening files in text mode (e.g. encoding=\"utf-8\").","path":"roku_remote/config.py","line":23,"fingerprint":"python.lang.best-practice.unspecified-open-encoding:roku_remote/config.py:23"},{"rule_id":"opengrep/python.lang.best-practice.unspecified-open-encoding","severity":"medium","message":"Missing 'encoding' parameter. 'open()' uses device locale encodings by default, corrupting files with special characters. Specify the encoding to ensure cross-platform support when opening files in text mode (e.g. encoding=\"utf-8\").","path":"roku_remote/config.py","line":33,"fingerprint":"python.lang.best-practice.unspecified-open-encoding:roku_remote/config.py:33"}],"evidence":[],"data":{},"error":null},{"analyzer":"qual-testing","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:has_tests":0.0,"check:test_ratio":0.0,"check:ci_present":0.0,"check:ci_runs_tests":0.0,"check:ci_runs_lint":0.0,"check:tests_cochange":0.0,"test_lines":0.0,"source_lines":987.0,"test_ratio":0.0,"ci_files":0.0,"cochange_share":0.0,"cochange_commits":3.0},"findings":[],"evidence":[],"data":{"test_commands":[],"lint_commands":[]},"error":null},{"analyzer":"qual-docs","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:readme":1.0,"check:license":1.0,"check:contributing":0.0,"check:changelog":0.0,"readme_lines":44.0},"findings":[],"evidence":[{"kind":"docs","description":"README.md","ref":"README.md","url":null,"weight":0.0},{"kind":"docs","description":"LICENSE","ref":"LICENSE","url":null,"weight":0.0}],"data":{},"error":null},{"analyzer":"qual-type-safety","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:strict_config":0.0,"check:low_escape_density":1.0,"escapes":0.0,"escapes_per_kloc":0.0},"findings":[],"evidence":[],"data":{},"error":null}],"flags":[]}