{"schema_version":"2","scorer_version":"0.1.0","scoring_version":"prov-5+qual-2+sec-2","generated_at":"2026-11-14T14:52:06.284447Z","repo":{"ref":{"host":"github.com","owner":"mastifdogo","name":"Bookeeping"},"default_branch":"main","clone_url":"https://github.com/mastifdogo/Bookeeping.git","html_url":"https://github.com/mastifdogo/Bookeeping","description":null,"stars":0,"forks":0,"is_fork":false,"is_archived":false,"is_private":false,"size_kb":1177,"primary_language":"TypeScript","license_spdx":null,"created_at":"2026-10-04T22:50:50Z","pushed_at":"2026-11-14T13:58:37Z","security_policy_url":null,"distribution":{"owner_created_at":"2023-05-07T22:53:45Z","owner_type":"User","release_assets":[{"name":"debian-13-ledger_v0.18.1_amd64.tar.zst","size":136463763,"download_count":1,"release_tag":"v0.18.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.18.1/debian-13-ledger_v0.18.1_amd64.tar.zst"},{"name":"ledger-v0.18.1-linux-amd64.tar.gz","size":45216411,"download_count":1,"release_tag":"v0.18.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.18.1/ledger-v0.18.1-linux-amd64.tar.gz"},{"name":"SHA256SUMS","size":205,"download_count":1,"release_tag":"v0.18.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.18.1/SHA256SUMS"},{"name":"debian-13-ledger_v0.18.0_amd64.tar.zst","size":136463581,"download_count":1,"release_tag":"v0.18.0","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.18.0/debian-13-ledger_v0.18.0_amd64.tar.zst"},{"name":"ledger-v0.18.0-linux-amd64.tar.gz","size":45217839,"download_count":1,"release_tag":"v0.18.0","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.18.0/ledger-v0.18.0-linux-amd64.tar.gz"},{"name":"SHA256SUMS","size":205,"download_count":1,"release_tag":"v0.18.0","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.18.0/SHA256SUMS"},{"name":"debian-12-ledger_v0.17.1_amd64.tar.zst","size":189227529,"download_count":1,"release_tag":"v0.17.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.1/debian-12-ledger_v0.17.1_amd64.tar.zst"},{"name":"ledger-v0.17.1-linux-amd64.tar.gz","size":45216717,"download_count":1,"release_tag":"v0.17.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.1/ledger-v0.17.1-linux-amd64.tar.gz"},{"name":"SHA256SUMS","size":205,"download_count":1,"release_tag":"v0.17.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.1/SHA256SUMS"},{"name":"debian-13-ledger_v0.17.1-debian13.1_amd64.tar.zst","size":136463662,"download_count":3,"release_tag":"v0.17.1-debian13.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.1-debian13.1/debian-13-ledger_v0.17.1-debian13.1_amd64.tar.zst"},{"name":"ledger-v0.17.1-debian13.1-linux-amd64.tar.gz","size":45217086,"download_count":1,"release_tag":"v0.17.1-debian13.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.1-debian13.1/ledger-v0.17.1-debian13.1-linux-amd64.tar.gz"},{"name":"SHA256SUMS","size":227,"download_count":1,"release_tag":"v0.17.1-debian13.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.1-debian13.1/SHA256SUMS"},{"name":"debian-12-ledger_v0.17.0_amd64.tar.zst","size":189249095,"download_count":1,"release_tag":"v0.17.0","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.0/debian-12-ledger_v0.17.0_amd64.tar.zst"},{"name":"ledger-v0.17.0-linux-amd64.tar.gz","size":45215780,"download_count":1,"release_tag":"v0.17.0","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.0/ledger-v0.17.0-linux-amd64.tar.gz"},{"name":"SHA256SUMS","size":205,"download_count":1,"release_tag":"v0.17.0","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.0/SHA256SUMS"},{"name":"debian-13-ledger_v0.17.0-debian13.2_amd64.tar.zst","size":136416294,"download_count":1,"release_tag":"v0.17.0-debian13.2","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.0-debian13.2/debian-13-ledger_v0.17.0-debian13.2_amd64.tar.zst"},{"name":"ledger-v0.17.0-debian13.2-linux-amd64.tar.gz","size":45214194,"download_count":1,"release_tag":"v0.17.0-debian13.2","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.0-debian13.2/ledger-v0.17.0-debian13.2-linux-amd64.tar.gz"},{"name":"SHA256SUMS","size":227,"download_count":1,"release_tag":"v0.17.0-debian13.2","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.0-debian13.2/SHA256SUMS"},{"name":"debian-13-ledger_v0.17.0-debian13.1_amd64.tar.zst","size":196364809,"download_count":1,"release_tag":"v0.17.0-debian13.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.0-debian13.1/debian-13-ledger_v0.17.0-debian13.1_amd64.tar.zst"},{"name":"ledger-v0.17.0-debian13.1-linux-amd64.tar.gz","size":45217907,"download_count":1,"release_tag":"v0.17.0-debian13.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.0-debian13.1/ledger-v0.17.0-debian13.1-linux-amd64.tar.gz"},{"name":"SHA256SUMS","size":227,"download_count":1,"release_tag":"v0.17.0-debian13.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.0-debian13.1/SHA256SUMS"},{"name":"debian-12-ledger_v0.16.2_amd64.tar.zst","size":184653786,"download_count":1,"release_tag":"v0.16.2","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.16.2/debian-12-ledger_v0.16.2_amd64.tar.zst"},{"name":"ledger-v0.16.2-linux-amd64.tar.gz","size":45203977,"download_count":2,"release_tag":"v0.16.2","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.16.2/ledger-v0.16.2-linux-amd64.tar.gz"},{"name":"SHA256SUMS","size":205,"download_count":2,"release_tag":"v0.16.2","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.16.2/SHA256SUMS"},{"name":"debian-12-ledger_v0.16.1_amd64.tar.zst","size":184656043,"download_count":1,"release_tag":"v0.16.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.16.1/debian-12-ledger_v0.16.1_amd64.tar.zst"},{"name":"ledger-v0.16.1-linux-amd64.tar.gz","size":45214454,"download_count":1,"release_tag":"v0.16.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.16.1/ledger-v0.16.1-linux-amd64.tar.gz"},{"name":"SHA256SUMS","size":205,"download_count":1,"release_tag":"v0.16.1","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.16.1/SHA256SUMS"},{"name":"debian-12-ledger_v0.16.0_amd64.tar.zst","size":184646603,"download_count":1,"release_tag":"v0.16.0","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.16.0/debian-12-ledger_v0.16.0_amd64.tar.zst"},{"name":"ledger-v0.16.0-linux-amd64.tar.gz","size":45201903,"download_count":1,"release_tag":"v0.16.0","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.16.0/ledger-v0.16.0-linux-amd64.tar.gz"},{"name":"SHA256SUMS","size":205,"download_count":1,"release_tag":"v0.16.0","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.16.0/SHA256SUMS"}]}},"commit_sha":"870cdaee1fe616d3f567bd79f2f4f3e7a6634681","profile":{"lines_by_language":{"TypeScript":24992,"Svelte":7340,"Shell":1477,"SQL":778,"JavaScript":104},"files_by_category":{"source":158,"other":17,"config":13,"test":12,"docs":8,"generated":2},"source_lines":30060,"test_lines":4631},"pillars":{"ai_provenance":{"score":100.0,"confidence":0.9,"coverage":1.0,"label":"explicit","breakdown":{"attributed_share":1.0,"suspected_share":0.0,"estimated_share":1.0,"ai_artifacts":11.0,"flagged_work_units":7.0,"flagged_releases":0.0,"style_index":0.033},"summary":"Explicit AI attribution on 100% of first-party code added; an estimated 100% including velocity signals."},"quality":{"score":64.7,"confidence":0.9,"coverage":1.0,"label":"weak","breakdown":{"complexity":52.0,"duplication":57.5,"lint":80.4,"testing":72.7,"docs":40.0,"type_safety":100.0,"process":null},"summary":"Code quality is weak: test-to-source ratio 0.15, CI runs tests; 22% of function code in complex or long functions; 9% duplicated lines. Weakest area: docs."},"security":{"score":78.4,"confidence":0.85,"coverage":1.0,"label":"adequate","breakdown":{"secrets":100.0,"sast":95.2,"dependencies":75.3,"ci_actions":62.8,"posture":20.0,"scorecard":null},"summary":"Security posture is adequate: 9 known vulnerabilities in 4 dependencies; 2 high-severity SAST findings; 3 high-severity workflow issues. Weakest area: posture."}},"analyzer_results":[{"analyzer":"sec-scorecard","pillar":"security","status":"skipped","tool_version":null,"metrics":{},"findings":[],"evidence":[],"data":{},"error":"no published OpenSSF Scorecard result for this repo"},{"analyzer":"sec-registry","pillar":"security","status":"ok","tool_version":null,"metrics":{"declared":13.0,"checked":13.0,"missing":0.0,"recent":0.0,"lookup_errors":0.0},"findings":[],"evidence":[],"data":{"phantom":false},"error":null},{"analyzer":"ai-attribution","pillar":"ai_provenance","status":"ok","tool_version":"signatures-v1","metrics":{"commits":81.0,"attributed_commits":78.0,"attributed_commit_share":0.9629629629629629,"effective_loc":41923.0,"attributed_loc":41923.0,"attributed_loc_share":1.0,"tools_detected":1.0},"findings":[],"evidence":[{"kind":"attribution-summary","description":"Claude Code: 78 attributed commits, 41,923 lines added","ref":null,"url":null,"weight":1.0},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"870cdaee1fe616d3f567bd79f2f4f3e7a6634681","url":"https://github.com/mastifdogo/Bookeeping/commit/870cdaee1fe616d3f567bd79f2f4f3e7a6634681","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"ad8da30d2bbfec0fee2a5353809b8b6c433f5ab6","url":"https://github.com/mastifdogo/Bookeeping/commit/ad8da30d2bbfec0fee2a5353809b8b6c433f5ab6","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"c61fd4ad7d99316a9cf85909b3904b4fd37bd056","url":"https://github.com/mastifdogo/Bookeeping/commit/c61fd4ad7d99316a9cf85909b3904b4fd37bd056","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"534cfca8d1cbda293abd43ee525440857172e5f0","url":"https://github.com/mastifdogo/Bookeeping/commit/534cfca8d1cbda293abd43ee525440857172e5f0","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"f4760b694f3e4e3e824584b6299a928c6a67a800","url":"https://github.com/mastifdogo/Bookeeping/commit/f4760b694f3e4e3e824584b6299a928c6a67a800","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"b9c025f7cb1ece0a8ea4dbd2418ecd7d451eddbf","url":"https://github.com/mastifdogo/Bookeeping/commit/b9c025f7cb1ece0a8ea4dbd2418ecd7d451eddbf","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"4403b8e219c1a6a27526d9389178880391815adf","url":"https://github.com/mastifdogo/Bookeeping/commit/4403b8e219c1a6a27526d9389178880391815adf","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"f6d44ffcf496da89fec800a7d60226bcd9769c3f","url":"https://github.com/mastifdogo/Bookeeping/commit/f6d44ffcf496da89fec800a7d60226bcd9769c3f","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"b6ebc93217a05391ba86ddcfedfce19c78ac4f94","url":"https://github.com/mastifdogo/Bookeeping/commit/b6ebc93217a05391ba86ddcfedfce19c78ac4f94","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"9e166334f1a96ec2f71401f1854fb4d4770d6db0","url":"https://github.com/mastifdogo/Bookeeping/commit/9e166334f1a96ec2f71401f1854fb4d4770d6db0","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"6fb55af203d4a9cb595f413365c24ca5ee27db0d","url":"https://github.com/mastifdogo/Bookeeping/commit/6fb55af203d4a9cb595f413365c24ca5ee27db0d","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"1f971347210ed4e74d0030bcb52e0b9dfe57e237","url":"https://github.com/mastifdogo/Bookeeping/commit/1f971347210ed4e74d0030bcb52e0b9dfe57e237","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"eb7c3f28eb870f6161969ac5a3bedd2c8b09c4ff","url":"https://github.com/mastifdogo/Bookeeping/commit/eb7c3f28eb870f6161969ac5a3bedd2c8b09c4ff","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"50186e3ad838a35e370cdc4f65925619e7737f6b","url":"https://github.com/mastifdogo/Bookeeping/commit/50186e3ad838a35e370cdc4f65925619e7737f6b","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"44bb5587a27a9480a4095ee9c4e5352dcdca0646","url":"https://github.com/mastifdogo/Bookeeping/commit/44bb5587a27a9480a4095ee9c4e5352dcdca0646","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"9dc60a20d6d9fda32acd89ccb22f78cfcef0f453","url":"https://github.com/mastifdogo/Bookeeping/commit/9dc60a20d6d9fda32acd89ccb22f78cfcef0f453","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"35ae821ad0bb4eed646b34930cf9a3b732787e9a","url":"https://github.com/mastifdogo/Bookeeping/commit/35ae821ad0bb4eed646b34930cf9a3b732787e9a","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"17e4600bf45eebc89cf927354b1fe2c87e8dbfcb","url":"https://github.com/mastifdogo/Bookeeping/commit/17e4600bf45eebc89cf927354b1fe2c87e8dbfcb","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"58ff0bb9dbbce274896cb7d9671ca19ed7bbed1f","url":"https://github.com/mastifdogo/Bookeeping/commit/58ff0bb9dbbce274896cb7d9671ca19ed7bbed1f","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"50d6ec4ad46145d18e840f9562db8e3e88d754a2","url":"https://github.com/mastifdogo/Bookeeping/commit/50d6ec4ad46145d18e840f9562db8e3e88d754a2","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"c3060955d6865bd31d75225952c56a638b0c5edf","url":"https://github.com/mastifdogo/Bookeeping/commit/c3060955d6865bd31d75225952c56a638b0c5edf","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"be12d6caf430eb435eb7f98b2c5a4010e3b913b1","url":"https://github.com/mastifdogo/Bookeeping/commit/be12d6caf430eb435eb7f98b2c5a4010e3b913b1","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"3cc3d3f4486742def18a53c5181cf076160f3a55","url":"https://github.com/mastifdogo/Bookeeping/commit/3cc3d3f4486742def18a53c5181cf076160f3a55","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"0bc5e26bc047e4550aebb53b79452c3ad2d6119c","url":"https://github.com/mastifdogo/Bookeeping/commit/0bc5e26bc047e4550aebb53b79452c3ad2d6119c","weight":0.9},{"kind":"attributed-commit","description":"Claude Code: author email noreply@anthropic.com","ref":"238243da81f73772a65886b49d6e47c6d690a664","url":"https://github.com/mastifdogo/Bookeeping/commit/238243da81f73772a65886b49d6e47c6d690a664","weight":0.9}],"data":{"attributed_loc_by_commit":{"dc7db93af5e16912d63deaceb4eae1e4275cda5e":2547,"5c31f90e7ab9ee7e2441fbbe68cd4d341bfee471":1166,"438efb4518915fc7504d36a69c8872078365277e":2778,"b2289380455d7f2adc1995805c169a9c1ad6dc66":2298,"0c30989d089ccf9079294e6d3ec129556bab3408":443,"1103a9bb65e7bed330e23b5469631c62804579ef":0,"4571c8470a190c33aada03a3036c25888bd78719":0,"097bcb6e2fbbcc3fae749c432f2544b0b473d9b7":0,"843462822b41011d36db59228b4b7d71e1ffef9e":293,"d37e4e622f09c2f530e169925b37963b17b5ae09":0,"8b6a66965a15a2f21af912691059b7eee7dc4e5c":17,"9a0c2bad7b3d14aff3868b40f0211f6a239f70b2":4762,"d815289d625b3ab20b3a81bb6056ad82e74b185f":54,"cd887f6959ccc0d6418fc85fea135e37c6bb4e93":1390,"485daf14267e23928b92824a72c6a7f627544181":117,"0f62d3daf3369b6747738ec938ce53e796fa513b":216,"d0a18fef2109334488109361458283ad014997bb":1,"f8964af79bb341a8158d3601a04d53d806b14e91":2071,"3d0c85c2e01477bc9faac40cf223c39360e13172":18,"e22b78ea72c9150114f3e57d3c7f6cf1ff38e229":20,"1922f0c3de4be4b17273eebfa9235b56adfc26b2":48,"cf513ab3acbc7ae44d71c124b5b03d1abff263f4":1,"5960f8fa414f222da7dbe4dfe8c8704ea750767d":1013,"5ec5d2362bb027afff56a0f9f14ab6741968163f":1069,"e19f6504e25b43226788f5bcf98a817a64e5d5ac":3810,"1ca9ecc0ee2f6848ac974757c7bca88f2b23397a":347,"431b5b84891dfd3c0d924cc21e832e3bb0e6e23b":326,"ba019b58038169c19b92d198949ad27d9aec8a65":13,"95311cfd746f13c84f543cdd1e3fc309470b9e98":3127,"e7b2e232eddbb27c46b52ccad5be3900ce60d255":17,"7a85658bf9c5d0e5a98db0dab275c8539cc4b55d":7,"c9a61637d1c8629b48ed90f0859318b80b251f75":121,"5ae5e72fd9a4ba3cac3bacf959dade5b4a33ae8b":64,"e6f3cce79f1b82c09944f47c72900c0fb1e4a844":441,"77056e10bde6918470c23170c60b8fd557a69f7e":397,"638d2b2e7ca8cc702fd012b7028b57a760ea9cbe":1848,"2ceb2da32637f211a193de4fc64c202a3855797e":0,"2b76382cf5a96ec143514b242c196c081307bf6a":75,"571af6ced72d4382f40e69e079bbf463c16a2a81":0,"d06f5490a1f5765fec5aea3396df93501e282c79":0,"04f4eaf68b74ca7ef252d2ebc1aa524949488e4a":900,"c0bf53931ba10d0be8826f8477c0d5e6469f35e9":3,"1726095ba5330e962ea21cb134a49fe9aaafed6b":735,"afbade8d1bd1a2d6d53c6f3339e8352da0956e47":9,"e08e04987fa3c4ae64a291c0c21fe8c9a1491cea":2049,"b87f4c00a423be84139ffadafa837dcb93d1aa02":86,"59fd1f7e6810259ca40db3ce5376caf3b7e4b3ec":0,"92c38a107b57f37ecb947550af05007bf6be1f46":0,"758052ea02e906f8f993053715b77826ee01bc48":0,"91d9c7a6c39f4f4a708296eac89c9de23b78aefd":0,"558fff8b5dd75f154f975a76bea5ec42435b889b":0,"94738a545870755a2ec1e6709ccbee9da8e25f01":255,"758edfa07a45d5fa957245c8cca0dd26993194b3":67,"238243da81f73772a65886b49d6e47c6d690a664":231,"0bc5e26bc047e4550aebb53b79452c3ad2d6119c":1370,"3cc3d3f4486742def18a53c5181cf076160f3a55":1110,"be12d6caf430eb435eb7f98b2c5a4010e3b913b1":765,"c3060955d6865bd31d75225952c56a638b0c5edf":3,"50d6ec4ad46145d18e840f9562db8e3e88d754a2":214,"58ff0bb9dbbce274896cb7d9671ca19ed7bbed1f":369,"17e4600bf45eebc89cf927354b1fe2c87e8dbfcb":0,"35ae821ad0bb4eed646b34930cf9a3b732787e9a":0,"9dc60a20d6d9fda32acd89ccb22f78cfcef0f453":426,"44bb5587a27a9480a4095ee9c4e5352dcdca0646":1070,"50186e3ad838a35e370cdc4f65925619e7737f6b":58,"eb7c3f28eb870f6161969ac5a3bedd2c8b09c4ff":80,"1f971347210ed4e74d0030bcb52e0b9dfe57e237":0,"6fb55af203d4a9cb595f413365c24ca5ee27db0d":0,"9e166334f1a96ec2f71401f1854fb4d4770d6db0":384,"b6ebc93217a05391ba86ddcfedfce19c78ac4f94":0,"f6d44ffcf496da89fec800a7d60226bcd9769c3f":2,"4403b8e219c1a6a27526d9389178880391815adf":20,"f4760b694f3e4e3e824584b6299a928c6a67a800":197,"b9c025f7cb1ece0a8ea4dbd2418ecd7d451eddbf":197,"534cfca8d1cbda293abd43ee525440857172e5f0":20,"c61fd4ad7d99316a9cf85909b3904b4fd37bd056":4,"ad8da30d2bbfec0fee2a5353809b8b6c433f5ab6":381,"870cdaee1fe616d3f567bd79f2f4f3e7a6634681":3},"tools":{"claude-code":{"name":"Claude Code","commits":78,"loc":41923,"first_seen":1791166914,"last_seen":1794664714}},"monthly":{"2026-10":{"loc":24479,"attributed_loc":24479},"2026-11":{"loc":17444,"attributed_loc":17444}}},"error":null},{"analyzer":"ai-artifacts","pillar":"ai_provenance","status":"ok","tool_version":"signatures-v1","metrics":{"artifacts":11.0,"workflow_agents":0.0,"tools_configured":1.0,"earliest_adoption":1794075768.0},"findings":[],"evidence":[{"kind":"ai-artifact","description":".claude/skills/ledger-module/SKILL.md (claude-code configuration)","ref":".claude/skills/ledger-module/SKILL.md","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/.claude/skills/ledger-module/SKILL.md","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/ledger-module/scripts/check-module.ts (claude-code configuration)","ref":".claude/skills/ledger-module/scripts/check-module.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/.claude/skills/ledger-module/scripts/check-module.ts","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/ledger-module/scripts/new-module.sh (claude-code configuration)","ref":".claude/skills/ledger-module/scripts/new-module.sh","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/.claude/skills/ledger-module/scripts/new-module.sh","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/ledger-module/template/.github/workflows/release.yml (claude-code configuration)","ref":".claude/skills/ledger-module/template/.github/workflows/release.yml","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/.claude/skills/ledger-module/template/.github/workflows/release.yml","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/ledger-module/template/.gitignore (claude-code configuration)","ref":".claude/skills/ledger-module/template/.gitignore","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/.claude/skills/ledger-module/template/.gitignore","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/ledger-module/template/README.md (claude-code configuration)","ref":".claude/skills/ledger-module/template/README.md","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/.claude/skills/ledger-module/template/README.md","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/ledger-module/template/ledger-module.json (claude-code configuration)","ref":".claude/skills/ledger-module/template/ledger-module.json","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/.claude/skills/ledger-module/template/ledger-module.json","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/ledger-module/template/migrations/001_init.sql (claude-code configuration)","ref":".claude/skills/ledger-module/template/migrations/001_init.sql","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/.claude/skills/ledger-module/template/migrations/001_init.sql","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/ledger-module/template/server.mjs (claude-code configuration)","ref":".claude/skills/ledger-module/template/server.mjs","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/.claude/skills/ledger-module/template/server.mjs","weight":0.5},{"kind":"ai-artifact","description":".claude/skills/ledger-module/template/ui/index.html (claude-code configuration)","ref":".claude/skills/ledger-module/template/ui/index.html","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/.claude/skills/ledger-module/template/ui/index.html","weight":0.5},{"kind":"ai-artifact","description":"CLAUDE.md (claude-code configuration)","ref":"CLAUDE.md","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/CLAUDE.md","weight":0.5}],"data":{"artifacts":[{"tool":"claude-code","path":".claude/skills/ledger-module/SKILL.md","added_at":1794075768},{"tool":"claude-code","path":".claude/skills/ledger-module/scripts/check-module.ts","added_at":1794075768},{"tool":"claude-code","path":".claude/skills/ledger-module/scripts/new-module.sh","added_at":1794075768},{"tool":"claude-code","path":".claude/skills/ledger-module/template/.github/workflows/release.yml","added_at":1794179168},{"tool":"claude-code","path":".claude/skills/ledger-module/template/.gitignore","added_at":1794075768},{"tool":"claude-code","path":".claude/skills/ledger-module/template/README.md","added_at":1794075768},{"tool":"claude-code","path":".claude/skills/ledger-module/template/ledger-module.json","added_at":1794075768},{"tool":"claude-code","path":".claude/skills/ledger-module/template/migrations/001_init.sql","added_at":1794075768},{"tool":"claude-code","path":".claude/skills/ledger-module/template/server.mjs","added_at":1794075768},{"tool":"claude-code","path":".claude/skills/ledger-module/template/ui/index.html","added_at":1794075768},{"tool":"claude-code","path":"CLAUDE.md","added_at":1794540165}],"workflows":[],"tools":["claude-code"]},"error":null},{"analyzer":"ai-velocity","pillar":"ai_provenance","status":"ok","tool_version":"prov-4","metrics":{"work_units":31.0,"flagged_units":7.0,"pre_ai_era_bursts":0.0,"pre_ai_era_measured_loc":0.0,"pre_ai_era_burst_loc":0.0,"measured_loc":32565.0,"flagged_loc":23824.0,"flagged_loc_share":0.731582987870413,"max_loc_per_hour":1300.7870753935376,"median_loc_per_hour":361.0454985479187,"pr_timed_units":0.0,"excluded_import_loc":9358.0},"findings":[],"evidence":[{"kind":"velocity-burst","description":"6,978 lines of first-party code in ~5.4h (1,301 lines/hour, 5 commit session)","ref":"843462822b41011d36db59228b4b7d71e1ffef9e","url":"https://github.com/mastifdogo/Bookeeping/commit/843462822b41011d36db59228b4b7d71e1ffef9e","weight":0.39023612261806123},{"kind":"velocity-burst","description":"2,461 lines of first-party code in ~2.1h (1,190 lines/hour, 5 commit session)","ref":"58ff0bb9dbbce274896cb7d9671ca19ed7bbed1f","url":"https://github.com/mastifdogo/Bookeeping/commit/58ff0bb9dbbce274896cb7d9671ca19ed7bbed1f","weight":0.3570979443772673},{"kind":"velocity-burst","description":"1,069 lines of first-party code in ~1.0h (1,121 lines/hour, 1 commit session)","ref":"5ec5d2362bb027afff56a0f9f14ab6741968163f","url":"https://github.com/mastifdogo/Bookeeping/commit/5ec5d2362bb027afff56a0f9f14ab6741968163f","weight":0.33630061170987474},{"kind":"velocity-burst","description":"3,810 lines of first-party code in ~4.0h (952 lines/hour, 1 commit session)","ref":"e19f6504e25b43226788f5bcf98a817a64e5d5ac","url":"https://github.com/mastifdogo/Bookeeping/commit/e19f6504e25b43226788f5bcf98a817a64e5d5ac","weight":0.28575},{"kind":"velocity-burst","description":"3,795 lines of first-party code in ~4.8h (784 lines/hour, 5 commit session)","ref":"f8964af79bb341a8158d3601a04d53d806b14e91","url":"https://github.com/mastifdogo/Bookeeping/commit/f8964af79bb341a8158d3601a04d53d806b14e91","weight":0.23528128587830083},{"kind":"velocity-burst","description":"3,466 lines of first-party code in ~4.8h (724 lines/hour, 3 commit session)","ref":"95311cfd746f13c84f543cdd1e3fc309470b9e98","url":"https://github.com/mastifdogo/Bookeeping/commit/95311cfd746f13c84f543cdd1e3fc309470b9e98","weight":0.21719060052219322},{"kind":"velocity-burst","description":"2,245 lines of first-party code in ~4.3h (520 lines/hour, 2 commit session)","ref":"638d2b2e7ca8cc702fd012b7028b57a760ea9cbe","url":"https://github.com/mastifdogo/Bookeeping/commit/638d2b2e7ca8cc702fd012b7028b57a760ea9cbe","weight":0.1559328574184835}],"data":{"flagged_loc_by_commit":{"5c31f90e7ab9ee7e2441fbbe68cd4d341bfee471":1166,"438efb4518915fc7504d36a69c8872078365277e":2778,"b2289380455d7f2adc1995805c169a9c1ad6dc66":2298,"0c30989d089ccf9079294e6d3ec129556bab3408":443,"843462822b41011d36db59228b4b7d71e1ffef9e":293,"cd887f6959ccc0d6418fc85fea135e37c6bb4e93":1390,"485daf14267e23928b92824a72c6a7f627544181":117,"0f62d3daf3369b6747738ec938ce53e796fa513b":216,"d0a18fef2109334488109361458283ad014997bb":1,"f8964af79bb341a8158d3601a04d53d806b14e91":2071,"5ec5d2362bb027afff56a0f9f14ab6741968163f":1069,"e19f6504e25b43226788f5bcf98a817a64e5d5ac":3810,"431b5b84891dfd3c0d924cc21e832e3bb0e6e23b":326,"ba019b58038169c19b92d198949ad27d9aec8a65":13,"95311cfd746f13c84f543cdd1e3fc309470b9e98":3127,"77056e10bde6918470c23170c60b8fd557a69f7e":397,"638d2b2e7ca8cc702fd012b7028b57a760ea9cbe":1848,"3cc3d3f4486742def18a53c5181cf076160f3a55":1110,"be12d6caf430eb435eb7f98b2c5a4010e3b913b1":765,"c3060955d6865bd31d75225952c56a638b0c5edf":3,"50d6ec4ad46145d18e840f9562db8e3e88d754a2":214,"58ff0bb9dbbce274896cb7d9671ca19ed7bbed1f":369},"excluded_import_commits":["9a0c2bad7b3d14aff3868b40f0211f6a239f70b2","dc7db93af5e16912d63deaceb4eae1e4275cda5e","e08e04987fa3c4ae64a291c0c21fe8c9a1491cea"]},"error":null},{"analyzer":"ai-release-velocity","pillar":"ai_provenance","status":"ok","tool_version":"prov-4","metrics":{"releases":40.0,"flagged_releases":0.0,"max_loc_per_day":49704.0},"findings":[],"evidence":[],"data":{"releases":[{"from":"0.0.0","to":"v0.0.0","loc":0,"days":0.04,"loc_per_day":0.0,"flagged":false},{"from":"v0.0.0","to":"v0.4.0","loc":0,"days":0.04,"loc_per_day":0.0,"flagged":false},{"from":"v0.4.0","to":"v0.4.1","loc":0,"days":0.04,"loc_per_day":0.0,"flagged":false},{"from":"v0.4.1","to":"v0.4.2","loc":17,"days":0.49,"loc_per_day":34.9,"flagged":false},{"from":"v0.4.2","to":"v0.5.0","loc":1778,"days":18.94,"loc_per_day":93.9,"flagged":false},{"from":"v0.5.0","to":"v0.6.0","loc":2071,"days":0.04,"loc_per_day":49704.0,"flagged":false},{"from":"v0.6.0","to":"v0.6.1","loc":18,"days":0.26,"loc_per_day":68.8,"flagged":false},{"from":"v0.6.1","to":"v0.6.2","loc":20,"days":0.04,"loc_per_day":480.0,"flagged":false},{"from":"v0.6.2","to":"v0.7.0","loc":48,"days":0.04,"loc_per_day":1152.0,"flagged":false},{"from":"v0.7.0","to":"v0.7.1","loc":1,"days":0.04,"loc_per_day":24.0,"flagged":false},{"from":"v0.7.1","to":"v0.8.0","loc":2082,"days":0.6,"loc_per_day":3443.2,"flagged":false},{"from":"v0.8.0","to":"v0.9.0","loc":3810,"days":0.69,"loc_per_day":5543.4,"flagged":false},{"from":"v0.9.0","to":"v0.9.1","loc":347,"days":1.0,"loc_per_day":347.9,"flagged":false},{"from":"v0.9.1","to":"v0.10.0","loc":3466,"days":11.26,"loc_per_day":307.9,"flagged":false},{"from":"v0.10.0","to":"v0.10.1","loc":209,"days":0.17,"loc_per_day":1258.0,"flagged":false},{"from":"v0.10.1","to":"v0.10.2","loc":441,"days":0.04,"loc_per_day":10584.0,"flagged":false},{"from":"v0.10.2","to":"v0.11.0","loc":2245,"days":0.6,"loc_per_day":3758.3,"flagged":false},{"from":"v0.11.0","to":"v0.11.1","loc":75,"days":0.24,"loc_per_day":318.4,"flagged":false},{"from":"v0.11.1","to":"v0.11.2","loc":900,"days":0.08,"loc_per_day":11121.3,"flagged":false},{"from":"v0.11.2","to":"v0.11.3","loc":738,"days":0.29,"loc_per_day":2505.2,"flagged":false},{"from":"v0.11.3","to":"v0.11.4","loc":9,"days":0.33,"loc_per_day":27.1,"flagged":false},{"from":"v0.11.4","to":"v0.12.0","loc":0,"days":0.04,"loc_per_day":0.0,"flagged":false},{"from":"v0.12.0","to":"v0.12.1","loc":86,"days":2.08,"loc_per_day":41.3,"flagged":false},{"from":"v0.12.1","to":"v0.13.0","loc":255,"days":0.43,"loc_per_day":590.8,"flagged":false},{"from":"v0.13.0","to":"v0.13.1","loc":298,"days":0.04,"loc_per_day":7152.0,"flagged":false},{"from":"v0.13.1","to":"v0.13.2","loc":1370,"days":0.93,"loc_per_day":1465.7,"flagged":false},{"from":"v0.13.2","to":"v0.14.0","loc":1878,"days":0.07,"loc_per_day":27913.2,"flagged":false},{"from":"v0.14.0","to":"v0.14.1","loc":214,"days":0.04,"loc_per_day":5136.0,"flagged":false},{"from":"v0.14.1","to":"v0.14.2","loc":369,"days":0.04,"loc_per_day":8856.0,"flagged":false},{"from":"v0.14.2","to":"v0.15.0","loc":426,"days":0.43,"loc_per_day":996.2,"flagged":false},{"from":"v0.15.0","to":"v0.16.0","loc":1070,"days":0.04,"loc_per_day":25680.0,"flagged":false},{"from":"v0.16.0","to":"v0.16.1","loc":58,"days":0.04,"loc_per_day":1392.0,"flagged":false},{"from":"v0.16.1","to":"v0.16.2","loc":80,"days":0.04,"loc_per_day":1920.0,"flagged":false},{"from":"v0.16.2","to":"v0.17.0","loc":384,"days":0.17,"loc_per_day":2291.4,"flagged":false},{"from":"v0.17.0","to":"v0.17.0-debian13.1","loc":2,"days":0.04,"loc_per_day":48.0,"flagged":false},{"from":"v0.17.0-debian13.1","to":"v0.17.0-debian13.2","loc":20,"days":0.07,"loc_per_day":278.2,"flagged":false},{"from":"v0.17.0-debian13.2","to":"v0.17.1","loc":197,"days":0.04,"loc_per_day":4728.0,"flagged":false},{"from":"v0.17.1","to":"v0.17.1-debian13.1","loc":219,"days":0.04,"loc_per_day":5256.0,"flagged":false},{"from":"v0.17.1-debian13.1","to":"v0.18.0","loc":217,"days":0.18,"loc_per_day":1187.6,"flagged":false},{"from":"v0.18.0","to":"v0.18.1","loc":4,"days":0.04,"loc_per_day":96.0,"flagged":false}]},"error":null},{"analyzer":"ai-stylometry","pillar":"ai_provenance","status":"ok","tool_version":null,"metrics":{"lines_scanned":30060.0,"index":0.033,"count:narrated_steps":1.0,"per_kloc:narrated_steps":0.033,"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: * Step 2: asks whether the user has approved yet. On approval, creates the","ref":"backend/src/backup.ts:803","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/backup.ts#L803","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":4.0,"findings_high":2.0,"findings_medium":2.0,"findings_low":0.0,"weighted_findings":4.1,"scanned_lines":29290.0,"parse_errors":5.0},"findings":[{"rule_id":"opengrep/javascript.express.security.injection.tainted-sql-string","severity":"high","message":"Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available [confidence medium]","path":"backend/src/ledger.ts","line":330,"fingerprint":"javascript.express.security.injection.tainted-sql-string:backend/src/ledger.ts:330"},{"rule_id":"opengrep/javascript.express.security.injection.tainted-sql-string","severity":"high","message":"Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available [confidence medium]","path":"backend/src/ledger.ts","line":392,"fingerprint":"javascript.express.security.injection.tainted-sql-string:backend/src/ledger.ts:392"},{"rule_id":"opengrep/javascript.lang.security.audit.detect-non-literal-regexp","severity":"medium","message":"RegExp() called with a `words` function argument, this might allow an attacker to cause a Regular Expression Denial-of-Service (ReDoS) within your application as RegExP blocks the main thread. For this reason, it is recommended to use hardcoded regexes instead. If your regex is run on user-controlle [confidence low]","path":"backend/src/migrate.ts","line":276,"fingerprint":"javascript.lang.security.audit.detect-non-literal-regexp:backend/src/migrate.ts:276"},{"rule_id":"opengrep/bash.lang.security.ifs-tampering","severity":"medium","message":"The special variable IFS affects how splitting takes place when expanding unquoted variables. Don't set it globally. Prefer a dedicated utility such as 'cut' or 'awk' if you need to split input data. If you must use 'read', set IFS locally using e.g. 'IFS=\",\" read -a my_array'. [confidence low]","path":"deploy/lxc-template/build-lxc-template.sh","line":143,"fingerprint":"bash.lang.security.ifs-tampering:deploy/lxc-template/build-lxc-template.sh:143"}],"evidence":[],"data":{"rulesets":["typescript","javascript","bash"]},"error":null},{"analyzer":"sec-deps","pillar":"security","status":"ok","tool_version":"osv-scanner version: 2.7.1","metrics":{"vulnerable_packages":4.0,"vulnerabilities":9.0,"vulns_critical":0.0,"vulns_high":1.0,"vulns_medium":7.0,"vulns_low":1.0,"vulns_unknown":0.0,"penalty":17.0},"findings":[{"rule_id":"osv/GHSA-587h-7wmj-h5pm","severity":"high","message":"vite@8.3.2 (npm) is affected by GHSA-587h-7wmj-h5pm","path":"frontend/package-lock.json","line":null,"fingerprint":"vite@8.3.2 (npm):GHSA-587h-7wmj-h5pm"},{"rule_id":"osv/GHSA-jf9x-2fg2-hx4w","severity":"medium","message":"@sveltejs/adapter-static@4.0.0 (npm) is affected by GHSA-jf9x-2fg2-hx4w","path":"frontend/package-lock.json","line":null,"fingerprint":"@sveltejs/adapter-static@4.0.0 (npm):GHSA-jf9x-2fg2-hx4w"},{"rule_id":"osv/GHSA-mw6w-2fmv-pvw3","severity":"medium","message":"@sveltejs/kit@3.0.0 (npm) is affected by GHSA-mw6w-2fmv-pvw3","path":"frontend/package-lock.json","line":null,"fingerprint":"@sveltejs/kit@3.0.0 (npm):GHSA-mw6w-2fmv-pvw3"},{"rule_id":"osv/GHSA-gcqx-w48m-w2h4","severity":"medium","message":"deepmerge@4.3.1 (npm) is affected by GHSA-gcqx-w48m-w2h4","path":"frontend/package-lock.json","line":null,"fingerprint":"deepmerge@4.3.1 (npm):GHSA-gcqx-w48m-w2h4"},{"rule_id":"osv/GHSA-698v-4r3x-3vcv","severity":"medium","message":"vite@8.3.2 (npm) is affected by GHSA-698v-4r3x-3vcv","path":"frontend/package-lock.json","line":null,"fingerprint":"vite@8.3.2 (npm):GHSA-698v-4r3x-3vcv"},{"rule_id":"osv/GHSA-r825-w8mm-5pxw","severity":"medium","message":"vite@8.3.2 (npm) is affected by GHSA-r825-w8mm-5pxw","path":"frontend/package-lock.json","line":null,"fingerprint":"vite@8.3.2 (npm):GHSA-r825-w8mm-5pxw"},{"rule_id":"osv/GHSA-rq7h-c2jc-7f22","severity":"medium","message":"vite@8.3.2 (npm) is affected by GHSA-rq7h-c2jc-7f22","path":"frontend/package-lock.json","line":null,"fingerprint":"vite@8.3.2 (npm):GHSA-rq7h-c2jc-7f22"},{"rule_id":"osv/GHSA-vfpm-58rq-9qcg","severity":"medium","message":"vite@8.3.2 (npm) is affected by GHSA-vfpm-58rq-9qcg","path":"frontend/package-lock.json","line":null,"fingerprint":"vite@8.3.2 (npm):GHSA-vfpm-58rq-9qcg"},{"rule_id":"osv/GHSA-9jrq-w75r-8gcw","severity":"low","message":"vite@8.3.2 (npm) is affected by GHSA-9jrq-w75r-8gcw","path":"frontend/package-lock.json","line":null,"fingerprint":"vite@8.3.2 (npm):GHSA-9jrq-w75r-8gcw"}],"evidence":[],"data":{"ecosystems":["npm"]},"error":null},{"analyzer":"sec-actions","pillar":"security","status":"ok","tool_version":"zizmor 1.32.0","metrics":{"workflows":1.0,"findings":4.0,"findings_high":3.0,"findings_medium":0.0,"findings_low":1.0,"penalty":27.9},"findings":[{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/release.yml","line":56,"fingerprint":"unpinned-uses:.github/workflows/release.yml:56"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/release.yml","line":65,"fingerprint":"unpinned-uses:.github/workflows/release.yml:65"},{"rule_id":"zizmor/cache-poisoning","severity":"high","message":"runtime artifacts potentially vulnerable to a cache poisoning attack [confidence low]","path":".github/workflows/release.yml","line":65,"fingerprint":"cache-poisoning:.github/workflows/release.yml:65"},{"rule_id":"zizmor/artipacked","severity":"low","message":"credential persistence through GitHub Actions artifacts [confidence low]","path":".github/workflows/release.yml","line":56,"fingerprint":"artipacked:.github/workflows/release.yml:56"}],"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":1.0,"check:lockfiles":1.0,"signed_commit_share":1.0,"unpinned_manifests":0.0},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-distribution","pillar":"security","status":"ok","tool_version":null,"metrics":{"signals":2.0,"binary_assets":10.0,"suspicious":0.0},"findings":[],"evidence":[{"kind":"binary-release-asset","description":"release v0.18.1 ships ledger-v0.18.1-linux-amd64.tar.gz (1 downloads)","ref":"ledger-v0.18.1-linux-amd64.tar.gz","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.18.1/ledger-v0.18.1-linux-amd64.tar.gz","weight":0.0},{"kind":"binary-release-asset","description":"release v0.18.0 ships ledger-v0.18.0-linux-amd64.tar.gz (1 downloads)","ref":"ledger-v0.18.0-linux-amd64.tar.gz","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.18.0/ledger-v0.18.0-linux-amd64.tar.gz","weight":0.0},{"kind":"binary-release-asset","description":"release v0.17.1 ships ledger-v0.17.1-linux-amd64.tar.gz (1 downloads)","ref":"ledger-v0.17.1-linux-amd64.tar.gz","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.1/ledger-v0.17.1-linux-amd64.tar.gz","weight":0.0},{"kind":"binary-release-asset","description":"release v0.17.1-debian13.1 ships ledger-v0.17.1-debian13.1-linux-amd64.tar.gz (1 downloads)","ref":"ledger-v0.17.1-debian13.1-linux-amd64.tar.gz","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.1-debian13.1/ledger-v0.17.1-debian13.1-linux-amd64.tar.gz","weight":0.0},{"kind":"binary-release-asset","description":"release v0.17.0 ships ledger-v0.17.0-linux-amd64.tar.gz (1 downloads)","ref":"ledger-v0.17.0-linux-amd64.tar.gz","url":"https://github.com/mastifdogo/Bookeeping/releases/download/v0.17.0/ledger-v0.17.0-linux-amd64.tar.gz","weight":0.0},{"kind":"readme-download-lure","description":"gives an archive password","ref":"README.md","url":null,"weight":0.0}],"data":{"signals":["binary-release-assets","readme-download-lure"],"suspicious":false,"unusual_traction":false,"metadata":true},"error":null},{"analyzer":"qual-complexity","pillar":"quality","status":"ok","tool_version":"lizard 1.25.1","metrics":{"functions":1457.0,"function_nloc":10562.0,"mean_ccn":3.44,"p90_ccn":7.0,"complex_functions":47.0,"long_functions":5.0,"many_param_functions":1.0,"risky_nloc_share":0.2182},"findings":[],"evidence":[{"kind":"complex-function","description":"buildPlan in backend/src/migrate.ts: complexity 112, 179 lines","ref":"backend/src/migrate.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/migrate.ts#L686","weight":1.0},{"kind":"complex-function","description":"callProvider in backend/src/llm.ts: complexity 61, 100 lines","ref":"backend/src/llm.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/llm.ts#L346","weight":1.0},{"kind":"complex-function","description":"parseSettingsSpec in backend/src/module-settings.ts: complexity 59, 58 lines","ref":"backend/src/module-settings.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/module-settings.ts#L40","weight":0.9833333333333333},{"kind":"complex-function","description":"cleanMapping in backend/src/migrate.ts: complexity 52, 72 lines","ref":"backend/src/migrate.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/migrate.ts#L596","weight":0.8666666666666667},{"kind":"complex-function","description":"runBackup in backend/src/backup.ts: complexity 44, 120 lines","ref":"backend/src/backup.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/backup.ts#L1108","weight":0.7333333333333333},{"kind":"complex-function","description":"performRestore in backend/src/restore.ts: complexity 43, 133 lines","ref":"backend/src/restore.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/restore.ts#L375","weight":0.7166666666666667},{"kind":"complex-function","description":"(anonymous) in backend/src/llm.ts: complexity 41, 41 lines","ref":"backend/src/llm.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/llm.ts#L175","weight":0.6833333333333333},{"kind":"complex-function","description":"applyConfigChange in backend/src/backup.ts: complexity 40, 44 lines","ref":"backend/src/backup.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/backup.ts#L297","weight":0.6666666666666666},{"kind":"complex-function","description":"decodeUserBody in backend/src/http.ts: complexity 38, 29 lines","ref":"backend/src/http.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/http.ts#L547","weight":0.6333333333333333},{"kind":"complex-function","description":"resolve in backend/src/migrate.ts: complexity 37, 32 lines","ref":"backend/src/migrate.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/migrate.ts#L714","weight":0.6166666666666667}],"data":{},"error":null},{"analyzer":"qual-duplication","pillar":"quality","status":"ok","tool_version":"repotrust-dup-w6","metrics":{"compared_lines":23571.0,"duplicated_lines":2176.0,"duplicated_share":0.0923,"files":158.0},"findings":[],"evidence":[{"kind":"duplicate-code","description":"6+ duplicated lines: backend/src/accounts.ts:36 and backend/src/types.ts:35","ref":"backend/src/accounts.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/accounts.ts#L36","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: backend/src/entities.ts:17 and frontend/src/lib/api/schema.d.ts:1669","ref":"backend/src/entities.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/entities.ts#L17","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: backend/src/http.ts:1382 and backend/src/http.ts:1429","ref":"backend/src/http.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/http.ts#L1382","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: backend/src/ledger.ts:316 and backend/src/ledger.ts:378","ref":"backend/src/ledger.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/ledger.ts#L316","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: backend/src/llm.ts:70 and frontend/src/routes/settings/llm/+page.svelte:18","ref":"backend/src/llm.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/llm.ts#L70","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: backend/src/reconcile.ts:31 and backend/src/types.ts:149","ref":"backend/src/reconcile.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/backend/src/reconcile.ts#L31","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: deploy/create-org-db.sh:14 and deploy/migrate-db.sh:16","ref":"deploy/create-org-db.sh","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/deploy/create-org-db.sh#L14","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: deploy/create-org-db.sh:20 and deploy/setup-db.sh:32","ref":"deploy/create-org-db.sh","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/deploy/create-org-db.sh#L20","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: frontend/src/lib/api/schema.d.ts:8 and frontend/src/lib/api/schema.d.ts:25","ref":"frontend/src/lib/api/schema.d.ts","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/frontend/src/lib/api/schema.d.ts#L8","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: frontend/src/lib/components/ExpenseForm.svelte:136 and frontend/src/routes/entities/+page.svelte:154","ref":"frontend/src/lib/components/ExpenseForm.svelte","url":"https://github.com/mastifdogo/Bookeeping/blob/870cdaee1fe616d3f567bd79f2f4f3e7a6634681/frontend/src/lib/components/ExpenseForm.svelte#L136","weight":0.3}],"data":{},"error":null},{"analyzer":"qual-lint","pillar":"quality","status":"ok","tool_version":"opengrep 1.33.1; rules f1d2b562b414","metrics":{"findings":34.0,"weighted_findings":25.5,"scanned_lines":29290.0,"category:correctness":34.0},"findings":[{"rule_id":"opengrep/typescript.lang.correctness.useless-ternary","severity":"high","message":"It looks like no matter how typeof a.content === \"string\" is evaluated, this expression returns Buffer.from(a.content).toString(\"base64\"). This is probably a copy-paste error.","path":"backend/src/gmail.ts","line":437,"fingerprint":"typescript.lang.correctness.useless-ternary:backend/src/gmail.ts:437"},{"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":".claude/skills/ledger-module/scripts/check-module.ts","line":174,"fingerprint":"javascript.lang.correctness.no-replaceall:.claude/skills/ledger-module/scripts/check-module.ts:174"},{"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":"backend/src/backup.ts","line":372,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/backup.ts:372"},{"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":"backend/src/backup.ts","line":394,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/backup.ts:394"},{"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":"backend/src/backup.ts","line":642,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/backup.ts:642"},{"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":"backend/src/backup.ts","line":959,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/backup.ts:959"},{"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":"backend/src/backup.ts","line":986,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/backup.ts:986"},{"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":"backend/src/csv.ts","line":22,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/csv.ts:22"},{"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":"backend/src/migrate.ts","line":699,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/migrate.ts:699"},{"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":"backend/src/module-host.ts","line":145,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/module-host.ts:145"},{"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":"backend/src/module-import.ts","line":131,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/module-import.ts:131"},{"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":"backend/src/module-installer.ts","line":56,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/module-installer.ts:56"},{"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":"backend/src/module-installer.ts","line":257,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/module-installer.ts:257"},{"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":"backend/src/module-installer.ts","line":258,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/module-installer.ts:258"},{"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":"backend/src/restore.ts","line":254,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/restore.ts:254"},{"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":"backend/src/restore.ts","line":255,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/restore.ts:255"},{"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":"backend/src/search.ts","line":34,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/search.ts:34"},{"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":"backend/src/updater.ts","line":454,"fingerprint":"javascript.lang.correctness.no-replaceall:backend/src/updater.ts:454"},{"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":"frontend/src/lib/money.ts","line":20,"fingerprint":"javascript.lang.correctness.no-replaceall:frontend/src/lib/money.ts:20"},{"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":"frontend/src/lib/money.ts","line":39,"fingerprint":"javascript.lang.correctness.no-replaceall:frontend/src/lib/money.ts:39"},{"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":".claude/skills/ledger-module/scripts/check-module.ts","line":231,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:.claude/skills/ledger-module/scripts/check-module.ts:231"},{"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":".claude/skills/ledger-module/scripts/check-module.ts","line":231,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:.claude/skills/ledger-module/scripts/check-module.ts:231"},{"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":".claude/skills/ledger-module/scripts/check-module.ts","line":232,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:.claude/skills/ledger-module/scripts/check-module.ts:232"},{"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":".claude/skills/ledger-module/scripts/check-module.ts","line":232,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:.claude/skills/ledger-module/scripts/check-module.ts:232"},{"rule_id":"opengrep/javascript.lang.correctness.useless-assignment","severity":"low","message":"`hit` is assigned twice; the first assignment is useless","path":"backend/src/module-import.ts","line":133,"fingerprint":"javascript.lang.correctness.useless-assignment:backend/src/module-import.ts:133"},{"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":"backend/src/module-settings.ts","line":88,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:backend/src/module-settings.ts:88"},{"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":"backend/src/module-settings.ts","line":88,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:backend/src/module-settings.ts:88"},{"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":"backend/src/search.ts","line":40,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:backend/src/search.ts:40"},{"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":"backend/src/search.ts","line":40,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:backend/src/search.ts:40"},{"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":"backend/src/search.ts","line":40,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:backend/src/search.ts:40"},{"rule_id":"opengrep/bash.lang.correctness.unquoted-variable-expansion-in-command","severity":"low","message":"Variable expansions must be double-quoted so as to prevent being split into multiple pieces according to whitespace or whichever separator is specified by the IFS variable. If you really wish to split the variable's contents, you may use a variable that starts with an underscore e.g. $_X instead of ","path":"deploy/create-org-db.sh","line":30,"fingerprint":"bash.lang.correctness.unquoted-variable-expansion-in-command:deploy/create-org-db.sh:30"},{"rule_id":"opengrep/bash.lang.correctness.unquoted-command-substitution-in-command","severity":"low","message":"The result of command substitution $(...) or `...`, if unquoted, is split on whitespace or other separators specified by the IFS variable. You should surround it with double quotes to avoid splitting the result.","path":"deploy/install.sh","line":140,"fingerprint":"bash.lang.correctness.unquoted-command-substitution-in-command:deploy/install.sh:140"},{"rule_id":"opengrep/bash.lang.correctness.unquoted-command-substitution-in-command","severity":"low","message":"The result of command substitution $(...) or `...`, if unquoted, is split on whitespace or other separators specified by the IFS variable. You should surround it with double quotes to avoid splitting the result.","path":"deploy/install.sh","line":140,"fingerprint":"bash.lang.correctness.unquoted-command-substitution-in-command:deploy/install.sh:140"},{"rule_id":"opengrep/bash.lang.correctness.unquoted-variable-expansion-in-command","severity":"low","message":"Variable expansions must be double-quoted so as to prevent being split into multiple pieces according to whitespace or whichever separator is specified by the IFS variable. If you really wish to split the variable's contents, you may use a variable that starts with an underscore e.g. $_X instead of ","path":"deploy/setup-db.sh","line":49,"fingerprint":"bash.lang.correctness.unquoted-variable-expansion-in-command:deploy/setup-db.sh:49"}],"evidence":[],"data":{},"error":null},{"analyzer":"qual-testing","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:has_tests":1.0,"check:test_ratio":0.3081,"check:ci_present":1.0,"check:ci_runs_tests":1.0,"check:ci_runs_lint":0.0,"check:tests_cochange":1.0,"test_lines":4631.0,"source_lines":30060.0,"test_ratio":0.1541,"ci_files":1.0,"cochange_share":0.7414,"cochange_commits":58.0},"findings":[],"evidence":[{"kind":"ci","description":"CI config: .github/workflows/release.yml","ref":".github/workflows/release.yml","url":null,"weight":0.0},{"kind":"ci","description":"CI runs tests (make test)","ref":null,"url":null,"weight":0.0}],"data":{"test_commands":["make test"],"lint_commands":[]},"error":null},{"analyzer":"qual-docs","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:readme":1.0,"check:license":0.0,"check:contributing":0.0,"check:changelog":0.0,"readme_lines":349.0},"findings":[],"evidence":[{"kind":"docs","description":"README.md","ref":"README.md","url":null,"weight":0.0}],"data":{},"error":null},{"analyzer":"qual-type-safety","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:strict_config":1.0,"check:low_escape_density":1.0,"escapes":26.0,"escapes_per_kloc":1.273},"findings":[],"evidence":[{"kind":"typing","description":"TypeScript strict type checking: backend/tsconfig.json","ref":"backend/tsconfig.json","url":null,"weight":0.0}],"data":{},"error":null},{"analyzer":"x-blame","pillar":"ai_provenance","status":"ok","tool_version":"git-blame","metrics":{"ai_lines":30060.0,"other_lines":0.0,"files_blamed":158.0,"blame_failures":0.0,"quality:ai_findings":34.0,"quality:ai_per_kloc":1.131,"quality:other_findings":0.0,"security:ai_findings":4.0,"security:ai_per_kloc":0.133,"security:other_findings":0.0},"findings":[],"evidence":[],"data":{"sampled":false,"comparable":false},"error":null}],"flags":[]}