RepoTrust

Leaderboard github.com

3b1b/manim

Animation engine for explanatory math videos

  • View repository ↗
  • Python
  • ★ 96,514
  • commit fafa083a4fb2
  • scored 2026-11-14
  • scoring prov-5+qual-2+sec-2

AI provenance

2%

explicit

Confidence
95%
Coverage
100%

Estimated share of AI-generated code. Explicit attribution is a lower bound.

Code quality

66/100

adequate

Confidence
90%
Coverage
100%

Complexity, duplication, lint density, tests, CI, docs and review process.

Security

71/100

adequate

Confidence
85%
Coverage
100%

Secrets, static analysis, vulnerable dependencies, CI and supply-chain posture.

AI provenance

2% explicit

Explicit AI attribution on 2% of first-party code added; an estimated 2% including velocity signals.

How the score is built

  • Explicitly attributed share2%
  • Unattributed share in AI-pace bursts0%
  • Estimated AI-generated share2%
  • AI tool configuration files0
  • Work sessions at AI pace0
  • Releases at AI pace0
  • Coding-style index (1.0+ means possible)0.04

Attributed AI tools

ToolCommitsLines addedFirst seenLast seen
Claude Code7010,9832026-08-032026-09-09

Lines added per month all AI-attributed share

  1. 2015-035,473 · 0% AI
  2. 2015-042,525 · 0% AI
  3. 2015-052,624 · 0% AI
  4. 2015-064,719 · 0% AI
  5. 2015-084,213 · 0% AI
  6. 2015-092,657 · 0% AI
  7. 2015-107,005 · 0% AI
  8. 2015-111,670 · 0% AI
  9. 2015-122,501 · 0% AI
  10. 2016-012,282 · 0% AI
  11. 2016-022,636 · 0% AI
  12. 2016-033,506 · 0% AI
  13. 2016-044,476 · 0% AI
  14. 2016-058,081 · 0% AI
  15. 2016-079,394 · 0% AI
  16. 2016-089,782 · 0% AI
  17. 2016-098,259 · 0% AI
  18. 2016-102,776 · 0% AI
  19. 2016-1110,403 · 0% AI
  20. 2016-125,092 · 0% AI
  21. 2017-019,999 · 0% AI
  22. 2017-029,243 · 0% AI
  23. 2017-0312,953 · 0% AI
  24. 2017-0415,356 · 0% AI
  25. 2017-0510,493 · 0% AI
  26. 2017-068,201 · 0% AI
  27. 2017-076,876 · 0% AI
  28. 2017-088,661 · 0% AI
  29. 2017-099,196 · 0% AI
  30. 2017-1010,048 · 0% AI
  31. 2017-112,627 · 0% AI
  32. 2017-127,620 · 0% AI
  33. 2018-0124,831 · 0% AI
  34. 2018-0217,786 · 0% AI
  35. 2018-0320,153 · 0% AI
  36. 2018-0420,518 · 0% AI
  37. 2018-0514,871 · 0% AI
  38. 2018-066,426 · 0% AI
  39. 2018-077,337 · 0% AI
  40. 2018-0812,662 · 0% AI
  41. 2018-092,484 · 0% AI
  42. 2018-101,271 · 0% AI
  43. 2018-116,495 · 0% AI
  44. 2018-123,295 · 0% AI
  45. 2019-018,983 · 0% AI
  46. 2019-0211,150 · 0% AI
  47. 2019-0310,624 · 0% AI
  48. 2019-046,574 · 0% AI
  49. 2019-053,236 · 0% AI
  50. 2019-0631,491 · 0% AI
  51. 2019-074,384 · 0% AI
  52. 2019-082,812 · 0% AI
  53. 2019-093,764 · 0% AI
  54. 2019-102,050 · 0% AI
  55. 2019-112,875 · 0% AI
  56. 2019-126,343 · 0% AI
  57. 2020-01218 · 0% AI
  58. 2020-026,120 · 0% AI
  59. 2020-0310,722 · 0% AI
  60. 2020-043,497 · 0% AI
  61. 2020-055,013 · 0% AI
  62. 2020-069,095 · 0% AI
  63. 2020-07207 · 0% AI
  64. 2020-0810,984 · 0% AI
  65. 2020-0939 · 0% AI
  66. 2020-103 · 0% AI
  67. 2020-11816 · 0% AI
  68. 2020-1210,252 · 0% AI
  69. 2021-015,222 · 0% AI
  70. 2021-022,142 · 0% AI
  71. 2021-03153 · 0% AI
  72. 2021-04111 · 0% AI
  73. 2021-051 · 0% AI
  74. 2021-06322 · 0% AI
  75. 2021-0778 · 0% AI
  76. 2021-08569 · 0% AI
  77. 2021-091,202 · 0% AI
  78. 2021-10299 · 0% AI
  79. 2021-111,889 · 0% AI
  80. 2021-12554 · 0% AI
  81. 2022-011,105 · 0% AI
  82. 2022-024,449 · 0% AI
  83. 2022-034,954 · 0% AI
  84. 2022-046,220 · 0% AI
  85. 2022-054,277 · 0% AI
  86. 2022-06257 · 0% AI
  87. 2022-0719 · 0% AI
  88. 2022-081,097 · 0% AI
  89. 2022-0966 · 0% AI
  90. 2022-101 · 0% AI
  91. 2022-11214 · 0% AI
  92. 2022-126,573 · 0% AI
  93. 2023-014,266 · 0% AI
  94. 2023-02737 · 0% AI
  95. 2023-0318 · 0% AI
  96. 2023-041 · 0% AI
  97. 2023-050 · 0% AI
  98. 2023-06140 · 0% AI
  99. 2023-0865 · 0% AI
  100. 2023-09128 · 0% AI
  101. 2023-101 · 0% AI
  102. 2023-1126 · 0% AI
  103. 2023-121 · 0% AI
  104. 2024-01149 · 0% AI
  105. 2024-02295 · 0% AI
  106. 2024-03439 · 0% AI
  107. 2024-041 · 0% AI
  108. 2024-052 · 0% AI
  109. 2024-066 · 0% AI
  110. 2024-0720 · 0% AI
  111. 2024-081,207 · 0% AI
  112. 2024-09282 · 0% AI
  113. 2024-10112 · 0% AI
  114. 2024-11492 · 0% AI
  115. 2024-123,022 · 0% AI
  116. 2025-011 · 0% AI
  117. 2025-0255 · 0% AI
  118. 2025-03106 · 0% AI
  119. 2025-06569 · 0% AI
  120. 2025-10224 · 0% AI
  121. 2026-02316 · 0% AI
  122. 2026-03157 · 0% AI
  123. 2026-07262 · 0% AI
  124. 2026-0810,555 · 96% AI
  125. 2026-09868 · 100% AI

Findings in AI-attributed lines vs the rest

From git blame: 4,446 lines trace to AI-attributed commits, 22,491 to others. Reported, not scored.

Findings per 1,000 linesAI-attributedOtherRatio
Code quality0.681.510.45×
Security0.000.620.00×

Evidence by analyzer

Explicit AI attributionok26 items
attributed_commit_share
1.2%
attributed_commits
70
attributed_loc
10,983
attributed_loc_share
1.9%
commits
5,603
effective_loc
567,025
tools_detected
1
AI tool configurationok
artifacts
0
tools_configured
0
workflow_agents
0
Commit velocityok
excluded_import_loc
22,262
flagged_loc
0
flagged_loc_share
0.0%
flagged_units
0
max_loc_per_hour
4,940.60
measured_loc
544,763
median_loc_per_hour
85.23
pr_timed_units
116
pre_ai_era_burst_loc
80,125
pre_ai_era_bursts
18
pre_ai_era_measured_loc
486,411
work_units
2,232
Release velocityok
flagged_releases
0
max_loc_per_day
1,077.50
releases
20
Coding styleok1 item
count:assistant_voice
0
count:emoji_in_code
0
count:narrated_steps
1
count:placeholder
0
files:assistant_voice
0
files:emoji_in_code
0
files:narrated_steps
1
files:placeholder
0
index
0.04
lines_scanned
26,937
per_kloc:assistant_voice
0
per_kloc:emoji_in_code
0
per_kloc:narrated_steps
0.04
per_kloc:placeholder
0
Findings in AI-written linesok
ai_lines
4,446
blame_failures
0
files_blamed
108
other_lines
22,491
quality:ai_findings
3
quality:ai_per_kloc
0.68
quality:other_findings
34
quality:other_per_kloc
1.51
quality:ratio
0.45
security:ai_findings
0
security:ai_per_kloc
0
security:other_findings
14
security:other_per_kloc
0.62
security:ratio
0

Code quality

66 adequate

Code quality is adequate: test-to-source ratio 0.05, no CI test run detected; 3% of function code in complex or long functions; 1% duplicated lines. Weakest area: testing.

How the score is built

  • Complexity92
  • Duplication93
  • Lint and smells54
  • Tests and CI40
  • Documentation65
  • Type safety40
  • Review process75

Evidence by analyzer

Complexity (lizard)ok5 items
complex_functions
3
function_nloc
17,081
functions
1,964
long_functions
3
many_param_functions
70
mean_ccn
2.09
p90_ccn
4
risky_nloc_share
2.9%
Duplication (jscpd)ok10 items
compared_lines
20,013
duplicated_lines
244
duplicated_share
1.2%
files
108
Lintok
category:best-practice
6
category:correctness
18
category:maintainability
13
findings
37
scanned_lines
26,937
weighted_findings
67
Tests and CIok2 items
  • CI config: .github/workflows/docs.yml .github/workflows/docs.yml
  • CI config: .github/workflows/publish.yml .github/workflows/publish.yml
check:ci_present
yes
check:ci_runs_lint
no
check:ci_runs_tests
no
check:has_tests
yes
check:test_ratio
no
check:tests_cochange
no
ci_files
2
cochange_commits
264
cochange_share
4.9%
source_lines
26,937
test_lines
1,461
test_ratio
0.05
Documentationok2 items
  • README.md README.md
  • LICENSE.md LICENSE.md
check:changelog
no
check:contributing
no
check:license
yes
check:readme
yes
readme_lines
134
Type safetyok
check:low_escape_density
yes
check:strict_config
no
escapes
78
escapes_per_kloc
2.90

Security

71 adequate

Security posture is adequate: 8 high-severity SAST findings; 5 high-severity workflow issues. Weakest area: posture.

How the score is built

  • Secrets100
  • Static analysis (SAST)90
  • Vulnerable dependencies100
  • CI workflows33
  • Security posture0
  • OpenSSF Scorecard29

Evidence by analyzer

OpenSSF Scorecardok12 items
aggregate
4.30
check:Binary-Artifacts
yes
check:CII-Best-Practices
no
check:Code-Review
yes
check:Dangerous-Workflow
yes
check:Fuzzing
no
check:License
yes
check:Maintained
yes
check:Pinned-Dependencies
no
check:SAST
no
check:Security-Policy
no
check:Signed-Releases
no
check:Token-Permissions
no
Package registriesok
checked
35
declared
35
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
14
findings_high
8
findings_low
0
findings_medium
6
parse_errors
0
scanned_lines
26,937
weighted_findings
8.55
Dependencies (osv-scanner)ok
penalty
0
vulnerabilities
0
vulnerable_packages
0
vulns_critical
0
vulns_high
0
vulns_low
0
vulns_medium
0
vulns_unknown
0
CI workflows (zizmor)ok
findings
10
findings_high
5
findings_low
2
findings_medium
3
penalty
66.30
workflows
2
Security postureok
check:dependency_updates
no
check:lockfiles
yes
check:security_policy
no
check:signed_commits
no
signed_commit_share
42.5%
unpinned_manifests
0
Release downloadsok4 items
binary_assets
4
signals
1
suspicious
0

Findings

28 high31 medium1 low1 info

SeverityRuleLocationMessageTool
high opengrep/python.lang.correctness.return-in-init manimlib/animation/indication.py:316 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/animation/numbers.py:47 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/animation/numbers.py:62 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/animation/specialized.py:44 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/mobject/changing.py:121 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/mobject/changing.py:49 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/mobject/functions.py:105 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/mobject/interactive.py:325 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/mobject/number_line.py:294 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/mobject/number_line.py:302 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/mobject/number_line.py:303 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/mobject/svg/drawings.py:216 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/mobject/three_dimensions.py:383 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.correctness.return-in-init manimlib/mobject/vector_field.py:470 `return` should never appear inside a class __init__ function. This will cause a runtime error. Lint
high opengrep/python.lang.best-practice.open-never-closed manimlib/scene/scene_file_writer.py:366 file object opened without corresponding close Lint
high zizmor/unpinned-uses .github/workflows/docs.yml:18 unpinned action reference [confidence high] CI workflows (zizmor)
high zizmor/unpinned-uses .github/workflows/docs.yml:21 unpinned action reference [confidence high] CI workflows (zizmor)
high zizmor/unpinned-uses .github/workflows/docs.yml:37 unpinned action reference [confidence high] CI workflows (zizmor)
high zizmor/unpinned-uses .github/workflows/publish.yml:17 unpinned action reference [confidence high] CI workflows (zizmor)
high zizmor/unpinned-uses .github/workflows/publish.yml:20 unpinned action reference [confidence high] CI workflows (zizmor)
high opengrep/python.lang.security.use-defused-xml manimlib/mobject/svg/svg_mobject.py:3 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... Static analysis (opengrep)
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit manimlib/scene/scene_file_writer.py:241 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... Static analysis (opengrep)
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit manimlib/scene/scene_file_writer.py:344 Detected subprocess function 'call' 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... Static analysis (opengrep)
high opengrep/python.lang.security.audit.dangerous-spawn-process-audit manimlib/scene/scene_file_writer.py:378 Found dynamic content when spawning a process. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here. [confidence low] Static analysis (opengrep)
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit manimlib/scene/scene_file_writer.py:394 Detected subprocess function 'call' 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... Static analysis (opengrep)
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit manimlib/utils/sounds.py:26 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... Static analysis (opengrep)
high opengrep/python.lang.security.audit.subprocess-shell-true manimlib/utils/sounds.py:28 Found 'subprocess' function 'Popen' 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... Static analysis (opengrep)
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit manimlib/utils/tex_file_writing.py:113 Detected subprocess function 'run' 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... Static analysis (opengrep)
medium opengrep/python.lang.best-practice.unspecified-open-encoding manimlib/config.py:338 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.is-function-without-parentheses manimlib/extract_scene.py:182 Is "is_reload" a function or an attribute? If it is a function, you may have meant run_config.is_reload() because run_config.is_reload is always true. Lint
medium opengrep/python.lang.maintainability.is-function-without-parentheses manimlib/mobject/mobject.py:2163 Is "is_chaining" a function or an attribute? If it is a function, you may have meant self.is_chaining() because self.is_chaining is always true. Lint
medium opengrep/python.lang.maintainability.is-function-without-parentheses manimlib/mobject/mobject.py:2173 Is "is_chaining" a function or an attribute? If it is a function, you may have meant self.is_chaining() because self.is_chaining is always true. Lint
medium opengrep/python.lang.maintainability.is-function-without-parentheses manimlib/mobject/mobject.py:2188 Is "is_chaining" a function or an attribute? If it is a function, you may have meant self.is_chaining() because self.is_chaining is always true. Lint
medium opengrep/python.lang.best-practice.unspecified-open-encoding manimlib/renderer/shader_source.py:118 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.common-mistakes.string-concat-in-list manimlib/renderer/shader_source.py:93 Detected strings that are implicitly concatenated inside a list. Python will implicitly concatenate strings when not explicitly delimited. Was this supposed to be individual elements of the list? Lint
medium opengrep/python.lang.correctness.common-mistakes.string-concat-in-list manimlib/renderer/shader_source.py:96 Detected strings that are implicitly concatenated inside a list. Python will implicitly concatenate strings when not explicitly delimited. Was this supposed to be individual elements of the list? Lint
medium opengrep/python.lang.maintainability.is-function-without-parentheses manimlib/scene/interactive_scene.py:124 Is "is_selecting" a function or an attribute? If it is a function, you may have meant self.is_selecting() because self.is_selecting is always true. Lint
medium opengrep/python.lang.maintainability.is-function-without-parentheses manimlib/scene/interactive_scene.py:125 Is "is_grabbing" a function or an attribute? If it is a function, you may have meant self.is_grabbing() because self.is_grabbing is always true. Lint
medium opengrep/python.lang.maintainability.is-function-without-parentheses manimlib/scene/interactive_scene.py:401 Is "is_selecting" a function or an attribute? If it is a function, you may have meant self.is_selecting() because self.is_selecting is always true. Lint
medium opengrep/python.lang.maintainability.is-function-without-parentheses manimlib/scene/interactive_scene.py:408 Is "is_selecting" a function or an attribute? If it is a function, you may have meant self.is_selecting() because self.is_selecting is always true. Lint
medium opengrep/python.lang.maintainability.is-function-without-parentheses manimlib/scene/interactive_scene.py:431 Is "is_grabbing" a function or an attribute? If it is a function, you may have meant self.is_grabbing() because self.is_grabbing is always true. Lint
medium opengrep/python.lang.maintainability.is-function-without-parentheses manimlib/scene/interactive_scene.py:547 Is "is_grabbing" a function or an attribute? If it is a function, you may have meant self.is_grabbing() because self.is_grabbing is always true. Lint
medium opengrep/python.lang.maintainability.is-function-without-parentheses manimlib/scene/interactive_scene.py:610 Is "is_grabbing" a function or an attribute? If it is a function, you may have meant self.is_grabbing() because self.is_grabbing is always true. Lint
medium opengrep/python.lang.maintainability.is-function-without-parentheses manimlib/scene/scene.py:722 Is "is_closing" a function or an attribute? If it is a function, you may have meant self.window.is_closing() because self.window.is_closing is always true. Lint
medium opengrep/python.lang.maintainability.is-function-without-parentheses manimlib/scene/scene_embed.py:179 Is "is_reload" a function or an attribute? If it is a function, you may have meant run_config.is_reload() because run_config.is_reload is always true. Lint
medium opengrep/python.lang.correctness.unchecked-subprocess-call manimlib/scene/scene_file_writer.py:344 This is not checking the return value of this subprocess call; if it fails no exception will be raised. Consider subprocess.check_call() instead Lint
medium opengrep/python.lang.best-practice.unspecified-open-encoding manimlib/scene/scene_file_writer.py:366 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 manimlib/scene/scene_file_writer.py:393 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.unchecked-subprocess-call manimlib/scene/scene_file_writer.py:394 This is not checking the return value of this subprocess call; if it fails no exception will be raised. Consider subprocess.check_call() instead Lint
medium opengrep/python.lang.best-practice.unspecified-open-encoding manimlib/utils/svg_export.py:67 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 zizmor/excessive-permissions .github/workflows/docs.yml:12 overly broad permissions [confidence medium] CI workflows (zizmor)
medium zizmor/artipacked .github/workflows/docs.yml:17 credential persistence through GitHub Actions artifacts [confidence low] CI workflows (zizmor)
medium zizmor/excessive-permissions .github/workflows/publish.yml:8 overly broad permissions [confidence medium] CI workflows (zizmor)
medium opengrep/python.lang.security.audit.exec-detected manimlib/extract_scene.py:178 Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by... Static analysis (opengrep)
medium opengrep/python.lang.security.audit.exec-detected manimlib/extract_scene.py:24 Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by... Static analysis (opengrep)
medium opengrep/python.lang.security.deserialization.avoid-pickle manimlib/mobject/mobject.py:635 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 manimlib/mobject/mobject.py:638 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.audit.regex_dos manimlib/mobject/svg/text_mobject.py:232 Detected usage of re.compile with an inefficient regular expression. This can lead to regular expression denial of service, which can result in service down time. Instead, check all regexes or use safer alternatives such as pyre2.... Static analysis (opengrep)
medium opengrep/python.lang.security.audit.dynamic-urllib-use-detected manimlib/utils/file_ops.py:41 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... Static analysis (opengrep)
low zizmor/artipacked .github/workflows/publish.yml:17 credential persistence through GitHub Actions artifacts [confidence low] CI workflows (zizmor)
info zizmor/use-trusted-publishing .github/workflows/publish.yml:37 prefer trusted publishing for authentication [confidence high] CI workflows (zizmor)

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.

AnalyzerPillarStatusVersionFindingsNote
AI tool configurationAI provenanceoksignatures-v10
Explicit AI attributionAI provenanceoksignatures-v10
Release velocityAI provenanceokprov-50
Coding styleAI provenanceok—0
Commit velocityAI provenanceokprov-50
Findings in AI-written linesAI provenanceokgit-blame0
Complexity (lizard)Code qualityoklizard 1.25.10
DocumentationCode qualityok—0
Duplication (jscpd)Code qualityokrepotrust-dup-w60
LintCode qualityokopengrep 1.33.1; rules f1d2b562b41437
Tests and CICode qualityok—0
Type safetyCode qualityok—0
CI workflows (zizmor)Securityokzizmor 1.32.010
Dependencies (osv-scanner)Securityokosv-scanner version: 2.7.10
Release downloadsSecurityok—0
Security postureSecurityok—0
Package registriesSecurityok—0
Static analysis (opengrep)Securityokopengrep 1.33.1; rules f1d2b562b41414
OpenSSF ScorecardSecurityokscorecard v5.6.00
Secrets (gitleaks)Securityokgitleaks 8.30.10

Score history

ScoredCommitScoringAI provenanceQualitySecurity
2026-11-14fafa083a4fb2prov-5+qual-2+sec-22%6671

Embed a badge

Maintainers can show these in a README. Badges update when the repository is re-scored.

[![RepoTrust ai](https://repotrust.synapticcyber.com/badge/github.com/3b1b/manim/ai.svg)](https://repotrust.synapticcyber.com/r/github.com/3b1b/manim/)
[![RepoTrust quality](https://repotrust.synapticcyber.com/badge/github.com/3b1b/manim/quality.svg)](https://repotrust.synapticcyber.com/r/github.com/3b1b/manim/)
[![RepoTrust security](https://repotrust.synapticcyber.com/badge/github.com/3b1b/manim/security.svg)](https://repotrust.synapticcyber.com/r/github.com/3b1b/manim/)
Full text report
  • Repository: https://github.com/3b1b/manim
  • Commit: fafa083a4fb274bba9cabde0b6e2f50ba6da0622
  • Generated: 2026-11-14T15:06:19+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) 2 explicit 95% 100%
Code quality 66 adequate 90% 100%
Security 71 adequate 85% 100%

AI provenance

Explicit AI attribution on 2% of first-party code added; an estimated 2% including velocity signals.

  • Explicitly attributed share (lower bound): 1.9%
  • Unattributed share in AI-consistent velocity bursts: 0.0%
  • Estimated AI-generated share: 1.9%
AI tool Attributed commits Lines added
Claude Code 70 10,983

Current source lines last changed by AI-attributed commits: 4,446 of 26,937.

Findings per 1,000 lines AI-attributed Other Ratio
Quality 0.675 1.512 0.45x
Security 0.0 0.622 0.0x
  • Stylometry index: 0.04 per 1,000 lines (narrated steps 1, placeholders 0, assistant phrasing 0, emoji 0). Reported as a signal, not scored.
Month Lines added Attributed to AI
2024-11 492 0%
2024-12 3,022 0%
2025-01 1 0%
2025-02 55 0%
2025-03 106 0%
2025-06 569 0%
2025-10 224 0%
2026-02 316 0%
2026-03 157 0%
2026-07 262 0%
2026-08 10,555 96%
2026-09 868 100%

Evidence

  • Claude Code: trailer 'Co-Authored-By: Claude' (fafa083a4fb2)
  • Claude Code: trailer 'Co-authored-by: Claude' (013d97626c45)
  • Claude Code: trailer 'Co-Authored-By: Claude' (31290eb25b2f)
  • Claude Code: trailer 'Co-Authored-By: Claude' (1f105f90201a)
  • Claude Code: trailer 'Co-authored-by: Claude' (53dcadca091e)
  • Claude Code: trailer 'Co-Authored-By: Claude' (ef8e9b802f0b)
  • Claude Code: trailer 'Co-Authored-By: Claude' (a58e6d38dc54)
  • Claude Code: trailer 'Co-Authored-By: Claude' (bf78e8b94b6f)
  • Claude Code: trailer 'Co-Authored-By: Claude' (8bd32c7aa6d4)
  • Claude Code: trailer 'Co-Authored-By: Claude' (2c53c13a34b5)
  • Claude Code: trailer 'Co-Authored-By: Claude' (024db54580e0)
  • Claude Code: trailer 'Co-Authored-By: Claude' (d7726853edf6)
  • Claude Code: trailer 'Co-Authored-By: Claude' (bfe798af299f)
  • Claude Code: trailer 'Co-Authored-By: Claude' (793109b84ca7)
  • Claude Code: trailer 'Co-Authored-By: Claude' (b409d777f782)

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 adequate: test-to-source ratio 0.05, no CI test run detected; 3% of function code in complex or long functions; 1% duplicated lines. Weakest area: testing.

Area Score
Complexity (lizard) 92
Duplication 93
Code smells (Opengrep) 54
Tests and CI 40
Documentation 65
Type safety 40
Process (Scorecard review/maintenance) 75
  • Functions: 1,964; mean complexity 2.1, 90th percentile 4; 3 complex and 3 long functions
  • Duplicated lines: 1.2% of 20,013 compared
  • Tests: 1,461 test lines for 26,937 source lines (ratio 0.05); CI test commands: none detected; 5% of recent source commits also change tests
  • Docs missing or thin: contributing, changelog

Most complex functions:

Security

Security posture is adequate: 8 high-severity SAST findings; 5 high-severity workflow issues. Weakest area: posture.

Area Score
Secrets (gitleaks, tree + history) 100
Static analysis (Opengrep) 90
Vulnerable dependencies (OSV) 100
CI workflows (zizmor) 33
Posture (policy, updates, signing, lockfiles) 0
OpenSSF Scorecard 29
  • Posture checks passed: lockfiles; missing: security policy, dependency updates, signed commits
  • OpenSSF Scorecard aggregate: 4.3/10 (published 2026-11-09)

Top findings

Severity Finding Location
high opengrep/python.lang.security.use-defused-xml: 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] manimlib/mobject/svg/svg_mobject.py:3
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit: 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] manimlib/scene/scene_file_writer.py:241
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit: Detected subprocess function 'call' 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] manimlib/scene/scene_file_writer.py:344
high opengrep/python.lang.security.audit.dangerous-spawn-process-audit: Found dynamic content when spawning a process. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here. [confidence low] manimlib/scene/scene_file_writer.py:378
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit: Detected subprocess function 'call' 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] manimlib/scene/scene_file_writer.py:394
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit: 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] manimlib/utils/sounds.py:26
high opengrep/python.lang.security.audit.subprocess-shell-true: Found 'subprocess' function 'Popen' 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] manimlib/utils/sounds.py:28
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit: Detected subprocess function 'run' 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] manimlib/utils/tex_file_writing.py:113
high zizmor/unpinned-uses: unpinned action reference [confidence high] .github/workflows/docs.yml:18
high zizmor/unpinned-uses: unpinned action reference [confidence high] .github/workflows/docs.yml:21
high zizmor/unpinned-uses: unpinned action reference [confidence high] .github/workflows/docs.yml:37
high zizmor/unpinned-uses: unpinned action reference [confidence high] .github/workflows/publish.yml:17
high zizmor/unpinned-uses: unpinned action reference [confidence high] .github/workflows/publish.yml:20
medium opengrep/python.lang.security.audit.exec-detected: Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources. [confidence low] manimlib/extract_scene.py:24
medium opengrep/python.lang.security.audit.exec-detected: Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources. [confidence low] manimlib/extract_scene.py:178
medium opengrep/python.lang.security.deserialization.avoid-pickle: 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 text-based serialization format. [confidence low] manimlib/mobject/mobject.py:635
medium opengrep/python.lang.security.deserialization.avoid-pickle: 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 text-based serialization format. [confidence low] manimlib/mobject/mobject.py:638
medium opengrep/python.lang.security.audit.regex_dos: Detected usage of re.compile with an inefficient regular expression. This can lead to regular expression denial of service, which can result in service down time. Instead, check all regexes or use safer alternatives such as pyre2. [confidence low] manimlib/mobject/svg/text_mobject.py:232
medium opengrep/python.lang.security.audit.dynamic-urllib-use-detected: 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] manimlib/utils/file_ops.py:41
medium zizmor/artipacked: credential persistence through GitHub Actions artifacts [confidence low] .github/workflows/docs.yml:17
medium zizmor/excessive-permissions: overly broad permissions [confidence medium] .github/workflows/docs.yml:12
medium zizmor/excessive-permissions: overly broad permissions [confidence medium] .github/workflows/publish.yml:8
low zizmor/artipacked: credential persistence through GitHub Actions artifacts [confidence low] .github/workflows/publish.yml:17
info zizmor/use-trusted-publishing: prefer trusted publishing for authentication [confidence high] .github/workflows/publish.yml:37

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.

Distribution signals

Signals consistent with a repository that exists to distribute a download. They are heuristics, not a verdict; release files were not downloaded or inspected.

Repository profile

  • Source lines: 26,937; test lines: 1,461
Language Lines
Python 28,398