{"schema_version":"2","scorer_version":"0.1.0","scoring_version":"prov-5+qual-2+sec-2","generated_at":"2026-11-14T14:52:02.387893Z","repo":{"ref":{"host":"github.com","owner":"aileo","name":"pensa"},"default_branch":"main","clone_url":"https://github.com/aileo/pensa.git","html_url":"https://github.com/aileo/pensa","description":"Organize family gifts without carrying it all in your head. Everyone's wishes, the dates coming up and who gives what live in one place — and nobody ever sees what is meant for them.","stars":0,"forks":0,"is_fork":false,"is_archived":false,"is_private":false,"size_kb":3475,"primary_language":"TypeScript","license_spdx":"MIT","created_at":"2026-09-29T16:29:27Z","pushed_at":"2026-10-31T20:43:38Z","security_policy_url":null,"distribution":{"owner_created_at":"2014-06-18T19:07:57Z","owner_type":"User","release_assets":[]}},"commit_sha":"f10cc33fc364c99149236d17184a4acf18e452de","profile":{"lines_by_language":{"TypeScript":7615,"JavaScript":329,"SQL":170},"files_by_category":{"source":65,"config":33,"binary":26,"docs":16,"other":8,"test":8,"generated":4},"source_lines":6247,"test_lines":1867},"pillars":{"ai_provenance":{"score":100.0,"confidence":0.85,"coverage":1.0,"label":"explicit","breakdown":{"attributed_share":1.0,"suspected_share":0.0,"estimated_share":1.0,"ai_artifacts":0.0,"flagged_work_units":1.0,"flagged_releases":0.0,"style_index":0.08},"summary":"Explicit AI attribution on 100% of first-party code added; an estimated 100% including velocity signals."},"quality":{"score":80.5,"confidence":0.9,"coverage":1.0,"label":"strong","breakdown":{"complexity":61.5,"duplication":88.3,"lint":79.8,"testing":79.9,"docs":100.0,"type_safety":100.0,"process":null},"summary":"Code quality is strong: test-to-source ratio 0.30, CI runs tests; 16% of function code in complex or long functions; 2% duplicated lines. Weakest area: complexity."},"security":{"score":55.4,"confidence":0.85,"coverage":1.0,"label":"weak","breakdown":{"secrets":100.0,"sast":87.6,"dependencies":35.0,"ci_actions":2.1,"posture":0.0,"scorecard":null},"summary":"Security posture is weak: 31 known vulnerabilities in 11 dependencies; 1 high-severity SAST findings; 18 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":30.0,"checked":30.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":62.0,"attributed_commits":61.0,"attributed_commit_share":0.9838709677419355,"effective_loc":11404.0,"attributed_loc":11404.0,"attributed_loc_share":1.0,"tools_detected":1.0},"findings":[],"evidence":[{"kind":"attribution-summary","description":"GitHub Copilot coding agent: 61 attributed commits, 11,404 lines added","ref":null,"url":null,"weight":1.0},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"f10cc33fc364c99149236d17184a4acf18e452de","url":"https://github.com/aileo/pensa/commit/f10cc33fc364c99149236d17184a4acf18e452de","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"6eee32e8380ffdca9f8bb939efa744c5a5bd4fe5","url":"https://github.com/aileo/pensa/commit/6eee32e8380ffdca9f8bb939efa744c5a5bd4fe5","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"682fce4cfb44336d4fdc6de3e3fcb67f299e98cc","url":"https://github.com/aileo/pensa/commit/682fce4cfb44336d4fdc6de3e3fcb67f299e98cc","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"a53d036c1cbb5b92c3236db5aa554161fbc4ee15","url":"https://github.com/aileo/pensa/commit/a53d036c1cbb5b92c3236db5aa554161fbc4ee15","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"ebe6fcba28e18676942f65459744dfec317d0a50","url":"https://github.com/aileo/pensa/commit/ebe6fcba28e18676942f65459744dfec317d0a50","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"6becadea6ceee35eebf0a0a3db43ef05b840b6f8","url":"https://github.com/aileo/pensa/commit/6becadea6ceee35eebf0a0a3db43ef05b840b6f8","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"4fad5342db8c1d5683d7a5ed453666d7965b6052","url":"https://github.com/aileo/pensa/commit/4fad5342db8c1d5683d7a5ed453666d7965b6052","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"00659c203982176ae74934d18232e73ea0044932","url":"https://github.com/aileo/pensa/commit/00659c203982176ae74934d18232e73ea0044932","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"f7ab5405c065550adce1b6dba8865d3c4e2c1096","url":"https://github.com/aileo/pensa/commit/f7ab5405c065550adce1b6dba8865d3c4e2c1096","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"bf7a9d18a41414ac354cfe5ae07d1640efef74f8","url":"https://github.com/aileo/pensa/commit/bf7a9d18a41414ac354cfe5ae07d1640efef74f8","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"b1cbf34a535fe034e62c40b088cff462771ea77b","url":"https://github.com/aileo/pensa/commit/b1cbf34a535fe034e62c40b088cff462771ea77b","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"a520caa0d8625baf56da0064084094e9e045deca","url":"https://github.com/aileo/pensa/commit/a520caa0d8625baf56da0064084094e9e045deca","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"3684084f457a5a6c2e1e3e5f6df16187571659c9","url":"https://github.com/aileo/pensa/commit/3684084f457a5a6c2e1e3e5f6df16187571659c9","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"cf5d282ca66e3d553497579f55e2219c4906f8bb","url":"https://github.com/aileo/pensa/commit/cf5d282ca66e3d553497579f55e2219c4906f8bb","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"e6f72aac3127712351fc234eb84538d558fc6114","url":"https://github.com/aileo/pensa/commit/e6f72aac3127712351fc234eb84538d558fc6114","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"3071a57a2b6ade7c7976cc9b499999b99e6dd785","url":"https://github.com/aileo/pensa/commit/3071a57a2b6ade7c7976cc9b499999b99e6dd785","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"8c575a76f4c75a92dc1fce851662fc3a2a2d5869","url":"https://github.com/aileo/pensa/commit/8c575a76f4c75a92dc1fce851662fc3a2a2d5869","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"5a22a1cd5d208a2338bb1cb65672769ab89b23cc","url":"https://github.com/aileo/pensa/commit/5a22a1cd5d208a2338bb1cb65672769ab89b23cc","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"e59cf96e3218c4673948a7883d0b675a2d844719","url":"https://github.com/aileo/pensa/commit/e59cf96e3218c4673948a7883d0b675a2d844719","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"bb5d19d662e9c765c2068ce014c6109815a770e2","url":"https://github.com/aileo/pensa/commit/bb5d19d662e9c765c2068ce014c6109815a770e2","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"b031fa9a5ffb52f1c97b239f0fc193aa927f17ed","url":"https://github.com/aileo/pensa/commit/b031fa9a5ffb52f1c97b239f0fc193aa927f17ed","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"15b43fb28b489987549f1e1ab2cc83f7299bb500","url":"https://github.com/aileo/pensa/commit/15b43fb28b489987549f1e1ab2cc83f7299bb500","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"afa2301ae8547de1675359525de7b02e99e2926e","url":"https://github.com/aileo/pensa/commit/afa2301ae8547de1675359525de7b02e99e2926e","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"7212bb9aca46fa3fc5aab27a8aa5cd7fa84d91e6","url":"https://github.com/aileo/pensa/commit/7212bb9aca46fa3fc5aab27a8aa5cd7fa84d91e6","weight":0.9},{"kind":"attributed-commit","description":"GitHub Copilot coding agent: trailer 'Co-authored-by: Copilot'","ref":"b7faf9f1089449d1ecf83445a8b54876fdff2e78","url":"https://github.com/aileo/pensa/commit/b7faf9f1089449d1ecf83445a8b54876fdff2e78","weight":0.9}],"data":{"attributed_loc_by_commit":{"c2f008fffdcf7e5dc576433db9c7046ec00b4974":0,"2061305ddc95cad300e6a78a9dd0b5a78b175e42":1520,"1d007eb46f6a2ce9d5e954523c7f1975df351bb3":98,"ae5fb7aa9f236a386d1a03d78a95e2b0d0de9876":148,"3542c89b98743ec5e09ff9df93237512298278bb":147,"e42e35afcaa55d7fe7eb042076d41f3c5461d2a9":45,"4a6095990a3638fb347f46e769e3723a77ce31b9":518,"555474750d971b23028f1cb29a78a8c75190cb6e":47,"1579692dbdf3f5fc3ac7d0fb09c363dfbfb875be":0,"46f9224a5bedcee8095c3fc78ad3d8780b9bfbac":399,"8af9f727a80063eedf72b63d723915a25e01bc99":106,"3f17fe6ede81997c13be21d483c613b2d52418a3":249,"e44b6b1bf3df8220277cf1da1fbc06ace927927d":86,"065deaaa7768da3532557684c3c00cd59cdb1123":41,"45234bf5dca590eca6f11446163abef1063cf8f2":250,"83225238ddb05cebfd01663d826e3b1d166d1d58":311,"429786edc904420def2ef7b9c69e41a16c7976c8":108,"959cc37ed9289503508987a8d870f51ce7b8b04d":124,"94357b6274fd9869d7be645b8d9e2aa8a84661ab":68,"f3f9d6366602c2f90150da783de4f4d113693228":0,"e05766226e6f232061173e6bb6c04572c740637b":0,"9c1997f9a81a8ad0ae236c841fec04ee09aa42d8":0,"d7488789bca4a30c836bb7d0ae24d545288a4901":0,"27c08b8a05173e3127f537853781075cb0725780":137,"e58acac6820adfd2bad9a8e33009631b19b61a74":0,"eb69ce0b720b2972a512f66e75bef4d28b26a095":214,"8b46bba2f1c3453a47cdbd0486b733ece4a706c8":0,"100a69b731f519e6997473a11dc978e0103ede8e":483,"88d847fb942ddedcb7c031a132acaa30a5b30bc8":0,"6042b5a1e14989c884f52ee391e4502e22cee2fc":190,"5c50de0e99bf8d08e6203e9ef6bdc957e0dfd491":23,"ba662e9104f56c151f8ba4f1509386e0ee84fc3f":0,"d95c5625eb9df2a75ec7fe72d201313239e54f74":125,"c9ae42d7b0597ea59e90b52d312a9a0fcc43cd5f":0,"7b0d0905d9681b1634e01905f0e185beeedb41fd":0,"8968c81e4213ae9643a43a63c416890474b0d3d1":2265,"b7faf9f1089449d1ecf83445a8b54876fdff2e78":720,"7212bb9aca46fa3fc5aab27a8aa5cd7fa84d91e6":76,"afa2301ae8547de1675359525de7b02e99e2926e":6,"15b43fb28b489987549f1e1ab2cc83f7299bb500":13,"b031fa9a5ffb52f1c97b239f0fc193aa927f17ed":4,"bb5d19d662e9c765c2068ce014c6109815a770e2":16,"e59cf96e3218c4673948a7883d0b675a2d844719":1,"5a22a1cd5d208a2338bb1cb65672769ab89b23cc":29,"8c575a76f4c75a92dc1fce851662fc3a2a2d5869":171,"3071a57a2b6ade7c7976cc9b499999b99e6dd785":308,"e6f72aac3127712351fc234eb84538d558fc6114":216,"cf5d282ca66e3d553497579f55e2219c4906f8bb":0,"3684084f457a5a6c2e1e3e5f6df16187571659c9":216,"a520caa0d8625baf56da0064084094e9e045deca":124,"b1cbf34a535fe034e62c40b088cff462771ea77b":45,"bf7a9d18a41414ac354cfe5ae07d1640efef74f8":385,"f7ab5405c065550adce1b6dba8865d3c4e2c1096":155,"00659c203982176ae74934d18232e73ea0044932":81,"4fad5342db8c1d5683d7a5ed453666d7965b6052":0,"6becadea6ceee35eebf0a0a3db43ef05b840b6f8":282,"ebe6fcba28e18676942f65459744dfec317d0a50":208,"a53d036c1cbb5b92c3236db5aa554161fbc4ee15":0,"682fce4cfb44336d4fdc6de3e3fcb67f299e98cc":411,"6eee32e8380ffdca9f8bb939efa744c5a5bd4fe5":73,"f10cc33fc364c99149236d17184a4acf18e452de":162},"tools":{"github-copilot":{"name":"GitHub Copilot coding agent","commits":61,"loc":11404,"first_seen":1790699372,"last_seen":1793479412}},"monthly":{"2026-09":{"loc":5437,"attributed_loc":5437},"2026-10":{"loc":5967,"attributed_loc":5967}}},"error":null},{"analyzer":"ai-artifacts","pillar":"ai_provenance","status":"ok","tool_version":"signatures-v1","metrics":{"artifacts":0.0,"workflow_agents":0.0,"tools_configured":0.0},"findings":[],"evidence":[],"data":{"artifacts":[],"workflows":[],"tools":[]},"error":null},{"analyzer":"ai-velocity","pillar":"ai_provenance","status":"ok","tool_version":"prov-4","metrics":{"work_units":25.0,"flagged_units":1.0,"pre_ai_era_bursts":0.0,"pre_ai_era_measured_loc":0.0,"pre_ai_era_burst_loc":0.0,"measured_loc":11404.0,"flagged_loc":2265.0,"flagged_loc_share":0.19861452122062434,"max_loc_per_hour":770.0,"median_loc_per_hour":226.1115663410022,"pr_timed_units":14.0,"excluded_import_loc":0.0},"findings":[],"evidence":[{"kind":"velocity-burst","description":"2,265 lines of first-party code in ~4.0h (566 lines/hour, 1 commit session)","ref":"8968c81e4213ae9643a43a63c416890474b0d3d1","url":"https://github.com/aileo/pensa/commit/8968c81e4213ae9643a43a63c416890474b0d3d1","weight":0.169875}],"data":{"flagged_loc_by_commit":{"8968c81e4213ae9643a43a63c416890474b0d3d1":2265},"excluded_import_commits":[]},"error":null},{"analyzer":"ai-release-velocity","pillar":"ai_provenance","status":"ok","tool_version":"prov-4","metrics":{"releases":10.0,"flagged_releases":0.0,"max_loc_per_day":11760.0},"findings":[],"evidence":[],"data":{"releases":[{"from":"v0.1.0","to":"v0.2.0","loc":137,"days":0.04,"loc_per_day":3288.0,"flagged":false},{"from":"v0.2.0","to":"v0.3.0","loc":697,"days":0.07,"loc_per_day":10526.3,"flagged":false},{"from":"v0.3.0","to":"v0.4.0","loc":213,"days":0.04,"loc_per_day":5112.0,"flagged":false},{"from":"v0.4.0","to":"v0.5.0","loc":125,"days":0.08,"loc_per_day":1636.6,"flagged":false},{"from":"v0.5.0","to":"v0.6.0","loc":3825,"days":7.63,"loc_per_day":501.4,"flagged":false},{"from":"v0.6.0","to":"v0.7.0","loc":1006,"days":23.04,"loc_per_day":43.7,"flagged":false},{"from":"v0.7.0","to":"v0.8.0","loc":490,"days":0.04,"loc_per_day":11760.0,"flagged":false},{"from":"v0.8.0","to":"v0.8.1","loc":411,"days":0.05,"loc_per_day":9098.2,"flagged":false},{"from":"v0.8.1","to":"v0.9.0","loc":73,"days":0.19,"loc_per_day":387.0,"flagged":false},{"from":"v0.9.0","to":"v0.9.1","loc":162,"days":0.12,"loc_per_day":1389.4,"flagged":false}]},"error":null},{"analyzer":"ai-stylometry","pillar":"ai_provenance","status":"ok","tool_version":null,"metrics":{"lines_scanned":6247.0,"index":0.08,"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":1.0,"per_kloc:emoji_in_code":0.16,"files:emoji_in_code":1.0,"count:assistant_voice":0.0,"per_kloc:assistant_voice":0.0,"files:assistant_voice":0.0},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-secrets","pillar":"security","status":"ok","tool_version":"gitleaks 8.30.1","metrics":{"secrets_current":0.0,"secrets_history":0.0,"secrets_nonprod":0.0,"secrets_low_confidence":0.0},"findings":[],"evidence":[],"data":{},"error":null},{"analyzer":"sec-sast","pillar":"security","status":"ok","tool_version":"opengrep 1.33.1; rules f1d2b562b414","metrics":{"findings":3.0,"findings_high":1.0,"findings_medium":2.0,"findings_low":0.0,"weighted_findings":2.3,"scanned_lines":6077.0,"parse_errors":2.0},"findings":[{"rule_id":"opengrep/dockerfile.security.missing-user","severity":"high","message":"By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'. [confidence medium]","path":"apps/web/Dockerfile","line":18,"fingerprint":"dockerfile.security.missing-user:apps/web/Dockerfile:18"},{"rule_id":"opengrep/javascript.jquery.security.audit.jquery-insecure-selector","severity":"medium","message":"User controlled data in a `$(...)` is an anti-pattern that can lead to XSS vulnerabilities [confidence low]","path":"apps/api/src/metadata.ts","line":311,"fingerprint":"javascript.jquery.security.audit.jquery-insecure-selector:apps/api/src/metadata.ts:311"},{"rule_id":"opengrep/javascript.lang.security.html-in-template-string","severity":"medium","message":"This template literal looks like HTML and has interpolated variables. These variables are not HTML-encoded by default. If the variables contain HTML tags, these may be interpreted by the browser, resulting in cross-site scripting (XSS). [confidence low]","path":"site/.vitepress/config.ts","line":76,"fingerprint":"javascript.lang.security.html-in-template-string:site/.vitepress/config.ts:76"}],"evidence":[],"data":{"rulesets":["typescript","javascript","dockerfile"]},"error":null},{"analyzer":"sec-deps","pillar":"security","status":"ok","tool_version":"osv-scanner version: 2.7.1","metrics":{"vulnerable_packages":11.0,"vulnerabilities":31.0,"vulns_critical":0.0,"vulns_high":9.0,"vulns_medium":20.0,"vulns_low":2.0,"vulns_unknown":0.0,"penalty":63.0},"findings":[{"rule_id":"osv/GHSA-27r3-jxmh-p828","severity":"high","message":"body-parser@2.3.0 (npm) is affected by GHSA-27r3-jxmh-p828","path":"apps/api/package-lock.json","line":null,"fingerprint":"body-parser@2.3.0 (npm):GHSA-27r3-jxmh-p828"},{"rule_id":"osv/GHSA-68fv-2mgg-jv7q","severity":"high","message":"source-map-js@1.2.1 (npm) is affected by GHSA-68fv-2mgg-jv7q; also in apps/web/package-lock.json","path":"apps/api/package-lock.json","line":null,"fingerprint":"source-map-js@1.2.1 (npm):GHSA-68fv-2mgg-jv7q"},{"rule_id":"osv/GHSA-2m5v-pch6-74hx","severity":"high","message":"undici@7.30.0 (npm) is affected by GHSA-2m5v-pch6-74hx","path":"apps/api/package-lock.json","line":null,"fingerprint":"undici@7.30.0 (npm):GHSA-2m5v-pch6-74hx"},{"rule_id":"osv/GHSA-4w7w-5xrc-9h26","severity":"high","message":"undici@7.30.0 (npm) is affected by GHSA-4w7w-5xrc-9h26","path":"apps/api/package-lock.json","line":null,"fingerprint":"undici@7.30.0 (npm):GHSA-4w7w-5xrc-9h26"},{"rule_id":"osv/GHSA-qrxm-fqhp-jwvm","severity":"high","message":"undici@7.30.0 (npm) is affected by GHSA-qrxm-fqhp-jwvm","path":"apps/api/package-lock.json","line":null,"fingerprint":"undici@7.30.0 (npm):GHSA-qrxm-fqhp-jwvm"},{"rule_id":"osv/GHSA-xjj6-f33q-929c","severity":"high","message":"undici@7.30.0 (npm) is affected by GHSA-xjj6-f33q-929c","path":"apps/api/package-lock.json","line":null,"fingerprint":"undici@7.30.0 (npm):GHSA-xjj6-f33q-929c"},{"rule_id":"osv/GHSA-587h-7wmj-h5pm","severity":"high","message":"vite@8.3.1 (npm) is affected by GHSA-587h-7wmj-h5pm; also in apps/web/package-lock.json","path":"apps/api/package-lock.json","line":null,"fingerprint":"vite@8.3.1 (npm):GHSA-587h-7wmj-h5pm"},{"rule_id":"osv/GHSA-mrhx-c7xc-m3w5","severity":"high","message":"zod@4.6.5 (npm) is affected by GHSA-mrhx-c7xc-m3w5","path":"apps/api/package-lock.json","line":null,"fingerprint":"zod@4.6.5 (npm):GHSA-mrhx-c7xc-m3w5"},{"rule_id":"osv/GHSA-587h-7wmj-h5pm","severity":"high","message":"vite@5.4.21 (npm) is affected by GHSA-587h-7wmj-h5pm","path":"site/package-lock.json","line":null,"fingerprint":"vite@5.4.21 (npm):GHSA-587h-7wmj-h5pm"},{"rule_id":"osv/GHSA-qxg6-89mg-rqv8","severity":"medium","message":"@vitest/mocker@5.0.2 (npm) is affected by GHSA-qxg6-89mg-rqv8","path":"apps/api/package-lock.json","line":null,"fingerprint":"@vitest/mocker@5.0.2 (npm):GHSA-qxg6-89mg-rqv8"},{"rule_id":"osv/GHSA-xp26-3454-mjgp","severity":"medium","message":"@vitest/mocker@5.0.2 (npm) is affected by GHSA-xp26-3454-mjgp","path":"apps/api/package-lock.json","line":null,"fingerprint":"@vitest/mocker@5.0.2 (npm):GHSA-xp26-3454-mjgp"},{"rule_id":"osv/GHSA-rxp7-6hxx-x8q5","severity":"medium","message":"ip-address@10.7.2 (npm) is affected by GHSA-rxp7-6hxx-x8q5","path":"apps/api/package-lock.json","line":null,"fingerprint":"ip-address@10.7.2 (npm):GHSA-rxp7-6hxx-x8q5"},{"rule_id":"osv/GHSA-g3hv-75wg-m249","severity":"medium","message":"minimatch@10.2.6 (npm) is affected by GHSA-g3hv-75wg-m249","path":"apps/api/package-lock.json","line":null,"fingerprint":"minimatch@10.2.6 (npm):GHSA-g3hv-75wg-m249"},{"rule_id":"osv/GHSA-6pq8-jhm2-2vcw","severity":"medium","message":"qs@6.16.0 (npm) is affected by GHSA-6pq8-jhm2-2vcw","path":"apps/api/package-lock.json","line":null,"fingerprint":"qs@6.16.0 (npm):GHSA-6pq8-jhm2-2vcw"},{"rule_id":"osv/GHSA-4qv8-2p9j-2685","severity":"medium","message":"undici@7.30.0 (npm) is affected by GHSA-4qv8-2p9j-2685","path":"apps/api/package-lock.json","line":null,"fingerprint":"undici@7.30.0 (npm):GHSA-4qv8-2p9j-2685"},{"rule_id":"osv/GHSA-55wc-3pg8-jfw6","severity":"medium","message":"undici@7.30.0 (npm) is affected by GHSA-55wc-3pg8-jfw6","path":"apps/api/package-lock.json","line":null,"fingerprint":"undici@7.30.0 (npm):GHSA-55wc-3pg8-jfw6"},{"rule_id":"osv/GHSA-9fm3-97px-rjf6","severity":"medium","message":"undici@7.30.0 (npm) is affected by GHSA-9fm3-97px-rjf6","path":"apps/api/package-lock.json","line":null,"fingerprint":"undici@7.30.0 (npm):GHSA-9fm3-97px-rjf6"},{"rule_id":"osv/GHSA-f72v-6w45-q472","severity":"medium","message":"undici@7.30.0 (npm) is affected by GHSA-f72v-6w45-q472","path":"apps/api/package-lock.json","line":null,"fingerprint":"undici@7.30.0 (npm):GHSA-f72v-6w45-q472"},{"rule_id":"osv/GHSA-698v-4r3x-3vcv","severity":"medium","message":"vite@8.3.1 (npm) is affected by GHSA-698v-4r3x-3vcv; also in apps/web/package-lock.json","path":"apps/api/package-lock.json","line":null,"fingerprint":"vite@8.3.1 (npm):GHSA-698v-4r3x-3vcv"},{"rule_id":"osv/GHSA-r825-w8mm-5pxw","severity":"medium","message":"vite@8.3.1 (npm) is affected by GHSA-r825-w8mm-5pxw; also in apps/web/package-lock.json","path":"apps/api/package-lock.json","line":null,"fingerprint":"vite@8.3.1 (npm):GHSA-r825-w8mm-5pxw"},{"rule_id":"osv/GHSA-rq7h-c2jc-7f22","severity":"medium","message":"vite@8.3.1 (npm) is affected by GHSA-rq7h-c2jc-7f22; also in apps/web/package-lock.json","path":"apps/api/package-lock.json","line":null,"fingerprint":"vite@8.3.1 (npm):GHSA-rq7h-c2jc-7f22"},{"rule_id":"osv/GHSA-vfpm-58rq-9qcg","severity":"medium","message":"vite@8.3.1 (npm) is affected by GHSA-vfpm-58rq-9qcg; also in apps/web/package-lock.json","path":"apps/api/package-lock.json","line":null,"fingerprint":"vite@8.3.1 (npm):GHSA-vfpm-58rq-9qcg"},{"rule_id":"osv/GHSA-67mh-4wv8-2f99","severity":"medium","message":"esbuild@0.21.5 (npm) is affected by GHSA-67mh-4wv8-2f99","path":"site/package-lock.json","line":null,"fingerprint":"esbuild@0.21.5 (npm):GHSA-67mh-4wv8-2f99"},{"rule_id":"osv/GHSA-4w7w-66w2-5vf9","severity":"medium","message":"vite@5.4.21 (npm) is affected by GHSA-4w7w-66w2-5vf9","path":"site/package-lock.json","line":null,"fingerprint":"vite@5.4.21 (npm):GHSA-4w7w-66w2-5vf9"},{"rule_id":"osv/GHSA-698v-4r3x-3vcv","severity":"medium","message":"vite@5.4.21 (npm) is affected by GHSA-698v-4r3x-3vcv","path":"site/package-lock.json","line":null,"fingerprint":"vite@5.4.21 (npm):GHSA-698v-4r3x-3vcv"},{"rule_id":"osv/GHSA-fx2h-pf6j-xcff","severity":"medium","message":"vite@5.4.21 (npm) is affected by GHSA-fx2h-pf6j-xcff","path":"site/package-lock.json","line":null,"fingerprint":"vite@5.4.21 (npm):GHSA-fx2h-pf6j-xcff"},{"rule_id":"osv/GHSA-r825-w8mm-5pxw","severity":"medium","message":"vite@5.4.21 (npm) is affected by GHSA-r825-w8mm-5pxw","path":"site/package-lock.json","line":null,"fingerprint":"vite@5.4.21 (npm):GHSA-r825-w8mm-5pxw"},{"rule_id":"osv/GHSA-rq7h-c2jc-7f22","severity":"medium","message":"vite@5.4.21 (npm) is affected by GHSA-rq7h-c2jc-7f22","path":"site/package-lock.json","line":null,"fingerprint":"vite@5.4.21 (npm):GHSA-rq7h-c2jc-7f22"},{"rule_id":"osv/GHSA-v6wh-96g9-6wx3","severity":"medium","message":"vite@5.4.21 (npm) is affected by GHSA-v6wh-96g9-6wx3","path":"site/package-lock.json","line":null,"fingerprint":"vite@5.4.21 (npm):GHSA-v6wh-96g9-6wx3"},{"rule_id":"osv/GHSA-9jrq-w75r-8gcw","severity":"low","message":"vite@8.3.1 (npm) is affected by GHSA-9jrq-w75r-8gcw; also in apps/web/package-lock.json","path":"apps/api/package-lock.json","line":null,"fingerprint":"vite@8.3.1 (npm):GHSA-9jrq-w75r-8gcw"},{"rule_id":"osv/GHSA-9jrq-w75r-8gcw","severity":"low","message":"vite@5.4.21 (npm) is affected by GHSA-9jrq-w75r-8gcw","path":"site/package-lock.json","line":null,"fingerprint":"vite@5.4.21 (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":3.0,"findings":27.0,"findings_high":18.0,"findings_medium":9.0,"findings_low":0.0,"penalty":231.6},"findings":[{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/ci.yml","line":21,"fingerprint":"unpinned-uses:.github/workflows/ci.yml:21"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/ci.yml","line":22,"fingerprint":"unpinned-uses:.github/workflows/ci.yml:22"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/ci.yml","line":61,"fingerprint":"unpinned-uses:.github/workflows/ci.yml:61"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/ci.yml","line":62,"fingerprint":"unpinned-uses:.github/workflows/ci.yml:62"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/ci.yml","line":83,"fingerprint":"unpinned-uses:.github/workflows/ci.yml:83"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/ci.yml","line":84,"fingerprint":"unpinned-uses:.github/workflows/ci.yml:84"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/ci.yml","line":85,"fingerprint":"unpinned-uses:.github/workflows/ci.yml:85"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/pages.yml","line":23,"fingerprint":"unpinned-uses:.github/workflows/pages.yml:23"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/pages.yml","line":24,"fingerprint":"unpinned-uses:.github/workflows/pages.yml:24"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/pages.yml","line":43,"fingerprint":"unpinned-uses:.github/workflows/pages.yml:43"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/pages.yml","line":45,"fingerprint":"unpinned-uses:.github/workflows/pages.yml:45"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/pages.yml","line":63,"fingerprint":"unpinned-uses:.github/workflows/pages.yml:63"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/release.yml","line":31,"fingerprint":"unpinned-uses:.github/workflows/release.yml:31"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/release.yml","line":33,"fingerprint":"unpinned-uses:.github/workflows/release.yml:33"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/release.yml","line":35,"fingerprint":"unpinned-uses:.github/workflows/release.yml:35"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/release.yml","line":37,"fingerprint":"unpinned-uses:.github/workflows/release.yml:37"},{"rule_id":"zizmor/unpinned-uses","severity":"high","message":"unpinned action reference [confidence high]","path":".github/workflows/release.yml","line":44,"fingerprint":"unpinned-uses:.github/workflows/release.yml:44"},{"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/artipacked","severity":"medium","message":"credential persistence through GitHub Actions artifacts [confidence low]","path":".github/workflows/ci.yml","line":21,"fingerprint":"artipacked:.github/workflows/ci.yml:21"},{"rule_id":"zizmor/artipacked","severity":"medium","message":"credential persistence through GitHub Actions artifacts [confidence low]","path":".github/workflows/ci.yml","line":61,"fingerprint":"artipacked:.github/workflows/ci.yml:61"},{"rule_id":"zizmor/artipacked","severity":"medium","message":"credential persistence through GitHub Actions artifacts [confidence low]","path":".github/workflows/ci.yml","line":83,"fingerprint":"artipacked:.github/workflows/ci.yml:83"},{"rule_id":"zizmor/excessive-permissions","severity":"medium","message":"overly broad permissions [confidence medium]","path":".github/workflows/ci.yml","line":1,"fingerprint":"excessive-permissions:.github/workflows/ci.yml:1"},{"rule_id":"zizmor/excessive-permissions","severity":"medium","message":"overly broad permissions [confidence medium]","path":".github/workflows/ci.yml","line":14,"fingerprint":"excessive-permissions:.github/workflows/ci.yml:14"},{"rule_id":"zizmor/excessive-permissions","severity":"medium","message":"overly broad permissions [confidence medium]","path":".github/workflows/ci.yml","line":34,"fingerprint":"excessive-permissions:.github/workflows/ci.yml:34"},{"rule_id":"zizmor/excessive-permissions","severity":"medium","message":"overly broad permissions [confidence medium]","path":".github/workflows/ci.yml","line":76,"fingerprint":"excessive-permissions:.github/workflows/ci.yml:76"},{"rule_id":"zizmor/artipacked","severity":"medium","message":"credential persistence through GitHub Actions artifacts [confidence low]","path":".github/workflows/pages.yml","line":23,"fingerprint":"artipacked:.github/workflows/pages.yml:23"},{"rule_id":"zizmor/artipacked","severity":"medium","message":"credential persistence through GitHub Actions artifacts [confidence low]","path":".github/workflows/release.yml","line":31,"fingerprint":"artipacked:.github/workflows/release.yml:31"}],"evidence":[],"data":{},"error":null},{"analyzer":"sec-posture","pillar":"security","status":"ok","tool_version":null,"metrics":{"check:security_policy":0.0,"check:dependency_updates":0.0,"check:signed_commits":0.0,"check:lockfiles":0.0,"signed_commit_share":0.4032,"unpinned_manifests":1.0},"findings":[],"evidence":[{"kind":"posture","description":"package.json has no lockfile alongside it (unpinned dependencies)","ref":"package.json","url":null,"weight":0.3}],"data":{},"error":null},{"analyzer":"sec-distribution","pillar":"security","status":"ok","tool_version":null,"metrics":{"signals":0.0,"binary_assets":0.0,"suspicious":0.0},"findings":[],"evidence":[],"data":{"signals":[],"suspicious":false,"unusual_traction":false,"metadata":true},"error":null},{"analyzer":"qual-complexity","pillar":"quality","status":"ok","tool_version":"lizard 1.25.1","metrics":{"functions":895.0,"function_nloc":4772.0,"mean_ccn":2.59,"p90_ccn":5.0,"complex_functions":16.0,"long_functions":2.0,"many_param_functions":0.0,"risky_nloc_share":0.1622},"findings":[],"evidence":[{"kind":"complex-function","description":"AuthenticatedApp in apps/web/src/AppShell.tsx: complexity 93, 133 lines","ref":"apps/web/src/AppShell.tsx","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/web/src/AppShell.tsx#L108","weight":1.0},{"kind":"complex-function","description":"ReservationRow in apps/web/src/features/reservations/ReservationComponents.tsx: complexity 58, 48 lines","ref":"apps/web/src/features/reservations/ReservationComponents.tsx","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/web/src/features/reservations/ReservationComponents.tsx#L129","weight":0.9666666666666667},{"kind":"complex-function","description":"publicAddress in apps/api/src/metadata.ts: complexity 30, 17 lines","ref":"apps/api/src/metadata.ts","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/api/src/metadata.ts#L11","weight":0.5},{"kind":"complex-function","description":"update in apps/api/src/services/reservations.ts: complexity 28, 105 lines","ref":"apps/api/src/services/reservations.ts","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/api/src/services/reservations.ts#L191","weight":0.4666666666666667},{"kind":"complex-function","description":"extract in apps/api/src/metadata.ts: complexity 27, 30 lines","ref":"apps/api/src/metadata.ts","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/api/src/metadata.ts#L309","weight":0.45},{"kind":"complex-function","description":"HistoryPanel in apps/web/src/features/history/HistoryPanel.tsx: complexity 27, 46 lines","ref":"apps/web/src/features/history/HistoryPanel.tsx","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/web/src/features/history/HistoryPanel.tsx#L8","weight":0.45},{"kind":"complex-function","description":"PersonWishesPanel in apps/web/src/AppShell.tsx: complexity 22, 38 lines","ref":"apps/web/src/AppShell.tsx","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/web/src/AppShell.tsx#L51","weight":0.36666666666666664},{"kind":"complex-function","description":"SortableWishList in apps/web/src/components/organisms/SortableWishList.tsx: complexity 21, 49 lines","ref":"apps/web/src/components/organisms/SortableWishList.tsx","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/web/src/components/organisms/SortableWishList.tsx#L45","weight":0.35},{"kind":"complex-function","description":"Auth in apps/web/src/features/auth/Auth.tsx: complexity 19, 86 lines","ref":"apps/web/src/features/auth/Auth.tsx","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/web/src/features/auth/Auth.tsx#L9","weight":0.31666666666666665},{"kind":"complex-function","description":"(anonymous) in apps/web/src/features/families/FamilyComponents.tsx: complexity 19, 13 lines","ref":"apps/web/src/features/families/FamilyComponents.tsx","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/web/src/features/families/FamilyComponents.tsx#L224","weight":0.31666666666666665}],"data":{},"error":null},{"analyzer":"qual-duplication","pillar":"quality","status":"ok","tool_version":"repotrust-dup-w6","metrics":{"compared_lines":5107.0,"duplicated_lines":106.0,"duplicated_share":0.0208,"files":65.0},"findings":[],"evidence":[{"kind":"duplicate-code","description":"6+ duplicated lines: apps/api/src/services/families.ts:128 and apps/api/src/services/families.ts:211","ref":"apps/api/src/services/families.ts","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/api/src/services/families.ts#L128","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: apps/api/src/services/families.ts:421 and apps/api/src/services/wishes.ts:154","ref":"apps/api/src/services/families.ts","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/api/src/services/families.ts#L421","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: apps/api/src/services/reservations.ts:68 and apps/api/src/services/reservations.ts:112","ref":"apps/api/src/services/reservations.ts","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/api/src/services/reservations.ts#L68","weight":0.3},{"kind":"duplicate-code","description":"6+ duplicated lines: apps/api/src/services/reservations.ts:408 and apps/api/src/services/wishes.ts:236","ref":"apps/api/src/services/reservations.ts","url":"https://github.com/aileo/pensa/blob/f10cc33fc364c99149236d17184a4acf18e452de/apps/api/src/services/reservations.ts#L408","weight":0.3}],"data":{},"error":null},{"analyzer":"qual-lint","pillar":"quality","status":"ok","tool_version":"opengrep 1.33.1; rules f1d2b562b414","metrics":{"findings":7.0,"weighted_findings":5.5,"scanned_lines":6077.0,"category:best-practice":5.0,"category:correctness":2.0},"findings":[{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"It's best practice to explicitly pass props to an HTML component rather than use the spread operator. The spread operator risks passing invalid HTML props to an HTML element, which can cause console warnings or worse, give malicious actors a way to inject unexpected attributes.","path":"apps/web/src/components/atoms/FormLabel.tsx","line":4,"fingerprint":"typescript.react.best-practice.react-props-spreading:apps/web/src/components/atoms/FormLabel.tsx:4"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"It's best practice to explicitly pass props to an HTML component rather than use the spread operator. The spread operator risks passing invalid HTML props to an HTML element, which can cause console warnings or worse, give malicious actors a way to inject unexpected attributes.","path":"apps/web/src/components/atoms/SelectInput.tsx","line":4,"fingerprint":"typescript.react.best-practice.react-props-spreading:apps/web/src/components/atoms/SelectInput.tsx:4"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"It's best practice to explicitly pass props to an HTML component rather than use the spread operator. The spread operator risks passing invalid HTML props to an HTML element, which can cause console warnings or worse, give malicious actors a way to inject unexpected attributes.","path":"apps/web/src/components/atoms/TextArea.tsx","line":4,"fingerprint":"typescript.react.best-practice.react-props-spreading:apps/web/src/components/atoms/TextArea.tsx:4"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-spreading","severity":"medium","message":"It's best practice to explicitly pass props to an HTML component rather than use the spread operator. The spread operator risks passing invalid HTML props to an HTML element, which can cause console warnings or worse, give malicious actors a way to inject unexpected attributes.","path":"apps/web/src/components/atoms/TextInput.tsx","line":4,"fingerprint":"typescript.react.best-practice.react-props-spreading:apps/web/src/components/atoms/TextInput.tsx:4"},{"rule_id":"opengrep/typescript.react.best-practice.react-props-in-state","severity":"medium","message":"Copying a prop into state in React -- this is bad practice as all updates to it are ignored. Instead, read props directly in your component and avoid copying props into state.","path":"apps/web/src/reorder.ts","line":88,"fingerprint":"typescript.react.best-practice.react-props-in-state:apps/web/src/reorder.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":"apps/web/src/routes.ts","line":53,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:apps/web/src/routes.ts:53"},{"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":"apps/web/src/routes.ts","line":53,"fingerprint":"javascript.lang.correctness.missing-template-string-indicator:apps/web/src/routes.ts:53"}],"evidence":[],"data":{},"error":null},{"analyzer":"qual-testing","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:has_tests":1.0,"check:test_ratio":0.5977,"check:ci_present":1.0,"check:ci_runs_tests":1.0,"check:ci_runs_lint":0.0,"check:tests_cochange":1.0,"test_lines":1867.0,"source_lines":6247.0,"test_ratio":0.2989,"ci_files":3.0,"cochange_share":0.6444,"cochange_commits":45.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/pages.yml","ref":".github/workflows/pages.yml","url":null,"weight":0.0},{"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 (npm test)","ref":null,"url":null,"weight":0.0}],"data":{"test_commands":["npm test"],"lint_commands":[]},"error":null},{"analyzer":"qual-docs","pillar":"quality","status":"ok","tool_version":null,"metrics":{"check:readme":1.0,"check:license":1.0,"check:contributing":1.0,"check:changelog":1.0,"readme_lines":97.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":"docs/CONTRIBUTING.md","ref":"docs/CONTRIBUTING.md","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":1.0,"check:low_escape_density":1.0,"escapes":0.0,"escapes_per_kloc":0.0},"findings":[],"evidence":[{"kind":"typing","description":"TypeScript strict type checking: apps/api/tsconfig.json","ref":"apps/api/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":6247.0,"other_lines":0.0,"files_blamed":65.0,"blame_failures":0.0,"quality:ai_findings":7.0,"quality:ai_per_kloc":1.121,"quality:other_findings":0.0,"security:ai_findings":2.0,"security:ai_per_kloc":0.32,"security:other_findings":0.0},"findings":[],"evidence":[],"data":{"sampled":false,"comparable":false},"error":null}],"flags":[]}