{"schema_version":"2","scorer_version":"0.1.0","scoring_version":"prov-4+qual-2+sec-2","generated_at":"2026-11-13T23:18:39.504797Z","repo":{"ref":{"host":"github.com","owner":"Hugo-Grellier","name":"ballast"},"default_branch":"main","clone_url":"https://github.com/Hugo-Grellier/ballast.git","html_url":"https://github.com/Hugo-Grellier/ballast","description":null,"stars":0,"forks":0,"is_fork":false,"is_archived":false,"is_private":false,"size_kb":9688,"primary_language":"Python","license_spdx":"MIT","created_at":"2026-09-25T07:12:15Z","pushed_at":"2026-10-30T07:06:53Z","security_policy_url":null,"distribution":{"owner_created_at":"2021-10-05T07:28:16Z","owner_type":"User","release_assets":[{"name":"ballast","size":82224,"download_count":3,"release_tag":"v1.1.0","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v1.1.0/ballast"},{"name":"ballast.sha256","size":74,"download_count":3,"release_tag":"v1.1.0","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v1.1.0/ballast.sha256"},{"name":"ballast","size":78859,"download_count":2,"release_tag":"v1.0.0","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v1.0.0/ballast"},{"name":"ballast.sha256","size":74,"download_count":2,"release_tag":"v1.0.0","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v1.0.0/ballast.sha256"},{"name":"ballast","size":78860,"download_count":2,"release_tag":"v0.10.0","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v0.10.0/ballast"},{"name":"ballast.sha256","size":74,"download_count":2,"release_tag":"v0.10.0","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v0.10.0/ballast.sha256"},{"name":"ballast","size":74685,"download_count":2,"release_tag":"v0.9.0","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v0.9.0/ballast"},{"name":"ballast.sha256","size":74,"download_count":2,"release_tag":"v0.9.0","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v0.9.0/ballast.sha256"},{"name":"ballast","size":73240,"download_count":2,"release_tag":"v0.8.1","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v0.8.1/ballast"},{"name":"ballast.sha256","size":74,"download_count":2,"release_tag":"v0.8.1","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v0.8.1/ballast.sha256"},{"name":"ballast","size":73240,"download_count":2,"release_tag":"v0.8.0","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v0.8.0/ballast"},{"name":"ballast.sha256","size":74,"download_count":2,"release_tag":"v0.8.0","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v0.8.0/ballast.sha256"},{"name":"ballast","size":68601,"download_count":2,"release_tag":"v0.7.1","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v0.7.1/ballast"},{"name":"ballast.sha256","size":74,"download_count":2,"release_tag":"v0.7.1","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v0.7.1/ballast.sha256"},{"name":"ballast","size":68601,"download_count":2,"release_tag":"v0.7.0","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v0.7.0/ballast"},{"name":"ballast.sha256","size":74,"download_count":2,"release_tag":"v0.7.0","url":"https://github.com/Hugo-Grellier/ballast/releases/download/v0.7.0/ballast.sha256"}]}},"commit_sha":"ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9","profile":{"lines_by_language":{"Python":14284,"JavaScript":406},"files_by_category":{"docs":497,"config":33,"test":16,"source":15,"binary":9,"other":2,"generated":1},"source_lines":6744,"test_lines":7946},"pillars":{"ai_provenance":{"score":97.5,"confidence":0.95,"coverage":1.0,"label":"explicit","breakdown":{"attributed_share":0.9746,"suspected_share":0.0,"estimated_share":0.9746,"ai_artifacts":3.0,"flagged_work_units":14.0,"flagged_releases":5.0},"summary":"Explicit AI attribution on 97% of first-party code added; an estimated 97% including velocity signals."},"quality":{"score":80.9,"confidence":0.9,"coverage":1.0,"label":"strong","breakdown":{"complexity":64.8,"duplication":82.3,"lint":80.1,"testing":100.0,"docs":85.0,"type_safety":40.0,"process":null},"summary":"Code quality is strong: test-to-source ratio 1.18, CI runs tests; 14% of function code in complex or long functions; 3% duplicated lines. Weakest area: type safety."},"security":{"score":76.7,"confidence":0.85,"coverage":1.0,"label":"adequate","breakdown":{"secrets":96.7,"sast":75.0,"dependencies":100.0,"ci_actions":26.0,"posture":60.0,"scorecard":null},"summary":"Security posture is adequate: 6 high-severity SAST findings; 6 high-severity workflow issues. Weakest area: ci actions."}},"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":1.0,"checked":1.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":168.0,"attributed_commits":142.0,"attributed_commit_share":0.8452380952380952,"effective_loc":95546.0,"attributed_loc":93120.0,"attributed_loc_share":0.9746090888158583,"tools_detected":1.0},"findings":[],"evidence":[{"kind":"attribution-summary","description":"Claude Code: 142 attributed commits, 93,120 lines added","ref":null,"url":null,"weight":1.0},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9","url":"https://github.com/Hugo-Grellier/ballast/commit/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"8f580d315594dd7e2635ca70def298ac63c34ffb","url":"https://github.com/Hugo-Grellier/ballast/commit/8f580d315594dd7e2635ca70def298ac63c34ffb","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"0f07432dc14a7f207c85ba5f38533e686cb19536","url":"https://github.com/Hugo-Grellier/ballast/commit/0f07432dc14a7f207c85ba5f38533e686cb19536","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"33e2557051bd240543be8ab912740be5f9ba0aae","url":"https://github.com/Hugo-Grellier/ballast/commit/33e2557051bd240543be8ab912740be5f9ba0aae","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"2fc1dcc9f8d755849bcbf6b0652da251243338a8","url":"https://github.com/Hugo-Grellier/ballast/commit/2fc1dcc9f8d755849bcbf6b0652da251243338a8","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"56f68448ca073c4b9e442bd11fddf97be45c01ed","url":"https://github.com/Hugo-Grellier/ballast/commit/56f68448ca073c4b9e442bd11fddf97be45c01ed","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"ca3150840b937c1000f28ac6d06ab3bc106c91b3","url":"https://github.com/Hugo-Grellier/ballast/commit/ca3150840b937c1000f28ac6d06ab3bc106c91b3","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"5e51a22e09edac2f73476272b425094bee1a4a9c","url":"https://github.com/Hugo-Grellier/ballast/commit/5e51a22e09edac2f73476272b425094bee1a4a9c","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"a87ba98c59486904185b24037dedd6943790e103","url":"https://github.com/Hugo-Grellier/ballast/commit/a87ba98c59486904185b24037dedd6943790e103","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"2bc2ed701ef8738a20c4df3533cf8ea63c45daea","url":"https://github.com/Hugo-Grellier/ballast/commit/2bc2ed701ef8738a20c4df3533cf8ea63c45daea","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"03de61e4851d934bc556245075c8e7d16c613ef1","url":"https://github.com/Hugo-Grellier/ballast/commit/03de61e4851d934bc556245075c8e7d16c613ef1","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"d2f41e2173c9271803090b466b34dabef5a02460","url":"https://github.com/Hugo-Grellier/ballast/commit/d2f41e2173c9271803090b466b34dabef5a02460","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"4fe173a0424c0a714a6fba459c6dc845efb6fb2a","url":"https://github.com/Hugo-Grellier/ballast/commit/4fe173a0424c0a714a6fba459c6dc845efb6fb2a","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"9d358274021b1297c67bde18cc3f7e0af5602bb6","url":"https://github.com/Hugo-Grellier/ballast/commit/9d358274021b1297c67bde18cc3f7e0af5602bb6","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"9cb56dac27d5e021754bd1d82568fb0a9164877a","url":"https://github.com/Hugo-Grellier/ballast/commit/9cb56dac27d5e021754bd1d82568fb0a9164877a","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"c126a87a55e2ade98e60ed20f8759e86964c0c10","url":"https://github.com/Hugo-Grellier/ballast/commit/c126a87a55e2ade98e60ed20f8759e86964c0c10","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"8ead0ef90b5933a4305a3928f1dff8a9304aaa35","url":"https://github.com/Hugo-Grellier/ballast/commit/8ead0ef90b5933a4305a3928f1dff8a9304aaa35","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"c36092bb6dda1f63ff8b47d3799325c4c1789150","url":"https://github.com/Hugo-Grellier/ballast/commit/c36092bb6dda1f63ff8b47d3799325c4c1789150","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"392205d31247bdebe8395c22db072dcf8b56b3eb","url":"https://github.com/Hugo-Grellier/ballast/commit/392205d31247bdebe8395c22db072dcf8b56b3eb","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"e1399dfce7bfec3256cba1ca65603f0b10be6ff8","url":"https://github.com/Hugo-Grellier/ballast/commit/e1399dfce7bfec3256cba1ca65603f0b10be6ff8","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"b0717de77720877b84b9b99e9d45b662f8bb0a41","url":"https://github.com/Hugo-Grellier/ballast/commit/b0717de77720877b84b9b99e9d45b662f8bb0a41","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"9234bbfd9a177a8463032910de50d0e1fa8c5f21","url":"https://github.com/Hugo-Grellier/ballast/commit/9234bbfd9a177a8463032910de50d0e1fa8c5f21","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"61f4d71261f79859c947913bd892e8f1c371f20c","url":"https://github.com/Hugo-Grellier/ballast/commit/61f4d71261f79859c947913bd892e8f1c371f20c","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"65d04edc65fa11e070e968a816965d08dd3f0243","url":"https://github.com/Hugo-Grellier/ballast/commit/65d04edc65fa11e070e968a816965d08dd3f0243","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: message 'Generated with Claude Code'","ref":"fa6d6143cf3effd11530777fe0410454ac72287d","url":"https://github.com/Hugo-Grellier/ballast/commit/fa6d6143cf3effd11530777fe0410454ac72287d","weight":0.9}],"data":{"attributed_loc_by_commit":{"b45492c8eaef3ea9ff4822e279c1af82527fa2f7":0,"cc14b214b79e2be4054722e02033934bcdd12471":8476,"76a33a6e3151ea1991237e609bf7312e19353300":0,"d488fa57e74d00f1c1a84471453e224c1eaaf8d4":91,"4cb80aa8c21c3b56448c4c4cc224806df93fefdc":0,"23dfb36a982e0f2dea8b49494dd5ce6685c16f0f":0,"71e20a32f07d87e6cfc4a2519c6cd537c89cbf91":0,"ef1ffe6a5dd1967755a14ec9f58dc57be41eec7d":52,"c7664413963014af46d75d9ec9bc3af1e87e9dcd":1417,"0675e0af7ca9532e2ec6565e4255b0e871e23eed":33,"ec9551c2e0f3ecd793a0c391c52bb10914590ec4":2972,"d3e3958645d805488bf9bf1e8acae29950b7478c":0,"9d4c866a7969c856cc05e7d7d941f1ab5ee71e81":10715,"9ebc4db94c2088642691fa2b04404c21415a5564":0,"dd3d4cc563c79262db6121b426915d86470df9c2":25,"ed9fd6fc920ee5485421e77c05d4e39ee70ccb1e":126,"24281e95e518cf2186a9457780c78d48f00ce541":0,"868dbf18d1588d15dbb62ad03f40c2738e2a7783":21,"706dc1138e324d04b18c3065c8548abd8b57e71f":70,"fcc498e2b1cef24a0ae0e605ff5f58d9fe398b54":160,"bcf77f32d9c1cd0cfffe074cfc9a279e6ef5d86a":62,"9a1ff5ca03f042a276c0470d9b7a77965f318d88":0,"e26906db4b3e5bae97e154443700b95bcaeb8743":59,"f68345460ea2a00f0699d161f8cd4b2d568e0cda":5495,"52031c1bb7f8bed12430da59d34acb5ac4972d4e":0,"36df129d4717fadc60140b3af9c036b60c7fd913":2438,"042f884c60daf17cabf78ce52bc2d4e605aada0a":4115,"7052c4060792f638307a27b0f60e18f65b70d513":0,"bc4ea3e4d395014ae3e8cccbb5e6a8d1e7e2d142":12,"1ce1f9a529bb39c7a50dd7dea4382a34356f690c":1931,"24820ce7cb3141d695c52394cc2fc9d6987f02b1":9316,"0d5ff50f5f2312ee8fd51b10c091570904647da6":117,"0258627fcb934822dc3eb63f11fbc64ad2ac1481":1268,"0a668c39cd5f9960c80bfd6ae70cdb6bc5708baa":47,"60a220a00a8766fae8b230d311ab18fee88cc799":5043,"240dec1f9d5260ddb72ee66d33a94cdb56b08384":0,"e401a6d88c2d4d253c58053da69dd59ea720bf5a":130,"3f7180f23357723ed7e77eafc8b3a3e0ac5e601b":365,"a31c73799af3cb159b9697be60eda6bfb92d28da":22,"11134f1a395cdaec7822135459eb17abd981c616":207,"b90ea0f790f67ee701b38cc41281f1b1371c3922":63,"be7006f6e2f2a4306fcc6c6b5ad9f7b4f9aa0d5b":0,"1d153b2c00a494817c9838748b88fdec19ae3f1b":326,"685e2cabe0a62f1c8819299d52b9e9f6ae3f46f9":1334,"28dd8908349008df6ee897bc3810fcef440869da":2404,"a5cfe84ccbe30471adb9ad4f968a6df7a54ba963":0,"28ce199710c7bd09e367b1ab211bc999d1cc8ef2":0,"a386c78ef12a0ce9930fcb00f7d845e4d9e0f44e":488,"e6fce67ce69e03903de41b67d09760ab1927a45e":257,"0ff3e131a5edd6ac8b6953e3cb25fd6f84235393":333,"51edd7d480ac3f95e378b44dd5d4a3fbb6a62d1e":33,"9005229bddb2c73211458122d01fce2ee1c08708":0,"7ae08ed90344ad8eb7906f88388c79a3675f3538":3317,"a9c8e1cec29aeec4e82bdc790ece1ab67ab3e1f2":4097,"282f7f3ec3e51d830eccdcc2eb0a526a0cb0b0a9":68,"bcac2bd27fe1b84a5921b5760e708ada463155ea":482,"37d8acec8605661d40d66f1cb92db8b9047ab3b5":749,"4a28076c48c17c9aba6c170550fa8c5bbbf32961":144,"f2bb77564da3e4b98d5e85e141d8ba1b27adb9dc":27,"09d8596dac302e1fadc89b5bd51eee229a8588a5":173,"f4dcf958a14de927f11505f4ef57659ffcd36a9b":0,"bd09afee8d86afc73b85d8b979c181f3dfd51a92":2,"308471da7c7e54bb3b16368675b7836cb4851504":180,"f91b9cb425e10b2a6610ba6305ca434ce909c297":409,"88d73eb698baf6b2cde7034d8acdcfc13d56de10":565,"4fc8624e70161b6f0318f7be16d2bcb19da54fa7":1131,"e7a4e8f63a02a157568e5af4a149dcfdbae82833":0,"47f2ad67ba06e9706343958456b2df3caa657656":0,"2d356c0db7907173172194641ca00a251ffd4722":0,"416d13eb9b1ff164992cb8054aa67500243683d1":0,"f5ca1f443059dbb7458f6bb85bf78476a59979cc":0,"7a931469e03fd56bab80e213be342c65a40d1719":8,"7bbe9661b729aec3a2736b272a97b241b08a6e87":174,"7ee95a41335992d459cc975e64e4c4e981f04f4b":0,"b2022d944f0546ab80529268a9b8a5a0bdc20601":2,"dfa191c6b1299348f4e76ed481bfa82be1465167":0,"81d39fcb74c68dde883b03e44f94cb1c6ffa2d87":0,"09fb427a0ab30a5506a0e6d530abd9ef9aa19b20":602,"d215a632b3bf074ec2cb9bea1eb673a29cf8f818":2542,"617df9c1eab920db9874e66fe4bb5e0f83df2a08":293,"0bddeb8ceb6b2f74b5390d2a0cfad5929ad1eca4":0,"578a93a6638aa9f04527ebfc35d0ff402130da18":238,"68ef048256ac578c31407f24f4fef05389523db0":4668,"db3c97e33b3b1a705febca2a0a48646ee9325f70":949,"af4e739271123ef1425b3b8e2150f7d3698632bd":1980,"d9db04bdc70acdad6fe43294396cac9d842f140b":0,"413d7fca9e43ee01a91ea0da4392da9c80a544fc":0,"87abfea3825f84dfd0b8db1c657a29cc0c964c07":309,"2f6d0ff64efb1408769ebe34cdd9f328c9afa130":125,"440c20ea0c2658357fa9623556770f28e635bb2c":0,"28a51506a0b8c19824c56d1fe326303a0bc61c16":21,"063af65fbb3b95da5ddb91bb64d07e54cfd102a8":75,"adc89222402d9504c815657181eced6e80eb2ec1":116,"25729e2d880c900f824e8d7376b77e4f674cbb74":48,"cbd03423ef773eba98d3860d57b1c78f40410948":132,"9e0b93fe777f84759e2f00e345aee8ebe817bf1a":97,"123d50ce75cc776e9f4298d37089badc43e9ccb2":0,"a83f393cf492ffccfa3ae7ca3707dca709337cf0":82,"8071fdfa01df5b2b25a434b99d9d201a044da08b":114,"4645074f44d76bba9d1dd8d733db0aecd5cc157b":286,"0654319a18e612f8d6254db6987d09b115c45a5a":27,"e6f4df74e7d4413e454c1854ff5e1583db4c4b35":35,"26b646eb0c0f5fd1f5c740a87f48bbadb64b96a3":0,"0edee07ba81a28db9568f5e95e5ccfe4ec787ad9":53,"700c468d003ecf0016b3967759ea344c9d6cb9cb":260,"508bb45ed76fb04c55ef7193b649d2e34bc89c5c":108,"348c9484ca270ef714e426ae7b0880f5878f63b0":13,"bce49d42c2e2697331e56d674dad442d571220b8":154,"130c7fe4b17e05c0b9d0bbf03e6b7fd166dbc073":0,"a57eb9d2a99e5ee5ff34f58a6b192e0e8b453b40":574,"6314f9405d52fc19a5838e02f59ec012ab951756":62,"d6ee3941c2ebef19b7d74d85459a144aabaff910":102,"de074610e1dffc5b11e3265edc09bfe62be7e3f3":15,"8ca76b1f63cb210ee64074feb85ad93e18f98eda":42,"6231dc68fa0ae0731604b319ee297396544b8b8c":14,"d0c0de0727a0a0555cd80fe3fb1805bdc2225edd":25,"254bd579a3dac29eca788bf11d64bf3544de7fec":14,"fa6d6143cf3effd11530777fe0410454ac72287d":0,"65d04edc65fa11e070e968a816965d08dd3f0243":89,"61f4d71261f79859c947913bd892e8f1c371f20c":633,"9234bbfd9a177a8463032910de50d0e1fa8c5f21":808,"b0717de77720877b84b9b99e9d45b662f8bb0a41":82,"e1399dfce7bfec3256cba1ca65603f0b10be6ff8":770,"392205d31247bdebe8395c22db072dcf8b56b3eb":0,"c36092bb6dda1f63ff8b47d3799325c4c1789150":88,"8ead0ef90b5933a4305a3928f1dff8a9304aaa35":17,"c126a87a55e2ade98e60ed20f8759e86964c0c10":340,"9cb56dac27d5e021754bd1d82568fb0a9164877a":299,"9d358274021b1297c67bde18cc3f7e0af5602bb6":1040,"4fe173a0424c0a714a6fba459c6dc845efb6fb2a":326,"d2f41e2173c9271803090b466b34dabef5a02460":173,"03de61e4851d934bc556245075c8e7d16c613ef1":372,"2bc2ed701ef8738a20c4df3533cf8ea63c45daea":0,"a87ba98c59486904185b24037dedd6943790e103":282,"5e51a22e09edac2f73476272b425094bee1a4a9c":1285,"ca3150840b937c1000f28ac6d06ab3bc106c91b3":0,"56f68448ca073c4b9e442bd11fddf97be45c01ed":81,"2fc1dcc9f8d755849bcbf6b0652da251243338a8":159,"33e2557051bd240543be8ab912740be5f9ba0aae":172,"0f07432dc14a7f207c85ba5f38533e686cb19536":57,"8f580d315594dd7e2635ca70def298ac63c34ffb":181,"ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9":140},"tools":{"claude-code":{"name":"Claude Code","commits":142,"loc":93120,"first_seen":1790675556,"last_seen":1792677599}},"monthly":{"2026-09":{"loc":0,"attributed_loc":0},"2026-10":{"loc":95546,"attributed_loc":93120}}},"error":null},{"analyzer":"ai-artifacts","pillar":"ai_provenance","status":"ok","tool_version":"signatures-v1","metrics":{"artifacts":3.0,"workflow_agents":0.0,"tools_configured":2.0,"earliest_adoption":1790675556.0},"findings":[],"evidence":[{"kind":"ai-artifact","description":"CLAUDE.md (claude-code configuration)","ref":"CLAUDE.md","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/CLAUDE.md","weight":0.5},{"kind":"ai-artifact","description":"AGENTS.md (generic-agent configuration)","ref":"AGENTS.md","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/AGENTS.md","weight":0.5},{"kind":"ai-artifact","description":"templates/AGENTS.md (generic-agent configuration)","ref":"templates/AGENTS.md","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/templates/AGENTS.md","weight":0.5}],"data":{"artifacts":[{"tool":"claude-code","path":"CLAUDE.md","added_at":1790945206},{"tool":"generic-agent","path":"AGENTS.md","added_at":1790945206},{"tool":"generic-agent","path":"templates/AGENTS.md","added_at":1790675556}],"workflows":[],"tools":["claude-code","generic-agent"]},"error":null},{"analyzer":"ai-velocity","pillar":"ai_provenance","status":"ok","tool_version":"prov-4","metrics":{"work_units":108.0,"flagged_units":14.0,"pre_ai_era_bursts":0.0,"pre_ai_era_measured_loc":0.0,"pre_ai_era_burst_loc":0.0,"measured_loc":87070.0,"flagged_loc":56096.0,"flagged_loc_share":0.6442632364763983,"max_loc_per_hour":8230.0,"median_loc_per_hour":290.30999349663995,"pr_timed_units":108.0,"excluded_import_loc":8476.0},"findings":[],"evidence":[{"kind":"velocity-burst","description":"4,115 lines of first-party code in ~0.5h (8,230 lines/hour, PR #59)","ref":"042f884c60daf17cabf78ce52bc2d4e605aada0a","url":"https://github.com/Hugo-Grellier/ballast/commit/042f884c60daf17cabf78ce52bc2d4e605aada0a","weight":0.6},{"kind":"velocity-burst","description":"2,972 lines of first-party code in ~0.5h (5,944 lines/hour, PR #33)","ref":"ec9551c2e0f3ecd793a0c391c52bb10914590ec4","url":"https://github.com/Hugo-Grellier/ballast/commit/ec9551c2e0f3ecd793a0c391c52bb10914590ec4","weight":0.6},{"kind":"velocity-burst","description":"5,043 lines of first-party code in ~0.9h (5,742 lines/hour, PR #71)","ref":"60a220a00a8766fae8b230d311ab18fee88cc799","url":"https://github.com/Hugo-Grellier/ballast/commit/60a220a00a8766fae8b230d311ab18fee88cc799","weight":0.6},{"kind":"velocity-burst","description":"4,097 lines of first-party code in ~1.4h (2,955 lines/hour, PR #103)","ref":"a9c8e1cec29aeec4e82bdc790ece1ab67ab3e1f2","url":"https://github.com/Hugo-Grellier/ballast/commit/a9c8e1cec29aeec4e82bdc790ece1ab67ab3e1f2","weight":0.6},{"kind":"velocity-burst","description":"10,715 lines of first-party code in ~4.2h (2,543 lines/hour, PR #39)","ref":"9d4c866a7969c856cc05e7d7d941f1ab5ee71e81","url":"https://github.com/Hugo-Grellier/ballast/commit/9d4c866a7969c856cc05e7d7d941f1ab5ee71e81","weight":0.6},{"kind":"velocity-burst","description":"2,438 lines of first-party code in ~1.0h (2,458 lines/hour, PR #57)","ref":"36df129d4717fadc60140b3af9c036b60c7fd913","url":"https://github.com/Hugo-Grellier/ballast/commit/36df129d4717fadc60140b3af9c036b60c7fd913","weight":0.6},{"kind":"velocity-burst","description":"9,316 lines of first-party code in ~4.3h (2,176 lines/hour, PR #67)","ref":"24820ce7cb3141d695c52394cc2fc9d6987f02b1","url":"https://github.com/Hugo-Grellier/ballast/commit/24820ce7cb3141d695c52394cc2fc9d6987f02b1","weight":0.6},{"kind":"velocity-burst","description":"1,268 lines of first-party code in ~0.7h (1,697 lines/hour, PR #69)","ref":"0258627fcb934822dc3eb63f11fbc64ad2ac1481","url":"https://github.com/Hugo-Grellier/ballast/commit/0258627fcb934822dc3eb63f11fbc64ad2ac1481","weight":0.509085501858736},{"kind":"velocity-burst","description":"2,404 lines of first-party code in ~1.8h (1,342 lines/hour, PR #87)","ref":"28dd8908349008df6ee897bc3810fcef440869da","url":"https://github.com/Hugo-Grellier/ballast/commit/28dd8908349008df6ee897bc3810fcef440869da","weight":0.40259265002325945},{"kind":"velocity-burst","description":"2,542 lines of first-party code in ~2.0h (1,244 lines/hour, PR #155)","ref":"d215a632b3bf074ec2cb9bea1eb673a29cf8f818","url":"https://github.com/Hugo-Grellier/ballast/commit/d215a632b3bf074ec2cb9bea1eb673a29cf8f818","weight":0.37311225876596904},{"kind":"velocity-burst","description":"3,317 lines of first-party code in ~3.0h (1,095 lines/hour, PR #101)","ref":"7ae08ed90344ad8eb7906f88388c79a3675f3538","url":"https://github.com/Hugo-Grellier/ballast/commit/7ae08ed90344ad8eb7906f88388c79a3675f3538","weight":0.32838573654780456},{"kind":"velocity-burst","description":"1,334 lines of first-party code in ~1.5h (882 lines/hour, PR #86)","ref":"685e2cabe0a62f1c8819299d52b9e9f6ae3f46f9","url":"https://github.com/Hugo-Grellier/ballast/commit/685e2cabe0a62f1c8819299d52b9e9f6ae3f46f9","weight":0.26459504132231404},{"kind":"velocity-burst","description":"1,040 lines of first-party code in ~1.4h (756 lines/hour, PR #285)","ref":"9d358274021b1297c67bde18cc3f7e0af5602bb6","url":"https://github.com/Hugo-Grellier/ballast/commit/9d358274021b1297c67bde18cc3f7e0af5602bb6","weight":0.22686325994748535},{"kind":"velocity-burst","description":"5,495 lines of first-party code in ~7.3h (751 lines/hour, PR #54)","ref":"f68345460ea2a00f0699d161f8cd4b2d568e0cda","url":"https://github.com/Hugo-Grellier/ballast/commit/f68345460ea2a00f0699d161f8cd4b2d568e0cda","weight":0.22519637232952605}],"data":{"flagged_loc_by_commit":{"ec9551c2e0f3ecd793a0c391c52bb10914590ec4":2972,"9d4c866a7969c856cc05e7d7d941f1ab5ee71e81":10715,"f68345460ea2a00f0699d161f8cd4b2d568e0cda":5495,"36df129d4717fadc60140b3af9c036b60c7fd913":2438,"042f884c60daf17cabf78ce52bc2d4e605aada0a":4115,"24820ce7cb3141d695c52394cc2fc9d6987f02b1":9316,"0258627fcb934822dc3eb63f11fbc64ad2ac1481":1268,"60a220a00a8766fae8b230d311ab18fee88cc799":5043,"685e2cabe0a62f1c8819299d52b9e9f6ae3f46f9":1334,"28dd8908349008df6ee897bc3810fcef440869da":2404,"7ae08ed90344ad8eb7906f88388c79a3675f3538":3317,"a9c8e1cec29aeec4e82bdc790ece1ab67ab3e1f2":4097,"d215a632b3bf074ec2cb9bea1eb673a29cf8f818":2542,"9d358274021b1297c67bde18cc3f7e0af5602bb6":1040},"excluded_import_commits":["cc14b214b79e2be4054722e02033934bcdd12471"]},"error":null},{"analyzer":"ai-release-velocity","pillar":"ai_provenance","status":"ok","tool_version":"prov-4","metrics":{"releases":17.0,"flagged_releases":5.0,"max_loc_per_day":114472.1},"findings":[],"evidence":[{"kind":"release-burst","description":"v0.3.0 → v0.4.0: 10,715 lines in 0.27 days (40,102.9 lines/day)","ref":"v0.3.0...v0.4.0","url":"https://github.com/Hugo-Grellier/ballast/compare/v0.3.0...v0.4.0","weight":0.4},{"kind":"release-burst","description":"v0.4.2 → v0.5.0: 5,554 lines in 0.36 days (15,336.1 lines/day)","ref":"v0.4.2...v0.5.0","url":"https://github.com/Hugo-Grellier/ballast/compare/v0.4.2...v0.5.0","weight":0.4},{"kind":"release-burst","description":"v0.5.0 → v0.6.0: 6,553 lines in 0.06 days (114,472.1 lines/day)","ref":"v0.5.0...v0.6.0","url":"https://github.com/Hugo-Grellier/ballast/compare/v0.5.0...v0.6.0","weight":0.4},{"kind":"release-burst","description":"v0.6.0 → v0.7.0: 17,734 lines in 0.48 days (36,972.6 lines/day)","ref":"v0.6.0...v0.7.0","url":"https://github.com/Hugo-Grellier/ballast/compare/v0.6.0...v0.7.0","weight":0.4},{"kind":"release-burst","description":"v0.8.1 → v0.9.0: 9,057 lines in 0.61 days (14,955.4 lines/day)","ref":"v0.8.1...v0.9.0","url":"https://github.com/Hugo-Grellier/ballast/compare/v0.8.1...v0.9.0","weight":0.4}],"data":{"releases":[{"from":"v0.1.0","to":"v0.2.0","loc":1691,"days":1.74,"loc_per_day":970.9,"flagged":false},{"from":"v0.2.0","to":"v0.3.0","loc":3005,"days":0.36,"loc_per_day":8282.8,"flagged":false},{"from":"v0.3.0","to":"v0.4.0","loc":10715,"days":0.27,"loc_per_day":40102.9,"flagged":true},{"from":"v0.4.0","to":"v0.4.1","loc":151,"days":0.54,"loc_per_day":281.2,"flagged":false},{"from":"v0.4.1","to":"v0.4.2","loc":313,"days":0.12,"loc_per_day":2565.5,"flagged":false},{"from":"v0.4.2","to":"v0.5.0","loc":5554,"days":0.36,"loc_per_day":15336.1,"flagged":true},{"from":"v0.5.0","to":"v0.6.0","loc":6553,"days":0.06,"loc_per_day":114472.1,"flagged":true},{"from":"v0.6.0","to":"v0.7.0","loc":17734,"days":0.48,"loc_per_day":36972.6,"flagged":true},{"from":"v0.7.0","to":"v0.7.1","loc":787,"days":0.17,"loc_per_day":4732.5,"flagged":false},{"from":"v0.7.1","to":"v0.8.0","loc":4064,"days":0.14,"loc_per_day":28892.4,"flagged":false},{"from":"v0.8.0","to":"v0.8.1","loc":1111,"days":0.21,"loc_per_day":5384.6,"flagged":false},{"from":"v0.8.1","to":"v0.9.0","loc":9057,"days":0.61,"loc_per_day":14955.4,"flagged":true},{"from":"v0.9.0","to":"v0.10.0","loc":2287,"days":0.38,"loc_per_day":6094.9,"flagged":false},{"from":"v0.10.0","to":"v1.0.0","loc":184,"days":3.6,"loc_per_day":51.1,"flagged":false},{"from":"v1.0.0","to":"v1.1.0","loc":8343,"days":2.82,"loc_per_day":2959.7,"flagged":false},{"from":"v1.1.0","to":"v2.0.0","loc":3522,"days":1.08,"loc_per_day":3248.8,"flagged":false},{"from":"v2.0.0","to":"v2.1.0","loc":3016,"days":0.34,"loc_per_day":8908.2,"flagged":false}]},"error":null},{"analyzer":"ai-stylometry","pillar":"ai_provenance","status":"ok","tool_version":null,"metrics":{"lines_scanned":6744.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":1.0,"secrets_low_confidence":0.0},"findings":[{"rule_id":"gitleaks/aws-access-token","severity":"low","message":"Possible aws-access-token secret in the current tree (test/docs/example file)","path":"tests/test_progress.py","line":64,"fingerprint":"tests/test_progress.py:aws-access-token:64"}],"evidence":[],"data":{},"error":null},{"analyzer":"sec-sast","pillar":"security","status":"ok","tool_version":"opengrep 1.33.1; rules f1d2b562b414","metrics":{"findings":6.0,"findings_high":6.0,"findings_medium":0.0,"findings_low":0.0,"weighted_findings":5.55,"scanned_lines":6744.0,"parse_errors":0.0},"findings":[{"rule_id":"opengrep/python.lang.security.audit.dangerous-os-exec-audit","severity":"high","message":"Found dynamic content when spawning a process. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here. [confidence low]","path":"tools/cli.py","line":24,"fingerprint":"python.lang.security.audit.dangerous-os-exec-audit:tools/cli.py:24"},{"rule_id":"opengrep/python.lang.security.audit.dangerous-os-exec-tainted-env-args","severity":"high","message":"Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands. [confidence medium]","path":"tools/cli.py","line":24,"fingerprint":"python.lang.security.audit.dangerous-os-exec-tainted-env-args:tools/cli.py:24"},{"rule_id":"opengrep/python.lang.security.audit.dangerous-subprocess-use-audit","severity":"high","message":"Detected subprocess function 'Popen' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. [confidence low]","path":"tools/codex.py","line":63,"fingerprint":"python.lang.security.audit.dangerous-subprocess-use-audit:tools/codex.py:63"},{"rule_id":"opengrep/python.lang.security.audit.dangerous-subprocess-use-audit","severity":"high","message":"Detected subprocess function 'Popen' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. [confidence low]","path":"tools/dashboard.py","line":103,"fingerprint":"python.lang.security.audit.dangerous-subprocess-use-audit:tools/dashboard.py:103"},{"rule_id":"opengrep/python.lang.security.audit.dangerous-subprocess-use-audit","severity":"high","message":"Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. [confidence low]","path":"tools/qualify.py","line":64,"fingerprint":"python.lang.security.audit.dangerous-subprocess-use-audit:tools/qualify.py:64"},{"rule_id":"opengrep/python.lang.security.audit.dangerous-subprocess-use-audit","severity":"high","message":"Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. [confidence low]","path":"tools/worktree.py","line":42,"fingerprint":"python.lang.security.audit.dangerous-subprocess-use-audit:tools/worktree.py:42"}],"evidence":[],"data":{"rulesets":["python","javascript"]},"error":null},{"analyzer":"sec-deps","pillar":"security","status":"ok","tool_version":"osv-scanner version: 2.7.1","metrics":{"vulnerable_packages":0.0,"vulnerabilities":0.0,"vulns_critical":0.0,"vulns_high":0.0,"vulns_medium":0.0,"vulns_low":0.0,"vulns_unknown":0.0,"penalty":0.0},"findings":[],"evidence":[],"data":{"ecosystems":["PyPI"]},"error":null},{"analyzer":"sec-actions","pillar":"security","status":"ok","tool_version":"zizmor 1.32.0","metrics":{"workflows":4.0,"findings":11.0,"findings_high":6.0,"findings_medium":2.0,"findings_low":3.0,"penalty":80.9},"findings":[{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/ci.yml","line":15,"fingerprint":"unpinned-uses:.github/workflows/ci.yml:15"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/ci.yml","line":16,"fingerprint":"unpinned-uses:.github/workflows/ci.yml:16"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/ci.yml","line":23,"fingerprint":"unpinned-uses:.github/workflows/ci.yml:23"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/ci.yml","line":24,"fingerprint":"unpinned-uses:.github/workflows/ci.yml:24"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/pr-body.yml","line":19,"fingerprint":"unpinned-uses:.github/workflows/pr-body.yml:19"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/release-please.yml","line":18,"fingerprint":"unpinned-uses:.github/workflows/release-please.yml:18"},{"rule_id":"zizmor/dependabot-cooldown","severity":"medium","message":"insufficient cooldown in Dependabot updates [confidence high]","path":".github/dependabot.yml","line":3,"fingerprint":"dependabot-cooldown:.github/dependabot.yml:3"},{"rule_id":"zizmor/dependabot-cooldown","severity":"medium","message":"insufficient cooldown in Dependabot updates [confidence high]","path":".github/dependabot.yml","line":14,"fingerprint":"dependabot-cooldown:.github/dependabot.yml:14"},{"rule_id":"zizmor/artipacked","severity":"low","message":"credential persistence through GitHub Actions artifacts [confidence low]","path":".github/workflows/ci.yml","line":15,"fingerprint":"artipacked:.github/workflows/ci.yml:15"},{"rule_id":"zizmor/artipacked","severity":"low","message":"credential persistence through GitHub Actions artifacts [confidence low]","path":".github/workflows/ci.yml","line":23,"fingerprint":"artipacked:.github/workflows/ci.yml:23"},{"rule_id":"zizmor/artipacked","severity":"low","message":"credential persistence through GitHub Actions artifacts [confidence low]","path":".github/workflows/pr-body.yml","line":19,"fingerprint":"artipacked:.github/workflows/pr-body.yml:19"}],"evidence":[],"data":{},"error":null},{"analyzer":"sec-posture","pillar":"security","status":"ok","tool_version":null,"metrics":{"check:security_policy":0.0,"check:dependency_updates":1.0,"check:signed_commits":1.0,"check:lockfiles":1.0,"signed_commit_share":0.994,"unpinned_manifests":0.0},"findings":[],"evidence":[{"kind":"posture","description":"Dependency updates: .github/dependabot.yml","ref":".github/dependabot.yml","url":null,"weight":0.0}],"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":312.0,"function_nloc":5003.0,"mean_ccn":5.92,"p90_ccn":13.0,"complex_functions":15.0,"long_functions":0.0,"many_param_functions":0.0,"risky_nloc_share":0.1447},"findings":[],"evidence":[{"kind":"complex-function","description":"worker in tools/dashboard.py: complexity 26, 67 lines","ref":"tools/dashboard.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/tools/dashboard.py#L198","weight":0.43333333333333335},{"kind":"complex-function","description":"specs in tools/merge_check.py: complexity 25, 67 lines","ref":"tools/merge_check.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/tools/merge_check.py#L474","weight":0.4166666666666667},{"kind":"complex-function","description":"finish_execution in tools/coordinate.py: complexity 24, 63 lines","ref":"tools/coordinate.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/tools/coordinate.py#L734","weight":0.4},{"kind":"complex-function","description":"validate in tools/progress.py: complexity 24, 35 lines","ref":"tools/progress.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/tools/progress.py#L56","weight":0.4},{"kind":"complex-function","description":"issue_view in tools/coordinate.py: complexity 23, 37 lines","ref":"tools/coordinate.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/tools/coordinate.py#L1132","weight":0.38333333333333336},{"kind":"complex-function","description":"required_contexts in tools/merge_check.py: complexity 23, 30 lines","ref":"tools/merge_check.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/tools/merge_check.py#L231","weight":0.38333333333333336},{"kind":"complex-function","description":"policy in tools/admission.py: complexity 22, 29 lines","ref":"tools/admission.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/tools/admission.py#L146","weight":0.36666666666666664},{"kind":"complex-function","description":"establish in tools/worker.py: complexity 22, 74 lines","ref":"tools/worker.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/tools/worker.py#L248","weight":0.36666666666666664},{"kind":"complex-function","description":"do_POST in tools/dashboard.py: complexity 21, 63 lines","ref":"tools/dashboard.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/tools/dashboard.py#L512","weight":0.35},{"kind":"complex-function","description":"issue in tools/dashboard.py: complexity 21, 81 lines","ref":"tools/dashboard.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/tools/dashboard.py#L267","weight":0.35}],"data":{},"error":null},{"analyzer":"qual-duplication","pillar":"quality","status":"ok","tool_version":"repotrust-dup-w6","metrics":{"compared_lines":5419.0,"duplicated_lines":176.0,"duplicated_share":0.0325,"files":15.0},"findings":[],"evidence":[{"kind":"duplicate-code","description":"6+ duplicated lines: templates/github/scripts/pr_body.py:1 and tools/pr_body.py:1","ref":"templates/github/scripts/pr_body.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/templates/github/scripts/pr_body.py#L1","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: tools/coordinate.py:844 and tools/coordinate.py:865","ref":"tools/coordinate.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/tools/coordinate.py#L844","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: tools/coordinate.py:1358 and tools/worktree.py:279","ref":"tools/coordinate.py","url":"https://github.com/Hugo-Grellier/ballast/blob/ba7f3de48b738ee2fa34ebb1a70f2528b74a66e9/tools/coordinate.py#L1358","weight":0.3}],"data":{},"error":null},{"analyzer":"qual-lint","pillar":"quality","status":"ok","tool_version":"opengrep 1.33.1; rules f1d2b562b414","metrics":{"findings":2.0,"weighted_findings":6.0,"scanned_lines":6744.0,"category:best-practice":2.0},"findings":[{"rule_id":"opengrep/python.lang.best-practice.arbitrary-sleep","severity":"high","message":"time.sleep() call; did you mean to leave this in?","path":"tools/worker.py","line":511,"fingerprint":"python.lang.best-practice.arbitrary-sleep:tools/worker.py:511"},{"rule_id":"opengrep/python.lang.best-practice.arbitrary-sleep","severity":"high","message":"time.sleep() call; did you mean to leave this in?","path":"tools/worker.py","line":514,"fingerprint":"python.lang.best-practice.arbitrary-sleep:tools/worker.py:514"}],"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":1.0,"check:tests_cochange":1.0,"test_lines":7946.0,"source_lines":6744.0,"test_ratio":1.1782,"ci_files":4.0,"cochange_share":0.9886,"cochange_commits":88.0},"findings":[],"evidence":[{"kind":"ci","description":"CI config: .github/workflows/ci.yml","ref":".github/workflows/ci.yml","url":null,"weight":0.0},{"kind":"ci","description":"CI config: .github/workflows/pr-body.yml","ref":".github/workflows/pr-body.yml","url":null,"weight":0.0},{"kind":"ci","description":"CI config: .github/workflows/pr-title.yml","ref":".github/workflows/pr-title.yml","url":null,"weight":0.0},{"kind":"ci","description":"CI config: .github/workflows/release-please.yml","ref":".github/workflows/release-please.yml","url":null,"weight":0.0},{"kind":"ci","description":"CI runs tests (unittest)","ref":null,"url":null,"weight":0.0},{"kind":"ci","description":"CI runs linters (ruff)","ref":null,"url":null,"weight":0.0}],"data":{"test_commands":["unittest"],"lint_commands":["ruff"]},"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":1.0,"readme_lines":70.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},{"kind":"docs","description":"CHANGELOG.md","ref":"CHANGELOG.md","url":null,"weight":0.0}],"data":{},"error":null},{"analyzer":"qual-type-safety","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:strict_config":0.0,"check:low_escape_density":1.0,"escapes":3.0,"escapes_per_kloc":0.461},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"x-blame","pillar":"ai_provenance","status":"ok","tool_version":"git-blame","metrics":{"ai_lines":5648.0,"other_lines":1096.0,"files_blamed":15.0,"blame_failures":0.0,"quality:ai_findings":2.0,"quality:ai_per_kloc":0.354,"quality:other_findings":0.0,"quality:other_per_kloc":0.0,"security:ai_findings":4.0,"security:ai_per_kloc":0.708,"security:other_findings":2.0,"security:other_per_kloc":1.825,"security:ratio":0.39},"findings":[],"evidence":[],"data":{"sampled":false,"comparable":true},"error":null}],"flags":[]}