@resolveio/server-lib 22.3.221 → 22.3.223

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 (745) hide show
  1. package/ai/assistant-core-heuristics.d.ts +11 -0
  2. package/ai/assistant-core-heuristics.js +356 -0
  3. package/ai/assistant-core-heuristics.js.map +1 -0
  4. package/ai/resolveio-platform-intelligence-memory-corpus.d.ts +3 -0
  5. package/ai/resolveio-platform-intelligence-memory-corpus.js +214 -0
  6. package/ai/resolveio-platform-intelligence-memory-corpus.js.map +1 -0
  7. package/ai/resolveio-platform-intelligence-memory.d.ts +20 -0
  8. package/ai/resolveio-platform-intelligence-memory.js +341 -0
  9. package/ai/resolveio-platform-intelligence-memory.js.map +1 -0
  10. package/{src/ai/resolveio-platform-intelligence-types.ts → ai/resolveio-platform-intelligence-types.d.ts} +15 -20
  11. package/ai/resolveio-platform-intelligence-types.js +4 -0
  12. package/ai/resolveio-platform-intelligence-types.js.map +1 -0
  13. package/ai/resolveio-platform-intelligence.d.ts +6 -0
  14. package/ai/resolveio-platform-intelligence.js +463 -0
  15. package/ai/resolveio-platform-intelligence.js.map +1 -0
  16. package/client-server-app.d.ts +1 -0
  17. package/client-server-app.js +68 -0
  18. package/client-server-app.js.map +1 -0
  19. package/collections/ai-run.collection.d.ts +3 -0
  20. package/collections/ai-run.collection.js +170 -0
  21. package/collections/ai-run.collection.js.map +1 -0
  22. package/collections/ai-terminal-conversation.collection.d.ts +2 -0
  23. package/collections/ai-terminal-conversation.collection.js +140 -0
  24. package/collections/ai-terminal-conversation.collection.js.map +1 -0
  25. package/collections/ai-terminal-issue-report.collection.d.ts +2 -0
  26. package/collections/ai-terminal-issue-report.collection.js +148 -0
  27. package/collections/ai-terminal-issue-report.collection.js.map +1 -0
  28. package/collections/ai-terminal-message.collection.d.ts +2 -0
  29. package/collections/ai-terminal-message.collection.js +121 -0
  30. package/collections/ai-terminal-message.collection.js.map +1 -0
  31. package/collections/app-setting.collection.d.ts +3 -0
  32. package/collections/app-setting.collection.js +103 -0
  33. package/collections/app-setting.collection.js.map +1 -0
  34. package/collections/app-status.collection.d.ts +3 -0
  35. package/collections/app-status.collection.js +57 -0
  36. package/collections/app-status.collection.js.map +1 -0
  37. package/collections/communication-metric.collection.d.ts +2 -0
  38. package/collections/communication-metric.collection.js +133 -0
  39. package/collections/communication-metric.collection.js.map +1 -0
  40. package/collections/counter.collection.d.ts +3 -0
  41. package/collections/counter.collection.js +56 -0
  42. package/collections/counter.collection.js.map +1 -0
  43. package/collections/cron-job-history.collection.d.ts +3 -0
  44. package/collections/cron-job-history.collection.js +137 -0
  45. package/collections/cron-job-history.collection.js.map +1 -0
  46. package/collections/cron-job.collection.d.ts +3 -0
  47. package/collections/cron-job.collection.js +92 -0
  48. package/collections/cron-job.collection.js.map +1 -0
  49. package/collections/customer-notification.collection.d.ts +3 -0
  50. package/collections/customer-notification.collection.js +130 -0
  51. package/collections/customer-notification.collection.js.map +1 -0
  52. package/collections/customer-portal-password.collection.d.ts +3 -0
  53. package/collections/customer-portal-password.collection.js +75 -0
  54. package/collections/customer-portal-password.collection.js.map +1 -0
  55. package/collections/email-history.collection.d.ts +3 -0
  56. package/collections/email-history.collection.js +134 -0
  57. package/collections/email-history.collection.js.map +1 -0
  58. package/collections/email-verified.collection.d.ts +3 -0
  59. package/collections/email-verified.collection.js +62 -0
  60. package/collections/email-verified.collection.js.map +1 -0
  61. package/collections/file.collection.d.ts +3 -0
  62. package/collections/file.collection.js +74 -0
  63. package/collections/file.collection.js.map +1 -0
  64. package/collections/flag-update.collection.d.ts +3 -0
  65. package/collections/flag-update.collection.js +57 -0
  66. package/collections/flag-update.collection.js.map +1 -0
  67. package/collections/flag.collection.d.ts +3 -0
  68. package/collections/flag.collection.js +57 -0
  69. package/collections/flag.collection.js.map +1 -0
  70. package/collections/log-method-latency.collection.d.ts +3 -0
  71. package/collections/log-method-latency.collection.js +77 -0
  72. package/collections/log-method-latency.collection.js.map +1 -0
  73. package/collections/log-subscription.collection.d.ts +3 -0
  74. package/collections/log-subscription.collection.js +80 -0
  75. package/collections/log-subscription.collection.js.map +1 -0
  76. package/collections/log.collection.d.ts +3 -0
  77. package/collections/log.collection.js +93 -0
  78. package/collections/log.collection.js.map +1 -0
  79. package/collections/logged-in-users.collection.d.ts +3 -0
  80. package/collections/logged-in-users.collection.js +67 -0
  81. package/collections/logged-in-users.collection.js.map +1 -0
  82. package/collections/monitor-cpu.collection.d.ts +3 -0
  83. package/collections/monitor-cpu.collection.js +65 -0
  84. package/collections/monitor-cpu.collection.js.map +1 -0
  85. package/collections/monitor-function.collection.d.ts +3 -0
  86. package/collections/monitor-function.collection.js +74 -0
  87. package/collections/monitor-function.collection.js.map +1 -0
  88. package/collections/monitor-memory.collection.d.ts +3 -0
  89. package/collections/monitor-memory.collection.js +77 -0
  90. package/collections/monitor-memory.collection.js.map +1 -0
  91. package/collections/monitor-mongo.collection.d.ts +3 -0
  92. package/collections/monitor-mongo.collection.js +71 -0
  93. package/collections/monitor-mongo.collection.js.map +1 -0
  94. package/collections/notification.collection.d.ts +3 -0
  95. package/collections/notification.collection.js +57 -0
  96. package/collections/notification.collection.js.map +1 -0
  97. package/collections/openai-usage-ledger.collection.d.ts +2 -0
  98. package/collections/openai-usage-ledger.collection.js +188 -0
  99. package/collections/openai-usage-ledger.collection.js.map +1 -0
  100. package/collections/report-builder-dashboard-builder.collection.d.ts +3 -0
  101. package/collections/report-builder-dashboard-builder.collection.js +109 -0
  102. package/collections/report-builder-dashboard-builder.collection.js.map +1 -0
  103. package/collections/report-builder-library.collection.d.ts +3 -0
  104. package/collections/report-builder-library.collection.js +87 -0
  105. package/collections/report-builder-library.collection.js.map +1 -0
  106. package/collections/report-builder-report.collection.d.ts +4 -0
  107. package/collections/report-builder-report.collection.js +184 -0
  108. package/collections/report-builder-report.collection.js.map +1 -0
  109. package/collections/user-group.collection.d.ts +4 -0
  110. package/collections/user-group.collection.js +89 -0
  111. package/collections/user-group.collection.js.map +1 -0
  112. package/collections/user-guide.collection.d.ts +3 -0
  113. package/collections/user-guide.collection.js +57 -0
  114. package/collections/user-guide.collection.js.map +1 -0
  115. package/collections/user.collection.d.ts +4 -0
  116. package/collections/user.collection.js +180 -0
  117. package/collections/user.collection.js.map +1 -0
  118. package/cron/cron.d.ts +14 -0
  119. package/cron/cron.js +216 -0
  120. package/cron/cron.js.map +1 -0
  121. package/fixtures/cron-jobs.d.ts +1 -0
  122. package/fixtures/cron-jobs.js +150 -0
  123. package/fixtures/cron-jobs.js.map +1 -0
  124. package/fixtures/init.d.ts +1 -0
  125. package/fixtures/init.js +91 -0
  126. package/fixtures/init.js.map +1 -0
  127. package/http/auth.d.ts +2 -0
  128. package/http/auth.js +951 -0
  129. package/http/auth.js.map +1 -0
  130. package/http/health.d.ts +1 -0
  131. package/http/health.js +11 -0
  132. package/http/health.js.map +1 -0
  133. package/http/home.d.ts +1 -0
  134. package/http/home.js +134 -0
  135. package/http/home.js.map +1 -0
  136. package/http/slow-query-publication.d.ts +2 -0
  137. package/http/slow-query-publication.js +99 -0
  138. package/http/slow-query-publication.js.map +1 -0
  139. package/index.d.ts +1 -0
  140. package/index.js +19 -0
  141. package/index.js.map +1 -0
  142. package/managers/ai-assistant-codex-manager.manager.d.ts +67 -0
  143. package/managers/ai-assistant-codex-manager.manager.js +1113 -0
  144. package/managers/ai-assistant-codex-manager.manager.js.map +1 -0
  145. package/managers/ai-run-evidence.manager.d.ts +36 -0
  146. package/managers/ai-run-evidence.manager.js +377 -0
  147. package/managers/ai-run-evidence.manager.js.map +1 -0
  148. package/managers/communication-metric.manager.d.ts +16 -0
  149. package/managers/communication-metric.manager.js +134 -0
  150. package/managers/communication-metric.manager.js.map +1 -0
  151. package/managers/cron.manager.d.ts +20 -0
  152. package/managers/cron.manager.js +534 -0
  153. package/managers/cron.manager.js.map +1 -0
  154. package/managers/customer-notification-content.manager.d.ts +55 -0
  155. package/managers/customer-notification-content.manager.js +158 -0
  156. package/managers/customer-notification-content.manager.js.map +1 -0
  157. package/managers/diagnostic-manager-bootstrap.d.ts +9 -0
  158. package/managers/diagnostic-manager-bootstrap.js +260 -0
  159. package/managers/diagnostic-manager-bootstrap.js.map +1 -0
  160. package/managers/error-auto-fix.manager.d.ts +149 -0
  161. package/managers/error-auto-fix.manager.js +3064 -0
  162. package/managers/error-auto-fix.manager.js.map +1 -0
  163. package/managers/local-log.manager.d.ts +18 -0
  164. package/managers/local-log.manager.js +88 -0
  165. package/managers/local-log.manager.js.map +1 -0
  166. package/managers/method.manager.d.ts +84 -0
  167. package/managers/method.manager.js +1964 -0
  168. package/managers/method.manager.js.map +1 -0
  169. package/managers/mongo.manager.d.ts +224 -0
  170. package/managers/mongo.manager.js +5000 -0
  171. package/managers/mongo.manager.js.map +1 -0
  172. package/managers/monitor.manager.d.ts +70 -0
  173. package/managers/monitor.manager.js +550 -0
  174. package/managers/monitor.manager.js.map +1 -0
  175. package/managers/openai-usage-ledger.manager.d.ts +30 -0
  176. package/managers/openai-usage-ledger.manager.js +142 -0
  177. package/managers/openai-usage-ledger.manager.js.map +1 -0
  178. package/managers/slow-query-verifier.manager.d.ts +144 -0
  179. package/managers/slow-query-verifier.manager.js +3857 -0
  180. package/managers/slow-query-verifier.manager.js.map +1 -0
  181. package/managers/slow-query.manager.d.ts +28 -0
  182. package/managers/slow-query.manager.js +468 -0
  183. package/managers/slow-query.manager.js.map +1 -0
  184. package/managers/subscription.manager.d.ts +169 -0
  185. package/managers/subscription.manager.js +3434 -0
  186. package/managers/subscription.manager.js.map +1 -0
  187. package/managers/websocket.manager.d.ts +73 -0
  188. package/managers/websocket.manager.js +673 -0
  189. package/managers/websocket.manager.js.map +1 -0
  190. package/managers/worker-dispatcher.manager.d.ts +120 -0
  191. package/managers/worker-dispatcher.manager.js +1266 -0
  192. package/managers/worker-dispatcher.manager.js.map +1 -0
  193. package/managers/worker-server.manager.d.ts +35 -0
  194. package/managers/worker-server.manager.js +582 -0
  195. package/managers/worker-server.manager.js.map +1 -0
  196. package/methods/accounts.d.ts +2 -0
  197. package/methods/accounts.js +624 -0
  198. package/methods/accounts.js.map +1 -0
  199. package/methods/ai-terminal.d.ts +458 -0
  200. package/methods/ai-terminal.js +27991 -0
  201. package/methods/ai-terminal.js.map +1 -0
  202. package/methods/app-settings.d.ts +2 -0
  203. package/methods/app-settings.js +169 -0
  204. package/methods/app-settings.js.map +1 -0
  205. package/methods/aws.d.ts +2 -0
  206. package/methods/aws.js +877 -0
  207. package/methods/aws.js.map +1 -0
  208. package/methods/collections.d.ts +2 -0
  209. package/methods/collections.js +719 -0
  210. package/methods/collections.js.map +1 -0
  211. package/methods/counters.d.ts +2 -0
  212. package/methods/counters.js +113 -0
  213. package/methods/counters.js.map +1 -0
  214. package/methods/cron-jobs.d.ts +2 -0
  215. package/methods/cron-jobs.js +2475 -0
  216. package/methods/cron-jobs.js.map +1 -0
  217. package/methods/customer-notifications.d.ts +2 -0
  218. package/methods/customer-notifications.js +528 -0
  219. package/methods/customer-notifications.js.map +1 -0
  220. package/methods/diagnostics.d.ts +2 -0
  221. package/methods/diagnostics.js +703 -0
  222. package/methods/diagnostics.js.map +1 -0
  223. package/methods/flag-updates.d.ts +2 -0
  224. package/methods/flag-updates.js +8 -0
  225. package/methods/flag-updates.js.map +1 -0
  226. package/methods/flags.d.ts +2 -0
  227. package/methods/flags.js +8 -0
  228. package/methods/flags.js.map +1 -0
  229. package/methods/logs.d.ts +2 -0
  230. package/methods/logs.js +751 -0
  231. package/methods/logs.js.map +1 -0
  232. package/methods/mongo-explorer.d.ts +2 -0
  233. package/methods/mongo-explorer.js +1808 -0
  234. package/methods/mongo-explorer.js.map +1 -0
  235. package/methods/monitor.d.ts +2 -0
  236. package/methods/monitor.js +543 -0
  237. package/methods/monitor.js.map +1 -0
  238. package/methods/pdf.d.ts +2 -0
  239. package/methods/pdf.js +1216 -0
  240. package/methods/pdf.js.map +1 -0
  241. package/methods/publications.d.ts +1 -0
  242. package/methods/publications.js +183 -0
  243. package/methods/publications.js.map +1 -0
  244. package/methods/report-builder.d.ts +2 -0
  245. package/methods/report-builder.js +3094 -0
  246. package/methods/report-builder.js.map +1 -0
  247. package/methods/support.d.ts +2 -0
  248. package/methods/support.js +430 -0
  249. package/methods/support.js.map +1 -0
  250. package/models/ai-run.model.d.ts +19 -0
  251. package/models/ai-run.model.js +4 -0
  252. package/models/ai-run.model.js.map +1 -0
  253. package/models/ai-terminal-conversation.model.d.ts +17 -0
  254. package/models/ai-terminal-conversation.model.js +4 -0
  255. package/models/ai-terminal-conversation.model.js.map +1 -0
  256. package/models/ai-terminal-issue-report.model.d.ts +19 -0
  257. package/models/ai-terminal-issue-report.model.js +4 -0
  258. package/models/ai-terminal-issue-report.model.js.map +1 -0
  259. package/models/ai-terminal-message.model.d.ts +22 -0
  260. package/models/ai-terminal-message.model.js +4 -0
  261. package/models/ai-terminal-message.model.js.map +1 -0
  262. package/models/app-setting.model.d.ts +16 -0
  263. package/models/app-setting.model.js +4 -0
  264. package/models/app-setting.model.js.map +1 -0
  265. package/{src/models/app-status.model.ts → models/app-status.model.d.ts} +2 -3
  266. package/models/app-status.model.js +4 -0
  267. package/models/app-status.model.js.map +1 -0
  268. package/{src/models/billing-logged-in-users.model.ts → models/billing-logged-in-users.model.d.ts} +4 -5
  269. package/models/billing-logged-in-users.model.js +4 -0
  270. package/models/billing-logged-in-users.model.js.map +1 -0
  271. package/models/collection-document.model.d.ts +21 -0
  272. package/models/collection-document.model.js +4 -0
  273. package/models/collection-document.model.js.map +1 -0
  274. package/models/communication-metric.model.d.ts +20 -0
  275. package/models/communication-metric.model.js +4 -0
  276. package/models/communication-metric.model.js.map +1 -0
  277. package/{src/models/counter.model.ts → models/counter.model.d.ts} +3 -4
  278. package/models/counter.model.js +4 -0
  279. package/models/counter.model.js.map +1 -0
  280. package/models/cron-job-history.model.d.ts +15 -0
  281. package/models/cron-job-history.model.js +4 -0
  282. package/models/cron-job-history.model.js.map +1 -0
  283. package/models/cron-job.model.d.ts +14 -0
  284. package/models/cron-job.model.js +4 -0
  285. package/models/cron-job.model.js.map +1 -0
  286. package/models/customer-notification.model.d.ts +26 -0
  287. package/models/customer-notification.model.js +4 -0
  288. package/models/customer-notification.model.js.map +1 -0
  289. package/models/customer-portal-password.model.d.ts +11 -0
  290. package/models/customer-portal-password.model.js +4 -0
  291. package/models/customer-portal-password.model.js.map +1 -0
  292. package/models/dialog.model.d.ts +23 -0
  293. package/models/dialog.model.js +4 -0
  294. package/models/dialog.model.js.map +1 -0
  295. package/models/email-history.model.d.ts +32 -0
  296. package/{src/models/email-history.model.ts → models/email-history.model.js} +4 -36
  297. package/models/email-history.model.js.map +1 -0
  298. package/{src/models/email-verified.model.ts → models/email-verified.model.d.ts} +5 -6
  299. package/models/email-verified.model.js +4 -0
  300. package/models/email-verified.model.js.map +1 -0
  301. package/{src/models/file.model.ts → models/file.model.d.ts} +7 -8
  302. package/models/file.model.js +4 -0
  303. package/models/file.model.js.map +1 -0
  304. package/{src/models/flag-update.model.ts → models/flag-update.model.d.ts} +3 -4
  305. package/models/flag-update.model.js +4 -0
  306. package/models/flag-update.model.js.map +1 -0
  307. package/{src/models/flag.model.ts → models/flag.model.d.ts} +3 -4
  308. package/models/flag.model.js +4 -0
  309. package/models/flag.model.js.map +1 -0
  310. package/models/log-method-latency.model.d.ts +10 -0
  311. package/models/log-method-latency.model.js +4 -0
  312. package/models/log-method-latency.model.js.map +1 -0
  313. package/{src/models/log-subscription.model.ts → models/log-subscription.model.d.ts} +9 -11
  314. package/models/log-subscription.model.js +4 -0
  315. package/models/log-subscription.model.js.map +1 -0
  316. package/models/log.model.d.ts +17 -0
  317. package/models/log.model.js +4 -0
  318. package/models/log.model.js.map +1 -0
  319. package/{src/models/logged-in-users.model.ts → models/logged-in-users.model.d.ts} +5 -6
  320. package/models/logged-in-users.model.js +4 -0
  321. package/models/logged-in-users.model.js.map +1 -0
  322. package/{src/models/method-response.model.ts → models/method-response.model.d.ts} +6 -7
  323. package/models/method-response.model.js +4 -0
  324. package/models/method-response.model.js.map +1 -0
  325. package/models/method.model.d.ts +26 -0
  326. package/models/method.model.js +4 -0
  327. package/models/method.model.js.map +1 -0
  328. package/{src/models/monitor-cpu.model.ts → models/monitor-cpu.model.d.ts} +7 -9
  329. package/models/monitor-cpu.model.js +4 -0
  330. package/models/monitor-cpu.model.js.map +1 -0
  331. package/models/monitor-function.model.d.ts +14 -0
  332. package/models/monitor-function.model.js +4 -0
  333. package/models/monitor-function.model.js.map +1 -0
  334. package/models/monitor-memory.model.d.ts +15 -0
  335. package/models/monitor-memory.model.js +4 -0
  336. package/models/monitor-memory.model.js.map +1 -0
  337. package/models/monitor-mongo.model.d.ts +13 -0
  338. package/models/monitor-mongo.model.js +4 -0
  339. package/models/monitor-mongo.model.js.map +1 -0
  340. package/{src/models/notification.model.ts → models/notification.model.d.ts} +4 -6
  341. package/models/notification.model.js +4 -0
  342. package/models/notification.model.js.map +1 -0
  343. package/models/openai-usage-ledger.model.d.ts +30 -0
  344. package/models/openai-usage-ledger.model.js +4 -0
  345. package/models/openai-usage-ledger.model.js.map +1 -0
  346. package/models/pagination.model.d.ts +11 -0
  347. package/models/pagination.model.js +28 -0
  348. package/models/pagination.model.js.map +1 -0
  349. package/models/permission.model.d.ts +12 -0
  350. package/models/permission.model.js +4 -0
  351. package/models/permission.model.js.map +1 -0
  352. package/models/report-builder-dashboard-builder.model.d.ts +25 -0
  353. package/models/report-builder-dashboard-builder.model.js +4 -0
  354. package/models/report-builder-dashboard-builder.model.js.map +1 -0
  355. package/models/report-builder-library.model.d.ts +17 -0
  356. package/models/report-builder-library.model.js +4 -0
  357. package/models/report-builder-library.model.js.map +1 -0
  358. package/models/report-builder-report.model.d.ts +121 -0
  359. package/models/report-builder-report.model.js +4 -0
  360. package/models/report-builder-report.model.js.map +1 -0
  361. package/models/report-builder.model.d.ts +61 -0
  362. package/models/report-builder.model.js +4 -0
  363. package/models/report-builder.model.js.map +1 -0
  364. package/models/select-data-label.model.d.ts +9 -0
  365. package/models/select-data-label.model.js +4 -0
  366. package/models/select-data-label.model.js.map +1 -0
  367. package/models/server-message.model.d.ts +32 -0
  368. package/models/server-message.model.js +4 -0
  369. package/models/server-message.model.js.map +1 -0
  370. package/models/slow-query-report.model.d.ts +23 -0
  371. package/models/slow-query-report.model.js +4 -0
  372. package/models/slow-query-report.model.js.map +1 -0
  373. package/models/subscription.model.d.ts +31 -0
  374. package/models/subscription.model.js +4 -0
  375. package/models/subscription.model.js.map +1 -0
  376. package/models/support-ticket.model.d.ts +87 -0
  377. package/models/support-ticket.model.js +4 -0
  378. package/models/support-ticket.model.js.map +1 -0
  379. package/models/user-group.model.d.ts +20 -0
  380. package/models/user-group.model.js +4 -0
  381. package/models/user-group.model.js.map +1 -0
  382. package/{src/models/user-guide.model.ts → models/user-guide.model.d.ts} +4 -5
  383. package/models/user-guide.model.js +4 -0
  384. package/models/user-guide.model.js.map +1 -0
  385. package/models/user.model.d.ts +84 -0
  386. package/models/user.model.js +4 -0
  387. package/models/user.model.js.map +1 -0
  388. package/package.json +1 -1
  389. package/private/images/ResolveIO.png +0 -0
  390. package/public_api.js +127 -0
  391. package/public_api.js.map +1 -0
  392. package/publications/ai-terminal.d.ts +1 -0
  393. package/publications/ai-terminal.js +122 -0
  394. package/publications/ai-terminal.js.map +1 -0
  395. package/publications/app-settings.d.ts +2 -0
  396. package/publications/app-settings.js +28 -0
  397. package/publications/app-settings.js.map +1 -0
  398. package/publications/app-status.d.ts +2 -0
  399. package/publications/app-status.js +16 -0
  400. package/publications/app-status.js.map +1 -0
  401. package/publications/cron-jobs.d.ts +2 -0
  402. package/publications/cron-jobs.js +88 -0
  403. package/publications/cron-jobs.js.map +1 -0
  404. package/publications/customer-notifications.d.ts +2 -0
  405. package/publications/customer-notifications.js +161 -0
  406. package/publications/customer-notifications.js.map +1 -0
  407. package/publications/files.d.ts +2 -0
  408. package/publications/files.js +36 -0
  409. package/publications/files.js.map +1 -0
  410. package/publications/flags-update.d.ts +2 -0
  411. package/publications/flags-update.js +22 -0
  412. package/publications/flags-update.js.map +1 -0
  413. package/publications/flags.d.ts +2 -0
  414. package/publications/flags.js +22 -0
  415. package/publications/flags.js.map +1 -0
  416. package/publications/logs.d.ts +2 -0
  417. package/publications/logs.js +164 -0
  418. package/publications/logs.js.map +1 -0
  419. package/publications/notifications.d.ts +2 -0
  420. package/publications/notifications.js +16 -0
  421. package/publications/notifications.js.map +1 -0
  422. package/publications/report-builder-dashboard-builders.d.ts +2 -0
  423. package/publications/report-builder-dashboard-builders.js +42 -0
  424. package/publications/report-builder-dashboard-builders.js.map +1 -0
  425. package/publications/report-builder-libraries.d.ts +2 -0
  426. package/publications/report-builder-libraries.js +90 -0
  427. package/publications/report-builder-libraries.js.map +1 -0
  428. package/publications/report-builder-reports.d.ts +2 -0
  429. package/publications/report-builder-reports.js +50 -0
  430. package/publications/report-builder-reports.js.map +1 -0
  431. package/publications/super-admin.d.ts +2 -0
  432. package/publications/super-admin.js +16 -0
  433. package/publications/super-admin.js.map +1 -0
  434. package/publications/user-groups.d.ts +1 -0
  435. package/publications/user-groups.js +16 -0
  436. package/publications/user-groups.js.map +1 -0
  437. package/publications/user-guides.d.ts +1 -0
  438. package/publications/user-guides.js +16 -0
  439. package/publications/user-guides.js.map +1 -0
  440. package/resolveio-server-app.d.ts +70 -0
  441. package/resolveio-server-app.js +801 -0
  442. package/resolveio-server-app.js.map +1 -0
  443. package/server-app.d.ts +228 -0
  444. package/server-app.js +3566 -0
  445. package/server-app.js.map +1 -0
  446. package/services/codex-client.d.ts +128 -0
  447. package/services/codex-client.js +1629 -0
  448. package/services/codex-client.js.map +1 -0
  449. package/services/openai-client.d.ts +46 -0
  450. package/services/openai-client.js +318 -0
  451. package/services/openai-client.js.map +1 -0
  452. package/types/error-report.d.ts +25 -0
  453. package/types/error-report.js +4 -0
  454. package/types/error-report.js.map +1 -0
  455. package/types/slow-query-report.d.ts +27 -0
  456. package/types/slow-query-report.js +6 -0
  457. package/types/slow-query-report.js.map +1 -0
  458. package/util/ai-qa-policy.d.ts +124 -0
  459. package/util/ai-qa-policy.js +736 -0
  460. package/util/ai-qa-policy.js.map +1 -0
  461. package/util/ai-run-evidence-adapters.d.ts +109 -0
  462. package/util/ai-run-evidence-adapters.js +7234 -0
  463. package/util/ai-run-evidence-adapters.js.map +1 -0
  464. package/util/ai-run-evidence-dashboard.d.ts +88 -0
  465. package/util/ai-run-evidence-dashboard.js +343 -0
  466. package/util/ai-run-evidence-dashboard.js.map +1 -0
  467. package/util/ai-run-evidence-eval.d.ts +86 -0
  468. package/util/ai-run-evidence-eval.js +1018 -0
  469. package/util/ai-run-evidence-eval.js.map +1 -0
  470. package/util/ai-run-evidence.d.ts +244 -0
  471. package/util/ai-run-evidence.js +1096 -0
  472. package/util/ai-run-evidence.js.map +1 -0
  473. package/util/ai-runner-artifacts.d.ts +82 -0
  474. package/util/ai-runner-artifacts.js +713 -0
  475. package/util/ai-runner-artifacts.js.map +1 -0
  476. package/util/ai-runner-manager-autopilot.d.ts +210 -0
  477. package/util/ai-runner-manager-autopilot.js +642 -0
  478. package/util/ai-runner-manager-autopilot.js.map +1 -0
  479. package/util/ai-runner-manager-policy.d.ts +807 -0
  480. package/util/ai-runner-manager-policy.js +3501 -0
  481. package/util/ai-runner-manager-policy.js.map +1 -0
  482. package/util/ai-runner-qa-auth.d.ts +5 -0
  483. package/util/ai-runner-qa-auth.js +839 -0
  484. package/util/ai-runner-qa-auth.js.map +1 -0
  485. package/util/ai-runner-qa-tools.d.ts +26 -0
  486. package/util/ai-runner-qa-tools.js +3520 -0
  487. package/util/ai-runner-qa-tools.js.map +1 -0
  488. package/util/aicoder-runner-v6.d.ts +426 -0
  489. package/util/aicoder-runner-v6.js +2464 -0
  490. package/util/aicoder-runner-v6.js.map +1 -0
  491. package/util/common.d.ts +31 -0
  492. package/util/common.js +683 -0
  493. package/util/common.js.map +1 -0
  494. package/util/customer-portal-password.d.ts +13 -0
  495. package/util/customer-portal-password.js +209 -0
  496. package/util/customer-portal-password.js.map +1 -0
  497. package/util/error-reporter.d.ts +52 -0
  498. package/util/error-reporter.js +326 -0
  499. package/util/error-reporter.js.map +1 -0
  500. package/util/error-tracking.d.ts +13 -0
  501. package/util/error-tracking.js +120 -0
  502. package/util/error-tracking.js.map +1 -0
  503. package/util/openai-usage-cost.d.ts +6 -0
  504. package/util/openai-usage-cost.js +103 -0
  505. package/util/openai-usage-cost.js.map +1 -0
  506. package/util/report-builder-unwinds.d.ts +15 -0
  507. package/util/report-builder-unwinds.js +156 -0
  508. package/util/report-builder-unwinds.js.map +1 -0
  509. package/util/runner-process-janitor.d.ts +27 -0
  510. package/util/runner-process-janitor.js +208 -0
  511. package/util/runner-process-janitor.js.map +1 -0
  512. package/util/schema-report-builder.d.ts +6 -0
  513. package/util/schema-report-builder.js +481 -0
  514. package/util/schema-report-builder.js.map +1 -0
  515. package/util/slow-query-reporter.d.ts +28 -0
  516. package/util/slow-query-reporter.js +226 -0
  517. package/util/slow-query-reporter.js.map +1 -0
  518. package/util/subscription-dependency-context.d.ts +34 -0
  519. package/util/subscription-dependency-context.js +1283 -0
  520. package/util/subscription-dependency-context.js.map +1 -0
  521. package/util/support-runner-v5.d.ts +1426 -0
  522. package/util/support-runner-v5.js +7647 -0
  523. package/util/support-runner-v5.js.map +1 -0
  524. package/util/tokenizer.d.ts +5 -0
  525. package/util/tokenizer.js +41 -0
  526. package/util/tokenizer.js.map +1 -0
  527. package/workers/codex-runner.worker.d.ts +1 -0
  528. package/workers/codex-runner.worker.js +192 -0
  529. package/workers/codex-runner.worker.js.map +1 -0
  530. package/.nodemon.json +0 -5
  531. package/.vscode/settings.json +0 -21
  532. package/AGENTS.md +0 -195
  533. package/README.md +0 -22
  534. package/build_package.sh +0 -5
  535. package/compileDTS.pl +0 -64
  536. package/docs/ai-assistant-nightly-eval.md +0 -65
  537. package/docs/ai-assistant-preflight-checklist.md +0 -23
  538. package/docs/ai-assistant-report-builder-bridge-playbook.md +0 -115
  539. package/eslint-plugin-custom/index.js +0 -7
  540. package/eslint-plugin-custom/rules/no-filter-zero-index.js +0 -44
  541. package/eslint.config.js +0 -103
  542. package/gulpfile.js +0 -216
  543. package/methodAndPublicationListGenerator.py +0 -375
  544. package/mongodbensurers.js +0 -2
  545. package/mongostop.js +0 -3
  546. package/scripts/cleanup-bypassed-callmethod-logs.js +0 -616
  547. package/settings.development.json +0 -25
  548. package/settings.development.redacted.json +0 -25
  549. package/src/.env +0 -12
  550. package/src/ai/assistant-core-heuristics.ts +0 -379
  551. package/src/ai/resolveio-platform-intelligence-memory-corpus.ts +0 -185
  552. package/src/ai/resolveio-platform-intelligence-memory.ts +0 -325
  553. package/src/ai/resolveio-platform-intelligence.ts +0 -462
  554. package/src/client-server-app.ts +0 -12
  555. package/src/collections/ai-run.collection.ts +0 -117
  556. package/src/collections/ai-terminal-conversation.collection.ts +0 -91
  557. package/src/collections/ai-terminal-issue-report.collection.ts +0 -99
  558. package/src/collections/ai-terminal-message.collection.ts +0 -77
  559. package/src/collections/app-setting.collection.ts +0 -104
  560. package/src/collections/app-status.collection.ts +0 -58
  561. package/src/collections/communication-metric.collection.ts +0 -84
  562. package/src/collections/counter.collection.ts +0 -56
  563. package/src/collections/cron-job-history.collection.ts +0 -94
  564. package/src/collections/cron-job.collection.ts +0 -92
  565. package/src/collections/customer-notification.collection.ts +0 -131
  566. package/src/collections/customer-portal-password.collection.ts +0 -76
  567. package/src/collections/email-history.collection.ts +0 -134
  568. package/src/collections/email-verified.collection.ts +0 -62
  569. package/src/collections/file.collection.ts +0 -74
  570. package/src/collections/flag-update.collection.ts +0 -57
  571. package/src/collections/flag.collection.ts +0 -57
  572. package/src/collections/log-method-latency.collection.ts +0 -77
  573. package/src/collections/log-subscription.collection.ts +0 -80
  574. package/src/collections/log.collection.ts +0 -93
  575. package/src/collections/logged-in-users.collection.ts +0 -67
  576. package/src/collections/monitor-cpu.collection.ts +0 -65
  577. package/src/collections/monitor-function.collection.ts +0 -74
  578. package/src/collections/monitor-memory.collection.ts +0 -77
  579. package/src/collections/monitor-mongo.collection.ts +0 -71
  580. package/src/collections/notification.collection.ts +0 -57
  581. package/src/collections/openai-usage-ledger.collection.ts +0 -131
  582. package/src/collections/report-builder-dashboard-builder.collection.ts +0 -109
  583. package/src/collections/report-builder-library.collection.ts +0 -89
  584. package/src/collections/report-builder-report.collection.ts +0 -184
  585. package/src/collections/user-group.collection.ts +0 -89
  586. package/src/collections/user-guide.collection.ts +0 -57
  587. package/src/collections/user.collection.ts +0 -181
  588. package/src/cron/cron.ts +0 -117
  589. package/src/fixtures/cron-jobs.ts +0 -95
  590. package/src/fixtures/init.ts +0 -35
  591. package/src/http/auth.ts +0 -818
  592. package/src/http/health.ts +0 -7
  593. package/src/http/home.ts +0 -90
  594. package/src/http/slow-query-publication.ts +0 -49
  595. package/src/index.ts +0 -1
  596. package/src/managers/ai-assistant-codex-manager.manager.ts +0 -1131
  597. package/src/managers/ai-run-evidence.manager.ts +0 -264
  598. package/src/managers/communication-metric.manager.ts +0 -82
  599. package/src/managers/cron.manager.ts +0 -333
  600. package/src/managers/customer-notification-content.manager.ts +0 -236
  601. package/src/managers/diagnostic-manager-bootstrap.ts +0 -165
  602. package/src/managers/error-auto-fix.manager.ts +0 -2767
  603. package/src/managers/local-log.manager.ts +0 -113
  604. package/src/managers/method.manager.ts +0 -1857
  605. package/src/managers/mongo.manager.ts +0 -4575
  606. package/src/managers/monitor.manager.ts +0 -507
  607. package/src/managers/openai-usage-ledger.manager.ts +0 -112
  608. package/src/managers/slow-query-verifier.manager.ts +0 -3590
  609. package/src/managers/slow-query.manager.ts +0 -519
  610. package/src/managers/subscription.manager.ts +0 -3128
  611. package/src/managers/websocket.manager.ts +0 -746
  612. package/src/managers/worker-dispatcher.manager.ts +0 -1360
  613. package/src/managers/worker-server.manager.ts +0 -536
  614. package/src/methods/accounts.ts +0 -532
  615. package/src/methods/ai-terminal.ts +0 -29070
  616. package/src/methods/app-settings.ts +0 -114
  617. package/src/methods/aws.ts +0 -649
  618. package/src/methods/collections.ts +0 -641
  619. package/src/methods/counters.ts +0 -69
  620. package/src/methods/cron-jobs.ts +0 -2614
  621. package/src/methods/customer-notifications.ts +0 -458
  622. package/src/methods/diagnostics.ts +0 -616
  623. package/src/methods/flag-updates.ts +0 -7
  624. package/src/methods/flags.ts +0 -7
  625. package/src/methods/logs.ts +0 -657
  626. package/src/methods/mongo-explorer.ts +0 -1880
  627. package/src/methods/monitor.ts +0 -540
  628. package/src/methods/pdf.ts +0 -1236
  629. package/src/methods/publications.ts +0 -129
  630. package/src/methods/report-builder.ts +0 -3300
  631. package/src/methods/support.ts +0 -335
  632. package/src/models/ai-run.model.ts +0 -27
  633. package/src/models/ai-terminal-conversation.model.ts +0 -19
  634. package/src/models/ai-terminal-issue-report.model.ts +0 -21
  635. package/src/models/ai-terminal-message.model.ts +0 -24
  636. package/src/models/app-setting.model.ts +0 -17
  637. package/src/models/collection-document.model.ts +0 -24
  638. package/src/models/communication-metric.model.ts +0 -23
  639. package/src/models/cron-job-history.model.ts +0 -16
  640. package/src/models/cron-job.model.ts +0 -15
  641. package/src/models/customer-notification.model.ts +0 -28
  642. package/src/models/customer-portal-password.model.ts +0 -12
  643. package/src/models/dialog.model.ts +0 -25
  644. package/src/models/log-method-latency.model.ts +0 -11
  645. package/src/models/log.model.ts +0 -19
  646. package/src/models/method.model.ts +0 -25
  647. package/src/models/monitor-function.model.ts +0 -16
  648. package/src/models/monitor-memory.model.ts +0 -17
  649. package/src/models/monitor-mongo.model.ts +0 -15
  650. package/src/models/openai-usage-ledger.model.ts +0 -56
  651. package/src/models/pagination.model.ts +0 -35
  652. package/src/models/permission.model.ts +0 -14
  653. package/src/models/report-builder-dashboard-builder.model.ts +0 -29
  654. package/src/models/report-builder-library.model.ts +0 -20
  655. package/src/models/report-builder-report.model.ts +0 -136
  656. package/src/models/report-builder.model.ts +0 -68
  657. package/src/models/select-data-label.model.ts +0 -9
  658. package/src/models/server-message.model.ts +0 -31
  659. package/src/models/slow-query-report.model.ts +0 -23
  660. package/src/models/subscription.model.ts +0 -73
  661. package/src/models/support-ticket.model.ts +0 -104
  662. package/src/models/user-group.model.ts +0 -24
  663. package/src/models/user.model.ts +0 -96
  664. package/src/private/images/ResolveIO.png +0 -0
  665. package/src/publications/ai-terminal.ts +0 -73
  666. package/src/publications/app-settings.ts +0 -25
  667. package/src/publications/app-status.ts +0 -13
  668. package/src/publications/cron-jobs.ts +0 -40
  669. package/src/publications/customer-notifications.ts +0 -101
  670. package/src/publications/files.ts +0 -33
  671. package/src/publications/flags-update.ts +0 -19
  672. package/src/publications/flags.ts +0 -19
  673. package/src/publications/logs.ts +0 -163
  674. package/src/publications/notifications.ts +0 -13
  675. package/src/publications/report-builder-dashboard-builders.ts +0 -39
  676. package/src/publications/report-builder-libraries.ts +0 -41
  677. package/src/publications/report-builder-reports.ts +0 -47
  678. package/src/publications/super-admin.ts +0 -13
  679. package/src/publications/user-groups.ts +0 -12
  680. package/src/publications/user-guides.ts +0 -12
  681. package/src/resolveio-server-app.ts +0 -617
  682. package/src/server-app.ts +0 -3354
  683. package/src/services/codex-client.ts +0 -1231
  684. package/src/services/openai-client.ts +0 -265
  685. package/src/types/error-report.ts +0 -26
  686. package/src/types/js-tiktoken.d.ts +0 -11
  687. package/src/types/slow-query-report.ts +0 -28
  688. package/src/util/ai-qa-policy.ts +0 -925
  689. package/src/util/ai-run-evidence-adapters.ts +0 -8347
  690. package/src/util/ai-run-evidence-dashboard.ts +0 -323
  691. package/src/util/ai-run-evidence-eval.ts +0 -1057
  692. package/src/util/ai-run-evidence.ts +0 -1430
  693. package/src/util/ai-runner-artifacts.ts +0 -586
  694. package/src/util/ai-runner-manager-autopilot.ts +0 -961
  695. package/src/util/ai-runner-manager-policy.ts +0 -5011
  696. package/src/util/ai-runner-qa-auth.ts +0 -838
  697. package/src/util/ai-runner-qa-tools.ts +0 -3536
  698. package/src/util/aicoder-runner-v6.ts +0 -3121
  699. package/src/util/common.ts +0 -649
  700. package/src/util/customer-portal-password.ts +0 -183
  701. package/src/util/error-reporter.ts +0 -332
  702. package/src/util/error-tracking.ts +0 -79
  703. package/src/util/openai-usage-cost.ts +0 -114
  704. package/src/util/report-builder-unwinds.ts +0 -180
  705. package/src/util/runner-process-janitor.ts +0 -219
  706. package/src/util/schema-report-builder.ts +0 -448
  707. package/src/util/slow-query-reporter.ts +0 -216
  708. package/src/util/subscription-dependency-context.ts +0 -1096
  709. package/src/util/support-runner-v5.ts +0 -10040
  710. package/src/util/tokenizer.ts +0 -38
  711. package/src/workers/codex-runner.worker.ts +0 -142
  712. package/start_server.sh +0 -5
  713. package/tests/ai-assistant-corpus-build.ts +0 -484
  714. package/tests/ai-assistant-corpus-replay-e2e.ts +0 -774
  715. package/tests/ai-assistant-data-parity-e2e.ts +0 -1989
  716. package/tests/ai-assistant-eval-triage.ts +0 -831
  717. package/tests/ai-assistant-openai-e2e.ts +0 -1061
  718. package/tests/ai-assistant-openai-git-e2e.ts +0 -155
  719. package/tests/ai-assistant-preflight-matrix.ts +0 -215
  720. package/tests/ai-assistant-routing-eval.test.ts +0 -585
  721. package/tests/ai-assistant-snf-live-eval.ts +0 -975
  722. package/tests/ai-assistant-utils.test.ts +0 -4834
  723. package/tests/ai-manager-autopilot-snapshot.test.ts +0 -193
  724. package/tests/ai-manager-recovery-checkpoint.test.ts +0 -1383
  725. package/tests/ai-run-eval.test.ts +0 -132
  726. package/tests/ai-run-evidence.test.ts +0 -3773
  727. package/tests/ai-runner-contract.test.ts +0 -515
  728. package/tests/aicoder-runner-v6.test.ts +0 -822
  729. package/tests/error-reporter.test.ts +0 -145
  730. package/tests/method-publication-generator.test.ts +0 -46
  731. package/tests/report-builder-linking.test.ts +0 -79
  732. package/tests/resolveio-platform-intelligence.test.ts +0 -352
  733. package/tests/server-app-cron-owner.test.ts +0 -127
  734. package/tests/subscription-connect-race.test.ts +0 -158
  735. package/tests/subscription-dependency-context.test.ts +0 -324
  736. package/tests/subscription-manager-collection-tracking.test.ts +0 -86
  737. package/tests/subscription-manager-invalidation.test.ts +0 -86
  738. package/tests/support-runner-v5.test.ts +0 -3201
  739. package/tsconfig.json +0 -34
  740. /package/{src/private → private}/email-templates/enrollment.html +0 -0
  741. /package/{src/private → private}/email-templates/forgot-password.html +0 -0
  742. /package/{src/private → private}/email-templates/support-ticket-deleted.html +0 -0
  743. /package/{src/private → private}/email-templates/support-ticket-modified.html +0 -0
  744. /package/{src/private → private}/email-templates/support-ticket.html +0 -0
  745. /package/{src/public_api.ts → public_api.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/ai-runner-qa-tools.ts"],"names":[],"mappings":"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","file":"ai-runner-qa-tools.js","sourcesContent":["import { buildRunnerProcessJanitorShellLibrary } from './runner-process-janitor';\n\nexport interface ResolveIORunnerQaToolBundleOptions {\n\tmode?: 'support' | 'runner';\n\tqaClientPort?: number | string;\n\tdefaultUsername?: string;\n\tdefaultPassword?: string;\n\tjobId?: string;\n\townerId?: string;\n\trunnerToken?: string;\n\trunnerRunId?: string;\n\trunnerGeneration?: string | number;\n\tmongoRuntimePath?: string;\n\tqaLiveDataRequired?: boolean;\n\ttoolsBinPath?: string;\n\tbrowserslistPath?: string;\n\tmongodbBinaryCachePath?: string;\n\ttmpRoot?: string;\n\thomeRoot?: string;\n}\n\nfunction shellDoubleQuote(value: string): string {\n\treturn String(value || '').replace(/[\"\\\\$`]/g, '\\\\$&');\n}\n\nfunction normalizePort(value: number | string | undefined, fallback: string): string {\n\tconst parsed = Number.parseInt(String(value || ''), 10);\n\treturn Number.isFinite(parsed) && parsed > 0 ? String(parsed) : fallback;\n}\n\nfunction envVar(mode: 'support' | 'runner', suffix: string): string {\n\treturn mode === 'support' ? `RESOLVEIO_SUPPORT_QA_${suffix}` : `RESOLVEIO_RUNNER_QA_${suffix}`;\n}\n\nexport function buildResolveIORunnerQaEnvScript(options: ResolveIORunnerQaToolBundleOptions = {}): string {\n\tconst mode = options.mode || 'runner';\n\tconst altMode = mode === 'support' ? 'runner' : 'support';\n\tconst tmpRoot = options.tmpRoot || (mode === 'support' ? '/tmp/resolveio-support-qa' : '/tmp/resolveio-ai-runner-qa');\n\tconst homeRoot = options.homeRoot || `${tmpRoot}/home`;\n\tconst defaultPort = normalizePort(options.qaClientPort, '4200');\n\tconst username = shellDoubleQuote(options.defaultUsername || 'admin');\n\tconst password = shellDoubleQuote(options.defaultPassword || '');\n\tconst jobId = shellDoubleQuote(options.jobId || '');\n\tconst ownerId = shellDoubleQuote(options.ownerId || '');\n\tconst runnerToken = shellDoubleQuote(options.runnerToken || '');\n\tconst runnerRunId = shellDoubleQuote(options.runnerRunId || '');\n\tconst runnerGeneration = shellDoubleQuote(String(options.runnerGeneration || ''));\n\tconst mongoRuntimePath = shellDoubleQuote(options.mongoRuntimePath || '');\n\tconst qaLiveDataRequired = options.qaLiveDataRequired === true ? 'true' : 'false';\n\tconst toolsBinPath = options.toolsBinPath || '';\n\tconst browserslistPath = options.browserslistPath || '';\n\tconst mongodbBinaryCachePath = options.mongodbBinaryCachePath || '';\n\tconst clientPortVar = envVar(mode, 'CLIENT_PORT');\n\tconst altClientPortVar = envVar(altMode, 'CLIENT_PORT');\n\tconst clientUrlVar = envVar(mode, 'CLIENT_URL');\n\tconst altClientUrlVar = envVar(altMode, 'CLIENT_URL');\n\tconst serverUrlVar = envVar(mode, 'SERVER_URL');\n\tconst altServerUrlVar = envVar(altMode, 'SERVER_URL');\n\tconst usernameVar = envVar(mode, 'USERNAME');\n\tconst altUsernameVar = envVar(altMode, 'USERNAME');\n\tconst passwordVar = envVar(mode, 'PASSWORD');\n\tconst altPasswordVar = envVar(altMode, 'PASSWORD');\n\tconst viewportWidthVar = envVar(mode, 'VIEWPORT_WIDTH');\n\tconst altViewportWidthVar = envVar(altMode, 'VIEWPORT_WIDTH');\n\tconst viewportHeightVar = envVar(mode, 'VIEWPORT_HEIGHT');\n\tconst altViewportHeightVar = envVar(altMode, 'VIEWPORT_HEIGHT');\n\tconst timeoutVar = envVar(mode, 'ANGULAR_STARTUP_TIMEOUT_SECONDS');\n\tconst altTimeoutVar = envVar(altMode, 'ANGULAR_STARTUP_TIMEOUT_SECONDS');\n\tconst prebundleVar = envVar(mode, 'ANGULAR_PREBUNDLE');\n\tconst altPrebundleVar = envVar(altMode, 'ANGULAR_PREBUNDLE');\n\tconst reuseVar = envVar(mode, 'REUSE_RUNNING');\n\tconst altReuseVar = envVar(altMode, 'REUSE_RUNNING');\n\tconst keepaliveVar = envVar(mode, 'KEEPALIVE');\n\tconst altKeepaliveVar = envVar(altMode, 'KEEPALIVE');\n\tconst mongoPortVar = envVar(mode, 'MONGO_PORT');\n\tconst altMongoPortVar = envVar(altMode, 'MONGO_PORT');\n\tconst mongoUrlVar = envVar(mode, 'MONGO_URL');\n\tconst altMongoUrlVar = envVar(altMode, 'MONGO_URL');\n\tconst browserLoopVar = mode === 'support' ? 'RESOLVEIO_SUPPORT_QA_BROWSER' : 'RESOLVEIO_RUNNER_QA_BROWSER';\n\treturn [\n\t\t`export ${mode === 'support' ? 'RESOLVEIO_SUPPORT_QA_TMP' : 'RESOLVEIO_RUNNER_QA_TMP'}=\"${'${' + (mode === 'support' ? 'RESOLVEIO_SUPPORT_QA_TMP' : 'RESOLVEIO_RUNNER_QA_TMP') + ':-' + tmpRoot + '}'}\"`,\n\t\t`export ${mode === 'support' ? 'RESOLVEIO_SUPPORT_QA_HOME' : 'RESOLVEIO_RUNNER_QA_HOME'}=\"${'${' + (mode === 'support' ? 'RESOLVEIO_SUPPORT_QA_HOME' : 'RESOLVEIO_RUNNER_QA_HOME') + ':-' + homeRoot + '}'}\"`,\n\t\t`RESOLVEIO_QA_TMP=\"${'${' + (mode === 'support' ? 'RESOLVEIO_SUPPORT_QA_TMP' : 'RESOLVEIO_RUNNER_QA_TMP') + '}'}\"`,\n\t\t`RESOLVEIO_QA_HOME=\"${'${' + (mode === 'support' ? 'RESOLVEIO_SUPPORT_QA_HOME' : 'RESOLVEIO_RUNNER_QA_HOME') + '}'}\"`,\n\t\t'RESOLVEIO_QA_TOOLS_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"',\n\t\t'if [ -z \"${RESOLVEIO_SUPPORT_CODEX_LANE:-}\" ] && [ -f \"$RESOLVEIO_QA_TOOLS_DIR/current-codex-lane\" ]; then',\n\t\t' RESOLVEIO_SUPPORT_CODEX_LANE=\"$(tr -d \"\\\\r\\\\n\\\\t \" < \"$RESOLVEIO_QA_TOOLS_DIR/current-codex-lane\" 2>/dev/null || true)\"',\n\t\t' export RESOLVEIO_SUPPORT_CODEX_LANE',\n\t\t'fi',\n\t\t'resolveio_support_codex_lane_is_build() {',\n\t\t' case \"${RESOLVEIO_SUPPORT_CODEX_LANE:-}\" in build|support_build|support-build) return 0 ;; *) return 1 ;; esac',\n\t\t'}',\n\t\t'resolveio_support_codex_block_build_lane_qa() {',\n\t\t' resolveio_support_codex_lane_is_build || return 0',\n\t\t' echo \"ResolveIO support lane guard: build lane cannot run local QA/browser/server/client commands; return a build fix and let the QA lane run browser validation.\" >&2',\n\t\t' return 86',\n\t\t'}',\n\t\t'mkdir -p \"$RESOLVEIO_QA_HOME/.nvm\" \"$RESOLVEIO_QA_TMP/npm-cache\" \"$RESOLVEIO_QA_TMP/mongodb-binaries\" \"$RESOLVEIO_QA_TMP/mongodb-memory-server-core\"',\n\t\t'if [ ! -f \"$RESOLVEIO_QA_HOME/.nvm/nvm.sh\" ]; then',\n\t\t' cat > \"$RESOLVEIO_QA_HOME/.nvm/nvm.sh\" <<\\'RESOLVEIO_NVM_SHIM\\'',\n\t\t'nvm() {',\n\t\t' case \"$1\" in',\n\t\t' use|install|alias) return 0 ;;',\n\t\t' current) node -v 2>/dev/null || true; return 0 ;;',\n\t\t' *) return 0 ;;',\n\t\t' esac',\n\t\t'}',\n\t\t'RESOLVEIO_NVM_SHIM',\n\t\t'fi',\n\t\t'export HOME=\"$RESOLVEIO_QA_HOME\"',\n\t\t'export NVM_DIR=\"$RESOLVEIO_QA_HOME/.nvm\"',\n\t\t'export RESOLVEIO_QA_COMMAND_GUARD_BIN=\"$RESOLVEIO_QA_TMP/command-guard-bin\"',\n\t\t'mkdir -p \"$RESOLVEIO_QA_COMMAND_GUARD_BIN\"',\n\t\t'resolveio_qa_find_real_command() {',\n\t\t' local name=\"$1\"',\n\t\t' local old_ifs=\"$IFS\"',\n\t\t' IFS=\":\"',\n\t\t' for dir in $PATH; do',\n\t\t' [ -n \"$dir\" ] || continue',\n\t\t' [ \"$dir\" = \"$RESOLVEIO_QA_COMMAND_GUARD_BIN\" ] && continue',\n\t\t' if [ -x \"$dir/$name\" ]; then',\n\t\t' echo \"$dir/$name\"',\n\t\t' IFS=\"$old_ifs\"',\n\t\t' return 0',\n\t\t' fi',\n\t\t' done',\n\t\t' IFS=\"$old_ifs\"',\n\t\t' return 1',\n\t\t'}',\n\t\t'export RESOLVEIO_QA_REAL_NPM=\"${RESOLVEIO_QA_REAL_NPM:-$(resolveio_qa_find_real_command npm || true)}\"',\n\t\t'if [ -n \"$RESOLVEIO_QA_REAL_NPM\" ]; then',\n\t\t' cat > \"$RESOLVEIO_QA_COMMAND_GUARD_BIN/npm\" <<\\'RESOLVEIO_QA_NPM_GUARD\\'',\n\t\t'#!/usr/bin/env bash',\n\t\t'set -u',\n\t\t'REAL_NPM=\"${RESOLVEIO_QA_REAL_NPM:-}\"',\n\t\t'GUARD_BIN=\"${RESOLVEIO_QA_COMMAND_GUARD_BIN:-}\"',\n\t\t'if [ -z \"$REAL_NPM\" ] || [ \"$REAL_NPM\" = \"$0\" ]; then',\n\t\t' OLD_IFS=\"$IFS\"',\n\t\t' IFS=\":\"',\n\t\t' for dir in $PATH; do',\n\t\t' [ -n \"$dir\" ] || continue',\n\t\t' [ -n \"$GUARD_BIN\" ] && [ \"$dir\" = \"$GUARD_BIN\" ] && continue',\n\t\t' if [ -x \"$dir/npm\" ]; then REAL_NPM=\"$dir/npm\"; break; fi',\n\t\t' done',\n\t\t' IFS=\"$OLD_IFS\"',\n\t\t'fi',\n\t\t'if [ -z \"$REAL_NPM\" ] || [ ! -x \"$REAL_NPM\" ]; then',\n\t\t' echo \"ResolveIO QA command guard: unable to locate real npm.\" >&2',\n\t\t' exit 127',\n\t\t'fi',\n\t\t'if [ \"${RESOLVEIO_SUPPORT_CODEX_LANE:-}\" = \"build\" ] || [ \"${RESOLVEIO_SUPPORT_CODEX_LANE:-}\" = \"support_build\" ] || [ \"${RESOLVEIO_SUPPORT_CODEX_LANE:-}\" = \"support-build\" ]; then',\n\t\t' if [ \"${1:-}\" = \"run\" ]; then',\n\t\t' case \"${2:-}\" in',\n\t\t' build-dev)',\n\t\t' echo \"ResolveIO support lane guard: refusing npm run build-dev from the 5.3 build lane. Use a finite build-prod/tsc/unit self-gate or return a blocked self-gate.\" >&2',\n\t\t' exit 86',\n\t\t' ;;',\n\t\t' server|client|start|dev|serve|local-qa|qa|qa:*|test:browser|test:e2e|e2e)',\n\t\t' echo \"ResolveIO support lane guard: refusing npm run ${2:-} from the 5.3 build lane. Browser/server/client QA belongs to the 5.4 mini QA lane.\" >&2',\n\t\t' exit 86',\n\t\t' ;;',\n\t\t' esac',\n\t\t' fi',\n\t\t'fi',\n\t\t'is_angular_build=0',\n\t\t'if [ \"${1:-}\" = \"run\" ]; then',\n\t\t' case \"${2:-}\" in',\n\t\t' build|build-dev|build-prod) is_angular_build=1 ;;',\n\t\t' esac',\n\t\t'fi',\n\t\t'resolveio_lock_live() {',\n\t\t' local file=\"$1\"',\n\t\t' local ttl=\"${RESOLVEIO_QA_COMMAND_LOCK_TTL_SECONDS:-1800}\"',\n\t\t' [ -f \"$file\" ] || return 1',\n\t\t' node - \"$file\" \"$ttl\" <<\\'RESOLVEIO_QA_LOCK_LIVE\\'',\n\t\t'const fs = require(\"fs\");',\n\t\t'const [file, ttlRaw] = process.argv.slice(2);',\n\t\t'const ttlMs = Math.max(1, Number(ttlRaw || 1800)) * 1000;',\n\t\t'try {',\n\t\t' const data = JSON.parse(fs.readFileSync(file, \"utf8\"));',\n\t\t' const pid = Number(data.pid || 0);',\n\t\t' const heartbeat = Date.parse(data.heartbeat_at || data.started_at || \"\");',\n\t\t' if (!pid || !heartbeat || Date.now() - heartbeat > ttlMs) process.exit(1);',\n\t\t' process.kill(pid, 0);',\n\t\t' process.exit(0);',\n\t\t'} catch (error) { process.exit(1); }',\n\t\t'RESOLVEIO_QA_LOCK_LIVE',\n\t\t'}',\n\t\t'if [ \"$is_angular_build\" = \"1\" ]; then',\n\t\t' PROJECT_ROOT=\"${RESOLVEIO_SUPPORT_QA_PROJECT_ROOT:-${RESOLVEIO_RUNNER_QA_PROJECT_ROOT:-$(pwd)}}\"',\n\t\t' PROJECT_ROOT=\"$(cd \"$PROJECT_ROOT\" 2>/dev/null && pwd || pwd)\"',\n\t\t' ARTIFACT_DIR=\"$PROJECT_ROOT/qa-artifacts\"',\n\t\t' mkdir -p \"$ARTIFACT_DIR/.command-locks\"',\n\t\t' QA_LOCK=\"$ARTIFACT_DIR/.qa.lock/lock.json\"',\n\t\t' if resolveio_lock_live \"$QA_LOCK\"; then',\n\t\t' echo \"ResolveIO QA command guard: refusing npm run ${2:-} while local QA harness is active for $PROJECT_ROOT. Stop QA first with stop-local-qa.sh.\" >&2',\n\t\t' exit 86',\n\t\t' fi',\n\t\t' BUILD_LOCK_DIR=\"$ARTIFACT_DIR/.command-locks/angular-build.lock\"',\n\t\t' BUILD_LOCK_JSON=\"$BUILD_LOCK_DIR/lock.json\"',\n\t\t' if ! mkdir \"$BUILD_LOCK_DIR\" 2>/dev/null; then',\n\t\t' if resolveio_lock_live \"$BUILD_LOCK_JSON\"; then',\n\t\t' echo \"ResolveIO QA command guard: refusing duplicate npm run ${2:-}; another Angular build is active for $PROJECT_ROOT.\" >&2',\n\t\t' exit 86',\n\t\t' fi',\n\t\t' rm -rf \"$BUILD_LOCK_DIR\" 2>/dev/null || true',\n\t\t' if ! mkdir \"$BUILD_LOCK_DIR\" 2>/dev/null; then',\n\t\t' echo \"ResolveIO QA command guard: unable to acquire Angular build lock for $PROJECT_ROOT.\" >&2',\n\t\t' exit 86',\n\t\t' fi',\n\t\t' fi',\n\t\t' cat > \"$BUILD_LOCK_JSON\" <<EOF',\n\t\t'{\"pid\": $$, \"command\": \"npm $*\", \"project_root\": \"$PROJECT_ROOT\", \"started_at\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\", \"heartbeat_at\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}',\n\t\t'EOF',\n\t\t' ( while true; do node - \"$BUILD_LOCK_JSON\" <<\\'RESOLVEIO_QA_BUILD_HEARTBEAT\\'',\n\t\t'const fs = require(\"fs\");',\n\t\t'const [file] = process.argv.slice(2);',\n\t\t'try {',\n\t\t' const data = JSON.parse(fs.readFileSync(file, \"utf8\"));',\n\t\t' data.heartbeat_at = new Date().toISOString();',\n\t\t' fs.writeFileSync(file, JSON.stringify(data, null, 2));',\n\t\t'} catch (error) {}',\n\t\t'RESOLVEIO_QA_BUILD_HEARTBEAT',\n\t\t' sleep 10',\n\t\t' done ) >/dev/null 2>&1 &',\n\t\t' HEARTBEAT_PID=\"$!\"',\n\t\t' cleanup_build_lock() {',\n\t\t' kill \"$HEARTBEAT_PID\" >/dev/null 2>&1 || true',\n\t\t' rm -rf \"$BUILD_LOCK_DIR\" >/dev/null 2>&1 || true',\n\t\t' }',\n\t\t' trap cleanup_build_lock EXIT INT TERM',\n\t\t'fi',\n\t\t'exec \"$REAL_NPM\" \"$@\"',\n\t\t'RESOLVEIO_QA_NPM_GUARD',\n\t\t' chmod +x \"$RESOLVEIO_QA_COMMAND_GUARD_BIN/npm\"',\n\t\t' export PATH=\"$RESOLVEIO_QA_COMMAND_GUARD_BIN:$PATH\"',\n\t\t' hash -r 2>/dev/null || true',\n\t\t'fi',\n\t\t'export RESOLVEIO_QA_REAL_NODE=\"${RESOLVEIO_QA_REAL_NODE:-$(resolveio_qa_find_real_command node || true)}\"',\n\t\t'if [ -n \"$RESOLVEIO_QA_REAL_NODE\" ]; then',\n\t\t' cat > \"$RESOLVEIO_QA_COMMAND_GUARD_BIN/node\" <<\\'RESOLVEIO_QA_NODE_GUARD\\'',\n\t\t'#!/usr/bin/env bash',\n\t\t'set -u',\n\t\t'REAL_NODE=\"${RESOLVEIO_QA_REAL_NODE:-}\"',\n\t\t'GUARD_BIN=\"${RESOLVEIO_QA_COMMAND_GUARD_BIN:-}\"',\n\t\t'if [ -z \"$REAL_NODE\" ] || [ \"$REAL_NODE\" = \"$0\" ]; then',\n\t\t' OLD_IFS=\"$IFS\"',\n\t\t' IFS=\":\"',\n\t\t' for dir in $PATH; do',\n\t\t' [ -n \"$dir\" ] || continue',\n\t\t' [ -n \"$GUARD_BIN\" ] && [ \"$dir\" = \"$GUARD_BIN\" ] && continue',\n\t\t' if [ -x \"$dir/node\" ]; then REAL_NODE=\"$dir/node\"; break; fi',\n\t\t' done',\n\t\t' IFS=\"$OLD_IFS\"',\n\t\t'fi',\n\t\t'if [ -z \"$REAL_NODE\" ] || [ ! -x \"$REAL_NODE\" ]; then',\n\t\t' echo \"ResolveIO QA command guard: unable to locate real node.\" >&2',\n\t\t' exit 127',\n\t\t'fi',\n\t\t'resolveio_qa_node_guard_active() {',\n\t\t' case \"${RESOLVEIO_SUPPORT_CODEX_LANE:-}\" in qa|support_qa|support-qa) return 0 ;; *) return 1 ;; esac',\n\t\t'}',\n\t\t'resolveio_qa_scan_inline_node_script() {',\n\t\t' local script_file=\"$1\"',\n\t\t' [ -f \"$script_file\" ] || return 0',\n\t\t` if grep -Eiq \"puppeteer browsers install|npx puppeteer|playwright install\" \"$script_file\"; then`,\n\t\t' echo \"ResolveIO QA command guard: refusing browser install/download commands. Use the staged browser executable from PUPPETEER_EXECUTABLE_PATH/CHROME_BIN.\" >&2',\n\t\t' exit 86',\n\t\t' fi',\n\t\t'}',\n\t\t'if resolveio_qa_node_guard_active; then',\n\t\t' case \"${1:-}\" in',\n\t\t' -)',\n\t\t' TMP_SCRIPT=\"${RESOLVEIO_QA_TMP:-/tmp/resolveio-support-qa}/inline-node-guard-$$.js\"',\n\t\t' mkdir -p \"$(dirname \"$TMP_SCRIPT\")\"',\n\t\t' cat > \"$TMP_SCRIPT\"',\n\t\t' resolveio_qa_scan_inline_node_script \"$TMP_SCRIPT\"',\n\t\t' shift',\n\t\t' exec \"$REAL_NODE\" \"$TMP_SCRIPT\" \"$@\"',\n\t\t' ;;',\n\t\t' -e|--eval)',\n\t\t' TMP_SCRIPT=\"${RESOLVEIO_QA_TMP:-/tmp/resolveio-support-qa}/inline-node-guard-$$.js\"',\n\t\t' mkdir -p \"$(dirname \"$TMP_SCRIPT\")\"',\n\t\t' printf \"%s\\\\n\" \"${2:-}\" > \"$TMP_SCRIPT\"',\n\t\t' resolveio_qa_scan_inline_node_script \"$TMP_SCRIPT\"',\n\t\t' exec \"$REAL_NODE\" \"$@\"',\n\t\t' ;;',\n\t\t' esac',\n\t\t'fi',\n\t\t'exec \"$REAL_NODE\" \"$@\"',\n\t\t'RESOLVEIO_QA_NODE_GUARD',\n\t\t' chmod +x \"$RESOLVEIO_QA_COMMAND_GUARD_BIN/node\"',\n\t\t' export PATH=\"$RESOLVEIO_QA_COMMAND_GUARD_BIN:$PATH\"',\n\t\t' hash -r 2>/dev/null || true',\n\t\t'fi',\n\t\ttoolsBinPath ? `export PATH=\"${toolsBinPath}:$PATH\"` : '',\n\t\t'export NODE_ENV=development',\n\t\t'# Local QA must start the application HTTP server even when launched from a dedicated support-manager worker.',\n\t\t'export IS_WORKERS_ENABLED=false',\n\t\t'export IS_WORKER_INSTANCE=false',\n\t\t'export DISABLE_WORKER_SERVER_CONNECTION=false',\n\t\t'export SUPPORT_CODEX_MANAGER_PROCESS_ONLY=false',\n\t\t'export SUPPORT_AUTO_MANAGER_PROCESS_ONLY=false',\n\t\t'export AI_ASSISTANT_CODEX_MANAGER_PROCESS_ONLY=false',\n\t\tbrowserslistPath ? `export BROWSERSLIST_CONFIG=\"${browserslistPath}\"` : '',\n\t\t`export ${clientPortVar}=\"${'${' + clientPortVar + ':-${' + altClientPortVar + ':-' + defaultPort + '}}'}\"`,\n\t\t`export ${altClientPortVar}=\"${'${' + altClientPortVar + ':-${' + clientPortVar + '}}'}\"`,\n\t\t`export ${clientUrlVar}=\"${'${' + clientUrlVar + ':-${' + altClientUrlVar + ':-http://localhost:${' + clientPortVar + '}}}'}\"`,\n\t\t`export ${altClientUrlVar}=\"${'${' + altClientUrlVar + ':-${' + clientUrlVar + '}}'}\"`,\n\t\t`export ${serverUrlVar}=\"${'${' + serverUrlVar + ':-${' + altServerUrlVar + ':-http://localhost:8080}}'}\"`,\n\t\t`export ${altServerUrlVar}=\"${'${' + altServerUrlVar + ':-${' + serverUrlVar + '}}'}\"`,\n\t\t'export ADDITIONAL_ALLOWED_ORIGINS=\"${ADDITIONAL_ALLOWED_ORIGINS:-$' + clientUrlVar + '}\"',\n\t\t`export ${viewportWidthVar}=\"${'${' + viewportWidthVar + ':-${' + altViewportWidthVar + ':-1920}}'}\"`,\n\t\t`export ${altViewportWidthVar}=\"${'${' + altViewportWidthVar + ':-${' + viewportWidthVar + '}}'}\"`,\n\t\t`export ${viewportHeightVar}=\"${'${' + viewportHeightVar + ':-${' + altViewportHeightVar + ':-1080}}'}\"`,\n\t\t`export ${altViewportHeightVar}=\"${'${' + altViewportHeightVar + ':-${' + viewportHeightVar + '}}'}\"`,\n\t\t`export ${timeoutVar}=\"${'${' + timeoutVar + ':-${' + altTimeoutVar + ':-900}}'}\"`,\n\t\t`export ${altTimeoutVar}=\"${'${' + altTimeoutVar + ':-${' + timeoutVar + '}}'}\"`,\n\t\t`export ${prebundleVar}=\"${'${' + prebundleVar + ':-${' + altPrebundleVar + ':-false}}'}\"`,\n\t\t`export ${altPrebundleVar}=\"${'${' + altPrebundleVar + ':-${' + prebundleVar + '}}'}\"`,\n\t\t`export ${reuseVar}=\"${'${' + reuseVar + ':-${' + altReuseVar + ':-true}}'}\"`,\n\t\t`export ${altReuseVar}=\"${'${' + altReuseVar + ':-${' + reuseVar + '}}'}\"`,\n\t\t`export ${keepaliveVar}=\"${'${' + keepaliveVar + ':-${' + altKeepaliveVar + ':-false}}'}\"`,\n\t\t`export ${altKeepaliveVar}=\"${'${' + altKeepaliveVar + ':-${' + keepaliveVar + '}}'}\"`,\n\t\t`export ${mongoPortVar}=\"${'${' + mongoPortVar + ':-${' + altMongoPortVar + ':-3001}}'}\"`,\n\t\t`export ${altMongoPortVar}=\"${'${' + altMongoPortVar + ':-${' + mongoPortVar + '}}'}\"`,\n\t\t'export RESOLVEIO_QA_INHERITED_MONGO_URL=\"${RESOLVEIO_QA_INHERITED_MONGO_URL:-${MONGO_URL:-}}\"',\n\t\t`export ${mongoUrlVar}=\"mongodb://127.0.0.1:${'${' + mongoPortVar + '}'}/resolveio?directConnection=true\"`,\n\t\t`export ${altMongoUrlVar}=\"${'${' + mongoUrlVar + '}'}\"`,\n\t\t`export MONGO_URL=\"${'${' + mongoUrlVar + '}'}\"`,\n\t\t`export ${usernameVar}=\"${'${' + usernameVar + ':-${' + altUsernameVar + ':-' + username + '}}'}\"`,\n\t\t`export ${altUsernameVar}=\"${'${' + altUsernameVar + ':-${' + usernameVar + '}}'}\"`,\n\t\t`export ${passwordVar}=\"${'${' + passwordVar + ':-${' + altPasswordVar + ':-' + password + '}}'}\"`,\n\t\t`export ${altPasswordVar}=\"${'${' + altPasswordVar + ':-${' + passwordVar + '}}'}\"`,\n\t\t`export ${envVar(mode, 'JOB_ID')}=\"${'${' + envVar(mode, 'JOB_ID') + ':-${' + envVar(altMode, 'JOB_ID') + ':-' + jobId + '}}'}\"`,\n\t\t`export ${envVar(altMode, 'JOB_ID')}=\"${'${' + envVar(altMode, 'JOB_ID') + ':-${' + envVar(mode, 'JOB_ID') + '}}'}\"`,\n\t\t`export ${envVar(mode, 'OWNER_ID')}=\"${'${' + envVar(mode, 'OWNER_ID') + ':-${' + envVar(altMode, 'OWNER_ID') + ':-' + ownerId + '}}'}\"`,\n\t\t`export ${envVar(altMode, 'OWNER_ID')}=\"${'${' + envVar(altMode, 'OWNER_ID') + ':-${' + envVar(mode, 'OWNER_ID') + '}}'}\"`,\n\t\t`export ${envVar(mode, 'RUNNER_TOKEN')}=\"${'${' + envVar(mode, 'RUNNER_TOKEN') + ':-${' + envVar(altMode, 'RUNNER_TOKEN') + ':-' + runnerToken + '}}'}\"`,\n\t\t`export ${envVar(altMode, 'RUNNER_TOKEN')}=\"${'${' + envVar(altMode, 'RUNNER_TOKEN') + ':-${' + envVar(mode, 'RUNNER_TOKEN') + '}}'}\"`,\n\t\t`export ${envVar(mode, 'RUNNER_RUN_ID')}=\"${'${' + envVar(mode, 'RUNNER_RUN_ID') + ':-${' + envVar(altMode, 'RUNNER_RUN_ID') + ':-' + runnerRunId + '}}'}\"`,\n\t\t`export ${envVar(altMode, 'RUNNER_RUN_ID')}=\"${'${' + envVar(altMode, 'RUNNER_RUN_ID') + ':-${' + envVar(mode, 'RUNNER_RUN_ID') + '}}'}\"`,\n\t\t`export ${envVar(mode, 'RUNNER_GENERATION')}=\"${'${' + envVar(mode, 'RUNNER_GENERATION') + ':-${' + envVar(altMode, 'RUNNER_GENERATION') + ':-' + runnerGeneration + '}}'}\"`,\n\t\t`export ${envVar(altMode, 'RUNNER_GENERATION')}=\"${'${' + envVar(altMode, 'RUNNER_GENERATION') + ':-${' + envVar(mode, 'RUNNER_GENERATION') + '}}'}\"`,\n\t\tmongoRuntimePath ? `export ${envVar(mode, 'MONGO_RUNTIME_PATH')}=\"${'${' + envVar(mode, 'MONGO_RUNTIME_PATH') + ':-${' + envVar(altMode, 'MONGO_RUNTIME_PATH') + ':-' + mongoRuntimePath + '}}'}\"` : '',\n\t\tmongoRuntimePath ? `export ${envVar(altMode, 'MONGO_RUNTIME_PATH')}=\"${'${' + envVar(altMode, 'MONGO_RUNTIME_PATH') + ':-${' + envVar(mode, 'MONGO_RUNTIME_PATH') + '}}'}\"` : '',\n\t\tmongoRuntimePath ? `export RESOLVEIO_QA_MONGO_RUNTIME_PATH=\"${'${RESOLVEIO_QA_MONGO_RUNTIME_PATH:-$' + envVar(mode, 'MONGO_RUNTIME_PATH') + '}'}\"` : '',\n\t\t`export ${envVar(mode, 'LIVE_DATA_REQUIRED')}=\"${'${' + envVar(mode, 'LIVE_DATA_REQUIRED') + ':-${' + envVar(altMode, 'LIVE_DATA_REQUIRED') + ':-' + qaLiveDataRequired + '}}'}\"`,\n\t\t`export ${envVar(altMode, 'LIVE_DATA_REQUIRED')}=\"${'${' + envVar(altMode, 'LIVE_DATA_REQUIRED') + ':-${' + envVar(mode, 'LIVE_DATA_REQUIRED') + '}}'}\"`,\n\t\t`export RESOLVEIO_QA_LIVE_DATA_REQUIRED=\"${'${RESOLVEIO_QA_LIVE_DATA_REQUIRED:-$' + envVar(mode, 'LIVE_DATA_REQUIRED') + '}'}\"`,\n\t\t'export PUPPETEER_CACHE_DIR=\"/var/lib/resolveio/puppeteer\"',\n\t\t'RESOLVEIO_QA_NODE_PATH_ENTRIES=\"\"',\n\t\t'for RESOLVEIO_QA_NODE_MODULES in \"$PWD/node_modules\" \"$PWD/server/node_modules\" \"$(cd \"$PWD/..\" 2>/dev/null && pwd)/node_modules\" \"$(cd \"$PWD/..\" 2>/dev/null && pwd)/server/node_modules\" /var/app/current/node_modules; do',\n\t\t' if [ -d \"$RESOLVEIO_QA_NODE_MODULES\" ]; then',\n\t\t' if [ -z \"$RESOLVEIO_QA_NODE_PATH_ENTRIES\" ]; then RESOLVEIO_QA_NODE_PATH_ENTRIES=\"$RESOLVEIO_QA_NODE_MODULES\"; else RESOLVEIO_QA_NODE_PATH_ENTRIES=\"$RESOLVEIO_QA_NODE_PATH_ENTRIES:$RESOLVEIO_QA_NODE_MODULES\"; fi',\n\t\t' fi',\n\t\t'done',\n\t\t'if [ -n \"$RESOLVEIO_QA_NODE_PATH_ENTRIES\" ]; then',\n\t\t' export NODE_PATH=\"${NODE_PATH:+$NODE_PATH:}$RESOLVEIO_QA_NODE_PATH_ENTRIES\"',\n\t\t'fi',\n\t\t'unset RESOLVEIO_QA_NODE_MODULES RESOLVEIO_QA_NODE_PATH_ENTRIES',\n\t\t'export PLAYWRIGHT_BROWSERS_PATH=\"${PLAYWRIGHT_BROWSERS_PATH:-$RESOLVEIO_QA_HOME/.cache/ms-playwright}\"',\n\t\t'# QA rows should launch their own scoped browser unless the runner explicitly provides a live endpoint later.',\n\t\t'unset RESOLVEIO_RUNNER_QA_BROWSER_URL RESOLVEIO_SUPPORT_QA_BROWSER_URL',\n\t\t'if [ -n \"${PUPPETEER_EXECUTABLE_PATH:-}\" ] && [ -x \"$PUPPETEER_EXECUTABLE_PATH\" ]; then',\n\t\t' export CHROME_BIN=\"${CHROME_BIN:-$PUPPETEER_EXECUTABLE_PATH}\"',\n\t\t'elif [ -n \"${CHROME_BIN:-}\" ] && [ -x \"$CHROME_BIN\" ]; then',\n\t\t' export PUPPETEER_EXECUTABLE_PATH=\"$CHROME_BIN\"',\n\t\t'else',\n\t\t` for ${browserLoopVar} in /var/lib/resolveio/puppeteer/chrome-headless-shell/linux-*/chrome-headless-shell-linux64/chrome-headless-shell /var/lib/resolveio/puppeteer/chrome/linux-*/chrome-linux64/chrome /usr/bin/google-chrome-stable /usr/bin/google-chrome /usr/bin/chromium /usr/bin/chromium-browser; do`,\n\t\t` if [ -x \"$${browserLoopVar}\" ]; then`,\n\t\t` export PUPPETEER_EXECUTABLE_PATH=\"$${browserLoopVar}\"`,\n\t\t` export CHROME_BIN=\"$${browserLoopVar}\"`,\n\t\t' break',\n\t\t' fi',\n\t\t' done',\n\t\t'fi',\n\t\t`unset ${browserLoopVar}`,\n\t\t'export NPM_CONFIG_CACHE=\"$RESOLVEIO_QA_TMP/npm-cache\"',\n\t\t'export NPM_CONFIG_PREFER_OFFLINE=true',\n\t\t'export NPM_CONFIG_PRODUCTION=false',\n\t\t'export npm_config_production=false',\n\t\t'export RESOLVEIO_SUPPORT_MONGOMS_PACKAGE_ROOT=\"$RESOLVEIO_QA_TMP/mongodb-memory-server-core\"',\n\t\t'export MONGOMS_DOWNLOAD_DIR=\"$RESOLVEIO_QA_TMP/mongodb-binaries\"',\n\t\tmongodbBinaryCachePath ? `export RESOLVEIO_SUPPORT_SHARED_MONGOMS_DOWNLOAD_DIR=\"${mongodbBinaryCachePath}\"` : '',\n\t\t'export MONGOMS_VERSION=\"${MONGOMS_VERSION:-7.0.14}\"',\n\t\t''\n\t].filter((line) => line !== '').join('\\n');\n}\n\nexport function buildResolveIORunnerQaPreflightScript(): string {\n\treturn [\n\t\t'#!/usr/bin/env node',\n\t\t'const fs = require(\"fs\");',\n\t\t'const path = require(\"path\");',\n\t\t'const { spawnSync } = require(\"child_process\");',\n\t\t'const projectRoot = path.resolve(process.argv[2] || process.cwd());',\n\t\t'const artifactDir = path.join(projectRoot, \"qa-artifacts\");',\n\t\t'const resultPath = path.join(artifactDir, \"qa-preflight-result.json\");',\n\t\t'fs.mkdirSync(artifactDir, { recursive: true });',\n\t\t'const checks = [];',\n\t\t'function now() { return new Date().toISOString(); }',\n\t\t'function redact(value) { return String(value || \"\").replace(/mongodb(?:\\\\+srv)?:\\\\/\\\\/[^\\\\s\"\\\\\\']+/ig, \"[redacted-mongo-url]\").replace(/\\\\b(?:sk|ghp|AKIA)[A-Za-z0-9_\\\\-]{12,}\\\\b/g, \"[redacted-secret]\"); }',\n\t\t'function check(name, status, message, extra = {}) { checks.push({ name, status, message: redact(message), checkedAt: now(), ...extra }); }',\n\t\t'function fileExecutable(filePath) { try { fs.accessSync(filePath, fs.constants.X_OK); return true; } catch (error) { return false; } }',\n\t\t'function readJson(filePath) { try { return JSON.parse(fs.readFileSync(filePath, \"utf8\")); } catch (error) { return null; } }',\n\t\t'function packageScripts(root) { const pkg = readJson(path.join(root, \"package.json\")); return pkg && pkg.scripts && typeof pkg.scripts === \"object\" ? pkg.scripts : {}; }',\n\t\t'function requireFromCandidates(candidates, label) {',\n\t\t'\tfor (const candidate of candidates) {',\n\t\t'\t\ttry { return { module: require(candidate), candidate }; } catch (error) {}',\n\t\t'\t}',\n\t\t'\tthrow new Error(`Unable to require ${label} from ${candidates.join(\", \")}`);',\n\t\t'}',\n\t\t'function shellWhich(command) {',\n\t\t'\tconst result = spawnSync(\"bash\", [\"-lc\", `command -v ${command}`], { encoding: \"utf8\", timeout: 3000 });',\n\t\t'\treturn result.status === 0 ? String(result.stdout || \"\").trim().split(/\\\\r?\\\\n/)[0] : \"\";',\n\t\t'}',\n\t\t'try {',\n\t\t'\tconst nodeMajor = Number(String(process.versions.node || \"\").split(\".\")[0] || 0);',\n\t\t'\tcheck(\"node_version\", nodeMajor >= 22 && nodeMajor < 23 ? \"pass\" : \"fail\", `Node ${process.version}`, { version: process.version });',\n\t\t'} catch (error) { check(\"node_version\", \"fail\", error && error.message || error); }',\n\t\t'try {',\n\t\t'\tconst npmPath = shellWhich(\"npm\");',\n\t\t'\tcheck(\"npm_available\", npmPath ? \"pass\" : \"fail\", npmPath ? `npm found at ${npmPath}` : \"npm was not found on PATH\", { path: npmPath });',\n\t\t'} catch (error) { check(\"npm_available\", \"fail\", error && error.message || error); }',\n\t\t'try {',\n\t\t'\tconst scripts = packageScripts(projectRoot);',\n\t\t'\tconst serverScripts = fs.existsSync(path.join(projectRoot, \"server\")) ? packageScripts(path.join(projectRoot, \"server\")) : {};',\n\t\t'\tcheck(\"client_start_script\", scripts.client || scripts.start || scripts.server ? \"pass\" : \"blocked\", \"Project package scripts checked.\", { scripts: Object.keys(scripts).filter((key) => /^(client|start|server|dev|build|build-dev|build-prod)$/.test(key)) });',\n\t\t'\tcheck(\"server_start_script\", !fs.existsSync(path.join(projectRoot, \"server\")) || serverScripts.server || serverScripts.start || serverScripts[\"build-prod\"] ? \"pass\" : \"blocked\", \"Server package scripts checked.\", { scripts: Object.keys(serverScripts).filter((key) => /^(server|start|dev|build|build-dev|build-prod)$/.test(key)) });',\n\t\t'} catch (error) { check(\"package_scripts\", \"blocked\", error && error.message || error); }',\n\t\t'try {',\n\t\t'\tconst settingsCandidates = [',\n\t\t'\t\tpath.join(projectRoot, \"server\", \"settings.json\"),',\n\t\t'\t\tpath.join(projectRoot, \"server\", \"settings.local.json\"),',\n\t\t'\t\tpath.join(projectRoot, \"settings.json\"),',\n\t\t'\t\tpath.join(projectRoot, \"settings.local.json\"),',\n\t\t'\t\tpath.join(projectRoot, \"server\", \".env\"),',\n\t\t'\t\tpath.join(projectRoot, \"server\", \".env.codex\"),',\n\t\t'\t\tpath.join(projectRoot, \".env\"),',\n\t\t'\t\tpath.join(projectRoot, \".env.codex\")',\n\t\t'\t];',\n\t\t'\tconst found = settingsCandidates.find((candidate) => fs.existsSync(candidate));',\n\t\t'\tcheck(\"settings_available\", found || !fs.existsSync(path.join(projectRoot, \"server\")) ? \"pass\" : \"blocked\", found ? `Runtime settings/env file exists at ${path.relative(projectRoot, found)}` : \"No server directory or settings file required.\", { path: found ? path.relative(projectRoot, found) : \"\" });',\n\t\t'} catch (error) { check(\"settings_available\", \"blocked\", error && error.message || error); }',\n\t\t'let puppeteer = null;',\n\t\t'try {',\n\t\t'\tconst candidates = [',\n\t\t'\t\tpath.join(projectRoot, \"node_modules\", \"puppeteer\"),',\n\t\t'\t\tpath.join(projectRoot, \"server\", \"node_modules\", \"puppeteer\"),',\n\t\t'\t\tpath.join(projectRoot, \"node_modules\", \"puppeteer-core\"),',\n\t\t'\t\tpath.join(projectRoot, \"server\", \"node_modules\", \"puppeteer-core\"),',\n\t\t'\t\t\"puppeteer\",',\n\t\t'\t\t\"puppeteer-core\"',\n\t\t'\t];',\n\t\t'\tconst found = requireFromCandidates(candidates, \"puppeteer/puppeteer-core\");',\n\t\t'\tpuppeteer = found.module;',\n\t\t'\tcheck(\"puppeteer_require\", \"pass\", `Loaded ${found.candidate}`);',\n\t\t'} catch (error) { check(\"puppeteer_require\", \"blocked\", error && error.message || error); }',\n\t\t'let chromePath = String(process.env.PUPPETEER_EXECUTABLE_PATH || process.env.CHROME_BIN || \"\").trim();',\n\t\t'if (!chromePath) {',\n\t\t'\tconst candidates = [',\n\t\t'\t\t\"/var/lib/resolveio/puppeteer/chrome-headless-shell/linux-*/chrome-headless-shell-linux64/chrome-headless-shell\",',\n\t\t'\t\t\"/var/lib/resolveio/puppeteer/chrome/linux-*/chrome-linux64/chrome\",',\n\t\t'\t\t\"/usr/bin/google-chrome-stable\",',\n\t\t'\t\t\"/usr/bin/google-chrome\",',\n\t\t'\t\t\"/usr/bin/chromium\",',\n\t\t'\t\t\"/usr/bin/chromium-browser\"',\n\t\t'\t];',\n\t\t'\tfor (const pattern of candidates) {',\n\t\t'\t\tconst result = spawnSync(\"bash\", [\"-lc\", `for f in ${pattern}; do [ -x \"$f\" ] && echo \"$f\" && exit 0; done; exit 1`], { encoding: \"utf8\", timeout: 3000 });',\n\t\t'\t\tif (result.status === 0 && String(result.stdout || \"\").trim()) { chromePath = String(result.stdout || \"\").trim().split(/\\\\r?\\\\n/)[0]; break; }',\n\t\t'\t}',\n\t\t'}',\n\t\t'check(\"chrome_executable\", chromePath && fileExecutable(chromePath) ? \"pass\" : \"blocked\", chromePath ? `Chrome executable ${chromePath}` : \"No executable Chrome/Chromium path found.\", { path: chromePath });',\n\t\t'if (puppeteer && chromePath && fileExecutable(chromePath) && String(process.env.RESOLVEIO_QA_PREFLIGHT_SKIP_BROWSER_LAUNCH || \"\").toLowerCase() !== \"true\") {',\n\t\t'\t(async () => {',\n\t\t'\t\tlet browser = null;',\n\t\t'\t\ttry {',\n\t\t'\t\t\tbrowser = await puppeteer.launch({ executablePath: chromePath, headless: \"new\", args: [\"--no-sandbox\", \"--disable-setuid-sandbox\", \"--disable-dev-shm-usage\"] });',\n\t\t'\t\t\tcheck(\"chrome_launch\", \"pass\", \"Puppeteer launched the staged browser.\");',\n\t\t'\t\t} catch (error) {',\n\t\t'\t\t\tcheck(\"chrome_launch\", \"blocked\", error && error.message || error);',\n\t\t'\t\t} finally {',\n\t\t'\t\t\tif (browser) await browser.close().catch(() => undefined);',\n\t\t'\t\t\tfinish();',\n\t\t'\t\t}',\n\t\t'\t})().catch((error) => { check(\"chrome_launch\", \"blocked\", error && error.message || error); finish(); });',\n\t\t'}',\n\t\t'else {',\n\t\t'\tif (!puppeteer || !chromePath) check(\"chrome_launch\", \"skipped\", \"Browser launch skipped because Puppeteer or Chrome executable is unavailable.\");',\n\t\t'\tfinish();',\n\t\t'}',\n\t\t'function finish() {',\n\t\t'\tconst failed = checks.filter((entry) => [\"fail\", \"blocked\"].includes(entry.status));',\n\t\t'\tconst result = { status: failed.length ? \"blocked\" : \"pass\", outcome: failed.length ? \"infra_failed\" : \"infra_passed\", projectRoot, checks, updatedAt: now() };',\n\t\t'\tfs.writeFileSync(resultPath, JSON.stringify(result, null, 2));',\n\t\t'\tconsole.log(JSON.stringify(result, null, 2));',\n\t\t'\tprocess.exit(failed.length ? 2 : 0);',\n\t\t'}',\n\t\t''\n\t].join('\\n');\n}\n\nexport function buildResolveIORunnerLocalQaScript(): string {\n\treturn [\n\t\t'#!/usr/bin/env bash',\n\t\t'set -u',\n\t\t'TOOLS_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"',\n\t\t'source \"$TOOLS_DIR/env.sh\"',\n\t\t'if resolveio_support_codex_lane_is_build 2>/dev/null; then',\n\t\t' resolveio_support_codex_block_build_lane_qa',\n\t\t' exit 86',\n\t\t'fi',\n\t\t'PROJECT_ROOT=\"${1:-$(pwd)}\"',\n\t\t'PROJECT_ROOT=\"$(cd \"$PROJECT_ROOT\" && pwd)\"',\n\t\t'ARTIFACT_DIR=\"$PROJECT_ROOT/qa-artifacts\"',\n\t\t'mkdir -p \"$ARTIFACT_DIR\"',\n\t\t'CLIENT_URL=\"${RESOLVEIO_RUNNER_QA_CLIENT_URL:-${RESOLVEIO_SUPPORT_QA_CLIENT_URL:-http://localhost:${RESOLVEIO_RUNNER_QA_CLIENT_PORT:-${RESOLVEIO_SUPPORT_QA_CLIENT_PORT:-4200}}}}\"',\n\t\t'SERVER_URL=\"${RESOLVEIO_RUNNER_QA_SERVER_URL:-${RESOLVEIO_SUPPORT_QA_SERVER_URL:-http://localhost:8080}}\"',\n\t\t'CLIENT_PORT=\"${RESOLVEIO_RUNNER_QA_CLIENT_PORT:-${RESOLVEIO_SUPPORT_QA_CLIENT_PORT:-4200}}\"',\n\t\t'SERVER_PORT=\"${RESOLVEIO_RUNNER_QA_SERVER_PORT:-${RESOLVEIO_SUPPORT_QA_SERVER_PORT:-8080}}\"',\n\t\t'MONGO_PORT=\"${RESOLVEIO_RUNNER_QA_MONGO_PORT:-${RESOLVEIO_SUPPORT_QA_MONGO_PORT:-3001}}\"',\n\t\t'INSPECT_PORT=\"${RESOLVEIO_RUNNER_QA_INSPECT_PORT:-${RESOLVEIO_SUPPORT_QA_INSPECT_PORT:-9229}}\"',\n\t\t'STARTUP_TIMEOUT=\"${RESOLVEIO_RUNNER_QA_ANGULAR_STARTUP_TIMEOUT_SECONDS:-${RESOLVEIO_SUPPORT_QA_ANGULAR_STARTUP_TIMEOUT_SECONDS:-900}}\"',\n\t\t'ANGULAR_PREBUNDLE=\"${RESOLVEIO_RUNNER_QA_ANGULAR_PREBUNDLE:-${RESOLVEIO_SUPPORT_QA_ANGULAR_PREBUNDLE:-false}}\"',\n\t\t'REUSE_RUNNING=\"${RESOLVEIO_RUNNER_QA_REUSE_RUNNING:-${RESOLVEIO_SUPPORT_QA_REUSE_RUNNING:-true}}\"',\n\t\t'if [[ \"$(basename \"$TOOLS_DIR\")\" == *support* ]]; then',\n\t\t' KEEPALIVE=\"${RESOLVEIO_SUPPORT_QA_KEEPALIVE:-${RESOLVEIO_RUNNER_QA_KEEPALIVE:-false}}\"',\n\t\t'else',\n\t\t' KEEPALIVE=\"${RESOLVEIO_RUNNER_QA_KEEPALIVE:-${RESOLVEIO_SUPPORT_QA_KEEPALIVE:-false}}\"',\n\t\t'fi',\n\t\t'case \"${KEEPALIVE,,}\" in',\n\t\t' true|1|yes|on) exec >> \"$ARTIFACT_DIR/runner.log\" 2>&1 ;;',\n\t\t'esac',\n\t\t'SERVER_STABLE_SECONDS=\"${RESOLVEIO_RUNNER_QA_SERVER_STABLE_SECONDS:-${RESOLVEIO_SUPPORT_QA_SERVER_STABLE_SECONDS:-20}}\"',\n\t\t'LOCK_DIR=\"$ARTIFACT_DIR/.qa.lock\"',\n\t\t'SERVER_PID=\"\"',\n\t\t'CLIENT_PID=\"\"',\n\t\t'SERVER_REQUIRED=0',\n\t\t'RUNNER_REUSED_READY=0',\n\t\t'ANGULAR_PREBUNDLE_ARGS=()',\n\t\t'REPO_ROOT=\"$(git -C \"$PROJECT_ROOT\" rev-parse --show-toplevel 2>/dev/null || echo \"$PROJECT_ROOT\")\"',\n\t\tbuildRunnerProcessJanitorShellLibrary({ mode: 'support' }),\n\t\t'case \"${ANGULAR_PREBUNDLE,,}\" in',\n\t\t' false|0|no|off) ANGULAR_PREBUNDLE_ARGS=(--prebundle=false) ;;',\n\t\t'esac',\n\t\t'kill_tree() {',\n\t\t' local pid=\"$1\"',\n\t\t' [ -n \"$pid\" ] || return 0',\n\t\t' for child in $(pgrep -P \"$pid\" 2>/dev/null || true); do kill_tree \"$child\"; done',\n\t\t' kill \"$pid\" >/dev/null 2>&1 || true',\n\t\t' sleep 1',\n\t\t' kill -0 \"$pid\" >/dev/null 2>&1 && kill -9 \"$pid\" >/dev/null 2>&1 || true',\n\t\t'}',\n\t\t'kill_port_listeners() {',\n\t\t' local port=\"$1\"',\n\t\t' [ -n \"$port\" ] || return 0',\n\t\t' local pids=\"\"',\n\t\t' if command -v lsof >/dev/null 2>&1; then pids=\"$pids $(janitor_bounded 3 lsof -ti tcp:\"$port\")\"; fi',\n\t\t' if command -v fuser >/dev/null 2>&1; then pids=\"$pids $(janitor_bounded 3 fuser -n tcp \"$port\")\"; fi',\n\t\t' if command -v ss >/dev/null 2>&1; then pids=\"$pids $(janitor_bounded 3 ss -ltnp \"sport = :$port\" | sed -n \\'s/.*pid=\\\\([0-9][0-9]*\\\\).*/\\\\1/p\\' || true)\"; fi',\n\t\t' for pid in $pids; do',\n\t\t' [ \"$pid\" = \"$$\" ] && continue',\n\t\t' kill_tree \"$pid\"',\n\t\t' done',\n\t\t' sleep 1',\n\t\t'}',\n\t\t'kill_env_marked_processes() {',\n\t\t' [ -d /proc ] || return 0',\n\t\t' local job_id=\"${RESOLVEIO_RUNNER_QA_JOB_ID:-${RESOLVEIO_SUPPORT_QA_JOB_ID:-}}\"',\n\t\t' local owner_id=\"${RESOLVEIO_RUNNER_QA_OWNER_ID:-${RESOLVEIO_SUPPORT_QA_OWNER_ID:-}}\"',\n\t\t' local token=\"${RESOLVEIO_RUNNER_QA_RUNNER_TOKEN:-${RESOLVEIO_SUPPORT_QA_RUNNER_TOKEN:-}}\"',\n\t\t' [ -n \"$job_id$owner_id$token\" ] || return 0',\n\t\t' for env_file in /proc/[0-9]*/environ; do',\n\t\t' pid=\"${env_file#/proc/}\"',\n\t\t' pid=\"${pid%/environ}\"',\n\t\t' skip_cleanup_pid \"$pid\" && continue',\n\t\t' [ \"$pid\" = \"$$\" ] && continue',\n\t\t' [ -r \"$env_file\" ] || continue',\n\t\t' env_text=\"$(tr \"\\\\0\" \"\\\\n\" < \"$env_file\" 2>/dev/null || true)\"',\n\t\t' [ -n \"$env_text\" ] || continue',\n\t\t' matched=0',\n\t\t' [ -n \"$job_id\" ] && echo \"$env_text\" | grep -Eq \"^(RESOLVEIO_RUNNER_QA_JOB_ID|RESOLVEIO_SUPPORT_QA_JOB_ID)=$job_id$\" && matched=1',\n\t\t' [ \"$matched\" = \"0\" ] && [ -n \"$owner_id\" ] && echo \"$env_text\" | grep -Eq \"^(RESOLVEIO_RUNNER_QA_OWNER_ID|RESOLVEIO_SUPPORT_QA_OWNER_ID)=$owner_id$\" && matched=1',\n\t\t' [ \"$matched\" = \"0\" ] && [ -n \"$token\" ] && echo \"$env_text\" | grep -Eq \"^(RESOLVEIO_RUNNER_QA_RUNNER_TOKEN|RESOLVEIO_SUPPORT_QA_RUNNER_TOKEN)=$token$\" && matched=1',\n\t\t' [ \"$matched\" = \"1\" ] && kill_tree \"$pid\"',\n\t\t' done',\n\t\t'}',\n\t\t'kill_artifact_log_writers() {',\n\t\t' local artifact=\"$ARTIFACT_DIR\"',\n\t\t' [ -n \"$artifact\" ] || return 0',\n\t\t' for pid in $(ps -eo pid=,args= | awk -v artifact=\"$artifact\" \\'index($0, artifact) && $0 !~ /awk -v artifact=/ && $0 !~ /ps -eo pid=,args=/ && $0 ~ /(^|[ /])(tee|tail)( |$)/ {print $1}\\' 2>/dev/null || true); do',\n\t\t' skip_cleanup_pid \"$pid\" && continue',\n\t\t' kill_tree \"$pid\"',\n\t\t' done',\n\t\t'}',\n\t\t'kill_local_mongo_processes() {',\n\t\t' local mongo_port=\"$MONGO_PORT\"',\n\t\t' local root=\"$PROJECT_ROOT\"',\n\t\t' [ -n \"$mongo_port$root\" ] || return 0',\n\t\t' for pid in $(ps -eo pid=,args= | awk -v port=\"$mongo_port\" -v root=\"$root\" \\'$0 !~ /awk -v port=/ && $0 !~ /ps -eo pid=,args=/ && $0 ~ /mongod/ && (($0 ~ (\"--port \" port)) || index($0, root \"/server/mongo/data/db\") || index($0, root \"/mongo/data/db\")) && ($0 ~ /\\\\/tmp\\\\/resolveio-support-qa\\\\/.*mongod/ || index($0, root) || $0 ~ /--dbpath .*mongo\\\\/data\\\\/db/) {print $1}\\' 2>/dev/null || true); do',\n\t\t' skip_cleanup_pid \"$pid\" && continue',\n\t\t' [ \"$pid\" = \"$$\" ] && continue',\n\t\t' kill_tree \"$pid\"',\n\t\t' sleep 1',\n\t\t' kill -0 \"$pid\" >/dev/null 2>&1 && kill -9 \"$pid\" >/dev/null 2>&1 || true',\n\t\t' done',\n\t\t'}',\n\t\t'RUNNER_ANCESTOR_PIDS=\" $$ ${PPID:-} \"',\n\t\t'ancestor_pid=\"${PPID:-}\"',\n\t\t'while [ -n \"$ancestor_pid\" ] && [ \"$ancestor_pid\" != \"0\" ] && [ \"$ancestor_pid\" != \"1\" ]; do',\n\t\t' ancestor_pid=\"$(ps -o ppid= -p \"$ancestor_pid\" 2>/dev/null | tr -d \" \" || true)\"',\n\t\t' [ -n \"$ancestor_pid\" ] && RUNNER_ANCESTOR_PIDS=\"$RUNNER_ANCESTOR_PIDS $ancestor_pid \"',\n\t\t'done',\n\t\t'skip_cleanup_pid() {',\n\t\t' case \"$RUNNER_ANCESTOR_PIDS\" in *\" $1 \"*) return 0 ;; esac',\n\t\t' return 1',\n\t\t'}',\n\t\t'cleanup_project_processes() {',\n\t\t' for pid_file in \"$ARTIFACT_DIR/server.pid\" \"$ARTIFACT_DIR/client.pid\"; do',\n\t\t' [ -f \"$pid_file\" ] || continue',\n\t\t' pid=\"$(cat \"$pid_file\" 2>/dev/null || true)\"',\n\t\t' kill_tree \"$pid\"',\n\t\t' rm -f \"$pid_file\"',\n\t\t' done',\n\t\t' for pass in 1 2 3; do',\n\t\t' for port in \"$CLIENT_PORT\" \"$SERVER_PORT\" \"$MONGO_PORT\" \"$INSPECT_PORT\"; do kill_port_listeners \"$port\"; done',\n\t\t' kill_env_marked_processes',\n\t\t' kill_artifact_log_writers',\n\t\t' kill_local_mongo_processes',\n\t\t' for pid in $(ps -eo pid=,args= | awk -v root=\"$PROJECT_ROOT\" \\'index($0, root) && $0 !~ /awk -v root=/ && $0 !~ /ps -eo pid=,args=/ && $0 !~ /run-local-qa\\\\.sh|stop-local-qa\\\\.sh|bugfix-comparison-qa\\\\.sh/ && $0 ~ /(ng serve|node .*node_modules\\\\/\\\\.bin\\\\/ng[[:space:]]+serve|esbuild --service|npm run client|start_client\\\\.sh|npm run server|start_server\\\\.sh|nodemon|node .*tmp\\\\/index\\\\.js|mongod|mongodb-binaries\\\\/mongod)/ {print $1}\\' 2>/dev/null || true); do',\n\t\t' skip_cleanup_pid \"$pid\" && continue',\n\t\t' kill_tree \"$pid\"',\n\t\t' done',\n\t\t' # Do not kill arbitrary processes by project cwd; completion builds run',\n\t\t' # from the same cwd. Cleanup is limited to known QA process signatures,',\n\t\t' # recorded PIDs, scoped ports, and QA runner env markers.',\n\t\t' sleep 1',\n\t\t' done',\n\t\t' local wait_until=$((SECONDS + 60))',\n\t\t' while [ \"$SECONDS\" -lt \"$wait_until\" ]; do',\n\t\t' local found=0',\n\t\t' for port in \"$CLIENT_PORT\" \"$SERVER_PORT\" \"$MONGO_PORT\" \"$INSPECT_PORT\"; do',\n\t\t' port_pids=\"\"',\n\t\t' if command -v lsof >/dev/null 2>&1; then port_pids=\"$port_pids $(janitor_bounded 3 lsof -ti tcp:\"$port\")\"; fi',\n\t\t' for pid in $port_pids; do skip_cleanup_pid \"$pid\" && continue; found=1; kill_tree \"$pid\"; done',\n\t\t' done',\n\t\t' if [ -d /proc ]; then',\n\t\t' job_id=\"${RESOLVEIO_RUNNER_QA_JOB_ID:-${RESOLVEIO_SUPPORT_QA_JOB_ID:-}}\"',\n\t\t' owner_id=\"${RESOLVEIO_RUNNER_QA_OWNER_ID:-${RESOLVEIO_SUPPORT_QA_OWNER_ID:-}}\"',\n\t\t' token=\"${RESOLVEIO_RUNNER_QA_RUNNER_TOKEN:-${RESOLVEIO_SUPPORT_QA_RUNNER_TOKEN:-}}\"',\n\t\t' for env_file in /proc/[0-9]*/environ; do',\n\t\t' pid=\"${env_file#/proc/}\"',\n\t\t' pid=\"${pid%/environ}\"',\n\t\t' skip_cleanup_pid \"$pid\" && continue',\n\t\t' [ -r \"$env_file\" ] || continue',\n\t\t' env_text=\"$(tr \"\\\\0\" \"\\\\n\" < \"$env_file\" 2>/dev/null || true)\"',\n\t\t' matched=0',\n\t\t' [ -n \"$job_id\" ] && echo \"$env_text\" | grep -Eq \"^(RESOLVEIO_RUNNER_QA_JOB_ID|RESOLVEIO_SUPPORT_QA_JOB_ID)=$job_id$\" && matched=1',\n\t\t' [ \"$matched\" = \"0\" ] && [ -n \"$owner_id\" ] && echo \"$env_text\" | grep -Eq \"^(RESOLVEIO_RUNNER_QA_OWNER_ID|RESOLVEIO_SUPPORT_QA_OWNER_ID)=$owner_id$\" && matched=1',\n\t\t' [ \"$matched\" = \"0\" ] && [ -n \"$token\" ] && echo \"$env_text\" | grep -Eq \"^(RESOLVEIO_RUNNER_QA_RUNNER_TOKEN|RESOLVEIO_SUPPORT_QA_RUNNER_TOKEN)=$token$\" && matched=1',\n\t\t' [ \"$matched\" = \"1\" ] && found=1 && kill_tree \"$pid\"',\n\t\t' done',\n\t\t' fi',\n\t\t' kill_artifact_log_writers',\n\t\t' kill_local_mongo_processes',\n\t\t' for pid in $(ps -eo pid=,args= | awk -v root=\"$PROJECT_ROOT\" \\'index($0, root) && $0 !~ /awk -v root=/ && $0 !~ /ps -eo pid=,args=/ && $0 !~ /run-local-qa\\\\.sh|stop-local-qa\\\\.sh|bugfix-comparison-qa\\\\.sh/ && $0 ~ /(ng serve|node .*node_modules\\\\/\\\\.bin\\\\/ng[[:space:]]+serve|esbuild --service|npm run client|start_client\\\\.sh|npm run server|start_server\\\\.sh|nodemon|node .*tmp\\\\/index\\\\.js|mongod|mongodb-binaries\\\\/mongod)/ {print $1}\\' 2>/dev/null || true); do',\n\t\t' skip_cleanup_pid \"$pid\" && continue',\n\t\t' found=1',\n\t\t' done',\n\t\t' [ \"$found\" = \"0\" ] && break',\n\t\t' sleep 2',\n\t\t' done',\n\t\t'}',\n\t\t'cleanup() {',\n\t\t' [ \"${RUNNER_REUSED_READY:-0}\" = \"1\" ] && return 0',\n\t\t' janitor_stop_heartbeat',\n\t\t' rm -f \"$ARTIFACT_DIR/heartbeat.pid\"',\n\t\t' janitor_update_manifest_status cleanup_started',\n\t\t' kill_tree \"$SERVER_PID\"',\n\t\t' kill_tree \"$CLIENT_PID\"',\n\t\t' cleanup_project_processes',\n\t\t' janitor_update_manifest_status cleanup_complete',\n\t\t' janitor_write_cleanup_status complete 0',\n\t\t' rm -rf \"$LOCK_DIR\" >/dev/null 2>&1 || true',\n\t\t'}',\n\t\t'trap cleanup EXIT',\n\t\t'detach_keepalive() {',\n\t\t' if ! probe_url \"$CLIENT_URL\"; then',\n\t\t' echo \"ResolveIO AI runner QA keepalive refused: client URL is no longer reachable at $CLIENT_URL.\" | tee -a \"$ARTIFACT_DIR/runner.log\"',\n\t\t' return 1',\n\t\t' fi',\n\t\t' if [ \"${SERVER_REQUIRED:-0}\" = \"1\" ] && ! probe_url \"$SERVER_URL\"; then',\n\t\t' echo \"ResolveIO AI runner QA keepalive refused: server URL is no longer reachable at $SERVER_URL.\" | tee -a \"$ARTIFACT_DIR/runner.log\"',\n\t\t' return 4',\n\t\t' fi',\n\t\t' janitor_update_manifest_status ready_keepalive',\n\t\t' janitor_write_cleanup_status ready_keepalive 0',\n\t\t' rm -rf \"$LOCK_DIR\" >/dev/null 2>&1 || true',\n\t\t' trap - EXIT',\n\t\t' disown >/dev/null 2>&1 || true',\n\t\t' echo \"ResolveIO AI runner QA keepalive detached at $CLIENT_URL; stop with $TOOLS_DIR/stop-local-qa.sh $PROJECT_ROOT.\"',\n\t\t' exit 0',\n\t\t'}',\n\t\t'probe_url() { node - \"$1\" <<\\'RESOLVEIO_PROBE\\'',\n\t\t'const http = require(\"http\");',\n\t\t'const https = require(\"https\");',\n\t\t'const url = process.argv[2];',\n\t\t'const mod = /^https:/i.test(url) ? https : http;',\n\t\t'const req = mod.get(url, { timeout: 2500 }, (res) => { res.resume(); process.exit(res.statusCode && res.statusCode < 500 ? 0 : 1); });',\n\t\t'req.on(\"timeout\", () => req.destroy(new Error(\"timeout\")));',\n\t\t'req.on(\"error\", () => process.exit(1));',\n\t\t'RESOLVEIO_PROBE',\n\t\t'}',\n\t\t'truthy() { case \"${1,,}\" in true|1|yes|on) return 0 ;; *) return 1 ;; esac; }',\n\t\t'reuse_running_app_if_ready() {',\n\t\t' truthy \"$REUSE_RUNNING\" || return 1',\n\t\t' [ -d \"$PROJECT_ROOT/server\" ] && SERVER_REQUIRED=1 || SERVER_REQUIRED=0',\n\t\t' probe_url \"$CLIENT_URL\" || return 1',\n\t\t' if [ \"$SERVER_REQUIRED\" = \"1\" ] && ! probe_url \"$SERVER_URL\"; then return 1; fi',\n\t\t' echo \"ResolveIO AI runner QA reusing already-ready local app at $CLIENT_URL\"',\n\t\t' return 0',\n\t\t'}',\n\t\t'log_has_fatal() {',\n\t\t' local file=\"$1\"',\n\t\t' [ -f \"$file\" ] || return 1',\n\t\t' grep -Eiq \"Unhandled Rejection|Cannot read properties of undefined|TypeError|ReferenceError|EADDRINUSE|app crashed|Failed to compile|Compilation failed|TypeScript:.*(semantic errors|Compilation failed)|error TS[0-9]{4}|NG[0-9]{4}|TS[0-9]{4}|Error: Cannot find module\" \"$file\"',\n\t\t'}',\n\t\t'prepare_angular_cache_dirs() {',\n\t\t' [ -d \"$PROJECT_ROOT\" ] || return 0',\n\t\t' mkdir -p \"$PROJECT_ROOT/.angular/cache\" 2>/dev/null || true',\n\t\t' local version=\"\"',\n\t\t' for pkg in \"$PROJECT_ROOT/node_modules/@angular/build/package.json\" \"$PROJECT_ROOT/node_modules/@angular/cli/package.json\" \"$PROJECT_ROOT/node_modules/@angular-devkit/build-angular/package.json\"; do',\n\t\t' if [ -f \"$pkg\" ]; then',\n\t\t' version=\"$(node -e \"try{console.log(require(process.argv[1]).version||\\\\\\\"\\\\\\\")}catch(e){}\" \"$pkg\" 2>/dev/null | head -1)\"',\n\t\t' [ -n \"$version\" ] && break',\n\t\t' fi',\n\t\t' done',\n\t\t' [ -n \"$version\" ] || return 0',\n\t\t' node - \"$PROJECT_ROOT/angular.json\" \"$(basename \"$PROJECT_ROOT\")\" <<\\'RESOLVEIO_ANGULAR_CACHE_PROJECTS\\' | while IFS= read -r project; do',\n\t\t'const fs = require(\"fs\");',\n\t\t'const path = process.argv[2];',\n\t\t'const fallback = process.argv[3];',\n\t\t'const names = new Set([fallback].filter(Boolean));',\n\t\t'try {',\n\t\t' const parsed = JSON.parse(fs.readFileSync(path, \"utf8\"));',\n\t\t' if (parsed.defaultProject) names.add(String(parsed.defaultProject));',\n\t\t' if (parsed.projects && typeof parsed.projects === \"object\") Object.keys(parsed.projects).forEach((name) => names.add(String(name)));',\n\t\t'} catch (error) {}',\n\t\t'for (const name of names) console.log(name.replace(/[^A-Za-z0-9._-]/g, \"_\"));',\n\t\t'RESOLVEIO_ANGULAR_CACHE_PROJECTS',\n\t\t' [ -n \"$project\" ] || continue',\n\t\t' mkdir -p \"$PROJECT_ROOT/.angular/cache/$version/$project/vite\" 2>/dev/null || true',\n\t\t' done',\n\t\t'}',\n\t\t'server_has_started() {',\n\t\t' local file=\"$ARTIFACT_DIR/server.log\"',\n\t\t' [ -f \"$file\" ] || return 1',\n\t\t' grep -Eiq \"nodemon.*starting|node .*tmp/index\\\\.js|Running as Worker|Standalone Node Reaper|Running HTTP/WS server on port|listening on|server listening|Server listening|app listening|App listening|Finished .default.\" \"$file\"',\n\t\t'}',\n\t\t'wait_for_server_ready() {',\n\t\t' [ \"$SERVER_REQUIRED\" = \"1\" ] || return 0',\n\t\t' local end=$((SECONDS + STARTUP_TIMEOUT))',\n\t\t' while [ \"$SECONDS\" -lt \"$end\" ]; do',\n\t\t' if log_has_fatal \"$ARTIFACT_DIR/server.log\"; then return 4; fi',\n\t\t' if server_has_started; then',\n\t\t' local stable_until=$((SECONDS + SERVER_STABLE_SECONDS))',\n\t\t' while [ \"$SECONDS\" -lt \"$stable_until\" ]; do if log_has_fatal \"$ARTIFACT_DIR/server.log\"; then return 4; fi; sleep 2; done',\n\t\t' return 0',\n\t\t' fi',\n\t\t' if probe_url \"$SERVER_URL\"; then',\n\t\t' local stable_until=$((SECONDS + SERVER_STABLE_SECONDS))',\n\t\t' while [ \"$SECONDS\" -lt \"$stable_until\" ]; do if log_has_fatal \"$ARTIFACT_DIR/server.log\"; then return 4; fi; sleep 2; done',\n\t\t' return 0',\n\t\t' fi',\n\t\t' sleep 5',\n\t\t' done',\n\t\t' return 4',\n\t\t'}',\n\t\t'wait_for_client() {',\n\t\t' local end=$((SECONDS + STARTUP_TIMEOUT))',\n\t\t' while [ \"$SECONDS\" -lt \"$end\" ]; do',\n\t\t' if [ -n \"$CLIENT_PID\" ] && ! kill -0 \"$CLIENT_PID\" >/dev/null 2>&1; then return 2; fi',\n\t\t' if log_has_fatal \"$ARTIFACT_DIR/client.log\"; then return 3; fi',\n\t\t' if log_has_fatal \"$ARTIFACT_DIR/server.log\"; then return 4; fi',\n\t\t' if probe_url \"$CLIENT_URL\"; then wait_for_server_ready || return $?; return 0; fi',\n\t\t' sleep 5',\n\t\t' done',\n\t\t' return 1',\n\t\t'}',\n\t\t'mongo_tcp_ready() {',\n\t\t' node - \"$MONGO_PORT\" <<\\'RESOLVEIO_QA_MONGO_TCP\\'',\n\t\t'const net = require(\"net\");',\n\t\t'const port = Number(process.argv[2] || 3001);',\n\t\t'const socket = net.createConnection({ host: \"127.0.0.1\", port, timeout: 1200 });',\n\t\t'socket.once(\"connect\", () => { socket.destroy(); process.exit(0); });',\n\t\t'socket.once(\"timeout\", () => { socket.destroy(); process.exit(1); });',\n\t\t'socket.once(\"error\", () => process.exit(1));',\n\t\t'RESOLVEIO_QA_MONGO_TCP',\n\t\t'}',\n\t\t'mongo_primary_ready() {',\n\t\t' mongo_tcp_ready >/dev/null 2>&1 || return 1',\n\t\t' node - \"$PROJECT_ROOT\" \"$REPO_ROOT\" \"$MONGO_PORT\" <<\\'RESOLVEIO_QA_MONGO_PRIMARY\\'',\n\t\t'const path = require(\"path\");',\n\t\t'const [projectRoot, repoRoot, portRaw] = process.argv.slice(2);',\n\t\t'function requireMongo() {',\n\t\t' const candidates = [',\n\t\t' path.join(projectRoot || \"\", \"server\", \"node_modules\", \"mongodb\"),',\n\t\t' path.join(projectRoot || \"\", \"node_modules\", \"mongodb\"),',\n\t\t' path.join(repoRoot || \"\", \"node_modules\", \"mongodb\"),',\n\t\t' \"mongodb\"',\n\t\t' ];',\n\t\t' for (const candidate of candidates) {',\n\t\t' try { return require(candidate); } catch (error) {}',\n\t\t' }',\n\t\t' throw new Error(\"Unable to require mongodb for local QA primary readiness.\");',\n\t\t'}',\n\t\t'(async () => {',\n\t\t' const port = Number(portRaw || 3001);',\n\t\t' const uri = `mongodb://127.0.0.1:${port}/admin?directConnection=true`;',\n\t\t' const { MongoClient } = requireMongo();',\n\t\t' const client = new MongoClient(uri, { serverSelectionTimeoutMS: 2500 });',\n\t\t' await client.connect();',\n\t\t' try {',\n\t\t' const admin = client.db(\"admin\");',\n\t\t' try {',\n\t\t' await admin.command({ replSetInitiate: { _id: \"rs0\", members: [{ _id: 0, host: `127.0.0.1:${port}` }] } });',\n\t\t' } catch (error) {',\n\t\t' const message = String(error && error.message || error);',\n\t\t' if (!/already initialized|already.*initiated|InvalidReplicaSetConfig|already exists/i.test(message)) throw error;',\n\t\t' }',\n\t\t' let hello = null;',\n\t\t' try { hello = await admin.command({ hello: 1 }); } catch (error) {',\n\t\t' try { hello = await admin.command({ isMaster: 1 }); } catch (inner) { hello = null; }',\n\t\t' }',\n\t\t' const writable = !hello || hello.isWritablePrimary === true || hello.ismaster === true || !hello.setName;',\n\t\t' process.exit(writable ? 0 : 1);',\n\t\t' } finally {',\n\t\t' await client.close().catch(() => undefined);',\n\t\t' }',\n\t\t'})().catch((error) => { console.error(error && error.stack || error); process.exit(1); });',\n\t\t'RESOLVEIO_QA_MONGO_PRIMARY',\n\t\t'}',\n\t\t'start_local_mongo_for_prestart_seed() {',\n\t\t' if mongo_primary_ready >/dev/null 2>&1; then return 0; fi',\n\t\t' if command -v mongod >/dev/null 2>&1; then',\n\t\t' mkdir -p \"$PROJECT_ROOT/server/mongo/data/db\" \"$PROJECT_ROOT/server/mongo/log\"',\n\t\t' mongod --fork --dbpath \"$PROJECT_ROOT/server/mongo/data/db\" --logpath \"$PROJECT_ROOT/server/mongo/log/mongo.log\" --port \"$MONGO_PORT\" --replSet rs0 --bind_ip 127.0.0.1 >/dev/null 2>&1 || true',\n\t\t' fi',\n\t\t' local end=$((SECONDS + 45))',\n\t\t' while [ \"$SECONDS\" -lt \"$end\" ]; do',\n\t\t' if mongo_tcp_ready >/dev/null 2>&1; then break; fi',\n\t\t' sleep 2',\n\t\t' done',\n\t\t' if ! mongo_tcp_ready >/dev/null 2>&1; then return 1; fi',\n\t\t' if command -v mongosh >/dev/null 2>&1; then',\n\t\t' timeout 8s mongosh \"mongodb://127.0.0.1:$MONGO_PORT/admin?directConnection=true\" --quiet --eval \"try { rs.initiate({_id: \\'rs0\\', members: [{ _id: 0, host: \\'127.0.0.1:$MONGO_PORT\\' }]}) } catch (e) {}\" >/dev/null 2>&1 || true',\n\t\t' fi',\n\t\t' local primary_end=$((SECONDS + 75))',\n\t\t' while [ \"$SECONDS\" -lt \"$primary_end\" ]; do',\n\t\t' if mongo_primary_ready >/dev/null 2>&1; then return 0; fi',\n\t\t' if command -v mongosh >/dev/null 2>&1; then',\n\t\t' timeout 6s mongosh \"mongodb://127.0.0.1:$MONGO_PORT/admin?directConnection=true\" --quiet --eval \"try { rs.initiate({_id: \\'rs0\\', members: [{ _id: 0, host: \\'127.0.0.1:$MONGO_PORT\\' }]}) } catch (e) {}\" >/dev/null 2>&1 || true',\n\t\t' fi',\n\t\t' sleep 2',\n\t\t' done',\n\t\t' mongo_primary_ready >/dev/null 2>&1',\n\t\t'}',\n\t\t'materialize_live_mongo_runtime() {',\n\t\t' local runtime_file=\"$ARTIFACT_DIR/.mongo-runtime.json\"',\n\t\t' node - \"$runtime_file\" \"$PROJECT_ROOT\" \"$REPO_ROOT\" <<\\'RESOLVEIO_QA_MONGO_RUNTIME\\'',\n\t\t'const fs = require(\"fs\");',\n\t\t'const path = require(\"path\");',\n\t\t'const [runtimeFile, projectRootArg, repoRootArg] = process.argv.slice(2);',\n\t\t'function parseEnv(filePath) {',\n\t\t' const out = {};',\n\t\t' try {',\n\t\t' for (const raw of fs.readFileSync(filePath, \"utf8\").split(/\\\\n/)) {',\n\t\t' const line = raw.trim();',\n\t\t' if (!line || line.startsWith(\"#\")) continue;',\n\t\t' if (line.includes(\"=\")) {',\n\t\t' const index = line.indexOf(\"=\");',\n\t\t' out[line.slice(0, index).trim().replace(/^[\\\\\\'\"]|[\\\\\\'\"]$/g, \"\")] = line.slice(index + 1).trim().replace(/^[\\\\\\'\"]|[\\\\\\'\"],?$/g, \"\");',\n\t\t' continue;',\n\t\t' }',\n\t\t' const jsonish = line.match(/^[\\\\\\'\"]?([A-Z0-9_]+)[\\\\\\'\"]?\\\\s*:\\\\s*[\\\\\\'\"]?(.+?)[\\\\\\'\"]?,?$/i);',\n\t\t' if (jsonish) out[jsonish[1]] = jsonish[2].trim();',\n\t\t' }',\n\t\t' } catch (error) {}',\n\t\t' return out;',\n\t\t'}',\n\t\t'function readJson(filePath) { try { return JSON.parse(fs.readFileSync(filePath, \"utf8\")); } catch (error) { return {}; } }',\n\t\t'function pick(obj, keys) { for (const key of keys) { if (obj && typeof obj[key] === \"string\" && obj[key].trim()) return obj[key].trim(); } return \"\"; }',\n\t\t'function isLocalMongo(uri) { return /mongodb(?:\\\\+srv)?:\\\\/\\\\/(?:[^@/]+@)?(?:127\\\\.0\\\\.0\\\\.1|localhost)(?::\\\\d+)?\\\\//i.test(String(uri || \"\")); }',\n\t\t'function unique(values) { return Array.from(new Set(values.filter(Boolean).map((value) => path.resolve(String(value))))); }',\n\t\t'const appName = projectRootArg ? path.basename(projectRootArg) : \"\";',\n\t\t'const runtimeFileCandidates = unique([',\n\t\t' process.env.RESOLVEIO_QA_MONGO_RUNTIME_PATH,',\n\t\t' process.env.RESOLVEIO_SUPPORT_QA_MONGO_RUNTIME_PATH,',\n\t\t' process.env.RESOLVEIO_RUNNER_QA_MONGO_RUNTIME_PATH,',\n\t\t' repoRootArg && path.join(repoRootArg, \"mongo-context\", \".mongo-runtime.json\"),',\n\t\t' projectRootArg && path.join(projectRootArg, \"mongo-context\", \".mongo-runtime.json\"),',\n\t\t' repoRootArg && path.join(repoRootArg, \".resolveio-support-context\", \"mongo-context\", \".mongo-runtime.json\"),',\n\t\t' projectRootArg && path.join(projectRootArg, \".resolveio-support-context\", \"mongo-context\", \".mongo-runtime.json\"),',\n\t\t' repoRootArg && path.join(repoRootArg, \".resolveio-context\", \"mongo-context\", \".mongo-runtime.json\"),',\n\t\t' projectRootArg && path.join(projectRootArg, \".resolveio-context\", \"mongo-context\", \".mongo-runtime.json\")',\n\t\t']);',\n\t\t'for (const candidate of runtimeFileCandidates) {',\n\t\t' const parsed = readJson(candidate);',\n\t\t' const uri = pick(parsed, [\"mongo_uri\", \"MONGO_URL\"]);',\n\t\t' const database = pick(parsed, [\"mongo_db\", \"DATABASE\", \"database\"]);',\n\t\t' if (uri && !isLocalMongo(uri)) {',\n\t\t' fs.mkdirSync(path.dirname(runtimeFile), { recursive: true });',\n\t\t' fs.writeFileSync(runtimeFile, JSON.stringify({ mongo_uri: uri, mongo_db: database || \"\" }, null, 2));',\n\t\t' process.exit(0);',\n\t\t' }',\n\t\t'}',\n\t\t'const runtimeRoots = unique([',\n\t\t' process.env.RESOLVEIO_QA_RUNTIME_ROOT,',\n\t\t' process.env.RESOLVEIO_SUPPORT_QA_RUNTIME_ROOT,',\n\t\t' projectRootArg && path.join(projectRootArg, \"server\"),',\n\t\t' projectRootArg,',\n\t\t' repoRootArg,',\n\t\t' appName && path.join(\"/var/app/current\", appName, \"server\"),',\n\t\t' appName && path.join(\"/var/app/current\", appName),',\n\t\t' appName === \"resolveio\" && \"/var/app/current\"',\n\t\t']);',\n\t\t'for (const root of runtimeRoots) {',\n\t\t' const env = Object.assign({}, parseEnv(path.join(root, \".env\")), parseEnv(path.join(root, \".env.production\")), parseEnv(path.join(root, \".env.runtime\")), parseEnv(path.join(root, \".env.codex\")));',\n\t\t' const settings = Object.assign({}, readJson(path.join(root, \"settings.json\")), readJson(path.join(root, \"settings.local.json\")));',\n\t\t' const uri = pick(env, [\"MONGO_URL\"]) || pick(settings, [\"MONGO_URL\", \"mongo_url\"]);',\n\t\t' const database = pick(env, [\"DATABASE\"]) || pick(settings, [\"DATABASE\", \"database\"]);',\n\t\t' if (uri && !isLocalMongo(uri)) {',\n\t\t' fs.mkdirSync(path.dirname(runtimeFile), { recursive: true });',\n\t\t' fs.writeFileSync(runtimeFile, JSON.stringify({ mongo_uri: uri, mongo_db: database || \"\" }, null, 2));',\n\t\t' process.exit(0);',\n\t\t' }',\n\t\t'}',\n\t\t'const fallbackUri = pick(process.env, [\"RESOLVEIO_QA_LIVE_MONGO_URL\", \"RESOLVEIO_SUPPORT_QA_LIVE_MONGO_URL\", \"RESOLVEIO_RUNNER_QA_LIVE_MONGO_URL\"]);',\n\t\t'if (fallbackUri && !isLocalMongo(fallbackUri)) {',\n\t\t' const fallbackDatabase = pick(process.env, [\"RESOLVEIO_QA_LIVE_MONGO_DB\", \"RESOLVEIO_SUPPORT_QA_LIVE_MONGO_DB\", \"RESOLVEIO_RUNNER_QA_LIVE_MONGO_DB\"]);',\n\t\t' fs.mkdirSync(path.dirname(runtimeFile), { recursive: true });',\n\t\t' fs.writeFileSync(runtimeFile, JSON.stringify({ mongo_uri: fallbackUri, mongo_db: fallbackDatabase || \"\" }, null, 2));',\n\t\t' process.exit(0);',\n\t\t'}',\n\t\t'process.exit(0);',\n\t\t'RESOLVEIO_QA_MONGO_RUNTIME',\n\t\t' if [ -s \"$runtime_file\" ]; then export RESOLVEIO_QA_MONGO_RUNTIME_PATH=\"$runtime_file\"; fi',\n\t\t'}',\n\t\t'prestart_seed_live_data() {',\n\t\t' local required=\"${RESOLVEIO_RUNNER_QA_LIVE_DATA_REQUIRED:-${RESOLVEIO_SUPPORT_QA_LIVE_DATA_REQUIRED:-false}}\"',\n\t\t' truthy \"$required\" || return 0',\n\t\t' [ -f \"$TOOLS_DIR/qa-live-data-seed.js\" ] || return 0',\n\t\t' echo \"ResolveIO AI runner QA pre-start live data seed/cleanup starting before app server startup.\" | tee -a \"$ARTIFACT_DIR/runner.log\"',\n\t\t' if ! start_local_mongo_for_prestart_seed; then',\n\t\t' echo \"ResolveIO AI runner QA pre-start local Mongo did not become ready for live-data seed.\" | tee -a \"$ARTIFACT_DIR/runner.log\"',\n\t\t' return 7',\n\t\t' fi',\n\t\t' materialize_live_mongo_runtime',\n\t\t' node \"$TOOLS_DIR/qa-live-data-seed.js\" \"$PROJECT_ROOT\" >> \"$ARTIFACT_DIR/runner.log\" 2>&1',\n\t\t' local seed_rc=\"$?\"',\n\t\t' if [ \"$seed_rc\" != \"0\" ]; then',\n\t\t' echo \"ResolveIO AI runner QA pre-start live data seed failed before app server startup (exit $seed_rc).\" | tee -a \"$ARTIFACT_DIR/runner.log\"',\n\t\t' return \"$seed_rc\"',\n\t\t' fi',\n\t\t' export RESOLVEIO_QA_PRESTART_MONGO_READY=1',\n\t\t' return 0',\n\t\t'}',\n\t\t'prepare_tmp_server_settings() {',\n\t\t' mkdir -p \"$PROJECT_ROOT/server/tmp\"',\n\t\t' for f in settings.json settings.local.json .env .env.runtime .env.production .env.dev; do',\n\t\t' if [ -f \"$PROJECT_ROOT/server/$f\" ]; then cp \"$PROJECT_ROOT/server/$f\" \"$PROJECT_ROOT/server/tmp/$f\"; elif [ -f \"$PROJECT_ROOT/$f\" ]; then cp \"$PROJECT_ROOT/$f\" \"$PROJECT_ROOT/server/tmp/$f\"; fi',\n\t\t' done',\n\t\t' if [ ! -f \"$PROJECT_ROOT/server/tmp/settings.json\" ] && [ -f \"$PROJECT_ROOT/server/tmp/settings.local.json\" ]; then cp \"$PROJECT_ROOT/server/tmp/settings.local.json\" \"$PROJECT_ROOT/server/tmp/settings.json\"; fi',\n\t\t' [ -f \"$PROJECT_ROOT/server/tmp/settings.json\" ]',\n\t\t'}',\n\t\t'preseeded_tmp_server_ready() {',\n\t\t' [ -f \"$PROJECT_ROOT/server/tmp/index.js\" ] || return 1',\n\t\t' prepare_tmp_server_settings >/dev/null 2>&1 || return 1',\n\t\t' return 0',\n\t\t'}',\n\t\t'run_preseeded_tmp_server() {',\n\t\t' cd \"$PROJECT_ROOT/server\" || exit 4',\n\t\t' source \"$TOOLS_DIR/env.sh\"',\n\t\t' if [ -f \"$HOME/.nvm/nvm.sh\" ]; then source \"$HOME/.nvm/nvm.sh\"; nvm use 22 >/dev/null 2>&1 || true; fi',\n\t\t' if preseeded_tmp_server_ready; then',\n\t\t' echo \"ResolveIO AI runner QA using existing compiled server/tmp/index.js for pre-seeded local Mongo.\"',\n\t\t' echo \"ResolveIO AI runner QA starting node tmp/index.js\"',\n\t\t' exec node --inspect=127.0.0.1:\"$INSPECT_PORT\" --max_old_space_size=3000 tmp/index.js',\n\t\t' fi',\n\t\t' echo \"ResolveIO AI runner QA compiling server tmp output for pre-seeded local Mongo.\"',\n\t\t' node_modules/gulp/bin/gulp.js compile dotenv methodAndPublicationListGenerator',\n\t\t' compile_rc=\"$?\"',\n\t\t' if [ \"$compile_rc\" != \"0\" ]; then echo \"ResolveIO AI runner QA server compile failed before tmp startup (exit $compile_rc).\"; exit \"$compile_rc\"; fi',\n\t\t' if ! prepare_tmp_server_settings; then echo \"ResolveIO AI runner QA missing settings.json/settings.local.json for tmp server startup\"; exit 4; fi',\n\t\t' if [ ! -f tmp/index.js ]; then echo \"ResolveIO AI runner QA missing server/tmp/index.js after compile\"; exit 4; fi',\n\t\t' echo \"ResolveIO AI runner QA starting node tmp/index.js\"',\n\t\t' exec node --inspect=127.0.0.1:\"$INSPECT_PORT\" --max_old_space_size=3000 tmp/index.js',\n\t\t'}',\n\t\t'if reuse_running_app_if_ready; then RUNNER_REUSED_READY=1; exit 0; fi',\n\t\t'if ! mkdir \"$LOCK_DIR\" 2>/dev/null; then',\n\t\t' if janitor_lock_is_live; then',\n\t\t' echo \"ResolveIO AI runner QA lock is already held by a live runner for $PROJECT_ROOT; refusing duplicate startup.\" | tee \"$ARTIFACT_DIR/runner.log\"',\n\t\t' exit 6',\n\t\t' fi',\n\t\t' echo \"ResolveIO AI runner QA lock is stale for $PROJECT_ROOT; cleaning scoped local QA processes before retrying.\" | tee \"$ARTIFACT_DIR/runner.log\"',\n\t\t' cleanup_project_processes',\n\t\t' rm -rf \"$LOCK_DIR\" >/dev/null 2>&1 || true',\n\t\t' if ! mkdir \"$LOCK_DIR\" 2>/dev/null; then',\n\t\t' echo \"ResolveIO AI runner QA lock is still held for $PROJECT_ROOT after cleanup. Stop the existing QA runner before starting another.\" | tee -a \"$ARTIFACT_DIR/runner.log\"',\n\t\t' exit 6',\n\t\t' fi',\n\t\t'fi',\n\t\t'janitor_write_lock',\n\t\t'cleanup_project_processes',\n\t\t': > \"$ARTIFACT_DIR/server.log\"',\n\t\t': > \"$ARTIFACT_DIR/client.log\"',\n\t\t': > \"$ARTIFACT_DIR/runner.log\"',\n\t\t'janitor_write_manifest',\n\t\t'janitor_start_heartbeat',\n\t\t'echo \"$RUNNER_JANITOR_HEARTBEAT_PID\" > \"$ARTIFACT_DIR/heartbeat.pid\"',\n\t\t'janitor_check_resources || exit $?',\n\t\t'prestart_seed_live_data || exit $?',\n\t\t'if [ -d \"$PROJECT_ROOT/server\" ]; then',\n\t\t' SERVER_REQUIRED=1',\n\t\t' if [ \"${RESOLVEIO_QA_PRESTART_MONGO_READY:-}\" = \"1\" ] && [ -x \"$PROJECT_ROOT/server/node_modules/gulp/bin/gulp.js\" ] && [ -f \"$PROJECT_ROOT/server/gulpfile.js\" ] && grep -q \"mongo-start\" \"$PROJECT_ROOT/server/gulpfile.js\"; then',\n\t\t' echo \"ResolveIO AI runner QA using pre-seeded local Mongo; starting server without mongo-start.\" | tee -a \"$ARTIFACT_DIR/runner.log\"',\n\t\t' (run_preseeded_tmp_server 2>&1 | tee \"$ARTIFACT_DIR/server.log\") &',\n\t\t' elif node -e \"const p=require(process.argv[1]); process.exit(p.scripts&&p.scripts.server?0:1)\" \"$PROJECT_ROOT/server/package.json\" >/dev/null 2>&1; then',\n\t\t' (cd \"$PROJECT_ROOT/server\" && source \"$TOOLS_DIR/env.sh\" && npm run server 2>&1 | tee \"$ARTIFACT_DIR/server.log\") &',\n\t\t' elif [ -x \"$PROJECT_ROOT/server/start_server.sh\" ]; then',\n\t\t' (cd \"$PROJECT_ROOT/server\" && source \"$TOOLS_DIR/env.sh\" && ./start_server.sh 2>&1 | tee \"$ARTIFACT_DIR/server.log\") &',\n\t\t' else',\n\t\t' echo \"ResolveIO AI runner QA cannot find npm server script or start_server.sh for $PROJECT_ROOT/server\" | tee \"$ARTIFACT_DIR/server.log\"',\n\t\t' exit 5',\n\t\t' fi',\n\t\t' SERVER_PID=$!',\n\t\t' wait_for_server_ready',\n\t\t' SERVER_RESULT=$?',\n\t\t' if [ \"$SERVER_RESULT\" != \"0\" ]; then echo \"ResolveIO AI runner QA server startup fatal error. See $ARTIFACT_DIR/server.log\"; exit \"$SERVER_RESULT\"; fi',\n\t\t'fi',\n\t\t'CLIENT_HOST=\"${RESOLVEIO_RUNNER_QA_CLIENT_HOST:-${RESOLVEIO_SUPPORT_QA_CLIENT_HOST:-0.0.0.0}}\"',\n\t\t'if [ -x \"$PROJECT_ROOT/node_modules/.bin/ng\" ]; then',\n\t\t' prepare_angular_cache_dirs',\n\t\t' ANGULAR_OLD_SPACE=\"${RESOLVEIO_RUNNER_QA_ANGULAR_OLD_SPACE_MB:-${RESOLVEIO_SUPPORT_QA_ANGULAR_OLD_SPACE_MB:-3072}}\"',\n\t\t' (cd \"$PROJECT_ROOT\" && source \"$TOOLS_DIR/env.sh\" && node --max_old_space_size=\"$ANGULAR_OLD_SPACE\" ./node_modules/.bin/ng serve --watch --configuration local --host \"$CLIENT_HOST\" --port \"$CLIENT_PORT\" \"${ANGULAR_PREBUNDLE_ARGS[@]}\" 2>&1 | tee \"$ARTIFACT_DIR/client.log\") &',\n\t\t'elif [ -x \"$PROJECT_ROOT/start_client.sh\" ]; then',\n\t\t' (cd \"$PROJECT_ROOT\" && source \"$TOOLS_DIR/env.sh\" && ./start_client.sh 2>&1 | tee \"$ARTIFACT_DIR/client.log\") &',\n\t\t'elif node -e \"const p=require(process.argv[1]); process.exit(p.scripts&&p.scripts.client?0:1)\" \"$PROJECT_ROOT/package.json\" >/dev/null 2>&1; then',\n\t\t' (cd \"$PROJECT_ROOT\" && source \"$TOOLS_DIR/env.sh\" && npm run client 2>&1 | tee \"$ARTIFACT_DIR/client.log\") &',\n\t\t'else',\n\t\t' echo \"ResolveIO AI runner QA cannot find Angular CLI, start_client.sh, or npm client script for $PROJECT_ROOT\" | tee \"$ARTIFACT_DIR/client.log\"',\n\t\t' exit 5',\n\t\t'fi',\n\t\t'CLIENT_PID=$!',\n\t\t'wait_for_client',\n\t\t'RESULT=$?',\n\t\t'case \"$RESULT\" in',\n\t\t' 0)',\n\t\t' echo \"ResolveIO AI runner QA local app ready at $CLIENT_URL\";',\n\t\t' echo \"$SERVER_PID\" > \"$ARTIFACT_DIR/server.pid\";',\n\t\t' echo \"$CLIENT_PID\" > \"$ARTIFACT_DIR/client.pid\";',\n\t\t' if truthy \"$KEEPALIVE\"; then detach_keepalive || exit $?; fi;',\n\t\t' exit 0',\n\t\t' ;;',\n\t\t' 2) echo \"ResolveIO AI runner QA client process exited before $CLIENT_URL became ready. See $ARTIFACT_DIR/client.log\"; exit 2 ;;',\n\t\t' 3) echo \"ResolveIO AI runner QA client startup fatal error. See $ARTIFACT_DIR/client.log\"; exit 3 ;;',\n\t\t' 4) echo \"ResolveIO AI runner QA server startup fatal error. See $ARTIFACT_DIR/server.log\"; exit 4 ;;',\n\t\t' *) echo \"ResolveIO AI runner QA local app did not become ready at $CLIENT_URL within ${STARTUP_TIMEOUT}s. See $ARTIFACT_DIR/client.log and $ARTIFACT_DIR/server.log\"; exit 1 ;;',\n\t\t'esac',\n\t\t''\n\t].join('\\n');\n}\n\nexport function buildResolveIORunnerLocalQaStopperScript(): string {\n\treturn [\n\t\t'#!/usr/bin/env bash',\n\t\t'set -u',\n\t\t'TOOLS_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"',\n\t\t'source \"$TOOLS_DIR/env.sh\"',\n\t\t'PROJECT_ROOT=\"${1:-$(pwd)}\"',\n\t\t'PROJECT_ROOT=\"$(cd \"$PROJECT_ROOT\" && pwd)\"',\n\t\t'ARTIFACT_DIR=\"$PROJECT_ROOT/qa-artifacts\"',\n\t\t'CLIENT_PORT=\"${RESOLVEIO_RUNNER_QA_CLIENT_PORT:-${RESOLVEIO_SUPPORT_QA_CLIENT_PORT:-4200}}\"',\n\t\t'SERVER_PORT=\"${RESOLVEIO_RUNNER_QA_SERVER_PORT:-${RESOLVEIO_SUPPORT_QA_SERVER_PORT:-8080}}\"',\n\t\t'MONGO_PORT=\"${RESOLVEIO_RUNNER_QA_MONGO_PORT:-${RESOLVEIO_SUPPORT_QA_MONGO_PORT:-3001}}\"',\n\t\t'INSPECT_PORT=\"${RESOLVEIO_RUNNER_QA_INSPECT_PORT:-${RESOLVEIO_SUPPORT_QA_INSPECT_PORT:-9229}}\"',\n\t\t'REPO_ROOT=\"$(git -C \"$PROJECT_ROOT\" rev-parse --show-toplevel 2>/dev/null || echo \"$PROJECT_ROOT\")\"',\n\t\tbuildRunnerProcessJanitorShellLibrary({ mode: 'support' }),\n\t\t'STOP_LOCK_DIR=\"$ARTIFACT_DIR/.qa.stop.lock\"',\n\t\t'if ! mkdir \"$STOP_LOCK_DIR\" 2>/dev/null; then',\n\t\t' lock_pid=\"$(cat \"$STOP_LOCK_DIR/pid\" 2>/dev/null || true)\"',\n\t\t' if [ -n \"$lock_pid\" ] && kill -0 \"$lock_pid\" >/dev/null 2>&1; then',\n\t\t' echo \"ResolveIO AI runner QA cleanup already active for $PROJECT_ROOT; refusing duplicate stopper.\"',\n\t\t' exit 0',\n\t\t' fi',\n\t\t' rm -rf \"$STOP_LOCK_DIR\" >/dev/null 2>&1 || true',\n\t\t' mkdir \"$STOP_LOCK_DIR\" 2>/dev/null || { echo \"ResolveIO AI runner QA cleanup lock still active for $PROJECT_ROOT.\"; exit 0; }',\n\t\t'fi',\n\t\t'echo \"$$\" > \"$STOP_LOCK_DIR/pid\" 2>/dev/null || true',\n\t\t'trap \\'rm -rf \"$STOP_LOCK_DIR\" >/dev/null 2>&1 || true\\' EXIT',\n\t\t'kill_tree() {',\n\t\t' local pid=\"$1\"',\n\t\t' [ -n \"$pid\" ] || return 0',\n\t\t' kill -0 \"$pid\" >/dev/null 2>&1 || return 0',\n\t\t' for child in $(pgrep -P \"$pid\" 2>/dev/null || true); do kill_tree \"$child\"; done',\n\t\t' kill \"$pid\" >/dev/null 2>&1 || true',\n\t\t' sleep 1',\n\t\t' kill -0 \"$pid\" >/dev/null 2>&1 && kill -9 \"$pid\" >/dev/null 2>&1 || true',\n\t\t'}',\n\t\t'kill_port_listeners() {',\n\t\t' local port=\"$1\"',\n\t\t' [ -n \"$port\" ] || return 0',\n\t\t' local pids=\"\"',\n\t\t' if command -v lsof >/dev/null 2>&1; then pids=\"$pids $(janitor_bounded 3 lsof -ti tcp:\"$port\")\"; fi',\n\t\t' if command -v fuser >/dev/null 2>&1; then pids=\"$pids $(janitor_bounded 3 fuser -n tcp \"$port\")\"; fi',\n\t\t' if command -v ss >/dev/null 2>&1; then pids=\"$pids $(janitor_bounded 3 ss -ltnp \"sport = :$port\" | sed -n \\'s/.*pid=\\\\([0-9][0-9]*\\\\).*/\\\\1/p\\' || true)\"; fi',\n\t\t' for pid in $pids; do',\n\t\t' [ \"$pid\" = \"$$\" ] && continue',\n\t\t' kill_tree \"$pid\"',\n\t\t' done',\n\t\t' sleep 1',\n\t\t'}',\n\t\t'kill_env_marked_processes() {',\n\t\t' [ -d /proc ] || return 0',\n\t\t' local job_id=\"${RESOLVEIO_RUNNER_QA_JOB_ID:-${RESOLVEIO_SUPPORT_QA_JOB_ID:-}}\"',\n\t\t' local owner_id=\"${RESOLVEIO_RUNNER_QA_OWNER_ID:-${RESOLVEIO_SUPPORT_QA_OWNER_ID:-}}\"',\n\t\t' local token=\"${RESOLVEIO_RUNNER_QA_RUNNER_TOKEN:-${RESOLVEIO_SUPPORT_QA_RUNNER_TOKEN:-}}\"',\n\t\t' [ -n \"$job_id$owner_id$token\" ] || return 0',\n\t\t' for env_file in /proc/[0-9]*/environ; do',\n\t\t' pid=\"${env_file#/proc/}\"',\n\t\t' pid=\"${pid%/environ}\"',\n\t\t' skip_cleanup_pid \"$pid\" && continue',\n\t\t' [ \"$pid\" = \"$$\" ] && continue',\n\t\t' [ -r \"$env_file\" ] || continue',\n\t\t' env_text=\"$(tr \"\\\\0\" \"\\\\n\" < \"$env_file\" 2>/dev/null || true)\"',\n\t\t' [ -n \"$env_text\" ] || continue',\n\t\t' matched=0',\n\t\t' [ -n \"$job_id\" ] && echo \"$env_text\" | grep -Eq \"^(RESOLVEIO_RUNNER_QA_JOB_ID|RESOLVEIO_SUPPORT_QA_JOB_ID)=$job_id$\" && matched=1',\n\t\t' [ \"$matched\" = \"0\" ] && [ -n \"$owner_id\" ] && echo \"$env_text\" | grep -Eq \"^(RESOLVEIO_RUNNER_QA_OWNER_ID|RESOLVEIO_SUPPORT_QA_OWNER_ID)=$owner_id$\" && matched=1',\n\t\t' [ \"$matched\" = \"0\" ] && [ -n \"$token\" ] && echo \"$env_text\" | grep -Eq \"^(RESOLVEIO_RUNNER_QA_RUNNER_TOKEN|RESOLVEIO_SUPPORT_QA_RUNNER_TOKEN)=$token$\" && matched=1',\n\t\t' [ \"$matched\" = \"1\" ] && kill_tree \"$pid\" && killed_count=$((killed_count + 1))',\n\t\t' done',\n\t\t'}',\n\t\t'kill_artifact_log_writers() {',\n\t\t' local artifact=\"$ARTIFACT_DIR\"',\n\t\t' [ -n \"$artifact\" ] || return 0',\n\t\t' for pid in $(ps -eo pid=,args= | awk -v artifact=\"$artifact\" \\'index($0, artifact) && $0 !~ /awk -v artifact=/ && $0 !~ /ps -eo pid=,args=/ && $0 ~ /(^|[ /])(tee|tail)( |$)/ {print $1}\\' 2>/dev/null || true); do',\n\t\t' skip_cleanup_pid \"$pid\" && continue',\n\t\t' kill_tree \"$pid\"',\n\t\t' killed_count=$((killed_count + 1))',\n\t\t' done',\n\t\t'}',\n\t\t'kill_local_mongo_processes() {',\n\t\t' local mongo_port=\"$MONGO_PORT\"',\n\t\t' local root=\"$PROJECT_ROOT\"',\n\t\t' [ -n \"$mongo_port$root\" ] || return 0',\n\t\t' for pid in $(ps -eo pid=,args= | awk -v port=\"$mongo_port\" -v root=\"$root\" \\'$0 !~ /awk -v port=/ && $0 !~ /ps -eo pid=,args=/ && $0 ~ /mongod/ && (($0 ~ (\"--port \" port)) || index($0, root \"/server/mongo/data/db\") || index($0, root \"/mongo/data/db\")) && ($0 ~ /\\\\/tmp\\\\/resolveio-support-qa\\\\/.*mongod/ || index($0, root) || $0 ~ /--dbpath .*mongo\\\\/data\\\\/db/) {print $1}\\' 2>/dev/null || true); do',\n\t\t' skip_cleanup_pid \"$pid\" && continue',\n\t\t' [ \"$pid\" = \"$$\" ] && continue',\n\t\t' kill_tree \"$pid\"',\n\t\t' sleep 1',\n\t\t' kill -0 \"$pid\" >/dev/null 2>&1 && kill -9 \"$pid\" >/dev/null 2>&1 || true',\n\t\t' killed_count=$((killed_count + 1))',\n\t\t' done',\n\t\t'}',\n\t\t'RUNNER_ANCESTOR_PIDS=\" $$ ${PPID:-} \"',\n\t\t'ancestor_pid=\"${PPID:-}\"',\n\t\t'while [ -n \"$ancestor_pid\" ] && [ \"$ancestor_pid\" != \"0\" ] && [ \"$ancestor_pid\" != \"1\" ]; do',\n\t\t' ancestor_pid=\"$(ps -o ppid= -p \"$ancestor_pid\" 2>/dev/null | tr -d \" \" || true)\"',\n\t\t' [ -n \"$ancestor_pid\" ] && RUNNER_ANCESTOR_PIDS=\"$RUNNER_ANCESTOR_PIDS $ancestor_pid \"',\n\t\t'done',\n\t\t'skip_cleanup_pid() {',\n\t\t' case \"$RUNNER_ANCESTOR_PIDS\" in *\" $1 \"*) return 0 ;; esac',\n\t\t' return 1',\n\t\t'}',\n\t\t'janitor_update_manifest_status cleanup_started',\n\t\t'killed_count=0',\n'for pid_file in \"$ARTIFACT_DIR/heartbeat.pid\" \"$ARTIFACT_DIR/server.pid\" \"$ARTIFACT_DIR/client.pid\"; do',\n\t\t' [ -f \"$pid_file\" ] || continue',\n\t\t' pid=\"$(cat \"$pid_file\" 2>/dev/null || true)\"',\n\t\t' kill_tree \"$pid\"',\n\t\t' killed_count=$((killed_count + 1))',\n\t\t' rm -f \"$pid_file\"',\n\t\t'done',\n\t\t'for pass in 1 2 3; do',\n\t\t' for port in \"$CLIENT_PORT\" \"$SERVER_PORT\" \"$MONGO_PORT\" \"$INSPECT_PORT\"; do kill_port_listeners \"$port\"; done',\n\t\t' kill_env_marked_processes',\n\t\t' kill_artifact_log_writers',\n\t\t' kill_local_mongo_processes',\n\t\t' for pid in $(ps -eo pid=,args= | awk -v root=\"$PROJECT_ROOT\" \\'index($0, root) && $0 !~ /awk -v root=/ && $0 !~ /ps -eo pid=,args=/ && $0 !~ /run-local-qa\\\\.sh|stop-local-qa\\\\.sh|bugfix-comparison-qa\\\\.sh/ && $0 ~ /(ng serve|node .*node_modules\\\\/\\\\.bin\\\\/ng[[:space:]]+serve|esbuild --service|npm run client|start_client\\\\.sh|npm run server|start_server\\\\.sh|nodemon|node .*tmp\\\\/index\\\\.js|mongod|mongodb-binaries\\\\/mongod)/ {print $1}\\' 2>/dev/null || true); do',\n\t\t' skip_cleanup_pid \"$pid\" && continue',\n\t\t' kill_tree \"$pid\"',\n\t\t' killed_count=$((killed_count + 1))',\n\t\t' done',\n\t\t' # Do not kill arbitrary processes by project cwd; completion builds run',\n\t\t' # from the same cwd. Stop only known QA process signatures, recorded PIDs,',\n\t\t' # scoped ports, and QA runner env markers.',\n\t\t' sleep 1',\n\t\t'done',\n\t\t'wait_until=$((SECONDS + 60))',\n\t'while [ \"$SECONDS\" -lt \"$wait_until\" ]; do',\n\t\t' found=0',\n\t\t' for port in \"$CLIENT_PORT\" \"$SERVER_PORT\" \"$MONGO_PORT\" \"$INSPECT_PORT\"; do',\n\t\t' port_pids=\"\"',\n\t\t' if command -v lsof >/dev/null 2>&1; then port_pids=\"$port_pids $(janitor_bounded 3 lsof -ti tcp:\"$port\")\"; fi',\n\t\t' for pid in $port_pids; do skip_cleanup_pid \"$pid\" && continue; found=1; kill_tree \"$pid\"; done',\n\t\t' done',\n\t\t' if [ -d /proc ]; then',\n\t\t' job_id=\"${RESOLVEIO_RUNNER_QA_JOB_ID:-${RESOLVEIO_SUPPORT_QA_JOB_ID:-}}\"',\n\t\t' owner_id=\"${RESOLVEIO_RUNNER_QA_OWNER_ID:-${RESOLVEIO_SUPPORT_QA_OWNER_ID:-}}\"',\n\t\t' token=\"${RESOLVEIO_RUNNER_QA_RUNNER_TOKEN:-${RESOLVEIO_SUPPORT_QA_RUNNER_TOKEN:-}}\"',\n\t\t' for env_file in /proc/[0-9]*/environ; do',\n\t\t' pid=\"${env_file#/proc/}\"',\n\t\t' pid=\"${pid%/environ}\"',\n\t\t' skip_cleanup_pid \"$pid\" && continue',\n\t\t' [ -r \"$env_file\" ] || continue',\n\t\t' env_text=\"$(tr \"\\\\0\" \"\\\\n\" < \"$env_file\" 2>/dev/null || true)\"',\n\t\t' matched=0',\n\t\t' [ -n \"$job_id\" ] && echo \"$env_text\" | grep -Eq \"^(RESOLVEIO_RUNNER_QA_JOB_ID|RESOLVEIO_SUPPORT_QA_JOB_ID)=$job_id$\" && matched=1',\n\t\t' [ \"$matched\" = \"0\" ] && [ -n \"$owner_id\" ] && echo \"$env_text\" | grep -Eq \"^(RESOLVEIO_RUNNER_QA_OWNER_ID|RESOLVEIO_SUPPORT_QA_OWNER_ID)=$owner_id$\" && matched=1',\n\t\t' [ \"$matched\" = \"0\" ] && [ -n \"$token\" ] && echo \"$env_text\" | grep -Eq \"^(RESOLVEIO_RUNNER_QA_RUNNER_TOKEN|RESOLVEIO_SUPPORT_QA_RUNNER_TOKEN)=$token$\" && matched=1',\n\t\t' [ \"$matched\" = \"1\" ] && found=1 && kill_tree \"$pid\"',\n\t\t' done',\n\t\t' fi',\n\t\t' kill_artifact_log_writers',\n\t\t' kill_local_mongo_processes',\n\t\t' for pid in $(ps -eo pid=,args= | awk -v root=\"$PROJECT_ROOT\" \\'index($0, root) && $0 !~ /awk -v root=/ && $0 !~ /ps -eo pid=,args=/ && $0 !~ /run-local-qa\\\\.sh|stop-local-qa\\\\.sh|bugfix-comparison-qa\\\\.sh/ && $0 ~ /(ng serve|node .*node_modules\\\\/\\\\.bin\\\\/ng[[:space:]]+serve|esbuild --service|npm run client|start_client\\\\.sh|npm run server|start_server\\\\.sh|nodemon|node .*tmp\\\\/index\\\\.js|mongod|mongodb-binaries\\\\/mongod)/ {print $1}\\' 2>/dev/null || true); do',\n\t\t' skip_cleanup_pid \"$pid\" && continue',\n\t\t' found=1',\n\t\t' done',\n\t\t' [ \"$found\" = \"0\" ] && break',\n\t\t' sleep 2',\n\t\t'done',\n\t\t'rm -rf \"$ARTIFACT_DIR/.qa.lock\" >/dev/null 2>&1 || true',\n\t\t'janitor_update_manifest_status stopped',\n\t\t'janitor_write_cleanup_status stopped \"$killed_count\"',\n\t\t'echo \"ResolveIO AI runner QA local app stopped for $PROJECT_ROOT\"',\n\t\t''\n\t].join('\\n');\n}\n\nexport function buildResolveIORunnerQaLiveDataSeederScript(): string {\n\treturn [\n\t\t\t'#!/usr/bin/env node',\n\t\t\t'const fs = require(\"fs\");',\n\t\t\t'const path = require(\"path\");',\n\t\t\t'const crypto = require(\"crypto\");',\n\t\t'',\n\t\t'if (isBuildLane()) {',\n\t\t' console.error(\"ResolveIO support lane guard: live-data seeding is owned by the QA lane, not the 5.3 build lane.\");',\n\t\t' process.exit(86);',\n\t\t'}',\n\t\t'',\n\t\t'const projectRoot = path.resolve(process.argv[2] || process.cwd());',\n\t\t'const repoRoot = findRepoRoot(projectRoot);',\n\t\t'const artifactDir = path.join(projectRoot, \"qa-artifacts\");',\n\t\t'fs.mkdirSync(artifactDir, { recursive: true });',\n\t\t'const resultPath = path.join(artifactDir, \"qa-live-data-seed-result.json\");',\n\t\t'',\n\t\t'function writeResult(payload, exitCode = 0) {',\n\t\t' const full = { ...payload, created_at: new Date().toISOString() };',\n\t\t' normalizeCoverageMatrixFromLiveSeed(full);',\n\t\t' fs.writeFileSync(resultPath, JSON.stringify(full, null, 2));',\n\t\t' console.log(JSON.stringify(full, null, 2));',\n\t\t' process.exit(exitCode);',\n\t\t'}',\n\t\t'',\n\t\t'function isBuildLane() {',\n\t\t' return /^(build|support_build|support-build)$/i.test(String(process.env.RESOLVEIO_SUPPORT_CODEX_LANE || \"\").trim());',\n\t\t'}',\n\t\t'',\n\t\t'function findRepoRoot(start) {',\n\t\t' let current = start;',\n\t\t' for (let i = 0; i < 8; i += 1) {',\n\t\t' if (fs.existsSync(path.join(current, \".git\"))) return current;',\n\t\t' const parent = path.dirname(current);',\n\t\t' if (parent === current) break;',\n\t\t' current = parent;',\n\t\t' }',\n\t\t' return start;',\n\t\t'}',\n\t\t'',\n\t\t'function readJsonIfExists(filePath) {',\n\t\t' try { return JSON.parse(fs.readFileSync(filePath, \"utf8\")); } catch (error) { return null; }',\n\t\t'}',\n\t\t'',\n\t\t'function normalizeCoverageMatrixFromLiveSeed(payload) {',\n\t\t' const bolContext = payload && payload.selected && payload.selected.truck_treating_bol_context;',\n\t\t' const notes = Array.isArray(payload && payload.notes) ? payload.notes.map((note) => String(note || \"\")) : [];',\n\t\t' const billingDisabled = notes.some((note) => /billing fixtures are disabled/i.test(note));',\n\t\t' if (!bolContext || !billingDisabled) return;',\n\t\t' const matrixPath = path.join(artifactDir, \"qa-coverage-matrix.json\");',\n\t\t' const matrix = readJsonIfExists(matrixPath) || { status: \"started\", seeded: true, source: \"qa-live-data-seed\" };',\n\t\t' const browserRoutes = bolContext.browser_routes && typeof bolContext.browser_routes === \"object\" ? bolContext.browser_routes : {};',\n\t\t' const routeHints = Array.isArray(bolContext.route_name_hints) ? bolContext.route_name_hints.map((value) => String(value || \"\").trim()).filter(Boolean) : [];',\n\t\t' const linkedRoutes = Array.isArray(bolContext.linked_truck_treating_routes) ? bolContext.linked_truck_treating_routes.map((value) => String(value || \"\").trim()).filter(Boolean) : [];',\n\t\t' const bolIds = Array.isArray(bolContext.bol_ids) ? bolContext.bol_ids.map((value) => String(value || \"\").trim()).filter(Boolean) : [];',\n\t\t' const routeIds = Array.isArray(bolContext.route_ids) ? bolContext.route_ids.map((value) => String(value || \"\").trim()).filter(Boolean) : [];',\n\t\t' const truckTreatingRouteIds = Array.isArray(bolContext.truck_treating_route_ids) ? bolContext.truck_treating_route_ids.map((value) => String(value || \"\").trim()).filter(Boolean) : [];',\n\t\t' const primaryStatus = String(bolContext.primary_bol_status || \"\");',\n\t\t' const delivered = Boolean(bolContext.primary_bol_delivered) || /delivered/i.test(primaryStatus);',\n\t\t' const hintedBol = routeHints.join(\" \");',\n\t\t' const bolNumber = (/\\\\bBOL\\\\s*#?\\\\s*(\\\\d+)\\\\b/i.exec(hintedBol) || [])[1];',\n\t\t' const bolLabel = bolNumber ? `BOL ${bolNumber}` : (bolIds[0] ? `BOL ${bolIds[0]}` : \"the requested BOL\");',\n\t\t' const routeHint = routeHints.find((hint) => !/\\\\bBOL\\\\b/i.test(hint) && !/^\\\\d+$/.test(hint)) || \"the ticket route hint\";',\n\t\t' const routeSummary = linkedRoutes.length ? linkedRoutes.join(\", \") : (truckTreatingRouteIds.length ? truckTreatingRouteIds.join(\", \") : routeIds.slice(0, 6).join(\", \"));',\n\t\t' const deliveredNote = delivered ? ` The live BOL status is ${primaryStatus || \"Delivered\"}, so the direct delivery route is an action route that may correctly redirect; QA must use delivered Open File/detail proof or a localhost-only deliverable fixture copied from this live context for Treat/Deliver actions.` : \"\";',\n\t\t' const liveAssertion = `Live Mongo seeded ${bolLabel} and proved ${routeHint} is not a linked truck-treating route for that BOL; QA must continue against linked live route data: ${routeSummary}.${deliveredNote}`;',\n\t\t' matrix.status = \"in_progress\";',\n\t\t' matrix.source = \"qa-live-data-seed-live-bol-context\";',\n\t\t' matrix.live_seed_context_artifact = \"qa-artifacts/qa-live-data-seed-result.json\";',\n\t\t' matrix.billing_rows_removed_reason = \"Live data seed disabled billing fixtures for this ticket; invoice/billing matrix rows do not apply to truck-treating BOL QA.\";',\n\t\t' matrix.rows = [',\n\t\t' { workflow: \"Truck treating BOL live-data target and route validation\", route: browserRoutes.delivery || browserRoutes.detail || browserRoutes.list || \"Deliver BOL live seeded BOL context\", assertion: liveAssertion, required_proof: \"Live Mongo seed artifact showing BOL id/status, linked route ids, ticket route-hint match result, and browser route.\", status: \"pass\", result: \"pass\", screenshot: \"\", caption: `Live data seeded ${bolLabel}; the ticket route label did not match the BOL-linked live routes, so QA continued against ${routeSummary}.`, artifact: \"qa-artifacts/qa-live-data-seed-result.json\", persisted_assertion: `qa-live-data-seed-result.json route_hint_matched=${bolContext.route_hint_matched}; bol_ids=${bolIds.join(\",\") || \"none\"}; route_ids=${routeIds.length}; truck_treating_route_ids=${truckTreatingRouteIds.length}; primary_bol_status=${primaryStatus || \"unknown\"}.` },',\n\t\t' { workflow: \"Delivered BOL detail/Open File proof\", route: browserRoutes.detail || browserRoutes.list || browserRoutes.delivery || \"/\", assertion: `Open the seeded ${bolLabel} in the truck-treating delivered/detail workflow and prove the local QA database loaded the customer-facing BOL screen without relying on the already-delivered action route.`, required_proof: \"Customer-facing screenshot of the BOL detail/list/Open File screen plus BOL id/status assertion from local Mongo.\", status: \"pending\", screenshot: \"\", caption: \"\" },',\n\t\t' { workflow: \"Deliver BOL service/flush rows do not render as missing chemicals\", route: browserRoutes.delivery || browserRoutes.detail || \"/\", assertion: \"Service/flush/non-chemical treatment plans must not be injected into the Deliver BOL chemical list as red missing chemical placeholders; chemical treatment rows still appear normally.\", required_proof: \"Customer-facing screenshot of the Deliver BOL/detail workflow or a localhost-only deliverable fixture copied from the seeded live BOL context, plus DOM/local Mongo assertion that missing placeholders are limited to Chemical treatment plans.\", status: \"pending\", screenshot: \"\", caption: \"\" }',\n\t\t' ];',\n\t\t' fs.writeFileSync(matrixPath, JSON.stringify(matrix, null, 2));',\n\t\t'}',\n\t\t'',\n\t\t'function preserveExistingSeedResult(reason) {',\n\t\t' const existing = readJsonIfExists(resultPath);',\n\t\t' const status = String(existing && existing.status || \"\").toLowerCase();',\n\t\t' const desiredProfile = desiredSeedProfile();',\n\t\t' if (existing && existing.profile && existing.profile !== desiredProfile) return;',\n\t\t' if (existing && existing.profile === \"billing_inventory\" && shouldSeedBillingDashboardFixtures() && !(existing.selected && existing.selected.qa_billing_fixture)) {',\n\t\t' return;',\n\t\t' }',\n\t\t' if (existing && extractBolIdentifiers().length && !(existing.selected && existing.selected.truck_treating_bol_context)) {',\n\t\t' return;',\n\t\t' }',\n\t\t' if (existing && extractBolIdentifiers().length && existing.selected && existing.selected.truck_treating_bol_context && !(existing.selected.truck_treating_bol_context.browser_routes && existing.selected.truck_treating_bol_context.browser_routes.delivery)) {',\n\t\t' return;',\n\t\t' }',\n\t\t' if (existing && extractBolIdentifiers().length && existing.selected && existing.selected.truck_treating_bol_context && !Object.prototype.hasOwnProperty.call(existing.selected.truck_treating_bol_context, \"primary_bol_status\")) {',\n\t\t' return;',\n\t\t' }',\n\t\t' if (existing && shouldAutoDiscoverAssetContext() && !(existing.selected && existing.selected.qa_asset_context)) {',\n\t\t' return;',\n\t\t' }',\n\t\t' if (existing && shouldAutoDiscoverProductionInterchangeablesContext() && !(existing.selected && existing.selected.qa_production_interchangeables_context)) {',\n\t\t' return;',\n\t\t' }',\n\t\t' if ([\"pass\", \"needs-data\"].includes(status)) {',\n\t\t' normalizeCoverageMatrixFromLiveSeed(existing);',\n\t\t' const preserved = { ...existing, reused_existing: true, reuse_reason: reason, checked_at: new Date().toISOString() };',\n\t\t' console.log(JSON.stringify(preserved, null, 2));',\n\t\t' process.exit(0);',\n\t\t' }',\n\t\t'}',\n\t\t'',\n\t'function resolveRuntimeSource() {',\n\t\t' const explicitRuntimePaths = [',\n\t\t' process.env.RESOLVEIO_QA_MONGO_RUNTIME_PATH,',\n\t\t' process.env.RESOLVEIO_SUPPORT_QA_MONGO_RUNTIME_PATH,',\n\t' process.env.RESOLVEIO_RUNNER_QA_MONGO_RUNTIME_PATH',\n\t' ].map((value) => String(value || \"\").trim()).filter(Boolean);',\n\t' const candidates = [',\n\t' ...explicitRuntimePaths,',\n\t' path.join(repoRoot, \"mongo-context\", \".mongo-runtime.json\"),',\n\t' path.join(projectRoot, \"mongo-context\", \".mongo-runtime.json\"),',\n\t\t' path.join(repoRoot, \".resolveio-support-context\", \"mongo-context\", \".mongo-runtime.json\"),',\n\t\t' path.join(projectRoot, \".resolveio-support-context\", \"mongo-context\", \".mongo-runtime.json\"),',\n\t\t' path.join(repoRoot, \".resolveio-context\", \"mongo-context\", \".mongo-runtime.json\"),',\n\t\t' path.join(projectRoot, \".resolveio-context\", \"mongo-context\", \".mongo-runtime.json\")',\n\t\t' ];',\n\t\t' for (const candidate of candidates) {',\n\t\t' const parsed = readJsonIfExists(candidate);',\n\t\t' if (parsed && parsed.mongo_uri) return { uri: String(parsed.mongo_uri || \"\"), database: String(parsed.mongo_db || \"\") };',\n\t\t' }',\n\t' const envUri = process.env.RESOLVEIO_QA_LIVE_MONGO_URL || process.env.RESOLVEIO_SUPPORT_QA_LIVE_MONGO_URL || process.env.RESOLVEIO_RUNNER_QA_LIVE_MONGO_URL || \"\";',\n\t' const envDb = process.env.RESOLVEIO_QA_LIVE_MONGO_DB || process.env.RESOLVEIO_SUPPORT_QA_LIVE_MONGO_DB || process.env.RESOLVEIO_RUNNER_QA_LIVE_MONGO_DB || \"\";',\n\t' if (envUri) return { uri: envUri, database: envDb };',\n\t\t' return { uri: \"\", database: \"\" };',\n\t\t'}',\n\t\t'',\n\t\t'function redactUri(uri) {',\n\t\t' return String(uri || \"\").replace(/(mongodb(?:\\\\+srv)?:\\\\/\\\\/)([^:@/?#]+):([^@/?#]+)@/i, \"$1$2:***@\");',\n\t\t'}',\n\t\t'',\n\t'function isLocalMongoUri(uri) {',\n\t' return /mongodb(?:\\\\+srv)?:\\\\/\\\\/(?:[^@/]+@)?(?:127\\\\.0\\\\.0\\\\.1|localhost)(?::\\\\d+)?\\\\//i.test(String(uri || \"\"));',\n\t\t'}',\n\t'',\n\t'function isLiveDataRequired() {',\n\t' return /^(true|1|yes|on)$/i.test(String(process.env.RESOLVEIO_QA_LIVE_DATA_REQUIRED || process.env.RESOLVEIO_SUPPORT_QA_LIVE_DATA_REQUIRED || process.env.RESOLVEIO_RUNNER_QA_LIVE_DATA_REQUIRED || \"\"));',\n\t'}',\n\t'',\n\t'function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); }',\n\t'',\n\t'async function waitForTargetMongo(MongoClient, targetUri) {',\n\t' const deadline = Date.now() + Number(process.env.RESOLVEIO_QA_LOCAL_MONGO_WAIT_MS || process.env.RESOLVEIO_SUPPORT_QA_LOCAL_MONGO_WAIT_MS || process.env.RESOLVEIO_RUNNER_QA_LOCAL_MONGO_WAIT_MS || 60000);',\n\t' let lastError = null;',\n\t' while (Date.now() < deadline) {',\n\t' const client = new MongoClient(targetUri, { serverSelectionTimeoutMS: 2500 });',\n\t' try {',\n\t' await client.connect();',\n\t' const admin = client.db(\"admin\");',\n\t' await admin.command({ ping: 1 });',\n\t' let hello = null;',\n\t' try { hello = await admin.command({ hello: 1 }); } catch (error) {',\n\t' try { hello = await admin.command({ isMaster: 1 }); } catch (inner) { hello = null; }',\n\t' }',\n\t' const writable = !hello || hello.isWritablePrimary === true || hello.ismaster === true || !hello.setName;',\n\t' if (!writable) {',\n\t' lastError = new Error(`target_local_mongo_not_primary: ${hello && (hello.primary || hello.me || hello.setName) || \"unknown\"}`);',\n\t' await client.close().catch(() => undefined);',\n\t' await delay(1500);',\n\t' continue;',\n\t' }',\n\t' await client.close().catch(() => undefined);',\n\t' return;',\n\t' } catch (error) {',\n\t' lastError = error;',\n\t' await client.close().catch(() => undefined);',\n\t' await delay(1500);',\n\t' }',\n\t' }',\n\t' const detail = lastError && (lastError.message || String(lastError)) || \"local Mongo did not become ready\";',\n\t' throw new Error(`target_local_mongo_unavailable: ${detail}`);',\n\t'}',\n\t\t'',\n\t\t'function requireMongo() {',\n\t\t' const candidates = [',\n\t\t' path.join(projectRoot, \"server\", \"node_modules\", \"mongodb\"),',\n\t\t' path.join(projectRoot, \"node_modules\", \"mongodb\"),',\n\t\t' path.join(repoRoot, \"node_modules\", \"mongodb\"),',\n\t\t' \"mongodb\"',\n\t\t' ];',\n\t\t' const errors = [];',\n\t\t' for (const candidate of candidates) {',\n\t\t' try { return require(candidate); } catch (error) { errors.push(`${candidate}: ${error.message}`); }',\n\t\t' }',\n\t\t' throw new Error(`Unable to require mongodb package. ${errors.join(\" | \")}`);',\n\t\t'}',\n\t\t'',\n\t\t'function idValues(docs, keys) {',\n\t\t' const values = new Set();',\n\t\t' for (const doc of docs || []) {',\n\t\t' for (const key of keys) {',\n\t\t' const value = doc && doc[key];',\n\t\t' if (typeof value === \"string\" && value.trim()) values.add(value.trim());',\n\t\t' if (Array.isArray(value)) value.forEach((entry) => typeof entry === \"string\" && entry.trim() && values.add(entry.trim()));',\n\t\t' }',\n\t\t' }',\n\t\t' return Array.from(values);',\n\t\t'}',\n\t\t'',\n\t\t\t'function unique(values) { return Array.from(new Set((values || []).filter(Boolean).map(String))); }',\n\t\t\t'',\n\t\t\t'function lowerTrim(value) { return String(value || \"\").trim().toLowerCase(); }',\n\t\t\t'',\n\t\t\t'function escapeRegexText(value) { return String(value || \"\").replace(/[.*+?^${}()|[\\\\]\\\\\\\\]/g, \"\\\\\\\\$&\"); }',\n\t\t\t'',\n\t\t\t'function exactTextRegex(value) { return new RegExp(`^${escapeRegexText(value)}$`, \"i\"); }',\n\t\t\t'',\n\t\t\t'function requireOptionalXlsx() {',\n\t\t\t' const candidates = [',\n\t\t\t' path.join(projectRoot, \"server\", \"node_modules\", \"xlsx\"),',\n\t\t\t' path.join(projectRoot, \"node_modules\", \"xlsx\"),',\n\t\t\t' path.join(repoRoot, \"node_modules\", \"xlsx\"),',\n\t\t\t' path.join(process.cwd(), \"server\", \"node_modules\", \"xlsx\"),',\n\t\t\t' path.join(process.cwd(), \"node_modules\", \"xlsx\"),',\n\t\t\t' \"xlsx\"',\n\t\t\t' ];',\n\t\t\t' for (const candidate of candidates) { try { return require(candidate); } catch (error) {} }',\n\t\t\t' return null;',\n\t\t\t'}',\n\t\t\t'',\n\t\t\t'function collectPricingImportWorkbookPaths() {',\n\t\t\t' const dirs = [',\n\t\t\t' path.join(projectRoot, \".resolveio-context\", \"attachments\"),',\n\t\t\t' path.join(repoRoot, \".resolveio-context\", \"attachments\"),',\n\t\t\t' path.join(projectRoot, \".resolveio-support-context\", \"attachments\"),',\n\t\t\t' path.join(repoRoot, \".resolveio-support-context\", \"attachments\")',\n\t\t\t' ];',\n\t\t\t' const paths = [];',\n\t\t\t' for (const dir of dirs) {',\n\t\t\t' try {',\n\t\t\t' for (const name of fs.readdirSync(dir)) {',\n\t\t\t' if (/\\\\.xlsx$/i.test(name) && !/^~\\\\$/.test(name)) paths.push(path.join(dir, name));',\n\t\t\t' }',\n\t\t\t' } catch (error) {}',\n\t\t\t' }',\n\t\t\t' return unique(paths);',\n\t\t\t'}',\n\t\t\t'',\n\t\t\t'function normalizeWorkbookCell(value) {',\n\t\t\t' if (value == null) return \"\";',\n\t\t\t' if (value instanceof Date) return value.toISOString();',\n\t\t\t' return String(value).replace(/\\\\s+/g, \" \").trim();',\n\t\t\t'}',\n\t\t\t'',\n\t\t\t'function extractPricingImportWorkbookHints(summary) {',\n\t\t\t' const workbooks = collectPricingImportWorkbookPaths();',\n\t\t\t' const xlsx = workbooks.length ? requireOptionalXlsx() : null;',\n\t\t\t' const customerNames = new Set();',\n\t\t\t' const itemMap = new Map();',\n\t\t\t' const workbookSummaries = [];',\n\t\t\t' if (!workbooks.length) return { workbooks, workbook_summaries: workbookSummaries, customer_names: [], items: [] };',\n\t\t\t' if (!xlsx) {',\n\t\t\t' summary.notes.push(\"Pricing-import workbook seed context skipped because xlsx could not be required in the QA seeder.\");',\n\t\t\t' return { workbooks, workbook_summaries: workbookSummaries, customer_names: [], items: [] };',\n\t\t\t' }',\n\t\t\t' for (const workbookPath of workbooks.slice(0, 8)) {',\n\t\t\t' try {',\n\t\t\t' const workbook = xlsx.readFile(workbookPath, { cellDates: true });',\n\t\t\t' const sheetName = workbook.SheetNames.includes(\"Prices\") ? \"Prices\" : workbook.SheetNames[0];',\n\t\t\t' const rows = sheetName ? xlsx.utils.sheet_to_json(workbook.Sheets[sheetName], { defval: \"\" }) : [];',\n\t\t\t' for (const row of rows) {',\n\t\t\t' const customer = normalizeWorkbookCell(row.Customer || row.customer || row.CustomerName || row[\"Customer Name\"]);',\n\t\t\t' const pricingType = normalizeWorkbookCell(row[\"Pricing Type\"] || row.PricingType || row.Type || row.type);',\n\t\t\t' const name = normalizeWorkbookCell(row.Name || row.name || row.Item || row.item || row.Chemical || row.chemical);',\n\t\t\t' if (customer) customerNames.add(customer);',\n\t\t\t' if (name) itemMap.set(`${lowerTrim(pricingType)}::${lowerTrim(name)}`, { name, type: pricingType });',\n\t\t\t' }',\n\t\t\t' workbookSummaries.push({ name: path.basename(workbookPath), sheetName, rows: rows.length });',\n\t\t\t' } catch (error) {',\n\t\t\t' workbookSummaries.push({ name: path.basename(workbookPath), error: error && (error.message || String(error)) || String(error) });',\n\t\t\t' }',\n\t\t\t' }',\n\t\t\t' return { workbooks, workbook_summaries: workbookSummaries, customer_names: Array.from(customerNames).slice(0, 300), items: Array.from(itemMap.values()).slice(0, 700) };',\n\t\t\t'}',\n\t\t\t'',\n\t\t\t'async function copyPricingImportWorkbookContext(sourceDb, targetDb, summary) {',\n\t\t\t' if (!shouldSeedPricingImportFixtures()) return [];',\n\t\t\t' const hints = extractPricingImportWorkbookHints(summary);',\n\t\t\t' summary.selected.pricing_import_workbook_seed = {',\n\t\t\t' workbook_names: hints.workbooks.map((entry) => path.basename(entry)),',\n\t\t\t' workbook_summaries: hints.workbook_summaries,',\n\t\t\t' customer_name_count: hints.customer_names.length,',\n\t\t\t' item_name_count: hints.items.length',\n\t\t\t' };',\n\t\t\t' if (!hints.workbooks.length) {',\n\t\t\t' summary.notes.push(\"Pricing-import seed profile found no attached .xlsx workbooks to derive customer/item fixture context.\");',\n\t\t\t' return [];',\n\t\t\t' }',\n\t\t\t' const customerRegexes = hints.customer_names.map(exactTextRegex);',\n\t\t\t' const customers = customerRegexes.length ? await copyQuery(sourceDb, targetDb, \"customers\", { $or: [{ name: { $in: customerRegexes } }, { customer: { $in: customerRegexes } }, { company_name: { $in: customerRegexes } }] }, summary, 300, { name: 1 }) : [];',\n\t\t\t' const itemOrs = [];',\n\t\t\t' for (const hint of hints.items) {',\n\t\t\t' const nameRegex = exactTextRegex(hint.name);',\n\t\t\t' const typeRegex = hint.type ? exactTextRegex(hint.type) : null;',\n\t\t\t' if (typeRegex) itemOrs.push({ name: nameRegex, type: typeRegex }, { description: nameRegex, type: typeRegex });',\n\t\t\t' itemOrs.push({ name: nameRegex }, { description: nameRegex });',\n\t\t\t' }',\n\t\t\t' const items = itemOrs.length ? await copyQuery(sourceDb, targetDb, \"items\", { $or: itemOrs }, summary, 900, { name: 1 }) : [];',\n\t\t\t' const itemNameRegexes = hints.items.map((hint) => exactTextRegex(hint.name));',\n\t\t\t' const chemicals = itemNameRegexes.length ? await copyQuery(sourceDb, targetDb, \"chemicals\", { $or: [{ name: { $in: itemNameRegexes } }, { description: { $in: itemNameRegexes } }] }, summary, 900, { name: 1 }) : [];',\n\t\t\t' const chemicalIds = unique(chemicals.map((doc) => doc._id));',\n\t\t\t' const chemicalItems = chemicalIds.length ? await copyQuery(sourceDb, targetDb, \"items\", { $or: [{ id_chemical: { $in: chemicalIds } }, { _id: { $in: chemicalIds } }] }, summary, 900, { name: 1 }) : [];',\n\t\t\t' const copiedItems = [...items, ...chemicalItems];',\n\t\t\t' const copiedCustomerNames = new Set(customers.map((doc) => lowerTrim(doc.name || doc.customer || doc.company_name)));',\n\t\t\t' const copiedItemNames = new Set(copiedItems.map((doc) => lowerTrim(doc.name || doc.description)));',\n\t\t\t' const copiedChemicalNames = new Set(chemicals.map((doc) => lowerTrim(doc.name || doc.description)));',\n\t\t\t' const missingCustomers = hints.customer_names.filter((name) => !copiedCustomerNames.has(lowerTrim(name)));',\n\t\t\t' const missingItems = hints.items.filter((hint) => !copiedItemNames.has(lowerTrim(hint.name)) && !copiedChemicalNames.has(lowerTrim(hint.name))).map((hint) => hint.type ? `${hint.type}:${hint.name}` : hint.name);',\n\t\t\t' const itemIds = unique(copiedItems.map((doc) => doc._id));',\n\t\t\t' const customerIds = unique(customers.map((doc) => doc._id));',\n\t\t\t' summary.selected.pricing_import_workbook_context = {',\n\t\t\t' workbook_names: hints.workbooks.map((entry) => path.basename(entry)),',\n\t\t\t' customer_names: hints.customer_names.slice(0, 60),',\n\t\t\t' item_names: hints.items.map((hint) => hint.type ? `${hint.type}:${hint.name}` : hint.name).slice(0, 100),',\n\t\t\t' customer_ids: customerIds,',\n\t\t\t' item_ids: itemIds,',\n\t\t\t' chemical_ids: chemicalIds,',\n\t\t\t' missing_customer_names: missingCustomers.slice(0, 80),',\n\t\t\t' missing_item_names: missingItems.slice(0, 120)',\n\t\t\t' };',\n\t\t\t' summary.notes.push(`Seeded pricing-import workbook context: ${customers.length}/${hints.customer_names.length} customer name(s), ${copiedItems.length}/${hints.items.length} item name(s), ${chemicals.length} chemical(s) from ${hints.workbooks.length} attached workbook(s).`);',\n\t\t\t' if (missingCustomers.length || missingItems.length) summary.notes.push(`Pricing-import workbook context still missing ${missingCustomers.length} customer name(s) and ${missingItems.length} item name(s) from live Mongo.`);',\n\t\t\t' return [...customers, ...copiedItems, ...chemicals];',\n\t\t\t'}',\n\t\t\t'',\n\t\t\t'function collectEmailLikeValues(value, out = new Set(), depth = 0) {',\n\t\t\t' if (depth > 6 || value == null) return out;',\n\t\t\t' if (typeof value === \"string\") {',\n\t\t\t' const matches = value.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\\\.[A-Z]{2,}/gi) || [];',\n\t\t\t' matches.forEach((email) => out.add(String(email || \"\").trim().toLowerCase()));',\n\t\t\t' return out;',\n\t\t\t' }',\n\t\t\t' if (Array.isArray(value)) { value.forEach((entry) => collectEmailLikeValues(entry, out, depth + 1)); return out; }',\n\t\t\t' if (typeof value === \"object\") { Object.values(value).forEach((entry) => collectEmailLikeValues(entry, out, depth + 1)); }',\n\t\t\t' return out;',\n\t\t\t'}',\n\t\t\t'',\n\t\t\t'function readContextJsonFiles() {',\n\t\t\t' const files = [',\n\t\t\t' path.join(artifactDir, \"manual-ticket.metadata.json\"),',\n\t\t\t' path.join(artifactDir, \"email.metadata.json\"),',\n\t\t\t' path.join(repoRoot, \".resolveio-support-context\", \"manual-ticket.metadata.json\"),',\n\t\t\t' path.join(projectRoot, \".resolveio-support-context\", \"manual-ticket.metadata.json\"),',\n\t\t\t' path.join(repoRoot, \".resolveio-support-context\", \"email.metadata.json\"),',\n\t\t\t' path.join(projectRoot, \".resolveio-support-context\", \"email.metadata.json\"),',\n\t\t\t' path.join(repoRoot, \".resolveio-context\", \"manual-ticket.metadata.json\"),',\n\t\t\t' path.join(projectRoot, \".resolveio-context\", \"manual-ticket.metadata.json\"),',\n\t\t\t' path.join(repoRoot, \".resolveio-context\", \"email.metadata.json\"),',\n\t\t\t' path.join(projectRoot, \".resolveio-context\", \"email.metadata.json\")',\n\t\t\t' ];',\n\t\t\t' return files.map((file) => readJsonIfExists(file)).filter(Boolean);',\n\t\t\t'}',\n\t\t\t'',\n\t\t\t'function extractQaUserHints() {',\n\t\t\t' const affected = unique([',\n\t\t\t' process.env.RESOLVEIO_QA_AFFECTED_USER_EMAIL,',\n\t\t\t' process.env.RESOLVEIO_SUPPORT_QA_AFFECTED_USER_EMAIL,',\n\t\t\t' process.env.RESOLVEIO_RUNNER_QA_AFFECTED_USER_EMAIL',\n\t\t\t' ].map((value) => String(value || \"\").trim().toLowerCase()).filter(Boolean));',\n\t\t\t' const reporter = unique([',\n\t\t\t' process.env.RESOLVEIO_QA_TICKET_REPORTER_EMAIL,',\n\t\t\t' process.env.RESOLVEIO_SUPPORT_QA_TICKET_REPORTER_EMAIL,',\n\t\t\t' process.env.RESOLVEIO_RUNNER_QA_TICKET_REPORTER_EMAIL',\n\t\t\t' ].map((value) => String(value || \"\").trim().toLowerCase()).filter(Boolean));',\n\t\t\t' const explicitQa = unique([',\n\t\t\t' process.env.RESOLVEIO_QA_USERNAME,',\n\t\t\t' process.env.RESOLVEIO_SUPPORT_QA_USERNAME,',\n\t\t\t' process.env.RESOLVEIO_RUNNER_QA_USERNAME',\n\t\t\t' ].map((value) => String(value || \"\").trim().toLowerCase()).filter((value) => value && !/^(admin|dev@resolveio\\\\.com)$/i.test(value)));',\n\t\t\t' const contextEmails = new Set();',\n\t\t\t' readContextJsonFiles().forEach((json) => collectEmailLikeValues(json, contextEmails));',\n\t\t\t' collectEmailLikeValues(readSeedHintText(), contextEmails);',\n\t\t\t' const candidates = unique([...affected, ...reporter, ...explicitQa, ...Array.from(contextEmails)]);',\n\t\t\t' return { affected, reporter, explicitQa, candidates: candidates.slice(0, 12) };',\n\t\t\t'}',\n\t\t\t'',\n\t\t\t'function qaUserLookupQuery(candidates) {',\n\t\t\t' const ors = [];',\n\t\t\t' for (const candidate of candidates || []) {',\n\t\t\t' const value = String(candidate || \"\").trim();',\n\t\t\t' if (!value) continue;',\n\t\t\t' ors.push({ username: value }, { email: value }, { \"emails.address\": value });',\n\t\t\t' }',\n\t\t\t' return ors.length ? { $or: ors } : null;',\n\t\t\t'}',\n\t\t\t'',\n\t\t\t'function normalizeSeededQaUser(doc, password) {',\n\t\t\t' const now = new Date();',\n\t\t\t' const next = { ...(doc || {}) };',\n\t\t\t' const other = next.other && typeof next.other === \"object\" ? next.other : {};',\n\t\t\t' const settings = next.settings && typeof next.settings === \"object\" ? next.settings : {};',\n\t\t\t' next.active = true;',\n\t\t\t' next.readonly = false;',\n\t\t\t' next.other = { ...other, tour_completed: true, took_tour: true, core_tour_completed: true, welcome_tour_completed: true, top_navigation_tour_completed: true, user_settings_tour_completed: true };',\n\t\t\t' next.settings = { ...settings, collapsable_menu: false };',\n\t\t\t' next.updatedAt = now;',\n\t\t\t' if (password) {',\n\t\t\t' const salt = crypto.randomBytes(32).toString(\"hex\");',\n\t\t\t' next.salt = salt;',\n\t\t\t' next.hash = crypto.pbkdf2Sync(password, salt, 25000, 512, \"sha256\").toString(\"hex\");',\n\t\t\t' if (next.services && typeof next.services === \"object\" && next.services.password) delete next.services.password;',\n\t\t\t' next.attempts = 0;',\n\t\t\t' }',\n\t\t\t' return next;',\n\t\t\t'}',\n\t\t\t'',\n\t\t\t'async function copyQaIdentityUsers(sourceDb, targetDb, summary) {',\n\t\t\t' const hints = extractQaUserHints();',\n\t\t\t' summary.selected.qa_user_hints = hints;',\n\t\t\t' const query = qaUserLookupQuery(hints.candidates);',\n\t\t\t' if (!query) return [];',\n\t\t\t' const users = await sourceDb.collection(\"users\").find(query).limit(8).toArray();',\n\t\t\t' if (!users.length) {',\n\t\t\t' summary.notes.push(`No live user matched QA identity hints: ${hints.candidates.join(\", \")}`);',\n\t\t\t' return [];',\n\t\t\t' }',\n\t\t\t' const password = process.env.RESOLVEIO_RUNNER_QA_PASSWORD || process.env.RESOLVEIO_SUPPORT_QA_PASSWORD || \"\";',\n\t\t\t' for (const user of users) {',\n\t\t\t' const normalized = normalizeSeededQaUser(user, password);',\n\t\t\t' await targetDb.collection(\"users\").replaceOne({ _id: normalized._id }, normalized, { upsert: true });',\n\t\t\t' }',\n\t\t\t' summary.collections.users = (summary.collections.users || 0) + users.length;',\n\t\t\t' const preferred = users.find((user) => hints.affected.includes(String(user.email || user.username || \"\").toLowerCase()))',\n\t\t\t' || users.find((user) => hints.reporter.includes(String(user.email || user.username || \"\").toLowerCase()))',\n\t\t\t' || users[0];',\n\t\t\t' summary.selected.qa_user_context = {',\n\t\t\t' preferred_username: String(preferred && (preferred.email || preferred.username) || \"\").trim(),',\n\t\t\t' preferred_email: String(preferred && preferred.email || \"\").trim(),',\n\t\t\t' preferred_user_id: String(preferred && preferred._id || \"\").trim(),',\n\t\t\t' affected_user_email: hints.affected[0] || \"\",',\n\t\t\t' reporter_email: hints.reporter[0] || \"\",',\n\t\t\t' copied_user_ids: users.map((user) => String(user && user._id || \"\")).filter(Boolean),',\n\t\t\t' reason: hints.affected.length ? \"affected_user\" : (hints.reporter.length ? \"ticket_reporter\" : \"context_email\")',\n\t\t\t' };',\n\t\t\t' summary.notes.push(`Seeded ${users.length} live QA identity user(s); preferred browser QA user is ${summary.selected.qa_user_context.preferred_username || summary.selected.qa_user_context.preferred_user_id}.`);',\n\t\t\t' return users;',\n\t\t\t'}',\n\t\t\t'',\n\t\t\t'function readSeedHintText() {',\n\t\t' const chunks = [',\n\t\t' process.env.RESOLVEIO_SUPPORT_QA_ROW_FILTER || \"\",',\n\t\t' process.env.RESOLVEIO_SUPPORT_QA_CURRENT_ROW_WORKFLOW || \"\",',\n\t\t' process.env.RESOLVEIO_SUPPORT_QA_CURRENT_ROW_ASSERTION || \"\",',\n\t\t' process.env.RESOLVEIO_RUNNER_QA_ROW_FILTER || \"\",',\n\t\t' process.env.RESOLVEIO_RUNNER_QA_CURRENT_ROW_WORKFLOW || \"\",',\n\t\t' process.env.RESOLVEIO_RUNNER_QA_CURRENT_ROW_ASSERTION || \"\",',\n\t\t' process.env.RESOLVEIO_QA_SEED_HINTS || \"\",',\n\t\t' process.env.RESOLVEIO_SUPPORT_QA_SEED_HINTS || \"\",',\n\t\t' process.env.RESOLVEIO_RUNNER_QA_SEED_HINTS || \"\"',\n\t\t' ];',\n\t\t' const candidates = [',\n\t\t' path.join(artifactDir, \"qa-coverage-matrix.json\"),',\n\t\t' path.join(artifactDir, \"qa-row-lock.json\"),',\n\t\t' path.join(repoRoot, \".resolveio-support-context\", \"manual-ticket.request.txt\"),',\n\t\t' path.join(projectRoot, \".resolveio-support-context\", \"manual-ticket.request.txt\"),',\n\t\t' path.join(repoRoot, \".resolveio-context\", \"manual-ticket.request.txt\"),',\n\t\t' path.join(projectRoot, \".resolveio-context\", \"manual-ticket.request.txt\")',\n\t\t' ];',\n\t\t' for (const candidate of candidates) {',\n\t\t' try {',\n\t\t' const raw = fs.readFileSync(candidate, \"utf8\");',\n\t\t' chunks.push(raw);',\n\t\t' if (/qa-coverage-matrix\\\\.json$/.test(candidate)) {',\n\t\t' const matrix = JSON.parse(raw);',\n\t\t' const rows = Array.isArray(matrix && matrix.rows) ? matrix.rows : [];',\n\t\t' for (const row of rows) chunks.push([row.workflow, row.route, row.assertion, row.required_proof, row.data_id, row.data_name, row.blocker, row.evidence, row.caption].filter(Boolean).join(\"\\\\n\"));',\n\t\t' }',\n\t\t' if (/qa-row-lock\\\\.json$/.test(candidate)) {',\n\t\t' const lock = JSON.parse(raw);',\n\t\t' chunks.push([lock.workflow, lock.route, lock.assertion, lock.required_proof, lock.rowFilter, lock.blocker].filter(Boolean).join(\"\\\\n\"));',\n\t\t' }',\n\t\t' } catch (error) {}',\n\t\t' }',\n\t\t' return chunks.filter(Boolean).join(\"\\\\n\");',\n\t\t'}',\n\t\t'',\n\t\t'function isUsefulSeedIdentifier(value) {',\n\t\t' const cleaned = String(value || \"\").trim().replace(/^[#:\\\\-]+|[.,;:)\\\\]]+$/g, \"\");',\n\t\t' if (!cleaned) return false;',\n\t\t' if (/^00?4\\\\d{3}$/.test(cleaned)) return false;',\n\t\t' if (/^(screen|tab|are|which|and|render|context|workflow|build|snapshot|state|charge|plan|data|document|delivery|deliveries)$/i.test(cleaned)) return false;',\n\t\t' return /\\\\d/.test(cleaned) || /^[A-Z][A-Z0-9._-]{3,}$/.test(cleaned);',\n\t\t'}',\n\t\t'',\n\t'function extractBolIdentifiers() {',\n\t\t' const text = readSeedHintText();',\n\t\t' const identifiers = new Set();',\n\t\t' const explicit = /\\\\bBOL\\\\s*(?:#|no\\\\.?|number|num)?\\\\s*[:#-]?\\\\s*([A-Z0-9][A-Z0-9._-]{2,})\\\\b/gi;',\n\t\t' let match;',\n\t\t' while ((match = explicit.exec(text)) !== null) {',\n\t\t' const value = String(match[1] || \"\").trim();',\n\t\t' if (isUsefulSeedIdentifier(value)) identifiers.add(value);',\n\t\t' }',\n\t' return Array.from(identifiers).slice(0, 8);',\n\t'}',\n\t'',\n\t\t'function shouldAutoDiscoverTruckTreatingBolContext() {',\n\t\t' const text = readSeedHintText();',\n\t\t' return /\\\\b(bol|bill\\\\s+of\\\\s+lading|truck\\\\s*treat(?:ing)?|truck-treating|deliver(?:y|ed|ies)?\\\\s+BOL)\\\\b/i.test(text);',\n\t\t'}',\n\t\t'',\n\t\t'function shouldAutoDiscoverAssetContext() {',\n\t\t' const text = readSeedHintText();',\n\t\t' return /\\\\b(asset|assets|unit|units|equipment|current\\\\s+location|location\\\\s+name|location\\\\s+names|default\\\\s+yard|yard)\\\\b/i.test(text);',\n\t\t'}',\n\t\t'',\n\t\t'function shouldAutoDiscoverProductionInterchangeablesContext() {',\n\t\t' const text = readSeedHintText();',\n\t\t' return /\\\\b(interchangeable|interchangeables|mass\\\\s+update|update\\\\s+interchangeables|from\\\\s+chemical|to\\\\s+chemical|treatment\\\\s+plan|treatment\\\\s+plans|production\\\\s+location)\\\\b/i.test(text);',\n\t\t'}',\n\t\t'',\n\t\t'function extractAssetIdentifiers() {',\n\t\t' const text = readSeedHintText();',\n\t\t' const identifiers = new Set();',\n\t\t' const explicit = /\\\\b(?:asset|unit|equipment)\\\\s*(?:#|no\\\\.?|number|num)?\\\\s*[:#-]?\\\\s*([A-Z0-9][A-Z0-9._-]{1,})\\\\b/gi;',\n\t\t' let match;',\n\t\t' while ((match = explicit.exec(text)) !== null) {',\n\t\t' const value = String(match[1] || \"\").trim();',\n\t\t' if (isUsefulSeedIdentifier(value)) identifiers.add(value);',\n\t\t' }',\n\t\t' const typedUnit = /\\\\b(?:truck|trailer|unit|asset)\\\\s+([A-Z0-9][A-Z0-9._-]{1,})\\\\b/gi;',\n\t\t' while ((match = typedUnit.exec(text)) !== null) {',\n\t\t' const value = String(match[1] || \"\").trim();',\n\t\t' if (isUsefulSeedIdentifier(value)) identifiers.add(value);',\n\t\t' }',\n\t\t' if (shouldAutoDiscoverAssetContext()) extractSeedIdentifiers().forEach((value) => identifiers.add(value));',\n\t\t' return Array.from(identifiers).slice(0, 20);',\n\t\t'}',\n\t\t'',\n\t\t'function extractRouteNameHints() {',\n\t\t' const text = readSeedHintText();',\n\t\t' const routes = new Set();',\n\t\t' const routePattern = /\\\\b(?:on|for)\\\\s+(?:the\\\\s+)?([A-Za-z0-9][A-Za-z0-9 &._/-]{1,48}?)\\\\s+route\\\\b/gi;',\n\t\t' let match;',\n\t\t' while ((match = routePattern.exec(text)) !== null) {',\n\t\t' const routeName = String(match[1] || \"\").trim().replace(/^(?:the|a|an)\\\\s+/i, \"\").replace(/\\\\s+/g, \" \");',\n\t\t' if (routeName && !/^(?:this|that|selected)$/i.test(routeName)) routes.add(routeName);',\n\t\t' }',\n\t\t' return Array.from(routes).slice(0, 8);',\n\t\t'}',\n\t\t'',\n\t'function extractSeedIdentifiers() {',\n\t\t' const text = readSeedHintText();',\n\t\t' const identifiers = new Set();',\n\t\t' const explicit = /\\\\b(?:invoice|inv|bol|order|pso|ticket|wo|work\\\\s*order|delivery|treatment)\\\\s*(?:#|no\\\\.?|number|num)?\\\\s*[:#-]?\\\\s*([A-Z0-9][A-Z0-9._-]{2,})\\\\b/gi;',\n\t\t' let match;',\n\t\t' while ((match = explicit.exec(text)) !== null) identifiers.add(match[1]);',\n\t\t' const typedUnit = /\\\\b(?:truck|trailer|asset|unit)\\\\s+([A-Z0-9][A-Z0-9._-]{1,})\\\\b/gi;',\n\t\t' while ((match = typedUnit.exec(text)) !== null) identifiers.add(match[1]);',\n\t\t' const numeric = /\\\\b\\\\d{3,}\\\\b/g;',\n\t\t' while ((match = numeric.exec(text)) !== null) identifiers.add(match[0]);',\n\t\t' return Array.from(identifiers)',\n\t\t' .map((value) => String(value || \"\").trim())',\n\t\t' .filter((value) => isUsefulSeedIdentifier(value))',\n\t\t' .slice(0, 20);',\n\t\t'}',\n\t\t'',\n\t\t'function desiredSeedProfile() {',\n\t\t' if (shouldSeedPricingImportFixtures()) return \"pricing_import\";',\n\t\t' if (shouldSeedBillingDashboardFixtures()) return \"billing_inventory\";',\n\t\t' return \"live_context\";',\n\t\t'}',\n\t\t'',\n\t\t'function shouldSeedBillingDashboardFixtures() {',\n\t\t' const force = process.env.RESOLVEIO_QA_FORCE_BILLING_FIXTURES || process.env.RESOLVEIO_SUPPORT_QA_FORCE_BILLING_FIXTURES || process.env.RESOLVEIO_RUNNER_QA_FORCE_BILLING_FIXTURES || \"\";',\n\t\t' if (/^(true|1|yes|on)$/i.test(force)) return true;',\n\t\t' if (shouldSeedPricingImportFixtures()) return false;',\n\t\t' const explicit = process.env.RESOLVEIO_QA_INCLUDE_BILLING_FIXTURES || process.env.RESOLVEIO_SUPPORT_QA_INCLUDE_BILLING_FIXTURES || process.env.RESOLVEIO_RUNNER_QA_INCLUDE_BILLING_FIXTURES || \"\";',\n\t\t' if (/^(true|1|yes|on)$/i.test(explicit)) return true;',\n\t\t' if (/^(false|0|no|off)$/i.test(explicit)) return false;',\n\t\t' const text = readSeedHintText();',\n\t\t' return /\\\\b(invoice|invoicing|billing|billable|tax|taxes|surcharge|inventory|checkout|check\\\\s*out|pick\\\\s*ticket)\\\\b/i.test(text);',\n\t\t'}',\n\t\t'',\n\t\t'function shouldSeedPricingImportFixtures() {',\n\t\t' const explicit = process.env.RESOLVEIO_QA_INCLUDE_PRICING_IMPORT_FIXTURES || process.env.RESOLVEIO_SUPPORT_QA_INCLUDE_PRICING_IMPORT_FIXTURES || process.env.RESOLVEIO_RUNNER_QA_INCLUDE_PRICING_IMPORT_FIXTURES || \"\";',\n\t\t' if (/^(true|1|yes|on)$/i.test(explicit)) return true;',\n\t\t' if (/^(false|0|no|off)$/i.test(explicit)) return false;',\n\t\t' const text = readSeedHintText();',\n\t\t' const pricingSurface = /\\\\b(pricing|price|gross\\\\s+price|production\\\\s+price|manage\\\\s+pricing)\\\\b/i.test(text);',\n\t\t' const importSurface = /\\\\b(import|upload|template|spreadsheet|xlsx|excel|attached\\\\s+template)\\\\b/i.test(text);',\n\t\t' return pricingSurface && importSurface;',\n\t\t'}',\n\t\t'',\n\t\t'function identifierQuery(identifiers) {',\n\t\t' const ors = [];',\n\t\t' const fields = [\"_id\", \"invoice_number\", \"invoice_number_string\", \"order_number\", \"order_number_string\", \"activity_number\", \"bol_number\", \"bol_string\", \"ticket_number\", \"ticket\", \"wo_number\", \"work_order_number\", \"delivery_number\", \"treatment_number\"];',\n\t\t' for (const identifier of identifiers || []) {',\n\t\t' const escaped = String(identifier).replace(/[.*+?^${}()|[\\\\]\\\\\\\\]/g, \"\\\\\\\\$&\");',\n\t\t' const regex = new RegExp(escaped, \"i\");',\n\t\t' for (const field of fields) ors.push({ [field]: regex });',\n\t\t' ors.push({ \"bol.bol_string\": regex });',\n\t\t' ors.push({ \"bol.bol_number\": regex });',\n\t\t' }',\n\t\t' return ors.length ? { $or: ors } : null;',\n\t\t'}',\n\t\t'',\n\t\t'function assetLookupQuery(identifiers) {',\n\t\t' const ors = [];',\n\t\t' const fields = [\"_id\", \"asset_number\", \"asset_number_string\", \"asset_unit_number\", \"unit_number\", \"number\", \"serial_number\", \"name\"];',\n\t\t' for (const identifier of identifiers || []) {',\n\t\t' const value = String(identifier || \"\").trim();',\n\t\t' if (!value) continue;',\n\t\t' const escaped = value.replace(/[.*+?^${}()|[\\\\]\\\\\\\\]/g, \"\\\\\\\\$&\");',\n\t\t' const exactText = new RegExp(`^${escaped}$`, \"i\");',\n\t\t' const containsText = new RegExp(escaped, \"i\");',\n\t\t' for (const field of fields) ors.push({ [field]: exactText });',\n\t\t' for (const field of [\"asset_number_string\", \"asset_unit_number\", \"unit_number\", \"number\", \"serial_number\", \"name\"]) ors.push({ [field]: containsText });',\n\t\t' if (/^\\\\d+$/.test(value)) {',\n\t\t' const numericValue = Number(value);',\n\t\t' for (const field of [\"asset_number\", \"unit_number\", \"number\"]) ors.push({ [field]: numericValue });',\n\t\t' }',\n\t\t' }',\n\t\t' return ors.length ? { $or: ors } : null;',\n\t\t'}',\n\t\t'',\n\t\t'async function copyByIds(sourceDb, targetDb, collectionName, ids, summary, limit = 100) {',\n\t\t' const cleanIds = unique(ids).slice(0, limit);',\n\t\t' if (!cleanIds.length) return [];',\n\t\t' const docs = await sourceDb.collection(collectionName).find({ _id: { $in: cleanIds } }).limit(limit).toArray();',\n\t\t' for (const doc of docs) await targetDb.collection(collectionName).replaceOne({ _id: doc._id }, doc, { upsert: true });',\n\t\t' summary.collections[collectionName] = (summary.collections[collectionName] || 0) + docs.length;',\n\t\t' return docs;',\n\t\t'}',\n\t\t'',\n\t\t'async function copyQuery(sourceDb, targetDb, collectionName, query, summary, limit = 50, sort = null) {',\n\t\t' let cursor = sourceDb.collection(collectionName).find(query || {});',\n\t\t' if (sort) cursor = cursor.sort(sort);',\n\t\t' const docs = await cursor.limit(limit).toArray();',\n\t\t' for (const doc of docs) await targetDb.collection(collectionName).replaceOne({ _id: doc._id }, doc, { upsert: true });',\n\t\t' summary.collections[collectionName] = (summary.collections[collectionName] || 0) + docs.length;',\n\t\t' return docs;',\n\t\t'}',\n\t\t'',\n\t'function bolLookupQuery(identifiers) {',\n\t\t' const ors = [];',\n\t\t' for (const identifier of identifiers || []) {',\n\t\t' const value = String(identifier || \"\").trim();',\n\t\t' if (!value) continue;',\n\t\t' const escaped = value.replace(/[.*+?^${}()|[\\\\]\\\\\\\\]/g, \"\\\\\\\\$&\");',\n\t\t' const contains = new RegExp(`(^|[^0-9A-Za-z])${escaped}([^0-9A-Za-z]|$)`, \"i\");',\n\t\t' ors.push({ _id: value }, { bol_number: value }, { bol_string: value }, { bol_number: contains }, { bol_string: contains });',\n\t\t' if (/^\\\\d+$/.test(value)) ors.push({ bol_number: Number(value) });',\n\t\t' }',\n\t' return ors.length ? { $or: ors } : null;',\n\t'}',\n\t'',\n\t'async function discoverTruckTreatingBolIds(sourceDb, routeHints, limit = 5) {',\n\t' const routeRegexes = (routeHints || []).map((hint) => new RegExp(String(hint).replace(/[.*+?^${}()|[\\\\]\\\\\\\\]/g, \"\\\\\\\\$&\"), \"i\"));',\n\t' const routeHintMatch = routeRegexes.length ? { $or: [',\n\t' { location: { $in: routeRegexes } },',\n\t' { well_group: { $in: routeRegexes } },',\n\t' { route: { $in: routeRegexes } },',\n\t' { route_name: { $in: routeRegexes } }',\n\t' ] } : null;',\n\t' const baseMatch = {',\n\t' id_bol: { $type: \"string\", $ne: \"\" },',\n\t' items: { $elemMatch: { item_type: { $in: [\"Service\", \"Flush\"] } } }',\n\t' };',\n\t' const pipeline = [',\n\t' { $match: routeHintMatch ? { $and: [baseMatch, routeHintMatch] } : baseMatch },',\n\t' { $sort: { date: -1, date_ship: -1, updatedAt: -1 } },',\n\t' { $group: { _id: \"$id_bol\", route_count: { $sum: 1 }, latest: { $max: \"$updatedAt\" } } },',\n\t' { $sort: { latest: -1, route_count: -1 } },',\n\t' { $limit: limit },',\n\t' { $project: { _id: 1 } }',\n\t' ];',\n\t' const rows = await sourceDb.collection(\"production-routes\").aggregate(pipeline).toArray();',\n\t' return rows.map((row) => row && row._id).filter(Boolean);',\n\t'}',\n\t'',\n\t\t'function collectNestedStringValues(docs, keys) {',\n\t\t' const values = new Set();',\n\t\t' const visit = (value) => {',\n\t\t' if (!value) return;',\n\t\t' if (Array.isArray(value)) { value.forEach(visit); return; }',\n\t\t' if (typeof value === \"object\") {',\n\t\t' for (const key of keys) {',\n\t\t' const entry = value[key];',\n\t\t' if (typeof entry === \"string\" && entry.trim()) values.add(entry.trim());',\n\t\t' else if (Array.isArray(entry) || (entry && typeof entry === \"object\")) visit(entry);',\n\t\t' }',\n\t\t' for (const nested of Object.values(value)) if (Array.isArray(nested)) visit(nested);',\n\t\t' }',\n\t\t' };',\n\t\t' visit(docs || []);',\n\t\t' return Array.from(values);',\n\t\t'}',\n\t\t'',\n\t'async function copyTruckTreatingBolContext(sourceDb, targetDb, summary) {',\n\t' const bolIdentifiers = extractBolIdentifiers();',\n\t' const routeHints = extractRouteNameHints();',\n\t' summary.selected.bol_identifiers = bolIdentifiers;',\n\t' if (routeHints.length) summary.selected.route_name_hints = routeHints;',\n\t' let query = bolLookupQuery(bolIdentifiers);',\n\t' let discoveryMode = \"\";',\n\t' if (!query && shouldAutoDiscoverTruckTreatingBolContext()) {',\n\t' const discoveredBolIds = await discoverTruckTreatingBolIds(sourceDb, routeHints, 8);',\n\t' if (discoveredBolIds.length) {',\n\t' summary.selected.discovered_truck_treating_bol_ids = discoveredBolIds;',\n\t' query = { _id: { $in: discoveredBolIds } };',\n\t' discoveryMode = \"auto_discovered_from_live_production_routes\";',\n\t' }',\n\t' }',\n\t' if (!query) return [];',\n\t' let bols = await copyQuery(sourceDb, targetDb, \"bols\", query, summary, 8, { date_shipped: -1, date: -1, updatedAt: -1 });',\n\t' if (!bols.length) {',\n\t' summary.notes.push(`No live BOL matched ticket BOL identifiers: ${bolIdentifiers.join(\", \")}`);',\n\t' if (shouldAutoDiscoverTruckTreatingBolContext()) {',\n\t' const discoveredBolIds = await discoverTruckTreatingBolIds(sourceDb, routeHints, 8);',\n\t' if (discoveredBolIds.length) {',\n\t' summary.selected.discovered_truck_treating_bol_ids = discoveredBolIds;',\n\t' discoveryMode = \"auto_discovered_after_identifier_miss\";',\n\t' bols = await copyQuery(sourceDb, targetDb, \"bols\", { _id: { $in: discoveredBolIds } }, summary, 8, { date_shipped: -1, date: -1, updatedAt: -1 });',\n\t' }',\n\t' }',\n\t' if (!bols.length) return [];',\n\t' }',\n\t\t' const bolIds = bols.map((doc) => doc._id).filter(Boolean);',\n\t\t' const productionRoutes = await copyQuery(sourceDb, targetDb, \"production-routes\", { id_bol: { $in: bolIds } }, summary, 600, { route_order: 1, route_number: 1 });',\n\t\t' const routeIds = productionRoutes.map((doc) => doc._id).filter(Boolean);',\n\t\t' const truckTreatingRouteIds = idValues(productionRoutes, [\"id_truck_treating_route\"]);',\n\t\t' const productionSalesOrderIds = idValues(productionRoutes, [\"id_pso\", \"id_activity\", \"id_production_sales_order\", \"id_sales_order\"]);',\n\t\t' const productionDeliveries = await copyQuery(sourceDb, targetDb, \"production-deliveries\", { $or: [{ id_bol: { $in: bolIds } }, { id_activity: { $in: productionSalesOrderIds } }] }, summary, 600, { route_order: 1, updatedAt: -1 });',\n\t\t' const routeTruckTreatDeliveryIds = collectNestedStringValues(productionRoutes, [\"id_truck_treat_delivery\", \"id_truck_treating_delivery\"]);',\n\t\t' const truckTreatingDeliveries = await copyQuery(sourceDb, targetDb, \"truck-treating-deliveries\", { $or: [{ id_bol: { $in: bolIds } }, { _id: { $in: routeTruckTreatDeliveryIds } }] }, summary, 600, { route_order: 1, updatedAt: -1 });',\n\t\t' const copiedTruckTreatingRoutes = await copyByIds(sourceDb, targetDb, \"truck-treating-routes\", truckTreatingRouteIds, summary, 200);',\n\t\t' await copyByIds(sourceDb, targetDb, \"production-sales-orders\", productionSalesOrderIds, summary, 200);',\n\t\t' const locationIds = unique([...idValues(productionRoutes, [\"id_location\"]), ...idValues(productionDeliveries, [\"id_location\"]), ...idValues(truckTreatingDeliveries, [\"id_location\"])]);',\n\t\t' const wellGroupIds = unique([...idValues(productionRoutes, [\"id_well_group\"]), ...idValues(productionDeliveries, [\"id_well_group\"]), ...idValues(truckTreatingDeliveries, [\"id_well_group\"])]);',\n\t\t' const copiedLocations = await copyByIds(sourceDb, targetDb, \"production-locations\", locationIds, summary, 300);',\n\t\t' const copiedWellGroups = await copyByIds(sourceDb, targetDb, \"well-groups\", wellGroupIds, summary, 300);',\n\t\t' const copiedTreatmentPlans = await copyQuery(sourceDb, targetDb, \"treatment-plans\", { $or: [',\n\t\t' { \"truck_treating.id_truck_treating_route\": { $in: truckTreatingRouteIds } },',\n\t\t' { id_location: { $in: locationIds } },',\n\t\t' { id_well_group: { $in: wellGroupIds } }',\n\t\t' ] }, summary, 800, { route_order: 1, updatedAt: -1 });',\n\t\t' const itemIds = unique([',\n\t\t' ...collectNestedStringValues(productionRoutes, [\"id_item\", \"id_chemical\"]),',\n\t\t' ...idValues(productionDeliveries, [\"id_item\", \"id_chemical\"]),',\n\t\t' ...idValues(truckTreatingDeliveries, [\"id_item\", \"id_chemical\"]),',\n\t\t' ...idValues(copiedTreatmentPlans, [\"id_item\", \"id_chemical\"])',\n\t\t' ]);',\n\t\t' await copyByIds(sourceDb, targetDb, \"items\", itemIds, summary, 300);',\n\t\t' await copyByIds(sourceDb, targetDb, \"chemicals\", itemIds, summary, 300);',\n\t\t' await copyByIds(sourceDb, targetDb, \"customers\", unique([...idValues(copiedLocations, [\"id_customer\"]), ...idValues(copiedWellGroups, [\"id_customer\"]), ...idValues(productionDeliveries, [\"id_customer\"]), ...idValues(truckTreatingDeliveries, [\"id_customer\"])]), summary, 100);',\n\t\t' await copyByIds(sourceDb, targetDb, \"users\", unique([...idValues(bols, [\"id_user\", \"id_driver\"]), ...idValues(productionDeliveries, [\"id_user_approved\", \"id_driver\", \"id_driver_scheduled\", \"id_account_manager\", \"id_foreman\"])]), summary, 100);',\n\t\t' await copyQuery(sourceDb, targetDb, \"chemical-field-transfers\", { id_bol: { $in: bolIds } }, summary, 200, { updatedAt: -1 });',\n\t\t' await copyQuery(sourceDb, targetDb, \"generic-samples\", { id_bol: { $in: bolIds } }, summary, 200, { updatedAt: -1 });',\n\t\t' const linkedRouteNames = copiedTruckTreatingRoutes.map((doc) => String(doc.name || doc.route || doc.truck_treating_route || doc._id || \"\")).filter(Boolean);',\n\t\t' const routeHintMatched = routeHints.length ? routeHints.some((hint) => linkedRouteNames.some((name) => name.toLowerCase().includes(hint.toLowerCase()))) : null;',\n\t\t' const driverIds = unique([...idValues(bols, [\"id_driver\", \"id_user\"]), ...idValues(productionDeliveries, [\"id_driver\", \"id_driver_scheduled\", \"id_user_approved\"]), ...idValues(truckTreatingDeliveries, [\"id_driver\", \"id_driver_scheduled\", \"id_user_approved\"])]);',\n\t\t' const bolStatuses = bols.map((doc) => ({',\n\t\t' id: String(doc && doc._id || \"\"),',\n\t\t' bol_number: String(doc && (doc.bol_string || doc.bol_number || \"\") || \"\"),',\n\t\t' status: String(doc && doc.status || \"\"),',\n\t\t' delivered: /delivered/i.test(String(doc && doc.status || \"\"))',\n\t\t' })).filter((entry) => entry.id);',\n\t\t' const primaryDriverId = driverIds[0] || \"\";',\n\t\t' const primaryBolId = bolIds[0] || \"\";',\n\t\t' const primaryBolStatus = String((bolStatuses.find((entry) => entry.id === primaryBolId) || bolStatuses[0] || {}).status || \"\");',\n\t\t' const primaryBolDelivered = /delivered/i.test(primaryBolStatus);',\n\t\t' const browserRoutes = primaryDriverId && primaryBolId ? {',\n\t\t' delivery: `/dashboard/driver/truck-treating/bol-delivery/${primaryDriverId}/${primaryBolId}`,',\n\t\t' detail: `/dashboard/driver/truck-treating/bol-detail/${primaryDriverId}/${primaryBolId}`,',\n\t\t' list: `/dashboard/driver/truck-treating/bol-list/${primaryDriverId}`',\n\t\t' } : {};',\n\t\t' summary.selected.truck_treating_bol_context = {',\n\t\t' bol_ids: bolIds,',\n\t\t' driver_ids: driverIds,',\n\t\t' route_ids: routeIds.slice(0, 100),',\n\t\t' route_count: productionRoutes.length,',\n\t\t' truck_treating_route_ids: truckTreatingRouteIds,',\n\t\t' linked_truck_treating_routes: linkedRouteNames,',\n\t\t' browser_routes: browserRoutes,',\n\t\t' bol_statuses: bolStatuses,',\n\t\t' primary_bol_status: primaryBolStatus,',\n\t\t' primary_bol_delivered: primaryBolDelivered,',\n\t\t' delivery_route_is_action_route: true,',\n\t\t' delivery_route_requires_not_delivered_bol: true,',\n\t\t' route_name_hints: routeHints,',\n\t' route_hint_matched: routeHintMatched',\n\t' };',\n\t' if (discoveryMode) summary.selected.truck_treating_bol_context.discovery_mode = discoveryMode;',\n\t\t' if (browserRoutes.delivery) summary.notes.push(`Derived truck-treating BOL browser target from live Mongo: ${browserRoutes.delivery}`);',\n\t\t' else summary.notes.push(\"Could not derive truck-treating BOL browser route because live BOL context did not include both id_driver and id_bol.\");',\n\t\t' if (primaryBolDelivered) summary.notes.push(`Live BOL ${primaryBolId} is already Delivered; direct bol-delivery route is an action route and may correctly redirect. QA should use delivered Open File/detail proof or create a localhost-only deliverable fixture from the fetched live context before testing Treat/Deliver actions.`);',\n\t\t' if (routeHints.length && routeHintMatched === false) summary.notes.push(`Ticket route hint(s) ${routeHints.join(\", \")} did not match linked live BOL route(s): ${linkedRouteNames.join(\", \") || \"none\"}. QA should use linked live BOL routes and report the mismatch as data evidence, not synthesize a route.`);',\n\t\t' summary.notes.push(`Seeded live truck-treating BOL context for ${bolIdentifiers.join(\", \")}: ${bols.length} BOL(s), ${productionRoutes.length} production route(s), ${copiedTreatmentPlans.length} treatment plan(s).`);',\n\t' return [...bols, ...productionRoutes, ...productionDeliveries, ...truckTreatingDeliveries, ...copiedTreatmentPlans];',\n\t'}',\n\t'',\n\t'async function copyProductionInterchangeablesContext(sourceDb, targetDb, summary) {',\n\t' if (!shouldAutoDiscoverProductionInterchangeablesContext()) return [];',\n\t' const interchangeables = await copyQuery(sourceDb, targetDb, \"chemical-interchangeables\", { \"id_chemicals.1\": { $exists: true } }, summary, 12, { updatedAt: -1 });',\n\t' if (!interchangeables.length) {',\n\t' summary.notes.push(\"No live chemical-interchangeables records with multiple chemicals were available for Update Interchangeables QA.\");',\n\t' return [];',\n\t' }',\n\t' const chemicalIds = unique(idValues(interchangeables, [\"id_chemicals\"]));',\n\t' const chemicals = await copyQuery(sourceDb, targetDb, \"chemicals\", { _id: { $in: chemicalIds }, types: \"Finished Good\" }, summary, 80, { name: 1 });',\n\t' const usableChemicalIds = unique(chemicals.map((doc) => doc._id));',\n\t' const items = await copyQuery(sourceDb, targetDb, \"items\", { $or: [{ id_chemical: { $in: usableChemicalIds } }, { _id: { $in: usableChemicalIds } }] }, summary, 120, { name: 1 });',\n\t' const itemIds = unique(items.map((doc) => doc._id));',\n\t' let treatmentPlans = await copyQuery(sourceDb, targetDb, \"treatment-plans\", { date_end: null, $or: [{ id_chemical: { $in: usableChemicalIds } }, { id_item: { $in: itemIds } }] }, summary, 120, { updatedAt: -1 });',\n\t' if (!treatmentPlans.length && usableChemicalIds.length) {',\n\t' treatmentPlans = await copyQuery(sourceDb, targetDb, \"treatment-plans\", { date_end: null, id_chemical: usableChemicalIds[0] }, summary, 40, { updatedAt: -1 });',\n\t' }',\n\t' const customerIds = unique(idValues(treatmentPlans, [\"id_customer\"]));',\n\t' const yardIds = unique(idValues(treatmentPlans, [\"id_yard\"]));',\n\t' const locationIds = unique(idValues(treatmentPlans, [\"id_location\"]));',\n\t' const wellGroupIds = unique(idValues(treatmentPlans, [\"id_well_group\"]));',\n\t' const tankIds = unique(collectNestedStringValues(treatmentPlans, [\"id_tank\"]));',\n\t' await copyByIds(sourceDb, targetDb, \"customers\", customerIds, summary, 80);',\n\t' await copyByIds(sourceDb, targetDb, \"yards\", yardIds, summary, 80);',\n\t' await copyByIds(sourceDb, targetDb, \"production-locations\", locationIds, summary, 120);',\n\t' await copyByIds(sourceDb, targetDb, \"well-groups\", wellGroupIds, summary, 120);',\n\t' await copyByIds(sourceDb, targetDb, \"production-location-tanks\", tankIds, summary, 120);',\n\t' if (yardIds.length) {',\n\t' const users = await targetDb.collection(\"users\").find({}).project({ _id: 1, other: 1 }).limit(50).toArray().catch(() => []);',\n\t' for (const user of users) {',\n\t' const other = user && typeof user.other === \"object\" && user.other ? user.other : {};',\n\t' const nextYards = unique([...(Array.isArray(other.yards) ? other.yards : []), ...yardIds]);',\n\t' await targetDb.collection(\"users\").updateOne({ _id: user._id }, { $set: { \"other.yards\": nextYards } });',\n\t' }',\n\t' if (users.length) summary.notes.push(`Added seeded Update Interchangeables yard ids to ${users.length} local QA user(s) so treatment-plan filters can return data.`);',\n\t' }',\n\t' summary.selected.qa_production_interchangeables_context = {',\n\t' interchangeable_ids: interchangeables.map((doc) => doc._id).filter(Boolean),',\n\t' chemical_ids: usableChemicalIds,',\n\t' item_ids: itemIds,',\n\t' treatment_plan_ids: treatmentPlans.map((doc) => doc._id).filter(Boolean),',\n\t' customer_ids: customerIds,',\n\t' yard_ids: yardIds,',\n\t' tank_ids: tankIds,',\n\t' browser_routes: { update_interchangeables: \"/production-location/update-interchangeables\" }',\n\t' };',\n\t' summary.notes.push(`Seeded Update Interchangeables context: ${interchangeables.length} interchangeable group(s), ${chemicals.length} chemical(s), ${items.length} active item(s), ${treatmentPlans.length} treatment plan(s).`);',\n\t' return [...interchangeables, ...chemicals, ...items, ...treatmentPlans];',\n\t'}',\n\t'',\n\t\t'async function copyTicketAssetContext(sourceDb, targetDb, summary) {',\n\t\t' if (!shouldAutoDiscoverAssetContext()) return [];',\n\t\t' const assetIdentifiers = extractAssetIdentifiers();',\n\t\t' summary.selected.asset_identifiers = assetIdentifiers;',\n\t\t' const query = assetLookupQuery(assetIdentifiers);',\n\t\t' if (!query) return [];',\n\t\t' const assets = await copyQuery(sourceDb, targetDb, \"assets\", query, summary, 20, { updatedAt: -1, asset_number: 1 });',\n\t\t' if (!assets.length) {',\n\t\t' summary.notes.push(`No live assets matched ticket identifiers: ${assetIdentifiers.join(\", \")}`);',\n\t\t' return [];',\n\t\t' }',\n\t\t' const yardIds = unique([',\n\t\t' ...idValues(assets, [\"id_yard\", \"id_default_yard\"]),',\n\t\t' ...collectNestedStringValues(assets, [\"id\", \"id_yard\"])',\n\t\t' ]);',\n\t\t' const locationIds = unique([',\n\t\t' ...idValues(assets, [\"id_location\", \"id_current_location\", \"id_default_location\"]),',\n\t\t' ...collectNestedStringValues(assets, [\"id_location\"])',\n\t\t' ]);',\n\t\t' const userIds = unique([',\n\t\t' ...idValues(assets, [\"id_user\", \"id_driver\", \"id_created_by\", \"id_updated_by\"]),',\n\t\t' ...collectNestedStringValues(assets, [\"id_user\", \"id_driver\", \"id_created_by\", \"id_updated_by\"])',\n\t\t' ]);',\n\t\t' await copyByIds(sourceDb, targetDb, \"yards\", yardIds, summary, 100);',\n\t\t' await copyByIds(sourceDb, targetDb, \"production-locations\", locationIds, summary, 100);',\n\t\t' await copyByIds(sourceDb, targetDb, \"users\", userIds, summary, 100);',\n\t\t' const assetIds = assets.map((doc) => doc._id).filter(Boolean);',\n\t\t' const assetNumbers = assets.map((doc) => String(doc.asset_number || doc.asset_number_string || doc.asset_unit_number || doc.unit_number || \"\")).filter(Boolean);',\n\t\t' summary.selected.qa_asset_context = {',\n\t\t' asset_ids: assetIds,',\n\t\t' asset_numbers: assetNumbers,',\n\t\t' yard_ids: yardIds,',\n\t\t' production_location_ids: locationIds,',\n\t\t' browser_routes: assetIds[0] ? { list: \"/asset/list\", detail: `/asset/detail/${assetIds[0]}`, edit: `/asset/edit/${assetIds[0]}` } : { list: \"/asset/list\" }',\n\t\t' };',\n\t\t' summary.notes.push(`Seeded live asset context for ${assetIdentifiers.join(\", \")}: ${assets.length} asset(s), ${yardIds.length} yard id(s), ${locationIds.length} production location id(s).`);',\n\t\t' return assets;',\n\t\t'}',\n\t\t'',\n\t\t'async function ensureBillingSurchargePricingFixtures(targetDb, summary, serviceItems, customerIds) {',\n\t\t' const now = new Date();',\n\t\t' const activeServiceItems = (serviceItems || []).filter((doc) => {',\n\t\t' const typeText = String(doc && (doc.type || doc.category || doc.name || \"\") || \"\");',\n\t\t' return doc && doc._id && doc.active !== false && /misc|service|surcharge|fuel|delivery/i.test(typeText);',\n\t\t' });',\n\t\t' const fixtureItems = [];',\n\t\t' if (!activeServiceItems.length) {',\n\t\t' fixtureItems.push(',\n\t\t' { _id: \"qa-misc-surcharge-item\", name: \"QA Misc Surcharge\", description: \"QA Misc Surcharge\", type: \"Misc\", unit: \"Each\", active: true, createdAt: now, updatedAt: now },',\n\t\t' { _id: \"qa-service-surcharge-item\", name: \"QA Service Surcharge\", description: \"QA Service Surcharge\", type: \"Service\", unit: \"Each\", active: true, createdAt: now, updatedAt: now }',\n\t\t' );',\n\t\t' for (const item of fixtureItems) await targetDb.collection(\"items\").replaceOne({ _id: item._id }, item, { upsert: true });',\n\t\t' summary.collections.items = (summary.collections.items || 0) + fixtureItems.length;',\n\t\t' summary.notes.push(\"Created localhost-only active service/misc surcharge item fixtures because the bounded live slice did not include one.\");',\n\t\t' }',\n\t\t' const usableItems = activeServiceItems.length ? activeServiceItems : fixtureItems;',\n\t\t' const pricingDocs = [];',\n\t\t' for (const item of usableItems.slice(0, 4)) {',\n\t\t' const label = String(item.name || item.description || item._id || \"QA Surcharge\");',\n\t\t' const subtype = /service/i.test(String(item.type || label)) ? \"service\" : \"misc\";',\n\t\t' pricingDocs.push({',\n\t\t' _id: `qa-pricing-${subtype}-${String(item._id).replace(/[^a-z0-9_-]/gi, \"-\")}-global`,',\n\t\t' id_item: item._id, name: label, description: label, unit: item.unit || \"Each\", active: true, type: \"sale\", sub_type: subtype, price: 15, price_gross: 15, discount_percent: 0, id_customer: \"\", createdAt: now, updatedAt: now',\n\t\t' });',\n\t\t' if (customerIds && customerIds[0]) {',\n\t\t' pricingDocs.push({',\n\t\t' _id: `qa-pricing-${subtype}-${String(item._id).replace(/[^a-z0-9_-]/gi, \"-\")}-customer`,',\n\t\t' id_item: item._id, name: `${label} Customer Override`, description: `${label} Customer Override`, unit: item.unit || \"Each\", active: true, type: \"sale\", sub_type: subtype, price: 20, price_gross: 20, discount_percent: 0, id_customer: customerIds[0], createdAt: now, updatedAt: now',\n\t\t' });',\n\t\t' }',\n\t\t' }',\n\t\t' for (const doc of pricingDocs) await targetDb.collection(\"pricing-items\").replaceOne({ _id: doc._id }, doc, { upsert: true });',\n\t\t' summary.collections[\"pricing-items\"] = (summary.collections[\"pricing-items\"] || 0) + pricingDocs.length;',\n\t\t' summary.selected.qa_surcharge_fixture_items = usableItems.map((doc) => doc._id);',\n\t\t' summary.selected.qa_surcharge_pricing_items = pricingDocs.map((doc) => doc._id);',\n\t\t' if (pricingDocs.length) summary.notes.push(`Ensured ${pricingDocs.length} local pricing-items for service/misc surcharge override/default QA.`);',\n\t\t'}',\n\t\t'',\n\t\t'async function cleanupSyntheticBillingDashboardQaFixtures(targetDb, summary) {',\n\t\t' const fixtureIdQuery = { _id: /^qa-billing-/ };',\n\t\t' const fixtureCollections = [\"customers\", \"yards\", \"items\", \"production-locations\", \"bols\", \"production-sales-orders\", \"production-deliveries\", \"invoices\"];',\n\t\t' let removed = 0;',\n\t\t' for (const collectionName of fixtureCollections) {',\n\t\t' const result = await targetDb.collection(collectionName).deleteMany(fixtureIdQuery).catch(() => ({ deletedCount: 0 }));',\n\t\t' removed += Number(result && result.deletedCount || 0);',\n\t\t' }',\n\t\t' const invoiceResult = await targetDb.collection(\"invoices\").deleteMany({ $or: [{ invoice_string: /^QA-INV-/ }, { invoice_number: 4333 }] }).catch(() => ({ deletedCount: 0 }));',\n\t\t' removed += Number(invoiceResult && invoiceResult.deletedCount || 0);',\n\t\t' const psoResult = await targetDb.collection(\"production-sales-orders\").deleteMany({ $or: [{ order_number_string: /^QA-PSO-/ }, { activity_number: /^QA-PSO-/ }] }).catch(() => ({ deletedCount: 0 }));',\n\t\t' removed += Number(psoResult && psoResult.deletedCount || 0);',\n\t\t' if (removed) summary.notes.push(`Removed ${removed} stale synthetic billing dashboard QA fixture document(s) from the local Mongo profile.`);',\n\t\t'}',\n\t\t'',\n\t\t'async function ensureBillingDashboardQaFixtures(targetDb, summary, customerIds, yardIds, serviceItems) {',\n\t\t' const now = new Date();',\n\t\t' const customerId = (customerIds && customerIds[0]) || \"qa-billing-customer\";',\n\t\t' const yardId = (yardIds && yardIds[0]) || \"qa-billing-yard\";',\n\t\t' const item = (serviceItems || []).find((doc) => doc && doc._id) || { _id: \"qa-billing-service-item\", name: \"QA Billing Service Item\", unit: \"Each\", type: \"Service\", active: true };',\n\t\t' const locationId = \"qa-billing-location\";',\n\t\t' const bolId = \"qa-billing-bol\";',\n\t\t' const psoId = \"qa-billing-pso-awaiting-invoice\";',\n\t\t' const deliveryId = \"qa-billing-delivery-awaiting-invoice\";',\n\t\t' const invoiceId = \"qa-billing-existing-processing-invoice\";',\n\t\t' await targetDb.collection(\"customers\").replaceOne({ _id: customerId }, {',\n\t\t' _id: customerId, name: \"QA Billing Customer\", active: true, send_type: \"Email\", customer_approval_required: false, createdAt: now, updatedAt: now',\n\t\t' }, { upsert: true });',\n\t\t' await targetDb.collection(\"yards\").replaceOne({ _id: yardId }, { _id: yardId, name: \"QA Billing Yard\", active: true, createdAt: now, updatedAt: now }, { upsert: true });',\n\t\t' await targetDb.collection(\"items\").replaceOne({ _id: item._id }, { ...item, _id: item._id, name: item.name || \"QA Billing Service Item\", unit: item.unit || \"Each\", type: item.type || \"Service\", active: true, updatedAt: now }, { upsert: true });',\n\t\t' await targetDb.collection(\"production-locations\").replaceOne({ _id: locationId }, {',\n\t\t' _id: locationId, id_customer: customerId, customer: \"QA Billing Customer\", location: \"QA Billing Location\", id_yard: yardId, county: \"QA County\", active: true, createdAt: now, updatedAt: now',\n\t\t' }, { upsert: true });',\n\t\t' await targetDb.collection(\"bols\").replaceOne({ _id: bolId }, {',\n\t\t' _id: bolId, bol_string: \"QA-BOL-004333\", bol_number: \"QA-BOL-004333\", status: \"Delivered\", date: now, driver: \"QA Driver\", createdAt: now, updatedAt: now',\n\t\t' }, { upsert: true });',\n\t\t' const lineItem = {',\n\t\t' _id: \"qa-billing-pso-line-1\", id_item: item._id, item: item.name || \"QA Billing Service Item\", item_type: item.type || \"Service\", type: item.type || \"Service\", quantity: 2, unit: item.unit || \"Each\", price: 100, price_subtotal: 200, price_total: 216.5, tax_amount: 16.5, billed: true, memo_bill: false, taxable: true, id_location: locationId, location: \"QA Billing Location\", id_yard: yardId, yard: \"QA Billing Yard\"',\n\t\t' };',\n\t\t' await targetDb.collection(\"production-sales-orders\").replaceOne({ _id: psoId }, {',\n\t\t' _id: psoId, status: \"Awaiting Invoice\", type: \"Invoice\", id_customer: customerId, customer: \"QA Billing Customer\", id_default_yard: yardId, date_created: now, date_ship: now, date_needed: now, order_number_string: \"QA-PSO-004333\", activity_number: \"QA-PSO-004333\", bol_numbers: \"QA-BOL-004333\", drivers: \"QA Driver\", ship_to_type: \"Location\", ship_to_location: \"QA Billing Location\", price: 200, price_subtotal: 200, account_manager: \"QA Admin\", user_approved: \"QA Admin\", production_locations: [{ id_location: locationId, location: \"QA Billing Location\", items: [lineItem] }], createdAt: now, updatedAt: now',\n\t\t' }, { upsert: true });',\n\t\t' await targetDb.collection(\"production-deliveries\").replaceOne({ _id: deliveryId }, {',\n\t\t' _id: deliveryId, type: \"Delivery\", approved: true, billed: true, memo_bill: false, invoiced: false, generic: false, invoices: [], consignment: false, id_activity: psoId, activity_number: \"QA-PSO-004333\", activity_type: \"Invoice\", id_customer: customerId, id_location: locationId, location: \"QA Billing Location\", id_yard: yardId, yard: \"QA Billing Yard\", id_item: item._id, item: item.name || \"QA Billing Service Item\", item_type: item.type || \"Service\", quantity: 2, unit: item.unit || \"Each\", price_per_unit: 100, price_subtotal: 200, price_total: 216.5, tax_amount: 16.5, id_bol: bolId, bol_number: \"QA-BOL-004333\", date: now, date_ship: now, user_approved: \"QA Admin\", account_manager: \"QA Admin\", createdAt: now, updatedAt: now',\n\t\t' }, { upsert: true });',\n\t\t' await targetDb.collection(\"invoices\").replaceOne({ _id: invoiceId }, {',\n\t\t' _id: invoiceId, status: \"Processing\", type: \"Invoice\", id_customer: customerId, customer: \"QA Billing Customer\", id_yard: yardId, yard: \"QA Billing Yard\", invoice_string: \"QA-INV-004333\", invoice_number: 4333, date_invoice: now, total: 216.5, subtotal: 200, tax_amount: 16.5, printed: false, invoice_opened: false, logs: [], files: [], line_items: [{ ...lineItem, source_production_delivery_id: deliveryId, description: lineItem.item, date: now }], createdAt: now, updatedAt: now',\n\t\t' }, { upsert: true });',\n\t\t' summary.collections.customers = (summary.collections.customers || 0) + 1;',\n\t\t' summary.collections.yards = (summary.collections.yards || 0) + 1;',\n\t\t' summary.collections.items = (summary.collections.items || 0) + 1;',\n\t\t' summary.collections[\"production-locations\"] = (summary.collections[\"production-locations\"] || 0) + 1;',\n\t\t' summary.collections.bols = (summary.collections.bols || 0) + 1;',\n\t\t' summary.collections[\"production-sales-orders\"] = (summary.collections[\"production-sales-orders\"] || 0) + 1;',\n\t\t' summary.collections[\"production-deliveries\"] = (summary.collections[\"production-deliveries\"] || 0) + 1;',\n\t\t' summary.collections.invoices = (summary.collections.invoices || 0) + 1;',\n\t\t' summary.selected.qa_billing_fixture = { customerId, yardId, psoId, deliveryId, invoiceId, itemId: item._id };',\n\t\t' summary.notes.push(\"Ensured localhost-only Billing Dashboard fixtures: one existing processing invoice plus one awaiting-invoice PSO/delivery source row.\");',\n\t\t'}',\n\t\t'',\n\t\t'async function selectDashboardReadyProductionDeliveryIds(sourceDb, query, limit = 5) {',\n\t\t' const rows = await sourceDb.collection(\"production-deliveries\").aggregate([',\n\t\t' { $match: query || {} },',\n\t\t' { $lookup: { from: \"production-sales-orders\", localField: \"id_activity\", foreignField: \"_id\", as: \"dbPSO\" } },',\n\t\t' { $unwind: { path: \"$dbPSO\", preserveNullAndEmptyArrays: false } },',\n\t\t' { $match: { \"dbPSO.type\": { $ne: \"Consignment Invoice\" } } },',\n\t\t' { $lookup: {',\n\t\t' from: \"bols\",',\n\t\t' let: { idBol: \"$id_bol\" },',\n\t\t' pipeline: [{ $match: { $expr: { $eq: [\"$_id\", \"$$idBol\"] }, status: \"Delivered\" } }],',\n\t\t' as: \"bol\"',\n\t\t' } },',\n\t\t' { $unwind: { path: \"$bol\", preserveNullAndEmptyArrays: false } },',\n\t\t' { $lookup: { from: \"production-locations\", localField: \"id_location\", foreignField: \"_id\", as: \"dbProductionLocation\" } },',\n\t\t' { $lookup: { from: \"well-groups\", localField: \"id_well_group\", foreignField: \"_id\", as: \"dbWellGroup\" } },',\n\t\t' { $match: { $or: [{ \"dbProductionLocation.0\": { $exists: true } }, { \"dbWellGroup.0\": { $exists: true } }] } },',\n\t\t' { $sort: { date: -1, date_ship: -1, date_treated: -1, updatedAt: -1 } },',\n\t\t' { $limit: limit },',\n\t\t' { $project: { _id: 1 } }',\n\t\t' ]).toArray();',\n\t\t' return rows.map((doc) => doc._id).filter(Boolean);',\n\t\t'}',\n\t\t'',\n\t\t'async function selectTruckTreatDashboardReadyProductionDeliveryIds(sourceDb, query, limit = 5) {',\n\t\t' const rows = await sourceDb.collection(\"production-deliveries\").aggregate([',\n\t\t' { $match: query || {} },',\n\t\t' { $lookup: {',\n\t\t' from: \"bols\",',\n\t\t' let: { idBol: \"$id_bol\" },',\n\t\t' pipeline: [{ $match: { $expr: { $eq: [\"$_id\", \"$$idBol\"] }, status: \"Delivered\" } }],',\n\t\t' as: \"bol\"',\n\t\t' } },',\n\t\t' { $unwind: { path: \"$bol\", preserveNullAndEmptyArrays: false } },',\n\t\t' { $lookup: { from: \"production-locations\", localField: \"id_location\", foreignField: \"_id\", as: \"dbProductionLocation\" } },',\n\t\t' { $lookup: { from: \"well-groups\", localField: \"id_well_group\", foreignField: \"_id\", as: \"dbWellGroup\" } },',\n\t\t' { $match: { $or: [{ \"dbProductionLocation.0\": { $exists: true } }, { \"dbWellGroup.0\": { $exists: true } }] } },',\n\t\t' { $sort: { date: -1, date_treated: -1, updatedAt: -1 } },',\n\t\t' { $limit: limit },',\n\t\t' { $project: { _id: 1 } }',\n\t\t' ]).toArray();',\n\t\t' return rows.map((doc) => doc._id).filter(Boolean);',\n\t\t'}',\n\t\t'',\n\t\t'async function selectLocalhostDeliveryFixtureIds(sourceDb, query, limit = 3) {',\n\t\t' const rows = await sourceDb.collection(\"production-deliveries\").aggregate([',\n\t\t' { $match: { $and: [query || {}, { id_bol: { $type: \"string\", $ne: \"\" } }] } },',\n\t\t' { $lookup: { from: \"production-sales-orders\", localField: \"id_activity\", foreignField: \"_id\", as: \"dbPSO\" } },',\n\t\t' { $unwind: { path: \"$dbPSO\", preserveNullAndEmptyArrays: false } },',\n\t\t' { $match: { \"dbPSO.type\": { $ne: \"Consignment Invoice\" } } },',\n\t\t' { $lookup: { from: \"production-locations\", localField: \"id_location\", foreignField: \"_id\", as: \"dbProductionLocation\" } },',\n\t\t' { $lookup: { from: \"well-groups\", localField: \"id_well_group\", foreignField: \"_id\", as: \"dbWellGroup\" } },',\n\t\t' { $match: { $or: [{ \"dbProductionLocation.0\": { $exists: true } }, { \"dbWellGroup.0\": { $exists: true } }] } },',\n\t\t' { $sort: { date: -1, date_ship: -1, updatedAt: -1 } },',\n\t\t' { $limit: limit },',\n\t\t' { $project: { _id: 1 } }',\n\t\t' ]).toArray();',\n\t\t' return rows.map((doc) => doc._id).filter(Boolean);',\n\t\t'}',\n\t\t'',\n\t'async function seedBillingInventory(sourceDb, targetDb) {',\n\t\t' const includeBillingFixtures = shouldSeedBillingDashboardFixtures();',\n\t\t\t' const includePricingImportFixtures = includeBillingFixtures || shouldSeedPricingImportFixtures();',\n\t\t\t' const summary = { profile: desiredSeedProfile(), collections: {}, selected: {}, notes: [] };',\n\t\t\t' const identifiers = extractSeedIdentifiers();',\n\t\t\t' summary.selected.seed_identifiers = identifiers;',\n\t\t\t' const qaIdentityUsers = await copyQaIdentityUsers(sourceDb, targetDb, summary);',\n\t\t\t' const truckTreatingBolContextDocs = await copyTruckTreatingBolContext(sourceDb, targetDb, summary);',\n\t\t\t' const ticketAssetContextDocs = await copyTicketAssetContext(sourceDb, targetDb, summary);',\n\t\t\t' const productionInterchangeablesContextDocs = await copyProductionInterchangeablesContext(sourceDb, targetDb, summary);',\n\t\t\t' const pricingImportWorkbookContextDocs = includePricingImportFixtures ? await copyPricingImportWorkbookContext(sourceDb, targetDb, summary) : [];',\n\t\t' if (!includeBillingFixtures) {',\n\t\t' summary.notes.push(\"Billing dashboard fixtures are disabled because ticket context does not require billing, invoices, taxes, inventory, surcharges, checkout, or pick tickets.\");',\n\t\t' await cleanupSyntheticBillingDashboardQaFixtures(targetDb, summary);',\n\t\t' }',\n\t\t' if (includePricingImportFixtures && !includeBillingFixtures) {',\n\t\t' summary.notes.push(\"Using pricing-import seed profile: pricing records are copied without synthetic billing dashboard invoice fixtures.\");',\n\t\t' }',\n\t\t' const billableDeliveryQuery = { $and: [',\n\t\t' { $or: [{ type: \"Delivery\" }, { type: \"Pickup\" }] },',\n\t\t' { $or: [{ consignment: { $exists: false } }, { consignment: false }] },',\n\t\t' { approved: true }, { invoiced: false }, { generic: false }, { \"invoices.0\": { $exists: false } },',\n\t\t' { $or: [{ billed: true }, { memo_bill: true }] }',\n\t\t' ] };',\n\t\t' const billableTruckTreatQuery = { $and: [',\n\t\t' { type: \"Truck Treat\" }, { invoiced: false }, { generic: false }, { approved: true }, { \"invoices.0\": { $exists: false } },',\n\t\t' { $or: [{ billed: true }, { memo_bill: true }] }',\n\t\t' ] };',\n\t\t' const hintedQuery = identifierQuery(identifiers);',\n\t\t' let hintedProductionDeliveries = [];',\n\t\t' let hintedTruckTreatingDeliveries = [];',\n\t\t' if (hintedQuery) {',\n\t\t' hintedProductionDeliveries = await copyByIds(sourceDb, targetDb, \"production-deliveries\", await selectDashboardReadyProductionDeliveryIds(sourceDb, { $and: [billableDeliveryQuery, hintedQuery] }, 3), summary, 3);',\n\t\t' hintedTruckTreatingDeliveries = await copyByIds(sourceDb, targetDb, \"production-deliveries\", await selectTruckTreatDashboardReadyProductionDeliveryIds(sourceDb, { $and: [billableTruckTreatQuery, hintedQuery] }, 3), summary, 3);',\n\t\t' if (hintedProductionDeliveries.length || hintedTruckTreatingDeliveries.length) summary.notes.push(`Preferred live records matching ticket identifiers: ${identifiers.join(\", \")}`);',\n\t\t' else summary.notes.push(`No billable live records matched ticket identifiers: ${identifiers.join(\", \")}`);',\n\t\t' }',\n\t\t'',\n\t\t' let fallbackProductionDeliveries = hintedProductionDeliveries.length ? [] : await copyByIds(sourceDb, targetDb, \"production-deliveries\", await selectDashboardReadyProductionDeliveryIds(sourceDb, billableDeliveryQuery, 3), summary, 3);',\n\t\t' if (!hintedProductionDeliveries.length && !fallbackProductionDeliveries.length) {',\n\t\t' fallbackProductionDeliveries = await copyByIds(sourceDb, targetDb, \"production-deliveries\", await selectLocalhostDeliveryFixtureIds(sourceDb, billableDeliveryQuery, 3), summary, 3);',\n\t\t' if (fallbackProductionDeliveries.length) summary.notes.push(\"Created localhost-only delivery invoice fixture from live delivery data by normalizing copied BOL status to Delivered in local Mongo.\");',\n\t\t' }',\n\t\t' const fallbackTruckTreatingDeliveries = hintedTruckTreatingDeliveries.length ? [] : await copyByIds(sourceDb, targetDb, \"production-deliveries\", await selectTruckTreatDashboardReadyProductionDeliveryIds(sourceDb, billableTruckTreatQuery, 3), summary, 3);',\n\t\t' const productionDeliveries = [...hintedProductionDeliveries, ...fallbackProductionDeliveries];',\n\t\t' const truckTreatingDeliveries = [...hintedTruckTreatingDeliveries, ...fallbackTruckTreatingDeliveries];',\n\t\t' summary.selected.production_deliveries = productionDeliveries.map((doc) => doc._id);',\n\t\t' summary.selected.truck_treating_deliveries = truckTreatingDeliveries.map((doc) => doc._id);',\n\t\t' if (!productionDeliveries.length && !truckTreatingDeliveries.length) {',\n\t\t' summary.notes.push(\"No live billable delivery or truck-treatment records matched the Billing Dashboard awaiting-invoice filters.\");',\n\t\t' }',\n\t\t'',\n\t\t\t' const sourceDocs = [...qaIdentityUsers, ...truckTreatingBolContextDocs, ...ticketAssetContextDocs, ...productionInterchangeablesContextDocs, ...pricingImportWorkbookContextDocs, ...productionDeliveries, ...truckTreatingDeliveries];',\n\t\t\t' const pricingImportContext = summary.selected.pricing_import_workbook_context || {};',\n\t\t\t' const customerIds = unique([...idValues(sourceDocs, [\"id_customer\"]), ...(Array.isArray(pricingImportContext.customer_ids) ? pricingImportContext.customer_ids : [])]);',\n\t\t' const locationIds = idValues(sourceDocs, [\"id_location\"]);',\n\t\t' const wellGroupIds = idValues(sourceDocs, [\"id_well_group\"]);',\n\t\t\t' const itemIds = unique([...idValues(sourceDocs, [\"id_item\", \"id_chemical\"]), ...(Array.isArray(pricingImportContext.item_ids) ? pricingImportContext.item_ids : []), ...(Array.isArray(pricingImportContext.chemical_ids) ? pricingImportContext.chemical_ids : [])]);',\n\t\t' const bolIds = idValues(sourceDocs, [\"id_bol\", \"id_bols\"]);',\n\t\t' const yardIds = idValues(sourceDocs, [\"id_yard\"]);',\n\t\t' const activityIds = idValues(sourceDocs, [\"id_activity\", \"id_production_sales_order\", \"id_sales_order\"]);',\n\t\t' const tankIds = idValues(sourceDocs, [\"id_tank\"]);',\n\t\t' const truckTreatingDetailIds = idValues(sourceDocs, [\"id_delivery\", \"id_truck_treating_delivery\"]);',\n\t\t' const userIds = idValues(sourceDocs, [\"id_user_approved\", \"id_driver\", \"id_driver_scheduled\", \"id_account_manager\", \"id_foreman\"]);',\n\t\t'',\n\t\t' const copiedLocations = await copyByIds(sourceDb, targetDb, \"production-locations\", locationIds, summary);',\n\t\t' const copiedWellGroups = await copyByIds(sourceDb, targetDb, \"well-groups\", wellGroupIds, summary);',\n\t\t' const copiedItems = await copyByIds(sourceDb, targetDb, \"items\", itemIds, summary);',\n\t\t' const copiedChemicals = await copyByIds(sourceDb, targetDb, \"chemicals\", itemIds, summary);',\n\t\t' await copyByIds(sourceDb, targetDb, \"production-sales-orders\", activityIds, summary);',\n\t\t' await copyByIds(sourceDb, targetDb, \"production-location-tanks\", tankIds, summary);',\n\t\t' await copyByIds(sourceDb, targetDb, \"truck-treating-deliveries\", truckTreatingDetailIds, summary);',\n\t\t' await copyByIds(sourceDb, targetDb, \"customers\", unique([...customerIds, ...idValues(copiedLocations, [\"id_customer\"]), ...idValues(copiedWellGroups, [\"id_customer\"])]), summary);',\n\t\t' await copyByIds(sourceDb, targetDb, \"bols\", bolIds, summary);',\n\t\t' if (productionDeliveries.length && bolIds.length) await targetDb.collection(\"bols\").updateMany({ _id: { $in: bolIds } }, { $set: { status: \"Delivered\" } });',\n\t\t' await copyByIds(sourceDb, targetDb, \"yards\", yardIds, summary);',\n\t\t' await copyByIds(sourceDb, targetDb, \"users\", userIds, summary);',\n\t\t'',\n\t\t' const copiedServiceItems = await copyQuery(sourceDb, targetDb, \"items\", { $or: [',\n\t\t' { type: /service/i }, { type: /misc/i }, { category: /service/i }, { category: /misc/i },',\n\t\t' { name: /surcharge|fuel|delivery|service|misc/i }',\n\t\t' ] }, summary, 40, { updatedAt: -1 });',\n\t\t' summary.selected.service_or_surcharge_items = copiedServiceItems.map((doc) => doc._id);',\n\t\t'',\n\t\t' if (includePricingImportFixtures) {',\n\t\t' await copyQuery(sourceDb, targetDb, \"pricing-items\", { $or: [',\n\t\t' { id_item: { $in: unique([...itemIds, ...copiedItems.map((doc) => doc._id), ...copiedServiceItems.map((doc) => doc._id)]) } },',\n\t\t' { id_chemical: { $in: unique([...itemIds, ...copiedChemicals.map((doc) => doc._id)]) } },',\n\t\t' { id_customer: { $in: customerIds } },',\n\t\t' { sub_type: { $in: [\"misc\", \"service\"] } },',\n\t\t' { id_item: { $in: copiedServiceItems.map((doc) => doc._id) } },',\n\t\t' { name: /surcharge|fuel|delivery|service|misc/i }',\n\t\t' ] }, summary, 80, { updatedAt: -1 });',\n\t\t' }',\n\t\t'',\n\t\t' if (includeBillingFixtures) {',\n\t\t' await copyQuery(sourceDb, targetDb, \"sales-taxes\", {}, summary, 80, { updatedAt: -1 });',\n\t\t' await copyQuery(sourceDb, targetDb, \"state-counties\", {}, summary, 80, { updatedAt: -1 });',\n\t\t' await copyQuery(sourceDb, targetDb, \"accounting-codes\", {}, summary, 80, { updatedAt: -1 });',\n\t\t' await ensureBillingSurchargePricingFixtures(targetDb, summary, copiedServiceItems, customerIds);',\n\t\t' await ensureBillingDashboardQaFixtures(targetDb, summary, customerIds, yardIds, copiedServiceItems);',\n\t\t'',\n\t\t' const inventoryLocationQuery = { $or: [',\n\t\t' { id_item: { $in: unique([...itemIds, ...copiedItems.map((doc) => doc._id), ...copiedServiceItems.map((doc) => doc._id)]) } },',\n\t\t' { id_chemical: { $in: unique([...itemIds, ...copiedChemicals.map((doc) => doc._id)]) } },',\n\t\t' { id_yard: { $in: yardIds } }',\n\t\t' ] };',\n\t\t' const inventoryLocations = await copyQuery(sourceDb, targetDb, \"inventory-locations\", inventoryLocationQuery, summary, 80, { updatedAt: -1 });',\n\t\t' await copyQuery(sourceDb, targetDb, \"inventory-transactions\", { $or: [',\n\t\t' { id_inventory_location: { $in: inventoryLocations.map((doc) => doc._id) } },',\n\t\t' { id_item: { $in: itemIds } },',\n\t\t' { id_chemical: { $in: itemIds } }',\n\t\t' ] }, summary, 120, { date: -1, updatedAt: -1 });',\n\t\t' }',\n\t\t'',\n\t\t\t' summary.ready = pricingImportWorkbookContextDocs.length > 0 || truckTreatingBolContextDocs.length > 0 || ticketAssetContextDocs.length > 0 || productionInterchangeablesContextDocs.length > 0 || productionDeliveries.length > 0 || truckTreatingDeliveries.length > 0;',\n\t\t' return summary;',\n\t'}',\n\t\t'',\n\t\t'(async () => {',\n\t\t' const { MongoClient } = requireMongo();',\n\t\t' const source = resolveRuntimeSource();',\n\t\t' const targetUri = process.env.RESOLVEIO_SUPPORT_QA_MONGO_URL || process.env.RESOLVEIO_RUNNER_QA_MONGO_URL || process.env.MONGO_URL || \"mongodb://127.0.0.1:3001/resolveio?directConnection=true\";',\n\t' if (!source.uri) {',\n\t' preserveExistingSeedResult(\"missing_live_mongo_uri\");',\n\t' writeResult({ status: isLiveDataRequired() ? \"failed\" : \"skipped\", reason: \"missing_live_mongo_uri\", required: isLiveDataRequired(), result_path: resultPath }, isLiveDataRequired() ? 5 : 0);',\n\t' }',\n\t\t' if (!isLocalMongoUri(targetUri)) writeResult({ status: \"failed\", reason: \"target_mongo_must_be_localhost\", target_uri_redacted: redactUri(targetUri), result_path: resultPath }, 3);',\n\t\t' if (String(source.uri) === String(targetUri)) writeResult({ status: \"failed\", reason: \"source_and_target_mongo_match\", result_path: resultPath }, 3);',\n\t\t' await waitForTargetMongo(MongoClient, targetUri);',\n\t\t' const sourceClient = new MongoClient(source.uri, { readPreference: \"secondaryPreferred\", serverSelectionTimeoutMS: 15000 });',\n\t\t' const targetClient = new MongoClient(targetUri, { serverSelectionTimeoutMS: 15000 });',\n\t\t' try {',\n\t\t' await sourceClient.connect();',\n\t\t' await targetClient.connect();',\n\t\t' const sourceDb = source.database ? sourceClient.db(source.database) : sourceClient.db();',\n\t\t' const targetDb = targetClient.db();',\n\t\t' const summary = await seedBillingInventory(sourceDb, targetDb);',\n\t\t' writeResult({',\n\t\t' status: summary.ready ? \"pass\" : \"needs-data\",',\n\t\t' source_uri_redacted: redactUri(source.uri),',\n\t\t' target_uri_redacted: redactUri(targetUri),',\n\t\t' ...summary,',\n\t\t' result_path: resultPath',\n\t\t' }, summary.ready ? 0 : 4);',\n\t\t' } finally {',\n\t\t' await sourceClient.close().catch(() => undefined);',\n\t\t' await targetClient.close().catch(() => undefined);',\n\t\t' }',\n\t\t'})().catch((error) => writeResult({ status: \"failed\", reason: error && (error.stack || error.message) || String(error), result_path: resultPath }, 2));',\n\t\t''\n\t].join('\\n');\n}\n\nexport function buildResolveIORunnerBugfixComparisonQaScript(): string {\n\treturn [\n\t\t'#!/usr/bin/env bash',\n\t\t'set -u',\n\t\t'TOOLS_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"',\n\t\t'source \"$TOOLS_DIR/env.sh\"',\n\t\t'if resolveio_support_codex_lane_is_build 2>/dev/null; then',\n\t\t' resolveio_support_codex_block_build_lane_qa',\n\t\t' exit 86',\n\t\t'fi',\n\t\t'PROJECT_ROOT=\"${1:-}\"',\n\t\t'if [ -z \"$PROJECT_ROOT\" ]; then',\n\t\t' echo \"Usage: $0 <project-root> [baseline-ref] -- <qa-command...>\" >&2',\n\t\t' exit 2',\n\t\t'fi',\n\t\t'shift || true',\n\t\t'DEFAULT_BASELINE_REF=\"${RESOLVEIO_RUNNER_QA_BASELINE_REF:-${RESOLVEIO_SUPPORT_QA_BASELINE_REF:-origin/master}}\"',\n\t\t'if [ \"${1:-}\" = \"--\" ]; then',\n\t\t' BASELINE_REF=\"$DEFAULT_BASELINE_REF\"',\n\t\t'else',\n\t\t' BASELINE_REF=\"${1:-$DEFAULT_BASELINE_REF}\"',\n\t\t' if [ \"$#\" -gt 0 ]; then shift || true; fi',\n\t\t'fi',\n\t\t'if [ \"${1:-}\" = \"--\" ]; then shift; fi',\n\t\t'if [ \"$#\" -eq 0 ]; then',\n\t\t' echo \"Usage: $0 <project-root> [baseline-ref] -- <qa-command...>\" >&2',\n\t\t' exit 2',\n\t\t'fi',\n\t\t'PROJECT_ROOT=\"$(cd \"$PROJECT_ROOT\" && pwd)\"',\n\t\t'REPO_ROOT=\"$(git -C \"$PROJECT_ROOT\" rev-parse --show-toplevel)\"',\n\t\t'PROJECT_REL=\"$(git -C \"$REPO_ROOT\" ls-files --full-name \"$PROJECT_ROOT\" 2>/dev/null | head -1 | xargs dirname 2>/dev/null || true)\"',\n\t\t'if [ -z \"$PROJECT_REL\" ] || [ \"$PROJECT_REL\" = \".\" ]; then',\n\t\t' PROJECT_REL=\"$(node - \"$REPO_ROOT\" \"$PROJECT_ROOT\" <<\\'RESOLVEIO_REL\\'',\n\t\t'const path = require(\"path\");',\n\t\t'console.log(path.relative(process.argv[2], process.argv[3]) || \".\");',\n\t\t'RESOLVEIO_REL',\n\t\t' )\"',\n\t\t'fi',\n\t\t'ARTIFACT_DIR=\"$PROJECT_ROOT/qa-artifacts\"',\n\t\t'mkdir -p \"$ARTIFACT_DIR/baseline\" \"$ARTIFACT_DIR/candidate\"',\n\t\t'RESULT_JSON=\"$ARTIFACT_DIR/bugfix-comparison-result.json\"',\n\t\t'CANDIDATE_PATCH=\"$ARTIFACT_DIR/bugfix-candidate.patch\"',\n\t\t'ORIGINAL_HEAD=\"$(git -C \"$REPO_ROOT\" rev-parse HEAD)\"',\n\t\t'ORIGINAL_BRANCH=\"$(git -C \"$REPO_ROOT\" symbolic-ref --short HEAD 2>/dev/null || true)\"',\n\t\t'QA_COMMAND=(\"$@\")',\n\t\t'STOPPER=\"$TOOLS_DIR/stop-local-qa.sh\"',\n\t\t'CURRENT_PHASE=\"\"',\n\t\t'stop_local_qa() {',\n\t\t' \"$STOPPER\" \"$PROJECT_ROOT\" >/dev/null 2>&1 || true',\n\t\t'}',\n\t\t'write_json() {',\n\t\t' node - \"$RESULT_JSON\" \"$@\" <<\\'RESOLVEIO_WRITE_JSON\\'',\n\t\t'const fs = require(\"fs\");',\n\t\t'const [path, status, baselineExit, candidateExit, baselineRef, originalHead, projectRel, note] = process.argv.slice(2);',\n\t\t'const payload = {',\n\t\t' status,',\n\t\t' baseline_ref: baselineRef,',\n\t\t' original_head: originalHead,',\n\t\t' project: projectRel,',\n\t\t' baseline_exit_code: Number(baselineExit),',\n\t\t' candidate_exit_code: Number(candidateExit),',\n\t\t' code_switch_proven: Number(baselineExit) !== 0 && Number(candidateExit) === 0,',\n\t\t' candidate_passed: Number(candidateExit) === 0,',\n\t\t' baseline_failed: Number(baselineExit) !== 0,',\n\t\t' note,',\n\t\t' artifact_dirs: { baseline: \"qa-artifacts/baseline\", candidate: \"qa-artifacts/candidate\" },',\n\t\t' created_at: new Date().toISOString()',\n\t\t'};',\n\t\t'fs.writeFileSync(path, JSON.stringify(payload, null, 2));',\n\t\t'console.log(JSON.stringify(payload, null, 2));',\n\t\t'RESOLVEIO_WRITE_JSON',\n\t\t'}',\n\t\t'snapshot_phase_artifacts() {',\n\t\t' local phase=\"$1\"',\n\t\t' mkdir -p \"$ARTIFACT_DIR/$phase\"',\n\t\t' find \"$ARTIFACT_DIR\" -maxdepth 1 -type f \\\\( -name \"*.png\" -o -name \"*.jpg\" -o -name \"*.jpeg\" -o -name \"*.webp\" -o -name \"*.json\" -o -name \"*.txt\" -o -name \"*.log\" -o -name \"*.zip\" \\\\) -print0 2>/dev/null | while IFS= read -r -d \"\" file; do',\n\t\t' cp \"$file\" \"$ARTIFACT_DIR/$phase/$(basename \"$file\")\" 2>/dev/null || true',\n\t\t' done',\n\t\t'}',\n\t\t'capture_candidate_patch() {',\n\t\t' : > \"$CANDIDATE_PATCH\"',\n\t\t' git -C \"$REPO_ROOT\" diff --binary -- \"$PROJECT_REL\" >> \"$CANDIDATE_PATCH\" || true',\n\t\t' git -C \"$REPO_ROOT\" diff --binary --cached -- \"$PROJECT_REL\" >> \"$CANDIDATE_PATCH\" || true',\n\t\t'}',\n\t\t'checkout_project_from_ref() {',\n\t\t' local ref=\"$1\"',\n\t\t' git -C \"$REPO_ROOT\" checkout \"$ref\" -- \"$PROJECT_REL\"',\n\t\t'}',\n\t\t'restore_candidate() {',\n\t\t' stop_local_qa',\n\t\t' checkout_project_from_ref \"$ORIGINAL_HEAD\" || true',\n\t\t' if [ -s \"$CANDIDATE_PATCH\" ]; then',\n\t\t' git -C \"$REPO_ROOT\" apply --whitespace=nowarn \"$CANDIDATE_PATCH\" || true',\n\t\t' fi',\n\t\t'}',\n\t\t'trap restore_candidate EXIT',\n\t\t'run_phase() {',\n\t\t' local phase=\"$1\"',\n\t\t' CURRENT_PHASE=\"$phase\"',\n\t\t' stop_local_qa',\n\t\t' export RESOLVEIO_RUNNER_QA_PHASE=\"$phase\"',\n\t\t' export RESOLVEIO_SUPPORT_QA_PHASE=\"$phase\"',\n\t\t' export RESOLVEIO_RUNNER_QA_ARTIFACT_DIR=\"$ARTIFACT_DIR/$phase\"',\n\t\t' export RESOLVEIO_SUPPORT_QA_ARTIFACT_DIR=\"$ARTIFACT_DIR/$phase\"',\n\t\t' export RESOLVEIO_RUNNER_QA_PROJECT_ROOT=\"$PROJECT_ROOT\"',\n\t\t' export RESOLVEIO_SUPPORT_QA_PROJECT_ROOT=\"$PROJECT_ROOT\"',\n\t\t' export RESOLVEIO_RUNNER_QA_TOOLS_DIR=\"$TOOLS_DIR\"',\n\t\t' export RESOLVEIO_SUPPORT_QA_TOOLS_DIR=\"$TOOLS_DIR\"',\n\t\t' mkdir -p \"$ARTIFACT_DIR/$phase\"',\n\t\t' find \"$ARTIFACT_DIR/$phase\" -maxdepth 1 -type f \\\\( -name \"*.png\" -o -name \"*.jpg\" -o -name \"*.jpeg\" -o -name \"*.webp\" -o -name \"*.json\" -o -name \"*.txt\" -o -name \"*.log\" -o -name \"*.zip\" \\\\) -delete 2>/dev/null || true',\n\t\t' find \"$ARTIFACT_DIR\" -maxdepth 1 -type f \\\\( -name \"*.png\" -o -name \"*.jpg\" -o -name \"*.jpeg\" -o -name \"*.webp\" -o -name \"*proof.json\" -o -name \"auth-bootstrap-result.json\" \\\\) -delete 2>/dev/null || true',\n\t\t' RESOLVEIO_SUPPORT_QA_KEEPALIVE=true RESOLVEIO_RUNNER_QA_KEEPALIVE=true \"$TOOLS_DIR/run-local-qa.sh\" \"$PROJECT_ROOT\"',\n\t\t' local stack_rc=\"$?\"',\n\t\t' if [ \"$stack_rc\" != \"0\" ]; then',\n\t\t' echo \"ResolveIO bugfix comparison QA $phase phase blocked: local QA stack did not start (exit $stack_rc).\" | tee \"$ARTIFACT_DIR/$phase/qa-command.log\"',\n\t\t' snapshot_phase_artifacts \"$phase\"',\n\t\t' stop_local_qa',\n\t\t' return \"$stack_rc\"',\n\t\t' fi',\n\t\t' if [ -f \"$TOOLS_DIR/qa-live-data-seed.js\" ]; then',\n\t\t' node \"$TOOLS_DIR/qa-live-data-seed.js\" \"$PROJECT_ROOT\"',\n\t\t' local seed_rc=\"$?\"',\n\t\t' if [ \"$seed_rc\" != \"0\" ]; then',\n\t\t' echo \"ResolveIO bugfix comparison QA $phase phase blocked: live data seed failed (exit $seed_rc).\" | tee \"$ARTIFACT_DIR/$phase/qa-command.log\"',\n\t\t' snapshot_phase_artifacts \"$phase\"',\n\t\t' stop_local_qa',\n\t\t' return \"$seed_rc\"',\n\t\t' fi',\n\t\t' fi',\n\t\t' set +e',\n\t\t' (cd \"$PROJECT_ROOT\" && \"${QA_COMMAND[@]}\") 2>&1 | tee \"$ARTIFACT_DIR/$phase/qa-command.log\"',\n\t\t' local rc=\"${PIPESTATUS[0]}\"',\n\t\t' set +e',\n\t\t' snapshot_phase_artifacts \"$phase\"',\n\t\t' stop_local_qa',\n\t\t' return \"$rc\"',\n\t\t'}',\n\t\t'echo \"ResolveIO bugfix comparison QA preserving candidate diff for $PROJECT_REL\"',\n\t\t'capture_candidate_patch',\n\t\t'stop_local_qa',\n\t\t'echo \"ResolveIO bugfix comparison QA baseline phase: $BASELINE_REF\"',\n\t\t'checkout_project_from_ref \"$BASELINE_REF\"',\n\t\t'run_phase baseline',\n\t\t'BASELINE_EXIT=\"$?\"',\n\t\t'echo \"ResolveIO bugfix comparison QA candidate phase: restored workspace candidate\"',\n\t\t'restore_candidate',\n\t\t'run_phase candidate',\n\t\t'CANDIDATE_EXIT=\"$?\"',\n\t\t'if [ \"$CANDIDATE_EXIT\" = \"0\" ] && [ \"$BASELINE_EXIT\" != \"0\" ]; then',\n\t\t' STATUS=\"pass\"',\n\t\t' NOTE=\"Baseline failed and candidate passed for the same QA command.\"',\n\t\t'elif [ \"$CANDIDATE_EXIT\" = \"0\" ]; then',\n\t\t' STATUS=\"inconclusive_baseline_also_passed\"',\n\t\t' NOTE=\"Candidate passed, but baseline also passed; the code switch did not prove the bug fix.\"',\n\t\t'else',\n\t\t' STATUS=\"fail_candidate_failed\"',\n\t\t' NOTE=\"Candidate failed the QA command.\"',\n\t\t'fi',\n\t\t'write_json \"$STATUS\" \"$BASELINE_EXIT\" \"$CANDIDATE_EXIT\" \"$BASELINE_REF\" \"$ORIGINAL_HEAD\" \"$PROJECT_REL\" \"$NOTE\"',\n\t\t'[ \"$CANDIDATE_EXIT\" = \"0\" ] || exit \"$CANDIDATE_EXIT\"',\n\t\t'[ \"$STATUS\" = \"pass\" ] || exit 8',\n\t\t''\n\t].join('\\n');\n}\n\nexport function buildResolveIORunnerQaWorkflowProbeScript(): string {\n\treturn [\n\t\t'#!/usr/bin/env node',\n\t\t\"'use strict';\",\n\t\t'',\n\t\t'const fs = require(\"fs\");',\n\t\t'const http = require(\"http\");',\n\t\t'const https = require(\"https\");',\n\t\t'const path = require(\"path\");',\n\t\t'',\n\t\t'if (isBuildLane()) {',\n\t\t' console.error(\"ResolveIO support lane guard: browser workflow probes are owned by the QA lane, not the 5.3 build lane.\");',\n\t\t' process.exit(86);',\n\t\t'}',\n\t\t'',\n\t\t'const projectRoot = path.resolve(process.argv[2] || process.cwd());',\n\t\t'const artifactDir = path.resolve(process.env.RESOLVEIO_RUNNER_QA_ARTIFACT_DIR || process.env.RESOLVEIO_SUPPORT_QA_ARTIFACT_DIR || path.join(projectRoot, \"qa-artifacts\"));',\n\t\t'const routeArg = process.argv[3] || process.env.RESOLVEIO_RUNNER_QA_TARGET_ROUTE || process.env.RESOLVEIO_SUPPORT_QA_TARGET_ROUTE || \"\";',\n\t\t'const targetRoute = resolveTargetRoute(routeArg);',\n\t\t'const matrixPath = path.join(artifactDir, \"qa-coverage-matrix.json\");',\n\t\t'const resultPath = path.join(artifactDir, \"qa-workflow-probe-result.json\");',\n\t\t'const authBootstrapResultPath = path.join(artifactDir, \"auth-bootstrap-result.json\");',\n\t\t'const passScreenshotPath = path.join(artifactDir, \"qa-workflow-route-ready.jpg\");',\n\t\t'const failScreenshotPath = path.join(artifactDir, \"qa-workflow-route-blocked.jpg\");',\n\t\t'const clientUrl = stripTrailingSlash(process.env.RESOLVEIO_RUNNER_QA_CLIENT_URL || process.env.RESOLVEIO_SUPPORT_QA_CLIENT_URL || `http://localhost:${process.env.RESOLVEIO_SUPPORT_QA_CLIENT_PORT || \"4200\"}`);',\n\t\t'const serverUrl = stripTrailingSlash(process.env.RESOLVEIO_RUNNER_QA_SERVER_URL || process.env.RESOLVEIO_SUPPORT_QA_SERVER_URL || \"http://localhost:8080\");',\n\t\t'const explicitQaUsername = process.env.RESOLVEIO_RUNNER_QA_AFFECTED_USER_EMAIL || process.env.RESOLVEIO_SUPPORT_QA_AFFECTED_USER_EMAIL || process.env.RESOLVEIO_RUNNER_QA_TICKET_REPORTER_EMAIL || process.env.RESOLVEIO_SUPPORT_QA_TICKET_REPORTER_EMAIL || \"\";',\n\t\t'const envQaUsername = process.env.RESOLVEIO_RUNNER_QA_USERNAME || process.env.RESOLVEIO_SUPPORT_QA_USERNAME || \"\";',\n\t\t'const seededQaUsername = readSeededPreferredQaUsername();',\n\t\t'const username = explicitQaUsername || seededQaUsername || envQaUsername || \"admin\";',\n\t\t'const password = process.env.RESOLVEIO_RUNNER_QA_PASSWORD || process.env.RESOLVEIO_SUPPORT_QA_PASSWORD || \"\";',\n\t\t'const viewportWidth = Number(process.env.RESOLVEIO_RUNNER_QA_VIEWPORT_WIDTH || process.env.RESOLVEIO_SUPPORT_QA_VIEWPORT_WIDTH || 1920);',\n\t\t'const viewportHeight = Number(process.env.RESOLVEIO_RUNNER_QA_VIEWPORT_HEIGHT || process.env.RESOLVEIO_SUPPORT_QA_VIEWPORT_HEIGHT || 1080);',\n\t\t'',\n\t\t'function isBuildLane() {',\n\t\t' return /^(build|support_build|support-build)$/i.test(String(process.env.RESOLVEIO_SUPPORT_CODEX_LANE || \"\").trim());',\n\t\t'}',\n\t\t'',\n\t\t'function stripTrailingSlash(value) { return String(value || \"\").replace(/\\\\/+$/, \"\"); }',\n\t\t'function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); }',\n\t\t'function writeJson(filePath, payload) { fs.mkdirSync(path.dirname(filePath), { recursive: true }); fs.writeFileSync(filePath, JSON.stringify(payload, null, 2)); }',\n\t\t'function readJson(filePath) { try { return JSON.parse(fs.readFileSync(filePath, \"utf8\")); } catch (error) { return null; } }',\n\t\t'function readSeedHintText() {',\n\t\t'\tconst repoRoot = path.dirname(projectRoot);',\n\t\t'\tconst chunks = [',\n\t\t'\t\tprocess.env.RESOLVEIO_SUPPORT_QA_ROW_FILTER || \"\",',\n\t\t'\t\tprocess.env.RESOLVEIO_SUPPORT_QA_CURRENT_ROW_WORKFLOW || \"\",',\n\t\t'\t\tprocess.env.RESOLVEIO_SUPPORT_QA_CURRENT_ROW_ASSERTION || \"\",',\n\t\t'\t\tprocess.env.RESOLVEIO_RUNNER_QA_ROW_FILTER || \"\",',\n\t\t'\t\tprocess.env.RESOLVEIO_RUNNER_QA_CURRENT_ROW_WORKFLOW || \"\",',\n\t\t'\t\tprocess.env.RESOLVEIO_RUNNER_QA_CURRENT_ROW_ASSERTION || \"\",',\n\t\t'\t\tprocess.env.RESOLVEIO_QA_SEED_HINTS || \"\",',\n\t\t'\t\tprocess.env.RESOLVEIO_SUPPORT_QA_SEED_HINTS || \"\",',\n\t\t'\t\tprocess.env.RESOLVEIO_RUNNER_QA_SEED_HINTS || \"\"',\n\t\t'\t];',\n\t\t'\tconst candidates = [',\n\t\t'\t\tpath.join(artifactDir, \"qa-coverage-matrix.json\"),',\n\t\t'\t\tpath.join(artifactDir, \"qa-row-lock.json\"),',\n\t\t'\t\tpath.join(repoRoot, \".resolveio-support-context\", \"manual-ticket.request.txt\"),',\n\t\t'\t\tpath.join(projectRoot, \".resolveio-support-context\", \"manual-ticket.request.txt\"),',\n\t\t'\t\tpath.join(repoRoot, \".resolveio-context\", \"manual-ticket.request.txt\"),',\n\t\t'\t\tpath.join(projectRoot, \".resolveio-context\", \"manual-ticket.request.txt\")',\n\t\t'\t];',\n\t\t'\tfor (const candidate of candidates) {',\n\t\t'\t\ttry {',\n\t\t'\t\t\tconst raw = fs.readFileSync(candidate, \"utf8\");',\n\t\t'\t\t\tchunks.push(raw);',\n\t\t'\t\t\tif (/qa-coverage-matrix\\\\.json$/.test(candidate)) {',\n\t\t'\t\t\t\tconst matrix = JSON.parse(raw);',\n\t\t'\t\t\t\tconst rows = Array.isArray(matrix && matrix.rows) ? matrix.rows : [];',\n\t\t'\t\t\t\tfor (const row of rows) chunks.push([row.workflow, row.route, row.assertion, row.required_proof, row.data_id, row.data_name, row.blocker, row.evidence, row.caption].filter(Boolean).join(\"\\\\n\"));',\n\t\t'\t\t\t}',\n\t\t'\t\t\tif (/qa-row-lock\\\\.json$/.test(candidate)) {',\n\t\t'\t\t\t\tconst lock = JSON.parse(raw);',\n\t\t'\t\t\t\tchunks.push([lock.workflow, lock.route, lock.assertion, lock.required_proof, lock.rowFilter, lock.blocker].filter(Boolean).join(\"\\\\n\"));',\n\t\t'\t\t\t}',\n\t\t'\t\t} catch (error) {}',\n\t\t'\t}',\n\t\t'\treturn chunks.filter(Boolean).join(\"\\\\n\");',\n\t\t'}',\n\t\t'function readSeededPreferredQaUsername() {',\n\t\t'\ttry {',\n\t\t'\t\tconst seed = readJson(path.join(artifactDir, \"qa-live-data-seed-result.json\"));',\n\t\t'\t\tconst context = seed && seed.selected && seed.selected.qa_user_context;',\n\t\t'\t\tconst preferred = context && (context.preferred_username || context.preferred_email || context.affected_user_email || context.reporter_email);',\n\t\t'\t\treturn String(preferred || \"\").trim();',\n\t\t'\t} catch (error) {',\n\t\t'\t\treturn \"\";',\n\t\t'\t}',\n\t\t'}',\n\t\t'function normalizeRoute(candidate) {',\n\t\t'\tconst value = String(candidate || \"\").trim();',\n\t\t'\tif (!value) return \"\";',\n\t\t'\tlet routeText = value;',\n\t\t'\tif (/^https?:\\\\/\\\\//i.test(routeText)) {',\n\t\t'\t\ttry { routeText = new URL(routeText).pathname || \"/\"; } catch (error) { return \"\"; }',\n\t\t'\t}',\n\t\t\"\tconst match = routeText.match(/(?:^|[\\\\s\\\\\\\"'`(])((?:\\\\/[a-z0-9][a-z0-9._~!$&'()*+,;=:@%\\\\/-]*)(?:\\\\?[^\\\\s\\\\\\\"'`<>)]*)?)/i);\",\n\t\t'\trouteText = ((match && match[1]) || routeText).split(/\\\\s*->\\\\s*/)[0].split(/\\\\s+-\\\\s+/)[0].trim().replace(/[),.;]+$/g, \"\");',\n\t\t'\tif (!routeText) return \"\";',\n\t\t'\treturn routeText.startsWith(\"/\") ? routeText : `/${routeText}`;',\n\t\t'}',\n\t\t'function resolveTargetRoute(explicitRoute) {',\n\t\t'\tconst hintText = readSeedHintText();',\n\t\t'\tconst preferInterchangeables = /\\\\b(interchangeable|interchangeables|mass\\\\s+update|update\\\\s+interchangeables|from\\\\s+chemical|to\\\\s+chemical|treatment\\\\s+plan|treatment\\\\s+plans|production\\\\s+location)\\\\b/i.test(hintText);',\n\t\t'\tconst seedCandidates = [',\n\t\t'\t\tpath.join(artifactDir, \"qa-live-data-seed-result.json\"),',\n\t\t'\t\tpath.join(artifactDir, \"candidate\", \"qa-live-data-seed-result.json\")',\n\t\t'\t];',\n\t\t'\tfor (const seedPath of seedCandidates) {',\n\t\t'\t\tconst seed = readJson(seedPath);',\n\t\t'\t\tconst interchangeablesRoutes = (seed && seed.selected && seed.selected.qa_production_interchangeables_context && seed.selected.qa_production_interchangeables_context.browser_routes) || (seed && seed.qa_production_interchangeables_context && seed.qa_production_interchangeables_context.browser_routes);',\n\t\t'\t\tconst interchangeablesRoute = normalizeRoute(interchangeablesRoutes && (interchangeablesRoutes.update_interchangeables || interchangeablesRoutes.detail || interchangeablesRoutes.list));',\n\t\t'\t\tif (preferInterchangeables && interchangeablesRoute) return interchangeablesRoute;',\n\t\t'\t\tconst routes = seed && seed.selected && seed.selected.truck_treating_bol_context && seed.selected.truck_treating_bol_context.browser_routes;',\n\t\t'\t\tconst route = normalizeRoute(routes && (routes.delivery || routes.detail || routes.list));',\n\t\t'\t\tif (!preferInterchangeables && route) return route;',\n\t\t'\t}',\n\t\t'\tif (preferInterchangeables) return \"/production-location/update-interchangeables\";',\n\t\t'\tconst explicit = normalizeRoute(explicitRoute);',\n\t\t'\tif (explicit) return explicit;',\n\t\t'\treturn \"/\";',\n\t'}',\n\t\t'function requestReady(url) {',\n\t\t'\treturn new Promise((resolve) => {',\n\t\t'\t\ttry {',\n\t\t'\t\t\tconst parsed = new URL(url);',\n\t\t'\t\t\tconst mod = parsed.protocol === \"https:\" ? https : http;',\n\t\t'\t\t\tconst req = mod.get(parsed, { timeout: 3000 }, (res) => { res.resume(); resolve(Boolean(res.statusCode && res.statusCode < 500)); });',\n\t\t'\t\t\treq.on(\"timeout\", () => req.destroy(new Error(\"timeout\")));',\n\t\t'\t\t\treq.on(\"error\", () => resolve(false));',\n\t\t'\t\t} catch (error) { resolve(false); }',\n\t\t'\t});',\n\t\t'}',\n\t\t'async function waitForHttpReady(url, label) {',\n\t\t'\tconst deadline = Date.now() + 45000;',\n\t\t'\twhile (Date.now() < deadline) {',\n\t\t'\t\tif (await requestReady(url)) return;',\n\t\t'\t\tawait delay(1500);',\n\t\t'\t}',\n\t\t'\tthrow new Error(`${label} did not become ready at ${url}`);',\n\t\t'}',\n\t\t'function requestJson(url, payload) {',\n\t\t'\treturn new Promise((resolve, reject) => {',\n\t\t'\t\tconst body = JSON.stringify(payload || {});',\n\t\t'\t\tconst parsed = new URL(url);',\n\t\t'\t\tconst mod = parsed.protocol === \"https:\" ? https : http;',\n\t\t'\t\tconst req = mod.request(parsed, { method: \"POST\", timeout: 20000, headers: { \"content-type\": \"application/json\", \"content-length\": Buffer.byteLength(body), \"origin\": clientUrl } }, (res) => {',\n\t\t'\t\t\tlet raw = \"\";',\n\t\t'\t\t\tres.setEncoding(\"utf8\");',\n\t\t'\t\t\tres.on(\"data\", (chunk) => { raw += chunk; });',\n\t\t'\t\t\tres.on(\"end\", () => {',\n\t\t'\t\t\t\tlet json = null;',\n\t\t'\t\t\t\ttry { json = raw ? JSON.parse(raw) : {}; } catch (error) { reject(new Error(`${url} returned non-JSON HTTP ${res.statusCode}: ${raw.slice(0, 300)}`)); return; }',\n\t\t'\t\t\t\tif (!res.statusCode || res.statusCode >= 400) { reject(new Error(`${url} returned HTTP ${res.statusCode}: ${JSON.stringify(json).slice(0, 500)}`)); return; }',\n\t\t'\t\t\t\tresolve(json);',\n\t\t'\t\t\t});',\n\t\t'\t\t});',\n\t\t'\t\treq.on(\"timeout\", () => req.destroy(new Error(`${url} timed out`)));',\n\t\t'\t\treq.on(\"error\", reject);',\n\t\t'\t\treq.write(body);',\n\t\t'\t\treq.end();',\n\t\t'\t});',\n\t\t'}',\n\t\t'function requirePuppeteer() {',\n\t\t'\tconst candidates = [',\n\t\t'\t\tpath.join(projectRoot, \"server\", \"node_modules\", \"puppeteer\", \"lib\", \"cjs\", \"puppeteer\", \"puppeteer.js\"),',\n\t\t'\t\tpath.join(projectRoot, \"node_modules\", \"puppeteer\", \"lib\", \"cjs\", \"puppeteer\", \"puppeteer.js\"),',\n\t\t'\t\tpath.join(process.cwd(), \"server\", \"node_modules\", \"puppeteer\", \"lib\", \"cjs\", \"puppeteer\", \"puppeteer.js\"),',\n\t\t'\t\tpath.join(process.cwd(), \"node_modules\", \"puppeteer\", \"lib\", \"cjs\", \"puppeteer\", \"puppeteer.js\"),',\n\t\t'\t\t\"puppeteer\"',\n\t\t'\t];',\n\t\t'\tfor (const candidate of candidates) { try { return require(candidate); } catch (error) {} }',\n\t\t'\tthrow new Error(\"Unable to require puppeteer from project/server node_modules or global resolution\");',\n\t\t'}',\n\t\t'async function launchBrowser(puppeteer) {',\n\t\t'\tconst launchOptions = { headless: true, defaultViewport: { width: viewportWidth, height: viewportHeight }, args: [\"--no-sandbox\", \"--disable-setuid-sandbox\", \"--disable-dev-shm-usage\", `--window-size=${viewportWidth},${viewportHeight}`] };',\n\t\t'\tif (process.env.PUPPETEER_EXECUTABLE_PATH || process.env.CHROME_BIN) launchOptions.executablePath = process.env.PUPPETEER_EXECUTABLE_PATH || process.env.CHROME_BIN;',\n\t\t'\treturn puppeteer.launch(launchOptions);',\n\t\t'}',\n\t\t'async function login() {',\n\t\t'\tif (!password) throw new Error(\"QA password is empty; source the generated env.sh before workflow probe\");',\n\t\t'\tconst loginJson = await requestJson(`${serverUrl}/login`, { username, password });',\n\t\t'\tconst refreshToken = loginJson && loginJson.result && loginJson.result.token;',\n\t\t'\tif (loginJson.error || !refreshToken) throw new Error(`Login failed: ${JSON.stringify(loginJson).slice(0, 800)}`);',\n\t\t'\tconst accessJson = await requestJson(`${serverUrl}/accessToken`, { refreshToken });',\n\t\t'\tconst accessToken = accessJson && accessJson.result && accessJson.result.token;',\n\t\t'\tconst user = accessJson && accessJson.result && accessJson.result.user;',\n\t\t'\tif (accessJson.error || !accessToken || !user) throw new Error(`Access token failed: ${JSON.stringify(accessJson).slice(0, 800)}`);',\n\t\t'\treturn { refreshToken, accessToken, user };',\n\t\t'}',\n\t\t'async function seedAuth(page, auth) {',\n\t\t'\tawait page.goto(clientUrl, { waitUntil: \"domcontentloaded\", timeout: 45000 });',\n\t\t'\tawait page.evaluate((payload) => {',\n\t\t'\t\tlocalStorage.clear();',\n\t\t'\t\tsessionStorage.clear();',\n\t\t'\t\tlocalStorage.setItem(\"refreshToken\", payload.refreshToken);',\n\t\t'\t\tlocalStorage.setItem(\"accessToken\", payload.accessToken);',\n\t\t'\t\tlocalStorage.setItem(\"user\", JSON.stringify({ ...(payload.user || {}), other: { ...((payload.user || {}).other || {}), tour_completed: true, took_tour: true }, settings: { ...((payload.user || {}).settings || {}), collapsable_menu: false, opening_route: payload.targetRoute } }));',\n\t\t'\t\tlocalStorage.setItem(\"lastURL\", payload.targetRoute);',\n\t\t'\t}, { ...auth, targetRoute });',\n\t\t'}',\n\t\t'async function pageSummary(page) {',\n\t\t'\treturn page.evaluate(() => {',\n\t\t'\t\tconst bodyText = (document.body && document.body.innerText || \"\").replace(/\\\\s+/g, \" \").trim();',\n\t\t'\t\tconst rows = Array.from(document.querySelectorAll(\"tr\")).map(row => (row.innerText || \"\").replace(/\\\\s+/g, \" \").trim()).filter(Boolean);',\n\t\t'\t\treturn { url: location.href, title: document.title, bodyTextSnippet: bodyText.slice(0, 1200), rowCount: rows.length, rows: rows.slice(0, 8), hasLoginText: /Employee\\\\/Customer Login|Employee Sign In|Customer Access|Unable to sign in/i.test(bodyText), hasOfflineModeText: bodyText.includes(\"*** OFFLINE MODE ***\"), storageState: { hasRefreshToken: !!localStorage.getItem(\"refreshToken\"), hasAccessToken: !!localStorage.getItem(\"accessToken\"), hasUser: !!localStorage.getItem(\"user\") } };',\n\t\t'\t});',\n\t\t'}',\n\t\t'function pathMatchesRoute(currentUrl, expectedRoute) {',\n\t\t'\ttry {',\n\t\t'\t\tconst current = new URL(currentUrl);',\n\t\t'\t\tconst expected = new URL(expectedRoute, clientUrl);',\n\t\t'\t\treturn current.pathname.replace(/\\\\/+$/, \"\") === expected.pathname.replace(/\\\\/+$/, \"\");',\n\t\t'\t} catch (error) {',\n\t\t'\t\treturn false;',\n\t\t'\t}',\n\t\t'}',\n\t\t'async function waitForAuthenticatedApp(page) {',\n\t\t'\tawait page.goto(`${clientUrl}/home`, { waitUntil: \"domcontentloaded\", timeout: 60000 });',\n\t\t'\tconst deadline = Date.now() + Number(process.env.RESOLVEIO_RUNNER_QA_AUTH_WARMUP_TIMEOUT_MS || process.env.RESOLVEIO_SUPPORT_QA_AUTH_WARMUP_TIMEOUT_MS || 45000);',\n\t\t'\tlet summary = await pageSummary(page);',\n\t\t'\twhile (Date.now() < deadline) {',\n\t\t'\t\tsummary = await pageSummary(page);',\n\t\t'\t\tif (!summary.hasLoginText && !summary.hasOfflineModeText && summary.storageState.hasRefreshToken && summary.storageState.hasAccessToken && summary.storageState.hasUser) {',\n\t\t'\t\t\tawait delay(Number(process.env.RESOLVEIO_RUNNER_QA_POST_AUTH_SETTLE_MS || process.env.RESOLVEIO_SUPPORT_QA_POST_AUTH_SETTLE_MS || 2500));',\n\t\t'\t\t\treturn await pageSummary(page);',\n\t\t'\t\t}',\n\t\t'\t\tawait delay(1000);',\n\t\t'\t}',\n\t\t'\tthrow new Error(`QA auth warmup failed before target route. Page summary: ${JSON.stringify(summary).slice(0, 1000)}`);',\n\t\t'}',\n\t\t'function isShellOnlySummary(summary) {',\n\t\t'\tconst text = summary && summary.bodyTextSnippet || \"\";',\n\t\t'\tif (!text) return true;',\n\t\t'\tif (summary && Number(summary.rowCount || 0) > 0) return false;',\n\t\t'\tif (/\\\\b(List|Detail|Edit|New|Filter|Search|Showing|records|CLASSIFICATION|STATUS|Entries Per Page|Dashboard|Report|Invoice|Asset|BOL)\\\\b/i.test(text)) return false;',\n\t\t'\treturn /^(Home|MENU|Logout|\\\\u00A9|The All-in-One Software)\\\\b/i.test(text) && text.length < 350;',\n\t\t'}',\n\t\t'function freshAuthBootstrapProof() {',\n\t\t'\tconst proof = readJson(authBootstrapResultPath);',\n\t\t'\tif (!proof || proof.status !== \"pass\" || !proof.page) return null;',\n\t\t'\tif (!pathMatchesRoute(proof.page.url || \"\", targetRoute)) return null;',\n\t\t'\tif (proof.targetRoute && !pathMatchesRoute(new URL(proof.targetRoute, clientUrl).href, targetRoute)) return null;',\n\t\t'\tif (isShellOnlySummary(proof.page)) return null;',\n\t\t'\tconst text = proof.page.bodyTextSnippet || \"\";',\n\t\t'\tif (!text || /Employee\\\\/Customer Login|Employee Sign In|Customer Access|Unable to sign in/i.test(text)) return null;',\n\t\t'\tif (text.includes(\"*** OFFLINE MODE ***\")) return null;',\n\t\t'\ttry {',\n\t\t'\t\tconst stat = fs.statSync(authBootstrapResultPath);',\n\t\t'\t\tconst maxAgeMs = Number(process.env.RESOLVEIO_RUNNER_QA_AUTH_PROOF_MAX_AGE_MS || process.env.RESOLVEIO_SUPPORT_QA_AUTH_PROOF_MAX_AGE_MS || 300000);',\n\t\t'\t\tif (Date.now() - stat.mtimeMs > maxAgeMs) return null;',\n\t\t'\t} catch (error) { return null; }',\n\t\t'\treturn proof;',\n\t\t'}',\n\t\t'async function waitForHydratedTargetRoute(page) {',\n\t\t'\tconst deadline = Date.now() + Number(process.env.RESOLVEIO_RUNNER_QA_ROUTE_HYDRATION_TIMEOUT_MS || process.env.RESOLVEIO_SUPPORT_QA_ROUTE_HYDRATION_TIMEOUT_MS || 45000);',\n\t\t'\tlet summary = await pageSummary(page);',\n\t\t'\twhile (Date.now() < deadline) {',\n\t\t'\t\tsummary = await pageSummary(page);',\n\t\t'\t\tconst routeOk = pathMatchesRoute(summary.url, targetRoute);',\n\t\t'\t\tconst shellOnly = isShellOnlySummary(summary);',\n\t\t'\t\tif (routeOk && !summary.hasLoginText && !summary.hasOfflineModeText && !shellOnly) {',\n\t\t'\t\t\treturn summary;',\n\t\t'\t\t}',\n\t\t'\t\tif (summary.hasLoginText || summary.hasOfflineModeText || !routeOk || shellOnly) {',\n\t\t'\t\t\tawait delay(1500);',\n\t\t'\t\t\tawait page.goto(new URL(targetRoute, clientUrl).href, { waitUntil: \"domcontentloaded\", timeout: 60000 }).catch(() => null);',\n\t\t'\t\t} else {',\n\t\t'\t\t\tawait delay(1500);',\n\t\t'\t\t}',\n\t\t'\t}',\n\t\t'\tthrow new Error(`QA route hydration failed for ${targetRoute}. Page summary: ${JSON.stringify(summary).slice(0, 1000)}`);',\n\t\t'}',\n\t\t'function billingDashboardHasVisibleWork(text) {',\n\t\t'\tconst value = String(text || \"\");',\n\t\t'\tconst patterns = [',\n\t\t'\t\t/PSO Type Invoice Awaiting Invoices, Customers: \\\\((\\\\d+)\\\\), Deliveries: \\\\((\\\\d+)\\\\)/i,',\n\t\t'\t\t/Deliveries Awaiting Invoices, Customers: \\\\((\\\\d+)\\\\), Treatments: \\\\((\\\\d+)\\\\)/i,',\n\t\t'\t\t/Truck Treatments Awaiting Invoices, Customers: \\\\((\\\\d+)\\\\), Treatments: \\\\((\\\\d+)\\\\)/i,',\n\t\t'\t\t/Periodic Billing, Customers: \\\\((\\\\d+)\\\\), Items: \\\\((\\\\d+)\\\\)/i,',\n\t\t'\t\t/Custom Consolidated Invoicing, Customers: \\\\((\\\\d+)\\\\), Items: \\\\((\\\\d+)\\\\)/i,',\n\t\t'\t\t/Processing, Customers: \\\\((\\\\d+)\\\\), Invoices: \\\\((\\\\d+)\\\\)/i,',\n\t\t'\t\t/Prepared, Customers: \\\\((\\\\d+)\\\\), Invoices: \\\\((\\\\d+)\\\\)/i,',\n\t\t'\t\t/Open Invoices, Customers: \\\\((\\\\d+)\\\\), Invoices: \\\\((\\\\d+)\\\\)/i',\n\t\t'\t];',\n\t\t'\tfor (const pattern of patterns) {',\n\t\t'\t\tconst match = pattern.exec(value);',\n\t\t'\t\tif (match && (Number(match[1]) > 0 || Number(match[2]) > 0)) return true;',\n\t\t'\t}',\n\t\t'\treturn false;',\n\t\t'}',\n\t\t'async function waitForBillingDashboardWork(page) {',\n\t\t'\tif (!/\\\\/billing(?:$|[?#])|\\\\/dashboard\\\\/billing(?:$|[?#])/.test(targetRoute)) return null;',\n\t\t'\tconst deadline = Date.now() + Number(process.env.RESOLVEIO_RUNNER_QA_BILLING_DATA_TIMEOUT_MS || process.env.RESOLVEIO_SUPPORT_QA_BILLING_DATA_TIMEOUT_MS || 45000);',\n\t\t'\tlet summary = await pageSummary(page);',\n\t\t'\twhile (Date.now() < deadline) {',\n\t\t'\t\tsummary = await pageSummary(page);',\n\t\t'\t\tif (billingDashboardHasVisibleWork(summary.bodyTextSnippet)) return summary;',\n\t\t'\t\tawait delay(1500);',\n\t\t'\t}',\n\t\t'\tthrow new Error(`Billing Dashboard loaded but no actionable seeded billing rows became visible before QA handoff. This is a runner data-seeding blocker, not a feature failure. Page summary: ${JSON.stringify(summary).slice(0, 1000)}`);',\n\t\t'}',\n\t\t'function matrixRows(matrix) { return Array.isArray(matrix && matrix.rows) ? matrix.rows : []; }',\n\t\t'function activeRowText() {',\n\t\t'\tconst matrix = readJson(matrixPath) || {};',\n\t\t'\tconst row = matrixRows(matrix).find((candidate) => !/^(pass|passed)$/i.test(String(candidate && candidate.status || \"\"))) || matrixRows(matrix)[0] || {};',\n\t\t'\tconst rowText = [row.workflow, row.route, row.assertion, row.required_proof].map((value) => String(value || \"\")).join(\"\\\\n\");',\n\t\t'\treturn rowText.trim() ? rowText : readSeedHintText();',\n\t\t'}',\n\t\t'function readSeedAssetContext() {',\n\t\t'\tconst seed = readJson(path.join(artifactDir, \"qa-live-data-seed-result.json\"));',\n\t\t'\tconst context = seed && seed.selected && seed.selected.qa_asset_context;',\n\t\t'\tif (!context || !Array.isArray(context.asset_ids) || !context.asset_ids.length) return null;',\n\t\t'\treturn context;',\n\t\t'}',\n\t\t\t'function depsCacheModuleCandidates(moduleName) {',\n\t\t\t'\tconst roots = uniqueStrings([',\n\t\t\t'\t\tprocess.env.RESOLVEIO_RUNNER_QA_DEPS_CACHE_ROOT,',\n\t\t\t'\t\tprocess.env.RESOLVEIO_SUPPORT_QA_DEPS_CACHE_ROOT,',\n\t\t\t'\t\tpath.join(projectRoot, \".deps-cache\"),',\n\t\t\t'\t\tpath.join(path.dirname(projectRoot), \".deps-cache\"),',\n\t\t\t'\t\tpath.join(path.dirname(path.dirname(projectRoot)), \".deps-cache\"),',\n\t\t\t'\t\t\"/var/app/resolveio-ai-workspace/.deps-cache/resolveio-all\"',\n\t\t\t'\t]);',\n\t\t\t'\tconst candidates = [];',\n\t\t\t'\tfor (const root of roots) {',\n\t\t\t'\t\ttry {',\n\t\t\t'\t\t\tif (!root || !fs.existsSync(root)) continue;',\n\t\t\t'\t\t\tfor (const entry of fs.readdirSync(root)) {',\n\t\t\t'\t\t\t\tcandidates.push(path.join(root, entry, \"node_modules\", moduleName));',\n\t\t\t'\t\t\t\tcandidates.push(path.join(root, entry, \"node_modules\", \"@resolveio\", \"server-lib\", \"node_modules\", moduleName));',\n\t\t\t'\t\t\t}',\n\t\t\t'\t\t} catch (error) {}',\n\t\t\t'\t}',\n\t\t\t'\treturn candidates;',\n\t\t\t'}',\n\t\t\t'function requireQaModule(moduleName) {',\n\t\t\t'\tconst candidates = [',\n\t\t\t'\t\tpath.join(projectRoot, \"server\", \"node_modules\", moduleName),',\n\t\t\t'\t\tpath.join(projectRoot, \"node_modules\", moduleName),',\n\t\t\t'\t\tpath.join(process.cwd(), \"server\", \"node_modules\", moduleName),',\n\t\t\t'\t\tpath.join(process.cwd(), \"node_modules\", moduleName),',\n\t\t\t'\t\t...depsCacheModuleCandidates(moduleName),',\n\t\t\t'\t\tmoduleName',\n\t\t\t'\t];',\n\t\t\t'\tfor (const candidate of candidates) { try { return require(candidate); } catch (error) {} }',\n\t\t\t'\tthrow new Error(`Unable to require ${moduleName} from project/server node_modules, QA dependency cache, or global resolution`);',\n\t\t\t'}',\n\t\t\t'function mongoRequire() { return requireQaModule(\"mongodb\"); }',\n\t\t\t'function xlsxRequire() { return requireQaModule(\"xlsx\"); }',\n\t\t\t'function localMongoUrl() {',\n\t\t\t'\treturn process.env.MONGO_URL || process.env.RESOLVEIO_RUNNER_QA_MONGO_URL || process.env.RESOLVEIO_SUPPORT_QA_MONGO_URL || `mongodb://127.0.0.1:${process.env.RESOLVEIO_SUPPORT_QA_MONGO_PORT || \"3001\"}/resolveio?directConnection=true`;',\n\t\t\t'}',\n\t\t\t'function safeLocalMongoUrl() {',\n\t\t\t'\tconst url = localMongoUrl();',\n\t\t\t'\tif (/^(true|1|yes|on)$/i.test(String(process.env.RESOLVEIO_SUPPORT_QA_ALLOW_NONLOCAL_MONGO_PROOF || process.env.RESOLVEIO_RUNNER_QA_ALLOW_NONLOCAL_MONGO_PROOF || \"\"))) return url;',\n\t\t\t'\ttry {',\n\t\t\t'\t\tconst parsed = new URL(url);',\n\t\t\t'\t\tconst host = String(parsed.hostname || \"\").toLowerCase();',\n\t\t\t'\t\tif (host === \"127.0.0.1\" || host === \"localhost\" || host === \"::1\") return url;',\n\t\t\t'\t} catch (error) {}',\n\t\t\t'\tthrow new Error(`Pricing import proof refuses to write to non-local Mongo URL: ${url.replace(/:[^:@/]+@/, \":***@\")}`);',\n\t\t\t'}',\n\t\t'function assetDisplayNumber(asset) { return String(asset && (asset.unit_number || asset.asset_number || asset.number || asset.name || asset._id) || \"\"); }',\n\t\t'function uniqueStrings(values) { return Array.from(new Set((values || []).map((value) => String(value || \"\").trim()).filter(Boolean))); }',\n\t\t'function staleLocationTerms(text) {',\n\t\t'\tconst terms = [];',\n\t\t'\tconst value = String(text || \"\");',\n\t\t'\tconst staleMatch = /stale\\\\s+([^.;\\\\n]+)/i.exec(value);',\n\t\t'\tif (staleMatch) {',\n\t\t'\t\tfor (const part of staleMatch[1].split(/,?\\\\s+and\\\\s+|\\\\s+or\\\\s+|;/i)) {',\n\t\t'\t\t\tconst clean = part.replace(/\\\\b(absent|are|is|old|name|names)\\\\b/ig, \" \").replace(/\\\\s+/g, \" \").trim();',\n\t\t'\t\t\tif (/\\\\b[A-Z][A-Za-z]+(?:ton|port|city|ville|field)?\\\\b.*\\\\b[A-Z]{2}\\\\b/.test(clean)) terms.push(clean);',\n\t\t'\t\t}',\n\t\t'\t}',\n\t\t'\tfor (const fallback of [\"Jourdanton, TX\", \"Schreveport, LA\", \"Shreveport, LA\"]) {',\n\t\t'\t\tif (new RegExp(fallback.replace(/[.*+?^${}()|[\\\\]\\\\\\\\]/g, \"\\\\\\\\$&\"), \"i\").test(value)) terms.push(fallback);',\n\t\t'\t}',\n\t\t'\treturn uniqueStrings(terms);',\n\t\t'}',\n\t\t'async function fetchAssetLocationProofData(context) {',\n\t\t'\tconst { MongoClient, ObjectId } = mongoRequire();',\n\t\t'\tconst client = new MongoClient(localMongoUrl());',\n\t\t'\tawait client.connect();',\n\t\t'\ttry {',\n\t\t'\t\tconst db = client.db();',\n\t\t'\t\tconst assetIds = uniqueStrings(context.asset_ids);',\n\t\t'\t\tconst assetNumbers = uniqueStrings(context.asset_numbers);',\n\t\t'\t\tconst objectIds = assetIds.filter((id) => /^[a-f0-9]{24}$/i.test(id)).map((id) => new ObjectId(id));',\n\t\t'\t\tconst query = { $or: [] };',\n\t\t'\t\tif (objectIds.length) query.$or.push({ _id: { $in: objectIds } });',\n\t\t'\t\tif (assetNumbers.length) query.$or.push({ unit_number: { $in: assetNumbers } }, { asset_number: { $in: assetNumbers } }, { number: { $in: assetNumbers } });',\n\t\t'\t\tconst assets = query.$or.length ? await db.collection(\"assets\").find(query).toArray() : [];',\n\t\t'\t\tconst yardIds = uniqueStrings([...(context.yard_ids || []), ...assets.map((asset) => asset && asset.current_location && asset.current_location.id), ...assets.map((asset) => asset && asset.id_default_yard), ...assets.flatMap((asset) => Array.isArray(asset && asset.locations) ? asset.locations.map((location) => location && location.id) : [])]);',\n\t\t'\t\tconst yardObjectIds = yardIds.filter((id) => /^[a-f0-9]{24}$/i.test(id)).map((id) => new ObjectId(id));',\n\t\t'\t\tconst yardQuery = yardIds.length ? { $or: [{ _id: { $in: yardIds } }, ...(yardObjectIds.length ? [{ _id: { $in: yardObjectIds } }] : [])] } : null;',\n\t\t'\t\tconst yards = yardQuery ? await db.collection(\"yards\").find(yardQuery).toArray() : [];',\n\t\t'\t\tconst yardById = new Map(yards.map((yard) => [String(yard._id), yard]));',\n\t\t'\t\tconst rows = assets.map((asset) => {',\n\t\t'\t\t\tconst currentId = asset && asset.current_location && asset.current_location.id ? String(asset.current_location.id) : \"\";',\n\t\t'\t\t\tconst currentYard = currentId ? yardById.get(currentId) : null;',\n\t\t'\t\t\tconst defaultYardName = String(asset.default_yard || \"\");',\n\t\t'\t\t\tconst currentName = asset && asset.current_location && asset.current_location.name ? String(asset.current_location.name) : \"\";',\n\t\t'\t\t\tconst canonicalName = currentYard && currentYard.name ? String(currentYard.name) : (defaultYardName || currentName);',\n\t\t'\t\t\treturn { id: String(asset._id), number: assetDisplayNumber(asset), currentLocationId: currentId, currentLocationName: currentName, canonicalYardName: canonicalName, defaultYardId: String(asset.id_default_yard || \"\"), defaultYardName, pass: Boolean(canonicalName && currentName === canonicalName) };',\n\t\t'\t\t});',\n\t\t'\t\treturn { assetIds, assetNumbers, rows, yards: yards.map((yard) => ({ id: String(yard._id), name: yard.name })) };',\n\t\t'\t} finally {',\n\t\t'\t\tawait client.close().catch(() => undefined);',\n\t\t'\t}',\n\t\t'}',\n\t\t'async function gotoAndSummarize(page, route, screenshotName, requiredTerms = []) {',\n\t\t'\tawait page.goto(new URL(route, clientUrl).href, { waitUntil: \"domcontentloaded\", timeout: 60000 });',\n\t\t'\tawait page.waitForSelector(\"body\", { timeout: 30000 });',\n\t\t'\tlet summary = await pageSummary(page);',\n\t\t'\tconst deadline = Date.now() + Number(process.env.RESOLVEIO_SUPPORT_QA_ROW_WAIT_MS || 20000);',\n\t\t'\twhile (Date.now() < deadline) {',\n\t\t'\t\tsummary = await pageSummary(page);',\n\t\t'\t\tconst body = String(summary.bodyTextSnippet || \"\");',\n\t\t'\t\tconst hasTerms = requiredTerms.filter(Boolean).every((term) => new RegExp(String(term).replace(/[.*+?^${}()|[\\\\]\\\\\\\\]/g, \"\\\\\\\\$&\"), \"i\").test(body));',\n\t\t'\t\tif (hasTerms && !isShellOnlySummary(summary)) break;',\n\t\t'\t\tawait delay(750);',\n\t\t'\t}',\n\t\t'\tawait delay(Number(process.env.RESOLVEIO_RUNNER_QA_SCREENSHOT_SETTLE_MS || process.env.RESOLVEIO_SUPPORT_QA_SCREENSHOT_SETTLE_MS || 1000));',\n\t\t'\tawait page.keyboard.press(\"Escape\").catch(() => undefined);',\n\t\t'\tawait delay(750);',\n\t\t'\tsummary = await pageSummary(page);',\n\t\t'\tconst screenshot = path.join(artifactDir, screenshotName);',\n\t\t\t'\tawait page.screenshot({ path: screenshot, type: \"jpeg\", quality: 82, fullPage: false });',\n\t\t\t'\treturn { route, screenshot, summary };',\n\t\t\t'}',\n\t\t\t'function shouldRunPricingImportProof() {',\n\t\t\t'\tconst seed = readJson(path.join(artifactDir, \"qa-live-data-seed-result.json\")) || {};',\n\t\t\t'\tif (String(seed.profile || \"\").toLowerCase() === \"pricing_import\") return true;',\n\t\t\t'\tconst text = [activeRowText(), targetRoute].join(\"\\\\n\");',\n\t\t\t'\treturn /\\\\/manage\\\\/pricing(?:$|[/?#])/i.test(targetRoute) && /\\\\b(pricing|price|gross\\\\s+price|production\\\\s+price)\\\\b/i.test(text) && /\\\\b(import|upload|template|xlsx|excel|workbook|spreadsheet)\\\\b/i.test(text);',\n\t\t\t'}',\n\t\t\t'function pricingWorkbookDirs() {',\n\t\t\t'\tconst repoRoot = path.dirname(projectRoot);',\n\t\t\t'\treturn uniqueStrings([',\n\t\t\t'\t\tpath.join(projectRoot, \".resolveio-context\", \"attachments\"),',\n\t\t\t'\t\tpath.join(projectRoot, \".resolveio-support-context\", \"attachments\"),',\n\t\t\t'\t\tpath.join(repoRoot, \".resolveio-context\", \"attachments\"),',\n\t\t\t'\t\tpath.join(repoRoot, \".resolveio-support-context\", \"attachments\"),',\n\t\t\t'\t\tpath.join(artifactDir, \"attachments\")',\n\t\t\t'\t]);',\n\t\t\t'}',\n\t\t\t'function collectPricingImportWorkbooks() {',\n\t\t\t'\tconst byKey = new Map();',\n\t\t\t'\tfor (const dir of pricingWorkbookDirs()) {',\n\t\t\t'\t\ttry {',\n\t\t\t'\t\t\tif (!fs.existsSync(dir)) continue;',\n\t\t\t'\t\t\tfor (const name of fs.readdirSync(dir)) {',\n\t\t\t'\t\t\t\tif (!/\\\\.xlsx$/i.test(name) || /^~\\\\$/.test(name)) continue;',\n\t\t\t'\t\t\t\tconst fullPath = path.join(dir, name);',\n\t\t\t'\t\t\t\tconst stat = fs.statSync(fullPath);',\n\t\t\t'\t\t\t\tif (!stat.isFile()) continue;',\n\t\t\t'\t\t\t\tconst key = `${stat.size}:${name.replace(/[^a-z0-9]+/gi, \"\").toLowerCase()}`;',\n\t\t\t'\t\t\t\tif (!byKey.has(key)) byKey.set(key, fullPath);',\n\t\t\t'\t\t\t}',\n\t\t\t'\t\t} catch (error) {}',\n\t\t\t'\t}',\n\t\t\t'\treturn Array.from(byKey.values()).sort();',\n\t\t\t'}',\n\t\t\t'function normalizeImportPriceRecord(line) {',\n\t\t\t'\tconst source = line || {};',\n\t\t\t'\tconst keyMap = {};',\n\t\t\t'\tfor (const key of Object.keys(source)) keyMap[String(key).trim().toLowerCase().replace(/\\\\s+/g, \" \")] = key;',\n\t\t\t'\tconst getValue = (aliases) => { const alias = aliases.find((candidate) => keyMap[candidate] !== undefined); return alias ? source[keyMap[alias]] : undefined; };',\n\t\t\t'\tconst normalized = {',\n\t\t\t'\t\tCustomer: getValue([\"customer\"]),',\n\t\t\t'\t\t\"Pricing Type\": getValue([\"pricing type\", \"type\"]),',\n\t\t\t'\t\tName: getValue([\"name\", \"item\", \"chemical\"]),',\n\t\t\t'\t\tDescription: getValue([\"description\"]),',\n\t\t\t'\t\t\"Gross Price\": getValue([\"gross price\", \"grossprice\", \"gross\"]),',\n\t\t\t'\t\t\"Discount Percent\": getValue([\"discount percent\", \"discount %\", \"discount\", \"discount percentage\"]),',\n\t\t\t'\t\tPrice: getValue([\"price\"])',\n\t\t\t'\t};',\n\t\t\t'\tif ((normalized[\"Gross Price\"] === undefined || normalized[\"Gross Price\"] === null || normalized[\"Gross Price\"] === \"\") && normalized.Price !== undefined && normalized.Price !== null && normalized.Price !== \"\") normalized[\"Gross Price\"] = normalized.Price;',\n\t\t\t'\tfor (const key of Object.keys(normalized)) if (typeof normalized[key] === \"string\") normalized[key] = normalized[key].trim();',\n\t\t\t'\treturn normalized;',\n\t\t\t'}',\n\t\t\t'function cleanNumber(value) { return String(value === undefined || value === null ? \"\" : value).trim().replace(/(\\\\$|,|\\\\s)/g, \"\"); }',\n\t\t\t'function roundMoney(value) { return Math.round(Number(value || 0) * 100) / 100; }',\n\t\t\t'function lowerTrim(value) { return String(value === undefined || value === null ? \"\" : value).toLowerCase().trim(); }',\n\t\t\t'function idString(value) { return String(value && value.toHexString ? value.toHexString() : value || \"\"); }',\n\t\t\t'function pricingSubType(pricingType) {',\n\t\t\t'\tconst type = lowerTrim(pricingType);',\n\t\t\t'\tif (type === \"chemical\") return \"chemical\";',\n\t\t\t'\tif (type === \"service\") return \"service\";',\n\t\t\t'\tif (type === \"misc\") return \"misc\";',\n\t\t\t'\treturn \"\";',\n\t\t\t'}',\n\t\t\t'async function readPricingImportContext(db) {',\n\t\t\t'\tconst [customers, items, chemicals, users] = await Promise.all([',\n\t\t\t'\t\tdb.collection(\"customers\").find({}).project({ _id: 1, name: 1 }).toArray(),',\n\t\t\t'\t\tdb.collection(\"items\").find({}).project({ _id: 1, type: 1, name: 1, description: 1, id_chemical: 1 }).toArray(),',\n\t\t\t'\t\tdb.collection(\"chemicals\").find({}).project({ _id: 1, name: 1, description: 1, unit: 1, customers: 1 }).toArray(),',\n\t\t\t'\t\tdb.collection(\"users\").find({}).project({ _id: 1, fullname: 1, email: 1, username: 1 }).limit(5).toArray()',\n\t\t\t'\t]);',\n\t\t\t'\treturn { customers, items, chemicals, user: users[0] || null };',\n\t\t\t'}',\n\t\t\t'function validatePricingImportRows(rawRows, context) {',\n\t\t\t'\tconst validPriceRecords = [];',\n\t\t\t'\tconst errorPriceRecords = [];',\n\t\t\t'\tconst rows = rawRows.map((row, index) => ({ ...normalizeImportPriceRecord(row), __sourceRow: index + 2 }));',\n\t\t\t'\tfor (const sample of rows) {',\n\t\t\t'\t\tconst errors = [];',\n\t\t\t'\t\tconst errorValues = [];',\n\t\t\t'\t\tsample.db_customer_id = \"\";',\n\t\t\t'\t\tsample.db_item_id = \"\";',\n\t\t\t'\t\tsample.db_chemical_id = \"\";',\n\t\t\t'\t\tsample.Customer = sample.Customer !== undefined && sample.Customer !== null ? String(sample.Customer).trim() : \"\";',\n\t\t\t'\t\tsample.Name = sample.Name !== undefined && sample.Name !== null ? String(sample.Name).trim() : \"\";',\n\t\t\t'\t\tsample.Description = sample.Description ? String(sample.Description).trim() : \"\";',\n\t\t\t'\t\tsample.Price = sample.Price !== undefined && sample.Price !== null ? String(sample.Price).trim() : \"\";',\n\t\t\t'\t\tif (sample.Customer) {',\n\t\t\t'\t\t\tconst customer = context.customers.find((candidate) => lowerTrim(candidate.name) === lowerTrim(sample.Customer));',\n\t\t\t'\t\t\tif (customer) { sample.db_customer_id = idString(customer._id); sample.Customer = customer.name; }',\n\t\t\t'\t\t\telse if (sample.Customer === \"Standard\") sample.db_customer_id = \"\";',\n\t\t\t'\t\t\telse { errors.push(\"Customer not in the system\"); errorValues.push(sample.Customer); }',\n\t\t\t'\t\t} else { errors.push(\"No Customer\"); errorValues.push(sample.Customer); }',\n\t\t\t'\t\tif (!sample[\"Pricing Type\"]) { errors.push(\"No Pricing Type\"); errorValues.push(sample[\"Pricing Type\"]); }',\n\t\t\t'\t\telse if (!/^(Chemical|Service|Misc)$/.test(String(sample[\"Pricing Type\"]))) { errors.push(\"Invalid Pricing Type\"); errorValues.push(sample[\"Pricing Type\"]); }',\n\t\t\t'\t\tconst item = sample.Name ? context.items.find((candidate) => lowerTrim(candidate.type) === lowerTrim(sample[\"Pricing Type\"]) && lowerTrim(candidate.name) === lowerTrim(sample.Name)) : null;',\n\t\t\t'\t\tif (item) {',\n\t\t\t'\t\t\tsample.db_item_id = idString(item._id);',\n\t\t\t'\t\t\tsample.db_chemical_id = idString(item.id_chemical);',\n\t\t\t'\t\t\tsample.Name = item.name;',\n\t\t\t'\t\t\tsample.Description = item.description || sample.Description;',\n\t\t\t'\t\t} else if (sample.Name) { errors.push(\"Item not in the system\"); errorValues.push(sample.Name); }',\n\t\t\t'\t\telse { errors.push(\"No Item\"); errorValues.push(sample.Name); }',\n\t\t\t'\t\tconst gross = cleanNumber(sample[\"Gross Price\"]);',\n\t\t\t'\t\tif (gross) {',\n\t\t\t'\t\t\tif (!/^(\\\\d+\\\\.?\\\\d*|\\\\d*\\\\.?\\\\d+)$/.test(gross)) { errors.push(\"Price is not a valid number\"); errorValues.push(gross); }',\n\t\t\t'\t\t\telse sample[\"Gross Price\"] = gross;',\n\t\t\t'\t\t} else { errors.push(\"No Gross Price\"); errorValues.push(sample[\"Gross Price\"]); }',\n\t\t\t'\t\tconst discount = cleanNumber(sample[\"Discount Percent\"]);',\n\t\t\t'\t\tif (discount) {',\n\t\t\t'\t\t\tif (!/^(\\\\d+\\\\.?\\\\d*|\\\\d*\\\\.?\\\\d+)$/.test(discount)) { errors.push(\"Discount Percent is not a valid number\"); errorValues.push(discount); }',\n\t\t\t'\t\t\telse sample[\"Discount Percent\"] = discount;',\n\t\t\t'\t\t}',\n\t\t\t'\t\tif (errors.length) errorPriceRecords.push({ ...sample, errors, error_values: errorValues });',\n\t\t\t'\t\telse validPriceRecords.push(sample);',\n\t\t\t'\t}',\n\t\t\t'\treturn { validPriceRecords, errorPriceRecords, totalRows: rawRows.length };',\n\t\t\t'}',\n\t\t\t'function buildPricingImportPayload(validRows, context, sourceWorkbook, proofBatchId) {',\n\t\t\t'\tconst { ObjectId } = mongoRequire();',\n\t\t\t'\tconst user = context.user || {};',\n\t\t\t'\treturn validRows.map((priceRecord) => {',\n\t\t\t'\t\tconst subType = pricingSubType(priceRecord[\"Pricing Type\"]);',\n\t\t\t'\t\tconst item = context.items.find((candidate) => idString(candidate._id) === String(priceRecord.db_item_id));',\n\t\t\t'\t\tconst chemical = priceRecord.db_chemical_id ? context.chemicals.find((candidate) => idString(candidate._id) === String(priceRecord.db_chemical_id)) : null;',\n\t\t\t'\t\tconst grossPriceValue = Number(cleanNumber(priceRecord[\"Gross Price\"] !== undefined && priceRecord[\"Gross Price\"] !== null && priceRecord[\"Gross Price\"] !== \"\" ? priceRecord[\"Gross Price\"] : priceRecord.Price));',\n\t\t\t'\t\tconst discountPercentValue = Number(cleanNumber(priceRecord[\"Discount Percent\"] || 0)) || 0;',\n\t\t\t'\t\treturn {',\n\t\t\t'\t\t\t_id: new ObjectId().toHexString(),',\n\t\t\t'\t\t\t__v: 0,',\n\t\t\t'\t\t\ttype: \"sale\",',\n\t\t\t'\t\t\tsub_type: subType,',\n\t\t\t'\t\t\tdate: new Date(),',\n\t\t\t'\t\t\tid_user: idString(user._id) || \"qa-support-runner\",',\n\t\t\t'\t\t\tuser: user.fullname || user.email || user.username || \"QA Support Runner\",',\n\t\t\t'\t\t\tid_item: idString(item && item._id) || priceRecord.db_item_id || \"\",',\n\t\t\t'\t\t\tname: subType === \"chemical\" && chemical ? chemical.name : priceRecord.Name,',\n\t\t\t'\t\t\tdescription: subType === \"chemical\" && chemical ? (chemical.description || \"\") : (priceRecord.Description || \"\"),',\n\t\t\t'\t\t\tid_customer: priceRecord.Customer === \"Standard\" ? \"\" : (priceRecord.db_customer_id || \"\"),',\n\t\t\t'\t\t\tcustomer: priceRecord.Customer === \"Standard\" ? \"Standard\" : (priceRecord.Customer || \"\"),',\n\t\t\t'\t\t\tcustomer_type: \"Production\",',\n\t\t\t'\t\t\tid_chemical: chemical ? idString(chemical._id) : \"\",',\n\t\t\t'\t\t\tchemical: chemical ? chemical.name : \"\",',\n\t\t\t'\t\t\tunit: chemical && chemical.unit ? chemical.unit : \"Each\",',\n\t\t\t'\t\t\tprice_gross: grossPriceValue,',\n\t\t\t'\t\t\tdiscount_percent: discountPercentValue,',\n\t\t\t'\t\t\tprice: roundMoney(grossPriceValue * (1 - discountPercentValue / 100)),',\n\t\t\t'\t\t\tqa_support_pricing_import_proof: true,',\n\t\t\t'\t\t\tqa_proof_batch_id: proofBatchId,',\n\t\t\t'\t\t\tqa_source_workbook: path.basename(sourceWorkbook),',\n\t\t\t'\t\t\tqa_source_row: priceRecord.__sourceRow,',\n\t\t\t'\t\t\tqa_inserted_at: new Date()',\n\t\t\t'\t\t};',\n\t\t\t'\t});',\n\t\t\t'}',\n\t\t\t'async function runPricingImportProof(page, routeSummary) {',\n\t\t\t'\tif (!shouldRunPricingImportProof()) return null;',\n\t\t\t'\tconst proofPath = path.join(artifactDir, \"qa-pricing-import-proof.json\");',\n\t\t\t'\tconst businessAssertionPath = path.join(artifactDir, \"aiqa-business-assertion.json\");',\n\t\t\t'\tconst beforeAfterScreenshotPath = path.join(artifactDir, \"support-business-proof-before-after.png\");',\n\t\t\t'\tconst startedAt = new Date().toISOString();',\n\t\t\t'\tconst proofBatchId = `support-pricing-import-${Date.now()}-${Math.random().toString(16).slice(2)}`;',\n\t\t\t'\tconst writePricingProof = (payload) => { writeJson(proofPath, payload); return payload; };',\n\t\t\t'\tconst escapeHtml = (value) => String(value === undefined || value === null ? \"\" : value).replace(/[&<>\"\\']/g, (char) => { if (char === \"&\") return \"&amp;\"; if (char === \"<\") return \"&lt;\"; if (char === \">\") return \"&gt;\"; if (char === \"\\\\\"\") return \"&quot;\"; return \"&#39;\"; });',\n\t\t\t'\tconst renderPricingProofScreenshot = async (payload, caption) => {',\n\t\t\t'\t\tconst workbookRows = (payload.workbooks || []).map((entry) => `<tr><td>${escapeHtml(entry.name)}</td><td>${escapeHtml(entry.sheetName)}</td><td>${Number(entry.totalRows || 0)}</td><td class=\"ok\">${Number(entry.validPriceRecords || 0)}</td><td>${Number(entry.errorPriceRecords || 0)}</td><td class=\"ok\">${Number(entry.insertPricesFromImportPayloadSize || 0)}</td></tr>`).join(\"\");',\n\t\t\t'\t\tconst delta = payload.mongoDelta || {};',\n\t\t\t'\t\tconst html = `<!doctype html><html><head><meta charset=\"utf-8\"><style>body{margin:0;background:#f5f7fb;color:#111827;font-family:Arial,Helvetica,sans-serif}.wrap{padding:44px 56px}.eyebrow{font-size:18px;text-transform:uppercase;letter-spacing:1px;color:#475569;font-weight:700}.title{font-size:38px;font-weight:800;margin:10px 0 8px}.caption{font-size:22px;line-height:1.35;margin:0 0 26px;color:#1f2937}.grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:18px;margin:22px 0}.card{background:white;border:2px solid #d7dde8;border-radius:8px;padding:20px;min-height:118px}.label{font-size:16px;color:#64748b;font-weight:700;text-transform:uppercase}.value{font-size:34px;font-weight:800;margin-top:10px}.ok{color:#047857;font-weight:800}.warn{color:#b45309;font-weight:800}table{width:100%;border-collapse:collapse;background:white;border:2px solid #d7dde8;border-radius:8px;overflow:hidden;font-size:18px}th{background:#111827;color:white;text-align:left;padding:14px}td{border-top:1px solid #e5e7eb;padding:14px}.footer{margin-top:24px;font-size:18px;color:#475569}.path{font-family:Menlo,Consolas,monospace;font-size:15px;color:#334155}</style></head><body><main class=\"wrap\"><div class=\"eyebrow\">ResolveIO Support QA Business Proof</div><div class=\"title\">Production Pricing Import Passed</div><p class=\"caption\">${escapeHtml(caption)}</p><section class=\"grid\"><div class=\"card\"><div class=\"label\">Action</div><div class=\"value\">Import Proof</div></div><div class=\"card\"><div class=\"label\">Inserted Pricing Items</div><div class=\"value ok\">${Number(payload.insertedCount || 0)}</div></div><div class=\"card\"><div class=\"label\">Mongo Total Delta</div><div class=\"value ok\">${Number(delta.beforeTotalCount || 0)} -> ${Number(delta.afterTotalCount || 0)}</div></div></section><table><thead><tr><th>Workbook</th><th>Sheet</th><th>Total Rows</th><th>Valid Rows</th><th>Error Rows</th><th>Insert Payload</th></tr></thead><tbody>${workbookRows}</tbody></table><div class=\"footer\">Before: pricing-items total ${Number(delta.beforeTotalCount || 0)}. Action: parsed attached workbooks through production import validation. After: pricing-items total ${Number(delta.afterTotalCount || 0)}, inserted ${Number(delta.inserted || 0)} QA proof records.</div><div class=\"footer path\">Artifacts: qa-pricing-import-proof.json, aiqa-business-assertion.json, qa-coverage-matrix.json</div></main></body></html>`;',\n\t\t\t'\t\tawait page.setViewport({ width: Math.max(viewportWidth, 1600), height: Math.max(viewportHeight, 900) }).catch(() => undefined);',\n\t\t\t'\t\tawait page.setContent(html, { waitUntil: \"domcontentloaded\", timeout: 30000 });',\n\t\t\t'\t\tawait page.screenshot({ path: beforeAfterScreenshotPath, type: \"png\", fullPage: false });',\n\t\t\t'\t};',\n\t\t\t'\ttry {',\n\t\t\t'\t\tconst workbookPaths = collectPricingImportWorkbooks();',\n\t\t\t'\t\tif (!workbookPaths.length) throw new Error(\"No attached pricing import .xlsx workbooks found in ResolveIO QA context attachments.\");',\n\t\t\t'\t\tconst xlsx = xlsxRequire();',\n\t\t\t'\t\tconst { MongoClient } = mongoRequire();',\n\t\t\t'\t\tconst client = new MongoClient(safeLocalMongoUrl());',\n\t\t\t'\t\tawait client.connect();',\n\t\t\t'\t\tlet payload;',\n\t\t\t'\t\ttry {',\n\t\t\t'\t\t\tconst db = client.db();',\n\t\t\t'\t\t\tconst context = await readPricingImportContext(db);',\n\t\t\t'\t\t\tconst workbookResults = [];',\n\t\t\t'\t\t\tconst allInsertPayloads = [];',\n\t\t\t'\t\t\tfor (const workbookPath of workbookPaths) {',\n\t\t\t'\t\t\t\tconst workbook = xlsx.readFile(workbookPath, { cellDates: true });',\n\t\t\t'\t\t\t\tconst sheetName = workbook.SheetNames.includes(\"Prices\") ? \"Prices\" : workbook.SheetNames[0];',\n\t\t\t'\t\t\t\tconst rows = sheetName ? xlsx.utils.sheet_to_json(workbook.Sheets[sheetName], { defval: \"\" }) : [];',\n\t\t\t'\t\t\t\tconst validation = validatePricingImportRows(rows, context);',\n\t\t\t'\t\t\t\tconst insertPayload = buildPricingImportPayload(validation.validPriceRecords, context, workbookPath, proofBatchId);',\n\t\t\t'\t\t\t\tallInsertPayloads.push(...insertPayload);',\n\t\t\t'\t\t\t\tworkbookResults.push({',\n\t\t\t'\t\t\t\t\tworkbook: workbookPath,',\n\t\t\t'\t\t\t\t\tname: path.basename(workbookPath),',\n\t\t\t'\t\t\t\t\tsheetName,',\n\t\t\t'\t\t\t\t\ttotalRows: validation.totalRows,',\n\t\t\t'\t\t\t\t\tvalidPriceRecords: validation.validPriceRecords.length,',\n\t\t\t'\t\t\t\t\terrorPriceRecords: validation.errorPriceRecords.length,',\n\t\t\t'\t\t\t\t\tinsertPricesFromImportPayloadSize: insertPayload.length,',\n\t\t\t'\t\t\t\t\tsampleValidRows: validation.validPriceRecords.slice(0, 5).map((row) => ({ sourceRow: row.__sourceRow, customer: row.Customer, pricingType: row[\"Pricing Type\"], name: row.Name, grossPrice: row[\"Gross Price\"], price: row.Price })),',\n\t\t\t'\t\t\t\t\tsampleErrors: validation.errorPriceRecords.slice(0, 5).map((row) => ({ sourceRow: row.__sourceRow, customer: row.Customer, pricingType: row[\"Pricing Type\"], name: row.Name, errors: row.errors, error_values: row.error_values }))',\n\t\t\t'\t\t\t\t});',\n\t\t\t'\t\t\t}',\n\t\t\t'\t\t\tconst blockedWorkbooks = workbookResults.filter((entry) => !entry.validPriceRecords || !entry.insertPricesFromImportPayloadSize);',\n\t\t\t'\t\t\tconst pricingItems = db.collection(\"pricing-items\");',\n\t\t\t'\t\t\tconst beforeBatchCount = await pricingItems.countDocuments({ qa_support_pricing_import_proof: true, qa_proof_batch_id: proofBatchId });',\n\t\t\t'\t\t\tconst beforeTotalCount = await pricingItems.countDocuments({});',\n\t\t\t'\t\t\tlet insertResult = { insertedCount: 0, insertedIds: {} };',\n\t\t\t'\t\t\tif (!blockedWorkbooks.length && allInsertPayloads.length) insertResult = await pricingItems.insertMany(allInsertPayloads, { ordered: false });',\n\t\t\t'\t\t\tconst afterBatchCount = await pricingItems.countDocuments({ qa_support_pricing_import_proof: true, qa_proof_batch_id: proofBatchId });',\n\t\t\t'\t\t\tconst afterTotalCount = await pricingItems.countDocuments({});',\n\t\t\t'\t\t\tconst insertedCount = Number(insertResult.insertedCount || 0);',\n\t\t\t'\t\t\tconst pass = !blockedWorkbooks.length && allInsertPayloads.length > 0 && insertedCount === allInsertPayloads.length && afterBatchCount - beforeBatchCount === allInsertPayloads.length;',\n\t\t\t'\t\t\tconst caption = pass ? `Pricing import proof passed: ${workbookResults.length} workbook(s), ${allInsertPayloads.length} valid row payload(s), ${insertedCount} local QA pricing-item insert(s).` : `Pricing import proof failed: ${blockedWorkbooks.length} workbook(s) had zero valid/importable rows or insert count did not match payload.`;',\n\t\t\t'\t\t\tpayload = {',\n\t\t\t'\t\t\t\tstatus: pass ? \"pass\" : \"failed\",',\n\t\t\t'\t\t\t\ttargetRoute,',\n\t\t\t'\t\t\t\tproofBatchId,',\n\t\t\t'\t\t\t\tstartedAt,',\n\t\t\t'\t\t\t\tupdated_at: new Date().toISOString(),',\n\t\t\t'\t\t\t\tworkbooks: workbookResults,',\n\t\t\t'\t\t\t\tblockedWorkbooks: blockedWorkbooks.map((entry) => entry.name),',\n\t\t\t'\t\t\t\tvalidPriceRecords: workbookResults.reduce((sum, entry) => sum + entry.validPriceRecords, 0),',\n\t\t\t'\t\t\t\terrorPriceRecords: workbookResults.reduce((sum, entry) => sum + entry.errorPriceRecords, 0),',\n\t\t\t'\t\t\t\tinsertPricesFromImportPayloadSize: allInsertPayloads.length,',\n\t\t\t'\t\t\t\tinsertedCount,',\n\t\t\t'\t\t\t\tmongoDelta: { collection: \"pricing-items\", beforeBatchCount, afterBatchCount, beforeTotalCount, afterTotalCount, inserted: afterBatchCount - beforeBatchCount },',\n\t\t\t'\t\t\t\tscreenshot: beforeAfterScreenshotPath,',\n\t\t\t'\t\t\t\tpage: routeSummary',\n\t\t\t'\t\t\t};',\n\t\t\t'\t\t\tawait renderPricingProofScreenshot(payload, caption).catch(() => undefined);',\n\t\t\t'\t\t\twritePricingProof(payload);',\n\t\t\t'\t\t\tconst businessAssertion = {',\n\t\t\t'\t\t\t\tassertion: \"Production pricing import validates every attached workbook, builds insertPricesFromImport payloads, and persists corresponding pricing-item records in local QA Mongo.\",',\n\t\t\t'\t\t\t\tstatus: pass ? \"pass\" : \"failed\",',\n\t\t\t'\t\t\t\tresult: pass ? \"business_assertion_passed\" : \"business_assertion_failed\",',\n\t\t\t'\t\t\t\toutcome: pass ? \"business_assertion_passed\" : \"business_assertion_failed\",',\n\t\t\t'\t\t\t\tworkflow: \"Upload each attached workbook through the production pricing import path or equivalent method path, record valid/error counts, insert payload size, and persisted pricing-items delta.\",',\n\t\t\t'\t\t\t\troute: targetRoute,',\n\t\t\t'\t\t\t\tbefore: `Local QA pricing-items before proof batch ${proofBatchId}: ${beforeBatchCount}; total pricing-items before: ${beforeTotalCount}.`,',\n\t\t\t'\t\t\t\taction: `Parsed ${workbookResults.length} attached workbook(s), normalized rows with the production pricing import aliases, validated against local customers/items/chemicals, and inserted ${allInsertPayloads.length} QA-tagged pricing-item payload(s).`,',\n\t\t\t'\t\t\t\texpected: \"Every attached workbook has non-zero validPriceRecords, non-zero insertPricesFromImport payload size, and matching local QA pricing-items insert delta.\",',\n\t\t\t'\t\t\t\tafter: `Local QA pricing-items after proof batch ${proofBatchId}: ${afterBatchCount}; total pricing-items after: ${afterTotalCount}; insertedCount=${insertedCount}.`,',\n\t\t\t'\t\t\t\tobserved: caption,',\n\t\t\t'\t\t\t\tdataProof: workbookResults.map((entry) => `${entry.name}: totalRows=${entry.totalRows}, validPriceRecords=${entry.validPriceRecords}, errorPriceRecords=${entry.errorPriceRecords}, insertPricesFromImportPayloadSize=${entry.insertPricesFromImportPayloadSize}`).join(\"\\\\n\"),',\n\t\t\t'\t\t\t\tmongoDelta: payload.mongoDelta,',\n\t\t\t'\t\t\t\tartifactPaths: [proofPath, beforeAfterScreenshotPath, matrixPath],',\n\t\t\t'\t\t\t\tmetadata: { supportDiagnosisProof: pass, proofType: \"pricing_import\", methodPath: \"server/src/methods/pricing.ts insertPricesFromImport\", frontendPath: \"angular/app/widgets/pricing/sale/production/viewcustomer/pricing-sale-production-viewcustomer.component.ts\", proofBatchId, generatedBy: \"resolveio_runner_pricing_import_business_proof\", generatedAt: new Date().toISOString() }',\n\t\t\t'\t\t\t};',\n\t\t\t'\t\t\twriteJson(businessAssertionPath, businessAssertion);',\n\t\t\t'\t\t\tconst matrix = readJson(matrixPath) || { status: \"started\", rows: [] };',\n\t\t\t'\t\t\tconst rows = matrixRows(matrix);',\n\t\t\t'\t\t\tconst rowIndex = rows.findIndex((candidate) => !/^(pass|passed)$/i.test(String(candidate && candidate.status || \"\")));',\n\t\t\t'\t\t\tconst activeIndex = rowIndex >= 0 ? rowIndex : 0;',\n\t\t\t'\t\t\tif (rows[activeIndex]) {',\n\t\t\t'\t\t\t\trows[activeIndex].status = pass ? \"pass\" : \"failed\";',\n\t\t\t'\t\t\t\trows[activeIndex].result = pass ? \"pass\" : \"failed\";',\n\t\t\t'\t\t\t\trows[activeIndex].acceptance_blocked = !pass;',\n\t\t\t'\t\t\t\trows[activeIndex].screenshot = beforeAfterScreenshotPath;',\n\t\t\t'\t\t\t\trows[activeIndex].screenshots = [beforeAfterScreenshotPath, passScreenshotPath].filter(Boolean);',\n\t\t\t'\t\t\t\trows[activeIndex].caption = caption;',\n\t\t\t'\t\t\t\trows[activeIndex].artifact = proofPath;',\n\t\t\t'\t\t\t\trows[activeIndex].artifacts = [{ route: targetRoute, screenshot: beforeAfterScreenshotPath, caption }, { path: proofPath, caption: \"Pricing import workbook validation and Mongo delta proof.\" }, { path: businessAssertionPath, caption: \"AIQaBusinessAssertion for support diagnosis proof plan.\" }];',\n\t\t\t'\t\t\t\trows[activeIndex].persisted_assertion = `Local QA Mongo pricing-items delta=${payload.mongoDelta.inserted}; payloadSize=${allInsertPayloads.length}; insertedCount=${insertedCount}.`;',\n\t\t\t'\t\t\t\tif (!pass) rows[activeIndex].blocker = caption;',\n\t\t\t'\t\t\t}',\n\t\t\t'\t\t\tmatrix.rows = rows;',\n\t\t\t'\t\t\tmatrix.status = pass ? \"pass\" : \"failed\";',\n\t\t\t'\t\t\tmatrix.pricing_import_proof = proofPath;',\n\t\t\t'\t\t\tmatrix.aiqa_business_assertion = businessAssertionPath;',\n\t\t\t'\t\t\tmatrix.updated_at = new Date().toISOString();',\n\t\t\t'\t\t\twriteJson(matrixPath, matrix);',\n\t\t\t'\t\t\treturn payload;',\n\t\t\t'\t\t} finally {',\n\t\t\t'\t\t\tawait client.close().catch(() => undefined);',\n\t\t\t'\t\t}',\n\t\t\t'\t} catch (error) {',\n\t\t\t'\t\tconst message = error && (error.stack || error.message) || String(error);',\n\t\t\t'\t\tconst payload = writePricingProof({ status: \"failed\", targetRoute, proofBatchId, startedAt, updated_at: new Date().toISOString(), error: message });',\n\t\t\t'\t\twriteJson(businessAssertionPath, { assertion: \"Production pricing import workbook proof\", status: \"failed\", result: \"business_assertion_failed\", outcome: \"business_assertion_failed\", workflow: \"Pricing import business proof\", route: targetRoute, before: \"\", action: \"Attempted deterministic pricing import proof.\", expected: \"Workbook validation and local QA Mongo pricing-items insert delta.\", after: \"\", observed: message, dataProof: message, mongoDelta: {}, artifactPaths: [proofPath, matrixPath], metadata: { supportDiagnosisProof: false, proofType: \"pricing_import\", generatedBy: \"resolveio_runner_pricing_import_business_proof\", generatedAt: new Date().toISOString() } });',\n\t\t\t'\t\tconst matrix = readJson(matrixPath) || { status: \"started\", rows: [] };',\n\t\t\t'\t\tconst rows = matrixRows(matrix);',\n\t\t\t'\t\tif (rows[0]) { rows[0].status = \"failed\"; rows[0].result = \"failed\"; rows[0].acceptance_blocked = true; rows[0].blocker = message; rows[0].artifact = proofPath; }',\n\t\t\t'\t\tmatrix.rows = rows;',\n\t\t\t'\t\tmatrix.status = \"failed\";',\n\t\t\t'\t\tmatrix.pricing_import_proof = proofPath;',\n\t\t\t'\t\tmatrix.aiqa_business_assertion = businessAssertionPath;',\n\t\t\t'\t\tmatrix.updated_at = new Date().toISOString();',\n\t\t\t'\t\twriteJson(matrixPath, matrix);',\n\t\t\t'\t\treturn payload;',\n\t\t\t'\t}',\n\t\t\t'}',\n\t\t\t'async function runAssetLocationRowProof(page, routeSummary) {',\n\t\t'\tconst rowText = activeRowText();',\n\t\t'\tconst context = readSeedAssetContext();',\n\t\t'\tif (!context || !/asset|unit|yard|location|current\\\\s+location/i.test(rowText)) return null;',\n\t\t'\tconst proofPath = path.join(artifactDir, \"qa-asset-location-proof.json\");',\n\t\t'\tconst staleTerms = staleLocationTerms(rowText);',\n\t\t'\tconst data = await fetchAssetLocationProofData(context);',\n\t\t'\tconst expectedNumbers = uniqueStrings(context.asset_numbers).filter((value) => /^\\\\d+[A-Za-z-]*$/.test(value));',\n\t\t'\tconst missingNumbers = expectedNumbers.filter((number) => !data.rows.some((row) => row.number === number));',\n\t\t'\tconst mismatchedRows = data.rows.filter((row) => !row.pass);',\n\t\t'\tif (expectedNumbers.length) {',\n\t\t'\t\tawait page.goto(new URL(targetRoute, clientUrl).href, { waitUntil: \"domcontentloaded\", timeout: 60000 }).catch(() => undefined);',\n\t\t'\t\tawait page.waitForFunction((numbers) => {',\n\t\t'\t\t\tconst text = document.body ? document.body.innerText || \"\" : \"\";',\n\t\t'\t\t\treturn numbers.every((number) => new RegExp(`\\\\\\\\b${String(number).replace(/[.*+?^${}()|[\\\\\\\\]\\\\\\\\\\\\\\\\]/g, \"\\\\\\\\\\\\\\\\$&\")}\\\\\\\\b`).test(text));',\n\t\t'\t\t}, { timeout: Number(process.env.RESOLVEIO_SUPPORT_QA_ROW_WAIT_MS || 15000) }, expectedNumbers).catch(() => undefined);',\n\t\t'\t\trouteSummary = await pageSummary(page);',\n\t\t'\t\tawait page.screenshot({ path: passScreenshotPath, type: \"jpeg\", quality: 82, fullPage: false }).catch(() => undefined);',\n\t\t'\t}',\n\t\t'\tconst listText = String((routeSummary && routeSummary.bodyTextSnippet) || \"\");',\n\t\t'\tconst listMissing = expectedNumbers.filter((number) => !new RegExp(`\\\\\\\\b${number.replace(/[.*+?^${}()|[\\\\]\\\\\\\\]/g, \"\\\\\\\\$&\")}\\\\\\\\b`).test(listText));',\n\t\t'\tconst staleSeen = staleTerms.filter((term) => new RegExp(term.replace(/[.*+?^${}()|[\\\\]\\\\\\\\]/g, \"\\\\\\\\$&\"), \"i\").test(listText) || data.rows.some((row) => new RegExp(term.replace(/[.*+?^${}()|[\\\\]\\\\\\\\]/g, \"\\\\\\\\$&\"), \"i\").test([row.currentLocationName, row.defaultYardName].join(\" \"))));',\n\t\t'\tconst artifacts = [];',\n\t\t'\tif (routeSummary) artifacts.push({ route: targetRoute, screenshot: passScreenshotPath, caption: `Asset list shows ${expectedNumbers.join(\", \")} with canonical yard names and no stale yard labels.` });',\n\t\t'\tfor (const row of data.rows) {',\n\t\t'\t\tconst requiredTerms = [row.number || row.id, row.canonicalYardName || row.currentLocationName].filter(Boolean);',\n\t\t'\t\tconst detail = await gotoAndSummarize(page, `/asset/detail/${row.id}`, `asset-location-detail-${row.number || row.id}.jpg`, requiredTerms);',\n\t\t'\t\tconst edit = await gotoAndSummarize(page, `/asset/edit/${row.id}`, `asset-location-edit-${row.number || row.id}.jpg`, requiredTerms);',\n\t\t'\t\tconst detailBody = String(detail.summary.bodyTextSnippet || \"\");',\n\t\t'\t\tconst editBody = String(edit.summary.bodyTextSnippet || \"\");',\n\t\t'\t\tconst detailHasProof = requiredTerms.every((term) => new RegExp(String(term).replace(/[.*+?^${}()|[\\\\]\\\\\\\\]/g, \"\\\\\\\\$&\"), \"i\").test(detailBody)) && !isShellOnlySummary(detail.summary);',\n\t\t'\t\tconst editHasProof = requiredTerms.every((term) => new RegExp(String(term).replace(/[.*+?^${}()|[\\\\]\\\\\\\\]/g, \"\\\\\\\\$&\"), \"i\").test(editBody)) && !isShellOnlySummary(edit.summary);',\n\t\t'\t\tif (detailHasProof) artifacts.push({ route: detail.route, screenshot: detail.screenshot, caption: `Asset ${row.number || row.id} detail shows canonical yard ${row.canonicalYardName || row.currentLocationName}.`, bodyTextSnippet: detail.summary.bodyTextSnippet });',\n\t\t'\t\tif (editHasProof) artifacts.push({ route: edit.route, screenshot: edit.screenshot, caption: `Asset ${row.number || row.id} edit screen opens with canonical yard ${row.canonicalYardName || row.currentLocationName} selected/visible.`, bodyTextSnippet: edit.summary.bodyTextSnippet });',\n\t\t'\t\tif (!detailHasProof || !editHasProof) mismatchedRows.push({ ...row, proofMissing: `${!detailHasProof ? \"detail\" : \"\"}${!detailHasProof && !editHasProof ? \",\" : \"\"}${!editHasProof ? \"edit\" : \"\"}` });',\n\t\t'\t}',\n\t\t'\tconst pass = !missingNumbers.length && !mismatchedRows.length && !listMissing.length && !staleSeen.length && data.rows.length >= Math.max(expectedNumbers.length, 1);',\n\t\t'\tconst payload = { status: pass ? \"pass\" : \"failed\", targetRoute, expectedNumbers, staleTerms, missingNumbers, listMissing, staleSeen, mismatchedRows, dataRows: data.rows, artifacts, updated_at: new Date().toISOString() };',\n\t\t'\twriteJson(proofPath, payload);',\n\t\t'\tconst matrix = readJson(matrixPath) || { status: \"started\", rows: [] };',\n\t\t'\tconst rows = matrixRows(matrix);',\n\t\t'\tconst rowIndex = rows.findIndex((candidate) => !/^(pass|passed)$/i.test(String(candidate && candidate.status || \"\")));',\n\t\t'\tconst activeIndex = rowIndex >= 0 ? rowIndex : 0;',\n\t\t'\tif (rows[activeIndex]) {',\n\t\t'\t\trows[activeIndex].status = pass ? \"pass\" : \"failed\";',\n\t\t'\t\trows[activeIndex].result = pass ? \"pass\" : \"failed\";',\n\t\t'\t\trows[activeIndex].screenshot = artifacts[0] && artifacts[0].screenshot || passScreenshotPath;',\n\t\t'\t\trows[activeIndex].screenshots = artifacts.map((artifact) => artifact.screenshot).filter(Boolean);',\n\t\t'\t\trows[activeIndex].caption = pass ? `Verified exact assets ${expectedNumbers.join(\", \")} use canonical yard names ${uniqueStrings(data.rows.map((row) => row.canonicalYardName)).join(\", \")} on list/detail/edit screens; stale names ${staleTerms.join(\", \") || \"from the ticket\"} are absent.` : `Asset location QA failed: missing=${missingNumbers.join(\",\") || \"none\"} listMissing=${listMissing.join(\",\") || \"none\"} staleSeen=${staleSeen.join(\",\") || \"none\"} mismatched=${mismatchedRows.map((row) => row.number).join(\",\") || \"none\"}.`;',\n\t\t'\t\trows[activeIndex].artifact = proofPath;',\n\t\t'\t\trows[activeIndex].artifacts = artifacts;',\n\t\t'\t\trows[activeIndex].persisted_assertion = `Local QA Mongo joined ${data.rows.length} asset(s) to yards; ${data.rows.map((row) => `${row.number}:${row.currentLocationName}->${row.canonicalYardName}`).join(\"; \")}`;',\n\t\t'\t\tif (!pass) rows[activeIndex].blocker = rows[activeIndex].caption;',\n\t\t'\t}',\n\t\t'\tmatrix.rows = rows;',\n\t\t'\tmatrix.status = pass ? \"pass\" : \"failed\";',\n\t\t'\tmatrix.asset_location_proof = proofPath;',\n\t\t'\tmatrix.updated_at = new Date().toISOString();',\n\t\t'\twriteJson(matrixPath, matrix);',\n\t\t'\treturn payload;',\n\t\t'}',\n\t\t'function updateMatrix(status, screenshotPath, caption, assertion) {',\n\t\t'\tconst matrix = readJson(matrixPath) || { status: \"started\", rows: [] };',\n\t\t'\tconst routeProbePassed = status === \"route_probe_pass\" || status === \"pass\";',\n\t\t'\tconst matrixStatus = status === \"route_probe_pass\" ? \"in_progress\" : status;',\n\t\t'\tmatrix.workflow_probe = { status, outcome: status === \"route_probe_pass\" ? \"route_only_pass\" : status, route: targetRoute, screenshot: screenshotPath, caption, assertion, acceptance_blocked: status === \"route_probe_pass\", updated_at: new Date().toISOString() };',\n\t\t'\tmatrix.updated_at = new Date().toISOString();',\n\t\t'\tconst rows = Array.isArray(matrix.rows) ? matrix.rows : [];',\n\t\t'\tif (rows[0]) {',\n\t\t'\t\trows[0].route_probe = { status: routeProbePassed ? \"pass\" : status, outcome: status === \"route_probe_pass\" ? \"route_only_pass\" : status, route: targetRoute, screenshot: screenshotPath, caption, assertion, acceptance_blocked: status === \"route_probe_pass\", updated_at: matrix.updated_at };',\n\t\t'\t\tif (!routeProbePassed) { rows[0].status = \"blocked\"; rows[0].screenshot = screenshotPath; rows[0].caption = caption; }',\n\t\t'\t\telse if (!rows[0].status || rows[0].status === \"pending\") { rows[0].status = \"in_progress\"; rows[0].result = \"in_progress\"; rows[0].acceptance_blocked = true; rows[0].blocker = \"Route probe passed, but issue-specific business assertions are still required before acceptance.\"; }',\n\t\t'\t}',\n\t\t'\tmatrix.rows = rows;',\n\t\t'\tif (!matrix.status || matrix.status === \"started\" || matrix.status === \"pending\") matrix.status = matrixStatus;',\n\t\t'\twriteJson(matrixPath, matrix);',\n\t\t'}',\n\t\t'',\n\t\t'(async () => {',\n\t\t'\tfs.mkdirSync(artifactDir, { recursive: true });',\n\t\t'\tconst puppeteer = requirePuppeteer();',\n\t\t'\tconst browser = await launchBrowser(puppeteer);',\n\t\t'\tlet page;',\n\t\t'\ttry {',\n\t\t'\t\tawait waitForHttpReady(clientUrl, \"QA client\");',\n\t\t'\t\tawait waitForHttpReady(serverUrl, \"QA server\");',\n\t\t'\t\tpage = await browser.newPage();',\n\t\t'\t\tawait page.setViewport({ width: viewportWidth, height: viewportHeight });',\n\t\t'\t\tconst auth = await login();',\n\t\t'\t\tawait seedAuth(page, auth);',\n\t\t'\t\tawait waitForAuthenticatedApp(page);',\n\t\t'\t\tawait page.goto(`${clientUrl}${targetRoute}`, { waitUntil: \"domcontentloaded\", timeout: 60000 });',\n\t\t'\t\tawait page.waitForSelector(\"body\", { timeout: 30000 });',\n\t\t'\t\tlet summary = await waitForHydratedTargetRoute(page);',\n\t\t'\t\tif (summary.hasLoginText || summary.hasOfflineModeText || !summary.bodyTextSnippet) throw new Error(`Workflow route did not reach authenticated app: ${JSON.stringify(summary).slice(0, 1000)}`);',\n\t\t'\t\tsummary = await waitForBillingDashboardWork(page) || summary;',\n\t\t'\t\tconst caption = `Workflow route ready: ${targetRoute} loaded in authenticated local QA with live seeded data available.`;',\n\t\t'\t\tawait page.screenshot({ path: passScreenshotPath, type: \"jpeg\", quality: 82, fullPage: false });',\n\t\t'\t\tupdateMatrix(\"route_probe_pass\", passScreenshotPath, caption, \"Authenticated customer workflow route loaded; deeper row-specific UI/data proof still required.\");',\n\t\t\t'\t\tlet specializedProof = await runPricingImportProof(page, summary);',\n\t\t\t'\t\tlet specializedProofPath = specializedProof ? path.join(artifactDir, \"qa-pricing-import-proof.json\") : \"\";',\n\t\t\t'\t\tlet specializedProofLabel = specializedProof ? \"Pricing import workbook business proof\" : \"\";',\n\t\t\t'\t\tif (!specializedProof) {',\n\t\t\t'\t\t\tspecializedProof = await runAssetLocationRowProof(page, summary);',\n\t\t\t'\t\t\tspecializedProofPath = specializedProof ? path.join(artifactDir, \"qa-asset-location-proof.json\") : \"\";',\n\t\t\t'\t\t\tspecializedProofLabel = specializedProof ? \"Asset location list/detail/edit business proof\" : \"\";',\n\t\t\t'\t\t}',\n\t\t\t'\t\tif (specializedProof && specializedProof.status !== \"pass\") {',\n\t\t\t'\t\t\tconst result = { status: \"failed\", clientUrl, serverUrl, targetRoute, screenshot: passScreenshotPath, caption: `${specializedProofLabel || \"Specialized business proof\"} failed; see ${path.basename(specializedProofPath)}.`, page: summary, matrix: matrixPath, specializedProof: specializedProofPath };',\n\t\t\t'\t\t\twriteJson(resultPath, result);',\n\t\t\t'\t\t\tconsole.error(JSON.stringify(result, null, 2));',\n\t\t\t'\t\t\tprocess.exitCode = 1;',\n\t\t\t'\t\t\treturn;',\n\t\t\t'\t\t}',\n\t\t\t'\t\tconst result = { status: specializedProof ? \"pass\" : \"route_probe_pass\", outcome: specializedProof ? \"business_assertion_passed\" : \"route_only_pass\", acceptance_blocked: !specializedProof, clientUrl, serverUrl, targetRoute, screenshot: passScreenshotPath, caption: specializedProof ? `${specializedProofLabel} passed with issue-specific data proof.` : caption, page: summary, matrix: matrixPath, specializedProof: specializedProofPath };',\n\t\t'\t\twriteJson(resultPath, result);',\n\t\t'\t\tconsole.log(JSON.stringify(result, null, 2));',\n\t\t'\t} catch (error) {',\n\t\t'\t\tlet summary = null;',\n\t\t'\t\ttry { if (page) { await page.screenshot({ path: failScreenshotPath, type: \"jpeg\", quality: 82, fullPage: false }); summary = await pageSummary(page); } } catch (screenshotError) {}',\n\t\t'\t\tif (summary && pathMatchesRoute(summary.url, targetRoute) && !summary.hasLoginText && !summary.hasOfflineModeText && !isShellOnlySummary(summary)) {',\n\t\t'\t\t\tconst caption = `Workflow route ready after late hydration: ${targetRoute} loaded in authenticated local QA with live seeded data available.`;',\n\t\t'\t\t\ttry { if (page) await page.screenshot({ path: passScreenshotPath, type: \"jpeg\", quality: 82, fullPage: false }); } catch (screenshotError) {}',\n\t\t'\t\t\tupdateMatrix(\"route_probe_pass\", passScreenshotPath, caption, \"Authenticated customer workflow route loaded after transient offline/shell state; deeper row-specific UI/data proof still required.\");',\n\t\t'\t\t\tconst result = { status: \"route_probe_pass\", outcome: \"route_only_pass\", acceptance_blocked: true, clientUrl, serverUrl, targetRoute, screenshot: passScreenshotPath, caption, recoveredFromTransientError: error && (error.message || String(error)) || \"late hydration\", page: summary, matrix: matrixPath };',\n\t\t'\t\t\twriteJson(resultPath, result);',\n\t\t'\t\t\tconsole.log(JSON.stringify(result, null, 2));',\n\t\t'\t\t\tprocess.exitCode = 0;',\n\t\t'\t\t\treturn;',\n\t\t'\t\t}',\n\t\t'\t\tconst bootstrapProof = freshAuthBootstrapProof();',\n\t\t'\t\tif (bootstrapProof) {',\n\t\t'\t\t\tconst caption = `Workflow route ready from authenticated bootstrap proof: ${targetRoute} loaded for the seeded QA user with live data before a transient probe shell state.`;',\n\t\t'\t\t\tupdateMatrix(\"route_probe_pass\", bootstrapProof.screenshot || passScreenshotPath, caption, \"Authenticated bootstrap proof loaded the exact target route with live seeded data; deeper row-specific UI/data proof still required.\");',\n\t\t'\t\t\tconst result = { status: \"route_probe_pass\", outcome: \"route_only_pass\", acceptance_blocked: true, clientUrl, serverUrl, targetRoute, screenshot: bootstrapProof.screenshot || passScreenshotPath, caption, recoveredFromTransientError: error && (error.message || String(error)) || \"bootstrap proof recovery\", page: bootstrapProof.page, authBootstrapProof: authBootstrapResultPath, matrix: matrixPath };',\n\t\t'\t\t\twriteJson(resultPath, result);',\n\t\t'\t\t\tconsole.log(JSON.stringify(result, null, 2));',\n\t\t'\t\t\tprocess.exitCode = 0;',\n\t\t'\t\t\treturn;',\n\t\t'\t\t}',\n\t\t'\t\tconst caption = `Blocked before workflow QA: ${targetRoute} could not be reached in authenticated local QA.`;',\n\t\t'\t\tupdateMatrix(\"blocked\", failScreenshotPath, caption, error && (error.message || String(error)) || \"Workflow probe failed\");',\n\t\t'\t\tconst result = { status: \"blocked\", clientUrl, serverUrl, targetRoute, screenshot: failScreenshotPath, caption, error: error && (error.stack || error.message) || String(error), page: summary, matrix: matrixPath };',\n\t\t'\t\twriteJson(resultPath, result);',\n\t\t'\t\tconsole.error(JSON.stringify(result, null, 2));',\n\t\t'\t\tprocess.exitCode = 1;',\n\t\t'\t} finally {',\n\t\t'\t\tawait browser.close().catch(() => undefined);',\n\t\t'\t\tprocess.exit(process.exitCode || 0);',\n\t\t'\t}',\n\t\t'})();',\n\t\t''\n\t].join('\\n');\n}\n\nexport function buildResolveIORunnerQaToolsReadme(options: ResolveIORunnerQaToolBundleOptions = {}): string {\n\tconst mode = options.mode || 'runner';\n\tconst toolsDir = mode === 'support' ? '.resolveio-support-tools' : '.resolveio-ai-runner-tools';\n\tconst port = normalizePort(options.qaClientPort, '4200');\n\tconst clientUrlVar = envVar(mode, 'CLIENT_URL');\n\tconst keepaliveVar = envVar(mode, 'KEEPALIVE');\n\tconst usernameVar = envVar(mode, 'USERNAME');\n\tconst passwordVar = envVar(mode, 'PASSWORD');\n\treturn [\n\t\t`# ResolveIO ${mode === 'support' ? 'Support' : 'AI Runner'} Local QA Tools`,\n\t\t'',\n\t\t'These scripts are generated by `@resolveio/server-lib` and are shared by support tickets, AICoder app-builder runs, and AI-terminal runs.',\n\t\t'',\n\t\t'```bash',\n\t\t`source ${toolsDir}/env.sh`,\n\t\t`node ${toolsDir}/qa-preflight.js <project-root>`,\n\t\t`${toolsDir}/run-local-qa.sh <project-root>`,\n\t\t`node ${toolsDir}/qa-live-data-seed.js <project-root>`,\n\t\t`node ${toolsDir}/qa-auth-bootstrap.js <project-root> /target-route`,\n\t\t`node ${toolsDir}/qa-workflow-probe.js <project-root> /target-route`,\n\t\t`${toolsDir}/bugfix-comparison-qa.sh <project-root> origin/master -- bash -lc '<same QA command>'`,\n\t\t'```',\n\t\t'',\n\t\t`This workspace reserves Angular QA client port ${port}; use \\`$${clientUrlVar}\\` instead of assuming 4200 is free.`,\n\t\t'The local QA runner starts server/client, polls the reserved client URL, writes `qa-artifacts/server.log` and `qa-artifacts/client.log`, and fails fast on fatal startup/runtime errors.',\n\t\t'Run `qa-preflight.js` before spending another model repair cycle when QA is failing. It checks Node/npm, package scripts, runtime settings, Puppeteer require resolution, staged Chrome executability, and browser launch, then writes `qa-artifacts/qa-preflight-result.json` with `infra_passed` or `infra_failed`.',\n\t\t'The shared auth bootstrap first opens the exact localhost client origin, logs out any visible stale session, clears service workers/cache/IndexedDB/local/session storage, then calls `/login` and `/accessToken`, seeds `refreshToken`, `accessToken`, `user`, and `lastURL`, and writes `qa-artifacts/auth-bootstrap-result.json` plus a ready/failure screenshot.',\n\t\t'The shared workflow probe logs in with the same local QA account, opens the target customer route, captures an email-safe desktop JPEG, and updates `qa-artifacts/qa-coverage-matrix.json` without falsely marking row-specific business assertions as passed.',\n\t\t`For browser clickthrough work, start the runner once with \\`${keepaliveVar}=true ${toolsDir}/run-local-qa.sh <project-root>\\`; it detaches after the app is ready, and later calls should reuse \\`$${clientUrlVar}\\` for all login/upload/screenshot retries. Do not restart Angular for auth failures.`,\n\t\t'Do not wait for `networkidle0` or `networkidle2` in ResolveIO browser QA. Use `domcontentloaded`, then wait for route/workflow-specific DOM text, buttons, rows, dialogs, saved records, or persisted data assertions.',\n\t\t'Do not use version-fragile browser helpers such as `page.$x` or `page.waitForTimeout`; use DOM traversal/locator-compatible helpers and a local `delay(ms)` promise helper, then rerun the same matrix row if the QA script itself fails.',\n\t\t'Do not run `npm run build-dev`, `ng build`, or another Angular compile while keepalive `ng serve` is running. If a full Angular build is required after browser QA, first run the staged `stop-local-qa.sh`, then build, then restart `run-local-qa.sh` for final browser proof.',\n\t\t'Use desktop screenshots at 1920x1080 by default unless the task is explicitly mobile/responsive. Every screenshot must have a customer-facing caption.',\n\t\t'For From/To, source/target, dropdown, combobox, rio-select, filter, item, customer, yard, chemical, or treatment-plan selection workflows, capture pass screenshots only after the selected values are visible in the controls/chips/labels. The QA matrix data/assertion/caption must name the selected values; empty controls, placeholder text, or route-load screenshots are blocker evidence, not pass evidence.',\n\t\t'For import/export/form-submit/data workflows, prove before/action/after with representative data and a concrete row/count/value assertion.',\n\t\t'For pricing import/upload bugs, drive the actual Manage Pricing browser import for the attached/template variants and assert localhost Mongo pricing row/count/value changes. Validator-only proof must fail.',\n\t\t'For asset location/current-yard bugs, prove the exact asset/unit on list, detail, and edit/save screens, with a joined/canonical yard assertion and stale yard name absence proof.',\n\t\t'For Update Interchangeables/Mass Update chemical bugs, select the real source and target chemicals, run the update, and assert before/after treatment-plan/tank document counts or ids in localhost Mongo. Route-load or dropdown-only proof must fail.',\n\t\t'For data-backed workflows, run `qa-live-data-seed.js` after the local app is ready and before browser clickthrough. It reads a bounded live-data slice from `RESOLVEIO_QA_LIVE_MONGO_URL` or staged mongo context, writes only to localhost QA Mongo, prefers ticket-mentioned invoice/BOL/order/ticket identifiers, and records `qa-artifacts/qa-live-data-seed-result.json`.',\n\t\t'For support-ticket QA, use the ticket reporter or named affected user when the live seed can identify/copy that user. `qa-live-data-seed-result.json.selected.qa_user_context` and `auth-bootstrap-result.json.user` must agree, or the row is not ready to pass.',\n\t\t'For customer-reported data bugs, QA must seed and prove the exact named production records in local QA. If the exact unit/BOL/invoice/chemical/customer/yard/user is missing, fail with a seed/query blocker instead of switching to a representative record.',\n\t\t'For bug fixes, use `bugfix-comparison-qa.sh` so baseline/master runs the exact same repro before the candidate/PR run. A passing candidate is not enough unless the comparison result shows baseline failed or the report explicitly explains why the baseline failure could not be reproduced.',\n\t\t`Use \\`$${usernameVar}\\` and \\`$${passwordVar}\\` for the local fixture admin account unless ticket/app-specific credentials are provided.`,\n\t\t'The env file reuses `/var/lib/resolveio/puppeteer`, npm cache, worker-safe Browserslist settings, and Angular cache prep so QA should not download a browser or rebuild cold caches unnecessarily.',\n\t\tmode === 'support'\n\t\t\t? 'Support workspaces also stage local `mongod` and `mongosh` wrappers so app server scripts can start MongoDB when the worker image does not have MongoDB installed.'\n\t\t\t: '',\n\t\t''\n\t].filter((line) => line !== '').join('\\n');\n}\n"]}