@hoanghainh/komagu 2.5.0 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/assess/lsa/examples/eval-run-6/gptoss-a/ai-run-stats.json +87 -0
  3. package/assess/lsa/examples/eval-run-6/gptoss-a/auth-model.md +120 -0
  4. package/assess/lsa/examples/eval-run-6/gptoss-a/batches/index.json +60 -0
  5. package/assess/lsa/examples/eval-run-6/gptoss-a/batches/injection-001.json +383 -0
  6. package/assess/lsa/examples/eval-run-6/gptoss-a/batches/injection-002.json +205 -0
  7. package/assess/lsa/examples/eval-run-6/gptoss-a/batches/privilege-001.json +838 -0
  8. package/assess/lsa/examples/eval-run-6/gptoss-a/batches/privilege-002.json +124 -0
  9. package/assess/lsa/examples/eval-run-6/gptoss-a/batches/routes-001.json +778 -0
  10. package/assess/lsa/examples/eval-run-6/gptoss-a/batches/routes-002.json +546 -0
  11. package/assess/lsa/examples/eval-run-6/gptoss-a/batches/routes-003.json +661 -0
  12. package/assess/lsa/examples/eval-run-6/gptoss-a/batches/routes-004.json +659 -0
  13. package/assess/lsa/examples/eval-run-6/gptoss-a/batches/routes-005.json +612 -0
  14. package/assess/lsa/examples/eval-run-6/gptoss-a/batches/routes-006.json +106 -0
  15. package/assess/lsa/examples/eval-run-6/gptoss-a/coverage.json +19 -0
  16. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/bola-routes-001.json +516 -0
  17. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/bola-routes-002.json +332 -0
  18. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/bola-routes-003.json +218 -0
  19. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/bola-routes-004.json +561 -0
  20. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/bola-routes-005.json +316 -0
  21. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/bola-routes-006.json +14 -0
  22. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/inj-injection-001.json +782 -0
  23. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/inj-injection-002.json +418 -0
  24. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/priv-privilege-001.json +627 -0
  25. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/priv-privilege-002.json +253 -0
  26. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-1.json +68 -0
  27. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-10.json +68 -0
  28. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-11.json +61 -0
  29. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-12.json +60 -0
  30. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-13.json +60 -0
  31. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-14.json +66 -0
  32. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-15.json +69 -0
  33. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-16.json +60 -0
  34. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-17.json +61 -0
  35. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-18.json +69 -0
  36. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-19.json +64 -0
  37. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-2.json +60 -0
  38. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-20.json +60 -0
  39. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-21.json +61 -0
  40. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-22.json +50 -0
  41. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-3.json +60 -0
  42. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-4.json +60 -0
  43. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-5.json +60 -0
  44. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-6.json +70 -0
  45. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-7.json +60 -0
  46. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-8.json +60 -0
  47. package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-9.json +60 -0
  48. package/assess/lsa/examples/eval-run-6/gptoss-a/findings.json +4857 -0
  49. package/assess/lsa/examples/eval-run-6/gptoss-a/mass-assignment.candidates.json +232 -0
  50. package/assess/lsa/examples/eval-run-6/gptoss-a/report.ja.md +2112 -0
  51. package/assess/lsa/examples/eval-run-6/gptoss-a/report.md +2112 -0
  52. package/assess/lsa/examples/eval-run-6/gptoss-a/routes/routes-001.json +425 -0
  53. package/assess/lsa/examples/eval-run-6/gptoss-a/routes/routes-002.json +333 -0
  54. package/assess/lsa/examples/eval-run-6/gptoss-a/routes/routes-003.json +400 -0
  55. package/assess/lsa/examples/eval-run-6/gptoss-a/routes/routes-004.json +403 -0
  56. package/assess/lsa/examples/eval-run-6/gptoss-a/routes/routes-005.json +398 -0
  57. package/assess/lsa/examples/eval-run-6/gptoss-a/routes/routes-006.json +63 -0
  58. package/assess/lsa/examples/eval-run-6/gptoss-a/score.json +82 -0
  59. package/assess/lsa/examples/eval-run-6/gptoss-a/stack-profile.json +225 -0
  60. package/assess/lsa/examples/eval-run-6/gptoss-b/ai-run-stats.json +91 -0
  61. package/assess/lsa/examples/eval-run-6/gptoss-b/auth-model.md +120 -0
  62. package/assess/lsa/examples/eval-run-6/gptoss-b/batches/index.json +60 -0
  63. package/assess/lsa/examples/eval-run-6/gptoss-b/batches/injection-001.json +383 -0
  64. package/assess/lsa/examples/eval-run-6/gptoss-b/batches/injection-002.json +205 -0
  65. package/assess/lsa/examples/eval-run-6/gptoss-b/batches/privilege-001.json +838 -0
  66. package/assess/lsa/examples/eval-run-6/gptoss-b/batches/privilege-002.json +124 -0
  67. package/assess/lsa/examples/eval-run-6/gptoss-b/batches/routes-001.json +778 -0
  68. package/assess/lsa/examples/eval-run-6/gptoss-b/batches/routes-002.json +546 -0
  69. package/assess/lsa/examples/eval-run-6/gptoss-b/batches/routes-003.json +661 -0
  70. package/assess/lsa/examples/eval-run-6/gptoss-b/batches/routes-004.json +659 -0
  71. package/assess/lsa/examples/eval-run-6/gptoss-b/batches/routes-005.json +612 -0
  72. package/assess/lsa/examples/eval-run-6/gptoss-b/batches/routes-006.json +106 -0
  73. package/assess/lsa/examples/eval-run-6/gptoss-b/coverage.json +21 -0
  74. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/bola-routes-001.json +593 -0
  75. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/bola-routes-002.json +367 -0
  76. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/bola-routes-003.json +207 -0
  77. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/bola-routes-004.json +477 -0
  78. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/bola-routes-005.json +341 -0
  79. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/bola-routes-006.json +14 -0
  80. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/inj-injection-001.json +821 -0
  81. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/inj-injection-002.json +410 -0
  82. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/priv-privilege-001.json +649 -0
  83. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/priv-privilege-002.json +222 -0
  84. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-1.json +60 -0
  85. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-10.json +67 -0
  86. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-11.json +68 -0
  87. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-12.json +60 -0
  88. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-13.json +60 -0
  89. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-14.json +64 -0
  90. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-15.json +70 -0
  91. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-16.json +60 -0
  92. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-17.json +61 -0
  93. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-18.json +60 -0
  94. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-19.json +65 -0
  95. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-2.json +60 -0
  96. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-20.json +60 -0
  97. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-21.json +62 -0
  98. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-22.json +50 -0
  99. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-3.json +60 -0
  100. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-4.json +60 -0
  101. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-5.json +60 -0
  102. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-6.json +60 -0
  103. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-7.json +64 -0
  104. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-8.json +60 -0
  105. package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-9.json +60 -0
  106. package/assess/lsa/examples/eval-run-6/gptoss-b/findings.json +4966 -0
  107. package/assess/lsa/examples/eval-run-6/gptoss-b/mass-assignment.candidates.json +232 -0
  108. package/assess/lsa/examples/eval-run-6/gptoss-b/routes/routes-001.json +425 -0
  109. package/assess/lsa/examples/eval-run-6/gptoss-b/routes/routes-002.json +333 -0
  110. package/assess/lsa/examples/eval-run-6/gptoss-b/routes/routes-003.json +400 -0
  111. package/assess/lsa/examples/eval-run-6/gptoss-b/routes/routes-004.json +403 -0
  112. package/assess/lsa/examples/eval-run-6/gptoss-b/routes/routes-005.json +398 -0
  113. package/assess/lsa/examples/eval-run-6/gptoss-b/routes/routes-006.json +63 -0
  114. package/assess/lsa/examples/eval-run-6/gptoss-b/score.json +87 -0
  115. package/assess/lsa/examples/eval-run-6/gptoss-b/stack-profile.json +225 -0
  116. package/assess/lsa/examples/eval-run-6/ground-truth.json +851 -0
  117. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/ai-run-stats.json +96 -0
  118. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/auth-model.md +191 -0
  119. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/index.json +60 -0
  120. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/injection-001.json +383 -0
  121. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/injection-002.json +205 -0
  122. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/privilege-001.json +838 -0
  123. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/privilege-002.json +124 -0
  124. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/routes-001.json +778 -0
  125. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/routes-002.json +546 -0
  126. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/routes-003.json +661 -0
  127. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/routes-004.json +659 -0
  128. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/routes-005.json +612 -0
  129. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/routes-006.json +106 -0
  130. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/coverage.json +31 -0
  131. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/bola-routes-001.json +527 -0
  132. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/bola-routes-002.json +568 -0
  133. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/bola-routes-003.json +467 -0
  134. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/bola-routes-004.json +342 -0
  135. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/bola-routes-005.json +693 -0
  136. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/bola-routes-006.json +16 -0
  137. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/inj-injection-001.json +1123 -0
  138. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/inj-injection-002.json +391 -0
  139. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/priv-privilege-001.json +726 -0
  140. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/priv-privilege-002.json +306 -0
  141. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-1.json +137 -0
  142. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-10.json +106 -0
  143. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-11.json +81 -0
  144. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-12.json +135 -0
  145. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-13.json +135 -0
  146. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-14.json +135 -0
  147. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-15.json +110 -0
  148. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-16.json +116 -0
  149. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-17.json +141 -0
  150. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-18.json +135 -0
  151. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-19.json +140 -0
  152. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-2.json +135 -0
  153. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-20.json +82 -0
  154. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-21.json +74 -0
  155. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-22.json +99 -0
  156. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-3.json +140 -0
  157. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-4.json +145 -0
  158. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-5.json +135 -0
  159. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-6.json +135 -0
  160. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-7.json +87 -0
  161. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-8.json +125 -0
  162. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-9.json +135 -0
  163. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings.json +6989 -0
  164. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/mass-assignment.candidates.json +232 -0
  165. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/memory.log +36 -0
  166. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/routes/routes-001.json +425 -0
  167. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/routes/routes-002.json +333 -0
  168. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/routes/routes-003.json +400 -0
  169. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/routes/routes-004.json +403 -0
  170. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/routes/routes-005.json +398 -0
  171. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/routes/routes-006.json +63 -0
  172. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/score.json +106 -0
  173. package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/stack-profile.json +225 -0
  174. package/assess/lsa/examples/eval-run-6/qwen-16k-partial/auth-model.md +517 -0
  175. package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/bola-routes-001.json +5 -0
  176. package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/bola-routes-002.json +428 -0
  177. package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/bola-routes-003.json +388 -0
  178. package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/bola-routes-004.json +463 -0
  179. package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/bola-routes-005.json +5 -0
  180. package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/bola-routes-006.json +67 -0
  181. package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/inj-injection-001.json +964 -0
  182. package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings.partial.json +1872 -0
  183. package/assess/lsa/examples/eval-run-6/qwen-16k-partial/memory.log +194 -0
  184. package/assess/lsa/examples/eval-run-6/qwen-16k-partial/score.partial.json +108 -0
  185. package/assess/lsa/examples/eval-run-6/qwen-16k-partial/stack-profile.json +225 -0
  186. package/assess/lsa/scripts/laravel_routes.py +102 -0
  187. package/assess/lsa/scripts/map_routes.py +4 -1
  188. package/assess/lsa/tests/EVAL-RESULTS.md +126 -0
  189. package/assess/lsa/tests/test_eval_run_6.py +104 -0
  190. package/assess/lsa/tests/test_laravel_routes.py +95 -0
  191. package/examples/member-portal/backend-dotnet/Auth/DemoAuthenticationHandler.cs +75 -0
  192. package/examples/member-portal/backend-dotnet/Program.cs +1 -72
  193. package/examples/member-portal/backend-spring/src/main/kotlin/io/komagu/portal/Application.kt +4 -0
  194. package/examples/member-portal/backend-spring/src/main/kotlin/io/komagu/portal/controller/Controllers.kt +3 -0
  195. package/examples/member-portal/backend-spring/src/main/kotlin/io/komagu/portal/model/Entities.kt +4 -0
  196. package/examples/member-portal/tests/test_d6_demo_app.py +4 -4
  197. package/examples/member-portal/tests/test_d6_remediation_verification.py +6 -6
  198. package/operate/ai/client.py +27 -10
  199. package/operate/ai/runner.py +4 -2
  200. package/operate/cli/__init__.py +1 -1
  201. package/operate/cli/commands/scan.py +8 -1
  202. package/operate/cross_user_tester/runner.py +4 -1
  203. package/operate/devsecops/sbom.py +12 -4
  204. package/operate/simulate/scenarios.py +11 -2
  205. package/operate/tests/test_ai_reasoning_effort.py +65 -0
  206. package/operate/tests/test_ai_route_inventory.py +53 -0
  207. package/operate/tests/test_audit_minimum_versions.py +89 -0
  208. package/operate/tests/test_cli.py +1 -1
  209. package/operate/tests/test_scheme_and_xml_guards.py +67 -0
  210. package/package.json +1 -1
  211. package/remediate/authz/dotnet/src/Komagu.Security.Authorization/LoggingSecurityAuditSink.cs +19 -3
  212. package/remediate/authz/golang/authz_test.go +5 -2
  213. package/remediate/authz/spring/src/main/kotlin/io/komagu/security/authorization/DefaultKomaguSecurityManager.kt +74 -78
  214. package/remediate/authz/spring/src/main/kotlin/io/komagu/security/spring/OwnershipAspect.kt +129 -158
  215. package/remediate/deps/patcher.py +2 -1
  216. package/remediate/edge/mock-backend/app.py +2 -1
  217. package/remediate/edge/tests/test_edge_security.py +5 -5
  218. package/remediate/ekyc/requirements.txt +1 -1
  219. package/remediate/identity/dotnet/src/Komagu.Security.Identity/OidcServiceCollectionExtensions.cs +19 -6
  220. package/remediate/identity/python/requirements.txt +2 -2
  221. package/remediate/identity/spring/src/main/kotlin/io/komagu/security/identity/KomaguIdentityAutoConfiguration.kt +31 -38
  222. package/remediate/legacy_shims/tests/test_legacy_shims.py +8 -8
  223. package/remediate/query/dotnet/src/Komagu.Security.Query/SafeSortAllowList.cs +5 -2
  224. package/remediate/query/spring/src/main/kotlin/io/komagu/security/query/SafeSortAllowList.kt +10 -11
  225. package/remediate/query/spring/src/main/kotlin/io/komagu/security/query/detekt/StringBuiltSqlQueryRule.kt +19 -24
@@ -0,0 +1,194 @@
1
+ 09:52:36 swap=4035.12M compr_pages=64881.
2
+ 09:53:36 swap=3979.12M compr_pages=59199. qwen3.5:9b-16k df9cabffde69 7.7 GB 100% GPU 16384 mlx 4 minutes from now
3
+ 09:54:36 swap=3979.12M compr_pages=54490. qwen3.5:9b-16k df9cabffde69 7.7 GB 100% GPU 16384 mlx 4 minutes from now
4
+ 09:55:37 swap=3947.12M compr_pages=50800. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx 4 minutes from now
5
+ 09:56:37 swap=3907.12M compr_pages=44875. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx 3 minutes from now
6
+ 09:57:37 swap=3883.12M compr_pages=41637. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx 2 minutes from now
7
+ 09:58:37 swap=3883.12M compr_pages=41241. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx About a minute from now
8
+ 09:59:37 swap=3883.12M compr_pages=40752. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx 19 seconds from now
9
+ 10:00:37 swap=3859.12M compr_pages=40148. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
10
+ 10:01:37 swap=3859.12M compr_pages=39241. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
11
+ 10:02:37 swap=3859.12M compr_pages=39063. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
12
+ 10:03:37 swap=3859.12M compr_pages=38927. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
13
+ 10:04:37 swap=3859.12M compr_pages=38809. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
14
+ 10:05:37 swap=3859.12M compr_pages=38871. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
15
+ 10:06:38 swap=3859.12M compr_pages=38172. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
16
+ 10:07:38 swap=3859.12M compr_pages=37902. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
17
+ 10:08:38 swap=3859.12M compr_pages=37864. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
18
+ 10:09:38 swap=3859.12M compr_pages=37889. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
19
+ 10:10:38 swap=3859.12M compr_pages=37644. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
20
+ 10:11:38 swap=3851.12M compr_pages=37970. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
21
+ 10:12:38 swap=3843.12M compr_pages=65044. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
22
+ 10:13:38 swap=3843.12M compr_pages=64971. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
23
+ 10:14:38 swap=3827.12M compr_pages=64578. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
24
+ 10:15:38 swap=3827.12M compr_pages=64150. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
25
+ 10:16:38 swap=3819.12M compr_pages=62677. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
26
+ 10:17:39 swap=3811.12M compr_pages=96962. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
27
+ 10:18:39 swap=3878.06M compr_pages=112102. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
28
+ 10:19:39 swap=3878.06M compr_pages=103797. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
29
+ 10:20:39 swap=3878.06M compr_pages=114963. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
30
+ 10:21:39 swap=3878.06M compr_pages=110533. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
31
+ 10:22:39 swap=3878.06M compr_pages=273980. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
32
+ 10:23:39 swap=3870.06M compr_pages=211233. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
33
+ 10:24:39 swap=3870.06M compr_pages=108526. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
34
+ 10:25:39 swap=3870.06M compr_pages=118798. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
35
+ 10:26:39 swap=4004.38M compr_pages=101431. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
36
+ 10:27:40 swap=4089.06M compr_pages=84737. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
37
+ 10:28:40 swap=4204.50M compr_pages=75464. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
38
+ 10:29:40 swap=4196.50M compr_pages=78904. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
39
+ 10:30:40 swap=4180.50M compr_pages=77700. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
40
+ 10:31:40 swap=4148.50M compr_pages=87928. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
41
+ 10:32:40 swap=4399.19M compr_pages=72290. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
42
+ 10:33:40 swap=4367.19M compr_pages=80804. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
43
+ 10:34:40 swap=4359.19M compr_pages=81899. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
44
+ 10:35:40 swap=4359.19M compr_pages=82155. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
45
+ 10:36:40 swap=4343.19M compr_pages=79847. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
46
+ 10:37:41 swap=4327.19M compr_pages=83183. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
47
+ 10:38:41 swap=4311.19M compr_pages=85176. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
48
+ 10:39:41 swap=4311.19M compr_pages=79893. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
49
+ 10:40:41 swap=4303.19M compr_pages=89396. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
50
+ 10:41:41 swap=4303.19M compr_pages=84304. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
51
+ 10:42:41 swap=4279.19M compr_pages=92256. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
52
+ 10:43:41 swap=4255.19M compr_pages=95541. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
53
+ 10:44:41 swap=4255.19M compr_pages=93634. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
54
+ 10:45:41 swap=4255.19M compr_pages=91721. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
55
+ 10:46:41 swap=4566.44M compr_pages=84918. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
56
+ 10:47:41 swap=4566.44M compr_pages=79129. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
57
+ 10:48:42 swap=4550.44M compr_pages=82408. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
58
+ 10:49:42 swap=4542.44M compr_pages=74890. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
59
+ 10:50:42 swap=4518.44M compr_pages=77523. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
60
+ 10:51:42 swap=4510.44M compr_pages=78731. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
61
+ 10:52:42 swap=4494.44M compr_pages=74023. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
62
+ 10:53:42 swap=4494.44M compr_pages=82684. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
63
+ 10:54:42 swap=4494.44M compr_pages=78663. qwen3.5:9b-16k df9cabffde69 8.1 GB 100% GPU 16384 mlx Stopping...
64
+ 10:55:42 swap=5654.31M compr_pages=263663. qwen3.5:9b-16k df9cabffde69 13 GB 100% GPU 16384 mlx 4 minutes from now
65
+ 10:56:42 swap=5707.38M compr_pages=323390. qwen3.5:9b-16k df9cabffde69 13 GB 100% GPU 16384 mlx 3 minutes from now
66
+ 10:57:42 swap=5776.06M compr_pages=324464. qwen3.5:9b-16k df9cabffde69 13 GB 100% GPU 16384 mlx 2 minutes from now
67
+ 10:58:43 swap=5813.00M compr_pages=320503. qwen3.5:9b-16k df9cabffde69 13 GB 100% GPU 16384 mlx About a minute from now
68
+ 10:59:43 swap=5816.88M compr_pages=322897. qwen3.5:9b-16k df9cabffde69 13 GB 100% GPU 16384 mlx 13 seconds from now
69
+ 11:00:43 swap=7483.56M compr_pages=212605. qwen3.5:9b-16k df9cabffde69 18 GB 100% GPU 16384 mlx 4 minutes from now
70
+ 11:01:43 swap=7139.56M compr_pages=208222. qwen3.5:9b-16k df9cabffde69 18 GB 100% GPU 16384 mlx 3 minutes from now
71
+ 11:02:43 swap=7075.56M compr_pages=255099. qwen3.5:9b-16k df9cabffde69 18 GB 100% GPU 16384 mlx 2 minutes from now
72
+ 11:03:43 swap=8078.19M compr_pages=187260. qwen3.5:9b-16k df9cabffde69 19 GB 100% GPU 16384 mlx 4 minutes from now
73
+ 11:04:43 swap=8038.19M compr_pages=173358. qwen3.5:9b-16k df9cabffde69 19 GB 100% GPU 16384 mlx 3 minutes from now
74
+ 11:05:43 swap=8367.44M compr_pages=207183. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 4 minutes from now
75
+ 11:06:43 swap=8487.00M compr_pages=204468. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 3 minutes from now
76
+ 11:07:43 swap=8455.00M compr_pages=232246. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 2 minutes from now
77
+ 11:08:44 swap=8447.00M compr_pages=239444. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx About a minute from now
78
+ 11:09:44 swap=8439.00M compr_pages=242980. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 47 seconds from now
79
+ 11:10:44 swap=8415.00M compr_pages=246253. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
80
+ 11:11:44 swap=8382.94M compr_pages=245169. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
81
+ 11:12:44 swap=8382.94M compr_pages=244120. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
82
+ 11:13:44 swap=8382.94M compr_pages=249119. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
83
+ 11:14:44 swap=8382.94M compr_pages=252691. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
84
+ 11:15:44 swap=8350.94M compr_pages=249009. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
85
+ 11:16:44 swap=8238.88M compr_pages=266646. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
86
+ 11:17:44 swap=8238.88M compr_pages=256759. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
87
+ 11:18:45 swap=8238.88M compr_pages=265588. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
88
+ 11:19:45 swap=8230.88M compr_pages=255995. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
89
+ 11:20:45 swap=8230.88M compr_pages=258677. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
90
+ 11:21:45 swap=8182.88M compr_pages=261018. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
91
+ 11:22:45 swap=8182.88M compr_pages=266870. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
92
+ 11:23:45 swap=8174.88M compr_pages=267543. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
93
+ 11:24:45 swap=8174.88M compr_pages=263850. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
94
+ 11:25:45 swap=8174.88M compr_pages=266616. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
95
+ 11:26:45 swap=8386.25M compr_pages=255322. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
96
+ 11:27:45 swap=8378.25M compr_pages=252580. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
97
+ 11:28:46 swap=8354.19M compr_pages=263380. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
98
+ 11:29:46 swap=8346.19M compr_pages=263499. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
99
+ 11:30:46 swap=8346.19M compr_pages=263068. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
100
+ 11:31:46 swap=8346.19M compr_pages=263143. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
101
+ 11:32:46 swap=8338.19M compr_pages=262997. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
102
+ 11:33:46 swap=8322.19M compr_pages=261590. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
103
+ 11:34:46 swap=8470.81M compr_pages=256655. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
104
+ 11:35:46 swap=8470.81M compr_pages=255705. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
105
+ 11:36:46 swap=8470.81M compr_pages=262981. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
106
+ 11:37:46 swap=8454.81M compr_pages=259862. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
107
+ 11:38:47 swap=8454.81M compr_pages=266087. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
108
+ 11:39:47 swap=8454.81M compr_pages=268642. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
109
+ 11:40:47 swap=8430.81M compr_pages=268974. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
110
+ 11:41:47 swap=8398.81M compr_pages=261050. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
111
+ 11:42:47 swap=8390.81M compr_pages=260495. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
112
+ 11:43:47 swap=8390.81M compr_pages=261952. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
113
+ 11:44:47 swap=8374.81M compr_pages=269987. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
114
+ 11:45:47 swap=8444.56M compr_pages=257446. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
115
+ 11:46:47 swap=8444.56M compr_pages=252521. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
116
+ 11:47:47 swap=8444.56M compr_pages=242793. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
117
+ 11:48:48 swap=8444.56M compr_pages=240203. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
118
+ 11:49:48 swap=8444.56M compr_pages=240607. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
119
+ 11:50:48 swap=8436.56M compr_pages=233075. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
120
+ 11:51:48 swap=8428.56M compr_pages=241779. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
121
+ 11:52:48 swap=8420.56M compr_pages=238934. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
122
+ 11:53:48 swap=8420.56M compr_pages=247984. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
123
+ 11:54:48 swap=8420.56M compr_pages=250233. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
124
+ 11:55:48 swap=8583.25M compr_pages=240525. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
125
+ 11:56:48 swap=8559.25M compr_pages=231459. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
126
+ 11:57:48 swap=8551.25M compr_pages=226095. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
127
+ 11:58:48 swap=8551.25M compr_pages=233797. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
128
+ 11:59:49 swap=8551.25M compr_pages=232769. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
129
+ 12:00:49 swap=8551.25M compr_pages=239418. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
130
+ 12:01:49 swap=8551.25M compr_pages=241936. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
131
+ 12:02:49 swap=8551.25M compr_pages=245847. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
132
+ 12:03:49 swap=8543.25M compr_pages=271885. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
133
+ 12:04:49 swap=8543.25M compr_pages=248811. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
134
+ 12:05:49 swap=8543.25M compr_pages=255818. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 4 minutes from now
135
+ 12:06:49 swap=8837.06M compr_pages=232600. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 4 minutes from now
136
+ 12:07:49 swap=8854.31M compr_pages=228016. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 3 minutes from now
137
+ 12:08:49 swap=12038.00M compr_pages=316416. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 2 minutes from now
138
+ 12:09:50 swap=12288.12M compr_pages=291532. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx About a minute from now
139
+ 12:10:50 swap=12250.38M compr_pages=312140. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 27 seconds from now
140
+ 12:11:50 swap=12313.62M compr_pages=316165. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
141
+ 12:12:50 swap=12352.12M compr_pages=315953. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
142
+ 12:13:50 swap=12389.81M compr_pages=315281. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
143
+ 12:14:50 swap=12404.06M compr_pages=314409. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
144
+ 12:15:50 swap=12438.69M compr_pages=311168. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
145
+ 12:16:50 swap=12316.19M compr_pages=308629. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
146
+ 12:17:50 swap=11164.38M compr_pages=79429. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 4 minutes from now
147
+ 12:18:50 swap=11100.38M compr_pages=77184. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 3 minutes from now
148
+ 12:19:51 swap=11092.38M compr_pages=68750. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 2 minutes from now
149
+ 12:20:51 swap=11084.38M compr_pages=68730. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx 59 seconds from now
150
+ 12:21:51 swap=11076.38M compr_pages=66627. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
151
+ 12:22:51 swap=11060.38M compr_pages=66576. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
152
+ 12:23:51 swap=11060.38M compr_pages=66588. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
153
+ 12:24:51 swap=11060.38M compr_pages=66461. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
154
+ 12:25:51 swap=11060.38M compr_pages=66325. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
155
+ 12:26:51 swap=10924.38M compr_pages=117118. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
156
+ 12:27:51 swap=10876.38M compr_pages=218682. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
157
+ 12:28:51 swap=10876.38M compr_pages=193343. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
158
+ 12:29:52 swap=10876.38M compr_pages=187670. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
159
+ 12:30:52 swap=10876.38M compr_pages=183000. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
160
+ 12:31:52 swap=10868.38M compr_pages=179572. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
161
+ 12:32:52 swap=10860.38M compr_pages=179008. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
162
+ 12:33:52 swap=10860.38M compr_pages=178277. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
163
+ 12:34:52 swap=10860.38M compr_pages=177567. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
164
+ 12:35:52 swap=10860.38M compr_pages=177159. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
165
+ 12:36:52 swap=10860.38M compr_pages=182111. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
166
+ 12:37:52 swap=10852.38M compr_pages=180857. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
167
+ 12:38:52 swap=10852.38M compr_pages=178757. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
168
+ 12:39:52 swap=10852.38M compr_pages=181546. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
169
+ 12:40:53 swap=10844.38M compr_pages=180632. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
170
+ 12:41:53 swap=10836.38M compr_pages=176393. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
171
+ 12:42:53 swap=10836.38M compr_pages=178288. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
172
+ 12:43:53 swap=10836.38M compr_pages=177971. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
173
+ 12:44:53 swap=10836.38M compr_pages=177447. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
174
+ 12:45:53 swap=10836.38M compr_pages=176680. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
175
+ 12:46:53 swap=10836.38M compr_pages=175175. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
176
+ 12:47:53 swap=10804.38M compr_pages=184445. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
177
+ 12:48:53 swap=10804.38M compr_pages=185046. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
178
+ 12:49:53 swap=10804.38M compr_pages=184982. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
179
+ 12:50:54 swap=10788.38M compr_pages=186393. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
180
+ 12:51:54 swap=10780.38M compr_pages=189058. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
181
+ 12:52:54 swap=10780.38M compr_pages=191830. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
182
+ 12:53:54 swap=10780.38M compr_pages=190764. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
183
+ 12:54:54 swap=10780.38M compr_pages=190909. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
184
+ 12:55:54 swap=10780.38M compr_pages=193410. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
185
+ 12:56:54 swap=10772.38M compr_pages=189663. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
186
+ 12:57:54 swap=10772.38M compr_pages=189032. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
187
+ 12:58:54 swap=10772.38M compr_pages=194076. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
188
+ 12:59:54 swap=10764.38M compr_pages=195139. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
189
+ 13:00:54 swap=10764.38M compr_pages=184071. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
190
+ 13:01:55 swap=10764.38M compr_pages=183065. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
191
+ 13:02:55 swap=10756.38M compr_pages=178916. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
192
+ 13:03:55 swap=10756.38M compr_pages=176942. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
193
+ 13:04:55 swap=10756.38M compr_pages=179105. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
194
+ 13:05:55 swap=10756.38M compr_pages=172865. qwen3.5:9b-16k df9cabffde69 20 GB 100% GPU 16384 mlx Stopping...
@@ -0,0 +1,108 @@
1
+ {
2
+ "per_category": {
3
+ "bola": {
4
+ "truth_vulnerable": 29,
5
+ "found": 12,
6
+ "recall": 0.414,
7
+ "false_positive_on_safe_code": [],
8
+ "missed": [
9
+ "java-legacy/WebContent/order/detail.jsp:5",
10
+ "java-legacy/src/com/acme/struts/EditUserAction.java:13",
11
+ "java-legacy/src/com/acme/web/InvoiceController.java:29",
12
+ "perl-cgi/cgi-bin/order.cgi:19",
13
+ "dotnet-legacy/Web/Orders/EditOrder.aspx.vb:8",
14
+ "dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:13",
15
+ "dotnet-legacy/Web/Controllers/CustomerController.cs:29",
16
+ "dotnet-legacy/Web/Controllers/InvoiceController.cs:13",
17
+ "dotnet-legacy/Web/Controllers/InvoiceController.cs:28",
18
+ "dotnet-legacy/Web/Handlers/GetFile.ashx:10",
19
+ "python-flask/profile.py:18",
20
+ "python-flask/profile.py:26",
21
+ "classic-asp/shop/member.asp:7",
22
+ "classic-asp/shop/member.asp:10",
23
+ "classic-asp/shop/order.asp:6",
24
+ "coldfusion/app/OrderService.cfc:5",
25
+ "coldfusion/app/order.cfm:3"
26
+ ]
27
+ },
28
+ "injection": {
29
+ "truth_vulnerable": 34,
30
+ "found": 22,
31
+ "recall": 0.647,
32
+ "false_positive_on_safe_code": [],
33
+ "missed": [
34
+ "php-plain/order_detail.php:6",
35
+ "php-plain/search.php:8",
36
+ "php-plain/search.php:9",
37
+ "php-plain/search.php:14",
38
+ "java-legacy/src/com/acme/web/OrderServlet.java:15",
39
+ "java-legacy/src/com/acme/web/OrderServlet.java:17",
40
+ "java-legacy/src/com/acme/mapper/OrderMapper.xml:9",
41
+ "dotnet-legacy/Web/Controllers/InvoiceController.cs:28",
42
+ "python-flask/app.py:29",
43
+ "php-codeigniter/application/controllers/Invoice.php:10",
44
+ "sql-procs/sp_search_orders.sql:5",
45
+ "sql-procs/sp_search_orders.sql:6"
46
+ ]
47
+ },
48
+ "bfla": {
49
+ "truth_vulnerable": 10,
50
+ "found": 0,
51
+ "recall": 0.0,
52
+ "false_positive_on_safe_code": [],
53
+ "missed": [
54
+ "php-plain/admin.php:8",
55
+ "php-plain/admin.php:12",
56
+ "php-plain/manage_users.php:6",
57
+ "php-plain/admin/delete_user.php:6",
58
+ "php-plain/admin/promote.php:5",
59
+ "java-legacy/src/com/acme/web/AdminUserController.java:15",
60
+ "dotnet-legacy/Web/Controllers/AdminController.cs:15",
61
+ "dotnet-legacy/Web/Controllers/AdminController.cs:32",
62
+ "node-express/routes/admin.js:9",
63
+ "node-express/routes/admin.js:17"
64
+ ]
65
+ },
66
+ "mass_assignment": {
67
+ "truth_vulnerable": 15,
68
+ "found": 0,
69
+ "recall": 0.0,
70
+ "false_positive_on_safe_code": [],
71
+ "missed": [
72
+ "php-plain/profile.php:6",
73
+ "php-plain/profile.php:10",
74
+ "php-plain/register.php:4",
75
+ "java-legacy/src/com/acme/web/AccountController.java:14",
76
+ "java-legacy/src/com/acme/web/AccountController.java:27",
77
+ "java-legacy/src/com/acme/web/ProfileServlet.java:12",
78
+ "php-laravel/app/Http/Controllers/AccountController.php:13",
79
+ "php-laravel/app/Http/Controllers/AccountController.php:23",
80
+ "php-laravel/app/Http/Controllers/AccountController.php:36",
81
+ "dotnet-legacy/Web/Controllers/CustomerController.cs:12",
82
+ "dotnet-legacy/Web/Controllers/CustomerController.cs:30",
83
+ "python-flask/profile.py:10",
84
+ "python-flask/profile.py:27",
85
+ "node-express/routes/profile.js:8",
86
+ "node-express/routes/profile.js:16"
87
+ ]
88
+ }
89
+ },
90
+ "active_findings": 45,
91
+ "matched_findings": 33,
92
+ "precision": 0.733,
93
+ "unmatched_findings": [
94
+ "BOLA-R-0020-1",
95
+ "BOLA-R-0022-1",
96
+ "BOLA-R-0023-1",
97
+ "BOLA-R-0030-1",
98
+ "BOLA-R-0032-1",
99
+ "BOLA-R-0035-1",
100
+ "BOLA-R-0066-1",
101
+ "BOLA-R-0067-1",
102
+ "BOLA-R-0059-1",
103
+ "BOLA-R-0055-verdict",
104
+ "BOLA-R-0056-verdict",
105
+ "BOLA-R-0065-1"
106
+ ],
107
+ "needs_review_not_scored": []
108
+ }
@@ -0,0 +1,225 @@
1
+ {
2
+ "repo": "repo",
3
+ "generated_by": "lsa detect_stack.py 0.3.1",
4
+ "stacks": [
5
+ {
6
+ "id": "php",
7
+ "language": "php",
8
+ "version_hint": null,
9
+ "evidence": [
10
+ "20 file(s) with extension .php, .php3, .php4, .php5, .phtml"
11
+ ],
12
+ "confirmed": false
13
+ },
14
+ {
15
+ "id": "php-codeigniter",
16
+ "language": "php",
17
+ "version_hint": null,
18
+ "evidence": [
19
+ "marker file php-codeigniter/system/core/CodeIgniter.php"
20
+ ],
21
+ "confirmed": false
22
+ },
23
+ {
24
+ "id": "php-laravel",
25
+ "language": "php",
26
+ "version_hint": null,
27
+ "evidence": [
28
+ "pattern /Route::(get|post|put|delete|any|match|re/ in php-laravel/routes/web.php"
29
+ ],
30
+ "confirmed": false
31
+ },
32
+ {
33
+ "id": "java-servlet",
34
+ "language": "java",
35
+ "version_hint": null,
36
+ "evidence": [
37
+ "marker file java-legacy/WebContent/WEB-INF/web.xml",
38
+ "pattern /extends\\s+HttpServlet|@WebServlet/ in java-legacy/src/com/acme/web/OrderServlet.java",
39
+ "pattern /extends\\s+HttpServlet|@WebServlet/ in java-legacy/src/com/acme/web/ProfileServlet.java"
40
+ ],
41
+ "confirmed": false
42
+ },
43
+ {
44
+ "id": "java-jsp",
45
+ "language": "java",
46
+ "version_hint": null,
47
+ "evidence": [
48
+ "1 file(s) with extension .jsp, .jspf"
49
+ ],
50
+ "confirmed": false
51
+ },
52
+ {
53
+ "id": "java-struts1",
54
+ "language": "java",
55
+ "version_hint": null,
56
+ "evidence": [
57
+ "marker file java-legacy/WebContent/WEB-INF/struts-config.xml",
58
+ "pattern /extends\\s+(Dispatch|LookupDispatch|Mappi/ in java-legacy/src/com/acme/struts/EditUserAction.java"
59
+ ],
60
+ "confirmed": false
61
+ },
62
+ {
63
+ "id": "java-spring-mvc",
64
+ "language": "java",
65
+ "version_hint": null,
66
+ "evidence": [
67
+ "pattern /@(Controller|RestController)\\b|@RequestM/ in java-legacy/src/com/acme/web/AccountController.java",
68
+ "pattern /@(Controller|RestController)\\b|@RequestM/ in java-legacy/src/com/acme/web/AdminUserController.java",
69
+ "pattern /@(Controller|RestController)\\b|@RequestM/ in java-legacy/src/com/acme/web/InvoiceController.java"
70
+ ],
71
+ "confirmed": false
72
+ },
73
+ {
74
+ "id": "java-mybatis",
75
+ "language": "java",
76
+ "version_hint": null,
77
+ "evidence": [
78
+ "pattern /<mapper\\s+namespace=|org\\.apache\\.ibatis/ in java-legacy/src/com/acme/mapper/OrderMapper.xml"
79
+ ],
80
+ "confirmed": false
81
+ },
82
+ {
83
+ "id": "java-hibernate",
84
+ "language": "java",
85
+ "version_hint": null,
86
+ "evidence": [
87
+ "pattern /org\\.hibernate\\.(?!validator\\b)|\\.hbm\\.x/ in java-legacy/src/com/acme/web/InvoiceController.java"
88
+ ],
89
+ "confirmed": false
90
+ },
91
+ {
92
+ "id": "dotnet-webforms",
93
+ "language": "csharp/vbnet",
94
+ "version_hint": null,
95
+ "evidence": [
96
+ "2 file(s) with extension .ascx, .aspx"
97
+ ],
98
+ "confirmed": false
99
+ },
100
+ {
101
+ "id": "dotnet-handlers",
102
+ "language": "csharp/vbnet",
103
+ "version_hint": null,
104
+ "evidence": [
105
+ "1 file(s) with extension .ashx"
106
+ ],
107
+ "confirmed": false
108
+ },
109
+ {
110
+ "id": "dotnet-mvc",
111
+ "language": "csharp/vbnet",
112
+ "version_hint": null,
113
+ "evidence": [
114
+ "pattern /:\\s*(ControllerBase|Controller)\\b|Inheri/ in dotnet-legacy/Web/Controllers/AdminController.cs",
115
+ "pattern /:\\s*(ControllerBase|Controller)\\b|Inheri/ in dotnet-legacy/Web/Controllers/CustomerController.cs",
116
+ "pattern /:\\s*(ControllerBase|Controller)\\b|Inheri/ in dotnet-legacy/Web/Controllers/InvoiceController.cs"
117
+ ],
118
+ "confirmed": false
119
+ },
120
+ {
121
+ "id": "classic-asp",
122
+ "language": "vbscript",
123
+ "version_hint": null,
124
+ "evidence": [
125
+ "4 file(s) with extension .asa, .asp"
126
+ ],
127
+ "confirmed": false
128
+ },
129
+ {
130
+ "id": "perl-cgi",
131
+ "language": "perl",
132
+ "version_hint": null,
133
+ "evidence": [
134
+ "1 file(s) with extension .cgi",
135
+ "pattern /use\\s+CGI\\b|CGI->new|use\\s+DBI\\b/ in perl-cgi/cgi-bin/order.cgi"
136
+ ],
137
+ "confirmed": false
138
+ },
139
+ {
140
+ "id": "coldfusion",
141
+ "language": "cfml",
142
+ "version_hint": null,
143
+ "evidence": [
144
+ "2 file(s) with extension .cfc, .cfm, .cfml"
145
+ ],
146
+ "confirmed": false
147
+ },
148
+ {
149
+ "id": "node-express",
150
+ "language": "javascript",
151
+ "version_hint": null,
152
+ "evidence": [
153
+ "pattern /require\\(\\s*['\\\"]express['\\\"]\\s*\\)|from\\/ in node-express/routes/admin.js",
154
+ "pattern /require\\(\\s*['\\\"]express['\\\"]\\s*\\)|from\\/ in node-express/routes/orders.js",
155
+ "pattern /require\\(\\s*['\\\"]express['\\\"]\\s*\\)|from\\/ in node-express/routes/profile.js"
156
+ ],
157
+ "confirmed": false
158
+ },
159
+ {
160
+ "id": "python-flask",
161
+ "language": "python",
162
+ "version_hint": null,
163
+ "evidence": [
164
+ "pattern /from\\s+flask\\s+import|import\\s+flask/ in python-flask/app.py",
165
+ "pattern /from\\s+flask\\s+import|import\\s+flask/ in python-flask/profile.py"
166
+ ],
167
+ "confirmed": false
168
+ },
169
+ {
170
+ "id": "sql-procedures",
171
+ "language": "sql",
172
+ "version_hint": null,
173
+ "evidence": [
174
+ "pattern /(?i)create\\s+(or\\s+replace\\s+)?proc(edur/ in sql-procs/sp_search_orders.sql"
175
+ ],
176
+ "confirmed": false
177
+ }
178
+ ],
179
+ "data_access": [
180
+ "JDBC",
181
+ "mysql_* (no binding)",
182
+ "ColdFusion cfquery",
183
+ "Entity Framework / LINQ to SQL",
184
+ "ADO.NET",
185
+ "Hibernate/JPA",
186
+ "Classic ADO",
187
+ "MyBatis/iBATIS",
188
+ "Perl DBI",
189
+ "MongoDB",
190
+ "PDO"
191
+ ],
192
+ "databases": [
193
+ "MySQL",
194
+ "SQL Server",
195
+ "MongoDB"
196
+ ],
197
+ "file_counts": {
198
+ ".php": 20,
199
+ ".java": 7,
200
+ ".cs": 5,
201
+ ".asp": 4,
202
+ ".xml": 3,
203
+ ".js": 3,
204
+ ".aspx": 2,
205
+ ".py": 2,
206
+ ".cfc": 1,
207
+ ".cfm": 1,
208
+ ".config": 1,
209
+ ".ashx": 1,
210
+ ".vb": 1,
211
+ ".jsp": 1,
212
+ ".cgi": 1,
213
+ ".sql": 1
214
+ },
215
+ "knowledge_files": [
216
+ "knowledge/stacks/php.md",
217
+ "knowledge/stacks/java.md",
218
+ "knowledge/stacks/dotnet.md",
219
+ "knowledge/stacks/classic-asp.md",
220
+ "knowledge/stacks/perl-cgi.md",
221
+ "knowledge/stacks/coldfusion.md",
222
+ "knowledge/stacks/node-python-ruby.md"
223
+ ],
224
+ "notes": "Heuristic result. The stack-detector agent must confirm each item."
225
+ }
@@ -0,0 +1,102 @@
1
+ """Resolve Laravel route declarations to the controller method that handles them (#380).
2
+
3
+ `Route::post('/x', [AccountController::class, 'register'])` is found in `routes/web.php`, but the
4
+ code an auditor needs is `AccountController::register`. Without this step every Laravel route
5
+ pointed at its declaration line, so the auditors read the route file and never the controller.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import re
10
+ from pathlib import Path
11
+ from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple
12
+
13
+ from lsa_common import line_of, read_text
14
+
15
+ # [XController::class, 'method'] or 'XController@method' / 'App\Http\Controllers\XController@method'
16
+ ROUTE_ACTION = re.compile(
17
+ r"\[\s*\\?([\w\\]+)::class\s*,\s*['\"](\w+)['\"]\s*\]"
18
+ r"|['\"]\\?([\w\\]+)@(\w+)['\"]"
19
+ )
20
+ PHP_FUNCTION = re.compile(
21
+ r"^[ \t]*(?:(?:public|protected|private|static|final|abstract)\s+)*function\s+&?(\w+)\s*\(", re.M)
22
+
23
+
24
+ def route_action(stmt: str) -> Optional[str]:
25
+ """`Class@method` named by a Laravel route statement (class without namespace), or None."""
26
+ m = ROUTE_ACTION.search(stmt)
27
+ if not m:
28
+ return None
29
+ cls, method = (m.group(1), m.group(2)) if m.group(1) else (m.group(3), m.group(4))
30
+ return f"{cls.rsplit(chr(92), 1)[-1]}@{method}"
31
+
32
+
33
+ def php_class_index(rels: Iterable[str]) -> Dict[str, List[str]]:
34
+ """Map a PHP file's base name (the class name by PSR-4 convention) to every file with that name."""
35
+ index: Dict[str, List[str]] = {}
36
+ for rel in rels:
37
+ if rel.endswith(".php"):
38
+ index.setdefault(rel.rsplit("/", 1)[-1][:-4], []).append(rel)
39
+ return index
40
+
41
+
42
+ def find_method(text: str, cls: str, method: str) -> Optional[Tuple[int, int]]:
43
+ """(start, end) offsets of `method` in class `cls`, or None when the class or method is absent."""
44
+ if not re.search(rf"\bclass\s+{re.escape(cls)}\b", text):
45
+ return None
46
+ starts = list(PHP_FUNCTION.finditer(text))
47
+ for i, m in enumerate(starts):
48
+ if m.group(1) == method:
49
+ end = starts[i + 1].start() if i + 1 < len(starts) else len(text)
50
+ return m.start(), end
51
+ return None
52
+
53
+
54
+ def _merge(existing: List[Dict[str, Any]], extra: List[Dict[str, Any]],
55
+ key: Callable[[Dict[str, Any]], Any]) -> List[Dict[str, Any]]:
56
+ seen = {key(d) for d in existing}
57
+ return existing + [d for d in extra if key(d) not in seen]
58
+
59
+
60
+ def _locate(index: Dict[str, List[str]], texts: Dict[str, str], target: Path, enc: Any,
61
+ cls: str, method: str) -> Optional[Tuple[str, int, int]]:
62
+ for rel in index.get(cls, []):
63
+ if rel not in texts:
64
+ texts[rel] = read_text(target / rel, enc)
65
+ span = find_method(texts[rel], cls, method)
66
+ if span:
67
+ return rel, span[0], span[1]
68
+ return None
69
+
70
+
71
+ def resolve_laravel_handlers(items: List[Dict[str, Any]], target: Path, enc: Any, collector: Any,
72
+ rels: Iterable[str]) -> List[Dict[str, Any]]:
73
+ """Return items with Laravel routes pointed at their controller method, when it can be found.
74
+
75
+ Inputs, guard hints and data hints from the method body are added to those taken from the route
76
+ statement. A route whose controller or method is not in the repo keeps its declaration.
77
+ """
78
+ index = php_class_index(rels)
79
+ texts: Dict[str, str] = {}
80
+ out: List[Dict[str, Any]] = []
81
+ for it in items:
82
+ symbol = (it.get("handler") or {}).get("symbol") or ""
83
+ found = (_locate(index, texts, target, enc, *symbol.split("@", 1))
84
+ if it.get("stack") == "php-laravel" and "@" in symbol else None)
85
+ if not found:
86
+ out.append(it)
87
+ continue
88
+ rel, start, end = found
89
+ line = line_of(texts[rel], start)
90
+ body = texts[rel][start:end]
91
+ out.append({
92
+ **it,
93
+ "handler": {"file": rel, "line": line, "symbol": symbol},
94
+ "id_params": _merge(list(it.get("id_params") or []), collector.inputs("php", body, line),
95
+ lambda d: (d.get("name"), d.get("source"))),
96
+ "guard_hints": _merge(list(it.get("guard_hints") or []), collector.guards(body, line),
97
+ lambda d: d.get("hint")),
98
+ "data_hints": _merge(list(it.get("data_hints") or []), collector.data_ops(body, line),
99
+ lambda d: (d.get("op"), d.get("line"))),
100
+ "notes": f"declared in {it['handler']['file']}:{it['handler']['line']}",
101
+ })
102
+ return out