{"schema_version":"2","scorer_version":"0.1.0","scoring_version":"prov-5+qual-2+sec-2","generated_at":"2026-11-14T14:52:01.001640Z","repo":{"ref":{"host":"github.com","owner":"MattGibney","name":"Epoch-Foundry"},"default_branch":"main","clone_url":"https://github.com/MattGibney/Epoch-Foundry.git","html_url":"https://github.com/MattGibney/Epoch-Foundry","description":null,"stars":0,"forks":0,"is_fork":false,"is_archived":false,"is_private":false,"size_kb":1059,"primary_language":"TypeScript","license_spdx":null,"created_at":"2026-03-06T15:04:52Z","pushed_at":"2026-08-31T17:28:51Z","security_policy_url":null,"distribution":{"owner_created_at":"2019-03-11T12:28:30Z","owner_type":"User","release_assets":[]}},"commit_sha":"75f19103a9369845ccf16680eb73502f19d3a22f","profile":{"lines_by_language":{"TypeScript":8729,"JavaScript":1176},"files_by_category":{"source":49,"docs":12,"config":7,"other":7,"binary":5,"generated":2},"source_lines":9905,"test_lines":0},"pillars":{"ai_provenance":{"score":0.0,"confidence":0.65,"coverage":1.0,"label":"possible","breakdown":{"attributed_share":0.0,"suspected_share":0.1969,"estimated_share":0.0,"ai_artifacts":1.0,"flagged_work_units":2.0,"flagged_releases":null,"style_index":0.0},"summary":"Weak signals consistent with AI-assisted development."},"quality":{"score":38.5,"confidence":0.9,"coverage":1.0,"label":"poor","breakdown":{"complexity":53.6,"duplication":71.8,"lint":27.6,"testing":0.0,"docs":40.0,"type_safety":100.0,"process":null},"summary":"Code quality is poor: test-to-source ratio 0.00, no CI test run detected; 21% of function code in complex or long functions; 6% duplicated lines. Weakest area: testing."},"security":{"score":58.0,"confidence":0.85,"coverage":1.0,"label":"weak","breakdown":{"secrets":90.5,"sast":96.5,"dependencies":7.8,"ci_actions":null,"posture":0.0,"scorecard":null},"summary":"Security posture is weak: 78 known vulnerabilities in 24 dependencies. 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":26.0,"checked":26.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":131.0,"attributed_commits":0.0,"attributed_commit_share":0.0,"effective_loc":22189.0,"attributed_loc":0.0,"attributed_loc_share":0.0,"tools_detected":0.0},"findings":[],"evidence":[],"data":{"attributed_loc_by_commit":{},"tools":{},"monthly":{"2026-03":{"loc":18749,"attributed_loc":0},"2026-05":{"loc":314,"attributed_loc":0},"2026-08":{"loc":3126,"attributed_loc":0}}},"error":null},{"analyzer":"ai-artifacts","pillar":"ai_provenance","status":"ok","tool_version":"signatures-v1","metrics":{"artifacts":1.0,"workflow_agents":0.0,"tools_configured":1.0,"earliest_adoption":1772809455.0},"findings":[],"evidence":[{"kind":"ai-artifact","description":"AGENTS.md (generic-agent configuration)","ref":"AGENTS.md","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/AGENTS.md","weight":0.5}],"data":{"artifacts":[{"tool":"generic-agent","path":"AGENTS.md","added_at":1772809455}],"workflows":[],"tools":["generic-agent"]},"error":null},{"analyzer":"ai-velocity","pillar":"ai_provenance","status":"ok","tool_version":"prov-4","metrics":{"work_units":25.0,"flagged_units":2.0,"pre_ai_era_bursts":0.0,"pre_ai_era_measured_loc":0.0,"pre_ai_era_burst_loc":0.0,"measured_loc":22189.0,"flagged_loc":4368.0,"flagged_loc_share":0.19685429717427555,"max_loc_per_hour":838.656,"median_loc_per_hour":189.2727953099663,"pr_timed_units":0.0,"excluded_import_loc":0.0},"findings":[],"evidence":[{"kind":"velocity-burst","description":"1,938 lines of first-party code in ~3.5h (552 lines/hour, 1 commit session)","ref":"dbbd2cf66f5d76f1bc4e1268de0f95bb4e388830","url":"https://github.com/MattGibney/Epoch-Foundry/commit/dbbd2cf66f5d76f1bc4e1268de0f95bb4e388830","weight":0.16569347688410385},{"kind":"velocity-burst","description":"2,430 lines of first-party code in ~4.6h (532 lines/hour, 18 commit session)","ref":"18c6b1a5870ecbf4bfa15507d235241f6f7a978b","url":"https://github.com/MattGibney/Epoch-Foundry/commit/18c6b1a5870ecbf4bfa15507d235241f6f7a978b","weight":0.1596933187294633}],"data":{"flagged_loc_by_commit":{"cbfc21d63b30b4a6f044db802638483a5175ef6e":249,"1e184c95a118c8c15b9e912321969679b22b44d0":57,"be70bb9351ba253bbca651e619430dd6ad799125":39,"e530047b72953c4afa31cf6d37d6738770a9cae9":7,"551f3f5076c7a269b347bc317b7c89bbebda33bf":2,"d59c821c041cdcac447ce313048e9d4f1e14958e":103,"08e045d09172190d208b48c0648be024ba4eda93":351,"3ef62ce624f34ad13e3b87a5493524c0887a8965":87,"01c1669b57668ce0914dfbcc7b1df802df94ab0e":7,"c5bd4c869b428effe539e8c8685686a597ffdbb3":253,"85caebe2b400c26c1d0cbaa211be89097db09683":36,"3d48e9218138614f43a89288e711141c0be52906":315,"37f9820751582b81fe00b975b2c2c34dd9254dda":22,"3381b24b46923ae2be91fd33ea83f2affec376c7":6,"915f20db106723d8884591867d553b004a66f4b3":155,"9788077d76f7b16ae77473e87439ec82c41b6293":150,"c1b150a978541fcbc1dd43a795597bffedd874ee":56,"18c6b1a5870ecbf4bfa15507d235241f6f7a978b":535,"dbbd2cf66f5d76f1bc4e1268de0f95bb4e388830":1938},"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":9905.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":3.0},"findings":[{"rule_id":"gitleaks/generic-api-key","severity":"low","message":"Possible generic-api-key secret in the current tree","path":"src/lib/progression-config.ts","line":1430,"fingerprint":"src/lib/progression-config.ts:generic-api-key:1430"},{"rule_id":"gitleaks/generic-api-key","severity":"low","message":"Possible generic-api-key secret in the current tree","path":"src/data/epoch-content.generated.json","line":13711,"fingerprint":"src/data/epoch-content.generated.json:generic-api-key:13711"},{"rule_id":"gitleaks/generic-api-key","severity":"low","message":"Possible generic-api-key secret in history (commit 18c6b1a587); removed from the current tree but still retrievable","path":"src/lib/game-engine.ts","line":955,"fingerprint":"18c6b1a5870ecbf4bfa15507d235241f6f7a978b:src/lib/game-engine.ts:generic-api-key:955"}],"evidence":[],"data":{},"error":null},{"analyzer":"sec-sast","pillar":"security","status":"ok","tool_version":"opengrep 1.33.1; rules f1d2b562b414","metrics":{"findings":4.0,"findings_high":0.0,"findings_medium":4.0,"findings_low":0.0,"weighted_findings":1.0,"scanned_lines":9905.0,"parse_errors":2.0},"findings":[{"rule_id":"opengrep/javascript.lang.security.audit.detect-non-literal-regexp","severity":"medium","message":"RegExp() called with a `name` 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 hardcoded regexes instead. If your regex is run on user-controlled [confidence low]","path":"scripts/generate-epoch-content.mjs","line":313,"fingerprint":"javascript.lang.security.audit.detect-non-literal-regexp:scripts/generate-epoch-content.mjs:313"},{"rule_id":"opengrep/javascript.lang.security.audit.detect-non-literal-regexp","severity":"medium","message":"RegExp() called with a `name` 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 hardcoded regexes instead. If your regex is run on user-controlled [confidence low]","path":"scripts/generate-epoch-content.mjs","line":359,"fingerprint":"javascript.lang.security.audit.detect-non-literal-regexp:scripts/generate-epoch-content.mjs:359"},{"rule_id":"opengrep/javascript.lang.security.audit.detect-non-literal-regexp","severity":"medium","message":"RegExp() called with a `name` 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 hardcoded regexes instead. If your regex is run on user-controlled [confidence low]","path":"scripts/generate-epoch-content.mjs","line":457,"fingerprint":"javascript.lang.security.audit.detect-non-literal-regexp:scripts/generate-epoch-content.mjs:457"},{"rule_id":"opengrep/javascript.lang.security.audit.detect-non-literal-regexp","severity":"medium","message":"RegExp() called with a `{ name }` 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 hardcoded regexes instead. If your regex is run on user-contro [confidence low]","path":"scripts/generate-epoch-content.mjs","line":473,"fingerprint":"javascript.lang.security.audit.detect-non-literal-regexp:scripts/generate-epoch-content.mjs:473"}],"evidence":[],"data":{"rulesets":["typescript","javascript"]},"error":null},{"analyzer":"sec-deps","pillar":"security","status":"ok","tool_version":"osv-scanner version: 2.7.1","metrics":{"vulnerable_packages":24.0,"vulnerabilities":78.0,"vulns_critical":0.0,"vulns_high":45.0,"vulns_medium":27.0,"vulns_low":6.0,"vulns_unknown":0.0,"penalty":153.0},"findings":[{"rule_id":"osv/GHSA-fv7c-fp4j-7gwp","severity":"high","message":"@babel/plugin-transform-modules-systemjs@7.29.0 (npm) is affected by GHSA-fv7c-fp4j-7gwp","path":"package-lock.json","line":null,"fingerprint":"@babel/plugin-transform-modules-systemjs@7.29.0 (npm):GHSA-fv7c-fp4j-7gwp"},{"rule_id":"osv/GHSA-3jxr-9vmj-r5cp","severity":"high","message":"brace-expansion@1.1.12 (npm) is affected by GHSA-3jxr-9vmj-r5cp","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@1.1.12 (npm):GHSA-3jxr-9vmj-r5cp"},{"rule_id":"osv/GHSA-6j4f-fj2g-mc7p","severity":"high","message":"brace-expansion@1.1.12 (npm) is affected by GHSA-6j4f-fj2g-mc7p","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@1.1.12 (npm):GHSA-6j4f-fj2g-mc7p"},{"rule_id":"osv/GHSA-mh99-v99m-4gvg","severity":"high","message":"brace-expansion@1.1.12 (npm) is affected by GHSA-mh99-v99m-4gvg","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@1.1.12 (npm):GHSA-mh99-v99m-4gvg"},{"rule_id":"osv/GHSA-qhr7-859c-m2p7","severity":"high","message":"brace-expansion@1.1.12 (npm) is affected by GHSA-qhr7-859c-m2p7","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@1.1.12 (npm):GHSA-qhr7-859c-m2p7"},{"rule_id":"osv/GHSA-rgw5-rvv9-x895","severity":"high","message":"brace-expansion@1.1.12 (npm) is affected by GHSA-rgw5-rvv9-x895","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@1.1.12 (npm):GHSA-rgw5-rvv9-x895"},{"rule_id":"osv/GHSA-3jxr-9vmj-r5cp","severity":"high","message":"brace-expansion@2.0.2 (npm) is affected by GHSA-3jxr-9vmj-r5cp","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@2.0.2 (npm):GHSA-3jxr-9vmj-r5cp"},{"rule_id":"osv/GHSA-6j4f-fj2g-mc7p","severity":"high","message":"brace-expansion@2.0.2 (npm) is affected by GHSA-6j4f-fj2g-mc7p","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@2.0.2 (npm):GHSA-6j4f-fj2g-mc7p"},{"rule_id":"osv/GHSA-mh99-v99m-4gvg","severity":"high","message":"brace-expansion@2.0.2 (npm) is affected by GHSA-mh99-v99m-4gvg","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@2.0.2 (npm):GHSA-mh99-v99m-4gvg"},{"rule_id":"osv/GHSA-qhr7-859c-m2p7","severity":"high","message":"brace-expansion@2.0.2 (npm) is affected by GHSA-qhr7-859c-m2p7","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@2.0.2 (npm):GHSA-qhr7-859c-m2p7"},{"rule_id":"osv/GHSA-rgw5-rvv9-x895","severity":"high","message":"brace-expansion@2.0.2 (npm) is affected by GHSA-rgw5-rvv9-x895","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@2.0.2 (npm):GHSA-rgw5-rvv9-x895"},{"rule_id":"osv/GHSA-3jxr-9vmj-r5cp","severity":"high","message":"brace-expansion@5.0.4 (npm) is affected by GHSA-3jxr-9vmj-r5cp","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@5.0.4 (npm):GHSA-3jxr-9vmj-r5cp"},{"rule_id":"osv/GHSA-6j4f-fj2g-mc7p","severity":"high","message":"brace-expansion@5.0.4 (npm) is affected by GHSA-6j4f-fj2g-mc7p","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@5.0.4 (npm):GHSA-6j4f-fj2g-mc7p"},{"rule_id":"osv/GHSA-mh99-v99m-4gvg","severity":"high","message":"brace-expansion@5.0.4 (npm) is affected by GHSA-mh99-v99m-4gvg","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@5.0.4 (npm):GHSA-mh99-v99m-4gvg"},{"rule_id":"osv/GHSA-qhr7-859c-m2p7","severity":"high","message":"brace-expansion@5.0.4 (npm) is affected by GHSA-qhr7-859c-m2p7","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@5.0.4 (npm):GHSA-qhr7-859c-m2p7"},{"rule_id":"osv/GHSA-rgw5-rvv9-x895","severity":"high","message":"brace-expansion@5.0.4 (npm) is affected by GHSA-rgw5-rvv9-x895","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@5.0.4 (npm):GHSA-rgw5-rvv9-x895"},{"rule_id":"osv/GHSA-73wf-gq98-2v4g","severity":"high","message":"browserslist@4.28.1 (npm) is affected by GHSA-73wf-gq98-2v4g","path":"package-lock.json","line":null,"fingerprint":"browserslist@4.28.1 (npm):GHSA-73wf-gq98-2v4g"},{"rule_id":"osv/GHSA-c83g-rgw3-j3cx","severity":"high","message":"browserslist@4.28.1 (npm) is affected by GHSA-c83g-rgw3-j3cx","path":"package-lock.json","line":null,"fingerprint":"browserslist@4.28.1 (npm):GHSA-c83g-rgw3-j3cx"},{"rule_id":"osv/GHSA-4c8g-83qw-93j6","severity":"high","message":"fast-uri@3.1.0 (npm) is affected by GHSA-4c8g-83qw-93j6","path":"package-lock.json","line":null,"fingerprint":"fast-uri@3.1.0 (npm):GHSA-4c8g-83qw-93j6"},{"rule_id":"osv/GHSA-7p8r-x3mc-p8w7","severity":"high","message":"fast-uri@3.1.0 (npm) is affected by GHSA-7p8r-x3mc-p8w7","path":"package-lock.json","line":null,"fingerprint":"fast-uri@3.1.0 (npm):GHSA-7p8r-x3mc-p8w7"},{"rule_id":"osv/GHSA-f65p-4m7j-42xc","severity":"high","message":"fast-uri@3.1.0 (npm) is affected by GHSA-f65p-4m7j-42xc","path":"package-lock.json","line":null,"fingerprint":"fast-uri@3.1.0 (npm):GHSA-f65p-4m7j-42xc"},{"rule_id":"osv/GHSA-jqff-g426-hqxp","severity":"high","message":"fast-uri@3.1.0 (npm) is affected by GHSA-jqff-g426-hqxp","path":"package-lock.json","line":null,"fingerprint":"fast-uri@3.1.0 (npm):GHSA-jqff-g426-hqxp"},{"rule_id":"osv/GHSA-q3j6-qgpj-74h6","severity":"high","message":"fast-uri@3.1.0 (npm) is affected by GHSA-q3j6-qgpj-74h6","path":"package-lock.json","line":null,"fingerprint":"fast-uri@3.1.0 (npm):GHSA-q3j6-qgpj-74h6"},{"rule_id":"osv/GHSA-qw65-cvwx-89v3","severity":"high","message":"fast-uri@3.1.0 (npm) is affected by GHSA-qw65-cvwx-89v3","path":"package-lock.json","line":null,"fingerprint":"fast-uri@3.1.0 (npm):GHSA-qw65-cvwx-89v3"},{"rule_id":"osv/GHSA-v2hh-gcrm-f6hx","severity":"high","message":"fast-uri@3.1.0 (npm) is affected by GHSA-v2hh-gcrm-f6hx","path":"package-lock.json","line":null,"fingerprint":"fast-uri@3.1.0 (npm):GHSA-v2hh-gcrm-f6hx"},{"rule_id":"osv/GHSA-v39h-62p7-jpjc","severity":"high","message":"fast-uri@3.1.0 (npm) is affected by GHSA-v39h-62p7-jpjc","path":"package-lock.json","line":null,"fingerprint":"fast-uri@3.1.0 (npm):GHSA-v39h-62p7-jpjc"},{"rule_id":"osv/GHSA-25h7-pfq9-p65f","severity":"high","message":"flatted@3.3.4 (npm) is affected by GHSA-25h7-pfq9-p65f","path":"package-lock.json","line":null,"fingerprint":"flatted@3.3.4 (npm):GHSA-25h7-pfq9-p65f"},{"rule_id":"osv/GHSA-rf6f-7fwh-wjgh","severity":"high","message":"flatted@3.3.4 (npm) is affected by GHSA-rf6f-7fwh-wjgh","path":"package-lock.json","line":null,"fingerprint":"flatted@3.3.4 (npm):GHSA-rf6f-7fwh-wjgh"},{"rule_id":"osv/GHSA-2883-xcg3-v3hh","severity":"high","message":"js-yaml@4.1.1 (npm) is affected by GHSA-2883-xcg3-v3hh","path":"package-lock.json","line":null,"fingerprint":"js-yaml@4.1.1 (npm):GHSA-2883-xcg3-v3hh"},{"rule_id":"osv/GHSA-52cp-r559-cp3m","severity":"high","message":"js-yaml@4.1.1 (npm) is affected by GHSA-52cp-r559-cp3m","path":"package-lock.json","line":null,"fingerprint":"js-yaml@4.1.1 (npm):GHSA-52cp-r559-cp3m"},{"rule_id":"osv/GHSA-5p4m-2wfm-xmqj","severity":"high","message":"js-yaml@4.1.1 (npm) is affected by GHSA-5p4m-2wfm-xmqj","path":"package-lock.json","line":null,"fingerprint":"js-yaml@4.1.1 (npm):GHSA-5p4m-2wfm-xmqj"},{"rule_id":"osv/GHSA-r5fr-rjxr-66jc","severity":"high","message":"lodash@4.17.23 (npm) is affected by GHSA-r5fr-rjxr-66jc","path":"package-lock.json","line":null,"fingerprint":"lodash@4.17.23 (npm):GHSA-r5fr-rjxr-66jc"},{"rule_id":"osv/GHSA-28wg-ghj8-5hjv","severity":"high","message":"nanoid@3.3.11 (npm) is affected by GHSA-28wg-ghj8-5hjv","path":"package-lock.json","line":null,"fingerprint":"nanoid@3.3.11 (npm):GHSA-28wg-ghj8-5hjv"},{"rule_id":"osv/GHSA-2v37-7h3g-55p8","severity":"high","message":"nanoid@3.3.11 (npm) is affected by GHSA-2v37-7h3g-55p8","path":"package-lock.json","line":null,"fingerprint":"nanoid@3.3.11 (npm):GHSA-2v37-7h3g-55p8"},{"rule_id":"osv/GHSA-xwg4-73v4-xw9w","severity":"high","message":"nanoid@3.3.11 (npm) is affected by GHSA-xwg4-73v4-xw9w","path":"package-lock.json","line":null,"fingerprint":"nanoid@3.3.11 (npm):GHSA-xwg4-73v4-xw9w"},{"rule_id":"osv/GHSA-c2c7-rcm5-vvqj","severity":"high","message":"picomatch@2.3.1 (npm) is affected by GHSA-c2c7-rcm5-vvqj","path":"package-lock.json","line":null,"fingerprint":"picomatch@2.3.1 (npm):GHSA-c2c7-rcm5-vvqj"},{"rule_id":"osv/GHSA-c2c7-rcm5-vvqj","severity":"high","message":"picomatch@4.0.3 (npm) is affected by GHSA-c2c7-rcm5-vvqj","path":"package-lock.json","line":null,"fingerprint":"picomatch@4.0.3 (npm):GHSA-c2c7-rcm5-vvqj"},{"rule_id":"osv/GHSA-6g55-p6wh-862q","severity":"high","message":"postcss@8.5.8 (npm) is affected by GHSA-6g55-p6wh-862q","path":"package-lock.json","line":null,"fingerprint":"postcss@8.5.8 (npm):GHSA-6g55-p6wh-862q"},{"rule_id":"osv/GHSA-r28c-9q8g-f849","severity":"high","message":"postcss@8.5.8 (npm) is affected by GHSA-r28c-9q8g-f849","path":"package-lock.json","line":null,"fingerprint":"postcss@8.5.8 (npm):GHSA-r28c-9q8g-f849"},{"rule_id":"osv/GHSA-5c6j-r48x-rmvq","severity":"high","message":"serialize-javascript@6.0.2 (npm) is affected by GHSA-5c6j-r48x-rmvq","path":"package-lock.json","line":null,"fingerprint":"serialize-javascript@6.0.2 (npm):GHSA-5c6j-r48x-rmvq"},{"rule_id":"osv/GHSA-68fv-2mgg-jv7q","severity":"high","message":"source-map-js@1.2.1 (npm) is affected by GHSA-68fv-2mgg-jv7q","path":"package-lock.json","line":null,"fingerprint":"source-map-js@1.2.1 (npm):GHSA-68fv-2mgg-jv7q"},{"rule_id":"osv/GHSA-587h-7wmj-h5pm","severity":"high","message":"vite@7.3.1 (npm) is affected by GHSA-587h-7wmj-h5pm","path":"package-lock.json","line":null,"fingerprint":"vite@7.3.1 (npm):GHSA-587h-7wmj-h5pm"},{"rule_id":"osv/GHSA-p9ff-h696-f583","severity":"high","message":"vite@7.3.1 (npm) is affected by GHSA-p9ff-h696-f583","path":"package-lock.json","line":null,"fingerprint":"vite@7.3.1 (npm):GHSA-p9ff-h696-f583"},{"rule_id":"osv/GHSA-v2wj-q39q-566r","severity":"high","message":"vite@7.3.1 (npm) is affected by GHSA-v2wj-q39q-566r","path":"package-lock.json","line":null,"fingerprint":"vite@7.3.1 (npm):GHSA-v2wj-q39q-566r"},{"rule_id":"osv/GHSA-mrhx-c7xc-m3w5","severity":"high","message":"zod@4.3.6 (npm) is affected by GHSA-mrhx-c7xc-m3w5","path":"package-lock.json","line":null,"fingerprint":"zod@4.3.6 (npm):GHSA-mrhx-c7xc-m3w5"},{"rule_id":"osv/GHSA-p498-v437-472g","severity":"medium","message":"@humanfs/node@0.16.7 (npm) is affected by GHSA-p498-v437-472g","path":"package-lock.json","line":null,"fingerprint":"@humanfs/node@0.16.7 (npm):GHSA-p498-v437-472g"},{"rule_id":"osv/GHSA-w5vr-8v7q-w6rv","severity":"medium","message":"baseline-browser-mapping@2.10.0 (npm) is affected by GHSA-w5vr-8v7q-w6rv","path":"package-lock.json","line":null,"fingerprint":"baseline-browser-mapping@2.10.0 (npm):GHSA-w5vr-8v7q-w6rv"},{"rule_id":"osv/GHSA-f886-m6hf-6m8v","severity":"medium","message":"brace-expansion@1.1.12 (npm) is affected by GHSA-f886-m6hf-6m8v","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@1.1.12 (npm):GHSA-f886-m6hf-6m8v"},{"rule_id":"osv/GHSA-q2hr-2g5m-vwhr","severity":"medium","message":"brace-expansion@1.1.12 (npm) is affected by GHSA-q2hr-2g5m-vwhr","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@1.1.12 (npm):GHSA-q2hr-2g5m-vwhr"},{"rule_id":"osv/GHSA-f886-m6hf-6m8v","severity":"medium","message":"brace-expansion@2.0.2 (npm) is affected by GHSA-f886-m6hf-6m8v","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@2.0.2 (npm):GHSA-f886-m6hf-6m8v"},{"rule_id":"osv/GHSA-q2hr-2g5m-vwhr","severity":"medium","message":"brace-expansion@2.0.2 (npm) is affected by GHSA-q2hr-2g5m-vwhr","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@2.0.2 (npm):GHSA-q2hr-2g5m-vwhr"},{"rule_id":"osv/GHSA-f886-m6hf-6m8v","severity":"medium","message":"brace-expansion@5.0.4 (npm) is affected by GHSA-f886-m6hf-6m8v","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@5.0.4 (npm):GHSA-f886-m6hf-6m8v"},{"rule_id":"osv/GHSA-jxxr-4gwj-5jf2","severity":"medium","message":"brace-expansion@5.0.4 (npm) is affected by GHSA-jxxr-4gwj-5jf2","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@5.0.4 (npm):GHSA-jxxr-4gwj-5jf2"},{"rule_id":"osv/GHSA-q2hr-2g5m-vwhr","severity":"medium","message":"brace-expansion@5.0.4 (npm) is affected by GHSA-q2hr-2g5m-vwhr","path":"package-lock.json","line":null,"fingerprint":"brace-expansion@5.0.4 (npm):GHSA-q2hr-2g5m-vwhr"},{"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-hrr3-gc8f-f4qj","severity":"medium","message":"fast-uri@3.1.0 (npm) is affected by GHSA-hrr3-gc8f-f4qj","path":"package-lock.json","line":null,"fingerprint":"fast-uri@3.1.0 (npm):GHSA-hrr3-gc8f-f4qj"},{"rule_id":"osv/GHSA-w74x-v6f9-j3xg","severity":"medium","message":"fast-uri@3.1.0 (npm) is affected by GHSA-w74x-v6f9-j3xg","path":"package-lock.json","line":null,"fingerprint":"fast-uri@3.1.0 (npm):GHSA-w74x-v6f9-j3xg"},{"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-h67p-54hq-rp68","severity":"medium","message":"js-yaml@4.1.1 (npm) is affected by GHSA-h67p-54hq-rp68","path":"package-lock.json","line":null,"fingerprint":"js-yaml@4.1.1 (npm):GHSA-h67p-54hq-rp68"},{"rule_id":"osv/GHSA-f23m-r3pf-42rh","severity":"medium","message":"lodash@4.17.23 (npm) is affected by GHSA-f23m-r3pf-42rh","path":"package-lock.json","line":null,"fingerprint":"lodash@4.17.23 (npm):GHSA-f23m-r3pf-42rh"},{"rule_id":"osv/GHSA-g3hv-75wg-m249","severity":"medium","message":"minimatch@10.2.4 (npm) is affected by GHSA-g3hv-75wg-m249","path":"package-lock.json","line":null,"fingerprint":"minimatch@10.2.4 (npm):GHSA-g3hv-75wg-m249"},{"rule_id":"osv/GHSA-3v7f-55p6-f55p","severity":"medium","message":"picomatch@2.3.1 (npm) is affected by GHSA-3v7f-55p6-f55p","path":"package-lock.json","line":null,"fingerprint":"picomatch@2.3.1 (npm):GHSA-3v7f-55p6-f55p"},{"rule_id":"osv/GHSA-3v7f-55p6-f55p","severity":"medium","message":"picomatch@4.0.3 (npm) is affected by GHSA-3v7f-55p6-f55p","path":"package-lock.json","line":null,"fingerprint":"picomatch@4.0.3 (npm):GHSA-3v7f-55p6-f55p"},{"rule_id":"osv/GHSA-fxqj-rqcc-2cmp","severity":"medium","message":"postcss@8.5.8 (npm) is affected by GHSA-fxqj-rqcc-2cmp","path":"package-lock.json","line":null,"fingerprint":"postcss@8.5.8 (npm):GHSA-fxqj-rqcc-2cmp"},{"rule_id":"osv/GHSA-qx2v-qp2m-jg93","severity":"medium","message":"postcss@8.5.8 (npm) is affected by GHSA-qx2v-qp2m-jg93","path":"package-lock.json","line":null,"fingerprint":"postcss@8.5.8 (npm):GHSA-qx2v-qp2m-jg93"},{"rule_id":"osv/GHSA-qj8w-gfj5-8c6v","severity":"medium","message":"serialize-javascript@6.0.2 (npm) is affected by GHSA-qj8w-gfj5-8c6v","path":"package-lock.json","line":null,"fingerprint":"serialize-javascript@6.0.2 (npm):GHSA-qj8w-gfj5-8c6v"},{"rule_id":"osv/GHSA-4w7w-66w2-5vf9","severity":"medium","message":"vite@7.3.1 (npm) is affected by GHSA-4w7w-66w2-5vf9","path":"package-lock.json","line":null,"fingerprint":"vite@7.3.1 (npm):GHSA-4w7w-66w2-5vf9"},{"rule_id":"osv/GHSA-698v-4r3x-3vcv","severity":"medium","message":"vite@7.3.1 (npm) is affected by GHSA-698v-4r3x-3vcv","path":"package-lock.json","line":null,"fingerprint":"vite@7.3.1 (npm):GHSA-698v-4r3x-3vcv"},{"rule_id":"osv/GHSA-fx2h-pf6j-xcff","severity":"medium","message":"vite@7.3.1 (npm) is affected by GHSA-fx2h-pf6j-xcff","path":"package-lock.json","line":null,"fingerprint":"vite@7.3.1 (npm):GHSA-fx2h-pf6j-xcff"},{"rule_id":"osv/GHSA-r825-w8mm-5pxw","severity":"medium","message":"vite@7.3.1 (npm) is affected by GHSA-r825-w8mm-5pxw","path":"package-lock.json","line":null,"fingerprint":"vite@7.3.1 (npm):GHSA-r825-w8mm-5pxw"},{"rule_id":"osv/GHSA-rq7h-c2jc-7f22","severity":"medium","message":"vite@7.3.1 (npm) is affected by GHSA-rq7h-c2jc-7f22","path":"package-lock.json","line":null,"fingerprint":"vite@7.3.1 (npm):GHSA-rq7h-c2jc-7f22"},{"rule_id":"osv/GHSA-v6wh-96g9-6wx3","severity":"medium","message":"vite@7.3.1 (npm) is affected by GHSA-v6wh-96g9-6wx3","path":"package-lock.json","line":null,"fingerprint":"vite@7.3.1 (npm):GHSA-v6wh-96g9-6wx3"},{"rule_id":"osv/GHSA-4x5r-pxfx-6jf8","severity":"low","message":"@babel/core@7.29.0 (npm) is affected by GHSA-4x5r-pxfx-6jf8","path":"package-lock.json","line":null,"fingerprint":"@babel/core@7.29.0 (npm):GHSA-4x5r-pxfx-6jf8"},{"rule_id":"osv/GHSA-g7r4-m6w7-qqqr","severity":"low","message":"esbuild@0.27.3 (npm) is affected by GHSA-g7r4-m6w7-qqqr","path":"package-lock.json","line":null,"fingerprint":"esbuild@0.27.3 (npm):GHSA-g7r4-m6w7-qqqr"},{"rule_id":"osv/GHSA-333x-w4r6-6crp","severity":"low","message":"fast-uri@3.1.0 (npm) is affected by GHSA-333x-w4r6-6crp","path":"package-lock.json","line":null,"fingerprint":"fast-uri@3.1.0 (npm):GHSA-333x-w4r6-6crp"},{"rule_id":"osv/GHSA-xhq7-xmqj-769h","severity":"low","message":"fast-uri@3.1.0 (npm) is affected by GHSA-xhq7-xmqj-769h","path":"package-lock.json","line":null,"fingerprint":"fast-uri@3.1.0 (npm):GHSA-xhq7-xmqj-769h"},{"rule_id":"osv/GHSA-m5mm-p8h7-m29v","severity":"low","message":"serialize-javascript@6.0.2 (npm) is affected by GHSA-m5mm-p8h7-m29v","path":"package-lock.json","line":null,"fingerprint":"serialize-javascript@6.0.2 (npm):GHSA-m5mm-p8h7-m29v"},{"rule_id":"osv/GHSA-9jrq-w75r-8gcw","severity":"low","message":"vite@7.3.1 (npm) is affected by GHSA-9jrq-w75r-8gcw","path":"package-lock.json","line":null,"fingerprint":"vite@7.3.1 (npm):GHSA-9jrq-w75r-8gcw"}],"evidence":[],"data":{"ecosystems":["npm"]},"error":null},{"analyzer":"sec-actions","pillar":"security","status":"skipped","tool_version":null,"metrics":{},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-posture","pillar":"security","status":"ok","tool_version":null,"metrics":{"check:security_policy":0.0,"check:dependency_updates":0.0,"check:signed_commits":0.0,"check:lockfiles":1.0,"signed_commit_share":0.0,"unpinned_manifests":0.0},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-distribution","pillar":"security","status":"ok","tool_version":null,"metrics":{"signals":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":656.0,"function_nloc":5718.0,"mean_ccn":2.59,"p90_ccn":5.0,"complex_functions":12.0,"long_functions":4.0,"many_param_functions":0.0,"risky_nloc_share":0.2079},"findings":[],"evidence":[{"kind":"complex-function","description":"validateProgressionConfig in src/lib/progression-config.ts: complexity 39, 122 lines","ref":"src/lib/progression-config.ts","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/lib/progression-config.ts#L1528","weight":0.65},{"kind":"complex-function","description":"parseHeavenlyEffects in scripts/generate-epoch-content.mjs: complexity 27, 47 lines","ref":"scripts/generate-epoch-content.mjs","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/scripts/generate-epoch-content.mjs#L663","weight":0.45},{"kind":"complex-function","description":"parseModernState in src/lib/game-save.ts: complexity 27, 89 lines","ref":"src/lib/game-save.ts","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/lib/game-save.ts#L251","weight":0.45},{"kind":"complex-function","description":"parseUpgradeEffect in scripts/generate-epoch-content.mjs: complexity 25, 46 lines","ref":"scripts/generate-epoch-content.mjs","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/scripts/generate-epoch-content.mjs#L436","weight":0.4166666666666667},{"kind":"complex-function","description":"localMultiplier in src/lib/game-engine.ts: complexity 24, 1 lines","ref":"src/lib/game-engine.ts","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/lib/game-engine.ts#L107","weight":0.4},{"kind":"complex-function","description":"metric in src/lib/game-engine.ts: complexity 24, 1 lines","ref":"src/lib/game-engine.ts","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/lib/game-engine.ts#L74","weight":0.4},{"kind":"complex-function","description":"AscensionScreen in src/screens/ascension-screen.tsx: complexity 24, 52 lines","ref":"src/screens/ascension-screen.tsx","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/screens/ascension-screen.tsx#L11","weight":0.4},{"kind":"complex-function","description":"App in src/App.tsx: complexity 21, 244 lines","ref":"src/App.tsx","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/App.tsx#L267","weight":0.35},{"kind":"complex-function","description":"loadGameStateWithSummary in src/lib/game-save.ts: complexity 21, 57 lines","ref":"src/lib/game-save.ts","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/lib/game-save.ts#L407","weight":0.35},{"kind":"complex-function","description":"normalizeRecord in src/lib/save-db.ts: complexity 20, 58 lines","ref":"src/lib/save-db.ts","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/lib/save-db.ts#L25","weight":0.3333333333333333}],"data":{},"error":null},{"analyzer":"qual-duplication","pillar":"quality","status":"ok","tool_version":"repotrust-dup-w6","metrics":{"compared_lines":7569.0,"duplicated_lines":418.0,"duplicated_share":0.0552,"files":49.0},"findings":[],"evidence":[{"kind":"duplicate-code","description":"6+ duplicated lines: scripts/phase1-balance-report.ts:12 and src/lib/progression-config.ts:143","ref":"scripts/phase1-balance-report.ts","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/scripts/phase1-balance-report.ts#L12","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: src/App.tsx:443 and src/App.tsx:562","ref":"src/App.tsx","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/App.tsx#L443","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: src/components/game/credits-header.tsx:42 and src/components/game/credits-header.tsx:69","ref":"src/components/game/credits-header.tsx","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/components/game/credits-header.tsx#L42","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: src/components/game/producer-list-row.tsx:11 and src/components/game/purchase-feedback-container.tsx:14","ref":"src/components/game/producer-list-row.tsx","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/components/game/producer-list-row.tsx#L11","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: src/components/ui/alert-dialog.tsx:129 and src/screens/reinvestment-screen.tsx:4","ref":"src/components/ui/alert-dialog.tsx","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/components/ui/alert-dialog.tsx#L129","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: src/components/ui/button.tsx:49 and src/components/ui/switch.tsx:17","ref":"src/components/ui/button.tsx","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/components/ui/button.tsx#L49","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: src/lib/dev-bootstrap.ts:97 and src/lib/dev-bootstrap.ts:131","ref":"src/lib/dev-bootstrap.ts","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/lib/dev-bootstrap.ts#L97","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: src/lib/progression-config.ts:4 and src/lib/progression-config.ts:78","ref":"src/lib/progression-config.ts","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/lib/progression-config.ts#L4","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: src/screens/operations-screen.tsx:43 and src/screens/production-screen.tsx:40","ref":"src/screens/operations-screen.tsx","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/screens/operations-screen.tsx#L43","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: src/screens/production-screen.tsx:41 and src/screens/tab-views.tsx:62","ref":"src/screens/production-screen.tsx","url":"https://github.com/MattGibney/Epoch-Foundry/blob/75f19103a9369845ccf16680eb73502f19d3a22f/src/screens/production-screen.tsx#L41","weight":0.3}],"data":{},"error":null},{"analyzer":"qual-lint","pillar":"quality","status":"ok","tool_version":"opengrep 1.33.1; rules f1d2b562b414","metrics":{"findings":51.0,"weighted_findings":51.0,"scanned_lines":9905.0,"category:best-practice":44.0,"category:correctness":7.0},"findings":[{"rule_id":"opengrep/javascript.lang.correctness.no-replaceall","severity":"medium","message":"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\") instead of mystring.replaceAll(\"bad\", \"good\") (https://discourse.thre","path":"scripts/generate-epoch-content.mjs","line":303,"fingerprint":"javascript.lang.correctness.no-replaceall:scripts/generate-epoch-content.mjs:303"},{"rule_id":"opengrep/javascript.lang.correctness.no-replaceall","severity":"medium","message":"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\") instead of mystring.replaceAll(\"bad\", \"good\") (https://discourse.thre","path":"scripts/generate-epoch-content.mjs","line":412,"fingerprint":"javascript.lang.correctness.no-replaceall:scripts/generate-epoch-content.mjs:412"},{"rule_id":"opengrep/javascript.lang.correctness.no-replaceall","severity":"medium","message":"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\") instead of mystring.replaceAll(\"bad\", \"good\") (https://discourse.thre","path":"scripts/generate-epoch-content.mjs","line":419,"fingerprint":"javascript.lang.correctness.no-replaceall:scripts/generate-epoch-content.mjs:419"},{"rule_id":"opengrep/javascript.lang.correctness.no-replaceall","severity":"medium","message":"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\") instead of mystring.replaceAll(\"bad\", \"good\") (https://discourse.thre","path":"scripts/generate-epoch-content.mjs","line":449,"fingerprint":"javascript.lang.correctness.no-replaceall:scripts/generate-epoch-content.mjs:449"},{"rule_id":"opengrep/javascript.lang.correctness.no-replaceall","severity":"medium","message":"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\") instead of mystring.replaceAll(\"bad\", \"good\") (https://discourse.thre","path":"scripts/generate-epoch-content.mjs","line":498,"fingerprint":"javascript.lang.correctness.no-replaceall:scripts/generate-epoch-content.mjs:498"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/App.tsx","line":972,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/App.tsx:972"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/App.tsx","line":981,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/App.tsx:981"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/App.tsx","line":992,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/App.tsx:992"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/App.tsx","line":1004,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/App.tsx:1004"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/App.tsx","line":1011,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/App.tsx:1011"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/App.tsx","line":1015,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/App.tsx:1015"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/App.tsx","line":1026,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/App.tsx:1026"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/App.tsx","line":1032,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/App.tsx:1032"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/App.tsx","line":1036,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/App.tsx:1036"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/App.tsx","line":1047,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/App.tsx:1047"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/game/purchase-feedback-container.tsx","line":99,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/game/purchase-feedback-container.tsx:99"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/game/upgrade-list-item.tsx","line":52,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/game/upgrade-list-item.tsx:52"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/alert-dialog.tsx","line":10,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/alert-dialog.tsx:10"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/alert-dialog.tsx","line":16,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/alert-dialog.tsx:16"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/alert-dialog.tsx","line":22,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/alert-dialog.tsx:22"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/alert-dialog.tsx","line":36,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/alert-dialog.tsx:36"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/alert-dialog.tsx","line":54,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/alert-dialog.tsx:54"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/alert-dialog.tsx","line":65,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/alert-dialog.tsx:65"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/alert-dialog.tsx","line":75,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/alert-dialog.tsx:75"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/alert-dialog.tsx","line":88,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/alert-dialog.tsx:88"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/alert-dialog.tsx","line":101,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/alert-dialog.tsx:101"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/alert-dialog.tsx","line":112,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/alert-dialog.tsx:112"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/alert-dialog.tsx","line":123,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/alert-dialog.tsx:123"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/button.tsx","line":67,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/button.tsx:67"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/button.tsx","line":72,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/button.tsx:72"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/button.tsx","line":72,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/button.tsx:72"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/popover.tsx","line":7,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/popover.tsx:7"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/popover.tsx","line":13,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/popover.tsx:13"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/popover.tsx","line":19,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/popover.tsx:19"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/popover.tsx","line":38,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/popover.tsx:38"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/sheet.tsx","line":8,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/sheet.tsx:8"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/sheet.tsx","line":14,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/sheet.tsx:14"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/sheet.tsx","line":18,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/sheet.tsx:18"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/sheet.tsx","line":22,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/sheet.tsx:22"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/sheet.tsx","line":36,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/sheet.tsx:36"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/sheet.tsx","line":68,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/sheet.tsx:68"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/sheet.tsx","line":87,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/sheet.tsx:87"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/sheet.tsx","line":97,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/sheet.tsx:97"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/sheet.tsx","line":110,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/sheet.tsx:110"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/sheet.tsx","line":123,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/sheet.tsx:123"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/sonner.tsx","line":18,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/sonner.tsx:18"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/switch.tsx","line":39,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/switch.tsx:39"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/switch.tsx","line":50,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/switch.tsx:50"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"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 actors a way to inject unexpected attributes.","path":"src/components/ui/switch.tsx","line":50,"fingerprint":"typescript.react.best-practice.react-props-spreading:src/components/ui/switch.tsx:50"},{"rule_id":"opengrep/javascript.lang.correctness.no-replaceall","severity":"medium","message":"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\") instead of mystring.replaceAll(\"bad\", \"good\") (https://discourse.thre","path":"src/lib/game-engine.ts","line":73,"fingerprint":"javascript.lang.correctness.no-replaceall:src/lib/game-engine.ts:73"},{"rule_id":"opengrep/javascript.lang.correctness.no-replaceall","severity":"medium","message":"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\") instead of mystring.replaceAll(\"bad\", \"good\") (https://discourse.thre","path":"src/lib/game-engine.ts","line":73,"fingerprint":"javascript.lang.correctness.no-replaceall:src/lib/game-engine.ts:73"}],"evidence":[],"data":{},"error":null},{"analyzer":"qual-testing","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:has_tests":0.0,"check:test_ratio":0.0,"check:ci_present":0.0,"check:ci_runs_tests":0.0,"check:ci_runs_lint":0.0,"check:tests_cochange":0.0,"test_lines":0.0,"source_lines":9905.0,"test_ratio":0.0,"ci_files":0.0,"cochange_share":0.0,"cochange_commits":123.0},"findings":[],"evidence":[],"data":{"test_commands":[],"lint_commands":[]},"error":null},{"analyzer":"qual-docs","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:readme":1.0,"check:license":0.0,"check:contributing":0.0,"check:changelog":0.0,"readme_lines":46.0},"findings":[],"evidence":[{"kind":"docs","description":"README.md","ref":"README.md","url":null,"weight":0.0}],"data":{},"error":null},{"analyzer":"qual-type-safety","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:strict_config":1.0,"check:low_escape_density":1.0,"escapes":0.0,"escapes_per_kloc":0.0},"findings":[],"evidence":[{"kind":"typing","description":"TypeScript strict type checking: tsconfig.app.json","ref":"tsconfig.app.json","url":null,"weight":0.0}],"data":{},"error":null}],"flags":[]}