{"schema_version":"2","scorer_version":"0.1.0","scoring_version":"prov-5+qual-2+sec-2","generated_at":"2026-11-14T14:52:05.570350Z","repo":{"ref":{"host":"github.com","owner":"joeyprijs","name":"gravity"},"default_branch":"main","clone_url":"https://github.com/joeyprijs/gravity.git","html_url":"https://github.com/joeyprijs/gravity","description":null,"stars":1,"forks":0,"is_fork":false,"is_archived":false,"is_private":false,"size_kb":3729,"primary_language":"JavaScript","license_spdx":"Unlicense","created_at":"2026-04-09T16:25:15Z","pushed_at":"2026-09-11T16:12:11Z","security_policy_url":null,"distribution":{"owner_created_at":"2012-09-04T14:46:42Z","owner_type":"User","release_assets":[]}},"commit_sha":"e99aa2ea58af23f30944684f6279e298c1559c65","profile":{"lines_by_language":{"JavaScript":13020,"Shell":98},"files_by_category":{"config":149,"source":33,"test":23,"docs":12,"other":3},"source_lines":7760,"test_lines":5358},"pillars":{"ai_provenance":{"score":93.2,"confidence":0.95,"coverage":1.0,"label":"explicit","breakdown":{"attributed_share":0.932,"suspected_share":0.0009,"estimated_share":0.932,"ai_artifacts":0.0,"flagged_work_units":4.0,"flagged_releases":null,"style_index":0.129},"summary":"Explicit AI attribution on 93% of first-party code added; an estimated 93% including velocity signals."},"quality":{"score":82.7,"confidence":0.9,"coverage":1.0,"label":"strong","breakdown":{"complexity":78.3,"duplication":98.3,"lint":72.5,"testing":90.0,"docs":65.0,"type_safety":null,"process":null},"summary":"Code quality is strong: test-to-source ratio 0.69, CI runs tests; 8% of function code in complex or long functions; 0% duplicated lines. Weakest area: docs."},"security":{"score":63.6,"confidence":0.85,"coverage":1.0,"label":"weak","breakdown":{"secrets":100.0,"sast":50.1,"dependencies":null,"ci_actions":63.1,"posture":0.0,"scorecard":null},"summary":"Security posture is weak: 14 high-severity SAST findings; 2 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":"skipped","tool_version":null,"metrics":{},"findings":[],"evidence":[],"data":{},"error":"no registry dependencies declared"},{"analyzer":"ai-attribution","pillar":"ai_provenance","status":"ok","tool_version":"signatures-v1","metrics":{"commits":351.0,"attributed_commits":329.0,"attributed_commit_share":0.9373219373219374,"effective_loc":38783.0,"attributed_loc":36145.0,"attributed_loc_share":0.9319805069231364,"tools_detected":1.0},"findings":[],"evidence":[{"kind":"attribution-summary","description":"Claude Code: 329 attributed commits, 36,145 lines added","ref":null,"url":null,"weight":1.0},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"e99aa2ea58af23f30944684f6279e298c1559c65","url":"https://github.com/joeyprijs/gravity/commit/e99aa2ea58af23f30944684f6279e298c1559c65","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"9105c3fafed4ea01d15cb062e902095989e84672","url":"https://github.com/joeyprijs/gravity/commit/9105c3fafed4ea01d15cb062e902095989e84672","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"946773aee692c5bbd434e2cdb80480ad5cf55bf3","url":"https://github.com/joeyprijs/gravity/commit/946773aee692c5bbd434e2cdb80480ad5cf55bf3","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"590679222b077088242ee1519e43d16fd605a72e","url":"https://github.com/joeyprijs/gravity/commit/590679222b077088242ee1519e43d16fd605a72e","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"e60b6bda14af99472ea32f2428bbe243412a7a2a","url":"https://github.com/joeyprijs/gravity/commit/e60b6bda14af99472ea32f2428bbe243412a7a2a","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"9ce8644e85370f4bc56a1acadc7eaca1436c0683","url":"https://github.com/joeyprijs/gravity/commit/9ce8644e85370f4bc56a1acadc7eaca1436c0683","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"25b0c81360b0c6191a887464126774dbc0637989","url":"https://github.com/joeyprijs/gravity/commit/25b0c81360b0c6191a887464126774dbc0637989","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"f10bb1ad1181a3473c4ca5203171407793e0c5ae","url":"https://github.com/joeyprijs/gravity/commit/f10bb1ad1181a3473c4ca5203171407793e0c5ae","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"4d48535ecb5a26c242db0cff897eafcb5bccd93a","url":"https://github.com/joeyprijs/gravity/commit/4d48535ecb5a26c242db0cff897eafcb5bccd93a","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"a88bffba9f834cedfa8f3372213206283b3f1843","url":"https://github.com/joeyprijs/gravity/commit/a88bffba9f834cedfa8f3372213206283b3f1843","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"cafb399d81ac4ab14f9c43b16955a252514ab341","url":"https://github.com/joeyprijs/gravity/commit/cafb399d81ac4ab14f9c43b16955a252514ab341","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"468c40c116e052f31e9df6967ac5d17ada81d45a","url":"https://github.com/joeyprijs/gravity/commit/468c40c116e052f31e9df6967ac5d17ada81d45a","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"fe47d737c073dacac8a2ed3f09361e9d303311d4","url":"https://github.com/joeyprijs/gravity/commit/fe47d737c073dacac8a2ed3f09361e9d303311d4","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"2cf1b3a82d80bfc905b2266649cc00e53c2c7634","url":"https://github.com/joeyprijs/gravity/commit/2cf1b3a82d80bfc905b2266649cc00e53c2c7634","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"4eb95542bc7855f6bb1d8f1c4eaf1dd328ac67a1","url":"https://github.com/joeyprijs/gravity/commit/4eb95542bc7855f6bb1d8f1c4eaf1dd328ac67a1","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"073dd1d34bb45da373b241c8cbf96c563a940952","url":"https://github.com/joeyprijs/gravity/commit/073dd1d34bb45da373b241c8cbf96c563a940952","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"5406b500872e5b575c31ecba2bc3ff95a451c958","url":"https://github.com/joeyprijs/gravity/commit/5406b500872e5b575c31ecba2bc3ff95a451c958","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"564d320b30a594c643607ecc6db19fe739365f29","url":"https://github.com/joeyprijs/gravity/commit/564d320b30a594c643607ecc6db19fe739365f29","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"d61de430e7f29ebbd6bb5fb485ae400c9ab4d9bd","url":"https://github.com/joeyprijs/gravity/commit/d61de430e7f29ebbd6bb5fb485ae400c9ab4d9bd","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"8ce62733256e9490cf92f273e6c35d88b05d5456","url":"https://github.com/joeyprijs/gravity/commit/8ce62733256e9490cf92f273e6c35d88b05d5456","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"27376f55edca4edc2b15c1737e1b313fb6c9c35c","url":"https://github.com/joeyprijs/gravity/commit/27376f55edca4edc2b15c1737e1b313fb6c9c35c","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"fd094af4b3d5b789fd3715bbffa5c888fa54d74d","url":"https://github.com/joeyprijs/gravity/commit/fd094af4b3d5b789fd3715bbffa5c888fa54d74d","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"c9cb01ddb6a6550d86a323f393cd675fb75f17e6","url":"https://github.com/joeyprijs/gravity/commit/c9cb01ddb6a6550d86a323f393cd675fb75f17e6","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"26e6293e8da312f2d770bcb6d6fad8095639d83b","url":"https://github.com/joeyprijs/gravity/commit/26e6293e8da312f2d770bcb6d6fad8095639d83b","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: trailer 'Co-Authored-By: Claude'","ref":"194eb19811711e19a963a979fb9f7b841ad58548","url":"https://github.com/joeyprijs/gravity/commit/194eb19811711e19a963a979fb9f7b841ad58548","weight":0.9}],"data":{"attributed_loc_by_commit":{"382497f6ab210f5f6fb75d4fe529c1810db16cf6":1703,"a39b43df6dedbbbc80dd7f8475ec6f78c0eb2956":0,"9f669a0a8a15757a88444a72247a4bcaf1ffdab8":0,"b5a05c9d201200abe766330a374aaa7671510de0":212,"3c86f810de66ae2d620818187bcc0c6a96246f56":238,"35a13a24a0e4d2ee74a0541c5acae3543344271b":48,"6053ba2599306a50553602d2dc487642a3abdaa3":149,"0f415cd5e7da871e4ec7d48ab5365014583b70a7":34,"2a4148b26ef8561bee7dcb783b073fdc30b77f7a":0,"64be9039206d48117cd17b8847e0b68fc56cea6b":0,"ceb45e4858705aac8fbd605503c5c83e7d750782":54,"6067dfb47e66d98a4b0b061f8e5f8184fa4813a7":11,"5cfff8b99ba7dbb33fcb039bf4b6fd8c17793397":1,"746d50727e66c7eb9f3c0f71c1fdfd68027d23bb":51,"4eedfec84fa43028c5927fa6c0b91f3985dd58f4":48,"7207a932c035e69386132d2473b6269ae7e639bf":22,"bbe94aeb557c52a7f752437982c92e3c54dbe7f7":107,"7aa169c624177a553c98520a032bc2ad61bc1f44":48,"cacd67d0057034f6c13d549f40402072e9ef6bae":14,"4e3710f9ef86531fc7344155de305d28a08cac8a":5,"17c675d79436883888324a8eab7d4f3e1b7d39f8":114,"363d4b1c7ee7a7653e89aae4857b28a27f57d53f":0,"21004260c0fb5208244db499f4dc2503acb2f643":3,"36506642e65ce8cb0c0ff69d14ece0d4ff0f9dec":33,"29ddb4f11f4b85fd1a91efd2d6c003646f49d6d0":9,"c33153b9350c48c51a7cf9eb9db6ba2ccf7d82c1":3,"5e043b0adc0be5e25955ea6141ecb373143b783f":9,"2f3e0e7d11b78102602e6ff44a21da8f31275bb3":93,"34f9bf68ea7857ed8f32e228a5d77c8443e58ecb":23,"c4d84dbda3eb0fb948422169fa3f38d9e000f531":3,"257de0dc455c562a9d78d38063efd36bd6be9780":21,"ea2e460ee3f77b1457d5d910ee7665f723b71471":1,"248959d8a0865172ef1d956ec33c356322e86740":102,"c7a6c9308aa2055b2e05172ff04f0bef3c0a90bf":20,"8715c01d99f388652deee1366cfcca25cb7f3fd9":5,"7b2ab14ee8a941e4317d8879dace8db710f3decc":1,"91e1ac6e0983db92c4191e89148e8e6c361202cc":14,"67ee8a3f5369760966f2012ccd617d2dd2e7cb9a":7,"637ab8662698b153132b5fb7e0631f631da3fd12":8,"d9195c9320411f90298add6c119769f8091e3c40":1066,"8947022d116aa9e6b6359b70612689a9f6d6e330":374,"d9b0f163465187b899427fd65fc1422bb048a12c":195,"545754f10a40b47ec22f0429455bd58f5d73a745":62,"d36557ca88400dcbdd467c36f647284265c1027f":18,"5d99f3db30d143b54c4c865fa971800604f0e830":2,"72af1332b6e032f0ad939a753b757ce61bc38ffe":89,"c5cae00e8b2b41cdc45b6caadfd407b4d9728ca9":97,"d3a018aae39bd8204e4abcdcfd613ae4175f04a9":1,"a287ad1f63ba3f3b77af7c0170c0b956400f40ad":102,"bece1ba999597d4f9439571342644d6523836015":54,"c0c235e849c16ad2ff0a64c685892306ab632449":306,"9aadf2a0d26bf5d2a14776dc222d813d746e40f1":33,"2f1595b54ec1c9769c486f33008339a94b046522":61,"1715cd29a249426c5b9a29ecd74b0f329cc0194e":0,"7efe24b6f98f73b7601b2de453069399a4480c07":13,"b088ac1e86e7439f9f96c06a674a1b029d28cca8":33,"34a19ad3327b6f192e7650acf74f9837505724cc":53,"3310e135bbca48ed76ec4a6c6bb143941c7fb698":4,"56cf4e726474d1d0a6794bb287e48102769a45f0":6,"f8fd0334cdaf038abacf9854613afc71a7956146":9,"7a20c83f1f0357a45e9e74642a46bd7f0ef99f1f":31,"ce6be0528bfbcd07ada625dd2005e79f3cace38f":35,"49070e9527679bbef55f0efa5ba89b6c1f869c4a":13,"866f18b7939b4c73068c3ed8d8c093197b02c673":3,"dc45eb3508cf0b6e14d48078b0beca2d0d4b10c3":1,"83a4253ac60e3da1f7ecca1a8087d9bcf17e7b82":0,"c9db0cedb8da69ff1662f2154fc1fb4b68f1eb56":1,"ff589fdeb5385de56171d0c0915402401b3d60eb":19,"c530c1344d253f1fabc5eac86a0c9de946e7afb3":27,"25c25e059c55407e2410acb1aed3b1695b2aea7c":55,"4af49c5bdb0c390c8ea1d5c8c40e10b8a013a9b8":2,"11e315f5f45536d4246c612232cb2c2860960d61":0,"32d3be24ccf9b2a023b06fb09862d122e4627d47":443,"ffe7b7423d36aec57134cb089df120a25f72eec5":28,"b0282e89ae66a59407f4277dbe64688c94a72e01":8,"248540c82d653a0ca91c208450e80046549b1829":82,"3dd82ab28d8ae19d8fd09f54c63af94c47dee9f1":8,"0791528a64b2d2d7f4669e53fc14688652963a87":1,"127d24ff7bc85377f23d000608de2ab539ae7b9b":37,"9330c331db91e921dec9ed8c520dd386b9d60ac6":428,"eb3fd785b6895e3643d9cc3a91711d10cbaec631":21,"3a7901e77680c2ef319efd34df9391d8728fa8da":58,"fd2e65a6f49b43d362c61bc3308ee4781787bc94":20,"e6559ca35daad80fed20ae2e01dbde6438fe756f":0,"2e42f6764fc158c463a923feb574341cb82ae3c4":2594,"8a473a843b1e455063287c831b5862e3118a2b4a":180,"586d08ac7f209480a9cd27dd14b11586e13ac793":0,"2e19c00812d64c509c0d40fc70bd31290356914b":285,"0d67e7b14717bb66275a18c3526c4c875021f82a":0,"7a6ac0710d70721594dad48f9b369c494cf34284":1140,"6e62634ffeedae43ad7d8d483e3a7bd65a39b575":1,"71aec9ceed252847292a4e700a026c31a34c6baf":7,"eac47285c55db76a9d75b43b4e2ffd4966b15e93":912,"7aca8deb50d5bd31b33c71e04c8b567f60c5bfe1":97,"cefae8b93124bb387a9bdd8bead3f3d17fa9a111":107,"8cade2f59cf9e4bd0c55a4a9e70473100dd689fd":10,"1f7b337b513e2c34071b36dc97fe179336402d17":0,"80c29429057d2614e6e867d4ee36655a2524ab7b":32,"bf7463dc2cc560d43f2ee208a0f04bcfd159ab76":61,"78c5aa7e1d1a0599a843a664c8ed711d641804b0":35,"b1f24b0a231e616612b5b2fe6521f4b050f6667b":137,"faa11439a5d02274a36efc8bfb32c3a3af9d8638":89,"da65dcf0ceae994c0c785668fec7e1a4a99541a8":0,"fb1195d9400e21c06901d804d0af89e500e7ac72":158,"8ddceb9074ad79cacd9ed21abe1fc19cd5e754c7":64,"b38b488c04f6f7201c58d4923d28698c3fcc37c4":131,"6e950dab623774f636c6dd2d5bda5022227020d9":0,"c9558450f40d32653b9e7aafb19476628cb404df":36,"2f7bf1a45cf33236855fd5d1b6ba8b64959125f8":57,"c2993abc7b001b6be890ac82773ce499a9255867":0,"a8e141e21a677a53b3ae0c0495f7dbeb1d3131a9":379,"cd4a774d01e163b1e91e0cba00f094f0cc647ec4":256,"7169cd10b48788c87cae6e049ea48f3a54177503":8,"012be781eca115b923c6e3971fd8d0c0e079b8b4":0,"c778184946599735db541b111f4a463ea2f2217d":281,"4bfa9e87e4a2e688027ebbe7d92267377bcb5265":167,"292030d6a2ddf305a6eca440487f027576864e9f":0,"d079d89738f44f19a2b94fba1d4c1b49022304af":0,"3fa2bc758b6999d3d0b0d97fb0553058499823e4":2,"842ba245305415b8115a5e0c165da0267df29991":0,"b49cf027d5fdbcd827bbeba8bde2dad9f1695c29":23,"e17892bc5117db193a530651ae9dc50db4278b94":42,"c18cfbd9ec54bcf33b9a6c876d83c6fb8d3850de":4,"5ad7338d1cfab3fda0c4d09f42ad6c64714227e6":2706,"2b91ea76d4c9033ceb87cac8a1874a7404c47044":36,"ca8ae7df5548ecbf24410461bbbe4698a994c89b":145,"5fa3ae6826b4ae8dbc1c067b0af7100bf10b92a2":251,"ad34944d4dfdc5e34f609db27816db6a2d6a9492":0,"48094030a8bc6b3527031b5414290ab021471c56":0,"1065092061522b6fecb2f3460bd005feecbb6d8d":97,"431a3cac8f0f4a32d75c8c0184066dd4e62a71ae":7,"f3ec92e0692e5d393a681af9363cc06f974cdac1":0,"193f519dc98cf06ea67b718e1b94c2fc5483a4af":0,"a2f6eb886e2705ccb1033d27f9b75113b2b30785":0,"21f94fabd115091acd0b9647a91808e09ef0019e":0,"4aac35ca25e601c8780013be0704eea20d0cad63":0,"baa12c94538fe075e56fd6579dc6f65bea9eb9bb":0,"6cc9598de737f09405664643032dbde3c44f7bc5":0,"14653934eaa9fd9ac68b753c88a3be82888381c7":0,"e96711d9eee527a6fe82ccd630fa85651b6a5e30":79,"b6e9d33bdb79e3b679c5ee13ef7b78e42295cce6":15,"d744a0e0b30fe200c76e3d7aa6ba06e3b5d0ec8f":0,"c1ea63891e94a9a465b4aad30e12acce307dc167":0,"24dc614bd86a8506e4db0d485e985aa3ce379c85":20,"32dd87baac33849f01abd61d80490df67167e4bf":0,"e34962270474f4d402d97cb2bb067c2de027e3fe":7,"8b317059441cd76f5b983f9dc0ef0f2f5b58b85c":6,"591adba225d051d483eaa1ad8afe23e531485b75":6,"73d7bf0385154bf669d5fe98c2ef3807e00e8f7b":4,"965a34163c115741ce69f29b07011da9952a84fb":324,"3a563b65a9a2ae7ccc9046c1b53fd04caeb8b12b":64,"fd8b512627eb3563eb980bc636c314bb422dce43":11,"e5885ab3dad2d3ee8c9d2bc8cf44e57dc6ae4621":59,"7898c8c64ce8541f017c12ce4a3aaafdefb9e108":3,"314fa9ac443142850dc330307cf265533588545f":81,"fdbec899979a9e3f46afddab57c99306ec2976f2":267,"af5e4b3ec0b062d48d50b727f772e1332d0a055a":0,"3e222cdb08abc8b9f27424015094f04bcff8ff6f":59,"6dbfc63611cf26bdc40cabc4bf8de0c64823c1d9":637,"2e6a0de037d4038258cdcb6569d0500f5693c34e":0,"a97508527ae805493cbc3d8350e1990cc75ac202":140,"f032a814af121f94179da03e71eacd23180c2e61":533,"d1bf5f7ce344849640cb8ce5ff897d5d7e317913":0,"462f0025fbf7604a0bfa9f123ac44c63596be352":59,"7cd68720227e45dae65a93c427b3540371dfdc78":115,"85428772626afcd38cf10c3515a1f1ff923a2ee0":69,"2686ceab0dcc4f6fdd2649b9d400bc0af50add4c":14,"79ffe0fffe8201a98076d804831e9f6f8d8d4af8":0,"af2e4de96bb1cf03f9a2d5c1ebb69993d579b7f5":0,"43ea29f3828a7772204d9a4fb37bdbbbbc66bf70":246,"8c780d96a314f44497b80d76069244c7b27188e8":396,"ea154c9626c23e0b2e1d2209cb6ff5900d0b6640":234,"a2e24134bdb049ed2a9024f528375f22e4d44256":131,"dbbb8f9aef0f2224727e58ec80bff6f91f9f8e7e":160,"67349bbfffd5ff426e03eef9c5005d7fdf8692a4":319,"337b67a4069986e0d29e616277c7e5131d6bdc65":7,"a0ba9f3ce17472ecaf2ce7090f0990e6513fee31":101,"8869e8e56c5f558b8c8f3ccb4d7921413fd8117d":0,"3bb7226199187c7033f5d6e68a4b78ed2e9afa6b":34,"1ba6c9d4cca2a67afb5ef8dd5338d81e39c1611a":0,"6e123c703501b64b74efd559f6939d4fd2af03d8":132,"617f973596400efa0d3e7fb0eb6a3f08f7bbb7ec":88,"2c6dc2dbe7f48900f8360d8825fe4686815be1b0":5,"b698ac76abd327b746b25ae0797066b78c9f522b":1733,"11314fc7945092bd6e702ad58533b54fa3abff3f":47,"0d5732e9ee156ddee8e4f40fbd52169286895ce6":218,"3a91f68fc78c151d947f9892e41f018c45cecf60":0,"a88b9426d566b9856252d2da6dd29acf9e889e40":51,"910a981f464e8edcf7ec5e95344e2a756cc1605e":2,"89da5e047096f9b107db38f56da25bc560d98493":0,"e2907d86a01435f595b27f68f761166267b2a031":54,"582f16d639718b384cb758a9766cb0bc30ccb0eb":32,"af3a645068c0163a5aa45a0ff336c58228e9ddfe":88,"ccee39a40c59955a75a9f0ec267ad7f6736d5523":20,"59240702ca80100b03eb3b3e45cf91f4fcea3a07":3,"1f0304c6fe49d3fef58b23df8ef6b98b99a5b131":114,"0e785fa26da9914817667928d2ef4b94e19d0e70":47,"2b93c30d35a71756afa8f5053adc80fdce54955d":113,"88a486d36f9ceb6d9a27441c79fea8a9e41c2185":20,"d3dd5e2681f2277b1675fe47373b5191100cd1a5":1083,"7baddec95177eaa1a7708eff5f91d156848bf60c":147,"fe76eeeb4966504904fc78be5bc1c95f135d0cec":67,"1269929a4e3e7dbcf61dedf28bcf5f8d7a96856b":0,"ae71465bd0b68fc7f738fce5e2dca8d83fe581c1":5,"edc9898733656add0b6abb48f4cbf852f85380ee":30,"b789014cbdb83ddc148e647f551e835c448c0cc3":8,"723562acfe1eb83d554cd42e47276d977a9c4ad9":245,"9b64a785db0955745d31c8fb59e79e2cdc70df1b":0,"2b9189aee6442806b40d3261806c2beee7a02d3c":0,"e15b7b829369ab7ef636b5372beceab3b7efc916":961,"6b73edd96e0197a958e0c2197281b7d75aade0b5":0,"f9c3d3127572848398f9a4614f2fe1e1c8dd2b48":63,"03726f25dfb981f28f45203bc9eadba5c927a0cd":20,"567a5d70d97f2bc292644bee7009f1557544fc10":42,"5f0fb3b5c32dffaf1c4c0a6f5d2ca6fd10cae1fb":0,"3bc3bc13a43f95e7d6febc4876454f140d7d5d01":307,"5f9cd5dcdb20036ec8d744f6be5c2d0f0f83a1b1":395,"52384a7050c8657ddc2282add67f9ecb0f53b2c0":0,"cd8370aa0ade4bed5a317f131f296a0154693eed":0,"5bc8e825d7a1910789e258ab9a5aa316de6d089b":0,"ee17f5ad8ea7b6d20b44dbede2be02688c874bd2":0,"40ebc49f2fc1538a939452bf9c1c82116f4bb357":107,"0c7d2555df42c493e939db766e48d535ed3ff5fb":0,"7c4cbb89510fea5075b9e5a789e462e601ca86ed":0,"f4138c5bbd1a481c32fe1e0385f0672142999d6a":0,"bc8005da1b23eadb3591cf298fa3d377af252d63":153,"c25afa310aa2a156a16725167eb6eacfcbd6db54":4,"fc99110094cf851741162070a30d71807fd8b562":88,"daf12b437c3552406bc25765bf825f2ba1d75e10":49,"a1853e319f55563d432ad82a327bc9fa21669cc1":36,"b97f22ab15d08f3b940c3e312772b47e44eb8421":0,"ce30fc05f361b7c31bbbd61adb1627a4c622a6d8":0,"1d8077f1adc23dd4c1d89255d77341cce8ab74a5":17,"c4fb22a06da0c9e3ce20ac91d1045af9b88801fd":4,"b5bfc00333cf9ca72f5cef37e319eec0234e71cc":199,"21d9a39c61818831e42c1d674fb85064352e2b3c":0,"3498b4fa2234a32d729c35463a9e86977d612e8a":0,"83a9894030acbb0b505c78d262c969d99a4124a9":5,"9fb16ce3affe339da8e37c7f508c27a8b7e27b43":0,"32a2a4ba5124a8a4b27bc0da54394eb77908f79b":32,"1dc02683533221f6e7b8cb533e951d8500301f8e":607,"9c6ab679c3938901a41570d56e8b67377be57d48":344,"8c1f1fc1d9c61ddd32d3d1111db5b57d7162846a":152,"f585000c693d170db2eb5b43531111466e25e1a4":75,"4bc896273235b343e5d729beb5bf4ab415f881a0":0,"e361fc7db993ac75a4a7625c9e4699f9fa70d761":0,"a57b3f36719d382e4aca0f7d27b99365df62b52f":69,"1c217381c400a7a87b571ba2b59c062bec8517c4":12,"694c45d8b14842128eb989e959d6686a52273b04":7,"db5f73928cb7d570a9a861169c620fe8b2722383":0,"b84f19672018cc6cea0db122a57fc54fde41c888":0,"ee2c19c884cdbf7b267a73f1cc4255e69b9877e7":0,"d84ba128cfcc1af4a75d1d38d1f0911df7a54dc0":57,"203fdd3b73f3d9bd5ef2f418e6bff17b559269e2":0,"bed2551d6f607ce77eb5285e8c0a1b2c0e4a8562":24,"a9b6742874c2e6b06dafd13e9a74cc94eb6287d9":6,"b1e60530bc6da23493531f56a4e2ab7b7b862989":91,"facfb03f76fe5ee4c7b16ff67982a742b1902c94":262,"6253300a7f9c90f146df98e06156e9d3c6388b28":2,"be6bdb1fa324cc5c0ab159a63bd797c29a265fe4":46,"e2abdac66e574a6e11ed9f9b56e71e3078119071":14,"eefd27aba2e36661ce100faef6230b937585d5c4":594,"ee6e1d8333dc2442aaa59363a658f12235616aa7":224,"196c020710e19e5188f1876319969b8beb7efb0b":187,"b3631582f4a99eec63d06a19f6753936c32fa694":0,"3564c92d5a18731df4d542e72a7672e42d0bf1ee":0,"cb85ae71eb4e72b9b4886dbc8c095098ea9946a9":117,"2f4070a39218e2d5c6102d5be4b7690d35dbe8d5":8,"f17f60d74b171885fe6bda2f4575dc556f51c75f":379,"6eecd2b62dac04760b1c444906e99af614d88e16":338,"5da42ad0ddb6e9ec84b95b90a3bc54fcb9c7ffba":104,"5a50daae27dc19803761f4a5fbfd25b18d196535":79,"5c0e81619df6886eb486e34652bb5f549d8339cf":26,"896dc5a5800b2c087cb2142185d434afd25515df":79,"0eaaad6d421a6aa1f3089f047fa8b5b4d17d4232":10,"032c2798ad422091c7b7a52b991e5b3b3d5e5df4":56,"fbca9d2f53499d823d0a717412100498a5689d22":0,"ea7f58a5c501b1682cee11a314ff2c6e7a407ce0":32,"f58feba2d8b629cd2736d4748b4cd7ce3be0a598":10,"63ed1048257726f004508af3403d788825725358":5,"d4613f9feb6bcd7dc5726fccd84453f82528aa62":0,"64769a15d25ddef1ebd56d462f183a979541e3e0":0,"fef3928558083b978150e760264169d6a2b60362":0,"eeec799a1ab500e7f4831d6e6e4c2c203fd968fb":0,"8bd4f42c4777d6cbf39cbf8abf238f29b6a69c2b":0,"c3e0735624dc2d1d0b9f693c1ad4c33de9d1637e":0,"559a64324f086ed9cf515b5046985ed3d875f2d3":0,"2959380ee6ecced2557377aae406e7d18d295e05":0,"232c6a5f218ba9f9856369419752211952f6a4ba":0,"fa78c78109283fb7d0f073ec0018055a717491ea":0,"c3f8264b4980253018f3fc6065658918a0581556":0,"fe9545655fd53f2e6eeae854648d1f8aea7dbe98":0,"99b2212ed7dcca7951db1b55ae26f1bea548773e":0,"0d8cbad07efd7a6d80eb863bc6c52ddbb7612b6f":0,"86b0297458879880169b937837b4b2338ebac6f1":0,"b22c60a6e9d816f16c6b3047622a01cbc3e908fe":0,"0519bfa0d006bbe2a924d586aa320f67757dfe13":0,"3f1754ab2d6359f58cd4022c54ef59ad6f2971dc":0,"63ace861e7addd53c20537ed5b9e3aeaa5da9382":0,"c55a3a438f900b707399d8d795db68abb4ff8cd8":0,"bbb4f66ff729f0e1299eb53581b2d7433a4130d9":0,"194eb19811711e19a963a979fb9f7b841ad58548":193,"298b7661fbefd123ac6111366c0e217cb269496d":0,"c677e5ecb5a881ecb440835060721a3f3969d00e":16,"76813b916551df856f63b109025bc97aea995949":629,"26e6293e8da312f2d770bcb6d6fad8095639d83b":76,"c9cb01ddb6a6550d86a323f393cd675fb75f17e6":32,"fd094af4b3d5b789fd3715bbffa5c888fa54d74d":0,"27376f55edca4edc2b15c1737e1b313fb6c9c35c":33,"8ce62733256e9490cf92f273e6c35d88b05d5456":86,"d61de430e7f29ebbd6bb5fb485ae400c9ab4d9bd":5,"564d320b30a594c643607ecc6db19fe739365f29":12,"5406b500872e5b575c31ecba2bc3ff95a451c958":0,"073dd1d34bb45da373b241c8cbf96c563a940952":41,"4eb95542bc7855f6bb1d8f1c4eaf1dd328ac67a1":0,"2cf1b3a82d80bfc905b2266649cc00e53c2c7634":0,"fe47d737c073dacac8a2ed3f09361e9d303311d4":157,"468c40c116e052f31e9df6967ac5d17ada81d45a":104,"cafb399d81ac4ab14f9c43b16955a252514ab341":21,"a88bffba9f834cedfa8f3372213206283b3f1843":231,"4d48535ecb5a26c242db0cff897eafcb5bccd93a":694,"f10bb1ad1181a3473c4ca5203171407793e0c5ae":0,"25b0c81360b0c6191a887464126774dbc0637989":938,"9ce8644e85370f4bc56a1acadc7eaca1436c0683":165,"e60b6bda14af99472ea32f2428bbe243412a7a2a":0,"590679222b077088242ee1519e43d16fd605a72e":12,"946773aee692c5bbd434e2cdb80480ad5cf55bf3":0,"9105c3fafed4ea01d15cb062e902095989e84672":0,"e99aa2ea58af23f30944684f6279e298c1559c65":0},"tools":{"claude-code":{"name":"Claude Code","commits":329,"loc":36145,"first_seen":1775751801,"last_seen":1789143129}},"monthly":{"2026-04":{"loc":9921,"attributed_loc":9887},"2026-05":{"loc":1990,"attributed_loc":0},"2026-06":{"loc":4605,"attributed_loc":4002},"2026-07":{"loc":14763,"attributed_loc":14763},"2026-08":{"loc":4059,"attributed_loc":4048},"2026-09":{"loc":3445,"attributed_loc":3445}}},"error":null},{"analyzer":"ai-artifacts","pillar":"ai_provenance","status":"ok","tool_version":"signatures-v1","metrics":{"artifacts":0.0,"workflow_agents":0.0,"tools_configured":0.0},"findings":[],"evidence":[],"data":{"artifacts":[],"workflows":[],"tools":[]},"error":null},{"analyzer":"ai-velocity","pillar":"ai_provenance","status":"ok","tool_version":"prov-4","metrics":{"work_units":96.0,"flagged_units":4.0,"pre_ai_era_bursts":0.0,"pre_ai_era_measured_loc":0.0,"pre_ai_era_burst_loc":0.0,"measured_loc":38783.0,"flagged_loc":8934.0,"flagged_loc_share":0.23035866230049248,"max_loc_per_hour":962.9987221354537,"median_loc_per_hour":119.80552247966412,"pr_timed_units":3.0,"excluded_import_loc":0.0},"findings":[],"evidence":[{"kind":"velocity-burst","description":"1,884 lines of first-party code in ~2.0h (963 lines/hour, 4 commit session)","ref":"25b0c81360b0c6191a887464126774dbc0637989","url":"https://github.com/joeyprijs/gravity/commit/25b0c81360b0c6191a887464126774dbc0637989","weight":0.28889961664063607},{"kind":"velocity-burst","description":"2,594 lines of first-party code in ~4.0h (648 lines/hour, 1 commit session)","ref":"2e42f6764fc158c463a923feb574341cb82ae3c4","url":"https://github.com/joeyprijs/gravity/commit/2e42f6764fc158c463a923feb574341cb82ae3c4","weight":0.19454999999999997},{"kind":"velocity-burst","description":"1,100 lines of first-party code in ~1.7h (639 lines/hour, 6 commit session)","ref":"789f4c348944235634998aafdd615a03fd2a3846","url":"https://github.com/joeyprijs/gravity/commit/789f4c348944235634998aafdd615a03fd2a3846","weight":0.19164381351830942},{"kind":"velocity-burst","description":"3,356 lines of first-party code in ~6.1h (554 lines/hour, 9 commit session)","ref":"24dc614bd86a8506e4db0d485e985aa3ce379c85","url":"https://github.com/joeyprijs/gravity/commit/24dc614bd86a8506e4db0d485e985aa3ce379c85","weight":0.16627580511973575}],"data":{"flagged_loc_by_commit":{"d9195c9320411f90298add6c119769f8091e3c40":1066,"b3e6d3e651af8fe95c322c89ff080ee20dee8945":1,"a2264fb5c62fe850e1475314781a790f16ade0ff":1,"0aba98158412af40d8c4a50aef06717e1dbcd583":9,"1ef63ccc0c43e4cffcff0a4a0b06291808513510":6,"789f4c348944235634998aafdd615a03fd2a3846":17,"2e42f6764fc158c463a923feb574341cb82ae3c4":2594,"5ad7338d1cfab3fda0c4d09f42ad6c64714227e6":2706,"2b91ea76d4c9033ceb87cac8a1874a7404c47044":36,"ca8ae7df5548ecbf24410461bbbe4698a994c89b":145,"5fa3ae6826b4ae8dbc1c067b0af7100bf10b92a2":251,"1065092061522b6fecb2f3460bd005feecbb6d8d":97,"431a3cac8f0f4a32d75c8c0184066dd4e62a71ae":7,"e96711d9eee527a6fe82ccd630fa85651b6a5e30":79,"b6e9d33bdb79e3b679c5ee13ef7b78e42295cce6":15,"24dc614bd86a8506e4db0d485e985aa3ce379c85":20,"cafb399d81ac4ab14f9c43b16955a252514ab341":21,"a88bffba9f834cedfa8f3372213206283b3f1843":231,"4d48535ecb5a26c242db0cff897eafcb5bccd93a":694,"25b0c81360b0c6191a887464126774dbc0637989":938},"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":7760.0,"index":0.129,"count:narrated_steps":1.0,"per_kloc:narrated_steps":0.129,"files:narrated_steps":1.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":[{"kind":"stylometry:narrated_steps","description":"step-by-step narration comment: // First, so the most-reached-for control never moves.","ref":"src/ui/combat-ui.js:82","url":"https://github.com/joeyprijs/gravity/blob/e99aa2ea58af23f30944684f6279e298c1559c65/src/ui/combat-ui.js#L82","weight":0.0}],"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":40.0,"findings_high":14.0,"findings_medium":17.0,"findings_low":9.0,"weighted_findings":15.312,"scanned_lines":7760.0,"parse_errors":0.0},"findings":[{"rule_id":"opengrep/javascript.browser.security.insecure-document-method","severity":"high","message":"User controlled data in methods like `innerHTML`, `outerHTML` or `document.write` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/core/utils.js","line":397,"fingerprint":"javascript.browser.security.insecure-document-method:src/core/utils.js:397"},{"rule_id":"opengrep/javascript.browser.security.insecure-innerhtml","severity":"high","message":"User controlled data in a `p.innerHTML` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/core/utils.js","line":397,"fingerprint":"javascript.browser.security.insecure-innerhtml:src/core/utils.js:397"},{"rule_id":"opengrep/javascript.browser.security.insecure-document-method","severity":"high","message":"User controlled data in methods like `innerHTML`, `outerHTML` or `document.write` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/core/utils.js","line":436,"fingerprint":"javascript.browser.security.insecure-document-method:src/core/utils.js:436"},{"rule_id":"opengrep/javascript.browser.security.insecure-innerhtml","severity":"high","message":"User controlled data in a `marker.innerHTML` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/core/utils.js","line":436,"fingerprint":"javascript.browser.security.insecure-innerhtml:src/core/utils.js:436"},{"rule_id":"opengrep/javascript.browser.security.insecure-document-method","severity":"high","message":"User controlled data in methods like `innerHTML`, `outerHTML` or `document.write` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/ui/ui.js","line":204,"fingerprint":"javascript.browser.security.insecure-document-method:src/ui/ui.js:204"},{"rule_id":"opengrep/javascript.browser.security.insecure-innerhtml","severity":"high","message":"User controlled data in a `btn.innerHTML` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/ui/ui.js","line":204,"fingerprint":"javascript.browser.security.insecure-innerhtml:src/ui/ui.js:204"},{"rule_id":"opengrep/javascript.browser.security.insecure-document-method","severity":"high","message":"User controlled data in methods like `innerHTML`, `outerHTML` or `document.write` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/ui/ui.js","line":307,"fingerprint":"javascript.browser.security.insecure-document-method:src/ui/ui.js:307"},{"rule_id":"opengrep/javascript.browser.security.insecure-innerhtml","severity":"high","message":"User controlled data in a `panel.innerHTML` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/ui/ui.js","line":307,"fingerprint":"javascript.browser.security.insecure-innerhtml:src/ui/ui.js:307"},{"rule_id":"opengrep/javascript.browser.security.insecure-document-method","severity":"high","message":"User controlled data in methods like `innerHTML`, `outerHTML` or `document.write` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/ui/ui.js","line":313,"fingerprint":"javascript.browser.security.insecure-document-method:src/ui/ui.js:313"},{"rule_id":"opengrep/javascript.browser.security.insecure-innerhtml","severity":"high","message":"User controlled data in a `panel.innerHTML` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/ui/ui.js","line":313,"fingerprint":"javascript.browser.security.insecure-innerhtml:src/ui/ui.js:313"},{"rule_id":"opengrep/javascript.browser.security.insecure-document-method","severity":"high","message":"User controlled data in methods like `innerHTML`, `outerHTML` or `document.write` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/ui/ui.js","line":371,"fingerprint":"javascript.browser.security.insecure-document-method:src/ui/ui.js:371"},{"rule_id":"opengrep/javascript.browser.security.insecure-innerhtml","severity":"high","message":"User controlled data in a `panel.innerHTML` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/ui/ui.js","line":371,"fingerprint":"javascript.browser.security.insecure-innerhtml:src/ui/ui.js:371"},{"rule_id":"opengrep/javascript.browser.security.insecure-document-method","severity":"high","message":"User controlled data in methods like `innerHTML`, `outerHTML` or `document.write` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/ui/ui.js","line":423,"fingerprint":"javascript.browser.security.insecure-document-method:src/ui/ui.js:423"},{"rule_id":"opengrep/javascript.browser.security.insecure-innerhtml","severity":"high","message":"User controlled data in a `item.innerHTML` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"src/ui/ui.js","line":423,"fingerprint":"javascript.browser.security.insecure-innerhtml:src/ui/ui.js:423"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/core/icons.js","line":114,"fingerprint":"javascript.lang.security.html-in-template-string:src/core/icons.js:114"},{"rule_id":"opengrep/javascript.lang.security.audit.unsafe-dynamic-method","severity":"medium","message":"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]","path":"src/core/state.js","line":264,"fingerprint":"javascript.lang.security.audit.unsafe-dynamic-method:src/core/state.js:264"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/core/utils.js","line":374,"fingerprint":"javascript.lang.security.html-in-template-string:src/core/utils.js:374"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/core/utils.js","line":384,"fingerprint":"javascript.lang.security.html-in-template-string:src/core/utils.js:384"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/core/utils.js","line":407,"fingerprint":"javascript.lang.security.html-in-template-string:src/core/utils.js:407"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/core/utils.js","line":436,"fingerprint":"javascript.lang.security.html-in-template-string:src/core/utils.js:436"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/ui/ui.js","line":20,"fingerprint":"javascript.lang.security.html-in-template-string:src/ui/ui.js:20"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/ui/ui.js","line":205,"fingerprint":"javascript.lang.security.html-in-template-string:src/ui/ui.js:205"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/ui/ui.js","line":307,"fingerprint":"javascript.lang.security.html-in-template-string:src/ui/ui.js:307"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/ui/ui.js","line":313,"fingerprint":"javascript.lang.security.html-in-template-string:src/ui/ui.js:313"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/ui/ui.js","line":345,"fingerprint":"javascript.lang.security.html-in-template-string:src/ui/ui.js:345"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/ui/ui.js","line":347,"fingerprint":"javascript.lang.security.html-in-template-string:src/ui/ui.js:347"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/ui/ui.js","line":366,"fingerprint":"javascript.lang.security.html-in-template-string:src/ui/ui.js:366"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/ui/ui.js","line":371,"fingerprint":"javascript.lang.security.html-in-template-string:src/ui/ui.js:371"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/ui/ui.js","line":375,"fingerprint":"javascript.lang.security.html-in-template-string:src/ui/ui.js:375"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/ui/ui.js","line":423,"fingerprint":"javascript.lang.security.html-in-template-string:src/ui/ui.js:423"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"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]","path":"src/ui/ui.js","line":424,"fingerprint":"javascript.lang.security.html-in-template-string:src/ui/ui.js:424"},{"rule_id":"opengrep/javascript.lang.security.audit.unsafe-formatstring","severity":"low","message":"Detected string concatenation with a non-literal variable in a util.format / console.log function. If an attacker injects a format specifier in the string, it will forge the log message. Try to use constant values for the format string. [confidence low]","path":"src/core/engine.js","line":98,"fingerprint":"javascript.lang.security.audit.unsafe-formatstring:src/core/engine.js:98"},{"rule_id":"opengrep/javascript.lang.security.audit.unsafe-formatstring","severity":"low","message":"Detected string concatenation with a non-literal variable in a util.format / console.log function. If an attacker injects a format specifier in the string, it will forge the log message. Try to use constant values for the format string. [confidence low]","path":"src/core/engine.js","line":109,"fingerprint":"javascript.lang.security.audit.unsafe-formatstring:src/core/engine.js:109"},{"rule_id":"opengrep/javascript.lang.security.audit.unsafe-formatstring","severity":"low","message":"Detected string concatenation with a non-literal variable in a util.format / console.log function. If an attacker injects a format specifier in the string, it will forge the log message. Try to use constant values for the format string. [confidence low]","path":"src/core/engine.js","line":119,"fingerprint":"javascript.lang.security.audit.unsafe-formatstring:src/core/engine.js:119"},{"rule_id":"opengrep/javascript.lang.security.audit.unsafe-formatstring","severity":"low","message":"Detected string concatenation with a non-literal variable in a util.format / console.log function. If an attacker injects a format specifier in the string, it will forge the log message. Try to use constant values for the format string. [confidence low]","path":"src/core/engine.js","line":170,"fingerprint":"javascript.lang.security.audit.unsafe-formatstring:src/core/engine.js:170"},{"rule_id":"opengrep/javascript.audit.detect-replaceall-sanitization","severity":"low","message":"Detected a call to `replaceAll()` in an attempt to HTML escape the string `String(str)`. Manually sanitizing input through a manually built list can be circumvented in many situations, and it's better to use a well known sanitization library such as `sanitize-html` or `DOMPurify`. [confidence low]","path":"src/core/utils.js","line":35,"fingerprint":"javascript.audit.detect-replaceall-sanitization:src/core/utils.js:35"},{"rule_id":"opengrep/javascript.audit.detect-replaceall-sanitization","severity":"low","message":"Detected a call to `replaceAll()` in an attempt to HTML escape the string `String(str)\n    .replaceAll('&', '&amp;')`. Manually sanitizing input through a manually built list can be circumvented in many situations, and it's better to use a well known sanitization library such as `sanitize-html` or ` [confidence low]","path":"src/core/utils.js","line":35,"fingerprint":"javascript.audit.detect-replaceall-sanitization:src/core/utils.js:35"},{"rule_id":"opengrep/javascript.audit.detect-replaceall-sanitization","severity":"low","message":"Detected a call to `replaceAll()` in an attempt to HTML escape the string `String(str)\n    .replaceAll('&', '&amp;')\n    .replaceAll('<', '&lt;')`. Manually sanitizing input through a manually built list can be circumvented in many situations, and it's better to use a well known sanitization library [confidence low]","path":"src/core/utils.js","line":35,"fingerprint":"javascript.audit.detect-replaceall-sanitization:src/core/utils.js:35"},{"rule_id":"opengrep/javascript.audit.detect-replaceall-sanitization","severity":"low","message":"Detected a call to `replaceAll()` in an attempt to HTML escape the string `String(str)\n    .replaceAll('&', '&amp;')\n    .replaceAll('<', '&lt;')\n    .replaceAll('>', '&gt;')`. Manually sanitizing input through a manually built list can be circumvented in many situations, and it's better to use a we [confidence low]","path":"src/core/utils.js","line":35,"fingerprint":"javascript.audit.detect-replaceall-sanitization:src/core/utils.js:35"},{"rule_id":"opengrep/javascript.lang.security.audit.unsafe-formatstring","severity":"low","message":"Detected string concatenation with a non-literal variable in a util.format / console.log function. If an attacker injects a format specifier in the string, it will forge the log message. Try to use constant values for the format string. [confidence low]","path":"src/systems/audio.js","line":151,"fingerprint":"javascript.lang.security.audit.unsafe-formatstring:src/systems/audio.js:151"}],"evidence":[],"data":{"rulesets":["javascript","bash"]},"error":null},{"analyzer":"sec-deps","pillar":"security","status":"skipped","tool_version":null,"metrics":{},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-actions","pillar":"security","status":"ok","tool_version":"zizmor 1.32.0","metrics":{"workflows":1.0,"findings":4.0,"findings_high":2.0,"findings_medium":2.0,"findings_low":0.0,"penalty":27.6},"findings":[{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/test.yml","line":11,"fingerprint":"unpinned-uses:.github/workflows/test.yml:11"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/test.yml","line":12,"fingerprint":"unpinned-uses:.github/workflows/test.yml:12"},{"rule_id":"zizmor/artipacked","severity":"medium","message":"credential persistence through GitHub Actions artifacts [confidence low]","path":".github/workflows/test.yml","line":11,"fingerprint":"artipacked:.github/workflows/test.yml:11"},{"rule_id":"zizmor/excessive-permissions","severity":"medium","message":"overly broad permissions [confidence medium]","path":".github/workflows/test.yml","line":8,"fingerprint":"excessive-permissions:.github/workflows/test.yml:8"}],"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":0.0,"signed_commit_share":0.0,"unpinned_manifests":1.0},"findings":[],"evidence":[{"kind":"posture","description":"package.json has no lockfile alongside it (unpinned dependencies)","ref":"package.json","url":null,"weight":0.3}],"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":822.0,"function_nloc":5597.0,"mean_ccn":3.05,"p90_ccn":6.0,"complex_functions":10.0,"long_functions":1.0,"many_param_functions":0.0,"risky_nloc_share":0.0815},"findings":[],"evidence":[{"kind":"complex-function","description":"validateRules in src/core/validate.js: complexity 82, 107 lines","ref":"src/core/validate.js","url":"https://github.com/joeyprijs/gravity/blob/e99aa2ea58af23f30944684f6279e298c1559c65/src/core/validate.js#L502","weight":1.0},{"kind":"complex-function","description":"validateActions in src/core/validate.js: complexity 33, 41 lines","ref":"src/core/validate.js","url":"https://github.com/joeyprijs/gravity/blob/e99aa2ea58af23f30944684f6279e298c1559c65/src/core/validate.js#L270","weight":0.55},{"kind":"complex-function","description":"validateItems in src/core/validate.js: complexity 32, 40 lines","ref":"src/core/validate.js","url":"https://github.com/joeyprijs/gravity/blob/e99aa2ea58af23f30944684f6279e298c1559c65/src/core/validate.js#L133","weight":0.5333333333333333},{"kind":"complex-function","description":"evaluateCondition in src/systems/condition.js: complexity 29, 45 lines","ref":"src/systems/condition.js","url":"https://github.com/joeyprijs/gravity/blob/e99aa2ea58af23f30944684f6279e298c1559c65/src/systems/condition.js#L37","weight":0.48333333333333334},{"kind":"complex-function","description":"validateCondition in src/core/validate.js: complexity 26, 36 lines","ref":"src/core/validate.js","url":"https://github.com/joeyprijs/gravity/blob/e99aa2ea58af23f30944684f6279e298c1559c65/src/core/validate.js#L213","weight":0.43333333333333335},{"kind":"complex-function","description":"itemStatLines in src/core/utils.js: complexity 25, 49 lines","ref":"src/core/utils.js","url":"https://github.com/joeyprijs/gravity/blob/e99aa2ea58af23f30944684f6279e298c1559c65/src/core/utils.js#L252","weight":0.4166666666666667},{"kind":"complex-function","description":"validateNpcs in src/core/validate.js: complexity 25, 35 lines","ref":"src/core/validate.js","url":"https://github.com/joeyprijs/gravity/blob/e99aa2ea58af23f30944684f6279e298c1559c65/src/core/validate.js#L424","weight":0.4166666666666667},{"kind":"complex-function","description":"adoptSave in src/core/save.js: complexity 24, 38 lines","ref":"src/core/save.js","url":"https://github.com/joeyprijs/gravity/blob/e99aa2ea58af23f30944684f6279e298c1559c65/src/core/save.js#L127","weight":0.4},{"kind":"complex-function","description":"validateScenes in src/core/validate.js: complexity 24, 38 lines","ref":"src/core/validate.js","url":"https://github.com/joeyprijs/gravity/blob/e99aa2ea58af23f30944684f6279e298c1559c65/src/core/validate.js#L377","weight":0.4},{"kind":"complex-function","description":"validateCheck in src/core/validate.js: complexity 19, 27 lines","ref":"src/core/validate.js","url":"https://github.com/joeyprijs/gravity/blob/e99aa2ea58af23f30944684f6279e298c1559c65/src/core/validate.js#L340","weight":0.31666666666666665}],"data":{},"error":null},{"analyzer":"qual-duplication","pillar":"quality","status":"ok","tool_version":"repotrust-dup-w6","metrics":{"compared_lines":5728.0,"duplicated_lines":16.0,"duplicated_share":0.0028,"files":33.0},"findings":[],"evidence":[{"kind":"duplicate-code","description":"6+ duplicated lines: src/systems/scene.js:384 and src/systems/scene.js:527","ref":"src/systems/scene.js","url":"https://github.com/joeyprijs/gravity/blob/e99aa2ea58af23f30944684f6279e298c1559c65/src/systems/scene.js#L384","weight":0.3}],"data":{},"error":null},{"analyzer":"qual-lint","pillar":"quality","status":"ok","tool_version":"opengrep 1.33.1; rules f1d2b562b414","metrics":{"findings":19.0,"weighted_findings":10.0,"scanned_lines":7760.0,"category:best-practice":2.0,"category:correctness":17.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":"src/core/utils.js","line":35,"fingerprint":"javascript.lang.correctness.no-replaceall:src/core/utils.js:35"},{"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/core/utils.js","line":35,"fingerprint":"javascript.lang.correctness.no-replaceall:src/core/utils.js:35"},{"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/core/utils.js","line":35,"fingerprint":"javascript.lang.correctness.no-replaceall:src/core/utils.js:35"},{"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/core/utils.js","line":35,"fingerprint":"javascript.lang.correctness.no-replaceall:src/core/utils.js:35"},{"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/core/utils.js","line":35,"fingerprint":"javascript.lang.correctness.no-replaceall:src/core/utils.js:35"},{"rule_id":"opengrep/javascript.lang.best-practice.javascript-prompt","severity":"medium","message":"found prompt() call; should this be in production code?","path":"src/plugins/curator/panel.js","line":125,"fingerprint":"javascript.lang.best-practice.javascript-prompt:src/plugins/curator/panel.js:125"},{"rule_id":"opengrep/javascript.lang.best-practice.javascript-prompt","severity":"medium","message":"found prompt() call; should this be in production code?","path":"src/plugins/curator/panel.js","line":179,"fingerprint":"javascript.lang.best-practice.javascript-prompt:src/plugins/curator/panel.js:179"},{"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/core/validate.js","line":336,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/core/validate.js:336"},{"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/core/validate.js","line":336,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/core/validate.js:336"},{"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/core/validate.js","line":496,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/core/validate.js:496"},{"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/core/validate.js","line":496,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/core/validate.js:496"},{"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/core/validate.js","line":523,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/core/validate.js:523"},{"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/core/validate.js","line":523,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/core/validate.js:523"},{"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/core/validate.js","line":597,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/core/validate.js:597"},{"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/core/validate.js","line":597,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/core/validate.js:597"},{"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/core/validate.js","line":612,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/core/validate.js:612"},{"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/core/validate.js","line":612,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/core/validate.js:612"},{"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/systems/actions.js","line":80,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/systems/actions.js:80"},{"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/systems/actions.js","line":80,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:src/systems/actions.js:80"}],"evidence":[],"data":{},"error":null},{"analyzer":"qual-testing","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:has_tests":1.0,"check:test_ratio":1.0,"check:ci_present":1.0,"check:ci_runs_tests":1.0,"check:ci_runs_lint":0.0,"check:tests_cochange":1.0,"test_lines":5358.0,"source_lines":7760.0,"test_ratio":0.6905,"ci_files":1.0,"cochange_share":0.393,"cochange_commits":201.0},"findings":[],"evidence":[{"kind":"ci","description":"CI config: .github/workflows/test.yml","ref":".github/workflows/test.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":771.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":"skipped","tool_version":null,"metrics":{},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"x-blame","pillar":"ai_provenance","status":"ok","tool_version":"git-blame","metrics":{"ai_lines":7581.0,"other_lines":179.0,"files_blamed":33.0,"blame_failures":0.0,"quality:ai_findings":19.0,"quality:ai_per_kloc":2.506,"quality:other_findings":0.0,"quality:other_per_kloc":0.0,"security:ai_findings":37.0,"security:ai_per_kloc":4.881,"security:other_findings":3.0,"security:other_per_kloc":16.76},"findings":[],"evidence":[],"data":{"sampled":false,"comparable":false},"error":null}],"flags":[]}