Leaderboard github.com
lihaohong6/Blue-Archive-bot
AI provenance
1%
possible
- Confidence
- 65%
- Coverage
- 100%
Estimated share of AI-generated code. Explicit attribution is a lower bound.
Code quality
38/100
poor
- Confidence
- 90%
- Coverage
- 100%
Complexity, duplication, lint density, tests, CI, docs and review process.
Security
66/100
weak
- Confidence
- 85%
- Coverage
- 100%
Secrets, static analysis, vulnerable dependencies, CI and supply-chain posture.
AI provenance
1% possible
Weak signals consistent with AI-assisted development. 1 commit(s) carry explicit AI attribution, too few to characterize the codebase.
How the score is built
- Explicitly attributed share1%
- Unattributed share in AI-pace bursts23%
- Estimated AI-generated share1%
- AI tool configuration files0
- Work sessions at AI pace1
- Releases at AI pacenot measured
- Coding-style index (1.0+ means possible)0.00
Attributed AI tools
| Tool | Commits | Lines added | First seen | Last seen |
|---|---|---|---|---|
| Claude Code | 1 | 68 | 2026-11-12 | 2026-11-12 |
Lines added per month all AI-attributed share
- 2023-12728 · 0% AI
- 2024-011,102 · 0% AI
- 2024-0252 · 0% AI
- 2024-04277 · 0% AI
- 2024-05176 · 0% AI
- 2024-06139 · 0% AI
- 2024-07295 · 0% AI
- 2024-0831 · 0% AI
- 2024-099 · 0% AI
- 2024-10984 · 0% AI
- 2024-11374 · 0% AI
- 2024-120 · 0% AI
- 2025-0139 · 0% AI
- 2025-0262 · 0% AI
- 2025-0324 · 0% AI
- 2025-04215 · 0% AI
- 2025-05233 · 0% AI
- 2025-073 · 0% AI
- 2025-0835 · 0% AI
- 2025-10193 · 0% AI
- 2025-11289 · 0% AI
- 2026-0778 · 0% AI
- 2026-08160 · 0% AI
- 2026-092,095 · 0% AI
- 2026-103,653 · 0% AI
- 2026-1168 · 100% AI
Findings in AI-attributed lines vs the rest
From git blame: 68 lines trace to AI-attributed commits, 5,980 to others. Too few lines in one group for a fair comparison. Reported, not scored.
| Findings per 1,000 lines | AI-attributed | Other | Ratio |
|---|---|---|---|
| Code quality | 0.00 | 6.52 | — |
| Security | 0.00 | 0.50 | — |
Evidence by analyzer
Explicit AI attributionok2 items
- Claude Code: 1 attributed commits, 68 lines added
- Claude Code: trailer 'Co-Authored-By: Claude'
- attributed_commit_share
- 0.8%
- attributed_commits
- 1
- attributed_loc
- 68
- attributed_loc_share
- 0.6%
- commits
- 126
- effective_loc
- 11,314
- tools_detected
- 1
AI tool configurationok
- artifacts
- 0
- tools_configured
- 0
- workflow_agents
- 0
Commit velocityok1 item
- excluded_import_loc
- 0
- flagged_loc
- 2,597
- flagged_loc_share
- 23.0%
- flagged_units
- 1
- max_loc_per_hour
- 637.47
- measured_loc
- 11,314
- median_loc_per_hour
- 40.11
- pr_timed_units
- 0
- pre_ai_era_burst_loc
- 0
- pre_ai_era_bursts
- 0
- pre_ai_era_measured_loc
- 0
- work_units
- 95
Release velocityskipped
Coding styleok
- count:assistant_voice
- 0
- count:emoji_in_code
- 0
- count:narrated_steps
- 0
- count:placeholder
- 0
- files:assistant_voice
- 0
- files:emoji_in_code
- 0
- files:narrated_steps
- 0
- files:placeholder
- 0
- index
- 0
- lines_scanned
- 6,048
- per_kloc:assistant_voice
- 0
- per_kloc:emoji_in_code
- 0
- per_kloc:narrated_steps
- 0
- per_kloc:placeholder
- 0
Findings in AI-written linesok
- ai_lines
- 68
- blame_failures
- 0
- files_blamed
- 46
- other_lines
- 5,980
- quality:ai_findings
- 0
- quality:ai_per_kloc
- 0
- quality:other_findings
- 39
- quality:other_per_kloc
- 6.52
- security:ai_findings
- 0
- security:ai_per_kloc
- 0
- security:other_findings
- 3
- security:other_per_kloc
- 0.50
Code quality
38 poor
Code quality is poor: test-to-source ratio 0.00, no CI test run detected; 23% of function code in complex or long functions; 0% duplicated lines. Weakest area: testing.
How the score is built
- Complexity51
- Duplication98
- Lint and smells17
- Tests and CI0
- Documentation45
- Type safety40
- Review processnot measured
Evidence by analyzer
Complexity (lizard)ok10 items
- plan_switches in model_viewer/exporter/switches.py: complexity 53, 61 lines
- parse_story in story/story_parser.py: complexity 49, 126 lines
- mark_props in model_viewer/exporter/props.py: complexity 42, 53 lines
- add_renderer in model_viewer/exporter/geometry.py: complexity 36, 71 lines
- write_glb in model_viewer/exporter/glb.py: complexity 35, 124 lines
- runtime_parts in model_viewer/exporter/switches.py: complexity 34, 50 lines
- get_scenario_character_id in story/story_utils.py: complexity 31, 84 lines
- main in model_viewer/export_models.py: complexity 23, 66 lines
- particle_mesh in model_viewer/exporter/fx.py: complexity 22, 26 lines
- make_conversation in momotalk.py: complexity 21, 66 lines
- complex_functions
- 14
- function_nloc
- 3,860
- functions
- 282
- long_functions
- 2
- many_param_functions
- 3
- mean_ccn
- 5.40
- p90_ccn
- 11
- risky_nloc_share
- 22.6%
Duplication (jscpd)ok1 item
- compared_lines
- 4,813
- duplicated_lines
- 14
- duplicated_share
- 0.3%
- files
- 46
Lintok
- category:best-practice
- 26
- category:correctness
- 1
- category:maintainability
- 12
- findings
- 39
- scanned_lines
- 6,048
- weighted_findings
- 43
Tests and CIok
- check:ci_present
- no
- check:ci_runs_lint
- no
- check:ci_runs_tests
- no
- check:has_tests
- no
- check:test_ratio
- no
- check:tests_cochange
- no
- ci_files
- 0
- cochange_commits
- 116
- cochange_share
- 0.0%
- source_lines
- 6,048
- test_lines
- 0
- test_ratio
- 0
Documentationok2 items
- README.md
README.md - LICENSE
LICENSE
- check:changelog
- no
- check:contributing
- no
- check:license
- yes
- check:readme
- no
- readme_lines
- 0
Type safetyok
- check:low_escape_density
- yes
- check:strict_config
- no
- escapes
- 2
- escapes_per_kloc
- 0.33
Security
66 weak
Security posture is weak: 52 known vulnerabilities in 5 dependencies; 1 high-severity SAST findings. Weakest area: posture.
How the score is built
- Secrets100
- Static analysis (SAST)88
- Vulnerable dependencies36
- CI workflowsnot measured
- Security posture0
- OpenSSF Scorecardnot measured
Evidence by analyzer
OpenSSF Scorecardskipped
no published OpenSSF Scorecard result for this repo
Package registriesok
- checked
- 6
- declared
- 6
- lookup_errors
- 0
- missing
- 0
- recent
- 0
Secrets (gitleaks)ok
- secrets_current
- 0
- secrets_history
- 0
- secrets_low_confidence
- 0
- secrets_nonprod
- 0
Static analysis (opengrep)ok
- findings
- 3
- findings_high
- 1
- findings_low
- 0
- findings_medium
- 2
- parse_errors
- 1
- scanned_lines
- 6,048
- weighted_findings
- 2.30
Dependencies (osv-scanner)ok
- penalty
- 61
- vulnerabilities
- 52
- vulnerable_packages
- 5
- vulns_critical
- 8
- vulns_high
- 30
- vulns_low
- 0
- vulns_medium
- 13
- vulns_unknown
- 1
CI workflows (zizmor)skipped
Security postureok
- check:dependency_updates
- no
- check:lockfiles
- yes
- check:security_policy
- no
- check:signed_commits
- no
- signed_commit_share
- 0.8%
- unpinned_manifests
- 0
Release downloadsok
- binary_assets
- 0
- signals
- 0
- suspicious
- 0
Findings
8 critical33 high53 medium
| Severity | Rule | Location | Message | Tool |
|---|---|---|---|---|
| critical | osv/GHSA-332p-7hrc-92wf |
uv.lock | [email protected] (PyPI) is affected by GHSA-332p-7hrc-92wf | Dependencies (osv-scanner) |
| critical | osv/GHSA-5x8w-8jj5-q52h |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4330, GHSA-5x8w-8jj5-q52h | Dependencies (osv-scanner) |
| critical | osv/GHSA-6q48-6c7w-9gw2 |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4320, GHSA-6q48-6c7w-9gw2 | Dependencies (osv-scanner) |
| critical | osv/GHSA-8g5g-8vmr-9782 |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4332, GHSA-8g5g-8vmr-9782 | Dependencies (osv-scanner) |
| critical | osv/GHSA-9v8h-qqgm-4m35 |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4322, GHSA-9v8h-qqgm-4m35 | Dependencies (osv-scanner) |
| critical | osv/GHSA-v9pv-5gc8-w2m6 |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4339, GHSA-v9pv-5gc8-w2m6 | Dependencies (osv-scanner) |
| critical | osv/GHSA-w889-685w-c8fh |
uv.lock | [email protected] (PyPI) is affected by GHSA-w889-685w-c8fh | Dependencies (osv-scanner) |
| critical | osv/GHSA-xvh5-g6gv-559v |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4363, GHSA-xvh5-g6gv-559v | Dependencies (osv-scanner) |
| high | opengrep/python.lang.best-practice.arbitrary-sleep |
scripts/manga.py:70 | time.sleep() call; did you mean to leave this in? | Lint |
| high | opengrep/python.lang.best-practice.arbitrary-sleep |
scripts/translate.py:38 | time.sleep() call; did you mean to leave this in? | Lint |
| high | opengrep/python.lang.security.audit.subprocess-shell-true |
portrait_spirite.py:146 | Found 'subprocess' function 'run' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious... | Static analysis (opengrep) |
| high | osv/GHSA-22hg-r758-rrw9 |
uv.lock | [email protected] (PyPI) is affected by GHSA-22hg-r758-rrw9 | Dependencies (osv-scanner) |
| high | osv/GHSA-27h8-gf7j-v5hc |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4326, GHSA-27h8-gf7j-v5hc | Dependencies (osv-scanner) |
| high | osv/GHSA-3j72-p6qg-6xp7 |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4341, GHSA-3j72-p6qg-6xp7 | Dependencies (osv-scanner) |
| high | osv/GHSA-4558-3h8r-v8xp |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4327, GHSA-4558-3h8r-v8xp | Dependencies (osv-scanner) |
| high | osv/GHSA-4rr5-89j8-mwwm |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4328, GHSA-4rr5-89j8-mwwm | Dependencies (osv-scanner) |
| high | osv/GHSA-58r4-6rv3-gfh8 |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4329, GHSA-58r4-6rv3-gfh8 | Dependencies (osv-scanner) |
| high | osv/GHSA-5xm2-6676-qcp9 |
uv.lock | [email protected] (PyPI) is affected by GHSA-5xm2-6676-qcp9 | Dependencies (osv-scanner) |
| high | osv/GHSA-65qm-jvmh-6pqg |
uv.lock | [email protected] (PyPI) is affected by GHSA-65qm-jvmh-6pqg | Dependencies (osv-scanner) |
| high | osv/GHSA-6655-6qjp-jx7x |
uv.lock | [email protected] (PyPI) is affected by GHSA-6655-6qjp-jx7x | Dependencies (osv-scanner) |
| high | osv/GHSA-78g4-xqwv-q3g8 |
uv.lock | [email protected] (PyPI) is affected by GHSA-78g4-xqwv-q3g8 | Dependencies (osv-scanner) |
| high | osv/GHSA-7mwm-ghpf-9vrm |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4331, GHSA-7mwm-ghpf-9vrm | Dependencies (osv-scanner) |
| high | osv/GHSA-8988-9cw3-xx77 |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4175, GHSA-8988-9cw3-xx77 | Dependencies (osv-scanner) |
| high | osv/GHSA-9v9v-9qvf-h2hj |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4343, GHSA-9v9v-9qvf-h2hj | Dependencies (osv-scanner) |
| high | osv/GHSA-c6hw-5grf-ff96 |
uv.lock | [email protected] (PyPI) is affected by GHSA-c6hw-5grf-ff96 | Dependencies (osv-scanner) |
| high | osv/GHSA-cp9v-662q-vvx9 |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4333, GHSA-cp9v-662q-vvx9 | Dependencies (osv-scanner) |
| high | osv/GHSA-f2g6-542v-9j58 |
uv.lock | [email protected] (PyPI) is affected by GHSA-f2g6-542v-9j58 | Dependencies (osv-scanner) |
| high | osv/GHSA-g4qv-2jxx-769h |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4342, GHSA-g4qv-2jxx-769h | Dependencies (osv-scanner) |
| high | osv/GHSA-g7cr-3p24-7wf7 |
uv.lock | [email protected] (PyPI) is affected by GHSA-g7cr-3p24-7wf7 | Dependencies (osv-scanner) |
| high | osv/GHSA-g842-9rc4-69pw |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4338, GHSA-g842-9rc4-69pw | Dependencies (osv-scanner) |
| high | osv/GHSA-gg2r-wvfm-q9rx |
uv.lock | [email protected] (PyPI) is affected by GHSA-gg2r-wvfm-q9rx | Dependencies (osv-scanner) |
| high | osv/GHSA-j4m9-6w36-pw47 |
uv.lock | [email protected] (PyPI) is affected by GHSA-j4m9-6w36-pw47 | Dependencies (osv-scanner) |
| high | osv/GHSA-jg86-v3jv-hrpm |
uv.lock | [email protected] (PyPI) is affected by GHSA-jg86-v3jv-hrpm | Dependencies (osv-scanner) |
| high | osv/GHSA-mmhr-3c5m-f64f |
uv.lock | [email protected] (PyPI) is affected by GHSA-mmhr-3c5m-f64f | Dependencies (osv-scanner) |
| high | osv/GHSA-mrfp-p49p-3hf2 |
uv.lock | [email protected] (PyPI) is affected by GHSA-mrfp-p49p-3hf2 | Dependencies (osv-scanner) |
| high | osv/GHSA-p4wg-p73j-c528 |
uv.lock | [email protected] (PyPI) is affected by GHSA-p4wg-p73j-c528 | Dependencies (osv-scanner) |
| high | osv/GHSA-pchr-8j38-3x4p |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4334, GHSA-pchr-8j38-3x4p | Dependencies (osv-scanner) |
| high | osv/GHSA-q45j-58j2-45rg |
uv.lock | [email protected] (PyPI) is affected by GHSA-q45j-58j2-45rg | Dependencies (osv-scanner) |
| high | osv/GHSA-vxq7-64xx-v4gw |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4177, GHSA-vxq7-64xx-v4gw | Dependencies (osv-scanner) |
| high | osv/GHSA-xcvg-w56q-r89m |
uv.lock | [email protected] (PyPI) is affected by GHSA-xcvg-w56q-r89m | Dependencies (osv-scanner) |
| high | osv/GHSA-xgh8-jp6q-p5x8 |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4335, GHSA-xgh8-jp6q-p5x8 | Dependencies (osv-scanner) |
| medium | opengrep/python.lang.best-practice.unspecified-open-encoding |
portrait_spirite.py:102 | 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"). | Lint |
| medium | opengrep/python.lang.best-practice.unspecified-open-encoding |
portrait_spirite.py:116 | 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"). | Lint |
| medium | opengrep/python.requests.best-practice.use-raise-for-status |
portrait_spirite.py:25 | There's an HTTP request made with requests, but the raise_for_status() utility method isn't used. This can result in request errors going unnoticed and your code behaving in unexpected ways, such as if your authorization API returns a... | Lint |
| medium | opengrep/python.requests.best-practice.use-timeout |
portrait_spirite.py:25 | Detected a 'requests' call without a timeout set. By default, 'requests' calls wait until the connection is closed. This means a 'requests' call without a timeout will hang the program if a response is never received. Consider setting a... | Lint |
| medium | opengrep/python.requests.best-practice.use-raise-for-status |
scripts/manga.py:42 | There's an HTTP request made with requests, but the raise_for_status() utility method isn't used. This can result in request errors going unnoticed and your code behaving in unexpected ways, such as if your authorization API returns a... | Lint |
| medium | opengrep/python.requests.best-practice.use-timeout |
scripts/manga.py:42 | Detected a 'requests' call without a timeout set. By default, 'requests' calls wait until the connection is closed. This means a 'requests' call without a timeout will hang the program if a response is never received. Consider setting a... | Lint |
| medium | opengrep/python.requests.best-practice.use-raise-for-status |
scripts/manga_jp.py:28 | There's an HTTP request made with requests, but the raise_for_status() utility method isn't used. This can result in request errors going unnoticed and your code behaving in unexpected ways, such as if your authorization API returns a... | Lint |
| medium | opengrep/python.requests.best-practice.use-timeout |
scripts/manga_jp.py:28 | Detected a 'requests' call without a timeout set. By default, 'requests' calls wait until the connection is closed. This means a 'requests' call without a timeout will hang the program if a response is never received. Consider setting a... | Lint |
| medium | opengrep/python.lang.best-practice.unspecified-open-encoding |
scripts/missions.py:23 | 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"). | Lint |
| medium | opengrep/python.lang.best-practice.unspecified-open-encoding |
scripts/missions.py:39 | 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"). | Lint |
| medium | opengrep/python.lang.best-practice.unspecified-open-encoding |
scripts/missions.py:51 | 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"). | Lint |
| medium | opengrep/python.lang.correctness.use-sys-exit |
scripts/missions.py:74 | Detected use of `exit`. Use `sys.exit` over the python shell `exit` built-in. `exit` is a helper for the interactive shell and may not be available on all Python implementations. | Lint |
| medium | opengrep/python.requests.best-practice.use-raise-for-status |
scripts/nexon_scrap.py:19 | There's an HTTP request made with requests, but the raise_for_status() utility method isn't used. This can result in request errors going unnoticed and your code behaving in unexpected ways, such as if your authorization API returns a... | Lint |
| medium | opengrep/python.requests.best-practice.use-timeout |
scripts/nexon_scrap.py:19 | Detected a 'requests' call without a timeout set. By default, 'requests' calls wait until the connection is closed. This means a 'requests' call without a timeout will hang the program if a response is never received. Consider setting a... | Lint |
| medium | opengrep/python.requests.best-practice.use-raise-for-status |
scripts/nexon_scrap.py:36 | There's an HTTP request made with requests, but the raise_for_status() utility method isn't used. This can result in request errors going unnoticed and your code behaving in unexpected ways, such as if your authorization API returns a... | Lint |
| medium | opengrep/python.requests.best-practice.use-timeout |
scripts/nexon_scrap.py:36 | Detected a 'requests' call without a timeout set. By default, 'requests' calls wait until the connection is closed. This means a 'requests' call without a timeout will hang the program if a response is never received. Consider setting a... | Lint |
| medium | opengrep/python.requests.best-practice.use-raise-for-status |
scripts/nexon_scrap.py:49 | There's an HTTP request made with requests, but the raise_for_status() utility method isn't used. This can result in request errors going unnoticed and your code behaving in unexpected ways, such as if your authorization API returns a... | Lint |
| medium | opengrep/python.requests.best-practice.use-timeout |
scripts/nexon_scrap.py:49 | Detected a 'requests' call without a timeout set. By default, 'requests' calls wait until the connection is closed. This means a 'requests' call without a timeout will hang the program if a response is never received. Consider setting a... | Lint |
| medium | opengrep/python.lang.best-practice.unspecified-open-encoding |
scripts/translate.py:10 | 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"). | Lint |
| medium | opengrep/python.lang.best-practice.unspecified-open-encoding |
skills/skill_classification.py:26 | 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"). | Lint |
| medium | opengrep/python.lang.best-practice.unspecified-open-encoding |
skills/skill_classification.py:30 | 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"). | Lint |
| medium | opengrep/python.lang.best-practice.unspecified-open-encoding |
skills/skill_classification.py:57 | 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"). | Lint |
| medium | opengrep/python.lang.best-practice.unspecified-open-encoding |
skills/skill_classification.py:79 | 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"). | Lint |
| medium | opengrep/python.lang.maintainability.return-not-in-function |
story/story_utils.py:258 | `return` only makes sense inside a function | Lint |
| medium | opengrep/python.lang.maintainability.return-not-in-function |
story/story_utils.py:259 | `return` only makes sense inside a function | Lint |
| medium | opengrep/python.requests.best-practice.use-raise-for-status |
update.py:8 | There's an HTTP request made with requests, but the raise_for_status() utility method isn't used. This can result in request errors going unnoticed and your code behaving in unexpected ways, such as if your authorization API returns a... | Lint |
| medium | opengrep/python.requests.best-practice.use-timeout |
update.py:8 | Detected a 'requests' call without a timeout set. By default, 'requests' calls wait until the connection is closed. This means a 'requests' call without a timeout will hang the program if a response is never received. Consider setting a... | Lint |
| medium | opengrep/python.lang.maintainability.return-not-in-function |
utils.py:23 | `return` only makes sense inside a function | Lint |
| medium | opengrep/python.lang.maintainability.return-not-in-function |
utils.py:27 | `return` only makes sense inside a function | Lint |
| medium | opengrep/python.lang.maintainability.code-after-unconditional-return |
utils.py:30 | code after return statement will not be executed | Lint |
| medium | opengrep/python.lang.maintainability.return-not-in-function |
utils.py:30 | `return` only makes sense inside a function | Lint |
| medium | opengrep/python.lang.maintainability.code-after-unconditional-return |
utils.py:41 | code after return statement will not be executed | Lint |
| medium | opengrep/python.lang.maintainability.return-not-in-function |
utils.py:41 | `return` only makes sense inside a function | Lint |
| medium | opengrep/python.lang.maintainability.code-after-unconditional-return |
utils.py:45 | code after return statement will not be executed | Lint |
| medium | opengrep/python.lang.maintainability.return-not-in-function |
utils.py:45 | `return` only makes sense inside a function | Lint |
| medium | opengrep/python.lang.maintainability.code-after-unconditional-return |
utils.py:63 | code after return statement will not be executed | Lint |
| medium | opengrep/python.lang.maintainability.return-not-in-function |
utils.py:63 | `return` only makes sense inside a function | Lint |
| medium | opengrep/python.lang.security.deserialization.avoid-pickle |
utils.py:51 | Avoid using `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar... | Static analysis (opengrep) |
| medium | opengrep/python.lang.security.deserialization.avoid-pickle |
utils.py:62 | Avoid using `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar... | Static analysis (opengrep) |
| medium | osv/GHSA-24rc-8hj2-v98c |
uv.lock | [email protected] (PyPI) is affected by GHSA-24rc-8hj2-v98c | Dependencies (osv-scanner) |
| medium | osv/GHSA-254f-3936-288h |
uv.lock | [email protected] (PyPI) is affected by GHSA-254f-3936-288h | Dependencies (osv-scanner) |
| medium | osv/GHSA-462x-pgg6-55fp |
uv.lock | [email protected] (PyPI) is affected by GHSA-462x-pgg6-55fp | Dependencies (osv-scanner) |
| medium | osv/GHSA-4j63-6c4x-wfg4 |
uv.lock | [email protected] (PyPI) is affected by GHSA-4j63-6c4x-wfg4 | Dependencies (osv-scanner) |
| medium | osv/GHSA-4rm8-3hmm-39fg |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4340, GHSA-4rm8-3hmm-39fg | Dependencies (osv-scanner) |
| medium | osv/GHSA-654x-cwwv-5j9c |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4336, GHSA-654x-cwwv-5j9c | Dependencies (osv-scanner) |
| medium | osv/GHSA-74r2-7ff9-mjj2 |
uv.lock | [email protected] (PyPI) is affected by GHSA-74r2-7ff9-mjj2 | Dependencies (osv-scanner) |
| medium | osv/GHSA-7g44-g9rc-x53w |
uv.lock | [email protected] (PyPI) is affected by GHSA-7g44-g9rc-x53w | Dependencies (osv-scanner) |
| medium | osv/GHSA-fc9g-5qg7-mf45 |
uv.lock | [email protected] (PyPI) is affected by GHSA-fc9g-5qg7-mf45 | Dependencies (osv-scanner) |
| medium | osv/GHSA-gh4c-6fx4-qh6g |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4176, GHSA-gh4c-6fx4-qh6g | Dependencies (osv-scanner) |
| medium | osv/GHSA-p8hx-v2p6-rp84 |
uv.lock | [email protected] (PyPI) is affected by PYSEC-2026-4337, GHSA-p8hx-v2p6-rp84 | Dependencies (osv-scanner) |
| medium | osv/GHSA-rfgq-q3w2-pmv2 |
uv.lock | [email protected] (PyPI) is affected by GHSA-rfgq-q3w2-pmv2 | Dependencies (osv-scanner) |
| medium | osv/GHSA-vx6w-vv9f-6gvg |
uv.lock | [email protected] (PyPI) is affected by GHSA-vx6w-vv9f-6gvg | Dependencies (osv-scanner) |
| medium | osv/GHSA-wqgw-9xfh-qf2g |
uv.lock | [email protected] (PyPI) is affected by GHSA-wqgw-9xfh-qf2g | Dependencies (osv-scanner) |
Tools and coverage
Every analyzer that ran on this commit. A failed or skipped tool is a coverage gap: its share of the score is left out and the coverage figure drops.
| Analyzer | Pillar | Status | Version | Findings | Note |
|---|---|---|---|---|---|
| AI tool configuration | AI provenance | ok | signatures-v1 | 0 | |
| Explicit AI attribution | AI provenance | ok | signatures-v1 | 0 | |
| Release velocity | AI provenance | skipped | — | 0 | |
| Coding style | AI provenance | ok | — | 0 | |
| Commit velocity | AI provenance | ok | prov-4 | 0 | |
| Findings in AI-written lines | AI provenance | ok | git-blame | 0 | |
| Complexity (lizard) | Code quality | ok | lizard 1.25.1 | 0 | |
| Documentation | Code quality | ok | — | 0 | |
| Duplication (jscpd) | Code quality | ok | repotrust-dup-w6 | 0 | |
| Lint | Code quality | ok | opengrep 1.33.1; rules f1d2b562b414 | 39 | |
| Tests and CI | Code quality | ok | — | 0 | |
| Type safety | Code quality | ok | — | 0 | |
| CI workflows (zizmor) | Security | skipped | — | 0 | |
| Dependencies (osv-scanner) | Security | ok | osv-scanner version: 2.7.1 | 52 | |
| Release downloads | Security | ok | — | 0 | |
| Security posture | Security | ok | — | 0 | |
| Package registries | Security | ok | — | 0 | |
| Static analysis (opengrep) | Security | ok | opengrep 1.33.1; rules f1d2b562b414 | 3 | |
| OpenSSF Scorecard | Security | skipped | — | 0 | no published OpenSSF Scorecard result for this repo |
| Secrets (gitleaks) | Security | ok | gitleaks 8.30.1 | 0 |
Score history
Scores from different scoring versions aren't directly comparable.
| Scored | Commit | Scoring | AI provenance | Quality | Security |
|---|---|---|---|---|---|
| 2026-11-14 | e17d00e98b24 | prov-5+qual-2+sec-2 | 1% | 38 | 66 |
| 2026-11-14 | e17d00e98b24 | prov-4+qual-2+sec-2 | 1% | 38 | 66 |
Full text report
- Repository: https://github.com/lihaohong6/Blue-Archive-bot
- Commit:
e17d00e98b2475067edbdbb938f2a697c02fabf7 - Generated: 2026-11-14T14:52:06+00:00
- Scorer 0.1.0, scoring prov-5+qual-2+sec-2, report schema v2
Scores
| Pillar | Score | Signal | Confidence | Coverage |
|---|---|---|---|---|
| AI provenance (estimated AI-generated share) | 1 | possible | 65% | 100% |
| Code quality | 38 | poor | 90% | 100% |
| Security | 66 | weak | 85% | 100% |
AI provenance
Weak signals consistent with AI-assisted development. 1 commit(s) carry explicit AI attribution, too few to characterize the codebase.
- Explicitly attributed share (lower bound): 0.6%
- Unattributed share in AI-consistent velocity bursts: 22.9%
- Estimated AI-generated share: 0.6%
| AI tool | Attributed commits | Lines added |
|---|---|---|
| Claude Code | 1 | 68 |
Current source lines last changed by AI-attributed commits: 68 of 6,048.
Too few lines in one group to compare finding densities.
| Month | Lines added | Attributed to AI |
|---|---|---|
| 2025-03 | 24 | 0% |
| 2025-04 | 215 | 0% |
| 2025-05 | 233 | 0% |
| 2025-07 | 3 | 0% |
| 2025-08 | 35 | 0% |
| 2025-10 | 193 | 0% |
| 2025-11 | 289 | 0% |
| 2026-07 | 78 | 0% |
| 2026-08 | 160 | 0% |
| 2026-09 | 2,095 | 0% |
| 2026-10 | 3,653 | 0% |
| 2026-11 | 68 | 100% |
Evidence
- Claude Code: trailer 'Co-Authored-By: Claude' (e17d00e98b24)
- 2,597 lines of first-party code in ~4.1h (637 lines/hour, 2 commit session) (f07ecf84e41a)
AI provenance describes how code was produced; it is not a quality judgment. Unless attribution is explicit, these are signals consistent with AI generation, not proof. Squash/rebase workflows, imported code, and rewritten history reduce accuracy.
Code quality
Code quality is poor: test-to-source ratio 0.00, no CI test run detected; 23% of function code in complex or long functions; 0% duplicated lines. Weakest area: testing.
| Area | Score |
|---|---|
| Complexity (lizard) | 51 |
| Duplication | 98 |
| Code smells (Opengrep) | 17 |
| Tests and CI | 0 |
| Documentation | 45 |
| Type safety | 40 |
| Process (Scorecard review/maintenance) | n/a |
- Functions: 282; mean complexity 5.4, 90th percentile 11; 14 complex and 2 long functions
- Duplicated lines: 0.3% of 4,813 compared
- Tests: 0 test lines for 6,048 source lines (ratio 0.00); CI test commands: none detected; 0% of recent source commits also change tests
- Docs missing or thin: readme, contributing, changelog
Most complex functions:
- plan_switches in model_viewer/exporter/switches.py: complexity 53, 61 lines
- parse_story in story/story_parser.py: complexity 49, 126 lines
- mark_props in model_viewer/exporter/props.py: complexity 42, 53 lines
- add_renderer in model_viewer/exporter/geometry.py: complexity 36, 71 lines
- write_glb in model_viewer/exporter/glb.py: complexity 35, 124 lines
Security
Security posture is weak: 52 known vulnerabilities in 5 dependencies; 1 high-severity SAST findings. Weakest area: posture.
| Area | Score |
|---|---|
| Secrets (gitleaks, tree + history) | 100 |
| Static analysis (Opengrep) | 88 |
| Vulnerable dependencies (OSV) | 36 |
| CI workflows (zizmor) | n/a |
| Posture (policy, updates, signing, lockfiles) | 0 |
| OpenSSF Scorecard | n/a |
-
Known vulnerabilities: 52 in 5 packages (critical 8, high 30, medium 13, low 0)
-
Posture checks passed: lockfiles; missing: security policy, dependency updates, signed commits
Top findings
| Severity | Finding | Location |
|---|---|---|
| critical | osv/GHSA-9v8h-qqgm-4m35: [email protected] (PyPI) is affected by PYSEC-2026-4322, GHSA-9v8h-qqgm-4m35 |
uv.lock |
| critical | osv/GHSA-6q48-6c7w-9gw2: [email protected] (PyPI) is affected by PYSEC-2026-4320, GHSA-6q48-6c7w-9gw2 |
uv.lock |
| critical | osv/GHSA-5x8w-8jj5-q52h: [email protected] (PyPI) is affected by PYSEC-2026-4330, GHSA-5x8w-8jj5-q52h |
uv.lock |
| critical | osv/GHSA-8g5g-8vmr-9782: [email protected] (PyPI) is affected by PYSEC-2026-4332, GHSA-8g5g-8vmr-9782 |
uv.lock |
| critical | osv/GHSA-v9pv-5gc8-w2m6: [email protected] (PyPI) is affected by PYSEC-2026-4339, GHSA-v9pv-5gc8-w2m6 |
uv.lock |
| critical | osv/GHSA-xvh5-g6gv-559v: [email protected] (PyPI) is affected by PYSEC-2026-4363, GHSA-xvh5-g6gv-559v |
uv.lock |
| critical | osv/GHSA-332p-7hrc-92wf: [email protected] (PyPI) is affected by GHSA-332p-7hrc-92wf |
uv.lock |
| critical | osv/GHSA-w889-685w-c8fh: [email protected] (PyPI) is affected by GHSA-w889-685w-c8fh |
uv.lock |
| high | opengrep/python.lang.security.audit.subprocess-shell-true: Found 'subprocess' function 'run' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use 'shell=False' instead. [confidence medium] |
portrait_spirite.py:146 |
| high | osv/GHSA-27h8-gf7j-v5hc: [email protected] (PyPI) is affected by PYSEC-2026-4326, GHSA-27h8-gf7j-v5hc |
uv.lock |
| high | osv/GHSA-4558-3h8r-v8xp: [email protected] (PyPI) is affected by PYSEC-2026-4327, GHSA-4558-3h8r-v8xp |
uv.lock |
| high | osv/GHSA-4rr5-89j8-mwwm: [email protected] (PyPI) is affected by PYSEC-2026-4328, GHSA-4rr5-89j8-mwwm |
uv.lock |
| high | osv/GHSA-58r4-6rv3-gfh8: [email protected] (PyPI) is affected by PYSEC-2026-4329, GHSA-58r4-6rv3-gfh8 |
uv.lock |
| high | osv/GHSA-7mwm-ghpf-9vrm: [email protected] (PyPI) is affected by PYSEC-2026-4331, GHSA-7mwm-ghpf-9vrm |
uv.lock |
| high | osv/GHSA-cp9v-662q-vvx9: [email protected] (PyPI) is affected by PYSEC-2026-4333, GHSA-cp9v-662q-vvx9 |
uv.lock |
| high | osv/GHSA-pchr-8j38-3x4p: [email protected] (PyPI) is affected by PYSEC-2026-4334, GHSA-pchr-8j38-3x4p |
uv.lock |
| high | osv/GHSA-xgh8-jp6q-p5x8: [email protected] (PyPI) is affected by PYSEC-2026-4335, GHSA-xgh8-jp6q-p5x8 |
uv.lock |
| high | osv/GHSA-g842-9rc4-69pw: [email protected] (PyPI) is affected by PYSEC-2026-4338, GHSA-g842-9rc4-69pw |
uv.lock |
| high | osv/GHSA-3j72-p6qg-6xp7: [email protected] (PyPI) is affected by PYSEC-2026-4341, GHSA-3j72-p6qg-6xp7 |
uv.lock |
| high | osv/GHSA-g4qv-2jxx-769h: [email protected] (PyPI) is affected by PYSEC-2026-4342, GHSA-g4qv-2jxx-769h |
uv.lock |
| high | osv/GHSA-9v9v-9qvf-h2hj: [email protected] (PyPI) is affected by PYSEC-2026-4343, GHSA-9v9v-9qvf-h2hj |
uv.lock |
| high | osv/GHSA-22hg-r758-rrw9: [email protected] (PyPI) is affected by GHSA-22hg-r758-rrw9 |
uv.lock |
| high | osv/GHSA-5xm2-6676-qcp9: [email protected] (PyPI) is affected by GHSA-5xm2-6676-qcp9 |
uv.lock |
| high | osv/GHSA-65qm-jvmh-6pqg: [email protected] (PyPI) is affected by GHSA-65qm-jvmh-6pqg |
uv.lock |
| high | osv/GHSA-78g4-xqwv-q3g8: [email protected] (PyPI) is affected by GHSA-78g4-xqwv-q3g8 |
uv.lock |
Static signals only: the scorer never runs the project's code. Secret findings are pattern matches that were not verified, and secret values are never stored.
Repository profile
- Source lines: 6,048; test lines: 0
| Language | Lines |
|---|---|
| Python | 5,998 |
| JavaScript | 47 |
| Shell | 3 |