{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"codehealth","informationUri":"https://codehealth.canine.dev","rules":[{"id":"D1","name":"Cyclomatic Complexity","shortDescription":{"text":"Cyclomatic Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/D1"},{"id":"D2","name":"Cognitive Complexity","shortDescription":{"text":"Cognitive Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/D2"},{"id":"D3","name":"God Classes","shortDescription":{"text":"God Classes"},"helpUri":"https://codehealth.canine.dev/dimensions/D3"},{"id":"D4","name":"Code Duplication","shortDescription":{"text":"Code Duplication"},"helpUri":"https://codehealth.canine.dev/dimensions/D4"},{"id":"D12","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/D12"},{"id":"D13","name":"Secret Scanning","shortDescription":{"text":"Secret Scanning"},"helpUri":"https://codehealth.canine.dev/dimensions/D13","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D14","name":"License Compliance","shortDescription":{"text":"License Compliance"},"helpUri":"https://codehealth.canine.dev/dimensions/D14"},{"id":"D15","name":"Churn \u00D7 Complexity Hotspots","shortDescription":{"text":"Churn \u00D7 Complexity Hotspots"},"helpUri":"https://codehealth.canine.dev/dimensions/D15"},{"id":"D16","name":"Bus Factor","shortDescription":{"text":"Bus Factor"},"helpUri":"https://codehealth.canine.dev/dimensions/D16"},{"id":"D17","name":"Explicit Debt","shortDescription":{"text":"Explicit Debt"},"helpUri":"https://codehealth.canine.dev/dimensions/D17"},{"id":"D19","name":"Documentation Quality","shortDescription":{"text":"Documentation Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D19"},{"id":"D21","name":"Naming Consistency","shortDescription":{"text":"Naming Consistency"},"helpUri":"https://codehealth.canine.dev/dimensions/D21"},{"id":"D22","name":"Internal API Consistency","shortDescription":{"text":"Internal API Consistency"},"helpUri":"https://codehealth.canine.dev/dimensions/D22"},{"id":"D26","name":"Project Cohesion","shortDescription":{"text":"Project Cohesion"},"helpUri":"https://codehealth.canine.dev/dimensions/D26"},{"id":"D28","name":"Secrets (history)","shortDescription":{"text":"Secrets (history)"},"helpUri":"https://codehealth.canine.dev/dimensions/D28","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D29","name":"Static Analysis (SAST)","shortDescription":{"text":"Static Analysis (SAST)"},"helpUri":"https://codehealth.canine.dev/dimensions/D29","relationships":[{"target":{"id":"CWE-79","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-94","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-77","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-79","CWE-89","CWE-78","CWE-94","CWE-77"]}},{"id":"D30","name":"Dependency Vulnerabilities","shortDescription":{"text":"Dependency Vulnerabilities"},"helpUri":"https://codehealth.canine.dev/dimensions/D30","relationships":[{"target":{"id":"CWE-1395","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-937","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1395","CWE-937"]}},{"id":"D34","name":"Knowledge Freshness","shortDescription":{"text":"Knowledge Freshness"},"helpUri":"https://codehealth.canine.dev/dimensions/D34"},{"id":"D35","name":"Change Coupling","shortDescription":{"text":"Change Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D35"},{"id":"D36","name":"Supply-chain Provenance \u0026 Signing","shortDescription":{"text":"Supply-chain Provenance \u0026 Signing"},"helpUri":"https://codehealth.canine.dev/dimensions/D36","relationships":[{"target":{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1357","CWE-494"]}},{"id":"D43","name":"Malicious Dependencies","shortDescription":{"text":"Malicious Dependencies"},"helpUri":"https://codehealth.canine.dev/dimensions/D43","relationships":[{"target":{"id":"CWE-506","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-506"]}},{"id":"AX10","name":"Code composition","shortDescription":{"text":"Code composition"},"helpUri":"https://codehealth.canine.dev/dimensions/AX10"},{"id":"AXB2","name":"Runtime readiness","shortDescription":{"text":"Runtime readiness"},"helpUri":"https://codehealth.canine.dev/dimensions/AXB2"},{"id":"M1","name":"Documentation (README)","shortDescription":{"text":"Documentation (README)"},"helpUri":"https://codehealth.canine.dev/dimensions/M1"},{"id":"M2","name":"Architecture documentation","shortDescription":{"text":"Architecture documentation"},"helpUri":"https://codehealth.canine.dev/dimensions/M2"},{"id":"M3","name":"Folder \u0026 project structure","shortDescription":{"text":"Folder \u0026 project structure"},"helpUri":"https://codehealth.canine.dev/dimensions/M3"},{"id":"M4","name":"Documentation accuracy","shortDescription":{"text":"Documentation accuracy"},"helpUri":"https://codehealth.canine.dev/dimensions/M4"},{"id":"P1","name":"CI/CD gates","shortDescription":{"text":"CI/CD gates"},"helpUri":"https://codehealth.canine.dev/dimensions/P1"},{"id":"P12","name":"CI test-gate honesty","shortDescription":{"text":"CI test-gate honesty"},"helpUri":"https://codehealth.canine.dev/dimensions/P12"},{"id":"P3","name":"Security \u0026 performance tooling","shortDescription":{"text":"Security \u0026 performance tooling"},"helpUri":"https://codehealth.canine.dev/dimensions/P3"},{"id":"P6","name":"Release Hygiene","shortDescription":{"text":"Release Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/P6"},{"id":"X9","name":"Subsumed condition operand","shortDescription":{"text":"Subsumed condition operand"},"helpUri":"https://codehealth.canine.dev/dimensions/X9"}]}},"results":[{"ruleId":"D1","level":"warning","message":{"text":"Parser.parse_tag (cyclomatic 22): Parser.parse_tag has cyclomatic complexity 22 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lib/slim/parser.rb"},"region":{"startLine":327}}}],"partialFingerprints":{"codehealthFindingId/v1":"84dcbc153a003b7e54e610312d7f00303742f579d47122168ca0cb22cf154469"}},{"ruleId":"D1","level":"warning","message":{"text":"Parser.parse_line_indicators (cyclomatic 17): Parser.parse_line_indicators has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lib/slim/parser.rb"},"region":{"startLine":200}}}],"partialFingerprints":{"codehealthFindingId/v1":"a10fd2c20a1ada57282c1686c5ce1342f4b95f88322d46484384682376d482c3"}},{"ruleId":"D2","level":"warning","message":{"text":"Parser.parse_tag (cognitive 29): Parser.parse_tag has cognitive complexity 29 (threshold 15). Drivers by points: if/else 14 (24 pts), boolean chains 3, loops 1, match/switch 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lib/slim/parser.rb"},"region":{"startLine":327}}}],"partialFingerprints":{"codehealthFindingId/v1":"b770f98a4ce923020f13af6afbad497c16c89508dd290a3116a0423798fe8ed8"}},{"ruleId":"D2","level":"warning","message":{"text":"Parser.parse_text_block (cognitive 25): Parser.parse_text_block has cognitive complexity 25 (threshold 15). Drivers by points: if/else 8 (17 pts), ternaries 2 (6 pts), boolean chains 1, loops 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lib/slim/parser.rb"},"region":{"startLine":275}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f17218badb8b40120d9dd094863d2180a22674b99a838c1a895982814f1a986"}},{"ruleId":"D2","level":"warning","message":{"text":"Parser.parse_attributes (cognitive 25): Parser.parse_attributes has cognitive complexity 25 (threshold 15). Drivers by points: if/else 8 (18 pts), match/switch 2 (5 pts), boolean chains 1, loops 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lib/slim/parser.rb"},"region":{"startLine":411}}}],"partialFingerprints":{"codehealthFindingId/v1":"fdca4923609f04d6235dd6695957a77b87929f32b164433ecb48b03b3bc53e03"}},{"ruleId":"D2","level":"warning","message":{"text":"Command.process (cognitive 17): Command.process has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9 (12 pts), boolean chains 2, ternaries 1 (2 pts), error handling 1 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lib/slim/command.rb"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7b3c206f41b773395fc9cdb08f38d8f9e246f7f046323a803ad7fbd17380ebd"}},{"ruleId":"D2","level":"warning","message":{"text":"Parser.parse_ruby_code (cognitive 16): Parser.parse_ruby_code has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (13 pts), boolean chains 2, loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lib/slim/parser.rb"},"region":{"startLine":470}}}],"partialFingerprints":{"codehealthFindingId/v1":"1450af7e771a8eb798e012c1eac09486f2ce399e9c9b2039190396a321d54dbc"}},{"ruleId":"D12","level":"warning","message":{"text":"Floating git dependency: temple: Gem \u0060temple\u0060 is declared in Gemfile from a git source (judofyr/temple) with no immutable pin \u2014 no \u0060ref:\u0060 or \u0060tag:\u0060 is given, so Bundler resolves whatever the default branch points at today. Two \u0060bundle install\u0060 runs of this commit can therefore install different code, and nothing in the repository records which revision a given build used. Pin it to a commit (\u0060ref: \u0022\u003Csha\u003E\u0022\u0060) or a release tag (\u0060tag: \u0022v1.2.3\u0022\u0060), or take the gem from rubygems.org if it publishes there."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"905d9a8e1935015d78688e26f4074f79e07b08cc149ccca395343b73e43fd658"}},{"ruleId":"D12","level":"warning","message":{"text":"Floating git dependency: tilt: Gem \u0060tilt\u0060 is declared in Gemfile from a git source (jeremyevans/tilt) with no immutable pin \u2014 no \u0060ref:\u0060 or \u0060tag:\u0060 is given, so Bundler resolves whatever the default branch points at today. Two \u0060bundle install\u0060 runs of this commit can therefore install different code, and nothing in the repository records which revision a given build used. Pin it to a commit (\u0060ref: \u0022\u003Csha\u003E\u0022\u0060) or a release tag (\u0060tag: \u0022v1.2.3\u0022\u0060), or take the gem from rubygems.org if it publishes there."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"9880a604f053b16448da56533d339c4605867f294ed3fc74883ea29909a02a99"}},{"ruleId":"D12","level":"warning","message":{"text":"Floating git dependency: rails: Gem \u0060rails\u0060 is declared in Gemfile from a git source (rails/rails) with no immutable pin \u2014 \u0060main\u0060 is a branch, not a commit. Two \u0060bundle install\u0060 runs of this commit can therefore install different code, and nothing in the repository records which revision a given build used. Pin it to a commit (\u0060ref: \u0022\u003Csha\u003E\u0022\u0060) or a release tag (\u0060tag: \u0022v1.2.3\u0022\u0060), or take the gem from rubygems.org if it publishes there."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"38819b2b14ea66b4467f221c82cefc0a59a88a07a01b317ec4ed0a0ae4771f21"}},{"ruleId":"D12","level":"warning","message":{"text":"Floating git dependency: sinatra: Gem \u0060sinatra\u0060 is declared in Gemfile from a git source (sinatra/sinatra) with no immutable pin \u2014 no \u0060ref:\u0060 or \u0060tag:\u0060 is given, so Bundler resolves whatever the default branch points at today. Two \u0060bundle install\u0060 runs of this commit can therefore install different code, and nothing in the repository records which revision a given build used. Pin it to a commit (\u0060ref: \u0022\u003Csha\u003E\u0022\u0060) or a release tag (\u0060tag: \u0022v1.2.3\u0022\u0060), or take the gem from rubygems.org if it publishes there."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"95aa0522282127653830c9a68ba51cbdfee0f32bdf55277127d68ab7681ff4b2"}},{"ruleId":"D17","level":"warning","message":{"text":"HackComment: # HACK: Manipulate stacktrace for Rails and other frameworks \u2014 a workaround marked in source: record what it is compensating for and what would allow its removal (the upstream fix, the API it is waiting on, the invariant it restores), so the next reader can judge whether it is still needed rather than rediscovering why it is there."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lib/slim/parser.rb"},"region":{"startLine":524}}}],"partialFingerprints":{"codehealthFindingId/v1":"e659c25eda825a78a140dfc2c116f7fa21556f0458ca41e8e0ff7a2a3eb13f77"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Reactivate sass tests \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"test/core/test_embedded_engines.rb"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"6887da6f3308fabf83c687530dddc702e21a24315e9a1fc6c6a2052b45998b82"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO Reenable streaming test \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"test/rails/test/test_slim.rb"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cbbd020f845ef94535da40983a18beddfecf4dd2ae38e2773dbdb410918c180"}},{"ruleId":"D22","level":"warning","message":{"text":"Inconsistent parameter handling for attribute setting. \u0060code_attr\u0060 takes an explicit \u0060escape\u0060 boolean, while \u0060attr\u0060 does not. It is unclear if \u0060attr\u0060 assumes a default escape behavior or if it is for non-escaped attributes, creating ambiguity in how to correctly set attributes.: Unify into a single method \u0060attr(name, value, escape: true)\u0060 or ensure both methods have consistent signatures regarding escaping, or clearly document that \u0060attr\u0060 is for literal/non-escaped values. (signatures: Slim.Splat.Builder.code_attr(name, escape, value) | Slim.Splat.Builder.attr(name, value))"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"5398ad9f21570d3558b493472c4d0f3cb10ec8967e777fc614ef809e027a1aae"}},{"ruleId":"D22","level":"warning","message":{"text":"Ambiguous distinction between \u0060on_slim_text\u0060 and \u0060on_slim_text_inline\u0060. The signatures differ only by the \u0060type\u0060 parameter in the first method. It is unclear if \u0060type\u0060 is a discriminator for block vs inline text, or if \u0060on_slim_text_inline\u0060 is a specialized override. This suggests a potential duplication of intent or unclear state management.: Clarify if \u0060type\u0060 in \u0060on_slim_text\u0060 covers all text cases, making \u0060on_slim_text_inline\u0060 redundant, or if they handle distinct parsing contexts that should be reflected in the method names or a unified interface. (signatures: Slim.Smart.Filter.on_slim_text(type, content) | Slim.Smart.Filter.on_slim_text_inline(content))"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"8bad62fba770a9b8f7370b61a2059462c63bcbced03c90ee0c300d7471cbc8cf"}},{"ruleId":"D22","level":"warning","message":{"text":"Inconsistent naming for the primary entry point method. While \u0060call\u0060 is common in Ruby for callable objects, \u0060Parser\u0060 uses \u0060call(str)\u0060 while other components like \u0060Engine\u0060 also use \u0060call\u0060. However, \u0060Parser.initialize\u0060 takes \u0060opts\u0060 while \u0060Engine\u0060 does not have a visible constructor in the list (or it\u0027s implicit). More critically, \u0060Slim.Parser.call\u0060 takes a \u0060str\u0060 (string), whereas \u0060Slim.Engine.call\u0060 takes \u0060input\u0060 (likely a string or IO). This is minor, but the lack of a unified \u0060parse\u0060 or \u0060render\u0060 verb across the board (some use \u0060call\u0060, some use \u0060run\u0060 in \u0060Command\u0060) is slightly inconsistent.: Standardize on \u0060call\u0060 for all callable components or use domain-specific verbs like \u0060parse\u0060 for parsers and \u0060render\u0060 for engines. \u0060Command.run()\u0060 is distinct enough to be acceptable, but \u0060Parser.call\u0060 vs \u0060Engine.call\u0060 should be documented as the standard callable pattern. (signatures: Slim.Parser.call(str) | Slim.Engine.call(input) | Slim.Translator.call(exp) | Slim.Smart.Filter.call(exp) | Slim.Smart.Escaper.call(exp) | Slim.LogicLess.call(exp) | Slim.TextCollector.call(exp) | Slim.NewlineCollector.call(exp) | Slim.OutputProtector.call(exp) | Slim.Translator.StaticTranslator.call(exp) | Slim.Translator.DynamicTranslator.call(exp))"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7cb744021ee944174ac302a993d7a2b0ff9766d773cfd087a2163678050f51ea"}},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"55a9feee9774121f2f799f78815f48406c361b20f27615a6b6c4aa576c312700"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"fed25ec4d2f2035f1e41d230e11987d2b940a006dd63cdf3d8a9edb8379e67d6"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"929889218fe2adba5577454da6e2fffb54a21f38de62c057ea511bf22abbc080"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d09778711c2a7896e57335a1954d627070532bdaabfc8867bd53efab869ddd08"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5737efc06c6e8974d9eca5116fd6fad508959b148616caec8005de3fc2426593"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8caabfc6a9d4924345de461e549d48eb0174a95279f612cb26222da79e543140"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"53315474bb32001c95429eb87437f2f6d6b5dc02b7dabcb3440cf7a4f84d5346"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1612e86d9d8a2ff8eb98673c7461072fd410af98d5407e15eba647f36b981ef0"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d951e19574a6bab28d2c3237c4d3902a5e18818e2a792861b89ffcb9f927b73c"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"447f9a3e4c80782aa1354fbc0016b48c8562e14d50ef3b75e51b66683250accd"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ace515990e7ee0f17b5c17e44dd168a5bdecf90804a3a3dd845cf05540978013"}},{"ruleId":"M2","level":"note","message":{"text":"No ADRs: No Architecture Decision Records found \u2014 no conventional ADR directory, no numbered \u0060NNNN-title\u0060 documents in any markup this check reads, and nothing ADR-shaped by content. Design rationale recorded elsewhere (a design-notes tree, a mailing list, pull-request discussion) is not visible to this check and is not re-findable per decision, so a future maintainer cannot ask why one choice was made and get an answer."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"670b3d6e36a756d63097d0dfbf90afd5fc761308800b9354894a07c3f4e4aa14"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: README advertises Docker containerisation, but no Dockerfile/compose file exists \u2014 searched for: \u0060dockerfile\u0060, \u0060docker-compose\u0060, \u0060compose.yaml\u0060, \u0060compose.yml\u0060. Each was matched case- and separator-insensitively against file and directory NAMES anywhere in the tree, and against the CONTENTS of manifest files (package.json, *.csproj, *.props, *.slnx, *.yml, Dockerfile); the README\u0027s own prose never counts, so a claim is never refuted by merely being made. Nothing outside that search was read \u2014 a footprint living only in a submodule, in a file type not listed here, or under a name none of those terms matches is not seen, and this row is then wrong."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d116e696b89ee5b5606de54018788ae795afe8387ffcf59a3c5f5c024f4aec80"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: README advertises a RAG / ML engine, but no ML/RAG code or dependency exists \u2014 searched for: \u0060rag\u0060, \u0060langchain\u0060, \u0060llamaindex\u0060, \u0060pinecone\u0060, \u0060weaviate\u0060, \u0060qdrant\u0060, \u0060embeddings\u0060. Each was matched case- and separator-insensitively against file and directory NAMES anywhere in the tree, and against the CONTENTS of manifest files (package.json, *.csproj, *.props, *.slnx, *.yml, Dockerfile); the README\u0027s own prose never counts, so a claim is never refuted by merely being made. Nothing outside that search was read \u2014 a footprint living only in a submodule, in a file type not listed here, or under a name none of those terms matches is not seen, and this row is then wrong."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"641c12de6a27c56ae4f356e613243d119d1728768480ea36e3ea12271e12b02c"}},{"ruleId":"P1","level":"note","message":{"text":"CI build step not evidenced: A CI pipeline exists but no build step was matched \u2014 changes may merge without the build ever running. A build step may be invoked directly as a command, or declared as a task that a runner named in the pipeline resolves."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"251015acef1a259fcc13b7c60660cc8917ccb3ae8056cb5165ae03312dd586e8"}},{"ruleId":"P3","level":"note","message":{"text":"No SAST: No static application security testing detected. For this repository\u0027s stack, add brakeman for Rails apps, otherwise \u0060semgrep --config=auto\u0060 or CodeQL\u0027s ruby pack as a CI step. What was searched, so you can tell an absence from a miss: the 4507 CI workflow file(s) in this repository, and the scanner and linter configuration checked in beside them. A scan that runs outside CI, one configured in your forge\u0027s web UI rather than in a committed file, or a tool whose name is none of those this check carries, is not seen \u2014 if that is your case the row is wrong, and saying so is more useful than adding a second scanner."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"6e54424179c892f03ef2fd003130ac4bd43f39bbf3b1ca0a0143e25acb80ec87"}}],"taxonomies":[{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d","organization":"MITRE","informationUri":"https://cwe.mitre.org/","isComprehensive":false,"shortDescription":{"text":"The MITRE Common Weakness Enumeration (CWE)."},"taxa":[{"id":"CWE-1357","guid":"e4d2e772-757e-0a5c-bd7d-77052949d866","name":"Reliance on Insufficiently Trustworthy Component","shortDescription":{"text":"Reliance on Insufficiently Trustworthy Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1357.html"},{"id":"CWE-1395","guid":"800e09e7-c11a-8654-9fa6-86f398995fed","name":"Dependency on Vulnerable Third-Party Component","shortDescription":{"text":"Dependency on Vulnerable Third-Party Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1395.html"},{"id":"CWE-259","guid":"ae9ad959-fbb6-9d5e-892d-3dca66da0b69","name":"Use of Hard-coded Password","shortDescription":{"text":"Use of Hard-coded Password"},"helpUri":"https://cwe.mitre.org/data/definitions/259.html"},{"id":"CWE-353","guid":"09d7e902-d4ee-f05d-ae6c-0a1554d0c18f","name":"CWE-353","shortDescription":{"text":"CWE-353"},"helpUri":"https://cwe.mitre.org/data/definitions/353.html"},{"id":"CWE-494","guid":"b8a65e0d-e459-4a55-a931-fc1136482375","name":"Download of Code Without Integrity Check","shortDescription":{"text":"Download of Code Without Integrity Check"},"helpUri":"https://cwe.mitre.org/data/definitions/494.html"},{"id":"CWE-506","guid":"401d6455-56e3-0552-9a39-f77461673e3f","name":"CWE-506","shortDescription":{"text":"CWE-506"},"helpUri":"https://cwe.mitre.org/data/definitions/506.html"},{"id":"CWE-77","guid":"332c8ade-6612-9f56-a06b-d8d90b1a8750","name":"Command Injection","shortDescription":{"text":"Command Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/77.html"},{"id":"CWE-78","guid":"2e31ceaf-c7ae-2e5e-9661-cfb1362789cf","name":"OS Command Injection","shortDescription":{"text":"OS Command Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/78.html"},{"id":"CWE-79","guid":"fd45580b-e8c4-fc5e-8c2f-aa8fab0b4dbf","name":"Cross-site Scripting (XSS)","shortDescription":{"text":"Cross-site Scripting (XSS)"},"helpUri":"https://cwe.mitre.org/data/definitions/79.html"},{"id":"CWE-798","guid":"5e8f057d-fee3-995a-a0cb-9fc5b0d174d1","name":"Use of Hard-coded Credentials","shortDescription":{"text":"Use of Hard-coded Credentials"},"helpUri":"https://cwe.mitre.org/data/definitions/798.html"},{"id":"CWE-89","guid":"6d08fdad-37eb-c150-bbf0-d7d946863407","name":"SQL Injection","shortDescription":{"text":"SQL Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/89.html"},{"id":"CWE-937","guid":"16f316ae-415c-b354-a59b-1f7905f756e9","name":"Using Components with Known Vulnerabilities","shortDescription":{"text":"Using Components with Known Vulnerabilities"},"helpUri":"https://cwe.mitre.org/data/definitions/937.html"},{"id":"CWE-94","guid":"75e7f50c-6c2f-dd52-bf40-bf6c52b861fd","name":"Code Injection","shortDescription":{"text":"Code Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/94.html"}]}],"properties":{"codehealthPublication":{"public":true,"notice":"This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings \u2014 which rule fired, in which file, on which line, and how to fix it \u2014 are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.","securityFindingsRedacted":11,"secretScannerRunsExcluded":0}},"redactionTokens":["A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."]}]}