{"schema_version":"2","scorer_version":"0.1.0","scoring_version":"prov-5+qual-2+sec-2","generated_at":"2026-11-14T14:52:01.804093Z","repo":{"ref":{"host":"github.com","owner":"Skipper551","name":"chinese-flashcards"},"default_branch":"main","clone_url":"https://github.com/Skipper551/chinese-flashcards.git","html_url":"https://github.com/Skipper551/chinese-flashcards","description":"Vibe-coded iPad handwriting flashcards for Chinese: write characters from memory with Apple Pencil, checked automatically, FSRS spaced repetition.","stars":0,"forks":0,"is_fork":false,"is_archived":false,"is_private":false,"size_kb":685,"primary_language":"TypeScript","license_spdx":"GPL-3.0","created_at":"2026-10-24T09:18:14Z","pushed_at":"2026-10-25T09:25:12Z","security_policy_url":null,"distribution":{"owner_created_at":"2023-10-23T03:51:27Z","owner_type":"User","release_assets":[]}},"commit_sha":"2eb0028081e00dd64e3443ce4593ee56e69ddb1d","profile":{"lines_by_language":{"TypeScript":3456,"Python":391},"files_by_category":{"source":24,"config":6,"other":6,"binary":6,"docs":5,"vendored":5,"test":5,"generated":1},"source_lines":3320,"test_lines":527},"pillars":{"ai_provenance":{"score":100.0,"confidence":0.73,"coverage":1.0,"label":"explicit","breakdown":{"attributed_share":1.0,"suspected_share":0.0,"estimated_share":1.0,"ai_artifacts":5.0,"flagged_work_units":1.0,"flagged_releases":null,"style_index":0.0},"summary":"Explicit AI attribution on 100% of first-party code added; an estimated 100% including velocity signals."},"quality":{"score":74.5,"confidence":0.9,"coverage":1.0,"label":"adequate","breakdown":{"complexity":72.0,"duplication":100.0,"lint":56.8,"testing":71.8,"docs":65.0,"type_safety":92.9,"process":null},"summary":"Code quality is adequate: test-to-source ratio 0.16, CI runs tests; 11% of function code in complex or long functions; 0% duplicated lines. Weakest area: lint."},"security":{"score":71.5,"confidence":0.85,"coverage":1.0,"label":"adequate","breakdown":{"secrets":100.0,"sast":92.4,"dependencies":86.1,"ci_actions":24.2,"posture":0.0,"scorecard":null},"summary":"Security posture is adequate: 3 known vulnerabilities in 3 dependencies; 1 high-severity SAST findings; 7 high-severity workflow issues. Weakest area: posture."}},"analyzer_results":[{"analyzer":"sec-scorecard","pillar":"security","status":"skipped","tool_version":null,"metrics":{},"findings":[],"evidence":[],"data":{},"error":"no published OpenSSF Scorecard result for this repo"},{"analyzer":"sec-registry","pillar":"security","status":"ok","tool_version":null,"metrics":{"declared":13.0,"checked":13.0,"missing":0.0,"recent":0.0,"lookup_errors":0.0},"findings":[],"evidence":[],"data":{"phantom":false},"error":null},{"analyzer":"ai-attribution","pillar":"ai_provenance","status":"ok","tool_version":"signatures-v1","metrics":{"commits":12.0,"attributed_commits":12.0,"attributed_commit_share":1.0,"effective_loc":3895.0,"attributed_loc":3895.0,"attributed_loc_share":1.0,"tools_detected":1.0},"findings":[],"evidence":[{"kind":"attribution-summary","description":"Claude Code: 12 attributed commits, 3,895 lines added","ref":null,"url":null,"weight":1.0},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"2eb0028081e00dd64e3443ce4593ee56e69ddb1d","url":"https://github.com/Skipper551/chinese-flashcards/commit/2eb0028081e00dd64e3443ce4593ee56e69ddb1d","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"778d3a94f123d1d36b0a3c08f14a132e34e7a4b9","url":"https://github.com/Skipper551/chinese-flashcards/commit/778d3a94f123d1d36b0a3c08f14a132e34e7a4b9","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"0646eb04108a439e3fa5767fd4a8996ef36244d3","url":"https://github.com/Skipper551/chinese-flashcards/commit/0646eb04108a439e3fa5767fd4a8996ef36244d3","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"386e95377ba6c315ef648b9a3f2fb962b0fd2ce8","url":"https://github.com/Skipper551/chinese-flashcards/commit/386e95377ba6c315ef648b9a3f2fb962b0fd2ce8","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"c9daf942014c8394beaa87dd74a12290a34da1d7","url":"https://github.com/Skipper551/chinese-flashcards/commit/c9daf942014c8394beaa87dd74a12290a34da1d7","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"438e656a41f697691dcd5fe77276397797a97128","url":"https://github.com/Skipper551/chinese-flashcards/commit/438e656a41f697691dcd5fe77276397797a97128","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"7981880caee234e3e0d6ca6f2a1e31abaf14a634","url":"https://github.com/Skipper551/chinese-flashcards/commit/7981880caee234e3e0d6ca6f2a1e31abaf14a634","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"92f443d7cef65004c63e3df09951ef0779128a7b","url":"https://github.com/Skipper551/chinese-flashcards/commit/92f443d7cef65004c63e3df09951ef0779128a7b","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"4c1bef5f8f10518838f0f9efe778e00dd5575e90","url":"https://github.com/Skipper551/chinese-flashcards/commit/4c1bef5f8f10518838f0f9efe778e00dd5575e90","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"9bfac3fac79a248f71bb575461eb68f1cde75a4d","url":"https://github.com/Skipper551/chinese-flashcards/commit/9bfac3fac79a248f71bb575461eb68f1cde75a4d","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"a83e6b093e309e4cda624927cc50f0c2d360267b","url":"https://github.com/Skipper551/chinese-flashcards/commit/a83e6b093e309e4cda624927cc50f0c2d360267b","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"7fa3659df60a1981a0a797df62efe61aa28850a4","url":"https://github.com/Skipper551/chinese-flashcards/commit/7fa3659df60a1981a0a797df62efe61aa28850a4","weight":0.9}],"data":{"attributed_loc_by_commit":{"7fa3659df60a1981a0a797df62efe61aa28850a4":158,"a83e6b093e309e4cda624927cc50f0c2d360267b":624,"4c1bef5f8f10518838f0f9efe778e00dd5575e90":0,"9bfac3fac79a248f71bb575461eb68f1cde75a4d":2599,"92f443d7cef65004c63e3df09951ef0779128a7b":0,"7981880caee234e3e0d6ca6f2a1e31abaf14a634":0,"438e656a41f697691dcd5fe77276397797a97128":3,"c9daf942014c8394beaa87dd74a12290a34da1d7":5,"0646eb04108a439e3fa5767fd4a8996ef36244d3":3,"386e95377ba6c315ef648b9a3f2fb962b0fd2ce8":391,"778d3a94f123d1d36b0a3c08f14a132e34e7a4b9":110,"2eb0028081e00dd64e3443ce4593ee56e69ddb1d":2},"tools":{"claude-code":{"name":"Claude Code","commits":12,"loc":3895,"first_seen":1792795244,"last_seen":1792920249}},"monthly":{"2026-10":{"loc":3895,"attributed_loc":3895}}},"error":null},{"analyzer":"ai-artifacts","pillar":"ai_provenance","status":"ok","tool_version":"signatures-v1","metrics":{"artifacts":5.0,"workflow_agents":0.0,"tools_configured":1.0,"earliest_adoption":1792795244.0},"findings":[],"evidence":[{"kind":"ai-artifact","description":".claude/launch.json (claude-code configuration)","ref":".claude/launch.json","url":"https://github.com/Skipper551/chinese-flashcards/blob/2eb0028081e00dd64e3443ce4593ee56e69ddb1d/.claude/launch.json","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/lecture-to-deck/README.md (claude-code configuration)","ref":".claude/skills/lecture-to-deck/README.md","url":"https://github.com/Skipper551/chinese-flashcards/blob/2eb0028081e00dd64e3443ce4593ee56e69ddb1d/.claude/skills/lecture-to-deck/README.md","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/lecture-to-deck/SKILL.md (claude-code configuration)","ref":".claude/skills/lecture-to-deck/SKILL.md","url":"https://github.com/Skipper551/chinese-flashcards/blob/2eb0028081e00dd64e3443ce4593ee56e69ddb1d/.claude/skills/lecture-to-deck/SKILL.md","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/lecture-to-deck/scripts/check.py (claude-code configuration)","ref":".claude/skills/lecture-to-deck/scripts/check.py","url":"https://github.com/Skipper551/chinese-flashcards/blob/2eb0028081e00dd64e3443ce4593ee56e69ddb1d/.claude/skills/lecture-to-deck/scripts/check.py","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/lecture-to-deck/scripts/extract.py (claude-code configuration)","ref":".claude/skills/lecture-to-deck/scripts/extract.py","url":"https://github.com/Skipper551/chinese-flashcards/blob/2eb0028081e00dd64e3443ce4593ee56e69ddb1d/.claude/skills/lecture-to-deck/scripts/extract.py","weight":0.5}],"data":{"artifacts":[{"tool":"claude-code","path":".claude/launch.json","added_at":1792795244},{"tool":"claude-code","path":".claude/skills/lecture-to-deck/README.md","added_at":1792893318},{"tool":"claude-code","path":".claude/skills/lecture-to-deck/SKILL.md","added_at":1792888526},{"tool":"claude-code","path":".claude/skills/lecture-to-deck/scripts/check.py","added_at":1792888526},{"tool":"claude-code","path":".claude/skills/lecture-to-deck/scripts/extract.py","added_at":1792888526}],"workflows":[],"tools":["claude-code"]},"error":null},{"analyzer":"ai-velocity","pillar":"ai_provenance","status":"ok","tool_version":"prov-4","metrics":{"work_units":5.0,"flagged_units":1.0,"pre_ai_era_bursts":0.0,"pre_ai_era_measured_loc":0.0,"pre_ai_era_burst_loc":0.0,"measured_loc":3895.0,"flagged_loc":3381.0,"flagged_loc_share":0.8680359435173299,"max_loc_per_hour":755.4369414101292,"median_loc_per_hour":98.5,"pr_timed_units":0.0,"excluded_import_loc":0.0},"findings":[],"evidence":[{"kind":"velocity-burst","description":"3,381 lines of first-party code in ~4.5h (755 lines/hour, 3 commit session)","ref":"9bfac3fac79a248f71bb575461eb68f1cde75a4d","url":"https://github.com/Skipper551/chinese-flashcards/commit/9bfac3fac79a248f71bb575461eb68f1cde75a4d","weight":0.22663108242303875}],"data":{"flagged_loc_by_commit":{"7fa3659df60a1981a0a797df62efe61aa28850a4":158,"a83e6b093e309e4cda624927cc50f0c2d360267b":624,"9bfac3fac79a248f71bb575461eb68f1cde75a4d":2599},"excluded_import_commits":[]},"error":null},{"analyzer":"ai-release-velocity","pillar":"ai_provenance","status":"skipped","tool_version":null,"metrics":{},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"ai-stylometry","pillar":"ai_provenance","status":"ok","tool_version":null,"metrics":{"lines_scanned":3320.0,"index":0.0,"count:narrated_steps":0.0,"per_kloc:narrated_steps":0.0,"files:narrated_steps":0.0,"count:placeholder":0.0,"per_kloc:placeholder":0.0,"files:placeholder":0.0,"count:emoji_in_code":0.0,"per_kloc:emoji_in_code":0.0,"files:emoji_in_code":0.0,"count:assistant_voice":0.0,"per_kloc:assistant_voice":0.0,"files:assistant_voice":0.0},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-secrets","pillar":"security","status":"ok","tool_version":"gitleaks 8.30.1","metrics":{"secrets_current":0.0,"secrets_history":0.0,"secrets_nonprod":0.0,"secrets_low_confidence":0.0},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-sast","pillar":"security","status":"ok","tool_version":"opengrep 1.33.1; rules f1d2b562b414","metrics":{"findings":1.0,"findings_high":1.0,"findings_medium":0.0,"findings_low":0.0,"weighted_findings":0.75,"scanned_lines":3320.0,"parse_errors":1.0},"findings":[{"rule_id":"opengrep/python.lang.security.use-defused-xml","severity":"high","message":"The Python documentation recommends using `defusedxml` instead of `xml` because the native Python `xml` library is vulnerable to XML External Entity (XXE) attacks. These attacks can leak confidential data and \"XML bombs\" can cause denial of service. [confidence low]","path":".claude/skills/lecture-to-deck/scripts/extract.py","line":19,"fingerprint":"python.lang.security.use-defused-xml:.claude/skills/lecture-to-deck/scripts/extract.py:19"}],"evidence":[],"data":{"rulesets":["typescript","javascript","python"]},"error":null},{"analyzer":"sec-deps","pillar":"security","status":"ok","tool_version":"osv-scanner version: 2.7.1","metrics":{"vulnerable_packages":3.0,"vulnerabilities":3.0,"vulns_critical":0.0,"vulns_high":0.0,"vulns_medium":3.0,"vulns_low":0.0,"vulns_unknown":0.0,"penalty":9.0},"findings":[{"rule_id":"osv/GHSA-gcqx-w48m-w2h4","severity":"medium","message":"deepmerge@4.3.1 (npm) is affected by GHSA-gcqx-w48m-w2h4","path":"package-lock.json","line":null,"fingerprint":"deepmerge@4.3.1 (npm):GHSA-gcqx-w48m-w2h4"},{"rule_id":"osv/GHSA-3g3m-2fjr-6pw4","severity":"medium","message":"glob@11.1.0 (npm) is affected by GHSA-3g3m-2fjr-6pw4","path":"package-lock.json","line":null,"fingerprint":"glob@11.1.0 (npm):GHSA-3g3m-2fjr-6pw4"},{"rule_id":"osv/GHSA-g3hv-75wg-m249","severity":"medium","message":"minimatch@10.2.6 (npm) is affected by GHSA-g3hv-75wg-m249","path":"package-lock.json","line":null,"fingerprint":"minimatch@10.2.6 (npm):GHSA-g3hv-75wg-m249"}],"evidence":[],"data":{"ecosystems":["npm"]},"error":null},{"analyzer":"sec-actions","pillar":"security","status":"ok","tool_version":"zizmor 1.32.0","metrics":{"workflows":1.0,"findings":8.0,"findings_high":7.0,"findings_medium":1.0,"findings_low":0.0,"penalty":85.2},"findings":[{"rule_id":"zizmor/excessive-permissions","severity":"high","message":"overly broad permissions [confidence high]","path":".github/workflows/deploy.yml","line":10,"fingerprint":"excessive-permissions:.github/workflows/deploy.yml:10"},{"rule_id":"zizmor/excessive-permissions","severity":"high","message":"overly broad permissions [confidence high]","path":".github/workflows/deploy.yml","line":11,"fingerprint":"excessive-permissions:.github/workflows/deploy.yml:11"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/deploy.yml","line":21,"fingerprint":"unpinned-uses:.github/workflows/deploy.yml:21"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/deploy.yml","line":22,"fingerprint":"unpinned-uses:.github/workflows/deploy.yml:22"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/deploy.yml","line":32,"fingerprint":"unpinned-uses:.github/workflows/deploy.yml:32"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/deploy.yml","line":33,"fingerprint":"unpinned-uses:.github/workflows/deploy.yml:33"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/deploy.yml","line":45,"fingerprint":"unpinned-uses:.github/workflows/deploy.yml:45"},{"rule_id":"zizmor/artipacked","severity":"medium","message":"credential persistence through GitHub Actions artifacts [confidence low]","path":".github/workflows/deploy.yml","line":21,"fingerprint":"artipacked:.github/workflows/deploy.yml:21"}],"evidence":[],"data":{},"error":null},{"analyzer":"sec-posture","pillar":"security","status":"ok","tool_version":null,"metrics":{"check:security_policy":0.0,"check:dependency_updates":0.0,"check:signed_commits":0.0,"check:lockfiles":1.0,"signed_commit_share":0.0,"unpinned_manifests":0.0},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-distribution","pillar":"security","status":"ok","tool_version":null,"metrics":{"signals":0.0,"binary_assets":0.0,"suspicious":0.0},"findings":[],"evidence":[],"data":{"signals":[],"suspicious":false,"unusual_traction":false,"metadata":true},"error":null},{"analyzer":"qual-complexity","pillar":"quality","status":"ok","tool_version":"lizard 1.25.1","metrics":{"functions":348.0,"function_nloc":2450.0,"mean_ccn":2.5,"p90_ccn":5.0,"complex_functions":5.0,"long_functions":1.0,"many_param_functions":0.0,"risky_nloc_share":0.1094},"findings":[],"evidence":[{"kind":"complex-function","description":"main in .claude/skills/lecture-to-deck/scripts/check.py: complexity 35, 61 lines","ref":".claude/skills/lecture-to-deck/scripts/check.py","url":"https://github.com/Skipper551/chinese-flashcards/blob/2eb0028081e00dd64e3443ce4593ee56e69ddb1d/.claude/skills/lecture-to-deck/scripts/check.py#L78","weight":0.5833333333333334},{"kind":"complex-function","description":"Study in src/screens/Study.tsx: complexity 29, 120 lines","ref":"src/screens/Study.tsx","url":"https://github.com/Skipper551/chinese-flashcards/blob/2eb0028081e00dd64e3443ce4593ee56e69ddb1d/src/screens/Study.tsx#L50","weight":0.48333333333333334},{"kind":"complex-function","description":"parseDelimited in src/import.ts: complexity 18, 36 lines","ref":"src/import.ts","url":"https://github.com/Skipper551/chinese-flashcards/blob/2eb0028081e00dd64e3443ce4593ee56e69ddb1d/src/import.ts#L36","weight":0.3},{"kind":"complex-function","description":"rows_of in .claude/skills/lecture-to-deck/scripts/check.py: complexity 17, 21 lines","ref":".claude/skills/lecture-to-deck/scripts/check.py","url":"https://github.com/Skipper551/chinese-flashcards/blob/2eb0028081e00dd64e3443ce4593ee56e69ddb1d/.claude/skills/lecture-to-deck/scripts/check.py#L34","weight":0.2833333333333333},{"kind":"complex-function","description":"pptx_shapes in .claude/skills/lecture-to-deck/scripts/extract.py: complexity 16, 30 lines","ref":".claude/skills/lecture-to-deck/scripts/extract.py","url":"https://github.com/Skipper551/chinese-flashcards/blob/2eb0028081e00dd64e3443ce4593ee56e69ddb1d/.claude/skills/lecture-to-deck/scripts/extract.py#L146","weight":0.26666666666666666}],"data":{},"error":null},{"analyzer":"qual-duplication","pillar":"quality","status":"ok","tool_version":"repotrust-dup-w6","metrics":{"compared_lines":2559.0,"duplicated_lines":0.0,"duplicated_share":0.0,"files":24.0},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"qual-lint","pillar":"quality","status":"ok","tool_version":"opengrep 1.33.1; rules f1d2b562b414","metrics":{"findings":9.0,"weighted_findings":7.5,"scanned_lines":3320.0,"category:best-practice":7.0,"category:correctness":2.0},"findings":[{"rule_id":"opengrep/javascript.lang.best-practice.assigned-undefined","severity":"medium","message":"`undefined` is not a reserved keyword in Javascript, so this is \"valid\" Javascript but highly confusing and likely to result in bugs.","path":"src/recognize.ts","line":184,"fingerprint":"javascript.lang.best-practice.assigned-undefined:src/recognize.ts:184"},{"rule_id":"opengrep/javascript.lang.best-practice.javascript-prompt","severity":"medium","message":"found prompt() call; should this be in production code?","path":"src/screens/Decks.tsx","line":24,"fingerprint":"javascript.lang.best-practice.javascript-prompt:src/screens/Decks.tsx:24"},{"rule_id":"opengrep/javascript.lang.best-practice.javascript-alert","severity":"medium","message":"found alert() call; should this be in production code?","path":"src/screens/Decks.tsx","line":26,"fingerprint":"javascript.lang.best-practice.javascript-alert:src/screens/Decks.tsx:26"},{"rule_id":"opengrep/javascript.lang.best-practice.javascript-prompt","severity":"medium","message":"found prompt() call; should this be in production code?","path":"src/screens/Decks.tsx","line":235,"fingerprint":"javascript.lang.best-practice.javascript-prompt:src/screens/Decks.tsx:235"},{"rule_id":"opengrep/javascript.lang.best-practice.javascript-confirm","severity":"medium","message":"found confirm() call; should this be in production code?","path":"src/screens/Decks.tsx","line":240,"fingerprint":"javascript.lang.best-practice.javascript-confirm:src/screens/Decks.tsx:240"},{"rule_id":"opengrep/javascript.lang.best-practice.javascript-confirm","severity":"medium","message":"found confirm() call; should this be in production code?","path":"src/screens/Decks.tsx","line":320,"fingerprint":"javascript.lang.best-practice.javascript-confirm:src/screens/Decks.tsx:320"},{"rule_id":"opengrep/javascript.lang.best-practice.javascript-confirm","severity":"medium","message":"found confirm() call; should this be in production code?","path":"src/screens/Settings.tsx","line":35,"fingerprint":"javascript.lang.best-practice.javascript-confirm:src/screens/Settings.tsx:35"},{"rule_id":"opengrep/javascript.lang.correctness.missing-template-string-indicator","severity":"low","message":"This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'?","path":"src/components/charts.tsx","line":125,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/components/charts.tsx:125"},{"rule_id":"opengrep/javascript.lang.correctness.missing-template-string-indicator","severity":"low","message":"This looks like a JavaScript template string. Are you missing a '$' in front of '{...}'?","path":"src/components/charts.tsx","line":125,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/components/charts.tsx:125"}],"evidence":[],"data":{},"error":null},{"analyzer":"qual-testing","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:has_tests":1.0,"check:test_ratio":0.3175,"check:ci_present":1.0,"check:ci_runs_tests":1.0,"check:ci_runs_lint":0.0,"check:tests_cochange":0.8889,"test_lines":527.0,"source_lines":3320.0,"test_ratio":0.1587,"ci_files":1.0,"cochange_share":0.2222,"cochange_commits":9.0},"findings":[],"evidence":[{"kind":"ci","description":"CI config: .github/workflows/deploy.yml","ref":".github/workflows/deploy.yml","url":null,"weight":0.0},{"kind":"ci","description":"CI runs tests (npm test)","ref":null,"url":null,"weight":0.0}],"data":{"test_commands":["npm test"],"lint_commands":[]},"error":null},{"analyzer":"qual-docs","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:readme":1.0,"check:license":1.0,"check:contributing":0.0,"check:changelog":0.0,"readme_lines":49.0},"findings":[],"evidence":[{"kind":"docs","description":"README.md","ref":"README.md","url":null,"weight":0.0},{"kind":"docs","description":"LICENSE","ref":"LICENSE","url":null,"weight":0.0}],"data":{},"error":null},{"analyzer":"qual-type-safety","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:strict_config":0.8822,"check:low_escape_density":1.0,"escapes":1.0,"escapes_per_kloc":0.301},"findings":[],"evidence":[{"kind":"typing","description":"TypeScript strict type checking: tsconfig.json","ref":"tsconfig.json","url":null,"weight":0.0}],"data":{},"error":null},{"analyzer":"x-blame","pillar":"ai_provenance","status":"ok","tool_version":"git-blame","metrics":{"ai_lines":3320.0,"other_lines":0.0,"files_blamed":24.0,"blame_failures":0.0,"quality:ai_findings":9.0,"quality:ai_per_kloc":2.711,"quality:other_findings":0.0,"security:ai_findings":1.0,"security:ai_per_kloc":0.301,"security:other_findings":0.0},"findings":[],"evidence":[],"data":{"sampled":false,"comparable":false},"error":null}],"flags":[]}