@memlab/mcp-server 2.18.1 → 2.86.0

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 (374) hide show
  1. package/README.md +30 -16
  2. package/bin/.eslintrc.js +26 -0
  3. package/bin/memlab-cli.js +313 -0
  4. package/dist/anonymized-snapshot.d.ts +75 -0
  5. package/dist/anonymized-snapshot.d.ts.map +1 -0
  6. package/dist/anonymized-snapshot.js +101 -0
  7. package/dist/anonymized-snapshot.js.map +1 -0
  8. package/dist/artifact-classes.d.ts +86 -0
  9. package/dist/artifact-classes.d.ts.map +1 -0
  10. package/dist/artifact-classes.js +261 -0
  11. package/dist/artifact-classes.js.map +1 -0
  12. package/dist/capture-mode.d.ts +60 -0
  13. package/dist/capture-mode.d.ts.map +1 -0
  14. package/dist/capture-mode.js +39 -0
  15. package/dist/capture-mode.js.map +1 -0
  16. package/dist/eval-hints.d.ts +41 -0
  17. package/dist/eval-hints.d.ts.map +1 -0
  18. package/dist/eval-hints.js +115 -0
  19. package/dist/eval-hints.js.map +1 -0
  20. package/dist/guardrail.d.ts.map +1 -1
  21. package/dist/guardrail.js +13 -0
  22. package/dist/guardrail.js.map +1 -1
  23. package/dist/heap-budget.d.ts +32 -0
  24. package/dist/heap-budget.d.ts.map +1 -0
  25. package/dist/heap-budget.js +90 -0
  26. package/dist/heap-budget.js.map +1 -0
  27. package/dist/heap-shapes.d.ts +148 -0
  28. package/dist/heap-shapes.d.ts.map +1 -0
  29. package/dist/heap-shapes.js +193 -0
  30. package/dist/heap-shapes.js.map +1 -0
  31. package/dist/heap-state.d.ts +109 -2
  32. package/dist/heap-state.d.ts.map +1 -1
  33. package/dist/heap-state.js +194 -3
  34. package/dist/heap-state.js.map +1 -1
  35. package/dist/index.js +102 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/progress.d.ts +25 -0
  38. package/dist/progress.d.ts.map +1 -0
  39. package/dist/progress.js +46 -0
  40. package/dist/progress.js.map +1 -0
  41. package/dist/react-shapes.d.ts +42 -0
  42. package/dist/react-shapes.d.ts.map +1 -0
  43. package/dist/react-shapes.js +149 -0
  44. package/dist/react-shapes.js.map +1 -0
  45. package/dist/result-handles.d.ts +11 -0
  46. package/dist/result-handles.d.ts.map +1 -0
  47. package/dist/result-handles.js +77 -0
  48. package/dist/result-handles.js.map +1 -0
  49. package/dist/server-version.d.ts +19 -0
  50. package/dist/server-version.d.ts.map +1 -0
  51. package/dist/server-version.js +19 -0
  52. package/dist/server-version.js.map +1 -0
  53. package/dist/snapshot-borrow.d.ts +67 -0
  54. package/dist/snapshot-borrow.d.ts.map +1 -0
  55. package/dist/snapshot-borrow.js +113 -0
  56. package/dist/snapshot-borrow.js.map +1 -0
  57. package/dist/string-index.d.ts +55 -0
  58. package/dist/string-index.d.ts.map +1 -0
  59. package/dist/string-index.js +99 -0
  60. package/dist/string-index.js.map +1 -0
  61. package/dist/tool-registry.d.ts +42 -0
  62. package/dist/tool-registry.d.ts.map +1 -0
  63. package/dist/tool-registry.js +20 -0
  64. package/dist/tool-registry.js.map +1 -0
  65. package/dist/tools/analyze-run.d.ts +12 -0
  66. package/dist/tools/analyze-run.d.ts.map +1 -0
  67. package/dist/tools/analyze-run.js +404 -0
  68. package/dist/tools/analyze-run.js.map +1 -0
  69. package/dist/tools/anonymize-snapshot.d.ts +12 -0
  70. package/dist/tools/anonymize-snapshot.d.ts.map +1 -0
  71. package/dist/tools/anonymize-snapshot.js +159 -0
  72. package/dist/tools/anonymize-snapshot.js.map +1 -0
  73. package/dist/tools/app-config.d.ts +12 -0
  74. package/dist/tools/app-config.d.ts.map +1 -0
  75. package/dist/tools/app-config.js +217 -0
  76. package/dist/tools/app-config.js.map +1 -0
  77. package/dist/tools/app-heap.d.ts +30 -0
  78. package/dist/tools/app-heap.d.ts.map +1 -0
  79. package/dist/tools/app-heap.js +106 -0
  80. package/dist/tools/app-heap.js.map +1 -0
  81. package/dist/tools/artifact-budget.d.ts +12 -0
  82. package/dist/tools/artifact-budget.d.ts.map +1 -0
  83. package/dist/tools/artifact-budget.js +219 -0
  84. package/dist/tools/artifact-budget.js.map +1 -0
  85. package/dist/tools/async-census.d.ts +12 -0
  86. package/dist/tools/async-census.d.ts.map +1 -0
  87. package/dist/tools/async-census.js +243 -0
  88. package/dist/tools/async-census.js.map +1 -0
  89. package/dist/tools/auto-investigate.d.ts.map +1 -1
  90. package/dist/tools/auto-investigate.js +54 -5
  91. package/dist/tools/auto-investigate.js.map +1 -1
  92. package/dist/tools/batch.d.ts +12 -0
  93. package/dist/tools/batch.d.ts.map +1 -0
  94. package/dist/tools/batch.js +196 -0
  95. package/dist/tools/batch.js.map +1 -0
  96. package/dist/tools/cache-analysis.d.ts +15 -0
  97. package/dist/tools/cache-analysis.d.ts.map +1 -1
  98. package/dist/tools/cache-analysis.js +240 -14
  99. package/dist/tools/cache-analysis.js.map +1 -1
  100. package/dist/tools/census-diff.d.ts +55 -0
  101. package/dist/tools/census-diff.d.ts.map +1 -0
  102. package/dist/tools/census-diff.js +228 -0
  103. package/dist/tools/census-diff.js.map +1 -0
  104. package/dist/tools/chain-walk.d.ts +12 -0
  105. package/dist/tools/chain-walk.d.ts.map +1 -0
  106. package/dist/tools/chain-walk.js +184 -0
  107. package/dist/tools/chain-walk.js.map +1 -0
  108. package/dist/tools/class-histogram.d.ts.map +1 -1
  109. package/dist/tools/class-histogram.js +14 -3
  110. package/dist/tools/class-histogram.js.map +1 -1
  111. package/dist/tools/collection-diff.d.ts +44 -0
  112. package/dist/tools/collection-diff.d.ts.map +1 -0
  113. package/dist/tools/collection-diff.js +343 -0
  114. package/dist/tools/collection-diff.js.map +1 -0
  115. package/dist/tools/collection-trend.d.ts +55 -0
  116. package/dist/tools/collection-trend.d.ts.map +1 -0
  117. package/dist/tools/collection-trend.js +315 -0
  118. package/dist/tools/collection-trend.js.map +1 -0
  119. package/dist/tools/detached-dom.d.ts +5 -0
  120. package/dist/tools/detached-dom.d.ts.map +1 -1
  121. package/dist/tools/detached-dom.js +368 -22
  122. package/dist/tools/detached-dom.js.map +1 -1
  123. package/dist/tools/dev-artifacts.d.ts +62 -6
  124. package/dist/tools/dev-artifacts.d.ts.map +1 -1
  125. package/dist/tools/dev-artifacts.js +685 -24
  126. package/dist/tools/dev-artifacts.js.map +1 -1
  127. package/dist/tools/diff-snapshots.d.ts.map +1 -1
  128. package/dist/tools/diff-snapshots.js +18 -2
  129. package/dist/tools/diff-snapshots.js.map +1 -1
  130. package/dist/tools/dom-audit.d.ts +37 -0
  131. package/dist/tools/dom-audit.d.ts.map +1 -0
  132. package/dist/tools/dom-audit.js +247 -0
  133. package/dist/tools/dom-audit.js.map +1 -0
  134. package/dist/tools/dominator-attribution.d.ts +12 -0
  135. package/dist/tools/dominator-attribution.d.ts.map +1 -0
  136. package/dist/tools/dominator-attribution.js +189 -0
  137. package/dist/tools/dominator-attribution.js.map +1 -0
  138. package/dist/tools/dominator-chain.d.ts +12 -0
  139. package/dist/tools/dominator-chain.d.ts.map +1 -0
  140. package/dist/tools/dominator-chain.js +92 -0
  141. package/dist/tools/dominator-chain.js.map +1 -0
  142. package/dist/tools/duplicate-objects.d.ts +12 -0
  143. package/dist/tools/duplicate-objects.d.ts.map +1 -0
  144. package/dist/tools/duplicate-objects.js +172 -0
  145. package/dist/tools/duplicate-objects.js.map +1 -0
  146. package/dist/tools/duplicated-strings.d.ts.map +1 -1
  147. package/dist/tools/duplicated-strings.js +49 -40
  148. package/dist/tools/duplicated-strings.js.map +1 -1
  149. package/dist/tools/eval-across.d.ts +12 -0
  150. package/dist/tools/eval-across.d.ts.map +1 -0
  151. package/dist/tools/eval-across.js +135 -0
  152. package/dist/tools/eval-across.js.map +1 -0
  153. package/dist/tools/eval.d.ts +79 -0
  154. package/dist/tools/eval.d.ts.map +1 -1
  155. package/dist/tools/eval.js +2523 -197
  156. package/dist/tools/eval.js.map +1 -1
  157. package/dist/tools/event-listener-leaks.d.ts.map +1 -1
  158. package/dist/tools/event-listener-leaks.js +42 -17
  159. package/dist/tools/event-listener-leaks.js.map +1 -1
  160. package/dist/tools/event-registry.d.ts.map +1 -1
  161. package/dist/tools/event-registry.js +42 -8
  162. package/dist/tools/event-registry.js.map +1 -1
  163. package/dist/tools/explain-delta.d.ts +12 -0
  164. package/dist/tools/explain-delta.d.ts.map +1 -0
  165. package/dist/tools/explain-delta.js +221 -0
  166. package/dist/tools/explain-delta.js.map +1 -0
  167. package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
  168. package/dist/tools/find-nodes-by-class.js +112 -13
  169. package/dist/tools/find-nodes-by-class.js.map +1 -1
  170. package/dist/tools/finding-index.d.ts +203 -0
  171. package/dist/tools/finding-index.d.ts.map +1 -0
  172. package/dist/tools/finding-index.js +566 -0
  173. package/dist/tools/finding-index.js.map +1 -0
  174. package/dist/tools/for-each.d.ts.map +1 -1
  175. package/dist/tools/for-each.js +15 -3
  176. package/dist/tools/for-each.js.map +1 -1
  177. package/dist/tools/get-referrers.d.ts.map +1 -1
  178. package/dist/tools/get-referrers.js +17 -0
  179. package/dist/tools/get-referrers.js.map +1 -1
  180. package/dist/tools/get-value.d.ts +16 -0
  181. package/dist/tools/get-value.d.ts.map +1 -1
  182. package/dist/tools/get-value.js +96 -2
  183. package/dist/tools/get-value.js.map +1 -1
  184. package/dist/tools/hunt-report.d.ts +12 -0
  185. package/dist/tools/hunt-report.d.ts.map +1 -0
  186. package/dist/tools/hunt-report.js +186 -0
  187. package/dist/tools/hunt-report.js.map +1 -0
  188. package/dist/tools/hypothesis.d.ts +12 -0
  189. package/dist/tools/hypothesis.d.ts.map +1 -0
  190. package/dist/tools/hypothesis.js +280 -0
  191. package/dist/tools/hypothesis.js.map +1 -0
  192. package/dist/tools/id-space-audit.d.ts +12 -0
  193. package/dist/tools/id-space-audit.d.ts.map +1 -0
  194. package/dist/tools/id-space-audit.js +262 -0
  195. package/dist/tools/id-space-audit.js.map +1 -0
  196. package/dist/tools/identify.d.ts +12 -0
  197. package/dist/tools/identify.d.ts.map +1 -0
  198. package/dist/tools/identify.js +205 -0
  199. package/dist/tools/identify.js.map +1 -0
  200. package/dist/tools/identity-diff.d.ts +12 -0
  201. package/dist/tools/identity-diff.d.ts.map +1 -0
  202. package/dist/tools/identity-diff.js +188 -0
  203. package/dist/tools/identity-diff.js.map +1 -0
  204. package/dist/tools/intern-opportunities.d.ts.map +1 -1
  205. package/dist/tools/intern-opportunities.js +116 -50
  206. package/dist/tools/intern-opportunities.js.map +1 -1
  207. package/dist/tools/ladder-probe.d.ts +65 -0
  208. package/dist/tools/ladder-probe.d.ts.map +1 -0
  209. package/dist/tools/ladder-probe.js +445 -0
  210. package/dist/tools/ladder-probe.js.map +1 -0
  211. package/dist/tools/ladder.d.ts +33 -0
  212. package/dist/tools/ladder.d.ts.map +1 -0
  213. package/dist/tools/ladder.js +266 -0
  214. package/dist/tools/ladder.js.map +1 -0
  215. package/dist/tools/largest-objects.d.ts.map +1 -1
  216. package/dist/tools/largest-objects.js +6 -2
  217. package/dist/tools/largest-objects.js.map +1 -1
  218. package/dist/tools/leak-report.d.ts +35 -0
  219. package/dist/tools/leak-report.d.ts.map +1 -0
  220. package/dist/tools/leak-report.js +398 -0
  221. package/dist/tools/leak-report.js.map +1 -0
  222. package/dist/tools/load-snapshot.d.ts +29 -0
  223. package/dist/tools/load-snapshot.d.ts.map +1 -1
  224. package/dist/tools/load-snapshot.js +294 -23
  225. package/dist/tools/load-snapshot.js.map +1 -1
  226. package/dist/tools/map-entries.d.ts +12 -0
  227. package/dist/tools/map-entries.d.ts.map +1 -0
  228. package/dist/tools/map-entries.js +139 -0
  229. package/dist/tools/map-entries.js.map +1 -0
  230. package/dist/tools/match-object.d.ts +12 -0
  231. package/dist/tools/match-object.d.ts.map +1 -0
  232. package/dist/tools/match-object.js +165 -0
  233. package/dist/tools/match-object.js.map +1 -0
  234. package/dist/tools/metric.d.ts +13 -0
  235. package/dist/tools/metric.d.ts.map +1 -0
  236. package/dist/tools/metric.js +185 -0
  237. package/dist/tools/metric.js.map +1 -0
  238. package/dist/tools/module-attribution.d.ts +36 -0
  239. package/dist/tools/module-attribution.d.ts.map +1 -0
  240. package/dist/tools/module-attribution.js +235 -0
  241. package/dist/tools/module-attribution.js.map +1 -0
  242. package/dist/tools/next-measurement.d.ts +26 -0
  243. package/dist/tools/next-measurement.d.ts.map +1 -0
  244. package/dist/tools/next-measurement.js +149 -0
  245. package/dist/tools/next-measurement.js.map +1 -0
  246. package/dist/tools/object-cost-breakdown.d.ts.map +1 -1
  247. package/dist/tools/object-cost-breakdown.js +64 -0
  248. package/dist/tools/object-cost-breakdown.js.map +1 -1
  249. package/dist/tools/object-shape.d.ts.map +1 -1
  250. package/dist/tools/object-shape.js +53 -5
  251. package/dist/tools/object-shape.js.map +1 -1
  252. package/dist/tools/population-diff.d.ts +57 -0
  253. package/dist/tools/population-diff.d.ts.map +1 -0
  254. package/dist/tools/population-diff.js +338 -0
  255. package/dist/tools/population-diff.js.map +1 -0
  256. package/dist/tools/population-vs-owners.d.ts +12 -0
  257. package/dist/tools/population-vs-owners.d.ts.map +1 -0
  258. package/dist/tools/population-vs-owners.js +183 -0
  259. package/dist/tools/population-vs-owners.js.map +1 -0
  260. package/dist/tools/property-names.d.ts +29 -0
  261. package/dist/tools/property-names.d.ts.map +1 -0
  262. package/dist/tools/property-names.js +131 -0
  263. package/dist/tools/property-names.js.map +1 -0
  264. package/dist/tools/quick-diagnosis.d.ts.map +1 -1
  265. package/dist/tools/quick-diagnosis.js +7 -1
  266. package/dist/tools/quick-diagnosis.js.map +1 -1
  267. package/dist/tools/react-owners.d.ts +12 -0
  268. package/dist/tools/react-owners.d.ts.map +1 -0
  269. package/dist/tools/react-owners.js +167 -0
  270. package/dist/tools/react-owners.js.map +1 -0
  271. package/dist/tools/react-update-queues.d.ts +12 -0
  272. package/dist/tools/react-update-queues.d.ts.map +1 -0
  273. package/dist/tools/react-update-queues.js +173 -0
  274. package/dist/tools/react-update-queues.js.map +1 -0
  275. package/dist/tools/replicate.d.ts +49 -0
  276. package/dist/tools/replicate.d.ts.map +1 -0
  277. package/dist/tools/replicate.js +241 -0
  278. package/dist/tools/replicate.js.map +1 -0
  279. package/dist/tools/retainer-diff.d.ts +12 -0
  280. package/dist/tools/retainer-diff.d.ts.map +1 -0
  281. package/dist/tools/retainer-diff.js +168 -0
  282. package/dist/tools/retainer-diff.js.map +1 -0
  283. package/dist/tools/retainer-layers.d.ts +23 -0
  284. package/dist/tools/retainer-layers.d.ts.map +1 -0
  285. package/dist/tools/retainer-layers.js +179 -0
  286. package/dist/tools/retainer-layers.js.map +1 -0
  287. package/dist/tools/retainer-summary.d.ts +18 -0
  288. package/dist/tools/retainer-summary.d.ts.map +1 -1
  289. package/dist/tools/retainer-summary.js +210 -51
  290. package/dist/tools/retainer-summary.js.map +1 -1
  291. package/dist/tools/retainer-trace.d.ts.map +1 -1
  292. package/dist/tools/retainer-trace.js +14 -2
  293. package/dist/tools/retainer-trace.js.map +1 -1
  294. package/dist/tools/round-audit.d.ts +66 -0
  295. package/dist/tools/round-audit.d.ts.map +1 -0
  296. package/dist/tools/round-audit.js +258 -0
  297. package/dist/tools/round-audit.js.map +1 -0
  298. package/dist/tools/round-digest.d.ts +12 -0
  299. package/dist/tools/round-digest.d.ts.map +1 -0
  300. package/dist/tools/round-digest.js +190 -0
  301. package/dist/tools/round-digest.js.map +1 -0
  302. package/dist/tools/script-census.d.ts +12 -0
  303. package/dist/tools/script-census.d.ts.map +1 -0
  304. package/dist/tools/script-census.js +182 -0
  305. package/dist/tools/script-census.js.map +1 -0
  306. package/dist/tools/search-nodes.d.ts.map +1 -1
  307. package/dist/tools/search-nodes.js +5 -1
  308. package/dist/tools/search-nodes.js.map +1 -1
  309. package/dist/tools/search-strings.d.ts.map +1 -1
  310. package/dist/tools/search-strings.js +53 -7
  311. package/dist/tools/search-strings.js.map +1 -1
  312. package/dist/tools/sequence-analysis.d.ts +53 -0
  313. package/dist/tools/sequence-analysis.d.ts.map +1 -1
  314. package/dist/tools/sequence-analysis.js +313 -89
  315. package/dist/tools/sequence-analysis.js.map +1 -1
  316. package/dist/tools/server-status.d.ts.map +1 -1
  317. package/dist/tools/server-status.js +4 -1
  318. package/dist/tools/server-status.js.map +1 -1
  319. package/dist/tools/settle-check.d.ts +12 -0
  320. package/dist/tools/settle-check.d.ts.map +1 -0
  321. package/dist/tools/settle-check.js +188 -0
  322. package/dist/tools/settle-check.js.map +1 -0
  323. package/dist/tools/shape-histogram.d.ts.map +1 -1
  324. package/dist/tools/shape-histogram.js +9 -2
  325. package/dist/tools/shape-histogram.js.map +1 -1
  326. package/dist/tools/sliced-strings.d.ts.map +1 -1
  327. package/dist/tools/sliced-strings.js +2 -1
  328. package/dist/tools/sliced-strings.js.map +1 -1
  329. package/dist/tools/snapshots.d.ts.map +1 -1
  330. package/dist/tools/snapshots.js +24 -6
  331. package/dist/tools/snapshots.js.map +1 -1
  332. package/dist/tools/sparse-elements.d.ts +12 -0
  333. package/dist/tools/sparse-elements.d.ts.map +1 -0
  334. package/dist/tools/sparse-elements.js +215 -0
  335. package/dist/tools/sparse-elements.js.map +1 -0
  336. package/dist/tools/stale-collections.d.ts +17 -0
  337. package/dist/tools/stale-collections.d.ts.map +1 -1
  338. package/dist/tools/stale-collections.js +28 -0
  339. package/dist/tools/stale-collections.js.map +1 -1
  340. package/dist/tools/string-patterns.d.ts.map +1 -1
  341. package/dist/tools/string-patterns.js +7 -5
  342. package/dist/tools/string-patterns.js.map +1 -1
  343. package/dist/tools/tools-index.d.ts +12 -0
  344. package/dist/tools/tools-index.d.ts.map +1 -0
  345. package/dist/tools/tools-index.js +492 -0
  346. package/dist/tools/tools-index.js.map +1 -0
  347. package/dist/tools/trace-all.d.ts +42 -0
  348. package/dist/tools/trace-all.d.ts.map +1 -0
  349. package/dist/tools/trace-all.js +263 -0
  350. package/dist/tools/trace-all.js.map +1 -0
  351. package/dist/tools/unit-cost.d.ts +12 -0
  352. package/dist/tools/unit-cost.d.ts.map +1 -0
  353. package/dist/tools/unit-cost.js +219 -0
  354. package/dist/tools/unit-cost.js.map +1 -0
  355. package/dist/tools/verify-fix.d.ts +23 -0
  356. package/dist/tools/verify-fix.d.ts.map +1 -0
  357. package/dist/tools/verify-fix.js +219 -0
  358. package/dist/tools/verify-fix.js.map +1 -0
  359. package/dist/tools/weakmap-entries.d.ts.map +1 -1
  360. package/dist/tools/weakmap-entries.js +6 -1
  361. package/dist/tools/weakmap-entries.js.map +1 -1
  362. package/dist/tools/weakref-census.d.ts +15 -0
  363. package/dist/tools/weakref-census.d.ts.map +1 -0
  364. package/dist/tools/weakref-census.js +147 -0
  365. package/dist/tools/weakref-census.js.map +1 -0
  366. package/dist/tools/what-if.d.ts +12 -0
  367. package/dist/tools/what-if.d.ts.map +1 -0
  368. package/dist/tools/what-if.js +285 -0
  369. package/dist/tools/what-if.js.map +1 -0
  370. package/dist/utils.d.ts +238 -3
  371. package/dist/utils.d.ts.map +1 -1
  372. package/dist/utils.js +507 -15
  373. package/dist/utils.js.map +1 -1
  374. package/package.json +7 -6
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+ import { z } from 'zod';
13
+ import { errorResult, formatNumber, markdownTable, toolResult, } from '../utils.js';
14
+ const MIN_ANALYZABLE_RUNGS = 3;
15
+ const WEAK_STEP_RATE = 0.5;
16
+ /**
17
+ * Decide whether a completed round can carry a conclusion.
18
+ *
19
+ * The recurring failure is not a round that fails — it is a round that LOOKS
20
+ * complete and is not. One run reported `165 ok / 135 fail`, was written up as
21
+ * valid, and had two of its ten declared operations at 58/165 and 0/165. Another
22
+ * was split down the middle by a page reload and read as "the app shrank, the
23
+ * cleanest round on record". Every signal needed to catch both is already in the
24
+ * manifest; nothing was reading it.
25
+ *
26
+ * Split out as a pure function so the adjudication is testable without a run.
27
+ */
28
+ export function auditManifest(m) {
29
+ const checks = [];
30
+ const rungs = m.rungs ?? [];
31
+ checks.push(rungs.length >= MIN_ANALYZABLE_RUNGS
32
+ ? {
33
+ name: 'rung count',
34
+ status: 'ok',
35
+ detail: `${rungs.length} rungs — enough to separate a trend from a single GC-band sample.`,
36
+ }
37
+ : {
38
+ name: 'rung count',
39
+ status: 'blocking',
40
+ detail: `${rungs.length} rung(s); ${MIN_ANALYZABLE_RUNGS} are needed. Two points make every series ` +
41
+ 'monotonic by construction. Record this round as UNANALYZED, not as "no leak".',
42
+ });
43
+ const splits = m.ladder_splits_after_rung ?? [];
44
+ const restarted = rungs.filter(r => r.isolate_restarted).length;
45
+ checks.push(splits.length === 0 && restarted === 0
46
+ ? {
47
+ name: 'ladder continuity',
48
+ status: 'ok',
49
+ detail: 'One isolate throughout — all rungs are comparable.',
50
+ }
51
+ : {
52
+ name: 'ladder continuity',
53
+ status: 'blocking',
54
+ detail: `The page reloaded after rung(s) ${splits.join(', ')} (${restarted} rung(s) flagged). ` +
55
+ 'Rungs across that boundary are DIFFERENT V8 isolates. Any delta spanning it is ' +
56
+ 'meaningless — analyze each segment on its own, or re-drive.',
57
+ });
58
+ const steps = m.steps ?? {};
59
+ const stepNames = Object.keys(steps);
60
+ if (stepNames.length === 0) {
61
+ checks.push({
62
+ name: 'per-step landing',
63
+ status: 'caveat',
64
+ detail: 'The combo declared no steps, so there is no evidence any particular surface was ' +
65
+ 'actually exercised — only that the cycle returned true. Declare `Combo.steps` to ' +
66
+ 'make coverage checkable.',
67
+ });
68
+ }
69
+ else {
70
+ const dead = stepNames.filter(n => (steps[n].landed ?? 0) === 0);
71
+ const weak = stepNames.filter(n => (steps[n].landed ?? 0) > 0 && (steps[n].rate ?? 1) < WEAK_STEP_RATE);
72
+ const raised = stepNames.filter(n => (steps[n].errors ?? 0) > 0);
73
+ if (dead.length > 0) {
74
+ checks.push({
75
+ name: 'per-step landing',
76
+ status: 'blocking',
77
+ detail: `${dead.length} declared step(s) NEVER landed: ${dead.join(', ')}. ` +
78
+ 'The ladder says nothing about those surfaces, however many cycles ran.',
79
+ });
80
+ }
81
+ else if (weak.length > 0) {
82
+ checks.push({
83
+ name: 'per-step landing',
84
+ status: 'caveat',
85
+ detail: `${weak.length} step(s) landed below ${WEAK_STEP_RATE * 100}%: ` +
86
+ weak
87
+ .map(n => `${n} ${steps[n].landed}/${steps[n].attempted}`)
88
+ .join(', ') +
89
+ '. Those surfaces are barely exercised; scope the conclusion accordingly.',
90
+ });
91
+ }
92
+ else {
93
+ checks.push({
94
+ name: 'per-step landing',
95
+ status: 'ok',
96
+ detail: `All ${stepNames.length} declared step(s) landed on the majority of cycles.`,
97
+ });
98
+ }
99
+ if (raised.length > 0) {
100
+ checks.push({
101
+ name: 'step exceptions',
102
+ status: 'caveat',
103
+ detail: `${raised.length} step(s) RAISED at least once: ${raised.join(', ')}. ` +
104
+ 'An exception is a bug in the combo, not a fact about the app — check it before ' +
105
+ 'reading anything into that step.',
106
+ });
107
+ }
108
+ }
109
+ const mutators = m.mutates_content_per_cycle ?? [];
110
+ checks.push(mutators.length === 0
111
+ ? {
112
+ name: 'content confound',
113
+ status: 'ok',
114
+ detail: 'No combo added content while driving; a per-cycle rate is attributable.',
115
+ }
116
+ : {
117
+ name: 'content confound',
118
+ status: 'blocking',
119
+ detail: `${mutators.join(', ')} added content DURING the ladder, so per-content and ` +
120
+ 'per-interaction growth are inseparable. A slope from this run is not attributable ' +
121
+ 'no matter how linear it is. Seed the content once up front and re-drive.',
122
+ });
123
+ const gating = m.gating_verified ?? {};
124
+ const gateKeys = Object.keys(gating);
125
+ // Prefer the runner's own summary. Counting read-back entries here while the
126
+ // runner counted declared-minus-absent produced two different fractions for
127
+ // the same bring-up ("16 verified" vs "14/16"), and both were quoted.
128
+ const summary = m.gating_summary;
129
+ // `declared === 0` is NOT a verified round. Taking the summary branch for it
130
+ // reported "0/0 prop(s) verified in-page. The round ran with every declared
131
+ // prop applied and read back." at status `ok` — a clean bill for a round that
132
+ // gated nothing. It belongs with the no-summary case below, which says so.
133
+ if (summary?.declared != null && summary.declared > 0) {
134
+ const verified = summary.verified ?? 0;
135
+ const absent = summary.absent ?? 0;
136
+ checks.push({
137
+ name: 'gating',
138
+ status: absent > 0 ? 'caveat' : 'ok',
139
+ detail: `${verified}/${summary.declared} prop(s) verified in-page` +
140
+ (absent > 0
141
+ ? `, ${absent} absent from this build's registry (${(summary.absent_props ?? []).join(', ')}). ` +
142
+ 'Absent is not failed — the prop does not exist in this build — but a round compared against ' +
143
+ 'one where it did exist is not comparing the same configuration.'
144
+ : '. The round ran with every declared prop applied and read back.'),
145
+ });
146
+ }
147
+ else {
148
+ checks.push(gateKeys.length === 0
149
+ ? {
150
+ name: 'gating',
151
+ status: 'caveat',
152
+ detail: 'No verified gating recorded. If the round depends on a flag being on or off, ' +
153
+ 'nothing here shows it actually was.',
154
+ }
155
+ : {
156
+ name: 'gating',
157
+ status: 'ok',
158
+ detail: `${gateKeys.length} gating value(s) verified in-page — a count of read-back entries, not of declared props. A runner new enough to write \`gating_summary\` reports the declared/verified/absent split instead.`,
159
+ });
160
+ }
161
+ const totals = m.totals ?? {};
162
+ const cycles = totals.cycles ?? 0;
163
+ const ok = totals.ok ?? 0;
164
+ const landRate = cycles > 0 ? ok / cycles : 0;
165
+ checks.push(cycles === 0
166
+ ? {
167
+ name: 'cycle landing',
168
+ status: 'blocking',
169
+ detail: 'No cycles ran.',
170
+ }
171
+ : landRate >= WEAK_STEP_RATE
172
+ ? {
173
+ name: 'cycle landing',
174
+ status: 'ok',
175
+ detail: `${formatNumber(ok)}/${formatNumber(cycles)} cycles landed (${(landRate * 100).toFixed(0)}%).`,
176
+ }
177
+ : {
178
+ name: 'cycle landing',
179
+ status: 'caveat',
180
+ detail: `only ${formatNumber(ok)}/${formatNumber(cycles)} cycles landed (${(landRate * 100).toFixed(0)}%).`,
181
+ });
182
+ const caveats = m.caveats ?? [];
183
+ if (caveats.length > 0) {
184
+ checks.push({
185
+ name: 'recorded caveats',
186
+ status: 'caveat',
187
+ detail: `${caveats.length} caveat(s) recorded by the runner — read them before concluding.`,
188
+ });
189
+ }
190
+ const verdict = checks.some(c => c.status === 'blocking')
191
+ ? 'UNTRUSTWORTHY'
192
+ : checks.some(c => c.status === 'caveat')
193
+ ? 'CAVEATED'
194
+ : 'TRUSTWORTHY';
195
+ return { checks, verdict };
196
+ }
197
+ const ICON = {
198
+ ok: '✅',
199
+ caveat: '⚠️',
200
+ blocking: '❌',
201
+ };
202
+ export function registerRoundAudit(server) {
203
+ server.tool('memlab_round_audit', "Read a leak hunt's `run.json` and say whether the round can carry a conclusion at all — BEFORE anyone reads its numbers. " +
204
+ 'Checks rung count, ladder continuity (a mid-run page reload silently splits the ladder into two V8 isolates), ' +
205
+ 'per-step landing (a declared surface that never actually opened), step exceptions, the content-mutation confound, ' +
206
+ 'verified gating, and the overall cycle landing rate.\n\n' +
207
+ 'Every one of these is already in the manifest and nothing was reading it. The failures this catches are rounds ' +
208
+ 'that LOOK complete: one was written up as valid with two of its ten declared operations at 58/165 and 0/165; ' +
209
+ 'another was split by a page reload and read as "the app shrank, cleanest round on record" when its valid segment ' +
210
+ 'said the opposite.\n\n' +
211
+ 'Returns TRUSTWORTHY / CAVEATED / UNTRUSTWORTHY. Run it first; `memlab_analyze_run` answers what the round MEASURED, ' +
212
+ 'this answers whether the round is worth measuring.', {
213
+ run_dir: z
214
+ .string()
215
+ .describe("Path to the hunt's output directory, or directly to its run.json."),
216
+ }, async ({ run_dir }) => {
217
+ try {
218
+ const manifestPath = run_dir.endsWith('.json')
219
+ ? run_dir
220
+ : path.join(run_dir, 'run.json');
221
+ if (!fs.existsSync(manifestPath)) {
222
+ return errorResult(new Error(`No manifest at ${manifestPath}. Point at the hunt's output directory (the one containing run.json and snapshots/).`));
223
+ }
224
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
225
+ const { checks, verdict } = auditManifest(manifest);
226
+ const lines = [
227
+ `## Round audit — \`${manifest.run_id ?? path.basename(path.dirname(manifestPath))}\``,
228
+ '',
229
+ markdownTable(['', 'Check', 'Finding'], checks.map(c => [ICON[c.status], c.name, c.detail])),
230
+ '',
231
+ `**Verdict: ${verdict}**`,
232
+ '',
233
+ ];
234
+ if (verdict === 'UNTRUSTWORTHY') {
235
+ lines.push('At least one blocking problem means a conclusion drawn from this round would not be supported by it. ' +
236
+ 'Fix and re-drive, or scope the conclusion to the part of the ladder that is still valid — and say which part that is.');
237
+ }
238
+ else if (verdict === 'CAVEATED') {
239
+ lines.push('Usable, but the caveats above have to travel with any number taken from it. A caveat dropped between ' +
240
+ 'the run and the write-up is how an unsupported claim gets recorded as a measurement.');
241
+ }
242
+ else {
243
+ lines.push('No structural problem found. This says the round is well-formed, NOT that its findings are real — ' +
244
+ 'replication (`memlab_replicate`) and retainer evidence are separate questions.');
245
+ }
246
+ if ((manifest.caveats ?? []).length > 0) {
247
+ lines.push('', '### Caveats recorded by the runner', '');
248
+ for (const c of manifest.caveats ?? [])
249
+ lines.push(`- ${c}`);
250
+ }
251
+ return toolResult(lines.join('\n'), null);
252
+ }
253
+ catch (e) {
254
+ return errorResult(e instanceof Error ? e : new Error(String(e)));
255
+ }
256
+ });
257
+ }
258
+ //# sourceMappingURL=round-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-audit.js","sourceRoot":"","sources":["../../src/tools/round-audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,aAAa,EACb,UAAU,GACX,MAAM,aAAa,CAAC;AAgCrB,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,CAAc;IAI1C,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IAE5B,MAAM,CAAC,IAAI,CACT,KAAK,CAAC,MAAM,IAAI,oBAAoB;QAClC,CAAC,CAAC;YACE,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,mEAAmE;SAC3F;QACH,CAAC,CAAC;YACE,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,UAAU;YAClB,MAAM,EACJ,GAAG,KAAK,CAAC,MAAM,aAAa,oBAAoB,4CAA4C;gBAC5F,+EAA+E;SAClF,CACN,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,CAAC,wBAAwB,IAAI,EAAE,CAAC;IAChD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC;IAChE,MAAM,CAAC,IAAI,CACT,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,KAAK,CAAC;QACpC,CAAC,CAAC;YACE,IAAI,EAAE,mBAAmB;YACzB,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,oDAAoD;SAC7D;QACH,CAAC,CAAC;YACE,IAAI,EAAE,mBAAmB;YACzB,MAAM,EAAE,UAAU;YAClB,MAAM,EACJ,mCAAmC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,SAAS,qBAAqB;gBACvF,iFAAiF;gBACjF,6DAA6D;SAChE,CACN,CAAC;IAEF,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IAC5B,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,QAAQ;YAChB,MAAM,EACJ,kFAAkF;gBAClF,mFAAmF;gBACnF,0BAA0B;SAC7B,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACjE,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAC3B,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,cAAc,CACzE,CAAC;QACF,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,kBAAkB;gBACxB,MAAM,EAAE,UAAU;gBAClB,MAAM,EACJ,GAAG,IAAI,CAAC,MAAM,mCAAmC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;oBACpE,wEAAwE;aAC3E,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,kBAAkB;gBACxB,MAAM,EAAE,QAAQ;gBAChB,MAAM,EACJ,GAAG,IAAI,CAAC,MAAM,yBAAyB,cAAc,GAAG,GAAG,KAAK;oBAChE,IAAI;yBACD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;yBACzD,IAAI,CAAC,IAAI,CAAC;oBACb,0EAA0E;aAC7E,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,kBAAkB;gBACxB,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,OAAO,SAAS,CAAC,MAAM,qDAAqD;aACrF,CAAC,CAAC;QACL,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,iBAAiB;gBACvB,MAAM,EAAE,QAAQ;gBAChB,MAAM,EACJ,GAAG,MAAM,CAAC,MAAM,kCAAkC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;oBACvE,iFAAiF;oBACjF,kCAAkC;aACrC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,CAAC,yBAAyB,IAAI,EAAE,CAAC;IACnD,MAAM,CAAC,IAAI,CACT,QAAQ,CAAC,MAAM,KAAK,CAAC;QACnB,CAAC,CAAC;YACE,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,IAAI;YACZ,MAAM,EACJ,yEAAyE;SAC5E;QACH,CAAC,CAAC;YACE,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,UAAU;YAClB,MAAM,EACJ,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,uDAAuD;gBAC7E,oFAAoF;gBACpF,0EAA0E;SAC7E,CACN,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,CAAC,eAAe,IAAI,EAAE,CAAC;IACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrC,6EAA6E;IAC7E,4EAA4E;IAC5E,sEAAsE;IACtE,MAAM,OAAO,GAAG,CAAC,CAAC,cAAc,CAAC;IACjC,6EAA6E;IAC7E,4EAA4E;IAC5E,8EAA8E;IAC9E,2EAA2E;IAC3E,IAAI,OAAO,EAAE,QAAQ,IAAI,IAAI,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;YACpC,MAAM,EACJ,GAAG,QAAQ,IAAI,OAAO,CAAC,QAAQ,2BAA2B;gBAC1D,CAAC,MAAM,GAAG,CAAC;oBACT,CAAC,CAAC,KAAK,MAAM,uCAAuC,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;wBAC9F,8FAA8F;wBAC9F,iEAAiE;oBACnE,CAAC,CAAC,iEAAiE,CAAC;SACzE,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CACT,QAAQ,CAAC,MAAM,KAAK,CAAC;YACnB,CAAC,CAAC;gBACE,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,QAAQ;gBAChB,MAAM,EACJ,+EAA+E;oBAC/E,qCAAqC;aACxC;YACH,CAAC,CAAC;gBACE,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,8LAA8L;aACzN,CACN,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IAClC,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;IAC1B,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,CAAC,IAAI,CACT,MAAM,KAAK,CAAC;QACV,CAAC,CAAC;YACE,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,gBAAgB;SACzB;QACH,CAAC,CAAC,QAAQ,IAAI,cAAc;YAC1B,CAAC,CAAC;gBACE,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;aACvG;YACH,CAAC,CAAC;gBACE,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,QAAQ,YAAY,CAAC,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;aAC5G,CACR,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;IAChC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,kEAAkE;SAC5F,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC;QACvD,CAAC,CAAC,eAAe;QACjB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;YACvC,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,aAAa,CAAC;IACpB,OAAO,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC;AAC3B,CAAC;AAED,MAAM,IAAI,GAAgC;IACxC,EAAE,EAAE,GAAG;IACP,MAAM,EAAE,IAAI;IACZ,QAAQ,EAAE,GAAG;CACd,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,MAAiB;IAClD,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,2HAA2H;QACzH,gHAAgH;QAChH,oHAAoH;QACpH,0DAA0D;QAC1D,iHAAiH;QACjH,+GAA+G;QAC/G,mHAAmH;QACnH,wBAAwB;QACxB,sHAAsH;QACtH,oDAAoD,EACtD;QACE,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,QAAQ,CACP,mEAAmE,CACpE;KACJ,EACD,KAAK,EAAE,EAAC,OAAO,EAAC,EAAE,EAAE;QAClB,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC5C,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBACjC,OAAO,WAAW,CAChB,IAAI,KAAK,CACP,kBAAkB,YAAY,sFAAsF,CACrH,CACF,CAAC;YACJ,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CACvB,CAAC;YACjB,MAAM,EAAC,MAAM,EAAE,OAAO,EAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;YAElD,MAAM,KAAK,GAAa;gBACtB,sBAAsB,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI;gBACtF,EAAE;gBACF,aAAa,CACX,CAAC,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,EACxB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CACpD;gBACD,EAAE;gBACF,cAAc,OAAO,IAAI;gBACzB,EAAE;aACH,CAAC;YACF,IAAI,OAAO,KAAK,eAAe,EAAE,CAAC;gBAChC,KAAK,CAAC,IAAI,CACR,uGAAuG;oBACrG,uHAAuH,CAC1H,CAAC;YACJ,CAAC;iBAAM,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;gBAClC,KAAK,CAAC,IAAI,CACR,uGAAuG;oBACrG,sFAAsF,CACzF,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CACR,oGAAoG;oBAClG,gFAAgF,CACnF,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,oCAAoC,EAAE,EAAE,CAAC,CAAC;gBACzD,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,OAAO,IAAI,EAAE;oBAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC/D,CAAC;YACD,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
11
+ export declare function registerRoundDigest(server: McpServer): void;
12
+ //# sourceMappingURL=round-digest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-digest.d.ts","sourceRoot":"","sources":["../../src/tools/round-digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAkJvE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4J3D"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import { z } from 'zod';
11
+ import fs from 'fs';
12
+ import path from 'path';
13
+ import { auditManifest } from './round-audit.js';
14
+ import { errorResult, toolResult, formatNumber, markdownTable, } from '../utils.js';
15
+ /** `run.json`, whether given the file or the directory holding it. */
16
+ function resolveManifestPath(input) {
17
+ let p = input;
18
+ try {
19
+ if (fs.existsSync(p) && fs.statSync(p).isDirectory()) {
20
+ p = path.join(p, 'run.json');
21
+ }
22
+ }
23
+ catch {
24
+ return null;
25
+ }
26
+ return fs.existsSync(p) ? p : null;
27
+ }
28
+ /** Words `analyze_run` uses in an adjudication cell. */
29
+ const VERDICT_RE = /LEAK CANDIDATE|LEAK|STEP FUNCTION|LINEAR|FLAT|ARTIFACT|NOISE|SHRANK|BOUNDED|NOT A LEAK|CANDIDATE|↑|↓/i;
30
+ /** Split a markdown row into trimmed cells, dropping the empty outer pair. */
31
+ function cells(line) {
32
+ const parts = line.split('|').map(c => c.trim());
33
+ if (parts.length > 0 && parts[0] === '')
34
+ parts.shift();
35
+ if (parts.length > 0 && parts[parts.length - 1] === '')
36
+ parts.pop();
37
+ return parts;
38
+ }
39
+ function parseAnalysis(text) {
40
+ const rows = [];
41
+ let skipped = 0;
42
+ let header = null;
43
+ let verdictCol = -1;
44
+ for (const line of text.split('\n')) {
45
+ const trimmed = line.trimStart();
46
+ if (!trimmed.startsWith('|')) {
47
+ // A blank line or prose ends the current table, so a header cannot leak
48
+ // into the next one.
49
+ if (trimmed === '') {
50
+ header = null;
51
+ verdictCol = -1;
52
+ }
53
+ continue;
54
+ }
55
+ if (/^\s*\|[\s:|-]+\|?\s*$/.test(line))
56
+ continue; // separator
57
+ const cs = cells(line);
58
+ if (cs.length < 2)
59
+ continue;
60
+ if (header == null) {
61
+ header = cs.map(c => c.toLowerCase());
62
+ verdictCol = header.findIndex(h => h.includes('adjudication') || h.includes('verdict'));
63
+ continue;
64
+ }
65
+ if (verdictCol < 0 || verdictCol >= cs.length) {
66
+ // A table with no verdict column (the ladder, the owner breakdown) is
67
+ // not a failure to parse — it simply is not what this reads.
68
+ continue;
69
+ }
70
+ const verdict = cs[verdictCol];
71
+ if (!VERDICT_RE.test(verdict)) {
72
+ skipped++;
73
+ continue;
74
+ }
75
+ // Column names vary between analysis sections; find each by heading rather
76
+ // than by position, and leave a cell blank when the table does not have it.
77
+ const at = (...names) => {
78
+ for (const n of names) {
79
+ const i = header?.findIndex(h => h.includes(n)) ?? -1;
80
+ if (i >= 0 && i < cs.length)
81
+ return cs[i];
82
+ }
83
+ return '';
84
+ };
85
+ rows.push({
86
+ metric: cs[0].replace(/^`|`$/g, ''),
87
+ delta: at('δ count', 'count', 'delta'),
88
+ rate: at('δ/cycle', '/cycle', 'rate'),
89
+ size: at('δ size', 'size'),
90
+ verdict,
91
+ });
92
+ }
93
+ return { rows, skipped };
94
+ }
95
+ export function registerRoundDigest(server) {
96
+ server.tool('memlab_round_digest', "The verdict table for a finished leak-hunt round, and nothing else. `memlab_analyze_run` writes ~30 KB of prose per round, which in practice gets grepped for verdicts rather than read — across a five-round sweep that is the single largest avoidable token cost in the analysis phase. This reads the run manifest plus any `*_analysis.txt` next to it and returns: the audit verdict and its blocking checks, the ladder shape (including whether a page reload split it), the per-metric rate/fit/verdict rows, and the round's own caveats. The full analysis stays on disk and is named in the output, so nothing is lost — it is just not paid for by default.", {
97
+ run_dir: z
98
+ .string()
99
+ .describe('Path to a leak-hunt run directory, or directly to its run.json.'),
100
+ include_analysis: z
101
+ .boolean()
102
+ .optional()
103
+ .default(true)
104
+ .describe('Parse `*_analysis.txt` files next to the manifest for their verdict rows (default true). Set false for the manifest audit alone.'),
105
+ max_metrics: z
106
+ .number()
107
+ .optional()
108
+ .default(25)
109
+ .describe('Maximum metric rows to show (default 25).'),
110
+ }, async ({ run_dir, include_analysis, max_metrics }) => {
111
+ try {
112
+ const manifestPath = resolveManifestPath(run_dir);
113
+ if (manifestPath == null) {
114
+ return errorResult(`No run.json at ${run_dir} (nor at ${path.join(run_dir, 'run.json')}).`);
115
+ }
116
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
117
+ const dir = path.dirname(manifestPath);
118
+ const audit = auditManifest(manifest);
119
+ const rungs = manifest.rungs ?? [];
120
+ const splits = manifest.ladder_splits_after_rung ?? [];
121
+ const lines = [
122
+ `# Round digest — ${manifest.run_id ?? path.basename(dir)}`,
123
+ '',
124
+ `**Audit verdict: ${audit.verdict}**`,
125
+ '',
126
+ ];
127
+ // Only the checks that change what a reader may claim. An "ok" check is
128
+ // the absence of a problem and does not need a row.
129
+ const notable = audit.checks.filter(c => c.status !== 'ok');
130
+ if (notable.length > 0) {
131
+ lines.push(markdownTable(['Check', 'Status', 'Detail'], notable.map(c => [c.name, c.status.toUpperCase(), c.detail])), '');
132
+ }
133
+ else {
134
+ lines.push('_All audit checks passed._', '');
135
+ }
136
+ const totals = manifest.totals ?? {};
137
+ lines.push(`Cycles ${formatNumber(totals.cycles ?? 0)} (ok ${formatNumber(totals.ok ?? 0)} / fail ${formatNumber(totals.fail ?? 0)}) · ` +
138
+ `${rungs.length} rung(s)` +
139
+ (splits.length > 0
140
+ ? ` · ⚠ ladder split after rung ${splits.join(', ')} — deltas spanning a split compare two V8 isolates`
141
+ : '') +
142
+ (manifest.stop_reason ? ` · stop: ${manifest.stop_reason}` : ''), '');
143
+ if (rungs.length > 0) {
144
+ const first = rungs[0];
145
+ const last = rungs[rungs.length - 1];
146
+ const delta = (last.post_gc_heap_mb ?? 0) - (first.post_gc_heap_mb ?? 0);
147
+ lines.push(`Post-GC heap ${(first.post_gc_heap_mb ?? 0).toFixed(1)} → ${(last.post_gc_heap_mb ?? 0).toFixed(1)} MB (${delta >= 0 ? '+' : ''}${delta.toFixed(1)} MB). ` +
148
+ 'Aggregate heap is the weakest signal in a round; the per-metric rows below decide.', '');
149
+ }
150
+ if (include_analysis) {
151
+ const analysisFiles = fs
152
+ .readdirSync(dir)
153
+ .filter(f => f.endsWith('_analysis.txt') || f === 'analysis.txt')
154
+ .sort();
155
+ if (analysisFiles.length === 0) {
156
+ lines.push('_No `*_analysis.txt` beside the manifest — run `memlab_analyze_run` first for the per-metric verdicts._', '');
157
+ }
158
+ for (const file of analysisFiles) {
159
+ const { rows, skipped } = parseAnalysis(fs.readFileSync(path.join(dir, file), 'utf8'));
160
+ lines.push(`## ${file}`, '');
161
+ if (rows.length === 0) {
162
+ lines.push(`_No verdict rows recognised (${formatNumber(skipped)} table line(s) skipped). Read the file directly: ${path.join(dir, file)}_`, '');
163
+ continue;
164
+ }
165
+ lines.push(markdownTable(['Metric', 'Δ count', 'Δ/cycle', 'Δ size', 'Verdict'], rows
166
+ .slice(0, max_metrics)
167
+ .map(r => [r.metric, r.delta, r.rate, r.size, r.verdict]), new Set([1, 2, 3])), '');
168
+ if (rows.length > max_metrics) {
169
+ lines.push(`_${formatNumber(rows.length - max_metrics)} further row(s) not shown; raise \`max_metrics\`._`, '');
170
+ }
171
+ // Never silent about what was not parsed: a digest that quietly
172
+ // dropped the one row carrying the finding would be worse than no
173
+ // digest at all.
174
+ if (skipped > 0) {
175
+ lines.push(`_${formatNumber(skipped)} table line(s) in this file were not recognised as verdict rows and are not represented above._`, '');
176
+ }
177
+ }
178
+ }
179
+ if ((manifest.caveats ?? []).length > 0) {
180
+ lines.push('## Round caveats (carry these into the write-up)', '', ...(manifest.caveats ?? []).map(c => `- ${c}`), '');
181
+ }
182
+ lines.push(`_Full analysis and manifest: ${dir}_`, '_This is a summary of files on disk, not a re-analysis. Run `memlab_analyze_run` to produce or refresh them._');
183
+ return toolResult(lines.join('\n'));
184
+ }
185
+ catch (err) {
186
+ return errorResult(err);
187
+ }
188
+ });
189
+ }
190
+ //# sourceMappingURL=round-digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-digest.js","sourceRoot":"","sources":["../../src/tools/round-digest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
11
+ export declare function registerScriptCensus(server: McpServer): void;
12
+ //# sourceMappingURL=script-census.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script-census.d.ts","sourceRoot":"","sources":["../../src/tools/script-census.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAuEvE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyJ5D"}