lastlight 0.1.15 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (478) hide show
  1. package/README.md +265 -118
  2. package/agent-context/rules.md +62 -9
  3. package/agent-context/security.md +69 -0
  4. package/config/default.yaml +89 -0
  5. package/deploy/.env.production.example +20 -2
  6. package/deploy/entrypoint.sh +16 -17
  7. package/deploy/native/README.md +160 -0
  8. package/deploy/native/install.sh +110 -0
  9. package/deploy/native/lastlight.env.example +95 -0
  10. package/deploy/native/lastlight.service +50 -0
  11. package/deploy/sandbox-entrypoint.sh +59 -42
  12. package/dist/admin/auth.d.ts +1 -1
  13. package/dist/admin/auth.js +3 -1
  14. package/dist/admin/auth.js.map +1 -1
  15. package/dist/admin/chat-session-reader.d.ts +11 -14
  16. package/dist/admin/chat-session-reader.js +27 -51
  17. package/dist/admin/chat-session-reader.js.map +1 -1
  18. package/dist/admin/docker.d.ts +37 -0
  19. package/dist/admin/docker.js +86 -1
  20. package/dist/admin/docker.js.map +1 -1
  21. package/dist/admin/index.js +38 -3
  22. package/dist/admin/index.js.map +1 -1
  23. package/dist/admin/log-search.test.d.ts +1 -0
  24. package/dist/admin/log-search.test.js +78 -0
  25. package/dist/admin/log-search.test.js.map +1 -0
  26. package/dist/admin/routes.d.ts +52 -3
  27. package/dist/admin/routes.js +780 -63
  28. package/dist/admin/routes.js.map +1 -1
  29. package/dist/admin/routes.test.js +680 -14
  30. package/dist/admin/routes.test.js.map +1 -1
  31. package/dist/admin/server-logs.test.d.ts +1 -0
  32. package/dist/admin/server-logs.test.js +58 -0
  33. package/dist/admin/server-logs.test.js.map +1 -0
  34. package/dist/admin/sessions.d.ts +26 -39
  35. package/dist/admin/sessions.js +86 -310
  36. package/dist/admin/sessions.js.map +1 -1
  37. package/dist/admin/sessions.test.d.ts +1 -0
  38. package/dist/admin/sessions.test.js +78 -0
  39. package/dist/admin/sessions.test.js.map +1 -0
  40. package/dist/admin/version.d.ts +15 -0
  41. package/dist/admin/version.js +73 -0
  42. package/dist/admin/version.js.map +1 -0
  43. package/dist/admin/version.test.d.ts +1 -0
  44. package/dist/admin/version.test.js +71 -0
  45. package/dist/admin/version.test.js.map +1 -0
  46. package/dist/cli-config.d.ts +55 -0
  47. package/dist/cli-config.js +119 -0
  48. package/dist/cli-config.js.map +1 -0
  49. package/dist/cli-config.test.d.ts +1 -0
  50. package/dist/cli-config.test.js +92 -0
  51. package/dist/cli-config.test.js.map +1 -0
  52. package/dist/cli-format.d.ts +19 -0
  53. package/dist/cli-format.js +107 -0
  54. package/dist/cli-format.js.map +1 -0
  55. package/dist/cli-server.d.ts +73 -0
  56. package/dist/cli-server.js +347 -0
  57. package/dist/cli-server.js.map +1 -0
  58. package/dist/cli-server.test.d.ts +1 -0
  59. package/dist/cli-server.test.js +38 -0
  60. package/dist/cli-server.test.js.map +1 -0
  61. package/dist/cli-timeline.d.ts +35 -0
  62. package/dist/cli-timeline.js +373 -0
  63. package/dist/cli-timeline.js.map +1 -0
  64. package/dist/cli-timeline.test.d.ts +1 -0
  65. package/dist/cli-timeline.test.js +104 -0
  66. package/dist/cli-timeline.test.js.map +1 -0
  67. package/dist/cli.d.ts +0 -19
  68. package/dist/cli.js +910 -194
  69. package/dist/cli.js.map +1 -1
  70. package/dist/config-overlay.test.d.ts +1 -0
  71. package/dist/config-overlay.test.js +112 -0
  72. package/dist/config-overlay.test.js.map +1 -0
  73. package/dist/config-resolve.d.ts +28 -0
  74. package/dist/config-resolve.js +47 -0
  75. package/dist/config-resolve.js.map +1 -0
  76. package/dist/config-resolve.test.d.ts +1 -0
  77. package/dist/config-resolve.test.js +68 -0
  78. package/dist/config-resolve.test.js.map +1 -0
  79. package/dist/config.d.ts +62 -49
  80. package/dist/config.js +452 -76
  81. package/dist/config.js.map +1 -1
  82. package/dist/config.test.js +201 -32
  83. package/dist/config.test.js.map +1 -1
  84. package/dist/connectors/github-webhook.js +83 -5
  85. package/dist/connectors/github-webhook.js.map +1 -1
  86. package/dist/connectors/github-webhook.test.d.ts +1 -0
  87. package/dist/connectors/github-webhook.test.js +156 -0
  88. package/dist/connectors/github-webhook.test.js.map +1 -0
  89. package/dist/connectors/messaging/session-manager.d.ts +18 -0
  90. package/dist/connectors/messaging/session-manager.js +83 -2
  91. package/dist/connectors/messaging/session-manager.js.map +1 -1
  92. package/dist/connectors/messaging/session-manager.test.d.ts +1 -0
  93. package/dist/connectors/messaging/session-manager.test.js +144 -0
  94. package/dist/connectors/messaging/session-manager.test.js.map +1 -0
  95. package/dist/connectors/slack/connector.d.ts +9 -0
  96. package/dist/connectors/slack/connector.js +15 -0
  97. package/dist/connectors/slack/connector.js.map +1 -1
  98. package/dist/connectors/slack/mrkdwn.js +81 -0
  99. package/dist/connectors/slack/mrkdwn.js.map +1 -1
  100. package/dist/connectors/slack/mrkdwn.test.js +49 -0
  101. package/dist/connectors/slack/mrkdwn.test.js.map +1 -1
  102. package/dist/connectors/types.d.ts +1 -1
  103. package/dist/cron/fanout.d.ts +33 -0
  104. package/dist/cron/fanout.js +55 -0
  105. package/dist/cron/fanout.js.map +1 -0
  106. package/dist/cron/fanout.test.d.ts +1 -0
  107. package/dist/cron/fanout.test.js +73 -0
  108. package/dist/cron/fanout.test.js.map +1 -0
  109. package/dist/cron/jobs.d.ts +5 -0
  110. package/dist/cron/jobs.js +10 -3
  111. package/dist/cron/jobs.js.map +1 -1
  112. package/dist/cron/scheduler.d.ts +12 -0
  113. package/dist/cron/scheduler.js +27 -1
  114. package/dist/cron/scheduler.js.map +1 -1
  115. package/dist/engine/agent-executor.d.ts +158 -0
  116. package/dist/engine/agent-executor.js +1140 -0
  117. package/dist/engine/agent-executor.js.map +1 -0
  118. package/dist/engine/agent-executor.test.d.ts +1 -0
  119. package/dist/engine/agent-executor.test.js +395 -0
  120. package/dist/engine/agent-executor.test.js.map +1 -0
  121. package/dist/engine/chat-runner.d.ts +123 -0
  122. package/dist/engine/chat-runner.js +379 -0
  123. package/dist/engine/chat-runner.js.map +1 -0
  124. package/dist/engine/chat-runner.test.d.ts +1 -0
  125. package/dist/engine/chat-runner.test.js +104 -0
  126. package/dist/engine/chat-runner.test.js.map +1 -0
  127. package/dist/engine/chat-skills.d.ts +45 -0
  128. package/dist/engine/chat-skills.js +184 -0
  129. package/dist/engine/chat-skills.js.map +1 -0
  130. package/dist/engine/chat-skills.test.d.ts +1 -0
  131. package/dist/engine/chat-skills.test.js +20 -0
  132. package/dist/engine/chat-skills.test.js.map +1 -0
  133. package/dist/engine/chat.d.ts +20 -23
  134. package/dist/engine/chat.js +251 -155
  135. package/dist/engine/chat.js.map +1 -1
  136. package/dist/engine/chat.test.d.ts +1 -0
  137. package/dist/engine/chat.test.js +42 -0
  138. package/dist/engine/chat.test.js.map +1 -0
  139. package/dist/engine/classifier.d.ts +35 -2
  140. package/dist/engine/classifier.js +170 -31
  141. package/dist/engine/classifier.js.map +1 -1
  142. package/dist/engine/classifier.test.d.ts +1 -0
  143. package/dist/engine/classifier.test.js +115 -0
  144. package/dist/engine/classifier.test.js.map +1 -0
  145. package/dist/engine/dispatcher.d.ts +60 -0
  146. package/dist/engine/dispatcher.js +601 -0
  147. package/dist/engine/dispatcher.js.map +1 -0
  148. package/dist/engine/dispatcher.test.d.ts +1 -0
  149. package/dist/engine/dispatcher.test.js +511 -0
  150. package/dist/engine/dispatcher.test.js.map +1 -0
  151. package/dist/engine/event-shim.d.ts +117 -0
  152. package/dist/engine/event-shim.js +435 -0
  153. package/dist/engine/event-shim.js.map +1 -0
  154. package/dist/engine/event-shim.test.d.ts +1 -0
  155. package/dist/engine/event-shim.test.js +194 -0
  156. package/dist/engine/event-shim.test.js.map +1 -0
  157. package/dist/engine/git-auth.d.ts +13 -17
  158. package/dist/engine/git-auth.js +99 -42
  159. package/dist/engine/git-auth.js.map +1 -1
  160. package/dist/engine/git-auth.test.d.ts +1 -0
  161. package/dist/engine/git-auth.test.js +117 -0
  162. package/dist/engine/git-auth.test.js.map +1 -0
  163. package/dist/engine/github-app-client.d.ts +7 -0
  164. package/dist/engine/github-app-client.js +16 -0
  165. package/dist/engine/github-app-client.js.map +1 -0
  166. package/dist/engine/github-app-client.test.d.ts +1 -0
  167. package/dist/engine/github-app-client.test.js +44 -0
  168. package/dist/engine/github-app-client.test.js.map +1 -0
  169. package/dist/engine/github-tools.d.ts +12 -0
  170. package/dist/engine/github-tools.js +261 -0
  171. package/dist/engine/github-tools.js.map +1 -0
  172. package/dist/engine/github.d.ts +1027 -43
  173. package/dist/engine/github.js +153 -14
  174. package/dist/engine/github.js.map +1 -1
  175. package/dist/engine/llm.d.ts +47 -0
  176. package/dist/engine/llm.js +221 -0
  177. package/dist/engine/llm.js.map +1 -0
  178. package/dist/engine/llm.test.d.ts +1 -0
  179. package/dist/engine/llm.test.js +189 -0
  180. package/dist/engine/llm.test.js.map +1 -0
  181. package/dist/engine/profiles.d.ts +249 -0
  182. package/dist/engine/profiles.js +42 -0
  183. package/dist/engine/profiles.js.map +1 -0
  184. package/dist/engine/router.d.ts +12 -6
  185. package/dist/engine/router.js +339 -81
  186. package/dist/engine/router.js.map +1 -1
  187. package/dist/engine/router.test.js +428 -78
  188. package/dist/engine/router.test.js.map +1 -1
  189. package/dist/engine/screen.d.ts +41 -0
  190. package/dist/engine/screen.js +93 -0
  191. package/dist/engine/screen.js.map +1 -0
  192. package/dist/engine/screen.test.d.ts +1 -0
  193. package/dist/engine/screen.test.js +82 -0
  194. package/dist/engine/screen.test.js.map +1 -0
  195. package/dist/index.js +377 -432
  196. package/dist/index.js.map +1 -1
  197. package/dist/managed-repos.d.ts +7 -9
  198. package/dist/managed-repos.js +12 -15
  199. package/dist/managed-repos.js.map +1 -1
  200. package/dist/managed-repos.test.js +24 -19
  201. package/dist/managed-repos.test.js.map +1 -1
  202. package/dist/notify/index.d.ts +15 -0
  203. package/dist/notify/index.js +6 -0
  204. package/dist/notify/index.js.map +1 -0
  205. package/dist/notify/model.d.ts +57 -0
  206. package/dist/notify/model.js +89 -0
  207. package/dist/notify/model.js.map +1 -0
  208. package/dist/notify/model.test.d.ts +1 -0
  209. package/dist/notify/model.test.js +109 -0
  210. package/dist/notify/model.test.js.map +1 -0
  211. package/dist/notify/notifier.d.ts +17 -0
  212. package/dist/notify/notifier.js +87 -0
  213. package/dist/notify/notifier.js.map +1 -0
  214. package/dist/notify/notifier.test.d.ts +1 -0
  215. package/dist/notify/notifier.test.js +100 -0
  216. package/dist/notify/notifier.test.js.map +1 -0
  217. package/dist/notify/render.d.ts +21 -0
  218. package/dist/notify/render.js +59 -0
  219. package/dist/notify/render.js.map +1 -0
  220. package/dist/notify/render.test.d.ts +1 -0
  221. package/dist/notify/render.test.js +65 -0
  222. package/dist/notify/render.test.js.map +1 -0
  223. package/dist/notify/transports/github.d.ts +26 -0
  224. package/dist/notify/transports/github.js +26 -0
  225. package/dist/notify/transports/github.js.map +1 -0
  226. package/dist/notify/transports/slack.d.ts +26 -0
  227. package/dist/notify/transports/slack.js +28 -0
  228. package/dist/notify/transports/slack.js.map +1 -0
  229. package/dist/notify/transports.test.d.ts +1 -0
  230. package/dist/notify/transports.test.js +71 -0
  231. package/dist/notify/transports.test.js.map +1 -0
  232. package/dist/notify/types.d.ts +95 -0
  233. package/dist/notify/types.js +16 -0
  234. package/dist/notify/types.js.map +1 -0
  235. package/dist/sandbox/docker-compose.test.d.ts +1 -0
  236. package/dist/sandbox/docker-compose.test.js +128 -0
  237. package/dist/sandbox/docker-compose.test.js.map +1 -0
  238. package/dist/sandbox/docker.d.ts +97 -9
  239. package/dist/sandbox/docker.js +192 -41
  240. package/dist/sandbox/docker.js.map +1 -1
  241. package/dist/sandbox/docker.test.d.ts +1 -0
  242. package/dist/sandbox/docker.test.js +137 -0
  243. package/dist/sandbox/docker.test.js.map +1 -0
  244. package/dist/sandbox/egress-allowlist.d.ts +69 -0
  245. package/dist/sandbox/egress-allowlist.js +164 -0
  246. package/dist/sandbox/egress-allowlist.js.map +1 -0
  247. package/dist/sandbox/egress-allowlist.test.d.ts +1 -0
  248. package/dist/sandbox/egress-allowlist.test.js +65 -0
  249. package/dist/sandbox/egress-allowlist.test.js.map +1 -0
  250. package/dist/sandbox/egress-firewall-config.d.ts +127 -0
  251. package/dist/sandbox/egress-firewall-config.js +434 -0
  252. package/dist/sandbox/egress-firewall-config.js.map +1 -0
  253. package/dist/sandbox/egress-firewall-config.test.d.ts +1 -0
  254. package/dist/sandbox/egress-firewall-config.test.js +244 -0
  255. package/dist/sandbox/egress-firewall-config.test.js.map +1 -0
  256. package/dist/sandbox/images.d.ts +23 -0
  257. package/dist/sandbox/images.js +55 -0
  258. package/dist/sandbox/images.js.map +1 -0
  259. package/dist/sandbox/index.d.ts +82 -3
  260. package/dist/sandbox/index.js +223 -93
  261. package/dist/sandbox/index.js.map +1 -1
  262. package/dist/sandbox/index.test.d.ts +1 -0
  263. package/dist/sandbox/index.test.js +157 -0
  264. package/dist/sandbox/index.test.js.map +1 -0
  265. package/dist/session-log.d.ts +63 -0
  266. package/dist/session-log.js +290 -0
  267. package/dist/session-log.js.map +1 -0
  268. package/dist/session-log.test.d.ts +1 -0
  269. package/dist/session-log.test.js +85 -0
  270. package/dist/session-log.test.js.map +1 -0
  271. package/dist/setup.d.ts +30 -1
  272. package/dist/setup.js +241 -25
  273. package/dist/setup.js.map +1 -1
  274. package/dist/setup.test.js +138 -6
  275. package/dist/setup.test.js.map +1 -1
  276. package/dist/state/approval-store.d.ts +86 -0
  277. package/dist/state/approval-store.js +140 -0
  278. package/dist/state/approval-store.js.map +1 -0
  279. package/dist/state/build-assets.d.ts +50 -0
  280. package/dist/state/build-assets.js +154 -0
  281. package/dist/state/build-assets.js.map +1 -0
  282. package/dist/state/build-assets.test.d.ts +1 -0
  283. package/dist/state/build-assets.test.js +106 -0
  284. package/dist/state/build-assets.test.js.map +1 -0
  285. package/dist/state/db.d.ts +65 -333
  286. package/dist/state/db.js +112 -835
  287. package/dist/state/db.js.map +1 -1
  288. package/dist/state/db.test.js +127 -91
  289. package/dist/state/db.test.js.map +1 -1
  290. package/dist/state/execution-store.d.ts +257 -0
  291. package/dist/state/execution-store.js +527 -0
  292. package/dist/state/execution-store.js.map +1 -0
  293. package/dist/state/migrate.d.ts +15 -0
  294. package/dist/state/migrate.js +175 -0
  295. package/dist/state/migrate.js.map +1 -0
  296. package/dist/state/workflow-run-store.d.ts +195 -0
  297. package/dist/state/workflow-run-store.js +363 -0
  298. package/dist/state/workflow-run-store.js.map +1 -0
  299. package/dist/state/workflow-run-store.test.d.ts +1 -0
  300. package/dist/state/workflow-run-store.test.js +264 -0
  301. package/dist/state/workflow-run-store.test.js.map +1 -0
  302. package/dist/telemetry/index.d.ts +38 -0
  303. package/dist/telemetry/index.js +253 -0
  304. package/dist/telemetry/index.js.map +1 -0
  305. package/dist/telemetry/index.test.d.ts +1 -0
  306. package/dist/telemetry/index.test.js +73 -0
  307. package/dist/telemetry/index.test.js.map +1 -0
  308. package/dist/telemetry/pi-events.d.ts +12 -0
  309. package/dist/telemetry/pi-events.js +134 -0
  310. package/dist/telemetry/pi-events.js.map +1 -0
  311. package/dist/telemetry/pi-events.test.d.ts +1 -0
  312. package/dist/telemetry/pi-events.test.js +69 -0
  313. package/dist/telemetry/pi-events.test.js.map +1 -0
  314. package/dist/workflows/dag.d.ts +13 -1
  315. package/dist/workflows/dag.js +7 -3
  316. package/dist/workflows/dag.js.map +1 -1
  317. package/dist/workflows/dag.test.js +22 -0
  318. package/dist/workflows/dag.test.js.map +1 -1
  319. package/dist/workflows/golden-build.test.d.ts +1 -0
  320. package/dist/workflows/golden-build.test.js +45 -0
  321. package/dist/workflows/golden-build.test.js.map +1 -0
  322. package/dist/workflows/loader-overlay.test.d.ts +1 -0
  323. package/dist/workflows/loader-overlay.test.js +101 -0
  324. package/dist/workflows/loader-overlay.test.js.map +1 -0
  325. package/dist/workflows/loader.d.ts +36 -11
  326. package/dist/workflows/loader.js +311 -87
  327. package/dist/workflows/loader.js.map +1 -1
  328. package/dist/workflows/loader.test.js +114 -10
  329. package/dist/workflows/loader.test.js.map +1 -1
  330. package/dist/workflows/loop-eval.js +2 -0
  331. package/dist/workflows/loop-eval.js.map +1 -1
  332. package/dist/workflows/loop-eval.test.js +14 -0
  333. package/dist/workflows/loop-eval.test.js.map +1 -1
  334. package/dist/workflows/phase-executor.d.ts +145 -0
  335. package/dist/workflows/phase-executor.js +691 -0
  336. package/dist/workflows/phase-executor.js.map +1 -0
  337. package/dist/workflows/phase-executor.test.d.ts +1 -0
  338. package/dist/workflows/phase-executor.test.js +434 -0
  339. package/dist/workflows/phase-executor.test.js.map +1 -0
  340. package/dist/workflows/phase-ref.d.ts +44 -0
  341. package/dist/workflows/phase-ref.js +78 -0
  342. package/dist/workflows/phase-ref.js.map +1 -0
  343. package/dist/workflows/phase-ref.test.d.ts +1 -0
  344. package/dist/workflows/phase-ref.test.js +24 -0
  345. package/dist/workflows/phase-ref.test.js.map +1 -0
  346. package/dist/workflows/resume.d.ts +5 -11
  347. package/dist/workflows/resume.js +88 -7
  348. package/dist/workflows/resume.js.map +1 -1
  349. package/dist/workflows/runner.d.ts +34 -27
  350. package/dist/workflows/runner.js +252 -930
  351. package/dist/workflows/runner.js.map +1 -1
  352. package/dist/workflows/runner.test.js +346 -35
  353. package/dist/workflows/runner.test.js.map +1 -1
  354. package/dist/workflows/schema.d.ts +52 -10
  355. package/dist/workflows/schema.js +147 -7
  356. package/dist/workflows/schema.js.map +1 -1
  357. package/dist/workflows/simple.d.ts +67 -3
  358. package/dist/workflows/simple.js +248 -87
  359. package/dist/workflows/simple.js.map +1 -1
  360. package/dist/workflows/simple.test.d.ts +1 -0
  361. package/dist/workflows/simple.test.js +107 -0
  362. package/dist/workflows/simple.test.js.map +1 -0
  363. package/dist/workflows/templates.d.ts +29 -0
  364. package/dist/workflows/templates.js +42 -4
  365. package/dist/workflows/templates.js.map +1 -1
  366. package/dist/workflows/templates.test.js +103 -0
  367. package/dist/workflows/templates.test.js.map +1 -1
  368. package/dist/workflows/triggers.d.ts +21 -0
  369. package/dist/workflows/triggers.js +44 -0
  370. package/dist/workflows/triggers.js.map +1 -0
  371. package/dist/workflows/verdict.d.ts +19 -0
  372. package/dist/workflows/verdict.js +30 -0
  373. package/dist/workflows/verdict.js.map +1 -0
  374. package/dist/workflows/verdict.test.d.ts +1 -0
  375. package/dist/workflows/verdict.test.js +44 -0
  376. package/dist/workflows/verdict.test.js.map +1 -0
  377. package/dist/worktree/manager.d.ts +1 -1
  378. package/dist/worktree/manager.js +14 -14
  379. package/dist/worktree/manager.js.map +1 -1
  380. package/dist/worktree/manager.test.d.ts +1 -0
  381. package/dist/worktree/manager.test.js +87 -0
  382. package/dist/worktree/manager.test.js.map +1 -0
  383. package/docker-compose.yml +206 -5
  384. package/package.json +19 -9
  385. package/sandbox.Dockerfile +97 -18
  386. package/skills/README.md +40 -0
  387. package/skills/browser-qa/SKILL.md +193 -0
  388. package/skills/browser-qa/scripts/agent-browser.mjs +380 -0
  389. package/skills/building/SKILL.md +95 -0
  390. package/skills/chat/SKILL.md +30 -11
  391. package/skills/code-review/SKILL.md +59 -0
  392. package/skills/debug-production/SKILL.md +108 -0
  393. package/skills/demo/SKILL.md +194 -0
  394. package/skills/demo/scripts/compose-demo.sh +205 -0
  395. package/skills/issue-answer/SKILL.md +90 -0
  396. package/skills/issue-comment/SKILL.md +38 -24
  397. package/skills/issue-triage/SKILL.md +103 -37
  398. package/skills/issue-triage/references/AGENT-BRIEF.md +61 -0
  399. package/skills/pr-comment/SKILL.md +64 -0
  400. package/skills/pr-review/SKILL.md +65 -49
  401. package/skills/qa-test/SKILL.md +97 -0
  402. package/skills/repo-health/SKILL.md +48 -45
  403. package/skills/security-feedback/SKILL.md +173 -0
  404. package/skills/security-feedback/references/templates.md +77 -0
  405. package/skills/security-review/SKILL.md +213 -0
  406. package/skills/security-review/references/issue-format.md +302 -0
  407. package/skills/verify/SKILL.md +118 -0
  408. package/workflows/answer.yaml +37 -0
  409. package/workflows/build.yaml +32 -22
  410. package/workflows/cron-security.yaml +6 -0
  411. package/workflows/demo.yaml +55 -0
  412. package/workflows/explore.yaml +9 -0
  413. package/workflows/pr-comment.yaml +16 -0
  414. package/workflows/pr-fix.yaml +3 -0
  415. package/workflows/pr-review.yaml +4 -1
  416. package/workflows/prompts/answer.md +67 -0
  417. package/workflows/prompts/architect.md +24 -7
  418. package/workflows/prompts/demo.md +100 -0
  419. package/workflows/prompts/executor.md +29 -20
  420. package/workflows/prompts/explore-ask.md +51 -22
  421. package/workflows/prompts/explore-publish.md +2 -2
  422. package/workflows/prompts/explore-read.md +24 -10
  423. package/workflows/prompts/explore-synthesize.md +15 -8
  424. package/workflows/prompts/fix.md +9 -10
  425. package/workflows/prompts/guardrails.md +26 -8
  426. package/workflows/prompts/pr-fix.md +6 -7
  427. package/workflows/prompts/pr.md +11 -10
  428. package/workflows/prompts/qa-browser.md +95 -0
  429. package/workflows/prompts/qa-synth.md +44 -0
  430. package/workflows/prompts/qa-test.md +60 -0
  431. package/workflows/prompts/re-reviewer.md +8 -9
  432. package/workflows/prompts/reviewer.md +10 -9
  433. package/workflows/prompts/verify-browser.md +93 -0
  434. package/workflows/prompts/verify-synth.md +44 -0
  435. package/workflows/prompts/verify.md +63 -0
  436. package/workflows/qa-test.yaml +87 -0
  437. package/workflows/security-feedback.yaml +25 -0
  438. package/workflows/security-review.yaml +29 -0
  439. package/workflows/verify.yaml +85 -0
  440. package/deploy/mcp-config.tmpl.json +0 -14
  441. package/dist/cron/rate-limits.d.ts +0 -26
  442. package/dist/cron/rate-limits.js +0 -193
  443. package/dist/cron/rate-limits.js.map +0 -1
  444. package/dist/engine/executor.d.ts +0 -75
  445. package/dist/engine/executor.js +0 -292
  446. package/dist/engine/executor.js.map +0 -1
  447. package/mcp-github-app/package.json +0 -18
  448. package/mcp-github-app/src/auth.js +0 -66
  449. package/mcp-github-app/src/github.js +0 -371
  450. package/mcp-github-app/src/index.js +0 -534
  451. package/skills/devops/webhook-subscriptions/SKILL.md +0 -180
  452. package/skills/github/DESCRIPTION.md +0 -3
  453. package/skills/github/codebase-inspection/SKILL.md +0 -115
  454. package/skills/github/github-auth/SKILL.md +0 -54
  455. package/skills/github/github-auth/scripts/gh-env.sh +0 -66
  456. package/skills/github/github-code-review/SKILL.md +0 -480
  457. package/skills/github/github-code-review/references/review-output-template.md +0 -74
  458. package/skills/github/github-issues/SKILL.md +0 -369
  459. package/skills/github/github-issues/templates/bug-report.md +0 -35
  460. package/skills/github/github-issues/templates/feature-request.md +0 -31
  461. package/skills/github/github-pr-workflow/SKILL.md +0 -395
  462. package/skills/github/github-pr-workflow/references/ci-troubleshooting.md +0 -183
  463. package/skills/github/github-pr-workflow/references/conventional-commits.md +0 -71
  464. package/skills/github/github-pr-workflow/templates/pr-body-bugfix.md +0 -35
  465. package/skills/github/github-pr-workflow/templates/pr-body-feature.md +0 -33
  466. package/skills/github/github-repo-management/SKILL.md +0 -515
  467. package/skills/github/github-repo-management/references/github-api-cheatsheet.md +0 -161
  468. package/skills/github-orchestrator/SKILL.md +0 -103
  469. package/skills/mcp/DESCRIPTION.md +0 -3
  470. package/skills/mcp/mcporter/SKILL.md +0 -122
  471. package/skills/mcp/native-mcp/SKILL.md +0 -356
  472. package/skills/software-development/architect/SKILL.md +0 -154
  473. package/skills/software-development/assure-guardrails/SKILL.md +0 -239
  474. package/skills/software-development/plan/SKILL.md +0 -64
  475. package/skills/software-development/requesting-code-review/SKILL.md +0 -291
  476. package/skills/software-development/subagent-driven-development/SKILL.md +0 -433
  477. package/skills/software-development/systematic-debugging/SKILL.md +0 -366
  478. package/skills/software-development/test-driven-development/SKILL.md +0 -342
@@ -0,0 +1,173 @@
1
+ ---
2
+ name: security-feedback
3
+ description: Process a maintainer's comment on a security scan-summary issue — break selected findings out into individual actionable issues, or record accepted risks / false positives in SECURITY.md.
4
+ version: 2.0.0
5
+ tags: [github, security, feedback]
6
+ ---
7
+
8
+ # Security Feedback
9
+
10
+ A maintainer commented on a `security`-labelled issue — almost always a per-run
11
+ **security scan summary** (one issue per scan, a task-list of findings). Based on
12
+ the comment, either:
13
+
14
+ - **Break selected findings into individual issues** (each can later feed `build`). Primary flow.
15
+ - **Record a suppression** in `SECURITY.md` (accepted risk / false positive).
16
+ - Reply for discussion, or ignore noise.
17
+
18
+ The parent issue's grammar is the contract defined in
19
+ `skills/security-review/references/issue-format.md`. This skill is staged into its
20
+ own workspace and **cannot read that file**, so it carries its own copy of the
21
+ row/severity regex below — **if you change the grammar, update both in lockstep.**
22
+
23
+ ## Context
24
+
25
+ - `context.repo` — `owner/name`
26
+ - `context.issueNumber` — the security summary issue (parent)
27
+ - `context.commentBody` — the triggering comment
28
+ - `context.sender` — the commenter's GitHub login
29
+
30
+ The parent body is not passed — fetch it at step 1.
31
+
32
+ ## 1. Fetch and parse the parent issue
33
+
34
+ `github_get_issue({ owner, repo, issue_number: issueNumber })`.
35
+
36
+ **Version check.** The body MUST start with `<!-- lastlight-security-scan-version: 1 -->`.
37
+ If the marker is missing or the version isn't `1`, reply: "Unknown scan-summary
38
+ format — this skill is at version 1 but the parent reports a different version.
39
+ Ask the maintainer to re-run `@last-light security-review`." Do not parse further.
40
+
41
+ **Parse each finding row** with this canonical regex (all three states):
42
+
43
+ ```
44
+ /^- \[([ x])\] <!-- item:(\d+) fp:([0-9a-f]{8,}) --> (?:~~)?\*\*(.+?)\*\* — `([^`]+):(\d+)` \(([a-z][a-z0-9-]*) · `([^`]+)`\)(?:~~ → #(\d+))?$/m
45
+ ```
46
+
47
+ Captures: `checkbox` (` `/`x`), `item`, `fp`, `title`, `file`, `line`, `tool`,
48
+ `rule`, and `subIssueNumber` (only when already broken out). Derive per row:
49
+
50
+ | Derived | Definition |
51
+ |---------|------------|
52
+ | `alreadyBrokenOut` | `subIssueNumber != null` — turned into a sub-issue on a prior run |
53
+ | `userTicked` | `checkbox === "x" && !alreadyBrokenOut` — the maintainer ticked the box, selecting it |
54
+
55
+ `userTicked` is the primary selection signal; `alreadyBrokenOut` rows are never
56
+ re-selected regardless of checkbox state.
57
+
58
+ **Severity** comes from the nearest preceding section header (tolerating a
59
+ trailing truncation suffix like `(showing first 7 of 25)`):
60
+
61
+ ```
62
+ /^### (🔴|🟠|🟡|🟢) (Critical|High|Medium|Low) \((\d+)\)(?:\s.*)?$/m
63
+ ```
64
+
65
+ Map Critical/High/Medium/Low → `p0-critical`/`p1-high`/`p2-medium`/`p3-low`.
66
+
67
+ **Parse the `<details>` block** after each row (starts `<details><summary>Details</summary>`,
68
+ ends `</details>`): the fenced block → `snippet` + `language`; paragraphs between
69
+ the fence and `**Suggested fix:**` → `explanation`; text after `**Suggested fix:**`
70
+ → `suggestedFix`.
71
+
72
+ Store each finding as `{ item, fp, title, file, line, tool, rule, severity,
73
+ language, snippet, explanation, suggestedFix, userTicked, alreadyBrokenOut, subIssueNumber? }`.
74
+
75
+ ## 2. Classify the comment intent
76
+
77
+ Pick the single best-fit bucket:
78
+
79
+ - **create-issues** — break selected findings out. Signals: bare `@last-light
80
+ create issues` (defaults to ticked), "create issues for…", "make issues for…",
81
+ "break out…", "file sub-issues for…", "create an issue for items 1, 3".
82
+ - **accept-risk** — accept a finding's risk. Signals: "accept-risk:", "we know
83
+ about this", "won't fix", "accepted".
84
+ - **false-positive** — not real. Signals: "false-positive:", "not a vulnerability",
85
+ "not applicable".
86
+ - **reopen** — re-evaluate a suppressed finding. Signals: "reopen", "re-evaluate".
87
+ - **discuss** — a question or conversation about the findings.
88
+ - **ignore** — noise (thanks, unrelated remark).
89
+
90
+ `accept-risk` / `false-positive` / `reopen` MUST name a specific finding via
91
+ `item N` / `item: N` — fall through to `discuss` if unresolved.
92
+
93
+ ## 3. Act
94
+
95
+ ### create-issues
96
+
97
+ 1. **Resolve the selection** (first match wins):
98
+ - **`ticked` / `checked` / `selected`** → every `userTicked` finding. Preferred UX.
99
+ - **Default (no qualifier)** → treat as `ticked`. If no rows are ticked, reply:
100
+ ```
101
+ No rows are ticked. Tick the checkboxes on the findings you want broken out, then comment again — or use one of:
102
+ - `@last-light create issues for the criticals`
103
+ - `@last-light create issues for items 1, 3, 5`
104
+ - `@last-light create issues for all`
105
+ ```
106
+ - `all` / `every` → every parsed finding regardless of tick state.
107
+ - `criticals` / `the criticals` / `p0-critical` → every `p0-critical` (same for
108
+ highs/mediums/lows). A count in the comment ("5 criticals") is ignored.
109
+ - `items N, M` / `item N` → specific 1-based item numbers from `<!-- item:N -->`.
110
+
111
+ In every form, silently drop `alreadyBrokenOut` findings and mention them in the
112
+ summary. If the selection is empty, reply:
113
+ ```
114
+ No findings matched `{selection text}`. This scan has: {nC} critical, {nH} high, {nM} medium, {nL} low. Ticked: {nTicked}. Already broken out: {nDone}.
115
+ ```
116
+ and create nothing. If the form is unrecognised (ambiguous), ask for clarification — don't guess.
117
+
118
+ 2. **For each selected finding**, `github_create_issue` using the sub-issue body
119
+ template in [references/templates.md](references/templates.md). Record each new
120
+ `subIssueNumber` against its `item`.
121
+
122
+ 3. **Rewrite the parent body.** For every finding just broken out, transition its
123
+ row to **broken-out**:
124
+ ```
125
+ - [x] <!-- item:N fp:FP --> ~~**TITLE** — `FILE:LINE` (TOOL · `RULE`)~~ → #SUBISSUE
126
+ ```
127
+ (checkbox `[x]`, title+location wrapped in `~~…~~`, ` → #SUBISSUE` appended).
128
+ Match by `item:N`. Do **not** touch rows that weren't selected, even if ticked.
129
+ Preserve all other content byte-for-byte. `github_update_issue`.
130
+
131
+ 4. **Post a summary comment** on the parent:
132
+ ```
133
+ Created {N} sub-issue(s) at @{sender}'s request:
134
+
135
+ - #{subN1} — {title 1} (item {item1})
136
+
137
+
138
+ {if any skipped}: Skipped {M} item(s) already broken out: items {list}.
139
+
140
+ Comment `@last-light build` on any sub-issue to start a fix.
141
+ ```
142
+
143
+ ### accept-risk / false-positive
144
+
145
+ 1. Resolve the target by `item N`; fall through to `discuss` if absent/unknown.
146
+ 2. Extract the reason (text after the first `:`, trimmed; "no reason given" if absent).
147
+ 3. `github_clone_repo`. Read `SECURITY.md`; create from the scaffold in
148
+ [references/templates.md](references/templates.md) if missing.
149
+ 4. Append a row to the matching table (accepted risks OR false positives) per the
150
+ template.
151
+ 5. Commit on branch `security/feedback-{parentIssueNumber}-{shortFingerprint}`,
152
+ push, and open a PR titled `security: record {accept-risk|false-positive} for {shortFingerprint}`.
153
+ 6. Comment on the parent: `Opened PR #{prNumber} to record this in SECURITY.md.
154
+ Once merged, this finding will be suppressed in future scans.`
155
+ 7. Do **not** tick the task-list checkbox — that marker is reserved for "broken out to sub-issue".
156
+
157
+ ### reopen
158
+
159
+ Reply: "To re-evaluate this finding, run `@last-light security-review` — the next
160
+ scan re-picks it up if `SECURITY.md` has been updated." Do not modify `SECURITY.md`.
161
+
162
+ ### discuss
163
+
164
+ Reply conversationally using the finding's `<details>` block (risk, tool, suggested
165
+ fix). Don't modify `SECURITY.md` or create sub-issues.
166
+
167
+ ### ignore
168
+
169
+ Take no action.
170
+
171
+ ## Tool usage
172
+
173
+ GitHub operations via `github_*` MCP tools only — never `gh` CLI, `curl`, or raw HTTP.
@@ -0,0 +1,77 @@
1
+ # security-feedback templates
2
+
3
+ ## Sub-issue body (create-issues)
4
+
5
+ `github_create_issue` with `title` = the finding's `title` (exactly as parsed, no
6
+ prefix/suffix), `labels` = `["security", severity]` (e.g. `["security",
7
+ "p0-critical"]`), and this body:
8
+
9
+ ````markdown
10
+ <!-- fp:{fingerprint} -->
11
+ <!-- parent-security-scan: #{parentIssueNumber} -->
12
+
13
+ Broken out from security scan #{parentIssueNumber} on {today's date} at @{sender}'s request.
14
+
15
+ **File**: `{file}:{line}`
16
+ **Tool**: {tool} · `{rule}`
17
+ **Severity**: {severity}
18
+
19
+ ```{language}
20
+ {snippet}
21
+ ```
22
+
23
+ {explanation}
24
+
25
+ ## Suggested fix
26
+
27
+ {suggestedFix}
28
+
29
+ ---
30
+
31
+ _To build a fix for this finding, comment `@last-light build` on this issue._
32
+ ````
33
+
34
+ ## SECURITY.md scaffold (accept-risk / false-positive)
35
+
36
+ Create this if `SECURITY.md` is missing, then append the row:
37
+
38
+ ```markdown
39
+ # SECURITY.md
40
+
41
+ This file configures the Last Light security scanner for this repository.
42
+
43
+ ## Tool configuration
44
+
45
+ | Tool | Severity floor |
46
+ |------|---------------|
47
+ | npm-audit | medium |
48
+ | semgrep | medium |
49
+ | gitleaks | high |
50
+ | claude | medium |
51
+
52
+ ## Accepted risks
53
+
54
+ Findings in this table are known risks the maintainers have explicitly accepted.
55
+ The scanner will not re-file issues for these findings.
56
+
57
+ | Fingerprint | Title | Reason | Date | Issue |
58
+ |-------------|-------|--------|------|-------|
59
+
60
+ ## False positives
61
+
62
+ Findings in this table have been classified as not real security issues.
63
+ The scanner will not re-file issues for these findings.
64
+
65
+ | Fingerprint | Title | Reason | Date | Issue |
66
+ |-------------|-------|--------|------|-------|
67
+ ```
68
+
69
+ Appended row (to whichever table matches the intent):
70
+
71
+ | Column | Value |
72
+ |--------|-------|
73
+ | Fingerprint | First 16 hex chars of the finding's `fp` |
74
+ | Title | Finding's `title` |
75
+ | Reason | Extracted reason (text after the first `:`; "no reason given" if absent) |
76
+ | Date | Today's date (YYYY-MM-DD, UTC) |
77
+ | Issue | `#{parentIssueNumber}` |
@@ -0,0 +1,213 @@
1
+ ---
2
+ name: security-review
3
+ description: Diff-scoped security review of SDLC concerns GitHub's scanners miss — workflow/CI hardening, auth changes, secret handling, supply-chain churn. Files one dated summary issue with a task-list of findings. Use on a security cron or when asked to scan a repo.
4
+ version: 2.0.0
5
+ tags: [github, security, review]
6
+ ---
7
+
8
+ # Security Review
9
+
10
+ Review **what changed in the repo since the last scan** with a security lens,
11
+ focused on SDLC concerns that GitHub's built-in scanners (Dependabot, Code
12
+ Scanning, Secret Scanning) and Renovate don't cover. File **one summary issue
13
+ per run**, dated, containing a GitHub task list of any findings. Honour
14
+ `SECURITY.md` to suppress accepted risks and false positives.
15
+
16
+ This is **not** a general vulnerability scanner. It does not run `npm audit`
17
+ (Dependabot does). It does not run `semgrep --config auto` over the whole tree
18
+ (Code Scanning does). It looks at the diff since the prior scan and surfaces what
19
+ humans introduced — CI hardening, auth changes, secret handling in new code,
20
+ supply-chain churn.
21
+
22
+ The summary issue's structure is the machine-parsed contract a maintainer's
23
+ later comment is processed against (the `security-feedback` skill). It is defined
24
+ in **[references/issue-format.md](references/issue-format.md)** — follow it
25
+ exactly when composing the issue (§9).
26
+
27
+ ## Context
28
+
29
+ - `context.repo` — `owner/name` to scan
30
+ - `context.deliverSlackSummary` — if true, output a one-line Slack summary as the final response
31
+ - `context.issueDir` — directory for the run summary file (e.g. `.lastlight/security-<date>`)
32
+
33
+ ## Procedure
34
+
35
+ ### 1. Clone, find the prior-scan anchor, read SECURITY.md
36
+
37
+ 1. Clone the target repo via `github_clone_repo`.
38
+ 2. **Prior scan anchor.** Query issues labelled `security-scan` (open OR closed),
39
+ newest first. Read the latest one's body for the
40
+ `<!-- lastlight-security-scan-ts: ... -->` comment and use that ISO-8601
41
+ timestamp as `priorScanTs`. No prior scan issue → `priorScanTs = now - 30 days`
42
+ (bootstrap floor — keeps the first run finite).
43
+ 3. Read `SECURITY.md` at the repo root (if present): per-tool severity floors
44
+ (default `medium`; skip `low`/`info`), the accepted-risks table, and the
45
+ false-positives table (both keyed by finding fingerprint).
46
+
47
+ ### 1.5. Compute the changeset
48
+
49
+ Most weeks the diff is dominated by Renovate/Dependabot churn — strip it so the
50
+ scope is what humans wrote.
51
+
52
+ 1. `git log --since="${priorScanTs}" --pretty=format:'%H|%an|%ae|%s'`.
53
+ 2. Drop a commit when **either**: author email matches
54
+ `*[bot]@users.noreply.github.com` and name is `dependabot[bot]` /
55
+ `renovate[bot]` / `github-actions[bot]`; OR the subject starts with
56
+ `chore(deps)`, `chore(deps-dev)`, `build(deps)`, `build(deps-dev)`, `fix(deps)`.
57
+ 3. Accumulate changed files from the surviving commits
58
+ (`git diff-tree --no-commit-id --name-only -r ${sha}`) into a deduped
59
+ `changedFiles` set.
60
+ 4. Drop entries that are **only** lockfiles (`package-lock.json`, `pnpm-lock.yaml`,
61
+ `yarn.lock`, `bun.lockb`, `Gemfile.lock`, `poetry.lock`, `uv.lock`,
62
+ `Cargo.lock`, `composer.lock`) — catches lockfile changes mixed into human commits.
63
+ 5. Build `commitsReviewed` = surviving commits as `{ shortSha, subject }` (used in the scope note).
64
+
65
+ **Early exit.** If `changedFiles` is empty after filtering, **stop**: run no
66
+ scanner, create no issue, emit no Slack message. Write the run summary file (§10)
67
+ recording "no relevant changes since prior scan" and return.
68
+
69
+ ### 2. Ensure labels exist
70
+
71
+ `github_create_label` for each (idempotent — ignore 422):
72
+
73
+ | Label | Color | Purpose |
74
+ |-------|-------|---------|
75
+ | `security` | `ee0701` | Any security-related issue |
76
+ | `security-scan` | `fbca04` | The per-run summary issue |
77
+ | `p0-critical` | `b60205` | Severity |
78
+ | `p1-high` | `d93f0b` | Severity |
79
+ | `p2-medium` | `fbca04` | Severity |
80
+ | `p3-low` | `0e8a16` | Severity |
81
+
82
+ ### 3. Run change-scoped scanners
83
+
84
+ Three sources, all narrowed to the changeset. Do **not** run `npm audit` or
85
+ `semgrep --config auto .` over the whole tree (covered elsewhere; the noise
86
+ drowns the signal).
87
+
88
+ - **Gitleaks (commit range):**
89
+ `gitleaks detect --source . --log-opts="--since=${priorScanTs}" --report-format json --report-path /tmp/gitleaks.json`
90
+ — secrets introduced in the new history.
91
+ - **Semgrep (changed files only):**
92
+ `semgrep --config auto --json $(printf -- '--include=%s ' "${changedFiles[@]}")`
93
+ — only files that changed; far less noise.
94
+ - **Claude SDLC review** — the unique value-add. Read `git diff ${priorScanTs}..HEAD`
95
+ plus the current contents of changed files against the checklist below. Each
96
+ match becomes a finding with `tool: "claude"` and the §4 severity.
97
+
98
+ - **GitHub Actions / CI** (`.github/workflows/*.yml`): actions pinned by
99
+ floating ref (`@main`/`@master`/`@v1`) not a commit SHA; `pull_request_target`
100
+ that checks out the PR head; missing top-level/job `permissions:` block;
101
+ `${{ secrets.* }}` interpolated into shell/`run:`/echo where it can land in
102
+ logs; untrusted PR body/title/branch interpolated into a `run:` block.
103
+ - **Dockerfile / compose**: base images on floating tags (no digest) introduced
104
+ here; new `RUN curl … | sh` / `wget … | bash`; new `--privileged`/`--cap-add`,
105
+ removed `security_opt`/`read_only` hardening; new host-exposed ports without need.
106
+ - **Auth / authorization**: modified middleware, route guards, role checks, CORS,
107
+ JWT verification, OAuth handlers, webhook signature verification (HMAC compare,
108
+ `crypto.timingSafeEqual` replaced with `===`).
109
+ - **Secret handling in new code**: new `process.env.*` reads whose value flows
110
+ into a log or HTTP response; new code logging Authorization headers/cookies/tokens;
111
+ hardcoded key/URL-shaped literals gitleaks missed.
112
+ - **Shell exec on attacker-influenced args**: new `execSync`/`exec`/`spawn` where
113
+ any argument is non-static (concatenation, interpolation, request-derived).
114
+ - **Supply-chain churn** (`package.json` diff): **new** top-level
115
+ `dependencies`/`devDependencies` entries (not version bumps — filtered at §1.5);
116
+ flag package name + publisher, higher severity for typosquat-shaped names;
117
+ removed integrity controls (`npm ci` → `npm install`, dropped `--ignore-scripts`
118
+ or provenance flags).
119
+ - **Release / publish flows**: changes to publish scripts, `npm publish`, release
120
+ CI steps, signing keys — anything touching what users download.
121
+
122
+ If the only changes are docs/tests/unrelated config and none of the above
123
+ applied, the run legitimately has **no findings** — proceed to §8.
124
+
125
+ ### 4. Normalize findings
126
+
127
+ Convert each to: `{ fingerprint, severity, tool, rule, file, line, title,
128
+ language, snippet, explanation, suggestedFix }`.
129
+
130
+ - `fingerprint` = `sha1(tool + ":" + rule + ":" + file + ":" + 3-line-context)`, lowercase hex.
131
+ - `severity` ∈ `p0-critical | p1-high | p2-medium | p3-low`.
132
+ - `tool` ∈ `npm-audit | semgrep | gitleaks | claude` (lowercase, hyphenated).
133
+ - `rule` = tool-native id, as-is. `file` = repo-relative, forward slashes.
134
+ - `line` = 1-based; `0` when not line-scoped. `title` = one line, no backticks/asterisks.
135
+
136
+ Severity mapping: npm-audit critical/high/moderate/low → p0/p1/p2/p3;
137
+ semgrep ERROR/WARNING/INFO → p1/p2/p3; gitleaks (all) → p1-high;
138
+ claude critical/high/medium/low → p0/p1/p2/p3.
139
+
140
+ ### 5. Apply severity floor
141
+
142
+ Drop findings below the SECURITY.md floor (default `medium` → drops `p3-low`).
143
+
144
+ ### 6. Filter accepted risks / false positives
145
+
146
+ Drop findings whose fingerprint prefix (first 16 hex chars) appears in the
147
+ SECURITY.md accepted-risks or false-positives tables.
148
+
149
+ ### 7. Sort and cap
150
+
151
+ Sort by `(severity rank p0<p1<p2<p3, then file asc, then line asc)`.
152
+
153
+ The issue body has a hard 65,536-char GitHub limit. Cap: keep **ALL** `p0-critical`
154
+ and **ALL** `p1-high`; keep at most **10** of `p2-medium`+`p3-low` combined (the
155
+ first 10 after the sort). Assign 1-based `item` numbers top-to-bottom across the
156
+ **kept** findings. `overflow` = survived-filtering minus kept; surface it in the
157
+ overflow note.
158
+
159
+ The cap intentionally puts no ceiling on critical/high — if a misconfigured
160
+ scanner emits hundreds of highs and the body still overflows, raise the
161
+ `SECURITY.md` floor or tune the scanner's rule severities (fix at the source, not
162
+ by hiding real findings).
163
+
164
+ ### 8. Early exit: no findings
165
+
166
+ If the filtered-and-capped list is empty, **do not** create the summary issue.
167
+ Write the run summary file (§10) recording why and return **silently** — no Slack
168
+ message. The cron is intentionally low-noise: only actual findings surface.
169
+
170
+ ### 9. Compose and create the summary issue
171
+
172
+ Render the body per [references/issue-format.md](references/issue-format.md) and
173
+ `github_create_issue` with `title: Security scan — {YYYY-MM-DD}` (UTC),
174
+ `labels: ["security", "security-scan"]`. Record `summaryIssueNumber`. Do **not**
175
+ touch prior `security-scan` issues — each scan is a point-in-time snapshot.
176
+
177
+ ### 10. Write the run summary file
178
+
179
+ Write `{issueDir}/security-summary.md`:
180
+
181
+ ```markdown
182
+ # Security Scan Summary — {repo}
183
+
184
+ **Date**: {YYYY-MM-DD}
185
+ **Prior scan anchor**: {priorScanTs} (issue #{priorScanIssueNumber} or "bootstrap floor")
186
+ **Commits reviewed**: {N} (after filtering Renovate/Dependabot/lockfile-only)
187
+ **Changed files**: {nFiles}
188
+ **Summary issue**: #{summaryIssueNumber} (or "none — no findings")
189
+
190
+ **Scanner raw counts**: gitleaks: {n}, semgrep: {n}, claude: {n}
191
+ **After severity floor**: {n}
192
+ **After SECURITY.md filtering**: {n} (filed)
193
+ **Suppressed**: {n} (accepted: {nA}, false-positive: {nFP})
194
+ {if overflow > 0}: **Overflow**: {overflow} lower-severity findings omitted (cap: ALL critical/high + first 10 medium/low)
195
+ ```
196
+
197
+ On a §1.5 early exit, still write the file and state `**Early exit**: no human
198
+ commits since prior scan`.
199
+
200
+ ### 11. Slack summary (optional)
201
+
202
+ If `context.deliverSlackSummary` is true, output as the final response:
203
+
204
+ - **With findings:**
205
+ ```
206
+ *Security scan: {repo}* — {n} findings filed in #{summaryIssueNumber} ({N} commits since {priorScanDate})
207
+ Critical: {nC} · High: {nH} · Medium: {nM} · Low: {nL}
208
+ ```
209
+ - **No findings** (scanners ran clean) or **§1.5 early exit** → emit nothing;
210
+ silence matches the cron's low-noise design. The run summary file still records
211
+ what was reviewed.
212
+
213
+ Otherwise output the run summary file contents as the final response.