RepoTrust

Leaderboard github.com

DietrichGebert/ponytail

Makes your AI agent think like the laziest senior dev in the room. The best code is the code you never wrote.

  • View repository ↗
  • JavaScript
  • ★ 190,687
  • commit 96608e078b2d
  • scored 2026-11-14
  • scoring prov-5+qual-2+sec-2

AI provenance

30%

explicit

Confidence
95%
Coverage
100%

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

Code quality

68/100

adequate

Confidence
90%
Coverage
100%

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

Security

68/100

weak

Confidence
85%
Coverage
100%

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

AI provenance

30% explicit

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

How the score is built

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

Attributed AI tools

ToolCommitsLines addedFirst seenLast seen
Claude Code983,8572026-06-122026-10-29
GitHub Copilot coding agent21302026-06-152026-10-03
OpenAI Codex3982026-06-202026-10-05
Cursor agent3572026-06-152026-10-03
Devin192026-06-262026-06-26

Lines added per month all AI-attributed share

  1. 2026-065,741 · 57% AI
  2. 2026-071,083 · 25% AI
  3. 2026-0892 · 0% AI
  4. 2026-09610 · 0% AI
  5. 2026-106,183 · 8% AI

Findings in AI-attributed lines vs the rest

From git blame: 2,373 lines trace to AI-attributed commits, 4,923 to others. Reported, not scored.

Findings per 1,000 linesAI-attributedOtherRatio
Code quality4.219.340.45×
Security5.909.950.59×

Evidence by analyzer

Explicit AI attributionok30 items
attributed_commit_share
29.4%
attributed_commits
106
attributed_loc
4,039
attributed_loc_share
29.5%
commits
361
effective_loc
13,709
tools_detected
5
AI tool configurationok5 items
artifacts
5
earliest_adoption
2026-06-12
tools_configured
5
workflow_agents
0
Commit velocityok
excluded_import_loc
0
flagged_loc
0
flagged_loc_share
0.0%
flagged_units
0
max_loc_per_hour
424.52
measured_loc
13,709
median_loc_per_hour
35.75
pr_timed_units
190
pre_ai_era_burst_loc
0
pre_ai_era_bursts
0
pre_ai_era_measured_loc
0
work_units
197
Release velocityok
flagged_releases
0
max_loc_per_day
6,311.50
releases
28
Coding styleok
count:assistant_voice
0
count:emoji_in_code
3
count:narrated_steps
0
count:placeholder
0
files:assistant_voice
0
files:emoji_in_code
2
files:narrated_steps
0
files:placeholder
0
index
0.21
lines_scanned
7,296
per_kloc:assistant_voice
0
per_kloc:emoji_in_code
0.41
per_kloc:narrated_steps
0
per_kloc:placeholder
0
Findings in AI-written linesok
ai_lines
2,373
blame_failures
0
files_blamed
38
other_lines
4,923
quality:ai_findings
10
quality:ai_per_kloc
4.21
quality:other_findings
46
quality:other_per_kloc
9.34
quality:ratio
0.45
security:ai_findings
14
security:ai_per_kloc
5.90
security:other_findings
49
security:other_per_kloc
9.95
security:ratio
0.59

Code quality

68 adequate

Code quality is adequate: test-to-source ratio 0.63, CI runs tests; 20% of function code in complex or long functions; 2% duplicated lines. Weakest area: lint.

How the score is built

  • Complexity55
  • Duplication90
  • Lint and smells28
  • Tests and CI90
  • Documentation80
  • Type safety40
  • Review processnot measured

Evidence by analyzer

Complexity (lizard)ok10 items
complex_functions
14
function_nloc
3,612
functions
460
long_functions
1
many_param_functions
1
mean_ccn
3.97
p90_ccn
8
risky_nloc_share
19.8%
Duplication (jscpd)ok5 items
compared_lines
5,950
duplicated_lines
103
duplicated_share
1.7%
files
38
Lintok
category:best-practice
6
category:correctness
31
category:maintainability
19
findings
56
scanned_lines
7,272
weighted_findings
37.50
Tests and CIok3 items
  • CI config: .github/workflows/publish.yml .github/workflows/publish.yml
  • CI config: .github/workflows/test.yml .github/workflows/test.yml
  • CI runs tests (npm test)
check:ci_present
yes
check:ci_runs_lint
no
check:ci_runs_tests
yes
check:has_tests
yes
check:test_ratio
yes
check:tests_cochange
yes
ci_files
2
cochange_commits
148
cochange_share
66.9%
source_lines
7,296
test_lines
4,563
test_ratio
0.63
Documentationok3 items
  • README.md README.md
  • LICENSE LICENSE
  • .github/CONTRIBUTING.md .github/CONTRIBUTING.md
check:changelog
no
check:contributing
yes
check:license
yes
check:readme
yes
readme_lines
163
Type safetyok
check:low_escape_density
yes
check:strict_config
no
escapes
10
escapes_per_kloc
2.23

Security

68 weak

Security posture is weak: 10 high-severity SAST findings; 1 high-severity workflow issues. Weakest area: posture.

How the score is built

  • Secrets100
  • Static analysis (SAST)37
  • Vulnerable dependenciesnot measured
  • CI workflows88
  • Security posture20
  • OpenSSF Scorecardnot measured

Evidence by analyzer

OpenSSF Scorecardskipped

no published OpenSSF Scorecard result for this repo

Package registriesskipped

no registry dependencies declared

Secrets (gitleaks)ok
secrets_current
0
secrets_history
0
secrets_low_confidence
0
secrets_nonprod
0
Static analysis (opengrep)ok
findings
63
findings_high
10
findings_low
0
findings_medium
53
parse_errors
0
scanned_lines
7,272
weighted_findings
20.75
Dependencies (osv-scanner)skipped
CI workflows (zizmor)ok
findings
5
findings_high
1
findings_low
2
findings_medium
2
penalty
8
workflows
2
Security postureok2 items
  • package.json has no lockfile alongside it (unpinned dependencies) package.json
  • pi-extension/package.json has no lockfile alongside it (unpinned dependencies) pi-extension/package.json
check:dependency_updates
no
check:lockfiles
no
check:security_policy
no
check:signed_commits
yes
signed_commit_share
96.0%
unpinned_manifests
2
Release downloadsok
binary_assets
0
signals
0
suspicious
0

Findings

13 high79 medium32 low

SeverityRuleLocationMessageTool
high opengrep/python.lang.best-practice.arbitrary-sleep benchmarks/agentic/tasks.py:552 time.sleep() call; did you mean to leave this in? Lint
high opengrep/python.lang.best-practice.arbitrary-sleep benchmarks/agentic/tasks.py:567 time.sleep() call; did you mean to leave this in? Lint
high zizmor/cache-poisoning .github/workflows/publish.yml:23 runtime artifacts potentially vulnerable to a cache poisoning attack [confidence low] CI workflows (zizmor)
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit benchmarks/agentic/judge.py:70 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)
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit benchmarks/agentic/run.py:167 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)
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit benchmarks/agentic/run.py:269 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 benchmarks/agentic/run.py:330 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)
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit benchmarks/agentic/run.py:381 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 benchmarks/agentic/run.py:460 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)
high opengrep/python.lang.security.audit.dangerous-subprocess-use-audit benchmarks/agentic/tasks.py:544 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 benchmarks/agentic/tasks.py:852 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)
high opengrep/javascript.lang.security.detect-child-process benchmarks/correctness.js:50 Detected calls to child_process from a function argument `cmd`. This could lead to a command injection if the input is user controllable. Try to avoid calls to child_process, and if it is needed ensure user input is correctly sanitized... Static analysis (opengrep)
high opengrep/javascript.lang.security.audit.spawn-shell-true scripts/publish-openclaw-skills.js:64 Found '$SPAWN' 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... Static analysis (opengrep)
medium opengrep/javascript.lang.best-practice.lazy-load-module .opencode/plugins/ponytail-frontmatter.cjs:14 Lazy loading can complicate code bundling if care is not taken, also `require`s are run synchronously by Node.js. If they are called from within a function, it may block other requests from being handled at a more critical time. The... Lint
medium opengrep/javascript.lang.best-practice.lazy-load-module .opencode/plugins/ponytail-frontmatter.cjs:52 Lazy loading can complicate code bundling if care is not taken, also `require`s are run synchronously by Node.js. If they are called from within a function, it may block other requests from being handled at a more critical time. The... Lint
medium opengrep/javascript.lang.correctness.no-replaceall .opencode/plugins/ponytail.mjs:116 The string method replaceAll is not supported in all versions of javascript, and is not supported by older browser versions. Consider using replace() with a regex as the first argument instead like mystring.replace(/bad/g, "good")... Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/compare.py:21 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/compare.py:22 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/compare.py:23 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/compare.py:24 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/compare.py:25 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/compare.py:26 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/compare.py:27 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/compare.py:28 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/compare.py:29 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/compare.py:30 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/compare.py:31 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/run.py:36 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/run.py:37 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/run.py:38 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/run.py:39 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/run.py:40 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/run.py:41 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/run.py:42 `return` only makes sense inside a function Lint
medium opengrep/python.lang.maintainability.return-not-in-function benchmarks/agentic/run.py:43 `return` only makes sense inside a function Lint
medium opengrep/typescript.react.best-practice.react-props-spreading hooks/band/register.tsx:453 It's best practice to explicitly pass props to an HTML component rather than use the spread operator. The spread operator risks passing invalid HTML props to an HTML element, which can cause console warnings or worse, give malicious... Lint
medium opengrep/typescript.react.best-practice.react-props-spreading hooks/band/register.tsx:480 It's best practice to explicitly pass props to an HTML component rather than use the spread operator. The spread operator risks passing invalid HTML props to an HTML element, which can cause console warnings or worse, give malicious... Lint
medium zizmor/artipacked .github/workflows/publish.yml:22 credential persistence through GitHub Actions artifacts [confidence low] CI workflows (zizmor)
medium zizmor/artipacked .github/workflows/test.yml:16 credential persistence through GitHub Actions artifacts [confidence low] CI workflows (zizmor)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename .opencode/plugins/ponytail-frontmatter.cjs:15 Detected that function argument `filePath` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename .opencode/plugins/ponytail-frontmatter.cjs:53 Detected that function argument `filePath` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/python.lang.security.audit.dynamic-urllib-use-detected benchmarks/agentic/judge.py:85 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)
medium opengrep/python.lang.security.audit.dynamic-urllib-use-detected benchmarks/agentic/tasks.py:541 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)
medium opengrep/python.lang.security.audit.non-literal-import benchmarks/agentic/tasks.py:601 Untrusted user input in `importlib.import_module()` function allows an attacker to load arbitrary code. Avoid dynamic values in `importlib.import_module()` or use a whitelist to prevent running untrusted code. [confidence low] Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.unsafe-dynamic-method benchmarks/behavior.js:50 Using non-static data to retrieve and run functions from the object is dangerous. If the data is user-controlled, it may allow executing arbitrary code. [confidence low] Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename benchmarks/correctness.js:133 Detected that function argument `blocks` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename benchmarks/correctness.js:178 Detected that function argument `blocks` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename benchmarks/correctness.js:226 Detected that function argument `blocks` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.unsafe-dynamic-method benchmarks/correctness.js:284 Using non-static data to retrieve and run functions from the object is dangerous. If the data is user-controlled, it may allow executing arbitrary code. [confidence low] Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.path-traversal.path-join-resolve-traversal benchmarks/correctness.js:72 Detected possible user input going into a `path.join` or `path.resolve` function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename benchmarks/correctness.js:73 Detected that function argument `ext` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/board.ts:511 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/board.ts:512 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/board.ts:513 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/board.ts:530 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/board.ts:536 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/board.ts:537 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/metrics.ts:117 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/metrics.ts:121 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/metrics.ts:122 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/metrics.ts:123 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/metrics.ts:124 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/metrics.ts:130 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string hooks/band/metrics.ts:134 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-regexp hooks/band/register.tsx:319 RegExp() called with a `$` function argument, this might allow an attacker to cause a Regular Expression Denial-of-Service (ReDoS) within your application as RegExP blocks the main thread. For this reason, it is recommended to use... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename hooks/ponytail-band-import.js:203 Detected that function argument `cwd` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.path-traversal.path-join-resolve-traversal hooks/ponytail-band-import.js:242 Detected possible user input going into a `path.join` or `path.resolve` function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename hooks/ponytail-band-import.js:86 Detected that function argument `file` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename hooks/ponytail-band-import.js:91 Detected that function argument `file` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename hooks/ponytail-band-import.js:98 Detected that function argument `file` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename hooks/ponytail-map.js:51 Detected that function argument `dir` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.path-traversal.path-join-resolve-traversal hooks/ponytail-map.js:54 Detected possible user input going into a `path.join` or `path.resolve` function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.path-traversal.path-join-resolve-traversal hooks/ponytail-map.js:54 Detected possible user input going into a `path.join` or `path.resolve` function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename hooks/ponytail-map.js:85 Detected that function argument `root` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.path-traversal.path-join-resolve-traversal hooks/ponytail-map.js:85 Detected possible user input going into a `path.join` or `path.resolve` function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.path-traversal.path-join-resolve-traversal hooks/ponytail-map.js:85 Detected possible user input going into a `path.join` or `path.resolve` function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename hooks/ponytail-map.js:86 Detected that function argument `root` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.path-traversal.path-join-resolve-traversal hooks/ponytail-map.js:86 Detected possible user input going into a `path.join` or `path.resolve` function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.path-traversal.path-join-resolve-traversal hooks/ponytail-map.js:86 Detected possible user input going into a `path.join` or `path.resolve` function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to... Static analysis (opengrep)
medium opengrep/javascript.lang.security.html-in-template-string pi-extension/index.js:22 This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS).... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename scripts/build-openclaw-skills.js:31 Detected that function argument `name` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.path-traversal.path-join-resolve-traversal scripts/build-openclaw-skills.js:48 Detected possible user input going into a `path.join` or `path.resolve` function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename scripts/check-rule-copies.js:8 Detected that function argument `relPath` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename scripts/check-versions.js:34 Detected that function argument `relPath` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename scripts/cursor-hooks.js:102 Detected that function argument `scope` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename scripts/cursor-hooks.js:110 Detected that function argument `scope` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename scripts/cursor-hooks.js:35 Detected that function argument `file` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename scripts/cursor-hooks.js:55 Detected that function argument `file` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename scripts/cursor-hooks.js:56 Detected that function argument `file` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename scripts/publish-openclaw-skills.js:32 Detected that function argument `e` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.path-traversal.path-join-resolve-traversal scripts/publish-openclaw-skills.js:32 Detected possible user input going into a `path.join` or `path.resolve` function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to... Static analysis (opengrep)
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename scripts/uninstall.js:19 Detected that function argument `filePath` has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled... Static analysis (opengrep)
low opengrep/javascript.lang.correctness.useless-assignment .opencode/plugins/ponytail.mjs:25 `const` is assigned twice; the first assignment is useless Lint
low opengrep/javascript.lang.correctness.useless-assignment .opencode/plugins/ponytail.mjs:26 `const` is assigned twice; the first assignment is useless Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator benchmarks/correctness.js:143 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:100 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:102 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:106 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:112 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:132 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:141 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:145 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:168 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:185 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:185 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:190 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:558 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:98 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/board.ts:98 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/metrics.ts:110 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.missing-template-string-indicator hooks/band/metrics.ts:110 This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'? Lint
low opengrep/javascript.lang.correctness.useless-assignment hooks/ponytail-activate.js:12 `const` is assigned twice; the first assignment is useless Lint
low opengrep/javascript.lang.correctness.useless-assignment hooks/ponytail-activate.js:13 `const` is assigned twice; the first assignment is useless Lint
low opengrep/javascript.lang.correctness.useless-assignment hooks/ponytail-activate.js:14 `const` is assigned twice; the first assignment is useless Lint
low opengrep/javascript.lang.correctness.useless-assignment hooks/ponytail-band-import.js:10 `const` is assigned twice; the first assignment is useless Lint
low opengrep/javascript.lang.correctness.useless-assignment hooks/ponytail-band-import.js:9 `const` is assigned twice; the first assignment is useless Lint
low opengrep/javascript.lang.correctness.useless-assignment hooks/ponytail-mode-tracker.js:7 `const` is assigned twice; the first assignment is useless Lint
low opengrep/javascript.lang.correctness.useless-assignment hooks/ponytail-mode-tracker.js:8 `const` is assigned twice; the first assignment is useless Lint
low opengrep/javascript.lang.correctness.useless-assignment hooks/ponytail-mode-tracker.js:9 `const` is assigned twice; the first assignment is useless Lint
low opengrep/javascript.lang.correctness.useless-assignment hooks/ponytail-runtime.js:4 `const` is assigned twice; the first assignment is useless Lint
low opengrep/javascript.lang.correctness.useless-assignment hooks/ponytail-subagent.js:13 `const` is assigned twice; the first assignment is useless Lint
low opengrep/javascript.lang.correctness.useless-assignment pi-extension/index.js:4 `const` is assigned twice; the first assignment is useless Lint
low zizmor/self-repository .github/workflows/publish.yml:13 use GitHub's dedicated self-repository syntax [confidence high] CI workflows (zizmor)
low zizmor/adhoc-packages .github/workflows/publish.yml:27 ad-hoc installation of packages [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 f1d2b562b41456
Tests and CICode qualityok—0
Type safetyCode qualityok—0
CI workflows (zizmor)Securityokzizmor 1.32.05
Dependencies (osv-scanner)Securityskipped—0
Release downloadsSecurityok—0
Security postureSecurityok—0
Package registriesSecurityskipped—0no registry dependencies declared
Static analysis (opengrep)Securityokopengrep 1.33.1; rules f1d2b562b41463
OpenSSF ScorecardSecurityskipped—0no published OpenSSF Scorecard result for this repo
Secrets (gitleaks)Securityokgitleaks 8.30.10

Score history

ScoredCommitScoringAI provenanceQualitySecurity
2026-11-1496608e078b2dprov-5+qual-2+sec-230%6868

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/DietrichGebert/ponytail/ai.svg)](https://repotrust.synapticcyber.com/r/github.com/DietrichGebert/ponytail/)
[![RepoTrust quality](https://repotrust.synapticcyber.com/badge/github.com/DietrichGebert/ponytail/quality.svg)](https://repotrust.synapticcyber.com/r/github.com/DietrichGebert/ponytail/)
[![RepoTrust security](https://repotrust.synapticcyber.com/badge/github.com/DietrichGebert/ponytail/security.svg)](https://repotrust.synapticcyber.com/r/github.com/DietrichGebert/ponytail/)
Full text report

Scores

Pillar Score Signal Confidence Coverage
AI provenance (estimated AI-generated share) 30 explicit 95% 100%
Code quality 68 adequate 90% 100%
Security 68 weak 85% 100%

AI provenance

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

  • Explicitly attributed share (lower bound): 29.5%
  • Unattributed share in AI-consistent velocity bursts: 0.0%
  • Estimated AI-generated share: 29.5%
AI tool Attributed commits Lines added
Claude Code 98 3,857
Cursor agent 3 57
OpenAI Codex 3 98
GitHub Copilot coding agent 2 130
Devin 1 9
  • AI tooling configured in repo: cline, cursor, generic-agent, github-copilot, windsurf

Current source lines last changed by AI-attributed commits: 2,373 of 7,296.

Findings per 1,000 lines AI-attributed Other Ratio
Quality 4.214 9.344 0.45x
Security 5.9 9.953 0.59x
  • Stylometry index: 0.21 per 1,000 lines (narrated steps 0, placeholders 0, assistant phrasing 0, emoji 3). Reported as a signal, not scored.
Month Lines added Attributed to AI
2026-06 5,741 57%
2026-07 1,083 25%
2026-08 92 0%
2026-09 610 0%
2026-10 6,183 8%

Evidence

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.63, CI runs tests; 20% of function code in complex or long functions; 2% duplicated lines. Weakest area: lint.

Area Score
Complexity (lizard) 55
Duplication 90
Code smells (Opengrep) 28
Tests and CI 90
Documentation 80
Type safety 40
Process (Scorecard review/maintenance) n/a
  • Functions: 460; mean complexity 4.0, 90th percentile 8; 14 complex and 1 long functions
  • Duplicated lines: 1.7% of 5,950 compared
  • Tests: 4,563 test lines for 7,296 source lines (ratio 0.63); CI test commands: npm test; 67% of recent source commits also change tests
  • Docs missing or thin: changelog

Most complex functions:

Security

Security posture is weak: 10 high-severity SAST findings; 1 high-severity workflow issues. Weakest area: posture.

Area Score
Secrets (gitleaks, tree + history) 100
Static analysis (Opengrep) 37
Vulnerable dependencies (OSV) n/a
CI workflows (zizmor) 88
Posture (policy, updates, signing, lockfiles) 20
OpenSSF Scorecard n/a
  • Posture checks passed: signed commits; missing: security policy, dependency updates, lockfiles

Top findings

Severity Finding Location
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] benchmarks/agentic/judge.py:70
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] benchmarks/agentic/run.py:167
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] benchmarks/agentic/run.py:269
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] benchmarks/agentic/run.py:330
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] benchmarks/agentic/run.py:381
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] benchmarks/agentic/run.py:460
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] benchmarks/agentic/tasks.py:544
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] benchmarks/agentic/tasks.py:852
high opengrep/javascript.lang.security.detect-child-process: Detected calls to child_process from a function argument cmd. This could lead to a command injection if the input is user controllable. Try to avoid calls to child_process, and if it is needed ensure user input is correctly sanitized or sandboxed. [confidence low] benchmarks/correctness.js:50
high opengrep/javascript.lang.security.audit.spawn-shell-true: Found '$SPAWN' 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 low] scripts/publish-openclaw-skills.js:64
high zizmor/cache-poisoning: runtime artifacts potentially vulnerable to a cache poisoning attack [confidence low] .github/workflows/publish.yml:23
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename: Detected that function argument filePath has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are validated. [confidence low] .opencode/plugins/ponytail-frontmatter.cjs:15
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename: Detected that function argument filePath has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are validated. [confidence low] .opencode/plugins/ponytail-frontmatter.cjs:53
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] benchmarks/agentic/judge.py:85
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] benchmarks/agentic/tasks.py:541
medium opengrep/python.lang.security.audit.non-literal-import: Untrusted user input in importlib.import_module() function allows an attacker to load arbitrary code. Avoid dynamic values in importlib.import_module() or use a whitelist to prevent running untrusted code. [confidence low] benchmarks/agentic/tasks.py:601
medium opengrep/javascript.lang.security.audit.unsafe-dynamic-method: Using non-static data to retrieve and run functions from the object is dangerous. If the data is user-controlled, it may allow executing arbitrary code. [confidence low] benchmarks/behavior.js:50
medium opengrep/javascript.lang.security.audit.path-traversal.path-join-resolve-traversal: Detected possible user input going into a path.join or path.resolve function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to sanitize or validate user input first. [confidence low] benchmarks/correctness.js:72
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename: Detected that function argument ext has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are validated. [confidence low] benchmarks/correctness.js:73
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename: Detected that function argument blocks has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are validated. [confidence low] benchmarks/correctness.js:133
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename: Detected that function argument blocks has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are validated. [confidence low] benchmarks/correctness.js:178
medium opengrep/javascript.lang.security.audit.detect-non-literal-fs-filename: Detected that function argument blocks has entered the fs module. An attacker could potentially control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are validated. [confidence low] benchmarks/correctness.js:226
medium opengrep/javascript.lang.security.audit.unsafe-dynamic-method: Using non-static data to retrieve and run functions from the object is dangerous. If the data is user-controlled, it may allow executing arbitrary code. [confidence low] benchmarks/correctness.js:284
medium opengrep/javascript.lang.security.html-in-template-string: This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS). [confidence low] hooks/band/board.ts:511
medium opengrep/javascript.lang.security.html-in-template-string: This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS). [confidence low] hooks/band/board.ts:512

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: 7,296; test lines: 4,563
Language Lines
JavaScript 6,822
Python 3,072
TypeScript 1,923
PowerShell 24
Shell 18